void CTransportCAI::UnloadUnits_Drop(Command& c, CTransportUnit* transport) {
	//called repeatedly for each unit till units are unloaded
		if(lastCall==gs->frameNum)	//avoid infinite loops
			return;
		lastCall=gs->frameNum;

		if(((CTransportUnit*)owner)->transported.empty() ){
			FinishCommand();
			return;
		}

		float3 pos(c.params[0],c.params[1],c.params[2]);
		float radius=c.params[3];
		bool canUnload = false;

		//at the start of each user command
		if (isFirstIteration )	{
			dropSpots.clear();
			startingDropPos = pos;

			approachVector = startingDropPos-owner->pos;
			approachVector.Normalize();
			canUnload = FindEmptyDropSpots(pos, pos + approachVector*max(16.0f,radius), dropSpots);

		} else if (!dropSpots.empty() ) {
			//make sure we check current spot infront of us each unload
			pos = dropSpots.back(); //take last landing pos as new start spot
			canUnload = dropSpots.size() > 0;
		}

		if( canUnload ){
			if(SpotIsClear(dropSpots.back(),((CTransportUnit*)owner)->transported.front().unit)) {
				float3 pos = dropSpots.back();
				Command c2;
				c2.id=CMD_UNLOAD_UNIT;
				c2.params.push_back(pos.x);
				c2.params.push_back(pos.y);
				c2.params.push_back(pos.z);
				c2.options=c.options | INTERNAL_ORDER;
				commandQue.push_front(c2);

				SlowUpdate();
				isFirstIteration = false;
				return;
			} else {
				dropSpots.pop_back();
			}
		} else {

			startingDropPos = float3(-1,-1,-1);
			isFirstIteration=true;
			dropSpots.clear();
			FinishCommand();
		}
}
Esempio n. 2
0
void CTransportCAI::UnloadUnits_Drop(Command& c, CTransportUnit* transport)
{
	// called repeatedly for each unit till units are unloaded
	if (lastCall == gs->frameNum) {
		// avoid infinite loops
		return;
	}

	lastCall = gs->frameNum;

	const auto& transportees = transport->GetTransportedUnits();

	if (transportees.empty()) {
		FinishCommand();
		return;
	}

	bool canUnload = false;

	// at the start of each user command
	if (isFirstIteration)	{
		dropSpots.clear();

		startingDropPos = c.GetPos(0);
		approachVector = (startingDropPos - owner->pos).Normalize();

		canUnload = FindEmptyDropSpots(startingDropPos, startingDropPos + approachVector * std::max(16.0f, c.params[3]), dropSpots);
	} else if (!dropSpots.empty() ) {
		// make sure we check current spot in front of us each
		// unload, take last landing pos as new start spot
		// pos = dropSpots.back();
		canUnload = !dropSpots.empty();
	}

	if (canUnload) {
		if (SpotIsClear(dropSpots.back(), (transportees.front()).unit)) {
			Command c2(CMD_UNLOAD_UNIT, c.options | INTERNAL_ORDER, dropSpots.back());
			commandQue.push_front(c2);

			SlowUpdate();
			isFirstIteration = false;
			return;
		} else {
			dropSpots.pop_back();
		}
	} else {
		startingDropPos = -OnesVector;
		isFirstIteration = true;
		dropSpots.clear();
		FinishCommand();
	}
}
Esempio n. 3
0
void CTransportCAI::UnloadUnits_Drop(Command& c, CTransportUnit* transport)
{
	// called repeatedly for each unit till units are unloaded
	if (lastCall == gs->frameNum) { // avoid infinite loops
		return;
	}
	lastCall = gs->frameNum;

	if (static_cast<CTransportUnit*>(owner)->GetTransportedUnits().empty()) {
		FinishCommand();
		return;
	}

	float3 pos = c.GetPos(0);
	float radius = c.params[3];
	bool canUnload = false;

	// at the start of each user command
	if (isFirstIteration)	{
		dropSpots.clear();
		startingDropPos = pos;

		approachVector = startingDropPos - owner->pos;
		approachVector.Normalize();
		canUnload = FindEmptyDropSpots(pos, pos + approachVector * std::max(16.0f,radius), dropSpots);
	} else if (!dropSpots.empty() ) {
		// make sure we check current spot infront of us each unload
		pos = dropSpots.back(); // take last landing pos as new start spot
		canUnload = !dropSpots.empty();
	}

	if (canUnload) {
		if (SpotIsClear(dropSpots.back(), static_cast<CTransportUnit*>(owner)->GetTransportedUnits().front().unit)) {
			const float3 pos = dropSpots.back();
			Command c2(CMD_UNLOAD_UNIT, c.options | INTERNAL_ORDER, pos);
			commandQue.push_front(c2);

			SlowUpdate();
			isFirstIteration = false;
			return;
		} else {
			dropSpots.pop_back();
		}
	} else {
		startingDropPos = float3(-1.0f, -1.0f, -1.0f);
		isFirstIteration = true;
		dropSpots.clear();
		FinishCommand();
	}
}
bool CTransportCAI::FindEmptyDropSpots(float3 startpos, float3 endpos, std::list<float3>& dropSpots) {
	//should only be used by air

	CTransportUnit* transport=(CTransportUnit*)owner;
	//dropSpots.clear();
	float gap = 25.5; //TODO - set tag for this?
	float3 dir = endpos - startpos;
	dir.Normalize();

	float3 nextPos = startpos;
	float3 pos;

	list<CTransportUnit::TransportedUnit>::iterator ti = transport->transported.begin();
	dropSpots.push_front(nextPos);

	//first spot
	if (ti!=transport->transported.end()) {
		//float3 p = nextPos; //test to make intended land spots visible
		//inMapDrawer->CreatePoint(p,ti->unit->unitDef->name);
		//p.z +=transport->transportCapacityUsed*5;
		nextPos += dir*(gap + ti->unit->radius);
		ti++;
	}

	//remaining spots
	if (dynamic_cast<CTAAirMoveType*>(owner->moveType)) {
		while (ti != transport->transported.end() && startpos.distance(nextPos) < startpos.distance(endpos)) {
			nextPos += dir*(ti->unit->radius);
			nextPos.y = ground->GetHeight(nextPos.x, nextPos.z);

			//check landing spot is ok for landing on
			if (!SpotIsClear(nextPos,ti->unit))
				continue;

			dropSpots.push_front(nextPos);
			//float3 p = nextPos; //test to make intended land spots visible
			//inMapDrawer->CreatePoint(p,ti->unit->unitDef->name);
			//p.z +=transport->transportCapacityUsed*5;
			nextPos += dir*(gap + ti->unit->radius);
			ti++;
		}
		return true;
	}
	return false;
}
Esempio n. 5
0
bool CTransportCAI::FindEmptyDropSpots(float3 startpos, float3 endpos, std::list<float3>& dropSpots)
{
	//should only be used by air

	CTransportUnit* transport = static_cast<CTransportUnit*>(owner);
	//dropSpots.clear();
	float gap = 25.5; // TODO - set tag for this?
	float3 dir = endpos - startpos;
	dir.Normalize();

	float3 nextPos = startpos;
	float3 pos;

	std::list<CTransportUnit::TransportedUnit>::const_iterator ti = transport->GetTransportedUnits().begin();
	dropSpots.push_front(nextPos);

	// first spot
	if (ti != transport->GetTransportedUnits().end()) {
		nextPos += dir * (gap + ti->unit->radius);
		++ti;
	}

	// remaining spots
	if (dynamic_cast<CHoverAirMoveType*>(owner->moveType)) {
		while (ti != transport->GetTransportedUnits().end() && startpos.SqDistance(nextPos) < startpos.SqDistance(endpos)) {
			nextPos += dir * (ti->unit->radius);
			nextPos.y = ground->GetHeightAboveWater(nextPos.x, nextPos.z);

			// check landing spot is ok for landing on
			if (!SpotIsClear(nextPos,ti->unit))
				continue;

			dropSpots.push_front(nextPos);
			nextPos += dir * (gap + ti->unit->radius);
			++ti;
		}
		return true;
	}
	return false;
}
Esempio n. 6
0
// should only be used by air
bool CTransportCAI::FindEmptyDropSpots(float3 startpos, float3 endpos, std::list<float3>& dropSpots)
{
	const float gap = 25.5f; // TODO - set tag for this?
	const float3 dir = (endpos - startpos).Normalize();

	float3 nextPos = startpos;

	dropSpots.push_front(nextPos);

	if (dynamic_cast<CHoverAirMoveType*>(owner->moveType) == NULL)
		return false;

	const auto& transportees = static_cast<CTransportUnit*>(owner)->GetTransportedUnits();
	auto ti = transportees.begin();

	// first spot
	if (ti != transportees.end()) {
		nextPos += (dir * (gap + ti->unit->radius));
		++ti;
	}

	// remaining spots
	while (ti != transportees.end() && startpos.SqDistance(nextPos) < startpos.SqDistance(endpos)) {
		nextPos += (dir * (ti->unit->radius));
		nextPos.y = CGround::GetHeightAboveWater(nextPos.x, nextPos.z);

		// check landing spot is ok for landing on
		if (!SpotIsClear(nextPos, ti->unit))
			continue;

		dropSpots.push_front(nextPos);
		nextPos += (dir * (gap + ti->unit->radius));
		++ti;
	}

	return true;
}