From ee977f94d73567aa3538b3a9b940b2711cf38aa3 Mon Sep 17 00:00:00 2001 From: ChillyDoom Date: Fri, 14 Nov 2014 16:54:56 +0000 Subject: [PATCH] - Moved bot thinking logic into DBot. --- src/b_bot.cpp | 21 ++++++ src/b_bot.h | 19 +++-- src/b_func.cpp | 32 +++++++-- src/b_game.cpp | 144 +++++++++++++------------------------ src/g_game.cpp | 9 +-- src/g_level.cpp | 4 ++ src/g_shared/a_pickups.cpp | 9 ++- src/p_interaction.cpp | 13 ++-- src/p_mobj.cpp | 29 ++++---- src/p_setup.cpp | 1 - src/p_user.cpp | 7 +- src/version.h | 2 +- 12 files changed, 154 insertions(+), 136 deletions(-) diff --git a/src/b_bot.cpp b/src/b_bot.cpp index dc6f2cdc4..6a088ffcb 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -30,6 +30,7 @@ DBot::DBot () void DBot::Clear () { + player = NULL; angle = 0; dest = NULL; prev = NULL; @@ -64,6 +65,10 @@ void DBot::Serialize (FArchive &arc) arc << savedyaw << savedpitch; } + else if (SaveVersion >= 4516) + { + arc << player; + } arc << angle << dest @@ -88,6 +93,22 @@ void DBot::Serialize (FArchive &arc) << oldy; } +void DBot::Tick () +{ + Super::Tick (); + + if (player->mo == NULL || bglobal.freeze) + { + return; + } + + BotThinkCycles.Clock(); + bglobal.m_Thinking = true; + bglobal.Think (player->mo, &netcmds[player - players][((gametic + 1)/ticdup)%BACKUPTICS]); + bglobal.m_Thinking = false; + BotThinkCycles.Unclock(); +} + CVAR (Int, bot_next_color, 11, 0) CVAR (Bool, bot_observer, false, 0) diff --git a/src/b_bot.h b/src/b_bot.h index 1862faee5..7740e5e00 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -14,6 +14,7 @@ #include "d_ticcmd.h" #include "r_defs.h" #include "a_pickups.h" +#include "stats.h" #define FORWARDWALK 0x1900 #define FORWARDRUN 0x3200 @@ -89,20 +90,22 @@ public: void ClearPlayer (int playernum, bool keepTeam); //(B_Game.c) - void Main (int buf); + void Main (); void Init (); void End(); bool SpawnBot (const char *name, int color = NOCOLOR); - bool LoadBots (); - void ForgetBots (); void TryAddBot (BYTE **stream, int player); void RemoveAllBots (bool fromlist); - void DestroyAllBots (); + bool LoadBots (); + void ForgetBots (); //(B_Func.c) bool Check_LOS (AActor *mobj1, AActor *mobj2, angle_t vangle); + void StartTravel (); + void FinishTravel (); //(B_Think.c) + void Think (AActor *actor, ticcmd_t *cmd); void WhatToGet (AActor *actor, AActor *item); //(B_move.c) @@ -144,7 +147,6 @@ private: bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); //(B_Think.c) - void Think (AActor *actor, ticcmd_t *cmd); void ThinkForMove (AActor *actor, ticcmd_t *cmd); void Set_enemy (AActor *actor); @@ -155,16 +157,18 @@ protected: bool observer; //Consoleplayer is observer. }; -class DBot : public DObject +class DBot : public DThinker { - DECLARE_CLASS(DBot,DObject) + DECLARE_CLASS(DBot,DThinker) HAS_OBJECT_POINTERS public: DBot (); void Clear (); void Serialize (FArchive &arc); + void Tick (); + player_t *player; angle_t angle; // The wanted angle that the bot try to get every tic. // (used to get a smooth view movement) TObjPtr dest; // Move Destination. @@ -205,6 +209,7 @@ public: //Externs extern FCajunMaster bglobal; +extern cycle_t BotThinkCycles, BotSupportCycles; EXTERN_CVAR (Float, bot_flag_return_time) EXTERN_CVAR (Int, bot_next_color) diff --git a/src/b_func.cpp b/src/b_func.cpp index 0303de8c6..9ea03d45e 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -272,10 +272,12 @@ shootmissile: bool FCajunMaster::IsLeader (player_t *player) { - for (int count = 0; count < MAXPLAYERS; count++) + DBot *Bot; + TThinkerIterator it; + + while ((Bot = it.Next ()) != NULL) { - if (players[count].Bot != NULL - && players[count].Bot->mate == player->mo) + if (Bot->mate == player->mo) { return true; } @@ -402,7 +404,7 @@ AActor *FCajunMaster::Find_enemy (AActor *bot) && bot != client->mo) { if (Check_LOS (bot, client->mo, vangle)) //Here's a strange one, when bot is standing still, the P_CheckSight within Check_LOS almost always returns false. tought it should be the same checksight as below but.. (below works) something must be fuckin wierd screded up. - //if(P_CheckSight( bot, players[count].mo)) + //if(P_CheckSight(bot, players[count].mo)) { temp = P_AproxDistance (client->mo->x - bot->x, client->mo->y - bot->y); @@ -552,3 +554,25 @@ bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FChec actor->flags = savedFlags; return res; } + +void FCajunMaster::StartTravel () +{ + DBot *Bot; + TThinkerIterator it; + + while ((Bot = it.Next ()) != NULL) + { + Bot->ChangeStatNum (STAT_TRAVELLING); + } +} + +void FCajunMaster::FinishTravel () +{ + DBot *Bot; + TThinkerIterator it(STAT_TRAVELLING); + + while ((Bot = it.Next ()) != NULL) + { + Bot->ChangeStatNum (STAT_DEFAULT); + } +} diff --git a/src/b_game.cpp b/src/b_game.cpp index 853ba7f23..a05106a70 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -94,71 +94,46 @@ FCajunMaster::~FCajunMaster() ForgetBots(); } -//This function is called every tick (from g_game.c), -//send bots into thinking (+more). -void FCajunMaster::Main (int buf) +//This function is called every tick (from g_game.c). +void FCajunMaster::Main () { - int i; - BotThinkCycles.Reset(); - if (demoplayback) + if (demoplayback || gamestate != GS_LEVEL || consoleplayer != Net_Arbitrator) return; - if (gamestate != GS_LEVEL) - return; - - m_Thinking = true; - - //Think for bots. - if (botnum) + //Add new bots? + if (wanted_botnum > botnum && !freeze) { - BotThinkCycles.Clock(); - for (i = 0; i < MAXPLAYERS; i++) + if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY)) { - if (playeringame[i] && players[i].mo && !freeze && players[i].Bot != NULL) - Think (players[i].mo, &netcmds[i][buf]); + if (!SpawnBot (getspawned[spawn_tries])) + wanted_botnum--; + spawn_tries++; } - BotThinkCycles.Unclock(); + + t_join--; } - if (consoleplayer == Net_Arbitrator) + //Check if player should go observer. Or un observe + if (bot_observer && !observer && !netgame) { - //Add new bots? - if (wanted_botnum > botnum && !freeze) - { - if (t_join == ((wanted_botnum - botnum) * SPAWN_DELAY)) - { - if (!SpawnBot (getspawned[spawn_tries])) - wanted_botnum--; - spawn_tries++; - } - - t_join--; - } - - //Check if player should go observer. Or un observe - if (bot_observer && !observer && !netgame) - { - Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName()); - observer = true; - players[consoleplayer].mo->UnlinkFromWorld (); - players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY; - players[consoleplayer].mo->flags2 |= MF2_FLY; - players[consoleplayer].mo->LinkToWorld (); - } - else if (!bot_observer && observer && !netgame) //Go back - { - Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName()); - observer = false; - players[consoleplayer].mo->UnlinkFromWorld (); - players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY; - players[consoleplayer].mo->flags2 &= ~MF2_FLY; - players[consoleplayer].mo->LinkToWorld (); - } + Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName()); + observer = true; + players[consoleplayer].mo->UnlinkFromWorld (); + players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY; + players[consoleplayer].mo->flags2 |= MF2_FLY; + players[consoleplayer].mo->LinkToWorld (); + } + else if (!bot_observer && observer && !netgame) //Go back + { + Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName()); + observer = false; + players[consoleplayer].mo->UnlinkFromWorld (); + players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY; + players[consoleplayer].mo->flags2 &= ~MF2_FLY; + players[consoleplayer].mo->LinkToWorld (); } - - m_Thinking = false; } void FCajunMaster::Init () @@ -195,22 +170,18 @@ void FCajunMaster::Init () //Called on each level exit (from g_game.c). void FCajunMaster::End () { - int i; - //Arrange wanted botnum and their names, so they can be spawned next level. getspawned.Clear(); - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && players[i].Bot != NULL) - { - if (deathmatch) - { - getspawned.Push(players[i].userinfo.GetName()); - } - } - } if (deathmatch) { + DBot *Bot; + TThinkerIterator it; + + while ((Bot = it.Next ()) != NULL) + { + getspawned.Push(Bot->player->userinfo.GetName()); + } + wanted_botnum = botnum; } } @@ -400,7 +371,7 @@ bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill) multiplayer = true; //Prevents cheating and so on; emulates real netgame (almost). players[bnum].Bot = new DBot; - GC::WriteBarrier (players[bnum].Bot); + players[bnum].Bot->player = &players[bnum]; players[bnum].Bot->skill = skill; playeringame[bnum] = true; players[bnum].mo = NULL; @@ -422,31 +393,30 @@ bool FCajunMaster::DoAddBot (BYTE *info, botskill_t skill) void FCajunMaster::RemoveAllBots (bool fromlist) { - int i, j; + DBot *Bot; + TThinkerIterator it; + int i; - for (i = 0; i < MAXPLAYERS; ++i) + while ((Bot = it.Next ()) != NULL) { - if (playeringame[i] && players[i].Bot != NULL) + // If a player is looking through this bot's eyes, make him + // look through his own eyes instead. + for (i = 0; i < MAXPLAYERS; ++i) { - // If a player is looking through this bot's eyes, make him - // look through his own eyes instead. - for (j = 0; j < MAXPLAYERS; ++j) + if (Bot->player != &players[i] && playeringame[i] && players[i].Bot == NULL) { - if (i != j && playeringame[j] && players[j].Bot == NULL) + if (players[i].camera == Bot->player->mo) { - if (players[j].camera == players[i].mo) + players[i].camera = players[i].mo; + if (i == consoleplayer) { - players[j].camera = players[j].mo; - if (j == consoleplayer) - { - StatusBar->AttachToPlayer (players + j); - } + StatusBar->AttachToPlayer (players + i); } } } - ClearPlayer (i, !fromlist); - FBehavior::StaticStartTypedScripts (SCRIPT_Disconnect, NULL, true, i); } + ClearPlayer (Bot->player - players, !fromlist); + FBehavior::StaticStartTypedScripts (SCRIPT_Disconnect, NULL, true, Bot->player - players); } if (fromlist) @@ -456,18 +426,6 @@ void FCajunMaster::RemoveAllBots (bool fromlist) botnum = 0; } -void FCajunMaster::DestroyAllBots () -{ - for (int i = 0; i < MAXPLAYERS; ++i) - { - if (players[i].Bot != NULL) - { - players[i].Bot->Destroy (); - players[i].Bot = NULL; - } - } -} - //------------------ //Reads data for bot from diff --git a/src/g_game.cpp b/src/g_game.cpp index af4a5411e..d56c58910 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1127,11 +1127,8 @@ void G_Ticker () // check, not just the player's x position like BOOM. DWORD rngsum = FRandom::StaticSumSeeds (); - if ((gametic % ticdup) == 0) - { - //Added by MC: For some of that bot stuff. The main bot function. - bglobal.Main (buf); - } + //Added by MC: For some of that bot stuff. The main bot function. + bglobal.Main (); for (i = 0; i < MAXPLAYERS; i++) { @@ -1394,7 +1391,6 @@ void G_PlayerReborn (int player) if (gamestate != GS_TITLELEVEL) { - // [GRB] Give inventory specified in DECORATE actor->GiveDefaultInventory (); p->ReadyWeapon = p->PendingWeapon; @@ -1405,6 +1401,7 @@ void G_PlayerReborn (int player) { botskill_t skill = p->Bot->skill; p->Bot->Clear (); + p->Bot->player = p; p->Bot->skill = skill; } } diff --git a/src/g_level.cpp b/src/g_level.cpp index 2a2d6471a..761ea4f48 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1164,6 +1164,8 @@ void G_StartTravel () } } } + + bglobal.StartTravel (); } //========================================================================== @@ -1261,6 +1263,8 @@ void G_FinishTravel () } } } + + bglobal.FinishTravel (); } //========================================================================== diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index fc3e863a2..f5c262d8c 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -1021,11 +1021,14 @@ void AInventory::Touch (AActor *toucher) P_GiveSecret(toucher, true, true, -1); } + DBot *Bot; + TThinkerIterator it; + //Added by MC: Check if item taken was the roam destination of any bot - for (int i = 0; i < MAXPLAYERS; i++) + while ((Bot = it.Next ()) != NULL) { - if (playeringame[i] && players[i].Bot != NULL && this == players[i].Bot->dest) - players[i].Bot->dest = NULL; + if (Bot->dest == this) + Bot->dest = NULL; } } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 88d95b25e..88cc89668 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -611,14 +611,17 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) if (player->Bot != NULL) player->Bot->t_respawn = (pr_botrespawn()%15)+((bglobal.botnum-1)*2)+TICRATE+1; + DBot *Bot; + TThinkerIterator it; + //Added by MC: Discard enemies. - for (int i = 0; i < MAXPLAYERS; i++) + while ((Bot = it.Next ()) != NULL) { - if (players[i].Bot != NULL && this == players[i].Bot->enemy) + if (this == Bot->enemy) { - if (players[i].Bot->dest == players[i].Bot->enemy) - players[i].Bot->dest = NULL; - players[i].Bot->enemy = NULL; + if (Bot->dest == Bot->enemy) + Bot->dest = NULL; + Bot->enemy = NULL; } } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index c7bfcea21..27bc50a83 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -84,7 +84,6 @@ static void PlayerLandedOnThing (AActor *mo, AActor *onmobj); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- -extern cycle_t BotSupportCycles; extern int BotWTG; EXTERN_CVAR (Int, cl_rockettrails) @@ -3043,7 +3042,6 @@ void AActor::Tick () AActor *onmo; - int i; //assert (state != NULL); if (state == NULL) @@ -3233,35 +3231,36 @@ void AActor::Tick () { BotSupportCycles.Clock(); bglobal.m_Thinking = true; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].Bot == NULL) - continue; + DBot *Bot; + TThinkerIterator it; + + while ((Bot = it.Next ()) != NULL) + { if (flags3 & MF3_ISMONSTER) { if (health > 0 - && !players[i].Bot->enemy - && player ? !IsTeammate (players[i].mo) : true - && P_AproxDistance (players[i].mo->x-x, players[i].mo->y-y) < MAX_MONSTER_TARGET_DIST - && P_CheckSight (players[i].mo, this, SF_SEEPASTBLOCKEVERYTHING)) + && !Bot->enemy + && player ? !IsTeammate (Bot->player->mo) : true + && P_AproxDistance (Bot->player->mo->x-x, Bot->player->mo->y-y) < MAX_MONSTER_TARGET_DIST + && P_CheckSight (Bot->player->mo, this, SF_SEEPASTBLOCKEVERYTHING)) { //Probably a monster, so go kill it. - players[i].Bot->enemy = this; + Bot->enemy = this; } } else if (flags & MF_SPECIAL) { //Item pickup time //clock (BotWTG); - bglobal.WhatToGet (players[i].mo, this); + bglobal.WhatToGet (Bot->player->mo, this); //unclock (BotWTG); BotWTG++; } else if (flags & MF_MISSILE) { - if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT)) + if (!Bot->missile && (flags3 & MF3_WARNBOT)) { //warn for incoming missiles. - if (target != players[i].mo && bglobal.Check_LOS (players[i].mo, this, ANGLE_90)) - players[i].Bot->missile = this; + if (target != Bot->player->mo && bglobal.Check_LOS (Bot->player->mo, this, ANGLE_90)) + Bot->missile = this; } } } diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 53b288798..6b5d9403f 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -4175,7 +4175,6 @@ static void P_Shutdown () P_FreeLevelData (); P_FreeExtraLevelData (); ST_Clear(); - bglobal.DestroyAllBots (); } #if 0 diff --git a/src/p_user.cpp b/src/p_user.cpp index 72b92b7d1..bf656d2b9 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -3066,7 +3066,6 @@ void player_t::Serialize (FArchive &arc) if (SaveVersion < 4514 && IsBot) { Bot = new DBot; - GC::WriteBarrier (Bot); arc << Bot->angle << Bot->dest @@ -3089,6 +3088,12 @@ void player_t::Serialize (FArchive &arc) << Bot->oldx << Bot->oldy; } + + if (SaveVersion < 4516 && Bot != NULL) + { + Bot->player = this; + } + if (arc.IsLoading ()) { // If the player reloaded because they pressed +use after dying, we diff --git a/src/version.h b/src/version.h index f091f416a..15d01d315 100644 --- a/src/version.h +++ b/src/version.h @@ -76,7 +76,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4515 +#define SAVEVER 4516 #define SAVEVERSTRINGIFY2(x) #x #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)