mobilecai.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 1,090 行 · 第 1/3 页
CPP
1,090 行
#include "StdAfx.h"
#include "MobileCAI.h"
#include "TransportCAI.h"
#include "LineDrawer.h"
#include "ExternalAI/Group.h"
#include "Game/GameHelper.h"
#include "Game/SelectedUnits.h"
#include "Game/Team.h"
#include "Game/UI/CommandColors.h"
#include "Game/UI/CursorIcons.h"
#include "Map/Ground.h"
#include "Rendering/GL/myGL.h"
#include "Sim/MoveTypes/MoveType.h"
#include "Sim/MoveTypes/TAAirMoveType.h"
#include "Sim/Units/UnitDef.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitHandler.h"
#include "Sim/Units/UnitTypes/TransportUnit.h"
#include "Sim/Weapons/Weapon.h"
#include "Sim/Weapons/WeaponDefHandler.h"
#include "Sim/Weapons/DGunWeapon.h"
#include "System/LogOutput.h"
#include "myMath.h"
#include "mmgr.h"
CR_BIND_DERIVED(CMobileCAI ,CCommandAI , );
CR_REG_METADATA(CMobileCAI, (
CR_MEMBER(goalPos),
CR_MEMBER(lastUserGoal),
CR_MEMBER(lastIdleCheck),
CR_MEMBER(tempOrder),
CR_MEMBER(lastPC),
CR_MEMBER(maxWantedSpeed),
CR_MEMBER(lastBuggerOffTime),
CR_MEMBER(buggerOffPos),
CR_MEMBER(buggerOffRadius),
CR_MEMBER(commandPos1),
CR_MEMBER(commandPos2),
CR_MEMBER(lastCloseInTry),
CR_MEMBER(cancelDistance),
CR_MEMBER(slowGuard),
CR_MEMBER(moveDir),
CR_RESERVED(16)
));
CMobileCAI::CMobileCAI()
: CCommandAI(),
// patrolTime(0),
goalPos(-1,-1,-1),
tempOrder(false),
lastBuggerOffTime(-200),
buggerOffPos(0,0,0),
buggerOffRadius(0),
maxWantedSpeed(0),
lastIdleCheck(0),
commandPos1(ZeroVector),
commandPos2(ZeroVector),
lastPC(-1),
cancelDistance(1024),
lastCloseInTry(-1),
slowGuard(false),
moveDir(gs->randFloat() > 0.5),
lastUserGoal(0,0,0)
{}
CMobileCAI::CMobileCAI(CUnit* owner)
: CCommandAI(owner),
// patrolTime(0),
goalPos(-1,-1,-1),
tempOrder(false),
lastBuggerOffTime(-200),
buggerOffPos(0,0,0),
buggerOffRadius(0),
maxWantedSpeed(0),
lastIdleCheck(0),
commandPos1(ZeroVector),
commandPos2(ZeroVector),
lastPC(-1),
cancelDistance(1024),
lastCloseInTry(-1),
slowGuard(false),
moveDir(gs->randFloat() > 0.5),
lastUserGoal(owner->pos)
{
CommandDescription c;
c.id=CMD_LOAD_ONTO;
c.action="loadonto";
c.type=CMDTYPE_ICON_UNIT;
c.name="Load units";
c.mouseicon=c.name;
c.hotkey="";
c.tooltip="Sets the unit to load itself onto a transport";
c.onlyKey = true;
possibleCommands.push_back(c);
c.onlyKey = false;
if (owner->unitDef->canmove) {
c.id=CMD_MOVE;
c.action="move";
c.type=CMDTYPE_ICON_FRONT;
c.name="Move";
c.mouseicon=c.name;
c.hotkey="m";
c.tooltip="Move: Order the unit to move to a position";
c.params.push_back("1000000"); // max distance
possibleCommands.push_back(c);
c.params.clear();
}
if(owner->unitDef->canPatrol){
c.id=CMD_PATROL;
c.action="patrol";
c.type=CMDTYPE_ICON_MAP;
c.name="Patrol";
c.mouseicon=c.name;
c.hotkey="p";
c.tooltip="Patrol: Order the unit to patrol to one or more waypoints";
possibleCommands.push_back(c);
c.params.clear();
}
if (owner->unitDef->canFight) {
c.id = CMD_FIGHT;
c.action="fight";
c.type = CMDTYPE_ICON_FRONT;
c.name = "Fight";
c.mouseicon=c.name;
c.hotkey = "f";
c.tooltip = "Fight: Order the unit to take action while moving to a position";
possibleCommands.push_back(c);
}
if(owner->unitDef->canGuard){
c.id=CMD_GUARD;
c.action="guard";
c.type=CMDTYPE_ICON_UNIT;
c.name="Guard";
c.mouseicon=c.name;
c.hotkey="g";
c.tooltip="Guard: Order a unit to guard another unit and attack units attacking it";
possibleCommands.push_back(c);
}
if(owner->unitDef->canfly){
c.params.clear();
c.id=CMD_AUTOREPAIRLEVEL;
c.action="autorepairlevel";
c.type=CMDTYPE_ICON_MODE;
c.name="Repair level";
c.mouseicon=c.name;
c.params.push_back("1");
c.params.push_back("LandAt 0");
c.params.push_back("LandAt 30");
c.params.push_back("LandAt 50");
c.params.push_back("LandAt 80");
c.tooltip=
"Repair level: Sets at which health level an aircraft will try to find a repair pad";
c.hotkey="";
possibleCommands.push_back(c);
nonQueingCommands.insert(CMD_AUTOREPAIRLEVEL);
c.params.clear();
c.id=CMD_IDLEMODE;
c.action="idlemode";
c.type=CMDTYPE_ICON_MODE;
c.name="Land mode";
c.mouseicon=c.name;
c.params.push_back("1");
c.params.push_back(" Fly ");
c.params.push_back("Land");
c.tooltip="Land mode: Sets what aircraft will do on idle";
c.hotkey="";
possibleCommands.push_back(c);
nonQueingCommands.insert(CMD_IDLEMODE);
}
nonQueingCommands.insert(CMD_SET_WANTED_MAX_SPEED);
}
CMobileCAI::~CMobileCAI()
{
}
void CMobileCAI::GiveCommandReal(const Command &c)
{
if (!AllowedCommand(c))
return;
if(owner->unitDef->canfly && c.id==CMD_AUTOREPAIRLEVEL){
if (c.params.empty()) {
return;
}
CTAAirMoveType* airMT;
if (owner->usingScriptMoveType) {
if(!dynamic_cast<CTAAirMoveType*>(owner->prevMoveType))
return;
airMT = (CTAAirMoveType*)owner->prevMoveType;
} else {
if(!dynamic_cast<CTAAirMoveType*>(owner->moveType))
return;
airMT = (CTAAirMoveType*)owner->moveType;
}
switch((int)c.params[0]){
case 0: { airMT->repairBelowHealth = 0.0f; break; }
case 1: { airMT->repairBelowHealth = 0.3f; break; }
case 2: { airMT->repairBelowHealth = 0.5f; break; }
case 3: { airMT->repairBelowHealth = 0.8f; break; }
}
for(vector<CommandDescription>::iterator cdi = possibleCommands.begin();
cdi != possibleCommands.end(); ++cdi){
if(cdi->id==CMD_AUTOREPAIRLEVEL){
char t[10];
SNPRINTF(t,10,"%d", (int)c.params[0]);
cdi->params[0]=t;
break;
}
}
selectedUnits.PossibleCommandChange(owner);
return;
}
if(owner->unitDef->canfly && c.id==CMD_IDLEMODE){
if (c.params.empty()) {
return;
}
CTAAirMoveType* airMT;
if (owner->usingScriptMoveType) {
if(!dynamic_cast<CTAAirMoveType*>(owner->prevMoveType))
return;
airMT = (CTAAirMoveType*)owner->prevMoveType;
} else {
if(!dynamic_cast<CTAAirMoveType*>(owner->moveType))
return;
airMT = (CTAAirMoveType*)owner->moveType;
}
switch((int)c.params[0]){
case 0: { airMT->autoLand = false; break; }
case 1: { airMT->autoLand = true; break; }
}
for(vector<CommandDescription>::iterator cdi = possibleCommands.begin();
cdi != possibleCommands.end(); ++cdi){
if(cdi->id==CMD_IDLEMODE){
char t[10];
SNPRINTF(t,10,"%d", (int)c.params[0]);
cdi->params[0]=t;
break;
}
}
selectedUnits.PossibleCommandChange(owner);
return;
}
if(!(c.options & SHIFT_KEY) && nonQueingCommands.find(c.id)==nonQueingCommands.end()){
tempOrder=false;
StopSlowGuard();
}
CCommandAI::GiveAllowedCommand(c);
}
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,
owner->unitDef->minAirBasePower);
if(lp){
myPlane->AddDeathDependence(lp);
myPlane->reservedPad=lp;
myPlane->padStatus=0;
myPlane->oldGoalPos=myPlane->goalPos;
return;
}
float3 landingPos = airBaseHandler->FindClosestAirBasePos(owner,
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,
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();
// }
//the attack order could terminate directly and thus cause a loop
if(commandQue.empty() || commandQue.front().id == CMD_ATTACK) {
return;
}
}
// treat any following CMD_SET_WANTED_MAX_SPEED commands as options
// to the current command (and ignore them when it's their turn
if (commandQue.size() >= 2 && !slowGuard) {
CCommandQueue::iterator it = commandQue.begin();
it++;
const Command& c = *it;
if ((c.id == CMD_SET_WANTED_MAX_SPEED) && (c.params.size() >= 1)) {
const float defMaxSpeed = owner->maxSpeed;
const float newMaxSpeed = min(c.params[0], defMaxSpeed);
if (newMaxSpeed > 0)
owner->moveType->SetMaxSpeed(newMaxSpeed);
}
}
Execute();
}
/**
* @brief Executes the first command in the commandQue
*/
void CMobileCAI::Execute()
{
Command& c = commandQue.front();
switch (c.id) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?