mirror of
https://git.code.sf.net/p/quake/prozac-qfcc
synced 2025-01-18 23:51:53 +00:00
Armor tweaks and Backstab tweaks
This commit is contained in:
parent
6d01c0b83a
commit
357501cad0
9 changed files with 328 additions and 128 deletions
16
client.qc
16
client.qc
|
@ -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);
|
||||
}
|
||||
|
|
10
combat.qc
10
combat.qc
|
@ -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);
|
||||
|
|
5
defs.qh
5
defs.qh
|
@ -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 */
|
||||
|
|
35
items.qc
35
items.qc
|
@ -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
16
jobs.qc
|
@ -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;
|
||||
|
|
11
player.qc
11
player.qc
|
@ -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 =
|
||||
|
|
4
tfort.qc
4
tfort.qc
|
@ -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;
|
||||
|
|
37
tfortmap.qc
37
tfortmap.qc
|
@ -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;
|
||||
|
|
322
weapons.qc
322
weapons.qc
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue