Fire FX tweakery, plus a cheat to test it.

This commit is contained in:
Mari the Deer 2022-06-05 00:23:58 +02:00
commit dbc28f1422
4 changed files with 87 additions and 138 deletions

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r93 \cu(Sat 4 Jun 22:09:46 CEST 2022)\c-";
SWWM_SHORTVER="\cw1.3pre r93 \cu(2022-06-04 22:09:46)\c-";
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r94 \cu(Sun 5 Jun 00:23:58 CEST 2022)\c-";
SWWM_SHORTVER="\cw1.3pre r94 \cu(2022-06-05 00:23:58)\c-";

View file

@ -1,6 +1,6 @@
// Quadravol projectiles and effects
Class OnFireLight : DynamicLight
Class OnFireLight : PointLightFlickerRandomAttenuated
{
OnFire of;
@ -9,54 +9,33 @@ Class OnFireLight : DynamicLight
Super.Tick();
if ( !of || !of.victim )
{
A_StopSound(CHAN_VOICE);
Destroy();
return;
}
Args[0] = clamp(of.Amount*4,0,255);
Args[1] = clamp(of.Amount*2,0,160);
Args[2] = clamp(of.Amount/2,0,24);
Args[3] = int(max(of.victim.radius,of.victim.height)*(of.victim.scale.x+of.victim.scale.y)*1.2+40+clamp(of.amount/5,0,120));
Args[3] = int(max(of.victim.radius,of.victim.height)*2.+20+clamp(of.amount/5,0,80));
Args[4] = args[3]+8;
SetOrigin(of.Victim.Vec3Offset(0,0,of.Victim.Height/2),true);
}
}
Class OnFire : Actor
Class OnFire : Thinker
{
OnFire prevfire, nextfire;
Actor victim, instigator, lite;
int amount, cnt, delay;
int amount, cnt;
double oangle;
override void OnDestroy()
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( hnd )
{
hnd.fires_cnt--;
if ( !prevfire )
{
hnd.fires = nextfire;
if ( nextfire ) nextfire.prevfire = null;
}
else
{
prevfire.nextfire = nextfire;
if ( nextfire ) nextfire.prevfire = prevfire;
}
}
Super.OnDestroy();
}
override void Tick()
{
if ( isFrozen() ) return;
if ( level.isFrozen() ) return;
if ( !victim )
{
A_StopSound(CHAN_5);
Destroy();
return;
}
SetOrigin(victim.pos,false);
if ( victim.waterlevel > 0 )
{
if ( lite ) lite.Destroy();
@ -69,65 +48,74 @@ Class OnFire : Actor
oangle = victim.angle;
if ( amount < -30 )
{
A_StopSound(CHAN_5);
Destroy();
return;
}
if ( cnt > 0 ) cnt--;
else
{
cnt = min(10,30-int(29*(min(1.,amount/500.)**3.)));
cnt = 10;
if ( victim.bSHOOTABLE && (victim.Health > 0) && (amount > 0) )
{
int flg = DMG_THRUSTLESS;
if ( victim is 'Centaur' ) flg |= DMG_FOILINVUL; // you're on fire, that shield is worthless
victim.DamageMobj(self,instigator,clamp(int(amount*.06),1,20),'Fire',flg); // need to use this actor as inflictor to have a proper obituary
victim.DamageMobj(instigator.FindInventory("Quadravol"),instigator,clamp(int(amount*.1),1,20),'Fire',flg);
if ( victim.bISMONSTER && !Random[FlameT](0,3) )
victim.Howl();
}
if ( !victim )
{
A_StopSound(CHAN_5);
Destroy();
return;
}
else SWWMUtility.DoExplosion(self,clamp(int(amount*.06),1,20),0,victim.radius+40,victim.radius,DE_NOBLEED|DE_NOSPLASH|DE_HOWL,'Fire',victim); // radius fire damage
}
double mult = max(victim.radius,victim.height)/30.;
if ( delay > 0 ) delay--;
if ( (level.maptime+special1)%6 ) return;
A_SoundVolume(CHAN_5,min(1.,mult*amount/80.));
int numpt = clamp(int(Random[FlameT](2,4)*amount*.01),1,4);
numpt = int(clamp(numpt*mult**.5,1,3));
if ( lite ) lite.A_SoundVolume(CHAN_VOICE,min(1.,mult*amount/80.));
if ( level.maptime%5 ) return;
int numpt = clamp(int(Random[FlameT](2,4)*amount*.02),1,4);
numpt = int(clamp(numpt*mult**.5,1,5));
for ( int i=0; i<numpt; i++ )
{
Vector3 pos = victim.Vec3Offset(FRandom[FlameT](-victim.radius,victim.radius)*0.8,FRandom[FlameT](-victim.radius,victim.radius)*0.8,FRandom[FlameT](victim.height*0.2,victim.height*0.8));
Vector3 pos = victim.Vec3Offset(FRandom[FlameT](-victim.radius,victim.radius)*.8,FRandom[FlameT](-victim.radius,victim.radius)*.8,FRandom[FlameT](victim.height*.2,victim.height*.8));
double ang = FRandom[FlameT](0,360);
double pt = FRandom[FlameT](-90,90);
if ( amount > 0 )
{
let c = victim.Spawn("OnFireTrail",pos);
c.special1 = Random[FlameT](-2,2);
c.scale *= max(.3,mult*0.5);
c.vel = victim.vel*0.5+(cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[FlameT](.5,2.)*c.scale.x;
}
if ( !(i%2) )
{
let s = victim.Spawn("SWWMHalfSmoke",pos);
s.scale *= max(1.,1.6*mult);
s.alpha *= min(amount+30,100)*.01;
s.vel = victim.vel*0.5+(cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[FlameT](.2,.6)*s.scale.x;
c.scale *= max(.3,mult*.5);
c.vel = victim.vel*.5+(cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[FlameT](.5,2.)*c.scale.x;
}
let s = victim.Spawn("SWWMHalfSmoke",pos);
s.scale *= max(1.,1.6*mult);
s.alpha *= min(amount+30,100)*.02;
s.vel = victim.vel*.5+(cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[FlameT](.2,.6)*s.scale.x;
}
// spread to nearby actors
let bt = BlockThingsIterator.Create(victim);
while ( bt.Next() )
{
let t = bt.Thing;
if ( !t || !t.bSHOOTABLE || (t.Health <= 0) || (t == victim) || (victim.Distance3D(t) > victim.radius+t.radius+20) || !victim.CheckSight(t,SF_IGNOREVISIBILITY|SF_IGNOREWATERBOUNDARY) )
continue;
int amt = max(1,amount/10);
let of = IsOnFire(t);
if ( of )
{
amt = min(5,amt);
of.amount = min(500,of.amount+amt);
of.cnt = min(of.cnt,5);
}
else Apply(t,instigator,amt);
}
bt.Destroy();
}
static OnFire Apply( Actor victim, Actor instigator, int amount, int delay = 0 )
static OnFire Apply( Actor victim, Actor instigator, int amount )
{
if ( amount <= 0 ) return null;
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return null;
let ti = ThinkerIterator.Create("OnFire",STAT_USER);
OnFire t;
for ( t=hnd.fires; t; t=t.nextfire )
while ( t = OnFire(ti.Next()) )
{
if ( t.victim != victim ) continue;
if ( instigator ) t.instigator = instigator;
@ -135,75 +123,33 @@ Class OnFire : Actor
t.cnt = min(t.cnt,5);
return t;
}
t = OnFire(Spawn("OnFire",victim.pos));
t = new("ONFire");
t.ChangeStatNum(STAT_USER);
t.victim = victim;
t.instigator = instigator;
t.amount = min(500,amount);
t.cnt = 1;
t.special1 = Random[FlameT](0,10);
t.A_StartSound("misc/flame",CHAN_5,CHANF_LOOP);
double mult = max(victim.radius,victim.height)/30.;
t.A_SoundVolume(CHAN_5,min(1.,mult*amount/80.));
// for chunks
t.delay = delay;
t.lite = Actor.Spawn("OnFireLight",victim.pos);
t.lite.specialf1 = 3;
OnFireLight(t.lite).of = t;
t.oangle = victim.angle;
// append
t.nextfire = hnd.fires;
if ( hnd.fires ) hnd.fires.prevfire = t;
hnd.fires = t;
hnd.fires_cnt++;
double mult = max(victim.radius,victim.height)/30.;
t.lite.A_StartSound("misc/flame",CHAN_VOICE,CHANF_LOOP);
t.lite.A_SoundVolume(CHAN_VOICE,min(1.,mult*amount/80.));
return t;
}
static OnFire IsOnFire( Actor victim )
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return null;
let ti = ThinkerIterator.Create("OnFire",STAT_USER);
OnFire t;
for ( t=hnd.fires; t; t=t.nextfire )
while ( t = OnFire(ti.Next()) )
{
if ( t.victim != victim ) continue;
if ( t.amount <= 0 ) return null;
if ( (t.victim != victim) || (t.amount <= 0) ) continue;
return t;
}
return null;
}
Default
{
+NOGRAVITY;
+NOBLOCKMAP;
+DONTSPLASH;
+NOEXTREMEDEATH;
+NOINTERACTION;
Obituary "$O_QUADRAVOL";
}
}
Class OnFireTrailLight : PaletteLight
{
Default
{
Tag "HellExpl";
Args 0,0,0,40;
ReactionTime 40;
}
override void Tick()
{
Super.Tick();
Args[0] /= 10;
Args[1] /= 10;
Args[2] /= 10;
Args[3] += 3;
if ( !target || (target.waterlevel > 0) )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
}
}
Class OnFireTrail : Actor
@ -214,6 +160,7 @@ Class OnFireTrail : Actor
Scale.x *= RandomPick[ExploS](-1,1);
Scale.y *= RandomPick[ExploS](-1,1);
roll = FRandom[ExploS](0,360);
SetState(SpawnState+Random[ExploS](0,19));
}
action void A_Flame()
{
@ -223,26 +170,18 @@ Class OnFireTrail : Actor
else
{
vel *= .98;
vel.z += .1+.2*abs(scale.x);
}
if ( waterlevel > 0 )
{
let s = Spawn("SWWMSmoke",pos);
s.vel = (FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2));
s.vel += vel*.3;
s.alpha *= alpha*2;
s.scale *= .5+abs(scale.x)*(.5+special1/6.);
Destroy();
return;
vel.z += .1+.4*abs(scale.x);
}
if ( !Random[FlameT](0,int(40*(default.alpha-alpha))) )
{
let s = Spawn("SWWMHalfSmoke",pos);
s.vel = (FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2));
s.vel += vel*.3;
s.alpha *= alpha*1.5;
s.alpha *= alpha*4;
s.scale *= .5+abs(scale.x)*(.5+special1/6.);
}
A_SetScale(scale.x*.98);
A_FadeOut(.005);
}
override void Tick()
{
@ -263,30 +202,21 @@ Class OnFireTrail : Actor
Speed 2;
Radius 4;
Height 4;
Alpha .6;
Scale .8;
Alpha .15;
Scale .3;
+NOBLOCKMAP;
+NOGRAVITY;
+NOFRICTION;
+SLIDESONWALLS;
+NOTELEPORT;
+FORCEXYBILLBOARD;
+ROLLSPRITE;
+ROLLCENTER;
+DROPOFF;
+NOBLOCKMONST;
+DONTSPLASH;
+NOINTERACTION;
}
States
{
Spawn:
XFLM ABCDEFGHIJKLMNOPQRST 1 Bright
{
A_Flame();
A_SetScale(scale.x*0.98);
A_FadeOut(0.02);
}
Wait;
XFLM ABCDEFGHIJKLMNOPQRST 1 Bright A_Flame();
Loop;
}
}

