Fireblaster (Flame Gun) added.

This commit is contained in:
Marisa the Magician 2019-09-21 23:20:38 +02:00
commit a95e4721f2
19 changed files with 581 additions and 8 deletions

View file

@ -1,13 +1,280 @@
Class UFireLight : PaletteLight
{
Default
{
Tag "FlamG";
Args 0,0,0,60;
}
}
Class UFireTrail : Actor
{
Default
{
RenderStyle "Add";
Radius 0.1;
Height 0;
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+NOTELEPORT;
Scale 0.5;
Alpha 0.2;
}
override void Tick()
{
Super.Tick();
if ( !target || !target.bMISSILE )
{
Destroy();
return;
}
SetOrigin(target.pos,true);
}
States
{
Spawn:
FGFL A -1 Bright;
Stop;
}
}
Class UFireball : Actor
{
Vector3 Acceleration;
double spreadf;
int ns, nsp;
property SpreadFactor : spreadf;
property NumSmokes : ns;
property NumSparks : nsp;
Default
{
DamageType 'Fire';
DamageFunction 30;
Radius 4;
Height 4;
Speed 15;
PROJECTILE;
+SKYEXPLODE;
+EXPLODEONWATER;
+FORCERADIUSDMG;
+NODAMAGETHRUST;
+FORCEXYBILLBOARD;
UFireball.SpreadFactor 0.2;
UFireball.NumSmokes 1;
UFireball.NumSparks 2;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( bAMBUSH ) return;
let l = Spawn("UFireTrail",pos);
l.target = self;
Acceleration = vel.unit()*50;
A_PlaySound("eightball/fly",CHAN_VOICE,1.0,true,3.,pitch:1.5);
}
action void A_Spread()
{
vel += invoker.Acceleration/TICRATE;
vel += (FRandom[EWizFX](-1,1),FRandom[EWizFX](-1,1),FRandom[EWizFX](-1,1))*FRandom[EWizFX](.5,1.)*invoker.spreadf;
Vector3 dir = vel.unit();
if ( vel.length() > 30. ) vel = dir*30.;
angle = atan2(dir.y,dir.x);
pitch = asin(-dir.z);
if ( waterlevel > 0 )
{
int numpt = Random[ExploS](10,15);
if ( bAMBUSH ) numpt /= 3;
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (dir*3+(FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1))).unit()*FRandom[ExploS](1,4);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.alpha *= 0.6;
s.scale *= FRandom[ExploS](0.9,2.0);
s.SetShade(Color(1,1,1)*Random[ExploS](64,128));
}
Destroy();
return;
}
for ( int i=0; i<invoker.ns; i++ )
{
let s = Spawn("UTSmoke",pos);
s.vel = (FRandom[FlameGun](-0.2,0.2),FRandom[FlameGun](-0.2,0.2),FRandom[FlameGun](-0.2,0.2));
s.vel += vel*0.2;
s.scale *= 0.5;
}
for ( int i=0; i<invoker.nsp; i++ )
{
if ( Random[FlameGun](0,3) ) continue;
let s = Spawn("UTSpark",pos);
s.vel = (FRandom[FlameGun](-0.2,0.2),FRandom[FlameGun](-0.2,0.2),FRandom[FlameGun](-0.2,0.2));
s.ClearBounce();
s.gravity *= 0.1;
s.A_SetTranslation('FlamGSpark');
}
}
action void A_FireballExplo()
{
A_SetRenderStyle(1.,STYLE_Add);
A_NoGravity();
if ( !bAMBUSH )
{
A_PlaySound("flamegun/exp",CHAN_VOICE,pitch:1.2);
Spawn("UFireLight",pos);
A_Explode(GetMissileDamage(0,0),60,XF_HURTSOURCE);
UTMainHandler.DoBlast(self,60,9000);
}
A_SprayDecal("SmallRocketBlast");
Scale *= FRandom[ExploS](0.6,0.9);
Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
int numpt = Random[ExploS](10,15);
if ( bAMBUSH ) numpt /= 3;
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (dir*3+(FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1))).unit()*FRandom[ExploS](2,8);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,1.5);
s.SetShade(Color(1,1,1)*Random[ExploS](64,128));
}
numpt = Random[ExploS](6,12);
if ( bAMBUSH ) numpt /= 3;
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,6);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[ExploS](10,20);
if ( bAMBUSH ) numpt /= 3;
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1)).unit()*FRandom[ExploS](2,12);
let s = Spawn("UTChip",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](0.9,1.3);
}
}
States
{
Spawn:
FIRB ABCDEFGHIJK 1 Bright A_Spread();
Loop;
Death:
TNT1 A 0 A_FireballExplo();
FGEX ABCDEFGH 2 Bright;
Stop;
}
}
Class UFireball2 : UFireball
{
Default
{
DamageFunction 50;
Speed 5;
UFireball.SpreadFactor 0.35;
UFireball.NumSmokes 2;
UFireball.NumSparks 4;
}
action void A_FireballExplo2()
{
scale *= 2.;
A_Explode(GetMissileDamage(0,0),90,XF_HURTSOURCE);
UTMainHandler.DoBlast(self,90,12000);
Vector3 dir = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
int numpt = Random[ExploS](10,15);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (dir*3+(FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1))).unit()*FRandom[ExploS](4,9);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.scale *= FRandom[ExploS](1.9,2.5);
s.SetShade(Color(1,1,1)*Random[ExploS](32,64));
}
Vector3 HitNormal = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
if ( BlockingLine )
{
HitNormal = (-BlockingLine.delta.y,BlockingLine.delta.x,0).unit();
if ( CurSector == BlockingLine.frontsector ) HitNormal *= -1;
}
else if ( BlockingFloor )
{
// find closest 3d floor for its normal
F3DFloor ff = null;
for ( int i=0; i<BlockingFloor.Get3DFloorCount(); i++ )
{
if ( !(BlockingFloor.Get3DFloor(i).top.ZAtPoint(pos.xy) ~== floorz) ) continue;
ff = BlockingFloor.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.top.Normal;
else HitNormal = BlockingFloor.floorplane.Normal;
}
else if ( BlockingCeiling )
{
// find closest 3d floor for its normal
F3DFloor ff = null;
for ( int i=0; i<BlockingCeiling.Get3DFloorCount(); i++ )
{
if ( !(BlockingCeiling.Get3DFloor(i).bottom.ZAtPoint(pos.xy) ~== ceilingz) ) continue;
ff = BlockingCeiling.Get3DFloor(i);
break;
}
if ( ff ) HitNormal = -ff.bottom.Normal;
else HitNormal = BlockingCeiling.ceilingplane.Normal;
}
for ( int i=0; i<12; i++ )
{
dir = (HitNormal*1.2+(FRandom[ExploS](-1,1),FRandom[ExploS](-1,1),FRandom[ExploS](-1,1))).unit();
let s = Spawn("UFireballEmber",level.Vec3Offset(pos,HitNormal*2));
s.vel = dir*s.speed*FRandom[ExploS](0.6,1.8);
s.angle = atan2(dir.y,dir.x);
s.pitch = asin(-dir.z);
s.target = target;
s.bHITOWNER = true;
}
}
States
{
Death:
TNT1 A 0 A_FireballExplo2();
Goto Super::Death;
}
}
Class UFireballEmber : UFireball
{
Default
{
DamageFunction 5;
+AMBUSH;
-NOGRAVITY;
Gravity 0.3;
Speed 8;
UFireball.SpreadFactor 0.5;
UFireball.NumSmokes 1;
UFireball.NumSparks 1;
}
States
{
Death:
TNT1 A 0
{
Scale *= 0.4;
}
Goto Super::Death;
}
}
Class FlameGun : UnrealWeapon
{
bool bCharging;
Default
{
Tag "$T_FLAMEGUN";
@ -21,7 +288,54 @@ Class FlameGun : UnrealWeapon
Weapon.AmmoType2 "FlameAmmo";
Weapon.AmmoUse2 20;
Weapon.AmmoGive 100;
UTWeapon.DropAmmo 25;
UTWeapon.DropAmmo 50;
}
action void A_FlameGunFire( bool bAlt = false )
{
Weapon weap = Weapon(invoker);
if ( !weap ) return;
if ( !weap.DepleteAmmo(weap.bAltFire,true,1) ) return;
A_PlaySound(bAlt?"flamegun/alt":"flamegun/fire",CHAN_WEAPON,Dampener.Active(self)?.2:1.);
invoker.FireEffect();
UTMainHandler.DoFlash(self,Color(32,96,255,0),1);
if ( bAlt )
{
A_QuakeEx(2,2,2,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
UTMainHandler.DoSwing(self,(FRandom[FlameGun](-0.6,-0.5),FRandom[FlameGun](-0.3,0.3)),4,-1,5,SWING_Spring,3,2.5);
}
else
{
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.1);
UTMainHandler.DoSwing(self,(FRandom[FlameGun](-0.3,-0.2),FRandom[FlameGun](-0.2,0.2)),4,-1,3,SWING_Spring,2,2);
}
if ( !Dampener.Active(self) ) A_AlertMonsters();
Vector3 x, y, z;
double a, s;
[x, y, z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10*x+3*y-z;
Actor p = Spawn(bAlt?"UFireball2":"UFireball",origin);
p.angle = angle;
p.pitch = BulletSlope();
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed;
p.target = self;
int numpt = Random[FlameGun](10,15);
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("UTViewSpark",origin);
UTViewSpark(s).ofs = (10,3,-1);
UTViewSpark(s).vvel = (FRandom[FlameGun](3,12),FRandom[FlameGun](-2,2),FRandom[FFlameGun](-2,2));
s.target = self;
s.A_SetTranslation('FlamGSpark');
}
for ( int i=0; i<8; i++ )
{
let s = Spawn("UTViewSmoke",origin);
UTViewSmoke(s).ofs = (10,3,-1);
UTViewSmoke(s).vvel = (FRandom[FlameGun](0,1.2),FRandom[FlameGun](-.3,.3),FRandom[FlameGun](-.3,.3));
s.target = self;
s.scale *= 1.6;
s.alpha *= 0.5;
}
}
States
{
@ -30,5 +344,79 @@ Class FlameGun : UnrealWeapon
Stop;
FGNP B -1;
Stop;
Select:
FGNS A 1 A_Raise(int.max);
Wait;
Ready:
FGNS ABCDEFGHIJ 2 A_WeaponReady(WRF_NOFIRE);
Goto Idle;
Dummy:
TNT1 A 1
{
A_CheckReload();
A_WeaponReady();
}
Wait;
Idle:
FGNI A 0 A_Overlay(-9999,"Dummy");
FGNI ABCDEFG 12;
FGNI A 0 A_Jump(40,"Twiddle");
Goto Idle+1;
Twiddle:
#### # 2 A_PlaySound("flamegun/idle",CHAN_6,Dampener.Active(self)?.1:1.);
FGNT ABCDEFGHIJKLM 3;
Goto Idle+1;
Fire:
#### # 1 A_Overlay(-9999,"Null");
FGNF A 2
{
A_PlaySound("flamegun/start",CHAN_6,Dampener.Active(self)?.1:1.);
if ( !Dampener.Active(self) ) A_AlertMonsters();
}
Hold:
FGNF B 1 A_FlameGunFire();
FGNF CDEF 1;
FGNF G 0
{
if ( invoker.CheckAmmo(0,false,true) )
A_Refire("Refire");
}
FGNF G 0 A_ClearRefire();
FGNF GHIJ 2;
FGNT A 0 A_PlaySound("flamegun/end",CHAN_6,Dampener.Active(self)?.1:1.);
FGNT ABCDEFGHIJKLM 2;
Goto Idle;
Refire:
FGNF G 2 A_PlaySound("flamegun/start",CHAN_6,Dampener.Active(self)?.1:1.);
Goto Hold;
AltFire:
#### # 1 A_Overlay(-9999,"Null");
FGNF A 1
{
A_PlaySound("flamegun/charge",CHAN_WEAPON,Dampener.Active(self)?.1:1.);
if ( !Dampener.Active(self) ) A_AlertMonsters();
}
FGNF A 1
{
invoker.special1++;
A_WeaponOffset(FRandom[FlameGun](-.1,.1)*invoker.special1,32+FRandom[FlameGun](-.1,.1)*invoker.special1);
return A_JumpIf(invoker.special1>40,"AltRelease");
}
Wait;
AltRelease:
FGNF B 2
{
invoker.special1 = 0;
A_WeaponOffset(0,32);
A_FlameGunFire(true);
}
FGNF CDEFGHIJ 2;
FGNT ABCDEFGHIJKLM 2;
Goto Idle;
Deselect:
FGND A 1 A_Overlay(-9999,"Null");
FGND BCDEFGHIJ 1;
FGND J 1 A_Lower(int.max);
Wait;
}
}

View file

@ -29,6 +29,8 @@ Class UNapalm : Actor
Class UFlamethrower : UnrealWeapon
{
bool bCharging;
Default
{
Tag "$T_FLAMETHROWER";

View file

@ -264,7 +264,9 @@ Class UPlayer : UTPlayer
if ( (player.ReadyWeapon is 'Eightball')
|| ((player.ReadyWeapon is 'DispersionPistol') && DispersionPistol(player.ReadyWeapon).bCharging)
|| ((player.ReadyWeapon is 'UBioRifle') && UBioRifle(player.ReadyWeapon).bCharging)
|| (player.ReadyWeapon is 'Razorjack')|| (player.ReadyWeapon is 'Stunner') )
|| ((player.ReadyWeapon is 'FlameGun') && FlameGun(player.ReadyWeapon).bCharging)
|| (player.ReadyWeapon is 'Razorjack') || (player.ReadyWeapon is 'Stunner')
|| ((player.ReadyWeapon is 'UFlamethrower') && UFlamethrower(player.ReadyWeapon).bCharging) )
{
if ( !InStateSequence(CurState,FindState("MissileRepStill")) )
SetStateLabel("MissileRepStill");