mirror of
https://git.code.sf.net/p/quake/game-source
synced 2024-11-25 05:11:58 +00:00
yay for type checking (I think). now the bots are /really/ screwed :(
This commit is contained in:
parent
c45e996252
commit
f4f6e897b3
6 changed files with 238 additions and 218 deletions
226
fbxa/bot_ai.qc
226
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)];
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue