- make soldiers sometimes retreat when low on health
- make "static" mode soldiers work.  more or less.
- Massive cleanup of obituary.qc.  I'd be surprised if there isn't a
  bug or two.
This commit is contained in:
Adam Olsen 2001-10-01 11:37:02 +00:00
parent 1993bb348f
commit c3ccddb39f
10 changed files with 1654 additions and 1889 deletions

1
BUGS
View file

@ -15,3 +15,4 @@
- sentries/teslas should check their pointcontents every frame, and blow up if they're out of the map
- topcolor gets reset every time you respawn (?), even though it shouldn't be. ditto for skin?
- prematch shouldn't force autoteam when it's done
- sometimes ID doesn't work. this may be because impulses are unreliable though :/

View file

@ -217,11 +217,11 @@ void() Menu_Army2 =
if (self.demon_one.army_ready == 0)
st += "\<none \>\n";
else if (self.demon_one.army_ready == 1)
st += "\<small \>\n";
st += "\<short \>\n";
else if (self.demon_one.army_ready == 2)
st += "\<medium\>\n";
else if (self.demon_one.army_ready == 3)
st += "\<large \>\n";
st += "\<long \>\n";
}
st += "\x98.. Reports: ";

View file

@ -74,20 +74,17 @@ float(float targteam, float attackteam) Teammate =
{
local float teammask;
if ( !teamplay ) return FALSE;
if ( !targteam ) return FALSE;
if ( targteam == attackteam ) return TRUE;
if ( number_of_teams < 3 ) return FALSE;
if (!teamplay) return FALSE;
if (!targteam) return FALSE;
if (targteam == attackteam) return TRUE;
if (number_of_teams < 3) return FALSE;
if ( targteam == 1 ) teammask = 1;
else if ( targteam == 2 ) teammask = 2;
else if ( targteam == 3 ) teammask = 4;
else if ( targteam == 4 ) teammask = 8;
teammask = 1 << (targteam - 1);
if ( attackteam == 1 && (friends1_mask & teammask)) return TRUE;
else if ( attackteam == 2 && (friends2_mask & teammask)) return TRUE;
else if ( attackteam == 3 && (friends3_mask & teammask)) return TRUE;
else if ( attackteam == 4 && (friends4_mask & teammask)) return TRUE;
if (attackteam == 1 && (friends1_mask & teammask)) return TRUE;
else if (attackteam == 2 && (friends2_mask & teammask)) return TRUE;
else if (attackteam == 3 && (friends3_mask & teammask)) return TRUE;
else if (attackteam == 4 && (friends4_mask & teammask)) return TRUE;
return FALSE;
};

View file

@ -1320,3 +1320,6 @@
#include "ofndefs.qh"
#define AVG(a,b) (((a) + (b)) * 0.5)
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#define BOUND(a,b,c) (MAX((a), MIN((b), (c))))

View file

