mirror of
https://git.code.sf.net/p/quake/game-source
synced 2024-11-10 14:41:57 +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)
|
if (!targ)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
[self targetDrop:targ];
|
[self targetDrop:targ];
|
||||||
if (targ.ent.classname == "waypoint")
|
if ([targ isKindOfClass:[Waypoint class]])
|
||||||
targ.b_sound &= ~b_clientflag;
|
((Waypoint)targ).b_sound &= ~b_clientflag;
|
||||||
|
|
||||||
// find a new route
|
// find a new route
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -174,8 +174,8 @@ Bot has lost its target.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (targ.ent.classname != "player")
|
//XXX if (targ.ent.classname != "player")
|
||||||
targ.search_time = time + 5;
|
//XXX targ.search_time = time + 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -188,7 +188,7 @@ removed.
|
||||||
|
|
||||||
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||||
*/
|
*/
|
||||||
-(void)checkLost:(Waypoint)targ
|
-(void)checkLost:(Target)targ
|
||||||
{
|
{
|
||||||
local vector dist;
|
local vector dist;
|
||||||
|
|
||||||
|
@ -199,65 +199,71 @@ removed.
|
||||||
dist_z = 0;
|
dist_z = 0;
|
||||||
|
|
||||||
// waypoints and items are lost if you get close enough to them
|
// waypoints and items are lost if you get close enough to them
|
||||||
if (targ.ent.flags & FL_ITEM) {
|
if ([targ isKindOfClass:[Waypoint class]]) {
|
||||||
if (vlen (targ.ent.origin - ent.origin) < 32)
|
local Waypoint way = (Waypoint) targ;
|
||||||
[self lost:targ :TRUE];
|
|
||||||
else if (!targ.ent.model)
|
|
||||||
[self lost:targ :TRUE];
|
|
||||||
} else if (targ.ent.classname == "waypoint") {
|
|
||||||
if (!(b_aiflags & (AI_SNIPER | AI_AMBUSH))) {
|
if (!(b_aiflags & (AI_SNIPER | AI_AMBUSH))) {
|
||||||
if (b_aiflags & AI_RIDE_TRAIN) {
|
if (b_aiflags & AI_RIDE_TRAIN) {
|
||||||
if (vlen (targ.origin - ent.origin) < 48)
|
if (vlen (way.origin - ent.origin) < 48)
|
||||||
[self lost:targ :TRUE];
|
[self lost:way :TRUE];
|
||||||
} else if (b_aiflags & AI_PRECISION) {
|
} else if (b_aiflags & AI_PRECISION) {
|
||||||
if (vlen (targ.origin - ent.origin) < 24)
|
if (vlen (way.origin - ent.origin) < 24)
|
||||||
[self lost:targ :TRUE];
|
[self lost:way :TRUE];
|
||||||
} else if (vlen (targ.origin - ent.origin) < 32)
|
} else if (vlen (way.origin - ent.origin) < 32)
|
||||||
[self lost:targ :TRUE];
|
[self lost:way :TRUE];
|
||||||
}
|
}
|
||||||
} else if (targ.ent.classname == "temp_waypoint") {
|
//temp_waypoint
|
||||||
if (vlen (targ.origin - ent.origin) < 32)
|
if (vlen (way.origin - ent.origin) < 32)
|
||||||
[self lost:targ :TRUE];
|
[self lost:way :TRUE];
|
||||||
} else if (targ.ent.classname == "player") {
|
} else if ([targ isKindOfClass:[Bot class]]) {
|
||||||
if (targ.ent.health <= 0)
|
local Bot bot = (Bot) targ;
|
||||||
[self lost:targ :TRUE];
|
if (bot.ent.health <= 0)
|
||||||
else if ((coop) || (teamplay && targ.ent.team == ent.team)) {
|
[self lost:bot :TRUE];
|
||||||
if (targ.targets[0].ent.classname == "player") {
|
else if ((coop) || (teamplay && bot.ent.team == ent.team)) {
|
||||||
if (![targ.targets[0] ishuman])
|
if (bot.targets[0].ent.classname == "player") {
|
||||||
[self lost:targ :TRUE];
|
if (![bot.targets[0] ishuman])
|
||||||
} else if (targ.ent.teleport_time > time) {
|
[self lost:bot :TRUE];
|
||||||
|
} else if (bot.ent.teleport_time > time) {
|
||||||
// try not to telefrag teammates
|
// try not to telefrag teammates
|
||||||
keys &= ~KEY_MOVE;
|
keys &= ~KEY_MOVE;
|
||||||
} else if (vlen (targ.origin - ent.origin) < 128) {
|
} else if (vlen (bot.ent.origin - ent.origin) < 128) {
|
||||||
if (vlen (targ.origin - ent.origin) < 48)
|
if (vlen (bot.ent.origin - ent.origin) < 48)
|
||||||
[self walkmove: ent.origin - targ.origin];
|
[self walkmove: ent.origin - bot.ent.origin];
|
||||||
else {
|
else {
|
||||||
keys &= ~KEY_MOVE;
|
keys &= ~KEY_MOVE;
|
||||||
[self startTopic:4];
|
[self startTopic:4];
|
||||||
}
|
}
|
||||||
ent.search_time = time + 5; // never time out
|
ent.search_time = time + 5; // never time out
|
||||||
} else if (![self canSee:targ])
|
} else if (![self canSee:bot])
|
||||||
[self lost:targ :FALSE];
|
[self lost:bot :FALSE];
|
||||||
} else if (waypoint_mode > WM_LOADED) {
|
} else if (waypoint_mode > WM_LOADED) {
|
||||||
if (vlen (targ.origin - ent.origin) < 128) {
|
if (vlen (bot.ent.origin - ent.origin) < 128) {
|
||||||
[self lost:targ :TRUE];
|
[self lost:bot :TRUE];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (targ.ent.classname == "func_button") {
|
} else {
|
||||||
// buttons are lost of their frame changes
|
if (targ.ent.flags & FL_ITEM) {
|
||||||
if (targ.ent.frame) {
|
if (vlen (targ.ent.origin - ent.origin) < 32)
|
||||||
[self lost:targ :TRUE];
|
[self lost:targ :TRUE];
|
||||||
if (ent.enemy == targ.ent)
|
else if (!targ.ent.model)
|
||||||
ent.enemy = NIL;
|
[self lost:targ :TRUE];
|
||||||
// if (target[0])
|
} else if (targ.ent.classname == "func_button") {
|
||||||
// [self getPath:target[0] :TRUE];
|
// buttons are lost of their frame changes
|
||||||
}
|
if (targ.ent.frame) {
|
||||||
} else if ((targ.ent.movetype == MOVETYPE_NONE) && (targ.ent.solid == SOLID_TRIGGER)) {
|
[self lost:targ :TRUE];
|
||||||
// trigger_multiple style triggers are lost if their thinktime changes
|
if (ent.enemy == targ.ent)
|
||||||
if (targ.ent.nextthink >= time) {
|
ent.enemy = NIL;
|
||||||
[self lost:targ :TRUE];
|
// if (target[0])
|
||||||
// if (target[0])
|
// [self getPath:target[0] :TRUE];
|
||||||
// [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
|
// 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 *!*
|
// *!* 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;
|
if (ent.health <= 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)
|
|
||||||
return 0;
|
return 0;
|
||||||
if (thisp) {
|
if (ent.items & IT_INVISIBILITY) //FIXME
|
||||||
/*XXX
|
p = 2;
|
||||||
if (thing.current_way) {
|
else if (coop) {
|
||||||
// check to see if it's unreachable
|
if (targets[0].ent.classname == "player")
|
||||||
if (thing.current_way.items == -1)
|
if (![targets[0] ishuman])
|
||||||
return 0;
|
return 0;
|
||||||
else
|
p = 100;
|
||||||
thisp += (13000 - thing.current_way.items) * 0.05;
|
} else if (teamplay && ent.team == bot.ent.team) {
|
||||||
}
|
if (targets[0].ent.classname == "player")
|
||||||
*/
|
return 0;
|
||||||
}
|
p = 100;
|
||||||
return thisp;
|
} 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
|
-(void)lookForCrap:(integer)scope
|
||||||
{
|
{
|
||||||
local Target foe, best = NIL;
|
local Target foe, best = NIL;
|
||||||
local float thatp, bestp, dist;
|
local integer thatp, bestp;
|
||||||
|
local float dist;
|
||||||
|
|
||||||
if (scope == 1)
|
if (scope == 1)
|
||||||
foe = [Target forEntity:findradius (ent.origin, 13000)];
|
foe = [Target forEntity:findradius (ent.origin, 13000)];
|
||||||
|
|
|
@ -77,9 +77,10 @@ weapon_range =
|
||||||
};
|
};
|
||||||
|
|
||||||
@implementation Bot (Fight)
|
@implementation Bot (Fight)
|
||||||
-(float)sizePlayer:(entity)e
|
-(float)sizePlayer:(Target)targ
|
||||||
{
|
{
|
||||||
local float sz;
|
local float sz;
|
||||||
|
local entity e = targ.ent;
|
||||||
|
|
||||||
sz = e.health + e.armorvalue * e.armortype;
|
sz = e.health + e.armorvalue * e.armortype;
|
||||||
switch (e.weapon) {
|
switch (e.weapon) {
|
||||||
|
@ -134,7 +135,7 @@ weapon_range =
|
||||||
if (ent.enemy) {
|
if (ent.enemy) {
|
||||||
v = ent.origin - realorigin (ent.enemy);
|
v = ent.origin - realorigin (ent.enemy);
|
||||||
foedist = vlen (v);
|
foedist = vlen (v);
|
||||||
foesz = [self sizePlayer:ent.enemy];
|
foesz = [self sizePlayer:[Target forEntity:ent.enemy]];
|
||||||
} else {
|
} else {
|
||||||
foedist = 3000;
|
foedist = 3000;
|
||||||
foesz = 9999999;
|
foesz = 9999999;
|
||||||
|
@ -184,9 +185,10 @@ weapon_range =
|
||||||
if (foe.health > 0) {
|
if (foe.health > 0) {
|
||||||
flen = vlen (foe.origin - ent.origin);
|
flen = vlen (foe.origin - ent.origin);
|
||||||
if (flen < foedist) {
|
if (flen < foedist) {
|
||||||
tsz = [self sizePlayer:foe];
|
local Target targ = [Target forEntity:foe];
|
||||||
|
tsz = [self sizePlayer:targ];
|
||||||
if (tsz < foesz) {
|
if (tsz < foesz) {
|
||||||
if ([self canSee:foe]) {
|
if ([self canSee:targ]) {
|
||||||
ent.enemy = foe;
|
ent.enemy = foe;
|
||||||
foedist = flen;
|
foedist = flen;
|
||||||
foesz = tsz;
|
foesz = tsz;
|
||||||
|
@ -316,7 +318,7 @@ attacking an enemy.
|
||||||
} else if (!ent.enemy.takedamage) {
|
} else if (!ent.enemy.takedamage) {
|
||||||
ent.enemy = NIL;
|
ent.enemy = NIL;
|
||||||
return;
|
return;
|
||||||
} else if (![self canSee:ent.enemy]) {
|
} else if (![self canSee:[Target forEntity:ent.enemy]]) {
|
||||||
ent.enemy = NIL;
|
ent.enemy = NIL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -340,7 +342,7 @@ attacking an enemy.
|
||||||
[self weaponSwitch:foedist];
|
[self weaponSwitch:foedist];
|
||||||
|
|
||||||
if (!(b_aiflags & (AI_PRECISION | AI_BLIND | AI_OBSTRUCTED))) {
|
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;
|
mysz = [self sizePlayer:self] + 5;
|
||||||
|
|
||||||
if (foesz > mysz) {
|
if (foesz > mysz) {
|
||||||
|
@ -378,7 +380,7 @@ attacking an enemy.
|
||||||
[self walkmove:v_right * -1];
|
[self walkmove:v_right * -1];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
foesz = [self sizePlayer:ent.enemy];
|
foesz = [self sizePlayer:[Target forEntity:ent.enemy]];
|
||||||
mysz = [self sizePlayer:self] + 5;
|
mysz = [self sizePlayer:self] + 5;
|
||||||
|
|
||||||
if (foesz > mysz)
|
if (foesz > mysz)
|
||||||
|
|
|
@ -50,49 +50,6 @@ integer bot_way_linker;
|
||||||
|
|
||||||
@implementation Bot (Way)
|
@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
|
-(void)deleteWaypoint:(Waypoint)what
|
||||||
{
|
{
|
||||||
if (current_way == what)
|
if (current_way == what)
|
||||||
|
@ -181,19 +138,18 @@ different bot.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
-(void)markPath:(entity)this
|
-(void)markPath:(Target)this
|
||||||
{
|
{
|
||||||
local Waypoint t;
|
local Waypoint t;
|
||||||
local integer flag;
|
local integer flag;
|
||||||
local Bot bot = (Bot)this.@this;
|
|
||||||
|
|
||||||
[Waypoint clearMyRoute:self];
|
[Waypoint clearMyRoute:self];
|
||||||
|
|
||||||
t = [this.@this findWaypoint:bot.current_way];
|
t = [this findWaypoint:this.current_way];
|
||||||
// FIXME
|
// FIXME
|
||||||
// ugh, better way to find players please!!!
|
// ugh, better way to find players please!!!
|
||||||
if (this.classname != "player")
|
if (this.ent.classname != "player")
|
||||||
bot.current_way = t;
|
this.current_way = t;
|
||||||
|
|
||||||
if (t.enemy == NIL) {
|
if (t.enemy == NIL) {
|
||||||
[self lost:this :FALSE];
|
[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)
|
if (this == NIL)
|
||||||
return;
|
return;
|
||||||
|
@ -389,8 +345,8 @@ very good all things considered.
|
||||||
local integer i;
|
local integer i;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (way.targets[i]) {
|
if (way.links[i]) {
|
||||||
DeveloperLightning (way, way.targets[i],
|
DeveloperLightning (way, way.links[i],
|
||||||
way.flags & (AI_TELELINK_1 << i));
|
way.flags & (AI_TELELINK_1 << i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ typedef struct bot_data_t bot_data_t;
|
||||||
|
|
||||||
@interface Target: Entity
|
@interface Target: Entity
|
||||||
{
|
{
|
||||||
|
@public
|
||||||
|
Waypoint current_way;
|
||||||
}
|
}
|
||||||
+(Target)forEntity:(entity)ent;
|
+(Target)forEntity:(entity)ent;
|
||||||
-(vector)realorigin;
|
-(vector)realorigin;
|
||||||
|
@ -19,12 +21,14 @@ typedef struct bot_data_t bot_data_t;
|
||||||
-(void)setOrigin:(vector) org;
|
-(void)setOrigin:(vector) org;
|
||||||
-(integer)recognizePlat:(integer)flag;
|
-(integer)recognizePlat:(integer)flag;
|
||||||
-(integer)ishuman;
|
-(integer)ishuman;
|
||||||
|
-(integer)priority:(Bot)bot;
|
||||||
|
-(Waypoint)findWaypoint:(Waypoint)start;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface Waypoint: Target
|
@interface Waypoint: Target
|
||||||
{
|
{
|
||||||
@public
|
@public
|
||||||
Waypoint [4] targets;
|
Waypoint [4] links;
|
||||||
integer flags;
|
integer flags;
|
||||||
vector origin;
|
vector origin;
|
||||||
|
|
||||||
|
@ -97,7 +101,6 @@ typedef struct bot_data_t bot_data_t;
|
||||||
float dyn_time;
|
float dyn_time;
|
||||||
Waypoint temp_way;
|
Waypoint temp_way;
|
||||||
Waypoint last_way;
|
Waypoint last_way;
|
||||||
Waypoint current_way;
|
|
||||||
Target [4] targets;
|
Target [4] targets;
|
||||||
entity avoid;
|
entity avoid;
|
||||||
vector obs_dir;
|
vector obs_dir;
|
||||||
|
@ -148,18 +151,18 @@ typedef struct bot_data_t bot_data_t;
|
||||||
-(integer)targetOnstack:(Target)scot;
|
-(integer)targetOnstack:(Target)scot;
|
||||||
-(void)targetAdd:(Target)e;
|
-(void)targetAdd:(Target)e;
|
||||||
-(void)targetDrop:(Target)e;
|
-(void)targetDrop:(Target)e;
|
||||||
-(void)lost:(Waypoint)targ :(integer)success;
|
-(void)lost:(Target)targ :(integer)success;
|
||||||
-(void)checkLost:(Waypoint)targ;
|
-(void)checkLost:(Target)targ;
|
||||||
-(void)handleAI;
|
-(void)handleAI;
|
||||||
-(void)path;
|
-(void)path;
|
||||||
-(float)priorityForThing:(Target)thing;
|
|
||||||
-(void)lookForCrap:(integer)scope;
|
-(void)lookForCrap:(integer)scope;
|
||||||
-(void)angleSet;
|
-(void)angleSet;
|
||||||
-(void)AI;
|
-(void)AI;
|
||||||
|
-(integer)priorityForThing:(Target)thing;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface Bot (Fight)
|
@interface Bot (Fight)
|
||||||
-(float)sizePlayer:(entity)e;
|
-(float)sizePlayer:(Target)targ;
|
||||||
-(void)dodgeStuff;
|
-(void)dodgeStuff;
|
||||||
-(void)weaponSwitch:(float)brange;
|
-(void)weaponSwitch:(float)brange;
|
||||||
-(void)shoot;
|
-(void)shoot;
|
||||||
|
@ -167,12 +170,11 @@ typedef struct bot_data_t bot_data_t;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface Bot (Way)
|
@interface Bot (Way)
|
||||||
-(Waypoint)findWaypoint:(Waypoint)start;
|
|
||||||
-(void)deleteWaypoint:(Waypoint)what;
|
-(void)deleteWaypoint:(Waypoint)what;
|
||||||
-(entity)findThing:(string)s;
|
-(entity)findThing:(string)s;
|
||||||
-(Waypoint)findRoute:(Waypoint)lastone;
|
-(Waypoint)findRoute:(Waypoint)lastone;
|
||||||
-(void)markPath:(entity)this;
|
-(void)markPath:(Target)this;
|
||||||
-(void)getPath:(Waypoint)this :(integer)direct;
|
-(void)getPath:(Target)this :(integer)direct;
|
||||||
-(integer)beginRoute;
|
-(integer)beginRoute;
|
||||||
-(void)spawnTempWaypoint:(vector)org;
|
-(void)spawnTempWaypoint:(vector)org;
|
||||||
-(void)dynamicWaypoint;
|
-(void)dynamicWaypoint;
|
||||||
|
|
|
@ -73,6 +73,9 @@ struct target_s = {
|
||||||
local Target t;
|
local Target t;
|
||||||
local struct target_s ele;
|
local struct target_s ele;
|
||||||
|
|
||||||
|
if (!ent)
|
||||||
|
return NIL;
|
||||||
|
|
||||||
if (ent.classname == "player")
|
if (ent.classname == "player")
|
||||||
return ent.@this;
|
return ent.@this;
|
||||||
|
|
||||||
|
@ -138,4 +141,95 @@ struct target_s = {
|
||||||
return 0;
|
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
|
@end
|
||||||
|
|
|
@ -56,6 +56,7 @@ Array waypoint_array;
|
||||||
{
|
{
|
||||||
if (!waypoint_array) {
|
if (!waypoint_array) {
|
||||||
waypoint_array = [[Array alloc] init];
|
waypoint_array = [[Array alloc] init];
|
||||||
|
[waypoint_array addItem:NIL];
|
||||||
waypoint_queue = [[List alloc] init];
|
waypoint_queue = [[List alloc] init];
|
||||||
waypoint_thinker = spawn ();
|
waypoint_thinker = spawn ();
|
||||||
waypoint_thinker.classname = "waypoint_thinker";
|
waypoint_thinker.classname = "waypoint_thinker";
|
||||||
|
@ -121,7 +122,7 @@ make_waypoint =
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (targets[i] == way) {
|
if (links[i] == way) {
|
||||||
if (flags & (AI_TELELINK_1 << i))
|
if (flags & (AI_TELELINK_1 << i))
|
||||||
return 2;
|
return 2;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -140,8 +141,8 @@ make_waypoint =
|
||||||
return 0; // already linked!!!
|
return 0; // already linked!!!
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (!targets[i]) {
|
if (!links[i]) {
|
||||||
targets[i] = way;
|
links[i] = way;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,8 +160,8 @@ make_waypoint =
|
||||||
return 0; // already linked!!!
|
return 0; // already linked!!!
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (!targets[i]) {
|
if (!links[i]) {
|
||||||
targets[i] = way;
|
links[i] = way;
|
||||||
flags |= AI_TELELINK_1 << i;
|
flags |= AI_TELELINK_1 << i;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -178,9 +179,9 @@ make_waypoint =
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (targets[i] == way) {
|
if (links[i] == way) {
|
||||||
flags &= ~(AI_TELELINK_1 << i);
|
flags &= ~(AI_TELELINK_1 << i);
|
||||||
targets[i] = NIL;
|
links[i] = NIL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -207,10 +208,10 @@ Waypoint Loading from file
|
||||||
|
|
||||||
-(void)fix
|
-(void)fix
|
||||||
{
|
{
|
||||||
targets[0] = [Waypoint waypointForNum:b_pants];
|
links[0] = [Waypoint waypointForNum:b_pants];
|
||||||
targets[1] = [Waypoint waypointForNum:b_skill];
|
links[1] = [Waypoint waypointForNum:b_skill];
|
||||||
targets[2] = [Waypoint waypointForNum:b_shirt];
|
links[2] = [Waypoint waypointForNum:b_shirt];
|
||||||
targets[3] = [Waypoint waypointForNum:b_frags];
|
links[3] = [Waypoint waypointForNum:b_frags];
|
||||||
}
|
}
|
||||||
|
|
||||||
+(void) fixWaypoints
|
+(void) fixWaypoints
|
||||||
|
@ -301,16 +302,16 @@ tripping the runaway loop counter
|
||||||
// can you say ugly?
|
// can you say ugly?
|
||||||
if (flags & AI_TRACE_TEST) {
|
if (flags & AI_TRACE_TEST) {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (targets[i]) {
|
if (links[i]) {
|
||||||
traceline (origin, targets[i].origin, TRUE, /*self*/NIL);
|
traceline (origin, links[i].origin, TRUE, /*self*/NIL);
|
||||||
if (trace_fraction == 1)
|
if (trace_fraction == 1)
|
||||||
[self followLink:targets[i].origin :AI_TELELINK_1 << i];
|
[self followLink:links[i] :AI_TELELINK_1 << i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (targets[i]) {
|
if (links[i]) {
|
||||||
[self followLink:targets[i].origin :AI_TELELINK_1 << i];
|
[self followLink:links[i] :AI_TELELINK_1 << i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -345,6 +346,15 @@ tripping the runaway loop counter
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-(integer)priority:(Bot)bot
|
||||||
|
{
|
||||||
|
if (flags & AI_SNIPER)
|
||||||
|
return 30;
|
||||||
|
else if (flags & AI_AMBUSH)
|
||||||
|
return 30;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue