Whole set of new features:

- Spent mags for Enforcer, Flak Cannon and Pulsegun.
- Fixed up bullet casing orientations.
- Terrain stuff (WIP).
This commit is contained in:
Marisa the Magician 2019-10-16 18:03:00 +02:00
commit da49775e7d
29 changed files with 568 additions and 10 deletions

View file

@ -167,12 +167,36 @@ Class UTCasing : Actor
PCAS A -1
{
pitch = 0;
angle = FRandom[Junk](0,360);
roll = FRandom[Junk](0,360);
}
Stop;
}
}
Class EnforcerMag : UTCasing
{
Default
{
BounceSound "enforcer/bounce";
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
heat = 0.;
}
States
{
Death:
PCAS A -1
{
pitch = RandomPick[Junk](-90,90);
angle = FRandom[Junk](0,360);
}
Stop;
}
}
Class Enforcer : UTWeapon
{
int ClipCount, SlaveClipCount;
@ -388,6 +412,8 @@ Class Enforcer : UTWeapon
}
origin = level.Vec3Offset(origin,x*8+ydir*y*6-z*2);
let c = Spawn("UTCasing",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-1.5,1.5)+y*ydir*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
}
@ -574,6 +600,13 @@ Class Enforcer : UTWeapon
if ( self is 'UTPlayer' )
UTPlayer(self).PlayReloading();
invoker.slavereload = (invoker.slaveactive&&(invoker.slaveclipcount<min(invoker.default.slaveclipcount,invoker.Ammo1.Amount)));
Vector3 x, y, z, origin;
[x,y,z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),x*4.+y*4.-z*8.);
let c = Spawn("EnforcerMag",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = vel*.5+x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-.5,.5)-z*FRandom[Junk](1,2);
}
ENFS A 0 A_PlaySound("enforcer/select",CHAN_WEAPON);
Goto Ready;
@ -599,6 +632,13 @@ Class Enforcer : UTWeapon
if ( self is 'UTPlayer' )
UTPlayer(self).PlayReloading();
invoker.slavereload = false;
Vector3 x, y, z, origin;
[x,y,z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),x*4.-y*4.-z*8.);
let c = Spawn("EnforcerMag",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = vel*.5+x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-.5,.5)-z*FRandom[Junk](1,2);
}
2NFS A 0 A_PlaySound("enforcer/select",CHAN_6);
Goto LeftReady;

View file

@ -607,6 +607,33 @@ Class FlakLight : DynamicLight
}
}
Class FlakMag : UTCasing
{
Default
{
BounceSound "flak/sbounce";
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
if ( special1 )
{
anglevel *= .1;
pitchvel *= .1;
}
}
States
{
Death:
PCAS A -1
{
pitch = RandomPick[Junk](-90,90);
angle = FRandom[Junk](0,360);
}
Stop;
}
}
Class FlakCannon : UTWeapon
{
action void A_Loading( bool first = false )
@ -714,6 +741,11 @@ Class FlakCannon : UTWeapon
s.scale *= 2.4;
s.alpha *= 0.5;
}
let c = Spawn("FlakMag",origin);
c.angle = angle;
c.pitch = BulletSlope();
c.vel = x*FRandom[Junk](15.,20.)+y*FRandom[Junk](-.1,.1)+z*FRandom[Junk](.1,.8);
c.special1 = 1;
}
Default
@ -756,7 +788,16 @@ Class FlakCannon : UTWeapon
Fire:
FLKF A 1 A_FireChunks();
FLKF BCDEFGHI 1;
FLKF J 4;
FLKF J 4
{
Vector3 x, y, z, origin;
[x,y,z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),x*4.+y*3.-z*8.);
let c = Spawn("FlakMag",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = vel*.5+x*FRandom[Junk](-.8,.1)+y*FRandom[Junk](-.2,.2)-z*FRandom[Junk](1,2);
}
Goto Loading;
AltFire:
FLKA A 1 A_FireSlug();

View file

@ -172,6 +172,8 @@ Class Minigun : UTWeapon
}
origin = level.Vec3Offset(origin,x*8+y*5-z*5);
let c = Spawn("UTCasing",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-1.5,1.5)+y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
c.Scale *= 0.5;
}

View file

