- removed the bot related properties from AWeapon.

This stuff is now kept locally in the bot code so that it doesn't infest the rest of the engine.
And please don't read the new botsupp.txt file as some new means to configure bots! This was merely done to get this data out of the way.
The bots are still broken beyond repair and virtually unusable, even if proper data is provided for all weapons.
This commit is contained in:
Christoph Oelckers 2018-11-24 23:48:23 +01:00
parent ead28db007
commit 8eb4697fbd
10 changed files with 131 additions and 89 deletions

View file

@ -47,6 +47,7 @@
#include "d_net.h"
#include "serializer.h"
#include "d_player.h"
#include "w_wad.h"
#include "vm.h"
IMPLEMENT_CLASS(DBot, false, true)
@ -246,69 +247,61 @@ CCMD (listbots)
// set the bot specific weapon information
// This is intentionally not in the weapon definition anymore.
BotInfoMap BotInfo;
void InitBotStuff()
{
static struct BotInit
int lump;
int lastlump = 0;
while (-1 != (lump = Wads.FindLump("BOTSUPP", &lastlump)))
{
const char *type;
int movecombatdist;
int weaponflags;
const char *projectile;
} botinits[] = {
{ "Pistol", 25000000, 0, NULL },
{ "Shotgun", 24000000, 0, NULL },
{ "SuperShotgun", 15000000, 0, NULL },
{ "Chaingun", 27000000, 0, NULL },
{ "RocketLauncher", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "Rocket" },
{ "PlasmaRifle", 27000000, 0, "PlasmaBall" },
{ "BFG9000", 10000000, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_BFG, "BFGBall" },
{ "GoldWand", 25000000, 0, NULL },
{ "GoldWandPowered", 25000000, 0, NULL },
{ "Crossbow", 24000000, 0, "CrossbowFX1" },
{ "CrossbowPowered", 24000000, 0, "CrossbowFX2" },
{ "Blaster", 27000000, 0, NULL },
{ "BlasterPowered", 27000000, 0, "BlasterFX1" },
{ "SkullRod", 27000000, 0, "HornRodFX1" },
{ "SkullRodPowered", 27000000, 0, "HornRodFX2" },
{ "PhoenixRod", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "PhoenixFX1" },
{ "Mace", 27000000, WIF_BOT_REACTION_SKILL_THING, "MaceFX2" },
{ "MacePowered", 27000000, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "MaceFX4" },
{ "FWeapHammer", 22000000, 0, "HammerMissile" },
{ "FWeapQuietus", 20000000, 0, "FSwordMissile" },
{ "CWeapStaff", 25000000, 0, "CStaffMissile" },
{ "CWeapFlane", 27000000, 0, "CFlameMissile" },
{ "MWeapWand", 25000000, 0, "MageWandMissile" },
{ "CWeapWraithverge", 22000000, 0, "HolyMissile" },
{ "MWeapFrost", 19000000, 0, "FrostMissile" },
{ "MWeapLightning", 23000000, 0, "LightningFloor" },
{ "MWeapBloodscourge", 20000000, 0, "MageStaffFX2" },
{ "StrifeCrossbow", 24000000, 0, "ElectricBolt" },
{ "StrifeCrossbow2", 24000000, 0, "PoisonBolt" },
{ "AssaultGun", 27000000, 0, NULL },
{ "MiniMissileLauncher", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "MiniMissile" },
{ "FlameThrower", 24000000, 0, "FlameMissile" },
{ "Mauler", 15000000, 0, NULL },
{ "Mauler2", 10000000, 0, "MaulerTorpedo" },
{ "StrifeGrenadeLauncher", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "HEGrenade" },
{ "StrifeGrenadeLauncher2", 18350080, WIF_BOT_REACTION_SKILL_THING|WIF_BOT_EXPLOSIVE, "PhosphorousGrenade" },
};
for(unsigned i=0;i<sizeof(botinits)/sizeof(botinits[0]);i++)
{
const PClass *cls = PClass::FindClass(botinits[i].type);
if (cls != NULL && cls->IsDescendantOf(NAME_Weapon))
FScanner sc(lump);
sc.SetCMode(true);
while (sc.GetString())
{
AWeapon *w = (AWeapon*)GetDefaultByType(cls);
if (w != NULL)
PClassActor *wcls = PClass::FindActor(sc.String);
if (wcls != NULL && wcls->IsDescendantOf(NAME_Weapon))
{
w->MoveCombatDist = botinits[i].movecombatdist/65536.;
w->WeaponFlags |= botinits[i].weaponflags;
w->ProjectileType = PClass::FindActor(botinits[i].projectile);
BotInfoData bi = {};
sc.MustGetStringName(",");
sc.MustGetNumber();
bi.MoveCombatDist = sc.Number;
while (sc.CheckString(","))
{
sc.MustGetString();
if (sc.Compare("BOT_REACTION_SKILL_THING"))
{
bi.flags |= BIF_BOT_REACTION_SKILL_THING;
}
else if (sc.Compare("BOT_EXPLOSIVE"))
{
bi.flags |= BIF_BOT_EXPLOSIVE;
}
else if (sc.Compare("BOT_BFG"))
{
bi.flags |= BIF_BOT_BFG;
}
else
{
PClassActor *cls = PClass::FindActor(sc.String);
bi.projectileType = cls;
if (cls == nullptr)
{
sc.ScriptError("Unknown token %s", sc.String);
}
}
}
BotInfo[wcls->TypeName] = bi;
}
else
{
sc.ScriptError("%s is not a weapon type", sc.String);
}
}
}
// Fixme: Export these, too.
static const char *warnbotmissiles[] = { "PlasmaBall", "Ripper", "HornRodFX1" };
for(unsigned i=0;i<countof(warnbotmissiles);i++)
{

View file

@ -13,6 +13,7 @@
#include "d_protocol.h"
#include "r_defs.h"
#include "a_pickups.h"
#include "a_weapons.h"
#include "stats.h"
#define FORWARDWALK 0x1900
@ -49,6 +50,7 @@
#define MMAXSELECT 100 //Maximum number of monsters that can be selected at a time.
struct FCheckPosition;
class AWeapon;
struct botskill_t
{
@ -78,6 +80,34 @@ struct botinfo_t
int lastteam;
};
struct BotInfoData
{
int MoveCombatDist = 0;
int flags = 0;
PClassActor *projectileType = nullptr;
};
enum
{
BIF_BOT_REACTION_SKILL_THING = 1,
BIF_BOT_EXPLOSIVE = 2,
BIF_BOT_BFG = 4,
};
using BotInfoMap = TMap<FName, BotInfoData>;
extern BotInfoMap BotInfo;
inline BotInfoData GetBotInfo(AWeapon *weap)
{
if (weap == nullptr) return BotInfoData();
auto k = BotInfo.CheckKey(weap->GetClass()->TypeName);
if (k) return *k;
return BotInfoData();
}
//Used to keep all the globally needed variables in nice order.
class FCajunMaster
{

View file

@ -188,7 +188,7 @@ void DBot::Dofire (ticcmd_t *cmd)
//Reaction skill thing.
if (first_shot &&
!(player->ReadyWeapon->WeaponFlags & WIF_BOT_REACTION_SKILL_THING))
!(GetBotInfo(player->ReadyWeapon).flags & BIF_BOT_REACTION_SKILL_THING))
{
t_react = (100-skill.reaction+1)/((pr_botdofire()%3)+3);
}
@ -203,21 +203,21 @@ void DBot::Dofire (ticcmd_t *cmd)
Dist = player->mo->Distance2D(enemy, player->mo->Vel.X - enemy->Vel.X, player->mo->Vel.Y - enemy->Vel.Y);
//FIRE EACH TYPE OF WEAPON DIFFERENT: Here should all the different weapons go.
if (player->ReadyWeapon->WeaponFlags & WIF_MELEEWEAPON)
if (GetBotInfo(player->ReadyWeapon).MoveCombatDist == 0)
{
//*4 is for atmosphere, the chainsaws sounding and all..
no_fire = (Dist > DEFMELEERANGE*4);
}
else if (player->ReadyWeapon->WeaponFlags & WIF_BOT_BFG)
else if (GetBotInfo(player->ReadyWeapon).flags & BIF_BOT_BFG)
{
//MAKEME: This should be smarter.
if ((pr_botdofire()%200)<=skill.reaction)
if(Check_LOS(enemy, SHOOTFOV))
no_fire = false;
}
else if (player->ReadyWeapon->ProjectileType != NULL)
else if (GetBotInfo(player->ReadyWeapon).projectileType != NULL)
{
if (player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE)
if (GetBotInfo(player->ReadyWeapon).flags & BIF_BOT_EXPLOSIVE)
{
//Special rules for RL
an = FireRox (enemy, cmd);
@ -234,7 +234,7 @@ void DBot::Dofire (ticcmd_t *cmd)
}
// prediction aiming
Dist = player->mo->Distance2D(enemy);
fm = Dist / GetDefaultByType (player->ReadyWeapon->ProjectileType)->Speed;
fm = Dist / GetDefaultByType (GetBotInfo(player->ReadyWeapon).projectileType)->Speed;
bglobal.SetBodyAt(enemy->Pos() + enemy->Vel.XY() * fm * 2, 1);
Angle = player->mo->AngleTo(bglobal.body1);
if (Check_LOS (enemy, SHOOTFOV))

View file

@ -345,7 +345,7 @@ void DBot::TurnToAng ()
if (player->ReadyWeapon != NULL)
{
if (player->ReadyWeapon->WeaponFlags & WIF_BOT_EXPLOSIVE)
if (GetBotInfo(player->ReadyWeapon).flags & BIF_BOT_EXPLOSIVE)
{
if (t_roam && !missile)
{ //Keep angle that where when shot where decided.
@ -356,7 +356,7 @@ void DBot::TurnToAng ()
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(GetBotInfo(player->ReadyWeapon).projectileType == NULL && GetBotInfo(player->ReadyWeapon).MoveCombatDist > 0)
if(Check_LOS(enemy, SHOOTFOV+5))
maxturn = 3;
}

View file

@ -173,9 +173,9 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
is (Megasphere)
) ||
dist < (GETINCOMBAT/4) ||
(player->ReadyWeapon == NULL || player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)
(GetBotInfo(player->ReadyWeapon).MoveCombatDist == 0)
)
&& (dist < GETINCOMBAT || (player->ReadyWeapon == NULL || player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON))
&& (dist < GETINCOMBAT || (GetBotInfo(player->ReadyWeapon).MoveCombatDist == 0))
&& Reachable (dest))
#undef is
{
@ -185,7 +185,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
dest = NULL; //To let bot turn right
if (player->ReadyWeapon != NULL && !(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON))
if (GetBotInfo(player->ReadyWeapon).MoveCombatDist == 0)
player->mo->flags &= ~MF_DROPOFF; //Don't jump off any ledges when fighting.
if (!(enemy->flags3 & MF3_ISMONSTER))
@ -205,7 +205,7 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
if (player->ReadyWeapon == NULL ||
player->mo->Distance2D(enemy) >
player->ReadyWeapon->MoveCombatDist)
GetBotInfo(player->ReadyWeapon).MoveCombatDist)
{
// If a monster, use lower speed (just for cooler apperance while strafing down doomed monster)
cmd->ucmd.forwardmove = (enemy->flags3 & MF3_ISMONSTER) ? FORWARDWALK : FORWARDRUN;
@ -273,8 +273,8 @@ void DBot::ThinkForMove (ticcmd_t *cmd)
{
if (enemy->player)
{
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))
if (((enemy->player->ReadyWeapon != NULL && GetBotInfo(enemy->player->ReadyWeapon).flags & BIF_BOT_EXPLOSIVE) ||
(pr_botmove()%100)>skill.isp) && (GetBotInfo(player->ReadyWeapon).MoveCombatDist != 0))
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 = player->mo->AngleTo(enemy);

View file

@ -68,12 +68,9 @@ DEFINE_FIELD(AWeapon, YAdjust)
DEFINE_FIELD(AWeapon, UpSound)
DEFINE_FIELD(AWeapon, ReadySound)
DEFINE_FIELD(AWeapon, SisterWeaponType)
DEFINE_FIELD(AWeapon, ProjectileType)
DEFINE_FIELD(AWeapon, AltProjectileType)
DEFINE_FIELD(AWeapon, SelectionOrder)
DEFINE_FIELD(AWeapon, MinSelAmmo1)
DEFINE_FIELD(AWeapon, MinSelAmmo2)
DEFINE_FIELD(AWeapon, MoveCombatDist)
DEFINE_FIELD(AWeapon, ReloadCounter)
DEFINE_FIELD(AWeapon, BobStyle)
DEFINE_FIELD(AWeapon, BobSpeed)
@ -184,9 +181,6 @@ void AWeapon::Serialize(FSerializer &arc)
("ammotype1", AmmoType1, def->AmmoType1)
("ammotype2", AmmoType2, def->AmmoType2)
("sisterweapontype", SisterWeaponType, def->SisterWeaponType)
("projectiletype", ProjectileType, def->ProjectileType)
("altprojectiletype", AltProjectileType, def->AltProjectileType)
("movecombatdist", MoveCombatDist, def->MoveCombatDist)
*/
}

View file

@ -142,11 +142,8 @@ public:
float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double)
FSoundIDNoInit UpSound, ReadySound; // Sounds when coming up and idle
PClassActor *SisterWeaponType; // Another weapon to pick up with this one
PClassActor *ProjectileType; // Projectile used by primary attack
PClassActor *AltProjectileType; // Projectile used by alternate attack
int SelectionOrder; // Lower-numbered weapons get picked first
int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo
double MoveCombatDist; // Used by bots, but do they *really* need it?
int ReloadCounter; // For A_CheckForReload
int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double)
float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs.
@ -210,11 +207,5 @@ enum
WIF_NODEATHDESELECT = 0x00020000, // Don't jump to the Deselect state when the player dies
WIF_NODEATHINPUT = 0x00040000, // The weapon cannot be fired/reloaded/whatever when the player is dead
WIF_CHEATNOTWEAPON = 0x08000000, // Give cheat considers this not a weapon (used by Sigil)
// Flags used only by bot AI:
WIF_BOT_REACTION_SKILL_THING = 1<<31, // I don't understand this
WIF_BOT_EXPLOSIVE = 1<<30, // weapon fires an explosive
WIF_BOT_BFG = 1<<28, // this is a BFG
};

