From e7da849f77765fc0ddf8db9ba4453b0f6e553f74 Mon Sep 17 00:00:00 2001 From: ChillyDoom Date: Sat, 29 Nov 2014 17:03:58 +0000 Subject: [PATCH] - Moved bot specific functions into DBot. --- src/b_bot.cpp | 4 +- src/b_bot.h | 71 ++++++------ src/b_func.cpp | 200 +++++++++++++++++----------------- src/b_move.cpp | 123 +++++++++++---------- src/b_think.cpp | 284 +++++++++++++++++++++++------------------------- src/p_mobj.cpp | 4 +- 6 files changed, 335 insertions(+), 351 deletions(-) diff --git a/src/b_bot.cpp b/src/b_bot.cpp index d2acdcab67..05cac045bb 100644 --- a/src/b_bot.cpp +++ b/src/b_bot.cpp @@ -66,7 +66,7 @@ void DBot::Serialize (FArchive &arc) arc << savedyaw << savedpitch; } - else if (SaveVersion >= 4516) + else { arc << player; } @@ -105,7 +105,7 @@ void DBot::Tick () BotThinkCycles.Clock(); bglobal.m_Thinking = true; - bglobal.Think (player->mo, &netcmds[player - players][((gametic + 1)/ticdup)%BACKUPTICS]); + Think (); bglobal.m_Thinking = false; BotThinkCycles.Unclock(); } diff --git a/src/b_bot.h b/src/b_bot.h index 7740e5e00d..69a2f7774f 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -89,7 +89,7 @@ public: void ClearPlayer (int playernum, bool keepTeam); - //(B_Game.c) + //(b_game.cpp) void Main (); void Init (); void End(); @@ -99,23 +99,16 @@ public: bool LoadBots (); void ForgetBots (); - //(B_Func.c) - bool Check_LOS (AActor *mobj1, AActor *mobj2, angle_t vangle); + //(b_func.cpp) void StartTravel (); void FinishTravel (); + bool IsLeader (player_t *player); + void SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum); + fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); + bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); - //(B_Think.c) - void Think (AActor *actor, ticcmd_t *cmd); - void WhatToGet (AActor *actor, AActor *item); - - //(B_move.c) - void Roam (AActor *actor, ticcmd_t *cmd); - bool Move (AActor *actor, ticcmd_t *cmd); - bool TryWalk (AActor *actor, ticcmd_t *cmd); - void NewChaseDir (AActor *actor, ticcmd_t *cmd); + //(b_move.cpp) bool CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cmd); - void TurnToAng (AActor *actor); - void Pitch (AActor *actor, AActor *target); bool IsDangerous (sector_t *sec); TArray getspawned; //Array of bots (their names) which should be spawned when starting a game. @@ -132,24 +125,9 @@ public: bool m_Thinking; private: - //(B_Game.c) + //(b_game.cpp) bool DoAddBot (BYTE *info, botskill_t skill); - //(B_Func.c) - bool Reachable (AActor *actor, AActor *target); - void Dofire (AActor *actor, ticcmd_t *cmd); - bool IsLeader (player_t *player); - AActor *Choose_Mate (AActor *bot); - AActor *Find_enemy (AActor *bot); - void SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum); - fixed_t FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd); - angle_t FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd); - bool SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm); - - //(B_Think.c) - void ThinkForMove (AActor *actor, ticcmd_t *cmd); - void Set_enemy (AActor *actor); - protected: bool ctf; int loaded_bots; @@ -168,13 +146,17 @@ public: void Serialize (FArchive &arc); void Tick (); + //(b_think.cpp) + void WhatToGet (AActor *item); + + //(b_func.cpp) + bool Check_LOS (AActor *to, angle_t vangle); + 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. TObjPtr prev; // Previous move destination. - - TObjPtr enemy; // The dead meat. TObjPtr missile; // A threatening missile that needs to be avoided. TObjPtr mate; // Friend (used for grouping in teamplay or coop). @@ -204,6 +186,27 @@ public: fixed_t oldx; fixed_t oldy; + +private: + //(B_think.cpp) + void Think (); + void ThinkForMove (ticcmd_t *cmd); + void Set_enemy (); + + //(B_func.cpp) + bool Reachable (AActor *target); + void Dofire (ticcmd_t *cmd); + AActor *Choose_Mate (); + AActor *Find_enemy (); + angle_t FireRox (AActor *enemy, ticcmd_t *cmd); + + //(b_move.cpp) + void Roam (ticcmd_t *cmd); + bool Move (ticcmd_t *cmd); + bool TryWalk (ticcmd_t *cmd); + void NewChaseDir (ticcmd_t *cmd); + void TurnToAng (); + void Pitch (AActor *target); }; @@ -220,7 +223,3 @@ EXTERN_CVAR (Bool, bot_watersplash) EXTERN_CVAR (Bool, bot_chat) #endif // __B_BOT_H__ - - - - diff --git a/src/b_func.cpp b/src/b_func.cpp index 349155a814..7165d2cc1e 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -24,24 +24,23 @@ static FRandom pr_botdofire ("BotDoFire"); -//Checks TRUE reachability from -//one looker to another. First mobj (looker) is looker. -bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) +//Checks TRUE reachability from bot to a looker. +bool DBot::Reachable (AActor *rtarget) { - if (looker == rtarget) + if (player->mo == rtarget) return false; if ((rtarget->Sector->ceilingplane.ZatPoint (rtarget->x, rtarget->y) - rtarget->Sector->floorplane.ZatPoint (rtarget->x, rtarget->y)) - < looker->height) //Where rtarget is, looker can't be. + < player->mo->height) //Where rtarget is, player->mo can't be. return false; - sector_t *last_s = looker->Sector; - fixed_t last_z = last_s->floorplane.ZatPoint (looker->x, looker->y); - fixed_t estimated_dist = P_AproxDistance (looker->x - rtarget->x, looker->y - rtarget->y); + sector_t *last_s = player->mo->Sector; + fixed_t last_z = last_s->floorplane.ZatPoint (player->mo->x, player->mo->y); + fixed_t estimated_dist = P_AproxDistance (player->mo->x - rtarget->x, player->mo->y - rtarget->y); bool reachable = true; - FPathTraverse it(looker->x+looker->velx, looker->y+looker->vely, rtarget->x, rtarget->y, PT_ADDLINES|PT_ADDTHINGS); + FPathTraverse it(player->mo->x+player->mo->velx, player->mo->y+player->mo->vely, rtarget->x, rtarget->y, PT_ADDLINES|PT_ADDTHINGS); intercept_t *in; while ((in = it.Next())) { @@ -55,8 +54,8 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) frac = in->frac - FixedDiv (4*FRACUNIT, MAX_TRAVERSE_DIST); dist = FixedMul (frac, MAX_TRAVERSE_DIST); - hitx = it.Trace().x + FixedMul (looker->velx, frac); - hity = it.Trace().y + FixedMul (looker->vely, frac); + hitx = it.Trace().x + FixedMul (player->mo->velx, frac); + hity = it.Trace().y + FixedMul (player->mo->vely, frac); if (in->isaline) { @@ -76,7 +75,7 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) if (!bglobal.IsDangerous (s) && //Any nukage/lava? (floorheight <= (last_z+MAXMOVEHEIGHT) && ((ceilingheight == floorheight && line->special) - || (ceilingheight - floorheight) >= looker->height))) //Does it fit? + || (ceilingheight - floorheight) >= player->mo->height))) //Does it fit? { last_z = floorheight; last_s = s; @@ -95,7 +94,7 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) } thing = in->d.thing; - if (thing == looker) //Can't reach self in this case. + if (thing == player->mo) //Can't reach self in this case. continue; if (thing == rtarget && (rtarget->Sector->floorplane.ZatPoint (rtarget->x, rtarget->y) <= (last_z+MAXMOVEHEIGHT))) { @@ -115,16 +114,16 @@ bool FCajunMaster::Reachable (AActor *looker, AActor *rtarget) //if these conditions are true, the function returns true. //GOOD TO KNOW is that the player's view angle //in doom is 90 degrees infront. -bool FCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle) +bool DBot::Check_LOS (AActor *to, angle_t vangle) { - if (!P_CheckSight (from, to, SF_SEEPASTBLOCKEVERYTHING)) + if (!P_CheckSight (player->mo, to, SF_SEEPASTBLOCKEVERYTHING)) return false; // out of sight if (vangle == ANGLE_MAX) return true; if (vangle == 0) return false; //Looker seems to be blind. - return (angle_t)abs (R_PointToAngle2 (from->x, from->y, to->x, to->y) - from->angle) <= vangle/2; + return (angle_t)abs (R_PointToAngle2 (player->mo->x, player->mo->y, to->x, to->y) - player->mo->angle) <= vangle/2; } //------------------------------------- @@ -132,7 +131,7 @@ bool FCajunMaster::Check_LOS (AActor *from, AActor *to, angle_t vangle) //------------------------------------- //The bot will check if it's time to fire //and do so if that is the case. -void FCajunMaster::Dofire (AActor *actor, ticcmd_t *cmd) +void DBot::Dofire (ticcmd_t *cmd) { bool no_fire; //used to prevent bot from pumping rockets into nearby walls. int aiming_penalty=0; //For shooting at shading target, if screen is red, MAKEME: When screen red. @@ -140,49 +139,48 @@ void FCajunMaster::Dofire (AActor *actor, ticcmd_t *cmd) fixed_t dist; angle_t an; int m; - AActor *enemy = actor->player->Bot->enemy; if (!enemy || !(enemy->flags & MF_SHOOTABLE) || enemy->health <= 0) return; - if (actor->player->ReadyWeapon == NULL) + if (player->ReadyWeapon == NULL) return; - if (actor->player->damagecount > actor->player->Bot->skill.isp) + if (player->damagecount > skill.isp) { - actor->player->Bot->first_shot = true; + first_shot = true; return; } //Reaction skill thing. - if (actor->player->Bot->first_shot && - !(actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_REACTION_SKILL_THING)) + if (first_shot && + !(player->ReadyWeapon->WeaponFlags & WIF_BOT_REACTION_SKILL_THING)) { - actor->player->Bot->t_react = (100-actor->player->Bot->skill.reaction+1)/((pr_botdofire()%3)+3); + t_react = (100-skill.reaction+1)/((pr_botdofire()%3)+3); } - actor->player->Bot->first_shot = false; - if (actor->player->Bot->t_react) + first_shot = false; + if (t_react) return; //MAKEME: Decrease the rocket suicides even more. no_fire = true; - //actor->player->angle = R_PointToAngle2(actor->x, actor->y, actor->player->enemy->x, actor->player->enemy->y); + //angle = R_PointToAngle2(player->mo->x, player->mo->y, player->enemy->x, player->enemy->y); //Distance to enemy. - dist = P_AproxDistance ((actor->x + actor->velx) - (enemy->x + enemy->velx), - (actor->y + actor->vely) - (enemy->y + enemy->vely)); + dist = P_AproxDistance ((player->mo->x + player->mo->velx) - (enemy->x + enemy->velx), + (player->mo->y + player->mo->vely) - (enemy->y + enemy->vely)); //FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go. - if (actor->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) + if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON) { - if ((actor->player->ReadyWeapon->ProjectileType != NULL)) + if ((player->ReadyWeapon->ProjectileType != NULL)) { - if (actor->player->ReadyWeapon->CheckAmmo (AWeapon::PrimaryFire, false, true)) + if (player->ReadyWeapon->CheckAmmo (AWeapon::PrimaryFire, false, true)) { // This weapon can fire a projectile and has enough ammo to do so goto shootmissile; } - else if (!(actor->player->ReadyWeapon->WeaponFlags & WIF_AMMO_OPTIONAL)) + else if (!(player->ReadyWeapon->WeaponFlags & WIF_AMMO_OPTIONAL)) { // Ammo is required, so don't shoot. This is for weapons that shoot // missiles that die at close range, such as the powered-up Phoneix Rod. @@ -195,51 +193,51 @@ void FCajunMaster::Dofire (AActor *actor, ticcmd_t *cmd) no_fire = (dist > (MELEERANGE*4)); } } - else if (actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG) + else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG) { //MAKEME: This should be smarter. - if ((pr_botdofire()%200)<=actor->player->Bot->skill.reaction) - if(Check_LOS(actor, actor->player->Bot->enemy, SHOOTFOV)) + if ((pr_botdofire()%200)<=skill.reaction) + if(Check_LOS(enemy, SHOOTFOV)) no_fire = false; } - else if (actor->player->ReadyWeapon->ProjectileType != NULL) + else if (player->ReadyWeapon->ProjectileType != NULL) { - if (actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) + if (player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) { //Special rules for RL - an = FireRox (actor, enemy, cmd); + an = FireRox (enemy, cmd); if(an) { - actor->player->Bot->angle = an; + angle = an; //have to be somewhat precise. to avoid suicide. - if (abs (actor->player->Bot->angle - actor->angle) < 12*ANGLE_1) + if (abs (angle - player->mo->angle) < 12*ANGLE_1) { - actor->player->Bot->t_rocket = 9; + t_rocket = 9; no_fire = false; } } } // prediction aiming shootmissile: - dist = P_AproxDistance (actor->x - enemy->x, actor->y - enemy->y); - m = dist / GetDefaultByType (actor->player->ReadyWeapon->ProjectileType)->Speed; - SetBodyAt (enemy->x + enemy->velx*m*2, enemy->y + enemy->vely*m*2, enemy->z, 1); - actor->player->Bot->angle = R_PointToAngle2 (actor->x, actor->y, body1->x, body1->y); - if (Check_LOS (actor, enemy, SHOOTFOV)) + dist = P_AproxDistance (player->mo->x - enemy->x, player->mo->y - enemy->y); + m = dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed; + bglobal.SetBodyAt (enemy->x + enemy->velx*m*2, enemy->y + enemy->vely*m*2, enemy->z, 1); + angle = R_PointToAngle2 (player->mo->x, player->mo->y, bglobal.body1->x, bglobal.body1->y); + if (Check_LOS (enemy, SHOOTFOV)) no_fire = false; } else { //Other weapons, mostly instant hit stuff. - actor->player->Bot->angle = R_PointToAngle2 (actor->x, actor->y, enemy->x, enemy->y); + angle = R_PointToAngle2 (player->mo->x, player->mo->y, enemy->x, enemy->y); aiming_penalty = 0; if (enemy->flags & MF_SHADOW) aiming_penalty += (pr_botdofire()%25)+10; - if (enemy->Sector->lightlevelplayer->powers & PW_INFRARED)*/) + if (enemy->Sector->lightlevelpowers & PW_INFRARED)*/) aiming_penalty += pr_botdofire()%40;//Dark - if (actor->player->damagecount) - aiming_penalty += actor->player->damagecount; //Blood in face makes it hard to aim - aiming_value = actor->player->Bot->skill.aiming - aiming_penalty; + if (player->damagecount) + aiming_penalty += player->damagecount; //Blood in face makes it hard to aim + aiming_value = skill.aiming - aiming_penalty; if (aiming_value <= 0) aiming_value = 1; m = ((SHOOTFOV/2)-(aiming_value*SHOOTFOV/200)); //Higher skill is more accurate @@ -248,18 +246,18 @@ shootmissile: if (m) { - if (actor->player->Bot->increase) - actor->player->Bot->angle += m; + if (increase) + angle += m; else - actor->player->Bot->angle -= m; + angle -= m; } - if (abs (actor->player->Bot->angle - actor->angle) < 4*ANGLE_1) + if (abs (angle - player->mo->angle) < 4*ANGLE_1) { - actor->player->Bot->increase = !actor->player->Bot->increase; + increase = !increase; } - if (Check_LOS (actor, enemy, (SHOOTFOV/2))) + if (Check_LOS (enemy, (SHOOTFOV/2))) no_fire = false; } if (!no_fire) //If going to fire weapon @@ -267,7 +265,7 @@ shootmissile: cmd->ucmd.buttons |= BT_ATTACK; } //Prevents bot from jerking, when firing automatic things with low skill. - //actor->angle = R_PointToAngle2(actor->x, actor->y, actor->player->enemy->x, actor->player->enemy->y); + //player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, player->enemy->x, player->enemy->y); } bool FCajunMaster::IsLeader (player_t *player) @@ -287,7 +285,7 @@ bool FCajunMaster::IsLeader (player_t *player) //This function is called every //tick (for each bot) to set //the mate (teammate coop mate). -AActor *FCajunMaster::Choose_Mate (AActor *bot) +AActor *DBot::Choose_Mate () { int count; fixed_t closest_dist, test; @@ -295,20 +293,20 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot) AActor *observer; //is mate alive? - if (bot->player->Bot->mate) + if (mate) { - if (bot->player->Bot->mate->health <= 0) - bot->player->Bot->mate = NULL; + if (mate->health <= 0) + mate = NULL; else - bot->player->Bot->last_mate = bot->player->Bot->mate; + last_mate = mate; } - if (bot->player->Bot->mate) //Still is.. - return bot->player->Bot->mate; + if (mate) //Still is.. + return mate; //Check old_mates status. - if (bot->player->Bot->last_mate) - if (bot->player->Bot->last_mate->health <= 0) - bot->player->Bot->last_mate = NULL; + if (last_mate) + if (last_mate->health <= 0) + last_mate = NULL; target = NULL; closest_dist = FIXED_MAX; @@ -324,17 +322,17 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot) if (playeringame[count] && client->mo - && bot != client->mo - && (bot->IsTeammate (client->mo) || !deathmatch) + && player->mo != client->mo + && (player->mo->IsTeammate (client->mo) || !deathmatch) && client->mo->health > 0 && client->mo != observer - && ((bot->health/2) <= client->mo->health || !deathmatch) - && !IsLeader(client)) //taken? + && ((player->mo->health/2) <= client->mo->health || !deathmatch) + && !bglobal.IsLeader(client)) //taken? { - if (P_CheckSight (bot, client->mo, SF_IGNOREVISIBILITY)) + if (P_CheckSight (player->mo, client->mo, SF_IGNOREVISIBILITY)) { - test = P_AproxDistance (client->mo->x - bot->x, - client->mo->y - bot->y); + test = P_AproxDistance (client->mo->x - player->mo->x, + client->mo->y - player->mo->y); if (test < closest_dist) { @@ -347,15 +345,15 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot) /* //Make a introducing to mate. - if(target && target!=bot->player->last_mate) + if(target && target!=last_mate) { if((P_Random()%(200*bglobal.botnum))<3) { - bot->player->chat = c_teamup; + chat = c_teamup; if(target->bot) - strcpy(bot->player->c_target, botsingame[target->bot_id]); + strcpy(c_target, botsingame[target->bot_id]); else if(target->player) - strcpy(bot->player->c_target, player_names[target->play_id]); + strcpy(c_target, player_names[target->play_id]); } } */ @@ -365,7 +363,7 @@ AActor *FCajunMaster::Choose_Mate (AActor *bot) } //MAKEME: Make this a smart decision -AActor *FCajunMaster::Find_enemy (AActor *bot) +AActor *DBot::Find_enemy () { int count; fixed_t closest_dist, temp; //To target. @@ -375,15 +373,15 @@ AActor *FCajunMaster::Find_enemy (AActor *bot) if (!deathmatch) { // [RH] Take advantage of the Heretic/Hexen code to be a little smarter - return P_RoughMonsterSearch (bot, 20); + return P_RoughMonsterSearch (player->mo, 20); } //Note: It's hard to ambush a bot who is not alone - if (bot->player->Bot->allround || bot->player->Bot->mate) + if (allround || mate) vangle = ANGLE_MAX; else vangle = ENEMY_SCAN_FOV; - bot->player->Bot->allround = false; + allround = false; target = NULL; closest_dist = FIXED_MAX; @@ -396,21 +394,21 @@ AActor *FCajunMaster::Find_enemy (AActor *bot) { player_t *client = &players[count]; if (playeringame[count] - && !bot->IsTeammate (client->mo) + && !player->mo->IsTeammate (client->mo) && client->mo != observer && client->mo->health > 0 - && bot != client->mo) + && player->mo != 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 (Check_LOS (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(player->mo, players[count].mo)) { - temp = P_AproxDistance (client->mo->x - bot->x, - client->mo->y - bot->y); + temp = P_AproxDistance (client->mo->x - player->mo->x, + client->mo->y - player->mo->y); //Too dark? if (temp > DARK_DIST && client->mo->Sector->lightlevel < WHATS_DARK /*&& - bot->player->Powers & PW_INFRARED*/) + player->Powers & PW_INFRARED*/) continue; if (temp < closest_dist) @@ -494,16 +492,16 @@ fixed_t FCajunMaster::FakeFire (AActor *source, AActor *dest, ticcmd_t *cmd) return dist; } -angle_t FCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd) +angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) { fixed_t dist; angle_t ang; AActor *actor; int m; - SetBodyAt (bot->x + FixedMul(bot->velx, 5*FRACUNIT), - bot->y + FixedMul(bot->vely, 5*FRACUNIT), - bot->z + (bot->height / 2), 2); + bglobal.SetBodyAt (player->mo->x + FixedMul(player->mo->velx, 5*FRACUNIT), + player->mo->y + FixedMul(player->mo->vely, 5*FRACUNIT), + player->mo->z + (player->mo->height / 2), 2); actor = bglobal.body2; @@ -513,16 +511,16 @@ angle_t FCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd) //Predict. m = (((dist+1)/FRACUNIT) / GetDefaultByName("Rocket")->Speed); - SetBodyAt (enemy->x + FixedMul(enemy->velx, (m+2*FRACUNIT)), - enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1); + bglobal.SetBodyAt (enemy->x + FixedMul(enemy->velx, (m+2*FRACUNIT)), + enemy->y + FixedMul(enemy->vely, (m+2*FRACUNIT)), ONFLOORZ, 1); dist = P_AproxDistance(actor->x-bglobal.body1->x, actor->y-bglobal.body1->y); //try the predicted location if (P_CheckSight (actor, bglobal.body1, SF_IGNOREVISIBILITY)) //See the predicted location, so give a test missile { FCheckPosition tm; - if (SafeCheckPosition (bot, actor->x, actor->y, tm)) + if (bglobal.SafeCheckPosition (player->mo, actor->x, actor->y, tm)) { - if (FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) + if (bglobal.FakeFire (actor, bglobal.body1, cmd) >= SAFE_SELF_MISDIST) { ang = R_PointToAngle2 (actor->x, actor->y, bglobal.body1->x, bglobal.body1->y); return ang; @@ -532,9 +530,9 @@ angle_t FCajunMaster::FireRox (AActor *bot, AActor *enemy, ticcmd_t *cmd) //Try fire straight. if (P_CheckSight (actor, enemy, 0)) { - if (FakeFire (bot, enemy, cmd) >= SAFE_SELF_MISDIST) + if (bglobal.FakeFire (player->mo, enemy, cmd) >= SAFE_SELF_MISDIST) { - ang = R_PointToAngle2(bot->x, bot->y, enemy->x, enemy->y); + ang = R_PointToAngle2(player->mo->x, player->mo->y, enemy->x, enemy->y); return ang; } } diff --git a/src/b_move.cpp b/src/b_move.cpp index f020cf4fc0..fd04054577 100644 --- a/src/b_move.cpp +++ b/src/b_move.cpp @@ -27,57 +27,57 @@ static FRandom pr_botnewchasedir ("BotNewChaseDir"); extern dirtype_t opposite[9]; extern dirtype_t diags[4]; -//Called while the bot moves after its player->dest mobj +//Called while the bot moves after its dest mobj //which can be a weapon/enemy/item whatever. -void FCajunMaster::Roam (AActor *actor, ticcmd_t *cmd) +void DBot::Roam (ticcmd_t *cmd) { int delta; - if (Reachable(actor, actor->player->Bot->dest)) + if (Reachable(dest)) { // Straight towards it. - actor->player->Bot->angle = R_PointToAngle2(actor->x, actor->y, actor->player->Bot->dest->x, actor->player->Bot->dest->y); + angle = R_PointToAngle2(player->mo->x, player->mo->y, dest->x, dest->y); } - else if (actor->movedir < 8) // turn towards movement direction if not there yet + else if (player->mo->movedir < 8) // turn towards movement direction if not there yet { - actor->player->Bot->angle &= (angle_t)(7<<29); - delta = actor->player->Bot->angle - (actor->movedir << 29); + angle &= (angle_t)(7<<29); + delta = angle - (player->mo->movedir << 29); if (delta > 0) - actor->player->Bot->angle -= ANG45; + angle -= ANG45; else if (delta < 0) - actor->player->Bot->angle += ANG45; + angle += ANG45; } // chase towards destination. - if (--actor->movecount < 0 || !Move (actor, cmd)) + if (--player->mo->movecount < 0 || !Move (cmd)) { - NewChaseDir (actor, cmd); + NewChaseDir (cmd); } } -bool FCajunMaster::Move (AActor *actor, ticcmd_t *cmd) +bool DBot::Move (ticcmd_t *cmd) { fixed_t tryx, tryy; bool try_ok; int good; - if (actor->movedir == DI_NODIR) + if (player->mo->movedir == DI_NODIR) return false; - if ((unsigned)actor->movedir >= 8) + if ((unsigned)player->mo->movedir >= 8) I_Error ("Weird bot movedir!"); - tryx = actor->x + 8*xspeed[actor->movedir]; - tryy = actor->y + 8*yspeed[actor->movedir]; + tryx = player->mo->x + 8*xspeed[player->mo->movedir]; + tryy = player->mo->y + 8*yspeed[player->mo->movedir]; - try_ok = CleanAhead (actor, tryx, tryy, cmd); + try_ok = bglobal.CleanAhead (player->mo, tryx, tryy, cmd); if (!try_ok) //Anything blocking that could be opened etc.. { if (!spechit.Size ()) return false; - actor->movedir = DI_NODIR; + player->mo->movedir = DI_NODIR; good = 0; line_t *ld; @@ -86,16 +86,16 @@ bool FCajunMaster::Move (AActor *actor, ticcmd_t *cmd) { bool tryit = true; - if (ld->special == Door_LockedRaise && !P_CheckKeys (actor, ld->args[3], false)) + if (ld->special == Door_LockedRaise && !P_CheckKeys (player->mo, ld->args[3], false)) tryit = false; - else if (ld->special == Generic_Door && !P_CheckKeys (actor, ld->args[4], false)) + else if (ld->special == Generic_Door && !P_CheckKeys (player->mo, ld->args[4], false)) tryit = false; if (tryit && - (P_TestActivateLine (ld, actor, 0, SPAC_Use) || - P_TestActivateLine (ld, actor, 0, SPAC_Push))) + (P_TestActivateLine (ld, player->mo, 0, SPAC_Use) || + P_TestActivateLine (ld, player->mo, 0, SPAC_Push))) { - good |= ld == actor->BlockingLine ? 1 : 2; + good |= ld == player->mo->BlockingLine ? 1 : 2; } } if (good && ((pr_botopendoor() >= 203) ^ (good & 1))) @@ -113,16 +113,16 @@ bool FCajunMaster::Move (AActor *actor, ticcmd_t *cmd) return true; } -bool FCajunMaster::TryWalk (AActor *actor, ticcmd_t *cmd) +bool DBot::TryWalk (ticcmd_t *cmd) { - if (!Move (actor, cmd)) + if (!Move (cmd)) return false; - actor->movecount = pr_bottrywalk() & 60; + player->mo->movecount = pr_bottrywalk() & 60; return true; } -void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) +void DBot::NewChaseDir (ticcmd_t *cmd) { fixed_t deltax; fixed_t deltay; @@ -134,7 +134,7 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) dirtype_t turnaround; - if (!actor->player->Bot->dest) + if (!dest) { #ifndef BOT_RELEASE_COMPILE Printf ("Bot tried move without destination\n"); @@ -142,11 +142,11 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) return; } - olddir = (dirtype_t)actor->movedir; + olddir = (dirtype_t)player->mo->movedir; turnaround = opposite[olddir]; - deltax = actor->player->Bot->dest->x - actor->x; - deltay = actor->player->Bot->dest->y - actor->y; + deltax = dest->x - player->mo->x; + deltay = dest->y - player->mo->y; if (deltax > 10*FRACUNIT) d[1] = DI_EAST; @@ -165,8 +165,8 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) // try direct route if (d[1] != DI_NODIR && d[2] != DI_NODIR) { - actor->movedir = diags[((deltay<0)<<1)+(deltax>0)]; - if (actor->movedir != turnaround && TryWalk(actor, cmd)) + player->mo->movedir = diags[((deltay<0)<<1)+(deltax>0)]; + if (player->mo->movedir != turnaround && TryWalk(cmd)) return; } @@ -186,16 +186,16 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) if (d[1]!=DI_NODIR) { - actor->movedir = d[1]; - if (TryWalk (actor, cmd)) + player->mo->movedir = d[1]; + if (TryWalk (cmd)) return; } if (d[2]!=DI_NODIR) { - actor->movedir = d[2]; + player->mo->movedir = d[2]; - if (TryWalk(actor, cmd)) + if (TryWalk(cmd)) return; } @@ -203,9 +203,9 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) // so pick another direction. if (olddir!=DI_NODIR) { - actor->movedir = olddir; + player->mo->movedir = olddir; - if (TryWalk(actor, cmd)) + if (TryWalk(cmd)) return; } @@ -218,9 +218,9 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) { if (tdir!=turnaround) { - actor->movedir = tdir; + player->mo->movedir = tdir; - if (TryWalk(actor, cmd)) + if (TryWalk(cmd)) return; } } @@ -233,9 +233,9 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) { if (tdir!=turnaround) { - actor->movedir = tdir; + player->mo->movedir = tdir; - if (TryWalk(actor, cmd)) + if (TryWalk(cmd)) return; } } @@ -243,12 +243,12 @@ void FCajunMaster::NewChaseDir (AActor *actor, ticcmd_t *cmd) if (turnaround != DI_NODIR) { - actor->movedir = turnaround; - if (TryWalk(actor, cmd)) + player->mo->movedir = turnaround; + if (TryWalk(cmd)) return; } - actor->movedir = DI_NODIR; // can not move + player->mo->movedir = DI_NODIR; // can not move } @@ -307,48 +307,48 @@ bool FCajunMaster::CleanAhead (AActor *thing, fixed_t x, fixed_t y, ticcmd_t *cm #define MAXTURN (15*ANGLE_1) //Max degrees turned in one tic. Lower is smother but may cause the bot not getting where it should = crash #define TURNSENS 3 //Higher is smoother but slower turn. -void FCajunMaster::TurnToAng (AActor *actor) +void DBot::TurnToAng () { int maxturn = MAXTURN; - if (actor->player->ReadyWeapon != NULL) + if (player->ReadyWeapon != NULL) { - if (actor->player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) + if (player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) { - if (actor->player->Bot->t_roam && !actor->player->Bot->missile) + if (t_roam && !missile) { //Keep angle that where when shot where decided. return; } } - if(actor->player->Bot->enemy) - if(!actor->player->Bot->dest) //happens when running after item in combat situations, or normal, prevents weak turns - if(actor->player->ReadyWeapon->ProjectileType == NULL && !(actor->player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)) - if(Check_LOS(actor, actor->player->Bot->enemy, SHOOTFOV+5*ANGLE_1)) + if(enemy) + if(!dest) //happens when running after item in combat situations, or normal, prevents weak turns + if(player->ReadyWeapon->ProjectileType == NULL && !(player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)) + if(Check_LOS(enemy, SHOOTFOV+5*ANGLE_1)) maxturn = 3; } - int distance = actor->player->Bot->angle - actor->angle; + int distance = angle - player->mo->angle; - if (abs (distance) < OKAYRANGE && !actor->player->Bot->enemy) + if (abs (distance) < OKAYRANGE && !enemy) return; distance /= TURNSENS; if (abs (distance) > maxturn) distance = distance < 0 ? -maxturn : maxturn; - actor->angle += distance; + player->mo->angle += distance; } -void FCajunMaster::Pitch (AActor *actor, AActor *target) +void DBot::Pitch (AActor *target) { double aim; double diff; - diff = target->z - actor->z; - aim = atan (diff / (double)P_AproxDistance (actor->x - target->x, actor->y - target->y)); - actor->pitch = -(int)(aim * ANGLE_180/M_PI); + diff = target->z - player->mo->z; + aim = atan (diff / (double)P_AproxDistance (player->mo->x - target->x, player->mo->y - target->y)); + player->mo->pitch = -(int)(aim * ANGLE_180/M_PI); } //Checks if a sector is dangerous. @@ -371,4 +371,3 @@ bool FCajunMaster::IsDangerous (sector_t *sec) || special == Damage_InstantDeath || special == sDamage_SuperHellslime; } - diff --git a/src/b_think.cpp b/src/b_think.cpp index e5ee8775c2..34baeee9c2 100644 --- a/src/b_think.cpp +++ b/src/b_think.cpp @@ -24,47 +24,49 @@ static FRandom pr_botmove ("BotMove"); //This function is called each tic for each bot, //so this is what the bot does. -void FCajunMaster::Think (AActor *actor, ticcmd_t *cmd) +void DBot::Think () { + ticcmd_t *cmd = &netcmds[player - players][((gametic + 1)/ticdup)%BACKUPTICS]; + memset (cmd, 0, sizeof(*cmd)); - if (actor->player->Bot->enemy && actor->player->Bot->enemy->health <= 0) - actor->player->Bot->enemy = NULL; + if (enemy && enemy->health <= 0) + enemy = NULL; - if (actor->health > 0) //Still alive + if (player->mo->health > 0) //Still alive { if (teamplay || !deathmatch) - actor->player->Bot->mate = Choose_Mate (actor); + mate = Choose_Mate (); - angle_t oldyaw = actor->angle; - int oldpitch = actor->pitch; + angle_t oldyaw = player->mo->angle; + int oldpitch = player->mo->pitch; - Set_enemy (actor); - ThinkForMove (actor, cmd); - TurnToAng (actor); + Set_enemy (); + ThinkForMove (cmd); + TurnToAng (); - cmd->ucmd.yaw = (short)((actor->angle - oldyaw) >> 16) / ticdup; - cmd->ucmd.pitch = (short)((oldpitch - actor->pitch) >> 16); + cmd->ucmd.yaw = (short)((player->mo->angle - oldyaw) >> 16) / ticdup; + cmd->ucmd.pitch = (short)((oldpitch - player->mo->pitch) >> 16); if (cmd->ucmd.pitch == -32768) cmd->ucmd.pitch = -32767; cmd->ucmd.pitch /= ticdup; - actor->angle = oldyaw + (cmd->ucmd.yaw << 16) * ticdup; - actor->pitch = oldpitch - (cmd->ucmd.pitch << 16) * ticdup; + player->mo->angle = oldyaw + (cmd->ucmd.yaw << 16) * ticdup; + player->mo->pitch = oldpitch - (cmd->ucmd.pitch << 16) * ticdup; } - if (actor->player->Bot->t_active) actor->player->Bot->t_active--; - if (actor->player->Bot->t_strafe) actor->player->Bot->t_strafe--; - if (actor->player->Bot->t_react) actor->player->Bot->t_react--; - if (actor->player->Bot->t_fight) actor->player->Bot->t_fight--; - if (actor->player->Bot->t_rocket) actor->player->Bot->t_rocket--; - if (actor->player->Bot->t_roam) actor->player->Bot->t_roam--; + if (t_active) t_active--; + if (t_strafe) t_strafe--; + if (t_react) t_react--; + if (t_fight) t_fight--; + if (t_rocket) t_rocket--; + if (t_roam) t_roam--; //Respawn ticker - if (actor->player->Bot->t_respawn) + if (t_respawn) { - actor->player->Bot->t_respawn--; + t_respawn--; } - else if (actor->health <= 0) + else if (player->mo->health <= 0) { // Time to respawn cmd->ucmd.buttons |= BT_USE; } @@ -72,62 +74,57 @@ void FCajunMaster::Think (AActor *actor, ticcmd_t *cmd) //how the bot moves. //MAIN movement function. -void FCajunMaster::ThinkForMove (AActor *actor, ticcmd_t *cmd) +void DBot::ThinkForMove (ticcmd_t *cmd) { - player_t *b; fixed_t dist; bool stuck; int r; - b = actor->player; - if (b->Bot == NULL) - return; - stuck = false; - dist = b->Bot->dest ? P_AproxDistance(actor->x-b->Bot->dest->x, actor->y-b->Bot->dest->y) : 0; + dist = dest ? P_AproxDistance(player->mo->x-dest->x, player->mo->y-dest->y) : 0; - if (b->Bot->missile && - ((!b->Bot->missile->velx || !b->Bot->missile->vely) || !Check_LOS(actor, b->Bot->missile, SHOOTFOV*3/2))) + if (missile && + ((!missile->velx || !missile->vely) || !Check_LOS(missile, SHOOTFOV*3/2))) { - b->Bot->sleft = !b->Bot->sleft; - b->Bot->missile = NULL; //Probably ended its travel. + sleft = !sleft; + missile = NULL; //Probably ended its travel. } - if (actor->pitch > 0) - actor->pitch -= 80; - else if (actor->pitch <= -60) - actor->pitch += 80; + if (player->mo->pitch > 0) + player->mo->pitch -= 80; + else if (player->mo->pitch <= -60) + player->mo->pitch += 80; //HOW TO MOVE: - if (b->Bot->missile && (P_AproxDistance(actor->x-b->Bot->missile->x, actor->y-b->Bot->missile->y)mo->x-missile->x, player->mo->y-missile->y)Bot->missile); - actor->player->Bot->angle = R_PointToAngle2(actor->x, actor->y, b->Bot->missile->x, b->Bot->missile->y); - cmd->ucmd.sidemove = b->Bot->sleft ? -SIDERUN : SIDERUN; + Pitch (missile); + angle = R_PointToAngle2(player->mo->x, player->mo->y, missile->x, missile->y); + cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; cmd->ucmd.forwardmove = -FORWARDRUN; //Back IS best. - if ((P_AproxDistance(actor->x-b->Bot->oldx, actor->y-b->Bot->oldy)<50000) - && b->Bot->t_strafe<=0) + if ((P_AproxDistance(player->mo->x-oldx, player->mo->y-oldy)<50000) + && t_strafe<=0) { - b->Bot->t_strafe = 5; - b->Bot->sleft = !b->Bot->sleft; + t_strafe = 5; + sleft = !sleft; } //If able to see enemy while avoiding missile, still fire at enemy. - if (b->Bot->enemy && Check_LOS (actor, b->Bot->enemy, SHOOTFOV)) - Dofire (actor, cmd); //Order bot to fire current weapon + if (enemy && Check_LOS (enemy, SHOOTFOV)) + Dofire (cmd); //Order bot to fire current weapon } - else if (b->Bot->enemy && P_CheckSight (actor, b->Bot->enemy, 0)) //Fight! + else if (enemy && P_CheckSight (player->mo, enemy, 0)) //Fight! { - Pitch (actor, b->Bot->enemy); + Pitch (enemy); //Check if it's more important to get an item than fight. - if (b->Bot->dest && (b->Bot->dest->flags&MF_SPECIAL)) //Must be an item, that is close enough. + if (dest && (dest->flags&MF_SPECIAL)) //Must be an item, that is close enough. { -#define is(x) b->Bot->dest->IsKindOf (PClass::FindClass (#x)) +#define is(x) dest->IsKindOf (PClass::FindClass (#x)) if ( ( - (actor->health < b->Bot->skill.isp && + (player->mo->health < skill.isp && (is (Medikit) || is (Stimpack) || is (Soulsphere) || @@ -140,78 +137,78 @@ void FCajunMaster::ThinkForMove (AActor *actor, ticcmd_t *cmd) is (Megasphere) ) || dist < (GETINCOMBAT/4) || - (b->ReadyWeapon == NULL || b->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON) + (player->ReadyWeapon == NULL || player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON) ) - && (dist < GETINCOMBAT || (b->ReadyWeapon == NULL || b->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) - && Reachable (actor, b->Bot->dest)) + && (dist < GETINCOMBAT || (player->ReadyWeapon == NULL || player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) + && Reachable (dest)) #undef is { goto roam; //Pick it up, no matter the situation. All bonuses are nice close up. } } - b->Bot->dest = NULL; //To let bot turn right + dest = NULL; //To let bot turn right - if (b->ReadyWeapon != NULL && !(b->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) - actor->flags &= ~MF_DROPOFF; //Don't jump off any ledges when fighting. + if (player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) + player->mo->flags &= ~MF_DROPOFF; //Don't jump off any ledges when fighting. - if (!(b->Bot->enemy->flags3 & MF3_ISMONSTER)) - b->Bot->t_fight = AFTERTICS; + if (!(enemy->flags3 & MF3_ISMONSTER)) + t_fight = AFTERTICS; - if (b->Bot->t_strafe <= 0 && - (P_AproxDistance(actor->x-b->Bot->oldx, actor->y-b->Bot->oldy)<50000 + if (t_strafe <= 0 && + (P_AproxDistance(player->mo->x-oldx, player->mo->y-oldy)<50000 || ((pr_botmove()%30)==10)) ) { stuck = true; - b->Bot->t_strafe = 5; - b->Bot->sleft = !b->Bot->sleft; + t_strafe = 5; + sleft = !sleft; } - b->Bot->angle = R_PointToAngle2(actor->x, actor->y, b->Bot->enemy->x, b->Bot->enemy->y); + angle = R_PointToAngle2(player->mo->x, player->mo->y, enemy->x, enemy->y); - if (b->ReadyWeapon == NULL || - P_AproxDistance(actor->x-b->Bot->enemy->x, actor->y-b->Bot->enemy->y) > - b->ReadyWeapon->MoveCombatDist) + if (player->ReadyWeapon == NULL || + P_AproxDistance(player->mo->x-enemy->x, player->mo->y-enemy->y) > + player->ReadyWeapon->MoveCombatDist) { // If a monster, use lower speed (just for cooler apperance while strafing down doomed monster) - cmd->ucmd.forwardmove = (b->Bot->enemy->flags3 & MF3_ISMONSTER) ? FORWARDWALK : FORWARDRUN; + cmd->ucmd.forwardmove = (enemy->flags3 & MF3_ISMONSTER) ? FORWARDWALK : FORWARDRUN; } else if (!stuck) //Too close, so move away. { // If a monster, use lower speed (just for cooler apperance while strafing down doomed monster) - cmd->ucmd.forwardmove = (b->Bot->enemy->flags3 & MF3_ISMONSTER) ? -FORWARDWALK : -FORWARDRUN; + cmd->ucmd.forwardmove = (enemy->flags3 & MF3_ISMONSTER) ? -FORWARDWALK : -FORWARDRUN; } //Strafing. - if (b->Bot->enemy->flags3 & MF3_ISMONSTER) //It's just a monster so take it down cool. + if (enemy->flags3 & MF3_ISMONSTER) //It's just a monster so take it down cool. { - cmd->ucmd.sidemove = b->Bot->sleft ? -SIDEWALK : SIDEWALK; + cmd->ucmd.sidemove = sleft ? -SIDEWALK : SIDEWALK; } else { - cmd->ucmd.sidemove = b->Bot->sleft ? -SIDERUN : SIDERUN; + cmd->ucmd.sidemove = sleft ? -SIDERUN : SIDERUN; } - Dofire (actor, cmd); //Order bot to fire current weapon + Dofire (cmd); //Order bot to fire current weapon } - else if (b->Bot->mate && !b->Bot->enemy && (!b->Bot->dest || b->Bot->dest==b->Bot->mate)) //Follow mate move. + else if (mate && !enemy && (!dest || dest==mate)) //Follow mate move. { fixed_t matedist; - Pitch (actor, b->Bot->mate); + Pitch (mate); - if (!Reachable (actor, b->Bot->mate)) + if (!Reachable (mate)) { - if (b->Bot->mate == b->Bot->dest && pr_botmove.Random() < 32) + if (mate == dest && pr_botmove.Random() < 32) { // [RH] If the mate is the dest, pick a new dest sometimes - b->Bot->dest = NULL; + dest = NULL; } goto roam; } - actor->player->Bot->angle = R_PointToAngle2(actor->x, actor->y, b->Bot->mate->x, b->Bot->mate->y); + angle = R_PointToAngle2(player->mo->x, player->mo->y, mate->x, mate->y); - matedist = P_AproxDistance(actor->x - b->Bot->mate->x, actor->y - b->Bot->mate->y); + matedist = P_AproxDistance(player->mo->x - mate->x, player->mo->y - mate->y); if (matedist > (FRIEND_DIST*2)) cmd->ucmd.forwardmove = FORWARDRUN; else if (matedist > FRIEND_DIST) @@ -221,42 +218,42 @@ void FCajunMaster::ThinkForMove (AActor *actor, ticcmd_t *cmd) } else //Roam after something. { - b->Bot->first_shot = true; + first_shot = true; ///// roam: ///// - if (b->Bot->enemy && Check_LOS (actor, b->Bot->enemy, SHOOTFOV*3/2)) //If able to see enemy while avoiding missile , still fire at it. - Dofire (actor, cmd); //Order bot to fire current weapon + if (enemy && Check_LOS (enemy, SHOOTFOV*3/2)) //If able to see enemy while avoiding missile , still fire at it. + Dofire (cmd); //Order bot to fire current weapon - if (b->Bot->dest && !(b->Bot->dest->flags&MF_SPECIAL) && b->Bot->dest->health < 0) + if (dest && !(dest->flags&MF_SPECIAL) && dest->health < 0) { //Roaming after something dead. - b->Bot->dest = NULL; + dest = NULL; } - if (b->Bot->dest == NULL) + if (dest == NULL) { - if (b->Bot->t_fight && b->Bot->enemy) //Enemy/bot has jumped around corner. So what to do? + if (t_fight && enemy) //Enemy/bot has jumped around corner. So what to do? { - if (b->Bot->enemy->player) + if (enemy->player) { - if (((b->Bot->enemy->player->ReadyWeapon != NULL && b->Bot->enemy->player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) || - (pr_botmove()%100)>b->Bot->skill.isp) && b->ReadyWeapon != NULL && !(b->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) - b->Bot->dest = b->Bot->enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy. - else //hide while b->t_fight, but keep view at enemy. - b->Bot->angle = R_PointToAngle2(actor->x, actor->y, b->Bot->enemy->x, b->Bot->enemy->y); + if (((enemy->player->ReadyWeapon != NULL && enemy->player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE) || + (pr_botmove()%100)>skill.isp) && player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)) + dest = enemy;//Dont let enemy kill the bot by supressive fire. So charge enemy. + else //hide while t_fight, but keep view at enemy. + angle = R_PointToAngle2(player->mo->x, player->mo->y, enemy->x, enemy->y); } //Just a monster, so kill it. else - b->Bot->dest = b->Bot->enemy; + dest = enemy; - //VerifFavoritWeapon(actor->player); //Dont know why here.., but it must be here, i know the reason, but not why at this spot, uh. + //VerifFavoritWeapon(player); //Dont know why here.., but it must be here, i know the reason, but not why at this spot, uh. } else //Choose a distant target. to get things going. { r = pr_botmove(); if (r < 128) { - TThinkerIterator it (STAT_INVENTORY, firstthing); + TThinkerIterator it (STAT_INVENTORY, bglobal.firstthing); AInventory *item = it.Next(); if (item != NULL || (item = it.Next()) != NULL) @@ -271,60 +268,53 @@ void FCajunMaster::ThinkForMove (AActor *actor, ticcmd_t *cmd) { item = it.Next(); } - firstthing = item; - b->Bot->dest = item; + bglobal.firstthing = item; + dest = item; } } - else if (b->Bot->mate && (r < 179 || P_CheckSight(actor, b->Bot->mate))) + else if (mate && (r < 179 || P_CheckSight(player->mo, mate))) { - b->Bot->dest = b->Bot->mate; + dest = mate; } else if ((playeringame[(r&(MAXPLAYERS-1))]) && players[(r&(MAXPLAYERS-1))].mo->health > 0) { - b->Bot->dest = players[(r&(MAXPLAYERS-1))].mo; + dest = players[(r&(MAXPLAYERS-1))].mo; } } - if (b->Bot->dest) + if (dest) { - b->Bot->t_roam = MAXROAM; + t_roam = MAXROAM; } } - if (b->Bot->dest) + if (dest) { //Bot has a target so roam after it. - Roam (actor, cmd); + Roam (cmd); } } //End of movement main part. - if (!b->Bot->t_roam && b->Bot->dest) + if (!t_roam && dest) { - b->Bot->prev = b->Bot->dest; - b->Bot->dest = NULL; + prev = dest; + dest = NULL; } - if (b->Bot->t_fight<(AFTERTICS/2)) - actor->flags |= MF_DROPOFF; + if (t_fight<(AFTERTICS/2)) + player->mo->flags |= MF_DROPOFF; - b->Bot->oldx = actor->x; - b->Bot->oldy = actor->y; + oldx = player->mo->x; + oldy = player->mo->y; } //BOT_WhatToGet // //Determines if the bot will roam after an item or not. -void FCajunMaster::WhatToGet (AActor *actor, AActor *item) +void DBot::WhatToGet (AActor *item) { - player_t *b = actor->player; - - if (b == NULL) - { - return; - } - #define typeis(x) item->IsKindOf (PClass::FindClass (#x)) if ((item->renderflags & RF_INVISIBLE) //Under respawn and away. - || item == b->Bot->prev) + || item == prev) { return; } @@ -338,7 +328,7 @@ void FCajunMaster::WhatToGet (AActor *actor, AActor *item) // FIXME AWeapon *heldWeapon; - heldWeapon = static_cast (b->mo->FindInventory (item->GetClass())); + heldWeapon = static_cast (player->mo->FindInventory (item->GetClass())); if (heldWeapon != NULL) { if (!weapgiveammo) @@ -354,39 +344,38 @@ void FCajunMaster::WhatToGet (AActor *actor, AActor *item) { AAmmo *ammo = static_cast (item); const PClass *parent = ammo->GetParentAmmo (); - AInventory *holdingammo = b->mo->FindInventory (parent); + AInventory *holdingammo = player->mo->FindInventory (parent); if (holdingammo != NULL && holdingammo->Amount >= holdingammo->MaxAmount) { return; } } - else if ((typeis (Megasphere) || typeis (Soulsphere) || typeis (HealthBonus)) && actor->health >= deh.MaxSoulsphere) + else if ((typeis (Megasphere) || typeis (Soulsphere) || typeis (HealthBonus)) && player->mo->health >= deh.MaxSoulsphere) return; - else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && actor->health >= deh.MaxHealth /*MAXHEALTH*/) + else if (item->IsKindOf (RUNTIME_CLASS(AHealth)) && player->mo->health >= deh.MaxHealth /*MAXHEALTH*/) return; - if ((b->Bot->dest == NULL || - !(b->Bot->dest->flags & MF_SPECIAL)/* || - !Reachable (actor, b->dest)*/)/* && - Reachable (actor, item)*/) // Calling Reachable slows this down tremendously + if ((dest == NULL || + !(dest->flags & MF_SPECIAL)/* || + !Reachable (dest)*/)/* && + Reachable (item)*/) // Calling Reachable slows this down tremendously { - b->Bot->prev = b->Bot->dest; - b->Bot->dest = item; - b->Bot->t_roam = MAXROAM; + prev = dest; + dest = item; + t_roam = MAXROAM; } } -void FCajunMaster::Set_enemy (AActor *actor) +void DBot::Set_enemy () { AActor *oldenemy; - AActor **enemy = &actor->player->Bot->enemy; - if (*enemy - && (*enemy)->health > 0 - && P_CheckSight (actor, *enemy)) + if (enemy + && enemy->health > 0 + && P_CheckSight (player->mo, enemy)) { - oldenemy = *enemy; + oldenemy = enemy; } else { @@ -395,15 +384,14 @@ void FCajunMaster::Set_enemy (AActor *actor) // [RH] Don't even bother looking for a different enemy if this is not deathmatch // and we already have an existing enemy. - if (deathmatch || !*enemy) + if (deathmatch || !enemy) { - actor->player->Bot->allround = !!*enemy; - *enemy = NULL; - *enemy = Find_enemy(actor); - if (!*enemy) - *enemy = oldenemy; //Try go for last (it will be NULL if there wasn't anyone) + allround = !!enemy; + enemy = Find_enemy(); + if (!enemy) + enemy = oldenemy; //Try go for last (it will be NULL if there wasn't anyone) } //Verify that that enemy is really something alive that bot can kill. - if (*enemy && (((*enemy)->health < 0 || !((*enemy)->flags&MF_SHOOTABLE)) || actor->IsFriend(*enemy))) - *enemy = NULL; + if (enemy && ((enemy->health < 0 || !(enemy->flags&MF_SHOOTABLE)) || player->mo->IsFriend(enemy))) + enemy = NULL; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index cf6bccc8a9..557f5fa941 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3259,7 +3259,7 @@ void AActor::Tick () else if (flags & MF_SPECIAL) { //Item pickup time //clock (BotWTG); - bglobal.WhatToGet (players[i].mo, this); + players[i].Bot->WhatToGet (this); //unclock (BotWTG); BotWTG++; } @@ -3267,7 +3267,7 @@ void AActor::Tick () { if (!players[i].Bot->missile && (flags3 & MF3_WARNBOT)) { //warn for incoming missiles. - if (target != players[i].mo && bglobal.Check_LOS (players[i].mo, this, ANGLE_90)) + if (target != players[i].mo && players[i].Bot->Check_LOS (this, ANGLE_90)) players[i].Bot->missile = this; } }