Skip to content

Commit

Permalink
Added CTF bots
Browse files Browse the repository at this point in the history
  • Loading branch information
SpookyScaryDev committed Sep 18, 2024
1 parent 787ae73 commit 4d552fe
Show file tree
Hide file tree
Showing 31 changed files with 1,506 additions and 164 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ set(SRC_COMMON
"${DIR_SRC}/maps_map_dm3.c"
"${DIR_SRC}/maps_map_dm4.c"
"${DIR_SRC}/maps_map_dm6.c"
"${DIR_SRC}/maps_map_e2m2.c"
"${DIR_SRC}/maps_map_povdmm4.c"
"${DIR_SRC}/marker_load.c"
"${DIR_SRC}/marker_util.c"
Expand Down
26 changes: 20 additions & 6 deletions include/fb_globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ extern gedict_t *dropper;
#define FB_PREFER_ROCKET_LAUNCHER 1
#define FB_PREFER_LIGHTNING_GUN 2

#define FB_CTF_ROLE_ATTACK 0
#define FB_CTF_ROLE_MIDFIELD 1
#define FB_CTF_ROLE_DEFEND 2

#define GAME_ENABLE_POWERUPS 1
#define GAME_ENABLE_RUNES 2
#define GAME_RUNE_RJ 4
Expand Down Expand Up @@ -132,6 +136,9 @@ extern gedict_t *dropper;
#define BOTPATH_CURLJUMP_HINT (1 << 23)
#define BOTPATH_FULL_AIRCONTROL (1 << 24)
#define BOTPATH_RJ_IN_PROGRESS (1 << 25)
#define HOOK (1 << 26)
#define LOOK_BUTTON (1 << 27) // Indicates path which points to a button to shoot
#define FIRE_BUTTON (1 << 28) // Set when a bot should try shooting a button
#define DELIBERATE_AIR_WAIT_GROUND (DELIBERATE_AIR | WAIT_GROUND)
#define SAVED_DESCRIPTION (DM6_DOOR | ROCKET_JUMP | JUMP_LEDGE | VERTICAL_PLATFORM | BOTPATH_DOOR | BOTPATH_DOOR_CLOSED | NO_DODGE)
#define NOT_ROCKET_JUMP (~ROCKET_JUMP)
Expand All @@ -149,6 +156,10 @@ extern gedict_t *dropper;
#define MARKER_DYNAMICALLY_ADDED 256 // Added dynamically by server. Do not include in .bot file generation
#define MARKER_EXPLICIT_VIEWOFFSET 512 // Viewoffset has been set by map definition and should be included in .bot file generation
#define MARKER_NOTOUCH 1024 // Not touchable - used when two markers on top of each other
#define MARKER_FLAG1_DEFEND 2048 // Point used to defend flag 1 (red)
#define MARKER_FLAG2_DEFEND 4096 // Point used to defend flag 1 (blue)
#define MARKER_LOOK_BUTTON 8192 // A button can be shot from this marker - set automatically
#define MARKER_E2M2_DISCHARGE 16384 // Bots on red team will run here then discharge at the start of the map

// Bot flags (FIXME: fb.state? check. consistent naming, comment with descriptions)
#define CAMPBOT 1
Expand All @@ -169,6 +180,7 @@ float boomstick_only(void);

float CountTeams(void);
qbool EnemyDefenceless(gedict_t *self);
qbool EnemyHasFlag (gedict_t* self);

qbool enemy_shaft_attack(gedict_t *self, gedict_t *enemy);
float W_BestWeapon(void);
Expand All @@ -181,6 +193,7 @@ float WeaponCode(float w);
float crandom(void);

void BotCanRocketJump(gedict_t *self);
void BotCanHook(gedict_t *self);
qbool VisibleEntity(gedict_t *ent);
gedict_t* IdentifyMostVisibleTeammate(gedict_t *self);
float anglemod(float v);
Expand Down Expand Up @@ -237,11 +250,11 @@ gedict_t* HigherSightFromFunction(gedict_t *from_marker, gedict_t *to_marker);
gedict_t* SightFromMarkerFunction(gedict_t *from_marker, gedict_t *to_marker);
gedict_t* SubZoneNextPathMarker(gedict_t *from_marker, gedict_t *to_marker);
float SubZoneArrivalTime(float zone_time, gedict_t *middle_marker, gedict_t *to_marker,
qbool rl_routes);
qbool rl_routes, qbool hook_routes);
float SightFromTime(gedict_t *from_marker, gedict_t *to_marker);
void ZoneMarker(gedict_t *from_marker, gedict_t *to_marker, qbool path_normal, qbool rj_routes);
void ZoneMarker(gedict_t *from_marker, gedict_t *to_marker, qbool path_normal, qbool rj_routes, qbool hook_routes);
gedict_t* ZonePathMarker(gedict_t *from_marker, gedict_t *to_marker, qbool path_normal,
qbool rl_jump_routes);
qbool rl_jump_routes, qbool hook_routes);

