Esempio n. 1
0
bool transporterIsEmpty(const DROID *psTransporter)
{
	ASSERT(isTransporter(psTransporter), "Non-transporter droid given");

	// Assume dead droids and non-transporter droids to be empty
	return (isDead((const BASE_OBJECT *)psTransporter)
	        || !isTransporter(psTransporter)
	        || psTransporter->psGroup->psList == nullptr
	        || psTransporter->psGroup->psList == psTransporter);
}
Esempio n. 2
0
/*sets psCurrTransporter */
void setCurrentTransporter(UDWORD id)
{
	DROID	*psDroid;
	UDWORD	currID;

	psCurrTransporter = nullptr;
	currID = IDTRANS_START;

	//loop thru all the droids to find the selected one
	for (psDroid = transInterfaceDroidList(); psDroid != nullptr; psDroid = psDroid->psNext)
	{
		if (isTransporter(psDroid) &&
		    (psDroid->action != DACTION_TRANSPORTOUT &&
		     psDroid->action != DACTION_TRANSPORTIN))
		{
			if (currID == id)
			{
				break;
			}
			currID++;
		}
	}
	if (psDroid)
	{
		psCurrTransporter = psDroid;
		//set the data for the transporter timer
		widgSetUserData(psWScreen, IDTRANTIMER_DISPLAY, (void *)psCurrTransporter);
	}
}
Esempio n. 3
0
// Set the secondary order state for all currently selected droids. And Factory (if one selected)
// Returns true if successful.
//
static bool SetSecondaryState(SECONDARY_ORDER sec, unsigned State)
{
	// This code is similar to kfsf_SetSelectedDroidsState() in keybind.cpp. Unfortunately, it seems hard to un-duplicate the code.
	for (unsigned i = 0; i < SelectedDroids.size(); ++i)
	{
		if (SelectedDroids[i])
		{
			//Only set the state if it's not a transporter.
			if (!isTransporter(SelectedDroids[i]))
			{
				if (!secondarySetState(SelectedDroids[i], sec, (SECONDARY_STATE)State))
				{
					return false;
				}
			}
		}
	}

	// set the Factory settings
	if (psSelectedFactory)
	{
		if (!setFactoryState(psSelectedFactory, sec, (SECONDARY_STATE)State))
		{
			return false;
		}
	}

	return true;
}
Esempio n. 4
0
// sendGiftDroids()
// We give selected droid(s) as a gift to another player.
//
// \param from  :player that sent us the droid
// \param to    :player that should be getting the droid
static void sendGiftDroids(uint8_t from, uint8_t to)
{
	DROID        *psD;
	uint8_t      giftType = DROID_GIFT;
	uint8_t      totalToSend;

	if (apsDroidLists[from] == NULL)
	{
		return;
	}

	/*
	 * Work out the number of droids to send. As well as making sure they are
	 * selected we also need to make sure they will NOT put the receiving player
	 * over their droid limit.
	 */

	for (totalToSend = 0, psD = apsDroidLists[from];
	     psD && getNumDroids(to) + totalToSend < getMaxDroids(to) && totalToSend != UINT8_MAX;
	     psD = psD->psNext)
	{
		if (psD->selected)
		{
			++totalToSend;
		}
	}
	/*
	 * We must send one droid at a time, due to the fact that giftSingleDroid()
	 * does its own net calls.
	 */

	for (psD = apsDroidLists[from]; psD && totalToSend != 0; psD = psD->psNext)
	{
		if (isTransporter(psD)
		    && !transporterIsEmpty(psD))
		{
			CONPRINTF(ConsoleString, (ConsoleString, _("Tried to give away a non-empty %s - but this is not allowed."), psD->aName));
			continue;
		}
		if (psD->selected)
		{
			NETbeginEncode(NETgameQueue(selectedPlayer), GAME_GIFT);
			NETuint8_t(&giftType);
			NETuint8_t(&from);
			NETuint8_t(&to);
			// Add the droid to the packet
			NETuint32_t(&psD->id);
			NETend();

			// Decrement the number of droids left to send
			--totalToSend;
		}
	}
}
Esempio n. 5
0
static void ChangeDriver(void)
{
	if (psDrivenDroid != NULL)
	{
		debug(LOG_NEVER, "Driver Changed\n");

		for (DROID *psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid = psDroid->psNext)
		{
			if (psDroid->sMove.Status == MOVEDRIVE)
			{
				ASSERT(!isTransporter(psDroid), "Tried to control a transporter");
				psDroid->sMove.Status = MOVEINACTIVE;
			}
		}
	}
}
Esempio n. 6
0
/*replaces any components necessary for units that are inside a transporter*/
void replaceTransDroidComponents(DROID *psTransporter, UDWORD oldType,
                                 UDWORD oldCompInc, UDWORD newCompInc)
{
	DROID       *psCurr;

	ASSERT(isTransporter(psTransporter), "invalid unit type");

	for (psCurr = psTransporter->psGroup->psList; psCurr != NULL; psCurr =
	         psCurr->psGrpNext)
	{
		if (psCurr != psTransporter)
		{
			switchComponent(psCurr, oldType, oldCompInc, newCompInc);
		}
	}
}
Esempio n. 7
0
/*for a given list of droids, replace the old component if exists*/
void replaceDroidComponent(DROID *pList, UDWORD oldType, UDWORD oldCompInc,
                           UDWORD newCompInc)
{
	DROID   *psDroid;

	//check thru the droids
	for (psDroid = pList; psDroid != NULL; psDroid = psDroid->psNext)
	{
		switchComponent(psDroid, oldType, oldCompInc, newCompInc);
		// Need to replace the units inside the transporter
		if (isTransporter(psDroid))
		{
			replaceTransDroidComponents(psDroid, oldType, oldCompInc, newCompInc);
		}
	}
}
Esempio n. 8
0
// Stop droid driving mode.
//
void StopDriverMode(void)
{
	if (psDrivenDroid != NULL)
	{
		debug(LOG_NEVER, "Drive mode canceled");
		addConsoleMessage("Driver mode canceled.", LEFT_JUSTIFY, SYSTEM_MESSAGE);

		psDrivenDroid = NULL;

		for (DROID *psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid = psDroid->psNext)
		{
			if (psDroid->sMove.Status == MOVEDRIVE)
			{
				ASSERT(!isTransporter(psDroid), "Tried to control a transporter");
				psDroid->sMove.Status = MOVEINACTIVE;
			}
		}
	}

	setDrivingStatus(false);
	driveInitVars(false);	// reset everything again
	DriveControlEnabled = false;
	DirectControl = false;
}
Esempio n. 9
0
// this is able to handle multiple weapon graphics now
// removed mountRotation,they get such stuff from psObj directly now
static bool displayCompObj(DROID *psDroid, bool bButton, const glm::mat4 &viewMatrix)
{
	iIMDShape *psMoveAnim, *psStillAnim;
	SDWORD				iConnector;
	PROPULSION_STATS	*psPropStats;
	SDWORD				pieFlag, iPieData;
	PIELIGHT			brightness;
	UDWORD				colour;
	UBYTE	i;
	bool				didDrawSomething = false;

	glm::mat4 modelMatrix(1.f);

	if (graphicsTime - psDroid->timeLastHit < GAME_TICKS_PER_SEC / 4 && psDroid->lastHitWeapon == WSC_ELECTRONIC && !gamePaused())
	{
		colour = getPlayerColour(rand() % MAX_PLAYERS);
	}
	else
	{
		colour = getPlayerColour(psDroid->player);
	}

	/* get propulsion stats */
	psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION];
	ASSERT_OR_RETURN(didDrawSomething, psPropStats != nullptr, "invalid propulsion stats pointer");

	//set pieflag for button object or ingame object
	if (bButton)
	{
		pieFlag = pie_BUTTON;
		brightness = WZCOL_WHITE;
	}
	else
	{
		pieFlag = pie_SHADOW;
		brightness = pal_SetBrightness(psDroid->illumination);
		// NOTE: Beware of transporters that are offscreen, on a mission!  We should *not* be checking tiles at this point in time!
		if (!isTransporter(psDroid) && !missionIsOffworld())
		{
			MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y);
			if (psTile->jammerBits & alliancebits[psDroid->player])
			{
				pieFlag |= pie_ECM;
			}
		}
	}

	/* set default components transparent */
	if (psDroid->asBits[COMP_PROPULSION] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		iPieData = 0;
	}

	if (!bButton && psPropStats->propulsionType == PROPULSION_TYPE_PROPELLOR)
	{
		// FIXME: change when adding submarines to the game
		modelMatrix *= glm::translate(glm::vec3(0.f, -world_coord(1) / 2.3f, 0.f));
	}

	iIMDShape *psShapeProp = (leftFirst ? getLeftPropulsionIMD(psDroid) : getRightPropulsionIMD(psDroid));
	if (psShapeProp)
	{
		if (pie_Draw3DShape(psShapeProp, 0, colour, brightness, pieFlag, iPieData, viewMatrix * modelMatrix))
		{
			didDrawSomething = true;
		}
	}

	/* set default components transparent */
	if (psDroid->asBits[COMP_BODY] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	/* Get the body graphic now*/
	iIMDShape *psShapeBody = BODY_IMD(psDroid, psDroid->player);
	if (psShapeBody)
	{
		iIMDShape *strImd = psShapeBody;
		if (psDroid->droidType == DROID_PERSON)
		{
			modelMatrix *= glm::scale(glm::vec3(.75f)); // FIXME - hideous....!!!!
		}
		if (strImd->objanimpie[psDroid->animationEvent])
		{
			strImd = psShapeBody->objanimpie[psDroid->animationEvent];
		}
		glm::mat4 viewModelMatrix = viewMatrix * modelMatrix;
		while (strImd)
		{
			if (drawShape(psDroid, strImd, colour, brightness, pieFlag, iPieData, viewModelMatrix))
			{
				didDrawSomething = true;
			}
			strImd = strImd->next;
		}
	}

	/* Render animation effects based on movement or lack thereof, if any */
	psMoveAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppMoveIMDList[psDroid->asBits[COMP_PROPULSION]];
	psStillAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppStillIMDList[psDroid->asBits[COMP_PROPULSION]];
	glm::mat4 viewModelMatrix = viewMatrix * modelMatrix;
	if (!bButton && psMoveAnim && psDroid->sMove.Status != MOVEINACTIVE)
	{
		if (pie_Draw3DShape(psMoveAnim, getModularScaledGraphicsTime(psMoveAnim->animInterval, psMoveAnim->numFrames), colour, brightness, pie_ADDITIVE, 200, viewModelMatrix))
		{
			didDrawSomething = true;
		}
	}
	else if (!bButton && psStillAnim) // standing still
	{
		if (pie_Draw3DShape(psStillAnim, getModularScaledGraphicsTime(psStillAnim->animInterval, psStillAnim->numFrames), colour, brightness, 0, 0, viewModelMatrix))
		{
			didDrawSomething = true;
		}
	}

	//don't change the screen coords of an object if drawing it in a button
	if (!bButton)
	{
		/* set up all the screen coords stuff - need to REMOVE FROM THIS LOOP */
		calcScreenCoords(psDroid, viewModelMatrix);
	}

	/* set default components transparent */
	if (psDroid->asWeaps[0].nStat        == 0 &&
	    psDroid->asBits[COMP_SENSOR]     == 0 &&
	    psDroid->asBits[COMP_ECM]        == 0 &&
	    psDroid->asBits[COMP_BRAIN]      == 0 &&
	    psDroid->asBits[COMP_REPAIRUNIT] == 0 &&
	    psDroid->asBits[COMP_CONSTRUCT]  == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	if (psShapeBody && psShapeBody->nconnectors)
	{
		/* vtol weapons attach to connector 2 (underneath);
		 * all others to connector 1 */
		/* VTOL's now skip the first 5 connectors(0 to 4),
		VTOL's use 5,6,7,8 etc now */
		if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT && psDroid->droidType == DROID_WEAPON)
		{
			iConnector = VTOL_CONNECTOR_START;
		}
		else
		{
			iConnector = 0;
		}

		switch (psDroid->droidType)
		{
		case DROID_DEFAULT:
		case DROID_TRANSPORTER:
		case DROID_SUPERTRANSPORTER:
		case DROID_CYBORG:
		case DROID_CYBORG_SUPER:
		case DROID_WEAPON:
		case DROID_COMMAND:		// command droids have a weapon to store all the graphics
			/*	Get the mounting graphic - we've already moved to the right position
			Allegedly - all droids will have a mount graphic so this shouldn't
			fall on it's arse......*/
			/* Double check that the weapon droid actually has any */
			for (i = 0; i < psDroid->numWeaps; i++)
			{
				if ((psDroid->asWeaps[i].nStat > 0 || psDroid->droidType == DROID_DEFAULT)
				    && psShapeBody->connectors)
				{
					Rotation rot = getInterpolatedWeaponRotation(psDroid, i, graphicsTime);

					glm::mat4 localModelMatrix = modelMatrix;

					//to skip number of VTOL_CONNECTOR_START ground unit connectors
					if (iConnector < VTOL_CONNECTOR_START)
					{
						localModelMatrix *= glm::translate(glm::vec3(psShapeBody->connectors[i].xzy()));
					}
					else
					{
						localModelMatrix *= glm::translate(glm::vec3(psShapeBody->connectors[iConnector + i].xzy()));
					}
					localModelMatrix *= glm::rotate(UNDEG(-rot.direction), glm::vec3(0.f, 1.f, 0.f));

					/* vtol weapons inverted */
					if (iConnector >= VTOL_CONNECTOR_START)
					{
						//this might affect gun rotation
						localModelMatrix *= glm::rotate(UNDEG(65536 / 2), glm::vec3(0.f, 0.f, 1.f));
					}

					/* Get the mount graphic */
					iIMDShape *psShape = WEAPON_MOUNT_IMD(psDroid, i);

					int recoilValue = getRecoil(psDroid->asWeaps[i]);
					localModelMatrix *= glm::translate(glm::vec3(0.f, 0.f, recoilValue / 3.f));

					/* Draw it */
					if (psShape)
					{
						if (pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData, viewMatrix * localModelMatrix))
						{
							didDrawSomething = true;
						}
					}
					localModelMatrix *= glm::translate(glm::vec3(0, 0, recoilValue));

					/* translate for weapon mount point */
					if (psShape && psShape->nconnectors)
					{
						localModelMatrix *= glm::translate(glm::vec3(psShape->connectors->xzy()));
					}

					/* vtol weapons inverted */
					if (iConnector >= VTOL_CONNECTOR_START)
					{
						//pitch the barrel down
						localModelMatrix *= glm::rotate(UNDEG(-rot.pitch), glm::vec3(1.f, 0.f, 0.f));
					}
					else
					{
						//pitch the barrel up
						localModelMatrix *= glm::rotate(UNDEG(rot.pitch), glm::vec3(1.f, 0.f, 0.f));
					}

					/* Get the weapon (gun?) graphic */
					psShape = WEAPON_IMD(psDroid, i);

					// We have a weapon so we draw it and a muzzle flash from weapon connector
					if (psShape)
					{
						glm::mat4 localViewModelMatrix = viewMatrix * localModelMatrix;
						if (pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData, localViewModelMatrix))
						{
							didDrawSomething = true;
						}
						drawMuzzleFlash(psDroid->asWeaps[i], psShape, MUZZLE_FLASH_PIE(psDroid, i), brightness, pieFlag, iPieData, localViewModelMatrix);
					}
				}
			}
			break;

		case DROID_SENSOR:
		case DROID_CONSTRUCT:
		case DROID_CYBORG_CONSTRUCT:
		case DROID_ECM:
		case DROID_REPAIR:
		case DROID_CYBORG_REPAIR:
			{
				Rotation rot = getInterpolatedWeaponRotation(psDroid, 0, graphicsTime);
				iIMDShape *psShape = nullptr;
				iIMDShape *psMountShape = nullptr;

				switch (psDroid->droidType)
				{
				default:
					ASSERT(false, "Bad component type");
					break;
				case DROID_SENSOR:
					psMountShape = SENSOR_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the sensor graphic, assuming it's there */
					psShape = SENSOR_IMD(psDroid, psDroid->player);
					break;
				case DROID_CONSTRUCT:
				case DROID_CYBORG_CONSTRUCT:
					psMountShape = CONSTRUCT_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the construct graphic assuming it's there */
					psShape = CONSTRUCT_IMD(psDroid, psDroid->player);
					break;
				case DROID_ECM:
					psMountShape = ECM_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the ECM graphic assuming it's there.... */
					psShape = ECM_IMD(psDroid, psDroid->player);
					break;
				case DROID_REPAIR:
				case DROID_CYBORG_REPAIR:
					psMountShape = REPAIR_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the Repair graphic assuming it's there.... */
					psShape = REPAIR_IMD(psDroid, psDroid->player);
					break;
				}
				/*	Get the mounting graphic - we've already moved to the right position
				Allegedly - all droids will have a mount graphic so this shouldn't
				fall on it's arse......*/
				//sensor and cyborg and ecm uses connectors[0]

				glm::mat4 localModelMatrix = modelMatrix;
				/* vtol weapons inverted */
				if (iConnector >= VTOL_CONNECTOR_START)
				{
					//this might affect gun rotation
					localModelMatrix *= glm::rotate(UNDEG(65536 / 2), glm::vec3(0.f, 0.f, 1.f));
				}

				localModelMatrix *= glm::translate(glm::vec3(psShapeBody->connectors[0].xzy()));

				localModelMatrix *= glm::rotate(UNDEG(-rot.direction), glm::vec3(0.f, 1.f, 0.f));
				/* Draw it */
				if (psMountShape)
				{
					if (pie_Draw3DShape(psMountShape, 0, colour, brightness, pieFlag, iPieData, viewMatrix * localModelMatrix))
					{
						didDrawSomething = true;
					}
				}

				/* translate for construct mount point if cyborg */
				if (cyborgDroid(psDroid) && psMountShape && psMountShape->nconnectors)
				{
					localModelMatrix *= glm::translate(glm::vec3(psMountShape->connectors[0].xzy()));
				}

				/* Draw it */
				if (psShape)
				{
					if (pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData, viewMatrix * localModelMatrix))
					{
						didDrawSomething = true;
					}

					// In repair droid case only:
					if ((psDroid->droidType == DROID_REPAIR || psDroid->droidType == DROID_CYBORG_REPAIR) &&
					    psShape->nconnectors && psDroid->action == DACTION_DROIDREPAIR)
					{
						Spacetime st = interpolateObjectSpacetime(psDroid, graphicsTime);
						localModelMatrix *= glm::translate(glm::vec3(psShape->connectors[0].xzy()));
						localModelMatrix *= glm::translate(glm::vec3(0.f, -20.f, 0.f));

						psShape = getImdFromIndex(MI_FLAME);

						/* Rotate for droid */
						localModelMatrix *= glm::rotate(UNDEG(st.rot.direction), glm::vec3(0.f, 1.f, 0.f));
						localModelMatrix *= glm::rotate(UNDEG(-st.rot.pitch), glm::vec3(1.f, 0.f, 0.f));
						localModelMatrix *= glm::rotate(UNDEG(-st.rot.roll), glm::vec3(0.f, 0.f, 1.f));
						//rotate Y
						localModelMatrix *= glm::rotate(UNDEG(rot.direction), glm::vec3(0.f, 1.f, 0.f));

						localModelMatrix *= glm::rotate(UNDEG(-player.r.y), glm::vec3(0.f, 1.f, 0.f));
						localModelMatrix *= glm::rotate(UNDEG(-player.r.x), glm::vec3(1.f, 0.f, 0.f));

						if (pie_Draw3DShape(psShape, getModularScaledGraphicsTime(psShape->animInterval, psShape->numFrames), 0, brightness, pie_ADDITIVE, 140, viewMatrix * localModelMatrix))
						{
							didDrawSomething = true;
						}

//						localModelMatrix *= glm::rotate(UNDEG(player.r.x), glm::vec3(1.f, 0.f, 0.f)); // Not used?
//						localModelMatrix *= glm::rotate(UNDEG(player.r.y), glm::vec3(0.f, 1.f, 0.f)); // Not used?
					}
				}
				break;
			}
		case DROID_PERSON:
			// no extra mounts for people
			break;
		default:
			ASSERT(!"invalid droid type", "Whoa! Weirdy type of droid found in drawComponentObject!!!");
			break;
		}
	}

	/* set default components transparent */
	if (psDroid->asBits[COMP_PROPULSION] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	// now render the other propulsion side
	psShapeProp = (leftFirst ? getRightPropulsionIMD(psDroid) : getLeftPropulsionIMD(psDroid));
	if (psShapeProp)
	{
		if (pie_Draw3DShape(psShapeProp, 0, colour, brightness, pieFlag, iPieData, viewModelMatrix)) // Safe to use viewModelMatrix because modelView has not been changed since it was calculated
		{
			didDrawSomething = true;
		}
	}

	return didDrawSomething;
}
Esempio n. 10
0
// Find the best nearest target for a droid.
// If extraRange is higher than zero, then this is the range it accepts for movement to target.
// Returns integer representing target priority, -1 if failed
int aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot, int extraRange)
{
	SDWORD				bestMod = 0, newMod, failure = -1;
	BASE_OBJECT                     *psTarget = NULL, *bestTarget = NULL, *tempTarget;
	bool				electronic = false;
	STRUCTURE			*targetStructure;
	WEAPON_EFFECT			weaponEffect;
	TARGET_ORIGIN tmpOrigin = ORIGIN_UNKNOWN;

	//don't bother looking if empty vtol droid
	if (vtolEmpty(psDroid))
	{
		return failure;
	}

	/* Return if have no weapons */
	// The ai orders a non-combat droid to patrol = crash without it...
	if ((psDroid->asWeaps[0].nStat == 0 || psDroid->numWeaps == 0) && psDroid->droidType != DROID_SENSOR)
	{
		return failure;
	}
	// Check if we have a CB target to begin with
	if (!proj_Direct(asWeaponStats + psDroid->asWeaps[weapon_slot].nStat))
	{
		WEAPON_STATS *psWStats = psDroid->asWeaps[weapon_slot].nStat + asWeaponStats;

		bestTarget = aiSearchSensorTargets((BASE_OBJECT *)psDroid, weapon_slot, psWStats, &tmpOrigin);
		bestMod = targetAttackWeight(bestTarget, (BASE_OBJECT *)psDroid, weapon_slot);
	}

	weaponEffect = (asWeaponStats + psDroid->asWeaps[weapon_slot].nStat)->weaponEffect;

	electronic = electronicDroid(psDroid);

	// Range was previously 9*TILE_UNITS. Increasing this doesn't seem to help much, though. Not sure why.
	int droidRange = std::min(aiDroidRange(psDroid, weapon_slot) + extraRange, objSensorRange(psDroid) + 6 * TILE_UNITS);

	static GridList gridList;  // static to avoid allocations.
	gridList = gridStartIterate(psDroid->pos.x, psDroid->pos.y, droidRange);
	for (GridIterator gi = gridList.begin(); gi != gridList.end(); ++gi)
	{
		BASE_OBJECT *friendlyObj = NULL;
		BASE_OBJECT *targetInQuestion = *gi;

		/* This is a friendly unit, check if we can reuse its target */
		if (aiCheckAlliances(targetInQuestion->player, psDroid->player))
		{
			friendlyObj = targetInQuestion;
			targetInQuestion = NULL;

			/* Can we see what it is doing? */
			if (friendlyObj->visible[psDroid->player] == UBYTE_MAX)
			{
				if (friendlyObj->type == OBJ_DROID)
				{
					DROID	*friendlyDroid = (DROID *)friendlyObj;

					/* See if friendly droid has a target */
					tempTarget = friendlyDroid->psActionTarget[0];
					if (tempTarget && !tempTarget->died)
					{
						//make sure a weapon droid is targeting it
						if (friendlyDroid->numWeaps > 0)
						{
							// make sure this target wasn't assigned explicitly to this droid
							if (friendlyDroid->order.type != DORDER_ATTACK)
							{
								targetInQuestion = tempTarget;  //consider this target
							}
						}
					}
				}
				else if (friendlyObj->type == OBJ_STRUCTURE)
				{
					tempTarget = ((STRUCTURE *)friendlyObj)->psTarget[0];
					if (tempTarget && !tempTarget->died)
					{
						targetInQuestion = tempTarget;
					}
				}
			}
		}

		if (targetInQuestion != NULL
		    && targetInQuestion != psDroid  // in case friendly unit had me as target
		    && (targetInQuestion->type == OBJ_DROID || targetInQuestion->type == OBJ_STRUCTURE || targetInQuestion->type == OBJ_FEATURE)
		    && targetInQuestion->visible[psDroid->player] == UBYTE_MAX
		    && !aiCheckAlliances(targetInQuestion->player, psDroid->player)
		    && validTarget(psDroid, targetInQuestion, weapon_slot)
		    && objPosDiffSq(psDroid, targetInQuestion) < droidRange * droidRange)
		{
			if (targetInQuestion->type == OBJ_DROID)
			{
				// in multiPlayer - don't attack Transporters with EW
				if (bMultiPlayer)
				{
					// if not electronic then valid target
					if (!electronic
					    || (electronic
					        && !isTransporter((DROID *)targetInQuestion)))
					{
						//only a valid target if NOT a transporter
						psTarget = targetInQuestion;
					}
				}
				else
				{
					psTarget = targetInQuestion;
				}
			}
			else if (targetInQuestion->type == OBJ_STRUCTURE)
			{
				STRUCTURE *psStruct = (STRUCTURE *)targetInQuestion;

				if (electronic)
				{
					/* don't want to target structures with resistance of zero if using electronic warfare */
					if (validStructResistance((STRUCTURE *)targetInQuestion))
					{
						psTarget = targetInQuestion;
					}
				}
				else if (psStruct->asWeaps[0].nStat > 0)
				{
					// structure with weapons - go for this
					psTarget = targetInQuestion;
				}
				else if ((psStruct->pStructureType->type != REF_WALL && psStruct->pStructureType->type != REF_WALLCORNER)
				         || driveModeActive() || (bMultiPlayer && !isHumanPlayer(psDroid->player)))
				{
					psTarget = targetInQuestion;
				}
			}
			else if (targetInQuestion->type == OBJ_FEATURE
			         && psDroid->lastFrustratedTime > 0
			         && gameTime - psDroid->lastFrustratedTime < FRUSTRATED_TIME
			         && ((FEATURE *)targetInQuestion)->psStats->damageable
			         && psDroid->player != scavengerPlayer())  // hack to avoid scavs blowing up their nice feature walls
			{
				psTarget = targetInQuestion;
				objTrace(psDroid->id, "considering shooting at %s in frustration", objInfo(targetInQuestion));
			}

			/* Check if our weapon is most effective against this object */
			if (psTarget != NULL && psTarget == targetInQuestion)		//was assigned?
			{
				newMod = targetAttackWeight(psTarget, (BASE_OBJECT *)psDroid, weapon_slot);

				/* Remember this one if it's our best target so far */
				if (newMod >= 0 && (newMod > bestMod || bestTarget == NULL))
				{
					bestMod = newMod;
					tmpOrigin = ORIGIN_ALLY;
					bestTarget = psTarget;
				}
			}
		}
	}

	if (bestTarget)
	{
		ASSERT(!bestTarget->died, "AI gave us a target that is already dead.");
		targetStructure = visGetBlockingWall((BASE_OBJECT *)psDroid, bestTarget);

		/* See if target is blocked by a wall; only affects direct weapons */
		if (proj_Direct(asWeaponStats + psDroid->asWeaps[weapon_slot].nStat)
		    && targetStructure)
		{
			//are we any good against walls?
			if (asStructStrengthModifier[weaponEffect][targetStructure->pStructureType->strength] >= 100)		//can attack atleast with default strength
			{
				bestTarget = (BASE_OBJECT *)targetStructure;			//attack wall
			}
		}

		*ppsObj = bestTarget;
		return bestMod;
	}

	return failure;
}
Esempio n. 11
0
// Call once per frame.
//
void driveUpdate(void)
{
	DROID *psDroid;
	PROPULSION_STATS *psPropStats;

	AllInRange = true;

	if (!DirectControl)
	{
		return;
	}

	if (psDrivenDroid != NULL)
	{
		if (bMultiMessages && (driveBumpTime < gameTime))	// send latest info about driven droid.
		{
			sendDroidInfo(psDrivenDroid, DroidOrder(DORDER_MOVE, psDrivenDroid->pos.xy), false);
		}

		// Check the driven droid is still selected
		if (psDrivenDroid->selected == false)
		{
			// if it's not then reset the driving system.
			driveSelectionChanged();
			return;
		}

		// Update the driven droid.
		if (driveControl(psDrivenDroid))
		{
			// If control did something then force the droid's move status.
			if (psDrivenDroid->sMove.Status != MOVEDRIVE)
			{
				psDrivenDroid->sMove.Status = MOVEDRIVE;
				ASSERT(!isTransporter(psDrivenDroid), "Tried to control a transporter");
				driveDir = UNDEG(psDrivenDroid->rot.direction);
			}
			DoFollowRangeCheck = true;
		}

		// Is the driven droid under user control?
		if (psDrivenDroid->sMove.Status == MOVEDRIVE)
		{
			// Is it a command droid
			if ((psDrivenDroid->droidType == DROID_COMMAND) &&
			    (psDrivenDroid->psGroup != NULL))
			{
				driveMoveCommandFollowers(psDrivenDroid);
			}

			for (psDroid = apsDroidLists[selectedPlayer]; psDroid; psDroid = psDroid->psNext)
			{
				psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION];

				if ((psDroid->selected) &&
				    (psDroid != psDrivenDroid) &&
				    !isTransporter(psDroid) &&
				    ((psPropStats->propulsionType != PROPULSION_TYPE_LIFT) || cyborgDroid(psDroid)))
				{
					// Send new orders to it's followers.
					driveMoveFollower(psDroid);
				}
			}
		}

		if (AllInRange)
		{
			DoFollowRangeCheck = false;
		}
		if (driveBumpTime < gameTime)
		{
			// Send next order in 1 second.
			driveBumpTime = gameTime + GAME_TICKS_PER_SEC;
		}
	}
	else
	{
		if (StartDriverMode(NULL) == false)
		{
			// nothing
		}
	}
}
Esempio n. 12
0
// multiple turrets display removed the pointless mountRotation
void displayComponentObject(DROID *psDroid)
{
	Vector3i position, rotation;
	Spacetime st = interpolateObjectSpacetime(psDroid, graphicsTime);

	leftFirst = angleDelta(player.r.y - st.rot.direction) <= 0;

	/* Push the matrix */
	pie_MatBegin(true);

	/* Get the real position */
	position.x = st.pos.x - player.p.x;
	position.z = -(st.pos.y - player.p.z);
	position.y = st.pos.z;

	if (isTransporter(psDroid))
	{
		position.y += bobTransporterHeight();
	}

	/* Get all the pitch,roll,yaw info */
	rotation.y = -st.rot.direction;
	rotation.x = st.rot.pitch;
	rotation.z = st.rot.roll;

	/* Translate origin */
	pie_TRANSLATE(position.x, position.y, position.z);

	/* Rotate for droid */
	pie_MatRotY(rotation.y);
	pie_MatRotX(rotation.x);
	pie_MatRotZ(rotation.z);

	if (graphicsTime - psDroid->timeLastHit < GAME_TICKS_PER_SEC && psDroid->lastHitWeapon == WSC_ELECTRONIC)
	{
		objectShimmy((BASE_OBJECT *) psDroid);
	}

	if (psDroid->lastHitWeapon == WSC_EMP && graphicsTime - psDroid->timeLastHit < EMP_DISABLE_TIME)
	{
		Vector3i position;

		//add an effect on the droid
		position.x = st.pos.x + DROID_EMP_SPREAD;
		position.y = st.pos.z + rand() % 8;
		position.z = st.pos.y + DROID_EMP_SPREAD;
		effectGiveAuxVar(90 + rand() % 20);
		addEffect(&position, EFFECT_EXPLOSION, EXPLOSION_TYPE_PLASMA, false, NULL, 0);
	}

	if (psDroid->visible[selectedPlayer] == UBYTE_MAX)
	{
		//ingame not button object
		//should render 3 mounted weapons now
		displayCompObj(psDroid, false);
	}
	else
	{
		int frame = graphicsTime / BLIP_ANIM_DURATION + psDroid->id % 8192; // de-sync the blip effect, but don't overflow the int
		pie_Draw3DShape(getImdFromIndex(MI_BLIP), frame, 0, WZCOL_WHITE, pie_ADDITIVE, psDroid->visible[selectedPlayer] / 2);
	}
	pie_MatEnd();
}
Esempio n. 13
0
/* Add the Droids back at home form */
bool intAddDroidsAvailForm()
{
	// Is the form already up?
	bool Animate = true;
	if (widgGetFromID(psWScreen, IDTRANS_DROIDS) != nullptr)
	{
		intRemoveTransDroidsAvailNoAnim();
		Animate = false;
	}

	if (intIsRefreshing())
	{
		Animate = false;
	}

	WIDGET *parent = psWScreen->psForm;

	/* Add the droids available form */
	IntFormAnimated *transDroids = new IntFormAnimated(parent, Animate);  // Do not animate the opening, if the window was already open.
	transDroids->id = IDTRANS_DROIDS;
	transDroids->setGeometry(TRANSDROID_X, TRANSDROID_Y, TRANSDROID_WIDTH, TRANSDROID_HEIGHT);

	/* Add the close button */
	W_BUTINIT sButInit;
	sButInit.formID = IDTRANS_DROIDS;
	sButInit.id = IDTRANS_DROIDCLOSE;
	sButInit.x = TRANSDROID_WIDTH - CLOSE_WIDTH;
	sButInit.y = 0;
	sButInit.width = CLOSE_WIDTH;
	sButInit.height = CLOSE_HEIGHT;
	sButInit.pTip = _("Close");
	sButInit.pDisplay = intDisplayImageHilight;
	sButInit.UserData = PACKDWORD_TRI(0, IMAGE_CLOSEHILIGHT , IMAGE_CLOSE);
	if (!widgAddButton(psWScreen, &sButInit))
	{
		return false;
	}

	//now add the tabbed droids available form
	IntListTabWidget *droidList = new IntListTabWidget(transDroids);
	droidList->id = IDTRANS_DROIDTAB;
	droidList->setChildSize(OBJ_BUTWIDTH, OBJ_BUTHEIGHT);
	droidList->setChildSpacing(OBJ_GAP, OBJ_GAP);
	int droidListWidth = OBJ_BUTWIDTH * 2 + OBJ_GAP;
	droidList->setGeometry((TRANSDROID_WIDTH - droidListWidth) / 2, AVAIL_STARTY + 15, droidListWidth, TRANSDROID_HEIGHT - (AVAIL_STARTY + 15));

	/* Add the droids available buttons */
	int nextButtonId = IDTRANS_DROIDSTART;

	/* Add the state of repair bar for each droid*/
	W_BARINIT sBarInit;
	sBarInit.id = IDTRANS_REPAIRBARSTART;
	sBarInit.x = STAT_TIMEBARX;
	sBarInit.y = STAT_TIMEBARY;
	sBarInit.width = STAT_PROGBARWIDTH;
	sBarInit.height = STAT_PROGBARHEIGHT;
	sBarInit.size = 50;
	sBarInit.sCol = WZCOL_ACTION_PROGRESS_BAR_MAJOR;
	sBarInit.sMinorCol = WZCOL_ACTION_PROGRESS_BAR_MINOR;

	//add droids built before the mission
	for (DROID *psDroid = mission.apsDroidLists[selectedPlayer]; psDroid != nullptr; psDroid = psDroid->psNext)
	{
		//stop adding the buttons once IDTRANS_DROIDEND has been reached
		if (nextButtonId == IDTRANS_DROIDEND)
		{
			break;
		}
		//don't add Transporter Droids!
		if (!isTransporter(psDroid))
		{
			/* Set the tip and add the button */
			IntTransportButton *button = new IntTransportButton(droidList);
			button->id = nextButtonId;
			button->setTip(droidGetName(psDroid));
			button->setObject(psDroid);
			droidList->addWidgetToLayout(button);

			//add bar to indicate stare of repair
			sBarInit.size = (UWORD) PERCENT(psDroid->body, psDroid->originalBody);
			if (sBarInit.size > 100)
			{
				sBarInit.size = 100;
			}

			sBarInit.formID = nextButtonId;
			//sBarInit.iRange = TBAR_MAX_REPAIR;
			if (!widgAddBarGraph(psWScreen, &sBarInit))
			{
				return false;
			}

			/* Update the init struct for the next button */
			++nextButtonId;
			ASSERT(nextButtonId < IDTRANS_DROIDEND, "Too many Droids Built buttons");

			//and bar
			sBarInit.id += 1;
		}
	}

	//reset which tab we were on
	droidList->setCurrentPage(objMajor);

	return true;
}
Esempio n. 14
0
static bool selTransporter(DROID *droid)
{
	return isTransporter(droid);
}
Esempio n. 15
0
// multiple turrets display removed the pointless mountRotation
void displayComponentObject(DROID *psDroid, const glm::mat4 &viewMatrix)
{
	Vector3i position, rotation;
	Spacetime st = interpolateObjectSpacetime(psDroid, graphicsTime);

	leftFirst = angleDelta(player.r.y - st.rot.direction) <= 0;

	/* Get the real position */
	position.x = st.pos.x - player.p.x;
	position.z = -(st.pos.y - player.p.z);
	position.y = st.pos.z;

	if (isTransporter(psDroid))
	{
		position.y += bobTransporterHeight();
	}

	/* Get all the pitch,roll,yaw info */
	rotation.y = -st.rot.direction;
	rotation.x = st.rot.pitch;
	rotation.z = st.rot.roll;

	/* Translate origin */
	/* Rotate for droid */
	glm::mat4 modelMatrix = glm::translate(glm::vec3(position)) *
		glm::rotate(UNDEG(rotation.y), glm::vec3(0.f, 1.f, 0.f)) *
		glm::rotate(UNDEG(rotation.x), glm::vec3(1.f, 0.f, 0.f)) *
		glm::rotate(UNDEG(rotation.z), glm::vec3(0.f, 0.f, 1.f));

	if (graphicsTime - psDroid->timeLastHit < GAME_TICKS_PER_SEC && psDroid->lastHitWeapon == WSC_ELECTRONIC)
	{
		modelMatrix *= objectShimmy((BASE_OBJECT *) psDroid);
	}

	// now check if the projected circle is within the screen boundaries
	if(!clipDroidOnScreen(psDroid, viewMatrix * modelMatrix))
	{
		return;
	}

	if (psDroid->lastHitWeapon == WSC_EMP && graphicsTime - psDroid->timeLastHit < EMP_DISABLE_TIME)
	{
		Vector3i position;

		//add an effect on the droid
		position.x = st.pos.x + DROID_EMP_SPREAD;
		position.y = st.pos.z + rand() % 8;
		position.z = st.pos.y + DROID_EMP_SPREAD;
		effectGiveAuxVar(90 + rand() % 20);
		addEffect(&position, EFFECT_EXPLOSION, EXPLOSION_TYPE_PLASMA, false, nullptr, 0);
	}

	if (psDroid->visible[selectedPlayer] == UBYTE_MAX)
	{
		//ingame not button object
		//should render 3 mounted weapons now
		if (displayCompObj(psDroid, false, viewMatrix * modelMatrix))
		{
			// did draw something to the screen - update the framenumber
			psDroid->sDisplay.frameNumber = frameGetFrameNumber();
		}
	}
	else
	{
		int frame = graphicsTime / BLIP_ANIM_DURATION + psDroid->id % 8192; // de-sync the blip effect, but don't overflow the int
		if (pie_Draw3DShape(getImdFromIndex(MI_BLIP), frame, 0, WZCOL_WHITE, pie_ADDITIVE, psDroid->visible[selectedPlayer] / 2, viewMatrix * modelMatrix))
		{
			psDroid->sDisplay.frameNumber = frameGetFrameNumber();
		}
	}
}
Esempio n. 16
0
// this is able to handle multiple weapon graphics now
// removed mountRotation,they get such stuff from psObj directly now
static void displayCompObj(DROID *psDroid, bool bButton)
{
	iIMDShape               *psShape, *psMoveAnim, *psStillAnim, *psShapeTemp = NULL, *psMountShape;
	SDWORD				iConnector;
	PROPULSION_STATS	*psPropStats;
	SDWORD				pieFlag, iPieData;
	PIELIGHT			brightness;
	UDWORD				colour;
	UBYTE	i;

	if (graphicsTime - psDroid->timeLastHit < GAME_TICKS_PER_SEC / 4 && psDroid->lastHitWeapon == WSC_ELECTRONIC && !gamePaused())
	{
		colour = getPlayerColour(rand() % MAX_PLAYERS);
	}
	else
	{
		colour = getPlayerColour(psDroid->player);
	}

	/* get propulsion stats */
	psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION];
	ASSERT_OR_RETURN(, psPropStats != NULL, "invalid propulsion stats pointer");

	//set pieflag for button object or ingame object
	if (bButton)
	{
		pieFlag = pie_BUTTON;
		brightness = WZCOL_WHITE;
	}
	else
	{
		pieFlag = pie_SHADOW;
		brightness = pal_SetBrightness(psDroid->illumination);
		// NOTE: Beware of transporters that are offscreen, on a mission!  We should *not* be checking tiles at this point in time!
		if (!isTransporter(psDroid) && !missionIsOffworld())
		{
			MAPTILE *psTile = worldTile(psDroid->pos.x, psDroid->pos.y);
			if (psTile->jammerBits & alliancebits[psDroid->player])
			{
				pieFlag |= pie_ECM;
			}
		}
	}

	/* set default components transparent */
	if (psDroid->asBits[COMP_PROPULSION] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		iPieData = 0;
	}

	if (!bButton && psPropStats->propulsionType == PROPULSION_TYPE_PROPELLOR)
	{
		// FIXME: change when adding submarines to the game
		pie_TRANSLATE(0, -world_coord(1) / 2.3f, 0);
	}

	//uses psShapeTemp too separate it from turret's psShape
	psShapeTemp = (leftFirst ? getLeftPropulsionIMD(psDroid) : getRightPropulsionIMD(psDroid));
	if (psShapeTemp != NULL)
	{
		pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData);
	}

	/* set default components transparent */
	if (psDroid->asBits[COMP_BODY] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	/* Get the body graphic now*/
	//uses psShapeTemp too separate it from turret's psShape
	psShapeTemp = BODY_IMD(psDroid, psDroid->player);
	if (psShapeTemp != NULL)
	{
		// FIXME
		if (psDroid->droidType == DROID_PERSON)
		{
			/* draw body if not animating */
			if (psDroid->psCurAnim == NULL  || psDroid->psCurAnim->bVisible == false)
			{
				// FIXME - hideous....!!!!
				pie_MatScale(.75f);
				pie_Draw3DShape(psShapeTemp, 0, psDroid->player - 6, brightness, pieFlag, iPieData);
			}
		}
		else if (cyborgDroid(psDroid))
		{
			/* draw body if cyborg not animating */
			if (psDroid->psCurAnim == NULL || psDroid->psCurAnim->bVisible == false)
			{
				pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData);
			}
		}
		else
		{
			pie_Draw3DShape(psShapeTemp, 0, colour, brightness, pieFlag, iPieData);
		}
	}

	/* Render animation effects based on movement or lack thereof, if any */
	psMoveAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppMoveIMDList[psDroid->asBits[COMP_PROPULSION]];
	psStillAnim = asBodyStats[psDroid->asBits[COMP_BODY]].ppStillIMDList[psDroid->asBits[COMP_PROPULSION]];
	if (!bButton && psMoveAnim && psDroid->sMove.Status != MOVEINACTIVE)
	{
		pie_Draw3DShape(psMoveAnim, getModularScaledGraphicsTime(psMoveAnim->animInterval, psMoveAnim->numFrames), colour, brightness, pie_ADDITIVE, 200);
	}
	else if (!bButton && psStillAnim) // standing still
	{
		pie_Draw3DShape(psStillAnim, getModularScaledGraphicsTime(psStillAnim->animInterval, psStillAnim->numFrames), colour, brightness, 0, 0);
	}

	//don't change the screen coords of an object if drawing it in a button
	if (!bButton)
	{
		/* set up all the screen coords stuff - need to REMOVE FROM THIS LOOP */
		calcScreenCoords(psDroid);
	}

	/* set default components transparent */
	if (psDroid->asWeaps[0].nStat        == 0 &&
	    psDroid->asBits[COMP_SENSOR]     == 0 &&
	    psDroid->asBits[COMP_ECM]        == 0 &&
	    psDroid->asBits[COMP_BRAIN]      == 0 &&
	    psDroid->asBits[COMP_REPAIRUNIT] == 0 &&
	    psDroid->asBits[COMP_CONSTRUCT]  == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	psShapeTemp = BODY_IMD(psDroid, psDroid->player);
	if (psShapeTemp->nconnectors)
	{
		/* vtol weapons attach to connector 2 (underneath);
		 * all others to connector 1 */
		/* VTOL's now skip the first 5 connectors(0 to 4),
		VTOL's use 5,6,7,8 etc now */
		if (psPropStats->propulsionType == PROPULSION_TYPE_LIFT && psDroid->droidType == DROID_WEAPON)
		{
			iConnector = VTOL_CONNECTOR_START;
		}
		else
		{
			iConnector = 0;
		}

		switch (psDroid->droidType)
		{
		case DROID_DEFAULT:
		case DROID_TRANSPORTER:
		case DROID_SUPERTRANSPORTER:
		case DROID_CYBORG:
		case DROID_CYBORG_SUPER:
		case DROID_WEAPON:
		case DROID_COMMAND:		// command droids have a weapon to store all the graphics
			/*	Get the mounting graphic - we've already moved to the right position
			Allegedly - all droids will have a mount graphic so this shouldn't
			fall on it's arse......*/
			/* Double check that the weapon droid actually has any */
			for (i = 0; i < psDroid->numWeaps; i++)
			{
				if ((psDroid->asWeaps[i].nStat > 0 || psDroid->droidType == DROID_DEFAULT)
				    && psShapeTemp->connectors)
				{
					Rotation rot = getInterpolatedWeaponRotation(psDroid, i, graphicsTime);

					pie_MatBegin(!bButton);

					//to skip number of VTOL_CONNECTOR_START ground unit connectors
					if (iConnector < VTOL_CONNECTOR_START)
					{
						pie_TRANSLATE(psShapeTemp->connectors[i].x,
						              psShapeTemp->connectors[i].z,
						              psShapeTemp->connectors[i].y);
					}
					else
					{
						pie_TRANSLATE(psShapeTemp->connectors[iConnector + i].x,
						              psShapeTemp->connectors[iConnector + i].z,
						              psShapeTemp->connectors[iConnector + i].y);
					}

					pie_MatRotY(-rot.direction);

					/* vtol weapons inverted */
					if (iConnector >= VTOL_CONNECTOR_START)
					{
						pie_MatRotZ(65536 / 2); //this might affect gun rotation
					}

					/* Get the mount graphic */
					psShape = WEAPON_MOUNT_IMD(psDroid, i);

					int recoilValue = getRecoil(psDroid->asWeaps[i]);
					pie_TRANSLATE(0, 0, recoilValue / 3);

					/* Draw it */
					if (psShape)
					{
						pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData);
					}

					pie_TRANSLATE(0, 0, recoilValue);

					/* translate for weapon mount point */
					if (psShape && psShape->nconnectors)
					{
						pie_TRANSLATE(psShape->connectors->x, psShape->connectors->z, psShape->connectors->y);
					}

					/* vtol weapons inverted */
					if (iConnector >= VTOL_CONNECTOR_START)
					{
						//pitch the barrel down
						pie_MatRotX(-rot.pitch);
					}
					else
					{
						//pitch the barrel up
						pie_MatRotX(rot.pitch);
					}

					/* Get the weapon (gun?) graphic */
					psShape = WEAPON_IMD(psDroid, i);

					// We have a weapon so we draw it and a muzzle flash from weapon connector
					if (psShape)
					{
						pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData);
						drawMuzzleFlash(psDroid->asWeaps[i], psShape, MUZZLE_FLASH_PIE(psDroid, i), brightness, pieFlag, iPieData);
					}
					/* Pop Matrix */
					pie_MatEnd();
				}
			}
			break;

		case DROID_SENSOR:
		case DROID_CONSTRUCT:
		case DROID_CYBORG_CONSTRUCT:
		case DROID_ECM:
		case DROID_REPAIR:
		case DROID_CYBORG_REPAIR:
			{
				Rotation rot = getInterpolatedWeaponRotation(psDroid, 0, graphicsTime);

				switch (psDroid->droidType)
				{
				default: ASSERT(false, "...");
				case DROID_SENSOR:
					psMountShape = SENSOR_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the sensor graphic, assuming it's there */
					psShape = SENSOR_IMD(psDroid, psDroid->player);
					break;
				case DROID_CONSTRUCT:
				case DROID_CYBORG_CONSTRUCT:
					psMountShape = CONSTRUCT_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the construct graphic assuming it's there */
					psShape = CONSTRUCT_IMD(psDroid, psDroid->player);
					break;
				case DROID_ECM:
					psMountShape = ECM_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the ECM graphic assuming it's there.... */
					psShape = ECM_IMD(psDroid, psDroid->player);
					break;
				case DROID_REPAIR:
				case DROID_CYBORG_REPAIR:
					psMountShape = REPAIR_MOUNT_IMD(psDroid, psDroid->player);
					/* Get the Repair graphic assuming it's there.... */
					psShape = REPAIR_IMD(psDroid, psDroid->player);
					break;
				}
				/*	Get the mounting graphic - we've already moved to the right position
				Allegedly - all droids will have a mount graphic so this shouldn't
				fall on it's arse......*/
				//sensor and cyborg and ecm uses connectors[0]
				pie_MatBegin(!bButton);
				/* vtol weapons inverted */
				if (iConnector >= VTOL_CONNECTOR_START)
				{
					pie_MatRotZ(65536 / 2); //this might affect gun rotation
				}

				pie_TRANSLATE(psShapeTemp->connectors[0].x,
				              psShapeTemp->connectors[0].z,
				              psShapeTemp->connectors[0].y);

				pie_MatRotY(-rot.direction);
				/* Draw it */
				if (psMountShape)
				{
					pie_Draw3DShape(psMountShape, 0, colour, brightness, pieFlag, iPieData);
				}

				/* translate for construct mount point if cyborg */
				if (cyborgDroid(psDroid) && psMountShape && psMountShape->nconnectors)
				{
					pie_TRANSLATE(psMountShape->connectors[0].x,
					              psMountShape->connectors[0].z,
					              psMountShape->connectors[0].y);
				}

				/* Draw it */
				if (psShape)
				{
					pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData);

					// In repair droid case only:
					if ((psDroid->droidType == DROID_REPAIR || psDroid->droidType == DROID_CYBORG_REPAIR) &&
					    psShape->nconnectors && psDroid->action == DACTION_DROIDREPAIR)
					{
						Spacetime st = interpolateObjectSpacetime(psDroid, graphicsTime);

						pie_TRANSLATE(psShape->connectors[0].x,
						              psShape->connectors[0].z,
						              psShape->connectors[0].y);
						pie_TRANSLATE(0, -20, 0);

						psShape = getImdFromIndex(MI_FLAME);

						/* Rotate for droid */
						pie_MatRotY(st.rot.direction);
						pie_MatRotX(-st.rot.pitch);
						pie_MatRotZ(-st.rot.roll);
						//rotate Y
						pie_MatRotY(rot.direction);

						pie_MatRotY(-player.r.y);
						pie_MatRotX(-player.r.x);

						pie_Draw3DShape(psShape, getModularScaledGraphicsTime(psShape->animInterval, psShape->numFrames), 0, brightness, pie_ADDITIVE, 140);

						pie_MatRotX(player.r.x);
						pie_MatRotY(player.r.y);
					}
				}
				/* Pop Matrix */
				pie_MatEnd();
				break;
			}
		case DROID_PERSON:
			// no extra mounts for people
			break;
		default:
			ASSERT(!"invalid droid type", "Whoa! Weirdy type of droid found in drawComponentObject!!!");
			break;
		}
	}
	/*	We've also got a handle on the psShape here for the weapon which has a connector to point to
		muzzle flash attachment points - just grab it from psShape->connectors->[x|y|z] */

	/* set default components transparent */
	if (psDroid->asBits[COMP_PROPULSION] == 0)
	{
		pieFlag  |= pie_TRANSLUCENT;
		iPieData  = DEFAULT_COMPONENT_TRANSLUCENCY;
	}
	else
	{
		pieFlag  &= ~pie_TRANSLUCENT;
		iPieData = 0;
	}

	psShape = (leftFirst ? getRightPropulsionIMD(psDroid) : getLeftPropulsionIMD(psDroid));
	if (psShape != NULL)
	{
		pie_Draw3DShape(psShape, 0, colour, brightness, pieFlag, iPieData);
	}
}
Esempio n. 17
0
/* Add the Transporter Button form */
bool intAddTransButtonForm()
{
	WIDGET *transForm = widgGetFromID(psWScreen, IDTRANS_FORM);

	/* Add the button form */
	IntListTabWidget *transList = new IntListTabWidget(transForm);
	transList->setChildSize(OBJ_BUTWIDTH, OBJ_BUTHEIGHT * 2);
	transList->setChildSpacing(OBJ_GAP, OBJ_GAP);
	int objListWidth = OBJ_BUTWIDTH * 5 + OBJ_GAP * 4;
	transList->setGeometry((OBJ_BACKWIDTH - objListWidth) / 2, TRANS_TABY, objListWidth, transForm->height() - TRANS_TABY);

	/* Add the transporter and status buttons */
	int nextObjButtonId = IDTRANS_START;
	int nextStatButtonId = IDTRANS_STATSTART;

	//add each button
	for (DROID *psDroid = transInterfaceDroidList(); psDroid; psDroid = psDroid->psNext)
	{
		//only interested in Transporter droids
		if ((isTransporter(psDroid) && (psDroid->action == DACTION_TRANSPORTOUT  ||
		                                psDroid->action == DACTION_TRANSPORTIN)) || !isTransporter(psDroid))
		{
			continue;
		}

		WIDGET *buttonHolder = new WIDGET(transList);
		transList->addWidgetToLayout(buttonHolder);

		IntStatusButton *statButton = new IntStatusButton(buttonHolder);
		statButton->id = nextStatButtonId;
		statButton->setGeometry(0, 0, OBJ_BUTWIDTH, OBJ_BUTHEIGHT);

		IntObjectButton *objButton = new IntObjectButton(buttonHolder);
		objButton->id = nextObjButtonId;
		objButton->setGeometry(0, OBJ_STARTY, OBJ_BUTWIDTH, OBJ_BUTHEIGHT);

		/* Set the tip and add the button */
		objButton->setTip(droidGetName(psDroid));
		objButton->setObject(psDroid);

		//set the first Transporter to be the current one if not already set
		if (psCurrTransporter == nullptr)
		{
			psCurrTransporter = psDroid;
		}

		/* if the current droid matches psCurrTransporter lock the button */
		if (psDroid == psCurrTransporter)
		{
			objButton->setState(WBUT_LOCK);
			transList->setCurrentPage(transList->pages() - 1);
		}

		//now do status button
		statButton->setObject(nullptr);

		/* Update the init struct for the next buttons */
		++nextObjButtonId;
		ASSERT(nextObjButtonId < IDTRANS_END, "Too many Transporter buttons");

		++nextStatButtonId;
		ASSERT(nextStatButtonId < IDTRANS_STATEND, "Too many Transporter status buttons");
	}
	return true;
}