diff --git a/language.version b/language.version index ec364c5f1..d227f9e5f 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r708 \cu(Mon 26 Dec 13:45:57 CET 2022)\c-"; -SWWM_SHORTVER="\cw1.3pre r708 \cu(2022-12-26 13:45:57)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r709 \cu(Mon 26 Dec 23:22:30 CET 2022)\c-"; +SWWM_SHORTVER="\cw1.3pre r709 \cu(2022-12-26 23:22:30)\c-"; diff --git a/zscript/player/swwm_player_inventory.zsc b/zscript/player/swwm_player_inventory.zsc index 40230bbd2..019ee73ce 100644 --- a/zscript/player/swwm_player_inventory.zsc +++ b/zscript/player/swwm_player_inventory.zsc @@ -172,8 +172,8 @@ extend Class Demolitionist // the default PickWeapon code breaks when dual weapons are involved // so we gotta roll out our own here // - // I could rewrite PickNextWeapon and PickPrevWeapon as well, but nah - // those always call CheckAmmo so it's fine + // we also need to override PickNextWeapon and PickPrevWeapon due to quirks of + // gestures private Weapon TraverseSlot( int slot, bool checkammo, int start, int end, Weapon cur ) { for ( int i=start; i>=end; i-- ) @@ -197,7 +197,12 @@ extend Class Demolitionist let cur = player.ReadyWeapon; bool found = false; int cs, ci; - if ( cur ) [found, cs, ci] = player.weapons.LocateWeapon(cur.GetClass()); + if ( cur ) + { + if ( cur is 'SWWMGesture' ) [found, cs, ci] = player.weapons.LocateWeapon(SWWMGesture(cur).formerweapon.GetClass()); + else if ( cur is 'SWWMItemGesture' ) [found, cs, ci] = player.weapons.LocateWeapon(SWWMItemGesture(cur).gest.formerweapon.GetClass()); + else [found, cs, ci] = player.weapons.LocateWeapon(cur.GetClass()); + } if ( found && (cs == slot) ) { // traverse the slot down from current index @@ -208,4 +213,79 @@ extend Class Demolitionist let w = TraverseSlot(slot,checkammo,slotsize-1,0,cur); return w?w:cur; } + + // we have to reimplement this because of gestures + private bool, int, int FindMostRecentWeaponSWWM() + { + let cur = player.ReadyWeapon; + if ( player.PendingWeapon != WP_NOCHANGE ) cur = player.PendingWeapon; + if ( cur ) + { + bool found = false; + int cs, ci; + if ( cur is 'SWWMGesture' ) [found, cs, ci] = player.weapons.LocateWeapon(SWWMGesture(cur).formerweapon.GetClass()); + else if ( cur is 'SWWMItemGesture' ) [found, cs, ci] = player.weapons.LocateWeapon(SWWMItemGesture(cur).gest.formerweapon.GetClass()); + else [found, cs, ci] = player.weapons.LocateWeapon(cur.GetClass()); + return found, cs, ci; + } + return false, 0 ,0; + } + + private Weapon PickPNWeapon( bool bPrev = false ) + { + bool found; + int sslot, sidx; + [found, sslot, sidx] = FindMostRecentWeaponSWWM(); + let cur = player.ReadyWeapon; + if ( cur is 'SWWMGesture' ) cur = SWWMGesture(cur).formerweapon; + else if ( cur is 'SWWMItemGesture' ) cur = SWWMItemGesture(cur).gest.formerweapon; + if ( !cur || found ) + { + int slot, idx; + if ( !cur ) + { + sslot = bPrev?0:(NUM_WEAPON_SLOTS-1); + sidx = bPrev?0:player.Weapons.SlotSize(sslot); + } + slot = sslot; + idx = sidx; + int checked = 0; + do + { + if ( bPrev ) + { + if ( --idx < 0 ) + { + checked++; + if ( --slot < 0 ) slot = NUM_WEAPON_SLOTS-1; + idx = player.Weapons.SlotSize(slot)-1; + } + } + else + { + if ( ++idx >= player.Weapons.SlotSize(slot) ) + { + idx = 0; + checked++; + if ( ++slot >= NUM_WEAPON_SLOTS ) slot = 0; + } + } + let type = player.Weapons.GetWeapon(slot,idx); + let w = Weapon(FindInventory(type)); + if ( w && w.CheckAmmo(Weapon.EitherFire,false) ) + return w; + } + while ( ((slot != sslot) || (idx != sidx)) && (checked <= NUM_WEAPON_SLOTS) ); + } + return player.ReadyWeapon; + } + + override Weapon PickPrevWeapon() + { + return PickPNWeapon(true); + } + override Weapon PickNextWeapon() + { + return PickPNWeapon(); + } } diff --git a/zscript/swwm_gesture.zsc b/zscript/swwm_gesture.zsc index 8d17490fc..e7bdd7d57 100644 --- a/zscript/swwm_gesture.zsc +++ b/zscript/swwm_gesture.zsc @@ -24,7 +24,7 @@ enum EGestureSlot // First person gestures Class SWWMGesture : SWWMWeapon { - Weapon formerweapon; + Weapon formerweapon, lastformerweapon; int whichgesture, nextgesture; bool deaded, queued; Class whichweapon; @@ -48,6 +48,10 @@ Class SWWMGesture : SWWMWeapon override void DoEffect() { Super.DoEffect(); + // show nametag if former weapon changes + if ( (lastformerweapon != formerweapon) && Owner && (Owner.player == players[consoleplayer]) && (displaynametags&2) ) + EventHandler.SendInterfaceEvent(consoleplayer,"swwmnametag."..formerweapon.GetTag()); + lastformerweapon = formerweapon; // if we're supposed to headpat but we're NOT the pending/ready weapon, something's very wrong here // try to fix that by force if ( pats && Owner && Owner.player && (Owner.player.ReadyWeapon != self) && (Owner.player.PendingWeapon != self) ) @@ -104,6 +108,7 @@ Class SWWMGesture : SWWMWeapon } if ( mo.player.PendingWeapon != WP_NOCHANGE ) w.formerweapon = mo.player.PendingWeapon; else w.formerweapon = mo.player.ReadyWeapon; + w.lastformerweapon = w.formerweapon; w.whichweapon = null; w.whichgesture = which; mo.player.PendingWeapon = w; @@ -138,6 +143,7 @@ Class SWWMGesture : SWWMWeapon } if ( mo.player.PendingWeapon != WP_NOCHANGE ) w.formerweapon = mo.player.PendingWeapon; else w.formerweapon = mo.player.ReadyWeapon; + w.lastformerweapon = w.formerweapon; w.whichgesture = GS_Null; w.whichweapon = a; mo.player.PendingWeapon = w; diff --git a/zscript/weapons/swwm_baseweapon.zsc b/zscript/weapons/swwm_baseweapon.zsc index dc035537e..4418a8511 100644 --- a/zscript/weapons/swwm_baseweapon.zsc +++ b/zscript/weapons/swwm_baseweapon.zsc @@ -386,13 +386,65 @@ Class SWWMWeapon : Weapon abstract if ( Owner.player ) { if ( !Owner.player.GetNeverSwitch() && !bNo_Auto_Switch && ReportHUDAmmo() ) // hey, as long as it works - Owner.player.PendingWeapon = self; + { + // if the player's current/next weapon is a gesture, set ourselves as the former weapon, to avoid breaking gesture sequences + if ( Owner.player.ReadyWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.ReadyWeapon); + g.formerweapon = self; + } + else if ( Owner.player.PendingWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.PendingWeapon); + g.formerweapon = self; + } + else if ( Owner.player.ReadyWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.ReadyWeapon); + ig.gest.formerweapon = self; + } + else if ( Owner.player.PendingWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.PendingWeapon); + ig.gest.formerweapon = self; + } + else Owner.player.PendingWeapon = self; + } if ( Owner.player.mo == players[consoleplayer].camera ) StatusBar.ReceivedWeapon(self); } GivenAsMorphWeapon = false; bSwappedTo = false; } + override bool Use( bool pickup ) + { + // we can simplify this + if ( !Owner.player || (Owner.player.ReadyWeapon == self) ) + return false; + // if the player's current/next weapon is a gesture, set ourselves as the former weapon, to avoid breaking gesture sequences + if ( Owner.player.ReadyWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.ReadyWeapon); + g.formerweapon = self; + } + else if ( Owner.player.PendingWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.PendingWeapon); + g.formerweapon = self; + } + else if ( Owner.player.ReadyWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.ReadyWeapon); + ig.gest.formerweapon = self; + } + else if ( Owner.player.PendingWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.PendingWeapon); + ig.gest.formerweapon = self; + } + else Owner.player.PendingWeapon = self; + return false; + } override void OwnerDied() { ClearBufferedAmmo(); diff --git a/zscript/weapons/swwm_splode.zsc b/zscript/weapons/swwm_splode.zsc index 6b2476cd7..24e03e550 100644 --- a/zscript/weapons/swwm_splode.zsc +++ b/zscript/weapons/swwm_splode.zsc @@ -211,6 +211,28 @@ Class ExplodiumGun : SWWMWeapon // switch to dual if already selected if ( Owner.player && (Owner.player.ReadyWeapon == self) && (Amount > 1) ) { + // if the player's current weapon is a gesture, set sister as the former weapon, to avoid breaking gesture sequences + if ( Owner.player.ReadyWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.ReadyWeapon); + g.formerweapon = SisterWeapon; + } + else if ( Owner.player.PendingWeapon is 'SWWMGesture' ) + { + let g = SWWMGesture(Owner.player.PendingWeapon); + g.formerweapon = SisterWeapon; + } + else if ( Owner.player.ReadyWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.ReadyWeapon); + ig.gest.formerweapon = SisterWeapon; + } + else if ( Owner.player.PendingWeapon is 'SWWMItemGesture' ) + { + let ig = SWWMItemGesture(Owner.player.PendingWeapon); + ig.gest.formerweapon = SisterWeapon; + } + else Owner.player.PendingWeapon = self; Owner.player.PendingWeapon = SisterWeapon; return false; }