Armor tweaks and Backstab tweaks

This commit is contained in:
Finny Merrill 2004-03-23 04:29:46 +00:00
parent 6d01c0b83a
commit 357501cad0
9 changed files with 328 additions and 128 deletions

View file

@ -2841,6 +2841,8 @@ void() PlayerPreThink =
if (self.health > 0 && self.solid != SOLID_NOT)
{
trace_ent = NIL;
// do a quick checkmove
checkmove (self.origin, self.mins, self.maxs, self.origin - '0 0 8192', MOVE_NORMAL, self);
@ -2856,6 +2858,13 @@ void() PlayerPreThink =
if (self.stucktime && self.stucktime < time &&
(trace_ent.solid == SOLID_BSP || trace_ent.classname == "player"))
{
#ifdef DEBUG
dprint ("Stuck kill, self: \n");
eprint (self);
dprint ("trace_ent: \n");
eprint (trace_ent);
#endif
TF_T_Damage (self, NIL, NIL, self.health + 100,
TF_TD_IGNOREARMOUR, TF_TD_OTHER);
}
@ -2863,6 +2872,13 @@ void() PlayerPreThink =
{
if (trace_ent.takedamage && trace_ent.classname != "player")
{
#ifdef DEBUG
dprint ("Physics kill, self: \n");
eprint (self);
dprint ("trace_ent: ");
eprint (trace_ent);
#endif
TF_T_Damage (trace_ent, NIL, NIL, self.health + 100,
TF_TD_IGNOREARMOUR, TF_TD_OTHER);
}

View file

@ -542,18 +542,18 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
}
}
else if ((targ.armorclass & AT_SAVEMELEE) && (deathmsg == DMSG_JUDOKA || deathmsg == DMSG_AXE || deathmsg == DMSG_BACKSTAB || deathmsg == DMSG_SPANNER))
else if ((targ.armorclass & AT_SAVEMELEE) && (T_AttackType = TF_TD_MELEE))
{
// This crap should all be in the weapon function. Stupid morons.
damage = floor(damage * 0.5);
if ((targ.velocity_x > 0 || targ.velocity_y > 0 || targ.velocity_z > 0) && random() > 0.6)
return;
if (deathmsg == DMSG_BACKSTAB) // O_O, why is this here?
T_flags = T_flags - (T_flags & TF_TD_IGNOREARMOUR);
}
else if ((targ.armorclass & AT_SAVEEXPLOSION) && (T_AttackType == TF_TD_EXPLOSION))
damage = floor(damage * 0.5);
else if ((targ.armorclass & AT_SAVEELECTRICITY) && (T_AttackType == TF_TD_ELECTRICITY || T_AttackType == TF_TD_NAIL))
else if ((targ.armorclass & AT_SAVEELECTRICITY) && (T_AttackType == TF_TD_ELECTRICITY))
damage = floor(damage * 0.5);
else if ((targ.armorclass & AT_SAVENAIL) && (T_AttackType == TF_TD_NAIL))
damage = floor(damage * 0.5);
else if ((targ.armorclass & AT_SAVEFIRE) && (T_AttackType == TF_TD_FIRE))
damage = floor(damage * 0.5);

View file

@ -269,6 +269,7 @@ float (entity e) EF_GlowColor;
#define TF_TD_ELECTRICITY 8 // Electric damage
#define TF_TD_FIRE 16 // Fire damage
#define TF_TD_NOSOUND 256 // Special damage. Makes no sound/painframe, etc
#define TF_TD_MELEE 512
//WK 152 Default, must be > 6.
@ -866,10 +867,12 @@ float (entity e) EF_GlowColor;
// Armor Classes : Bitfields. Use the "armorclass" of armor for the Armor Type.
#define AT_SAVESHOT 1 // Kevlar : Reduces bullet damage by 15%
#define AT_SAVEMELEE 2 // Gel : Reduces melee attacks by 15%
#define AT_SAVENAIL 2 // Wood : Reduces nail damage 15%
#define AT_SAVEEXPLOSION 4 // Blast : Reduces explosion damage 15%
#define AT_SAVEELECTRICITY 8 // Shock : Reduces electricity damage by 15%
#define AT_SAVEFIRE 16 // Asbestos : Reduces fire damage by 15%
#define AT_SAVEMELEE 32 // Gel : Reduces melee attacks by 15%
/*==========================================================================*/
/* TEAMFORTRESS CLASS DETAILS */

View file

@ -375,7 +375,21 @@ void() armor_touch =
bit = IT_ARMOR3;
}
if (other.armortype * other.armorvalue >= type*value)
local string st = infokey (NIL, "armor_add");
if (!st)
st = infokey (NIL, "ara");
if (other.armortype > type && (!st || (st != "no" && st != "0" && st != "off"))) {
value *= type / other.armortype;
type = other.armortype;
if (type == 0.8)
bit = IT_ARMOR3;
else if (type == 0.6)
bit = IT_ARMOR2;
}
if (other.armorvalue >= value)
{
// Engineers can still grab the metal
//WK - My 'Engineers' can too
@ -390,7 +404,7 @@ void() armor_touch =
}
}
if (other.armor_allowed * other.maxarmor <= type*value)
if (other.maxarmor * other.armor_allowed <= type * value)
{
if (other.armor_allowed == other.armortype)
{
@ -451,7 +465,7 @@ void() armor_touch =
value = other.maxarmor;
}
if (other.armortype * other.armorvalue < type*value)
if (other.armortype * other.armorvalue < type * value)
{
other.armortype = type;
other.armorvalue = value;
@ -459,6 +473,21 @@ void() armor_touch =
other.items = other.items & ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3) | bit;
}
if (other.armorvalue) {
// always get their bought armorclass back
if (other.tf_items & NIT_KEVLAR)
other.armorclass |= AT_SAVESHOT;
if (other.tf_items & NIT_GEL)
other.armorclass |= AT_SAVEMELEE;
if (other.tf_items & NIT_BLAST)
other.armorclass |= AT_SAVEEXPLOSION;
if (other.tf_items & NIT_CERAMIC)
other.armorclass |= AT_SAVEELECTRICITY;
if (other.tf_items & NIT_ASBESTOS)
other.armorclass |= AT_SAVEFIRE;
}
self.solid = SOLID_NOT;
self.model = "";
if (deathmatch != 2)

16
jobs.qc
View file

@ -61,6 +61,7 @@ float(entity thing) IsMonsterNonArmy;
float(entity thing) IsMonster; // for mines
void() JobArmy;
void() JobHacker;
void(entity e, boolean b, float f) find_melee;
//
// Functions for handling our "professions"
@ -569,7 +570,6 @@ void() JobJudoka =
{
//Take the weapon of any person in front of you and force a reload
self.job_finished = time + MISS_DELAY; //Delay if we don't hit
local vector source;
local vector dir;
local float chance;
local entity tWeapon,oself;
@ -578,13 +578,7 @@ void() JobJudoka =
if (self.attack_finished > time)
return;
makevectors(self.v_angle);
source = self.origin + '0 0 16';
if (self.cutf_items & CUTF_CLOSECOMBAT)
traceline(source, source + v_forward*96, FALSE, self);
else
traceline(source, source + v_forward*64, FALSE, self);
find_melee (self, TRUE, 48);
if (trace_fraction != 1.0 && trace_ent.classname == "player" && !Teammate(trace_ent.team_no, self.team_no) && trace_ent.playerclass != PC_UNDEFINED)
{
@ -665,14 +659,14 @@ void() JobJudoka =
//Hit fellow judoka or chaplan
sprint (self, PRINT_HIGH, "You throw him with a mighty Seoi Otoshi\n");
deathmsg = DMSG_JUDOKA;
TF_T_Damage (trace_ent, self, self, 150, TF_TD_NOTTEAM, TF_TD_OTHER);
TF_T_Damage (trace_ent, self, self, 150, TF_TD_NOTTEAM, TF_TD_MELEE);
}
else if (self.weapons_carried & trace_ent.current_weapon) {
sprint (self, PRINT_HIGH, "You knock his weapon out of his hands\n");
tWeapon.heat = 0; //I.e., we didn't take a weapon
trace_ent.attack_finished = time + DISARM_TIME;
deathmsg = DMSG_JUDOKA;
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM, TF_TD_OTHER);
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM, TF_TD_MELEE);
}
else if (trace_ent.current_weapon != 0 && trace_ent.current_weapon != WEAP_AXE){
//Steal their weapon if they have one
@ -719,7 +713,7 @@ void() JobJudoka =
trace_ent.current_weapon = 0;
deathmsg = DMSG_JUDOKA;
TF_T_Damage (trace_ent, self, self, 65, TF_TD_NOTTEAM, TF_TD_OTHER);
TF_T_Damage (trace_ent, self, self, 65, TF_TD_NOTTEAM, TF_TD_MELEE);
}
self.job_finished = time + HIT_DELAY;