// botweap.qc
void FrogbotSetFirepower(gedict_t *self);
Expand All @@ -267,6 +280,7 @@ void BotDamageInflictedEvent(gedict_t *attacker, gedict_t *targ);
void CheckCombatJump(gedict_t *self);
//void BotInLava(void);
void BotPerformRocketJump(gedict_t *self);
void BotPerformHook(gedict_t *self);

// botgoal.qc
void UpdateGoal(gedict_t *self);
Expand All @@ -288,8 +302,8 @@ void SetMarkerPathFlags(int marker_number, int path_index, int flags);
void SetMarkerPath(int source_marker, int path_index, int next_marker);
void SetMarkerViewOffset(int marker, float zOffset);

#define FROGBOT_PATH_FLAG_OPTIONS "w6rjva"
#define FROGBOT_MARKER_FLAG_OPTIONS "u6fbte"
#define FROGBOT_PATH_FLAG_OPTIONS "w6rjvahl"
#define FROGBOT_MARKER_FLAG_OPTIONS "u6fbte12"

// added for ktx
qbool fb_lg_disabled(void);
Expand Down Expand Up @@ -343,7 +357,7 @@ void SetJumpFlag(gedict_t *player, qbool jumping, const char *explanation);
void PathScoringLogic(float goal_respawn_time, qbool be_quiet, float lookahead_time,
qbool path_normal, vec3_t player_origin, vec3_t player_direction,
gedict_t *touch_marker_, gedict_t *goalentity_marker, qbool rocket_alert,
qbool rocket_jump_routes_allowed, qbool trace_bprint, gedict_t *player,
qbool rocket_jump_routes_allowed, qbool hook_routes_allowed, qbool trace_bprint, gedict_t *player,
float *best_score, gedict_t **linked_marker_, int *new_path_state,
int *new_angle_hint, int *new_rj_frame_delay, float new_rj_angles[2]);

Expand Down
1 change: 1 addition & 0 deletions include/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ void RegenFlags(qbool yes);
void AddHook(qbool yes);
void CTF_Obituary(gedict_t *targ, gedict_t *attacker);
void CTF_CheckFlagsAsKeys(void);
void TossFlag(void);

// logs.c
void log_open(const char *fmt, ...) PRINTF_FUNC(1);
Expand Down
20 changes: 19 additions & 1 deletion include/progs.h
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ typedef void (*fb_entity_funcref_t)(struct gedict_s* item);
#define NUMBER_PATHS 8
#endif
#ifndef NUMBER_SUBZONES
#define NUMBER_SUBZONES 32
#define NUMBER_SUBZONES 128 // TODO hiipe - check this, should be ok though?
#endif

