- Try to get rid of all implicit casts from string to name, color or class. - Use FindClass where needed. - Used a map in a case where a dictionary was unneeded. - Use new bounce flags where needed. - Replace Legacy of Rust weapons/ammo.
664 lines
20 KiB
Text
664 lines
20 KiB
Text
// inventory listing tab
|
|
|
|
Class DemolitionistInventoryTab : DemolitionistMenuTab
|
|
{
|
|
DemolitionistMenuList invlist;
|
|
int ofs, maxofs;
|
|
double smofs;
|
|
bool drag;
|
|
|
|
private bool CmpInventory( Inventory a, Inventory b )
|
|
{
|
|
int ta = 0, tb = 0;
|
|
if ( a is 'Weapon' ) ta = 2;
|
|
else if ( (a is 'BackpackItem') || (a is 'HammerspaceEmbiggener') ) ta = 3;
|
|
else if ( a is 'Ammo' ) ta = 4;
|
|
else if ( a is 'MagAmmo' ) ta = 5;
|
|
else if ( (a is 'PowerupGiver') || (a is 'AmmoFabricator') || a.bBIGPOWERUP ) ta = -4;
|
|
else if ( (a is 'Health') || (a is 'HealthPickup') || (a is 'SWWMHealth') ) ta = -2;
|
|
else if ( (a is 'Armor') || (a is 'SWWMSpareArmor') ) ta = -1;
|
|
else if ( a is 'PuzzleItem' ) ta = 1;
|
|
else if ( a.bINVBAR ) ta = -3;
|
|
if ( b is 'Weapon' ) tb = 2;
|
|
else if ( (b is 'BackpackItem') || (b is 'HammerspaceEmbiggener') ) tb = 3;
|
|
else if ( b is 'Ammo' ) tb = 4;
|
|
else if ( b is 'MagAmmo' ) tb = 5;
|
|
else if ( (b is 'PowerupGiver') || (b is 'AmmoFabricator') || b.bBIGPOWERUP ) tb = -4;
|
|
else if ( (b is 'Health') || (b is 'HealthPickup') || (b is 'SWWMHealth') ) tb = -2;
|
|
else if ( (b is 'Armor') || (b is 'SWWMSpareArmor') ) tb = -1;
|
|
else if ( b is 'PuzzleItem' ) tb = 1;
|
|
else if ( b.bINVBAR ) tb = -3;
|
|
if ( ta == tb )
|
|
{
|
|
if ( a is 'Weapon' )
|
|
{
|
|
let [dummya, slota] = players[consoleplayer].weapons.LocateWeapon(Weapon(a).GetClass());
|
|
if ( slota == 0 ) slota = 10;
|
|
let [dummyb, slotb] = players[consoleplayer].weapons.LocateWeapon(Weapon(b).GetClass());
|
|
if ( slotb == 0 ) slotb = 10;
|
|
if ( slota == slotb )
|
|
return (Weapon(a).SlotPriority <= Weapon(b).SlotPriority);
|
|
return slota > slotb;
|
|
}
|
|
else if ( a is 'Ammo' )
|
|
{
|
|
Class<Weapon> usesa, usesb;
|
|
foreach ( cls:AllActorClasses )
|
|
{
|
|
let w = (Class<Weapon>)(cls);
|
|
if ( !w ) continue;
|
|
let def = GetDefaultByType(w);
|
|
if ( w is 'SWWMWeapon' )
|
|
{
|
|
if ( SWWMWeapon(def).UsesAmmo(Ammo(a).GetClass()) )
|
|
usesa = w;
|
|
if ( SWWMWeapon(def).UsesAmmo(Ammo(b).GetClass()) )
|
|
usesb = w;
|
|
}
|
|
else
|
|
{
|
|
if ( (def.AmmoType1 == Ammo(a).GetClass()) || (def.AmmoType2 == Ammo(a).GetClass()) )
|
|
usesa = w;
|
|
if ( (def.AmmoType1 == Ammo(b).GetClass()) || (def.AmmoType2 == Ammo(b).GetClass()) )
|
|
usesb = w;
|
|
}
|
|
if ( usesa && usesb )
|
|
break;
|
|
}
|
|
if ( usesa && usesb )
|
|
{
|
|
let [dummya, slota] = players[consoleplayer].weapons.LocateWeapon(usesa);
|
|
if ( slota == 0 ) slota = 10;
|
|
let [dummyb, slotb] = players[consoleplayer].weapons.LocateWeapon(usesb);
|
|
if ( slotb == 0 ) slotb = 10;
|
|
if ( slota == slotb )
|
|
{
|
|
// sort by unit value
|
|
int vala = abs(a.default.Stamina);
|
|
int valb = abs(b.default.Stamina);
|
|
if ( vala == valb )
|
|
{
|
|
// sort alphabetically
|
|
return a.GetTag() > b.GetTag();
|
|
}
|
|
return vala > valb;
|
|
}
|
|
return slota > slotb;
|
|
}
|
|
}
|
|
else if ( a is 'MagAmmo' )
|
|
{
|
|
// oh boy this one gets complicated
|
|
Class<Ammo> pamoa, pamob;
|
|
pamoa = MagAmmo(a).ParentAmmo;
|
|
pamob = MagAmmo(b).ParentAmmo;
|
|
Class<Weapon> usesa, usesb;
|
|
foreach ( cls:AllActorClasses )
|
|
{
|
|
let w = (Class<Weapon>)(cls);
|
|
if ( !w ) continue;
|
|
let def = GetDefaultByType(w);
|
|
if ( w is 'SWWMWeapon' )
|
|
{
|
|
if ( SWWMWeapon(def).UsesAmmo(pamoa) )
|
|
usesa = w;
|
|
if ( SWWMWeapon(def).UsesAmmo(pamob) )
|
|
usesb = w;
|
|
}
|
|
else
|
|
{
|
|
if ( (def.AmmoType1 == pamoa) || (def.AmmoType2 == pamoa) )
|
|
usesa = w;
|
|
if ( (def.AmmoType1 == pamob) || (def.AmmoType2 == pamob) )
|
|
usesb = w;
|
|
}
|
|
if ( usesa && usesb )
|
|
break;
|
|
}
|
|
if ( usesa && usesb )
|
|
{
|
|
let [dummya, slota] = players[consoleplayer].weapons.LocateWeapon(usesa);
|
|
if ( slota == 0 ) slota = 10;
|
|
let [dummyb, slotb] = players[consoleplayer].weapons.LocateWeapon(usesb);
|
|
if ( slotb == 0 ) slotb = 10;
|
|
if ( slota == slotb )
|
|
{
|
|
// sort by unit value
|
|
int vala = GetDefaultByType(pamoa).Stamina;
|
|
int valb = GetDefaultByType(pamob).Stamina;
|
|
if ( vala == valb )
|
|
{
|
|
// sort alphabetically
|
|
return a.GetTag() > b.GetTag();
|
|
}
|
|
return vala > valb;
|
|
}
|
|
return slota > slotb;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// sort by unit value
|
|
int vala = abs(a.default.Stamina);
|
|
int valb = abs(b.default.Stamina);
|
|
if ( vala == valb )
|
|
{
|
|
// sort alphabetically
|
|
return a.GetTag() > b.GetTag();
|
|
}
|
|
return vala > valb;
|
|
}
|
|
}
|
|
return ta > tb;
|
|
}
|
|
private int partition_inventory( Array<DemolitionistMenuListItem> a, int l, int h )
|
|
{
|
|
DemolitionistMenuListItem pv = a[h];
|
|
int i = (l-1);
|
|
for ( int j=l; j<=(h-1); j++ )
|
|
{
|
|
if ( CmpInventory(DemolitionistMenuInvItem(pv).inv,DemolitionistMenuInvItem(a[j]).inv) )
|
|
{
|
|
i++;
|
|
DemolitionistMenuListItem tmp = a[j];
|
|
a[j] = a[i];
|
|
a[i] = tmp;
|
|
}
|
|
}
|
|
DemolitionistMenuListItem tmp = a[h];
|
|
a[h] = a[i+1];
|
|
a[i+1] = tmp;
|
|
return i+1;
|
|
}
|
|
private void qsort_inventory( Array<DemolitionistMenuListItem> a, int l, int h )
|
|
{
|
|
if ( l >= h ) return;
|
|
int p = partition_inventory(a,l,h);
|
|
qsort_inventory(a,l,p-1);
|
|
qsort_inventory(a,p+1,h);
|
|
}
|
|
|
|
override DemolitionistMenuTab Init( DemolitionistMenu master )
|
|
{
|
|
title = StringTable.Localize("$SWWM_INVTAB");
|
|
return Super.Init(master);
|
|
}
|
|
|
|
override void OnDestroy()
|
|
{
|
|
Super.OnDestroy();
|
|
if ( invlist ) invlist.Destroy();
|
|
}
|
|
|
|
override void OnSelect()
|
|
{
|
|
smofs = ofs;
|
|
}
|
|
override void OnDeselect()
|
|
{
|
|
smofs = ofs;
|
|
}
|
|
|
|
private bool FilterInventory( Inventory inv )
|
|
{
|
|
if ( !inv || (inv.Owner != players[consoleplayer].mo) ) return true;
|
|
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') || (!(inv is 'Ammo') && !(inv is 'Weapon') && !inv.bINVBAR) && !(inv is 'HammerspaceEmbiggener') && !(inv is 'SWWMCollectible') && !(inv is 'MagAmmo') || (inv is 'SWWMCollectible') ) return true;
|
|
// no hidden weapons
|
|
if ( (inv is 'SWWMWeapon') && SWWMWeapon(inv).bHIDEINMENU ) return true;
|
|
return false;
|
|
}
|
|
|
|
// notified that this item has already been used up, so remove it from the list
|
|
void UsedUp( Class<Inventory> itm )
|
|
{
|
|
for ( int i=0; i<invlist.items.Size(); i++ )
|
|
{
|
|
if ( DemolitionistMenuInvItem(invlist.items[i]).inv.GetClass() != itm )
|
|
continue;
|
|
invlist.items[i].Destroy();
|
|
invlist.items.Delete(i);
|
|
if ( invlist.selected > i ) invlist.selected = max(0,invlist.selected-1);
|
|
i--;
|
|
}
|
|
}
|
|
|
|
override void Ticker()
|
|
{
|
|
bool mustsort = false;
|
|
bool skipsel = false;
|
|
if ( !invlist )
|
|
{
|
|
mustsort = true;
|
|
skipsel = true;
|
|
// initialize
|
|
invlist = new('DemolitionistMenuList');
|
|
invlist.master = master;
|
|
invlist.selected = 0;
|
|
for ( Inventory i=players[consoleplayer].mo.inv; i; i=i.inv )
|
|
{
|
|
if ( FilterInventory(i) ) continue;
|
|
// make sure we sort alphabetically on first insert
|
|
String tag = i.GetTag();
|
|
bool greater = false;
|
|
for ( int j=0; j<invlist.items.Size(); j++ )
|
|
{
|
|
String tag2 = DemolitionistMenuInvItem(invlist.items[j]).inv.GetTag();
|
|
if ( tag > tag2 ) continue;
|
|
greater = true;
|
|
invlist.items.Insert(j,new('DemolitionistMenuInvItem').Init(master,i));
|
|
break;
|
|
}
|
|
if ( greater ) continue;
|
|
invlist.items.Push(new('DemolitionistMenuInvItem').Init(master,i));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if current entries must be deleted
|
|
for ( int i=0; i<invlist.items.Size(); i++ )
|
|
{
|
|
if ( !FilterInventory(DemolitionistMenuInvItem(invlist.items[i]).inv) ) continue;
|
|
invlist.items[i].Destroy();
|
|
invlist.items.Delete(i);
|
|
if ( invlist.selected > i ) invlist.selected = max(0,invlist.selected-1);
|
|
i--;
|
|
}
|
|
// check if new entries must be added
|
|
for ( Inventory inv=players[consoleplayer].mo.inv; inv; inv=inv.inv )
|
|
{
|
|
if ( FilterInventory(inv) ) continue;
|
|
// skip if it's already there
|
|
bool skipme = false;
|
|
foreach ( i:invlist.items )
|
|
{
|
|
if ( DemolitionistMenuInvItem(i).inv != inv ) continue;
|
|
skipme = true;
|
|
break;
|
|
}
|
|
if ( skipme ) continue;
|
|
// make sure we sort alphabetically on first insert
|
|
String tag = inv.GetTag();
|
|
bool greater = false;
|
|
for ( int j=0; j<invlist.items.Size(); j++ )
|
|
{
|
|
String tag2 = DemolitionistMenuInvItem(invlist.items[j]).inv.GetTag();
|
|
if ( tag > tag2 ) continue;
|
|
greater = true;
|
|
invlist.items.Insert(j,new('DemolitionistMenuInvItem').Init(master,inv));
|
|
mustsort = true;
|
|
break;
|
|
}
|
|
if ( greater ) continue;
|
|
invlist.items.Push(new('DemolitionistMenuInvItem').Init(master,inv));
|
|
mustsort = true;
|
|
}
|
|
}
|
|
// don't do anything if empty
|
|
if ( invlist.items.Size() <= 0 ) return;
|
|
// sort inventory
|
|
if ( mustsort )
|
|
{
|
|
DemolitionistMenuListItem csel = invlist.items[invlist.selected];
|
|
qsort_inventory(invlist.items,0,invlist.items.Size()-1);
|
|
let idx = invlist.items.Find(csel);
|
|
if ( !skipsel && (idx != invlist.items.Size()) && (idx != invlist.selected) )
|
|
invlist.selected = idx;
|
|
}
|
|
// rearrange all item positions
|
|
maxofs = 0;
|
|
int maxw = invlist.GetWidth();
|
|
int xx = 0;
|
|
int yy = 0;
|
|
foreach ( i:invlist.items )
|
|
{
|
|
maxofs = max(maxofs,int(xx+i.GetWidth()));
|
|
i.xpos = xx;
|
|
i.ypos = yy;
|
|
yy += 16;
|
|
if ( yy > (master.ws.y-62) )
|
|
{
|
|
xx += maxw+16; // pad
|
|
yy = 0;
|
|
}
|
|
}
|
|
maxofs = max(0,maxofs-int(master.ws.x-18));
|
|
if ( ofs > maxofs ) smofs = ofs = maxofs;
|
|
// update smooth scroll
|
|
smofs = (smofs*.6)+(ofs*.4);
|
|
if ( abs(smofs-ofs) < (1./master.hs) ) smofs = ofs;
|
|
// tick the list
|
|
invlist.Ticker();
|
|
}
|
|
|
|
// called when sending a scroll input
|
|
// returns true if the position actually changed
|
|
// speed: how many pixels to move (either back or forward)
|
|
bool Scroll( int speed )
|
|
{
|
|
if ( maxofs <= 0 ) return false;
|
|
int oldofs = ofs;
|
|
ofs = clamp(ofs+speed,0,maxofs);
|
|
return (ofs != oldofs);
|
|
}
|
|
// called when clicking on our scrollbar
|
|
// returns true if the position actually changed
|
|
// x: relative click position
|
|
bool SetOffset( double x )
|
|
{
|
|
if ( maxofs <= 0 ) return false;
|
|
int oldofs = ofs;
|
|
ofs = clamp(int(round((x-5.)/((master.ws.x-10.)/maxofs))),0,maxofs);
|
|
return (ofs != oldofs);
|
|
}
|
|
// called when keyboard scrolling
|
|
void KBScroll()
|
|
{
|
|
if ( maxofs <= 0 ) return;
|
|
int minx = (invlist.items[invlist.selected].xpos+invlist.items[invlist.selected].GetWidth())-int(master.ws.x-18);
|
|
int maxx = invlist.items[invlist.selected].xpos;
|
|
if ( ofs < minx ) ofs = clamp(minx,0,maxofs);
|
|
else if ( ofs > maxx ) ofs = clamp(maxx,0,maxofs);
|
|
}
|
|
|
|
override void MenuInput( int key )
|
|
{
|
|
if ( !invlist || (invlist.items.Size() <= 0) ) return;
|
|
switch ( key )
|
|
{
|
|
case MK_LEFT:
|
|
int prev = max(0,invlist.selected-22);
|
|
if ( prev == invlist.selected ) break;
|
|
invlist.selected = prev;
|
|
master.MenuSound("menu/demoscroll");
|
|
KBScroll();
|
|
break;
|
|
case MK_RIGHT:
|
|
int next = min(invlist.items.Size()-1,invlist.selected+22);
|
|
if ( next == invlist.selected ) break;
|
|
invlist.selected = next;
|
|
master.MenuSound("menu/demoscroll");
|
|
KBScroll();
|
|
break;
|
|
case MK_DOWN:
|
|
if ( invlist.selected < invlist.items.Size()-1 )
|
|
{
|
|
invlist.selected++;
|
|
master.MenuSound("menu/demoscroll");
|
|
KBScroll();
|
|
}
|
|
break;
|
|
case MK_UP:
|
|
if ( invlist.selected > 0 )
|
|
{
|
|
invlist.selected--;
|
|
master.MenuSound("menu/demoscroll");
|
|
KBScroll();
|
|
}
|
|
break;
|
|
case MK_ENTER:
|
|
if ( invlist.selected >= invlist.items.Size() ) break;
|
|
DemolitionistMenuInvItem(invlist.items[invlist.selected]).UseItem();
|
|
break;
|
|
case MK_BACK:
|
|
if ( invlist.selected >= invlist.items.Size() ) break;
|
|
DemolitionistMenuInvItem(invlist.items[invlist.selected]).DropItem();
|
|
break;
|
|
}
|
|
}
|
|
override void MouseInput( Vector2 pos, int btn )
|
|
{
|
|
if ( !invlist || (invlist.items.Size() <= 0) ) return;
|
|
switch ( btn )
|
|
{
|
|
case MB_LEFT:
|
|
// see if we're clicking the scrollbar (if it exists)
|
|
if ( pos.y > (master.ws.y-21) )
|
|
{
|
|
if ( SetOffset(pos.x) )
|
|
{
|
|
master.MenuSound("menu/demoscroll");
|
|
drag = true;
|
|
}
|
|
break;
|
|
}
|
|
// find which element we clicked
|
|
for ( int i=0; i<invlist.items.Size(); i++ )
|
|
{
|
|
if ( !invlist.items[i].CheckBounds((pos.x-9)+smofs,pos.y-23) )
|
|
continue;
|
|
invlist.selected = i;
|
|
KBScroll();
|
|
// use it
|
|
MenuInput(MK_ENTER);
|
|
break;
|
|
}
|
|
break;
|
|
case MB_RIGHT:
|
|
// find which element we clicked
|
|
for ( int i=0; i<invlist.items.Size(); i++ )
|
|
{
|
|
if ( !invlist.items[i].CheckBounds((pos.x-9)+smofs,pos.y-23) )
|
|
continue;
|
|
invlist.selected = i;
|
|
KBScroll();
|
|
// drop it
|
|
MenuInput(MK_BACK);
|
|
break;
|
|
}
|
|
break;
|
|
case MB_WHEELUP:
|
|
if ( Scroll(-invlist.GetWidth()/16) ) master.MenuSound("menu/demoscroll");
|
|
break;
|
|
case MB_WHEELDOWN:
|
|
if ( Scroll(invlist.GetWidth()/16) ) master.MenuSound("menu/demoscroll");
|
|
break;
|
|
case MB_DRAG:
|
|
if ( drag ) SetOffset(pos.x);
|
|
break;
|
|
case MB_RELEASE:
|
|
drag = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
override void Drawer( double fractic )
|
|
{
|
|
if ( !invlist || (invlist.items.Size() <= 0) )
|
|
{
|
|
String str = StringTable.Localize("$SWWM_NOINV");
|
|
double xx = int(master.ws.x-master.mSmallFont.StringWidth(str))/2;
|
|
double yy = int(master.ws.y-master.mSmallFont.GetHeight())/2;
|
|
Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
double ssmofs = (smofs~==ofs)?smofs:(smofs*(1.-fractic)+((smofs*.6)+(ofs*.4))*fractic);
|
|
double xx = 9;
|
|
double yy = 23;
|
|
Screen.SetClipRect(int((master.origin.x+9)*master.hs),int((master.origin.y+23)*master.hs),int((master.ws.x-18)*master.hs),int((master.ws.y-46)*master.hs));
|
|
invlist.Drawer((xx-ssmofs,yy));
|
|
Screen.ClearClipRect();
|
|
if ( maxofs <= 0 ) return;
|
|
yy = master.ws.y-21;
|
|
master.DrawHSeparator(0,yy,master.ws.x);
|
|
yy -= 4;
|
|
xx = floor(ssmofs*((master.ws.x-10)/maxofs))+2;
|
|
Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,"▬",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
|
|
// item use/drop transaction handling
|
|
Class MenuTransaction
|
|
{
|
|
enum ETransactionType
|
|
{
|
|
TT_ITEMUSE,
|
|
TT_ITEMDROP
|
|
};
|
|
int uid, type;
|
|
Class<Inventory> used;
|
|
bool skipresult;
|
|
}
|
|
|
|
extend Class DemolitionistMenu
|
|
{
|
|
Array<MenuTransaction> checklist;
|
|
int lasttuid;
|
|
|
|
void ItemUsed( int uid, bool result, bool usedup )
|
|
{
|
|
for ( int i=0; i<checklist.Size(); i++ )
|
|
{
|
|
if ( checklist[i].uid != uid ) continue;
|
|
if ( checklist[i].type != MenuTransaction.TT_ITEMUSE )
|
|
ThrowAbortException("transaction %d is not of type TT_ITEMUSE",uid);
|
|
// check if use succeeded
|
|
if ( checklist[i].skipresult || result )
|
|
{
|
|
// only play use sound if game isn't frozen
|
|
if ( !multiplayer && (menuactive == Menu.On) )
|
|
{
|
|
// if it's a weapon, play the select sound
|
|
// if it's a collectible or key, play the "hands up" sound
|
|
let w = (Class<Weapon>)(checklist[i].used);
|
|
if ( w )
|
|
{
|
|
// play if actually switching
|
|
if ( result )
|
|
{
|
|
String snd = GetDefaultByType(w).UpSound;
|
|
MenuSound(snd);
|
|
}
|
|
}
|
|
else if ( (checklist[i].used is 'SWWMCollectible') || (checklist[i].used is 'Key') )
|
|
MenuSound("demolitionist/handsup");
|
|
else
|
|
{
|
|
String snd = GetDefaultByType(checklist[i].used).UseSound;
|
|
MenuSound(snd);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_INVFAIL");
|
|
tmsgtic = MenuTime()+70;
|
|
MenuSound("menu/noinvuse");
|
|
}
|
|
if ( usedup )
|
|
{
|
|
int j = FindTabType('DemolitionistInventoryTab');
|
|
if ( j != -1 ) DemolitionistInventoryTab(tabs[j]).UsedUp(checklist[i].used);
|
|
}
|
|
checklist.Delete(i);
|
|
i--;
|
|
}
|
|
}
|
|
|
|
void ItemDropped( int uid, bool result, bool usedup )
|
|
{
|
|
for ( int i=0; i<checklist.Size(); i++ )
|
|
{
|
|
if ( checklist[i].uid != uid ) continue;
|
|
if ( checklist[i].type != MenuTransaction.TT_ITEMDROP )
|
|
ThrowAbortException("transaction %d is not of type TT_ITEMDROP",uid);
|
|
// check if drop failed
|
|
if ( !result )
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_INVNDROP");
|
|
tmsgtic = MenuTime()+70;
|
|
MenuSound("menu/noinvuse");
|
|
}
|
|
else if ( usedup )
|
|
{
|
|
int j = FindTabType('DemolitionistInventoryTab');
|
|
if ( j != -1 ) DemolitionistInventoryTab(tabs[j]).UsedUp(checklist[i].used);
|
|
}
|
|
checklist.Delete(i);
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// inventory item
|
|
Class DemolitionistMenuInvItem : DemolitionistMenuListItem
|
|
{
|
|
Inventory inv;
|
|
int col;
|
|
|
|
DemolitionistMenuInvItem Init( DemolitionistMenu master, Inventory i )
|
|
{
|
|
Super.Init(master,i.GetTag());
|
|
inv = i;
|
|
col = Font.CR_WHITE;
|
|
if ( i is 'Weapon' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPGold'):Font.CR_GOLD;
|
|
else if ( i is 'MagAmmo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPTan'):Font.CR_TAN;
|
|
else if ( (i is 'BackpackItem') || (i is 'HammerspaceEmbiggener') ) col = Font.CR_DARKBROWN;
|
|
else if ( i is 'Ammo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPBrown'):Font.CR_BROWN;
|
|
else if ( (i is 'PowerupGiver') || (i is 'AmmoFabricator') || i.bBIGPOWERUP ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPPurple'):Font.CR_PURPLE;
|
|
else if ( (i is 'Health') || (i is 'HealthPickup') || (i is 'SWWMHealth') ) col = Font.CR_RED;
|
|
else if ( (i is 'Armor') || (i is 'SWWMSpareArmor') ) col = Font.CR_GREEN;
|
|
else if ( i is 'PuzzleItem' ) col = Font.CR_LIGHTBLUE;
|
|
else if ( i is 'Key' ) col = Font.CR_UNTRANSLATED;
|
|
else if ( i is 'SWWMCollectible' ) col = Font.CR_PURPLE;
|
|
else if ( i.bINVBAR ) col = Font.CR_CYAN;
|
|
UpdateLabel();
|
|
return self;
|
|
}
|
|
|
|
// formatted name
|
|
private void UpdateLabel()
|
|
{
|
|
if ( !inv ) return;
|
|
if ( (inv is 'Ammo') || (inv is 'MagAmmo') )
|
|
label = String.Format("(%d/%d) %s",inv.Amount,inv.MaxAmount,SWWMUtility.GetAmmoTag(inv));
|
|
else if ( (inv.Amount > 1) || (!(inv is 'PuzzleItem') && !(inv is 'Weapon') && (inv.MaxAmount > 1)) )
|
|
label = String.Format("%dx %s",inv.Amount,inv.GetTag());
|
|
else label = inv.GetTag();
|
|
if ( inv is 'SWWMCollectible' )
|
|
label.AppendFormat(" \cj(\cg¥\cf%d\cj)\c-",inv.default.Stamina);
|
|
}
|
|
|
|
override void Ticker()
|
|
{
|
|
UpdateLabel();
|
|
}
|
|
|
|
override void Drawer( Vector2 pos, bool selected )
|
|
{
|
|
// the simplest drawer
|
|
Screen.DrawText(master.mSmallFont,col,master.origin.x+pos.x,master.origin.y+pos.y,label,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,selected?Color(0,0,0,0):Color(96,0,0,0));
|
|
}
|
|
|
|
void UseItem()
|
|
{
|
|
if ( !inv || (inv is 'Ammo') || (inv is 'MagAmmo') || (inv is 'HammerspaceEmbiggener') ) return;
|
|
// weapons can't be switched to if they have no ammo
|
|
if ( (inv is 'Weapon') && (((inv is 'SWWMWeapon') && !SWWMWeapon(inv).ReportHUDAmmo())
|
|
|| (!(inv is 'SWWMWeapon') && ((!Weapon(inv).Ammo1 || (Weapon(inv).Ammo1.Amount > 0) || Weapon(inv).bAMMO_OPTIONAL) || (Weapon(inv).Ammo2 && ((Weapon(inv).Ammo2.Amount > 0) || Weapon(inv).bALT_AMMO_OPTIONAL))))) )
|
|
{
|
|
master.MenuSound("menu/noinvuse");
|
|
master.tmsg = StringTable.Localize("$SWWM_INVNAMMO");
|
|
master.tmsgtic = Menu.MenuTime()+70;
|
|
return;
|
|
}
|
|
let t = new('MenuTransaction');
|
|
t.uid = master.GenTUID();
|
|
t.type = MenuTransaction.TT_ITEMUSE;
|
|
t.used = inv.GetClass();
|
|
// don't check weapons, keys or collectibles, always assume check succeeded
|
|
t.skipresult = ((inv is 'Weapon') || (inv is 'Key') || (inv is 'SWWMCollectible'));
|
|
master.checklist.Push(t);
|
|
EventHandler.SendNetworkCommand("swwmuseitem",NET_INT,t.uid,NET_INT,consoleplayer,NET_INT,inv.GetNetworkID());
|
|
}
|
|
|
|
void DropItem()
|
|
{
|
|
if ( !inv || (inv is 'Key') || (inv is 'SWWMCollectible') ) return;
|
|
let t = new('MenuTransaction');
|
|
t.uid = master.GenTUID();
|
|
t.type = MenuTransaction.TT_ITEMDROP;
|
|
t.skipresult = false;
|
|
master.checklist.Push(t);
|
|
EventHandler.SendNetworkCommand("swwmdropitem",NET_INT,t.uid,NET_INT,consoleplayer,NET_INT,inv.GetNetworkID());
|
|
}
|
|
}
|