View file

@ -323,7 +323,7 @@ void() player_axeb3 = [$axattb3, player_axeb4 ]
{
self.weaponframe=7;
if (self.current_weapon == WEAP_AXE)
W_FireAxe();
W_FireBackstab();
else // if (self.current_weapon == WEAP_SPANNER)
W_FireSpanner();
};
@ -347,7 +347,7 @@ void() player_axed3 = [$axattd3, player_axed4 ]
{
self.weaponframe=7;
if (self.current_weapon == WEAP_AXE)
W_FireAxe();
W_FireBackstab();
else // if (self.current_weapon == WEAP_SPANNER)
W_FireSpanner();
};
@ -1112,7 +1112,6 @@ void(string gibname, float dm) ThrowGib =
newmis = spawn();
newmis.origin = self.origin;
setmodel (newmis, gibname);
setsize (newmis, '0 0 0', '0 0 0');
newmis.velocity = VelocityForDamage (dm);
newmis.movetype = MOVETYPE_BOUNCE;
newmis.solid = SOLID_NOT;
@ -1129,6 +1128,8 @@ void(string gibname, float dm) ThrowGib =
newmis.skin=dm;
newmis.velocity = VelocityForDamage (-70);
}
setsize (newmis, '0 0 0', '0 0 0');
};
void(string gibname, float dm) ThrowHead =
@ -1158,6 +1159,8 @@ void(string gibname, float dm) ThrowHead =
self.nextthink = time + 20 + 20 * random();
}
*/
setorigin (self, self.origin);
//-OfN
};
@ -1175,6 +1178,8 @@ void(string gibname) HeadShotThrowHead =
self.origin_z = self.origin_z + 24;
self.flags = self.flags - (self.flags & FL_ONGROUND);
self.avelocity = '0 0 0';
setorigin (self, self.origin);
};
void() KillPlayer =

View file

@ -2416,6 +2416,10 @@ float(entity Player, float Armorclass) TeamFortress_DescribeArmor =
sprint (Player, PRINT_HIGH, "Kevlar ");
num = num + 1;
}
if (Armorclass & AT_SAVENAIL) {
sprint (Player, PRINT_HIGH, "Wood ");
num = num + 1;
}
sprint (Player, PRINT_HIGH, "armor");
return num;

View file

