Completed Chainsaw. Added some extra visual effects. Made various particle effects actor-based.

Removed key replacement classes, turns out this breaks maps.
This commit is contained in:
Marisa the Magician 2018-05-26 20:44:31 +02:00
commit eb6c8e1c35
190 changed files with 831 additions and 166 deletions

View file

@ -37,6 +37,47 @@ Class BioAmmo : Ammo
}
}
Class BioSpark : Actor
{
Default
{
RenderStyle "Add";
Radius 2;
Height 0;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+ROLLSPRITE;
+ROLLCENTER;
+NOTELEPORT;
BounceType "Doom";
BounceFactor 0.5;
WallBounceFactor 0.5;
Gravity 0.2;
Scale 0.04;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
frame = Random[GES](0,4);
roll = FRandom[GES](0,360);
}
States
{
Spawn:
GBLB # 1 Bright A_FadeOut(FRandom[GES](0.005,0.015));
Wait;
Death:
GBLB # 1 Bright A_FadeOut(FRandom[GES](0.04,0.06));
Wait;
Dummy:
GBLB ABCDE -1;
Stop;
}
}
Class BioHitbox : Actor
{
Default
@ -174,7 +215,8 @@ Class BioGel : Actor
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[GES](-1,1),FRandom[GES](-1,1),FRandom[GES](-1,1)).unit()*FRandom[GES](1,3);
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](1.2,2.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
let s = Spawn("BioSpark",pos);
s.vel = pvel;
}
}
if ( deadtimer <= -1 ) return;
@ -253,7 +295,8 @@ Class BioGel : Actor
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (normal+(FRandom[GES](-.8,.8),FRandom[GES](-.8,.8),FRandom[GES](-.8,.8))).unit()*FRandom[GES](3,6);
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](1.2,3.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
let s = Spawn("BioSpark",pos);
s.vel = pvel;
}
}
action void A_DropDrip()
@ -283,7 +326,8 @@ Class BioGel : Actor
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[GES](-1,1),FRandom[GES](-1,1),FRandom[GES](-1,1)).unit()*FRandom[GES](3,12);
A_SpawnParticle("40FF30",SPF_FULLBRIGHT,Random[GES](30,60),FRandom[GES](2.4,6.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,-0.2,3.0);
let s = Spawn("BioSpark",pos);
s.vel = pvel;
}
Scale *= 0.5;
}

View file

