From ea7775119d18fc903324eea3c7e10ab2600c3c70 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sun, 21 Mar 2021 00:51:52 +0100 Subject: [PATCH] Add option to only allow one emergency reboot per map (enforced on nightmare difficulties). Make Elemental Coating shader less eye-straining. Leave "ashen remains" when a target is erased by the Ynykron. Fix crushers not breaking if player isn't taking damage. --- language.def_menu | 3 +- language.es_menu | 3 +- language.version | 4 +- menudef.txt | 2 +- modeldef.ynykron | 15 +++++ models/extra/BigBlast.png | Bin 0 -> 6268 bytes shaders/pp/Barrier.fp | 8 +-- zscript/swwm_player.zsc | 45 +++++++++++++- zscript/swwm_player_items.zsc | 42 +------------ .../weapons/swwm_deathlydeathcannon_fx.zsc | 57 +++++++++++++++++- 10 files changed, 128 insertions(+), 51 deletions(-) create mode 100644 models/extra/BigBlast.png diff --git a/language.def_menu b/language.def_menu index 6251d092e..6bb9d2fd3 100644 --- a/language.def_menu +++ b/language.def_menu @@ -106,6 +106,7 @@ SWWM_OTHERVOICE = "Co-op Voice"; SWWM_REVIVE = "Emergency Reboot System"; SWWM_REVIVECOOLDOWN = "Reboot Cooldown"; SWWM_UNLIMITED = "Unlimited"; +SWWM_ONERETRY = "One Retry"; SWWM_NONE = "None"; SWWM_INTERART = "Intermission Art"; SWWM_BALLUSE = "Lead Balls can Activate Switches"; @@ -280,7 +281,7 @@ TOOLTIP_SWWM_EARBUSTER = "The Wallbuster's firing sounds may be painfully loud a 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_OTHERVOICE = "Allows you to hear other player's voice lines, provided you're close enough."; 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."; +TOOLTIP_SWWM_REVIVECOOLDOWN = "Time in minutes 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_INTERART = "If enabled, displays randomly selected fanart during intermissions."; TOOLTIP_SWWM_BALLUSE = "Lead Ball projectiles can remotely activate use switches (excluding exits). Potentially OP."; TOOLTIP_SWWM_BOSSHEALTHBARS = "Show a healthbar for vanilla boss encounters at the bottom of the screen. Just like Dark Souls™!"; diff --git a/language.es_menu b/language.es_menu index 32fb57654..bae27d3ad 100644 --- a/language.es_menu +++ b/language.es_menu @@ -104,6 +104,7 @@ SWWM_OTHERVOICE = "Voz en Cooperativo"; SWWM_REVIVE = "Sistema de Reinicio de Emergencia"; SWWM_REVIVECOOLDOWN = "Tiempo de recarga de Reinicio"; SWWM_UNLIMITED = "Ilimitado"; +SWWM_ONERETRY = "Un Reintento"; SWWM_NONE = "Ninguno"; SWWM_INTERART = "Arte de Intermisión"; SWWM_BALLUSE = "Las Bolas de Plomo Activan Botones"; @@ -277,7 +278,7 @@ TOOLTIP_SWWM_EARBUSTER = "Los sonidos de disparo del Wallbuster pueden a veces s 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_OTHERVOICE = "Te permite oír los comentarios de voz de otros jugadores, si estás lo suficientemente cerca."; 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."; +TOOLTIP_SWWM_REVIVECOOLDOWN = "Tiempo en minutos 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_INTERART = "Si está activado, muestra fanart aleatorio durante intermisiones."; TOOLTIP_SWWM_BALLUSE = "Los proyectiles de Bola de Plomo pueden activar botones utilizables remotamente (excluyendo salidas). Potencialmente roto."; TOOLTIP_SWWM_BOSSHEALTHBARS = "Muestra una barra de vida para bosses vanilla en la parte inferior de la pantalla. ¡Es justo como Dark Souls™!"; diff --git a/language.version b/language.version index 5b501028f..233e41e2e 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r386 \cu(Sat 20 Mar 23:26:41 CET 2021)\c-"; -SWWM_SHORTVER="\cw0.9.11b-pre r386 \cu(2021-03-20 23:26:41)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r387 \cu(Sun 21 Mar 00:57:23 CET 2021)\c-"; +SWWM_SHORTVER="\cw0.9.11b-pre r387 \cu(2021-03-21 00:57:23)\c-"; diff --git a/menudef.txt b/menudef.txt index be086bb09..d65fdfdd0 100644 --- a/menudef.txt +++ b/menudef.txt @@ -85,7 +85,7 @@ OptionMenu "SWWMOptionMenu" Option "$SWWM_MUTELEVEL", "swwm_mutevoice", "SWWMVoice" Option "$SWWM_6DOF", "swwm_fly6dof", "YesNo" Option "$SWWM_REVIVE", "swwm_revive", "YesNo" - ScaleSlider "$SWWM_REVIVECOOLDOWN", "swwm_revivecooldown", 0, 300, 30, "$SWWM_UNLIMITED" + ScaleSlider "$SWWM_REVIVECOOLDOWN", "swwm_revivecooldown", -1, 5, 1, "$SWWM_UNLIMITED", "$SWWM_ONERETRY" Option "$SWWM_MENUPAUSE", "swwm_menupause", "YesNo" Option "$SWWM_PRECISECROSSHAIR", "swwm_precisecrosshair", "YesNo" StaticText " " diff --git a/modeldef.ynykron b/modeldef.ynykron index 0c4979648..3e7665704 100644 --- a/modeldef.ynykron +++ b/modeldef.ynykron @@ -1,3 +1,18 @@ +Model "AshenRemains" +{ + Path "models/extra" + + Model 0 "flat_d.3d" + Scale 0.1 0.1 0.1 + ZOffset 0.1 + USEACTORPITCH + USEACTORROLL + DONTCULLBACKFACES + + Skin 0 "BigBlast.png" + FrameIndex XZW1 A 0 0 +} + Model "YnykronBeam" { Path "models/extra" diff --git a/models/extra/BigBlast.png b/models/extra/BigBlast.png new file mode 100644 index 0000000000000000000000000000000000000000..e99c463bbb6feb5f5b2b4d644865e8495a5bfc7b GIT binary patch literal 6268 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 KKbLh*2~7ZBoG7jU literal 0 HcmV?d00001 diff --git a/shaders/pp/Barrier.fp b/shaders/pp/Barrier.fp index bbf995819..20b48ac05 100644 --- a/shaders/pp/Barrier.fp +++ b/shaders/pp/Barrier.fp @@ -7,14 +7,14 @@ void main() flood += texture(WarpTex,uv*sr*2.+vec2(-timer*.07,-timer*.13)).xy; flood += texture(WarpTex,uv*sr*.5+vec2(0.,-timer*.06)).xy; flood /= 3.; - vec3 col = texture(InputTexture,uv).rgb*3.; + vec3 col = texture(InputTexture,uv).rgb*6.; for ( int i=0; i<3; i++ ) { - uv = (uv*.985)+.005; - uv += (flood-.5)*.005; + uv = (uv*.995)+.0025; + uv += (flood-.5)*.003; col += texture(InputTexture,uv).rgb; } - col.rgb /= 5.; + col.rgb /= 8.; col.rgb = pow(max(col.rgb,vec3(0.)),vec3(1.2,1.15,.77))*vec3(1.03,1.32,.98); FragColor = vec4(col,1.); } diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index 5f0eb82b1..16ee5612f 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -22,6 +22,7 @@ Class Demolitionist : PlayerPawn SWWMStats mystats; int cairtime; bool hasteleported; + bool hasrevived; int lastmpain; @@ -1328,6 +1329,41 @@ Class Demolitionist : PlayerPawn } } } + private void CheckBreakCrusher() + { + double gaph = (ceilingz-floorz); + if ( gaph > height*.6 ) return; + // the smaller the gap, the more likely the crusher will snap + if ( Random[Demolitionist](0,3) && (FRandom[Demolitionist](0,gaph/height) > .1) ) return; + double diffh = 8.+(default.height-gaph); // how much the crusher will have to "snap" after breaking + let ceil = ceilingsector; + let flor = floorsector; + let ceilse = ceil.ceilingdata; + let florse = flor.floordata; + if ( ceilse && florse ) + { + // snap both planes + let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot))); + q.special1 = 6; + q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot))); + q.special1 = 6; + SWWMCrusherBroken.Create(flor,ceil,diffh/2.); + } + else if ( ceilse ) + { + // snap ceiling + let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot))); + q.special1 = 10; + SWWMCrusherBroken.Create(null,ceil,diffh); + } + else if ( florse ) + { + // snap floor + let q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot))); + q.special1 = 10; + SWWMCrusherBroken.Create(flor,null,diffh); + } + } override int DamageMobj( Actor inflictor, Actor source, int damage, Name mod, int flags, double angle ) { // we still have to ENSURE ENTIRELY that this gets nullified (TELEFRAG_DAMAGE overrides damage factors somehow) @@ -1338,6 +1374,9 @@ Class Demolitionist : PlayerPawn let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); if ( hnd ) hnd.tookdamage[PlayerNumber()] = true; } + // check if we can break any active crushers + if ( (mod == 'Crush') && !inflictor && !source ) + CheckBreakCrusher(); // no damage whatsoever if ( scriptedinvul ) return 0; @@ -1832,8 +1871,9 @@ Class Demolitionist : PlayerPawn else if ( (player.cmd.buttons&BT_ATTACK) && (deadtimer > 120) && swwm_revive ) { // reboot (if possible) - if ( !FindInventory("ReviveCooldown") ) + if ( !FindInventory("ReviveCooldown") && (((swwm_revivecooldown >= 0) && (G_SkillPropertyInt(SKILLP_ACSReturn) < 4)) || !hasrevived) ) { + hasrevived = true; player.Resurrect(); player.damagecount = 0; player.bonuscount = 0; @@ -1857,7 +1897,7 @@ Class Demolitionist : PlayerPawn SWWMHandler.DoFlash(self,Color(255,128,192,255),30); SWWMScoreObj.Spawn(default.health,Vec3Offset(FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8),FRandom[ScoreBits](-8,8)+Height/2),ST_Health); if ( special1 > 2 ) special1 = 0; - if ( swwm_revivecooldown > 0 ) + if ( (swwm_revivecooldown > 0) && (G_SkillPropertyInt(SKILLP_ACSReturn) < 4) ) GiveInventory("ReviveCooldown",1); } else if ( level.maptime > revivefail ) @@ -2429,6 +2469,7 @@ Class Demolitionist : PlayerPawn dashfuel = default.dashfuel; last_boost = 0; last_kick = 0; + hasrevived = false; // cancel dash/boost A_StopSound(CHAN_JETPACK); fuelcooldown = 0.; diff --git a/zscript/swwm_player_items.zsc b/zscript/swwm_player_items.zsc index 0cde432dd..86fa3135d 100644 --- a/zscript/swwm_player_items.zsc +++ b/zscript/swwm_player_items.zsc @@ -71,43 +71,7 @@ Class AlmasteelPlating : Inventory // 80% reduction for explosions if ( flags&DMG_EXPLOSION ) newdamage = newdamage/5; // 50% reduction for crushing - if ( damageType == 'Crush' ) - { - newdamage = newdamage/2; - // additionally, check if we can break any active crushers - double gaph = (Owner.ceilingz-Owner.floorz); - if ( gaph > Owner.height*.6 ) return; - // the smaller the gap, the more likely the crusher will snap - if ( Random[Demolitionist](0,3) && (FRandom[Demolitionist](0,gaph/Owner.height) > .1) ) return; - double diffh = 8.+(Owner.default.height-gaph); // how much the crusher will have to "snap" after breaking - let ceil = Owner.ceilingsector; - let flor = Owner.floorsector; - let ceilse = ceil.ceilingdata; - let florse = flor.floordata; - if ( ceilse && florse ) - { - // snap both planes - let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot))); - q.special1 = 6; - q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot))); - q.special1 = 6; - SWWMCrusherBroken.Create(flor,ceil,diffh/2.); - } - else if ( ceilse ) - { - // snap ceiling - let q = Spawn("BustedQuake",(ceil.centerspot.x,ceil.centerspot.y,ceil.ceilingplane.ZAtPoint(ceil.centerspot))); - q.special1 = 10; - SWWMCrusherBroken.Create(null,ceil,diffh); - } - else if ( florse ) - { - // snap floor - let q = Spawn("BustedQuake",(flor.centerspot.x,flor.centerspot.y,flor.floorplane.ZAtPoint(flor.centerspot))); - q.special1 = 10; - SWWMCrusherBroken.Create(flor,null,diffh); - } - } + if ( damageType == 'Crush' ) newdamage = newdamage/2; } override bool HandlePickup( Inventory item ) { @@ -142,7 +106,7 @@ Class ReviveCooldown : Powerup Default { Inventory.Icon "graphics/HUD/Icons/I_Revive.png"; - Powerup.Duration -30; + Powerup.Duration -60; } override void Tick() @@ -156,7 +120,7 @@ Class ReviveCooldown : Powerup { Super.InitEffect(); // adjust the duration - EffectTics = max(0,swwm_revivecooldown)*GameTicRate; + EffectTics = clamp(swwm_revivecooldown*60,0,300)*GameTicRate; } override void EndEffect() { diff --git a/zscript/weapons/swwm_deathlydeathcannon_fx.zsc b/zscript/weapons/swwm_deathlydeathcannon_fx.zsc index 7ca07fc1b..1ac470a61 100644 --- a/zscript/weapons/swwm_deathlydeathcannon_fx.zsc +++ b/zscript/weapons/swwm_deathlydeathcannon_fx.zsc @@ -1,5 +1,47 @@ // Ynykron projectiles and effects +// there was an enemy here, but it's gone now +Class AshenRemains : Actor +{ + override void Tick() + { + double fz = CurSector.floorplane.ZAtPoint(pos.xy); + if ( fz != pos.z ) SetOrigin((pos.x,pos.y,fz),true); + if ( isFrozen() ) return; + special1++; + if ( special1 > 350 ) A_FadeOut(0.01); + } + override void PostBeginPlay() + { + if ( (waterlevel > 0) || GetFloorTerrain().isliquid ) + { + Destroy(); + return; + } + double fz = CurSector.floorplane.ZAtPoint(pos.xy); + SetZ(fz); + prev.z = fz; + SWWMUtility.SetToSlope(self,FRandom[Ynykron](0,360)); + } + default + { + RenderStyle "Shaded"; + StencilColor "000000"; + Radius .1; + Height 0.; + +NOBLOCKMAP; + +NOINTERACTION; + +DONTSPLASH; + +NOTELEPORT; + } + States + { + Spawn: + XZW1 A -1; + Stop; + } +} + // cheap way to let players know they just got fucking erased from existence Class PlayerGone : PlayerChunk { @@ -360,7 +402,15 @@ Class YnykronImpact : Actor { // voodoo dolls just get erased (how convenient) // otherwise instantly vaporize the fucker - if ( tracer.player && (tracer.player.mo != tracer) ) tracer.Destroy(); + if ( tracer.player && (tracer.player.mo != tracer) ) + { + if ( tracer.pos.z < (tracer.floorz+64) ) + { + let r = Spawn("AshenRemains",tracer.pos); + r.scale *= tracer.radius/16.; + } + tracer.Destroy(); + } else if ( tracer.CountInv("GrilledCheeseSandwich") > 0 ) { // force use the sandwich @@ -382,6 +432,11 @@ Class YnykronImpact : Actor tracer.A_ChangeLinkFlags(true); // remove from blockmap, should guarantee archviles not raising this IDontFeelSoGood.DeletThis(tracer); // ensures corpse is deleted too } + if ( tracer.pos.z < (tracer.floorz+64) ) + { + let r = Spawn("AshenRemains",tracer.pos); + r.scale *= tracer.radius/16.; + } } } if ( YnykronShot(master) )