- Doubled fuel capacity. - Increased fuel usage of dashing by 1.5x. - Reduced deceleration of boosting when holding jump. - Changed the fuel bar graphic to reflect new capacity. Increased air control. Fixed reported fuel usage (the fuel cells are 4L).
2396 lines
80 KiB
Text
2396 lines
80 KiB
Text
// internal "knowledge base" and more
|
|
Class SWWMKnowledgeBaseMenu : GenericMenu
|
|
{
|
|
enum EDemoTab
|
|
{
|
|
TAB_MISSION = 0,
|
|
TAB_STATS,
|
|
TAB_INVENTORY,
|
|
TAB_KEYS,
|
|
TAB_LIBRARY,
|
|
TAB_STORE,
|
|
TAB_TRADING,
|
|
TAB_CHAT,
|
|
TAB_SECRET,
|
|
TAB_HELP
|
|
};
|
|
|
|
TextureID MainWindow, TabSeparator, WindowSeparator, WindowSeparatorH,
|
|
FancyBg, EasterEgg, LoreSeparator, LoreSeparatorW;
|
|
transient CVar lang, fuzz;
|
|
transient Font TewiFont, MPlusFont;
|
|
int curtab, oldtab;
|
|
// for scrolling
|
|
bool sub;
|
|
int sel0, sel1, sel2;
|
|
int ofs0, ofs1, ofs2; // usually equal to above, except when using mouse input
|
|
int drag; // when dragging with the mouse, which scroller to affect (1 = ofs0 and so on)
|
|
// stats
|
|
SWWMStats stats;
|
|
// inventory lists
|
|
Array<Inventory> invlist;
|
|
// lore stuff
|
|
SWWMLoreLibrary lorelib;
|
|
Array<SWWMLore> lorelist;
|
|
int oldloresiz;
|
|
// store stuff
|
|
Array<Class<Inventory> > storelist;
|
|
Array<int> storeunits;
|
|
// trading
|
|
SWWMTradeHistory tradelib;
|
|
Array<int> playerlist;
|
|
// chat history total line count (includes breaks)
|
|
int chatlines;
|
|
// temporary bottom messages, such as "not enough money"
|
|
String tmsg;
|
|
int tmsgtic;
|
|
// menu keybind
|
|
int ikey[2];
|
|
String mkey[2];
|
|
// color for chat
|
|
CVar ccol, tcol;
|
|
// for checks (duh)
|
|
Class<Inventory> lastuse;
|
|
int lastuseamt;
|
|
int checkuse;
|
|
int checkdrop;
|
|
int checksend;
|
|
// seeeeecret
|
|
int kcode;
|
|
// crimey clock stuff
|
|
int c_year, c_month, c_day, c_hour, c_minute;
|
|
// mouse stuff
|
|
Vector2 curmouse;
|
|
bool isrclick;
|
|
|
|
// returns MPlus if we're playing in Japanese, otherwise returns the requested font
|
|
Font LangFont( Font req )
|
|
{
|
|
if ( !lang ) lang = CVar.GetCVar('language',players[consoleplayer]);
|
|
if ( lang.GetString() ~== "jp" ) return MPlusFont;
|
|
return req;
|
|
}
|
|
|
|
override void Init( Menu parent )
|
|
{
|
|
Super.Init(parent);
|
|
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) )
|
|
{
|
|
// can't open this menu outside of the game or if dead
|
|
Close();
|
|
return;
|
|
}
|
|
TewiFont = Font.GetFont('TewiShaded');
|
|
MPlusFont = Font.GetFont('MPlusShaded');
|
|
FancyBg = TexMan.CheckForTexture("graphics/tempbg.png",TexMan.Type_MiscPatch);
|
|
MainWindow = TexMan.CheckForTexture("graphics/KBase/MainWindow.png",TexMan.Type_MiscPatch);
|
|
TabSeparator = TexMan.CheckForTexture("graphics/KBase/TabSeparator.png",TexMan.Type_MiscPatch);
|
|
WindowSeparator = TexMan.CheckForTexture("graphics/KBase/WindowSeparator.png",TexMan.Type_MiscPatch);
|
|
WindowSeparatorH = TexMan.CheckForTexture("graphics/KBase/WindowSeparatorH.png",TexMan.Type_MiscPatch);
|
|
EasterEgg = TexMan.CheckForTexture("graphics/KBase/Drawing.png",TexMan.Type_MiscPatch);
|
|
LoreSeparator = TexMan.CheckForTexture("graphics/KBase/LibraryTabSeparator.png",TexMan.Type_MiscPatch);
|
|
LoreSeparatorW = TexMan.CheckForTexture("graphics/KBase/LibraryTabSeparatorJP.png",TexMan.Type_MiscPatch);
|
|
curtab = CVar.GetCVar('swwm_lasttab',players[consoleplayer]).GetInt();
|
|
int maxtab = multiplayer?TAB_CHAT:TAB_STORE;
|
|
if ( (curtab < TAB_MISSION) || (curtab > maxtab) ) curtab = TAB_MISSION;
|
|
if ( curtab == TAB_LIBRARY ) sel1 = CVar.GetCVar('swwm_lastloretab',players[consoleplayer]).GetInt();
|
|
MenuSound("menu/demoopen");
|
|
[ikey[0], ikey[1]] = Bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu");
|
|
mkey[0] = Bindings.NameKeys(ikey[0],0);
|
|
mkey[1] = Bindings.NameKeys(ikey[1],0);
|
|
ccol = CVar.GetCVar("msg3color",players[consoleplayer]);
|
|
tcol = CVar.GetCVar("msg4color",players[consoleplayer]);
|
|
lorelib = SWWMLoreLibrary.Find(players[consoleplayer]);
|
|
oldloresiz = lorelib.ent.Size();
|
|
tradelib = SWWMTradeHistory.Find(players[consoleplayer]);
|
|
stats = SWWMStats.Find(players[consoleplayer]);
|
|
tmsg = "$SWWM_MAINCONTROLS";
|
|
tmsgtic = gametic+70;
|
|
if ( gameinfo.gametype&GAME_Heretic )
|
|
{
|
|
c_year = 2171;
|
|
c_month = 3;
|
|
c_day = 9;
|
|
c_hour = 9;
|
|
c_minute = 41;
|
|
}
|
|
else if ( gameinfo.gametype&GAME_Hexen )
|
|
{
|
|
c_year = 2171;
|
|
c_month = 4;
|
|
c_day = 24;
|
|
c_hour = 16;
|
|
c_minute = 41;
|
|
}
|
|
else if ( gameinfo.gametype&GAME_Strife )
|
|
{
|
|
c_year = 2173;
|
|
c_month = 7;
|
|
c_day = 12;
|
|
c_hour = 11;
|
|
c_minute = 26;
|
|
}
|
|
else // Doom
|
|
{
|
|
c_year = 2148;
|
|
c_month = 5;
|
|
c_day = 5;
|
|
c_hour = 12;
|
|
c_minute = 27;
|
|
}
|
|
}
|
|
|
|
// please don't look at this
|
|
private String CrimeTime()
|
|
{
|
|
static const int days_in_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
|
|
bool leap_year;
|
|
int y = c_year, m = c_month, d = c_day, h = c_hour, mn = c_minute;
|
|
int addtime = level.totaltime/Thinker.TICRATE;
|
|
while ( addtime > 0 )
|
|
{
|
|
leap_year = (!(y%4) && ((y%100) || !(y%400)));
|
|
if ( addtime >= 86400 )
|
|
{
|
|
addtime -= 86400;
|
|
d++;
|
|
int md = days_in_month[m];
|
|
if ( leap_year && (m == 1) ) md++;
|
|
if ( d >= md )
|
|
{
|
|
d = 0;
|
|
m++;
|
|
if ( m > 11 )
|
|
{
|
|
m = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
else if ( addtime >= 3600 )
|
|
{
|
|
addtime -= 3600;
|
|
h++;
|
|
if ( h > 23 )
|
|
{
|
|
h = 0;
|
|
d++;
|
|
int md = days_in_month[m];
|
|
if ( leap_year && (m == 1) ) md++;
|
|
if ( d >= md )
|
|
{
|
|
d = 0;
|
|
m++;
|
|
if ( m > 11 )
|
|
{
|
|
m = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( addtime >= 60 )
|
|
{
|
|
addtime -= 60;
|
|
mn++;
|
|
if ( mn > 59 )
|
|
{
|
|
mn = 0;
|
|
h++;
|
|
if ( h > 23 )
|
|
{
|
|
h = 0;
|
|
d++;
|
|
int md = days_in_month[m];
|
|
if ( leap_year && (m == 1) ) md++;
|
|
if ( d >= md )
|
|
{
|
|
d = 0;
|
|
m++;
|
|
if ( m > 11 )
|
|
{
|
|
m = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// we finished counting
|
|
addtime = 0;
|
|
}
|
|
}
|
|
return String.Format("%04d-%02d-%02d %02d:%02d",y,m+1,d+1,h,mn);
|
|
}
|
|
|
|
override bool MenuEvent( int mkey, bool fromcontroller )
|
|
{
|
|
Font fnt = LangFont(TewiFont);
|
|
switch ( kcode )
|
|
{
|
|
case 0:
|
|
case 1:
|
|
if ( mkey == MKEY_UP ) kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
if ( mkey == MKEY_DOWN ) kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
case 4:
|
|
case 6:
|
|
if ( mkey == MKEY_LEFT ) kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
case 5:
|
|
case 7:
|
|
if ( mkey == MKEY_RIGHT ) kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
case 10:
|
|
if ( mkey == MKEY_ENTER )
|
|
{
|
|
MenuSound("misc/secret");
|
|
curtab = TAB_SECRET;
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
}
|
|
default:
|
|
kcode = 0;
|
|
break;
|
|
}
|
|
int maxtab = multiplayer?TAB_CHAT:TAB_STORE;
|
|
switch ( mkey )
|
|
{
|
|
case MKEY_BACK:
|
|
MenuSound("menu/democlose");
|
|
Close();
|
|
return true;
|
|
case MKEY_PAGEUP:
|
|
MenuSound("menu/demotab");
|
|
if ( (curtab <= TAB_MISSION) || (curtab > maxtab) ) curtab = maxtab;
|
|
else curtab--;
|
|
CVar.GetCVar('swwm_lasttab',players[consoleplayer]).SetInt(curtab);
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
invlist.Clear();
|
|
lorelist.Clear();
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
playerlist.Clear();
|
|
return true;
|
|
case MKEY_PAGEDOWN:
|
|
MenuSound("menu/demotab");
|
|
if ( curtab < maxtab ) curtab++;
|
|
else curtab = TAB_MISSION;
|
|
CVar.GetCVar('swwm_lasttab',players[consoleplayer]).SetInt(curtab);
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
invlist.Clear();
|
|
lorelist.Clear();
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
playerlist.Clear();
|
|
return true;
|
|
case MKEY_DOWN:
|
|
if ( curtab == TAB_HELP )
|
|
{
|
|
String str = StringTable.Localize("$SWWM_HELPTXT");
|
|
if ( multiplayer ) str = str..StringTable.Localize("$SWWM_HELPTXT_MP");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
if ( (l.Count() > 28) && (sel0 < l.Count()-28) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
sel0++;
|
|
}
|
|
}
|
|
else if ( curtab == TAB_MISSION )
|
|
{
|
|
String str = StringTable.Localize("$SWWM_MISSION_NONE");
|
|
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
|
|
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
|
|
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
if ( (l.Count() > 28) && (sel0 < l.Count()-28) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = ++sel0;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_CHAT) && (StatusBar is 'SWWMStatusBar') && (sel0 > 0) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
}
|
|
else if ( (curtab == TAB_LIBRARY) && (lorelist.Size() > 1) )
|
|
{
|
|
if ( sub )
|
|
{
|
|
String str = StringTable.Localize(lorelist[sel0].text);
|
|
int ofs = (lang.GetString()~=="jp")?212:132;
|
|
if ( lorelist.Size() > 26 ) ofs += 8;
|
|
BrokenLines l = fnt.BreakLines(str,635-ofs);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,626-ofs);
|
|
if ( (l.Count() > 28) && (sel2 < l.Count()-28) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs2 = ++sel2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
if ( sel0 >= lorelist.Size()-1 ) ofs0 = sel0 = 0;
|
|
else
|
|
{
|
|
sel0++;
|
|
// update ofs so selection stays on-screen
|
|
int ofs = max(ofs0-26,0);
|
|
if ( sel0 < ofs ) ofs0 = sel0+26;
|
|
else if ( sel0 > ofs+26 ) ofs0 = sel0;
|
|
}
|
|
}
|
|
}
|
|
else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 1) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = ++sel0;
|
|
if ( sel0 >= invlist.Size() ) ofs0 = sel0 = 0;
|
|
}
|
|
else if ( (curtab == TAB_STORE) && (storelist.Size() > 1) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = ++sel0;
|
|
if ( sel0 >= storelist.Size() ) ofs0 = sel0 = 0;
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub && (playerlist.Size() > 1) )
|
|
{
|
|
// scroll through player list
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = ++sel0;
|
|
if ( sel0 >= playerlist.Size() ) ofs0 = sel0 = 0;
|
|
}
|
|
else if ( sub && (sel0 == -1) && (sel1 < tradelib.ent.Size()-28) )
|
|
{
|
|
// scroll through trading history
|
|
MenuSound("menu/demoscroll");
|
|
ofs1 = ++sel1;
|
|
}
|
|
}
|
|
return true;
|
|
case MKEY_UP:
|
|
if ( (curtab == TAB_HELP) && (sel0 > 0) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
}
|
|
else if ( (curtab == TAB_MISSION) && (sel0 > 0) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
}
|
|
else if ( (curtab == TAB_CHAT) && (StatusBar is 'SWWMStatusBar') && (sel0 < SWWMStatusBar(StatusBar).FullHistory.Size()-1) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = ++sel0;
|
|
}
|
|
else if ( (curtab == TAB_LIBRARY) && (lorelist.Size() > 1) )
|
|
{
|
|
if ( sub )
|
|
{
|
|
if ( sel2 > 0 )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs2 = --sel2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
if ( sel0 <= 0 ) ofs0 = sel0 = lorelist.Size()-1;
|
|
else
|
|
{
|
|
sel0--;
|
|
// update ofs so selection stays on-screen
|
|
int ofs = max(ofs0-26,0);
|
|
if ( sel0 < ofs ) ofs0 = sel0+26;
|
|
else if ( sel0 > ofs+26 ) ofs0 = sel0;
|
|
}
|
|
}
|
|
}
|
|
else if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 1) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
if ( sel0 < 0 ) ofs0 = sel0 = invlist.Size()-1;
|
|
}
|
|
else if ( (curtab == TAB_STORE) && (storelist.Size() > 1) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
if ( sel0 < 0 ) ofs0 = sel0 = storelist.Size()-1;
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub && (playerlist.Size() > 1) )
|
|
{
|
|
// scroll through player list
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = --sel0;
|
|
if ( sel0 < 0 ) ofs0 = sel0 = playerlist.Size()-1;
|
|
}
|
|
else if ( sub && (sel0 == -1) && (sel1 > 0) )
|
|
{
|
|
// scroll through trading history
|
|
MenuSound("menu/demoscroll");
|
|
ofs1 = --sel1;
|
|
}
|
|
}
|
|
return true;
|
|
case MKEY_RIGHT:
|
|
if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 21) )
|
|
{
|
|
int oldsel = sel0;
|
|
ofs0 = sel0 += 22;
|
|
if ( sel0 >= invlist.Size() ) ofs0 = sel0 = invlist.Size()-1;
|
|
if ( sel0 != oldsel ) MenuSound("menu/demoscroll");
|
|
}
|
|
else if ( (curtab == TAB_STORE) && (storelist.Size() > 21) )
|
|
{
|
|
int oldsel = sel0;
|
|
ofs0 = sel0 += 22;
|
|
if ( sel0 >= storelist.Size() ) ofs0 = sel0 = storelist.Size()-1;
|
|
if ( sel0 != oldsel ) MenuSound("menu/demoscroll");
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = 0;
|
|
sub = false;
|
|
ofs1 = ++sel1;
|
|
if ( sel1 > LORE_LORE ) ofs1 = sel1 = LORE_ITEM;
|
|
CVar.GetCVar('swwm_lastloretab',players[consoleplayer]).SetInt(sel1);
|
|
}
|
|
else if ( (curtab == TAB_TRADING) && !sub && (playerlist.Size() > 21) ) // lol is this ever going to happen
|
|
{
|
|
int oldsel = sel0;
|
|
ofs0 = sel0 += 22;
|
|
if ( sel0 >= playerlist.Size() ) ofs0 = sel0 = playerlist.Size()-1;
|
|
if ( sel0 != oldsel ) MenuSound("menu/demoscroll");
|
|
}
|
|
return true;
|
|
case MKEY_LEFT:
|
|
if ( ((curtab == TAB_INVENTORY) || (curtab == TAB_KEYS) || ((curtab == TAB_TRADING) && sub && (sel0 != -1))) && (invlist.Size() > 21) && (sel0-22 >= 0) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 -= 22;
|
|
}
|
|
else if ( (curtab == TAB_STORE) && (storelist.Size() > 21) && (sel0-22 >= 0) )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 -= 22;
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = 0;
|
|
sub = false;
|
|
ofs1 = --sel1;
|
|
if ( sel1 < LORE_ITEM ) ofs1 = sel1 = LORE_LORE;
|
|
CVar.GetCVar('swwm_lastloretab',players[consoleplayer]).SetInt(sel1);
|
|
}
|
|
else if ( (curtab == TAB_TRADING) && !sub && (playerlist.Size() > 21) && (sel0-22 >= 0) ) // lol is this ever going to happen
|
|
{
|
|
ofs0 = sel0 -= 22;
|
|
MenuSound("menu/demoscroll");
|
|
}
|
|
return true;
|
|
case MKEY_ENTER:
|
|
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) && (sel0 < invlist.Size()) )
|
|
{
|
|
// can't use this
|
|
if ( invlist[sel0] is 'Ammo' ) return true;
|
|
lastuse = invlist[sel0].GetClass();
|
|
lastuseamt = invlist[sel0].Amount;
|
|
// don't check weapons (or the lamp)
|
|
if ( !(invlist[sel0] is 'Weapon') && !(invlist[sel0] is 'SWWMLamp') )
|
|
checkuse = gametic+(multiplayer?5:1);
|
|
EventHandler.SendNetworkEvent(String.Format("swwmuseitem.%s",invlist[sel0].GetClassName()),consoleplayer);
|
|
}
|
|
else if ( (curtab == TAB_STORE) && (storelist.Size() > 0) && (sel0 < storelist.Size()) )
|
|
{
|
|
let itm = GetDefaultByType(storelist[sel0]);
|
|
let amt = storeunits[sel0];
|
|
int price = int(itm.Stamina*(1.+.5*(amt-1)));
|
|
if ( !SWWMCredits.CanTake(players[consoleplayer],price) )
|
|
{
|
|
MenuSound("menu/noinvuse");
|
|
tmsg = StringTable.Localize("$SWWM_STOREMUNS");
|
|
tmsgtic = gametic+70;
|
|
return true;
|
|
}
|
|
let cur = players[consoleplayer].mo.FindInventory(storelist[sel0]);
|
|
int camt, max;
|
|
if ( cur )
|
|
{
|
|
camt = cur.Amount;
|
|
max = cur.MaxAmount;
|
|
}
|
|
else
|
|
{
|
|
camt = 0;
|
|
max = itm.MaxAmount;
|
|
}
|
|
if ( camt >= max )
|
|
{
|
|
MenuSound("menu/noinvuse");
|
|
tmsg = StringTable.Localize("$SWWM_STOREFULL");
|
|
tmsgtic = gametic+70;
|
|
return true;
|
|
}
|
|
EventHandler.SendNetworkEvent(String.Format("swwmstoregive.%s",storelist[sel0].GetClassName()),consoleplayer,price,amt);
|
|
if ( (camt+amt) >= max ) ofs1 = sel0 = max(0,sel0-1);
|
|
MenuSound("menu/buyinv");
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
if ( sub )
|
|
{
|
|
MenuSound("menu/democlose");
|
|
sub = false;
|
|
}
|
|
else if ( (lorelist.Size() > 0) && (sel0 < lorelist.Size()) )
|
|
{
|
|
// mark as read
|
|
if ( !lorelist[sel0].read )
|
|
EventHandler.SendNetworkEvent(String.Format("swwmmarkloreread.%s",lorelist[sel0].tag),consoleplayer);
|
|
MenuSound("menu/demosel");
|
|
sub = true;
|
|
ofs2 = sel2 = 0;
|
|
}
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub && (playerlist.Size() > 0) )
|
|
{
|
|
// pick a player
|
|
MenuSound("menu/demosel");
|
|
sub = true;
|
|
ofs1 = sel1 = 0;
|
|
}
|
|
else if ( sub && (sel0 != -1) && (invlist.Size() > 0) )
|
|
{
|
|
// trade item
|
|
lastuse = invlist[sel1].GetClass();
|
|
lastuseamt = invlist[sel1].Amount;
|
|
checksend = gametic+(multiplayer?5:1);
|
|
EventHandler.SendNetworkEvent(String.Format("swwmtrade.%s",invlist[sel1].GetClassName()),consoleplayer,playerlist[sel0]);
|
|
}
|
|
}
|
|
return true;
|
|
case MKEY_CLEAR:
|
|
if ( (curtab == TAB_INVENTORY) && (invlist.Size() > 0) )
|
|
{
|
|
lastuse = invlist[sel0].GetClass();
|
|
lastuseamt = invlist[sel0].Amount;
|
|
checkdrop = gametic+(multiplayer?5:1);
|
|
EventHandler.SendNetworkEvent(String.Format("swwmdropitem.%s",invlist[sel0].GetClassName()),consoleplayer);
|
|
}
|
|
else if ( (curtab == TAB_LIBRARY) && sub )
|
|
{
|
|
MenuSound("menu/democlose");
|
|
sub = false;
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub )
|
|
{
|
|
// open trading history
|
|
MenuSound("menu/demosel");
|
|
sub = true;
|
|
ofs0 = sel0 = -1;
|
|
ofs1 = sel1 = 0;
|
|
}
|
|
else if ( sub )
|
|
{
|
|
// go back
|
|
MenuSound("menu/democlose");
|
|
sub = false;
|
|
ofs0 = sel0 = 0;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return Super.MenuEvent(mkey,fromcontroller);
|
|
}
|
|
|
|
private int rnd( double num )
|
|
{
|
|
return int(num+((num<0)?-.5:.5));
|
|
}
|
|
|
|
override bool MouseEvent( int type, int mx, int my )
|
|
{
|
|
bool res = Super.MouseEvent(type,mx,my);
|
|
Font fnt = LangFont(TewiFont);
|
|
String str;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
|
|
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
Vector2 origin = (ss.x-640,ss.y-400)/2.;
|
|
Vector2 mpos = (mx/hs,my/hs)-origin;
|
|
int xx, yy, len;
|
|
if ( type == MOUSE_Click )
|
|
{
|
|
if ( (mpos.x < 0) || (mpos.x >= 641) || (mpos.y < 0) || (mpos.y >= 386) ) return res; // outside clickable area, ignore
|
|
else if ( mpos.y < 14 )
|
|
{
|
|
if ( isrclick ) return res;
|
|
// check which tab we're clicking
|
|
static const string tabnames[] =
|
|
{
|
|
"$SWWM_MISSTAB", "$SWWM_STATTAB", "$SWWM_INVTAB", "$SWWM_KEYTAB",
|
|
"$SWWM_KBASETAB", "$SWWM_STORETAB", "$SWWM_TRADETAB", "$SWWM_CHATTAB"
|
|
};
|
|
xx = 0;
|
|
int maxtab = multiplayer?TAB_CHAT:TAB_STORE;
|
|
for ( int i=TAB_MISSION; i<=maxtab; i++ )
|
|
{
|
|
len = fnt.StringWidth(tabnames[i])+6;
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+len) )
|
|
{
|
|
if ( curtab == i ) break;
|
|
MenuSound("menu/demotab");
|
|
curtab = i;
|
|
CVar.GetCVar('swwm_lasttab',players[consoleplayer]).SetInt(curtab);
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
invlist.Clear();
|
|
lorelist.Clear();
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
playerlist.Clear();
|
|
break;
|
|
}
|
|
xx += len;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_MISSION) && !isrclick )
|
|
{
|
|
// are we clicking where the scrollbar should be?
|
|
if ( mpos.x < 632 ) return res;
|
|
String str = StringTable.Localize("$SWWM_MISSION_NONE");
|
|
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
|
|
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
|
|
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
drag = 1;
|
|
}
|
|
else if ( curtab == TAB_INVENTORY )
|
|
{
|
|
// check what item we clicked
|
|
if ( mpos.y < 377 )
|
|
{
|
|
if ( invlist.Size() <= 0 ) return res; // clicked nothing
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
xx = 9;
|
|
yy = 23;
|
|
int cols = 1;
|
|
for ( int i=ofs; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
// check boundary
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+longest) && (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel0 != i ) MenuSound("menu/demoscroll");
|
|
sel0 = i;
|
|
ofs0 = (sel0/22)*22;
|
|
// drop on right click in inventory tab
|
|
if ( (curtab == TAB_INVENTORY) && isrclick ) MenuEvent(MKEY_CLEAR,false);
|
|
else if ( !isrclick ) MenuEvent(MKEY_ENTER,false);
|
|
return res;
|
|
}
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
}
|
|
else if ( !isrclick )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_TRADING) && sub && (sel0 != -1) )
|
|
{
|
|
// check what item we clicked
|
|
if ( mpos.y < 377 )
|
|
{
|
|
if ( invlist.Size() <= 0 ) return res; // clicked nothing
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs1/22)-(maxcol-1))*22);
|
|
xx = 9;
|
|
yy = 23;
|
|
int cols = 1;
|
|
for ( int i=ofs; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
// check boundary
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+longest) && (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel1 != i ) MenuSound("menu/demoscroll");
|
|
sel1 = i;
|
|
ofs1 = (sel1/22)*22;
|
|
// drop on right click in inventory tab
|
|
if ( (curtab == TAB_INVENTORY) && isrclick ) MenuEvent(MKEY_CLEAR,false);
|
|
else if ( !isrclick ) MenuEvent(MKEY_ENTER,false);
|
|
return res;
|
|
}
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
}
|
|
else if ( !isrclick )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_KEYS) && !isrclick )
|
|
{
|
|
// check what item we clicked
|
|
if ( mpos.y < 377 )
|
|
{
|
|
if ( invlist.Size() <= 0 ) return res; // clicked nothing
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
xx = 9;
|
|
yy = 23;
|
|
int cols = 1;
|
|
for ( int i=ofs; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
// check boundary
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+longest) && (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel0 != i ) MenuSound("menu/demoscroll");
|
|
sel0 = i;
|
|
ofs0 = (sel0/22)*22;
|
|
// do nothing, we just selected it
|
|
return res;
|
|
}
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
}
|
|
else if ( !isrclick )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_STORE) && !isrclick )
|
|
{
|
|
// check what item we clicked
|
|
if ( mpos.y < 377 )
|
|
{
|
|
if ( storelist.Size() <= 0 ) return res; // clicked nothing
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
if ( storeunits[i] > 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag());
|
|
else str = def.GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+96);
|
|
totalcol = (storelist.Size()/22)+1;
|
|
// gotta check both the tag and the price for clicking
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
int cols = 1;
|
|
for ( int i=ofs; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
// check boundary
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+longest+80) && (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel0 != i ) MenuSound("menu/demoscroll");
|
|
sel0 = i;
|
|
ofs0 = (sel0/22)*22;
|
|
MenuEvent(MKEY_ENTER,false);
|
|
return res;
|
|
}
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+96;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
}
|
|
else if ( !isrclick )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( storelist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
if ( storeunits[i] > 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag());
|
|
else str = def.GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+96);
|
|
totalcol = (storelist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_LIBRARY) && !isrclick )
|
|
{
|
|
double midp = (lang.GetString()~=="jp")?206:126;
|
|
if ( mpos.x < midp )
|
|
{
|
|
if ( mpos.y < 28 )
|
|
{
|
|
// switch category
|
|
if ( mpos.x < midp/2. ) MenuEvent(MKEY_LEFT,false);
|
|
else MenuEvent(MKEY_RIGHT,false);
|
|
}
|
|
else
|
|
{
|
|
// check what item we clicked
|
|
int xx = 3;
|
|
int yy = 32;
|
|
int ofs = max(0,ofs0-26);
|
|
for ( int i=ofs; i<lorelist.Size(); i++ )
|
|
{
|
|
if ( yy > 370 ) break;
|
|
// check boundary
|
|
if ( (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel0 != i ) MenuSound("menu/demoscroll");
|
|
if ( (sel0 != i) || !sub )
|
|
{
|
|
sel0 = i;
|
|
sub = false;
|
|
MenuEvent(MKEY_Enter,false);
|
|
}
|
|
return res;
|
|
}
|
|
yy += 13;
|
|
}
|
|
}
|
|
}
|
|
else if ( mpos.x < midp+8 )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( lorelist.Size() <= 27 ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = lorelist.Size()-27;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step ) step += 26;
|
|
if ( step != ofs0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = step;
|
|
drag = 1;
|
|
}
|
|
else if ( sub && (mpos.x >= 632) )
|
|
{
|
|
// check that scrollbar is present
|
|
str = StringTable.Localize(lorelist[sel0].text);
|
|
int ofs = (lang.GetString()~=="jp")?212:132;
|
|
if ( lorelist.Size() > 26 ) ofs += 8;
|
|
BrokenLines l = fnt.BreakLines(str,635-ofs);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,626-ofs);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel2 ) MenuSound("menu/demoscroll");
|
|
ofs2 = sel2 = step;
|
|
drag = 3;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_TRADING) && isrclick )
|
|
{
|
|
MenuEvent(MKEY_Back,false);
|
|
}
|
|
else if ( (curtab == TAB_TRADING) && !isrclick )
|
|
{
|
|
if ( !sub )
|
|
{
|
|
// check what item we clicked
|
|
if ( mpos.y < 377 )
|
|
{
|
|
if ( playerlist.Size() <= 0 ) return res; // clicked nothing
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<playerlist.Size(); i++ )
|
|
{
|
|
str = players[playerlist[i]].GetUserName();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (playerlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
xx = 9;
|
|
yy = 23;
|
|
int cols = 1;
|
|
for ( int i=ofs; i<playerlist.Size(); i++ )
|
|
{
|
|
str = players[playerlist[i]].GetUserName();
|
|
len = fnt.StringWidth(str);
|
|
// check text boundary
|
|
if ( (mpos.x >= xx) && (mpos.x < xx+len+1) && (mpos.y >= yy) && (mpos.y < yy+14) )
|
|
{
|
|
if ( sel0 != i ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = i;
|
|
MenuEvent(MKEY_Enter,false);
|
|
return res;
|
|
}
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
}
|
|
else if ( !isrclick )
|
|
{
|
|
// check that scrollbar is present (will it ever be???)
|
|
if ( playerlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<playerlist.Size(); i++ )
|
|
{
|
|
str = players[playerlist[i]].GetUserName();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (playerlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( sel0 == -1 )
|
|
{
|
|
// are we clicking where the scrollbar should be?
|
|
if ( mpos.x < 632 ) return res;
|
|
if ( tradelib.ent.Size() <= 28 ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = tradelib.ent.Size()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (curtab == TAB_CHAT) && !isrclick )
|
|
{
|
|
// are we clicking where the scrollbar should be?
|
|
if ( mpos.x < 632 ) return res;
|
|
let bar = SWWMStatusBar(StatusBar);
|
|
if ( !bar || (bar.FullHistory.Size() <= 1) ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = bar.FullHistory.Size()-1;
|
|
int step = szr-clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
drag = 1;
|
|
}
|
|
else if ( (curtab == TAB_HELP) && !isrclick )
|
|
{
|
|
// are we clicking where the scrollbar should be?
|
|
if ( mpos.x < 632 ) return res;
|
|
int k1, k2;
|
|
[k1, k2] = bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu");
|
|
String kstr = bindings.NameKeys(k1,k2);
|
|
str = String.Format(StringTable.Localize("$SWWM_HELPTXT"),kstr);
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
drag = 1;
|
|
}
|
|
}
|
|
else if ( (type == MOUSE_Move) && drag ) // scroll dragging
|
|
{
|
|
if ( curtab == TAB_MISSION )
|
|
{
|
|
String str = StringTable.Localize("$SWWM_MISSION_NONE");
|
|
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
|
|
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
|
|
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
}
|
|
else if ( (curtab == TAB_INVENTORY) || ((curtab == TAB_TRADING) && sub && (sel0 != -1)) )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( (invlist[i] is 'Ammo') || (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
}
|
|
else if ( curtab == TAB_KEYS )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( invlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
}
|
|
else if ( curtab == TAB_STORE )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( storelist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
if ( storeunits[i] > 1 ) str = String.Format("%dx %s",storeunits[i],def.GetTag());
|
|
else str = def.GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+96);
|
|
totalcol = (storelist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
if ( drag == 1 )
|
|
{
|
|
// check that scrollbar is present
|
|
if ( lorelist.Size() <= 27 ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = lorelist.Size()-27;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step ) step += 26;
|
|
if ( step != ofs0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = step;
|
|
}
|
|
else if ( drag == 3 )
|
|
{
|
|
// check that scrollbar is present
|
|
str = StringTable.Localize(lorelist[sel0].text);
|
|
int ofs = (lang.GetString()~=="jp")?212:132;
|
|
if ( lorelist.Size() > 26 ) ofs += 8;
|
|
BrokenLines l = fnt.BreakLines(str,635-ofs);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,626-ofs);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel2 ) MenuSound("menu/demoscroll");
|
|
ofs2 = sel2 = step;
|
|
}
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub )
|
|
{
|
|
// check that scrollbar is present (will it ever be???)
|
|
if ( playerlist.Size() <= 0 ) return res; // definitely no scrollbar
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<playerlist.Size(); i++ )
|
|
{
|
|
str = players[playerlist[i]].GetUserName();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
if ( maxcol >= totalcol ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = totalcol-maxcol;
|
|
int step = clamp(rnd((mpos.x-5.)/(630./szr)),0,szr);
|
|
if ( step > 0 ) step += (maxcol-1);
|
|
if ( step != (ofs0/22) ) MenuSound("menu/demoscroll");
|
|
ofs0 = step*22;
|
|
}
|
|
else if ( sel0 == -1 )
|
|
{
|
|
if ( tradelib.ent.Size() <= 28 ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = tradelib.ent.Size()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
}
|
|
}
|
|
else if ( curtab == TAB_CHAT )
|
|
{
|
|
let bar = SWWMStatusBar(StatusBar);
|
|
if ( !bar || (bar.FullHistory.Size() <= 1) ) return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = bar.FullHistory.Size()-1;
|
|
int step = szr-clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
}
|
|
else if ( curtab == TAB_HELP )
|
|
{
|
|
int k1, k2;
|
|
[k1, k2] = bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu");
|
|
String kstr = bindings.NameKeys(k1,k2);
|
|
str = String.Format(StringTable.Localize("$SWWM_HELPTXT"),kstr);
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
else return res; // no scrollbar
|
|
// calculate offset
|
|
int szr = l.Count()-28;
|
|
int step = clamp(rnd((mpos.y-24.)/(353./szr)),0,szr);
|
|
if ( step != sel0 ) MenuSound("menu/demoscroll");
|
|
ofs0 = sel0 = step;
|
|
}
|
|
}
|
|
else if ( type == MOUSE_Release ) drag = 0; // stop dragging any active scrolls
|
|
return res;
|
|
}
|
|
|
|
private bool CmpInventory( Inventory a, Inventory b )
|
|
{
|
|
int ta = 0, tb = 0;
|
|
if ( a is 'Weapon' ) ta = 2;
|
|
else if ( (a is 'Ammo') || (a is 'BackpackItem') || (a is 'HammerspaceEmbiggener') ) ta = 3;
|
|
else if ( (a is 'PowerupGiver') || (a is 'AmmoFabricator') || a.bBIGPOWERUP ) ta = -3;
|
|
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;
|
|
if ( b is 'Weapon' ) tb = 2;
|
|
else if ( (b is 'Ammo') || (b is 'BackpackItem') || (b is 'HammerspaceEmbiggener') ) tb = 3;
|
|
else if ( (b is 'PowerupGiver') || (b is 'AmmoFabricator') || b.bBIGPOWERUP ) tb = -3;
|
|
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;
|
|
return ta > tb;
|
|
}
|
|
|
|
private bool CmpInventoryClass( Class<Inventory> a, Class<Inventory> b )
|
|
{
|
|
int ta = 0, tb = 0;
|
|
let da = GetDefaultByType(a);
|
|
let db = GetDefaultByType(b);
|
|
if ( a is 'Weapon' ) ta = 2;
|
|
else if ( a is 'Ammo' ) ta = 1;
|
|
else if ( (a is 'PowerupGiver') || (a is 'AmmoFabricator') || da.bBIGPOWERUP ) ta = 3;
|
|
else if ( (a is 'Health') || (a is 'HealthPickup') || (a is 'SWWMHealth') ) ta = 5;
|
|
else if ( (a is 'Armor') || (a is 'SWWMSpareArmor') ) ta = 4;
|
|
if ( b is 'Weapon' ) tb = 2;
|
|
else if ( b is 'Ammo' ) tb = 1;
|
|
else if ( (b is 'PowerupGiver') || (b is 'AmmoFabricator') || db.bBIGPOWERUP ) tb = 3;
|
|
else if ( (b is 'Health') || (b is 'HealthPickup') || (b is 'SWWMHealth') ) tb = 5;
|
|
else if ( (b is 'Armor') || (b is 'SWWMSpareArmor') ) tb = 4;
|
|
return ta <= tb;
|
|
}
|
|
|
|
private int partition_inventory( Array<Inventory> a, int l, int h )
|
|
{
|
|
Inventory pv = a[h];
|
|
int i = (l-1);
|
|
for ( int j=l; j<=(h-1); j++ )
|
|
{
|
|
if ( CmpInventory(pv,a[j]) )
|
|
{
|
|
i++;
|
|
Inventory tmp = a[j];
|
|
a[j] = a[i];
|
|
a[i] = tmp;
|
|
}
|
|
}
|
|
Inventory tmp = a[h];
|
|
a[h] = a[i+1];
|
|
a[i+1] = tmp;
|
|
return i+1;
|
|
}
|
|
private void qsort_inventory( Array<Inventory> 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);
|
|
}
|
|
|
|
private int partition_store( Array<Class<Inventory> > a, Array<int> b, int l, int h )
|
|
{
|
|
Class<Inventory> pv = a[h];
|
|
int i = (l-1);
|
|
for ( int j=l; j<=(h-1); j++ )
|
|
{
|
|
if ( CmpInventoryClass(pv,a[j]) )
|
|
{
|
|
i++;
|
|
Class<Inventory> tmp = a[j];
|
|
a[j] = a[i];
|
|
a[i] = tmp;
|
|
int tmpi = b[j];
|
|
b[j] = b[i];
|
|
b[i] = tmpi;
|
|
}
|
|
}
|
|
Class<Inventory> tmp = a[h];
|
|
a[h] = a[i+1];
|
|
a[i+1] = tmp;
|
|
int tmpi = b[h];
|
|
b[h] = b[i+1];
|
|
b[i+1] = tmpi;
|
|
return i+1;
|
|
}
|
|
private void qsort_store( Array<Class<Inventory> > a, Array<int> b, int l, int h )
|
|
{
|
|
if ( l >= h ) return;
|
|
int p = partition_store(a,b,l,h);
|
|
qsort_store(a,b,l,p-1);
|
|
qsort_store(a,b,p+1,h);
|
|
}
|
|
|
|
override void Ticker()
|
|
{
|
|
Super.Ticker();
|
|
if ( players[consoleplayer].Health <= 0 )
|
|
{
|
|
// ded
|
|
Close();
|
|
return;
|
|
}
|
|
if ( !multiplayer && ((curtab == TAB_TRADING) || (curtab == TAB_CHAT)) )
|
|
{
|
|
MenuSound("menu/demotab");
|
|
curtab = TAB_MISSION;
|
|
CVar.GetCVar('swwm_lasttab',players[consoleplayer]).SetInt(curtab);
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
invlist.Clear();
|
|
lorelist.Clear();
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
playerlist.Clear();
|
|
}
|
|
if ( curtab == TAB_INVENTORY )
|
|
{
|
|
invlist.Clear();
|
|
// alphabetically sorted inventory
|
|
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.Inv )
|
|
{
|
|
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') || (inv is 'SWWMGesture') || (!(inv is 'Ammo') && !(inv is 'Weapon') && !inv.bINVBAR) && !(inv is 'HammerspaceEmbiggener') && !(inv is 'SWWMCollectable') ) continue;
|
|
String tag = inv.GetTag();
|
|
bool greater = false;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
String tag2 = invlist[i].GetTag();
|
|
if ( tag > tag2 ) continue;
|
|
greater = true;
|
|
invlist.Insert(i,inv);
|
|
break;
|
|
}
|
|
if ( greater ) continue;
|
|
invlist.Push(inv);
|
|
}
|
|
// re-sort by category
|
|
qsort_inventory(invlist,0,invlist.Size()-1);
|
|
}
|
|
else if ( curtab == TAB_KEYS )
|
|
{
|
|
invlist.Clear();
|
|
// keys sorted by their index
|
|
int n = Key.GetKeyTypeCount();
|
|
for ( int i=0; i<n; i++ )
|
|
{
|
|
let k = Key(players[consoleplayer].mo.FindInventory(Key.GetKeyType(i)));
|
|
if ( k ) invlist.Push(k);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_STORE )
|
|
{
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
// price-sorted buyables
|
|
for ( int i=0; i<AllActorClasses.Size(); i++ )
|
|
{
|
|
let type = (Class<Inventory>)(AllActorClasses[i]);
|
|
if ( !type ) continue;
|
|
// skip chanceboxes, since they're not yet implemented
|
|
if ( type is 'Chancebox' ) continue;
|
|
// no fabricators outside of hexen
|
|
if ( !(gameinfo.gametype&GAME_Hexen) && (type is 'AmmoFabricator') ) continue;
|
|
// skip maxed items
|
|
let cur = players[consoleplayer].mo.FindInventory(type);
|
|
if ( cur && (cur.Amount >= cur.MaxAmount) ) continue;
|
|
// ignore ammo for weapons not owned
|
|
bool notownedammo = false;
|
|
if ( type is 'Ammo' )
|
|
{
|
|
notownedammo = true;
|
|
let amo = (Class<Ammo>)(type);
|
|
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.inv )
|
|
{
|
|
if ( !(inv is 'Weapon') ) continue;
|
|
if ( (Weapon(inv).AmmoType1 == amo) || (Weapon(inv).AmmoType2 == amo) )
|
|
{
|
|
notownedammo = false;
|
|
break;
|
|
}
|
|
if ( (inv is 'SWWMWeapon') && SWWMWeapon(inv).UsesAmmo(amo) )
|
|
{
|
|
notownedammo = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( notownedammo ) continue;
|
|
let inv = GetDefaultByType(type);
|
|
// skip unimplemented weapons
|
|
if ( type is 'Weapon' )
|
|
{
|
|
let ready = inv.FindState("Ready");
|
|
if ( !ready || !ready.ValidateSpriteFrame() ) continue;
|
|
}
|
|
// ignore child ammos
|
|
if ( (type is 'Ammo') && (type.GetParentClass() != 'Ammo') ) continue;
|
|
if ( inv.Stamina <= 0 ) continue;
|
|
int amt = inv.Amount;
|
|
int price = int(inv.Stamina*(1.+.5*(amt-1)));
|
|
if ( type is 'Ammo' )
|
|
{
|
|
// get the largest affordable child pickup amount
|
|
for ( int j=0; j<AllActorClasses.Size(); j++ )
|
|
{
|
|
let type2 = (Class<Ammo>)(AllActorClasses[j]);
|
|
if ( !type2 || (type2.GetParentClass() != type) ) continue;
|
|
let inv2 = GetDefaultByType(type2);
|
|
int cprice = int(inv.Stamina*(1.+.5*(inv2.Amount-1)));
|
|
if ( (inv2.Amount > amt) && (cprice <= SWWMCredits.Get(players[consoleplayer])) )
|
|
{
|
|
price = cprice;
|
|
amt = inv2.Amount;
|
|
}
|
|
}
|
|
}
|
|
// sort by unit price
|
|
bool greater = false;
|
|
for ( int j=0; j<storelist.Size(); j++ )
|
|
{
|
|
let inv2 = GetDefaultByType(storelist[j]);
|
|
if ( inv.Stamina > inv2.Stamina ) continue;
|
|
greater = true;
|
|
storelist.Insert(j,type);
|
|
storeunits.Insert(j,amt);
|
|
break;
|
|
}
|
|
if ( greater ) continue;
|
|
storelist.Push(type);
|
|
storeunits.Push(amt);
|
|
}
|
|
// re-sort by category
|
|
qsort_store(storelist,storeunits,0,storelist.Size()-1);
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
// remember last position/size
|
|
SWWMLore oldone = null;
|
|
int oldsiz = lorelist.Size();
|
|
if ( lorelist.Size() > 0 ) oldone = lorelist[sel0];
|
|
// lore lore lore
|
|
lorelist.Clear();
|
|
for ( int i=0; i<lorelib.ent.Size(); i++ )
|
|
{
|
|
if ( lorelib.ent[i].tab != sel1 ) continue;
|
|
lorelist.Push(lorelib.ent[i]);
|
|
}
|
|
// readjust
|
|
if ( oldone && (lorelist.Size() != oldsiz) )
|
|
{
|
|
int idx = lorelist.Find(oldone);
|
|
if ( (idx > 0) && (idx < lorelist.Size()) )
|
|
sel0 = idx;
|
|
// update ofs so selection stays on-screen
|
|
int ofs = max(ofs0-26,0);
|
|
if ( sel0 < ofs ) ofs0 = sel0+26;
|
|
else if ( sel0 > ofs+26 ) ofs0 = sel0;
|
|
}
|
|
// add "new entries" message
|
|
if ( lorelib.ent.Size() != oldloresiz )
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_NEWLORE");
|
|
tmsgtic = gametic+70;
|
|
}
|
|
oldloresiz = lorelib.ent.Size();
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
// build player list
|
|
playerlist.Clear();
|
|
for ( int i=0; i<MAXPLAYERS; i++ )
|
|
{
|
|
if ( !playeringame[i] || (i==consoleplayer) ) continue;
|
|
playerlist.Push(i);
|
|
}
|
|
// build inventory list if open
|
|
if ( sub && (sel0 != -1) )
|
|
{
|
|
invlist.Clear();
|
|
// alphabetically sorted inventory
|
|
for ( Inventory inv=players[consoleplayer].mo.Inv; inv; inv=inv.Inv )
|
|
{
|
|
if ( (inv.Amount <= 0) || !inv.SpawnState.ValidateSpriteFrame() || (inv is 'Key') || (inv is 'BasicArmor') || (inv is 'HexenArmor') || (inv is 'Powerup') || (inv is 'SWWMArmor') || (inv is 'SWWMGesture') || (!(inv is 'Ammo') && !(inv is 'Weapon') && !inv.bINVBAR) && !(inv is 'HammerspaceEmbiggener') && !(inv is 'SWWMCollectable') ) continue;
|
|
String tag = inv.GetTag();
|
|
bool greater = false;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
String tag2 = invlist[i].GetTag();
|
|
if ( tag > tag2 ) continue;
|
|
greater = true;
|
|
invlist.Insert(i,inv);
|
|
break;
|
|
}
|
|
if ( greater ) continue;
|
|
invlist.Push(inv);
|
|
}
|
|
// re-sort by category
|
|
qsort_inventory(invlist,0,invlist.Size()-1);
|
|
}
|
|
}
|
|
// check if use succeeded
|
|
if ( checkuse && (gametic > checkuse) )
|
|
{
|
|
checkuse = 0;
|
|
int amt = players[consoleplayer].mo.CountInv(lastuse);
|
|
if ( amt == lastuseamt )
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_INVFAIL");
|
|
tmsgtic = gametic+70;
|
|
MenuSound("menu/noinvuse");
|
|
}
|
|
else
|
|
{
|
|
MenuSound(GetDefaultByType(lastuse).UseSound);
|
|
if ( (amt == 0) && (sel0 >= invlist.Size()) )
|
|
sel0 = max(0,sel0-1);
|
|
}
|
|
}
|
|
// check if drop succeeded
|
|
if ( checkdrop && (gametic > checkdrop) )
|
|
{
|
|
checkdrop = 0;
|
|
int amt = players[consoleplayer].mo.CountInv(lastuse);
|
|
if ( amt == lastuseamt )
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_INVNDROP");
|
|
tmsgtic = gametic+70;
|
|
MenuSound("menu/noinvuse");
|
|
}
|
|
else if ( (amt == 0) && (sel0 >= invlist.Size()) )
|
|
sel0 = max(0,sel0-1);
|
|
}
|
|
// check if trade succeeded
|
|
if ( checksend && (gametic > checksend) )
|
|
{
|
|
checksend = 0;
|
|
int amt = players[consoleplayer].mo.CountInv(lastuse);
|
|
if ( amt == lastuseamt )
|
|
{
|
|
tmsg = StringTable.Localize("$SWWM_TRADEFULL");
|
|
tmsgtic = gametic+70;
|
|
MenuSound("menu/noinvuse");
|
|
}
|
|
else
|
|
{
|
|
MenuSound("menu/demosel");
|
|
if ( (amt == 0) && (sel1 >= invlist.Size()) )
|
|
sel1 = max(0,sel1-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
override bool OnUiEvent( UIEvent ev )
|
|
{
|
|
switch ( ev.type )
|
|
{
|
|
case UIEvent.Type_KeyDown:
|
|
if ( ev.keychar == UiEvent.Key_F1 )
|
|
{
|
|
if ( curtab == TAB_HELP )
|
|
curtab = oldtab;
|
|
else
|
|
{
|
|
oldtab = curtab;
|
|
curtab = TAB_HELP;
|
|
}
|
|
sel0 = sel1 = sel2 = 0;
|
|
ofs0 = ofs1 = ofs2 = 0;
|
|
sub = false;
|
|
invlist.Clear();
|
|
lorelist.Clear();
|
|
storelist.Clear();
|
|
storeunits.Clear();
|
|
MenuSound("menu/demotab");
|
|
return true;
|
|
}
|
|
switch ( kcode )
|
|
{
|
|
case 8:
|
|
if ( ev.keystring ~== "B" )
|
|
kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
case 9:
|
|
if ( ev.keystring ~== "A" ) kcode++;
|
|
else kcode = 0;
|
|
break;
|
|
default:
|
|
kcode = 0;
|
|
break;
|
|
}
|
|
if( (ikey[0] && (ev.keystring == mkey[0])) || (ikey[1] && (ev.keystring == mkey[1])) )
|
|
{
|
|
MenuSound("menu/democlose");
|
|
Close();
|
|
return true;
|
|
}
|
|
break;
|
|
case UIEvent.Type_WheelDown:
|
|
if ( (curtab == TAB_LIBRARY) && sub && (lorelist.Size() > 1) )
|
|
{
|
|
// special handling, need to check which side is being scrolled
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
|
|
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
Vector2 origin = (ss.x-640,ss.y-400)/2.;
|
|
Vector2 mpos = (curmouse/hs)-origin;
|
|
double midp = (lang.GetString()~=="jp")?206:126;
|
|
if ( ((lorelist.Size() > 27) && (mpos.x < midp+8)) || (mpos.x < midp) )
|
|
{
|
|
MenuSound("menu/democlose");
|
|
sub = false;
|
|
}
|
|
}
|
|
return MenuEvent(MKEY_DOWN,false);
|
|
break;
|
|
case UIEvent.Type_WheelUp:
|
|
if ( (curtab == TAB_LIBRARY) && sub && (lorelist.Size() > 1) )
|
|
{
|
|
// special handling, need to check which side is being scrolled
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
|
|
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
Vector2 origin = (ss.x-640,ss.y-400)/2.;
|
|
Vector2 mpos = (curmouse/hs)-origin;
|
|
double midp = (lang.GetString()~=="jp")?206:126;
|
|
if ( ((lorelist.Size() > 27) && (mpos.x < midp+8)) || (mpos.x < midp) )
|
|
{
|
|
MenuSound("menu/democlose");
|
|
sub = false;
|
|
}
|
|
}
|
|
return MenuEvent(MKEY_UP,false);
|
|
break;
|
|
case UIEvent.Type_LButtonDown:
|
|
isrclick = false;
|
|
return Super.OnUIEvent(ev);
|
|
break;
|
|
case UIEvent.Type_RButtonDown:
|
|
isrclick = true;
|
|
// copy over what base menus do for L click
|
|
int y = ev.MouseY;
|
|
bool res = MouseEventBack(MOUSE_Click,ev.MouseX,y);
|
|
if ( res ) y = -1;
|
|
res |= MouseEvent(MOUSE_Click,ev.MouseX,y);
|
|
if ( res ) SetCapture(true);
|
|
return false;
|
|
break;
|
|
case UIEvent.Type_RButtonUp:
|
|
// copy over what base menus do for L release
|
|
if ( mMouseCapture )
|
|
{
|
|
SetCapture(false);
|
|
int y = ev.MouseY;
|
|
bool res = MouseEventBack(MOUSE_Release,ev.MouseX,y);
|
|
if ( res ) y = -1;
|
|
res |= MouseEvent(MOUSE_Release,ev.MouseX,y);
|
|
}
|
|
return false;
|
|
break;
|
|
case UIEvent.Type_MouseMove:
|
|
// store coords
|
|
curmouse = (ev.MouseX,ev.MouseY);
|
|
break;
|
|
}
|
|
return Super.OnUIEvent(ev);
|
|
}
|
|
|
|
override void Drawer()
|
|
{
|
|
Super.Drawer();
|
|
Font fnt = LangFont(TewiFont);
|
|
String str;
|
|
double hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
|
|
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
|
|
Vector2 origin = (ss.x-640,ss.y-400)/2.;
|
|
if ( !fuzz ) fuzz = CVar.GetCvar('swwm_fuzz',players[consoleplayer]);
|
|
if ( fuzz.GetBool() )
|
|
Screen.DrawTexture(FancyBg,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Add,DTA_Alpha,.5);
|
|
Screen.DrawTexture(MainWindow,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
// draw tabs
|
|
double xx = 3, yy = 0;
|
|
static const string tabnames[] =
|
|
{
|
|
"$SWWM_MISSTAB", "$SWWM_STATTAB", "$SWWM_INVTAB", "$SWWM_KEYTAB",
|
|
"$SWWM_KBASETAB", "$SWWM_STORETAB", "$SWWM_TRADETAB", "$SWWM_CHATTAB",
|
|
"$SWWM_SECRETTAB", "$SWWM_HELPTAB"
|
|
};
|
|
static const string ltabnames[] =
|
|
{
|
|
"$SWWM_LORETAB0", "$SWWM_LORETAB1", "$SWWM_LORETAB2"
|
|
};
|
|
int maxtab = multiplayer?TAB_CHAT:TAB_STORE;
|
|
int mx = maxtab;
|
|
if ( (curtab > TAB_CHAT) ) mx++;
|
|
for ( int i=0; i<=mx; i++ )
|
|
{
|
|
str = StringTable.Localize(tabnames[(i>maxtab)?curtab:i]);
|
|
Screen.DrawText(fnt,((i>maxtab)||(curtab==i))?Font.CR_FIRE:Font.CR_DARKGRAY,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx += fnt.StringWidth(str)+2;
|
|
Screen.DrawTexture(TabSeparator,false,origin.x+xx,origin.y+yy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx += 4;
|
|
}
|
|
int muns1, muns2;
|
|
[muns1, muns2] = SWWMCredits.Get(players[consoleplayer]);
|
|
str = "\cg¥\c-";
|
|
if ( muns2 > 0 ) str.AppendFormat("%d",muns2);
|
|
str.AppendFormat("%09d",muns1);
|
|
xx = 637-TewiFont.StringWidth(str);
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
// draw bottom messages
|
|
yy = 386;
|
|
if ( gametic < tmsgtic ) str = StringTable.Localize(tmsg);
|
|
else str = CrimeTime();
|
|
xx = 4;
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
str = "DemolitionOS v1.0";
|
|
xx = 637-fnt.StringWidth(str);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
// draw contents
|
|
if ( curtab == TAB_MISSION )
|
|
{
|
|
if ( gameinfo.gametype&GAME_Doom ) str = StringTable.Localize("$SWWM_MISSION_DOOM");
|
|
else if ( gameinfo.gametype&GAME_Heretic ) str = StringTable.Localize("$SWWM_MISSION_HERETIC");
|
|
else if ( gameinfo.gametype&GAME_Hexen ) str = StringTable.Localize("$SWWM_MISSION_HEXEN");
|
|
else str = StringTable.Localize("$SWWM_MISSION_NONE");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
xx = 6;
|
|
yy = 17;
|
|
int ofs = clamp(sel0,0,max(0,l.Count()-28));
|
|
for ( int i=ofs; i<l.Count(); i++ )
|
|
{
|
|
if ( yy >= 370 ) break;
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 13;
|
|
}
|
|
// scrollbar
|
|
if ( l.Count() > 28 )
|
|
{
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx = 634;
|
|
int szr = l.Count()-28;
|
|
yy = floor(ofs*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_STATS )
|
|
{
|
|
xx = 9;
|
|
yy = 23;
|
|
// wish I could use macros for this
|
|
int thour = ((level.totaltime-stats.lastspawn)/(3600*Thinker.TICRATE));
|
|
int tmin = ((level.totaltime-stats.lastspawn)/(60*Thinker.TICRATE))%60;
|
|
int tsec = ((level.totaltime-stats.lastspawn)/Thinker.TICRATE)%60;
|
|
str = String.Format("\cx%s\c-%02d\cu:\c-%02d\cu:\c-%02d",StringTable.Localize("$SWWM_STATUPTIME"),thour,tmin,tsec);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
if ( stats.grounddist > 32000. ) str = String.Format("\cx%s\c-%g\cukm\c-",StringTable.Localize("$SWWM_STATONFOOT"),stats.grounddist/32000.);
|
|
else str = String.Format("\cx%s\c-%g\cum\c-",StringTable.Localize("$SWWM_STATONFOOT"),stats.grounddist/32.);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
if ( stats.airdist > 32000. ) str = String.Format("\cx%s\c-%g\cukm\c-",StringTable.Localize("$SWWM_STATFLIGHT"),stats.airdist/32000.);
|
|
else str = String.Format("\cx%s\c-%g\cum\c-",StringTable.Localize("$SWWM_STATFLIGHT"),stats.airdist/32.);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATBOOST"),stats.boostcount);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDASH"),stats.dashcount);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATSTOMP"),stats.stompcount);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%g\cul\c-",StringTable.Localize("$SWWM_STATFUEL"),stats.fuelusage/60.);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%g\cukm/h\c-",StringTable.Localize("$SWWM_STATSPEED"),stats.topspeed*32000./(3600*Thinker.TICRATE));
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
thour = (stats.airtime/(3600*Thinker.TICRATE));
|
|
tmin = (stats.airtime/(60*Thinker.TICRATE))%60;
|
|
tsec = (stats.airtime/Thinker.TICRATE)%60;
|
|
str = String.Format("\cx%s\c-%02d\cu:\c-%02d\cu:\c-%02d",StringTable.Localize("$SWWM_STATAIRTIME"),thour,tmin,tsec);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATKILLS"),stats.kills);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDEATHS"),stats.deaths);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDDEALT"),stats.damagedealt);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATDTAKEN"),stats.damagetaken);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATTDEALT"),stats.topdealt);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATTTAKEN"),stats.toptaken);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATMKILL"),stats.mkill);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-%d",StringTable.Localize("$SWWM_STATSKILL"),stats.skill);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
str = String.Format("\cx%s\c-",StringTable.Localize("$SWWM_STATFAVWEAP"));
|
|
if ( stats.favweapon == -1 ) str = str.."N/A";
|
|
else
|
|
{
|
|
let def = GetDefaultByType(stats.wstats[stats.favweapon].w);
|
|
str = str..def.GetTag();
|
|
}
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
if ( stats.hhiscore > 0 ) str = String.Format("\cx%s\cu¥\c-%d%09d",StringTable.Localize("$SWWM_STATHISCORE"),stats.hhiscore,stats.hiscore);
|
|
else str = String.Format("\cx%s\cu¥\c-%09d",StringTable.Localize("$SWWM_STATHISCORE"),stats.hiscore);
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 16;
|
|
}
|
|
else if ( (curtab == TAB_INVENTORY) || ((curtab == TAB_TRADING) && sub && (sel0 != -1)) )
|
|
{
|
|
if ( invlist.Size() <= 0 )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOINV");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest, len;
|
|
int maxcol, totalcol, cols = 1;
|
|
// first pass, calculate longest item name
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( invlist[i] is 'Ammo' ) str = String.Format("(%d/%d) %s",invlist[i].Amount,invlist[i].MaxAmount,invlist[i].GetTag());
|
|
else if ( (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
for ( int i=ofs; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
if ( invlist[i] is 'Ammo' ) str = String.Format("(%d/%d) %s",invlist[i].Amount,invlist[i].MaxAmount,invlist[i].GetTag());
|
|
else if ( (invlist[i].Amount > 1) || (!(invlist[i] is 'PuzzleItem') && (invlist[i].MaxAmount > 1)) ) str = String.Format("%dx %s",invlist[i].Amount,invlist[i].GetTag());
|
|
else str = invlist[i].GetTag();
|
|
int clscol = Font.CR_WHITE;
|
|
if ( invlist[i] is 'Weapon' ) clscol = Font.CR_GOLD;
|
|
else if ( (invlist[i] is 'Ammo') || (invlist[i] is 'BackpackItem') || (invlist[i] is 'HammerspaceEmbiggener') ) clscol = Font.CR_BROWN;
|
|
else if ( (invlist[i] is 'PowerupGiver') || (invlist[i] is 'AmmoFabricator') || invlist[i].bBIGPOWERUP ) clscol = Font.CR_PURPLE;
|
|
else if ( (invlist[i] is 'Health') || (invlist[i] is 'HealthPickup') || (invlist[i] is 'SWWMHealth') ) clscol = Font.CR_RED;
|
|
else if ( (invlist[i] is 'Armor') || (invlist[i] is 'SWWMSpareArmor') ) clscol = Font.CR_GREEN;
|
|
else if ( invlist[i] is 'PuzzleItem' ) clscol = Font.CR_LIGHTBLUE;
|
|
Screen.DrawText(fnt,clscol,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0));
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
if ( maxcol < totalcol )
|
|
{
|
|
// draw scrollbar
|
|
int szr = totalcol-maxcol;
|
|
xx = floor((ofs/22.)*(630./szr))+2.;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_KEYS )
|
|
{
|
|
if ( invlist.Size() <= 0 )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOKEYS");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int maxcol, totalcol, cols = 1;
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
str = invlist[i].GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+24);
|
|
totalcol = (invlist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
for ( int i=0; i<invlist.Size(); i++ )
|
|
{
|
|
if ( !invlist[i] ) continue;
|
|
str = invlist[i].GetTag();
|
|
Screen.DrawText(fnt,Font.CR_UNTRANSLATED,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0));
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
if ( maxcol < totalcol )
|
|
{
|
|
// draw scrollbar
|
|
int szr = totalcol-maxcol;
|
|
xx = floor((ofs/22.)*(630./szr))+2.;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_LIBRARY )
|
|
{
|
|
xx = 3;
|
|
yy = 14;
|
|
// draw the category
|
|
int twidth = (lang.GetString()~=="jp")?200:120;
|
|
str = StringTable.Localize(ltabnames[sel1]);
|
|
Screen.DrawText(TewiFont,Font.CR_WHITE,origin.x+xx,origin.y+yy,"<",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawText(TewiFont,Font.CR_WHITE,origin.x+xx+twidth-6,origin.y+yy,">",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawText(fnt,Font.CR_FIRE,origin.x+xx+(twidth-fnt.StringWidth(str))/2,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
// draw "unread" indicators on sides
|
|
int ltab = sel1-1;
|
|
if ( ltab < 0 ) ltab = 2;
|
|
int rtab = sel1+1;
|
|
if ( rtab > 2 ) rtab = 0;
|
|
bool lunread = false, runread = false;
|
|
for ( int i=0; i<lorelib.ent.Size(); i++ )
|
|
{
|
|
if ( lorelib.ent[i].tab == ltab ) lunread |= !lorelib.ent[i].read;
|
|
if ( lorelib.ent[i].tab == rtab ) runread |= !lorelib.ent[i].read;
|
|
}
|
|
if ( lunread ) Screen.DrawText(TewiFont,Font.CR_GOLD,origin.x+xx+6,origin.y+yy,"‼",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
if ( runread ) Screen.DrawText(TewiFont,Font.CR_GOLD,origin.x+xx+twidth-12,origin.y+yy,"‼",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture((lang.GetString()~=="jp")?LoreSeparatorW:LoreSeparator,false,origin.x,origin.y+27,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 18;
|
|
// draw the current entries
|
|
int ofs = max(0,ofs0-26);
|
|
for ( int i=ofs; i<lorelist.Size(); i++ )
|
|
{
|
|
if ( yy > 370 ) break;
|
|
str = StringTable.Localize(lorelist[i].tag);
|
|
int len = fnt.StringWidth(str);
|
|
Screen.DrawText(fnt,(i==sel0)?Font.CR_FIRE:Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
if ( !lorelist[i].read )
|
|
Screen.DrawText(TewiFont,Font.CR_GOLD,origin.x+xx+len,origin.y+yy," ‼",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 13;
|
|
}
|
|
xx += twidth+2;
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+xx,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx += 3;
|
|
// scrollbar
|
|
if ( lorelist.Size() > 27 )
|
|
{
|
|
int szr = lorelist.Size()-27;
|
|
yy = floor((ofs)*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx += 5;
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+xx,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx += 3;
|
|
}
|
|
xx += 4;
|
|
// draw the entry text (if open)
|
|
if ( !sub )
|
|
{
|
|
str = StringTable.Localize("$SWWM_LOREUNSEL");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,origin.x+xx+((634-xx)-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
str = StringTable.Localize(lorelist[sel0].text);
|
|
BrokenLines l = fnt.BreakLines(str,int(635-xx));
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,int(626-xx));
|
|
yy = 17;
|
|
ofs = clamp(sel2,0,max(0,l.Count()-28));
|
|
for ( int i=ofs; i<l.Count(); i++ )
|
|
{
|
|
if ( yy > 370 ) break;
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 13;
|
|
}
|
|
// scrollbar
|
|
if ( l.Count() > 28 )
|
|
{
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx = 634;
|
|
int szr = l.Count()-28;
|
|
yy = floor(ofs*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_STORE )
|
|
{
|
|
if ( storelist.Size() <= 0 )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOSTORE");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
// draw all the stuff in the store
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int maxcol, totalcol;
|
|
for ( int i=0; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
if ( (storeunits[i] > 1) || (storelist[i] is 'Ammo') ) str = String.Format("%dx %s",storeunits[i],def.GetTag());
|
|
else str = def.GetTag();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
}
|
|
maxcol = 622/(longest+96);
|
|
totalcol = (storelist.Size()/22)+1;
|
|
int ofs = int(max(0,(ofs0/22)-(maxcol-1))*22);
|
|
int cols = 1;
|
|
for ( int i=ofs; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
if ( (storeunits[i] > 1) || (storelist[i] is 'Ammo') ) str = String.Format("%dx %s",storeunits[i],def.GetTag());
|
|
else str = def.GetTag();
|
|
int clscol = Font.CR_WHITE;
|
|
if ( storelist[i] is 'Weapon' ) clscol = Font.CR_GOLD;
|
|
else if ( storelist[i] is 'Ammo' ) clscol = Font.CR_BROWN;
|
|
else if ( (storelist[i] is 'PowerupGiver') || (storelist[i] is 'AmmoFabricator') || def.bBIGPOWERUP ) clscol = Font.CR_PURPLE;
|
|
else if ( (storelist[i] is 'Health') || (storelist[i] is 'HealthPickup') || (storelist[i] is 'SWWMHealth') ) clscol = Font.CR_RED;
|
|
else if ( (storelist[i] is 'Armor') || (storelist[i] is 'SWWMSpareArmor') ) clscol = Font.CR_GREEN;
|
|
Screen.DrawText(fnt,clscol,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0));
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+96;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
xx = 9;
|
|
yy = 23;
|
|
cols = 1;
|
|
for ( int i=ofs; i<storelist.Size(); i++ )
|
|
{
|
|
if ( !storelist[i] ) continue;
|
|
let def = GetDefaultByType(storelist[i]);
|
|
int price = int(def.Stamina*(1.+.5*(storeunits[i]-1)));
|
|
str = String.Format("¥%d",price);
|
|
len = TewiFont.StringWidth(str);
|
|
int clscol = Font.CR_FIRE;
|
|
if ( (price > muns1) && (muns2 <= 0) ) clscol = Font.CR_BLACK;
|
|
Screen.DrawText(TewiFont,clscol,origin.x+xx+longest+80-len,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0));
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+96;
|
|
yy = 23;
|
|
cols++;
|
|
if ( cols > maxcol ) break;
|
|
}
|
|
}
|
|
if ( maxcol < totalcol )
|
|
{
|
|
// draw scrollbar
|
|
int szr = totalcol-maxcol;
|
|
xx = floor((ofs/22.)*(630./szr))+2.;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_TRADING )
|
|
{
|
|
if ( !sub )
|
|
{
|
|
if ( playerlist.Size() <= 0 )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOTRADE");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
xx = 9;
|
|
yy = 23;
|
|
int longest = 0, len;
|
|
int ofs = int(floor(max(0,sel0-44)/22.)*22);
|
|
int cols = 1;
|
|
for ( int i=ofs; i<playerlist.Size(); i++ )
|
|
{
|
|
str = players[playerlist[i]].GetUserName();
|
|
len = fnt.StringWidth(str);
|
|
if ( len > longest ) longest = len;
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i!=sel0)?Color(96,0,0,0):Color(0,0,0,0));
|
|
yy += 16;
|
|
if ( yy >= 370 )
|
|
{
|
|
xx += longest+24;
|
|
yy = 23;
|
|
longest = 0;
|
|
cols++;
|
|
if ( cols > 3 ) break;
|
|
}
|
|
}
|
|
if ( playerlist.Size() > 65 )
|
|
{
|
|
// draw scrollbar
|
|
int szr = (playerlist.Size()/22)-2;
|
|
xx = floor((ofs/22)*(630./szr))+2;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+373,"▬",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
Screen.DrawTexture(WindowSeparatorH,false,origin.x,origin.y+377,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( sub )
|
|
{
|
|
if ( sel0 == -1 )
|
|
{
|
|
if ( tradelib.ent.Size() <= 0 )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOTRADEHIST");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
xx = 6;
|
|
yy = 17;
|
|
int ofs = clamp(sel1,0,max(0,tradelib.ent.Size()-28));
|
|
for ( int i=ofs; i<tradelib.ent.Size(); i++ )
|
|
{
|
|
if ( yy >= 370 ) break;
|
|
let ent = tradelib.ent[tradelib.ent.Size()-(i+1)];
|
|
int thour = (ent.timestamp/(3600*Thinker.TICRATE));
|
|
int tmin = (ent.timestamp/(60*Thinker.TICRATE))%60;
|
|
int tsec = (ent.timestamp/Thinker.TICRATE)%60;
|
|
str = String.Format("\cu[\cc%02d\cu:\cc%02d\cu:\cc%02d\cu]\c- ",thour,tmin,tsec);
|
|
str.AppendFormat("\cd%s %s\cd: \cj%dx \cf%s\c-",ent.type?StringTable.Localize("$SWWM_TRADEFROM"):StringTable.Localize("$SWWM_TRADETO"),ent.other,ent.amt,GetDefaultByType(ent.what).GetTag());
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 13;
|
|
}
|
|
// scrollbar
|
|
if ( tradelib.ent.Size() > 28 )
|
|
{
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx = 634;
|
|
int szr = tradelib.ent.Size()-28;
|
|
yy = floor(ofs*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( curtab == TAB_CHAT )
|
|
{
|
|
let bar = SWWMStatusBar(StatusBar);
|
|
if ( !bar || (bar.FullHistory.Size() <= 0) )
|
|
{
|
|
str = StringTable.Localize("$SWWM_NOCHAT");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,(ss.x-fnt.StringWidth(str))/2.,(ss.y-fnt.GetHeight())/2.,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
return;
|
|
}
|
|
int margin = TewiFont.StringWidth("[00:00:00] ");
|
|
int ofs = bar.FullHistory.Size()-(1+sel0);
|
|
xx = 3;
|
|
yy = 379;
|
|
for ( int i=ofs; i>=0; i-- )
|
|
{
|
|
int col = (bar.FullHistory[i].type==PRINT_TEAMCHAT)?tcol.GetInt():ccol.GetInt();
|
|
int thour = (bar.FullHistory[i].tic/(3600*Thinker.TICRATE));
|
|
int tmin = (bar.FullHistory[i].tic/(60*Thinker.TICRATE))%60;
|
|
int tsec = (bar.FullHistory[i].tic/Thinker.TICRATE)%60;
|
|
str = String.Format("\cu[\c-%02d\cu:\c-%02d\cu:\c-%02d\cu]\c- ",thour,tmin,tsec);
|
|
BrokenLines l = fnt.BreakLines(bar.FullHistory[i].str,626-margin);
|
|
double by = yy-13*l.Count();
|
|
if ( by < 17 ) break;
|
|
Screen.DrawText(TewiFont,Font.CR_WHITE,origin.x+xx,origin.y+by,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
for ( int j=0; j<l.Count(); j++ )
|
|
Screen.DrawText(fnt,col,origin.x+xx+margin,origin.y+by+j*13,l.StringAt(j),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy = by;
|
|
}
|
|
// scrollbar
|
|
if ( bar.FullHistory.Size() > 1 )
|
|
{
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx = 634;
|
|
int szr = bar.FullHistory.Size()-1;
|
|
yy = floor((szr-sel0)*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
else if ( curtab == TAB_SECRET )
|
|
{
|
|
Screen.DrawTexture(EasterEgg,false,origin.x+20,origin.y+40,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
str = StringTable.Localize("$SWWM_TODEMO");
|
|
Screen.DrawText(fnt,Font.CR_FIRE,origin.x+(640-fnt.StringWidth(str))/2.,origin.y+350,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
else if ( curtab == TAB_HELP )
|
|
{
|
|
// help tab
|
|
int k1, k2;
|
|
[k1, k2] = bindings.GetKeysForCommand("openmenu SWWMKnowledgeBaseMenu");
|
|
String kstr = bindings.NameKeys(k1,k2);
|
|
str = String.Format(StringTable.Localize("$SWWM_HELPTXT"),kstr);
|
|
if ( multiplayer ) str = str..StringTable.Localize("$SWWM_HELPTXT_MP");
|
|
BrokenLines l = fnt.BreakLines(str,629);
|
|
if ( l.Count() > 28 ) l = fnt.BreakLines(str,620);
|
|
xx = 6;
|
|
yy = 17;
|
|
int ofs = clamp(sel0,0,max(0,l.Count()-28));
|
|
for ( int i=ofs; i<l.Count(); i++ )
|
|
{
|
|
if ( yy >= 370 ) break;
|
|
Screen.DrawText(fnt,Font.CR_WHITE,origin.x+xx,origin.y+yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
yy += 13;
|
|
}
|
|
// scrollbar
|
|
if ( l.Count() > 28 )
|
|
{
|
|
Screen.DrawTexture(WindowSeparator,false,origin.x+631,origin.y+14,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
xx = 634;
|
|
int szr = l.Count()-28;
|
|
yy = floor(ofs*(353./szr))+17;
|
|
Screen.DrawText(TewiFont,Font.CR_FIRE,origin.x+xx,origin.y+yy,"▮",DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
|
|
}
|
|
}
|
|
}
|
|
}
|