@ -1,28 +1,133 @@
Class SawImpact : Actor
{
Default
{
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
A_SprayDecal("WallCrack",20);
int numpt = Random[Chainsaw](5,10);
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (-x+(FRandom[Chainsaw](-.8,.8),FRandom[Chainsaw](-.8,.8),FRandom[Chainsaw](-.8,.8))).unit()*FRandom[Chainsaw](0.1,1.2);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Chainsaw](128,192));
}
numpt = Random[Chainsaw](4,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)).unit()*FRandom[Chainsaw](2,8);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[Chainsaw](4,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1),FRandom[Chainsaw](-1,1)).unit()*FRandom[Chainsaw](2,8);
let s = Spawn("UTChip",pos);
s.vel = pvel;
}
Destroy();
}
}
Class UTChainsaw : UTWeapon replaces Chainsaw
{
double sawcnt;
action void A_SawHit()
{
A_QuakeEx(3,3,3,2,0,1,"",QF_RELATIVE,rollIntensity:0.15);
A_QuakeEx(2,2,2,2,0,1,"",QF_RELATIVE,rollIntensity:0.15);
invoker.sawcnt += 1./TICRATE;
if ( invoker.sawcnt < 0.15 ) return;
invoker.sawcnt = 0;
invoker.FireEffect();
A_AlertMonsters();
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-4.0*z;
FLineTraceData d;
LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
d.HitActor.DamageMobj(invoker,self,20,'slashed');
d.HitActor.vel -= x*(500/d.HitActor.mass);
vel += x*(100/mass);
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(5,5,5,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
}
else
{
d.HitActor.TraceBleed(20,invoker);
d.HitActor.SpawnBlood(d.HitLocation,atan2(-d.HitDir.y,-d.HitDir.x),20);
}
}
else if ( d.HitType != TRACE_HitNone )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4);
}
}
action void A_SawSwipe()
{
A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
invoker.FireEffect();
A_AlertMonsters();
Vector3 x, y, z;
[x, y, z] = Matrix4.GetAxes(pitch,angle,roll);
Vector3 origin = (pos.x,pos.y,player.viewz)+10.0*x-2.0*z;
FLineTraceData d;
LineTrace(angle,90,BulletSlope(),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType == TRACE_HitActor )
{
d.HitActor.DamageMobj(invoker,self,110,'Decapitated');
d.HitActor.vel = -y*(1200/d.HitActor.mass);
vel += x*(100/mass);
if ( d.HitActor.player ) d.HitActor.A_QuakeEx(5,5,5,6,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
if ( d.HitActor.bNOBLOOD )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
}
else
{
d.HitActor.TraceBleed(110,invoker);
d.HitActor.SpawnBlood(d.HitLocation,atan2(-d.HitDir.y,-d.HitDir.x),110);
}
}
else if ( d.HitType != TRACE_HitNone )
{
let p = Spawn("SawImpact",d.HitLocation-d.HitDir*4);
p.angle = atan2(d.HitDir.y,d.HitDir.x);
p.pitch = asin(-d.HitDir.z);
if ( d.HitType == TRACE_HitWall ) d.HitLine.RemoteActivate(self,d.LineSide,SPAC_Impact,d.HitLocation-d.HitDir*4);
}
}
Default
{
Tag "Chainsaw";
Obituary "%k ripped into %o with a blood soaked Chainsaw.";
Inventory.PickupMessage "It's been twenty five years since I've seen one of these."; // was five years in UT99
Weapon.UpSound "chainsaw/select";
Weapon.SlotNumber 1;
Weapon.SelectionOrder 9;
+WEAPON.MELEEWEAPON;
+FORCEPAIN;
}
States
{
@ -35,18 +140,27 @@ Class UTChainsaw : UTWeapon replaces Chainsaw
CSWS A 1 A_Raise(int.max);
Wait;
Ready:
CSWS ABCDEFGHIJLMNO 1 A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
CSWS ABCDEFGHIJLMNO 1
{
A_AlertMonsters();
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
}
Idle:
CSWI A 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
CSWI ABCDEFGHIJ 1
{
A_AlertMonsters();
A_WeaponReady();
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
}
Goto Idle+1;
Fire:
CSWJ A 1 A_PlaySound("chainsaw/fire",CHAN_6,looping:true);
CSWJ BCDEF 1 A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
CSWJ BCDEF 1
{
A_AlertMonsters();
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
}
Hold:
CSWJ G 1 A_SawHit();
CSWJ H 0 A_Refire(1);
@ -87,13 +201,25 @@ Class UTChainsaw : UTWeapon replaces Chainsaw
CSWJ S 1 A_SawHit();
CSWJ G 0 A_Refire("Hold");
Release:
CSWJ FEDCBA 1 A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
CSWJ FEDCBA 1
{
A_AlertMonsters();
A_QuakeEx(1,1,1,2,0,1,"",QF_RELATIVE,rollIntensity:0.1);
}
Goto Idle;
AltFire:
CSWA A 0 A_PlaySound("chainsaw/fire",CHAN_6);
CSWA ABCDEFG 2 A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
CSWA ABCDEFG 2
{
A_AlertMonsters();
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
}
CSWA H 2 A_SawSwipe();
CSWA IJK 2 A_QuakeEx(3,3,3,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
CSWA IJK 2
{
A_AlertMonsters();
A_QuakeEx(2,2,2,3,0,1,"",QF_RELATIVE,rollIntensity:0.15);
}
CSWA K 0 A_PlaySound("chainsaw/idle",CHAN_6,looping:true);
Goto Ready;
Deselect:

View file

@ -194,7 +194,19 @@ Class FlakChunk : Actor
if ( frame < 11 ) frame++;
}
lifetime += lifespeed;
if ( (waterlevel <= 0) && (frame < 10) ) A_SpawnParticle("AAAAAA",0,35,2.0,velx:FRandom[Flak](-0.1,0.1),vely:FRandom[Flak](-0.1,0.1),velz:FRandom[Flak](-0.1,0.1),accelz:0.02,startalphaf:scale.x/0.5,sizestep:0.2);
if ( (waterlevel <= 0) && (frame < 10) )
{
let s = Spawn("UTSmoke",pos);
s.vel = (FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1));
s.alpha = scale.x/0.5;
s.SetShade("AAAAAA");
}
else if ( waterlevel > 0 )
{
let s = Spawn("UTBubble",pos);
s.vel = (FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1),FRandom[Flak](-0.1,0.1));
s.scale *= scale.x*0.5;
}
if ( trail ) trail.alpha = max(0,11-frame)/11.;
if ( InStateSequence(CurState,FindState("Death")) ) return;
A_SetRoll(roll+rollvel,SPF_INTERPOLATE);
@ -205,11 +217,15 @@ Class FlakChunk : Actor
{
invoker.hasbounced = true;
A_SprayDecal("WallCrack",-8);
int numpt = Random[Flak](8,12);
for ( int i=0; i<numpt; i++ )
int numpt = Random[Flak](3,6);
if ( frame < 10 )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,4);
A_SpawnParticle("FFA000",SPF_FULLBRIGHT,Random[Flak](10,20),FRandom[Flak](1.2,3.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,3.0,-1,-0.25);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,4);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
}
A_Gravity();
invoker.rollvel = FRandom[Flak](50,100)*RandomPick[Flak](-1,1)*(vel.length()/speed);
@ -301,7 +317,11 @@ Class SlugSmoke : Actor
Super.Tick();
if ( globalfreeze || level.frozen ) return;
lifetime += lifespeed;
if ( waterlevel <= 0 ) A_SpawnParticle("AAAAAA",0,50,16.0,velx:FRandom[Flak](-0.5,0.5),vely:FRandom[Flak](-0.5,0.5),velz:FRandom[Flak](-0.5,0.5),accelz:0.05,startalphaf:scale.x,sizestep:1.0);
let s = Spawn("UTSmoke",pos);
s.vel = (FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5));
s.vel.z += 2.;
s.alpha = scale.x;
s.SetShade("AAAAAA");
scale.x = max(0,1-lifetime);
if ( scale.x <= 0 ) Destroy();
}
@ -399,11 +419,19 @@ Class FlakSlug : Actor
p.vel = (cos(p.angle)*cos(p.pitch),sin(p.angle)*cos(p.pitch),-sin(p.pitch))*p.speed*FRandom[Flak](0.5,1.5);
p.target = target;
}
int numpt = Random[Flak](40,80);
int numpt = Random[Flak](10,20);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,4);
A_SpawnParticle("FFA000",SPF_FULLBRIGHT,Random[Flak](20,40),FRandom[Flak](4.8,7.2),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,3.0,-1,-0.25);
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,8);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[Flak](20,40);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Flak](-1,1),FRandom[Flak](-1,1),FRandom[Flak](-1,1)).unit()*FRandom[Flak](2,8);
let s = Spawn("UTChip",pos);
s.vel = pvel;
}
}
States
@ -411,9 +439,13 @@ Class FlakSlug : Actor
Spawn:
FSLG A 1
{
if ( waterlevel > 0 ) return;
for ( int i=0; i<6; i++ )
A_SpawnParticle("AAAAAA",0,50,12.0,velx:FRandom[Flak](-0.5,0.5),vely:FRandom[Flak](-0.5,0.5),velz:FRandom[Flak](-0.5,0.5),accelz:0.02,startalphaf:0.5,sizestep:1.0);
{
let s = Spawn("UTSmoke",pos);
s.vel = (FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5),FRandom[Flak](-0.5,0.5));
s.alpha = 0.5;
s.SetShade("AAAAAA");
}
}
Wait;
Death:
@ -493,8 +525,10 @@ Class FlakCannon : UTWeapon
int numpt = Random[Flak](20,30);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8))).unit()*FRandom[Flak](2,4);
A_SpawnParticle("FFA000",SPF_FULLBRIGHT,Random[Flak](10,20),FRandom[Flak](2.4,3.6),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,-0.1,3.0,-1,-0.25);
Vector3 pvel = (x+(FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8))).unit()*FRandom[Flak](8,32);
let s = Spawn("UTSpark",origin);
s.vel = pvel;
s.alpha *= 0.2;
}
}
action void A_FireSlug()
@ -523,8 +557,10 @@ Class FlakCannon : UTWeapon
int numpt = Random[Flak](10,15);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8))).unit()*FRandom[Flak](2,4);
A_SpawnParticle("FFA000",SPF_FULLBRIGHT,Random[Flak](10,20),FRandom[Flak](2.4,3.6),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,-0.1,3.0,-1,-0.25);
Vector3 pvel = (x+(FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8),FRandom[Flak](-.8,.8))).unit()*FRandom[Flak](8,32);
let s = Spawn("UTSpark",origin);
s.vel = pvel;
s.alpha *= 0.2;
}
}

View file

@ -16,14 +16,24 @@ Class HammerImpact : Actor
Vector3 x = (cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Impact](-.8,.8),FRandom[Impact](-.8,.8),FRandom[Impact](-.8,.8))).unit()*FRandom[Impact](1,3);
A_SpawnParticle(Color(1,1,1)*Random[Impact](128,192),0,Random[Impact](30,60),FRandom[Impact](2,8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0.03,0.5,-1,0.5);
Vector3 pvel = (-x+(FRandom[Impact](-.8,.8),FRandom[Impact](-.8,.8),FRandom[Impact](-.8,.8))).unit()*FRandom[Impact](0.1,1.2);
let s = Spawn("UTSmoke",pos);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Impact](128,192));
}
numpt = Random[Impact](8,12);
numpt = Random[Impact](4,12);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Impact](-1,1),FRandom[Impact](-1,1),FRandom[Impact](-1,1)).unit()*FRandom[Impact](2,4);
A_SpawnParticle("FFA000",SPF_FULLBRIGHT,Random[Impact](10,20),FRandom[Impact](1.2,3.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,3.0,-1,-0.25);
Vector3 pvel = (FRandom[Impact](-1,1),FRandom[Impact](-1,1),FRandom[Impact](-1,1)).unit()*FRandom[Impact](2,8);
let s = Spawn("UTSpark",pos);
s.vel = pvel;
}
numpt = Random[Impact](4,16);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[Impact](-1,1),FRandom[Impact](-1,1),FRandom[Impact](-1,1)).unit()*FRandom[Impact](2,8);
let s = Spawn("UTChip",pos);
s.vel = pvel;
}
Destroy();
}
@ -92,17 +102,21 @@ Class ImpactHammer : UTWeapon replaces Fist
}
A_QuakeEx(realcharge*6,realcharge*6,realcharge*6,16,0,1,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:realcharge*0.2);
realcharge = max(1.0,realcharge);
int numpt = Random[Impact](20,40);
int numpt = Random[Impact](5,10);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Impact](-.4,.4),FRandom[Impact](-.4,.4),FRandom[Impact](-.4,.4))).unit()*FRandom[Impact](1,3)*realcharge;
A_SpawnParticle(Color(1,1,1)*Random[Impact](128,192),0,Random[Impact](30,60),FRandom[Impact](2,8),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0.03,0.5,-1,0.5);
let s = Spawn("UTSmoke",origin);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Impact](128,192));
}
numpt = Random[Impact](10,20);
numpt = Random[Impact](4,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5))).unit()*FRandom[Impact](2,4)*realcharge;
A_SpawnParticle(Color(1,1,1)*Random[Impact](16,64),0,Random[Impact](5,10),FRandom[Impact](0.3,0.8),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,-0.2,2.,-0.1);
Vector3 pvel = (x+(FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5))).unit()*FRandom[Impact](2,16)*realcharge;
let s = Spawn("UTChip",origin);
s.vel = pvel;
s.scale *= 0.4;
}
}
action void A_FireAltBlast()
@ -146,17 +160,21 @@ Class ImpactHammer : UTWeapon replaces Fist
if ( m.bSEEKERMISSILE ) m.tracer = m.target;
m.target = self;
}
int numpt = Random[Impact](20,40);
int numpt = Random[Impact](5,10);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Impact](-.4,.4),FRandom[Impact](-.4,.4),FRandom[Impact](-.4,.4))).unit()*FRandom[Impact](1,3);
A_SpawnParticle(Color(1,1,1)*Random[Impact](128,192),0,Random[Impact](30,60),FRandom[Impact](2,8),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0.03,0.5,-1,0.5);
let s = Spawn("UTSmoke",origin);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Impact](128,192));
}
numpt = Random[Impact](10,20);
numpt = Random[Impact](4,8);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5))).unit()*FRandom[Impact](2,4);
A_SpawnParticle(Color(1,1,1)*Random[Impact](16,64),0,Random[Impact](5,10),FRandom[Impact](0.3,0.8),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,-0.2,2.,-0.1);
Vector3 pvel = (x+(FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5),FRandom[Impact](-.5,.5))).unit()*FRandom[Impact](2,16);
let s = Spawn("UTChip",origin);
s.vel = pvel;
s.scale *= 0.4;
}
}
action void A_ImpactRefire( statelabel flash = null )
@ -261,6 +279,7 @@ Class ImpactHammer : UTWeapon replaces Fist
IMPF ABCDEFGHIJKLMNOP 1;
Goto Idle;
Deselect:
IMPD A 0 A_StopSound(CHAN_WEAPON);
IMPD ABCDE 3;
IMPD E 1 A_Lower(int.max);
Wait;

