This commit is contained in:
Christoph Oelckers 2014-10-25 18:26:42 +02:00
commit bd811bea87
10 changed files with 125 additions and 74 deletions

View File

@ -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++;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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:

View File

@ -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

View File

@ -236,6 +236,18 @@ void G_NewInit ()
{
int i;
// Destory all old player refrences that may still exist
TThinkerIterator<APlayerPawn> it(STAT_TRAVELLING);
APlayerPawn *pawn, *next;
next = it.Next();
while ((pawn = next) != NULL)
{
next = it.Next();
pawn->flags |= MF_NOSECTOR | MF_NOBLOCKMAP;
pawn->Destroy();
}
G_ClearSnapshots ();
ST_SetNeedRefresh();
netgame = false;

View File

@ -293,7 +293,6 @@ void FMapInfoParser::ParseGameInfo()
GAMEINFOKEY_STRING(mCheatKey, "cheatKey")
GAMEINFOKEY_STRING(mEasyKey, "easyKey")
GAMEINFOKEY_STRING(TitlePage, "titlePage")
GAMEINFOKEY_STRING(TitlePage, "titlePage")
GAMEINFOKEY_STRINGARRAY(creditPages, "addcreditPage", 8, false)
GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true)
GAMEINFOKEY_STRINGARRAY(PlayerClasses, "addplayerclasses", 0, false)

View File

@ -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);

View File

@ -767,7 +767,7 @@ void FHexenStartupScreen::NetProgress(int count)
y = ST_NETPROGRESS_Y;
ST_Util_DrawBlock (StartupBitmap, NetNotchBits, x, y, ST_NETNOTCH_WIDTH / 2, ST_NETNOTCH_HEIGHT);
}
S_Sound (CHAN_BODY, "Drip", 1, ATTN_NONE);
S_Sound (CHAN_BODY, "misc/netnotch", 1, ATTN_NONE);
I_GetEvent ();
}
}

View File

@ -985,6 +985,7 @@ $alias menu/clear PlatformStop
// Hexen does not have ripslop sound like Heretic
misc/ripslop dsempty
misc/netnotch blddrp1
$alias intermission/cooptotal *death
$alias intermission/nextstage DoorCloseLight