diff --git a/language.version b/language.version index d9b88900a..bee114a15 100644 --- a/language.version +++ b/language.version @@ -1,2 +1,2 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r704 \cu(Wed 23 Dec 20:04:54 CET 2020)"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw0.9.11b-pre r705 \cu(Wed 23 Dec 21:30:35 CET 2020)"; diff --git a/zscript/swwm_funstuff.zsc b/zscript/swwm_funstuff.zsc index 1f0c07098..03c6898d9 100644 --- a/zscript/swwm_funstuff.zsc +++ b/zscript/swwm_funstuff.zsc @@ -6,8 +6,10 @@ Class SWWMCollectible : Inventory abstract int avail; bool propagated; + Class gesture; Property Availability : avail; + Property GestureWeapon : gesture; // minimum gametype requirements enum EAvailability @@ -58,9 +60,9 @@ Class SWWMCollectible : Inventory abstract if ( Owner.player && !propagated ) { if ( pickup && CVar.GetCVar('swwm_collectanim',Owner.player) ) - SWWMGesture.SetSpecialGesture(Owner.player.mo,self,true); + SWWMGesture.SetSpecialGesture(Owner.player.mo,gesture); else if ( !pickup ) - SWWMGesture.SetSpecialGesture(Owner.player.mo,self); + SWWMGesture.SetSpecialGesture(Owner.player.mo,gesture,true); } // clean up the flag propagated = false; @@ -97,43 +99,104 @@ Class SWWMCollectible : Inventory abstract XZW1 A -1; Stop; } +} + +Class SWWMItemGesture : SWWMWeapon abstract +{ + SWWMGesture gest; // the base gesture weapon that we got picked from + + // these should prevent autoswitch when out of ammo + override bool ReportHUDAmmo() + { + return false; + } + override bool CheckAmmo( int firemode, bool autoswitch, bool requireammo, int ammocount ) + { + return false; + } + override bool Use( bool pickup ) + { + return false; + } + 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.Health <= 0) && (psp.CurState != ResolveState("Deselect")) ) + Owner.player.SetPSprite(PSP_WEAPON,ResolveState("Deselect")); + } - // helper action void A_FinishGesture() { - let gest = SWWMGesture(FindInventory("SWWMGesture")); + let gest = invoker.gest; if ( !gest ) { ThrowAbortException("Call to A_FinishGesture() without owned SWWMGesture"); return; } - if ( gest.sstate.Size() > 0 ) + if ( gest.sweapon.Size() > 0 ) { gest.whichgesture = GS_Null; - gest.whichstate = gest.sstate[0]; - gest.whichcaller = gest.scaller[0]; + gest.whichweapon = gest.sweapon[0]; + gest.whichuse = gest.suse[0]; // push back - gest.sstate.Delete(0); - gest.scaller.Delete(0); - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Ready")); + gest.sweapon.Delete(0); + gest.suse.Delete(0); + // go back to the main gesture and clear ourselves + player.ReadyWeapon = gest; + player.SetPSPrite(PSP_WEAPON,gest.ResolveState("Ready")); + invoker.Destroy(); return; } if ( gest.queued ) { - gest.whichstate = null; + gest.whichweapon = null; gest.whichgesture = gest.nextgesture; gest.queued = false; - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Ready")); + // go back to the main gesture and clear ourselves + player.ReadyWeapon = gest; + player.SetPSPrite(PSP_WEAPON,gest.ResolveState("Ready")); + invoker.Destroy(); return; } + // switch to old weapon and clear ourselves + player.ReadyWeapon = gest; player.PendingWeapon = gest.formerweapon; - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Deselect")); + player.SetPSPrite(PSP_WEAPON,gest.ResolveState("Deselect")); + invoker.Destroy(); + } + + Default + { + +WEAPON.CHEATNOTWEAPON; + +WEAPON.NO_AUTO_SWITCH; + +WEAPON.WIMPY_WEAPON; + +SWWMWEAPON.HIDEINMENU; + +INVENTORY.UNDROPPABLE; + +INVENTORY.UNTOSSABLE; + +INVENTORY.UNCLEARABLE; + Weapon.SelectionOrder int.max; + } + States + { + Select: + XZW1 A 1 A_FullRaise(); + Goto Ready; + Ready: + Fire: + XZW1 A 1 A_Print("Pickup gesture"); + XZW1 A -1 A_FinishGesture(); + Stop; + AltFire: + XZW1 A 1 A_Print("Use gesture"); + XZW1 A -1 A_FinishGesture(); + Stop; + Deselect: + XZW1 A -1 A_FullLower(); + Stop; } } diff --git a/zscript/swwm_hud.zsc b/zscript/swwm_hud.zsc index d690b940c..982fb569a 100644 --- a/zscript/swwm_hud.zsc +++ b/zscript/swwm_hud.zsc @@ -575,7 +575,7 @@ Class SWWMStatusBar : BaseStatusBar } if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) && (CPlayer.PendingWeapon != lastwep) ) { - if ( (ntags.GetInt()&2) && (CPlayer == players[consoleplayer]) && !(CPlayer.PendingWeapon is 'SWWMGesture') ) + if ( (ntags.GetInt()&2) && (CPlayer == players[consoleplayer]) && !(CPlayer.PendingWeapon is 'SWWMGesture') && !(CPlayer.PendingWeapon is 'SWWMItemGesture') ) { ntagstr = CPlayer.PendingWeapon.GetTag(); ntagtic = level.totaltime; @@ -1087,10 +1087,14 @@ Class SWWMStatusBar : BaseStatusBar { int ncolor = Font.CR_WHITE; SWWMGesture hasgesture = null; + SWWMItemGesture hasitemgesture = null; if ( CPlayer.PendingWeapon is 'SWWMGesture' ) hasgesture = SWWMGesture(CPlayer.PendingWeapon); else if ( CPlayer.ReadyWeapon is 'SWWMGesture' ) hasgesture = SWWMGesture(CPlayer.ReadyWeapon); + if ( CPlayer.PendingWeapon is 'SWWMItemGesture' ) hasitemgesture = SWWMItemGesture(CPlayer.PendingWeapon); + else if ( CPlayer.ReadyWeapon is 'SWWMItemGesture' ) hasitemgesture = SWWMItemGesture(CPlayer.ReadyWeapon); if ( !CPlayer.HasWeaponsInSlot(i%10) ) ncolor = Font.CR_DARKGRAY; else if ( hasgesture && hasgesture.formerweapon && (hasgesture.formerweapon.SlotNumber == (i%10)) ) ncolor = Font.CR_FIRE; + else if ( hasitemgesture && hasitemgesture.gest.formerweapon && (hasitemgesture.gest.formerweapon.SlotNumber == (i%10)) ) ncolor = Font.CR_FIRE; else if ( CPlayer.PendingWeapon && (CPlayer.PendingWeapon != WP_NOCHANGE) && (CPlayer.PendingWeapon.SlotNumber == (i%10)) ) ncolor = Font.CR_FIRE; else if ( (!CPlayer.PendingWeapon || (CPlayer.PendingWeapon == WP_NOCHANGE)) && CPlayer.ReadyWeapon && (CPlayer.ReadyWeapon.SlotNumber == (i%10)) ) ncolor = Font.CR_FIRE; else diff --git a/zscript/swwm_keys.zsc b/zscript/swwm_keys.zsc index 651d41535..adeff9a06 100644 --- a/zscript/swwm_keys.zsc +++ b/zscript/swwm_keys.zsc @@ -6,6 +6,9 @@ Class SWWMKey : Key abstract Mixin SWWMUseToPickup; bool propagated; + Class gesture; + + Property GestureWeapon : gesture; override void DoEffect() { @@ -25,9 +28,9 @@ Class SWWMKey : Key abstract if ( Owner.player && !propagated ) { if ( pickup && CVar.GetCVar('swwm_collectanimkey',Owner.player) ) - SWWMGesture.SetSpecialGesture(Owner.player.mo,self,true); + SWWMGesture.SetSpecialGesture(Owner.player.mo,gesture); else if ( !pickup ) - SWWMGesture.SetSpecialGesture(Owner.player.mo,self); + SWWMGesture.SetSpecialGesture(Owner.player.mo,gesture,true); } // clean up the flag propagated = false; @@ -41,44 +44,6 @@ Class SWWMKey : Key abstract +INVENTORY.AUTOACTIVATE; FloatBobStrength 0.25; } - - // helper - action void A_FinishGesture() - { - let gest = SWWMGesture(FindInventory("SWWMGesture")); - if ( !gest ) - { - ThrowAbortException("Call to A_FinishGesture() without owned SWWMGesture"); - return; - } - if ( gest.sstate.Size() > 0 ) - { - gest.whichgesture = GS_Null; - gest.whichstate = gest.sstate[0]; - gest.whichcaller = gest.scaller[0]; - // push back - gest.sstate.Delete(0); - gest.scaller.Delete(0); - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Ready")); - return; - } - if ( gest.queued ) - { - gest.whichstate = null; - gest.whichgesture = gest.nextgesture; - gest.queued = false; - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Ready")); - return; - } - player.PendingWeapon = gest.formerweapon; - let psp = player.FindPSprite(PSP_WEAPON); - psp.caller = gest; - psp.SetState(gest.ResolveState("Deselect")); - } } Class SWWMRedCard : SWWMKey diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index 632b721a7..930773ba8 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -1825,7 +1825,7 @@ Class Demolitionist : PlayerPawn if ( !player ) return; // add lore if any SWWMLoreLibrary.Add(player,item.GetClassName()); - if ( (item is 'Weapon') && !(item is 'SWWMGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() ) + if ( (item is 'Weapon') && !(item is 'SWWMGesture') && !(item is 'SWWMItemGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() ) SWWMHandler.AddOneliner("getweapon",2); if ( (item is 'Key') && !key_reentrant && !deathmatch ) { @@ -1989,10 +1989,15 @@ Class Demolitionist : PlayerPawn // prevent sudden stomping if we were previously falling lastvelz = vel.z; // early cancel gestures - if ( player && (player.ReadyWeapon is 'SWWMGesture') ) + if ( player ) { - player.PendingWeapon = SWWMGesture(player.ReadyWeapon).formerweapon; - player.SetPSprite(PSP_WEAPON,player.ReadyWeapon.ResolveState("Deselect")); + if ( player.ReadyWeapon is 'SWWMItemGesture' ) + player.ReadyWeapon = SWWMItemGesture(player.ReadyWeapon).gest; + if ( player.ReadyWeapon is 'SWWMGesture' ) + { + player.PendingWeapon = SWWMGesture(player.ReadyWeapon).formerweapon; + player.SetPSprite(PSP_WEAPON,player.ReadyWeapon.ResolveState("Deselect")); + } } // re-add ourselves to the "suckable list" (otherwise the Ynykron Singularity won't hurt us) let hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); @@ -3138,10 +3143,10 @@ Class SWWMGesture : SWWMWeapon Weapon formerweapon; int whichgesture, nextgesture; bool deaded, queued; - State whichstate; - Actor whichcaller; - Array sstate; - Array scaller; + bool whichuse; + Class whichweapon; + Array suse; + Array > sweapon; int gonect; HeadpatTracker pats; // for headpat gesture, our current tracker @@ -3154,6 +3159,10 @@ Class SWWMGesture : SWWMWeapon { return false; } + override bool Use( bool pickup ) + { + return false; + } override void DoEffect() { Super.DoEffect(); @@ -3171,7 +3180,8 @@ Class SWWMGesture : SWWMWeapon if ( mo.Health <= 0 ) return null; // dead if ( mo.player.cheats&CF_TOTALLYFROZEN ) return null; // frozen today SWWMGesture w = SWWMGesture(mo.FindInventory("SWWMGesture")); - if ( (mo.player.PendingWeapon == w) || (mo.player.ReadyWeapon == w) ) + if ( w && ((mo.player.PendingWeapon is 'SWWMGesture') || (mo.player.ReadyWeapon is 'SWWMGesture') + || (mo.player.PendingWeapon is 'SWWMItemGesture') || (mo.player.ReadyWeapon is 'SWWMItemGesture')) ) { // already gesturing // just queue another one @@ -3190,31 +3200,29 @@ Class SWWMGesture : SWWMWeapon } if ( mo.player.PendingWeapon != WP_NOCHANGE ) w.formerweapon = mo.player.PendingWeapon; else w.formerweapon = mo.player.ReadyWeapon; - w.whichstate = null; + w.whichweapon = null; w.whichgesture = which; mo.player.PendingWeapon = w; return w; } - // "special" gestures go to a specified state, which may be external - static SWWMGesture SetSpecialGesture( PlayerPawn mo, Actor a, bool pickup = false ) + // "special" gestures are run by switching to another "weapon" + static SWWMGesture SetSpecialGesture( PlayerPawn mo, Class a, bool used = false ) { if ( !mo || !(mo is 'Demolitionist') ) return null; // only Demo if ( mo.Health <= 0 ) return null; // dead if ( mo.player.cheats&CF_TOTALLYFROZEN ) return null; // frozen today - State which = null; - if ( pickup ) which = a.FindState("PickupGesture"); - else which = a.FindState("UseGesture"); - if ( !which ) return null; // state not found + if ( !a ) return null; SWWMGesture w = SWWMGesture(mo.FindInventory("SWWMGesture")); - if ( (mo.player.PendingWeapon == w) || (mo.player.ReadyWeapon == w) ) + if ( w && ((mo.player.PendingWeapon is 'SWWMGesture') || (mo.player.ReadyWeapon is 'SWWMGesture') + || (mo.player.PendingWeapon is 'SWWMItemGesture') || (mo.player.ReadyWeapon is 'SWWMItemGesture')) ) { // already gesturing // queue if unique - if ( w.sstate.Find(which) != w.sstate.Size() ) + if ( (w.sweapon.Size() <= 0) || (w.sweapon.Find(a) != w.sweapon.Size()) ) { - w.sstate.Push(which); - w.scaller.Push(a); + w.sweapon.Push(a); + w.suse.Push(used); } return null; } @@ -3226,8 +3234,8 @@ Class SWWMGesture : SWWMWeapon if ( mo.player.PendingWeapon != WP_NOCHANGE ) w.formerweapon = mo.player.PendingWeapon; else w.formerweapon = mo.player.ReadyWeapon; w.whichgesture = GS_Null; - w.whichstate = which; - w.whichcaller = a; + w.whichweapon = a; + w.whichuse = used; mo.player.PendingWeapon = w; return w; } @@ -3243,20 +3251,20 @@ Class SWWMGesture : SWWMWeapon action void A_FinishGesture() { - if ( invoker.sstate.Size() > 0 ) + if ( invoker.sweapon.Size() > 0 ) { invoker.whichgesture = GS_Null; - invoker.whichstate = invoker.sstate[0]; - invoker.whichcaller = invoker.scaller[0]; + invoker.whichweapon = invoker.sweapon[0]; + invoker.whichuse = invoker.suse[0]; // push back - invoker.sstate.Delete(0); - invoker.scaller.Delete(0); + invoker.sweapon.Delete(0); + invoker.suse.Delete(0); player.SetPSprite(PSP_WEAPON,ResolveState("Ready")); return; } if ( invoker.queued ) { - invoker.whichstate = null; + invoker.whichweapon = null; invoker.whichgesture = invoker.nextgesture; invoker.queued = false; player.SetPSprite(PSP_WEAPON,ResolveState("Ready")); @@ -3444,12 +3452,19 @@ Class SWWMGesture : SWWMWeapon Ready: XZW1 A 1 { - if ( invoker.whichstate ) + if ( invoker.whichweapon ) { - // set caller (gross hack) - let psp = player.FindPSPrite(PSP_WEAPON); - psp.caller = invoker.whichcaller; - return invoker.whichstate; + SWWMItemGesture g = SWWMItemGesture(FindInventory(invoker.whichweapon)); + if ( !g ) + { + g = SWWMItemGesture(Spawn(invoker.whichweapon)); + AddInventory(g); + } + g.gest = invoker; + player.ReadyWeapon = g; + if ( invoker.whichuse ) player.SetPSPrite(PSP_WEAPON,g.FindState("AltFire")); + else player.SetPSPrite(PSP_WEAPON,g.FindState("Fire")); + return ResolveState(null); } switch ( invoker.whichgesture ) {