View file

@ -44,7 +44,7 @@ Class DamageAmpLight : DynamicLight
Destroy();
return;
}
SetOrigin(target.pos+(0,0,target.height*0.5),true);
SetOrigin(target.pos,true);
args[LIGHT_INTENSITY] = Random[ASMD](10,12)*8;
bDORMANT = Powerup(master).isBlinking();
}

View file

@ -537,6 +537,7 @@ Class PulseGun : UTWeapon
PGR2 ABCDEFGHIJKLMNOPQRSTUVWX 1;
Goto Idle;
Deselect:
PGNS W 0 A_StopSound(CHAN_WEAPON);
PGNS WVUTSRQPONMLKJIHGFEDCBA 1;
PGNS A 1 A_Lower(int.max);
Wait;

View file

@ -178,6 +178,70 @@ Class SuperShockBlastRing : ShockBeamRing
}
}
Class ShockSpark : Actor
{
Default
{
RenderStyle "Add";
Radius 2;
Height 0;
+NOBLOCKMAP;
+NOGRAVITY;
+MISSILE;
+FORCEXYBILLBOARD;
+THRUACTORS;
+ROLLSPRITE;
+ROLLCENTER;
+NOTELEPORT;
BounceType "Doom";
BounceFactor 1.0;
WallBounceFactor 1.0;
Scale 0.1;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( !bAMBUSH )
{
roll = FRandom[ASMD](0,360);
let s = Spawn(GetClass(),pos);
s.bAMBUSH = true;
s.vel = vel;
s.scale = scale;
s.roll = roll;
}
}
States
{
Spawn:
ASMK A 1 Bright
{
A_FadeOut(FRandom[ASMD](0.0,0.1));
vel *= 0.98;
}
Wait;
}
}
Class ShockSparkTrail : ShockSpark
{
Default
{
+AMBUSH;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
roll = FRandom[ASMD](0,360);
}
States
{
Spawn:
ASMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.2));
Wait;
}
}
Class ShockBeam : Actor
{
ShockBeamTracer t;
@ -220,10 +284,9 @@ Class ShockBeam : Actor
Spawn("ShockBeamLight",Vec3Offset(tracedir.x*i,tracedir.y*i,tracedir.z*i));
for ( int i=0; i<t.Results.Distance; i+=2 )
{
Vector3 pofs = Level.Vec3Diff(pos,pos+tracedir*FRandom[ASMD](0,2)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5)));
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,30,2,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:1,sizestep:-.1);
A_SpawnParticle("5020FF",SPF_FULLBRIGHT,45,4,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:.5,sizestep:-.1);
A_SpawnParticle("402080",SPF_FULLBRIGHT,60,8,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:.25,sizestep:-.1);
Vector3 pofs = tracedir*FRandom[ASMD](0,2)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5));
let s = Spawn("ShockSparkTrail",Vec3Offset(tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z));
s.vel = (FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03));
}
if ( totaldist >= 10000.0 )
{
@ -265,10 +328,9 @@ Class ShockBeam : Actor
int numpt = Random[ASMD](200,300);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](2,8);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[ASMD](20,80),FRandom[ASMD](1.6,4.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.05);
A_SpawnParticle("5020FF",SPF_FULLBRIGHT,Random[ASMD](40,120),FRandom[ASMD](4.8,11.2),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.05);
A_SpawnParticle("402080",SPF_FULLBRIGHT,Random[ASMD](50,140),FRandom[ASMD](5.6,12.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.05);
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](1,32);
let s = Spawn("ShockSpark",b.pos);
s.vel = pvel;
}
}
else
@ -314,9 +376,8 @@ Class ShockBeam : Actor
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[ASMD](20,40),FRandom[ASMD](1.6,2.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.1);
A_SpawnParticle("5020FF",SPF_FULLBRIGHT,Random[ASMD](40,60),FRandom[ASMD](4.8,5.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.1);
A_SpawnParticle("402080",SPF_FULLBRIGHT,Random[ASMD](50,70),FRandom[ASMD](5.6,6.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.1);
let s = Spawn("ShockSpark",pos);
s.vel = pvel;
}
}
States
@ -332,6 +393,70 @@ Class ShockBeam : Actor
}
}
Class SuperShockSpark : Actor
{
Default
{
RenderStyle "Add";
Radius 2;
Height 0;
+NOBLOCKMAP;
+NOGRAVITY;
+MISSILE;
+FORCEXYBILLBOARD;
+THRUACTORS;
+ROLLSPRITE;
+ROLLCENTER;
+NOTELEPORT;
BounceType "Doom";
BounceFactor 1.0;
WallBounceFactor 1.0;
Scale 0.1;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( !bAMBUSH )
{
roll = FRandom[ASMD](0,360);
let s = Spawn(GetClass(),pos);
s.bAMBUSH = true;
s.vel = vel;
s.scale = scale;
s.roll = roll;
}
}
States
{
Spawn:
SSMK A 1 Bright
{
A_FadeOut(FRandom[ASMD](0.0,0.1));
vel *= 0.98;
}
Wait;
}
}
Class SuperShockSparkTrail : ShockSpark
{
Default
{
+AMBUSH;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
roll = FRandom[ASMD](0,360);
}
States
{
Spawn:
SSMK A 1 Bright A_FadeOut(FRandom[ASMD](0.0,0.2));
Wait;
}
}
Class SuperShockBeam : Actor
{
ShockBeamTracer t;
@ -375,10 +500,9 @@ Class SuperShockBeam : Actor
Spawn("SuperShockBeamLight",Vec3Offset(tracedir.x*i,tracedir.y*i,tracedir.z*i));
for ( int i=0; i<t.Results.Distance; i++ )
{
Vector3 pofs = Level.Vec3Diff(pos,pos+tracedir*FRandom[ASMD](0,1)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5)));
A_SpawnParticle("FFF080",SPF_FULLBRIGHT,30,2,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:1,sizestep:-.1);
A_SpawnParticle("FF5020",SPF_FULLBRIGHT,45,4,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:.5,sizestep:-.1);
A_SpawnParticle("804020",SPF_FULLBRIGHT,60,8,0,tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z,FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),startalphaf:.25,sizestep:-.1);
Vector3 pofs = tracedir*FRandom[ASMD](0,2)+(FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5),FRandom[ASMD](-.5,.5));
let s = Spawn("SuperShockSparkTrail",Vec3Offset(tracedir.x*i+pofs.x,tracedir.y*i+pofs.y,tracedir.z*i+pofs.z));
s.vel = (FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03),FRandom[ASMD](-.03,.03));
}
if ( totaldist >= 10000.0 )
{
@ -418,13 +542,12 @@ Class SuperShockBeam : Actor
r.pitch = asin(-t.Results.HitVector.z);
A_PlaySound("shock/blast",CHAN_WEAPON,attenuation:0.5);
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
int numpt = Random[ASMD](400,600);
int numpt = Random[ASMD](200,300);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](2,8);
A_SpawnParticle("FFF080",SPF_FULLBRIGHT,Random[ASMD](20,80),FRandom[ASMD](1.6,9.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.05);
A_SpawnParticle("FF5020",SPF_FULLBRIGHT,Random[ASMD](40,120),FRandom[ASMD](4.8,22.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.05);
A_SpawnParticle("804020",SPF_FULLBRIGHT,Random[ASMD](50,140),FRandom[ASMD](5.6,25.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.05);
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](2,64);
let s = Spawn("SuperShockSpark",b.pos);
s.vel = pvel;
}
}
else
@ -468,13 +591,12 @@ Class SuperShockBeam : Actor
A_PlaySound("shock/hit",CHAN_VOICE,attenuation:0.5);
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
A_AlertMonsters();
int numpt = Random[ASMD](40,100);
int numpt = Random[ASMD](20,50);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
A_SpawnParticle("FFF080",SPF_FULLBRIGHT,Random[ASMD](20,40),FRandom[ASMD](1.6,4.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.1);
A_SpawnParticle("FF5020",SPF_FULLBRIGHT,Random[ASMD](40,60),FRandom[ASMD](4.8,11.2),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.1);
A_SpawnParticle("804020",SPF_FULLBRIGHT,Random[ASMD](50,70),FRandom[ASMD](5.6,12.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.1);
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,24);
let s = Spawn("SuperShockSpark",pos);
s.vel = pvel;
}
}
States
@ -683,9 +805,8 @@ Class ShockBall : Actor
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
A_SpawnParticle("FFFFFF",SPF_FULLBRIGHT,Random[ASMD](20,40),FRandom[ASMD](1.6,2.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.1);
A_SpawnParticle("5020FF",SPF_FULLBRIGHT,Random[ASMD](40,60),FRandom[ASMD](4.8,5.6),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.1);
A_SpawnParticle("402080",SPF_FULLBRIGHT,Random[ASMD](50,70),FRandom[ASMD](5.6,6.4),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.1);
let s = Spawn("ShockSpark",pos);
s.vel = pvel;
}
}
Default
@ -742,13 +863,12 @@ Class SuperShockBall : Actor
A_PlaySound("sshock/blast",CHAN_6,attenuation:0.5);
A_QuakeEx(8,8,8,30,0,300,"",QF_RELATIVE|QF_SCALEDOWN,rollIntensity:0.25);
A_AlertMonsters();
int numpt = Random[ASMD](100,200);
int numpt = Random[ASMD](50,100);
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,12);
A_SpawnParticle("FFF080",SPF_FULLBRIGHT,Random[ASMD](20,40),FRandom[ASMD](1.6,4.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,1,-1,-.1);
A_SpawnParticle("FF5020",SPF_FULLBRIGHT,Random[ASMD](40,60),FRandom[ASMD](4.8,11.2),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.5,-1,-.1);
A_SpawnParticle("804020",SPF_FULLBRIGHT,Random[ASMD](50,70),FRandom[ASMD](5.6,12.8),0,0,0,0,pvel.x,pvel.y,pvel.z,0,0,0,.25,-1,-.1);
Vector3 pvel = (FRandom[ASMD](-1,1),FRandom[ASMD](-1,1),FRandom[ASMD](-1,1)).unit()*FRandom[ASMD](3,24);
let s = Spawn("SuperShockSpark",pos);
s.vel = pvel;
}
}
Default

