Base: Weapons now track weight (for Weapons_SwitchBest)

BotLib: Add CreateObjective() method that can be overridden
This commit is contained in:
Marco Cawthorne 2021-05-12 15:42:20 +02:00
parent eb3603335e
commit c5cea7a162
11 changed files with 137 additions and 33 deletions

View file

@ -78,7 +78,6 @@ MultiplayerRules::PlayerSpawn(base_player pp)
setmodel(pl, pl.model);
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
pl.view_ofs = VEC_PLAYER_VIEWPOS;
pl.velocity = [0,0,0];
pl.gravity = __NULL__;
pl.frame = 1;

View file

@ -44,7 +44,6 @@ SingleplayerRules::PlayerSpawn(base_player pl)
setmodel(pl, pl.model);
setsize(pl, VEC_HULL_MIN, VEC_HULL_MAX);
pl.view_ofs = VEC_PLAYER_VIEWPOS;
pl.velocity = [0,0,0];
pl.gravity = __NULL__;
pl.frame = 1;

View file

@ -21,6 +21,7 @@ typedef struct
int slot;
int slot_pos;
int allow_drop;
int weight; /* required for bestweapon */
void(void) draw;
void(void) holster;
@ -29,6 +30,7 @@ typedef struct
void(void) reload;
void(void) release;
void(void) crosshair;
int(void) isempty; /* kinda handy */
void(void) precache;
int(int, int) pickup;
@ -47,6 +49,7 @@ void Weapons_Release(void);
float Weapons_GetAim(int);
void Weapons_Reload(void);
int Weapons_IsEmpty(player, int);
void Weapons_DrawCrosshair(void);
void Weapons_MakeVectors(void);
vector Weapons_GetCameraPos(void);

View file

