Flamethrower primary fire implemented.
This commit is contained in:
parent
c0ad22d9e6
commit
bd6c799988
6 changed files with 278 additions and 4 deletions
|
|
@ -84,3 +84,5 @@ server bool sting_bhold = false; // biorifle can be held fully loaded
|
||||||
server bool sting_razoraim = false; // razorjack alt follows aim instead of
|
server bool sting_razoraim = false; // razorjack alt follows aim instead of
|
||||||
// being steered by player rotation
|
// being steered by player rotation
|
||||||
server bool sting_biosplash = false; // biorifle alt splashes like in ut
|
server bool sting_biosplash = false; // biorifle alt splashes like in ut
|
||||||
|
server bool sting_flametspread = false; // targets on fire spread the flames
|
||||||
|
// to anyone nearby (may be op)
|
||||||
|
|
|
||||||
BIN
graphics/Sky95.png
Normal file
BIN
graphics/Sky95.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
|
|
@ -247,6 +247,7 @@ STING_QOPTS = "Convenience features";
|
||||||
STING_AUTOSCUBA = "Automatic SCUBA Gear toggling";
|
STING_AUTOSCUBA = "Automatic SCUBA Gear toggling";
|
||||||
STING_RAZORAIM = "Razorjack altfire follows the crosshair";
|
STING_RAZORAIM = "Razorjack altfire follows the crosshair";
|
||||||
STING_BIOSPLASH = "Biorifle altfire splashes like in UT";
|
STING_BIOSPLASH = "Biorifle altfire splashes like in UT";
|
||||||
|
STING_FLAMETSPREAD = "Flamethrower fire spreads between targets";
|
||||||
STING_MCREDS = "Unreal Credits";
|
STING_MCREDS = "Unreal Credits";
|
||||||
STING_CDR = "Doomreal";
|
STING_CDR = "Doomreal";
|
||||||
STING_CLEAD = "Development Lead:";
|
STING_CLEAD = "Development Lead:";
|
||||||
|
|
@ -483,6 +484,7 @@ STING_QOPTS = "Características de comodidad";
|
||||||
STING_AUTOSCUBA = "Uso automático de Kit de Buceo";
|
STING_AUTOSCUBA = "Uso automático de Kit de Buceo";
|
||||||
STING_RAZORAIM = "El fuego alt. del Razorjack sigue el punto de mira";
|
STING_RAZORAIM = "El fuego alt. del Razorjack sigue el punto de mira";
|
||||||
STING_BIOSPLASH = "El fuego alt. del Biorifle salpica como en UT";
|
STING_BIOSPLASH = "El fuego alt. del Biorifle salpica como en UT";
|
||||||
|
STING_FLAMETSPREAD = "El fuego del Lanzallamas se propaga entre objetivos";
|
||||||
STING_MCREDS = "Créditos de Unreal";
|
STING_MCREDS = "Créditos de Unreal";
|
||||||
STING_CDR = "Doomreal";
|
STING_CDR = "Doomreal";
|
||||||
STING_CLEAD = "Desarrolladora Jefe:";
|
STING_CLEAD = "Desarrolladora Jefe:";
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ OptionMenu "UnrealOptionMenu"
|
||||||
Option "$STING_AUTOSCUBA", "sting_autoscuba", "YesNo"
|
Option "$STING_AUTOSCUBA", "sting_autoscuba", "YesNo"
|
||||||
Option "$STING_RAZORAIM", "sting_razoraim", "YesNo"
|
Option "$STING_RAZORAIM", "sting_razoraim", "YesNo"
|
||||||
Option "$STING_BIOSPLASH", "sting_biosplash", "YesNo"
|
Option "$STING_BIOSPLASH", "sting_biosplash", "YesNo"
|
||||||
|
Option "$STING_FLAMETSPREAD", "sting_flametspread", "YesNo"
|
||||||
}
|
}
|
||||||
|
|
||||||
AddOptionMenu "OptionsMenu"
|
AddOptionMenu "OptionsMenu"
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,263 @@ Class FlameAmmo : Ammo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class UFlameTrail : Actor
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Class OnFire : Thinker
|
Class OnFire : Thinker
|
||||||
{
|
{
|
||||||
|
Actor victim, instigator;
|
||||||
|
int amount, cnt;
|
||||||
|
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
if ( !victim )
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( victim.waterlevel > 0 )
|
||||||
|
{
|
||||||
|
victim.A_RemoveLight('OnFireLight');
|
||||||
|
amount -= victim.waterlevel**2;
|
||||||
|
}
|
||||||
|
else victim.A_AttachLight('OnFireLight',DynamicLight.RandomFlickerLight,Color(4,2,0)*clamp(amount,0,63),int(max(victim.radius,victim.height))+60+min(amount/4,40),int(max(victim.radius,victim.height))+60+min(amount/4,40)+8,DynamicLight.LF_ATTENUATE,(0,0,victim.height/2),0.1);
|
||||||
|
if ( victim.Health <= 0 ) amount = min(amount,100);
|
||||||
|
if ( !(level.maptime%3) )
|
||||||
|
amount -= ((victim.Health>0)?1:2);
|
||||||
|
if ( amount < -10 )
|
||||||
|
{
|
||||||
|
victim.A_RemoveLight('OnFireLight');
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( amount <= 0 ) return;
|
||||||
|
if ( cnt > 0 ) cnt--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cnt = 10;
|
||||||
|
if ( victim.bSHOOTABLE && (victim.Health > 0) )
|
||||||
|
victim.DamageMobj(instigator.FindInventory("UFlamethrower"),instigator,max(1,amount*(victim.bBOSS?0.05:0.15)),'Fire',DMG_THRUSTLESS);
|
||||||
|
if ( !victim )
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( level.maptime%5 ) return;
|
||||||
|
int numpt = clamp(int(Random[FlameT](2,4)*amount*0.02),1,4);
|
||||||
|
double mult = max(victim.radius,victim.height)/30.;
|
||||||
|
numpt = int(max(1,numpt*mult));
|
||||||
|
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));
|
||||||
|
double ang = FRandom[FlameT](0,360);
|
||||||
|
double pt = FRandom[FlameT](-90,90);
|
||||||
|
let c = victim.Spawn("UFlameTrail",pos);
|
||||||
|
c.scale *= max(1.,mult*0.35);
|
||||||
|
c.vel = victim.vel*0.5+(cos(ang)*cos(pt),sin(ang)*cos(pt),-sin(pt))*FRandom[FlameT](.5,2);
|
||||||
|
c.master = instigator;
|
||||||
|
c.tracer = victim;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Apply( Actor victim, Actor instigator, int amount )
|
||||||
|
{
|
||||||
|
if ( amount <= 0 ) return;
|
||||||
|
if ( victim is 'ShredCorpseHitbox' ) return;
|
||||||
|
let ti = ThinkerIterator.Create("OnFire",STAT_USER);
|
||||||
|
OnFire t;
|
||||||
|
while ( t = OnFire(ti.Next()) )
|
||||||
|
{
|
||||||
|
if ( t.victim != victim ) continue;
|
||||||
|
if ( instigator ) t.instigator = instigator;
|
||||||
|
t.amount = min(500,t.amount+amount);
|
||||||
|
t.cnt = min(t.cnt,3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
t = new("ONFire");
|
||||||
|
t.ChangeStatNum(STAT_USER);
|
||||||
|
t.victim = victim;
|
||||||
|
t.instigator = instigator;
|
||||||
|
t.amount = amount;
|
||||||
|
t.cnt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsOnFire( Actor victim )
|
||||||
|
{
|
||||||
|
let ti = ThinkerIterator.Create("OnFire",STAT_USER);
|
||||||
|
OnFire t;
|
||||||
|
while ( t = OnFire(ti.Next()) )
|
||||||
|
{
|
||||||
|
if ( t.victim != victim ) continue;
|
||||||
|
return (t.amount>0);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class UFlameLight : PaletteLight
|
||||||
|
{
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
Tag "Ampd";
|
||||||
|
Args 0,0,0,40;
|
||||||
|
ReactionTime 40;
|
||||||
|
}
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
Super.Tick();
|
||||||
|
Args[0] /= 5;
|
||||||
|
Args[1] /= 5;
|
||||||
|
Args[2] /= 5;
|
||||||
|
Args[3] += 4;
|
||||||
|
if ( !target || (target.waterlevel > 0) )
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetOrigin(target.pos,true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Class UFlameTrailLight : PaletteLight
|
||||||
|
{
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
Tag "Ampd";
|
||||||
|
Args 0,0,0,80;
|
||||||
|
ReactionTime 20;
|
||||||
|
}
|
||||||
|
override void Tick()
|
||||||
|
{
|
||||||
|
Super.Tick();
|
||||||
|
Args[0] /= 9;
|
||||||
|
Args[1] /= 9;
|
||||||
|
Args[2] /= 9;
|
||||||
|
if ( !target || (target.waterlevel > 0) )
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SetOrigin(target.pos,true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class UFlame : Actor
|
Class UFlame : Actor
|
||||||
{
|
{
|
||||||
|
override void PostBeginPlay()
|
||||||
|
{
|
||||||
|
Super.PostBeginPlay();
|
||||||
|
let l = Spawn("UFlameLight",pos);
|
||||||
|
l.target = self;
|
||||||
|
Scale.x *= RandomPick[ExploS](-1,1);
|
||||||
|
Scale.y *= RandomPick[ExploS](-1,1);
|
||||||
|
}
|
||||||
|
bool TraceCheck( Actor other )
|
||||||
|
{
|
||||||
|
Vector3 to;
|
||||||
|
double len;
|
||||||
|
FLineTraceData d;
|
||||||
|
to = level.Vec3Diff(pos,other.pos);
|
||||||
|
len = to.length();
|
||||||
|
to /= len;
|
||||||
|
if ( !LineTrace(atan2(to.y,to.x),len,asin(-to.z),TRF_THRUACTORS) ) return true;
|
||||||
|
to = level.Vec3Diff(pos,other.Vec3Offset(0,0,other.height/2));
|
||||||
|
len = to.length();
|
||||||
|
to /= len;
|
||||||
|
if ( !LineTrace(atan2(to.y,to.x),len,asin(-to.z),TRF_THRUACTORS) ) return true;
|
||||||
|
to = level.Vec3Diff(pos,other.Vec3Offset(0,0,other.height));
|
||||||
|
len = to.length();
|
||||||
|
to /= len;
|
||||||
|
if ( !LineTrace(atan2(to.y,to.x),len,asin(-to.z),TRF_THRUACTORS) ) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
action void A_Flame()
|
||||||
|
{
|
||||||
|
if ( waterlevel > 0 )
|
||||||
|
vel *= 0.9;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vel *= 0.98;
|
||||||
|
vel.z += 0.2;
|
||||||
|
}
|
||||||
|
if ( waterlevel > 0 ) bINVISIBLE = true;
|
||||||
|
if ( !Random[FlameT](0,int(30*(0.4-alpha))) && (!bINVISIBLE || (waterlevel > 0)) )
|
||||||
|
{
|
||||||
|
let s = Spawn("UTSmoke",pos+vel);
|
||||||
|
s.vel = (FRandom[FlameT](-0.2,0.2),FRandom[FlameT](-0.2,0.2),FRandom[FlameT](-0.2,0.2));
|
||||||
|
s.vel += vel*0.2;
|
||||||
|
s.alpha *= 0.4;
|
||||||
|
s.scale *= 2.5;
|
||||||
|
}
|
||||||
|
if ( bAMBUSH && !sting_flametspread ) return;
|
||||||
|
if ( Random[FlameT](0,int(12*(0.4-alpha))) ) return;
|
||||||
|
double rad = bAMBUSH?10:60;
|
||||||
|
if ( !bAMBUSH ) rad += 90*(0.4-alpha);
|
||||||
|
let bt = BlockThingsIterator.Create(self,rad+200);
|
||||||
|
while ( bt.Next() )
|
||||||
|
{
|
||||||
|
let t = bt.Thing;
|
||||||
|
if ( !t || !t.bSHOOTABLE || (t.Health <= 0) || (t == tracer) || (!bAMBUSH && (t == master) && (GetAge() < 6)) || (Distance3D(t) > rad+t.radius) || !invoker.TraceCheck(t) ) continue;
|
||||||
|
int amt = max(1,int(alpha*15));
|
||||||
|
if ( bAMBUSH && OnFire.IsOnFire(t) ) amt /= 2;
|
||||||
|
OnFire.Apply(t,master,amt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
RenderStyle "Add";
|
||||||
|
Speed 20;
|
||||||
|
Radius 4;
|
||||||
|
Height 4;
|
||||||
|
Alpha 0.4;
|
||||||
|
Scale 0.1;
|
||||||
|
+NOBLOCKMAP;
|
||||||
|
+NOGRAVITY;
|
||||||
|
+NOFRICTION;
|
||||||
|
+SLIDESONWALLS;
|
||||||
|
+ACTIVATEPCROSS;
|
||||||
|
+ACTIVATEIMPACT;
|
||||||
|
+NOTELEPORT;
|
||||||
|
+FORCEXYBILLBOARD;
|
||||||
|
+DROPOFF;
|
||||||
|
+NOBLOCKMONST;
|
||||||
|
}
|
||||||
|
States
|
||||||
|
{
|
||||||
|
Spawn:
|
||||||
|
SEXP AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTT 1 Bright
|
||||||
|
{
|
||||||
|
A_Flame();
|
||||||
|
A_SetScale(scale.x*1.08);
|
||||||
|
A_FadeOut(0.01);
|
||||||
|
}
|
||||||
|
Stop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Class UFlameTrail : UFlame
|
||||||
|
{
|
||||||
|
override void PostBeginPlay()
|
||||||
|
{
|
||||||
|
Actor.PostBeginPlay();
|
||||||
|
Scale.x *= RandomPick[ExploS](-1,1);
|
||||||
|
Scale.y *= RandomPick[ExploS](-1,1);
|
||||||
|
}
|
||||||
|
Default
|
||||||
|
{
|
||||||
|
Speed 2;
|
||||||
|
Alpha 0.3;
|
||||||
|
Scale 0.6;
|
||||||
|
+AMBUSH;
|
||||||
|
}
|
||||||
|
States
|
||||||
|
{
|
||||||
|
Spawn:
|
||||||
|
SEXP AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTT 1 Bright
|
||||||
|
{
|
||||||
|
A_Flame();
|
||||||
|
A_SetScale(scale.x*0.98);
|
||||||
|
A_FadeOut(0.01);
|
||||||
|
}
|
||||||
|
Stop;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Class UNapalm : Actor
|
Class UNapalm : Actor
|
||||||
|
|
@ -46,6 +293,13 @@ Class UFlamethrower : UnrealWeapon
|
||||||
Owner.A_PlaySound("flamet/down",CHAN_6,Dampener.Active(self)?.1:1.);
|
Owner.A_PlaySound("flamet/down",CHAN_6,Dampener.Active(self)?.1:1.);
|
||||||
return Super.CreateTossable(amt);
|
return Super.CreateTossable(amt);
|
||||||
}
|
}
|
||||||
|
override void DoEffect()
|
||||||
|
{
|
||||||
|
Super.DoEffect();
|
||||||
|
if ( Owner.player.ReadyWeapon != self ) return;
|
||||||
|
let psp = Owner.player.FindPSprite(-2);
|
||||||
|
if ( psp ) psp.alpha = (Owner.waterlevel>2)?.0:1.;
|
||||||
|
}
|
||||||
action void A_FireFlame()
|
action void A_FireFlame()
|
||||||
{
|
{
|
||||||
let weap = Weapon(invoker);
|
let weap = Weapon(invoker);
|
||||||
|
|
@ -60,6 +314,20 @@ Class UFlamethrower : UnrealWeapon
|
||||||
weap.DepleteAmmo(weap.bAltFire,true,1);
|
weap.DepleteAmmo(weap.bAltFire,true,1);
|
||||||
invoker.count -= 1.;
|
invoker.count -= 1.;
|
||||||
}
|
}
|
||||||
|
invoker.FireEffect();
|
||||||
|
A_AlertMonsters();
|
||||||
|
UTMainHandler.DoFlash(self,Color(32,255,128,0),1);
|
||||||
|
Vector3 x, y, z, x2, y2, z2;
|
||||||
|
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
|
||||||
|
Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+2.5*y-2*z);
|
||||||
|
Actor p = Spawn("UFlame",origin);
|
||||||
|
double a = FRandom[FlameT](0,360), s = FRandom[FlameT](0,.05);
|
||||||
|
[x2, y2, z2] = dt_CoordUtil.GetAxes(BulletSlope(),angle,roll);
|
||||||
|
Vector3 dir = (x2+y2*cos(a)*s+z2*sin(a)*s).unit();
|
||||||
|
p.angle = atan2(dir.y,dir.x);
|
||||||
|
p.pitch = asin(-dir.z);
|
||||||
|
p.vel = vel*0.5+(cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed*FRandom[FlameT](0.8,1.4);
|
||||||
|
p.master = self;
|
||||||
}
|
}
|
||||||
action void A_BeginFlame()
|
action void A_BeginFlame()
|
||||||
{
|
{
|
||||||
|
|
@ -121,6 +389,7 @@ Class UFlamethrower : UnrealWeapon
|
||||||
Weapon.AmmoUse2 1;
|
Weapon.AmmoUse2 1;
|
||||||
Weapon.AmmoGive 100;
|
Weapon.AmmoGive 100;
|
||||||
UTWeapon.DropAmmo 50;
|
UTWeapon.DropAmmo 50;
|
||||||
|
+NOEXTREMEDEATH;
|
||||||
}
|
}
|
||||||
States
|
States
|
||||||
{
|
{
|
||||||
|
|
@ -138,7 +407,7 @@ Class UFlamethrower : UnrealWeapon
|
||||||
{
|
{
|
||||||
A_PlaySound("flamet/idle",CHAN_6,Dampener.Active(self)?.1:1.,true);
|
A_PlaySound("flamet/idle",CHAN_6,Dampener.Active(self)?.1:1.,true);
|
||||||
A_Overlay(-2,"FlameReady");
|
A_Overlay(-2,"FlameReady");
|
||||||
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE,true);
|
A_OverlayFlags(-2,PSPF_RENDERSTYLE|PSPF_FORCESTYLE|PSPF_ALPHA|PSPF_FORCEALPHA,true);
|
||||||
A_OverlayRenderStyle(-2,STYLE_Add);
|
A_OverlayRenderStyle(-2,STYLE_Add);
|
||||||
}
|
}
|
||||||
FLMS GHIJ 2 A_WeaponReady(WRF_NOFIRE);
|
FLMS GHIJ 2 A_WeaponReady(WRF_NOFIRE);
|
||||||
|
|
|
||||||
|
|
@ -1204,7 +1204,7 @@ Class UnrealMainHandler : EventHandler
|
||||||
if ( (level.GetChecksum() ~== "959A613006CC3AA912C4A22908B7566A") || (level.GetChecksum() ~== "0EADB2F82732A968B8513E4DC6138439") )
|
if ( (level.GetChecksum() ~== "959A613006CC3AA912C4A22908B7566A") || (level.GetChecksum() ~== "0EADB2F82732A968B8513E4DC6138439") )
|
||||||
{
|
{
|
||||||
S_ChangeMusic("Cyrene");
|
S_ChangeMusic("Cyrene");
|
||||||
TextureID sky95 = TexMan.CheckForTexture("95Bg",TexMan.Type_Any);
|
TextureID sky95 = TexMan.CheckForTexture("Sky95",TexMan.Type_Any);
|
||||||
level.ChangeSky(sky95,sky95);
|
level.ChangeSky(sky95,sky95);
|
||||||
level.ReplaceTextures("rClfFlr0","C_flr19",0);
|
level.ReplaceTextures("rClfFlr0","C_flr19",0);
|
||||||
level.ReplaceTextures("rClfBas0","C_wal19k",0);
|
level.ReplaceTextures("rClfBas0","C_wal19k",0);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue