-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ctf Frogbots #365
base: master
Are you sure you want to change the base?
Ctf Frogbots #365
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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) | ||
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably gain a better name than There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be nice with MARKER_DISCHARGE_AT_START_RED, MARKER_DISCHARGE_AT_START_BLUE to make it generic for any map and team. Would require some other flag character as 'd' is taken. yay nasty char flags. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But even changing it to MARKER_DISCHARGE_AT_START_RED would be a good start at making it generic, moving maps_map_e2m2.c to bot_discharge_start.c, changing functions to DischargeAtStartLogic etc. |
||
|
||
// Bot flags (FIXME: fb.state? check. consistent naming, comment with descriptions) | ||
#define CAMPBOT 1 | ||
|
@@ -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); | ||
|
@@ -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); | ||
|
@@ -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); | ||
|
@@ -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); | ||
|
@@ -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); | ||
|
@@ -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]); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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? | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All arrays indexed by subzones uses this for size, so I can't find any reason for why this wouldn't be fine. Perhaps read through and verify yourself to remove your uncertainties, and finally the comment. It will only spread uncertainties for the next person reading it. |
||
#endif | ||
|
||
typedef struct fb_runaway_route_s { | ||
|
@@ -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) | ||
|
@@ -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 { | ||
|
@@ -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; | ||
|
@@ -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) | ||
|
@@ -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 | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,7 @@ | |
#define ATTACK_RESPAWN_TIME 3 | ||
|
||
qbool DM6FireAtDoor(gedict_t *self, vec3_t rel_pos); | ||
qbool E2M2DischargeLogic(gedict_t* self); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as the define name, get rid of map specific names in favor of more explanatory names. It's a generic feature that only happens to be commonly associated with e2m2. |
||
static void BotsModifyAimAtPlayerLogic(gedict_t *self); | ||
|
||
static void BotSetDesiredAngles(gedict_t *self, vec3_t rel_pos) | ||
|
@@ -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 | ||
|
@@ -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; | ||
|
@@ -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; | ||
} | ||
|
@@ -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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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) | ||
// Prioritize enemy with flag | ||
if (test_enemy->ctf_flag & CTF_FLAG) enemy_score /= 2; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Think the general style of the codebase is to always have newline + braces. 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; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps move LOOK_BUTTON and FIRE_BUTTON to 26 resp 27 (or I guess leave the 26 hook gap as it will be filled by this PR later), and open a separate PR for adding these to trim down the PR size given that they provide standalone functionality to bots.