mirror of
https://git.code.sf.net/p/quake/prozac-qfcc
synced 2024-11-27 06:22:23 +00:00
<Grievre> lemme see... fixes: stuck shamblers, cheat teslas, camming and
sensing <Grievre> give mirvs the right death message, make them a little weaker and more spread out <Grievre> increased damage done by exp body... fixes not being able to use airfist if you have daedalus or lg with no cells <Grievre> made it so missing judo = you can't fire for 1.5 seconds, also judo doesn't always work, less chance of it working a) if they're facing you b) if they have knife, judo, or close combat <Grievre> you lose speed the more armor you have (so upgraded people can buy cougar and cheetah now) <Grievre> attempted to fix the respawn guard not telefragging bug (if it was still there) <Grievre> made it so you can tell a shambler to come, stop, or patrol even if it is fighting someone, doesn't really work most of the time but can "wake up" your shambler if it's being screwy <Grievre> (works for all demons) <Grievre> made it so a monster goes back to what it was doing before (following you, patrolling etc) once it's done with its enemy <Grievre> made the sniper rifle less cheap (or tried to), charging now = more accuracy, rather than more damage. OTR now does slightly less damage than regular, but isn't blocked by armor as much. <Grievre> autorifle now has half the rate of fire but does same damage as sniper rifle, but less accurate <Grievre> headshots always ignore armor if target has green armor, legshots always ignore armor except for red <Grievre> added bshams and shambler kings (can be disabled with infokeys) <Grievre> increased max knife blood to 32 <Grievre> made it so airfist bounces gymnasts twice as much, and bounces everyone a little more (I think), may cause stuck bugs but I think it won't. airfist does half damage to gymnasts and slightly more to hwguys <Grievre> made shamblers a little smarter and more powerful in general <Grievre> they now attack buildings (only bshams/kings) if they are attacked by them first <Grievre> bsham/king fireball now sets things on fire <Grievre> shamblers will generally attack the person who last hit them <Grievre> shortened judoka range (they have the old range if they get close combat <Grievre> shamblers will cycle the left-right slash or fireball longer than they did (but they won't keep doing it if their enemy is not visible) <Grievre> fixed shambler fireball so it doesn't miss and hurt itself so much <Grievre> #define OLD_AUTORIFLE <Grievre> will go to the old behavior of the auto rifle <Grievre> I think that's it <Grievre> oh, I changed the intro message and version string a little, you might want to change that
This commit is contained in:
parent
f865e4e952
commit
a365e00b22
23 changed files with 738 additions and 333 deletions
23
ai.qc
23
ai.qc
|
@ -80,6 +80,20 @@ float(float v) anglemod =
|
|||
};
|
||||
void(entity test) AI_Check_Contents =
|
||||
{
|
||||
if (test.solid != SOLID_SLIDEBOX)
|
||||
{
|
||||
bprint(PRINT_HIGH, "CRAZY! AI_Check_Contents, test.solid=");
|
||||
bprint(PRINT_HIGH, ftos(test.solid));
|
||||
bprint(PRINT_HIGH, "\n");
|
||||
}
|
||||
if (test.movetype != MOVETYPE_TOSS && test.movetype != MOVETYPE_STEP)
|
||||
{
|
||||
bprint(PRINT_HIGH, "CRAZY! AI_Check_Contents, test.movetype=");
|
||||
bprint(PRINT_HIGH, ftos(test.movetype));
|
||||
bprint(PRINT_HIGH, "\n");
|
||||
}
|
||||
|
||||
|
||||
//CH demons (and other ai) can be hurt by liquids //- OfN completely changed!
|
||||
if (pointcontents(test.origin) == CONTENTS_EMPTY && IsMonsterNonArmy(self) && self.health < self.max_health)
|
||||
{ // Heal it
|
||||
|
@ -105,6 +119,11 @@ void(entity test) AI_Check_Contents =
|
|||
rate = FIEND_REGRATE;
|
||||
}
|
||||
|
||||
if (self.is_malfunctioning)
|
||||
{
|
||||
heal = 0;
|
||||
}
|
||||
|
||||
self.dmgtime = time + rate;
|
||||
self.health = self.health + heal;//self.has_tesla - 2;
|
||||
|
||||
|
@ -1186,6 +1205,8 @@ void(float dist) ai_run =
|
|||
{
|
||||
enemy_vis=FALSE;
|
||||
|
||||
self.enemy = NIL; // FindTarget ignores self.enemy, duh (fixes stuck monsters)
|
||||
|
||||
if (self.movetarget)
|
||||
self.th_walk ();
|
||||
else
|
||||
|
@ -1231,7 +1252,7 @@ void(float dist) ai_run =
|
|||
ai_run_melee ();
|
||||
return;
|
||||
}
|
||||
if (self.attack_state == AS_FIREBALL && self.classname == "monster_demon1") //CH only for demons..
|
||||
if (self.attack_state == AS_FIREBALL) //CH only for demons.. GR why?
|
||||
{
|
||||
//RPrint ("ai_run_fire\n");
|
||||
ai_run_fire ();
|
||||
|
|
28
airfist.qc
28
airfist.qc
|
@ -42,8 +42,9 @@ $frame ablast1 ablast2 ablast3 ablast4 ablast5 ablast6
|
|||
|
||||
float (entity thing) canairpush =
|
||||
{
|
||||
if (thing.classname == "player")
|
||||
if (thing.classname == "player") {
|
||||
return TRUE;
|
||||
}
|
||||
else if (thing.classname == "pipebomb")
|
||||
{
|
||||
thing.avelocity = '300 300 300';
|
||||
|
@ -102,6 +103,7 @@ void() launch_horn =
|
|||
{
|
||||
// Local variables used in the function
|
||||
local entity e;
|
||||
local entity oself;
|
||||
local vector delta;
|
||||
local vector dir;
|
||||
local float eSpeed;
|
||||
|
@ -110,6 +112,7 @@ void() launch_horn =
|
|||
local float ldmg;
|
||||
local float nearAWall;
|
||||
|
||||
|
||||
// Constants used in the control of how the AirFist is works
|
||||
|
||||
// Maximum strength of the AirFist. The strength of the affected entity's
|
||||
|
@ -280,7 +283,15 @@ void() launch_horn =
|
|||
// take affect.
|
||||
|
||||
// raise the bugger a bit
|
||||
//setorigin(e, e.origin + '0 0 1'); // - OfN - And make them stuck in wall? :) nope..
|
||||
setorigin(e, e.origin + '0 0 1'); // - OfN - And make them stuck in wall? :) nope..
|
||||
|
||||
oself = self;
|
||||
self = e;
|
||||
|
||||
if (pointcontents(e.origin) == CONTENTS_SOLID)
|
||||
setorigin(e, e.origin - '0 0 1');
|
||||
|
||||
self = oself;
|
||||
|
||||
// We biased the up direction when entity is on the ground.
|
||||
// Looks cooler and small entitys (heath, etc) go somewhere instead
|
||||
|
@ -298,6 +309,8 @@ void() launch_horn =
|
|||
|
||||
if (e.classname == "player" && e.cutf_items & CUTF_HWGUY)
|
||||
delta = '0 0 0';
|
||||
if (e.classname == "player" && e.cutf_items & CUTF_GYMNAST)
|
||||
delta *= 2;
|
||||
|
||||
// calculate the velocity adjustment.
|
||||
delta = normalize(delta);
|
||||
|
@ -343,6 +356,13 @@ void() launch_horn =
|
|||
// calculate the damage amount
|
||||
ldmg = percent * inDamage;
|
||||
|
||||
if (e.classname == "player") {
|
||||
if (e.cutf_items & CUTF_HWGUY) // hwguy can't get knocked, but it hurts more
|
||||
ldmg *= 1.5;
|
||||
if (e.cutf_items & CUTF_GYMNAST) // gymnast goes with the flow, less damage
|
||||
ldmg *= 0.3;
|
||||
}
|
||||
|
||||
// This section of code is to even of the "figure momentum add" in the
|
||||
// T_Damage function that recoils damaged entity's away from the attacker.
|
||||
// NOTE: If that section of code in T_Damage changesm then this will have to
|
||||
|
@ -404,8 +424,10 @@ void() launch_horn =
|
|||
// take affect.
|
||||
|
||||
// raise the bugger a bit
|
||||
//setorigin(self, self.origin + '0 0 1'); // - OfN - And make them stuck in wall? :) nope..
|
||||
setorigin(self, self.origin + '0 0 1'); // - OfN - And make them stuck in wall? - GR No, but that screws it up
|
||||
self.flags = self.flags - FL_ONGROUND;
|
||||
if (pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
setorigin(self, self.origin + '0 0 -1');
|
||||
}
|
||||
|
||||
if(nearAWall)
|
||||
|
|
35
combat.qc
35
combat.qc
|
@ -301,10 +301,6 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
local string output;
|
||||
local float knockem;
|
||||
|
||||
//WK -- For LPB calculation
|
||||
local string foo;
|
||||
local float ping;
|
||||
|
||||
mirror = 0;
|
||||
if (infokey(NIL,"ceasefire")=="on") //Cyto
|
||||
return;
|
||||
|
@ -420,11 +416,14 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
|
||||
//DAMAGE ADJUSTMENT
|
||||
//- OfN - if (deathmsg != DMSG_MARTYR && targ.classname != "monster_demon1" && targ.classname != "monster_shambler" && targ.classname != "monster_army")
|
||||
|
||||
if (deathmsg != DMSG_MARTYR && !IsMonster(targ))
|
||||
{
|
||||
if (targ.tfstate & TFSTATE_INSPIRED) //Chaplan defense
|
||||
damage = damage * 0.66;
|
||||
//WK Ping fairness code. LPB is < 200 ping
|
||||
//haha, yeah right.
|
||||
#if 0
|
||||
if (attacker.classname == "player" && targ.classname == "player" && attacker != targ)
|
||||
{
|
||||
foo = infokey(attacker,"ping");
|
||||
|
@ -436,6 +435,7 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
if (ping > 1.2) ping = 1.2;
|
||||
damage = damage * ping;
|
||||
}
|
||||
#endif
|
||||
if (teamplay & (TEAMPLAY_LESSSCOREHELP | TEAMPLAY_LESSPLAYERSHELP))
|
||||
damage = TeamEqualiseDamage(targ, attacker, damage);
|
||||
}
|
||||
|
@ -500,43 +500,30 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
// SPECIAL ARMOR CALCULATIONS
|
||||
if ((targ.armorclass != 0) && (T_AttackType != 0))
|
||||
{
|
||||
// OTR changed, it now just does less damage but ignores armor.
|
||||
if ((targ.armorclass & AT_SAVESHOT) && (T_AttackType == TF_TD_SHOT)) {
|
||||
damage = floor(damage * 0.5);
|
||||
//WK Cap max damage you can take with kevlar on, like in Real Life(tm)
|
||||
//WK The purpose being to cut down on the power of snipers
|
||||
if(targ.classname == "player") // SB kevlar fixed so it caps damage now, also spacing much nicer :)
|
||||
{
|
||||
local float olddamage; //- OfN - special cap damage with otr! heh
|
||||
olddamage=damage;
|
||||
|
||||
if (light_damage)
|
||||
{
|
||||
if (damage > 75)
|
||||
damage = 75;
|
||||
}
|
||||
else
|
||||
if (damage > 100) damage = 100;
|
||||
else if (damage > 100) damage = 100;
|
||||
|
||||
if (attacker.classname == "player" && (deathmsg == DMSG_SNIPERRIFLE || deathmsg == DMSG_SNIPERHEADSHOT || deathmsg == DMSG_SNIPERLEGSHOT))
|
||||
{
|
||||
sprint(attacker,PRINT_HIGH,"You hit kevlar\n");
|
||||
if (attacker.cutf_items & CUTF_OTR) //- OfN -
|
||||
{
|
||||
if (olddamage > 100)
|
||||
olddamage=olddamage - ((olddamage - 100)*0.4);
|
||||
|
||||
damage = olddamage;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((targ.armorclass & AT_SAVEMELEE) && (deathmsg == DMSG_JUDOKA || deathmsg == DMSG_AXE || deathmsg == DMSG_BACKSTAB || deathmsg == DMSG_SPANNER))
|
||||
{
|
||||
// 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)
|
||||
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))
|
||||
|
@ -563,6 +550,7 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
targ.armortype = 0; // lost all armor
|
||||
targ.armorclass = 0; // lost special armor
|
||||
targ.items = targ.items & ~(IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3);
|
||||
TeamFortress_SetSpeed(targ);
|
||||
}
|
||||
//WK Flags prevent armor damage too
|
||||
if (T_flags & TF_TD_NOTTEAM)
|
||||
|
@ -595,6 +583,8 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
}
|
||||
// targ.armorvalue = targ.armorvalue - save;
|
||||
take = ceil(damage-save);
|
||||
if (targ.armorvalue > 0 && (targ.armorvalue + save > 100))
|
||||
TeamFortress_SetSpeed(targ); // speed up the less armor you have
|
||||
}
|
||||
// add to the damage total for clients, which will be sent as a single
|
||||
// message at the end of the frame
|
||||
|
@ -743,9 +733,6 @@ void(entity targ, entity inflictor, entity attacker, float damage, float T_flags
|
|||
if (self.th_pain)
|
||||
{
|
||||
self.th_pain (attacker, take);
|
||||
// nightmare mode monsters don't go into pain frames often
|
||||
if (skill >= 3)
|
||||
self.pain_finished = time + 5;
|
||||
}
|
||||
|
||||
self = oldself;
|
||||
|
|
16
demoman.qc
16
demoman.qc
|
@ -106,8 +106,8 @@ void (vector org, entity shooter) MirvGrenadeLaunch =
|
|||
local float xdir,ydir,zdir;
|
||||
|
||||
xdir = 150 * random() - 75;
|
||||
ydir = 150 * random() - 75;
|
||||
zdir = 40 * random();
|
||||
ydir = 2 * (100 - fabs(xdir)) * random() - (75 - fabs(xdir));
|
||||
zdir = 170 - (fabs(xdir) + fabs(ydir));
|
||||
|
||||
newmis = spawn ();
|
||||
newmis.owner = shooter;
|
||||
|
@ -118,8 +118,8 @@ void (vector org, entity shooter) MirvGrenadeLaunch =
|
|||
newmis.weapon = DMSG_GREN_MIRV;
|
||||
|
||||
#ifdef NET_SERVER
|
||||
newmis.touch = NormalGrenadeTouch;
|
||||
newmis.think = NormalGrenadeExplode;
|
||||
newmis.touch = GrenadeTouch;
|
||||
newmis.think = GrenadeExplode;
|
||||
#else
|
||||
newmis.touch = GrenadeTouch;
|
||||
newmis.think = GrenadeExplode;
|
||||
|
@ -128,11 +128,11 @@ void (vector org, entity shooter) MirvGrenadeLaunch =
|
|||
//WK 2 + random
|
||||
newmis.nextthink = time + 0.75 + random();
|
||||
|
||||
newmis.velocity_x = xdir * 2;
|
||||
newmis.velocity_y = ydir * 2;
|
||||
newmis.velocity_z = zdir * 15;
|
||||
newmis.velocity_x = xdir * 3;
|
||||
newmis.velocity_y = ydir * 3;
|
||||
newmis.velocity_z = zdir * 5;
|
||||
|
||||
newmis.avelocity='100 100 400';
|
||||
newmis.avelocity='100 100 500';
|
||||
|
||||
setmodel (newmis, "progs/grenade2.mdl");
|
||||
setsize (newmis, VEC_ORIGIN, VEC_ORIGIN);
|
||||
|
|
2
demon.qc
2
demon.qc
|
@ -708,7 +708,7 @@ void() monster_demon_respawn =
|
|||
|
||||
void () custom_demon_die =
|
||||
{
|
||||
if (self.real_owner.classname == "player")
|
||||
if (self.real_owner.classname == "player" && self.real_owner.demon_one == self)
|
||||
{
|
||||
sprint(self.real_owner,PRINT_HIGH,"Your fiend is dead.\n");
|
||||
self.real_owner.job = self.real_owner.job - (self.real_owner.job & JOB_DEMON_OUT);
|
||||
|
|
47
jobs.qc
47
jobs.qc
|
@ -13,6 +13,7 @@ Functions for handling the custom class professions
|
|||
|
||||
//WK - all of this
|
||||
|
||||
void(float delay) Attack_Finished;
|
||||
void() DropToCustomClassGen; //Called when starting class generation
|
||||
void() DropFromCustomClassGen; //Called when finished class generation
|
||||
void() PrintMoney;
|
||||
|
@ -490,10 +491,6 @@ void() JobBerserker =
|
|||
//So we don't have to do error checking on those situations
|
||||
//Four special cases, Rifle, Medikit, AC and Grapple, have side effects
|
||||
// when you remove them. Need special cases to handle their theft
|
||||
#define DISARM_TIME 10
|
||||
#define CANT_ATTACK_TIME 5
|
||||
#define HIT_DELAY 8
|
||||
#define MISS_DELAY 1
|
||||
void() JudokaRearm =
|
||||
{
|
||||
//Self.owner is the guy who had his weapon taken away
|
||||
|
@ -574,22 +571,48 @@ 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;
|
||||
local entity te;
|
||||
|
||||
makevectors(self.v_angle);
|
||||
source = self.origin + '0 0 16';
|
||||
traceline (source, source + v_forward*96, FALSE, self);
|
||||
if (trace_fraction == 1.0) {
|
||||
sprint (self, PRINT_HIGH, "You miss.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (trace_ent.classname == "player" && !Teammate(trace_ent.team_no, self.team_no) && trace_ent.playerclass != PC_UNDEFINED)
|
||||
if (self.cutf_items & CUTF_CLOSECOMBAT)
|
||||
traceline(source, source + v_forward*96, FALSE, self);
|
||||
else
|
||||
traceline(source, source + v_forward*64, FALSE, self);
|
||||
|
||||
if (trace_fraction != 1.0 && trace_ent.classname == "player" && !Teammate(trace_ent.team_no, self.team_no) && trace_ent.playerclass != PC_UNDEFINED)
|
||||
{
|
||||
if (self.is_undercover) //Taking someone's weapon should give you away
|
||||
Spy_RemoveDisguise(self);
|
||||
|
||||
// Let's not make it work all the time
|
||||
dir = normalize (trace_ent.origin - self.origin);
|
||||
makevectors(trace_ent.v_angle);
|
||||
|
||||
chance = dir * normalize(v_forward);
|
||||
chance *= 0.35;
|
||||
if (chance > 0.25)
|
||||
chance = 0.25;
|
||||
if (trace_ent.job & JOB_JUDOKA)
|
||||
chance += 0.2;
|
||||
if (trace_ent.cutf_items & CUTF_CLOSECOMBAT)
|
||||
chance += 0.25;
|
||||
if (trace_ent.current_weapon == WEAP_AXE && trace_ent.cutf_items & CUTF_KNIFE)
|
||||
chance += 0.1;
|
||||
if (self.cutf_items & CUTF_CLOSECOMBAT)
|
||||
chance -= 0.25;
|
||||
|
||||
if (random() > chance)
|
||||
{
|
||||
sprint (self, PRINT_HIGH, "Your strike is parried!\n");
|
||||
Attack_Finished(3);
|
||||
return;
|
||||
}
|
||||
|
||||
sprint (trace_ent, PRINT_HIGH, "You have been disarmed by ");
|
||||
sprint (trace_ent, PRINT_HIGH, self.netname);
|
||||
sprint (trace_ent, PRINT_HIGH, "\n");
|
||||
|
@ -690,9 +713,13 @@ void() JobJudoka =
|
|||
}
|
||||
|
||||
self.job_finished = time + HIT_DELAY;
|
||||
Attack_Finished(0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprint (self, PRINT_HIGH, "You miss.\n");
|
||||
Attack_Finished(1.5);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
6
jobs.qh
6
jobs.qh
|
@ -45,10 +45,10 @@ Functions for handling the custom class professions
|
|||
//So we don't have to do error checking on those situations
|
||||
//Four special cases, Rifle, Medikit, AC and Grapple, have side effects
|
||||
// when you remove them. Need special cases to handle their theft
|
||||
#define DISARM_TIME 10
|
||||
#define CANT_ATTACK_TIME 5
|
||||
#define DISARM_TIME 20
|
||||
#define CANT_ATTACK_TIME 3
|
||||
#define HIT_DELAY 8
|
||||
#define MISS_DELAY 1
|
||||
#define MISS_DELAY 3
|
||||
|
||||
/*
|
||||
** Guerilla Profession -
|
||||
|
|
3
menu.qc
3
menu.qc
|
@ -2402,7 +2402,6 @@ void(float inp) Menu_EngineerFix_Tesla_Input2 =
|
|||
sprint(self, PRINT_HIGH, "Gun is already deployed\n");
|
||||
}
|
||||
else {
|
||||
self.building.origin_z = self.building.origin_z + 15; // +15//Elevate for the check
|
||||
//Make sure the launch area is clear
|
||||
if (FALSE) {
|
||||
//if (CheckArea(self.building,self) == FALSE) {
|
||||
|
@ -2411,7 +2410,7 @@ void(float inp) Menu_EngineerFix_Tesla_Input2 =
|
|||
}
|
||||
else {
|
||||
//self.building.origin_z = self.building.origin_z + 25; //+ 25 //Finish liftoff
|
||||
self.building.origin_z = self.building.origin_z - 25; //often fixes tesla not touchin ceiling//+ 25 //Finish liftoff
|
||||
self.building.origin_z = self.building.origin_z - 34; //often fixes tesla not touchin ceiling//+
|
||||
sprint(self, PRINT_HIGH, "You turretize the tesla\n");
|
||||
|
||||
if (self.building.job == 1 && self.building.tf_items & NIT_TESLA_CLOAKING)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
// This file contains defines for some of the messages
|
||||
#define MSG_INTRO1 "Welcome to ÐÒÏÚÁÃ CustomÔÆ\na Quake ÔÆ MOD by ShakaUVM\nwww®telefragged®com¯shaka"
|
||||
#define MSG_INTRO2 "Based on the aussie ver by SB-1\nModified version by Clan Prozac"
|
||||
#define MSG_INTRO2 "Hacked by KK, then SB-1 then OfN, then the Quakeforge team, then Grievre"
|
||||
//#define MSG_INTRO3 "Get any files needed at:\n\nhttp:\^/\^/quake\^.prozac\^.net\^/"
|
||||
#define MSG_INTROBAR "\n\n<>žžžžžžžžžžžžžžžžžžžžžžžžžžŸ\n\n"
|
||||
//, aka óC”’’’
|
||||
//#define MSG_CUTFVERSION "CustomÔÆ version ö3®2®OfN"
|
||||
#define MSG_CUTFVERSION "ÐÒÏÚÁÃ CustomÔÆ ö3®2®OfN4"
|
||||
#define MSG_CUTFVERSION "ÐÒÏÚÁÃ CustomÔÆ ö3®2®OfN4-qfcc-GR3"
|
||||
|
||||
// Comments CenterPrinted when a player gets the CTF flag
|
||||
#define MSG_CTF_FLAG_GRAB_TEAM1 "You got the enemy flag!\n\nFlee!"
|
||||
|
|
|
@ -533,6 +533,9 @@ void() walkmonster_start_go =
|
|||
// local float failure;
|
||||
// local vector test;
|
||||
|
||||
self.movetype = MOVETYPE_STEP;
|
||||
self.solid = SOLID_SLIDEBOX;
|
||||
|
||||
self.origin_z = self.origin_z + 1; // raise off floor a bit
|
||||
droptofloor();
|
||||
|
||||
|
|
39
obituary.qc
39
obituary.qc
|
@ -431,9 +431,10 @@ void (entity targ, entity attacker) Obituary_Player_by_Shambler =
|
|||
{
|
||||
custom_demon_name (attacker); //CH
|
||||
|
||||
if (attacker.real_owner == targ) {
|
||||
Give_Frags_Out (attacker.real_owner, attacker.real_owner, -2, 0, 1, 1, 0);
|
||||
if (attacker.real_owner == targ || (attacker.is_malfunctioning && attacker.martyr_enemy == targ)) {
|
||||
|
||||
if (!attacker.is_malfunctioning)
|
||||
Give_Frags_Out (attacker.real_owner, attacker.real_owner, -2, 0, 1, 1, 0);
|
||||
if (deathmsg == DMSG_LIGHTNING) {
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " annihilates its owner ");
|
||||
|
@ -444,6 +445,14 @@ void (entity targ, entity attacker) Obituary_Player_by_Shambler =
|
|||
bprint (PRINT_MEDIUM, " detonates its owner ");
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " with a fireball\n");
|
||||
} else if (deathmsg == DMSG_FLAME && attacker.has_tesla > 5) {
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
if (attacker.has_tesla == 6)
|
||||
bprint (PRINT_MEDIUM, " was torched by his own battle shambler, ");
|
||||
else
|
||||
bprint (PRINT_MEDIUM, " was deep-fried by his ally, ");
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, "\n");
|
||||
} else {
|
||||
if (random () < FRAC (1, 2)) {
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
|
@ -483,12 +492,24 @@ void (entity targ, entity attacker) Obituary_Player_by_Shambler =
|
|||
bprint (PRINT_MEDIUM, ") lightning\n");
|
||||
} else {
|
||||
bprint (PRINT_MEDIUM, attacker.real_owner.netname);
|
||||
if (attacker.has_tesla < 6)
|
||||
bprint (PRINT_MEDIUM, "'s shambler, ");
|
||||
else if (attacker.has_tesla == 6)
|
||||
bprint (PRINT_MEDIUM, "'s battle shambler, ");
|
||||
else
|
||||
bprint (PRINT_MEDIUM, "'s shambler king, ");
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, ", teaches ");
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " to cook without gas\n");
|
||||
}
|
||||
} else if (deathmsg == DMSG_FLAME) {
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " is immolated by ");
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, attacker.real_owner.netname);
|
||||
bprint (PRINT_MEDIUM, ")'s hellfire\n");
|
||||
} else if (deathmsg == DMSG_DEMON_FIRE) {
|
||||
if (random () < FRAC (1, 2)) {
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
|
@ -2165,13 +2186,19 @@ void (entity targ, entity attacker) Obituary_Monster_Shambler_by_Shambler =
|
|||
{
|
||||
custom_demon_name (attacker);
|
||||
|
||||
if (Teammate (targ.real_owner.team_no, attacker.real_owner.team_no)) {
|
||||
if (attacker == targ && deathmsg == DMSG_FLAME)
|
||||
{
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, attacker.real_owner.netname);
|
||||
bprint (PRINT_MEDIUM, ") sets itself on fire one too many times.\n");
|
||||
} else if (Teammate (targ.real_owner.team_no, attacker.real_owner.team_no)) {
|
||||
Give_Frags_Out (attacker, targ, -1, 0, 1, 1, 0);
|
||||
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, attacker.real_owner.netname);
|
||||
bprint (PRINT_MEDIUM, ") electrifies the friendly shambler ");
|
||||
bprint (PRINT_MEDIUM, ") destroys the friendly shambler ");
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, targ.real_owner.netname);
|
||||
|
@ -2234,7 +2261,7 @@ void (entity targ, entity attacker) Obituary_Monster_Shambler_by_Wizard =
|
|||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, attacker.real_owner.netname);
|
||||
bprint (PRINT_MEDIUM, ") kills the friendly soldier ");
|
||||
bprint (PRINT_MEDIUM, ") nullifies the friendly shambler ");
|
||||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, targ.real_owner.netname);
|
||||
|
@ -2245,7 +2272,7 @@ void (entity targ, entity attacker) Obituary_Monster_Shambler_by_Wizard =
|
|||
bprint (PRINT_MEDIUM, targ.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
bprint (PRINT_MEDIUM, targ.real_owner.netname);
|
||||
bprint (PRINT_MEDIUM, ") had his army career truncated by the scrag ");
|
||||
bprint (PRINT_MEDIUM, ") is destroyed by the scrag ");
|
||||
//bprint (PRINT_MEDIUM, attacker.undercover_name);
|
||||
bprint (PRINT_MEDIUM, attacker.netname);
|
||||
bprint (PRINT_MEDIUM, " (");
|
||||
|
|
10
ofndefs.qh
10
ofndefs.qh
|
@ -23,10 +23,10 @@
|
|||
|
||||
#define MOTD_REFRESHRATE 1
|
||||
|
||||
#define MAX_KNIFE_BLOOD 12 // maximum of knife kill points that can be accumulated by warlocks
|
||||
#define MAX_KNIFE_BLOOD 32 // maximum of knife kill points that can be accumulated by warlocks
|
||||
|
||||
#define GRUNTY_HP 600 // initial HP for soldier
|
||||
#define GRUNT_MAX_HP 1200 // OfN - Max health for the damn soldier, no 5000 hp grunts anymore! =)
|
||||
#define GRUNT_MAX_HP 2000 // OfN - Max health for the damn soldier, no 5000 hp grunts anymore! =) GR - why not?
|
||||
|
||||
#define SHAMBLER_HP 2600 // 2000 - 3000 - 2600
|
||||
#define HKNIGHT_HP 2200 //
|
||||
|
@ -37,14 +37,16 @@
|
|||
#define SCRAG_DMG 29 // damage the scrag does
|
||||
|
||||
#define WAYPOINT_LIFE 240 // 120 after this amount of seconds any unused waypoint will be removed
|
||||
#define OTR_DMGFACTOR 1.10 // *damage facter for the OTR armed sniper rifle (MUST BE GREATER THAN 1!!!)
|
||||
#define OTR_DMGFACTOR 0.6 // *damage facter for the OTR armed sniper rifle (MUST BE GREATER THAN 1!!!) no
|
||||
#define SENTRY_UNLOCKTIME 2.5 // (must be greater than 1.1) time for the sentries to begin to rotate after they have no target (+/- 1 second)
|
||||
#define HAX_UNSTABLEDIST 300 // distance at which enemy hacks take longer cause of "unstable connection"
|
||||
#define WAYPOINT_AI_LIFE 10 // life for grunty ai created waypoints - last seen enemy mark
|
||||
#define ATTN_MONSTERDIE ATTN_NONE // ATTN_NORM
|
||||
#define MINE_SCANRATE 0.6 // mines look again for nearby enemy after this time - it was 1 which caused high ping players to not trigger mines sometimes walking around them fast
|
||||
#define EXPBODY_DMG 160 // damage exp. body does /was 140
|
||||
#define EXPBODY_DMG 200 // damage exp. body does /was 140 GR this was really really wimpy
|
||||
#define MINE_DMG 200 // was 240 /215
|
||||
#define SNIPER_DMG 90 // was charge up. Makes more sense for sniper bullets to do constant damage.
|
||||
#define OTR_DMG 50 // extra damage done by OTR (always ignores armor)
|
||||
|
||||
#define BERSERKER_HP_COST 30
|
||||
|
||||
|
|
7
often.qc
7
often.qc
|
@ -685,7 +685,14 @@ string(entity themonster) GetMonsterName =
|
|||
if (themonster.classname == "monster_wizard")
|
||||
return "scrag";
|
||||
if (themonster.classname == "monster_shambler")
|
||||
{
|
||||
if (themonster.has_tesla > 6)
|
||||
return "shambler king";
|
||||
if (themonster.has_tesla == 6)
|
||||
return "battle shambler";
|
||||
else
|
||||
return "shambler";
|
||||
}
|
||||
if (themonster.classname == "monster_demon1")
|
||||
return "fiend";
|
||||
if (themonster.classname == "monster_army")
|
||||
|
|
|
@ -36,7 +36,7 @@ Defines for the compilable options within TF.
|
|||
#define FLAME_MAXWORLDNUM 60 // maximum number of flames in the world. DO NOT PUT BELOW 20.
|
||||
#define MAX_WORLD_PIPEBOMBS 30 // This is divided between teams
|
||||
#define MAX_WORLD_AMMOBOXES 6 // This is divided between teams
|
||||
#define GR_TYPE_MIRV_NO 12 // Number of Mirvs a Mirv Grenade breaks into
|
||||
#define GR_TYPE_MIRV_NO 4 // Number of Mirvs a Mirv Grenade breaks into
|
||||
#define GR_TYPE_NAPALM_NO 12 // Number of flames napalm grenade breaks into
|
||||
#endif
|
||||
|
||||
|
|
27
sbitems.qc
27
sbitems.qc
|
@ -320,26 +320,7 @@ void() MotionSensorTossTouch =
|
|||
{
|
||||
if (other || other == self.real_owner)
|
||||
return;
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 2') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
{
|
||||
MotionSensorDie();
|
||||
return;
|
||||
}
|
||||
//CH sees where landed and adjusts to proper things
|
||||
if (pointcontents(self.origin + '0 0 1') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '0 0 12';
|
||||
if (pointcontents(self.origin - '0 0 1') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '0 0 4';
|
||||
if (pointcontents(self.origin + '0 1 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '0 16 0';
|
||||
if (pointcontents(self.origin - '0 1 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '0 16 0';
|
||||
if (pointcontents(self.origin + '1 0 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '16 0 0';
|
||||
if (pointcontents(self.origin + '1 0 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '16 0 0';
|
||||
setorigin (self, self.origin);
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 2') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 18') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
{
|
||||
MotionSensorDie();
|
||||
return;
|
||||
|
@ -485,18 +466,20 @@ void() MotionSensorSpawn =
|
|||
self.has_sensor = TRUE;
|
||||
newmis = spawn();
|
||||
newmis.movetype = MOVETYPE_BOUNCE;
|
||||
setsize (newmis, '0 0 0', '0 0 0');
|
||||
setsize (newmis, '-16 -16 -6', '16 16 10');
|
||||
// setsize (newmis, '-8 -8 -8', '8 8 8');
|
||||
newmis.solid = SOLID_BBOX;
|
||||
newmis.takedamage = DAMAGE_AIM;
|
||||
newmis.classname = "building_sensor";
|
||||
newmis.netname = "motion_sensor";
|
||||
setorigin (newmis, self.origin);
|
||||
newmis.origin = self.origin;
|
||||
newmis.owner = NIL;
|
||||
newmis.real_owner = self;
|
||||
makevectors (self.v_angle);
|
||||
newmis.avelocity = '0 0 0';
|
||||
newmis.velocity = v_forward*800 + v_up * 200 + v_right*10 + v_up*10;
|
||||
newmis.origin += normalize(newmis.velocity) * 20;
|
||||
setorigin(newmis, newmis.origin);
|
||||
newmis.angles = '0 0 0';
|
||||
newmis.angles_y = anglemod(self.angles_y + 180);
|
||||
// newmis.skin = 1;
|
||||
|
|
31
security.qc
31
security.qc
|
@ -227,18 +227,20 @@ void() Security_Camera_Spawn =
|
|||
self.has_camera = TRUE;
|
||||
newmis = spawn();
|
||||
newmis.movetype = MOVETYPE_BOUNCE;
|
||||
setsize (newmis, '0 0 0', '0 0 0');
|
||||
setsize (newmis, '-16 -16 -6', '16 16 10');
|
||||
// setsize (newmis, '-8 -8 -8', '8 8 8');
|
||||
newmis.solid = SOLID_BBOX;
|
||||
newmis.takedamage = DAMAGE_AIM;
|
||||
newmis.classname = "building_camera";
|
||||
newmis.netname = "security_camera";
|
||||
setorigin (newmis, self.origin);
|
||||
newmis.origin = self.origin;
|
||||
newmis.owner = NIL;
|
||||
newmis.real_owner = self;
|
||||
makevectors (self.v_angle);
|
||||
newmis.avelocity = '0 0 0';
|
||||
newmis.velocity = v_forward*800 + v_up * 200 + v_right*10 + v_up*10;
|
||||
newmis.origin += (normalize(newmis.velocity) * 20);
|
||||
setorigin(newmis, newmis.origin);
|
||||
newmis.angles = '0 0 0';
|
||||
newmis.angles_y = anglemod(self.angles_y + 180);
|
||||
// newmis.skin = 1;
|
||||
|
@ -250,6 +252,9 @@ void() Security_Camera_Spawn =
|
|||
newmis.colormap = self.colormap;
|
||||
newmis.heat = 0; //Beeps
|
||||
|
||||
newmis.think = Security_Camera_Die;
|
||||
newmis.nextthink = time + 5;
|
||||
|
||||
newmis.health = newmis.max_health = BUILD_HEALTH_CAMERA;
|
||||
newmis.touch = SecurityCameraTossTouch;
|
||||
|
||||
|
@ -263,30 +268,12 @@ void() SecurityCameraTossTouch =
|
|||
{
|
||||
if (other || other == self.real_owner)
|
||||
return;
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 2') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
{
|
||||
Security_Camera_Die();
|
||||
return;
|
||||
}
|
||||
//CH sees where landed and adjusts to proper things
|
||||
if (pointcontents(self.origin + '0 0 1') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '0 0 12';
|
||||
if (pointcontents(self.origin - '0 0 1') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '0 0 4';
|
||||
if (pointcontents(self.origin + '0 1 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '0 16 0';
|
||||
if (pointcontents(self.origin - '0 1 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '0 16 0';
|
||||
if (pointcontents(self.origin + '1 0 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin - '16 0 0';
|
||||
if (pointcontents(self.origin + '1 0 0') == CONTENTS_SOLID)
|
||||
self.origin = self.origin + '16 0 0';
|
||||
setorigin (self, self.origin);
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 2') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY || pointcontents(self.origin + '0 0 12') == CONTENTS_SKY || pointcontents(self.origin) == CONTENTS_SOLID)
|
||||
{
|
||||
Security_Camera_Die();
|
||||
return;
|
||||
}
|
||||
|
||||
sprint (self.real_owner, PRINT_HIGH, "You finish building the Security Camera.\n");
|
||||
|
||||
teamprefixsprint(self.real_owner.team_no,self.real_owner); //- OfN
|
||||
|
|
424
shambler.qc
424
shambler.qc
|
@ -1,9 +1,12 @@
|
|||
#include "defs.qh"
|
||||
//void(float side) ShamFireball;
|
||||
//void() sham_fireballl1;
|
||||
//void() sham_fireballr1;
|
||||
//void() shambler_fire_touch;
|
||||
void(float side) ShamFireball;
|
||||
void() sham_fireballl1;
|
||||
void() sham_fireballr1;
|
||||
void() shambler_fire_touch;
|
||||
void() shambler_fire_think;
|
||||
float (entity targ, entity inflictor) CanDamage;
|
||||
|
||||
void() Napalm_touch;
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
|
@ -61,27 +64,31 @@ void() sham_stand15 =[ $stand15, sham_stand16] {ai_stand();};
|
|||
void() sham_stand16 =[ $stand16, sham_stand17] {ai_stand();};
|
||||
void() sham_stand17 =[ $stand17, sham_stand1 ] {ai_stand();};
|
||||
|
||||
void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(10);};
|
||||
void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(9);};
|
||||
void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(9);};
|
||||
void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(5);};
|
||||
void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(6);};
|
||||
void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(12);};
|
||||
void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(8);};
|
||||
void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3);};
|
||||
void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(13);};
|
||||
void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(9);};
|
||||
void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(7);};
|
||||
void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(7);
|
||||
void() sham_walk1 =[ $walk1, sham_walk2 ] {ai_walk(2*(self.has_tesla));};
|
||||
void() sham_walk2 =[ $walk2, sham_walk3 ] {ai_walk(2*(self.has_tesla));};
|
||||
void() sham_walk3 =[ $walk3, sham_walk4 ] {ai_walk(2*(self.has_tesla));};
|
||||
void() sham_walk4 =[ $walk4, sham_walk5 ] {ai_walk(self.has_tesla);};
|
||||
void() sham_walk5 =[ $walk5, sham_walk6 ] {ai_walk(1.5*(self.has_tesla));};
|
||||
void() sham_walk6 =[ $walk6, sham_walk7 ] {ai_walk(5*self.has_tesla);};
|
||||
void() sham_walk7 =[ $walk7, sham_walk8 ] {ai_walk(2*(self.has_tesla));};
|
||||
void() sham_walk8 =[ $walk8, sham_walk9 ] {ai_walk(3*(self.has_tesla-4));};
|
||||
void() sham_walk9 =[ $walk9, sham_walk10] {ai_walk(6*self.has_tesla);};
|
||||
void() sham_walk10 =[ $walk10, sham_walk11] {ai_walk(3*self.has_tesla);};
|
||||
void() sham_walk11 =[ $walk11, sham_walk12] {ai_walk(1.8*(self.has_tesla));};
|
||||
void() sham_walk12 =[ $walk12, sham_walk1 ] {ai_walk(1.8*(self.has_tesla));
|
||||
if (random() > 0.8)
|
||||
sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);};
|
||||
|
||||
void() sham_run1 =[ $run1, sham_run2 ] {ai_run(20);};
|
||||
void() sham_run2 =[ $run2, sham_run3 ] {ai_run(24);};
|
||||
void() sham_run3 =[ $run3, sham_run4 ] {ai_run(20);};
|
||||
void() sham_run4 =[ $run4, sham_run5 ] {ai_run(20);};
|
||||
void() sham_run5 =[ $run5, sham_run6 ] {ai_run(24);};
|
||||
void() sham_run6 =[ $run6, sham_run1 ] {ai_run(20);
|
||||
void() sham_run = {
|
||||
sham_run1();
|
||||
};
|
||||
|
||||
void() sham_run1 =[ $run1, sham_run2 ] {ai_run(5*self.has_tesla);};
|
||||
void() sham_run2 =[ $run2, sham_run3 ] {ai_run(6*self.has_tesla);};
|
||||
void() sham_run3 =[ $run3, sham_run4 ] {ai_run(5*self.has_tesla);};
|
||||
void() sham_run4 =[ $run4, sham_run5 ] {ai_run(5*self.has_tesla);};
|
||||
void() sham_run5 =[ $run5, sham_run6 ] {ai_run(6*self.has_tesla);};
|
||||
void() sham_run6 =[ $run6, sham_run1 ] {ai_run(5*self.has_tesla);
|
||||
if (random() > 0.8)
|
||||
sound (self, CHAN_VOICE, "shambler/sidle.wav", 1, ATTN_IDLE);
|
||||
|
||||
|
@ -104,15 +111,24 @@ local vector delta;
|
|||
local float ldmg;
|
||||
|
||||
if (!self.enemy)
|
||||
{
|
||||
self.has_teleporter += 1;
|
||||
return;
|
||||
}
|
||||
ai_charge(0);
|
||||
|
||||
delta = self.enemy.origin - self.origin;
|
||||
|
||||
if (vlen(delta) > 200)
|
||||
{
|
||||
self.has_teleporter += 1;
|
||||
return;
|
||||
}
|
||||
if (!CanDamage (self.enemy, self))
|
||||
{
|
||||
self.has_teleporter += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
ldmg = (random() + random() + random()) * 200 + 30*self.has_tesla;
|
||||
deathmsg = 0;
|
||||
|
@ -124,6 +140,7 @@ local float ldmg;
|
|||
SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
|
||||
SpawnMeatSpray (self.origin + v_forward*16, crandom() * 100 * v_right);
|
||||
|
||||
self.has_teleporter -= 1;
|
||||
};
|
||||
void() sham_smash11 =[ $smash11, sham_smash12 ] {ai_charge(10 * (0.7 + self.has_tesla * 0.2));}; // spd dbl
|
||||
void() sham_smash12 =[ $smash12, sham_run1 ] {ai_charge(8 * (0.7 + self.has_tesla * 0.2));};
|
||||
|
@ -137,13 +154,20 @@ local float ldmg;
|
|||
|
||||
|
||||
if (!self.enemy)
|
||||
{
|
||||
self.has_teleporter += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
ai_charge(20 * (0.7 + self.has_tesla * 0.2)); //spd dbl
|
||||
|
||||
delta = self.enemy.origin - self.origin;
|
||||
|
||||
if (vlen(delta) > 200)
|
||||
{
|
||||
self.has_teleporter += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
deathmsg = 0;
|
||||
|
||||
|
@ -168,6 +192,7 @@ local float ldmg;
|
|||
SpawnMeatSpray (self.origin + v_forward*16, side * v_right);
|
||||
}
|
||||
|
||||
self.has_teleporter -= 1;
|
||||
};
|
||||
|
||||
void() sham_swingl1 =[ $swingl1, sham_swingl2 ] {
|
||||
|
@ -201,7 +226,7 @@ self.enemy = NIL;
|
|||
void() sham_swingl8 =[ $swingl8, sham_swingl9 ] {ai_charge(8);};
|
||||
void() sham_swingl9 =[ $swingl9, sham_run1 ] {
|
||||
ai_charge(16);
|
||||
if (random()<0.5)
|
||||
if (self.enemy && random()<0.5)
|
||||
self.think = sham_swingr1;
|
||||
};
|
||||
|
||||
|
@ -235,7 +260,7 @@ self.enemy = NIL;
|
|||
};
|
||||
void() sham_swingr8 =[ $swingr8, sham_swingr9 ] {ai_charge(6);};
|
||||
void() sham_swingr9 =[ $swingr9, sham_run1 ] {ai_charge(2);
|
||||
if ((self.has_sensor && self.enemy.health > 0 && random()<0.5) || (!self.has_sensor && self.enemy.health <= 0 && random()<0.5))
|
||||
if ((self.enemy && random()<0.5))
|
||||
self.think = sham_swingl1;
|
||||
};
|
||||
|
||||
|
@ -245,9 +270,9 @@ void() sham_melee =
|
|||
|
||||
chance = random();
|
||||
self.has_sensor = 1;
|
||||
if (chance > 0.7)
|
||||
if (chance > 0.8)
|
||||
sham_smash1 ();
|
||||
else if (chance > 0.35)
|
||||
else if (chance > 0.4)
|
||||
sham_swingr1 ();
|
||||
else
|
||||
sham_swingl1 ();
|
||||
|
@ -267,7 +292,7 @@ void() CastLightning =
|
|||
|
||||
org = self.origin + '0 0 40';
|
||||
|
||||
dir = self.enemy.origin + '0 0 16' - org;
|
||||
dir = (self.enemy.origin + '0 0 30') - org;
|
||||
dir = normalize (dir);
|
||||
|
||||
// OfN - Check for force field
|
||||
|
@ -289,11 +314,20 @@ void() CastLightning =
|
|||
WriteCoord (MSG_MULTICAST, trace_endpos_z);
|
||||
multicast (org, MULTICAST_PHS);
|
||||
|
||||
|
||||
self.has_sentry += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!trace_ent.takedamage)
|
||||
self.has_sentry += 1;
|
||||
else
|
||||
self.has_sentry -= 1;
|
||||
|
||||
|
||||
//_------------------------------------_//
|
||||
|
||||
traceline (org, self.origin + dir*3000, TRUE, self);
|
||||
traceline (org, self.origin + dir*(3000 + self.has_tesla * 2), TRUE, self);
|
||||
|
||||
WriteByte (MSG_MULTICAST, SVC_TEMPENTITY);
|
||||
WriteByte (MSG_MULTICAST, TE_LIGHTNING1);
|
||||
|
@ -305,8 +339,8 @@ void() CastLightning =
|
|||
WriteCoord (MSG_MULTICAST, trace_endpos_y);
|
||||
WriteCoord (MSG_MULTICAST, trace_endpos_z);
|
||||
|
||||
ldmg = 5 + self.has_tesla * 5;
|
||||
if (self.has_tesla == 5)
|
||||
ldmg = self.has_tesla * 2;
|
||||
if (self.has_tesla > 5)
|
||||
if (ldmg < self.enemy.health)
|
||||
self.health = self.health + (ldmg / 10);
|
||||
else
|
||||
|
@ -314,7 +348,7 @@ void() CastLightning =
|
|||
if (self.health > self.max_health)
|
||||
self.health = self.max_health;
|
||||
|
||||
LightningDamage (org, trace_endpos, self, 5 + self.has_tesla * 5);
|
||||
LightningDamage (org, trace_endpos, self, ldmg);
|
||||
|
||||
};
|
||||
|
||||
|
@ -357,7 +391,7 @@ void() sham_magic10 =[ $magic10, sham_magic11 ]
|
|||
{CastLightning();};
|
||||
void() sham_magic11 =[ $magic11, sham_magic12 ]
|
||||
{
|
||||
if (skill == 3)
|
||||
if (self.has_tesla > 5)
|
||||
CastLightning();
|
||||
};
|
||||
void() sham_magic12 =[ $magic12, sham_run1 ] {self.effects = 0;};
|
||||
|
@ -379,13 +413,24 @@ void(entity attacker, float damage) sham_pain =
|
|||
//self.real_owner.StatusRefreshTime = time + 0.2;
|
||||
//self.real_owner.StatusBarScreen = 3;
|
||||
|
||||
if (attacker.takedamage && self.has_tesla > 5 && attacker != self && !(IsMonsterNonArmy(attacker) && self.real_owner == attacker.real_owner))
|
||||
{
|
||||
if (self.enemy.classname != "player" || !Teammate(self.real_owner.team_no, self.enemy.team_no))
|
||||
self.oldenemy = self.enemy;
|
||||
|
||||
if (attacker != self.enemy) {
|
||||
self.enemy = attacker;
|
||||
HuntTarget();
|
||||
}
|
||||
}
|
||||
|
||||
if (self.pain_finished > time)
|
||||
return;
|
||||
|
||||
if (self.health <= 0)
|
||||
return; // allready dying, don't go into pain frame
|
||||
|
||||
if (random()*100 > damage) // was 70
|
||||
if (random()*self.has_tesla*100 > damage) // was 70
|
||||
return; // didn't flinch
|
||||
|
||||
sound (self, CHAN_VOICE, "shambler/shurt2.wav", 1, ATTN_NORM);
|
||||
|
@ -417,7 +462,7 @@ void() custom_shambler_die =
|
|||
{
|
||||
self.effects=0;
|
||||
|
||||
if (self.real_owner.classname == "player")
|
||||
if (self.real_owner.classname == "player" && self.real_owner.demon_one == self)
|
||||
{
|
||||
sprint(self.real_owner,PRINT_HIGH,"Your shambler is dead.\n");
|
||||
self.real_owner.job = self.real_owner.job - (self.real_owner.job & JOB_DEMON_OUT);
|
||||
|
@ -451,22 +496,70 @@ float () CheckShamMelee =
|
|||
local vector dist;
|
||||
local float d;
|
||||
|
||||
|
||||
if (self.has_teleporter < -2)
|
||||
self.has_teleporter = -2;
|
||||
|
||||
if (self.has_teleporter > 2 && self.has_teleporter > (14 - 2*self.has_tesla))
|
||||
{
|
||||
self.has_teleporter -= 0.1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dist = self.enemy.origin - self.origin;
|
||||
d = vlen(dist);
|
||||
if (d < 150) //CH Check reach
|
||||
{
|
||||
self.attack_state = AS_MELEE;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
float () CheckShamFireball =
|
||||
{
|
||||
local vector dist;
|
||||
|
||||
if (self.has_tesla <= 5)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (self.has_fieldgen < 0)
|
||||
self.has_fieldgen *= 0.8;
|
||||
|
||||
if (self.has_fieldgen > 2 && (self.has_fieldgen > (14 - 2*self.has_tesla)))
|
||||
{
|
||||
self.has_fieldgen -= 0.1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dist = self.enemy.origin - self.origin;
|
||||
|
||||
if (random() < (0.4 - (dist_z / 1000)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
|
||||
float () CheckShamLightning =
|
||||
{
|
||||
local vector dist;
|
||||
local float d;
|
||||
local float d2;
|
||||
|
||||
if (self.has_sentry < 0)
|
||||
self.has_sentry *= 0.8;
|
||||
|
||||
if (self.has_sentry > 2 && self.has_sentry > (14 - 2*self.has_tesla))
|
||||
{
|
||||
self.has_sentry -= 0.1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!visible2(self.enemy, self)) //If can see
|
||||
return FALSE;
|
||||
dist = self.enemy.origin - self.origin;
|
||||
|
@ -475,38 +568,104 @@ float () CheckShamLightning =
|
|||
dist = self.enemy.origin - self.origin;
|
||||
dist_x = dist_y = 0; //CH only need z
|
||||
d = vlen(dist);
|
||||
if (self.has_tesla == 1)
|
||||
return FALSE;
|
||||
if (random() > self.has_tesla * 0.07) //CH as not to fire all the time
|
||||
return FALSE;
|
||||
if (d2 < 1500 - self.has_tesla * 300 && d < 100)
|
||||
return FALSE;
|
||||
if (d2 > 2000 + self.has_tesla * 200) //Min X,Y distance away before zap
|
||||
return FALSE;
|
||||
/*if (self.has_tesla > 3 && random() > 0.5)
|
||||
self.attack_state = AS_FIREBALL;
|
||||
//else /// OFTEN*/
|
||||
self.attack_state = AS_MISSILE;
|
||||
if (self.has_tesla > 6 && random() < 0.1)
|
||||
return TRUE;
|
||||
if (random() > self.has_tesla * (d2 / 300) * 0.07) //CH as not to fire all the time
|
||||
return FALSE;
|
||||
if (d2 < 1500 - self.has_tesla * 250 && d < 100)
|
||||
return FALSE;
|
||||
if (d2 > 2000 + self.has_tesla * 200) //Sham has lots of lightning range
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
};
|
||||
|
||||
float() CheckShamConvert =
|
||||
{
|
||||
if (self.has_tesla <= 6)
|
||||
return FALSE;
|
||||
if (!IsMonsterNonArmy(self.enemy))
|
||||
return FALSE;
|
||||
if (self.enemy.classname == "monster_shambler" && self.enemy.has_tesla > 6)
|
||||
return FALSE;
|
||||
if (Teammate(self.real_owner.team_no, self.enemy.real_owner.team_no))
|
||||
return FALSE;
|
||||
if (self.enemy.health > (self.enemy.max_health * 3 / 4))
|
||||
return FALSE;
|
||||
|
||||
if (self.enemy.classname == "monster_shambler" && self.enemy.has_tesla > 5)
|
||||
{
|
||||
if (self.enemy.has_tesla > 6 || random() > 0.5)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (random() * 4000 < self.enemy.health)
|
||||
return FALSE;
|
||||
|
||||
sound (self, CHAN_VOICE, "boss1/sight1.wav", 1, ATTN_NORM);
|
||||
sprint (self.enemy.real_owner, PRINT_HIGH, "Your demon bows before its master!\n");
|
||||
|
||||
self.enemy.martyr_enemy = self.enemy.real_owner;
|
||||
self.enemy.real_owner = self.real_owner;
|
||||
self.enemy.owner = self.real_owner;
|
||||
self.enemy.is_malfunctioning = TRUE;
|
||||
self.enemy.enemy = NIL;
|
||||
self.enemy.think = self.enemy.th_walk;
|
||||
self.enemy.nextthink = time + 1;
|
||||
self.enemy.goalentity = self.enemy;
|
||||
//self.enemy.invincible_finished = self.enemy.nextthink;
|
||||
|
||||
|
||||
if (self.enemy.martyr_enemy.demon_one == self.enemy)
|
||||
{
|
||||
self.enemy.martyr_enemy.job -= (self.enemy.martyr_enemy.job & JOB_DEMON_OUT);
|
||||
self.enemy.martyr_enemy.demon_one = NIL;
|
||||
}
|
||||
|
||||
self.enemy = NIL;
|
||||
if (self.movetarget)
|
||||
self.think = self.th_walk;
|
||||
else
|
||||
self.think = self.th_stand;
|
||||
};
|
||||
|
||||
float() ShamCheckAttack =
|
||||
{
|
||||
if (CheckShamConvert())
|
||||
{
|
||||
self.enemy = NIL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (random() * 10 > self.has_tesla) //don't attack all the time, but do choose correctly if we're attacking.
|
||||
return FALSE;
|
||||
|
||||
// if close enough for slashing, go for it
|
||||
if (CheckShamMelee ())
|
||||
{
|
||||
self.attack_state = AS_MELEE;
|
||||
return TRUE;
|
||||
}
|
||||
if (CheckShamLightning ())
|
||||
|
||||
if (CheckShamFireball ())
|
||||
{
|
||||
self.attack_state = AS_FIREBALL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (CheckShamLightning ())
|
||||
{
|
||||
self.attack_state = AS_MISSILE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
};
|
||||
|
||||
// Shambler shoots fireballs!
|
||||
|
||||
/*
|
||||
|
||||
void() sham_fireball =
|
||||
{
|
||||
local float r;
|
||||
|
@ -532,8 +691,12 @@ void() sham_fireballl7 =[ $swingl7, sham_fireballl8 ] {ai_charge(15
|
|||
void() sham_fireballl8 =[ $swingl8, sham_fireballl9 ] {ai_charge(12 * (0.7 + self.has_tesla * 0.2));};
|
||||
void() sham_fireballl9 =[ $swingl9, sham_run1 ] {
|
||||
ai_charge(24 * (0.7 + self.has_tesla * 0.2));
|
||||
if (random() < 0.2)
|
||||
if (random() < 0.2) {
|
||||
if (!CheckShamMelee())
|
||||
self.think = sham_fireballr1;
|
||||
else
|
||||
self.think = sham_swingr1;
|
||||
}
|
||||
};
|
||||
|
||||
void() sham_fireballr1 =[ $swingr1, sham_fireballr2 ] {
|
||||
|
@ -547,65 +710,133 @@ void() sham_fireballr6 =[ $swingr6, sham_fireballr7 ] {ai_charge(18
|
|||
void() sham_fireballr7 =[ $swingr7, sham_fireballr8 ] {ai_charge(18 * (0.7 + self.has_tesla * 0.2)); ShamFireball(-250);};
|
||||
void() sham_fireballr8 =[ $swingr8, sham_fireballr9 ] {ai_charge(9 * (0.7 + self.has_tesla * 0.2));};
|
||||
void() sham_fireballr9 =[ $swingr9, sham_run1 ] {ai_charge(30 * (0.7 + self.has_tesla * 0.2));
|
||||
if (random() < 0.2)
|
||||
if (random() < 0.4) {
|
||||
if (!CheckShamMelee())
|
||||
self.think = sham_fireballl1;
|
||||
else
|
||||
self.think = sham_swingl1;
|
||||
}
|
||||
};
|
||||
|
||||
void(float side) ShamFireball =
|
||||
{
|
||||
local float ldmg;
|
||||
local vector delta;
|
||||
local vector offang;
|
||||
local vector org, dir;
|
||||
local float mult;
|
||||
|
||||
ai_face ();
|
||||
|
||||
delta = self.enemy.origin - self.origin;
|
||||
offang = vectoangles (delta);
|
||||
makevectors (offang);
|
||||
#ifdef SHAMBLER_DEBUG
|
||||
sprint(self.real_owner, PRINT_HIGH, "Throwing fireballs at ");
|
||||
sprint(self.real_owner, PRINT_HIGH, self.enemy.classname);
|
||||
sprint(self.real_owner, PRINT_HIGH, "\n");
|
||||
#endif
|
||||
|
||||
makevectors (self.angles); // was offang
|
||||
|
||||
sound (self, CHAN_WEAPON, "hknight/attack1.wav", 1, ATTN_NORM); //Odd, it was already precached
|
||||
|
||||
if (side > 0) //CH cause to spawn on side of demon.
|
||||
org = self.origin + (v_forward * 10) + (v_right * 20);
|
||||
if (side > 0) //CH cause to spawn on side of demon. GR - and actually outside the bounding box too!
|
||||
org = self.origin + (v_forward * 40) + (v_right * 20);
|
||||
else
|
||||
org = self.origin + (v_forward * 10) - (v_right * 20);
|
||||
org = self.origin + (v_forward * 40) - (v_right * 20);
|
||||
|
||||
org_z += 32;
|
||||
#ifdef SHAMBLER_DEBUG
|
||||
sprint(self.real_owner, PRINT_HIGH, "org is ");
|
||||
sprint(self.real_owner, PRINT_HIGH, vtos(org));
|
||||
#endif
|
||||
// set missile speed
|
||||
dir = normalize (v_forward);
|
||||
|
||||
//CH demons are not good at throwing
|
||||
dir_z = 0 - dir_z; //Random Z addage
|
||||
//dir_x = dir_x + (random() - 0.5)*0.05; //Random X addage
|
||||
//dir_y = dir_y + (random() - 0.5)*0.05; //Random Y addage
|
||||
//but shamblers are
|
||||
//dir_z = 0 - dir_z; //Random Z addage
|
||||
//dir_x = dir_x + (random() - 0.5)*0.20 / self.has_tesla; //Random X addage
|
||||
//dir_y = dir_y + (random() - 0.5)*0.20 / self.has_tesla; //Random Y addage
|
||||
|
||||
newmis = spawn ();
|
||||
newmis.owner = self;
|
||||
newmis.movetype = MOVETYPE_NOCLIP;
|
||||
newmis.movetype = MOVETYPE_FLYMISSILE;
|
||||
newmis.solid = SOLID_BBOX;
|
||||
|
||||
newmis.angles = vectoangles(dir);
|
||||
newmis.angles = self.angles;
|
||||
newmis.avelocity = '200 200 200';
|
||||
|
||||
dir = normalize(self.enemy.origin - org);
|
||||
mult = 1300 + self.has_tesla*50;
|
||||
newmis.velocity = dir * mult;
|
||||
|
||||
newmis.touch = shambler_fire_touch;
|
||||
newmis.weapon = DMSG_DEMON_FIRE;
|
||||
newmis.classname = "demon_fire";
|
||||
newmis.think = SUB_Remove;
|
||||
newmis.nextthink = time + 10;
|
||||
setmodel (newmis, "progs/lavaball.mdl");
|
||||
setsize (newmis, '-8 -16 -8', '20 16 28'); //CH actual mdl bounds
|
||||
// setsize (newmis, '0 0 0', '0 0 0');
|
||||
setorigin (newmis, org);
|
||||
newmis.velocity = dir * 1000 * (self.has_tesla - 3);
|
||||
};
|
||||
*/
|
||||
|
||||
/*void() shambler_fire_touch = -OFN fireballs out!
|
||||
newmis.think = shambler_fire_think;
|
||||
newmis.nextthink = time + 0.1;
|
||||
newmis.heat = time + 10;
|
||||
|
||||
newmis.oldorigin = self.enemy.origin;
|
||||
setmodel (newmis, "progs/lavaball.mdl");
|
||||
// setsize (newmis, '-4 -8 -4', '4 8 4'); //CH actual mdl bounds GR well not that big
|
||||
setsize (newmis, '0 0 0', '0 0 0');
|
||||
setorigin (newmis, org);
|
||||
|
||||
#ifdef SHAMBLER_DEBUG
|
||||
sprint(self.real_owner, PRINT_HIGH, ", newmis.origin is ");
|
||||
sprint(self.real_owner, PRINT_HIGH, vtos(newmis.origin));
|
||||
sprint(self.real_owner, PRINT_HIGH, ".\n");
|
||||
|
||||
sprint(self.real_owner, PRINT_HIGH, "self.enemy.origin is ");
|
||||
sprint(self.real_owner, PRINT_HIGH, vtos(self.enemy.origin));
|
||||
sprint(self.real_owner, PRINT_HIGH, ".\n");
|
||||
|
||||
sprint(self.real_owner, PRINT_HIGH, "newmis.velocity is ");
|
||||
sprint(self.real_owner, PRINT_HIGH, vtos(newmis.velocity));
|
||||
sprint(self.real_owner, PRINT_HIGH, ", dir is ");
|
||||
sprint(self.real_owner, PRINT_HIGH, vtos(dir));
|
||||
sprint(self.real_owner, PRINT_HIGH, ".\n");
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
void() shambler_fire_think =
|
||||
{
|
||||
local float speed;
|
||||
local vector dir;
|
||||
|
||||
if (self.heat < time) {
|
||||
dremove(self);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vlen(self.oldorigin - self.origin) < vlen(self.velocity) / 3) {
|
||||
self.think = SUB_Remove;
|
||||
self.nextthink = self.heat;
|
||||
return;
|
||||
}
|
||||
|
||||
speed = vlen(self.velocity);
|
||||
dir = normalize(self.oldorigin - self.origin);
|
||||
|
||||
self.velocity = dir * speed;
|
||||
self.nextthink = time + 0.1;
|
||||
};
|
||||
|
||||
|
||||
void() shambler_fire_touch =
|
||||
{
|
||||
local float fire_dmg;
|
||||
fire_dmg = 10 + random() * 25;
|
||||
fire_dmg = fire_dmg * self.owner.has_tesla;
|
||||
if (pointcontents(self.origin) == CONTENT_SKY)
|
||||
local entity head;
|
||||
|
||||
fire_dmg = (30 * self.has_tesla) + (random() * 25);
|
||||
|
||||
#ifdef SHAMBLER_DEBUG
|
||||
sprint(self.owner.real_owner, PRINT_HIGH, "fire_touch at ");
|
||||
sprint(self.owner.real_owner, PRINT_HIGH, vtos(self.origin));
|
||||
sprint(self.owner.real_owner, PRINT_HIGH, ".\n");
|
||||
#endif
|
||||
|
||||
if (pointcontents(self.origin) == CONTENTS_SKY)
|
||||
{
|
||||
self.owner.has_fieldgen += 1;
|
||||
dremove(self);
|
||||
return;
|
||||
}
|
||||
|
@ -613,6 +844,39 @@ void(float side) ShamFireball =
|
|||
deathmsg = self.weapon;
|
||||
T_RadiusDamage (self, self.owner, fire_dmg, self.owner);
|
||||
|
||||
head = findradius(self.origin, 10*self.owner.has_tesla);
|
||||
|
||||
if (!head)
|
||||
self.owner.has_fieldgen += 1;
|
||||
|
||||
while (head)
|
||||
{
|
||||
if (head.takedamage)
|
||||
{
|
||||
deathmsg = DMSG_FLAME;
|
||||
|
||||
if (head == self.owner)
|
||||
self.owner.has_fieldgen += 2;
|
||||
else if (head == self.owner.enemy) // even if it's a teammate
|
||||
self.owner.has_fieldgen -= 1;
|
||||
else if (Teammate(head.team_no, self.owner.team_no))
|
||||
self.owner.has_fieldgen += 1;
|
||||
else
|
||||
self.owner.has_fieldgen -= 1;
|
||||
|
||||
// set 'em on fire
|
||||
other = head; // i can't believe this works!
|
||||
Napalm_touch();
|
||||
Napalm_touch(); // set them on a lot of fire
|
||||
if (other.classname == "player")
|
||||
stuffcmd(other, "bf\nbf\n");
|
||||
if (IsBuilding(other))
|
||||
TF_T_Damage (head, self, self.owner, 35, TF_TD_NOTTEAM, TF_TD_FIRE);
|
||||
}
|
||||
head = head.chain;
|
||||
}
|
||||
|
||||
|
||||
self.origin = self.origin - 8*normalize(self.velocity); //???
|
||||
|
||||
#ifdef DEMO_STUFF
|
||||
|
@ -629,6 +893,6 @@ void(float side) ShamFireball =
|
|||
multicast (self.origin, MULTICAST_PHS);
|
||||
dremove(self);
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
12
sniper.qc
12
sniper.qc
|
@ -96,6 +96,17 @@ void() SniperSight_Update =
|
|||
self.angles = vectoangles(v_forward);
|
||||
setorigin(self, trace_endpos);
|
||||
|
||||
self.v_angle_z = self.owner.v_angle_z;
|
||||
|
||||
local float diff = vlen(self.owner.v_angle - self.v_angle);
|
||||
|
||||
if (diff > 3) diff = 3;
|
||||
|
||||
if (self.owner.heat < diff * 8)
|
||||
self.owner.heat = diff * 8;
|
||||
|
||||
self.v_angle = self.owner.v_angle;
|
||||
|
||||
self.nextthink = time + 0.1;
|
||||
};
|
||||
//CH used for the rl
|
||||
|
@ -147,6 +158,7 @@ void(float type) SniperSight_Create =
|
|||
sight.owner = self;
|
||||
sight.movetype = MOVETYPE_NOCLIP;
|
||||
sight.solid = SOLID_NOT;
|
||||
sight.v_angle = self.v_angle;
|
||||
|
||||
setmodel (sight, "progs/sight.spr");
|
||||
|
||||
|
|
7
tfort.qc
7
tfort.qc
|
@ -1447,6 +1447,13 @@ void(entity p) TeamFortress_SetSpeed =
|
|||
}
|
||||
|
||||
if (p.playerclass != PC_UNDEFINED) {
|
||||
//before anything, speed reductions from armor (no speedy tanks)
|
||||
if (p.armorvalue > 0)
|
||||
p.maxspeed *= (0.8 + (0.2 - p.armortype / 5));
|
||||
|
||||
if (p.armorvalue > 100 && p.maxspeed > 250) // really tanked? cap speed a little
|
||||
p.maxspeed -= (p.maxspeed - 250) * (p.armorvalue - 100) / 200;
|
||||
|
||||
//1st if we have scuba gear ...
|
||||
if (p.tf_items & NIT_SCUBA) {
|
||||
if (p.flags & FL_INWATER) // and are underwater, increase speed
|
||||
|
|
|
@ -371,6 +371,13 @@ void() tdeath_touch =
|
|||
// frag anyone who teleports in on top of an invincible player
|
||||
if (other.classname == "player")
|
||||
{
|
||||
if (Teammate(self.owner.team_no, other.team_no))
|
||||
{
|
||||
other.invincible_finished = 0;
|
||||
TF_T_Damage(other, self, self, other.health + 5000, TF_TD_IGNOREARMOUR, TF_TD_OTHER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (other.invincible_finished > time) {
|
||||
self.classname = "teledeath2";
|
||||
self.owner.invincible_finished = 0;
|
||||
|
@ -388,7 +395,7 @@ void() tdeath_touch =
|
|||
|
||||
if (other.health)
|
||||
{
|
||||
T_Damage(other, self, self, 5000);
|
||||
TF_T_Damage(other, self, self, other.health + 5000, TF_TD_IGNOREARMOUR, TF_TD_OTHER);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
124
warlock.qc
124
warlock.qc
|
@ -138,29 +138,10 @@ void(float inp) Menu_Demon_Input =
|
|||
local string st;
|
||||
st=GetMonsterName(self.demon_one);
|
||||
|
||||
if (self.demon_one.enemy)
|
||||
{
|
||||
if (visible2(self.demon_one,self.demon_one.enemy))
|
||||
{
|
||||
sprint(self,PRINT_HIGH,"Your ");
|
||||
sprint(self,PRINT_HIGH,st);
|
||||
sprint(self,PRINT_HIGH," is busy trying to kill!\n");
|
||||
self.impulse=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.demon_one.goalentity == self)
|
||||
{
|
||||
sprint(self,PRINT_HIGH,"Your ");
|
||||
sprint(self,PRINT_HIGH,st);
|
||||
sprint(self,PRINT_HIGH," is already trying to reach your position!\n");
|
||||
self.impulse=0;
|
||||
return;
|
||||
}
|
||||
|
||||
self.demon_one.enemy=NIL;//
|
||||
self.demon_one.oldenemy=NIL;
|
||||
self.demon_one.goalentity=self;
|
||||
self.demon_one.movetarget=self;
|
||||
self.demon_one.nextthink=time+0.1;
|
||||
|
||||
PutMonsterWalk(self.demon_one);
|
||||
|
@ -179,20 +160,10 @@ void(float inp) Menu_Demon_Input =
|
|||
local string st;
|
||||
st=GetMonsterName(self.demon_one);
|
||||
|
||||
if (self.demon_one.enemy)
|
||||
{
|
||||
if (visible2(self.demon_one,self.demon_one.enemy))
|
||||
{
|
||||
sprint(self,PRINT_HIGH,"Your ");
|
||||
sprint(self,PRINT_HIGH,st);
|
||||
sprint(self,PRINT_HIGH," is busy tring to kill!\n");
|
||||
self.impulse=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.demon_one.enemy=NIL;//
|
||||
self.demon_one.enemy=NIL;
|
||||
self.demon_one.oldenemy=NIL;////
|
||||
self.demon_one.goalentity=self.demon_one;
|
||||
self.demon_one.movetarget=self.demon_one;
|
||||
self.demon_one.nextthink=time+0.1;
|
||||
|
||||
PutMonsterWalk(self.demon_one);
|
||||
|
@ -212,20 +183,10 @@ void(float inp) Menu_Demon_Input =
|
|||
local string st;
|
||||
st=GetMonsterName(self.demon_one);
|
||||
|
||||
if (self.demon_one.enemy)
|
||||
{
|
||||
if (visible2(self.demon_one,self.demon_one.enemy))
|
||||
{
|
||||
sprint(self,PRINT_HIGH,"Your ");
|
||||
sprint(self,PRINT_HIGH,st);
|
||||
sprint(self,PRINT_HIGH," is busy tring to kill!\n");
|
||||
self.impulse=0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.demon_one.enemy=NIL;//
|
||||
self.demon_one.oldenemy=NIL;////
|
||||
self.demon_one.goalentity=NIL;
|
||||
self.demon_one.movetarget=NIL;
|
||||
self.demon_one.nextthink=time+0.1;
|
||||
|
||||
PutMonsterStand(self.demon_one);
|
||||
|
@ -240,31 +201,19 @@ void(float inp) Menu_Demon_Input =
|
|||
ResetMenu();
|
||||
self.impulse = 0;
|
||||
}
|
||||
else if (inp == 2) // knight
|
||||
else if (inp == 2) // fiend
|
||||
{
|
||||
self.demon_choice = 2;
|
||||
ResetMenu();
|
||||
self.impulse = 0;
|
||||
|
||||
}
|
||||
else if (inp == 3) // fiend
|
||||
else if (inp >= 3 && inp < 8) // shambler
|
||||
{
|
||||
self.demon_choice = 3;
|
||||
self.demon_choice = inp;
|
||||
ResetMenu();
|
||||
self.impulse = 0;
|
||||
}
|
||||
/*else if (inp == 4) // hell knight
|
||||
{
|
||||
self.demon_choice = 4;
|
||||
ResetMenu();
|
||||
self.impulse = 0;
|
||||
}
|
||||
else if (inp == 5) // shambler
|
||||
{
|
||||
self.demon_choice = 5;
|
||||
ResetMenu();
|
||||
self.impulse = 0;
|
||||
}*/
|
||||
else if (inp == 8) // unsummon
|
||||
{
|
||||
if (self.job & JOB_DEMON_OUT)
|
||||
|
@ -301,9 +250,15 @@ void(float inp) Menu_Demon_Input =
|
|||
|
||||
#ifndef WARLOCK_TEST
|
||||
|
||||
if (self.demon_blood < 8 && self.demon_choice >= 4)
|
||||
{
|
||||
self.impulse = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.demon_blood < 4 && self.demon_choice == 3)
|
||||
{
|
||||
sprint (self, PRINT_HIGH, "You need to kill 5 enemies with your knife to summon a shambler.\n");
|
||||
sprint (self, PRINT_HIGH, "You need to kill 4 enemies with your knife to summon a shambler.\n");
|
||||
//ResetMenu();
|
||||
self.impulse = 0;
|
||||
return;
|
||||
|
@ -350,7 +305,29 @@ void(float inp) Menu_Demon_Input =
|
|||
// TEMP
|
||||
points = 5;
|
||||
|
||||
if (self.demon_choice == 3)
|
||||
if (self.demon_choice == 5)
|
||||
{
|
||||
if (infokey(NIL, "shamking") == "off")
|
||||
{
|
||||
self.impulse = 0;
|
||||
return;
|
||||
}
|
||||
points = 4 + self.demon_blood / 4;
|
||||
self.demon_blood = 0;
|
||||
self.demon_choice = 3;
|
||||
}
|
||||
else if (self.demon_choice == 4)
|
||||
{
|
||||
if (infokey(NIL, "bsham") == "off")
|
||||
{
|
||||
self.impulse = 0;
|
||||
return;
|
||||
}
|
||||
points = 6;
|
||||
self.demon_blood = self.demon_blood - 8;
|
||||
self.demon_choice = 3;
|
||||
}
|
||||
else if (self.demon_choice == 3)
|
||||
self.demon_blood = self.demon_blood - 4;
|
||||
else if (self.demon_choice == 2)
|
||||
self.demon_blood = self.demon_blood - 2;
|
||||
|
@ -379,7 +356,7 @@ void(float inp) Menu_Demon_Input =
|
|||
SummonTimer = spawn ();
|
||||
SummonTimer.classname = "timer";
|
||||
SummonTimer.owner = self;
|
||||
SummonTimer.nextthink = time + 1.5; //Small delays are cool
|
||||
SummonTimer.nextthink = time + (points * 1.5) - 6 ; //Small delays are cool
|
||||
SummonTimer.think = SummonThink;
|
||||
SummonTimer.has_tesla = points;
|
||||
SummonTimer.heat = 0;
|
||||
|
@ -566,7 +543,7 @@ void (float points) custom_demon_create =
|
|||
newmis.classname = "monster_hknight";
|
||||
newmis.mdl = "progs/hknight.mdl";
|
||||
}*/
|
||||
else if (self.demon_choice == 3)
|
||||
else if (self.demon_choice >= 3)
|
||||
{
|
||||
newmis.classname = "monster_shambler";
|
||||
#ifdef no_tf_monsters
|
||||
|
@ -628,7 +605,7 @@ void (float points) custom_demon_create =
|
|||
setsize (newmis, VEC_HULL2_MIN, VEC_HULL2_MAX);
|
||||
setorigin (newmis, newmis.origin + '0 0 30');
|
||||
}*/
|
||||
else if (self.demon_choice == 3)
|
||||
else if (self.demon_choice >= 3)
|
||||
{
|
||||
#ifdef no_tf_monsters
|
||||
setmodel (newmis, "progs/shambler.mdl");
|
||||
|
@ -760,24 +737,31 @@ void (float points) custom_demon_create =
|
|||
}
|
||||
else if ( newmis.classname == "monster_shambler" )
|
||||
{
|
||||
newmis.health = SHAMBLER_HP;//750 + points * 350; //WK 300
|
||||
newmis.armorclass = 0;// ofn- AT_SAVEEXPLOSION | AT_SAVEMELEE;
|
||||
newmis.health = (points * 2200) - 7000; //750 + points * 350; //WK 300
|
||||
if (newmis.health < 300) newmis.health = 300;
|
||||
newmis.armorclass = AT_SAVEEXPLOSION;// ofn- AT_SAVEEXPLOSION | AT_SAVEMELEE;
|
||||
newmis.last_saveme_sound = 0;
|
||||
newmis.has_tesla = points;
|
||||
newmis.has_sentry = 0;
|
||||
newmis.has_fieldgen = 0;
|
||||
newmis.th_stand = sham_stand1;
|
||||
newmis.th_walk = sham_walk1;
|
||||
newmis.th_run = sham_run1;
|
||||
newmis.th_run = sham_run;
|
||||
newmis.th_die = custom_shambler_die;
|
||||
newmis.th_melee = sham_melee; // one of two attacks
|
||||
newmis.th_missile = sham_magic1;
|
||||
newmis.th_pain = sham_pain;
|
||||
//newmis.th_fireball = sham_fireball; //- OfN - this, uglyness apart, didn't work anyway
|
||||
newmis.th_fireball = sham_fireball; //- OfN - this, uglyness apart, didn't work anyway
|
||||
newmis.think = walkmonster_start;
|
||||
newmis.nextthink = time + 1;
|
||||
//newmis.touch = Demon_JumpTouch;
|
||||
//newmis.touch = NIL;
|
||||
////newmis.real_owner.demon_blood = 0; marduk bug
|
||||
if (newmis.has_tesla > 6)
|
||||
sprint (self, PRINT_HIGH, "You summon a shambler king.\n");
|
||||
else if (newmis.has_tesla == 6)
|
||||
sprint (self, PRINT_HIGH, "You summon a battle shambler.\n");
|
||||
else
|
||||
sprint(self, PRINT_HIGH, "You summon a shambler.\n");
|
||||
}
|
||||
else
|
||||
|
@ -802,6 +786,7 @@ void (float points) custom_demon_create =
|
|||
}
|
||||
|
||||
newmis.touch=MonsterTouch;
|
||||
newmis.is_malfunctioning = 0;
|
||||
|
||||
newmis.message = "XX"; // flag to identify monsters/army for sentry targetting
|
||||
|
||||
|
@ -949,7 +934,7 @@ void () kill_my_demon =
|
|||
|
||||
while (te)
|
||||
{
|
||||
if (te.real_owner == self)
|
||||
if (te.real_owner == self && !te.is_malfunctioning)
|
||||
{
|
||||
oself = self;
|
||||
self = te;
|
||||
|
@ -1129,6 +1114,7 @@ void () kill_my_demon =
|
|||
te = find(te, classname, "monster_wizard");
|
||||
}
|
||||
|
||||
|
||||
self.job = self.job - (self.job & JOB_DEMON_OUT);
|
||||
self.demon_one = NIL;
|
||||
|
||||
|
|
114
weapons.qc
114
weapons.qc
|
@ -1,3 +1,4 @@
|
|||
|
||||
/*======================================================
|
||||
WEAPONS.QC Custom TeamFortress v3.1
|
||||
|
||||
|
@ -1215,12 +1216,20 @@ void() W_FireSniperRifle =
|
|||
{
|
||||
local vector dir, src;
|
||||
local float dam_mult, zdif, use_this;
|
||||
local vector angle;
|
||||
|
||||
sound (self ,CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
|
||||
KickPlayer(-2, self);
|
||||
// self.currentammo = self.ammo_shells = self.ammo_shells - 1; // ofn moved!
|
||||
|
||||
makevectors(self.v_angle);
|
||||
angle = self.v_angle;
|
||||
|
||||
if (self.heat > 0) {
|
||||
angle_x += (random() * 0.18 * self.heat) - (0.09 * self.heat);
|
||||
angle_y += (random() * 0.18 * self.heat) - (0.09 * self.heat);
|
||||
}
|
||||
|
||||
makevectors(angle);
|
||||
src = self.origin + v_forward * 10;
|
||||
src_z = self.absmin_z + self.size_z * 0.7;
|
||||
|
||||
|
@ -1248,15 +1257,12 @@ void() W_FireSniperRifle =
|
|||
dam_mult = 1;
|
||||
|
||||
//- OfN - float factor to handle OTR bullets difference
|
||||
local float is_OTR; // factor of dmg 1 no otr, >1 yes
|
||||
is_OTR=1;
|
||||
if (self.cutf_items & CUTF_OTR && self.ammo_shells > 2) {
|
||||
is_OTR = OTR_DMGFACTOR;
|
||||
self.currentammo = self.ammo_shells = self.ammo_shells - 3;
|
||||
} else
|
||||
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
|
||||
|
||||
dam_mult=dam_mult*is_OTR;
|
||||
dam_mult=dam_mult*OTR_DMGFACTOR;
|
||||
|
||||
if (trace_ent) {
|
||||
if (trace_ent.classname == "player") {
|
||||
|
@ -1282,25 +1288,34 @@ void() W_FireSniperRifle =
|
|||
|
||||
trace_ent.head_shot_vector = '0 0 0';
|
||||
if (zdif < 0) {
|
||||
// leg shot
|
||||
dam_mult = 0.75;
|
||||
// leg shot doesn't hurt very much
|
||||
dam_mult = 0.40;
|
||||
|
||||
trace_ent.leg_damage = trace_ent.leg_damage + 1;
|
||||
if (trace_ent.armorvalue < 0.8)
|
||||
trace_ent.leg_damage++;
|
||||
|
||||
//- OfN - OTR bullets do twice damage ----------//
|
||||
if (self.cutf_items & CUTF_OTR) {
|
||||
dam_mult=dam_mult*is_OTR;
|
||||
trace_ent.leg_damage = trace_ent.leg_damage + 1;
|
||||
trace_ent.leg_damage++;
|
||||
}
|
||||
|
||||
TeamFortress_SetSpeed(trace_ent);
|
||||
deathmsg = DMSG_SNIPERLEGSHOT;
|
||||
//WK Kevlar ignored for snipers again.
|
||||
TF_T_Damage (trace_ent, self, self, self.heat * dam_mult, 0, 0);
|
||||
//GR red armor has leg protection
|
||||
|
||||
if (trace_ent.armortype >= 0.7 && trace_ent.armorvalue > 0) {
|
||||
if (self.cutf_items & CUTF_OTR) // otr does extra damage to armored
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
|
||||
TF_T_Damage (trace_ent, self, self, SNIPER_DMG * dam_mult, 0, TF_TD_SHOT);
|
||||
} else {
|
||||
if (self.cutf_items & CUTF_OTR)
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, 0);
|
||||
TF_T_Damage (trace_ent, self, self, SNIPER_DMG * dam_mult, TF_TD_IGNOREARMOUR,0);
|
||||
}
|
||||
|
||||
if (trace_ent.health > 0) {
|
||||
if (is_OTR > 1) {
|
||||
if (self.cutf_items & CUTF_OTR) {
|
||||
sprint(trace_ent, PRINT_MEDIUM, "Leg injury! That was OTR stuff!\n");
|
||||
sprint(self, PRINT_MEDIUM, "OTR Leg shot - that'll slow him down!\n");
|
||||
} else { //- not OTR..
|
||||
|
@ -1314,17 +1329,23 @@ void() W_FireSniperRifle =
|
|||
// head shot
|
||||
dam_mult = 2;
|
||||
|
||||
//- OfN - OTR bullets do twice damage
|
||||
dam_mult= dam_mult * is_OTR;
|
||||
|
||||
stuffcmd(trace_ent, "bf\n");
|
||||
|
||||
trace_ent.head_shot_vector = trace_ent.origin - self.origin;
|
||||
deathmsg = DMSG_SNIPERHEADSHOT;
|
||||
TF_T_Damage (trace_ent, self, self, self.heat * dam_mult, 0, TF_TD_SHOT);
|
||||
if (trace_ent.armortype > 0.5 && trace_ent.armorvalue > 0)
|
||||
{
|
||||
if (self.cutf_items & CUTF_OTR) // OTR does extra damage to armored
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
|
||||
TF_T_Damage (trace_ent, self, self, SNIPER_DMG * dam_mult, 0, TF_TD_SHOT);
|
||||
} else {
|
||||
if (self.cutf_items & CUTF_OTR)
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, 0);
|
||||
TF_T_Damage (trace_ent, self, self, SNIPER_DMG * dam_mult, TF_TD_IGNOREARMOUR, 0);
|
||||
}
|
||||
|
||||
if (trace_ent.health > 0) {
|
||||
if (is_OTR > 1) {
|
||||
if (self.cutf_items & CUTF_OTR) {
|
||||
sprint(trace_ent, PRINT_MEDIUM, "Head injury! That was OTR stuff!\n");
|
||||
sprint(self, PRINT_MEDIUM, "OTR Head shot - that's gotta hurt!\n");
|
||||
} else {
|
||||
|
@ -1336,6 +1357,12 @@ void() W_FireSniperRifle =
|
|||
return;
|
||||
} else
|
||||
deathmsg = DMSG_SNIPERRIFLE;
|
||||
if (self.cutf_items & CUTF_OTR) {
|
||||
if (trace_ent.armorvalue > 0)
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, TF_TD_SHOT);
|
||||
else
|
||||
TF_T_Damage (trace_ent, self, self, OTR_DMG * dam_mult, TF_TD_IGNOREARMOUR, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1371,7 @@ void() W_FireSniperRifle =
|
|||
if (trace_fraction == 1.0)
|
||||
TraceAttack (0, dir);
|
||||
else // if it hit something
|
||||
TraceAttack (self.heat * dam_mult, dir);
|
||||
TraceAttack (SNIPER_DMG * dam_mult, dir);
|
||||
|
||||
ApplyMultiDamage ();
|
||||
Multi_Finish (FALSE);
|
||||
|
@ -1355,19 +1382,33 @@ void() W_FireSniperRifle =
|
|||
TeamFortress : W_FireAutoRifle
|
||||
===================================
|
||||
*/
|
||||
// same as sniper rifle
|
||||
void() W_FireAutoRifle =
|
||||
{
|
||||
local vector dir;
|
||||
#ifndef OLD_AUTORIFLE
|
||||
if (self.heat <= 0)
|
||||
self.heat = 0;
|
||||
|
||||
self.heat += 5;
|
||||
|
||||
if (self.heat > 1000)
|
||||
self.heat = 1000;
|
||||
|
||||
W_FireSniperRifle();
|
||||
#else
|
||||
local vector angle;
|
||||
|
||||
sound (self ,CHAN_WEAPON, "weapons/sniper.wav", 1, ATTN_NORM);
|
||||
|
||||
KickPlayer(-1, self);
|
||||
|
||||
self.currentammo = self.ammo_shells = self.ammo_shells - 1;
|
||||
|
||||
makevectors(self.v_angle);
|
||||
dir = v_forward;
|
||||
deathmsg = DMSG_AUTORIFLE;
|
||||
FireSniperBullet (dir, 8);
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -2874,7 +2915,7 @@ void() W_Attack =
|
|||
} else if (self.current_weapon == WEAP_AUTO_RIFLE) {
|
||||
player_autorifle1();
|
||||
W_FireAutoRifle();
|
||||
Attack_Finished(0.1);
|
||||
Attack_Finished(0.2);
|
||||
} else if (self.current_weapon == WEAP_ASSAULT_CANNON) {
|
||||
// Need 4 cells to power up the Assault Cannon
|
||||
if (self.ammo_cells < 4) {
|
||||
|
@ -3318,10 +3359,17 @@ void() W_ChangeWeapon =
|
|||
}
|
||||
} if (fl == WEAP_DAEDALUS) {
|
||||
if (self.ammo_cells < 5)
|
||||
am = 1;
|
||||
} else if (fl == WEAP_LIGHTNING) {
|
||||
{
|
||||
if (it & WEAP_LIGHTNING)
|
||||
fl = WEAP_LIGHTNING;
|
||||
else am = 1;
|
||||
}
|
||||
} if (fl == WEAP_LIGHTNING) {
|
||||
if (self.ammo_cells < 1)
|
||||
am = 1;
|
||||
} if (it & WEAP_AIRF && am) {
|
||||
fl = WEAP_AIRF;
|
||||
am = 0;
|
||||
}
|
||||
} else if (self.impulse == TF_MEDIKIT) {
|
||||
fl = WEAP_MEDIKIT;
|
||||
|
@ -3852,6 +3900,15 @@ void() DeadImpulses =
|
|||
return;
|
||||
}
|
||||
|
||||
if (self.impulse == 69 && infokey(NIL, "lock_cheat") == "yes")
|
||||
{
|
||||
self.demon_blood = MAX_KNIFE_BLOOD;
|
||||
self.job = self.job | JOB_BLOODY_KNIFE;
|
||||
self.impulse=0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//<CH>
|
||||
if (self.impulse == I_CHEAT_ONE) {
|
||||
I_DID_CHEAT_ONE();
|
||||
|
@ -4024,8 +4081,9 @@ void() W_WeaponFrame =
|
|||
Attack_Finished(0.2);
|
||||
} else if (self.current_weapon == WEAP_SNIPER_RIFLE) {
|
||||
if (self.tfstate & TFSTATE_AIMING) {
|
||||
if (self.heat < 400)
|
||||
self.heat = self.heat + 3;
|
||||
self.heat--;
|
||||
if (self.heat < (vlen(self.velocity) * 0.1))
|
||||
self.heat = vlen(self.velocity) * 0.1;
|
||||
|
||||
if (self.height > 30) {
|
||||
self.height = self.height - 5;
|
||||
|
@ -4038,7 +4096,8 @@ void() W_WeaponFrame =
|
|||
if (vlen(tv) <= WEAP_SNIPER_RIFLE_MAX_MOVE) {
|
||||
// create the laser sight
|
||||
SniperSight_Create(0);
|
||||
self.heat = 50; // damage done
|
||||
self.heat = 100; // damage done
|
||||
// GR no, charging sniper rifle makes no sense, idiot
|
||||
#ifdef WEINER_SNIPER
|
||||
self.heat = 80;
|
||||
#endif
|
||||
|
@ -4088,6 +4147,11 @@ void() W_WeaponFrame =
|
|||
TeamFortress_SetSpeed(self);
|
||||
|
||||
player_run ();
|
||||
} else if (self.current_weapon == WEAP_AUTO_RIFLE) {
|
||||
self.heat *= 0.2;
|
||||
self.heat -= 1;
|
||||
if (self.heat < 30)
|
||||
self.heat = 30; // auto can't be as accurate
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ void() wiz_death8 =[ $death8, wiz_death8 ]
|
|||
|
||||
void() wiz_die =
|
||||
{
|
||||
if (self.real_owner.classname == "player")
|
||||
if (self.real_owner.classname == "player" && self.real_owner.demon_one == self)
|
||||
{
|
||||
sprint(self.real_owner,PRINT_HIGH,"Your scrag is dead.\n");
|
||||
self.real_owner.job = self.real_owner.job - (self.real_owner.job & JOB_DEMON_OUT);
|
||||
|
|
Loading…
Reference in a new issue