swwmgz_m/zscript/player/swwm_player_inventory.zsc

283 lines
9.2 KiB
Text

// inventory functions
extend Class Demolitionist
{
override void GiveDefaultInventory()
{
if ( !player ) return;
bInDefaultInventory = true; // prevent default inventory from adding lore entries (fixes lore library disappearing when loading saves WHILE DEAD)
// we don't need hexen or basic armors
// we can simplify the code a lot here since no handling of many special conditions is needed
let sc = Inventory(Spawn('SayaCollar'));
if ( !sc.CallTryPickup(self) ) sc.Destroy();
let ap = Inventory(Spawn('AlmasteelPlating'));
if ( !ap.CallTryPickup(self) ) ap.Destroy();
let dp = Inventory(Spawn('DeepImpact'));
if ( !dp.CallTryPickup(self) ) dp.Destroy();
let eg = ExplodiumGun(Spawn('ExplodiumGun'));
eg.firstselect = true;
if ( !eg.CallTryPickup(self) ) eg.Destroy();
else player.ReadyWeapon = player.PendingWeapon = eg;
// in hexdd, we start with the chaos sphere in our grasp
if ( SWWMUtility.IsDeathkings() && SWWMUtility.CheckMD5List("vanillahexen.list") )
{
let cs = Inventory(Spawn('SWWMChaosSphere'));
if ( !cs.CallTryPickup(self) ) cs.Destroy();
}
// in deathmatch, we start with 8 embiggeners
if ( deathmatch )
{
let em = Inventory(Spawn('TradedHammerspaceEmbiggener'));
em.Amount = em.MaxAmount;
if ( !em.CallTryPickup(self) ) em.Destroy();
}
bInDefaultInventory = false;
}
override void ClearInventory()
{
Super.ClearInventory();
// remove some specific "undroppable" items
Actor last = self;
while ( last.inv )
{
let i = last.inv;
if ( ((i is 'SWWMArmor') && !i.bUNCLEARABLE) || (i is 'HammerspaceEmbiggener') )
{
i.DepleteOrDestroy();
if ( !i.bDestroyed ) last = i;
}
else last = i;
}
// clean up the "got weapons" so their obtain lines are played again
if ( mystats ) mystats.CleanGotWeapons();
}
override void RemoveInventory( Inventory item )
{
// stop any looping sounds our current weapon had
if ( (item is 'SWWMWeapon') && player && (SWWMWeapon(item) == player.ReadyWeapon) )
{
A_StopSound(CHAN_WEAPONEXTRA);
A_StopSound(CHAN_WEAPONEXTRA2);
A_StopSound(CHAN_WEAPONEXTRA3);
}
Super.RemoveInventory(item);
}
// skull keys, random chance of "alas poor yorick" line
private clearscope bool IsSkullKey( Inventory item )
{
String cname = item.GetClassName();
cname.MakeLower();
return (cname.IndexOf("skull") != -1);
}
override void AddInventory( Inventory item )
{
Super.AddInventory(item);
if ( !player ) return;
String cn = item.GetClassName();
if ( !bInDefaultInventory && (level.maptime > 0) && (!(item is 'SWWMWeapon') || !(cn.Left(4) ~== "Dual")) ) // dual weapons are ignored here, as they're handled separately
{
// add lore if any
SWWMLoreLibrary.Add(player,cn);
// weapon get oneliner
if ( (item is 'Weapon') && !(item is 'SWWMGesture') && !(item is 'SWWMItemGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && (player == players[consoleplayer]) && !ingivecheat )
{
if ( (item is 'HeavyMahSheenGun') && !Random[DemoLines](0,2) && SWWMHandler.AddOneliner("sheenspecial",2,20) )
{
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
A_StartSound("sheen/specialpick",CHAN_ITEM,CHANF_OVERLAP,1.,.5);
}
else if ( (item is 'SWWMWeapon') && (SWWMWeapon(item).GetLine != "") )
{
// fall back to generic weapon get if voicepack lacks weapon-specific lines
if ( !SWWMHandler.AddOneliner(SWWMWeapon(item).GetLine,2) )
SWWMHandler.AddOneliner("getweapon",2);
}
else SWWMHandler.AddOneliner("getweapon",2);
facegrin = true;
}
}
if ( (item is 'Key') && !ingivecheat && !deathmatch && !bInDefaultInventory )
{
// score
int score = 100;
if ( player == players[consoleplayer] ) Console.Printf(StringTable.Localize("$SWWM_FINDKEY"),item.GetTag(),score);
else Console.Printf(StringTable.Localize("$SWWM_FINDKEYREM"),player.GetUserName(),item.GetTag(),score);
SWWMCredits.Give(player,score);
if ( player == players[consoleplayer] ) SWWMScoreObj.SpawnAtActorBunch(100,self);
if ( !Random[DemoLines](0,5) && IsSkullKey(item) )
{
if ( !SWWMHandler.AddOneliner("skullget",2) )
SWWMHandler.AddOneliner("keyget",2);
}
else SWWMHandler.AddOneliner("keyget",2);
facegrin = true;
}
// add collectible to stats
if ( item is 'SWWMCollectible' )
{
let col = SWWMCollectible(item);
if ( !ingivecheat )
{
SWWMHandler.AddOneliner(col.GetLine,2);
facegrin = true;
}
if ( !mystats ) return;
let cls = col.GetClass();
if ( (mystats.ownedcollectibles.Size() > 0) && (mystats.ownedcollectibles.Find(cls) < mystats.ownedcollectibles.Size()) ) return;
mystats.ownedcollectibles.Push(cls);
}
// yorick
if ( (item is 'PuzzSkull') && mystats && !mystats.gotyorick && !ingivecheat )
{
mystats.gotyorick = true;
SWWMHandler.AddOneliner("skullget",2);
facegrin = true;
}
// notify key obtained to flash icon
if ( item is 'Key' )
EventHandler.SendInterfaceEvent(consoleplayer,"swwmkeyget."..item.GetClassName(),PlayerNumber());
}
override bool UseInventory( Inventory item )
{
if ( (player.cheats&CF_TOTALLYFROZEN) || isFrozen() ) return false;
if ( !Actor.UseInventory(item) )
{
if ( player == players[consoleplayer] )
{
if ( !(item is 'Weapon') && !(item is 'SWWMCollectible') && !(item is 'Key') )
A_StartSound("menu/noinvuse",CHAN_ITEMEXTRA);
if ( item is 'PuzzleItem' )
SWWMHandler.AddOneliner("puzzfail",2,20);
}
return false;
}
// use sounds of big powerups are heard by other players
if ( (player == players[consoleplayer]) || item.bBIGPOWERUP )
A_StartSound(item.UseSound,CHAN_ITEMEXTRA);
if ( (player == players[consoleplayer]) && (item is 'PuzzleItem') )
SWWMHandler.AddOneliner("puzzsucc",2,10);
return true;
}
// the default PickWeapon code breaks when dual weapons are involved
// so we gotta roll out our own here
//
// 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-- )
{
let type = player.weapons.GetWeapon(slot,i);
let w = Weapon(player.mo.FindInventory(type));
if ( !w || (w == cur) || (cur && cur.bPOWERED_UP && (w == cur.SisterWeapon)) )
continue;
String sn = w.GetClassName();
bool dual = ((type is 'SWWMWeapon') && (sn.Left(4) ~== "Dual"));
if ( (!checkammo && (!dual || (w.SisterWeapon && (w.SisterWeapon.Amount > 1))))
|| w.CheckAmmo(Weapon.EitherFire,false) )
return w;
}
return null;
}
override Weapon PickWeapon( int slot, bool checkammo )
{
int slotsize = player.weapons.SlotSize(slot);
let cur = player.ReadyWeapon;
bool found = false;
int cs, ci;
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
let w = TraverseSlot(slot,checkammo,ci-1,0,cur);
if ( !w ) w = TraverseSlot(slot,checkammo,slotsize-1,ci+1,cur);
return w?w:cur;
}
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 )
{
let [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();
}
}