swwmgz_m/zscript/swwm_gesture.zsc

766 lines
20 KiB
Text

// stuff related to gestures
Class HHitList
{
Actor a;
Vector3 dir;
}
enum EGestureSlot
{
// special use
GS_Headpat = -50,
GS_Grenade,
GS_EmptyMelee,
// no gesture
GS_Null = 0,
// general gestures
GS_Wave = 1,
GS_ThumbsUp,
GS_Victory,
GS_BlowKiss
};
// First person gestures
Class SWWMGesture : SWWMWeapon
{
Weapon formerweapon, lastformerweapon;
int whichgesture, nextgesture;
bool deaded, queued;
Class<SWWMItemGesture> whichweapon;
Array<Class<SWWMItemGesture> > sweapon;
int gonect;
HeadpatTracker pats; // for headpat gesture, our current tracker
// 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();
// 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) )
SetGesture(Owner.player.mo,GS_Headpat,true);
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"));
// check if we're waving at a dying enemy
if ( (psp.frame >= 3) && (psp.frame <= 12) && (psp.sprite == GetSpriteIndex('XZW1')) )
CheckWave();
}
private void CheckWave()
{
let hnd = SWWMHandler(EventHandler.Find("SWWMHandler"));
if ( !hnd ) return;
foreach ( a:hnd.suckableactors )
{
if ( !a || (a.Health > 0) || (a.tics == -1) || !(a.bISMONSTER || a.player) || !a.IsHostile(Owner) ) continue;
// check if we can see it
if ( !SWWMUtility.InPlayerFOV(Owner.player,a) ) continue;
// someone's dying
SWWMUtility.MarkAchievement("wave",Owner.player);
break;
}
}
static SWWMGesture SetGesture( PlayerPawn mo, int which, bool force = false )
{
if ( !mo || !(mo is 'Demolitionist') ) return null; // only Demo
if ( mo.Health <= 0 ) return null; // dead
if ( !force && (mo.player.cheats&CF_TOTALLYFROZEN) ) return null; // frozen today (unless forced)
SWWMGesture w = SWWMGesture(mo.FindInventory("SWWMGesture"));
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
if ( which <= 0 ) return null; // these gestures can't be queued
else
{
w.nextgesture = which;
w.queued = true;
}
return null;
}
if ( !w )
{
w = SWWMGesture(Spawn("SWWMGesture"));
mo.AddInventory(w);
}
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;
return w;
}
// "special" gestures are run by switching to another "weapon"
static SWWMGesture SetSpecialGesture( PlayerPawn mo, Class<SWWMItemGesture> a, bool forced = false )
{
if ( !mo || !(mo is 'Demolitionist') ) return null; // only Demo
if ( mo.Health <= 0 ) return null; // dead
if ( !forced && (mo.player.cheats&CF_TOTALLYFROZEN) ) return null; // frozen today (unless forced)
if ( !a ) return null;
SWWMGesture w = SWWMGesture(mo.FindInventory("SWWMGesture"));
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
foreach ( sw:w.sweapon )
{
if ( sw != a ) continue;
return null;
}
w.sweapon.Push(a);
return null;
}
if ( !w )
{
w = SWWMGesture(Spawn("SWWMGesture"));
mo.AddInventory(w);
}
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;
return w;
}
action void A_CallPlayerGesture( statelabel st, statelabel cst )
{
if ( invoker.Owner.Health <= 0 ) return;
if ( (player.crouchdir == -1) && invoker.Owner.FindState(cst) )
invoker.Owner.SetStateLabel(cst);
else if ( invoker.Owner.FindState(st) )
invoker.Owner.SetStateLabel(st);
}
action void A_FinishGesture()
{
if ( invoker.sweapon.Size() > 0 )
{
invoker.whichgesture = GS_Null;
invoker.whichweapon = invoker.sweapon[0];
// push back
invoker.sweapon.Delete(0);
player.SetPSprite(PSP_WEAPON,ResolveState("Ready"));
return;
}
if ( invoker.queued )
{
invoker.whichweapon = null;
invoker.whichgesture = invoker.nextgesture;
invoker.queued = false;
player.SetPSprite(PSP_WEAPON,ResolveState("Ready"));
return;
}
if ( invoker.formerweapon ) player.PendingWeapon = invoker.formerweapon;
else
{
player.PendingWeapon = player.mo.BestWeapon(null);
if ( (player.PendingWeapon is 'SWWMGesture') || (player.PendingWeapon is 'SWWMItemGesture') )
player.PendingWeapon = null;
}
player.SetPSprite(PSP_WEAPON,ResolveState("Deselect"));
}
action void A_Headpat()
{
A_StartSound("demolitionist/petting",CHAN_WEAPON,CHANF_OVERLAP,.4);
let pt = invoker.pats;
if ( !pt ) return;
int numpt = Random[ExploS](6,9);
Vector3 dir = SWWMUtility.Vec3FromAngles(angle,pitch);
Vector3 patpos = level.Vec3Offset(Vec2OffsetZ(0,0,player.viewz-4),dir*30.);
for ( int i=0; i<numpt; i++ )
{
let s = Spawn("LoveHeartSparkle",patpos);
s.angle = FRandom[ExploS](0,360);
s.pitch = FRandom[ExploS](-90,90);
}
if ( pt.target && pt.target.bSHOOTABLE )
{
int healamt = 10;
let raging = RagekitPower(FindInventory("RagekitPower"));
if ( raging )
{
healamt *= 8;
raging.DoHitFX();
}
if ( pt.target.GiveBody(healamt,pt.target.GetSpawnHealth()) )
SWWMHandler.DoFlash(pt.target,Color(32,224,128,255),10);
}
let s = Demolitionist(self).mystats;
if ( s ) s.pats++;
}
action void A_HeadpatEnd()
{
player.cheats &= ~CF_TOTALLYFROZEN;
Demolitionist(player.mo).scriptedinvul = false;
let pt = invoker.pats;
if ( !pt ) return;
invoker.pats = null;
pt.patting = false;
let t = pt.target;
if ( t )
{
if ( pt.patstate ) t.SetState(pt.patstate);
else t.tics = pt.oldtargettics;
t.bDORMANT = false;
if ( t.bISMONSTER )
{
if ( pt.lethalpat )
{
t.DamageMobj(invoker,self,t.Health,'Love',DMG_FORCED|DMG_THRUSTLESS);
pt.Destroy();
return;
}
// befriend
if ( t.bCOUNTKILL )
{
t.bCOUNTKILL = false;
level.total_monsters--;
}
if ( t.special && !(t.ActivationType&THINGSPEC_NoDeathSpecial) )
{
Actor whomst = level.actownspecial?t:self;
if ( t.ActivationType&THINGSPEC_ThingActs ) whomst = t;
else if ( t.ActivationType&THINGSPEC_TriggerActs ) whomst = self;
level.ExecuteSpecial(t.special,whomst,null,false,t.args[0],t.args[1],t.args[2],t.args[3],t.args[4]);
t.special = 0;
}
if ( !t.bFRIENDLY )
{
let s = Demolitionist(self).mystats;
if ( s ) s.befriend++;
if ( SWWMUtility.IdentifyingCaco(t) || SWWMUtility.IdentifyingDrug(t) || SWWMUtility.IdentifyingDoubleBoi(t) )
SWWMUtility.AchievementProgressInc("friend",1,player);
}
t.bFRIENDLY = true;
if ( deathmatch )
t.SetFriendPlayer(player);
// cancel any attacks
if ( t.InStateSequence(t.CurState,t.FindState("Missile"))
|| t.InStateSequence(t.CurState,t.FindState("Melee")) )
t.SetState(t.FindState("See"));
}
}
}
action void A_ThrowMag()
{
let weap = Weapon(invoker);
if ( !weap ) return;
Vector3 x2, y2, z2;
Vector3 origin = SWWMUtility.GetFireOffset(self,10,-2,-3);
double a = FRandom[Spread](0,360), s = FRandom[Spread](0,.005);
[x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
Vector3 dir = SWWMUtility.ConeSpread(x2,y2,z2,a,s);
let p = Spawn("ExplodiumMagProj",origin);
p.special1 = 7;
p.target = self;
p.angle = atan2(dir.y,dir.x);
p.pitch = asin(-dir.z);
p.vel = dir*p.speed*1.5;
if ( FindInventory("RagekitPower") ) p.vel *= 4.;
p.ClearBounce();
p.bEXPLODEONWATER = true;
if ( p.waterlevel <= 0 ) p.vel.z += 5.;
p.vel += vel*.5;
}
action bool CanPlantGrenade()
{
let weap = Weapon(invoker);
if ( !weap ) return false;
Vector3 origin = SWWMUtility.GetFireOffset(self,10,0,0);
FLineTraceData d;
LineTrace(angle+viewangle,DEFMELEERANGE*1.5,pitch+viewpitch,TRF_ABSPOSITION|TRF_THRUACTORS|TRF_NOSKY,origin.z,origin.x,origin.y,d);
return (d.HitType != TRACE_HitNone);
}
action void A_PlantMag()
{
let weap = Weapon(invoker);
if ( !weap ) return;
Vector3 x = SWWMUtility.GetPlayerViewDir(self);
Vector3 origin = SWWMUtility.GetFireOffset(self,10,0,0);
let p = Spawn("ExplodiumMagAttach",origin);
p.special1 = 7;
p.target = self;
p.angle = angle;
p.pitch = pitch;
p.vel = x*p.speed;
}
action void A_Smooch()
{
if ( swwm_mutevoice < 4 )
{
String myvoice = CVar.GetCVar('swwm_voicetype',player).GetString();
int loudlv = swwm_voiceamp;
int maxkiss = StringTable.Localize("$SWWM_"..myvoice.."_NKISS").ToInt();
int idx = (maxkiss<=1)?1:Random[DemoLines](1,maxkiss);
A_StartSound(String.Format("voice/%s/kiss%d",myvoice,idx),CHAN_DEMOVOICE,CHANF_OVERLAP);
if ( loudlv > 1 ) A_StartSound(String.Format("voice/%s/kiss%d",myvoice,idx),CHAN_DEMOVOICEAUX,CHANF_OVERLAP);
if ( loudlv > 2 ) A_StartSound(String.Format("voice/%s/kiss%d",myvoice,idx),CHAN_DEMOVOICEAUX2,CHANF_OVERLAP);
if ( loudlv > 3 ) A_StartSound(String.Format("voice/%s/kiss%d",myvoice,idx),CHAN_DEMOVOICEAUX3,CHANF_OVERLAP);
}
}
action void A_BlowKiss()
{
let weap = Weapon(invoker);
if ( !weap ) return;
Vector3 x2, y2, z2, dir;
Vector3 origin = SWWMUtility.GetFireOffset(self,10,0,-1);
[x2, y2, z2] = SWWMUtility.GetPlayerAxesAutoAimed(self);
let p = Spawn("LoveHeart",origin);
p.target = self;
p.angle = atan2(x2.y,x2.x);
p.pitch = asin(-x2.z);
p.vel = x2*p.speed;
// try to catch target in cone of vision
Array<HHitList> hits;
hits.Clear();
int rings = 1;
FLineTraceData d;
for ( double i=0; i<.2; i+=.02 )
{
for ( int j=0; j<360; j+=(360/rings) )
{
dir = SWWMUtility.ConeSpread(x2,y2,z2,j,i);
LineTrace(atan2(dir.y,dir.x),8000.,asin(-dir.z),TRF_ABSPOSITION,origin.z,origin.x,origin.y,d);
if ( d.HitType != TRACE_HitActor ) continue;
bool addme = true;
foreach ( hit:hits )
{
if ( hit.a != d.HitActor ) continue;
if ( (hit.dir dot x2) < (dir dot x2) )
hit.dir = dir; // closer to centerpoint
addme = false;
break;
}
if ( !addme ) continue;
let nhit = new("HHitList");
nhit.a = d.HitActor;
nhit.dir = dir;
hits.Push(nhit);
}
rings += 5;
}
int closest = -1;
double closestdot = -1;
for ( int i=0; i<hits.Size(); i++ )
{
double thisdot = (hits[i].dir dot x2);
if ( thisdot < closestdot ) continue;
closest = i;
closestdot = thisdot;
}
if ( closest != -1 ) p.tracer = hits[closest].a;
}
override void SetTags( String colname )
{
// gestures use model 0
A_ChangeModel("",0,"","",0,"models","DemoTags"..colname..".png",CMDL_USESURFACESKIN,-1);
}
Default
{
+WEAPON.CHEATNOTWEAPON;
+WEAPON.NO_AUTO_SWITCH;
+WEAPON.WIMPY_WEAPON;
+WEAPON.NOAUTOSWITCHTO;
+SWWMWEAPON.HIDEINMENU;
+INVENTORY.UNDROPPABLE;
+INVENTORY.UNTOSSABLE;
+INVENTORY.UNCLEARABLE;
Weapon.SelectionOrder int.max;
SWWMWeapon.BobFactor 0., 0.;
}
States
{
Select:
XZW1 A 1 A_FullRaise();
Goto Ready;
Ready:
XZW1 A 1
{
if ( invoker.whichweapon )
{
SWWMItemGesture g = SWWMItemGesture(FindInventory(invoker.whichweapon));
if ( !g )
{
g = SWWMItemGesture(Spawn(invoker.whichweapon));
AddInventory(g);
}
g.gest = invoker;
player.ReadyWeapon = g;
player.SetPSPrite(PSP_WEAPON,g.FindState("Fire"));
return ResolveState(null);
}
switch ( invoker.whichgesture )
{
case GS_Headpat:
return ResolveState("Headpat");
case GS_Grenade:
return ResolveState("QuickGrenade");
case GS_EmptyMelee:
return ResolveState("EmptyMelee");
case GS_Wave:
return ResolveState("Wave");
case GS_ThumbsUp:
return ResolveState("Approve");
case GS_Victory:
return ResolveState("Victory");
case GS_BlowKiss:
return ResolveState("BlowKiss");
}
return ResolveState("NoGesture");
}
Wait;
Fire:
XZW1 A 1;
Goto Ready;
Headpat:
XZW1 A 0 A_JumpIf(CountInv("RagekitPower"),"Ragepat");
XZW1 A 3 A_CallPlayerGesture("Headpat","Headpat");
XZW3 TU 3;
XZW3 V 2 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW3 WX 2;
XZW3 YZ 1;
XZW4 AB 1;
XZW4 C 2;
XZW4 D 2 A_Headpat();
XZW4 EF 2;
XZW4 GH 1;
HeadpatLoop:
XZW4 I 1;
XZW3 YZ 1;
XZW4 AB 1;
XZW4 C 2;
XZW4 D 2 A_Headpat();
XZW4 EF 2;
XZW4 GH 1;
XZW4 I 1
{
if ( player.cmd.buttons&BT_USE )
{
if ( FindInventory("RagekitPower") )
{
A_CallPlayerGesture("RagepatLoop","RagepatLoop");
return ResolveState("RagepatLoop");
}
else
{
A_CallPlayerGesture("HeadpatLoop","HeadpatLoop");
return ResolveState("HeadpatLoop");
}
}
return ResolveState(null);
}
XZW4 JK 2;
XZW4 L 2 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW4 MNOP 3;
XZW1 A 0 A_HeadpatEnd();
XZW1 A -1 A_FinishGesture();
Stop;
Ragepat:
XZW1 A 3 A_CallPlayerGesture("Ragepat","Ragepat");
XZW3 TU 2;
XZW3 V 1 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW3 WX 1;
XZW3 Y 1;
XZW4 AC 1;
XZW4 D 1 A_Headpat();
XZW4 EF 1;
XZW4 GI 1;
XZW3 Y 1;
XZW4 AC 1;
XZW4 D 1 A_Headpat();
XZW4 EF 1;
XZW4 GI 1;
XZW3 Y 1;
XZW4 AC 1;
XZW4 D 1 A_Headpat();
XZW4 EF 1;
XZW4 G 1;
RagepatLoop:
XZW4 I 1;
XZW3 Y 1;
XZW4 AC 1;
XZW4 D 1 A_Headpat();
XZW4 EF 1;
XZW4 G 1;
XZW4 I 1
{
if ( player.cmd.buttons&BT_USE )
{
if ( FindInventory("RagekitPower") )
{
A_CallPlayerGesture("RagepatLoop","RagepatLoop");
return ResolveState("RagepatLoop");
}
else
{
A_CallPlayerGesture("HeadpatLoop","HeadpatLoop");
return ResolveState("HeadpatLoop");
}
}
return ResolveState(null);
}
XZW4 JK 1;
XZW4 L 1 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW4 MNOP 2;
XZW1 A 0 A_HeadpatEnd();
XZW1 A -1 A_FinishGesture();
Stop;
QuickGrenade:
XZW4 Q 3;
XZW4 R 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW4 ST 3;
XZW4 U 3 A_PlayerReload();
XZW4 V 2 A_StartSound("explodium/magpin",CHAN_WEAPON,CHANF_OVERLAP);
XZW4 WX 2;
XZW4 Y 3 A_JumpIf(CanPlantGrenade(),"QuickGrenadePlant");
XZW4 Z 2
{
A_StartSound("explodium/throwmag",CHAN_WEAPON,CHANF_OVERLAP);
A_PlayerMelee();
}
XZW5 AB 2;
XZW5 CDEF 2;
XZW5 G 2 A_ThrowMag();
XZW5 HIJ 3;
XZW5 KL 4;
XZW4 Q 0 A_JumpIf(player.cmd.buttons&BT_USER4,"QuickGrenade");
XZW4 Q -1 A_FinishGesture();
Stop;
QuickGrenadePlant:
XZW4 Y 3;
XZW5 M 2 A_PlayerMelee();
XZW5 NOPQRSTU 2;
XZW5 V 2 A_PlantMag();
XZW5 W 4 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW5 XY 4;
XZW4 Q 0 A_JumpIf(player.cmd.buttons&BT_USER4,"QuickGrenade");
XZW4 Q -1 A_FinishGesture();
Stop;
EmptyMelee:
XZW0 ABC 1;
XZW0 D 1
{
A_PlayerMelee(true);
A_StartSound("demolitionist/swing",CHAN_WEAPON,CHANF_OVERLAP);
A_Parry(9);
}
XZW0 EF 1;
XZW0 G 1 A_Melee();
XZW0 HIJKLMN 2;
XZW0 A -1
{
if ( player.cmd.buttons&(BT_ATTACK|BT_ALTATTACK|BT_USER1) )
return ResolveState("EmptyMelee")+3;
A_FinishGesture();
return ResolveState(null);
}
Stop;
Wave:
XZW1 A 3 A_CallPlayerGesture("Wave","CrouchWave");
XZW1 B 3;
XZW1 C 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW1 DEFGHIJ 3;
XZW1 K 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW1 LMNOP 3;
XZW1 A -1 A_FinishGesture();
Stop;
Approve:
XZW1 A 3 A_CallPlayerGesture("Approve","CrouchApprove");
XZW1 QR 3;
XZW1 S 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW1 TUVWXY 3;
XZW1 Z 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 A 3;
XZW2 BCDEFG 3;
XZW1 A -1 A_FinishGesture();
Stop;
Victory:
XZW1 A 3 A_CallPlayerGesture("Victory","CrouchVictory");
XZW2 HI 3;
XZW2 J 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 KLMNOPQR 3;
XZW2 S 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW2 TUVWXYZ 3;
XZW1 A -1 A_FinishGesture();
Stop;
BlowKiss:
XZW1 A 3 A_CallPlayerGesture("BlowKiss","CrouchBlowKiss");
XZW3 A 3;
XZW3 B 3;
XZW3 C 3 A_StartSound("demolitionist/handsup",CHAN_WEAPON,CHANF_OVERLAP);
XZW3 DE 3;
XZW3 F 3 A_Smooch();
XZW3 GHIJ 3;
XZW3 K 3 A_StartSound("demolitionist/handsdown",CHAN_WEAPON,CHANF_OVERLAP);
XZW3 L 3 A_BlowKiss();
XZW3 MNOPQRS 3;
XZW1 A -1 A_FinishGesture();
Stop;
NoGesture:
XZW1 A -1 A_FinishGesture();
Stop;
SoftDeselect: // needed for item gestures so the weapon select sound doesn't get eaten up (dunno why)
XZW1 A 1;
Deselect:
XZW1 A -1 A_FullLower();
Stop;
}
}
// item gestures
Class SWWMItemGesture : SWWMWeapon abstract
{
SWWMGesture gest; // the base gesture weapon that we got picked from
bool gotused;
// 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 ( gotused )
{
// clear ourselves after use (don't pollute inventory list)
DepleteOrDestroy();
return;
}
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"));
}
action void A_FinishGesture()
{
A_WeaponOffset(0,32); // fix key punch offset
let gest = invoker.gest;
if ( !gest )
{
ThrowAbortException("Call to A_FinishGesture() without owned SWWMGesture");
return;
}
if ( gest.sweapon.Size() > 0 )
{
gest.whichgesture = GS_Null;
gest.whichweapon = gest.sweapon[0];
// push back
gest.sweapon.Delete(0);
// go back to the main gesture
player.ReadyWeapon = gest;
player.SetPSPrite(PSP_WEAPON,gest.ResolveState("Ready"));
invoker.gotused = true;
return;
}
if ( gest.queued )
{
gest.whichweapon = null;
gest.whichgesture = gest.nextgesture;
gest.queued = false;
// go back to the main gesture
player.ReadyWeapon = gest;
player.SetPSPrite(PSP_WEAPON,gest.ResolveState("Ready"));
invoker.gotused = true;
return;
}
// switch to old weapon
player.ReadyWeapon = gest;
if ( gest.formerweapon ) player.PendingWeapon = gest.formerweapon;
else
{
player.PendingWeapon = player.mo.BestWeapon(null);
if ( (player.PendingWeapon is 'SWWMGesture') || (player.PendingWeapon is 'SWWMItemGesture') )
player.PendingWeapon = null;
}
player.SetPSPrite(PSP_WEAPON,gest.ResolveState("SoftDeselect"));
invoker.gotused = true;
}
override void SetTags( String colname )
{
// gestures use model 0
A_ChangeModel("",0,"","",0,"models","DemoTags"..colname..".png",CMDL_USESURFACESKIN,-1);
}
Default
{
+WEAPON.CHEATNOTWEAPON;
+WEAPON.NO_AUTO_SWITCH;
+WEAPON.WIMPY_WEAPON;
+WEAPON.NOAUTOSWITCHTO;
+SWWMWEAPON.HIDEINMENU;
+INVENTORY.UNDROPPABLE;
+INVENTORY.UNTOSSABLE;
+INVENTORY.UNCLEARABLE;
Weapon.SelectionOrder int.max;
SWWMWeapon.BobFactor 0., 0.;
}
States
{
Select:
XZW1 A 1 A_FullRaise();
Goto Ready;
Ready:
Fire:
XZW1 A 1 A_Log("\cgUnimplemented pickup sequence for "..invoker.GetClassName().."\c-");
XZW1 A -1 A_FinishGesture();
Stop;
AltFire:
XZW1 A 1 A_Log("\cgUnimplemented use sequence for "..invoker.GetClassName().."\c-");
XZW1 A -1 A_FinishGesture();
Stop;
Deselect:
XZW1 A -1 A_FullLower();
Stop;
}
}