@ -531,6 +531,31 @@ Class StarterBolt : PulseBolt
}
}
Class PulseMag : UTCasing
{
Default
{
BounceSound "enforcer/bounce";
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
heat = 0.;
}
States
{
Death:
PCAS A -1
{
pitch = Normalize180(pitch);
if ( abs(deltaangle(pitch,0)) < 35 ) pitch = 0;
else pitch = (pitch>0)?90:-90;
angle = FRandom[Junk](0,360);
}
Stop;
}
}
Class PulseGun : UTWeapon
{
int clipcount;
@ -778,7 +803,17 @@ Class PulseGun : UTWeapon
invoker.clipcount = 0;
}
PGNR QRSTUVWXYZ 1;
PGR2 ABCD 1;
PGR2 A 1
{
Vector3 x, y, z, origin;
[x,y,z] = dt_CoordUtil.GetAxes(pitch,angle,roll);
origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),x*4.-y*6.-z*8.);
let c = Spawn("PulseMag",origin);
c.angle = angle;
c.pitch = pitch;
c.vel = vel*.5+x*FRandom[Junk](-.5,.5)+y*FRandom[Junk](-.5,.5)-z*FRandom[Junk](1,2);
}
PGR2 BCD 1;
PGR2 E 1
{
invoker.clipcount = Min(invoker.default.clipcount,invoker.Ammo1.Amount);

View file

@ -171,6 +171,8 @@ Class SniperRifle : UTWeapon
origin = level.Vec3Offset(origin,x*8+y*6-z*9);
let c = Spawn("UTCasing",origin);
c.scale *= 1.25;
c.angle = angle;
c.pitch = pitch;
c.vel = x*FRandom[Junk](-1.5,1.5)+y*FRandom[Junk](2,4)+z*FRandom[Junk](2,3);
}
override String GetObituary( Actor victim, Actor inflictor, Name mod, bool playerattack )

View file

