コード例 #1
0
void CBuilderCAI::ExecuteReclaim(Command &c)
{
	assert(owner->unitDef->canReclaim);
	CBuilder* fac=(CBuilder*)owner;
	if(c.params.size()==1){
		int id=(int) c.params[0];
		if(id>=MAX_UNITS){		//reclaim feature
			CFeature* feature=featureHandler->features[id-MAX_UNITS];
			if(feature){
				if(!ReclaimObject(feature)){
					StopMove();
					FinishCommand();
				}
			} else {
				StopMove();
				FinishCommand();
			}

		} else {							//reclaim unit
			CUnit* unit=uh->units[id];
			if(unit && unit!=owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(id)){
				if(!ReclaimObject(unit)){
					StopMove();
					FinishCommand();
				}
			} else {
				FinishCommand();
			}
		}
	} else if(c.params.size()==4){//area reclaim
		float3 pos(c.params[0],c.params[1],c.params[2]);
		float radius=c.params[3];
		if(FindReclaimableFeatureAndReclaim(pos,radius,c.options,true)){
			inCommand=false;
			SlowUpdate();
			return;
		}
		if(!(c.options & ALT_KEY)){
			FinishCommand();
		}
	} else {	//wrong number of parameters
		FinishCommand();
	}
	return;
}
コード例 #2
0
ファイル: BuilderCAI.cpp プロジェクト: Finkky/spring
void CBuilderCAI::ExecuteReclaim(Command& c)
{
	CBuilder* builder = (CBuilder*) owner;

	// not all builders are reclaim-capable by default
	if (!owner->unitDef->canReclaim)
		return;

	if (c.params.size() == 1 || c.params.size() == 5) {
		const int signedId = (int) c.params[0];

		if (signedId < 0) {
			LOG_L(L_WARNING, "Trying to reclaim unit or feature with id < 0 (%i), aborting.", signedId);
			return;
		}

		const unsigned int uid = signedId;

		//FIXME add a per-unit solution to better balance the load?
		const bool checkForBetterTarget = (gs->frameNum % (5 * UNIT_SLOWUPDATE_RATE)) < UNIT_SLOWUPDATE_RATE;
		if (checkForBetterTarget && (c.options & INTERNAL_ORDER) && (c.params.size() >= 5)) {
			// regular check if there is a closer reclaim target
			CSolidObject* obj;
			if (uid >= uh->MaxUnits()) {
				obj = featureHandler->GetFeature(uid - uh->MaxUnits());
			} else {
				obj = uh->GetUnit(uid);
			}
			if (obj) {
				const float3 pos(c.params[1], c.params[2], c.params[3]);
				const float radius = c.params[4];
				const float curdist = pos.SqDistance2D(obj->pos);

				const bool recUnits = !!(c.options & META_KEY);
				const bool recEnemyOnly = (c.options & META_KEY) && (c.options & CONTROL_KEY);
				const bool recSpecial = !!(c.options & CONTROL_KEY);

				ReclaimOption recopt = REC_NORESCHECK;
				if (recUnits)     recopt |= REC_UNITS;
				if (recEnemyOnly) recopt |= REC_ENEMYONLY;
				if (recSpecial)   recopt |= REC_SPECIAL;
				
				const int rid = FindReclaimTarget(pos, radius, c.options, recopt, curdist);
				if ((rid > 0) && (rid != uid)) {
					FinishCommand();
					RemoveUnitFromReclaimers(owner);
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}
		}

		if (uid >= uh->MaxUnits()) { // reclaim feature
			CFeature* feature = featureHandler->GetFeature(uid - uh->MaxUnits());

			if (feature != NULL) {
				bool featureBeingResurrected = IsFeatureBeingResurrected(feature->id, owner);
				featureBeingResurrected &= (c.options & INTERNAL_ORDER) && !(c.options & CONTROL_KEY);

				if (featureBeingResurrected || !ReclaimObject(feature)) {
					StopMove();
					FinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
				} else {
					AddUnitToFeatureReclaimers(owner);
				}
			} else {
				StopMove();
				FinishCommand();
				RemoveUnitFromFeatureReclaimers(owner);
			}

			RemoveUnitFromReclaimers(owner);
		} else { // reclaim unit
			CUnit* unit = uh->GetUnit(uid);

			if (unit != NULL && c.params.size() == 5) {
				const float3 pos(c.params[1], c.params[2], c.params[3]);
				const float radius = c.params[4] + 100.0f; // do not walk too far outside reclaim area

				const bool outOfReclaimRange =
					(pos.SqDistance2D(unit->pos) > radius * radius) ||
					(builder->curReclaim == unit && unit->isMoving && !IsInBuildRange(unit));
				const bool busyAlliedBuilder =
					unit->unitDef->builder &&
					!unit->commandAI->commandQue.empty() &&
					teamHandler->Ally(owner->allyteam, unit->allyteam);

				if (outOfReclaimRange || busyAlliedBuilder) {
					StopMove();
					RemoveUnitFromReclaimers(owner);
					FinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
					return;
				}
			}

			if (unit != NULL && unit != owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(unit->id) && unit->AllowedReclaim(owner)) {
				if (!ReclaimObject(unit)) {
					StopMove();
					FinishCommand();
				} else {
					AddUnitToReclaimers(owner);
				}
			} else {
				RemoveUnitFromReclaimers(owner);
				FinishCommand();
			}

			RemoveUnitFromFeatureReclaimers(owner);
		}
	} else if (c.params.size() == 4) {
		// area reclaim
		const float3 pos = c.GetPos(0);
		const float radius = c.params[3];
		const bool recUnits = !!(c.options & META_KEY);
		const bool recEnemyOnly = (c.options & META_KEY) && (c.options & CONTROL_KEY);
		const bool recSpecial = !!(c.options & CONTROL_KEY);

		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		builder->StopBuild();

		ReclaimOption recopt = REC_NORESCHECK;
		if (recUnits)     recopt |= REC_UNITS;
		if (recEnemyOnly) recopt |= REC_ENEMYONLY;
		if (recSpecial)   recopt |= REC_SPECIAL;

		if (FindReclaimTargetAndReclaim(pos, radius, c.options, recopt)) {
			inCommand = false;
			SlowUpdate();
			return;
		}
		if(!(c.options & ALT_KEY)){
			FinishCommand();
		}
	} else {
		// wrong number of parameters
		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		FinishCommand();
	}
}
コード例 #3
0
ファイル: BuilderCAI.cpp プロジェクト: Finkky/spring
void CBuilderCAI::ExecuteGuard(Command& c)
{
	if (!owner->unitDef->canGuard)
		return;

	CBuilder* builder = (CBuilder*) owner;
	CUnit* guardee = uh->GetUnit(c.params[0]);

	if (guardee == NULL) { FinishCommand(); return; }
	if (guardee == owner) { FinishCommand(); return; }
	if (UpdateTargetLostTimer(guardee->id) == 0) { FinishCommand(); return; }
	if (guardee->outOfMapTime > (GAME_SPEED * 5)) { FinishCommand(); return; }


	if (CBuilder* b = dynamic_cast<CBuilder*>(guardee)) {
		if (b->terraforming) {
			if (MoveInBuildRange(b->terraformCenter, b->terraformRadius * 0.7f)) {
				builder->HelpTerraform(b);
			} else {
				StopSlowGuard();
			}
			return;
		} else if (b->curReclaim && owner->unitDef->canReclaim) {
			StopSlowGuard();
			if (!ReclaimObject(b->curReclaim)) {
				StopMove();
			}
			return;
		} else if (b->curResurrect && owner->unitDef->canResurrect) {
			StopSlowGuard();
			if (!ResurrectObject(b->curResurrect)) {
				StopMove();
			}
			return;
		} else {
			builder->StopBuild();
		}

		const bool pushRepairCommand =
			(  b->curBuild != NULL) &&
			(  b->curBuild->soloBuilder == NULL || b->curBuild->soloBuilder == owner) &&
			(( b->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			( !b->curBuild->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options);
			nc.params.push_back(b->curBuild->id);

			commandQue.push_front(nc);
			inCommand = false;
			SlowUpdate();
			return;
		}
	}

	if (CFactory* fac = dynamic_cast<CFactory*>(guardee)) {
		const bool pushRepairCommand =
			(  fac->curBuild != NULL) &&
			(  fac->curBuild->soloBuilder == NULL || fac->curBuild->soloBuilder == owner) &&
			(( fac->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			 (!fac->curBuild->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options);
			nc.params.push_back(fac->curBuild->id);

			commandQue.push_front(nc);
			inCommand = false;
			// SlowUpdate();
			return;
		}
	}

	if (!(c.options & CONTROL_KEY) && IsUnitBeingReclaimed(guardee, owner))
		return;

	const float3 pos    = guardee->pos;
	const float  radius = (guardee->immobile) ? guardee->radius : guardee->radius * 0.8f; // in case of mobile units reduce radius a bit
	
	if (MoveInBuildRange(pos, radius)) {
		StartSlowGuard(guardee->moveType->GetMaxSpeed());

		const bool pushRepairCommand =
			(  guardee->health < guardee->maxHealth) &&
			(  guardee->soloBuilder == NULL || guardee->soloBuilder == owner) &&
			(( guardee->beingBuilt && owner->unitDef->canAssist) ||
			 (!guardee->beingBuilt && owner->unitDef->canRepair));

		if (pushRepairCommand) {
			StopSlowGuard();

			Command nc(CMD_REPAIR, c.options);
			nc.params.push_back(guardee->id);

			commandQue.push_front(nc);
			inCommand = false;
			return;
		} else {
			NonMoving();
		}
	} else {
		StopSlowGuard();
	}
}
コード例 #4
0
void CBuilderCAI::ExecuteReclaim(Command& c)
{
	assert(owner->unitDef->canReclaim);
	if(c.params.size()==1){
		int id=(int) c.params[0];
		if (id >= MAX_UNITS) {     //reclaim feature
			const CFeatureSet& fset = featureHandler->GetActiveFeatures();
			CFeatureSet::const_iterator it = fset.find(id - MAX_UNITS);
			if (it != fset.end()) {
				CFeature* feature = *it;
				if(!ReclaimObject(feature)){
					StopMove();
					FinishCommand();
					RemoveUnitFromFeatureReclaimers(owner);
				} else {
					AddUnitToFeatureReclaimers(owner);
				}
			} else {
				StopMove();
				FinishCommand();
				RemoveUnitFromFeatureReclaimers(owner);
			}
			RemoveUnitFromReclaimers(owner);

		} else {                   //reclaim unit
			CUnit* unit=uh->units[id];

			if(unit && unit!=owner && unit->unitDef->reclaimable && UpdateTargetLostTimer(id) && unit->AllowedReclaim(owner) ){
				if(!ReclaimObject(unit)){
					StopMove();
					FinishCommand();
				} else {
					AddUnitToReclaimers(owner);
				}
			} else {
				RemoveUnitFromReclaimers(owner);
				FinishCommand();
			}
			RemoveUnitFromFeatureReclaimers(owner);
		}
	} else if(c.params.size()==4){//area reclaim
		float3 pos(c.params[0],c.params[1],c.params[2]);
		float radius=c.params[3];
		const bool recAnyTeam = ((c.options & CONTROL_KEY) != 0);
		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		if (FindReclaimableFeatureAndReclaim(pos, radius, c.options, true, recAnyTeam)) {
			inCommand=false;
			SlowUpdate();
			return;
		}
		if(!(c.options & ALT_KEY)){
			FinishCommand();
		}
	} else {	//wrong number of parameters
		RemoveUnitFromReclaimers(owner);
		RemoveUnitFromFeatureReclaimers(owner);
		FinishCommand();
	}
	return;
}
コード例 #5
0
void CBuilderCAI::ExecuteGuard(Command& c)
{
	assert(owner->unitDef->canGuard);
	CBuilder* fac=(CBuilder*)owner;
	CUnit* guarded=uh->units[(int)c.params[0]];
	if (guarded && guarded!=owner && UpdateTargetLostTimer((int)c.params[0])) {
		if (CBuilder* b=dynamic_cast<CBuilder*>(guarded)) {
			if (b->terraforming) {
				if (f3SqDist(fac->pos, b->terraformCenter) <
						Square((fac->buildDistance * 0.8f) + (b->terraformRadius * 0.7f))) {
					StopMove();
					owner->moveType->KeepPointingTo(b->terraformCenter, fac->buildDistance*0.9f, false);
					fac->HelpTerraform(b);
				} else {
					StopSlowGuard();
					SetGoal(b->terraformCenter,fac->pos,fac->buildDistance*0.7f+b->terraformRadius*0.6f);
				}
				return;
			} else if (b->curReclaim && owner->unitDef->canReclaim){
				StopSlowGuard();
				if(!ReclaimObject(b->curReclaim)){
					StopMove();
				}
				return;
			} else {
				fac->StopBuild();
			}
			if (b->curBuild &&
			    (!b->curBuild->soloBuilder || (b->curBuild->soloBuilder == owner)) &&
			    (( b->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			     (!b->curBuild->beingBuilt && owner->unitDef->canRepair))) {
				StopSlowGuard();
				Command nc;
				nc.id=CMD_REPAIR;
				nc.options=c.options;
				nc.params.push_back(b->curBuild->id);
				commandQue.push_front(nc);
				inCommand=false;
				SlowUpdate();
				return;
			}
		}
		if(CFactory* f=dynamic_cast<CFactory*>(guarded)){
			if (f->curBuild &&
			    (!f->curBuild->soloBuilder || (f->curBuild->soloBuilder == owner)) &&
			    (( f->curBuild->beingBuilt && owner->unitDef->canAssist) ||
			     (!f->curBuild->beingBuilt && owner->unitDef->canRepair))) {
				StopSlowGuard();
				Command nc;
				nc.id=CMD_REPAIR;
				nc.options=c.options;
				nc.params.push_back(f->curBuild->id);
				commandQue.push_front(nc);
				inCommand=false;
				//					SlowUpdate();
				return;
			}
		}
		if (IsUnitBeingReclaimedByFriend(guarded))
			return;
		float3 curPos = owner->pos;
		float3 dif = guarded->pos - curPos;
		dif.Normalize();
		float3 goal = guarded->pos - dif * (fac->buildDistance * 0.5f);
		if (f3SqLen(guarded->pos - curPos) >
				(fac->buildDistance*1.1f + guarded->radius) *
				(fac->buildDistance*1.1f + guarded->radius)) {
			StopSlowGuard();
		}
		if (f3SqLen(guarded->pos - curPos) <
				(fac->buildDistance*0.9f + guarded->radius) *
				(fac->buildDistance*0.9f + guarded->radius)) {
			StartSlowGuard(guarded->maxSpeed);
			StopMove();
			//				logOutput.Print("should point with type 3?");
			owner->moveType->KeepPointingTo(guarded->pos,
				fac->buildDistance*0.9f+guarded->radius, false);
			if ((guarded->health < guarded->maxHealth) &&
			    (!guarded->soloBuilder || (guarded->soloBuilder == owner)) &&
			    (( guarded->beingBuilt && owner->unitDef->canAssist) ||
			     (!guarded->beingBuilt && owner->unitDef->canRepair))) {
				StopSlowGuard();

				Command nc;
				nc.id=CMD_REPAIR;
				nc.options=c.options;
				nc.params.push_back(guarded->id);
				commandQue.push_front(nc);
				inCommand=false;
				return;
			} else {
				NonMoving();
			}
		} else {
			if (f3SqLen(goalPos - goal) > 4000
					|| f3SqLen(goalPos - owner->pos) <
					   (owner->maxSpeed*30 + 1 + SQUARE_SIZE*2) *
					   (owner->maxSpeed*30 + 1 + SQUARE_SIZE*2)){
				SetGoal(goal,curPos);
			}
		}
	} else {
		FinishCommand();
	}
	return;
}