View file

@ -308,7 +308,7 @@ extend Class SWWMHandler
if ( consoleplayer == e.Args[0] )
{
Console.Printf("\cdHop!\c-");
S_StartSound("misc/buyinv",CHAN_ITEM,CHANF_UI);
S_StartSound("menu/buyinv",CHAN_ITEM,CHANF_UI);
}
let mo = players[e.Args[0]].mo;
Actor f = Actor(ThinkerIterator.Create("FroggyChair").Next());
@ -323,7 +323,7 @@ extend Class SWWMHandler
if ( consoleplayer == e.Args[0] )
{
Console.Printf("\cyAmnesiacs administered.\c-");
S_StartSound("misc/buyinv",CHAN_ITEM,CHANF_UI);
S_StartSound("menu/buyinv",CHAN_ITEM,CHANF_UI);
S_StartSound("bestsound",CHAN_VOICE,CHANF_UI);
}
let ti = ThinkerIterator.Create("Actor");
@ -395,6 +395,29 @@ extend Class SWWMHandler
sewercnt = gametic;
}
}
else if ( e.Name ~== "swwmonfirecheat" )
{
let ti = ThinkerIterator.Create("Actor");
Actor a;
bool burned = false;
while ( a = Actor(ti.Next()) )
{
if ( !a.bSHOOTABLE || a.player || !SWWMUtility.InPlayerFOV(players[e.Args[0]],a) ) continue;
OnFire.Apply(a,players[e.Args[0]].mo,500);
burned = true;
}
if ( consoleplayer != e.Args[0] ) return;
if ( burned )
{
Console.Printf("\cyBurn baby burn...\c-");
S_StartSound("menu/buyinv",CHAN_ITEM,CHANF_UI);
}
else
{
Console.Printf("\cyNothing to burn here.\c-");
S_StartSound("misc/nocheat",CHAN_ITEM,CHANF_UI);
}
}
}
private ui bool CheatInput( InputEvent e )
@ -403,7 +426,7 @@ extend Class SWWMHandler
static const String cht[] =
{
"swwmlodsofemone", "swwmdeeplore", "swwmfroggygang", "swwmforgetaboutit",
"swwmmisterproper", "swwmstinky",
"swwmmisterproper", "swwmstinky", "swwmpantsonfire",
// SWWM Platinum cheats
"swwmimstuck", "swwmarmojumbo", "swwmdangimhealthy",
"swwmwarriorofzaemonath", "swwmpowerparp", "swwmcannotseemyhands",
@ -416,7 +439,7 @@ extend Class SWWMHandler
static const String cmd[] =
{
"swwmmoneycheat", "swwmlorecheat", "swwmfroggycheat", "swwmamnesiacheat",
"swwmjanitorcheat", "swwmsewercountcheat",
"swwmjanitorcheat", "swwmsewercountcheat", "swwmonfirecheat",
// SWWM Platinum cheats
"swwmsafecheat", "swwmweaponcheat", "swwmhealcheat",
"swwmynykroncheat", "swwmgravcheat", "swwminvischeat",
@ -438,7 +461,7 @@ extend Class SWWMHandler
matchany = true;
if ( kstr != cht[i] ) continue;
let s = SWWMStats.Find(players[consoleplayer]);
if ( (i > 5) && !swwm_nomapmsg && (!s || !s.oldcheat) )
if ( (i > 6) && !swwm_nomapmsg && (!s || !s.oldcheat) )
{
let m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_ZNVSNAME"),StringTable.Localize("$SWWM_ZNVNAME"),"Znv");
m.seqname = "ZNVTXT";

View file

@ -14,10 +14,6 @@ Class SWWMHandler : EventHandler
transient ui String sswstr;
transient ui BrokenLines sswl;
// optimization
OnFire fires;
int fires_cnt;
// stuff to reduce worldthingspawned overhead
int bossmap;
int iwantdie;