Exemplo n.º 1
0
// problems: giving reclaim order on moving target causes commander
// to walk (messing up subsequent dgun order if target still moving)
// and does not take commander torso rotation time into account
//
void CDGunController::TrackAttackTarget(unsigned int currentFrame) {
	if (currentFrame - state.targetSelectionFrame == 5) {
		// five sim-frames have passed since selecting target, attack
		const UnitDef* udef = ai->cb->GetUnitDef(state.targetID);

		const float3 curTargetPos = ai->cb->GetUnitPos(state.targetID);						// current target position
		const float3 commanderPos = ai->cb->GetUnitPos(commanderID);						// current commander position

		const float  targetDist   = (commanderPos - curTargetPos).Length();					// distance to target
		const float3 targetDir    = (curTargetPos - state.oldTargetPos).Normalize();		// target direction of movement
		const float  targetSpeed  = (curTargetPos - state.oldTargetPos).Length() / 5;		// target speed per sim-frame during tracking interval

		const float  dgunDelay    = targetDist / commanderWD->projectilespeed;				// sim-frames needed for dgun to reach target position
		const float3 dgunPos      = curTargetPos + targetDir * (targetSpeed * dgunDelay);	// position where target will be in <dgunDelay> frames
		const float  maxRange     = ai->cb->GetUnitMaxRange(commanderID);

		bool haveClearShot = true;
		int orderType = -1;

		AIHCTraceRay rayData = {
			commanderPos,
			targetDir,
			maxRange,
			commanderID,
			-1,
			0
		};

		ai->cb->HandleCommand(AIHCTraceRayId, &rayData);

		if (rayData.hitUID != -1) {
			haveClearShot = (ai->cb->GetUnitAllyTeam(rayData.hitUID) != ai->cb->GetMyAllyTeam());
		}

		if ((commanderPos - dgunPos).Length() < maxRange * 0.9f) {
			// multiply by 0.9 to ensure commander does not have to walk
			if ((ai->cb->GetEnergy()) >= DGUN_MIN_ENERGY_LEVEL) {
				if (udef != NULL && !udef->weapons.empty() && haveClearShot) {
					IssueOrder(dgunPos, orderType = CMD_DGUN, 0);
				} else {
					IssueOrder(state.targetID, orderType = CMD_CAPTURE, 0);
				}
			} else {
				if (ai->cb->GetUnitHealth(state.targetID) < ai->cb->GetUnitMaxHealth(state.targetID) * 0.5f) {
					IssueOrder(state.targetID, orderType = CMD_RECLAIM, 0);
				} else {
					IssueOrder(state.targetID, orderType = CMD_CAPTURE, 0);
				}
			}

			if (orderType == CMD_DGUN   ) { state.dgunOrderFrame    = ai->cb->GetCurrentFrame(); }
			if (orderType == CMD_RECLAIM) { state.reclaimOrderFrame = ai->cb->GetCurrentFrame(); }
			if (orderType == CMD_CAPTURE) { state.captureOrderFrame = ai->cb->GetCurrentFrame(); }
		} else {
			state.Reset(currentFrame, true);
		}
	}

	state.Reset(currentFrame, false);
}
Exemplo n.º 2
0
void PlanetWars::ExecuteOrders()
{
	FleetMap::const_iterator begin = m_aFleets.begin();
	FleetMap::const_iterator end = m_aFleets.end();
	FleetMap::const_iterator it;

	for (it = begin ; it != end ; ++it)
	{
		if (it->second.GetStartTurn() == 0)
		{
			IssueOrder(it->second.GetSourcePlanet(), it->second.GetDestinationPlanet(), it->second.GetShipsCount());
			GetPlanet(it->second.GetSourcePlanet()).RemoveRealShips(it->second.GetShipsCount());
		}
	}
}
Exemplo n.º 3
0
// problems: giving reclaim order on moving target causes commander
// to walk (messing up subsequent dgun order if target still moving)
// and does not take commander torso rotation time into account
//
void CDGunController::TrackAttackTarget(unsigned int currentFrame) {
	if (currentFrame - state.targetSelectionFrame == 5) {
		// five sim-frames have passed since selecting target, attack
		const UnitDef* udef = ai->cb->GetUnitDef(state.targetID);

		const float3 curTargetPos = ai->cb->GetUnitPos(state.targetID);              // current target position
		const float3 commanderPos = ai->cb->GetUnitPos(commanderID);                 // current commander position

		const float3 targetDif    = (commanderPos - curTargetPos);
		const float  targetDist   = targetDif.Length();                              // distance to target
		const float3 targetVel    = (curTargetPos - state.oldTargetPos);

		float3 targetMoveDir   = targetVel;
		float  targetMoveSpeed = 0.0f;

		if (targetVel != ZeroVector) {
			targetMoveSpeed = targetVel.Length() / 5.0f;                             // target speed per sim-frame during tracking interval
			targetMoveDir   = targetVel / (targetMoveSpeed * 5.0f);                  // target direction of movement
		}

		const float  dgunDelay    = targetDist / commanderWD->projectilespeed;       // sim-frames needed for dgun to reach target position
		const float3 leadPos      = targetMoveDir * (targetMoveSpeed * dgunDelay);
		const float3 dgunPos      = curTargetPos + leadPos;                          // position where target will be in <dgunDelay> frames
		const float  maxRange     = ai->cb->GetUnitMaxRange(commanderID);

		bool haveClearShot = true;
		int orderType = -1;

		AIHCTraceRay rayData = {
			commanderPos,
			targetDif / targetDist, // direction
			maxRange,
			commanderID,
			-1,
			0
		};

		ai->cb->HandleCommand(AIHCTraceRayId, &rayData);

		if (rayData.hitUID != -1) {
			// note: still fails when allied structure is between us and enemy
			// can also fail if enemy is in front of allied structure and both
			// are within the d-gun's range
			haveClearShot = (ai->cb->GetUnitAllyTeam(rayData.hitUID) != ai->cb->GetMyAllyTeam());

			// TODO: get DGun weapon properties & check if it can pass through
			// a unit, if yes then allow executing the code below
			if(haveClearShot) {
				// check if there is a unit next to hit unit on DGun path...
				const float3 enemyPos = ai->cb->GetUnitPos(rayData.hitUID);
				const float segmentLeft = maxRange - commanderPos.distance(enemyPos);

				if(segmentLeft > 0.0) {
					AIHCTraceRay rayData2 = {
						enemyPos,
						targetDif / targetDist,
						segmentLeft,
						rayData.hitUID,
						-1,
						0
					};

					ai->cb->HandleCommand(AIHCTraceRayId, &rayData2);

					if(rayData2.hitUID != -1) {
						haveClearShot = (ai->cb->GetUnitAllyTeam(rayData2.hitUID) != ai->cb->GetMyAllyTeam());
					}
				}
			}
		}

		// multiply by 0.9 to ensure commander does not have to walk
		if ((commanderPos - dgunPos).Length() < maxRange * 0.9f) {
			bool canDGun =
				(ai->cb->GetEnergy() >= DGUN_MIN_ENERGY_LEVEL)
				&& haveClearShot
				&& (udef != NULL && !udef->weapons.empty());

			if(canDGun) {
				IssueOrder(dgunPos, orderType = CMD_DGUN, 0);
			} else {
				bool bDanger = ai->tm->ThreatAtThisPoint(commanderPos/*curTargetPos*/) > ai->tm->GetAverageThreat();
				if(bDanger) {
					state.Reset(currentFrame, true);
				} else {
					if (ai->cb->GetUnitHealth(state.targetID) < ai->cb->GetUnitMaxHealth(state.targetID) * 0.5f) {
						IssueOrder(state.targetID, orderType = CMD_RECLAIM, 0);
					} else {
						IssueOrder(state.targetID, orderType = CMD_CAPTURE, 0);
					}
				}
			}

			if (orderType == CMD_DGUN   ) { state.dgunOrderFrame    = ai->cb->GetCurrentFrame(); }
			if (orderType == CMD_RECLAIM) { state.reclaimOrderFrame = ai->cb->GetCurrentFrame(); }
			if (orderType == CMD_CAPTURE) { state.captureOrderFrame = ai->cb->GetCurrentFrame(); }
		} else {
			state.Reset(currentFrame, true);
		}
	}

	state.Reset(currentFrame, false);
}
Exemplo n.º 4
0
// problems: giving reclaim order on moving target causes commander
// to walk (messing up subsequent dgun order if target still moving)
// and does not take commander torso rotation time into account
//
void CDGunController::TrackAttackTarget(unsigned int currentFrame) {
	if (currentFrame - state.targetSelectionFrame == 5) {
		// five sim-frames have passed since selecting target, attack
		const UnitDef* udef = ai->cb->GetUnitDef(state.targetID);

		const float3 curTargetPos = ai->cb->GetUnitPos(state.targetID);              // current target position
		const float3 commanderPos = ai->cb->GetUnitPos(commanderID);                 // current commander position

		const float3 targetDif    = (commanderPos - curTargetPos);
		const float  targetDist   = targetDif.Length();                              // distance to target
		const float3 targetVel    = (curTargetPos - state.oldTargetPos);

		float3 targetMoveDir   = targetVel;
		float  targetMoveSpeed = 0.0f;

		if (targetVel != ZeroVector) {
			targetMoveSpeed = targetVel.Length() / 5.0f;                             // target speed per sim-frame during tracking interval
			targetMoveDir   = targetVel / (targetMoveSpeed * 5.0f);                  // target direction of movement
		}

		const float  dgunDelay    = targetDist / commanderWD->projectilespeed;       // sim-frames needed for dgun to reach target position
		const float3 leadPos      = targetMoveDir * (targetMoveSpeed * dgunDelay);
		const float3 dgunPos      = curTargetPos + leadPos;                          // position where target will be in <dgunDelay> frames
		const float  maxRange     = ai->cb->GetUnitMaxRange(commanderID);

		bool haveClearShot = true;
		int numSegments = 0;


		AIHCTraceRay rayData;
		float  rayLen = maxRange * 1.1f;
		float3 rayPos = commanderPos;
		float3 rayDir = targetDif / targetDist;
			rayDir.y = 0.0f;

		while (haveClearShot && (rayLen >= 1.0f)) {
			rayData.rayPos = rayPos;
			rayData.rayDir = targetDif / targetDist;
			rayData.rayLen = rayLen;
			rayData.srcUID = commanderID;
			rayData.hitUID = -1;
			rayData.flags  = 0;

			// modifies hitUID and rayLen
			ai->ccb->HandleCommand(AIHCTraceRayId, &rayData);

			// note: even if hitUnitID is -1, we can still end up destroying
			// our own units because dgun projectiles keep hugging the ground
			// rather than being absorbed by it on impact (which is assumed by
			// the trace)
			if (rayData.hitUID != -1) {
				if (ai->cb->GetUnitAllyTeam(rayData.hitUID) == ai->cb->GetMyAllyTeam()) {
					// hitUID is an allied unit
					haveClearShot = false;
				} else {
					// hitUID is an enemy unit
					rayPos = ai->ccb->GetUnitPos(rayData.hitUID);
				}
			}

			// make sure we always terminate
			rayLen -= rayData.rayLen;
		}


		// multiply by 0.9 to ensure commander does not have to walk
		if ((commanderPos - dgunPos).Length() < maxRange * 0.9f) {
			bool canDGun =
				(ai->cb->GetEnergy() >= DGUN_MIN_ENERGY_LEVEL)
				&& haveClearShot
				&& (udef != NULL && !udef->weapons.empty());

			if (canDGun) {
				IssueOrder(dgunPos, CMD_DGUN, 0);
			} else {
				bool bDanger = ai->tm->ThreatAtThisPoint(commanderPos/*curTargetPos*/) > ai->tm->GetAverageThreat();

				if (bDanger) {
					state.Reset(currentFrame, true);
				} else {
					if (ai->cb->GetUnitHealth(state.targetID) < ai->cb->GetUnitMaxHealth(state.targetID) * 0.5f) {
						IssueOrder(state.targetID, CMD_RECLAIM, 0);
					} else {
						IssueOrder(state.targetID, CMD_CAPTURE, 0);
					}
				}
			}
		} else {
			state.Reset(currentFrame, true);
		}
	}

	state.Reset(currentFrame, false);
}