View file

@ -456,9 +456,7 @@ static FFlagDef WeaponFlagDefs[] =
DEFINE_FLAG(WIF, WIMPY_WEAPON, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, POWERED_UP, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, STAFF2_KICKBACK, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF_BOT, EXPLOSIVE, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, MELEEWEAPON, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF_BOT, BFG, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, CHEATNOTWEAPON, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, NO_AUTO_SWITCH, AWeapon, WeaponFlags),
DEFINE_FLAG(WIF, AMMO_CHECKBOTH, AWeapon, WeaponFlags),
@ -469,6 +467,8 @@ static FFlagDef WeaponFlagDefs[] =
DEFINE_DUMMY_FLAG(NOLMS, false),
DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL, false),
DEFINE_DUMMY_FLAG(BFG, true),
DEFINE_DUMMY_FLAG(EXPLOSIVE, true),
};

37
wadsrc/static/botsupp.txt Normal file
View file

@ -0,0 +1,37 @@
// This is just a straight dump of an internal table. Contents are: Weapon type, distance coefficient, optional flags and an optional projectile type.
Pistol, 25000000
Shotgun, 24000000
SuperShotgun, 15000000
Chaingun, 27000000
RocketLauncher, 18350080, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, Rocket
PlasmaRifle, 27000000, PlasmaBall
BFG9000, 10000000, BOT_REACTION_SKILL_THING, BOT_BFG, BFGBall
GoldWand, 25000000
GoldWandPowered, 25000000
Crossbow, 24000000, CrossbowFX1
CrossbowPowered, 24000000, CrossbowFX2
Blaster, 27000000
BlasterPowered, 27000000, BlasterFX1
SkullRod, 27000000, HornRodFX1
SkullRodPowered, 27000000, HornRodFX2
PhoenixRod, 18350080, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, PhoenixFX1
Mace, 27000000, BOT_REACTION_SKILL_THING, MaceFX2
MacePowered, 27000000, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, MaceFX4
FWeapHammer, 22000000, HammerMissile
FWeapQuietus, 20000000, FSwordMissile
CWeapStaff, 25000000, CStaffMissile
CWeapFlame, 27000000, CFlameMissile
MWeapWand, 25000000, MageWandMissile
CWeapWraithverge, 22000000, HolyMissile
MWeapFrost, 19000000, FrostMissile
MWeapLightning, 23000000, LightningFloor
MWeapBloodscourge, 20000000, MageStaffFX2
StrifeCrossbow, 24000000, ElectricBolt
StrifeCrossbow2, 24000000, PoisonBolt
AssaultGun, 27000000
MiniMissileLauncher, 18350080, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, MiniMissile
FlameThrower, 24000000, FlameMissile
Mauler, 15000000
Mauler2, 10000000, MaulerTorpedo
StrifeGrenadeLauncher, 18350080, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, HEGrenade
StrifeGrenadeLauncher2, 18350080, BOT_REACTION_SKILL_THING, BOT_EXPLOSIVE, PhosphorousGrenade

