hexen2/H2MP/hcode/flames.hc
2000-11-10 00:00:00 +00:00

425 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")
{
sprint(self.owner,self.trigger_field.netname);
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);
sprint(self.owner,self.trigger_field.netname);
}
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.flags2&FL2_FIRERESIST)
{
if(self.aflag>0.1)
damagemult=self.aflag;
else
damagemult=0.1;
if(self.trigger_field.flags2&FL2_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.flags2&FL2_FIREHEAL)
other.health=other.health+1;
else if (!other.flags2&FL2_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;
};