@ -14,6 +14,12 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
var int g_weapon_weights[g_weapons.length];
#ifdef CLIENT
var int g_weapon_order[g_weapons.length];
#endif
void
Weapons_Init(void)
{
@ -46,6 +52,68 @@ Weapons_Init(void)
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].precache != __NULL__)
g_weapons[i].precache();
/* check our weapon weights */
int max = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].weight > max)
max = g_weapons[i].weight;
/* don't bother building the list if we've got no weights */
if (max <= 0)
return;
/* position in the weight array */
int w = 0;
/* loop through all weights */
for (int b = 0; b <= max; b++) {
/* loop through all weapons */
for (int i = 0; i < g_weapons.length; i++) {
/* if we've found a valid weight, add the weapon to the list */
if (g_weapons[i].weight == b) {
g_weapon_weights[w] = i;
w++;
}
}
}
#if 1
for (int i = 0; i < g_weapons.length; i++)
print(sprintf("Weapon-Weight order: %s, %i\n", g_weapons[g_weapon_weights[i]].name, i));
#endif
#ifdef CLIENT
/* build our slot-order table */
int st = 0;
int max_slots = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].slot > max_slots)
max_slots = g_weapons[i].slot;
int max_pos = 0;
for (int i = 0; i < g_weapons.length; i++)
if (g_weapons[i].slot_pos > max_pos)
max_pos = g_weapons[i].slot_pos;
/* loop through all slots */
for (int s = 0; s <= max_slots; s++) {
/* loop through all positions */
for (int p = 0; p < max_pos; p++) {
/* loop through all the weapons */
for (int i = 0; i < g_weapons.length; i++) {
if (g_weapons[i].slot == s && g_weapons[i].slot_pos == p) {
g_weapon_order[st] = i;
st++;
}
}
}
}
#if 0
for (int i = 0; i < g_weapons.length; i++)
print(sprintf("Weapon-List order: %s, %i\n", g_weapons[g_weapon_order[i]].name, i));
#endif
#endif
}
void
@ -172,6 +240,23 @@ Weapons_Release(void)
pl.gflags &= ~GF_SEMI_TOGGLED;
}
int
Weapons_IsEmpty(player pl, int w)
{
int i = pl.activeweapon;
int r = 0;
entity oself = self;
self = pl;
if (g_weapons[i].isempty != __NULL__)
r = g_weapons[i].isempty();
self = oself;
return (r);
}
void
Weapons_DrawCrosshair(void)
{

View file

@ -47,6 +47,8 @@ class bot:player
void(void) bot;
virtual void(string) ChatSay;
virtual void(string) ChatSayTeam;
virtual void(void) Pain;
virtual void(void) RouteClear;
virtual void(void) WeaponThink;
@ -54,6 +56,7 @@ class bot:player
virtual void(void) SeeThink;
virtual void(int, int) BrainThink;
virtual void(void) RunAI;
virtual void(void) CreateObjective;
virtual void(void) CheckRoute;
virtual void(void) PreFrame;
virtual void(void) PostFrame;

View file

@ -17,6 +17,25 @@
#define BOTROUTE_DESTINATION -1
#define BOTROUTE_END -2
void SV_SendChat(entity sender, string msg, entity eEnt, float fType);
void
bot::ChatSay(string msg)
{
SV_SendChat(this, msg, world, 0);
}
void
bot::ChatSayTeam(string msg)
{
entity a;
for (a = world; (a = find(a, ::classname, "player"));) {
if (a.team == this.team) {
SV_SendChat(self, msg, a, 1);
}
}
}
void
bot::Pain(void)
{
@ -43,7 +62,7 @@ bot::WeaponThink(void)
{
/* clip empty */
if (a_ammo1 == 0) {
/* still got ammo left */
/* still got ammo left, reload! */
if (a_ammo2 != 0) {
input_buttons &= ~INPUT_BUTTON0;
input_buttons |= INPUT_BUTTON4;
@ -260,6 +279,12 @@ bot::CheckRoute(void)
}
}
void
bot::CreateObjective(void)
{
route_calculate(this, Route_SelectDestination(this), 0, Bot_RouteCB);
}
void
bot::RunAI(void)
{
@ -286,7 +311,7 @@ bot::RunAI(void)
/* create our first route */
if (!m_iNodes && autocvar_bot_aimless == 0) {
route_calculate(this, Route_SelectDestination(this), 0, Bot_RouteCB);
CreateObjective();
dprint(sprintf("bot::RunAI: %s is calculating first bot route\n",
this.netname));

View file

@ -34,7 +34,7 @@ Spawn_ObserverCam(base_player pl)
eTarget = find(world, ::targetname, eCamera.target);
if (eTarget) {
pl.angles = vectoangles(eTarget.origin - eCamera.origin);
pl.angles[0] *= -1;
//pl.angles[0] *= -1;
}
}
} else {
@ -43,14 +43,7 @@ Spawn_ObserverCam(base_player pl)
if (eCamera) {
pl.origin = eCamera.origin;
if (eCamera.target) {
eTarget = find(world, ::targetname, eCamera.target);
if (eTarget) {
pl.angles = vectoangles(eTarget.origin - eCamera.origin);
pl.angles[0] *= -1;
}
}
pl.angles = eCamera.angles;
}
}

View file

@ -79,9 +79,7 @@ Weapons_RefreshAmmo(base_player pl)
=================
Weapons_SwitchBest
Really basic function that cycles through the highest-to-lowest
weapon ID order and picks the next available item with no regard to
ammo, or any sort of weighting system. FIXME
Switch to the 'best' weapon according to our weight system.
=================
*/
void
@ -91,8 +89,9 @@ Weapons_SwitchBest(base_player pl)
self = pl;
for (float i = g_weapons.length - 1; i >= 1 ; i--) {
if (pl.g_items & g_weapons[i].id) {
pl.activeweapon = i;
int x = g_weapon_weights[i];
if ((pl.g_items & g_weapons[x].id) && (!Weapons_IsEmpty((player)pl, x))) {
pl.activeweapon = x;
break;
}
}

View file

@ -47,15 +47,6 @@ const vector VEC_HULL_MAX = [16,16,36];
const vector VEC_CHULL_MIN = [-16,-16,-18];
const vector VEC_CHULL_MAX = [16,16,18];
/* Counter-Strike players are hunched over a little bit */
#ifdef CSTRIKE
const vector VEC_PLAYER_VIEWPOS = [0,0,20];
const vector VEC_PLAYER_CVIEWPOS = [0,0,12];
#else
const vector VEC_PLAYER_VIEWPOS = [0,0,24];
const vector VEC_PLAYER_CVIEWPOS = [0,0,12];
#endif
// Actually used by input_button etc.
#define INPUT_BUTTON0 0x00000001
#define INPUT_BUTTON2 0x00000002

View file

@ -62,6 +62,14 @@
#define PMOVE_STEP_RUNSPEED 220
#endif
#ifndef PHY_VIEWPOS
#define PHY_VIEWPOS [0,0,24]
#endif
#ifndef PHY_VIEWPOS_CROUCHED
#define PHY_VIEWPOS_CROUCHED [0,0,12]
#endif
/* if they're undefined by a config, they'll be set by the game/mod default */
var float autocvar_sv_stepheight = PMOVE_STEPHEIGHT;
var float autocvar_sv_airstepheight = PMOVE_AIRSTEPHEIGHT;
@ -146,11 +154,11 @@ PMove_Categorize(void)
if (self.flags & FL_CROUCHING) {
self.mins = VEC_CHULL_MIN;
self.maxs = VEC_CHULL_MAX;
self.view_ofs = VEC_PLAYER_CVIEWPOS;
self.view_ofs = PHY_VIEWPOS_CROUCHED;
} else {
self.mins = VEC_HULL_MIN;
self.maxs = VEC_HULL_MAX;
self.view_ofs = VEC_PLAYER_VIEWPOS;
self.view_ofs = PHY_VIEWPOS;
}
tracebox(self.origin, self.mins, self.maxs, self.origin - [0,0,1], MOVE_NORMAL, self);
@ -289,7 +297,7 @@ PMove_AccelMove(float move_time, float premove)
if (self.flags & FL_CROUCHING) {
setsize(self, VEC_CHULL_MIN, VEC_CHULL_MAX);
self.view_ofs = VEC_PLAYER_CVIEWPOS;
self.view_ofs = PHY_VIEWPOS_CROUCHED;
} else {
setsize(self, VEC_HULL_MIN, VEC_HULL_MAX);
if (iFixCrouch && QPMove_IsStuck(self, [0,0,0], VEC_HULL_MIN, VEC_HULL_MAX)) {
@ -301,7 +309,7 @@ PMove_AccelMove(float move_time, float premove)
}
}
setorigin(self, self.origin);
self.view_ofs = VEC_PLAYER_VIEWPOS;
self.view_ofs = PHY_VIEWPOS;
}
}

View file

@ -251,7 +251,6 @@ spectator::InputPrevious(void)
spec_ent = best;
#endif
print(sprintf("dddd: %d\n", spec_ent));
spec_flags |= GF_SEMI_TOGGLED;
WarpToTarget();
@ -374,7 +373,7 @@ void
spectator::spectator(void)
{
modelindex = 0;
flags = 0;
flags = FL_CLIENT;
solid = SOLID_NOT;
movetype = MOVETYPE_NOCLIP;
think = __NULL__;