@ -11,6 +11,7 @@ Class UTPlayer : DoomPlayer
int last_fm_tap, last_sm_tap;
int last_tap_fm, last_tap_sm;
int last_jump_held;
Actor underwatersnd;
int tempslide;
double ssup;
@ -250,7 +251,7 @@ Class UTPlayer : DoomPlayer
if ( lastvelz < -8 )
{
double vol = clamp((-lastvelz-8)*0.05,0.01,1.0);
if ( ((waterlevel > 0) || GetFloorTerrain().IsLiquid) && !bOnMobj ) A_PlaySound("ut/wetsplash",CHAN_AUTO,vol);
if ( ((waterlevel > 0) || GetFloorTerrain().IsLiquid) && !bOnMobj ) PlaySplash(vol);
else A_PlaySound("*uland",CHAN_AUTO,vol);
PlayLanding();
}
@ -265,13 +266,20 @@ Class UTPlayer : DoomPlayer
{
double vol = abs(vel.xy.length())*0.03;
if ( forcefootstep ) vol = clamp(-lastvelz*0.05,0.01,1.0);
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) A_PlaySound("ut/playerfootstepwet",CHAN_5,vol);
if ( (waterlevel > 0) || GetFloorTerrain().IsLiquid && !bOnMobj ) PlayWetFootstep(vol);
else PlayFootstep(vol);
}
if ( (waterlevel >= 2) && (lastwaterlevel < 2) )
A_PlaySound("ut/wetsplash",CHAN_AUTO);
PlaySplash(1.);
else if ( (waterlevel < 2) && (lastwaterlevel >= 2) )
A_PlaySound("ut/wetsurface",CHAN_AUTO);
PlaySurface();
if ( (waterlevel >= 3) && !underwatersnd )
{
underwatersnd = Spawn("UTUnderSound",pos);
underwatersnd.target = self;
}
else if ( (waterlevel < 3) && underwatersnd )
underwatersnd.Destroy();
lastground = player.onground;
lastvelz = prevvelz;
prevvelz = vel.z;
@ -385,8 +393,17 @@ Class UTPlayer : DoomPlayer
else Angle += cmd.yaw*(360./65536.);
player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2);
// slant (aka steep slope) detection
// TODO make it 3d floor aware when the PR makes it in
if ( floorsector.floorplane.normal dot (0,0,1) < (46342./65536.) )
Vector3 floornormal = floorsector.floorplane.normal;
for ( int i=0; i<floorsector.Get3DFloorCount(); i++ )
{
F3DFloor ff = floorsector.Get3DFloor(i);
if ( ff.top.ZAtPoint(pos.xy) ~== floorz )
{
floornormal = -ff.top.normal;
break;
}
}
if ( floornormal dot (0,0,1) < (46342./65536.) )
player.onground = false;
if ( player.onground ) lastgroundtic = gametic;
if ( !player.onground && !bNoGravity && (waterlevel < 2) && (abs(pos.z-floorz) <= maxdropoffheight) && (player.jumptics == 0) && (vel.z < 0) )
@ -726,7 +743,70 @@ Class UTPlayer : DoomPlayer
virtual void PlayFootstep( double vol )
{
A_PlaySound("ut/playerfootstep",CHAN_5,vol);
A_PlaySound("ut/playerfootstep",CHAN_AUTO,vol);
}
virtual void PlaySplash( double vol )
{
TerrainDef t = GetFloorTerrain();
String snd = "ut/wetsplash";
switch ( t.TerrainName )
{
case 'UTLava':
case 'Lava':
snd = "ut/lavasplash";
break;
case 'UTSlime':
case 'UTNukage':
case 'Slime':
case 'Nukage':
case 'Sludge':
snd = "ut/slimesplash";
break;
}
A_PlaySound(snd,CHAN_AUTO,vol);
}
virtual void PlaySurface()
{
TerrainDef t = GetFloorTerrain();
String snd = "ut/wetsurface";
switch ( t.TerrainName )
{
case 'UTLava':
case 'Lava':
snd = "ut/lavasurface";
break;
case 'UTSlime':
case 'UTNukage':
case 'Slime':
case 'Nukage':
case 'Sludge':
snd = "ut/slimesurface";
break;
}
A_PlaySound(snd,CHAN_AUTO);
}
virtual void PlayWetFootstep( double vol )
{
TerrainDef t = GetFloorTerrain();
String snd = "ut/playerfootstepwet";
switch ( t.TerrainName )
{
case 'UTLava':
case 'Lava':
snd = "ut/playerfootsteplava";
break;
case 'UTSlime':
case 'UTNukage':
case 'Slime':
case 'Nukage':
case 'Sludge':
snd = "ut/playerfootstepslime";
break;
}
A_PlaySound(snd,CHAN_AUTO,vol);
}
override void PlayIdle()
@ -1120,6 +1200,139 @@ Class UTPlayer : DoomPlayer
}
}
Class UTUnderSound : Actor
{
enum EFluidType
{
FLUID_WATER,
FLUID_SLIME,
FLUID_LAVA,
FLUID_NITRO
};
int curfluid, lastfluid;
String fluidsounds[4];
Default
{
+NOBLOCKMAP;
+NOGRAVITY;
+DONTSPLASH;
+NOINTERACTION;
}
int GetFluid()
{
int thisfluid = FLUID_WATER;
// try to guess where we are
for ( int i=0; i<CurSector.Get3DFloorCount(); i++ )
{
F3DFloor ff = CurSector.Get3DFloor(i);
switch ( ff.model.damagetype )
{
case 'Slime':
thisfluid = FLUID_SLIME;
break;
case 'Fire':
thisfluid = FLUID_LAVA;
break;
case 'Ice':
thisfluid = FLUID_NITRO;
break;
}
}
return thisfluid;
}
override void PostBeginPlay()
{
Super.PostBeginPlay();
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
curfluid = lastfluid = GetFluid();
fluidsounds[0] = 'ut/underwater';
fluidsounds[1] = 'ut/underslime';
fluidsounds[2] = 'ut/underlava';
fluidsounds[3] = 'ut/undernitro';
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,100.);
A_SoundVolume(CHAN_VOICE,(players[consoleplayer].camera==target)?1.:0.);
}
override void OnDestroy()
{
A_StopSound(CHAN_VOICE);
Super.OnDestroy();
}
override void Tick()
{
Super.Tick();
if ( !target )
{
Destroy();
return;
}
SetOrigin(target.Vec2OffsetZ(0,0,target.player.viewz),true);
curfluid = GetFluid();
if ( curfluid != lastfluid )
A_PlaySound(fluidsounds[curfluid],CHAN_VOICE|CHAN_LISTENERZ,1.,true,100.);
lastfluid = curfluid;
A_SoundVolume(CHAN_VOICE,(players[consoleplayer].camera==target)?1.:0.);
}
}
// TODO terrain stuff
Class UTTerrainFX : Actor
{
States
{
Spawn:
TNT1 A 1;
Stop;
}
}
Class UTWaterSplish : UTTerrainFX
{
}
Class UTWaterSplash : UTTerrainFX
{
}
Class UTBloodSplish : UTTerrainFX
{
}
Class UTBloodSplash : UTTerrainFX
{
}
Class UTSlimeSplish : UTTerrainFX
{
}
Class UTSlimeSplash : UTTerrainFX
{
}
Class UTNukageSplish : UTTerrainFX
{
}
Class UTNukageSplash : UTTerrainFX
{
}
Class UTLavaSplish : UTTerrainFX
{
}
Class UTLavaSplash : UTTerrainFX
{
}
Class UTNitroSplish : UTTerrainFX
{
}
Class UTNitroSplash : UTTerrainFX
{
}
// these only exist for sound
// female classes have identical sounds, so they use the same soundclass here
Class UTPlayerTMale1 : UTPlayer