2399 lines
80 KiB
Text
2399 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");
|
|
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
|
|
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.+.75*(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");
|
|
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
|
|
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");
|
|
else if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
|
|
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;
|
|
// 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.+.75*(amt-1)));
|
|
if ( type is 'Ammo' )
|
|
{
|
|
int maxneed = cur.MaxAmount-cur.Amount;
|
|
// get the largest affordable child pickup amount (that we need)
|
|
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.+.75*(inv2.Amount-1)));
|
|
if ( (inv2.Amount > amt) && (inv2.Amount <= maxneed) && (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 if ( gameinfo.gametype&GAME_Strife ) str = StringTable.Localize(players[consoleplayer].logtext);
|
|
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.+.75*(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);
|
|
}
|
|
}
|
|
}
|
|
}
|