typedef struct fb_runaway_route_s {
Expand All @@ -433,6 +433,7 @@ typedef struct fb_path_s {
struct gedict_s* next_marker; // next marker in the graph
float time; // time to travel if walking (0 if teleporting)
float rj_time; // time to travel if using rocket jump
float hook_time; // time to travel if using hook
int flags; // hints on how to travel to next marker

short angle_hint; // When travelling to marker, offset to standard angle (+ = anti-clockwise)
Expand All @@ -445,14 +446,18 @@ typedef struct fb_goal_s {
struct gedict_s* next_marker;
float time;
struct gedict_s* next_marker_rj;
struct gedict_s* next_marker_hook;
float rj_time;
float hook_time;
} fb_goal_t;

typedef struct fb_subzone_s {
struct gedict_s* next_marker;
float time;
struct gedict_s* next_marker_rj;
struct gedict_s* next_marker_hook;
float rj_time;
float hook_time;
} fb_subzone_t;

typedef struct fb_zone_s {
Expand All @@ -467,6 +472,11 @@ typedef struct fb_zone_s {
float rj_time;
struct gedict_s* next_rj;

// Hook
struct gedict_s* marker_hook;
float hook_time;
struct gedict_s* next_hook;

float reverse_time;
struct gedict_s* reverse_marker;
struct gedict_s* reverse_next;
Expand Down Expand Up @@ -525,6 +535,8 @@ typedef struct fb_botskill_s {
float combat_jump_chance;
float missile_dodge_time; // minimum time in seconds before bot dodges missile

int ctf_role; // attack, midfield or defense

qbool customised; // if set, customised file

qbool wiggle_run_dmm4; // if set, wiggle run on dmm4 (and up)
Expand Down Expand Up @@ -686,6 +698,12 @@ typedef struct fb_entvars_s {
int rocketJumpAngles[2]; // pitch/yaw for rocket jump angle
int lavaJumpState; // keep track of submerge/rise/fire sequence

// Hook logic
qbool canHook;
qbool hooking;
struct gedict_s* hookTarget;
vec3_t hookOldPosition;

// Editor
int last_jump_frame; // framecount when player last jumped. used to help setting rj fields

Expand Down
26 changes: 21 additions & 5 deletions src/bot_aim.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define ATTACK_RESPAWN_TIME 3

qbool DM6FireAtDoor(gedict_t *self, vec3_t rel_pos);
qbool E2M2DischargeLogic(gedict_t* self);
static void BotsModifyAimAtPlayerLogic(gedict_t *self);

static void BotSetDesiredAngles(gedict_t *self, vec3_t rel_pos)
Expand Down Expand Up @@ -50,11 +51,11 @@ static void BotSetDesiredAngles(gedict_t *self, vec3_t rel_pos)
static void BotStopFiring(gedict_t *bot)
{
qbool continuous = bot->fb.desired_weapon_impulse == 4 || bot->fb.desired_weapon_impulse == 5
|| bot->fb.desired_weapon_impulse == 8;
|| bot->fb.desired_weapon_impulse == 8 || bot->fb.desired_weapon_impulse == 22;
qbool correct_weapon = BotUsingCorrectWeapon(bot);
qbool enemy_alive = bot->s.v.enemy && ISLIVE(&g_edicts[bot->s.v.enemy]);

bot->fb.firing &= (continuous && correct_weapon && enemy_alive) || bot->fb.rocketJumping;
bot->fb.firing &= (continuous && correct_weapon && enemy_alive) || bot->fb.rocketJumping || bot->fb.hooking;
}

// Magic numbers here: 400 = 0.5 * sv_gravity
Expand Down Expand Up @@ -143,6 +144,16 @@ static void BotsFireAtWorldLogic(gedict_t *self, vec3_t rel_pos, float *rel_dist
return;
}

if (E2M2DischargeLogic(self))
{
return;
}

if (self->fb.path_state & FIRE_BUTTON)
{
return;
}

if (*rel_dist < 160)
{
vec3_t rel_pos2;
Expand Down Expand Up @@ -477,7 +488,7 @@ void BotsFireLogic(void)
AttackRespawns(self);

// a_attackfix()
if (!self->fb.rocketJumping && (self->s.v.enemy == 0) && !(self->fb.state & SHOT_FOR_LUCK))
if (!self->fb.rocketJumping && !self->fb.hooking && (self->s.v.enemy == 0) && !(self->fb.state & SHOT_FOR_LUCK) && !E2M2DischargeLogic(self))
{
self->fb.firing = false;
}
Expand All @@ -497,13 +508,18 @@ void BotsFireLogic(void)

BotsAimAtFloor(self, rel_pos, rel_dist);

if (!self->fb.rocketJumping)
if (!self->fb.rocketJumping && !self->fb.hooking)
{
SetFireButton(self, rel_pos, rel_dist);
SetFireButton(self, rel_pos, rel_dist);
}

BotSetDesiredAngles(self, rel_pos);
}

if (E2M2DischargeLogic(self))
{
self->fb.firing = true;
}
}

#endif // BOT_SUPPORT
9 changes: 6 additions & 3 deletions src/bot_botenemy.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,9 @@ static void BestEnemy_apply(gedict_t *test_enemy, float *best_score, gedict_t **
look_marker = SightFromMarkerFunction(from_marker, to_marker);
if (look_marker != NULL)
{
ZoneMarker(from_marker, look_marker, path_normal, test_enemy->fb.canRocketJump);
ZoneMarker(from_marker, look_marker, path_normal, test_enemy->fb.canRocketJump, test_enemy->fb.canHook);
traveltime = SubZoneArrivalTime(zone_time, middle_marker, look_marker,
test_enemy->fb.canRocketJump);
test_enemy->fb.canRocketJump, test_enemy->fb.canHook);
enemy_score = traveltime + g_random();
}
else
Expand All @@ -134,7 +134,10 @@ static void BestEnemy_apply(gedict_t *test_enemy, float *best_score, gedict_t **
enemy_score = look_traveltime + g_random();
}

if (enemy_score < *best_score && look_marker != NULL)
// Prioritize enemy with flag
if (test_enemy->ctf_flag & CTF_FLAG) enemy_score /= 2;

if (enemy_score < *best_score && look_marker != NULL) // TODO hiipe - crashes here sometimes! Surely it should be possible for look_marker to be NULL?
{
vec3_t marker_view;
vec3_t to_marker_view;
Expand Down
Loading

0 comments on commit 4d552fe

Please sign in to comment.