Player blood footprints now implemented.

This commit is contained in:
Mari the Deer 2025-03-09 14:17:35 +01:00
commit af27fbd987
6 changed files with 129 additions and 5 deletions

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1193 \cu(vie 07 mar 2025 17:27:59 CET)\c-";
SWWM_SHORTVER="\cw1.3pre r1193 \cu(2025-03-07 17:27:59)\c-";
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1194 \cu(dom 09 mar 2025 14:17:35 CET)\c-";
SWWM_SHORTVER="\cw1.3pre r1194 \cu(2025-03-09 14:17:35)\c-";

View file

@ -141,7 +141,7 @@ Model "mkBloodBlast"
{
Path "models/extra"
Model 0 "Flat.obj"
Scale 20 20 20
Scale 120 120 120
ZOffset 0.1
USEACTORPITCH
USEACTORROLL
@ -168,6 +168,23 @@ Model "mkBloodPool"
FrameIndex XZW1 B 0 0
}
Model "mkBloodStep"
{
Path "models/extra"
Model 0 "Flat.obj"
Scale 4 4 4
ZOffset 0.1
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
// texture ought to be assigned by script
Skin 0 "-noflat-"
FrameIndex XZW1 A 0 0
Scale 4 -4 4
FrameIndex XZW1 B 0 0
}
Model "mkFlyingGib"
{
Path "models"

View file

@ -124,6 +124,10 @@ Class Demolitionist : PlayerPawn
bool isAnalogMoving;
// bloody footprints (yes, separate for each foot)
double footblood[2];
Color footbloodcol[2];
SWWMHandler hnd;
Default

View file

@ -51,6 +51,52 @@ extend Class Demolitionist
return fact;
}
void LeaveFootprint( double yofs, bool foot )
{
Vector3 checkpos = level.Vec3Offset((pos.xy,floorz),(RotateVector((0,yofs*.25*radius),angle),0));
let s = level.PointInSector(checkpos.xy);
// part 1: leave a footprint
if ( footblood[foot] > 0. )
{
double zatstep = s.floorplane.ZAtPoint(checkpos.xy);
for ( int i=0; i<s.Get3DFloorCount(); i++ )
{
if ( !(s.Get3DFloor(i).flags&F3DFloor.FF_SOLID) ) continue;
double ffz = s.Get3DFloor(i).top.ZAtPoint(checkpos.xy);
if ( ffz > checkpos.z ) continue;
else if ( ffz < zatstep ) continue;
zatstep = ffz;
break;
}
if ( abs(floorz-zatstep) <= 8. )
{
let bs = Spawn("mkBloodStep",(checkpos.xy,zatstep));
bs.angle = angle;
bs.frame = foot;
bs.A_ChangeModel("",0,"","",0,"models/extra",String.Format("BloodFoot%d.png",Random[Blood](1,4)));
bs.alpha = min(1.,footblood[foot]);
bs.SetShade(footbloodcol[foot]);
}
footblood[foot] = max(0.,footblood[foot]*.95-.05);
}
// part 2: check for stepping on a blood pool, make feet bloody
if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
for ( mkBloodPool p=hnd.bloodpools; p; p=p.nextpool )
{
// vertical distance fast check
if ( abs(checkpos.z-p.pos.z) > 8. )
continue;
// horizontal distance slower check
double distsq = level.Vec2Diff(checkpos.xy,p.pos.xy).lengthsquared();
if ( distsq > (p.radius*p.radius+.25*radius*radius) )
continue;
// muck it up, with some color mixing too
double oldblood = footblood[foot];
footblood[foot] = 2.;
footbloodcol[foot] = SWWMUtility.LerpColor(p.stepcol,footbloodcol[foot],min(1.,oldblood)*.75);
}
}
void PlayFootstep( double yofs, int run = 0, double vol = .3, bool nosplash = false )
{
if ( run == 2 )
@ -83,6 +129,7 @@ extend Class Demolitionist
b.A_CheckTerrain();
}
}
LeaveFootprint(yofs,yofs>0);
}
override void CalcHeight()

View file

@ -322,6 +322,12 @@ extend Class Demolitionist
p.vel += vel*.2;
}
}
// clean up bloody footprints on water
if ( (waterlevel > 0) || GetFloorTerrain().isliquid )
{
if ( footblood[0] > 0. ) footblood[0] = max(0.,footblood[0]*.95-.05);
if ( footblood[1] > 0. ) footblood[1] = max(0.,footblood[1]*.95-.05);
}
CheckUnderwaterAmb();
SenseItems();
CheckItemMagnet();
@ -378,7 +384,10 @@ extend Class Demolitionist
if ( loudlv > 3 ) A_StartSound(String.Format("voice/%s/grunt%d",myvoice,idx),CHAN_DEMOVOICEAUX3,CHANF_OVERLAP);
}
if ( lastvelz < -1 )
PlayFootstep(0,1,clamp(-lastvelz*0.05,0.0,1.0),true);
{
PlayFootstep(-1,1,clamp(-lastvelz*0.05,0.0,1.0),true);
PlayFootstep(1,1,clamp(-lastvelz*0.05,0.0,1.0),true);
}
// bounce off slopes
if ( pos.z <= floorz )
{

View file

@ -759,7 +759,6 @@ Class mkGibber : SWWMNonInteractiveActor
{
let s = Spawn("mkBloodBlast",pos);
s.SetShade(shadecol);
s.scale *= radius/4.;
s.master = gibbed;
mksplat = false;
}
@ -894,6 +893,7 @@ Class mkBloodPool : SWWMNonInteractiveActor
double basesz, sz, accel;
Color stepcol;
mkBloodPool prevpool, nextpool;
bool bRaised; // dead body was revived, fade out faster
override void OnDestroy()
{
@ -939,6 +939,11 @@ Class mkBloodPool : SWWMNonInteractiveActor
if ( (waterlevel > 0) || GetFloorTerrain().isliquid )
A_FadeOut();
if ( !master ) A_FadeOut(.01);
else if ( (master.Health > 0) || bRaised )
{
bRaised = true;
A_FadeOut();
}
if ( accel <= double.epsilon ) return;
sz += accel;
accel *= .997;
@ -959,3 +964,45 @@ Class mkBloodPool : SWWMNonInteractiveActor
Stop;
}
}
// Bloody footsteps for player
// (Spawning handled also by player)
Class mkBloodStep : SWWMNonInteractiveActor
{
override void PostBeginPlay()
{
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
SetZ(fz);
prev.z = fz;
}
override void Tick()
{
if ( freezetics > 0 )
{
freezetics--;
return;
}
if ( isFrozen() ) return;
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
if ( fz != pos.z ) SetOrigin((pos.x,pos.y,fz),true);
if ( (waterlevel > 0) || GetFloorTerrain().isliquid )
A_FadeOut();
special1++;
// start fading out after one whole minute
if ( special1 > 2100 ) A_FadeOut(.01);
}
Default
{
RenderStyle "Shaded";
StencilColor "Red";
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}