Less hacky item gesture setup.

This commit is contained in:
Mari the Deer 2020-12-23 21:30:35 +01:00
commit d9771c7451
5 changed files with 141 additions and 94 deletions

View file

@ -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)";

View file

@ -6,8 +6,10 @@ Class SWWMCollectible : Inventory abstract
int avail;
bool propagated;
Class<SWWMItemGesture> 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;
}
}

View file

@ -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

View file

@ -6,6 +6,9 @@ Class SWWMKey : Key abstract
Mixin SWWMUseToPickup;
bool propagated;
Class<SWWMItemGesture> 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

View file

@ -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<State> sstate;
Array<Actor> scaller;
bool whichuse;
Class<SWWMItemGesture> whichweapon;
Array<bool> suse;
Array<Class<SWWMItemGesture> > 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<SWWMItemGesture> 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 )
{