本文整理汇总了C++中SetGoal函数的典型用法代码示例。如果您正苦于以下问题:C++ SetGoal函数的具体用法?C++ SetGoal怎么用?C++ SetGoal使用的例子?那么, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了SetGoal函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SetGoal
void PIDInterface::SetGoal(double xGoalDistance, double yGoalDistance, float speedMultiplier)
{
SetGoal(xGoalDistance, yGoalDistance);
m_speedMultiplier = speedMultiplier;
}
示例2: assert
void CBuilderCAI::ExecuteFight(Command& c)
{
assert((c.options & INTERNAL_ORDER) || owner->unitDef->canFight);
CBuilder* fac=(CBuilder*)owner;
if(tempOrder){
tempOrder=false;
inCommand=true;
}
if(c.params.size()<3){ //this shouldnt happen but anyway ...
logOutput.Print("Error: got fight cmd with less than 3 params on %s in BuilderCAI",owner->unitDef->humanName.c_str());
return;
}
if(c.params.size() >= 6){
if(!inCommand){
commandPos1 = float3(c.params[3],c.params[4],c.params[5]);
}
} else {
// Some hackery to make sure the line (commandPos1,commandPos2) is NOT
// rotated (only shortened) if we reach this because the previous return
// fight command finished by the 'if((curPos-pos).SqLength2D()<(64*64)){'
// condition, but is actually updated correctly if you click somewhere
// outside the area close to the line (for a new command).
commandPos1 = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
if (f3SqLen(owner->pos - commandPos1) > (96 * 96)) {
commandPos1 = owner->pos;
}
}
float3 pos(c.params[0],c.params[1],c.params[2]);
if (!inCommand) {
inCommand = true;
commandPos2 = pos;
}
if (c.params.size() >= 6) {
pos = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
}
if (pos!=goalPos) {
SetGoal(pos, owner->pos);
}
float3 curPosOnLine = ClosestPointOnLine(commandPos1, commandPos2, owner->pos);
if ((owner->unitDef->canRepair || owner->unitDef->canAssist) &&
FindRepairTargetAndRepair(curPosOnLine, 300*owner->moveState+fac->buildDistance-8,c.options,true)){
tempOrder = true;
inCommand = false;
if (lastPC1 != gs->frameNum) { //avoid infinite loops
lastPC1 = gs->frameNum;
SlowUpdate();
}
return;
}
if (owner->unitDef->canReclaim &&
FindReclaimableFeatureAndReclaim(curPosOnLine,300,c.options,false, false)) {
tempOrder = true;
inCommand = false;
if (lastPC2 != gs->frameNum) { //avoid infinite loops
lastPC2 = gs->frameNum;
SlowUpdate();
}
return;
}
if (f3SqLen(owner->pos - pos) < (64*64)) {
FinishCommand();
return;
}
if(owner->haveTarget && owner->moveType->progressState!=AMoveType::Done){
StopMove();
} else if(owner->moveType->progressState!=AMoveType::Active){
owner->moveType->StartMoving(goalPos, 8);
}
return;
}
示例3: Init
virtual void Init()
{
SetFlags( ACH_SAVE_GLOBAL );
SetGoal( 50 );
VarInit();
}
示例4: assert
/**
* @brief Causes this CMobileCAI to execute the attack order c
*/
void CMobileCAI::ExecuteAttack(Command &c)
{
assert(owner->unitDef->canAttack);
// limit how far away we fly
if (tempOrder && (owner->moveState < 2) && orderTarget
&& LinePointDist(ClosestPointOnLine(commandPos1, commandPos2, owner->pos),
commandPos2, orderTarget->pos)
> (500 * owner->moveState + owner->maxRange)) {
StopMove();
FinishCommand();
return;
}
// check if we are in direct command of attacker
if (!inCommand) {
// don't start counting until the owner->AttackGround() order is given
owner->commandShotCount = -1;
if (c.params.size() == 1) {
CUnit* targetUnit = uh->GetUnit(c.params[0]);
// check if we have valid target parameter and that we aren't attacking ourselves
if (targetUnit != NULL && targetUnit != owner) {
float3 fix = targetUnit->pos + owner->posErrorVector * 128;
float3 diff = float3(fix - owner->pos).Normalize();
SetGoal(fix - diff * targetUnit->radius, owner->pos);
orderTarget = targetUnit;
AddDeathDependence(orderTarget);
inCommand = true;
} else {
// unit may not fire on itself, cancel order
StopMove();
FinishCommand();
return;
}
}
else if (c.params.size() >= 3) {
// user gave force-fire attack command
float3 pos(c.params[0], c.params[1], c.params[2]);
SetGoal(pos, owner->pos);
inCommand = true;
}
}
else if ((c.params.size() == 3) && (owner->commandShotCount > 0) && (commandQue.size() > 1)) {
// the trailing CMD_SET_WANTED_MAX_SPEED in a command pair does not count
if ((commandQue.size() > 2) || (commandQue.back().id != CMD_SET_WANTED_MAX_SPEED)) {
StopMove();
FinishCommand();
return;
}
}
// if our target is dead or we lost it then stop attacking
// NOTE: unit should actually just continue to target area!
if (targetDied || (c.params.size() == 1 && UpdateTargetLostTimer(int(c.params[0])) == 0)) {
// cancel keeppointingto
StopMove();
FinishCommand();
return;
}
// user clicked on enemy unit (note that we handle aircrafts slightly differently)
if (orderTarget) {
//bool b1 = owner->AttackUnit(orderTarget, c.id == CMD_DGUN);
bool b2 = false;
bool b3 = false;
bool b4 = false;
float edgeFactor = 0.f; // percent offset to target center
float3 diff = owner->pos - orderTarget->midPos;
if (owner->weapons.size() > 0) {
if (!(c.options & ALT_KEY) && SkipParalyzeTarget(orderTarget)) {
StopMove();
FinishCommand();
return;
}
CWeapon* w = owner->weapons.front();
// if we have at least one weapon then check if we
// can hit target with our first (meanest) one
b2 = w->TryTargetRotate(orderTarget, c.id == CMD_DGUN);
b3 = Square(w->range - (w->relWeaponPos).Length())
> (orderTarget->pos.SqDistance(owner->pos));
b4 = w->TryTargetHeading(GetHeadingFromVector(-diff.x, -diff.z),
orderTarget->pos, orderTarget != NULL, orderTarget);
edgeFactor = fabs(w->targetBorder);
}
float diffLength2d = diff.Length2D();
// if w->AttackUnit() returned true then we are already
// in range with our biggest weapon so stop moving
// also make sure that we're not locked in close-in/in-range state loop
// due to rotates invoked by in-range or out-of-range states
//.........这里部分代码省略.........
示例5: FinishCommand
void CBuilderCAI::SlowUpdate()
{
if (commandQue.empty()) {
CMobileCAI::SlowUpdate();
return;
}
if (owner->stunned) {
return;
}
CBuilder* fac = (CBuilder*)owner;
Command& c = commandQue.front();
if (OutOfImmobileRange(c)) {
FinishCommand();
return;
}
map<int, string>::iterator boi = buildOptions.find(c.id);
if (!owner->beingBuilt && boi != buildOptions.end()) {
const UnitDef* ud = unitDefHandler->GetUnitByName(boi->second);
const float radius = GetUnitDefRadius(ud, c.id);
if (inCommand) {
if (building) {
if (f3SqDist(build.pos, fac->pos) > Square(fac->buildDistance + radius - 8.0f)) {
owner->moveType->StartMoving(build.pos, fac->buildDistance * 0.5f + radius);
} else {
StopMove();
// needed since above startmoving cancels this
owner->moveType->KeepPointingTo(build.pos, (fac->buildDistance + radius) * 0.6f, false);
}
if (!fac->curBuild && !fac->terraforming) {
building = false;
StopMove(); //cancel the effect of KeepPointingTo
FinishCommand();
}
// This can only be true if two builders started building
// the restricted unit in the same simulation frame
else if (uh->unitsByDefs[owner->team][build.def->id].size() > build.def->maxThisUnit) {
// unit restricted
building = false;
fac->StopBuild();
CancelRestrictedUnit(boi->second);
}
} else {
build.Parse(c);
if (uh->unitsByDefs[owner->team][build.def->id].size() >= build.def->maxThisUnit) {
// unit restricted, don't bother moving all the way
// to the construction site first before telling us
// (since greyed-out icons can still be clicked etc,
// would be better to prevent that but doesn't cover
// case where limit reached while builder en-route)
CancelRestrictedUnit(boi->second);
StopMove();
} else {
build.pos = helper->Pos2BuildPos(build);
const float sqdist = f3SqDist(build.pos, fac->pos);
if ((sqdist < Square(fac->buildDistance * 0.6f + radius)) ||
(!owner->unitDef->canmove && (sqdist <= Square(fac->buildDistance + radius - 8.0f)))) {
StopMove();
if (luaRules && !luaRules->AllowUnitCreation(build.def, owner, &build.pos)) {
FinishCommand();
}
else if (uh->maxUnits > (int) teamHandler->Team(owner->team)->units.size()) {
// max unitlimit reached
buildRetries++;
owner->moveType->KeepPointingTo(build.pos, fac->buildDistance * 0.7f + radius, false);
if (fac->StartBuild(build) || (buildRetries > 20)) {
building = true;
} else {
ENTER_MIXED;
if ((owner->team == gu->myTeam) && !(buildRetries & 7)) {
logOutput.Print("%s: Build pos blocked", owner->unitDef->humanName.c_str());
logOutput.SetLastMsgPos(owner->pos);
}
ENTER_SYNCED;
helper->BuggerOff(build.pos, radius);
NonMoving();
}
}
} else {
if (owner->moveType->progressState == AMoveType::Failed) {
if (++buildRetries > 5) {
StopMove();
FinishCommand();
}
}
SetGoal(build.pos, owner->pos, fac->buildDistance * 0.4f + radius);
}
}
}
} else { //!inCommand
BuildInfo bi;
bi.pos.x=floor(c.params[0]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
bi.pos.z=floor(c.params[2]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
//.........这里部分代码省略.........
示例6: SetWantedMaxSpeed
void CAirMoveType::StartMoving(float3 pos, float goalRadius, float speed)
{
SetWantedMaxSpeed(speed);
SetGoal(pos);
}
示例7: assert
void CAirCAI::ExecuteAttack(Command &c)
{
assert(owner->unitDef->canAttack);
targetAge++;
if (tempOrder && owner->moveState == 1) {
// limit how far away we fly
if (orderTarget && LinePointDist(commandPos1, commandPos2, orderTarget->pos) > 1500) {
owner->SetUserTarget(0);
FinishCommand();
return;
}
}
if (inCommand) {
if (targetDied || (c.params.size() == 1 && UpdateTargetLostTimer(int(c.params[0])) == 0)) {
FinishCommand();
return;
}
if ((c.params.size() == 3) && (owner->commandShotCount < 0) && (commandQue.size() > 1)) {
owner->AttackGround(float3(c.params[0], c.params[1], c.params[2]), true);
FinishCommand();
return;
}
if (orderTarget) {
if (orderTarget->unitDef->canfly && orderTarget->crashing) {
owner->SetUserTarget(0);
FinishCommand();
return;
}
if (!(c.options & ALT_KEY) && SkipParalyzeTarget(orderTarget)) {
owner->SetUserTarget(0);
FinishCommand();
return;
}
}
} else {
targetAge = 0;
owner->commandShotCount = -1;
if (c.params.size() == 1) {
const int targetID = int(c.params[0]);
const bool legalTarget = (targetID >= 0 && targetID < MAX_UNITS);
CUnit* targetUnit = (legalTarget)? uh->units[targetID]: 0x0;
if (legalTarget && targetUnit != 0x0 && targetUnit != owner) {
orderTarget = targetUnit;
owner->AttackUnit(orderTarget, false);
AddDeathDependence(orderTarget);
inCommand = true;
SetGoal(orderTarget->pos, owner->pos, cancelDistance);
} else {
FinishCommand();
return;
}
} else {
float3 pos(c.params[0], c.params[1], c.params[2]);
owner->AttackGround(pos, false);
inCommand = true;
}
}
return;
}
示例8: switch
void CTransportCAI::SlowUpdate(void)
{
if(commandQue.empty()){
CMobileCAI::SlowUpdate();
return;
}
CTransportUnit* transport=(CTransportUnit*)owner;
Command& c=commandQue.front();
switch(c.id){
case CMD_LOAD_UNITS:
if(c.params.size()==1){ //load single unit
if(transport->transportCapacityUsed >= owner->unitDef->transportCapacity){
FinishCommand();
return;
}
if(inCommand){
if(!owner->cob->busy)
FinishCommand();
return;
}
CUnit* unit=uh->units[(int)c.params[0]];
if(unit && CanTransport(unit)){
toBeTransportedUnitId=unit->id;
unit->toBeTransported=true;
if(unit->mass+transport->transportMassUsed > owner->unitDef->transportMass){
FinishCommand();
return;
}
if(goalPos.distance2D(unit->pos)>10){
float3 fix = unit->pos;
SetGoal(fix,owner->pos,64);
}
if(unit->pos.distance2D(owner->pos)<owner->unitDef->loadingRadius*0.9){
if(CTAAirMoveType* am=dynamic_cast<CTAAirMoveType*>(owner->moveType)){ //handle air transports differently
float3 wantedPos=unit->pos+UpVector*unit->model->height;
SetGoal(wantedPos,owner->pos);
am->dontCheckCol=true;
am->ForceHeading(unit->heading);
am->SetWantedAltitude(unit->model->height);
am->maxDrift=1;
//info->AddLine("cai dist %f %f %f",owner->pos.distance(wantedPos),owner->pos.distance2D(wantedPos),owner->pos.y-wantedPos.y);
if(owner->pos.distance(wantedPos)<4 && abs(owner->heading-unit->heading)<50 && owner->updir.dot(UpVector)>0.995){
am->dontCheckCol=false;
am->dontLand=true;
std::vector<int> args;
args.push_back((int)(unit->model->height*65536));
owner->cob->Call("BeginTransport",args);
std::vector<int> args2;
args2.push_back(0);
args2.push_back((int)(unit->model->height*65536));
owner->cob->Call("QueryTransport",args2);
((CTransportUnit*)owner)->AttachUnit(unit,args2[0]);
am->SetWantedAltitude(0);
FinishCommand();
return;
}
} else {
inCommand=true;
scriptReady=false;
StopMove();
std::vector<int> args;
args.push_back(unit->id);
owner->cob->Call("TransportPickup",args,ScriptCallback,this,0);
}
}
} else {
FinishCommand();
}
} else if(c.params.size()==4){ //load in radius
if(lastCall==gs->frameNum) //avoid infinite loops
return;
lastCall=gs->frameNum;
float3 pos(c.params[0],c.params[1],c.params[2]);
float radius=c.params[3];
CUnit* unit=FindUnitToTransport(pos,radius);
if(unit && ((CTransportUnit*)owner)->transportCapacityUsed < owner->unitDef->transportCapacity){
Command c2;
c2.id=CMD_LOAD_UNITS;
c2.params.push_back(unit->id);
c2.options=c.options | INTERNAL_ORDER;
commandQue.push_front(c2);
inCommand=false;
SlowUpdate();
return;
} else {
FinishCommand();
return;
}
}
break;
case CMD_UNLOAD_UNITS:{
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]);
//.........这里部分代码省略.........
示例9: Init
virtual void Init()
{
SetFlags( ACH_SAVE_GLOBAL );
SetGoal( 1 );
}
示例10: Init
virtual void Init()
{
SetFlags(ACH_SAVE_WITH_GAME);
SetGameDirFilter("firefightreloaded");
SetGoal(1);
}
示例11: GetUnitRadius
void CBuilderCAI::SlowUpdate()
{
if(commandQue.empty()){
CMobileCAI::SlowUpdate();
return;
}
if(owner->stunned){
return;
}
Command& c=commandQue.front();
CBuilder* fac=(CBuilder*)owner;
float3 curPos=owner->pos;
map<int,string>::iterator boi;
if((boi=buildOptions.find(c.id))!=buildOptions.end()){
const UnitDef* ud = unitDefHandler->GetUnitByName(boi->second);
const float radius = GetUnitRadius(ud, c.id);
if (inCommand) {
if (building) {
if (build.pos.distance2D(fac->pos) > fac->buildDistance+radius-8.0f) {
owner->moveType->StartMoving(build.pos, fac->buildDistance*0.5f+radius);
} else {
StopMove();
owner->moveType->KeepPointingTo(build.pos, (fac->buildDistance+radius)*0.6f, false); //needed since above startmoving cancels this
}
if(!fac->curBuild && !fac->terraforming){
building=false;
StopMove(); //cancel the effect of KeepPointingTo
FinishCommand();
}
} else {
build.Parse(c);
const float dist = build.pos.distance2D(fac->pos);
if ((dist < (fac->buildDistance * 0.6f + radius)) ||
(!owner->unitDef->canmove && (dist <= (fac->buildDistance+radius-8.0f)))) {
StopMove();
if(luaRules && !luaRules->AllowUnitCreation(build.def, owner, &build.pos)) {
FinishCommand();
}
else if(uh->unitsType[owner->team][build.def->id]>=build.def->maxThisUnit){ //unit restricted
ENTER_MIXED;
if(owner->team == gu->myTeam){
logOutput.Print("%s: Build failed, unit type limit reached",owner->unitDef->humanName.c_str());
logOutput.SetLastMsgPos(owner->pos);
}
ENTER_SYNCED;
FinishCommand();
}
else if(uh->maxUnits>(int)gs->Team(owner->team)->units.size()){ //max unitlimit reached
buildRetries++;
owner->moveType->KeepPointingTo(build.pos, fac->buildDistance*0.7f+radius, false);
if (fac->StartBuild(build) || (buildRetries > 20)) {
building=true;
} else {
ENTER_MIXED;
if ((owner->team == gu->myTeam) && !(buildRetries & 7)) {
logOutput.Print("%s: Build pos blocked",owner->unitDef->humanName.c_str());
logOutput.SetLastMsgPos(owner->pos);
}
ENTER_SYNCED;
helper->BuggerOff(build.pos,radius);
NonMoving();
}
}
} else {
if (owner->moveType->progressState == CMoveType::Failed) {
if (++buildRetries > 5) {
StopMove();
FinishCommand();
}
}
SetGoal(build.pos,owner->pos, fac->buildDistance*0.4f+radius);
}
}
} else { //!inCommand
BuildInfo bi;
bi.pos.x=floor(c.params[0]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
bi.pos.z=floor(c.params[2]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
bi.pos.y=c.params[1];
CFeature* f=0;
if (c.params.size()==4)
bi.buildFacing = int(c.params[3]);
bi.def = unitDefHandler->GetUnitByName(boi->second);
uh->TestUnitBuildSquare(bi,f,owner->allyteam);
if (f) {
if (!owner->unitDef->canReclaim || !f->def->reclaimable) {
// FIXME user shouldn't be able to queue buildings on top of features
// in the first place (in this case).
StopMove();
FinishCommand();
} else {
Command c2;
c2.id=CMD_RECLAIM;
c2.options=0;
c2.params.push_back(f->id+MAX_UNITS);
commandQue.push_front(c2);
SlowUpdate(); //this assumes that the reclaim command can never return directly without having reclaimed the target
//.........这里部分代码省略.........
示例12: RTTR_Assert
void Ware::GoalDestroyed()
{
if(state == STATE_WAITINWAREHOUSE)
{
// Ware ist noch im Lagerhaus auf der Warteliste
RTTR_Assert(false); // Should not happen. noBaseBuilding::WareNotNeeded handles this case!
goal = NULL; // just in case: avoid corruption although the ware itself might be lost (won't ever be carried again)
}
// Ist sie evtl. gerade mit dem Schiff unterwegs?
else if(state == STATE_ONSHIP)
{
// Ziel zunächst auf NULL setzen, was dann vom Zielhafen erkannt wird,
// woraufhin dieser die Ware gleich in sein Inventar mit übernimmt
goal = NULL;
}
// Oder wartet sie im Hafen noch auf ein Schiff
else if(state == STATE_WAITFORSHIP)
{
// Dann dem Hafen Bescheid sagen
RTTR_Assert(location);
RTTR_Assert(location->GetGOT() == GOT_NOB_HARBORBUILDING);
// This also adds the ware to the harbors inventory
static_cast<nobHarborBuilding*>(location)->CancelWareForShip(this);
// Kill the ware
gwg->GetPlayer(location->GetPlayer()).RemoveWare(this);
goal = NULL;
location = NULL;
GetEvMgr().AddToKillList(this);
}
else
{
// Ware ist unterwegs, Lagerhaus finden und Ware dort einliefern
RTTR_Assert(location);
RTTR_Assert(location->GetPlayer() < MAX_PLAYERS);
// Wird sie gerade aus einem Lagerhaus rausgetragen?
if(location->GetGOT() == GOT_NOB_STOREHOUSE || location->GetGOT() == GOT_NOB_HARBORBUILDING || location->GetGOT() == GOT_NOB_HQ)
{
if(location != goal)
{
SetGoal(static_cast<noBaseBuilding*>(location));
}
else //at the goal (which was just destroyed) and get carried out right now? -> we are about to get destroyed...
{
goal = NULL;
next_dir = INVALID_DIR;
}
}
// Wenn sie an einer Flagge liegt, muss der Weg neu berechnet werden und dem Träger Bescheid gesagt werden
else if(state == STATE_WAITATFLAG)
{
goal = NULL;
unsigned char oldNextDir = next_dir;
FindRouteToWarehouse();
if(oldNextDir != next_dir)
{
RemoveWareJobForDir(oldNextDir);
if(next_dir != INVALID_DIR)
{
RTTR_Assert(goal); // Having a nextDir implies having a goal
CallCarrier();
}else
RTTR_Assert(!goal); // Can only have a goal with a valid path
}
}
else if(state == STATE_CARRIED)
{
if(goal != location)
{
// find a warehouse for us (if we are entering a warehouse already set this as new goal (should only happen if its a harbor for shipping as the building wasnt our goal))
if(location->GetGOT() == GOT_NOB_STOREHOUSE || location->GetGOT() == GOT_NOB_HARBORBUILDING || location->GetGOT() == GOT_NOB_HQ) //currently carried into a warehouse? -> add ware (pathfinding will not return this wh because of path lengths 0)
{
if(location->GetGOT()!=GOT_NOB_HARBORBUILDING)
LOG.lprintf("WARNING: Ware::GoalDestroyed() -- ware is currently being carried into warehouse or hq that was not it's goal! ware id %i, type %i, player %i, wareloc %i,%i, goal loc %i,%i \n",GetObjId(),type,location->GetPlayer(),GetLocation()->GetX(),GetLocation()->GetY(), goal->GetX(), goal->GetY());
SetGoal(static_cast<noBaseBuilding*>(location));
}
else
{
goal = NULL;
FindRouteToWarehouse();
}
}else
{
// too late to do anything our road will be removed and ware destroyed when the carrier starts walking about
goal = NULL;
}
}
}
}
示例13: SetGoal
void Missile::RendGoal(Ball* cha){
SetGoal(cha->GetPosition() + D3DXVECTOR3(rand()%10-5,rand()%10-5,rand()%10-5));
}
示例14: StopMove
void CMobileCAI::SlowUpdate()
{
if(owner->unitDef->maxFuel>0 && dynamic_cast<CTAAirMoveType*>(owner->moveType)) {
CTAAirMoveType* myPlane=(CTAAirMoveType*)owner->moveType;
if(myPlane->reservedPad) {
return;
} else {
if(owner->currentFuel <= 0) {
StopMove();
owner->userAttackGround=false;
owner->userTarget=0;
inCommand=false;
CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
if(lp) {
myPlane->AddDeathDependence(lp);
myPlane->reservedPad=lp;
myPlane->padStatus=0;
myPlane->oldGoalPos=myPlane->goalPos;
return;
}
float3 landingPos = airBaseHandler->FindClosestAirBasePos(owner,8000,owner->unitDef->minAirBasePower);
if(landingPos != ZeroVector && owner->pos.distance2D(landingPos) > 300) {
inCommand=false;
StopMove();
SetGoal(landingPos,owner->pos);
} else {
if(myPlane->aircraftState == CTAAirMoveType::AIRCRAFT_FLYING)
myPlane->SetState(CTAAirMoveType::AIRCRAFT_LANDING);
}
return;
}
if(owner->currentFuel < myPlane->repairBelowHealth*owner->unitDef->maxFuel) {
if(commandQue.empty() || commandQue.front().id==CMD_PATROL) {
CAirBaseHandler::LandingPad* lp=airBaseHandler->FindAirBase(owner,8000,owner->unitDef->minAirBasePower);
if(lp) {
StopMove();
owner->userAttackGround=false;
owner->userTarget=0;
inCommand=false;
myPlane->AddDeathDependence(lp);
myPlane->reservedPad=lp;
myPlane->padStatus=0;
myPlane->oldGoalPos=myPlane->goalPos;
if(myPlane->aircraftState==CTAAirMoveType::AIRCRAFT_LANDED) {
myPlane->SetState(CTAAirMoveType::AIRCRAFT_TAKEOFF);
}
return;
}
}
}
}
}
if(!commandQue.empty() && commandQue.front().timeOut<gs->frameNum) {
StopMove();
FinishCommand();
return;
}
if(commandQue.empty()) {
// if(!owner->ai || owner->ai->State() != CHasState::Active) {
IdleCheck();
// }
if(commandQue.empty() || commandQue.front().id==CMD_ATTACK) //the attack order could terminate directly and thus cause a loop
return;
}
float3 curPos=owner->pos;
Command& c=commandQue.front();
switch(c.id) {
case CMD_STOP: {
StopMove();
CCommandAI::SlowUpdate();
break;
}
case CMD_MOVE: {
float3 pos(c.params[0],c.params[1],c.params[2]);
if(!(pos==goalPos)) {
SetGoal(pos,curPos);
}
if((curPos-goalPos).SqLength2D()<1024 || owner->moveType->progressState==CMoveType::Failed) {
FinishCommand();
}
break;
}
case CMD_PATROL: {
if(c.params.size()<3) { //this shouldnt happen but anyway ...
info->AddLine("Error: got patrol cmd with less than 3 params on %s in mobilecai",
owner->unitDef->humanName.c_str());
return;
}
Command temp;
temp.id = CMD_FIGHT;
temp.params.push_back(c.params[0]);
temp.params.push_back(c.params[1]);
temp.params.push_back(c.params[2]);
temp.options = c.options|INTERNAL_ORDER;
commandQue.push_back(c);
commandQue.pop_front();
//.........这里部分代码省略.........
示例15: FinishCommand
void CTransportCAI::ExecuteLoadUnits(Command& c)
{
CTransportUnit* transport = reinterpret_cast<CTransportUnit*>(owner);
if (c.params.size() == 1) {
// load single unit
CUnit* unit = unitHandler->GetUnit(c.params[0]);
if (unit == NULL) {
FinishCommand();
return;
}
if (c.options & INTERNAL_ORDER) {
if (unit->commandAI->commandQue.empty()) {
if (!LoadStillValid(unit)) {
FinishCommand();
return;
}
} else {
Command& currentUnitCommand = unit->commandAI->commandQue[0];
if ((currentUnitCommand.GetID() == CMD_LOAD_ONTO) && (currentUnitCommand.params.size() == 1) && (int(currentUnitCommand.params[0]) == owner->id)) {
if ((unit->moveType->progressState == AMoveType::Failed) && (owner->moveType->progressState == AMoveType::Failed)) {
unit->commandAI->FinishCommand();
FinishCommand();
return;
}
} else if (!LoadStillValid(unit)) {
FinishCommand();
return;
}
}
}
if (inCommand) {
if (!owner->script->IsBusy()) {
FinishCommand();
}
return;
}
if (unit != NULL && CanTransport(unit) && UpdateTargetLostTimer(int(c.params[0]))) {
SetTransportee(unit);
const float sqDist = unit->pos.SqDistance2D(owner->pos);
const bool inLoadingRadius = (sqDist <= Square(owner->unitDef->loadingRadius));
CTransportUnit* trans = static_cast<CTransportUnit*>(owner);
CHoverAirMoveType* am = dynamic_cast<CHoverAirMoveType*>(owner->moveType);
// subtract 1 square to account for PFS/GMT inaccuracy
const bool outOfRange = (goalPos.SqDistance2D(unit->pos) > Square(owner->unitDef->loadingRadius - SQUARE_SIZE));
const bool moveCloser = (!inLoadingRadius && (!owner->IsMoving() || (am != NULL && am->aircraftState != AAirMoveType::AIRCRAFT_FLYING)));
if (outOfRange || moveCloser) {
SetGoal(unit->pos, owner->pos, std::min(64.0f, owner->unitDef->loadingRadius));
}
if (inLoadingRadius) {
if (am != NULL) {
// handle air transports differently
float3 wantedPos = unit->pos;
wantedPos.y = trans->GetTransporteeWantedHeight(wantedPos, unit);
// calls am->StartMoving() which sets forceHeading to false (and also
// changes aircraftState, possibly in mid-pickup) --> must check that
// wantedPos == goalPos using some epsilon tolerance
// we do not want the forceHeading change at point of pickup because
// am->UpdateHeading() will suddenly notice a large deltaHeading and
// break the DOCKING_ANGLE constraint so call am->ForceHeading() next
SetGoal(wantedPos, owner->pos, 1.0f);
am->ForceHeading(trans->GetTransporteeWantedHeading(unit));
am->SetWantedAltitude(wantedPos.y - CGround::GetHeightAboveWater(wantedPos.x, wantedPos.z));
am->maxDrift = 1.0f;
// FIXME: kill the hardcoded constants, use the command's radius
const bool b1 = (owner->pos.SqDistance(wantedPos) < Square(AIRTRANSPORT_DOCKING_RADIUS));
const bool b2 = (std::abs(owner->heading - unit->heading) < AIRTRANSPORT_DOCKING_ANGLE);
const bool b3 = (owner->updir.dot(UpVector) > 0.995f);
if (b1 && b2 && b3) {
am->SetAllowLanding(false);
am->SetWantedAltitude(0.0f);
owner->script->BeginTransport(unit);
SetTransportee(NULL);
transport->AttachUnit(unit, owner->script->QueryTransport(unit));
FinishCommand();
return;
}
} else {
inCommand = true;
StopMove();
owner->script->TransportPickup(unit);
}
} else if (owner->moveType->progressState == AMoveType::Failed && sqDist < (200 * 200)) {
// if we're pretty close already but CGroundMoveType fails because it considers
//.........这里部分代码省略.........