fixing bots
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@6023 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
+15
-15
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// C++ Implementation: bot
|
||||
//
|
||||
// Description: Main bot code for Action Cube
|
||||
// Description: Main bot code for AssaultCube
|
||||
//
|
||||
// Main bot file
|
||||
//
|
||||
@@ -23,14 +23,14 @@ extern void spawnstate(playerent *d);
|
||||
|
||||
void CACBot::Spawn()
|
||||
{
|
||||
// Init all bot variabeles
|
||||
m_pMyEnt->nextprimary = 2 + rnd(4);
|
||||
m_pMyEnt->targetyaw = m_pMyEnt->targetpitch = 0.0f;
|
||||
m_pMyEnt->pBot = this;
|
||||
// Init all bot variabeles
|
||||
m_pMyEnt->nextprimary = 2 + rnd(5); // 2011jan18:ft: 2 == GUN_RIFLE, GUN_SHOTGUN, GUN_SUBGUN, GUN_SNIPER, GUN_ASSAULT - if CPISTOL is activated this needs a FIXME to rnd(6)
|
||||
m_pMyEnt->targetyaw = m_pMyEnt->targetpitch = 0.0f;
|
||||
m_pMyEnt->pBot = this;
|
||||
|
||||
spawnplayer(m_pMyEnt);
|
||||
|
||||
m_eCurrentBotState = STATE_NORMAL;
|
||||
spawnplayer(m_pMyEnt);
|
||||
|
||||
m_eCurrentBotState = STATE_NORMAL;
|
||||
m_iShootDelay = m_iChangeWeaponDelay = 0;
|
||||
m_iCheckEnvDelay = 0;
|
||||
m_vPrevOrigin = g_vecZero;
|
||||
@@ -39,7 +39,7 @@ void CACBot::Spawn()
|
||||
m_iStuckTime = 0;
|
||||
m_iStrafeTime = m_iStrafeCheckDelay = 0;
|
||||
m_iMoveDir = DIR_NONE;
|
||||
|
||||
|
||||
m_pPrevEnemy = NULL;
|
||||
m_iCombatNavTime = 0;
|
||||
m_iSPMoveTime = 0;
|
||||
@@ -52,27 +52,27 @@ void CACBot::Spawn()
|
||||
m_pHuntTarget = NULL;
|
||||
m_fPrevHuntDist = 0.0f;
|
||||
m_iHuntLastTurnLessTime = m_iHuntPlayerUpdateTime = m_iHuntPauseTime = 0;
|
||||
|
||||
|
||||
m_iLastJumpPad = 0;
|
||||
m_pTargetEnt = NULL;
|
||||
m_iCheckTeleporterDelay = m_iCheckJumppadsDelay = 0;
|
||||
m_iCheckEntsDelay = 0;
|
||||
m_iCheckTriggersDelay = 0;
|
||||
m_iLookForWaypointTime = 0;
|
||||
|
||||
|
||||
m_iAimDelay = 0;
|
||||
m_fYawToTurn = m_fPitchToTurn = 0.0f;
|
||||
|
||||
|
||||
m_vGoal = m_vWaterGoal = g_vecZero;
|
||||
|
||||
|
||||
ResetWaypointVars();
|
||||
}
|
||||
|
||||
void CACBot::CheckItemPickup()
|
||||
{
|
||||
checkitems(m_pMyEnt);
|
||||
checkitems(m_pMyEnt);
|
||||
}
|
||||
|
||||
|
||||
// AC Bot class end
|
||||
|
||||
#endif
|
||||
|
||||
+12
-1
@@ -37,7 +37,18 @@ public:
|
||||
};
|
||||
|
||||
inline void AddScreenText(const char *t, ...) {} // UNDONE
|
||||
inline void AddDebugText(const char *t, ...) {} // UNDONE
|
||||
inline void AddDebugText(const char *t, ...)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
va_list v;
|
||||
va_start(v, t);
|
||||
conoutf(t,v);
|
||||
va_end(v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+73
-92
@@ -1,7 +1,7 @@
|
||||
//
|
||||
// C++ Implementation: bot
|
||||
//
|
||||
// Description:
|
||||
// Description:
|
||||
//
|
||||
// Contains code of the base bot class
|
||||
//
|
||||
@@ -38,14 +38,14 @@ CBot::~CBot()
|
||||
|
||||
void CBot::Spawn()
|
||||
{
|
||||
// Init all bot variabeles
|
||||
spawnplayer(m_pMyEnt);
|
||||
|
||||
// Init all bot variabeles
|
||||
spawnplayer(m_pMyEnt);
|
||||
|
||||
m_pMyEnt->targetyaw = m_pMyEnt->targetpitch = 0.0f;
|
||||
m_pMyEnt->enemy = NULL;
|
||||
m_pMyEnt->maxspeed = 22.0f;
|
||||
m_pMyEnt->pBot = this;
|
||||
|
||||
m_pMyEnt->pBot = this;
|
||||
|
||||
m_eCurrentBotState = STATE_NORMAL;
|
||||
m_iShootDelay = m_iChangeWeaponDelay = 0;
|
||||
m_iCheckEnvDelay = 0;
|
||||
@@ -55,7 +55,7 @@ void CBot::Spawn()
|
||||
m_iStuckTime = 0;
|
||||
m_iStrafeTime = m_iStrafeCheckDelay = 0;
|
||||
m_iMoveDir = DIR_NONE;
|
||||
|
||||
|
||||
m_pPrevEnemy = NULL;
|
||||
m_iCombatNavTime = 0;
|
||||
m_iSPMoveTime = 0;
|
||||
@@ -72,7 +72,7 @@ void CBot::Spawn()
|
||||
m_iLookAroundDelay = m_iLookAroundTime = m_iLookAroundUpdateTime = 0;
|
||||
m_fLookAroundYaw = 0.0f;
|
||||
m_bLookLeft = false;
|
||||
|
||||
|
||||
m_iLastJumpPad = 0;
|
||||
m_pTargetEnt = NULL;
|
||||
while(!m_UnreachableEnts.Empty()) delete m_UnreachableEnts.Pop();
|
||||
@@ -80,75 +80,56 @@ void CBot::Spawn()
|
||||
m_iCheckEntsDelay = 0;
|
||||
m_iCheckTriggersDelay = 0;
|
||||
m_iLookForWaypointTime = 0;
|
||||
|
||||
|
||||
m_iAimDelay = 0;
|
||||
m_fYawToTurn = m_fPitchToTurn = 0.0f;
|
||||
|
||||
|
||||
m_vGoal = m_vWaterGoal = g_vecZero;
|
||||
|
||||
|
||||
ResetWaypointVars();
|
||||
}
|
||||
|
||||
void CBot::Think()
|
||||
{
|
||||
if (intermission)
|
||||
return;
|
||||
|
||||
// Bot is dead?
|
||||
if (m_pMyEnt->state == CS_DEAD)
|
||||
{
|
||||
if(lastmillis-m_pMyEnt->respawnoffset<1200)
|
||||
{
|
||||
m_pMyEnt->move = 0;
|
||||
moveplayer(m_pMyEnt, 1, true);
|
||||
}
|
||||
else if (!m_arena && lastmillis-m_pMyEnt->respawnoffset>5000)
|
||||
Spawn();
|
||||
|
||||
SendBotInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
CheckItemPickup();
|
||||
|
||||
TLinkedList<unreachable_ent_s*>::node_s *p = m_UnreachableEnts.GetFirst(), *tmp;
|
||||
while(p)
|
||||
{
|
||||
if ((lastmillis - p->Entry->time) > 3500)
|
||||
{
|
||||
tmp = p;
|
||||
p = p->next;
|
||||
delete tmp->Entry;
|
||||
m_UnreachableEnts.DeleteNode(tmp);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
|
||||
if (!BotManager.IdleBots())
|
||||
{
|
||||
MainAI();
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetMoveSpeed();
|
||||
}
|
||||
|
||||
// Aim to ideal yaw and pitch
|
||||
AimToIdeal();
|
||||
|
||||
// Store current location, to see if the bot is stuck
|
||||
m_vPrevOrigin = m_pMyEnt->o;
|
||||
|
||||
// Don't check for stuck if the bot doesn't want to move
|
||||
if (!m_pMyEnt->move && !m_pMyEnt->strafe)
|
||||
m_iStuckCheckDelay = max(m_iStuckCheckDelay, lastmillis+100.0f);
|
||||
|
||||
// Move the bot
|
||||
moveplayer(m_pMyEnt, 1, true);
|
||||
|
||||
// Update bot info on all clients
|
||||
SendBotInfo();
|
||||
if (intermission) return;
|
||||
// Bot is dead?
|
||||
if (m_pMyEnt->state == CS_DEAD)
|
||||
{
|
||||
if(lastmillis-m_pMyEnt->respawnoffset<1200)
|
||||
{
|
||||
m_pMyEnt->move = 0;
|
||||
moveplayer(m_pMyEnt, 1, true);
|
||||
}
|
||||
else if (!m_arena && lastmillis-m_pMyEnt->respawnoffset>5000) Spawn();
|
||||
SendBotInfo();
|
||||
return;
|
||||
}
|
||||
CheckItemPickup();
|
||||
TLinkedList<unreachable_ent_s*>::node_s *p = m_UnreachableEnts.GetFirst(), *tmp;
|
||||
while(p)
|
||||
{
|
||||
if ((lastmillis - p->Entry->time) > 3500)
|
||||
{
|
||||
tmp = p;
|
||||
p = p->next;
|
||||
delete tmp->Entry;
|
||||
m_UnreachableEnts.DeleteNode(tmp);
|
||||
continue;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
if (!BotManager.IdleBots()) { MainAI(); }
|
||||
else { ResetMoveSpeed(); }
|
||||
// Aim to ideal yaw and pitch
|
||||
AimToIdeal();
|
||||
// Store current location, to see if the bot is stuck
|
||||
m_vPrevOrigin = m_pMyEnt->o;
|
||||
// Don't check for stuck if the bot doesn't want to move
|
||||
if (!m_pMyEnt->move && !m_pMyEnt->strafe) m_iStuckCheckDelay = max(m_iStuckCheckDelay, lastmillis+100.0f);
|
||||
// Move the bot
|
||||
moveplayer(m_pMyEnt, 1, true);
|
||||
// Update bot info on all clients
|
||||
SendBotInfo();
|
||||
}
|
||||
|
||||
void CBot::AimToVec(const vec &o)
|
||||
@@ -177,7 +158,7 @@ void CBot::AimToIdeal()
|
||||
float YDiff = fabs(m_pMyEnt->targetyaw - m_pMyEnt->yaw);
|
||||
|
||||
// How higher the diff, how higher the offsets and aim speed
|
||||
|
||||
|
||||
if (XOffset)
|
||||
{
|
||||
if (RandomLong(0, 1))
|
||||
@@ -198,7 +179,7 @@ void CBot::AimToIdeal()
|
||||
else
|
||||
RealYOffset = 0.0f;
|
||||
|
||||
|
||||
|
||||
if (XDiff >= 1.0f)
|
||||
AimXSpeed = (AimXSpeed * (XDiff / 80.0f)) + (AimXSpeed * 0.25f);
|
||||
else
|
||||
@@ -211,16 +192,16 @@ void CBot::AimToIdeal()
|
||||
|
||||
m_fPitchToTurn = fabs((m_pMyEnt->targetpitch + RealXOffset) - m_pMyEnt->pitch);
|
||||
m_fYawToTurn = fabs((m_pMyEnt->targetyaw + RealYOffset) - m_pMyEnt->yaw);
|
||||
|
||||
|
||||
float flIdealPitch = ChangeAngle(AimXSpeed, m_pMyEnt->targetpitch + RealXOffset, m_pMyEnt->pitch);
|
||||
float flIdealYaw = ChangeAngle(AimYSpeed, m_pMyEnt->targetyaw + RealYOffset, m_pMyEnt->yaw);
|
||||
|
||||
|
||||
// m_pMyEnt->pitch = WrapXAngle(m_pMyEnt->targetpitch); // Uncomment for instant aiming
|
||||
// m_pMyEnt->yaw = WrapYZAngle(m_pMyEnt->targetyaw);
|
||||
|
||||
|
||||
m_pMyEnt->pitch = WrapXAngle(flIdealPitch);
|
||||
m_pMyEnt->yaw = WrapYZAngle(flIdealYaw);
|
||||
}
|
||||
m_pMyEnt->yaw = WrapYZAngle(flIdealYaw);
|
||||
}
|
||||
|
||||
// Function code by Botman
|
||||
float CBot::ChangeAngle(float speed, float ideal, float current)
|
||||
@@ -230,7 +211,7 @@ float CBot::ChangeAngle(float speed, float ideal, float current)
|
||||
|
||||
// find the difference in the current and ideal angle
|
||||
diff = fabs(current - ideal);
|
||||
|
||||
|
||||
// speed that we can turn during this frame...
|
||||
speed = speed * (float(BotManager.m_iFrameTime)/1000.0f);
|
||||
|
||||
@@ -241,7 +222,7 @@ float CBot::ChangeAngle(float speed, float ideal, float current)
|
||||
// check if the bot is already facing the idealpitch direction...
|
||||
if (diff <= 1.0f)
|
||||
return ideal;
|
||||
|
||||
|
||||
if ((current >= 180) && (ideal >= 180))
|
||||
{
|
||||
if (current > ideal)
|
||||
@@ -261,7 +242,7 @@ float CBot::ChangeAngle(float speed, float ideal, float current)
|
||||
else if ((current < 180) && (ideal >= 180))
|
||||
{
|
||||
current_180 = current + 180;
|
||||
|
||||
|
||||
if (current_180 > ideal)
|
||||
current += speed;
|
||||
else
|
||||
@@ -276,7 +257,7 @@ float CBot::ChangeAngle(float speed, float ideal, float current)
|
||||
}
|
||||
|
||||
|
||||
return current;
|
||||
return current;
|
||||
}
|
||||
|
||||
void CBot::SendBotInfo()
|
||||
@@ -303,7 +284,7 @@ float CBot::GetDistance(entity *e)
|
||||
|
||||
bool CBot::SelectGun(int Gun)
|
||||
{
|
||||
if(m_pMyEnt->weaponsel->reloading) return false;
|
||||
if(m_pMyEnt->weaponsel->reloading) return false;
|
||||
if (m_pMyEnt->gunselect != Gun) audiomgr.playsound(S_GUNCHANGE, m_pMyEnt);
|
||||
m_pMyEnt->gunselect = Gun;
|
||||
return true;
|
||||
@@ -319,21 +300,21 @@ bool CBot::IsVisible(vec o, int Dir, float flDist, bool CheckPlayers, float *pEn
|
||||
{
|
||||
static vec angles, end, forward, right, up;
|
||||
static traceresult_s tr;
|
||||
|
||||
|
||||
end = o;
|
||||
angles = GetViewAngles();
|
||||
angles.x = 0;
|
||||
|
||||
|
||||
if (Dir & UP)
|
||||
angles.x = WrapXAngle(angles.x + 45.0f);
|
||||
else if (Dir & DOWN)
|
||||
angles.x = WrapXAngle(angles.x - 45.0f);
|
||||
|
||||
|
||||
if ((Dir & FORWARD) || (Dir & BACKWARD))
|
||||
{
|
||||
if (Dir & BACKWARD)
|
||||
angles.y = WrapYZAngle(angles.y + 180.0f);
|
||||
|
||||
|
||||
if (Dir & LEFT)
|
||||
{
|
||||
if (Dir & FORWARD)
|
||||
@@ -357,17 +338,17 @@ bool CBot::IsVisible(vec o, int Dir, float flDist, bool CheckPlayers, float *pEn
|
||||
angles.x = WrapXAngle(angles.x + 90.0f);
|
||||
else if (Dir & DOWN)
|
||||
angles.x = WrapXAngle(angles.x - 90.0f);
|
||||
|
||||
|
||||
AnglesToVectors(angles, forward, right, up);
|
||||
|
||||
|
||||
forward.mul(flDist);
|
||||
end.add(forward);
|
||||
|
||||
|
||||
TraceLine(o, end, m_pMyEnt, CheckPlayers, &tr);
|
||||
|
||||
|
||||
if (pEndDist)
|
||||
*pEndDist = GetDistance(o, tr.end);
|
||||
|
||||
|
||||
return !tr.collided;
|
||||
}
|
||||
|
||||
@@ -386,7 +367,7 @@ void CBot::SetMoveDir(int iMoveDir, bool add)
|
||||
m_pMyEnt->strafe = -1;
|
||||
else if (!add)
|
||||
m_pMyEnt->strafe = 0;
|
||||
|
||||
|
||||
if (iMoveDir & UP)
|
||||
m_pMyEnt->jumpnext = true;
|
||||
}
|
||||
@@ -419,5 +400,5 @@ void CBot::ResetCurrentTask()
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Bot class end
|
||||
|
||||
@@ -241,7 +241,8 @@ public:
|
||||
|
||||
// AI Functions
|
||||
bool FindEnemy(void);
|
||||
void CheckReload(void);
|
||||
void CheckReload(void);
|
||||
void CheckWeaponSwitch(void); // 2011jan17:ft: fix non-shooting bots
|
||||
void ShootEnemy(void);
|
||||
bool CheckHunt(void);
|
||||
bool HuntEnemy(void);
|
||||
|
||||
+342
-325
File diff suppressed because it is too large
Load Diff
+88
-118
@@ -50,61 +50,51 @@ void CBotManager::Init()
|
||||
|
||||
void CBotManager::Think()
|
||||
{
|
||||
if (m_bInit)
|
||||
{
|
||||
Init();
|
||||
m_bInit = false;
|
||||
}
|
||||
if (m_bInit)
|
||||
{
|
||||
Init();
|
||||
m_bInit = false;
|
||||
}
|
||||
if (m_pBotToView) ViewBot();
|
||||
AddDebugText("m_sMaxAStarBots: %d", m_sMaxAStarBots);
|
||||
AddDebugText("m_sCurrentTriggerNr: %d", m_sCurrentTriggerNr);
|
||||
short x, y;
|
||||
WaypointClass.GetNodeIndexes(player1->o, &x, &y);
|
||||
AddDebugText("x: %d y: %d", x, y);
|
||||
|
||||
if (m_pBotToView)
|
||||
ViewBot();
|
||||
m_iFrameTime = lastmillis - m_iPrevTime;
|
||||
if (m_iFrameTime > 250) m_iFrameTime = 250;
|
||||
m_iPrevTime = lastmillis;
|
||||
|
||||
AddDebugText("m_sMaxAStarBots: %d", m_sMaxAStarBots);
|
||||
AddDebugText("m_sCurrentTriggerNr: %d", m_sCurrentTriggerNr);
|
||||
short x, y;
|
||||
WaypointClass.GetNodeIndexes(player1->o, &x, &y);
|
||||
AddDebugText("x: %d y: %d", x, y);
|
||||
|
||||
m_iFrameTime = lastmillis - m_iPrevTime;
|
||||
if (m_iFrameTime > 250) m_iFrameTime = 250;
|
||||
m_iPrevTime = lastmillis;
|
||||
|
||||
// Is it time to re-add bots?
|
||||
if ((m_fReAddBotDelay < lastmillis) && (m_fReAddBotDelay != -1.0f))
|
||||
{
|
||||
while(m_StoredBots.Empty() == false)
|
||||
{
|
||||
CStoredBot *pStoredBot = m_StoredBots.Pop();
|
||||
ReAddBot(pStoredBot);
|
||||
delete pStoredBot;
|
||||
}
|
||||
|
||||
m_fReAddBotDelay = -1.0f;
|
||||
}
|
||||
|
||||
// If this is a ded server check if there are any players, if not bots should be idle
|
||||
if (dedserv)
|
||||
{
|
||||
bool botsbeidle = true;
|
||||
loopv(players)
|
||||
{
|
||||
if (players[i] && (players[i]->state != CS_DEDHOST)) { botsbeidle = false; break; }
|
||||
}
|
||||
|
||||
if (botsbeidle) return;
|
||||
}
|
||||
|
||||
// Let all bots 'think'
|
||||
loopv(bots)
|
||||
{
|
||||
if (!bots[i])
|
||||
continue;
|
||||
|
||||
if (bots[i]->pBot)
|
||||
bots[i]->pBot->Think();
|
||||
else
|
||||
condebug("Error: pBot == NULL in bot ent\n");
|
||||
}
|
||||
// Is it time to re-add bots?
|
||||
if ((m_fReAddBotDelay < lastmillis) && (m_fReAddBotDelay != -1.0f))
|
||||
{
|
||||
while(m_StoredBots.Empty() == false)
|
||||
{
|
||||
CStoredBot *pStoredBot = m_StoredBots.Pop();
|
||||
ReAddBot(pStoredBot);
|
||||
delete pStoredBot;
|
||||
}
|
||||
m_fReAddBotDelay = -1.0f;
|
||||
}
|
||||
// If this is a ded server check if there are any players, if not bots should be idle
|
||||
if (dedserv)
|
||||
{
|
||||
bool botsbeidle = true;
|
||||
loopv(players) { if (players[i] && (players[i]->state != CS_DEDHOST)) { botsbeidle = false; break; } }
|
||||
if (botsbeidle) return;
|
||||
}
|
||||
// Let all bots 'think'
|
||||
loopv(bots)
|
||||
{
|
||||
if (!bots[i]) continue;
|
||||
if (bots[i]->pBot)
|
||||
{
|
||||
bots[i]->pBot->CheckWeaponSwitch(); // 2011jan17:ft: fix non-shooting bots
|
||||
bots[i]->pBot->Think();
|
||||
}
|
||||
else condebug("Error: pBot == NULL in bot ent\n");
|
||||
}
|
||||
}
|
||||
|
||||
void CBotManager::LoadBotNamesFile()
|
||||
@@ -894,72 +884,60 @@ void CBotManager::PickNextTrigger()
|
||||
|
||||
botent *CBotManager::CreateBot(const char *team, const char *skill, const char *name)
|
||||
{
|
||||
if (m_bInit)
|
||||
{
|
||||
Init();
|
||||
m_bInit = false;
|
||||
}
|
||||
if (m_bInit)
|
||||
{
|
||||
Init();
|
||||
m_bInit = false;
|
||||
}
|
||||
|
||||
botent *m = newbotent();
|
||||
if (!m) return NULL;
|
||||
loopi(NUMGUNS) m->ammo[i] = m->mag[i] = 0;
|
||||
loopi(NUMGUNS) m->ammo[i] = m->mag[i] = 0;
|
||||
m->lifesequence = 0;
|
||||
setskin(m, rnd(6));
|
||||
setskin(m, rnd(6));
|
||||
// Create new bot class, dependand on the current mod
|
||||
#if defined VANILLA_CUBE
|
||||
m->pBot = new CCubeBot;
|
||||
m->pBot = new CCubeBot;
|
||||
#elif defined AC_CUBE
|
||||
m->pBot = new CACBot;
|
||||
m->pBot = new CACBot;
|
||||
#else
|
||||
#error "Unsupported mod!"
|
||||
#error "Unsupported mod!"
|
||||
#endif
|
||||
m->type = ENT_BOT;
|
||||
m->pBot->m_pMyEnt = m;
|
||||
m->pBot->m_iLastBotUpdate = 0;
|
||||
m->pBot->m_bSendC2SInit = false;
|
||||
m->type = ENT_BOT;
|
||||
m->pBot->m_pMyEnt = m;
|
||||
m->pBot->m_iLastBotUpdate = 0;
|
||||
m->pBot->m_bSendC2SInit = false;
|
||||
|
||||
if (name && *name)
|
||||
copystring(m->name, name, 16);
|
||||
else
|
||||
copystring(m->name, BotManager.GetBotName(), 16);
|
||||
if (name && *name) copystring(m->name, name, 16);
|
||||
else copystring(m->name, BotManager.GetBotName(), 16);
|
||||
|
||||
const char *tempteam = team && *team && strcmp(team, "random") ? team : BotManager.GetBotTeam();
|
||||
m->team = TEAM_SPECT;
|
||||
loopi(TEAM_NUM) if(!strcmp(teamnames[i], tempteam)) { m->team = i; break; }
|
||||
const char *tempteam = team && *team && strcmp(team, "random") ? team : BotManager.GetBotTeam();
|
||||
m->team = TEAM_SPECT;
|
||||
loopi(TEAM_NUM) if(!strcmp(teamnames[i], tempteam)) { m->team = i; break; }
|
||||
|
||||
if (skill && *skill && strcmp(skill, "random"))
|
||||
{
|
||||
if (!strcasecmp(skill, "best"))
|
||||
m->pBot->m_sSkillNr = 0;
|
||||
else if (!strcasecmp(skill, "good"))
|
||||
m->pBot->m_sSkillNr = 1;
|
||||
else if (!strcasecmp(skill, "medium"))
|
||||
m->pBot->m_sSkillNr = 2;
|
||||
else if (!strcasecmp(skill, "worse"))
|
||||
m->pBot->m_sSkillNr = 3;
|
||||
else if (!strcasecmp(skill, "bad"))
|
||||
m->pBot->m_sSkillNr = 4;
|
||||
else
|
||||
{
|
||||
conoutf("Wrong skill specified. Should be best, good, medium, "
|
||||
"worse or bad");
|
||||
conoutf("Using default skill instead...");
|
||||
m->pBot->m_sSkillNr = BotManager.m_sBotSkill;
|
||||
}
|
||||
}
|
||||
else // No skill specified, use default
|
||||
m->pBot->m_sSkillNr = BotManager.m_sBotSkill;
|
||||
|
||||
m->pBot->m_pBotSkill = &BotManager.m_BotSkills[m->pBot->m_sSkillNr];
|
||||
|
||||
// Sync waypoints
|
||||
m->pBot->SyncWaypoints();
|
||||
|
||||
m->pBot->Spawn();
|
||||
|
||||
bots.add(m);
|
||||
|
||||
return m;
|
||||
if (skill && *skill && strcmp(skill, "random"))
|
||||
{
|
||||
if (!strcasecmp(skill, "best")) m->pBot->m_sSkillNr = 0;
|
||||
else if (!strcasecmp(skill, "good")) m->pBot->m_sSkillNr = 1;
|
||||
else if (!strcasecmp(skill, "medium")) m->pBot->m_sSkillNr = 2;
|
||||
else if (!strcasecmp(skill, "worse")) m->pBot->m_sSkillNr = 3;
|
||||
else if (!strcasecmp(skill, "bad")) m->pBot->m_sSkillNr = 4;
|
||||
else
|
||||
{
|
||||
conoutf("Wrong skill specified. Should be best, good, medium, "
|
||||
"worse or bad");
|
||||
conoutf("Using default skill instead...");
|
||||
m->pBot->m_sSkillNr = BotManager.m_sBotSkill;
|
||||
}
|
||||
}
|
||||
else // No skill specified, use default
|
||||
m->pBot->m_sSkillNr = BotManager.m_sBotSkill;
|
||||
m->pBot->m_pBotSkill = &BotManager.m_BotSkills[m->pBot->m_sSkillNr];
|
||||
// Sync waypoints
|
||||
m->pBot->SyncWaypoints();
|
||||
m->pBot->Spawn();
|
||||
bots.add(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
bool botmode()
|
||||
@@ -973,19 +951,12 @@ bool botmode()
|
||||
|
||||
void addbot(char *arg1, char *arg2, char *arg3)
|
||||
{
|
||||
if(!botmode()) return;
|
||||
if(!botmode()) return;
|
||||
conoutf("Creating bot...\n");
|
||||
botent *b = BotManager.CreateBot(arg1, arg2, arg3);
|
||||
|
||||
if (b)
|
||||
conoutf("connected: %s", b->name);
|
||||
else
|
||||
{
|
||||
conoutf("Error: Couldn't create bot!");
|
||||
return;
|
||||
}
|
||||
if (b) conoutf("connected: %s", b->name);
|
||||
else { conoutf("Error: Couldn't create bot!"); return; }
|
||||
}
|
||||
|
||||
COMMAND(addbot, ARG_3STR);
|
||||
|
||||
void addnbot(char *arg1, char *arg2, char *arg3)
|
||||
@@ -1001,7 +972,6 @@ void addnbot(char *arg1, char *arg2, char *arg3)
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND(addnbot, ARG_3STR);
|
||||
|
||||
void botsshoot(int Shoot)
|
||||
|
||||
Reference in New Issue
Block a user