From f4f6e897b37db39e9d68ad4d46ff04d75106c2b9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 22 Aug 2003 06:35:19 +0000 Subject: [PATCH] yay for type checking (I think). now the bots are /really/ screwed :( --- fbxa/bot_ai.qc | 226 +++++++++++++++++++--------------------------- fbxa/bot_fight.qc | 16 ++-- fbxa/bot_way.qc | 58 ++---------- fbxa/libfrikbot.h | 20 ++-- fbxa/target.r | 94 +++++++++++++++++++ fbxa/waypoint.r | 42 +++++---- 6 files changed, 238 insertions(+), 218 deletions(-) diff --git a/fbxa/bot_ai.qc b/fbxa/bot_ai.qc index 7a1b029..ba3bf74 100644 --- a/fbxa/bot_ai.qc +++ b/fbxa/bot_ai.qc @@ -144,14 +144,14 @@ Bot has lost its target. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ --(void)lost:(Waypoint)targ :(integer)success +-(void)lost:(Target)targ :(integer)success { if (!targ) return; [self targetDrop:targ]; - if (targ.ent.classname == "waypoint") - targ.b_sound &= ~b_clientflag; + if ([targ isKindOfClass:[Waypoint class]]) + ((Waypoint)targ).b_sound &= ~b_clientflag; // find a new route if (!success) { @@ -174,8 +174,8 @@ Bot has lost its target. } } - if (targ.ent.classname != "player") - targ.search_time = time + 5; + //XXX if (targ.ent.classname != "player") + //XXX targ.search_time = time + 5; } /* @@ -188,7 +188,7 @@ removed. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ --(void)checkLost:(Waypoint)targ +-(void)checkLost:(Target)targ { local vector dist; @@ -199,65 +199,71 @@ removed. dist_z = 0; // waypoints and items are lost if you get close enough to them - if (targ.ent.flags & FL_ITEM) { - if (vlen (targ.ent.origin - ent.origin) < 32) - [self lost:targ :TRUE]; - else if (!targ.ent.model) - [self lost:targ :TRUE]; - } else if (targ.ent.classname == "waypoint") { + if ([targ isKindOfClass:[Waypoint class]]) { + local Waypoint way = (Waypoint) targ; if (!(b_aiflags & (AI_SNIPER | AI_AMBUSH))) { if (b_aiflags & AI_RIDE_TRAIN) { - if (vlen (targ.origin - ent.origin) < 48) - [self lost:targ :TRUE]; + if (vlen (way.origin - ent.origin) < 48) + [self lost:way :TRUE]; } else if (b_aiflags & AI_PRECISION) { - if (vlen (targ.origin - ent.origin) < 24) - [self lost:targ :TRUE]; - } else if (vlen (targ.origin - ent.origin) < 32) - [self lost:targ :TRUE]; + if (vlen (way.origin - ent.origin) < 24) + [self lost:way :TRUE]; + } else if (vlen (way.origin - ent.origin) < 32) + [self lost:way :TRUE]; } - } else if (targ.ent.classname == "temp_waypoint") { - if (vlen (targ.origin - ent.origin) < 32) - [self lost:targ :TRUE]; - } else if (targ.ent.classname == "player") { - if (targ.ent.health <= 0) - [self lost:targ :TRUE]; - else if ((coop) || (teamplay && targ.ent.team == ent.team)) { - if (targ.targets[0].ent.classname == "player") { - if (![targ.targets[0] ishuman]) - [self lost:targ :TRUE]; - } else if (targ.ent.teleport_time > time) { + //temp_waypoint + if (vlen (way.origin - ent.origin) < 32) + [self lost:way :TRUE]; + } else if ([targ isKindOfClass:[Bot class]]) { + local Bot bot = (Bot) targ; + if (bot.ent.health <= 0) + [self lost:bot :TRUE]; + else if ((coop) || (teamplay && bot.ent.team == ent.team)) { + if (bot.targets[0].ent.classname == "player") { + if (![bot.targets[0] ishuman]) + [self lost:bot :TRUE]; + } else if (bot.ent.teleport_time > time) { // try not to telefrag teammates keys &= ~KEY_MOVE; - } else if (vlen (targ.origin - ent.origin) < 128) { - if (vlen (targ.origin - ent.origin) < 48) - [self walkmove: ent.origin - targ.origin]; + } else if (vlen (bot.ent.origin - ent.origin) < 128) { + if (vlen (bot.ent.origin - ent.origin) < 48) + [self walkmove: ent.origin - bot.ent.origin]; else { keys &= ~KEY_MOVE; [self startTopic:4]; } ent.search_time = time + 5; // never time out - } else if (![self canSee:targ]) - [self lost:targ :FALSE]; + } else if (![self canSee:bot]) + [self lost:bot :FALSE]; } else if (waypoint_mode > WM_LOADED) { - if (vlen (targ.origin - ent.origin) < 128) { - [self lost:targ :TRUE]; + if (vlen (bot.ent.origin - ent.origin) < 128) { + [self lost:bot :TRUE]; } } - } else if (targ.ent.classname == "func_button") { - // buttons are lost of their frame changes - if (targ.ent.frame) { - [self lost:targ :TRUE]; - if (ent.enemy == targ.ent) - ent.enemy = NIL; -// if (target[0]) -// [self getPath:target[0] :TRUE]; - } - } else if ((targ.ent.movetype == MOVETYPE_NONE) && (targ.ent.solid == SOLID_TRIGGER)) { - // trigger_multiple style triggers are lost if their thinktime changes - if (targ.ent.nextthink >= time) { - [self lost:targ :TRUE]; -// if (target[0]) -// [self getPath:target[0] :TRUE]; + } else { + if (targ.ent.flags & FL_ITEM) { + if (vlen (targ.ent.origin - ent.origin) < 32) + [self lost:targ :TRUE]; + else if (!targ.ent.model) + [self lost:targ :TRUE]; + } else if (targ.ent.classname == "func_button") { + // buttons are lost of their frame changes + if (targ.ent.frame) { + [self lost:targ :TRUE]; + if (ent.enemy == targ.ent) + ent.enemy = NIL; + // if (target[0]) + // [self getPath:target[0] :TRUE]; + } + } else if ((targ.ent.movetype == MOVETYPE_NONE) + && (targ.ent.solid == SOLID_TRIGGER)) { + // trigger_multiple style triggers are lost if their thinktime + // changes + if (targ.ent.nextthink >= time) { + [self lost:targ :TRUE]; + // if (target[0]) + // [self getPath:target[0] :TRUE]; + } } } // lose any target way above the bot's head @@ -512,99 +518,49 @@ the bot finds things it wants to kill/grab. // *!* Make sure you add code to checkLost to remove the target *!* --(float)priorityForThing:(Target)thing +-(integer)priority:(Bot)bot { - local float thisp; + local integer p; - thisp = 0; - // This is the most executed function in the bot. Careful what you do here. - if ((thing.flags & FL_ITEM) && thing.model && thing.search_time < time) { - // ugly hack - //XXX if (thing._last != ent) - //XXX thisp = 20; - if (thing.classname == "item_artifact_super_damage") - thisp = 65; - else if (thing.classname == "item_artifact_invulnerability") - thisp = 65; - else if (thing.classname == "item_health") { - if (thing.spawnflags & 2) - thisp = 55; - if (ent.health < 40) - thisp = thisp + 50; - } else if (thing.model == "progs/armor.mdl") { - if (ent.armorvalue < 200) { - if (thing.skin == 2) - thisp = 60; - else if (ent.armorvalue < 100) - thisp = thisp + 25; - } - } else if (thing.classname == "weapon_supershotgun") { - if (!(ent.items & IT_SUPER_SHOTGUN)) - thisp = 25; - } else if (thing.classname == "weapon_nailgun") { - if (!(ent.items & IT_NAILGUN)) - thisp = 30; - } else if (thing.classname == "weapon_supernailgun") { - if (!(ent.items & IT_SUPER_NAILGUN)) - thisp = 35; - } else if (thing.classname == "weapon_grenadelauncher") { - if (!(ent.items & IT_GRENADE_LAUNCHER)) - thisp = 45; - } else if (thing.classname == "weapon_rocketlauncher") { - if (!(ent.items & IT_ROCKET_LAUNCHER)) - thisp = 60; - } else if (thing.classname == "weapon_lightning") { - if (!(ent.items & IT_LIGHTNING)) - thisp = 50; - } - } else if ((thing.flags & FL_MONSTER) && thing.health > 0) - thisp = 45; - else if (thing.classname == "player") { - if (thing.health > 0) { - if (thing == ent) - return 0; - else { - if (thing.items & IT_INVISIBILITY) //FIXME - thisp = 2; - else if (coop) { - thisp = 100; - //XXX if (thing.targets[0].classname == "player") - //XXX if (!thing.targets[0].ishuman) - //XXX return 0; - } else if (teamplay && thing.team == ent.team) { - thisp = 100; - //XXX if (thing.targets[0].classname == "player") - //XXX return 0; - } else - thisp = 30; - } - } - } else if (thing.classname == "waypoint") { - //XXX if (thing.b_aiflags & AI_SNIPER) - //XXX thisp = 30; - //XXX else if (thing.b_aiflags & AI_AMBUSH) - //XXX thisp = 30; - } - if (pointcontents (thing.origin) < -3) + if (ent.health <= 0) return 0; - if (thisp) { - /*XXX - if (thing.current_way) { - // check to see if it's unreachable - if (thing.current_way.items == -1) + if (ent.items & IT_INVISIBILITY) //FIXME + p = 2; + else if (coop) { + if (targets[0].ent.classname == "player") + if (![targets[0] ishuman]) return 0; - else - thisp += (13000 - thing.current_way.items) * 0.05; - } - */ - } - return thisp; + p = 100; + } else if (teamplay && ent.team == bot.ent.team) { + if (targets[0].ent.classname == "player") + return 0; + p = 100; + } else + p = 30; + + if (current_way) { + // check to see if it's unreachable + if (current_way.items == -1) + return 0; + else + p += (integer) ((13000 - current_way.items) * 0.05); + } + return p; +} + +-(integer)priorityForThing:(Target)thing +{ + // This is the most executed function in the bot. Careful what you do here. + if (pointcontents ([thing origin]) < -3) + return 0; + return [thing priority:self]; } -(void)lookForCrap:(integer)scope { local Target foe, best = NIL; - local float thatp, bestp, dist; + local integer thatp, bestp; + local float dist; if (scope == 1) foe = [Target forEntity:findradius (ent.origin, 13000)]; diff --git a/fbxa/bot_fight.qc b/fbxa/bot_fight.qc index f276cdb..09de148 100644 --- a/fbxa/bot_fight.qc +++ b/fbxa/bot_fight.qc @@ -77,9 +77,10 @@ weapon_range = }; @implementation Bot (Fight) --(float)sizePlayer:(entity)e +-(float)sizePlayer:(Target)targ { local float sz; + local entity e = targ.ent; sz = e.health + e.armorvalue * e.armortype; switch (e.weapon) { @@ -134,7 +135,7 @@ weapon_range = if (ent.enemy) { v = ent.origin - realorigin (ent.enemy); foedist = vlen (v); - foesz = [self sizePlayer:ent.enemy]; + foesz = [self sizePlayer:[Target forEntity:ent.enemy]]; } else { foedist = 3000; foesz = 9999999; @@ -184,9 +185,10 @@ weapon_range = if (foe.health > 0) { flen = vlen (foe.origin - ent.origin); if (flen < foedist) { - tsz = [self sizePlayer:foe]; + local Target targ = [Target forEntity:foe]; + tsz = [self sizePlayer:targ]; if (tsz < foesz) { - if ([self canSee:foe]) { + if ([self canSee:targ]) { ent.enemy = foe; foedist = flen; foesz = tsz; @@ -316,7 +318,7 @@ attacking an enemy. } else if (!ent.enemy.takedamage) { ent.enemy = NIL; return; - } else if (![self canSee:ent.enemy]) { + } else if (![self canSee:[Target forEntity:ent.enemy]]) { ent.enemy = NIL; return; } @@ -340,7 +342,7 @@ attacking an enemy. [self weaponSwitch:foedist]; if (!(b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) { - foesz = [self sizePlayer:ent.enemy]; + foesz = [self sizePlayer:[Target forEntity:ent.enemy]]; mysz = [self sizePlayer:self] + 5; if (foesz > mysz) { @@ -378,7 +380,7 @@ attacking an enemy. [self walkmove:v_right * -1]; } } else { - foesz = [self sizePlayer:ent.enemy]; + foesz = [self sizePlayer:[Target forEntity:ent.enemy]]; mysz = [self sizePlayer:self] + 5; if (foesz > mysz) diff --git a/fbxa/bot_way.qc b/fbxa/bot_way.qc index 85290ce..cdd21bb 100644 --- a/fbxa/bot_way.qc +++ b/fbxa/bot_way.qc @@ -50,49 +50,6 @@ integer bot_way_linker; @implementation Bot (Way) -/* -FindWaypoint - -This is used quite a bit, by many different -functions big lag causer - -Finds the closest, fisible, waypoint to e -*/ --(Waypoint)findWaypoint:(Waypoint)start -{ - local Waypoint best, t; - local float dst, tdst; - local vector org; - local integer count, i; - - org = realorigin (ent); - - if (start) { - dst = vlen (start.origin - org); - best = start; - } else { - dst = 100000; - best = NIL; - } - count = [waypoint_array count]; - for (i = 0; i < count; i++) { - t = [waypoint_array getItemAt:i]; - // real players cut through ignore types - if (dst < 20) - return best; - if (!(t.flags & AI_IGNORE_TYPES) || ishuman) { - tdst = vlen (t.origin - org); - if (tdst < dst) { - if (sisible (ent, t.ent)) { - dst = tdst; - best = t; - } - } - } - } - return best; -} - -(void)deleteWaypoint:(Waypoint)what { if (current_way == what) @@ -181,19 +138,18 @@ different bot. */ --(void)markPath:(entity)this +-(void)markPath:(Target)this { local Waypoint t; local integer flag; - local Bot bot = (Bot)this.@this; [Waypoint clearMyRoute:self]; - t = [this.@this findWaypoint:bot.current_way]; + t = [this findWaypoint:this.current_way]; // FIXME // ugh, better way to find players please!!! - if (this.classname != "player") - bot.current_way = t; + if (this.ent.classname != "player") + this.current_way = t; if (t.enemy == NIL) { [self lost:this :FALSE]; @@ -260,7 +216,7 @@ Boy it's confusing. } } --(void)getPath:(Waypoint)this :(integer)direct +-(void)getPath:(Target)this :(integer)direct { if (this == NIL) return; @@ -389,8 +345,8 @@ very good all things considered. local integer i; for (i = 0; i < 4; i++) { - if (way.targets[i]) { - DeveloperLightning (way, way.targets[i], + if (way.links[i]) { + DeveloperLightning (way, way.links[i], way.flags & (AI_TELELINK_1 << i)); } } diff --git a/fbxa/libfrikbot.h b/fbxa/libfrikbot.h index d53e8a8..59f23b1 100644 --- a/fbxa/libfrikbot.h +++ b/fbxa/libfrikbot.h @@ -11,6 +11,8 @@ typedef struct bot_data_t bot_data_t; @interface Target: Entity { +@public + Waypoint current_way; } +(Target)forEntity:(entity)ent; -(vector)realorigin; @@ -19,12 +21,14 @@ typedef struct bot_data_t bot_data_t; -(void)setOrigin:(vector) org; -(integer)recognizePlat:(integer)flag; -(integer)ishuman; +-(integer)priority:(Bot)bot; +-(Waypoint)findWaypoint:(Waypoint)start; @end @interface Waypoint: Target { @public - Waypoint [4] targets; + Waypoint [4] links; integer flags; vector origin; @@ -97,7 +101,6 @@ typedef struct bot_data_t bot_data_t; float dyn_time; Waypoint temp_way; Waypoint last_way; - Waypoint current_way; Target [4] targets; entity avoid; vector obs_dir; @@ -148,18 +151,18 @@ typedef struct bot_data_t bot_data_t; -(integer)targetOnstack:(Target)scot; -(void)targetAdd:(Target)e; -(void)targetDrop:(Target)e; --(void)lost:(Waypoint)targ :(integer)success; --(void)checkLost:(Waypoint)targ; +-(void)lost:(Target)targ :(integer)success; +-(void)checkLost:(Target)targ; -(void)handleAI; -(void)path; --(float)priorityForThing:(Target)thing; -(void)lookForCrap:(integer)scope; -(void)angleSet; -(void)AI; +-(integer)priorityForThing:(Target)thing; @end @interface Bot (Fight) --(float)sizePlayer:(entity)e; +-(float)sizePlayer:(Target)targ; -(void)dodgeStuff; -(void)weaponSwitch:(float)brange; -(void)shoot; @@ -167,12 +170,11 @@ typedef struct bot_data_t bot_data_t; @end @interface Bot (Way) --(Waypoint)findWaypoint:(Waypoint)start; -(void)deleteWaypoint:(Waypoint)what; -(entity)findThing:(string)s; -(Waypoint)findRoute:(Waypoint)lastone; --(void)markPath:(entity)this; --(void)getPath:(Waypoint)this :(integer)direct; +-(void)markPath:(Target)this; +-(void)getPath:(Target)this :(integer)direct; -(integer)beginRoute; -(void)spawnTempWaypoint:(vector)org; -(void)dynamicWaypoint; diff --git a/fbxa/target.r b/fbxa/target.r index 5d57cb9..15c5c1d 100644 --- a/fbxa/target.r +++ b/fbxa/target.r @@ -73,6 +73,9 @@ struct target_s = { local Target t; local struct target_s ele; + if (!ent) + return NIL; + if (ent.classname == "player") return ent.@this; @@ -138,4 +141,95 @@ struct target_s = { return 0; } +-(integer)priority:(Bot)bot +{ + if ((ent.flags & FL_ITEM) && ent.model && ent.search_time < time) { + // ugly hack + //XXX if (ent._last != bot) + //XXX thisp = 20; + if (ent.classname == "item_artifact_super_damage") + return 65; + else if (ent.classname == "item_artifact_invulnerability") + return 65; + else if (ent.classname == "item_health") { + if (ent.spawnflags & 2) + return 55; + if (bot.ent.health < 40) + return 55 + 50; + } else if (ent.model == "progs/armor.mdl") { + if (bot.ent.armorvalue < 200) { + if (ent.skin == 2) + return 60; + else if (bot.ent.armorvalue < 100) + return 60 + 25; + } + } else if (ent.classname == "weapon_supershotgun") { + if (!(bot.ent.items & IT_SUPER_SHOTGUN)) + return 25; + } else if (ent.classname == "weapon_nailgun") { + if (!(bot.ent.items & IT_NAILGUN)) + return 30; + } else if (ent.classname == "weapon_supernailgun") { + if (!(bot.ent.items & IT_SUPER_NAILGUN)) + return 35; + } else if (ent.classname == "weapon_grenadelauncher") { + if (!(bot.ent.items & IT_GRENADE_LAUNCHER)) + return 45; + } else if (ent.classname == "weapon_rocketlauncher") { + if (!(bot.ent.items & IT_ROCKET_LAUNCHER)) + return 60; + } else if (ent.classname == "weapon_lightning") { + if (!(bot.ent.items & IT_LIGHTNING)) + return 50; + } + } else if ((ent.flags & FL_MONSTER) && ent.health > 0) + return 45; + return 0; +} + +/* +FindWaypoint + +This is used quite a bit, by many different +functions big lag causer + +Finds the closest, fisible, waypoint to e +*/ +-(Waypoint)findWaypoint:(Waypoint)start +{ + local Waypoint best, t; + local float dst, tdst; + local vector org; + local integer count, i; + local integer ishuman = [self ishuman]; + + org = [self realorigin]; + + if (start) { + dst = vlen ([start origin] - org); + best = start; + } else { + dst = 100000; + best = NIL; + } + count = [waypoint_array count]; + for (i = 0; i < count; i++) { + t = [waypoint_array getItemAt:i]; + // real players cut through ignore types + if (dst < 20) + return best; + if (!(t.flags & AI_IGNORE_TYPES) || ishuman) { + tdst = vlen (t.origin - org); + if (tdst < dst) { + traceline (ent.origin, t.origin, TRUE, ent); + if (trace_fraction == 1) { + dst = tdst; + best = t; + } + } + } + } + return best; +} + @end diff --git a/fbxa/waypoint.r b/fbxa/waypoint.r index 199df71..f7fbe0b 100644 --- a/fbxa/waypoint.r +++ b/fbxa/waypoint.r @@ -56,6 +56,7 @@ Array waypoint_array; { if (!waypoint_array) { waypoint_array = [[Array alloc] init]; + [waypoint_array addItem:NIL]; waypoint_queue = [[List alloc] init]; waypoint_thinker = spawn (); waypoint_thinker.classname = "waypoint_thinker"; @@ -121,7 +122,7 @@ make_waypoint = return 0; for (i = 0; i < 4; i++) { - if (targets[i] == way) { + if (links[i] == way) { if (flags & (AI_TELELINK_1 << i)) return 2; return 1; @@ -140,8 +141,8 @@ make_waypoint = return 0; // already linked!!! for (i = 0; i < 4; i++) { - if (!targets[i]) { - targets[i] = way; + if (!links[i]) { + links[i] = way; return 1; } } @@ -159,8 +160,8 @@ make_waypoint = return 0; // already linked!!! for (i = 0; i < 4; i++) { - if (!targets[i]) { - targets[i] = way; + if (!links[i]) { + links[i] = way; flags |= AI_TELELINK_1 << i; return 1; } @@ -178,9 +179,9 @@ make_waypoint = return; for (i = 0; i < 4; i++) { - if (targets[i] == way) { + if (links[i] == way) { flags &= ~(AI_TELELINK_1 << i); - targets[i] = NIL; + links[i] = NIL; } } } @@ -207,10 +208,10 @@ Waypoint Loading from file -(void)fix { - targets[0] = [Waypoint waypointForNum:b_pants]; - targets[1] = [Waypoint waypointForNum:b_skill]; - targets[2] = [Waypoint waypointForNum:b_shirt]; - targets[3] = [Waypoint waypointForNum:b_frags]; + links[0] = [Waypoint waypointForNum:b_pants]; + links[1] = [Waypoint waypointForNum:b_skill]; + links[2] = [Waypoint waypointForNum:b_shirt]; + links[3] = [Waypoint waypointForNum:b_frags]; } +(void) fixWaypoints @@ -301,16 +302,16 @@ tripping the runaway loop counter // can you say ugly? if (flags & AI_TRACE_TEST) { for (i = 0; i < 4; i++) { - if (targets[i]) { - traceline (origin, targets[i].origin, TRUE, /*self*/NIL); + if (links[i]) { + traceline (origin, links[i].origin, TRUE, /*self*/NIL); if (trace_fraction == 1) - [self followLink:targets[i].origin :AI_TELELINK_1 << i]; + [self followLink:links[i] :AI_TELELINK_1 << i]; } } } else { for (i = 0; i < 4; i++) { - if (targets[i]) { - [self followLink:targets[i].origin :AI_TELELINK_1 << i]; + if (links[i]) { + [self followLink:links[i] :AI_TELELINK_1 << i]; } } } @@ -345,6 +346,15 @@ tripping the runaway loop counter return self; } +-(integer)priority:(Bot)bot +{ + if (flags & AI_SNIPER) + return 30; + else if (flags & AI_AMBUSH) + return 30; + return 0; +} + @end