426 lines
13 KiB
C++
426 lines
13 KiB
C++
|
void(vector org) SpawnFlameAt;
|
||
|
|
||
|
void () FireDie =
|
||
|
{
|
||
|
T_RadiusDamage (self, self.owner, (self.dmg - 1)*125+25, world);
|
||
|
|
||
|
self.origin = self.origin - 8*normalize(self.velocity);
|
||
|
|
||
|
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
|
||
|
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
|
||
|
WriteCoord (MSG_BROADCAST, self.origin_x);
|
||
|
WriteCoord (MSG_BROADCAST, self.origin_y);
|
||
|
WriteCoord (MSG_BROADCAST, self.origin_z);
|
||
|
|
||
|
BecomeExplosion (FALSE);
|
||
|
remove(self);
|
||
|
};
|
||
|
|
||
|
void() FireDamage =
|
||
|
{
|
||
|
local float damagemult;
|
||
|
if(self.trigger_field.skin>110)
|
||
|
self.wait=0;
|
||
|
else self.wait = self.wait - 1;
|
||
|
|
||
|
if (self.trigger_field.classname == "player" && self.owner.classname != "player")
|
||
|
self.owner = self.trigger_field;
|
||
|
|
||
|
if (self.trigger_field.waterlevel > 2)
|
||
|
if(self.trigger_field.watertype == CONTENT_LAVA)
|
||
|
{
|
||
|
if(self.trigger_field.classname=="player")
|
||
|
{
|
||
|
sprintname(self.owner,PRINT_MEDIUM,self.trigger_field);
|
||
|
sprint(self.owner," jumped out of the frying pan into the fire!\n");
|
||
|
}
|
||
|
self.trigger_field.effects = 0;
|
||
|
self.trigger_field.onfire = 0;
|
||
|
remove(self);
|
||
|
// FireDie();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(self.trigger_field.classname=="player")
|
||
|
{
|
||
|
sound (self.owner, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
|
||
|
sprintname(self.owner,PRINT_MEDIUM,self.trigger_field);
|
||
|
}
|
||
|
sprint(self.owner," saved his ass by jumping in the water!\n");
|
||
|
self.trigger_field.effects = 0;
|
||
|
self.trigger_field.onfire = 0;
|
||
|
remove(self);
|
||
|
}
|
||
|
|
||
|
if ((self.waterlevel > 2) || (self.watertype == CONTENT_WATER) || (self.watertype == CONTENT_SLIME) || (pointcontents(self.origin) == CONTENT_WATER) || (pointcontents(self.origin) == CONTENT_SLIME))
|
||
|
{
|
||
|
sound (self.owner, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
|
||
|
sprint(self.owner,"Fireball fizzled underwater\n");
|
||
|
self.trigger_field.effects = 0;
|
||
|
self.trigger_field.onfire = 0;
|
||
|
remove(self);
|
||
|
}
|
||
|
|
||
|
// if (self.aflag != 5)
|
||
|
// {
|
||
|
//Non-explosive death
|
||
|
if ((self.wait < 1) || (self.trigger_field.health<=0))
|
||
|
{
|
||
|
self.trigger_field.effects = 0;
|
||
|
self.trigger_field.onfire = 0;
|
||
|
remove(self);
|
||
|
}
|
||
|
// }
|
||
|
// else if (self.wait < 1 || self.trigger_field.health <= 6)
|
||
|
// {
|
||
|
//explosive fireball death
|
||
|
// self.dmg = 2;
|
||
|
// self.trigger_field.onfire = 0;
|
||
|
// self.trigger_field.effects = 0;
|
||
|
// FireDie();
|
||
|
// }
|
||
|
if(self.trigger_field.onfire>0.5)
|
||
|
self.trigger_field.onfire=0.5;//Max out damage at 0.5 per think
|
||
|
if (!self.trigger_field.flags&FL_FIRERESIST)
|
||
|
{
|
||
|
if(self.aflag>0.1)
|
||
|
damagemult=self.aflag;
|
||
|
else
|
||
|
damagemult=0.1;
|
||
|
if(self.trigger_field.flags&FL_FIREHEAL)
|
||
|
self.trigger_field.health=self.trigger_field.health+2*damagemult*self.trigger_field.onfire;
|
||
|
else
|
||
|
T_Damage (self.trigger_field, self, self.owner, damagemult*self.trigger_field.onfire);
|
||
|
}
|
||
|
|
||
|
if(self.trigger_field.health<=17)
|
||
|
if(self.trigger_field.thingtype==THINGTYPE_WOOD)
|
||
|
{
|
||
|
self.trigger_field.skin=111;
|
||
|
self.trigger_field.deathtype="burnt crumble";
|
||
|
}
|
||
|
else if(self.trigger_field.thingtype==THINGTYPE_FLESH)
|
||
|
{
|
||
|
self.trigger_field.skin=112;
|
||
|
self.trigger_field.deathtype="burnt crumble";
|
||
|
}
|
||
|
|
||
|
//FIXME: need 3 different fire models to put on them,
|
||
|
//randomly choose one & scale it to their size, add more
|
||
|
// if they're more on fire. No more than 3. Only one
|
||
|
//fire sound, from "invisible" one doing actual damage.
|
||
|
//Use movechain function to link flames to target
|
||
|
if(random()<0.5)
|
||
|
SpawnFlameAt (self.origin);//This is causing an edict overflow hard crash...
|
||
|
|
||
|
self.origin = self.trigger_field.origin + '0 0 6';
|
||
|
self.think = FireDamage;
|
||
|
thinktime self : 0.1;
|
||
|
};
|
||
|
|
||
|
void() FireTouch2 =
|
||
|
{
|
||
|
self.trigger_field.effects = EF_BRIGHTLIGHT;
|
||
|
if(self.trigger_field.onfire<=0)
|
||
|
self.trigger_field.onfire = 1;
|
||
|
self.think=FireDamage;
|
||
|
thinktime self : 0;
|
||
|
};
|
||
|
|
||
|
void() FireTouch =
|
||
|
{
|
||
|
local float damg;
|
||
|
|
||
|
if (other == self.owner)
|
||
|
return; // don't explode on owner
|
||
|
|
||
|
if (pointcontents(self.origin) == CONTENT_SKY)
|
||
|
{
|
||
|
remove(self);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (other.takedamage&&other.thingtype!=1&&other.thingtype!=0&&other.thingtype!=3&&other.skin<111)
|
||
|
{
|
||
|
if(other.onfire)
|
||
|
{
|
||
|
other.onfire=other.onfire+0.1;
|
||
|
remove(self);
|
||
|
}
|
||
|
else
|
||
|
other.onfire=0.1;
|
||
|
sound (self, CHAN_WEAPON, "misc/combust.wav", 1, ATTN_NORM);
|
||
|
self.trigger_field = other;
|
||
|
self.origin = other.origin + '0 0 6';
|
||
|
|
||
|
if (other.classname == "player" || self.aflag == 5)
|
||
|
self.wait = 180;
|
||
|
else
|
||
|
self.wait = 40;
|
||
|
|
||
|
setsize (self, '0 0 0', '0 0 0');
|
||
|
|
||
|
self.think=FireTouch2;
|
||
|
thinktime self : 0;
|
||
|
self.movetype = MOVETYPE_NOCLIP;
|
||
|
self.velocity = '0 0 0' ;
|
||
|
self.avelocity = '0 0 1000';
|
||
|
if ((other.waterlevel < 2) && (other.classname == "player"))
|
||
|
sprint(other, "You're burning up!\n");
|
||
|
return;
|
||
|
}
|
||
|
else if (self.movetype == MOVETYPE_FLYMISSILE)
|
||
|
remove(self);
|
||
|
// FireDie();
|
||
|
sound (self, CHAN_WEAPON, "misc/fburn_sm.wav", 0.75, ATTN_STATIC); // bounce sound
|
||
|
SpawnPuff(self.origin,'0 0 0', 10,other);
|
||
|
// spawn_touchblood (10);
|
||
|
SpawnFlameAt (self.origin);
|
||
|
if (self.velocity == '0 0 0')
|
||
|
self.avelocity = '0 0 0';
|
||
|
if (self.aflag == 5)
|
||
|
{
|
||
|
self.trigger_field=self.enemy;
|
||
|
thinktime self : 0.05;
|
||
|
self.think = FireTouch2;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void () FireThink =
|
||
|
{
|
||
|
|
||
|
if (pointcontents(self.origin)==CONTENT_WATER||pointcontents(self.origin)==CONTENT_SLIME||(self.waterlevel > 2))
|
||
|
FireFizzle();
|
||
|
self.attack_finished = self.attack_finished + 0.1;
|
||
|
if (self.attack_finished > 5)
|
||
|
// if(self.model=="models/lavaball.spr")
|
||
|
// FireDie();
|
||
|
// else
|
||
|
remove(self);
|
||
|
thinktime self : 0.1;
|
||
|
self.think = FireThink;
|
||
|
};
|
||
|
|
||
|
void(entity loser) SpawnFlameOn =
|
||
|
{
|
||
|
if(pointcontents(loser.origin)<-2)
|
||
|
return;
|
||
|
//Used by player, archvile, and stickmine
|
||
|
local entity fire;
|
||
|
if (pointcontents(self.origin) < -2)
|
||
|
{
|
||
|
sound (self, CHAN_WEAPON, "misc/fout.wav", 1, ATTN_NORM);
|
||
|
return;
|
||
|
}
|
||
|
fire = spawn ();
|
||
|
fire.controller = self;
|
||
|
fire.movetype = MOVETYPE_NOCLIP;
|
||
|
fire.solid = SOLID_NOT;
|
||
|
fire.velocity = '0 0 0' ;
|
||
|
fire.avelocity = '0 0 1000';
|
||
|
fire.classname = "fire";
|
||
|
fire.dmg = 1;
|
||
|
fire.aflag = 0.25;
|
||
|
setmodel (fire, "models/null.spr");
|
||
|
fire.effects=EF_NODRAW;
|
||
|
setsize (fire, '0 0 0', '0 0 0');
|
||
|
if(self.classname=="fireballblast"||self.classname=="flaming arrow")
|
||
|
{
|
||
|
fire.enemy = loser;
|
||
|
setorigin (fire, (loser.absmax+loser.absmin)*0.5);
|
||
|
fire.owner=self;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
setorigin (fire, (self.enemy.absmax+self.enemy.absmin)*0.5);
|
||
|
fire.enemy = self.enemy;
|
||
|
fire.owner = self.controller;
|
||
|
}
|
||
|
sound (fire, CHAN_WEAPON, "misc/combust.wav", 1, ATTN_NORM);
|
||
|
if(!loser.onfire)
|
||
|
loser.onfire=0.1;
|
||
|
else
|
||
|
{
|
||
|
loser.onfire+=0.1;
|
||
|
remove(fire);
|
||
|
return;
|
||
|
}
|
||
|
fire.trigger_field = loser;
|
||
|
|
||
|
if (loser.classname == "player")
|
||
|
fire.wait = 120;
|
||
|
else
|
||
|
fire.wait = 40;
|
||
|
thinktime fire : 0.1;
|
||
|
fire.think=FireTouch2;
|
||
|
};
|
||
|
|
||
|
void(vector org) SpawnFlameAt =
|
||
|
{
|
||
|
if(pointcontents(self.origin)<-2)
|
||
|
return;
|
||
|
local entity fireflame;
|
||
|
local float xorg, yorg, zorg;
|
||
|
fireflame = spawn();
|
||
|
setmodel (fireflame, "models/flame2.mdl");
|
||
|
fireflame.movetype = MOVETYPE_FLY;
|
||
|
fireflame.solid = SOLID_NOT;
|
||
|
fireflame.classname = "missile";
|
||
|
fireflame.drawflags(+)MLS_ABSLIGHT;
|
||
|
fireflame.abslight=0.5;
|
||
|
fireflame.frame = rint(random());
|
||
|
setsize (fireflame, '-2 -2 -2', '1 1 1');
|
||
|
xorg = random(-15,15);
|
||
|
yorg = random(-15,15);
|
||
|
zorg = random(-25,25);
|
||
|
setorigin (fireflame, org + v_forward * xorg + v_right * yorg + v_up * zorg);
|
||
|
fireflame.velocity_x += random(-40,40);
|
||
|
fireflame.velocity_y += random(-40,40);
|
||
|
fireflame.velocity_z += random(300);
|
||
|
fireflame.avelocity = '0 0 0';
|
||
|
if (random() < 0.3)
|
||
|
sound (self, CHAN_WEAPON, "misc/fburn_sm.wav", 1, ATTN_NORM);
|
||
|
thinktime fireflame : 0.5; // remove after half second
|
||
|
fireflame.think = SUB_Remove;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
FlameTouch
|
||
|
================
|
||
|
*/
|
||
|
void () FlameTouch =
|
||
|
{
|
||
|
local float rn;
|
||
|
//Scale size relative to other.size?
|
||
|
if (other.takedamage)
|
||
|
{
|
||
|
if(other.flags&FL_FIREHEAL)
|
||
|
other.health=other.health+1;
|
||
|
else if (!other.flags&FL_FIRERESIST)
|
||
|
T_Damage(other,self,self.owner,5);
|
||
|
if(other.thingtype==THINGTYPE_FLESH||other.thingtype==THINGTYPE_WOOD)
|
||
|
{
|
||
|
//set on fire
|
||
|
rn = random();
|
||
|
// 50% chance
|
||
|
if (rn <= 0.5||other.onfire>=1)
|
||
|
{
|
||
|
if(other.onfire)
|
||
|
other.onfire = other.onfire + 0.1;
|
||
|
remove(self);
|
||
|
}
|
||
|
other.onfire = other.onfire + 0.1;
|
||
|
if(self.owner.movetype==MOVETYPE_NONE)
|
||
|
self.wait = 20;
|
||
|
else self.wait = 60;
|
||
|
self.aflag = 0.1;
|
||
|
self.trigger_field = other;
|
||
|
self.think = FireTouch2;
|
||
|
thinktime self : 0;
|
||
|
self.solid = SOLID_NOT;
|
||
|
setmodel (self,"models/flame2.mdl");
|
||
|
}
|
||
|
else if(self.netname=="firespike")
|
||
|
{
|
||
|
//FIXME:else sprite
|
||
|
remove(self);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(self.netname=="firespike")
|
||
|
{
|
||
|
if(other.thingtype==THINGTYPE_FLESH||other.thingtype==THINGTYPE_WOOD)
|
||
|
SpawnFlameAt(self.origin);
|
||
|
//FIXME:else sprite
|
||
|
remove(self);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
self.velocity = '0 0 0';
|
||
|
self.velocity_z = random(24,48);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/*
|
||
|
================
|
||
|
W_FireFlame
|
||
|
================
|
||
|
*/
|
||
|
void(float offset) W_FireFlame =
|
||
|
{
|
||
|
local entity flame;
|
||
|
local float rn;
|
||
|
|
||
|
if(self.movetype!=MOVETYPE_NONE)
|
||
|
{
|
||
|
if (self.waterlevel > 2)
|
||
|
{
|
||
|
// makevectors (self.v_angle);
|
||
|
|
||
|
rn = random();
|
||
|
if (rn < 0.5)
|
||
|
sound (self, CHAN_WEAPON, "player/swim1.wav", 1, ATTN_NORM);
|
||
|
else
|
||
|
sound (self, CHAN_WEAPON, "player/swim2.wav", 1, ATTN_NORM);
|
||
|
flame=spawn();
|
||
|
flame.owner=flame;
|
||
|
setorigin(flame,self.origin+self.proj_ofs + v_forward * 32 + v_up * random(8,16));
|
||
|
flame.think=DeathBubblesSpawn;
|
||
|
thinktime flame : 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Take away a shell
|
||
|
// self.currentammo = self.ammo_shells = self.ammo_shells - 1;
|
||
|
}
|
||
|
else if((random()>=0.1&&random()>=0.2)||(!other.takedamage))
|
||
|
return;
|
||
|
sound (self, CHAN_WEAPON, "paladin/purfire.wav", 1, ATTN_NORM);
|
||
|
|
||
|
flame = spawn ();
|
||
|
flame.owner = self;
|
||
|
flame.movetype = MOVETYPE_FLYMISSILE;
|
||
|
flame.solid = SOLID_BBOX;
|
||
|
flame.classname = "fire";
|
||
|
flame.drawflags(+)MLS_ABSLIGHT;
|
||
|
flame.abslight=0.5;
|
||
|
// set flame speed
|
||
|
|
||
|
if(self.classname=="player"&&self.playerclass==CLASS_PALADIN&&self.weapon==IT_WEAPON4)
|
||
|
{
|
||
|
self.punchangle_x= -1;
|
||
|
setmodel (flame, "models/purfir1.mdl");
|
||
|
flame.netname="firespike";
|
||
|
}
|
||
|
else
|
||
|
setmodel (flame, "models/flame2.mdl");
|
||
|
setsize (flame, '0 0 0', '0 0 0');
|
||
|
|
||
|
if(self.movetype==MOVETYPE_NONE)
|
||
|
{
|
||
|
flame.velocity='0 0 100';
|
||
|
setorigin (flame, self.origin + '0 0 16');
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
makevectors (self.v_angle);
|
||
|
flame.velocity = normalize(v_forward)*700 + v_up*random(32) + v_right * random(0-offset,offset);
|
||
|
setorigin (flame, self.origin+self.proj_ofs + v_forward * 32 + v_up * random(-8,8));
|
||
|
}
|
||
|
if(flame.netname=="firespike")
|
||
|
flame.angles=vectoangles(flame.velocity);
|
||
|
|
||
|
// flame.effects = 6;
|
||
|
flame.touch = FlameTouch;
|
||
|
|
||
|
flame.think = FireThink;
|
||
|
thinktime flame : 0;
|
||
|
self.attack_finished=time + 0.1;
|
||
|
};
|