View file

@ -312,87 +312,233 @@ Class UTItemFog : Actor replaces ItemFog
}
}
Class UTRedSkull : RedSkull replaces RedSkull
Class UTSpark : Actor
{
Default
{
Tag "Red Skull";
Inventory.PickupMessage "You got the Red Skull.";
RenderStyle "Add";
Radius 2;
Height 0;
+NOBLOCKMAP;
+FORCEXYBILLBOARD;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
BounceType "Doom";
BounceFactor 0.4;
Gravity 0.5;
Scale 0.05;
}
override void Tick()
{
Super.Tick();
if ( waterlevel > 0 )
{
let b = Spawn("UTBubble",pos);
b.vel = vel;
b.scale *= 0.3;
Destroy();
}
}
States
{
Spawn:
USKL A -1;
SPRK A 1 Bright A_FadeOut(0.01);
Wait;
Death:
SPRK A 1 Bright A_FadeOut(0.05);
Wait;
}
}
Class UTChip : Actor
{
int deadtimer;
double rollvel, anglevel, pitchvel;
Default
{
Radius 2;
Height 0;
+NOBLOCKMAP;
+MISSILE;
+MOVEWITHSECTOR;
+THRUACTORS;
+NOTELEPORT;
BounceType "Doom";
BounceFactor 0.3;
Gravity 0.7;
Scale 0.2;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
deadtimer = 0;
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
frame = Random[Junk](0,3);
scale *= Frandom[Junk](0.8,1.2);
}
override void Tick()
{
Super.Tick();
if ( level.frozen || globalfreeze ) return;
if ( InStateSequence(CurState,ResolveState("Death")) )
{
deadtimer++;
if ( deadtimer > 300 ) A_FadeOut(0.05);
return;
}
}
States
{
Spawn:
CHIP # 1
{
A_SetAngle(angle+anglevel,SPF_INTERPOLATE);
A_SetPitch(pitch+pitchvel,SPF_INTERPOLATE);
A_SetRoll(roll+rollvel,SPF_INTERPOLATE);
}
Loop;
Bounce:
CHIP # 0
{
anglevel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
pitchvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
rollvel = FRandom[Junk](10,30)*RandomPick[Junk](-1,1);
}
Goto Spawn;
Death:
CHIP # -1;
Stop;
Dummy:
CHIP ABCD -1;
Stop;
}
}
Class UTGoldSkull : YellowSkull replaces YellowSkull
Class UTBubble : Actor
{
Default
{
Tag "Gold Skull";
Inventory.PickupMessage "You got the Gold Skull.";
RenderStyle "Add";
Radius 2;
Height 0;
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+NOTELEPORT;
Scale 0.05;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
double ang, pt;
scale *= FRandom[Puff](0.5,1.5);
ang = FRandom[Puff](0,360);
pt = FRandom[Puff](-90,90);
vel += (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[Puff](0.2,0.8);
if ( waterlevel <= 0 ) Destroy();
SetState(ResolveState("Spawn")+Random[Puff](0,2));
}
override void Tick()
{
Super.Tick();
if ( level.frozen || globalfreeze ) return;
vel *= 0.96;
vel.z += 0.05;
if ( (waterlevel <= 0) || !Random[Puff](0,100) ) Destroy();
}
States
{
Spawn:
USKL B -1;
BUBL ABC -1;
Stop;
}
}
Class UTBlueSkull : BlueSkull replaces BlueSkull
Class UTSmoke : Actor
{
Default
{
Tag "Blue Skull";
Inventory.PickupMessage "You got the Blue Skull.";
RenderStyle "Shaded";
StencilColor "FFFFFF";
Radius 2;
Height 0;
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+THRUACTORS;
+NOTELEPORT;
BounceType "Hexen";
BounceFactor 1.0;
WallBounceFactor 1.0;
Scale 0.5;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
double ang, pt;
scale *= FRandom[Puff](0.5,1.5);
alpha *= FRandom[Puff](0.5,1.5);
ang = FRandom[Puff](0,360);
pt = FRandom[Puff](-90,90);
vel += (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[Puff](0.2,0.8);
}
override void Tick()
{
Super.Tick();
if ( level.frozen || globalfreeze ) return;
vel *= 0.96;
vel.z += 0.01;
A_FadeOut(1/32.);
if ( waterlevel > 0 )
{
let b = Spawn("UTBubble",pos);
b.vel = vel;
Destroy();
}
}
States
{
Spawn:
USKL C -1;
TNT1 A 0 NoDelay A_Jump(255,"US1","US2","US3","US4","US5","US6","US7","US8","US9","US10");
Stop;
}
}
Class UTRedKey : RedCard replaces RedCard
{
Default
{
Tag "Red Key";
Inventory.PickupMessage "You got the Red Key.";
}
States
{
Spawn:
UKEY A -1;
US1:
US1_ ABCDEFGHIJKLMNOP 2;
Stop;
}
}
Class UTGoldKey : YellowCard replaces YellowCard
{
Default
{
Tag "Gold Key";
Inventory.PickupMessage "You got the Gold Key.";
}
States
{
Spawn:
UKEY B -1;
US2:
US2_ ABCDEFGHIJKLMNOP 2;
Stop;
}
}
Class UTBlueKey : BlueCard replaces BlueCard
{
Default
{
Tag "Blue Key";
Inventory.PickupMessage "You got the Blue Key.";
}
States
{
Spawn:
UKEY C -1;
US3:
US3_ ABCDEFGHIJKLMNOP 2;
Stop;
US4:
US4_ ABCDEFGHIJKLMNO 2;
Stop;
US5:
US5_ ABCDEFGHIJKLMNO 2;
Stop;
US6:
US6_ ABCDEFGHIJKLMNOP 2;
Stop;
US7:
US7_ ABCDEFGHIJKLMNOP 2;
Stop;
US8:
US8_ ABCDEFGHIJKLMNOP 2;
Stop;
US9:
US9_ ABCDEFGHIJKLMNOP 2;
Stop;
US10:
US10 ABCDEFGHIJKLMNOP 2;
Stop;
}
}
@ -435,12 +581,10 @@ Class QueuedFlash
Class UTMainHandler : StaticEventHandler
{
ui TextureID tex;
transient int lastfrag;
Array<QueuedFlash> flashes;
override void WorldLoaded( WorldEvent e )
{
lastfrag = int.min;
if ( gamestate != GS_LEVEL || e.IsSaveGame ) return;
if ( level.levelname ~== "Modder Test Map" )
{
@ -489,8 +633,6 @@ Class UTMainHandler : StaticEventHandler
StatusBar.AttachMessage(gf,0,BaseStatusBar.HUDMSGLayer_UnderHUD);
}
if ( gametic <= 0 ) StartMenu();
if ( !(StatusBar is 'UTHUD') ) return;
UTHUD(StatusBar).lastfrag = lastfrag;
}
override void RenderOverlay( RenderEvent e )
@ -501,12 +643,6 @@ Class UTMainHandler : StaticEventHandler
Screen.DrawTexture(tex,true,0,0,DTA_VirtualWidth,1024,DTA_VirtualHeight,768);
}
override void WorldThingDamaged( WorldEvent e )
{
if ( (e.Thing.Health <= 0) && e.DamageSource && (e.DamageSource != e.Thing) && e.DamageSource.player && (e.DamageSource.player == players[consoleplayer]) )
lastfrag = gametic;
}
static void DoFlash( Actor camera, Color c, int duration )
{
QueuedFlash qf = new("QueuedFlash");

View file

@ -28,7 +28,7 @@ Class UTHud : BaseStatusBar
double HScale;
Color tintcolor, bgcolor;
double opacity;
int lastfrag, lastpickup, lastslot;
int lastfrag, lastfragcnt, lastpickup, lastslot;
ViewTracer vtracer;
Actor lastseen;
int lastseentic;
@ -42,6 +42,8 @@ Class UTHud : BaseStatusBar
{
Super.Init();
SetSize(0,320,200);
lastfrag = int.min;
lastfragcnt = 0;
vtracer = new("ViewTracer");
// Set defaults
DrawColor = WhiteColor = "White";
@ -310,7 +312,7 @@ Class UTHud : BaseStatusBar
double WeaponOffset = 128*WeapScale;
let cw = CPlayer.ReadyWeapon;
let pw = CPlayer.PendingWeapon;
if ( cw )
if ( cw && (cw.SlotNumber != -1) )
{
int slot = cw.SlotNumber?(cw.SlotNumber-1):9;
CurX = BaseX+slot*WeaponOffset;
@ -320,7 +322,7 @@ Class UTHud : BaseStatusBar
CurY = BaseY;
UTDrawPlainTex(WeaponBox,0.8);
}
if ( pw && (pw != WP_NOCHANGE) )
if ( pw && (pw.SlotNumber != -1) && (pw != WP_NOCHANGE) )
{
int slot = pw.SlotNumber?(pw.SlotNumber-1):9;
CurX = BaseX+slot*WeaponOffset-64*WeapScale;
@ -333,6 +335,7 @@ Class UTHud : BaseStatusBar
{
if ( !(i is 'Weapon') ) continue;
let w = Weapon(i);
if ( w.SlotNumber == -1 ) continue;
int slot = w.SlotNumber?(w.SlotNumber-1):9;
if ( !wslots[slot] ) wslots[slot] = w;
else if ( (wslots[slot] != cw) && ((wslots[slot] != pw)
@ -344,14 +347,10 @@ Class UTHud : BaseStatusBar
CurX = BaseX+i*WeaponOffset;
CurY = BaseY;
if ( !wslots[i] )
{
UTDrawTintedTex(Slots[i],1.6,tintcolor/2);
}
else if ( wslots[i] != cw )
{
if ( !UTDrawWeaponIcon(wslots[i],false,wslots[i]==pw,0.8) )
UTDrawTintedTex(Slots[i],1.6,tintcolor/2);
}
}
for ( int i=0; i<10; i++ )
{
@ -471,6 +470,16 @@ Class UTHud : BaseStatusBar
override void Tick()
{
Super.Tick();
if ( deathmatch||teamplay )
{
if ( CPlayer.fragcount != lastfragcnt ) lastfrag = gametic;
lastfragcnt = CPlayer.fragcount;
}
else
{
if ( CPlayer.killcount != lastfragcnt ) lastfrag = gametic;
lastfragcnt = CPlayer.killcount;
}
vtracer.ignore = CPlayer.mo;
vtracer.trace(CPlayer.mo.Vec2OffsetZ(0,0,CPlayer.viewz),CPlayer.mo.CurSector,(cos(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),sin(CPlayer.mo.angle)*cos(CPlayer.mo.pitch),-sin(CPlayer.mo.pitch)),1000,0);
if ( vtracer.Results.HitType != TRACE_HitActor ) return;

View file

@ -192,6 +192,48 @@ Class WarheadLight : DynamicLight
}
}
Class WarheadTrail : Actor
{
Default
{
RenderStyle "Add";
Radius 0.1;
Height 0;
+NOGRAVITY;
+NOCLIP;
+DONTSPLASH;
+FORCEXYBILLBOARD;
+ROLLSPRITE;
+ROLLCENTER;
Scale 0.2;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
double ang, pt;
scale *= FRandom[Puff](0.5,1.5);
alpha *= FRandom[Puff](0.5,1.5);
ang = FRandom[Puff](0,360);
pt = FRandom[Puff](-90,90);
vel += (cos(pt)*cos(ang),cos(pt)*sin(ang),-sin(pt))*FRandom[Puff](0.2,0.8);
roll = FRandom[Puff](0,360);
}
override void Tick()
{
Super.Tick();
if ( level.frozen || globalfreeze ) return;
vel *= 0.99;
A_FadeOut(0.1);
}
States
{
Spawn:
RTRL A -1 Bright;
Stop;
}
}
Class WarShell : Actor
{
double destangle, destpitch;
@ -245,14 +287,24 @@ Class WarShell : Actor
Vector3 taildir = -(cos(angle)*cos(pitch),sin(angle)*cos(pitch),-sin(pitch));
if ( waterlevel > 0 )
{
for ( int i=0; i<8; i++ )
A_SpawnParticle("6060FF",0,Random[Warhead](10,30),FRandom[Warhead](2,4),0,taildir.x*32,taildir.y*32,taildir.z*32,taildir.x*2+FRandom[Warhead](-.5,.5),taildir.y*2+FRandom[Warhead](-.5,.5),taildir.z*2+FRandom[Warhead](-.5,.5),accelz:0.2,fadestepf:0);
for ( int i=0; i<4; i++ )
{
let s = Spawn("UTBubble",pos+taildir*32+(FRandom[Warhead](-.5,.5),FRandom[Warhead](-.5,.5),FRandom[Warhead](-.5,.5)));
s.vel = taildir*2;
}
return;
}
for ( int i=0; i<8; i++ )
A_SpawnParticle("404040",0,20,2,0,taildir.x*32,taildir.y*32,taildir.z*32,taildir.x*2+FRandom[Warhead](-.5,.5),taildir.y*2+FRandom[Warhead](-.5,.5),taildir.z*2+FRandom[Warhead](-.5,.5),accelz:0.1,sizestep:1);
for ( int i=0; i<8; i++ )
A_SpawnParticle("FFA020",SPF_FULLBRIGHT,10,6,0,taildir.x*35+FRandom[Warhead](-1,1),taildir.y*35+FRandom[Warhead](-1,1),taildir.z*35+FRandom[Warhead](-1,1),taildir.x*4+FRandom[Warhead](-.25,.25),taildir.y*4+FRandom[Warhead](-.25,.25),taildir.z*4+FRandom[Warhead](-.25,.25));
for ( int i=0; i<4; i++ )
{
let s = Spawn("UTSmoke",pos+taildir*32+(FRandom[Warhead](-.5,.5),FRandom[Warhead](-.5,.5),FRandom[Warhead](-.5,.5)));
s.vel = taildir*2;
s.SetShade("404040");
}
for ( int i=0; i<4; i++ )
{
let s = Spawn("WarheadTrail",pos+taildir*35+(FRandom[Warhead](-1,1),FRandom[Warhead](-1,1),FRandom[Warhead](-1,1)));
s.vel = taildir*4;
}
}
action void A_Vaporize()
{
@ -545,7 +597,9 @@ Class WarheadLauncher : UTWeapon replaces BFG9000
for ( int i=0; i<numpt; i++ )
{
Vector3 pvel = (x+(FRandom[Warhead](-.8,.8),FRandom[Warhead](-.8,.8),FRandom[Warhead](-.8,.8))).unit()*FRandom[Warhead](1,2);
A_SpawnParticle(Color(1,1,1)*Random[Warhead](32,128),0,Random[Warhead](40,50),FRandom[Warhead](4,12),0,origin.x-pos.x,origin.y-pos.y,origin.z-pos.z,pvel.x,pvel.y,pvel.z,0,0,0.03,0.5,-1,0.5);
let s = Spawn("UTSmoke",origin);
s.vel = pvel;
s.SetShade(Color(1,1,1)*Random[Warhead](32,128));
}
}
action void A_WarheadAlt()