diff --git a/README.md b/README.md index f05ef49e5..f96d08f33 100644 --- a/README.md +++ b/README.md @@ -272,7 +272,7 @@ One mighty relic of the beginnings of **UnSX**. This beefy handcannon spews pote **Secondary fire:** Pumps more rounds into the gun, for extra potency *(up to 5x)*. Do note that the shot not only will become stronger, but also more unstable. -**Tertiary fire:** Switch the weapon stance, from two-handing to single-handing. You know, so you can give it a full-on spin like in the action movies. +**Tertiary fire:** Switch the weapon stance, from two-handing to one-handing. You know, so you can give it a full-on spin like in the action movies. **Reload:** Loads more rounds in reserve. diff --git a/decaldef.txt b/decaldef.txt index 5db06c8cb..d4d9841b0 100644 --- a/decaldef.txt +++ b/decaldef.txt @@ -251,6 +251,60 @@ decalgroup ShockMarkBig ShockMarkBig5 1 } +decal ShockMarkHuge1 +{ + pic shockmrk + shade "00 00 00" + randomflipx + randomflipy + x-scale 3.0 + y-scale 3.0 +} +decal ShockMarkHuge2 +{ + pic shockmk2 + shade "00 00 00" + randomflipx + randomflipy + x-scale 3.0 + y-scale 3.0 +} +decal ShockMarkHuge3 +{ + pic shockmk3 + shade "00 00 00" + randomflipx + randomflipy + x-scale 3.0 + y-scale 3.0 +} +decal ShockMarkHuge4 +{ + pic shockmk4 + shade "00 00 00" + randomflipx + randomflipy + x-scale 3.0 + y-scale 3.0 +} +decal ShockMarkHuge5 +{ + pic shockmk5 + shade "00 00 00" + randomflipx + randomflipy + x-scale 3.0 + y-scale 3.0 +} +decalgroup ShockMarkHuge +{ + ShockMarkHuge1 1 + ShockMarkHuge2 1 + ShockMarkHuge3 1 + ShockMarkHuge4 1 + ShockMarkHuge5 1 +} + decal BigBlast { pic bigblast diff --git a/gldefs.quadravol b/gldefs.quadravol index 6eefb2c93..3fd142e14 100644 --- a/gldefs.quadravol +++ b/gldefs.quadravol @@ -3,3 +3,14 @@ HardwareShader Texture "models/QuadLED.png" Shader "shaders/glsl/BrightCanvas.fp" Texture "scrtex" "QUADRLED" } + +PointLight QUADP1LIGHT +{ + Color 1.0 0.5 0.1 + Size 250 + Attenuate 1 +} +Object QuadProj +{ + Frame "QFBL" { light "QUADP1LIGHT" } +} diff --git a/language.def_base b/language.def_base index 8ec9a0125..40233a281 100644 --- a/language.def_base +++ b/language.def_base @@ -1089,7 +1089,7 @@ SWWM_INTERTIP181 = "Unlike the rapidly thrown quick grenades, the Explodium Gun' SWWM_INTERTIP182 = "The Sheen HMG sets the air on fire along each bullet's path, just from the sheer pressure of the cartridge used."; SWWM_INTERTIP183 = "The rare golden shells allow you to cause extreme destruction in a large radius. Just be careful not to stand too close."; SWWM_INTERTIP184 = "Be careful with your lead balls. They might ricochet back into your face and hurt real bad."; -SWWM_INTERTIP185 = "Once a target is set ablaze by the Quadravol's fireballs, the flames will rapidly spread to nearby targets as well."; +SWWM_INTERTIP185 = "Once you're set ablaze by the Quadravol, the quickest solution is to shake those flames off. Shame that your enemies aren't smart enough to know that."; SWWM_INTERTIP186 = "Somehow, the Quadravol can be used underwater. One has to wonder what those fireballs are made of."; SWWM_INTERTIP187 = "The Ray-Khom's alternate fire is lethal in contact with water. Do apply some common sense with this information."; SWWM_INTERTIP188 = "The Rafan-Kos can prepare a delicious cyberdemon roast in a matter of seconds."; diff --git a/language.es_base b/language.es_base index e8e6c5a91..0dd77fd33 100644 --- a/language.es_base +++ b/language.es_base @@ -972,7 +972,7 @@ SWWM_INTERTIP181 = "A diferencia de las granadas rápidas, el fuego secundario d SWWM_INTERTIP182 = "La Ametralladora Sheen incendia el aire al paso de cada bala, solo con la altísima presión de la munición que usa."; SWWM_INTERTIP183 = "Los poco comunes cartuchos dorados te permiten causar destrucción extrema en un radio amplio. Eso sí, ten cuidado de no estar demasiado cerca."; SWWM_INTERTIP184 = "Ten cuidado con tus bolas de plomo. Podrían rebotar y darte en la cara y eso duele mucho."; -SWWM_INTERTIP185 = "Una vez un objetivo ha sido incendiado por las bolas de fuego de la Quadravol, las llamas se propagarán rápidamente a otros objetivos cercanos también."; +SWWM_INTERTIP185 = "Una vez incendiado por la Quadravol, la solución más rápida es sacudirse fuera las llamas. Una pena que tus enemigos no sean tan listos como para saber eso."; SWWM_INTERTIP186 = "De alguna forma, la Quadravol puede usarse bajo el agua. Uno solo puede preguntarse de qué están hechas esas bolas de fuego."; SWWM_INTERTIP187 = "El fuego alternativo de la Ray-Khom es letal en contacto con el agua. Intenta aplicar el sentido común con esta información."; SWWM_INTERTIP188 = "La Rafan-Kos puede preparar un delicioso asado de ciberdemonio en cuestión de segundos."; diff --git a/language.version b/language.version index cac6197cc..9cb1abb1b 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r343 \cu(Thu 18 Aug 19:00:27 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r343 \cu(2022-08-18 19:00:27)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r344 \cu(Fri 19 Aug 00:59:11 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r344 \cu(2022-08-19 00:59:11)\c-"; diff --git a/modeldef.quadravol b/modeldef.quadravol index fe944155e..a5a30d3d8 100644 --- a/modeldef.quadravol +++ b/modeldef.quadravol @@ -57,6 +57,37 @@ Model "Quadravol" FrameIndex XZWZ O 2 107 } +Model "Quadravol" +{ + Path "models/extra" + Model 3 "Flat_d.3d" + Scale 0.1 0.1 0.1 + Offset 12 -60 -10 + RollOffset 90 + AngleOffset 90 + + Skin 3 "QuadMuz0.png" + FrameIndex XZW0 A 3 0 + Skin 3 "QuadMuz1.png" + FrameIndex XZW0 B 3 0 + Skin 3 "QuadMuz2.png" + FrameIndex XZW0 C 3 0 + Skin 3 "QuadMuz3.png" + FrameIndex XZW0 D 3 0 + Skin 3 "QuadMuz4.png" + FrameIndex XZW0 E 3 0 + Skin 3 "QuadMuz5.png" + FrameIndex XZW0 F 3 0 + Skin 3 "QuadMuz6.png" + FrameIndex XZW0 G 3 0 + Skin 3 "QuadMuz7.png" + FrameIndex XZW0 H 3 0 + Skin 3 "QuadMuz8.png" + FrameIndex XZW0 I 3 0 + Skin 3 "QuadMuz9.png" + FrameIndex XZW0 J 3 0 +} + Model "Quadravol" { Path "models" diff --git a/sndinfo.dlcweapons b/sndinfo.dlcweapons index 6a48db460..9e485fd1a 100644 --- a/sndinfo.dlcweapons +++ b/sndinfo.dlcweapons @@ -99,10 +99,12 @@ quadshot/hit1 sounds/dlc1/quadshot/quad_hit1.ogg quadshot/hit2 sounds/dlc1/quadshot/quad_hit2.ogg quadshot/hit3 sounds/dlc1/quadshot/quad_hit3.ogg $random quadshot/hit { quadshot/hit1 quadshot/hit2 quadshot/hit3 } +$limit quadshot/hit 16 quadshot/twohit1 sounds/dlc1/quadshot/quad_explo1.ogg quadshot/twohit2 sounds/dlc1/quadshot/quad_explo2.ogg quadshot/twohit3 sounds/dlc1/quadshot/quad_explo3.ogg $random quadshot/twohit { quadshot/twohit1 quadshot/twohit2 quadshot/twohit3 } +$limit quadshot/twohit 8 quadshot/extrahit sounds/dlc1/quadshot/quad_xexpl.ogg quadshot/pointblank sounds/dlc1/quadshot/quad_xxexpl.ogg quadshot/fly sounds/dlc1/quadshot/quad_fly.ogg diff --git a/zscript/dlc1/swwm_dlcweapons_hud.zsc b/zscript/dlc1/swwm_dlcweapons_hud.zsc index 0c5ed7202..475b1c067 100644 --- a/zscript/dlc1/swwm_dlcweapons_hud.zsc +++ b/zscript/dlc1/swwm_dlcweapons_hud.zsc @@ -94,7 +94,7 @@ extend Class Quadravol if ( chambered ) Screen.DrawTexture(BulletTex[charged],false,bx-14,by-10,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); Screen.DrawText(ChargeFont,Font.CR_UNTRANSLATED,bx-14,by-20,String.Format("%d",chargelevel),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); // PLACEHOLDER - String str = "THIS WEAPON IS NOT YET FUNCTIONAL"; + String str = "THIS WEAPON IS NOT YET FULLY IMPLEMENTED"; Screen.DrawText(NewSmallFont,Font.CR_RED,(Screen.GetWidth()-NewSmallFont.StringWidth(str)*CleanXFac_1)/2,Screen.GetHeight()-(swwm_hudmargin*hs+NewSmallFont.GetHeight()*CleanYFac_1),str,DTA_CleanNoMove_1,true); } } diff --git a/zscript/dlc1/swwm_notashotgun.zsc b/zscript/dlc1/swwm_notashotgun.zsc index 30bac7e2b..bce968990 100644 --- a/zscript/dlc1/swwm_notashotgun.zsc +++ b/zscript/dlc1/swwm_notashotgun.zsc @@ -76,6 +76,11 @@ Class Quadravol : SWWMWeapon else origin.A_StartSound(UpSound,CHAN_WEAPON,CHANF_OVERLAP); } + override Vector3 GetTraceOffset() + { + return (10,3,-2.5); + } + action State A_QuadFire() { static const String BaseNum[] = {"one","two","three","four","five"}; @@ -83,10 +88,62 @@ Class Quadravol : SWWMWeapon int idx = clamp(invoker.chargelevel-1,0,4); A_StartSound("quadshot/fire"..BaseNum[idx],CHAN_WEAPON,CHANF_OVERLAP); A_PlayerFire(); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + Vector3 origin = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz),10*x+3*y-2.5*z); + bool pointblank = false; + int rings = 1; + Vector3 dir; + for ( double i=0; i<.25; i+=.05 ) + { + for ( int j=0; j<360; j+=(360/rings) ) + { + dir = SWWMUtility.ConeSpread(x,y,z,j,i); + pointblank |= LineTrace(atan2(dir.y,dir.x),60,asin(-dir.z),TRF_ABSPOSITION|TRF_NOSKY,origin.z,origin.x,origin.y); + } + rings += 3; + } + Vector3 x2, y2, z2; + [x2, y2, z2] = swwm_CoordUtil.GetAxes(BulletSlope(),angle,roll); + double a, s; + Actor p; switch ( idx ) { case 0: - A_Log("\cg// TODO - Fire Level 1\c-"); + A_QuakeEx(3,3,3,15,0,10,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.4); + A_BumpFOV(.98); + A_SWWMFlash(); + SWWMHandler.DoFlash(self,Color(64,255,192,64),5); + A_AlertMonsters(swwm_uncapalert?0:2000); + SWWMUtility.DoKnockback(self,-x,1500.); + p = Spawn("QuadProj",origin); + p.target = self; + p.angle = atan2(x2.y,x2.x); + p.pitch = asin(-x2.z); + p.vel = x2*p.speed; + if ( pointblank ) + { + p.tracer = self; + p.special1 = 50; + p.special2 = 40000; + p.ExplodeMissile(null,null); + self.DamageMobj(invoker,self,40,'Fire',DMG_EXPLOSION); + } + for ( int i=0; i<4; i++ ) + { + let s = Spawn("SWWMSmoke",origin); + s.special1 = 1; + s.scale *= 1.3; + s.alpha *= .2; + s.vel += vel*.5+x*FRandom[Quadravol](5.,15.)+y*FRandom[Quadravol](-.5,.5)+z*FRandom[Quadravol](-.5,.5); + } + for ( int i=0; i<10; i++ ) + { + let s = Spawn("SWWMSpark",origin); + s.scale *= .3; + s.alpha *= .4; + s.vel += vel*.5+x*FRandom[Quadravol](4.,8.)+y*FRandom[Quadravol](-1.,1.)+z*FRandom[Quadravol](-1.,1.); + } break; case 1: A_Log("\cg// TODO - Fire Level 2\c-"); @@ -271,12 +328,13 @@ Class Quadravol : SWWMWeapon } FireOne: XZW2 A 1; - XZW3 OPQR 2; - XZW3 STUV 3; + XZW3 OPQR 1; + XZW3 STUV 2; Goto Ready; FireTwo: XZW2 A 1; - XZW3 WXYZ 2; + XZW3 WX 1; + XZW3 YZ 2; XZW4 ABCD 3; Goto Ready; FireThree: @@ -287,13 +345,15 @@ Class Quadravol : SWWMWeapon FireFour: XZW2 A 1; XZW4 MNOP 2; - XZW4 QRST 3; + XZW4 QR 3; + XZW4 ST 4; Goto Ready; FireFive: XZW2 A 1; - XZW4 UVWX 2; - XZW4 YZ 3; - XZW5 AB 3; + XZW4 UV 2; + XZW4 WX 3; + XZW4 YZ 4; + XZW5 AB 5; Goto Ready; AltFire: XZW2 A 2 A_PlayerCheckGun(); @@ -367,6 +427,15 @@ Class Quadravol : SWWMWeapon XZW2 BCDEFGHIJKLMNOPQR 1; XZW2 R -1 A_FullLower(); Stop; + Flash: + XZW0 A 2 Bright + { + let psp = player.GetPSprite(PSP_FLASH); + psp.frame = Random[GunFlash](0,9); + let l = Spawn("SWWMWeaponLight",pos); + l.target = self; + } + Stop; // TODO one-handed states } } diff --git a/zscript/dlc1/swwm_notashotgun_fx.zsc b/zscript/dlc1/swwm_notashotgun_fx.zsc index 2fd0d64b8..a77b457b1 100644 --- a/zscript/dlc1/swwm_notashotgun_fx.zsc +++ b/zscript/dlc1/swwm_notashotgun_fx.zsc @@ -13,6 +13,321 @@ Class QuadravolCasing : SWWMCasing } } +Class QuadExplLight : PaletteLight +{ + Default + { + Tag "QuadExpl"; + Args 0,0,0,150; + ReactionTime 20; + } +} + +Class QuadFlare : Actor +{ + bool bBig; + + Default + { + RenderStyle "Add"; + Radius .1; + Height 0.; + Alpha .5; + +NOGRAVITY; + +NOBLOCKMAP; + +DONTSPLASH; + +NOTELEPORT; + +FORCEXYBILLBOARD; + +NOINTERACTION; + } + + override void Tick() + { + if ( isFrozen() ) return; + if ( !master || !master.bMISSILE ) + { + if ( !bBig ) + { + bBig = true; + Scale *= 3.; + } + Scale *= .97; + A_FadeOut(.03); + return; + } + SetOrigin(master.pos,true); + } + + States + { + Spawn: + QFLR A -1 Bright; + Stop; + } +} + +Class QuadTrail : Actor +{ + Default + { + RenderStyle "Add"; + Radius .1; + Height 0.; + Alpha .5; + Scale 1.5; + +NOBLOCKMAP; + +NOGRAVITY; + +NOTELEPORT; + +FORCEXYBILLBOARD; + +ROLLSPRITE; + +ROLLCENTER; + +DONTSPLASH; + +NOINTERACTION; + } + override void PostBeginPlay() + { + Super.PostBeginPlay(); + Scale.x *= RandomPick[ExploS](-1,1); + Scale.y *= RandomPick[ExploS](-1,1); + roll = FRandom[ExploS](0,360); + SetState(SpawnState+Random[ExploS](0,19)); + } + action void A_Flame() + { + vel *= .9; + A_SetScale(scale.x*.96); + A_FadeOut(.05); + } + override void Tick() + { + if ( isFrozen() ) return; + SetOrigin(level.Vec3Offset(pos,vel),true); + if ( !CheckNoDelay() || (tics == -1) ) return; + if ( tics > 0 ) tics--; + while ( !tics ) + { + if ( !SetState(CurState.NextState) ) + return; + } + } + States + { + Spawn: + XFLM ABCDEFGHIJKLMNOPQRST 1 Bright A_Flame(); + Loop; + } +} + +Class QuadEmber : Actor +{ + Vector3 freq, amp, ph; + + Default + { + RenderStyle "Add"; + Radius .1; + Height 0; + Scale .3; + +NOBLOCKMAP; + +NOGRAVITY; + +DONTSPLASH; + +FORCEXYBILLBOARD; + +NOTELEPORT; + +NOINTERACTION; + } + override void PostBeginPlay() + { + Scale *= FRandom[ExploS](.5,1.5); + double ang = FRandom[ExploS](0,360), + pt = FRandom[ExploS](-90,90); + vel = SWWMUtility.Vec3FromAngles(ang,pt)*FRandom[ExploS](4.,8.); + freq = (FRandom[ExploS](.5,3.),FRandom[ExploS](.5,3.),FRandom[ExploS](.5,3.)); + amp = (FRandom[ExploS](.5,2.),FRandom[ExploS](.5,2.),FRandom[ExploS](.5,2.)); + ph = (FRandom[ExploS](0.,360.),FRandom[ExploS](0.,360.),FRandom[ExploS](0.,360.)); + specialf1 = FRandom[ExploS](.98,.99); + specialf2 = FRandom[ExploS](.98,.99); + } + override void Tick() + { + prev = pos; + if ( isFrozen() ) return; + if ( !InStateSequence(CurState,FindState("Death")) ) + { + vel *= .95; + vel += .2*(sin(ph.x)*amp.x,sin(ph.y)*amp.y,sin(ph.z)*amp.z); + vel.z -= .05*clamp(2.-amp.length(),0.,2.); + ph.x += freq.x*(360./GameTicRate); + ph.y += freq.y*(360./GameTicRate); + ph.z += freq.z*(360./GameTicRate); + freq *= specialf1; + amp *= specialf2; + Vector3 newpos = level.Vec3Offset(pos,vel); + if ( !level.IsPointInLevel(newpos) ) + { + vel *= 0; + SetStateLabel("Death"); + return; + } + SetOrigin(newpos,true); + UpdateWaterLevel(); + if ( waterlevel > 0 ) + { + vel *= 0; + SetStateLabel("Death"); + return; + } + A_FadeOut(FRandom[ExploS](.002,.005)); + } + else A_FadeOut(FRandom[ExploS](.02,.05)); + frame = clamp(int(round(4-alpha*4)),0,4); + if ( tics > 0 ) tics--; + while ( !tics ) + { + if ( !SetState(CurState.NextState) ) + return; + } + } + States + { + Spawn: + QEMB # -1 Bright; + Stop; + Death: + QEMB # -1 Bright; + Stop; + } +} + +Class QuadProj : Actor +{ + double drift, accelrate, maxspeed; + + Property Drift: drift; + Property AccelRate: accelrate; + Property MaxSpeed: maxspeed; + + override void PostBeginPlay() + { + Super.PostBeginPlay(); + A_StartSound("quadshot/fly",CHAN_BODY,CHANF_LOOP); + let t = Spawn("QuadFlare",pos); + t.master = self; + t.scale = scale*2.; + } + + // acceleration, drift and speed limit + void A_QuadMove() + { + A_QuadTrail(); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + double a = FRandom[Quadravol](0.,360.), s = FRandom[Quadravol](0.,drift); + vel += x*(accelrate/GameTicRate); + vel += SWWMUtility.CircleOffset(y,z,a,s); + double magvel = vel.length(); + Vector3 dir = (magvel<=0.)?x:(vel/magvel); + if ( magvel > maxspeed ) magvel = maxspeed; + vel = dir*magvel; + speed = magvel; + } + + virtual void A_QuadTrail() + { + let s = Spawn("QuadTrail",pos); + s.scale *= .6; + s.vel = vel*.2; + s = Spawn("SWWMHalfSmoke",pos); + s.vel = (FRandom[Quadravol](-.4,.4),FRandom[Quadravol](-.4,.4),FRandom[Quadravol](-.4,.4)); + s.vel += vel*.3; + s.alpha *= .4; + int numpt = Random[Quadravol](5,15); + for ( int i=0; i 0 ) { let c = victim.Spawn("OnFireTrail",pos); - c.scale *= max(.3,mult*.5); + c.scale *= max(.35,mult*.6); c.vel = victim.vel*.5+SWWMUtility.Vec3FromAngles(ang,pt)*FRandom[FlameT](.5,2.)*c.scale.x; } + if ( Random[FlameT](0,2) ) continue; let s = victim.Spawn("SWWMHalfSmoke",pos); - s.scale *= max(1.,1.6*mult); - s.alpha *= min(amount+30,100)*.02; + s.scale *= max(.5,mult*.75); + s.alpha *= min(amount+30,100)*.005; s.vel = victim.vel*.5+SWWMUtility.Vec3FromAngles(ang,pt)*FRandom[FlameT](.2,.6)*s.scale.x; } - // spread to nearby actors - let bt = BlockThingsIterator.Create(victim); + // this is too expensive, it has to go + /*let bt = BlockThingsIterator.Create(victim); while ( bt.Next() ) { let t = bt.Thing; @@ -123,7 +446,15 @@ Class OnFire : Thinker } else Apply(t,instigator,amt); } - bt.Destroy(); + bt.Destroy();*/ + // damage nearby actors instead + Actor inflictor = instigator; + if ( instigator ) + { + let q = instigator.FindInventory("Quadravol"); + if ( q ) inflictor = q; + } + SWWMUtility.DoExplosion(victim,clamp(int(amount*.15),1,50),0,victim.radius+40+amount/5,0,DE_NOBLEED|DE_NOSPLASH|DE_HOWL,'Fire',instigator,DMG_THRUSTLESS,instigator,inflictor); } static OnFire Apply( Actor victim, Actor instigator, int amount ) @@ -176,7 +507,7 @@ Class OnFireTrail : Actor Scale.x *= RandomPick[ExploS](-1,1); Scale.y *= RandomPick[ExploS](-1,1); roll = FRandom[ExploS](0,360); - SetState(SpawnState+Random[ExploS](0,19)); + SetState(SpawnState+Random[ExploS](0,39)); } action void A_Flame() { @@ -186,18 +517,19 @@ Class OnFireTrail : Actor else { vel *= .98; - vel.z += .1+.4*abs(scale.x); + vel.z += .1+.2*abs(scale.x); } if ( !Random[FlameT](0,int(40*(default.alpha-alpha))) ) { let s = Spawn("SWWMHalfSmoke",pos); s.vel = (FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2),FRandom[FlameT](-.2,.2)); s.vel += vel*.3; - s.alpha *= alpha*4; - s.scale *= .5+abs(scale.x)*(.5+special1/6.); + s.alpha *= alpha*.5; + s.scale *= .5+abs(scale.x*2)*(.5+special1/6.); + s.special1 = 1; } - A_SetScale(scale.x*.98); - A_FadeOut(.005); + A_SetScale(scale.x*.98,scale.y*.98); + A_FadeOut(.01); } override void Tick() { @@ -212,14 +544,18 @@ Class OnFireTrail : Actor return; } } + override bool CanCollideWith( Actor Other, bool passive ) + { + return false; + } Default { RenderStyle "Add"; Speed 2; - Radius 4; + Radius 2; Height 4; - Alpha .15; - Scale .3; + Alpha .3; + Scale .6; +NOBLOCKMAP; +NOGRAVITY; +NOTELEPORT; @@ -228,11 +564,12 @@ Class OnFireTrail : Actor +ROLLCENTER; +DONTSPLASH; +NOINTERACTION; + +MBFBOUNCER; } States { Spawn: - XFLM ABCDEFGHIJKLMNOPQRST 1 Bright A_Flame(); + XFLM AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTT 1 Bright A_Flame(); Loop; } } diff --git a/zscript/kbase/swwm_kbase.zsc b/zscript/kbase/swwm_kbase.zsc index 00b82fdd2..a7b946d43 100644 --- a/zscript/kbase/swwm_kbase.zsc +++ b/zscript/kbase/swwm_kbase.zsc @@ -311,7 +311,12 @@ Class DemolitionistMenu : GenericMenu override void Ticker() { Super.Ticker(); - if ( ((gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || isclosing) && (animtimer <= 0.) ) + if ( (players[consoleplayer].Health <= 0) && !isclosing ) + { + MenuSound("menu/democlose"); + isclosing = true; + } + if ( (gamestate != GS_LEVEL) || (isclosing && (animtimer <= 0.)) ) { // ded (or force close) DoClose(); diff --git a/zscript/swwm_thinkers_player.zsc b/zscript/swwm_thinkers_player.zsc index 93a42b5fb..72f0da233 100644 --- a/zscript/swwm_thinkers_player.zsc +++ b/zscript/swwm_thinkers_player.zsc @@ -173,6 +173,7 @@ Class SWWMStats : SWWMStaticThinker else if ( (inflictor is 'EvisceratorChunk') || (inflictor is 'EvisceratorProj') ) which = 'Eviscerator'; else if ( inflictor is 'SheenTrail' ) which = 'HeavyMahSheenGun'; else if ( (inflictor is 'HellblazerMissile') || (inflictor is 'HellblazerRavagerArm') || (inflictor is 'HellblazerWarheadArm') ) which = 'Hellblazer'; + else if ( (inflictor is 'QuadProj') || ((inflictor is 'Demolitionist') && (DamageType == 'Fire')) ) which = 'Quadravol'; // second one is a hack for fire effects else if ( (inflictor is 'BigBiospark') || (inflictor is 'BiosparkBall') || (inflictor is 'BiosparkBeamImpact') || (inflictor is 'BiosparkComboImpact') || (inflictor is 'BiosparkComboImpactSub') || (inflictor is 'BiosparkBeam') || (inflictor is 'BiosparkArc') || (inflictor is 'BiosparkCore') ) which = 'Sparkster'; else if ( (inflictor is 'SilverAirRip') || (inflictor is 'SilverAirRip2') || (inflictor is 'SilverImpact') || (inflictor is 'FatChodeImpact') || (inflictor is 'FatChodeExplosionArm') ) which = 'SilverBullet'; else if ( (inflictor is 'CandyBeam') || (inflictor is 'CandyPop') || (inflictor is 'CandyMagArm') || (inflictor is 'CandyGunProj') || (inflictor is 'CandyMagProj') || (inflictor is 'CandyBulletImpact') ) which = 'CandyGun'; diff --git a/zscript/utility/swwm_utility.zsc b/zscript/utility/swwm_utility.zsc index 3fb9897b0..2ca010a7f 100644 --- a/zscript/utility/swwm_utility.zsc +++ b/zscript/utility/swwm_utility.zsc @@ -12,7 +12,8 @@ enum EDoExplosionFlags DE_COUNTENEMIES = 128, // only count hits for hostiles DE_COUNTSTEALTH = 256, // only count hits for inactive monsters DE_COUNTFHKILLS = 512, // only count kills for enemies that were at full health - DE_NOHURTFRIEND = 1024 // splash damage will not affect allies + DE_NOHURTFRIEND = 1024, // splash damage will not affect allies + DE_QUADRAVOL = 2048 // splash burn from a Quadravol projectile, so it'll ignite enemies instead of dealing damage }; enum EExitType @@ -1185,7 +1186,7 @@ Class SWWMUtility // complete spherical and more accurate replacement of A_Explode // 100% free of the buggery GZDoom's own splash damage has // returns the number of shootables hit/killed - static play int, int DoExplosion( Actor Source, double Damage, double MomentumTransfer, double ExplosionRadius, double FullDamageRadius = 0., int flags = 0, Name DamageType = '', Actor ignoreme = null, int dmgflags = 0 ) + static play int, int DoExplosion( Actor Source, double Damage, double MomentumTransfer, double ExplosionRadius, double FullDamageRadius = 0., int flags = 0, Name DamageType = '', Actor ignoreme = null, int dmgflags = 0, Actor realsource = null, Actor realinflictor = null ) { // debug, display radius sphere if ( swwm_debugblast ) @@ -1202,7 +1203,7 @@ Class SWWMUtility } if ( !(flags&DE_NOSPLASH) ) Source.CheckSplash(ExplosionRadius); double brange = 1./(ExplosionRadius-FullDamageRadius); - Actor Instigator = (flags&DE_NOTMISSILE)?Source:Source.target; + Actor Instigator = realsource?realsource:(flags&DE_NOTMISSILE)?Source:Source.target; BlockThingsIterator bi = BlockThingsIterator.Create(Source,ExplosionRadius); int nhit = 0, nkill = 0; bool haskilled = false; @@ -1262,10 +1263,15 @@ Class SWWMUtility bool hostile = (Instigator&&a.IsHostile(Instigator)&&(a.bISMONSTER||a.player)); if ( (!(flags&DE_COUNTENEMIES) || hostile) && (!(flags&DE_COUNTSTEALTH) || inactive) ) nhit++; int dmg = int(Damage*damagescale); + if ( flags&DE_QUADRAVOL ) + { + OnFire.Apply(a,Instigator,dmg); // ignite + continue; + } if ( dmg <= 0 ) continue; // no harm int oldhp = a.Health; int basehp = a.GetSpawnHealth(); - int ndmg = a.DamageMobj(Source,Instigator,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION|dmgflags,atan2(-dir.y,-dir.x)); + int ndmg = a.DamageMobj(realinflictor?realinflictor:Source,Instigator,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION|dmgflags,atan2(-dir.y,-dir.x)); if ( a && !(flags&DE_NOBLEED) ) a.TraceBleed((ndmg>0)?ndmg:dmg,Source); if ( (flags&DE_HOWL) && a && (a.Health > 0) && a.bISMONSTER && !Random[DoBlast](0,3) ) a.Howl(); if ( hostile && (!a || (a.Health <= 0)) ) haskilled = true; @@ -1347,10 +1353,15 @@ Class SWWMUtility bool hostile = (Instigator&&a.IsHostile(Instigator)&&(a.bISMONSTER||a.player)); if ( (!(flags&DE_COUNTENEMIES) || hostile) && (!(flags&DE_COUNTSTEALTH) || inactive) ) nhit++; int dmg = int(Damage*damagescale); + if ( flags&DE_QUADRAVOL ) + { + OnFire.Apply(a,Instigator,dmg); // ignite + continue; + } if ( dmg <= 0 ) continue; // no harm int oldhp = a.Health; int basehp = a.GetSpawnHealth(); - int ndmg = a.DamageMobj(Source,Instigator,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION|dmgflags,atan2(-dir.y,-dir.x)); + int ndmg = a.DamageMobj(realinflictor?realinflictor:Source,Instigator,dmg,(DamageType=='')?Source.DamageType:DamageType,DMG_EXPLOSION|dmgflags,atan2(-dir.y,-dir.x)); if ( a && !(flags&DE_NOBLEED) ) a.TraceBleed((ndmg>0)?ndmg:dmg,Source); if ( (flags&DE_HOWL) && a && (a.Health > 0) && a.bISMONSTER && !Random[DoBlast](0,3) ) a.Howl(); if ( hostile && (!a || (a.Health <= 0)) ) haskilled = true; @@ -1424,6 +1435,7 @@ Class SWWMUtility if ( a is 'EvisceratorChunk' ) return true; if ( a is 'EvisceratorProj' ) return true; if ( a is 'HellblazerMissile' ) return true; + if ( a is 'QuadProj' ) return true; if ( a is 'BigBiospark' ) return true; if ( a is 'BiosparkBall' ) return true; if ( a is 'BiosparkCore' ) return true; diff --git a/zscript/weapons/swwm_blazeit_fx.zsc b/zscript/weapons/swwm_blazeit_fx.zsc index 1f532411a..ff0971945 100644 --- a/zscript/weapons/swwm_blazeit_fx.zsc +++ b/zscript/weapons/swwm_blazeit_fx.zsc @@ -369,7 +369,7 @@ Class HellblazerMissile : Actor s.scale *= FRandom[Hellblazer](0.9,1.8); } Spawn("HellblazerRing",pos); - if ( swwm_omnibust ) BusterWall.ProjectileBust(self,250,SWWMUtility.Vec3FromAngles(angle,pitch)); + if ( swwm_omnibust ) BusterWall.ProjectileBust(self,320,SWWMUtility.Vec3FromAngles(angle,pitch)); } void A_SubExpl( double xscale = 1. ) @@ -479,7 +479,7 @@ Class HellblazerCrackshot : HellblazerMissile c.ReactionTime += Random[Hellblazer](-10,10); HellblazerClusterMini(c).A_Steer(tracer); } - if ( swwm_omnibust ) BusterWall.ProjectileBust(self,200,SWWMUtility.Vec3FromAngles(angle,pitch)); + if ( swwm_omnibust ) BusterWall.ProjectileBust(self,250,SWWMUtility.Vec3FromAngles(angle,pitch)); } States diff --git a/zscript/weapons/swwm_danmaku.zsc b/zscript/weapons/swwm_danmaku.zsc index 5563814e1..adc5ef773 100644 --- a/zscript/weapons/swwm_danmaku.zsc +++ b/zscript/weapons/swwm_danmaku.zsc @@ -524,7 +524,7 @@ Class Eviscerator : SWWMWeapon XZWB ABC 2; Goto ReadyExt; Flash: - XZWZ A 2 + XZWZ A 2 Bright { let psp = player.GetPSprite(PSP_FLASH); psp.frame = Random[GunFlash](0,3); @@ -533,7 +533,7 @@ Class Eviscerator : SWWMWeapon } Stop; AltFlash: - XZWZ A 2 + XZWZ A 2 Bright { let psp = player.GetPSprite(PSP_FLASH); psp.frame = Random[GunFlash](4,7); diff --git a/zscript/weapons/swwm_splode.zsc b/zscript/weapons/swwm_splode.zsc index 0c838890e..85ee4b91d 100644 --- a/zscript/weapons/swwm_splode.zsc +++ b/zscript/weapons/swwm_splode.zsc @@ -553,7 +553,7 @@ Class ExplodiumGun : SWWMWeapon XZW2 B -1 A_FullLower(); Stop; Flash: - XZWZ A 2 + XZWZ A 2 Bright { let psp = player.GetPSprite(PSP_FLASH); psp.frame = Random[GunFlash](0,9); @@ -1176,7 +1176,7 @@ Class DualExplodiumGun : SWWMWeapon XZWB B 2; Stop; Flash: - XZWZ A 2 + XZWZ A 2 Bright { let psp = player.GetPSprite(PSP_FLASH); psp.frame = Random[GunFlash](0,9); @@ -1185,7 +1185,7 @@ Class DualExplodiumGun : SWWMWeapon } Stop; LeftFlash: - XZWZ K 2 + XZWZ K 2 Bright { let psp = player.GetPSprite(PSP_FLASH+1); psp.frame = Random[GunFlash](10,19); diff --git a/zscript/weapons/swwm_tastytreat.zsc b/zscript/weapons/swwm_tastytreat.zsc index 341d31663..a048dc325 100644 --- a/zscript/weapons/swwm_tastytreat.zsc +++ b/zscript/weapons/swwm_tastytreat.zsc @@ -689,7 +689,7 @@ Class CandyGun : SWWMWeapon XZWE U -1 A_FullLower(); Stop; Flash: - XZWZ A 2 + XZWZ A 2 Bright { let psp = player.GetPSprite(PSP_FLASH); psp.frame = Random[GunFlash](0,9);