mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-15 08:41:59 +00:00
- Fixed: Bots added by different setting controllers could be assigned the same player number.
This commit is contained in:
parent
1c500cead6
commit
1b7c07df65
6 changed files with 111 additions and 72 deletions
|
@ -125,7 +125,7 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
|
|||
bot = bot->next;
|
||||
if (bot)
|
||||
{
|
||||
bot->inuse = false;
|
||||
bot->inuse = BOTINUSE_No;
|
||||
bot->lastteam = keepTeam ? players[i].userinfo.GetTeam() : TEAM_NONE;
|
||||
}
|
||||
if (players[i].Bot != NULL)
|
||||
|
@ -172,7 +172,7 @@ CCMD (listbots)
|
|||
|
||||
while (thebot)
|
||||
{
|
||||
Printf ("%s%s\n", thebot->name, thebot->inuse ? " (active)" : "");
|
||||
Printf ("%s%s\n", thebot->name, thebot->inuse == BOTINUSE_Yes ? " (active)" : "");
|
||||
thebot = thebot->next;
|
||||
count++;
|
||||
}
|
||||
|
|
14
src/b_bot.h
14
src/b_bot.h
|
@ -60,6 +60,13 @@ struct botskill_t
|
|||
|
||||
FArchive &operator<< (FArchive &arc, botskill_t &skill);
|
||||
|
||||
enum
|
||||
{
|
||||
BOTINUSE_No,
|
||||
BOTINUSE_Waiting,
|
||||
BOTINUSE_Yes,
|
||||
};
|
||||
|
||||
//Info about all bots in the bots.cfg
|
||||
//Updated during each level start.
|
||||
//Info given to bots when they're spawned.
|
||||
|
@ -69,7 +76,7 @@ struct botinfo_t
|
|||
char *name;
|
||||
char *info;
|
||||
botskill_t skill;
|
||||
bool inuse;
|
||||
int inuse;
|
||||
int lastteam;
|
||||
};
|
||||
|
||||
|
@ -88,7 +95,7 @@ public:
|
|||
bool SpawnBot (const char *name, int color = NOCOLOR);
|
||||
bool LoadBots ();
|
||||
void ForgetBots ();
|
||||
void DoAddBot (BYTE **stream);
|
||||
void TryAddBot (BYTE **stream, int player);
|
||||
void RemoveAllBots (bool fromlist);
|
||||
void DestroyAllBots ();
|
||||
|
||||
|
@ -122,6 +129,9 @@ public:
|
|||
bool m_Thinking;
|
||||
|
||||
private:
|
||||
//(B_Game.c)
|
||||
bool DoAddBot (BYTE *info, botskill_t skill);
|
||||
|
||||
//(B_Func.c)
|
||||
bool Reachable (AActor *actor, AActor *target);
|
||||
void Dofire (AActor *actor, ticcmd_t *cmd);
|
||||
|
|
159
src/b_game.cpp
159
src/b_game.cpp
|
@ -89,8 +89,6 @@ enum
|
|||
BOTCFG_TEAM
|
||||
};
|
||||
|
||||
static bool waitingforspawn[MAXPLAYERS];
|
||||
|
||||
FCajunMaster::~FCajunMaster()
|
||||
{
|
||||
ForgetBots();
|
||||
|
@ -162,8 +160,6 @@ void FCajunMaster::Main (int buf)
|
|||
|
||||
void FCajunMaster::Init ()
|
||||
{
|
||||
int i;
|
||||
|
||||
botnum = 0;
|
||||
firstthing = NULL;
|
||||
spawn_tries = 0;
|
||||
|
@ -172,11 +168,6 @@ void FCajunMaster::Init ()
|
|||
body1 = NULL;
|
||||
body2 = NULL;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
waitingforspawn[i] = false;
|
||||
}
|
||||
|
||||
if (ctf && teamplay == false)
|
||||
teamplay = true; //Need teamplay for ctf. (which is not done yet)
|
||||
|
||||
|
@ -192,7 +183,7 @@ void FCajunMaster::Init ()
|
|||
|
||||
while (thebot != NULL)
|
||||
{
|
||||
thebot->inuse = false;
|
||||
thebot->inuse = BOTINUSE_No;
|
||||
thebot = thebot->next;
|
||||
}
|
||||
}
|
||||
|
@ -232,12 +223,10 @@ void FCajunMaster::End ()
|
|||
//The color parameter can be either a
|
||||
//color (range from 0-10), or = NOCOLOR.
|
||||
//The color parameter overides bots
|
||||
//induvidual colors if not = NOCOLOR.
|
||||
//individual colors if not = NOCOLOR.
|
||||
|
||||
bool FCajunMaster::SpawnBot (const char *name, int color)
|
||||
{
|
||||
int playernumber;
|
||||
|
||||
//COLORS
|
||||
static const char colors[11][17] =
|
||||
{
|
||||
|
@ -254,36 +243,31 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
"\\color\\cf df 90" //10 = Bleached Bone
|
||||
};
|
||||
|
||||
for (playernumber = 0; playernumber < MAXPLAYERS; playernumber++)
|
||||
{
|
||||
if (!playeringame[playernumber] && !waitingforspawn[playernumber])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (playernumber == MAXPLAYERS)
|
||||
{
|
||||
Printf ("The maximum of %d players/bots has been reached\n", MAXPLAYERS);
|
||||
return false;
|
||||
}
|
||||
|
||||
botinfo_t *thebot;
|
||||
int botshift;
|
||||
|
||||
if (name)
|
||||
{
|
||||
thebot = botinfo;
|
||||
|
||||
// Check if exist or already in the game.
|
||||
botshift = 0;
|
||||
while (thebot && stricmp (name, thebot->name))
|
||||
{
|
||||
thebot = thebot->next;
|
||||
botshift++;
|
||||
}
|
||||
|
||||
if (thebot == NULL)
|
||||
{
|
||||
Printf ("couldn't find %s in %s\n", name, BOTFILENAME);
|
||||
return false;
|
||||
}
|
||||
else if (thebot->inuse)
|
||||
else if (thebot->inuse == BOTINUSE_Waiting)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (thebot->inuse == BOTINUSE_Yes)
|
||||
{
|
||||
Printf ("%s is already in the thick\n", name);
|
||||
return false;
|
||||
|
@ -296,9 +280,13 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
{
|
||||
int rnum = (pr_botspawn() % loaded_bots);
|
||||
thebot = botinfo;
|
||||
botshift = 0;
|
||||
while (rnum)
|
||||
{
|
||||
--rnum, thebot = thebot->next;
|
||||
if (!thebot->inuse)
|
||||
botshift++;
|
||||
}
|
||||
if (thebot->inuse == BOTINUSE_No)
|
||||
vacant = true;
|
||||
}
|
||||
}
|
||||
|
@ -308,10 +296,10 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
return false;
|
||||
}
|
||||
|
||||
waitingforspawn[playernumber] = true;
|
||||
thebot->inuse = BOTINUSE_Waiting;
|
||||
|
||||
Net_WriteByte (DEM_ADDBOT);
|
||||
Net_WriteByte (playernumber);
|
||||
Net_WriteByte (botshift);
|
||||
{
|
||||
//Set color.
|
||||
char concat[512];
|
||||
|
@ -332,61 +320,104 @@ bool FCajunMaster::SpawnBot (const char *name, int color)
|
|||
Net_WriteByte(thebot->skill.reaction);
|
||||
Net_WriteByte(thebot->skill.isp);
|
||||
|
||||
thebot->inuse = true;
|
||||
|
||||
//Increment this.
|
||||
botnum++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FCajunMaster::DoAddBot (BYTE **stream)
|
||||
void FCajunMaster::TryAddBot (BYTE **stream, int player)
|
||||
{
|
||||
int bnum = ReadByte (stream);
|
||||
int botshift = ReadByte (stream);
|
||||
char *info = ReadString (stream);
|
||||
BYTE *infob = (BYTE *)info;
|
||||
botskill_t skill;
|
||||
skill.aiming = ReadByte (stream);
|
||||
skill.perfection = ReadByte (stream);
|
||||
skill.reaction = ReadByte (stream);
|
||||
skill.isp = ReadByte (stream);
|
||||
|
||||
D_ReadUserInfoStrings (bnum, &infob, false);
|
||||
botinfo_t *thebot = NULL;
|
||||
|
||||
if (consoleplayer == player)
|
||||
{
|
||||
thebot = botinfo;
|
||||
|
||||
while (botshift > 0)
|
||||
{
|
||||
thebot = thebot->next;
|
||||
botshift--;
|
||||
}
|
||||
}
|
||||
|
||||
if (DoAddBot ((BYTE *)info, skill))
|
||||
{
|
||||
if (consoleplayer == Net_Arbitrator)
|
||||
{
|
||||
//Increment this.
|
||||
botnum++;
|
||||
}
|
||||
|
||||
if (thebot != NULL)
|
||||
{
|
||||
thebot->inuse = BOTINUSE_Yes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thebot != NULL)
|
||||
{
|
||||
thebot->inuse = BOTINUSE_No;
|
||||
}
|
||||
}
|
||||
|
||||
delete[] info;
|
||||
}
|
||||
|
||||
bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill)
|
||||
{
|
||||
int bnum;
|
||||
|
||||
for (bnum = 0; bnum < MAXPLAYERS; bnum++)
|
||||
{
|
||||
if (!playeringame[bnum])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bnum == MAXPLAYERS)
|
||||
{
|
||||
Printf ("The maximum of %d players/bots has been reached\n", MAXPLAYERS);
|
||||
return false;
|
||||
}
|
||||
|
||||
D_ReadUserInfoStrings (bnum, &info, false);
|
||||
|
||||
if (!deathmatch && playerstarts[bnum].type == 0)
|
||||
{
|
||||
Printf ("%s tried to join, but there was no player %d start\n",
|
||||
players[bnum].userinfo.GetName(), bnum+1);
|
||||
ClearPlayer (bnum, false); // Make the bot inactive again
|
||||
if (botnum > 0)
|
||||
{
|
||||
botnum--;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
|
||||
players[bnum].Bot = new DBot;
|
||||
GC::WriteBarrier (players[bnum].Bot);
|
||||
players[bnum].Bot->skill = skill;
|
||||
playeringame[bnum] = true;
|
||||
players[bnum].mo = NULL;
|
||||
players[bnum].playerstate = PST_ENTER;
|
||||
|
||||
if (teamplay)
|
||||
Printf ("%s joined the %s team\n", players[bnum].userinfo.GetName(), Teams[players[bnum].userinfo.GetTeam()].GetName());
|
||||
else
|
||||
Printf ("%s joined the game\n", players[bnum].userinfo.GetName());
|
||||
|
||||
G_DoReborn (bnum, true);
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost).
|
||||
players[bnum].Bot = new DBot;
|
||||
GC::WriteBarrier (players[bnum].Bot);
|
||||
players[bnum].Bot->skill = skill;
|
||||
playeringame[bnum] = true;
|
||||
players[bnum].mo = NULL;
|
||||
players[bnum].playerstate = PST_ENTER;
|
||||
|
||||
if (teamplay)
|
||||
Printf ("%s joined the %s team\n", players[bnum].userinfo.GetName(), Teams[players[bnum].userinfo.GetTeam()].GetName());
|
||||
else
|
||||
Printf ("%s joined the game\n", players[bnum].userinfo.GetName());
|
||||
|
||||
G_DoReborn (bnum, true);
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->MultiplayerChanged ();
|
||||
}
|
||||
StatusBar->MultiplayerChanged ();
|
||||
}
|
||||
waitingforspawn[bnum] = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FCajunMaster::RemoveAllBots (bool fromlist)
|
||||
|
@ -421,8 +452,6 @@ void FCajunMaster::RemoveAllBots (bool fromlist)
|
|||
if (fromlist)
|
||||
{
|
||||
wanted_botnum = 0;
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
waitingforspawn[i] = false;
|
||||
}
|
||||
botnum = 0;
|
||||
}
|
||||
|
|
|
@ -2250,7 +2250,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
|
|||
break;
|
||||
|
||||
case DEM_ADDBOT:
|
||||
bglobal.DoAddBot (stream);
|
||||
bglobal.TryAddBot (stream, player);
|
||||
break;
|
||||
|
||||
case DEM_KILLBOTS:
|
||||
|
|
|
@ -112,7 +112,7 @@ enum EDemoCommand
|
|||
DEM_DROPPLAYER, // 13 Not implemented, takes a byte
|
||||
DEM_CHANGEMAP, // 14 Name of map to change to
|
||||
DEM_SUICIDE, // 15 Player wants to die
|
||||
DEM_ADDBOT, // 16 Byte: player#, String: userinfo for bot, 4 Bytes: skill (aiming, perfection, reaction, isp)
|
||||
DEM_ADDBOT, // 16 Byte: botshift, String: userinfo for bot, 4 Bytes: skill (aiming, perfection, reaction, isp)
|
||||
DEM_KILLBOTS, // 17 Remove all bots from the world
|
||||
DEM_INVUSEALL, // 18 Use every item (panic!)
|
||||
DEM_INVUSE, // 19 4 bytes: ID of item to use
|
||||
|
|
|
@ -280,7 +280,7 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
|
|||
}
|
||||
if (thebot)
|
||||
{
|
||||
thebot->inuse = true;
|
||||
thebot->inuse = BOTINUSE_Yes;
|
||||
}
|
||||
bglobal.botnum++;
|
||||
dst->userinfo.TransferFrom(uibackup2);
|
||||
|
|
Loading…
Reference in a new issue