From d186408279b2b24cf5266e36698ad3bfc86af45a Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 23 Jul 2003 22:44:15 +0000 Subject: [PATCH] progress :) --- fbxa/bot_ai.qc | 584 +++++++++++++++++++++++----------------------- fbxa/bot_fight.qc | 213 +++++++++-------- fbxa/bot_move.qc | 26 +-- fbxa/bot_qw.qc | 3 +- fbxa/bot_way.qc | 4 +- fbxa/libfrikbot.h | 34 ++- 6 files changed, 431 insertions(+), 433 deletions(-) diff --git a/fbxa/bot_ai.qc b/fbxa/bot_ai.qc index 9ebb88d..a442eea 100644 --- a/fbxa/bot_ai.qc +++ b/fbxa/bot_ai.qc @@ -44,6 +44,8 @@ this notice in its entirety. #include "libfrikbot.h" +float stagger_think; + @implementation Bot (AI) /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -54,21 +56,21 @@ checks to see if an entity is on the bot's stack -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -float(entity scot) target_onstack = +-(integer)target_onstack:(entity)scot { if (scot == NIL) return FALSE; - else if (self.target1 == scot) + else if (targets[0] == scot) return 1; - else if (self.target2 == scot) + else if (targets[1] == scot) return 2; - else if (self.target3 == scot) + else if (targets[2] == scot) return 3; - else if (self.target4 == scot) + else if (targets[3] == scot) return 4; else return FALSE; -}; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -80,19 +82,19 @@ LIFO stack, this will be the bot's new target1 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void(entity ent) target_add = +-(void)target_add:(entity)e { - if (ent == NIL) + if (e == NIL) return; - if (target_onstack (ent)) + if ([self target_onstack:e]) return; - self.target4 = self.target3; - self.target3 = self.target2; - self.target2 = self.target1; - self.target1 = ent; - self.search_time = time + 5; -}; + targets[3] = targets[2]; + targets[2] = targets[1]; + targets[1] = targets[0]; + targets[0] = e; + ent.search_time = time + 5; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -107,31 +109,31 @@ is gone too. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void(entity ent) target_drop = +-(void)target_drop:(entity)e { - switch (target_onstack (ent)) { + switch ([self target_onstack:e]) { case 1: - self.target1 = self.target2; - self.target2 = self.target3; - self.target3 = self.target4; - self.target4 = NIL; + targets[0] = targets[1]; + targets[1] = targets[2]; + targets[2] = targets[3]; + targets[3] = NIL; break; case 2: - self.target1 = self.target3; - self.target2 = self.target4; - self.target3 = self.target4 = NIL; + targets[0] = targets[2]; + targets[1] = targets[3]; + targets[2] = targets[3] = NIL; break; case 3: - self.target1 = self.target4; - self.target2 = self.target3 = self.target4 = NIL; + targets[0] = targets[3]; + targets[1] = targets[2] = targets[3] = NIL; break; case 4: - self.target1 = self.target2 = self.target3 = self.target4 = NIL; + targets[0] = targets[1] = targets[2] = targets[3] = NIL; default: break; } - self.search_time = time + 5; -}; + ent.search_time = time + 5; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -142,37 +144,37 @@ Bot has lost its target. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void(entity targ, float success) bot_lost = +-(void)lost:(entity)targ :(integer)success { if (!targ) return; - target_drop(targ); + [self target_drop:targ]; if (targ.classname == "waypoint") - targ.b_sound &= ~(ClientBitFlag (self.b_clientno)); + targ.b_sound &= ~(ClientBitFlag (b_clientno)); // find a new route if (!success) { - self.target1 = self.target2 = self.target3 = self.target4 = NIL; - self.last_way = FindWayPoint (self.current_way); + targets[0] = targets[1] = targets[2] = targets[3] = NIL; + last_way = FindWayPoint (current_way); ClearMyRoute (); - self.b_aiflags = 0; + b_aiflags = 0; } else { if (targ.classname == "item_artifact_invisibility") - if (self.items & 524288) + if (ent.items & 524288) bot_start_topic (3); if (targ.flags & FL_ITEM) { if (!targ.model) targ._last = NIL; else - targ._last = self; + targ._last = ent; } } if (targ.classname != "player") targ.search_time = time + 5; -}; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -184,11 +186,11 @@ removed. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void(entity targ) bot_check_lost = +-(void)check_lost:(entity)targ { local vector dist; - dist = realorigin (targ) - self.origin; + dist = realorigin (targ) - ent.origin; dist_z = 0; if (targ == NIL) @@ -196,83 +198,83 @@ void(entity targ) bot_check_lost = // waypoints and items are lost if you get close enough to them if (targ.flags & FL_ITEM) { - if (vlen (targ.origin - self.origin) < 32) - bot_lost (targ, TRUE); + if (vlen (targ.origin - ent.origin) < 32) + [self lost:targ :TRUE]; else if (!targ.model) - bot_lost (targ, TRUE); + [self lost:targ :TRUE]; } else if (targ.classname == "waypoint") { - if (!(self.b_aiflags & (AI_SNIPER | AI_AMBUSH))) { - if (self.b_aiflags & AI_RIDE_TRAIN) { - if (vlen (targ.origin - self.origin) < 48) - bot_lost (targ, TRUE); - } else if (self.b_aiflags & AI_PRECISION) { - if (vlen (targ.origin - self.origin) < 24) - bot_lost (targ, TRUE); - } else if (vlen (targ.origin - self.origin) < 32) - bot_lost (targ, TRUE); + if (!(b_aiflags & (AI_SNIPER | AI_AMBUSH))) { + if (b_aiflags & AI_RIDE_TRAIN) { + if (vlen (targ.origin - ent.origin) < 48) + [self lost:targ :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]; } } else if (targ.classname == "temp_waypoint") { - if (vlen (targ.origin - self.origin) < 32) - bot_lost (targ, TRUE); + if (vlen (targ.origin - ent.origin) < 32) + [self lost:targ :TRUE]; } else if (targ.classname == "player") { if (targ.health <= 0) - bot_lost (targ, TRUE); - else if ((coop) || (teamplay && targ.team == self.team)) { + [self lost:targ :TRUE]; + else if ((coop) || (teamplay && targ.team == ent.team)) { if (targ.target1.classname == "player") { if (!targ.target1.ishuman) - bot_lost (targ, TRUE); + [self lost:targ :TRUE]; } else if (targ.teleport_time > time) { // try not to telefrag teammates - self.keys &= 960; - } else if (vlen (targ.origin - self.origin) < 128) { - if (vlen (targ.origin - self.origin) < 48) - frik_walkmove (self.origin - targ.origin); + keys &= 960; + } else if (vlen (targ.origin - ent.origin) < 128) { + if (vlen (targ.origin - ent.origin) < 48) + [self walkmove: ent.origin - targ.origin]; else { - self.keys &= 960; + keys &= 960; bot_start_topic (4); } - self.search_time = time + 5; // never time out + ent.search_time = time + 5; // never time out } else if (!fisible(targ)) - bot_lost (targ, FALSE); + [self lost:targ :FALSE]; } else if (waypoint_mode > WM_LOADED) { - if (vlen (targ.origin - self.origin) < 128) { - bot_lost (targ, TRUE); + if (vlen (targ.origin - ent.origin) < 128) { + [self lost:targ :TRUE]; } } } else if (targ.classname == "func_button") { // buttons are lost of their frame changes if (targ.frame) { - bot_lost (targ, TRUE); - if (self.enemy == targ) - self.enemy = NIL; -// if (self.target1) -// bot_get_path (self.target1, TRUE); + [self lost:targ :TRUE]; + if (ent.enemy == targ) + ent.enemy = NIL; +// if (target[0]) +// bot_get_path (target[0], TRUE); } } else if ((targ.movetype == MOVETYPE_NONE) && (targ.solid == SOLID_TRIGGER)) { // trigger_multiple style triggers are lost if their thinktime changes if (targ.nextthink >= time) { - bot_lost (targ, TRUE); -// if (self.target1) -// bot_get_path (self.target1, TRUE); + [self lost:targ :TRUE]; +// if (target[0]) +// bot_get_path (target[0], TRUE); } } // lose any target way above the bot's head // FIXME: if the bot can fly in your mod.. - if ((targ.origin_z - self.origin_z) > 64) { - dist = targ.origin - self.origin; + if ((targ.origin_z - ent.origin_z) > 64) { + dist = targ.origin - ent.origin; dist_z = 0; if (vlen (dist) < 32) - if (self.flags & FL_ONGROUND) - if (!frik_recognize_plat (FALSE)) - bot_lost (targ, FALSE); + if (ent.flags & FL_ONGROUND) + if (![self recognize_plat:FALSE]) + [self lost:targ :FALSE]; } else if (targ.classname == "train") { - if (frik_recognize_plat (FALSE)) - bot_lost (targ, TRUE); + if ([self recognize_plat:FALSE]) + [self lost:targ :TRUE]; } // targets are lost if the bot's search time has expired - if (time > self.search_time) - bot_lost (targ, FALSE); -}; + if (time > ent.search_time) + [self lost:targ :FALSE]; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -284,7 +286,7 @@ based b_aiflags. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void() bot_handle_ai = +-(void)handle_ai { local entity newt; local vector v; @@ -294,121 +296,112 @@ void() bot_handle_ai = // wait is used by the ai to stop the bot until his search time expires / or route changes - if (self.b_aiflags & AI_WAIT) - self.keys &= 960; + if (b_aiflags & AI_WAIT) + keys &= 960; - if (self.b_aiflags & AI_DOORFLAG) { + if (b_aiflags & AI_DOORFLAG) { // was on a door when spawned - b_temp3 = self; - self = self.last_way; // if there is nothing there now - if (!frik_recognize_plat (FALSE)) { - newt = FindThing ("door"); // this is likely the door responsible (crossfingers) - self = b_temp3; + if (![ent.@this recognize_plat:FALSE]) { + newt = FindThing (ent, "door"); // this is likely the door responsible (crossfingers) - if (self.b_aiflags & AI_DOOR_NO_OPEN) { + if (b_aiflags & AI_DOOR_NO_OPEN) { if (newt.nextthink) - self.keys &= 960; // wait until it closes + keys &= 960; // wait until it closes else { - bot_lost (self.last_way, FALSE); + [self lost:last_way :FALSE]; } } else { if (newt.targetname) { newt = find (NIL, target, newt.targetname); if (newt.health > 0) { - self.enemy = newt; - bot_weapon_switch (1); + ent.enemy = newt; + [self weapon_switch:1]; } else { - // target_drop (self.last_way); - target_add (newt); + // target_drop (last_way); + [self target_add:newt]; // bot_get_path (newt, TRUE); } } - self.b_aiflags &= ~AI_DOORFLAG; + b_aiflags &= ~AI_DOORFLAG; } - } else - self = b_temp3; + } } - if (self.b_aiflags & AI_JUMP) { - if (self.flags & FL_ONGROUND) { - bot_jump (); - self.b_aiflags &= ~AI_JUMP; + if (b_aiflags & AI_JUMP) { + if (ent.flags & FL_ONGROUND) { + [self jump]; + b_aiflags &= ~AI_JUMP; } - } else if (self.b_aiflags & AI_SUPER_JUMP) { - if (self.weapon != 32) - self.impulse = 7; - else if (self.flags & FL_ONGROUND) { - self.b_aiflags &= ~AI_SUPER_JUMP; - if (bot_can_rj (self)) { - bot_jump (); - self.v_angle_x = self.b_angle_x = 80; - self.button0 = TRUE; + } else if (b_aiflags & AI_SUPER_JUMP) { + if (ent.weapon != 32) + ent.impulse = 7; + else if (ent.flags & FL_ONGROUND) { + b_aiflags &= ~AI_SUPER_JUMP; + if ([self can_rj]) { + [self jump]; + v_angle.x = b_angle.x = 80; + ent.button0 = TRUE; } else - bot_lost (self.target1, FALSE); + [self lost: targets[0] :FALSE]; } } - if (self.b_aiflags & AI_SURFACE) { - if (self.waterlevel > 2) { - self.keys = KEY_MOVEUP; - self.button2 = TRUE; // swim! + if (b_aiflags & AI_SURFACE) { + if (ent.waterlevel > 2) { + keys = KEY_MOVEUP; + ent.button2 = TRUE; // swim! } else - self.b_aiflags &= ~AI_SURFACE; + b_aiflags &= ~AI_SURFACE; } - if (self.b_aiflags & AI_RIDE_TRAIN) { + if (b_aiflags & AI_RIDE_TRAIN) { // simple, but effective // this can probably be used for a lot of different // things, not just trains (door elevators come to mind) - b_temp3 = self; - self = self.last_way; - - if (!frik_recognize_plat(FALSE)) { + if (![ent.@this recognize_plat:FALSE]) { // if there is nothing there now - self = b_temp3; - self.keys &= 960; + keys &= 960; } else { - self = b_temp3; - if (frik_recognize_plat (FALSE)) { - v = realorigin (trace_ent) + trace_ent.origin - self.origin; + if ([self recognize_plat:FALSE]) { + v = realorigin (trace_ent) + trace_ent.origin - ent.origin; v_z = 0; if (vlen (v) < 24) - self.keys &= 960; + keys &= 960; else { - self.b_aiflags |= AI_PRECISION; - self.keys = frik_KeysForDir (v); + b_aiflags |= AI_PRECISION; + keys = [self keysForDir:v]; } } } } - if (self.b_aiflags & AI_PLAT_BOTTOM) { - newt = FindThing ("plat"); + if (b_aiflags & AI_PLAT_BOTTOM) { + newt = FindThing (ent, "plat"); if (newt.state != 1) { - v = self.origin - realorigin (newt); + v = ent.origin - realorigin (newt); v_z = 0; if (vlen (v) > 96) - self.keys &= 960; + keys &= 960; else - frik_walkmove (v); + [self walkmove:v]; } else - self.b_aiflags &= ~AI_PLAT_BOTTOM; + b_aiflags &= ~AI_PLAT_BOTTOM; } - if (self.b_aiflags & AI_DIRECTIONAL) { - if ((normalize (self.last_way.origin - self.origin) * self.b_dir) > 0.4) { - self.b_aiflags &= ~AI_DIRECTIONAL; - bot_lost (self.target1, TRUE); + if (b_aiflags & AI_DIRECTIONAL) { + if ((normalize (last_way.origin - ent.origin) * b_dir) > 0.4) { + b_aiflags &= ~AI_DIRECTIONAL; + [self lost:targets[0] :TRUE]; } } - if (self.b_aiflags & AI_SNIPER) { - self.b_aiflags |= AI_WAIT | AI_PRECISION | AI_SNIPER; + if (b_aiflags & AI_SNIPER) { + b_aiflags |= AI_WAIT | AI_PRECISION | AI_SNIPER; // FIXME: Add a switch to wep command // FIXME: increase delay? } - if (self.b_aiflags & AI_AMBUSH) { - self.b_aiflags |= AI_WAIT | AI_AMBUSH; + if (b_aiflags & AI_AMBUSH) { + b_aiflags |= AI_WAIT | AI_AMBUSH; // FIXME: Add a switch to wep command // FIXME: increase delay? } -}; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -423,26 +416,26 @@ confused -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void() bot_path = +-(void)path { local entity jj, tele; - bot_check_lost (self.target1); - if (!self.target1) { - self.keys=0; + [self check_lost:targets[0]]; + if (!targets[0]) { + keys=0; return; } - if (target_onstack (self.last_way)) + if ([self target_onstack:last_way]) return; // old waypoint still being hunted - jj = FindRoute (self.last_way); + jj = FindRoute (last_way); if (!jj) { // this is an ugly hack - if (self.target1.current_way != self.last_way) { - if (self.target1.classname != "temp_waypoint") - if (self.target1.classname != "player") - bot_lost (self.target1, FALSE); + if (targets[0].current_way != last_way) { + if (targets[0].classname != "temp_waypoint") + if (targets[0].classname != "player") + [self lost:targets[0] :FALSE]; } return; @@ -453,50 +446,50 @@ void() bot_path = // Readahed types are AI conditions to perform while heading to a waypoint // point types are AI flags that should be executed once reaching a waypoint - self.b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (self.last_way.b_aiflags & AI_POINT_TYPES); - target_add (jj); - if (self.last_way) { - if (CheckLinked (self.last_way, jj) == 2) { + b_aiflags = (jj.b_aiflags & AI_READAHEAD_TYPES) | (last_way.b_aiflags & AI_POINT_TYPES); + [self target_add:jj]; + if (last_way) { + if (CheckLinked (last_way, jj) == 2) { // waypoints are telelinked - tele = FindThing ("trigger_teleport"); // this is probbly the teleport responsible - target_add (tele); + tele = FindThing (ent, "trigger_teleport"); // this is probbly the teleport responsible + [self target_add:tele]; } - traceline (self.last_way.origin, jj.origin, FALSE, self); // check for blockage + traceline (last_way.origin, jj.origin, FALSE, ent); // check for blockage if (trace_fraction != 1) { - if (trace_ent.classname == "door" && !(self.b_aiflags & AI_DOOR_NO_OPEN)) { + if (trace_ent.classname == "door" && !(b_aiflags & AI_DOOR_NO_OPEN)) { // a door blocks the way // linked doors fix if (trace_ent.owner) trace_ent = trace_ent.owner; - if ((trace_ent.health > 0) && (self.enemy == NIL)) { - self.enemy = trace_ent; - bot_weapon_switch (1); - self.b_aiflags = self.b_aiflags | AI_BLIND; // nick knack paddy hack + if ((trace_ent.health > 0) && (ent.enemy == NIL)) { + ent.enemy = trace_ent; + [self weapon_switch:1]; + b_aiflags = b_aiflags | AI_BLIND; // nick knack paddy hack } else if (trace_ent.targetname) { tele = find (NIL, target, trace_ent.targetname); if (tele.health > 0) { - self.enemy = tele; - bot_weapon_switch (1); + ent.enemy = tele; + [self weapon_switch:1]; } else { // target_drop (jj); - target_add (tele); + [self target_add:tele]; // bot_get_path (tele, TRUE); - self.b_aiflags |= AI_BLIND; // give a bot a bone + b_aiflags |= AI_BLIND; // give a bot a bone return; } } } else if (trace_ent.classname == "func_wall") { // give up - bot_lost (self.target1, FALSE); + [self lost:targets[0] :FALSE]; return; } } } // this is used for AI_DRIECTIONAL - self.b_dir = normalize (jj.origin - self.last_way.origin); + b_dir = normalize (jj.origin - last_way.origin); - self.last_way = jj; -}; + last_way = jj; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -514,7 +507,7 @@ the bot finds things it wants to kill/grab. // *!* Make sure you add code to bot_check_lost to remove the target *!* -float(entity thing) priority_for_thing = +-(float)priority_for_thing:(entity)thing { local float thisp; @@ -522,7 +515,7 @@ float(entity thing) priority_for_thing = // 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 - if (thing._last != self) + if (thing._last != ent) thisp = 20; if (thing.classname == "item_artifact_super_damage") thisp = 65; @@ -531,39 +524,39 @@ float(entity thing) priority_for_thing = else if (thing.classname == "item_health") { if (thing.spawnflags & 2) thisp = 55; - if (self.health < 40) + if (ent.health < 40) thisp = thisp + 50; } else if (thing.model == "progs/armor.mdl") { - if (self.armorvalue < 200) { + if (ent.armorvalue < 200) { if (thing.skin == 2) thisp = 60; - else if (self.armorvalue < 100) + else if (ent.armorvalue < 100) thisp = thisp + 25; } } else if (thing.classname == "weapon_supershotgun") { - if (!(self.items & 2)) // IT_SUPER_SHOTGUN + if (!(ent.items & 2)) // IT_SUPER_SHOTGUN thisp = 25; } else if (thing.classname == "weapon_nailgun") { - if (!(self.items & 4)) // IT_NAILGUN + if (!(ent.items & 4)) // IT_NAILGUN thisp = 30; } else if (thing.classname == "weapon_supernailgun") { - if (!(self.items & 8)) // IT_SUPER_NAILGUN + if (!(ent.items & 8)) // IT_SUPER_NAILGUN thisp = 35; } else if (thing.classname == "weapon_grenadelauncher") { - if (!(self.items & 16)) // IT_GRENADE_LAUNCHER + if (!(ent.items & 16)) // IT_GRENADE_LAUNCHER thisp = 45; } else if (thing.classname == "weapon_rocketlauncher") { - if (!(self.items & 32)) // IT_ROCKET_LAUNCHER + if (!(ent.items & 32)) // IT_ROCKET_LAUNCHER thisp = 60; } else if (thing.classname == "weapon_lightning") { - if (!(self.items & 64)) // IT_LIGHTNING + if (!(ent.items & 64)) // 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 == self) + if (thing == ent) return 0; else { if (thing.items & IT_INVISIBILITY) //FIXME @@ -573,7 +566,7 @@ float(entity thing) priority_for_thing = if (thing.target1.classname == "player") if (!thing.target1.ishuman) return 0; - } else if (teamplay && thing.team == self.team) { + } else if (teamplay && thing.team == ent.team) { thisp = 100; if (thing.target1.classname == "player") return 0; @@ -599,21 +592,21 @@ float(entity thing) priority_for_thing = } } return thisp; -}; +} -void(float scope) bot_look_for_crap = +-(void)look_for_crap:(integer)scope { local entity foe, best = NIL; local float thatp, bestp, dist; if (scope == 1) - foe = findradius (self.origin, 13000); + foe = findradius (ent.origin, 13000); else - foe = findradius (self.origin, 500); + foe = findradius (ent.origin, 500); bestp = 1; while (foe) { - thatp = priority_for_thing (foe); + thatp = [self priority_for_thing:foe]; if (thatp) if (!scope) if (!sisible (foe)) @@ -621,20 +614,20 @@ void(float scope) bot_look_for_crap = if (thatp > bestp) { bestp = thatp; best = foe; - dist = vlen (self.origin - foe.origin); + dist = vlen (ent.origin - foe.origin); } foe = foe.chain; } if (best == NIL) return; - if (!target_onstack (best)) { - target_add (best); + if (![self target_onstack:best]) { + [self target_add:best]; if (scope) { bot_get_path (best, FALSE); - self.b_aiflags |= AI_WAIT; + b_aiflags |= AI_WAIT; } } -}; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -647,81 +640,81 @@ generally making the bot look good. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -void() bot_angle_set = +-(void)angle_set { local float h; local vector view; - if (self.enemy) { - if (self.enemy.items & 524288) + if (ent.enemy) { + if (ent.enemy.items & 524288) if (random () > 0.2) return; - if (self.missile_speed == 0) - self.missile_speed = 10000; - if (self.enemy.solid == SOLID_BSP) { - view = (((self.enemy.absmin + self.enemy.absmax) * 0.5) - self.origin); + if (missile_speed == 0) + missile_speed = 10000; + if (ent.enemy.solid == SOLID_BSP) { + view = (((ent.enemy.absmin + ent.enemy.absmax) * 0.5) - ent.origin); } else { - h = vlen (self.enemy.origin - self.origin) / self.missile_speed; - if (self.enemy.flags & FL_ONGROUND) - view = self.enemy.velocity * h; + h = vlen (ent.enemy.origin - ent.origin) / missile_speed; + if (ent.enemy.flags & FL_ONGROUND) + view = ent.enemy.velocity * h; else - view = (self.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; - view = self.enemy.origin + view; + view = (ent.enemy.velocity - (sv_gravity * '0 0 1') * h) * h; + view = ent.enemy.origin + view; // FIXME: ? - traceline (self.enemy.origin, view, FALSE, self); + traceline (ent.enemy.origin, view, FALSE, ent); view = trace_endpos; - if (self.weapon == 32) + if (ent.weapon == 32) view = view - '0 0 22'; - view = normalize (view - self.origin); + view = normalize (view - ent.origin); } view = vectoangles (view); view_x = view_x * -1; - self.b_angle = view; - } else if (self.target1) { - view = realorigin (self.target1); - if (self.target1.flags & FL_ITEM) + b_angle = view; + } else if (targets[0]) { + view = realorigin (targets[0]); + if (targets[0].flags & FL_ITEM) view = view + '0 0 48'; - view -= (self.origin + self.view_ofs); + view -= (ent.origin + ent.view_ofs); view = vectoangles (view); view_x *= -1; - self.b_angle = view; + b_angle = view; } else - self.b_angle_x = 0; + b_angle.x = 0; // HACK HACK HACK HACK // The bot falls off ledges a lot because of "turning around" // so let the bot use instant turn around when not hunting a player - if (self.b_skill == 3) { - self.keys = self.keys & 63; - self.v_angle = self.b_angle; - while (self.v_angle_x < -180) - self.v_angle_x += 360; - while (self.v_angle_x > 180) - self.v_angle_x -= 360; - } else if ((self.enemy == NIL || self.enemy.movetype == MOVETYPE_PUSH) && self.target1.classname != "player") { - self.keys = self.keys & 63; - self.v_angle = self.b_angle; - while (self.v_angle_x < -180) - self.v_angle_x += 360; - while (self.v_angle_x > 180) - self.v_angle_x -= 360; - } else if (self.b_skill < 2) { + if (b_skill == 3) { + keys = keys & 63; + v_angle = b_angle; + while (v_angle.x < -180) + v_angle.x += 360; + while (v_angle.x > 180) + v_angle.x -= 360; + } else if ((ent.enemy == NIL || ent.enemy.movetype == MOVETYPE_PUSH) && targets[0].classname != "player") { + keys = keys & 63; + v_angle = b_angle; + while (v_angle.x < -180) + v_angle.x += 360; + while (v_angle.x > 180) + v_angle.x -= 360; + } else if (b_skill < 2) { // skill 2 handled in bot_phys - if (self.b_angle_x > 180) - self.b_angle_x -= 360; - self.keys = self.keys & 63; + if (b_angle.x > 180) + b_angle.x -= 360; + keys = keys & 63; - if (angcomp (self.b_angle_y, self.v_angle_y) > 10) - self.keys = KEY_LOOKLEFT; - else if (angcomp(self.b_angle_y, self.v_angle_y) < -10) - self.keys |= KEY_LOOKRIGHT; - if (angcomp(self.b_angle_x, self.v_angle_x) < -10) - self.keys |= KEY_LOOKUP; - else if (angcomp (self.b_angle_x, self.v_angle_x) > 10) - self.keys |= KEY_LOOKDOWN; + if (angcomp (b_angle.y, v_angle.y) > 10) + keys = KEY_LOOKLEFT; + else if (angcomp(b_angle.y, v_angle.y) < -10) + keys |= KEY_LOOKRIGHT; + if (angcomp(b_angle.x, v_angle.x) < -10) + keys |= KEY_LOOKUP; + else if (angcomp (b_angle.x, v_angle.x) > 10) + keys |= KEY_LOOKDOWN; } -}; +} /* -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= @@ -733,103 +726,102 @@ frame, the ai_time limits it's actual updating -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */ -float stagger_think; -void() BotAI = +-(void)AI { // am I dead? Fire randomly until I respawn // health < 1 is used because fractional healths show up as 0 on normal player // status bars, and the mod probably already compensated for that - if (self.health < 1) { - self.button0 = floor (random() * 2); - self.button2 = 0; - self.keys = 0; - self.b_aiflags = 0; + if (ent.health < 1) { + ent.button0 = floor (random() * 2); + ent.button2 = 0; + keys = 0; + b_aiflags = 0; ClearMyRoute (); - self.target1 = self.target2 = self.target3 = self.target4 = self.enemy = NIL; - self.last_way = NIL; + targets[0] = targets[1] = targets[2] = targets[3] = ent.enemy = NIL; + last_way = NIL; return; } // stagger the bot's AI out so they all don't think at the same time, causing game // 'spikes' - if (self.b_skill < 2) { - if (self.ai_time > time) + if (b_skill < 2) { + if (ai_time > time) return; - self.ai_time = time + 0.05; + ai_time = time + 0.05; if (bot_count > 0) { if ((time - stagger_think) < (0.1 / bot_count)) - self.ai_time += 0.1 / (2 * bot_count); + ai_time += 0.1 / (2 * bot_count); } else return; } - if (self.view_ofs == '0 0 0') + if (ent.view_ofs == '0 0 0') bot_start_topic (7); stagger_think = time; // shut the bot's buttons off, various functions will turn them on by AI end - self.button2 = 0; - self.button0 = 0; + ent.button2 = 0; + ent.button0 = 0; // target1 is like goalentity in normal Quake monster AI. // it's the bot's most immediate target - if (route_table == self) { + if (route_table == ent) { if (busy_waypoints <= 0) { if (waypoint_mode < WM_EDITOR) - bot_look_for_crap(TRUE); + [self look_for_crap:TRUE]; } - self.b_aiflags = 0; - self.keys = 0; - } else if (self.target1) { - frik_movetogoal (); - bot_path (); + b_aiflags = 0; + keys = 0; + } else if (targets[0]) { + [self movetogoal]; + [self path]; } else { if (waypoint_mode < WM_EDITOR) { - if (self.route_failed) { - frik_bot_roam(); - self.route_failed = 0; + if (route_failed) { + [self roam]; + route_failed = 0; } else if (!begin_route()) { - bot_look_for_crap (FALSE); + [self look_for_crap:FALSE]; } - self.keys = 0; + keys = 0; } else { - self.b_aiflags = AI_WAIT; - self.keys = 0; + b_aiflags = AI_WAIT; + keys = 0; } } - // bot_angle_set points the bot at it's goal (self.enemy or target1) - bot_angle_set (); + // bot_angle_set points the bot at it's goal (ent.enemy or target1) + [self angle_set]; // fight my enemy. Enemy is probably a field QC coders will most likely // use a lot for their own needs, since it's unused on a normal player // FIXME - if (self.enemy) - bot_fight_style (); + if (ent.enemy) + [self fight_style]; else if (random () < 0.2) if (random () < 0.2) - bot_weapon_switch (-1); - bot_dodge_stuff (); + [self weapon_switch:-1]; + [self dodge_stuff]; // checks to see if bot needs to start going up for air - if (self.waterlevel > 2) { - if (time > (self.air_finished - 2)) { - traceline (self.origin, self.origin + '0 0 6800', TRUE, self); + if (ent.waterlevel > 2) { + if (time > (ent.air_finished - 2)) { + traceline (ent.origin, ent.origin + '0 0 6800', TRUE, ent); if (trace_inopen) { - self.keys = KEY_MOVEUP; - self.button2 = TRUE; // swim! + keys = KEY_MOVEUP; + ent.button2 = TRUE; // swim! return; // skip ai flags for now - this is life or death } } } // b_aiflags handling - if (self.b_aiflags) - bot_handle_ai (); + if (b_aiflags) + [self handle_ai]; else bot_chat (); // don't want chat to screw him up if he's rjing or something -}; +} @end diff --git a/fbxa/bot_fight.qc b/fbxa/bot_fight.qc index 3bda7ee..57f59ae 100644 --- a/fbxa/bot_fight.qc +++ b/fbxa/bot_fight.qc @@ -42,10 +42,40 @@ this notice in its entirety. #include "libfrikbot.h" -.entity avoid; +/* +weapon_range -float (entity e) -bot_size_player = +_x "sweet spot range" - try to maintain this range if possible +_y minimum range bot can be to be effective (rl/gl) (move away) +_z maximum range bot can be to be effective (lg/axe) (move in) +*/ +vector (float wep) +weapon_range = +{ + switch (wep) { + case 4096: // IT_AXE + return '48 0 64'; + case 1: // IT_SHOTGUN + return '128 0 99999'; + case 2: // IT_SUPER_SHOTGUN + return '128 0 99999'; + case 4: // IT_NAILGUN + return '180 0 3000'; + case 8: // IT_SUPER_NAILGUN + return '180 0 3000'; + case 16: // IT_GRENADE_LAUNCHER + return '180 48 3000'; + case 32: // IT_ROCKET_LAUNCHER + return '180 48 3000'; + case 64: // IT_LIGHTNING + return '350 0 512'; + default: + break; + } +}; + +@implementation Bot (Fight) +-(float)size_player:(entity)e { local float sz; @@ -86,10 +116,9 @@ bot_size_player = if (e.items & 524288) // Invis sz += 250; return sz; -}; +} -void () -bot_dodge_stuff = +-(void)dodge_stuff { local entity foe; local float foedist, avdist, foesz, flen, tsz; @@ -100,10 +129,10 @@ bot_dodge_stuff = self.avoid = NIL; - if (self.enemy) { - v = self.origin - realorigin (self.enemy); + if (ent.enemy) { + v = ent.origin - realorigin (ent.enemy); foedist = vlen (v); - foesz = bot_size_player (self.enemy); + foesz = [self size_player:ent.enemy]; } else { foedist = 3000; foesz = 9999999; @@ -112,7 +141,7 @@ bot_dodge_stuff = foe = find (NIL, classname, "grenade"); while (foe) { - flen = vlen (foe.origin - self.origin); + flen = vlen (foe.origin - ent.origin); if (flen < avdist) { avdist = flen; self.avoid = foe; @@ -122,8 +151,8 @@ bot_dodge_stuff = if (!self.avoid) { foe = find (NIL, classname, "missile"); while (foe) { - if (foe.owner != self) { - flen = vlen (foe.origin - self.origin); + if (foe.owner != ent) { + flen = vlen (foe.origin - ent.origin); if (flen < avdist) { avdist = flen; self.avoid = foe; @@ -134,8 +163,8 @@ bot_dodge_stuff = if (!self.avoid) { foe = find(NIL, classname, "spike"); while (foe) { - if (foe.owner != self) { - flen = vlen(foe.origin - self.origin); + if (foe.owner != ent) { + flen = vlen(foe.origin - ent.origin); if (flen < avdist) { avdist = flen; self.avoid = foe; @@ -146,17 +175,17 @@ bot_dodge_stuff = } } if (coop) { - if (!self.enemy) { - foe = findradius (self.origin, foedist); + if (!ent.enemy) { + foe = findradius (ent.origin, foedist); while (foe) { if (foe.flags & FL_MONSTER) { if (foe.health > 0) { - flen = vlen (foe.origin - self.origin); + flen = vlen (foe.origin - ent.origin); if (flen < foedist) { - tsz = bot_size_player (foe); + tsz = [self size_player:foe]; if (tsz < foesz) { if (fisible (foe)) { - self.enemy = foe; + ent.enemy = foe; foedist = flen; foesz = tsz; } @@ -172,18 +201,18 @@ bot_dodge_stuff = for (i = 0; i < 32; i++) { if (!(foe = players[i])) continue; - if(foe != self) { + if(foe != ent) { if (foe.modelindex != 0) { if (foe.health > 0) { - if (!(teamplay && self.team == foe.team)) { - flen = vlen (foe.origin - self.origin); + if (!(teamplay && ent.team == foe.team)) { + flen = vlen (foe.origin - ent.origin); if (flen < foedist) { - tsz = bot_size_player(foe); + tsz = [self size_player:foe]; if (tsz < foesz) { if (fov(foe) || foe.b_sound > time || self.b_skill == 3) { if (fisible (foe)) { - self.enemy = foe; - foedist = vlen (foe.origin - self.origin); + ent.enemy = foe; + foedist = vlen (foe.origin - ent.origin); } } } @@ -194,84 +223,51 @@ bot_dodge_stuff = } } } -}; - -/* -weapon_range - -_x "sweet spot range" - try to maintain this range if possible -_y minimum range bot can be to be effective (rl/gl) (move away) -_z maximum range bot can be to be effective (lg/axe) (move in) -*/ -vector (float wep) -weapon_range = -{ - switch (wep) { - case 4096: // IT_AXE - return '48 0 64'; - case 1: // IT_SHOTGUN - return '128 0 99999'; - case 2: // IT_SUPER_SHOTGUN - return '128 0 99999'; - case 4: // IT_NAILGUN - return '180 0 3000'; - case 8: // IT_SUPER_NAILGUN - return '180 0 3000'; - case 16: // IT_GRENADE_LAUNCHER - return '180 48 3000'; - case 32: // IT_ROCKET_LAUNCHER - return '180 48 3000'; - case 64: // IT_LIGHTNING - return '350 0 512'; - default: - break; - } -}; +} /* bot_weapon_switch Pick a weapon based on range / ammo */ -void (float brange) -bot_weapon_switch = +-(void)weapon_switch:(float)brange { local float it, flag = 0, pulse = 0; local vector v; - it = self.items & 127; + it = ent.items & 127; while (it) { - if ((self.ammo_rockets >= 1) && (it & 32)) { + if ((ent.ammo_rockets >= 1) && (it & 32)) { flag = 32; pulse = 7; - } else if (self.waterlevel <= 1 && self.ammo_cells >= 1 && (it & 64)) { + } else if (ent.waterlevel <= 1 && ent.ammo_cells >= 1 && (it & 64)) { flag = 64; pulse = 8; - } else if (self.ammo_nails >= 2 && (it & 8)) { + } else if (ent.ammo_nails >= 2 && (it & 8)) { flag = 8; pulse = 5; - } else if ((self.ammo_rockets >= 1) && (it & 16)) { + } else if ((ent.ammo_rockets >= 1) && (it & 16)) { flag = 16; pulse = 6; - } else if (self.ammo_shells >= 2 && (it & 2)) { + } else if (ent.ammo_shells >= 2 && (it & 2)) { flag = 2; pulse = 3; - } else if (self.ammo_nails >= 1 && (it & 4)) { + } else if (ent.ammo_nails >= 1 && (it & 4)) { flag = 4; pulse = 4; - } else if (self.ammo_shells >= 1 && (it & 1)) { + } else if (ent.ammo_shells >= 1 && (it & 1)) { flag = 1; pulse = 2; } else { if (pulse) - self.impulse = pulse; + ent.impulse = pulse; return; } if (brange == -1) { if (pulse) - self.impulse = pulse; + ent.impulse = pulse; return; } @@ -280,26 +276,25 @@ bot_weapon_switch = it = it - flag; else { if (pulse) - self.impulse = pulse; + ent.impulse = pulse; return; } } -}; +} -void () -bot_shoot = +-(void)shoot { // quick little function to stop making him shoot the wrong way ! Argh local float g; - g = angcomp (self.v_angle_x, self.b_angle_x); + g = angcomp (v_angle.x, b_angle.x); if (fabs (g) > 30) return; // argh, too far away - g = angcomp (self.v_angle_y, self.b_angle_y); + g = angcomp (v_angle.y, b_angle.y); if (fabs (g) > 30) return; // not again! - self.button0 = TRUE; -}; + ent.button0 = TRUE; +} /* Bot_fight_style @@ -307,44 +302,43 @@ Bot_fight_style This is the core of the bot's thinking when attacking an enemy. */ -void () -bot_fight_style = +-(void)fight_style { local float foedist, mysz, foesz; local vector v, v1 = '0 0 0', v2 = '0 0 0', org; - if (self.enemy.health <= 0) { - self.enemy = NIL; + if (ent.enemy.health <= 0) { + ent.enemy = NIL; return; - } else if (!self.enemy.takedamage) { - self.enemy = NIL; + } else if (!ent.enemy.takedamage) { + ent.enemy = NIL; return; - } else if (!fisible (self.enemy)) { - self.enemy = NIL; + } else if (!fisible (ent.enemy)) { + ent.enemy = NIL; return; } - org = realorigin (self.enemy); + org = realorigin (ent.enemy); makevectors (self.v_angle); // decide if I should shoot - foedist = vlen (org - self.origin); - v = weapon_range (self.weapon); + foedist = vlen (org - ent.origin); + v = weapon_range (ent.weapon); if (foedist > v_y && foedist < v_z) { - traceline (self.origin + self.view_ofs, self.origin + self.view_ofs + v_forward * v_z, FALSE, self); - if (vlen(trace_endpos - (self.origin + self.view_ofs)) >= v_y) { + traceline (ent.origin + ent.view_ofs, ent.origin + ent.view_ofs + v_forward * v_z, FALSE, ent); + if (vlen(trace_endpos - (ent.origin + ent.view_ofs)) >= v_y) { // try to avoid shooting teammates if (trace_ent.classname == "player") - if ((trace_ent.team == self.team && teamplay) || (coop)) + if ((trace_ent.team == ent.team && teamplay) || (coop)) return; - bot_shoot (); + [self shoot]; } } else - bot_weapon_switch (foedist); + [self weapon_switch:foedist]; if (!(self.b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) { - foesz = bot_size_player (self.enemy); - mysz = bot_size_player (self) + 5; + foesz = [self size_player:ent.enemy]; + mysz = [self size_player:self] + 5; if (foesz > mysz) { if (teamplay) { @@ -360,29 +354,29 @@ bot_fight_style = if (self.avoid.velocity) v = self.avoid.velocity; else - v = normalize (self.avoid.origin - self.origin); + v = normalize (self.avoid.origin - ent.origin); v1_x = v_y; v1_y = v_y * -1; v2_x = v_y; v2_y = v_y * -1; - foedist = vlen (self.avoid.origin - (self.origin + v1)); - if (foedist < vlen (self.avoid.origin - (self.origin + v2))) - frik_walkmove (v2); + foedist = vlen (self.avoid.origin - (ent.origin + v1)); + if (foedist < vlen (self.avoid.origin - (ent.origin + v2))) + [self walkmove:v2]; else - frik_walkmove (v1); - } else if (!(self.enemy.flags & FL_MONSTER)) { + [self walkmove:v1]; + } else if (!(ent.enemy.flags & FL_MONSTER)) { if (foedist + 32 < v_x) - frik_walkmove (self.origin - org); + [self walkmove:ent.origin - org]; else if (foedist - 32 > v_x) - frik_walkmove (org - self.origin); + [self walkmove:org - ent.origin]; else if (self.wallhug) - frik_walkmove (v_right); + [self walkmove:v_right]; else - frik_walkmove (v_right * -1); + [self walkmove:v_right * -1]; } } else { - foesz = bot_size_player (self.enemy); - mysz = bot_size_player (self) + 5; + foesz = [self size_player:ent.enemy]; + mysz = [self size_player:self] + 5; if (foesz > mysz) return; @@ -390,4 +384,5 @@ bot_fight_style = return; self.keys &= 960; } -}; +} +@end diff --git a/fbxa/bot_move.qc b/fbxa/bot_move.qc index d2ff95a..e894273 100644 --- a/fbxa/bot_move.qc +++ b/fbxa/bot_move.qc @@ -143,7 +143,7 @@ manuever around. // TODO: something if (b_aiflags & AI_BLIND) return; - org = realorigin(ent.target1); + org = realorigin(targets[0]); if (danger) { b_aiflags |= AI_DANGER; @@ -153,7 +153,7 @@ manuever around. return; - if (ent.target1) { + if (targets[0]) { if (b_aiflags & AI_OBSTRUCTED) { if (!(b_aiflags & AI_DANGER)) { b_aiflags &= ~AI_OBSTRUCTED; @@ -243,8 +243,8 @@ Also responsible for jumping gaps. [self obstructed: ang :TRUE]; return; } else { - if (ent.target1) { - stop = realorigin(ent.target1); + if (targets[0]) { + stop = realorigin(targets[0]); if ((stop_z - ent.origin_z) < -32) return; // safe to fall } @@ -261,8 +261,8 @@ Also responsible for jumping gaps. [self obstructed: ang :TRUE]; return; } else { - if (ent.target1) { - stop = realorigin(ent.target1); + if (targets[0]) { + stop = realorigin(targets[0]); if ((stop_z - ent.origin_z) < -32) return; // safe to fall } @@ -271,10 +271,10 @@ Also responsible for jumping gaps. } } - if (ent.target1) { + if (targets[0]) { // getting furter away from my target? - test = vlen (ent.target1.origin - (ang + ent.origin)); - if (test > vlen (ent.target1.origin - ent.origin)) { + test = vlen (targets[0].origin - (ang + ent.origin)); + if (test > vlen (targets[0].origin - ent.origin)) { if (conts < -3) { // bad stuff down dare [self obstructed: ang :TRUE]; @@ -287,8 +287,8 @@ Also responsible for jumping gaps. } } if (hgt < -18) { - if (ent.target1) { - stop = realorigin (ent.target1); + if (targets[0]) { + stop = realorigin (targets[0]); if ((stop_z - ent.origin_z) < -32) return; // safe to fall } @@ -357,12 +357,12 @@ blah local vector way; local float g; - if (ent.target1 == NIL) { + if (targets[0] == NIL) { makevectors(v_angle); [self walkmove: v_forward]; return; } - way = realorigin(ent.target1) - ent.origin; + way = realorigin(targets[0]) - ent.origin; if (vlen(way) < 25) { keys = keys & 960; return; diff --git a/fbxa/bot_qw.qc b/fbxa/bot_qw.qc index a0005af..192d85f 100644 --- a/fbxa/bot_qw.qc +++ b/fbxa/bot_qw.qc @@ -133,7 +133,6 @@ entity [32] phys_objects; .float portal_time; .integer b_skill; .float switch_wallhug; -.float b_aiflags; .integer b_num; .float b_chattime; .float b_entertime; // QW shtuff @@ -551,7 +550,7 @@ BotFrame = while (num < max_clients) { if (self.ishuman == FALSE) { if (self.b_clientno > 0) { - frik_obstacles (); + [self.@this _obstacles]; CL_KeyMove (); SV_ClientThink (); SV_Physics_Client (); diff --git a/fbxa/bot_way.qc b/fbxa/bot_way.qc index 4e7fca3..c3fbc74 100644 --- a/fbxa/bot_way.qc +++ b/fbxa/bot_way.qc @@ -504,7 +504,7 @@ in bot_ai.qc */ -entity(string s) FindThing = +entity(entity ent, string s) FindThing = { local entity t; local float tdst, dst; @@ -513,7 +513,7 @@ entity(string s) FindThing = best = NIL; t = find (NIL, classname, s); while (t != NIL) { - tdst = vlen(((t.absmin + t.absmax) * 0.5) - self.origin); + tdst = vlen(((t.absmin + t.absmax) * 0.5) - ent.origin); if (tdst < dst) { dst = tdst; best = t; diff --git a/fbxa/libfrikbot.h b/fbxa/libfrikbot.h index c23d57a..1385f01 100644 --- a/fbxa/libfrikbot.h +++ b/fbxa/libfrikbot.h @@ -32,7 +32,8 @@ integer route_failed; integer dyn_flags, dyn_time, dyn_plat; entity temp_way, last_way, current_way; - entity [4] target; + entity [4] targets; + entity avoid; entity _next, _last; vector obs_dir; vector b_dir; @@ -61,6 +62,25 @@ @end @interface Bot (AI) +-(integer)target_onstack:(entity)scot; +-(void)target_add:(entity)e; +-(void)target_drop:(entity)e; +-(void)lost:(entity)targ :(integer)success; +-(void)check_lost:(entity)targ; +-(void)handle_ai; +-(void)path; +-(float)priority_for_thing:(entity)thing; +-(void)look_for_crap:(integer)scope; +-(void)angle_set; +-(void)AI; +@end + +@interface Bot (Fight) +-(float)size_player:(entity)e; +-(void)dodge_stuff; +-(void)weapon_switch:(float)brange; +-(void)shoot; +-(void)fight_style; @end #define FALSE 0 @@ -134,7 +154,7 @@ * wp * bot */ -@extern .float b_aiflags; +@extern .integer b_aiflags; /* b_num * bot bot number */ @@ -299,11 +319,6 @@ @extern void() ClientDisconnect; @extern void() SetNewParms; -// fight -@extern void(float brange) bot_weapon_switch; -@extern void() bot_fight_style; -@extern void() bot_dodge_stuff; - // rankings @extern integer (entity e) ClientNumber; @extern float(integer clientno) ClientBitFlag; @@ -339,7 +354,7 @@ @extern void() SV_Physics_Client; @extern void() SV_ClientThink; @extern void() CL_KeyMove; -@extern entity(string s) FindThing; +@extern entity(entity ent, string s) FindThing; // ai & misc @extern void() BotAI; @@ -350,11 +365,8 @@ @extern float(entity targ) sisible; @extern float(entity targ) fisible; @extern vector(entity ent) realorigin; -@extern void(entity ent) target_drop; -@extern void(entity ent) target_add; @extern void() KickABot; @extern void() BotImpulses; -@extern void(entity targ, float success) bot_lost; @extern string(integer r) BotName; @extern float(float v) frik_anglemod; @extern void() bot_chat;