@ -21,6 +21,15 @@
*/
#define ARMY_RANGE_NONE_MIN 0
#define ARMY_RANGE_NONE_MAX 0
#define ARMY_RANGE_SMALL_MIN 75
#define ARMY_RANGE_SMALL_MAX 100
#define ARMY_RANGE_MEDIUM_MIN 175
#define ARMY_RANGE_MEDIUM_MAX 200
#define ARMY_RANGE_LONG_MIN 250
#define ARMY_RANGE_LONG_MAX 275
// Function Prototypes
// Whenever a function is added within the grunty, add it up here
@ -218,8 +227,7 @@ void() grunty_run =
if (self.super_time <= time)
{
sprint(self.real_owner, PRINT_HIGH, "Hello, commander! I am currently running at speed ");
st = ftos(self.custom_speed);
sprint(self.real_owner, PRINT_HIGH, st);
sprint(self.real_owner, PRINT_HIGH, ftos(self.custom_speed));
sprint(self.real_owner, PRINT_HIGH, " towards ");
sprint(self.real_owner, PRINT_HIGH, self.goalentity.netname);
sprint(self.real_owner, PRINT_HIGH, "\n");
@ -961,6 +969,7 @@ void() GruntyCheckFire =
// RPrint("NONE\n");
}
};
float statehack;
void() GRun =
{
@ -1012,7 +1021,13 @@ void() GRun =
if (self.has_teleporter == 0)
self.has_teleporter = 3;*/
if (random() < 0.02) // to prevent us from strafing or whatever forever.
// 0% > 75% health, 50% < 25% health, range in between
local float chance = (BOUND (0.5, 1 - (self.health / self.max_health), 0.75) - 0.50) / 8;
// dprint ("retreat chance: " + ftos (chance) + "\n");
if (random () < chance)
self.has_teleporter = 3; // we're getting wasted, better retreat
if (random () < 0.02) // to prevent us from strafing or whatever forever.
self.has_teleporter = 0;
// Test to see if we want to do an evasive maneuver
@ -1042,11 +1057,58 @@ void() GRun =
{
self.has_teleporter = 0;
botmovedist(vectoyaw(v_forward), dist); // move
return;
}
else
{
if (self.is_malfunctioning == 2 && self.enemy != world) {
local float dist = vlen (self.origin - self.enemy.origin);
local float desired_min, desired_max;
if (self.army_ready == 0) {
desired_min = ARMY_RANGE_NONE_MIN;
desired_max = ARMY_RANGE_NONE_MAX;
} else if (self.army_ready == 1) {
desired_min = ARMY_RANGE_SMALL_MIN;
desired_max = ARMY_RANGE_SMALL_MAX;
} else if (self.army_ready == 2) {
desired_min = ARMY_RANGE_MEDIUM_MIN;
desired_max = ARMY_RANGE_MEDIUM_MAX;
} else { // if (self.army_ready == 3)
desired_min = ARMY_RANGE_LONG_MIN;
desired_max = ARMY_RANGE_LONG_MAX;
}
local string diststring = "dist: " + ftos (dist)
+ " min: " + ftos (desired_min)
+ " max: " + ftos (desired_max)
+ " action: ";
if (dist < desired_min) {
if (statehack != -1) {
// dprint ("me: " + vtos (self.origin) + " goal: " + vtos (self.goalentity.origin) + "\n");
dprint (diststring + "back off\n");
statehack = -1;
}
botmovedist (vectoyaw (v_forward), dist * -0.1); // back off
} else if (dist > desired_max) {
if (statehack != 1) {
// dprint ("me: " + vtos (self.origin) + " goal: " + vtos (self.goalentity.origin) + "\n");
dprint (diststring + "close in\n");
statehack = 1;
}
botmovedist (vectoyaw (v_forward), dist); // close in
} else {
if (statehack != 0) {
// dprint ("me: " + vtos (self.origin) + " goal: " + vtos (self.goalentity.origin) + "\n");
dprint (diststring + "do nothing *cough*\n");
statehack = 0;
}
if (random () < 0.1)
botmovedist (vectoyaw (v_forward), dist);
}
} else
botmovedist(vectoyaw(v_forward), dist); // move
if (random() * 20 < 1 && self.enemy != world) // if we get a score
if (random() < 0.05 && self.enemy != world) // if we get a score
{ // of one on a d20,
local float r; // special
r = random();
@ -1060,6 +1122,7 @@ void() GRun =
self.has_teleporter = 3; // italian style!
}
}
}
};
void (float angle, float dist) botmovedist =

View file

@ -150,8 +150,6 @@ void(entity inflictor, entity attacker, float damage, entity ignore) T_RadiusDam
void(entity bastard,float threshold) createBastard;
//CY Tinker
void() DoTinker;
//WW Needed for the Dismantling
void(entity targ, entity attacker) ClientObituary;
// WK --------------

File diff suppressed because it is too large Load diff

View file