@ -989,25 +989,40 @@ void(entity Goal, entity Player, entity AP, float addb) Apply_Results =
{
if (Goal.armortype)
Player.armortype = Goal.armortype;
else if (!Player.armorvalue || !Player.armortype)
Player.armortype = Player.armor_allowed;
Player.armorvalue = Player.armorvalue + Goal.armorvalue;
if (Goal.armorclass)
{ //WK Modify to | it with bought armor
//TODO: Make this a map specific option
//WK Don't give wooden armor since it doesn't exist
// any more. And we don't want gel for free, right?
Player.armorclass = Goal.armorclass - (Goal.armorclass & AT_SAVEMELEE);
if (Player.tf_items & NIT_KEVLAR)
Player.armorclass = Player.armorclass | AT_SAVESHOT;
if (Player.tf_items & NIT_GEL)
Player.armorclass = Player.armorclass | AT_SAVEMELEE;
if (Player.tf_items & NIT_BLAST)
Player.armorclass = Player.armorclass | AT_SAVEEXPLOSION;
if (Player.tf_items & NIT_CERAMIC)
Player.armorclass = Player.armorclass | AT_SAVEELECTRICITY;
if (Player.tf_items & NIT_ASBESTOS)
Player.armorclass = Player.armorclass | AT_SAVEFIRE;
Player.armorclass = Goal.armorclass;
}
// always get their bought armorclass back
if (Player.tf_items & NIT_KEVLAR)
Player.armorclass = Player.armorclass | AT_SAVESHOT;
if (Player.tf_items & NIT_GEL)
Player.armorclass = Player.armorclass | AT_SAVEMELEE;
if (Player.tf_items & NIT_BLAST)
Player.armorclass = Player.armorclass | AT_SAVEEXPLOSION;
if (Player.tf_items & NIT_CERAMIC)
Player.armorclass = Player.armorclass | AT_SAVEELECTRICITY;
if (Player.tf_items & NIT_ASBESTOS)
Player.armorclass = Player.armorclass | AT_SAVEFIRE;
Player.items &= ~(IT_ARMOR3 | IT_ARMOR2 | IT_ARMOR1);
if (Player.armortype >= 0.8)
Player.items |= IT_ARMOR3;
else if (Player.armortype >= 0.6)
Player.items |= IT_ARMOR2;
else if (Player.armortype >= 0.3)
Player.items |= IT_ARMOR1;
Player.ammo_shells = Player.ammo_shells + Goal.ammo_shells;
Player.ammo_nails = Player.ammo_nails + Goal.ammo_nails;
Player.ammo_rockets = Player.ammo_rockets + Goal.ammo_rockets;

View file

@ -239,11 +239,50 @@ void(float att_delay) Attack_Finished =
if (self.tfstate & TFSTATE_TRANQUILISED)
self.attack_finished = time + (att_delay * 1.5);
else if (self.aura == AURA_HASTE)
self.attack_finished = time + (att_delay * 0.75);
self.attack_finished = time + (att_delay * 0.5);
else
self.attack_finished = time + att_delay;
};
void (entity atk, boolean do_cc, float dist) find_melee =
{
local vector dir;
if (self.classname == "player") {
makevectors (atk.v_angle);
dir = v_forward;
} else {
dir = normalize (atk.enemy.origin - atk.origin);
}
local vector source = atk.origin + '0 0 16';
traceline (source, source + dir*dist, FALSE, atk);
if (trace_fraction != 1.0)
return;
if (do_cc && (atk.cutf_items & CUTF_CLOSECOMBAT)) {
local entity te = findradius (source, dist);
local float tdist = -0.6;
do {
local vector diff = source - (te.origin + '0 0 16');
diff_z *= 0.75; //hack
local float l;
l = (normalize (diff) * dir);
if (l < tdist && te.takedamage == DAMAGE_AIM) {
tdist = l;
trace_ent = te;
trace_fraction = 0.5;
}
} while ((te = te.chain));
}
};
/*
================
W_FireAxe
@ -251,49 +290,32 @@ W_FireAxe
*/
void() W_FireAxe =
{
local vector source;
local vector org, def;
local vector dir = NIL; //XXX false +ve on uninit
if (self.classname == "player")
makevectors(self.v_angle);
else
dir = normalize (self.enemy.origin - self.origin);
source = self.origin + '0 0 16';
local vector org;
if (self.classname == "player") {
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
traceline (source, source + v_forward*64, FALSE, self);
else
traceline (source, source + v_forward*96, FALSE, self);
}
else
traceline (source, source + dir*64, FALSE, self);
find_melee (self, TRUE, 64);
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.classname == "force_field") {
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
return;
}
if (trace_ent.classname == "force_field") {
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
return;
}
if (trace_ent.takedamage) {
trace_ent.axhitme = 1;
SpawnBlood (org, 20);
if (!(self.cutf_items & CUTF_KNIFE) || trace_ent.classname != "player") {
deathmsg = DMSG_AXE;
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 30, TF_TD_NOTTEAM, TF_TD_OTHER);
else
TF_T_Damage (trace_ent, self, self, 60, TF_TD_NOTTEAM, TF_TD_OTHER);
} else { // spy can try for the backstab!
deathmsg = DMSG_AXE;
if (!(self.cutf_items & CUTF_KNIFE)) {
TF_T_Damage (trace_ent, self, self, 30, TF_TD_NOTTEAM, TF_TD_MELEE);
} else {
//WK Only give blood if you hit an enemy when being a warlock
if ((!Teammate(trace_ent.team_no, self.team_no) || !(self.job & JOB_WARLOCK)) && prematch < time) {
self.job = self.job | JOB_BLOODY_KNIFE;
@ -303,35 +325,7 @@ void() W_FireAxe =
sprint(self,PRINT_HIGH,"You may only draw blood from enemies\n");
}
// Check direction of Attack
makevectors(trace_ent.v_angle);
def = v_right;
if (self.classname == "player")
makevectors(self.v_angle);
else
makevectors(self.angles);
// Backstab
if ((crossproduct(def,v_forward) * '0 0 1') > 0) {
deathmsg = DMSG_BACKSTAB;
ThrowGib("progs/gib1.mdl", -50);
ThrowGib("progs/gib2.mdl", 10);
ThrowGib("progs/gib3.mdl", 50);
ThrowGib ("progs/gib2.mdl", 25); //-added
//WK 120 & no IGNOREARMOR
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 100, TF_TD_IGNOREARMOUR | TF_TD_NOTTEAM, TF_TD_OTHER);
else
TF_T_Damage (trace_ent, self, self, 200, TF_TD_IGNOREARMOUR | TF_TD_NOTTEAM, TF_TD_OTHER);
} else {
deathmsg = DMSG_AXE;
//WK 40
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 50, TF_TD_NOTTEAM, TF_TD_OTHER);
else
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM, TF_TD_OTHER);
}
TF_T_Damage (trace_ent, self, self, 50, TF_TD_NOTTEAM, TF_TD_MELEE);
}
} else { // hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
@ -345,6 +339,130 @@ void() W_FireAxe =
}
};
boolean (boolean strict) is_backstab =
{
local float d;
local vector dir;
makevectors (trace_ent.angles);
dir = trace_ent.origin - self.origin;
dir_z *= 0.75; // hack
d = normalize (dir) * v_forward;
if (d < 0.3)
return FALSE;
if (!strict)
return TRUE;
if (d < 0.7)
return FALSE;
d = normalize (trace_ent.origin - trace_endpos) * v_forward;
if (d < 0.8)
return FALSE;
return TRUE;
};
/*
================
W_FireBackstab
================
*/
void() W_FireBackstab =
{
local vector org;
if (!(self.cutf_items & CUTF_KNIFE)) {
W_FireAxe ();
return;
}
find_melee (self, FALSE, 64);
if (trace_fraction == 1.0)
return;
org = trace_endpos - v_forward*4;
if (trace_ent.classname == "force_field") {
FieldExplosion(trace_ent,trace_endpos,trace_ent);
PutFieldWork(trace_ent);
return;
}
local boolean living = FALSE;
if (trace_ent.classname == "player" || IsMonster (trace_ent))
living = TRUE;
if (trace_ent.takedamage) {
trace_ent.axhitme = 1;
deathmsg = DMSG_BACKSTAB;
if (living) {
if (trace_ent.classname != "player" && trace_ent.real_owner)
trace_ent.team_no = trace_ent.real_owner.team_no;
//WK Only give blood if you hit an enemy when being a warlock
if ((!Teammate(trace_ent.team_no, self.team_no) || !(self.job & JOB_WARLOCK)) && prematch < time) {
self.job = self.job | JOB_BLOODY_KNIFE;
self.weaponmode = 1;
self.weaponmodel = "progs/v_knife2.mdl";
} else if (self.job & JOB_WARLOCK) {
sprint(self,PRINT_HIGH,"You may only draw blood from enemies\n");
}
}
if (is_backstab (TRUE) && living) {
SpawnBlood (org, 50);
local entity oself = self;
self = trace_ent;
ThrowGib ("progs/gib1.mdl", -50);
ThrowGib ("progs/gib2.mdl", 10);
ThrowGib ("progs/gib3.mdl", 50);
ThrowGib ("progs/gib2.mdl", 25);
self = oself;
if (trace_ent.classname == "player")
stuffcmd (trace_ent, "bf; bf\n");
if (!(trace_ent.armorclass & AT_SAVEMELEE))
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM | TF_TD_IGNOREARMOUR,
TF_TD_MELEE);
else
TF_T_Damage (trace_ent, self, self, 100, TF_TD_NOTTEAM, TF_TD_MELEE);
} else {
deathmsg = DMSG_AXE;
SpawnBlood (org, 10);
TF_T_Damage (trace_ent, self, self, 30, TF_TD_NOTTEAM, TF_TD_MELEE);
}
} else { // hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
WriteByte (MSG_MULTICAST, TE_GUNSHOT);
WriteByte (MSG_MULTICAST, 3);
WriteCoord (MSG_MULTICAST, org_x);
WriteCoord (MSG_MULTICAST, org_y);
WriteCoord (MSG_MULTICAST, org_z);
multicast (org, MULTICAST_PVS);
}
}
/*
================
W_FireSpanner
@ -352,17 +470,11 @@ W_FireSpanner
*/
void() W_FireSpanner =
{
local vector source;
local vector org;
local float healam;
local entity te;
makevectors(self.v_angle);
source = self.origin + '0 0 16';
if (self.cutf_items & CUTF_CLOSECOMBAT)
traceline (source, source + v_forward*96, FALSE, self);
else
traceline (source, source + v_forward*64, FALSE, self);
find_melee (self, TRUE, 64);
if (trace_fraction == 1.0)
return;
@ -419,8 +531,9 @@ void() W_FireSpanner =
// auto-repair/dismantle if hit twice
if (trace_ent == self.building) {
Engineer_AutoUse();
return;
} else if (trace_ent.classname == "building_dispenser") {
}
if (trace_ent.classname == "building_dispenser") {
Engineer_UseDispenser(trace_ent);
return;
} else if (trace_ent.classname == "building_sentrygun") {
@ -492,10 +605,7 @@ void() W_FireSpanner =
deathmsg = DMSG_SPANNER;
//WK 20
if (!(self.cutf_items & CUTF_CLOSECOMBAT))
TF_T_Damage (trace_ent, self, self, 20, TF_TD_NOTTEAM, TF_TD_OTHER);
else
TF_T_Damage (trace_ent, self, self, 40, TF_TD_NOTTEAM, TF_TD_OTHER);
TF_T_Damage (trace_ent, self, self, 20, TF_TD_NOTTEAM, TF_TD_MELEE);
}
} else { // hit wall
sound (self, CHAN_WEAPON, "player/axhit2.wav", 1, ATTN_NORM);
@ -520,18 +630,11 @@ void(float tno, entity ignore, entity ignore2) teamprefixsprintbi;
void(float inAuto) W_FireMedikit =
{
local vector source;
local vector org;
local float healam;
local entity te, BioInfection;
makevectors (self.v_angle);
source = self.origin + '0 0 16';
if (self.cutf_items & CUTF_CLOSECOMBAT)
traceline (source, source + v_forward*96, FALSE, self);
else
traceline (source, source + v_forward*64, FALSE, self);
find_melee (self, TRUE, 64);
if (trace_fraction == 1.0)
return;
@ -2784,6 +2887,12 @@ void() player_axe1;
void() player_axeb1;
void() player_axec1;
void() player_axed1;
void() player_axe2;
void() player_axeb2;
void() player_axec2;
void() player_axed2;
void() player_shot1;
void() player_nail1;
@ -2848,21 +2957,46 @@ void() W_Attack =
self.show_hostile = time + 1; // wake monsters up
if (self.current_weapon == WEAP_AXE) {
//if (self.cutf_items & CUTF_KNIFE) //WK Go berserk with the knife
// Attack_Finished(0.5); // no, don't (0.35)
//else
Attack_Finished(0.5);
local float af = 0.5;
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);
r = random();
if (r < 0.25)
player_axe1 ();
else if (r<0.5)
player_axeb1 ();
else if (r<0.75)
player_axec1 ();
else
player_axed1 ();
if (self.cutf_items & CUTF_KNIFE) {
find_melee (self, TRUE, 72);
if (!is_backstab (FALSE) || !trace_ent.takedamage ||
(trace_ent.classname != "player" && !IsMonster (trace_ent))) {
af -= 0.1;
if (r < 0.5)
player_axe2 ();
else
player_axec2 ();
} else {
af += 0.3;
if (r < 0.5)
player_axeb1 ();
else
player_axed1 ();
}
} else {
if (r < 0.25)
player_axe1 ();
else if (r<0.5)
player_axeb1 ();
else if (r<0.75)
player_axec1 ();
else
player_axed1 ();
}
if (self.cutf_items & CUTF_CLOSECOMBAT)
af -= 0.1;
Attack_Finished (af);
} else if (self.current_weapon == WEAP_SPANNER) {
Attack_Finished(0.35); //WK Berserk with spanner
sound (self, CHAN_WEAPON, "weapons/ax1.wav", 1, ATTN_NORM);