Unconditional blood replacement, new blood decals, corpse blood pools.

TODO: bloodied footsteps, can still re-use code from Soundless Mound there.
This commit is contained in:
Mari the Deer 2025-03-07 17:27:59 +01:00
commit f89393ca81
62 changed files with 540 additions and 22 deletions

View file

@ -19,7 +19,6 @@ nosave bool swwm_pois = true; // show points of interest highlighted by omnisi
nosave bool swwm_shaders = true; // use pp shaders for some effects
server bool swwm_revive = true; // allows the player to do an "emergency reboot" when dying
server int swwm_revivecooldown = 60; // cooldown after using a revive, in seconds (0: no limit)
server int swwm_blood = 1; // custom blood/gibbing (2: forcibly use our blood)
server int swwm_maxblood = 200; // max blood effects at any time
server int swwm_maxgibs = 100; // max gibs at any time
server int swwm_maxcasings = 100; // max casings and spent mags at any time

View file

@ -637,3 +637,335 @@ decal DemoSpray
y-scale 0.25
solid
}
// replace vanilla blood
decal BloodSplat1
{
pic blsplat1
shade "BloodDefault"
x-scale 0.6
y-scale 0.6
randomflipx
randomflipy
}
decal BloodSplat2
{
pic blsplat2
shade "BloodDefault"
x-scale 0.625
y-scale 0.625
randomflipx
randomflipy
}
decal BloodSplat3
{
pic blsplat3
shade "BloodDefault"
x-scale 0.675
y-scale 0.675
randomflipx
randomflipy
}
decal BloodSplat4
{
pic blsplat4
shade "BloodDefault"
x-scale 0.7
y-scale 0.7
randomflipx
randomflipy
}
decal BloodSplat5
{
pic blsplat5
shade "BloodDefault"
x-scale 0.725
y-scale 0.725
randomflipx
randomflipy
}
decal BloodSplat6
{
pic blsplat6
shade "BloodDefault"
x-scale 0.75
y-scale 0.75
randomflipx
randomflipy
}
decal BloodSplat7
{
pic blsplat7
shade "BloodDefault"
x-scale 0.775
y-scale 0.775
randomflipx
randomflipy
}
decal BloodSplat8
{
pic blsplat8
shade "BloodDefault"
x-scale 0.8
y-scale 0.8
randomflipx
randomflipy
}
decal BloodSplatX1
{
pic blsplat1
shade "BloodDefault"
x-scale 0.875
y-scale 0.875
randomflipx
randomflipy
LowerDecal "BloodSlide1"
}
decal BloodSlide1
{
pic blslide1
shade "BloodDefault"
x-scale 0.875
y-scale 0.875
randomflipx
animator BloodStretcher
}
decal BloodSplatX2
{
pic blsplat2
shade "BloodDefault"
x-scale 0.9
y-scale 0.9
randomflipx
randomflipy
LowerDecal "BloodSlide2"
}
decal BloodSlide2
{
pic blslide2
shade "BloodDefault"
x-scale 0.9
y-scale 0.9
randomflipx
animator BloodStretcher
}
decal BloodSplatX3
{
pic blsplat3
shade "BloodDefault"
x-scale 0.925
y-scale 0.925
randomflipx
randomflipy
LowerDecal "BloodSlide3"
}
decal BloodSlide3
{
pic blslide3
shade "BloodDefault"
x-scale 0.925
y-scale 0.925
randomflipx
animator BloodStretcher
}
decal BloodSplatX4
{
pic blsplat4
shade "BloodDefault"
x-scale 0.95
y-scale 0.95
randomflipx
randomflipy
LowerDecal "BloodSlide4"
}
decal BloodSlide4
{
pic blslide4
shade "BloodDefault"
x-scale 0.95
y-scale 0.95
randomflipx
animator BloodStretcher
}
decal BloodSplatX5
{
pic blsplat5
shade "BloodDefault"
x-scale 0.975
y-scale 0.975
randomflipx
randomflipy
LowerDecal "BloodSlide5"
}
decal BloodSlide5
{
pic blslide5
shade "BloodDefault"
x-scale 0.975
y-scale 0.975
randomflipx
animator BloodStretcher
}
decal BloodSplatX6
{
pic blsplat6
shade "BloodDefault"
x-scale 1.0
y-scale 1.0
randomflipx
randomflipy
LowerDecal "BloodSlide6"
}
decal BloodSlide6
{
pic blslide6
shade "BloodDefault"
x-scale 1.0
y-scale 1.0
randomflipx
animator BloodStretcher
}
decal BloodSplatX7
{
pic blsplat7
shade "BloodDefault"
x-scale 1.25
y-scale 1.25
randomflipx
randomflipy
LowerDecal "BloodSlide7"
}
decal BloodSlide7
{
pic blslide7
shade "BloodDefault"
x-scale 1.25
y-scale 1.25
randomflipx
animator BloodStretcher
}
decal BloodSplatX8
{
pic blsplat8
shade "BloodDefault"
x-scale 1.5
y-scale 1.5
randomflipx
randomflipy
LowerDecal "BloodSlide8"
}
decal BloodSlide8
{
pic blslide8
shade "BloodDefault"
x-scale 1.5
y-scale 1.5
randomflipx
animator BloodStretcher
}
decalgroup BloodSplat
{
BloodSplat1 1
BloodSplat2 1
BloodSplat3 1
BloodSplat4 1
BloodSplat5 1
BloodSplat6 1
BloodSplat7 1
BloodSplat8 1
BloodSplatX1 1
BloodSplatX2 1
BloodSplatX3 1
BloodSplatX4 1
BloodSplatX5 1
BloodSplatX6 1
BloodSplatX7 1
BloodSplatX8 1
}
decal BloodSmear1
{
pic blslide1
x-scale 0.625
y-scale 0.625
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear2
{
pic blslide2
x-scale 0.65
y-scale 0.65
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear3
{
pic blslide3
x-scale 0.675
y-scale 0.675
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear4
{
pic blslide4
x-scale 0.7
y-scale 0.7
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear5
{
pic blslide5
x-scale 0.725
y-scale 0.725
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear6
{
pic blslide6
x-scale 0.75
y-scale 0.75
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear7
{
pic blslide7
x-scale 0.775
y-scale 0.775
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decal BloodSmear8
{
pic blslide8
x-scale 0.8
y-scale 0.8
randomflipx
shade "BloodDefault"
animator BloodSmearer
}
decalgroup BloodSmear
{
BloodSmear1 1
BloodSmear2 1
BloodSmear3 1
BloodSmear4 1
BloodSmear5 1
BloodSmear6 1
BloodSmear7 1
BloodSmear8 1
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 939 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 957 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -58,7 +58,6 @@ SWWM_UNLIMITED = "Unlimited";
SWWM_ONERETRY = "One Retry";
SWWM_NONE = "None";
SWWM_BTITLE = "Balance Options";
SWWM_BLOOD = "Enable Custom Blood";
SWWM_FUZZ = "Enable Animated Menu BG";
SWWM_CBTALL = "Unrestricted Busting";
SWWM_DOOMFALL = "Force Monster Fall Damage";
@ -222,7 +221,6 @@ TOOLTIP_SWWM_POIS = "Show points of interest (such as key items and exits) when
TOOLTIP_SWWM_SHADERS = "Use postprocess shaders for things like powerups and the Silver Bullet scope. You can disable this if you'd prefer something lighter on the eyes.";
TOOLTIP_SWWM_REVIVE = "Allows the player to get back up after dying by pressing Fire. Has a configurable cooldown.";
TOOLTIP_SWWM_REVIVECOOLDOWN = "Time in seconds of downtime after using a reboot, where if you die again, you can't get back up. Set to 0 to allow unlimited reboots. Alternatively, you can also set it to only allow one reboot per map (enforced on expert difficulties).";
TOOLTIP_SWWM_BLOOD = "Enable custom blood and gore effects, adapted from Soundless Mound. Other loaded mods' gore will take priority unless set to \"Always\". BLUDTYPE patches from Nashgore are supported.";
TOOLTIP_SWWM_FUZZ = "Toggling this off is recommended if you're recording/streaming as this effect can harm video quality.";
TOOLTIP_SWWM_CBTALL = "Allows the Wallbuster and other weapons capable of map geometry destruction to break pretty much anything, not just doors and platforms. Note that this can break some maps, which is why this option is here.";
TOOLTIP_SWWM_DOOMFALL = "Makes monsters take fall damage outside of Hexen. Requires map reload if previously disabled.";

View file

@ -56,7 +56,6 @@ SWWM_UNLIMITED = "Ilimitado";
SWWM_ONERETRY = "Un Reintento";
SWWM_NONE = "Ninguno";
SWWM_BTITLE = "Opciones de Balance";
SWWM_BLOOD = "Habilitar Sangre Personalizada";
SWWM_FUZZ = "Habilitar Fondo Animado de Menú";
SWWM_CBTALL = "Reventamiento sin Restricciones";
SWWM_DOOMFALL = "Forzar Daño por Caída en Monstruos";
@ -217,7 +216,6 @@ TOOLTIP_SWWM_POIS = "Muestra puntos de interés (tales como llaves y salidas) cu
TOOLTIP_SWWM_SHADERS = "Usa shaders de postprocesado para cosas como potenciadores y la mira del Silver Bullet. Puedes desactivar esto si prefieres algo más ligero para la vista.";
TOOLTIP_SWWM_REVIVE = "Permite al jugador volver a levantarse tras morir pulsando Fuego. Tiene un cooldown configurable.";
TOOLTIP_SWWM_REVIVECOOLDOWN = "Tiempo en segundos tras reiniciar, durante el cual si mueres otra vez, no puedes volver a levantarte. Pon a 0 para permitir reinicios ilimitados. Alternativamente, puedes elegir que solo se permita un reinicio por mapa (forzado en dificultades expertas).";
TOOLTIP_SWWM_BLOOD = "Activa efectos de sangre y vísceras personalizados, adaptados de Soundless Mound. La sangre de otros mods tiene prioridad a menos que se elija \"Siempre\". Se soportan parches BLUDTYPE para Nashgore.";
TOOLTIP_SWWM_FUZZ = "Desactivar esto es recomendado si estás grabando o haciendo streaming, ya que este effecto puede dañar la calidad del vídeo.";
TOOLTIP_SWWM_CBTALL = "Permite a la Wallbuster y otras armas capaces de reventar geometría del mapa destruír casi cualquier cosa, no solo puertas y plataformas. Ten en cuenta que esto puede romper algunos mapas, razón de que haya esta opción.";
TOOLTIP_SWWM_DOOMFALL = "Hace que los monstruos reciban daño por caída fuera de Hexen. Requiere reinicio de mapa si fue desactivado anteriormente.";

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1192 \cu(vie 07 mar 2025 12:26:22 CET)\c-";
SWWM_SHORTVER="\cw1.3pre r1192 \cu(2025-03-07 12:26:22)\c-";
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-";

View file

@ -166,7 +166,6 @@ OptionMenu "SWWMOptionMenu"
Option "$SWWM_SHOWMAPTITLE", "swwm_showmaptitle", "YesNo"
StaticText " "
StaticText "$SWWM_ETITLE", 1
Option "$SWWM_BLOOD", "swwm_blood", "SWWMYesNoAlways"
Option "$SWWM_NOMAGDROP", "swwm_nomagdrop", "NoYes"
ScaleSliderFix "$SWWM_MAXBLOOD", "swwm_maxblood", -1, 1000, 100, "$SWWM_NONE", "$SWWM_UNLIMITED"
ScaleSliderFix "$SWWM_MAXGIBS", "swwm_maxgibs", -1, 1000, 100, "$SWWM_NONE", "$SWWM_UNLIMITED"

View file

@ -110,15 +110,62 @@ Model "mkBloodDrop"
FrameIndex SBLD H 0 0
Skin 0 "BloodDrop4.png"
FrameIndex SBLD I 0 0
ZOffset -0.1
Skin 0 "BloodDrop1.png"
Skin 0 "BloodDrop5.png"
FrameIndex SBLD J 0 0
Skin 0 "BloodDrop2.png"
Skin 0 "BloodDrop6.png"
FrameIndex SBLD K 0 0
Skin 0 "BloodDrop3.png"
Skin 0 "BloodDrop7.png"
FrameIndex SBLD L 0 0
Skin 0 "BloodDrop4.png"
Skin 0 "BloodDrop8.png"
FrameIndex SBLD M 0 0
ZOffset -0.1
Skin 0 "BloodSplat1.png"
FrameIndex SBLD N 0 0
Skin 0 "BloodSplat2.png"
FrameIndex SBLD O 0 0
Skin 0 "BloodSplat3.png"
FrameIndex SBLD P 0 0
Skin 0 "BloodSplat4.png"
FrameIndex SBLD Q 0 0
Skin 0 "BloodSplat1.png"
FrameIndex SBLD R 0 0
Skin 0 "BloodSplat2.png"
FrameIndex SBLD S 0 0
Skin 0 "BloodSplat3.png"
FrameIndex SBLD T 0 0
Skin 0 "BloodSplat4.png"
FrameIndex SBLD U 0 0
}
Model "mkBloodBlast"
{
Path "models/extra"
Model 0 "Flat.obj"
Scale 20 20 20
ZOffset 0.1
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
Skin 0 "BloodBlast.png"
FrameIndex XZW1 A 0 0
}
Model "mkBloodPool"
{
Path "models/extra"
Model 0 "Flat.obj"
Scale 60 60 60
ZOffset 0.1
USEACTORPITCH
USEACTORROLL
DONTCULLBACKFACES
Skin 0 "blodpool.png"
FrameIndex XZW1 A 0 0
// do not use for sprite-based monsters
Skin 0 "blodpool_shaded.png"
FrameIndex XZW1 B 0 0
}
Model "mkFlyingGib"

View file

@ -9,7 +9,7 @@ Model "AshenRemains"
USEACTORROLL
DONTCULLBACKFACES
Skin 0 "BigBlast.png"
Skin 0 "BloodBlast.png"
FrameIndex XZW1 A 0 0
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

BIN
models/extra/BloodBlast.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before After
Before After

BIN
models/extra/BloodDrop5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
models/extra/BloodDrop6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
models/extra/BloodDrop7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
models/extra/BloodDrop8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
models/extra/BloodFoot1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
models/extra/BloodFoot2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
models/extra/BloodFoot3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
models/extra/BloodFoot4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 906 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,008 B

BIN
models/extra/blodpool.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
sprites/MSMKA0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sprites/MSMKB0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sprites/MSMKC0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sprites/MSMKD0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

BIN
sprites/MSMKE0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
sprites/MSMKF0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

BIN
sprites/MSMKG0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
sprites/MSMKH0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -53,6 +53,9 @@ Class SWWMHandler : EventHandler
transient ui Vector2 oldplayerpos;
transient ui bool do_trace_steps;
// for bloody footsteps
mkBloodPool bloodpools;
enum EProfileTimer
{
PT_WORLDTICK,

View file

@ -32,6 +32,7 @@ extend Class SWWMHandler
if ( !b ) return;
mkGibber(a).gibbed = e.Thing;
mkGibber(a).delay = 40;
mkGibber(a).mksplat = true;
a.special1 = 1;
a.A_SetSize(e.Thing.default.radius,e.Thing.default.height);
return;
@ -42,6 +43,7 @@ extend Class SWWMHandler
if ( !b ) return;
mkGibber(a).gibbed = e.Thing;
mkGibber(a).delay = 60;
mkGibber(a).mksplat = true;
a.special1 = 1;
a.A_SetSize(e.Thing.default.radius,e.Thing.default.height);
}

View file

@ -196,8 +196,5 @@ extend Class SWWMHandler
oldmaxdebris = swwm_maxdebris;
oldmaxblood = swwm_maxblood;
oldmaxgibs = swwm_maxgibs;
if ( swwm_blood ) return;
while ( blods ) DeQueueBlod(blods);
while ( meats ) DeQueueMeat(meats);
}
}

View file

@ -675,8 +675,7 @@ extend Class SWWMHandler
return;
}
}
// only replace vanilla blood if no other gore mod is doing it (unless swwm_blood is set to 2)
if ( (((e.Replacee == "Blood") && (!e.Replacement || (e.Replacement == "Blood") || (swwm_blood >= 2))) || (bludtypes.Find(e.Replacee.GetClassName()) < bludtypes.Size())) && swwm_blood ) e.Replacement = "mkBlood";
if ( (e.Replacee is 'Blood') || (bludtypes.Find(e.Replacee.GetClassName()) < bludtypes.Size()) ) e.Replacement = 'mkBlood';
else if ( e.Replacee is 'ItemFog' ) e.Replacement = 'SWWMItemFog';
else if ( e.Replacee is 'TeleportFog' ) e.Replacement = 'SWWMTeleportFog';
else if ( (e.Replacee is 'CommanderKeen') && (!e.Replacement || (e.Replacement == 'CommanderKeen')) )

View file

@ -302,7 +302,7 @@ Class mkBloodDrop : SWWMNonInteractiveActor
}
SWWMUtility.SetToSlope(self,FRandom[Blood](0,360));
A_SetRenderStyle(1.,STYLE_Shaded);
frame = Random[Blood](5,8);
frame = Random[Blood](5,12);
int numpt = Random[Blood](4,8);
puff.lifetime = 20;
puff.startalpha = .5*alpha;
@ -357,7 +357,7 @@ Class mkBloodDrop : SWWMNonInteractiveActor
}
SWWMUtility.SetToSlope(self,FRandom[Blood](0,360),true);
A_SetRenderStyle(1.,STYLE_Shaded);
frame = Random[Blood](9,12);
frame = Random[Blood](13,20);
int numpt = Random[Blood](4,8);
puff.lifetime = 20;
puff.startalpha = .5*alpha;
@ -456,7 +456,7 @@ Class mkBloodSmoke : SWWMStaticSprite
override void SetupSprite()
{
texture = TexMan.CheckForTexture(String.Format("BSMK%c0",0x41+Random[Blood](0,19)));
texture = TexMan.CheckForTexture(String.Format("MSMK%c0",0x41+Random[Blood](0,7)));
Scale = (.5,.5);
Alpha = .35;
SetRenderStyle(STYLE_Shaded);
@ -653,6 +653,7 @@ Class mkGibber : SWWMNonInteractiveActor
color shadecol;
meta Class<Actor> gibtype; // allow custom gib types (will be used for monster pack)
bool psnd;
bool mksplat;
Property GibType: gibtype;
@ -754,6 +755,14 @@ Class mkGibber : SWWMNonInteractiveActor
A_StartSound("misc/gibber",CHAN_VOICE,CHANF_OVERLAP);
psnd = true;
}
if ( mksplat )
{
let s = Spawn("mkBloodBlast",pos);
s.SetShade(shadecol);
s.scale *= radius/4.;
s.master = gibbed;
mksplat = false;
}
BurstGibs();
if ( reactiontime <= 0 )
Destroy();
@ -767,6 +776,44 @@ Class mkGibber : SWWMNonInteractiveActor
}
}
// for exploding Cyberdemon/Spider
Class mkBloodBlast : SWWMNonInteractiveActor
{
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();
if ( !master ) A_FadeOut(.01);
}
override void PostBeginPlay()
{
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
SetZ(fz);
prev.z = fz;
A_QueueCorpse();
SWWMUtility.SetToSlope(self,FRandom[Blood](0,360));
}
default
{
RenderStyle "Shaded";
StencilColor "Red";
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}
// bare actors used for copying blood color to vanilla monsters
Class GreenBloodReference : Actor
{
@ -822,6 +869,93 @@ Class CorpseFallTracker : Thinker
// wait until body is dead on floor and at the last state of animation
if ( (mybody.Health > 0) || isflying || (mybody.tics != -1) || (mybody.vel.length() > 0) )
return;
let b = mybody.Spawn("mkBloodPool",mybody.pos);
Color shadecol;
if ( mybody.bloodcolor ) shadecol = Color(mybody.bloodcolor.r/2,mybody.bloodcolor.g/2,mybody.bloodcolor.b/2);
else shadecol = Color(80,0,0);
mkBloodPool(b).stepcol = shadecol;
b.master = mybody;
b.A_SetScale(mybody.default.radius/16.);
// futureproofing hack (heh)
let mtype = SWWMUtility.GetParentClassBefore(mybody.GetClass(),'Actor');
if ( mtype.GetClassName() == 'SWWMMonster' )
{
b.A_SetRenderStyle(1.,STYLE_Shaded);
b.SetShade(shadecol);
}
else b.translation = mybody.bloodtranslation;
Destroy();
}
}
// Blood pool
Class mkBloodPool : SWWMNonInteractiveActor
{
double basesz, sz, accel;
Color stepcol;
mkBloodPool prevpool, nextpool;
override void OnDestroy()
{
Super.OnDestroy();
if ( prevpool )
{
prevpool.nextpool = nextpool;
if ( nextpool ) nextpool.prevpool = prevpool;
}
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return;
hnd.bloodpools = nextpool;
}
override void PostBeginPlay()
{
double fz = CurSector.floorplane.ZAtPoint(pos.xy);
SetZ(fz);
prev.z = fz;
accel = .0012;
basesz = scale.x;
sz = .01;
A_SetScale(sz);
A_QueueCorpse();
SWWMUtility.SetToSlope(self,FRandom[Blood](0,360));
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return;
nextpool = hnd.bloodpools;
hnd.bloodpools = self;
if ( nextpool ) nextpool.prevpool = self;
}
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();
if ( !master ) A_FadeOut(.01);
if ( accel <= double.epsilon ) return;
sz += accel;
accel *= .997;
A_SetScale(basesz*sz);
A_SetSize(50.*basesz*sz);
}
Default
{
Radius 1;
Height 1;
StencilColor "Red";
}
States
{
Spawn:
XZW1 A -1;
Stop;
}
}

View file

@ -495,4 +495,14 @@ extend Class SWWMUtility
return true;
return target.bCOUNTITEM;
}
// return the highest parent class in hierarchy before a specific "highest class"
// useful to check stuff such as monster subtypes and the like
static Class<Object> GetParentClassBefore( Class<Object> baseclass, Class<Object> highestclass )
{
Class<Object> step = baseclass;
while ( (step.GetParentClass() != highestclass) && step.GetParentClass() )
step = step.GetParentClass();
return step;
}
}