diff --git a/gldefs.pp b/gldefs.pp index 7cf061c5b..7a05e92c8 100644 --- a/gldefs.pp +++ b/gldefs.pp @@ -37,6 +37,13 @@ HardwareShader PostProcess beforebloom Uniform vec2 CenterSpot } HardwareShader PostProcess beforebloom +{ + Name "WindBlur" + Shader "shaders/pp/WindBlur.fp" 330 + Uniform float Speed + Uniform float Fade +} +HardwareShader PostProcess beforebloom { Name "SilverScope" Shader "shaders/pp/SilverScope.fp" 330 diff --git a/language.def_voice b/language.def_voice index b23b7eec9..edfea0180 100644 --- a/language.def_voice +++ b/language.def_voice @@ -413,6 +413,8 @@ SWWM_SUBS_DEFAULT_BUTTONPUSH2 = "Boop."; SWWM_SUBS_DEFAULT_BUTTONPUSH3 = "Bop."; // Fall "scream" SWWM_SUBS_DEFAULT_FALLING = "Wheeeeeeeeeee~!"; +// Duplicate for hammer spin +SWWM_SUBS_DEFAULT_SPINNING = "$$SWWM_SUBS_DEFAULT_FALLING"; /// Special kill messages (rare) // Buttslam SWWM_SUBS_DEFAULT_NASSKILL = "3"; diff --git a/language.version b/language.version index 3f50bb72c..f02d9ed7b 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r297 \cu(Thu 11 Aug 16:24:23 CEST 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r297 \cu(2022-08-11 16:24:23)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r299 \cu(Thu 11 Aug 16:25:01 CEST 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r299 \cu(2022-08-11 16:25:01)\c-"; diff --git a/modeldef.hammer b/modeldef.hammer index c9a70de2a..586be1bd4 100644 --- a/modeldef.hammer +++ b/modeldef.hammer @@ -192,7 +192,7 @@ Model "ItamexHammer" FrameIndex XZW7 X 1 158 FrameIndex XZW7 Y 1 159 FrameIndex XZW7 Z 1 160 - FrameIndex XZW8 A 1 161 + FrameIndex XZW8 A 1 161 // RotationSnap FrameIndex XZW8 B 1 162 FrameIndex XZW8 C 1 163 FrameIndex XZW8 D 1 164 diff --git a/models/CombatHammer1st.blend b/models/CombatHammer1st.blend index f5ef49e53..a36abde7f 100644 Binary files a/models/CombatHammer1st.blend and b/models/CombatHammer1st.blend differ diff --git a/models/CombatHammer1st_a.3d b/models/CombatHammer1st_a.3d index 383230787..11e5ffe3d 100644 Binary files a/models/CombatHammer1st_a.3d and b/models/CombatHammer1st_a.3d differ diff --git a/models/CombatHammer1st_d.3d b/models/CombatHammer1st_d.3d index 6852eab1b..2456a7c74 100644 Binary files a/models/CombatHammer1st_d.3d and b/models/CombatHammer1st_d.3d differ diff --git a/shaders/pp/WindBlur.fp b/shaders/pp/WindBlur.fp new file mode 100644 index 000000000..0e9fa08f5 --- /dev/null +++ b/shaders/pp/WindBlur.fp @@ -0,0 +1,19 @@ +// simple linear wind blur effect for hammer spin + +void main() +{ + vec4 res = vec4(0.); + float d = Speed*.002; + float w = 1.2; + vec2 s = TexCoord; + float sum = 0.; + for ( int i=0; i<64; i++ ) + { + res += w*texture(InputTexture,s); + sum += w; + w *= .95; + s.x -= d; + } + res /= sum; + FragColor = mix(texture(InputTexture,TexCoord),vec4(res.rgb,1.),Fade*.75); +} diff --git a/sndinfo.defvoice b/sndinfo.defvoice index 43dcc58b6..493ddbe7d 100644 --- a/sndinfo.defvoice +++ b/sndinfo.defvoice @@ -389,6 +389,7 @@ voice/default/buttonpush1 sounds/voice/default/va/demobuttonpush1.ogg voice/default/buttonpush2 sounds/voice/default/va/demobuttonpush2.ogg voice/default/buttonpush3 sounds/voice/default/va/demobuttonpush3.ogg voice/default/falling sounds/voice/default/va/demofalling.ogg +$alias voice/default/spinning voice/default/falling voice/default/asskill1 sounds/voice/default/va/demoasskill1.ogg voice/default/asskill2 sounds/voice/default/va/demoasskill2.ogg voice/default/asskill3 sounds/voice/default/va/demoasskill3.ogg diff --git a/zscript/dlc1/swwm_dlcweapons_hud.zsc b/zscript/dlc1/swwm_dlcweapons_hud.zsc index 2945bade8..60a8ce0a3 100644 --- a/zscript/dlc1/swwm_dlcweapons_hud.zsc +++ b/zscript/dlc1/swwm_dlcweapons_hud.zsc @@ -1,5 +1,23 @@ // DrawWeapon code for DLC weapons +// Combat Hammer +extend Class ItamexHammer +{ + ui TextureID WeaponBox, BarTex; + + override void DrawWeapon( double TicFrac, double bx, double by, double hs, Vector2 ss ) + { + if ( !WeaponBox ) WeaponBox = TexMan.CheckForTexture("graphics/HUD/ItamexDisplay.png",TexMan.Type_Any); + if ( !BarTex ) BarTex = TexMan.CheckForTexture("graphics/HUD/ItamexBar.png",TexMan.Type_Any); + double ct = clamp(ChargeInter?ChargeInter.GetValue(TicFrac):charge,0.,100.); + if ( ct <= 0 ) return; + double ch = ct*.2; + Screen.DrawTexture(WeaponBox,false,bx-8,by-25,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); + Screen.DrawTexture(BarTex,false,bx-5,by-(2+ch),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcHeight,ch,DTA_DestHeightF,ch,DTA_ColorOverlay,Color(255,0,0,0)); + Screen.DrawTexture(BarTex,false,bx-6,by-(2+ch),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_SrcHeight,ch,DTA_DestHeightF,ch); + } +} + // Sheen HMG extend Class HeavyMahSheenGun { diff --git a/zscript/dlc1/swwm_hammertime.zsc b/zscript/dlc1/swwm_hammertime.zsc index 4fbd7b9de..57dfb94c9 100644 --- a/zscript/dlc1/swwm_hammertime.zsc +++ b/zscript/dlc1/swwm_hammertime.zsc @@ -4,24 +4,124 @@ Class ItamexHammer : SWWMWeapon { double charge; + int hitcnt, spintime; + transient ui SmoothDynamicValueInterpolator ChargeInter; - action State A_HammerHit() + override void HudTick() + { + Super.HudTick(); + if ( !ChargeInter ) ChargeInter = SmoothDynamicValueInterpolator.Create(charge,.5,1.,25.); + ChargeInter.Update(charge); + } + + action State A_HammerHit( bool nojump = false ) { Vector3 x, y, z; [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); SWWMUtility.DoKnockback(self,x,120000.); - if ( A_Melee(100,"itamex/hit",1.5,1.1,2.,MELEE_Rip|MELEE_FleshSound) ) + if ( A_Melee(100,"itamex/hit",1.5,1.1,2.,MELEE_Rip|MELEE_FleshSound|MELEE_HammerHit) ) { A_BumpFOV(.9); A_QuakeEx(5,5,5,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.35); A_AlertMonsters(swwm_uncapalert?0:800); - return ResolveState("FireHit"); + return nojump?ResolveState(null):ResolveState("FireHit"); } A_BumpFOV(.95); A_QuakeEx(1,1,1,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1); return ResolveState(null); } + override void DoEffect() + { + Super.DoEffect(); + if ( !Owner && !Owner.player && (Owner.player.ReadyWeapon != self) ) return; + let psp = Owner.player.FindPSprite(PSP_WEAPON); + if ( !psp ) return; + if ( Owner.IsActorPlayingSound(CHAN_WEAPONEXTRA,"itamex/spin") ) + psp.x += charge*.05; + psp.x *= .8; + } + + action void A_ChargeUp() + { + A_SetAngle(angle+invoker.charge*.2,SPF_INTERPOLATE); + A_SetPitch(pitch*.9,SPF_INTERPOLATE); + invoker.charge = min(100.,invoker.charge+20.); + if ( !IsActorPlayingSound(CHAN_WEAPONEXTRA,"itamex/spin") ) + A_StartSound("itamex/spin",CHAN_WEAPONEXTRA,CHANF_LOOP,.2); + A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5); + A_BumpFOV(1.+invoker.charge*.001); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMUtility.DoKnockback(self,x,2000.*invoker.charge); + invoker.hitcnt = 0; + invoker.spintime = 0; + } + + action void A_SpinReact() + { + if ( Random[Demolitionist](0,1) ) return; + if ( SWWMHandler.AddOneliner("spinning",2,5) ) + Demolitionist(self).facegrin = true; + } + + action State A_SpinMove() + { + A_SetAngle(angle+invoker.charge*.4,SPF_INTERPOLATE); + A_SetPitch(pitch*.9,SPF_INTERPOLATE); + invoker.charge = max(30.,invoker.charge-1.); + if ( (player.cmd.buttons&BT_ZOOM) && !(player.oldbuttons&BT_ZOOM) ) + invoker.charge = min(100.,invoker.charge+50.); + A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5); + A_BumpFOV(1.+invoker.charge*.001); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMUtility.DoKnockback(self,(cos(angle),sin(angle),.004),3000.*invoker.charge); + A_QuakeEx(1,1,1,15,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.1); + invoker.spintime++; + if ( invoker.hitcnt > 0 ) invoker.hitcnt--; + else if ( A_Melee(int(80+invoker.charge*1.2),"itamex/hit",2.5,2.,3.,MELEE_Rip|MELEE_FleshSound|MELEE_ExtraWide|MELEE_HammerHit) ) + { + A_BumpFOV(.9); + A_QuakeEx(5,5,5,20,0,1,"",QF_RELATIVE|QF_SCALEDOWN|QF_3D,rollIntensity:.35); + A_AlertMonsters(swwm_uncapalert?0:800); + A_WeaponOffset(32,0,WOF_ADD|WOF_INTERPOLATE); + SWWMUtility.DoKnockback(self,-x,6000.*invoker.charge); + invoker.hitcnt = 3; + } + if ( invoker.charge <= 30. ) + { + A_StartSound("itamex/swing",CHAN_WEAPON,CHANF_OVERLAP); + return ResolveState("ZoomEnd"); + } + return ResolveState(null); + } + + action void A_ChargeDown() + { + A_SetAngle(angle+invoker.charge*.6,SPF_INTERPOLATE); + A_SetPitch(pitch*.9,SPF_INTERPOLATE); + A_SoundVolume(CHAN_WEAPONEXTRA,(invoker.charge/100.)**.5); + invoker.charge = max(0.,invoker.charge-6.); + A_WeaponOffset(-16,0,WOF_ADD|WOF_INTERPOLATE); + A_BumpFOV(1.+invoker.charge*.001); + Vector3 x, y, z; + [x, y, z] = swwm_CoordUtil.GetAxes(pitch,angle,roll); + SWWMUtility.DoKnockback(self,x,4000.*invoker.charge); + if ( invoker.charge <= 0 ) A_StopSound(CHAN_WEAPONEXTRA); + } + + override void OwnerDied() + { + Super.OwnerDied(); + A_StopSound(CHAN_WEAPONEXTRA); + } + override void Travelled() + { + Super.Travelled(); + A_StopSound(CHAN_WEAPONEXTRA); + } + Default { Tag "$T_HAMMER"; @@ -50,7 +150,7 @@ Class ItamexHammer : SWWMWeapon XZW2 PQRST 3; Goto Ready; Ready: - XZW2 A 1 A_WeaponReady(); + XZW2 A 1 A_WeaponReady(WRF_ALLOWRELOAD|WRF_ALLOWZOOM|WRF_ALLOWUSER1); Wait; Fire: XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP); @@ -74,6 +174,63 @@ Class ItamexHammer : SWWMWeapon XZW4 B 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42); XZW4 C 2; Goto Ready; + AltFire: + XZW2 A 1; // TODO + Goto Ready; + Zoom: + XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP); + XZW5 XYZ 2; + XZW6 ABCDEF 1 A_ChargeUp(); + XZW6 G 0 A_SpinReact(); + XZW6 G 1 A_SpinMove(); + Wait; + ZoomEnd: + XZW6 GHIJ 1 A_ChargeDown(); + XZW6 K 1 + { + A_ChargeDown(); + A_HammerHit(true); + } + XZW6 LM 1 A_ChargeDown(); + XZW6 N 2 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP); + XZW6 OPQRST 2; + XZW6 UVW 3; + Goto Ready; + Reload: + XZW2 A 2 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP); + XZW6 XYZ 2; + XZW7 ABCDEF 2; + XZW7 G 1 A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.7,starttime:.2); + XZW7 HIJ 1; + XZW7 K 1 A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.8,starttime:.2); + XZW7 LMNO 1; + XZW7 P 1 A_StartSound("itamex/meleeend",CHAN_WEAPONEXTRA,pitch:.9,starttime:.2); + XZW7 QRST 1; + XZW7 U 1 A_StopSound(CHAN_WEAPONEXTRA); + XZW7 VWXYZ 1; + XZW8 A 0 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42); + XZW8 BCDE 3; + XZW8 FGHI 2; + Goto Ready; + User1: + XZW2 A 1; + XZW8 J 1 A_StartSound("itamex/meleestart",CHAN_WEAPON,CHANF_OVERLAP); + XZW8 KLM 1; + XZW8 N 2 A_StartSound("demolitionist/wswing",CHAN_WEAPON,CHANF_OVERLAP); + XZW8 OPQ 2; + XZW8 R 1 + { + A_Parry(9); + A_PlayerMelee(); + } + XZW8 S 1; + XZW8 T 3 A_Melee(50,"demolitionist/whitm",1.2,1.4); + XZW8 UVWXYZ 2; + XZW9 ABC 2; + XZW9 D 1 A_StartSound("itamex/meleeend",CHAN_WEAPON,CHANF_OVERLAP,starttime:.42); + XZW9 EFGH 1; + XZW9 IJKL 2; + Goto Ready; Deselect: XZW2 A 3 A_StartSound("itamex/deselect",CHAN_WEAPON,CHANF_OVERLAP); XZW2 BCD 3; diff --git a/zscript/handler/swwm_handler_shaders.zsc b/zscript/handler/swwm_handler_shaders.zsc index f937930fb..a55e56e2a 100644 --- a/zscript/handler/swwm_handler_shaders.zsc +++ b/zscript/handler/swwm_handler_shaders.zsc @@ -17,6 +17,7 @@ extend Class SWWMHandler PPShader.SetEnabled("DivineShader",false); PPShader.SetEnabled("Glitch",false); PPShader.SetEnabled("Grain",false); + PPShader.SetEnabled("WindBlur",false); } private ui void RenderShaders( RenderEvent e ) @@ -124,6 +125,13 @@ extend Class SWWMHandler noiz = min(lastdmg*.03*max(0,(lastdmgtimer-(gametic+e.Fractic))/35.),3.5); PPShader.SetUniform1f("Glitch","str2",noiz); } + if ( (demo.player.ReadyWeapon is 'ItamexHammer') && demo.IsActorPlayingSound(CHAN_WEAPONEXTRA,"itamex/spin") ) + { + PPShader.SetEnabled("WindBlur",true); + PPShader.SetUniform1f("WindBlur","Speed",ItamexHammer(demo.player.ReadyWeapon).charge/100.); + PPShader.SetUniform1f("WindBlur","Fade",(ItamexHammer(demo.player.ReadyWeapon).charge/100.)**.5); + } + else PPShader.SetEnabled("WindBlur",false); if ( !demo.InStateSequence(demo.CurState,demo.FindState("Dash")) ) { PPShader.SetEnabled("ZoomBlur",false); diff --git a/zscript/weapons/swwm_baseweapon_melee.zsc b/zscript/weapons/swwm_baseweapon_melee.zsc index be40ec651..51c78362e 100644 --- a/zscript/weapons/swwm_baseweapon_melee.zsc +++ b/zscript/weapons/swwm_baseweapon_melee.zsc @@ -370,7 +370,8 @@ extend Class SWWMWeapon MELEE_ForceBust = 8, // bust walls even without Omnibusting enabled MELEE_Vertical = 16, // ring is widened vertically, rather than horizontally MELEE_Wider = 32, // ring is widened by 2.5x rather than 1.5x - MELEE_ExtraWide = 64 // if Wider is also specified, widen by 5x, otherwise widen by 3x + MELEE_ExtraWide = 64, // if Wider is also specified, widen by 5x, otherwise widen by 3x + MELEE_HammerHit = 128 // is hammer melee (gibbing counts for "HAHA DAB" achievement) }; action void A_Parry( int duration ) @@ -446,6 +447,8 @@ extend Class SWWMWeapon let p = Spawn(raging?"BigPunchImpact":"PunchImpact",mt.hits[i].pos); p.angle = atan2(mt.hits[i].dir.y,mt.hits[i].dir.x); } + if ( (flags&MELEE_HammerHit) && (mt.hits[i].a.Health <= mt.hits[i].a.GetGibHealth()) ) + SWWMUtility.AchievementProgressInc("dab",1,player); } if ( raging ) {