View file

@ -13,17 +13,14 @@ class Weapon : StateProvider native
native uint WeaponFlags;
native class<Ammo> AmmoType1, AmmoType2; // Types of ammo used by self weapon
native int AmmoGive1, AmmoGive2; // Amount of each ammo to get when picking up weapon
native int MinAmmo1, MinAmmo2; // Minimum ammo needed to switch to self weapon
native int MinAmmo1, MinAmmo2; // not used anywhere.
native int AmmoUse1, AmmoUse2; // How much ammo to use with each shot
native int Kickback;
native float YAdjust; // For viewing the weapon fullscreen (visual only so no need to be a double)
native sound UpSound, ReadySound; // Sounds when coming up and idle
native class<Weapon> SisterWeaponType; // Another weapon to pick up with self one
native class<Actor> ProjectileType; // Projectile used by primary attack
native class<Actor> AltProjectileType; // Projectile used by alternate attack
native int SelectionOrder; // Lower-numbered weapons get picked first
native int MinSelAmmo1, MinSelAmmo2; // Ignore in BestWeapon() if inadequate ammo
native double MoveCombatDist; // Used by bots, but do they *really* need it?
native int ReloadCounter; // For A_CheckForReload
native int BobStyle; // [XA] Bobbing style. Defines type of bobbing (e.g. Normal, Alpha) (visual only so no need to be a double)
native float BobSpeed; // [XA] Bobbing speed. Defines how quickly a weapon bobs.