@ -6,12 +6,12 @@
=========================================================*/
//#define VERBOSE_GRUNTY
//#define WARLOCK_TEST // free summon
//#define ARMY_TEST // only 5 seconds for tele the soldier
#define WARLOCK_TEST // free summon
#define ARMY_TEST // only 5 seconds for tele the soldier
//- attack owner?
//#define MAD_GRUNTY //for testing purposes
//#define MAD_MONSTERS // for testing
#define MAD_GRUNTY //for testing purposes
#define MAD_MONSTERS // for testing
//#define MAD_TESLA // for testing
//#define GRUNTY_EXTRA_WEAPONS WEAP_ROCKET_LAUNCHER | WEAP_SUPER_SHOTGUN // 0

View file

@ -699,20 +699,20 @@ string(entity thebuilding) GetBuildingName =
{
if (thebuilding.classname == "building_dispenser")
return "dispenser";
if (thebuilding.classname == "building_sentrygun")
else if (thebuilding.classname == "building_sentrygun")
return "sentry gun";
if (thebuilding.classname == "building_tesla")
else if (thebuilding.classname == "building_tesla")
return "tesla sentry";
if (thebuilding.classname == "building_sensor")
else if (thebuilding.classname == "building_sensor")
return "motion sensor";
if (thebuilding.classname == "building_camera")
else if (thebuilding.classname == "building_camera")
return "security camera";
if (thebuilding.classname == "building_teleporter")
return "teleporter";
if (thebuilding.classname == "building_fieldgen")
else if (thebuilding.classname == "building_teleporter")
return "teleporter pad";
else if (thebuilding.classname == "building_fieldgen")
return "field generator";
return "unknown stuff";
else
return "unknown building (BUG)";
};
// soldiers don't target unoffensive buildings, or cloaked teslas!

View file

@ -1199,8 +1199,7 @@ void(float shotcount, vector dir, vector spread) FireBullets =
local vector direction;
local vector src;
// makevectors (self.v_angle); // umm, shouldn't this be dir?
makevectors (dir);
makevectors (self.v_angle);
src = self.origin + v_forward * 10;
src_z = self.absmin_z + self.size_z * 0.7;
@ -1213,10 +1212,7 @@ void(float shotcount, vector dir, vector spread) FireBullets =
direction += AVG (crandom(), crandom()) * spread_x * v_right;
direction += AVG (crandom(), crandom()) * spread_y * v_up;
if (self.current_weapon & WEAP_ASSAULT_CANNON)
traceline (src, src + direction * 2048, FALSE, self); //WK 2048
else
traceline (src, src + direction * 2024, FALSE, self); //WK 2048A
traceline (src, src + direction * 2048, FALSE, self);
if (trace_fraction == 1.0)
TraceAttack (0, direction);
@ -1290,7 +1286,8 @@ void() W_FireSuperShotgun =
dir = normalize (dir - self.origin);
}
deathmsg = DMSG_SSHOTGUN;
FireBullets (12, dir, '0.05 0.05 0'); //WK 14, 0.14, 0.08
FireBullets (6, dir, '0.05 0.05 0'); //WK 14, 0.14, 0.08
FireBullets (6, dir, '0.05 0.05 0');
};
@ -1515,12 +1512,12 @@ void() W_FireAssaultCannon =
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
dir = aim (self, 100000);
deathmsg = DMSG_ASSAULTCANNON;
//WK FireBullets (5, dir, '0.1 0.1 0');
FireBullets (5, dir, '0.15 0.10 0');
//We want more of a cone of fire...
// FireBullets (5, dir, '0.2 0.1 0');
// FireBullets (5, dir, '0.4 0.1 0');
FireBullets (7, dir, '0.16 0.12 0');
FireBullets (3, dir, '0.12 0.09 0');
// FireBullets (7, dir, '0.16 0.12 0');
// FireBullets (3, dir, '0.12 0.09 0');
};
/*