Messages tab implemented.

Reorganized some code.
This commit is contained in:
Mari the Deer 2022-03-24 18:08:38 +01:00
commit b59e1ba285
10 changed files with 518 additions and 304 deletions

View file

@ -521,8 +521,8 @@ SWWM_STOREFULL = "You can't hold more of that.";
SWWM_STOREMUNS = "You don't have enough money.";
SWWM_NOSTORE = "(no items left to buy)";
SWWM_NOSTORESELL = "(no items to be sold)";
SWWM_CHATTAB = "Chat Log";
SWWM_NOCHAT = "(chat history is empty)";
SWWM_CHATTAB = "Messages";
SWWM_NOCHAT = "(message history is empty)";
SWWM_SECRETTAB = "Secret";
SWWM_TODEMO = "\cx\"Fight for justice, Demo-chan! You can do it!\"\c- \cg♥\c- Ibuki & Saya";
SWWM_CUTIECLUB = "\cx\"Never lose hope, Demo-chan! We're all with you!\"\c- \cg♥\c- Cutie Club";
@ -615,7 +615,7 @@ SWWM_HELPTXT =
"\cfEnter/Left Click:\c- Sell\n"
"\cfBackspace/Right Click:\c- Switch to buying\n"
"\n"
"\cxChat Log Tab - Controls\c-\n"
"\cxMessages Tab - Controls\c-\n"
"\cx———————————————————————\c-\n"
"\n"
"\cfUp/Down:\c- Scroll";

View file

@ -500,8 +500,8 @@ SWWM_STOREFULL = "No puedes llevar más de eso.";
SWWM_STOREMUNS = "No tienes suficiente dinero.";
SWWM_NOSTORE = "(no queda nada que comprar)";
SWWM_NOSTORESELL = "(no tienes ítems que vender)";
SWWM_CHATTAB = "Hist. de Chat";
SWWM_NOCHAT = "(historial de chat vacío)";
SWWM_CHATTAB = "Mensajes";
SWWM_NOCHAT = "(historial de mensajes vacío)";
SWWM_SECRETTAB = "Secreto";
SWWM_TODEMO = "\cx\"¡Lucha por la justicia, Demo-chan! ¡Tú puedes!\"\c- \cg♥\c- Ibuki y Saya";
SWWM_CUTIECLUB = "\cx\"¡Jamás pierdas la esperanza, Demo-chan! ¡Estamos todas contigo!\"\c- \cg♥\c- Club Cuqui";
@ -594,8 +594,8 @@ SWWM_HELPTXT =
"\cfEnter/Click Izdo.:\c- Vender\n"
"\cfRetroceso/Click Dcho.:\c- Cambiar a compra\n"
"\n"
"\cxPestaña de Historial de Chat - Controles\c-\n"
"\cx————————————————————————————————————————\c-\n"
"\cxPestaña de Mensajes - Controles\c-\n"
"\cx———————————————————————————————\c-\n"
"\n"
"\cfArriba/Abajo:\c- Scroll";
// Wallbuster menu

View file

@ -1,3 +1,3 @@
[default]
SWWM_MODVER="\cyDEMOLITIONIST \cw1.2pre r195 \cu(Thu 24 Mar 16:28:58 CET 2022)\c-";
SWWM_SHORTVER="\cw1.2pre r195 \cu(2022-03-24 16:28:58)\c-";
SWWM_MODVER="\cyDEMOLITIONIST \cw1.2pre r195 \cu(Thu 24 Mar 18:08:38 CET 2022)\c-";
SWWM_SHORTVER="\cw1.2pre r195 \cu(2022-03-24 18:08:38)\c-";

View file

@ -113,296 +113,3 @@ Class DemolitionistMenuListItem ui
Screen.DrawText(smallfont,selected?Font.CR_FIRE:Font.CR_WHITE,master.origin.x+pos.x,master.origin.y+pos.y,label,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
// monster kill stat item
Class DemolitionistMenuKillItem : DemolitionistMenuListItem
{
MonsterKill s;
int width;
DemolitionistMenuKillItem Init( DemolitionistMenu master, MonsterKill s, int width = 0 )
{
Super.Init(master,"");
self.s = s;
self.width = width;
let m = GetDefaultByType(s.m);
self.label = m.GetTag(FallbackTag);
if ( self.label == FallbackTag )
{
self.label = m.GetClassName();
SWWMUtility.BeautifyClassName(self.label);
}
return self;
}
override int GetWidth()
{
return width;
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
// skip draw when out of bounds
if ( (master.origin.y+pos.y > clipbottom) || (master.origin.y+pos.y+smallfont.GetHeight() < cliptop) )
return;
Screen.DrawText(smallfont,Font.CR_FIRE,master.origin.x+pos.x,master.origin.y+pos.y,label,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
String str = String.Format("%d",s.kills);
Screen.DrawText(smallfont,Font.CR_WHITE,master.origin.x+pos.x+width-smallfont.StringWidth(str),master.origin.y+pos.y,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
// map stat item
Class DemolitionistMenuMapStatItem : DemolitionistMenuListItem
{
LevelStat s;
int width;
int maxlen[4];
DemolitionistMenuMapStatItem Init( DemolitionistMenu master, LevelStat s, int width = 0 )
{
Super.Init(master,"");
self.s = s;
self.width = width;
self.label = s.hub?s.levelname:String.Format("%s - %s",s.mapname.MakeUpper(),s.levelname);
return self;
}
override int GetWidth()
{
return width;
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
String str = label;
if ( selected ) str = "\cd▸\c- "..str;
bool smallname = smallfont.StringWidth(str)>(width-(maxlen[3]+maxlen[2]+maxlen[1]+maxlen[0]+24));
Screen.DrawText(smallname?smallfont2:smallfont,Font.CR_FIRE,master.origin.x+pos.x,master.origin.y+pos.y+smallname*2,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
double xx = pos.x+width;
double yy = pos.y+2;
int sec = Thinker.Tics2Seconds(s.time);
str = String.Format("%02d\cu:\c-%02d\cu:\c-%02d",sec/3600,(sec%3600)/60,sec%60);
Screen.DrawText(smallfont2,((s.suck>0)&&(sec>=(s.suck*3600)))?Font.CR_RED:(sec<=s.par)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[0],master.origin.y+yy,"T",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
if ( maxlen[0] > 0 ) xx -= maxlen[0]+8;
if ( s.stotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.scount,s.stotal);
Screen.DrawText(smallfont2,(s.scount>=s.stotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[1],master.origin.y+yy,"S",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
if ( maxlen[1] > 0 ) xx -= maxlen[1]+8;
if ( s.itotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.icount,s.itotal);
Screen.DrawText(smallfont2,(s.icount>=s.itotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[2],master.origin.y+yy,"I",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
if ( maxlen[2] > 0 ) xx -= maxlen[2]+8;
if ( s.ktotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.kcount,s.ktotal);
Screen.DrawText(smallfont2,(s.kcount>=s.ktotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[3],master.origin.y+yy,"K",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
}
// achievement item
Class DemolitionistMenuAchievementItem : DemolitionistMenuListItem
{
SWWMAchievementInfo a;
TextureID AchievementUnknown, BaseBox, BarTex[3];
bool ShouldObscure;
bool bHidden;
int width;
BrokenLines l;
String oldstr;
DemolitionistMenuAchievementItem Init( DemolitionistMenu master, SWWMAchievementInfo a, int width = 0 )
{
Super.Init(master,"");
self.a = a;
self.width = width;
AchievementUnknown = TexMan.CheckForTexture("graphics/Achievements/HiddenAchievement.png",TexMan.Type_Any);
BaseBox = TexMan.CheckForTexture("graphics/Achievements/NoAchievement.png",TexMan.Type_Any);
BarTex[0] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementBase.png",TexMan.Type_Any);
BarTex[1] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementProgress.png",TexMan.Type_Any);
BarTex[2] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementDone.png",TexMan.Type_Any);
ShouldObscure = (swwm_filterachievements==1);
Update();
return self;
}
// cache state/progress to not call it every frame
void Update()
{
a.state = master.shnd.achievementstate.At(a.basename).ToInt();
if ( !a.maxval ) return;
a.val = master.shnd.achievementprogress.At(a.basename).ToInt();
if ( !a.bitfield ) return;
int val = 0;
for ( int i=0; i<a.maxval; i++ )
val += !!(a.val&(1<<i));
a.val = val;
}
override int GetWidth()
{
return width;
}
override int GetHeight()
{
return 50; // hardcoded
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
if ( bHidden ) return;
bool completed = !!a.state;
bool hasprogress = (a.maxval && a.val);
double xx = master.origin.x+pos.x;
double yy = master.origin.y+pos.y;
Screen.DrawTexture(BaseBox,false,xx+1,yy+1,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_FillColor,(!completed&&!hasprogress&&ShouldObscure)?Color(8,8,8):Color(16,16,16));
Screen.DrawTexture((!completed&&!hasprogress&&ShouldObscure)?AchievementUnknown:a.icon,false,xx,yy,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_Desaturate,(!completed)*255,DTA_ColorOverlay,completed?Color(0,0,0,0):(hasprogress||!ShouldObscure)?Color(96,0,0,0):Color(192,0,0,0));
Screen.DrawTexture(BarTex[0],false,xx+1,yy+36,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_FillColor,Color(0,0,0));
String str;
if ( a.maxval && (!ShouldObscure || hasprogress) )
{
int val = clamp(a.val,0,a.maxval);
if ( val < a.maxval ) Screen.DrawTexture(BarTex[0],false,xx,yy+35,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawTexture(BarTex[completed?2:1],false,xx,yy+35,DTA_DestWidthF,width*(val/double(a.maxval)),DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
if ( completed ) str = String.Format("%s / %s",SWWMUtility.ThousandsNum(a.maxval),SWWMUtility.ThousandsNum(a.maxval));
else str = String.Format("%s / %s",SWWMUtility.ThousandsNum(val),SWWMUtility.ThousandsNum(a.maxval));
int ox = (width-smallfont2.StringWidth(str))/2;
Screen.DrawText(smallfont2,completed?Font.CR_GREEN:Font.CR_WHITE,xx+ox,yy+37,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
else Screen.DrawTexture(BarTex[completed?2:0],false,xx,yy+35,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
str = a.hasformat?String.Format(StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TXT"),a.maxval):StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TXT");
if ( str != oldstr )
{
if ( l ) l.Destroy();
l = smallfont2.BreakLines(str,width-40);
oldstr = str;
}
str = StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TAG");
if ( !completed && !hasprogress && ShouldObscure ) SWWMUtility.ObscureText(str,(gametic/3)+ypos*2+1);
int oy = (32-(14+(9*l.Count())))/2;
Screen.DrawText(smallfont,completed?Font.CR_GREEN:Font.CR_DARKGRAY,xx+36,yy+oy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
for ( int i=0; i<l.Count(); i++ )
{
str = l.StringAt(i);
if ( !completed && !hasprogress && ShouldObscure ) SWWMUtility.ObscureText(str,(gametic/3)+ypos*2+2+i);
Screen.DrawText(smallfont2,completed?Font.CR_WHITE:Font.CR_BLACK,xx+40,yy+oy+14+i*9,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
}
// inventory item
Class DemolitionistMenuInvItem : DemolitionistMenuListItem
{
Inventory inv;
int col;
DemolitionistMenuInvItem Init( DemolitionistMenu master, Inventory i )
{
Super.Init(master,"");
inv = i;
col = Font.CR_WHITE;
if ( i is 'Weapon' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPGold'):Font.CR_GOLD;
else if ( i is 'MagAmmo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPTan'):Font.CR_TAN;
else if ( (i is 'BackpackItem') || (i is 'HammerspaceEmbiggener') ) col = Font.CR_DARKBROWN;
else if ( i is 'Ammo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPBrown'):Font.CR_BROWN;
else if ( (i is 'PowerupGiver') || (i is 'AmmoFabricator') || i.bBIGPOWERUP ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPPurple'):Font.CR_PURPLE;
else if ( (i is 'Health') || (i is 'HealthPickup') || (i is 'SWWMHealth') ) col = Font.CR_RED;
else if ( (i is 'Armor') || (i is 'SWWMSpareArmor') ) col = Font.CR_GREEN;
else if ( i is 'PuzzleItem' ) col = Font.CR_LIGHTBLUE;
else if ( i is 'Key' ) col = Font.CR_UNTRANSLATED;
else if ( i is 'SWWMCollectible' ) col = Font.CR_PURPLE;
return self;
}
// how much of this item we can drop when right-clicking
int GetDropAmount()
{
return 0;
}
}
// lore entry
Class DemolitionistMenuLoreItem : DemolitionistMenuListItem
{
SWWMLore ent;
bool bActive; // currently being read
DemolitionistMenuLoreItem Init( DemolitionistMenu master, SWWMLore e )
{
Super.Init(master,"");
ent = e;
label = StringTable.Localize(ent.tag);
return self;
}
override int GetWidth()
{
if ( !ent.read ) return smallfont.StringWidth("‼"..label);
return smallfont.StringWidth(label);
}
// marks this entry as read
void MarkRead()
{
if ( ent.read ) return;
EventHandler.SendNetworkEvent(String.Format("swwmmarkloreread.%s",ent.tag),consoleplayer);
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
String str = label;
if ( !ent.read ) str = "\cf‼\c-"..label;
Screen.DrawText(smallfont,bActive?Font.CR_FIRE:Font.CR_WHITE,master.origin.x+pos.x,master.origin.y+pos.y,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_ColorOverlay,selected?Color(0,0,0,0):Color(96,0,0,0));
}
}
// store item (buy/sell)
Class DemolitionistMenuStoreItem : DemolitionistMenuListItem
{
Class<Inventory> inv;
int col;
bool bSell;
int width; // set in post after list init, used for positioning the price tag
DemolitionistMenuStoreItem Init( DemolitionistMenu master, Class<Inventory> i, bool bSell = false )
{
Super.Init(master,"");
inv = i;
col = Font.CR_WHITE;
let def = GetDefaultByType(i);
if ( i is 'Weapon' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPGold'):Font.CR_GOLD;
else if ( i is 'MagAmmo' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPTan'):Font.CR_TAN;
else if ( (i is 'BackpackItem') || (i is 'HammerspaceEmbiggener') ) col = Font.CR_DARKBROWN;
else if ( i is 'Ammo' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPBrown'):Font.CR_BROWN;
else if ( (i is 'PowerupGiver') || (i is 'AmmoFabricator') || def.bBIGPOWERUP ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPPurple'):Font.CR_PURPLE;
else if ( (i is 'Health') || (i is 'HealthPickup') || (i is 'SWWMHealth') ) col = Font.CR_RED;
else if ( (i is 'Armor') || (i is 'SWWMSpareArmor') ) col = Font.CR_GREEN;
self.bSell = bSell;
return self;
}
int GetPrice()
{
return 0;
}
int GetUnits()
{
return 0;
}
}
// chat message item
Class DemolitionistMenuChatItem : DemolitionistMenuListItem
{
}

View file

@ -2,10 +2,222 @@
Class DemolitionistChatTab : DemolitionistMenuTab
{
DemolitionistMenuList msglist;
int ofs, maxofs;
double smofs;
bool drag;
SWWMFullHistory hist;
override DemolitionistMenuTab Init( DemolitionistMenu master )
{
title = StringTable.Localize("$SWWM_CHATTAB");
bHidden = !SWWMFullHistory.Get();
hist = SWWMFullHistory.Get();
return Super.Init(master);
}
override void OnDestroy()
{
Super.OnDestroy();
if ( msglist ) msglist.Destroy();
}
override void OnSelect()
{
smofs = ofs;
}
override void OnDeselect()
{
smofs = ofs;
}
override void Ticker()
{
if ( !hist ) return;
int ypos = 0;
bool recenter = true;
if ( !msglist )
{
msglist = new("DemolitionistMenuList");
msglist.master = master;
msglist.selected = -1;
msglist.items.Resize(hist.msg.Size());
for ( int i=0; i<hist.msg.Size(); i++ )
{
msglist.items[i] = new("DemolitionistMenuChatItem").Init(master,hist.msg[i]);
msglist.items[i].ypos = ypos;
ypos += msglist.items[i].GetHeight();
}
}
else if ( msglist.items.Size() < hist.msg.Size() )
{
// theoretically we can assume that the message list will never shrink in the middle of gameplay, only grow
// also the array only ever has elements pushed, never inserted in-between
// if this somehow breaks, I don't know what the hell can do that
msglist.items.Resize(hist.msg.Size());
for ( int i=0; i<hist.msg.Size(); i++ )
{
if ( !msglist.items[i] )
{
msglist.items[i] = new("DemolitionistMenuChatItem").Init(master,hist.msg[i]);
msglist.items[i].ypos = ypos;
}
ypos += msglist.items[i].GetHeight();
}
if ( ofs < maxofs ) recenter = false; // don't recenter if we weren't at the bottom
}
else recenter = false;
maxofs = max(ypos-int(master.ws.y-46),0);
// push it to the bottom
if ( recenter ) ofs = maxofs;
// update smooth scroll
smofs = (smofs*.6)+(ofs*.4);
if ( abs(smofs-ofs) < (1./master.hs) ) smofs = ofs;
// tick the list (not really needed, as elements don't dynamically update anything)
msglist.Ticker();
}
// called when sending a scroll input
// returns true if the position actually changed
// speed: how many pixels to move (either back or forward)
bool Scroll( int speed )
{
if ( maxofs <= 0 ) return false;
int oldofs = ofs;
ofs = clamp(ofs+speed,0,maxofs);
return (ofs != oldofs);
}
// called when clicking on our scrollbar
// returns true if the position actually changed
// y: relative click position
bool SetOffset( double y )
{
if ( maxofs <= 0 ) return false;
int oldofs = ofs;
ofs = clamp(int(round((y-20.5)/((master.ws.y-41.)/maxofs))),0,maxofs);
return (ofs != oldofs);
}
override void MenuInput( int key )
{
if ( maxofs <= 0 ) return;
switch ( key )
{
case MK_DOWN:
if ( Scroll(16) ) master.MenuSound("menu/demoscroll");
break;
case MK_UP:
if ( Scroll(-16) ) master.MenuSound("menu/demoscroll");
break;
}
}
override void MouseInput( Vector2 pos, int btn )
{
if ( maxofs <= 0 ) return;
switch ( btn )
{
case MB_LEFT:
// see if we're clicking the scrollbar (if it exists)
if ( pos.x > (master.ws.x-8) )
{
SetOffset(pos.y);
master.MenuSound("menu/demoscroll");
drag = true;
break;
}
case MB_WHEELUP:
if ( Scroll(-8) ) master.MenuSound("menu/demoscroll");
break;
case MB_WHEELDOWN:
if ( Scroll(8) ) master.MenuSound("menu/demoscroll");
break;
case MB_DRAG:
if ( drag ) SetOffset(pos.y);
break;
case MB_RELEASE:
drag = false;
break;
}
}
override void Drawer()
{
if ( !hist || (msglist.items.Size() <= 0) )
{
String str = StringTable.Localize("$SWWM_NOCHAT");
double xx = int(master.ws.x-smallfont.StringWidth(str))/2;
double yy = int(master.ws.y-smallfont.GetHeight())/2;
Screen.DrawText(smallfont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
return;
}
double xx = 3;
double yy = 23;
int cliptop = int((master.origin.y+23)*master.hs);
int clipbottom = int((master.origin.y+master.ws.y-23)*master.hs);
int clipleft = int((master.origin.x+3)*master.hs);
int clipright = int((master.origin.x+master.ws.x-9)*master.hs);
msglist.Drawer((xx,yy-smofs),cliptop,clipbottom,clipleft,clipright);
if ( maxofs <= 0 ) return;
xx = master.ws.x-8;
master.DrawVSeparator(xx,14,master.ws.y-28);
xx += 2;
yy = floor(smofs*((master.ws.y-39)/maxofs))+14;
Screen.DrawText(smallfont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,"▮",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true);
}
}
// chat message item
Class DemolitionistMenuChatItem : DemolitionistMenuListItem
{
BrokenLines l;
int margin;
String tstamp;
DemolitionistMenuChatItem Init( DemolitionistMenu master, MsgLine m )
{
Super.Init(master,"");
if ( m.type == -1 )
{
// map change marker
label = String.Format("\cx[\c-%s\cx]\c-",m.str);
return self;
}
// actually use crimetime for the timestamps, for immersion
int rtime = (m.tic/GameTicRate)+(master.c_minute*60)+(master.c_hour*3600);
int thour = (rtime/3600)%24;
int tmin = (rtime/60)%60;
int tsec = rtime%60;
tstamp = String.Format("\cm[\c-%02d\cm:\c-%02d\cm:\c-%02d\cm]\c- ",thour,tmin,tsec);
margin = smallfont.StringWidth(tstamp);
l = smallfont.BreakLines(m.str,int(master.ws.x-14)-margin);
return self;
}
override void OnDestroy()
{
Super.OnDestroy();
if ( l ) l.Destroy();
}
override int GetWidth()
{
return int(master.ws.x-14);
}
override int GetHeight()
{
if ( l ) return l.Count()*14;
return 14;
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
if ( !l )
{
// we'll assume this is a level change label
double xx = int((master.ws.x-14)-smallfont.StringWidth(label))/2;
Screen.DrawText(smallfont,Font.CR_GOLD,master.origin.x+pos.x+xx,master.origin.y+pos.y,label,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
return;
}
Screen.DrawText(smallfont,Font.CR_DARKGRAY,master.origin.x+pos.x,master.origin.y+pos.y,tstamp,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
for ( int i=0; i<l.Count(); i++ )
Screen.DrawText(smallfont,Font.CR_WHITE,master.origin.x+pos.x+margin,master.origin.y+pos.y+i*14,l.StringAt(i),DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}

View file

@ -8,3 +8,34 @@ Class DemolitionistInventoryTab : DemolitionistMenuTab
return Super.Init(master);
}
}
// inventory item
Class DemolitionistMenuInvItem : DemolitionistMenuListItem
{
Inventory inv;
int col;
DemolitionistMenuInvItem Init( DemolitionistMenu master, Inventory i )
{
Super.Init(master,i.GetTag());
inv = i;
col = Font.CR_WHITE;
if ( i is 'Weapon' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPGold'):Font.CR_GOLD;
else if ( i is 'MagAmmo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPTan'):Font.CR_TAN;
else if ( (i is 'BackpackItem') || (i is 'HammerspaceEmbiggener') ) col = Font.CR_DARKBROWN;
else if ( i is 'Ammo' ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPBrown'):Font.CR_BROWN;
else if ( (i is 'PowerupGiver') || (i is 'AmmoFabricator') || i.bBIGPOWERUP ) col = SWWMUtility.IsVIPItem(i)?Font.FindFontColor('VIPPurple'):Font.CR_PURPLE;
else if ( (i is 'Health') || (i is 'HealthPickup') || (i is 'SWWMHealth') ) col = Font.CR_RED;
else if ( (i is 'Armor') || (i is 'SWWMSpareArmor') ) col = Font.CR_GREEN;
else if ( i is 'PuzzleItem' ) col = Font.CR_LIGHTBLUE;
else if ( i is 'Key' ) col = Font.CR_UNTRANSLATED;
else if ( i is 'SWWMCollectible' ) col = Font.CR_PURPLE;
return self;
}
// how much of this item we can drop when right-clicking
int GetDropAmount()
{
return 0;
}
}

View file

@ -419,3 +419,38 @@ Class DemolitionistLibraryTab : DemolitionistMenuTab
}
}
}
// lore entry
Class DemolitionistMenuLoreItem : DemolitionistMenuListItem
{
SWWMLore ent;
bool bActive; // currently being read
DemolitionistMenuLoreItem Init( DemolitionistMenu master, SWWMLore e )
{
Super.Init(master,"");
ent = e;
label = StringTable.Localize(ent.tag);
return self;
}
override int GetWidth()
{
if ( !ent.read ) return smallfont.StringWidth("‼"..label);
return smallfont.StringWidth(label);
}
// marks this entry as read
void MarkRead()
{
if ( ent.read ) return;
EventHandler.SendNetworkEvent(String.Format("swwmmarkloreread.%s",ent.tag),consoleplayer);
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
String str = label;
if ( !ent.read ) str = "\cf‼\c-"..label;
Screen.DrawText(smallfont,bActive?Font.CR_FIRE:Font.CR_WHITE,master.origin.x+pos.x,master.origin.y+pos.y,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_ColorOverlay,selected?Color(0,0,0,0):Color(96,0,0,0));
}
}

View file

@ -581,3 +581,185 @@ Class DemolitionistStatsTab : DemolitionistMenuTab
}
}
}
// monster kill stat item
Class DemolitionistMenuKillItem : DemolitionistMenuListItem
{
MonsterKill s;
int width;
DemolitionistMenuKillItem Init( DemolitionistMenu master, MonsterKill s, int width = 0 )
{
Super.Init(master,"");
self.s = s;
self.width = width;
let m = GetDefaultByType(s.m);
self.label = m.GetTag(FallbackTag);
if ( self.label == FallbackTag )
{
self.label = m.GetClassName();
SWWMUtility.BeautifyClassName(self.label);
}
return self;
}
override int GetWidth()
{
return width;
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
Screen.DrawText(smallfont,Font.CR_FIRE,master.origin.x+pos.x,master.origin.y+pos.y,label,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
String str = String.Format("%d",s.kills);
Screen.DrawText(smallfont,Font.CR_WHITE,master.origin.x+pos.x+width-smallfont.StringWidth(str),master.origin.y+pos.y,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
// map stat item
Class DemolitionistMenuMapStatItem : DemolitionistMenuListItem
{
LevelStat s;
int width;
int maxlen[4];
DemolitionistMenuMapStatItem Init( DemolitionistMenu master, LevelStat s, int width = 0 )
{
Super.Init(master,"");
self.s = s;
self.width = width;
self.label = s.hub?s.levelname:String.Format("%s - %s",s.mapname.MakeUpper(),s.levelname);
return self;
}
override int GetWidth()
{
return width;
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
String str = label;
if ( selected ) str = "\cd▸\c- "..str;
bool smallname = smallfont.StringWidth(str)>(width-(maxlen[3]+maxlen[2]+maxlen[1]+maxlen[0]+24));
Screen.DrawText(smallname?smallfont2:smallfont,Font.CR_FIRE,master.origin.x+pos.x,master.origin.y+pos.y+smallname*2,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
double xx = pos.x+width;
double yy = pos.y+2;
int sec = Thinker.Tics2Seconds(s.time);
str = String.Format("%02d\cu:\c-%02d\cu:\c-%02d",sec/3600,(sec%3600)/60,sec%60);
Screen.DrawText(smallfont2,((s.suck>0)&&(sec>=(s.suck*3600)))?Font.CR_RED:(sec<=s.par)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[0],master.origin.y+yy,"T",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
if ( maxlen[0] > 0 ) xx -= maxlen[0]+8;
if ( s.stotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.scount,s.stotal);
Screen.DrawText(smallfont2,(s.scount>=s.stotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[1],master.origin.y+yy,"S",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
if ( maxlen[1] > 0 ) xx -= maxlen[1]+8;
if ( s.itotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.icount,s.itotal);
Screen.DrawText(smallfont2,(s.icount>=s.itotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[2],master.origin.y+yy,"I",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
if ( maxlen[2] > 0 ) xx -= maxlen[2]+8;
if ( s.ktotal > 0 )
{
str = String.Format("%d\cu/\c-%d",s.kcount,s.ktotal);
Screen.DrawText(smallfont2,(s.kcount>=s.ktotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-smallfont2.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawText(smallfont2,Font.CR_FIRE,master.origin.x+xx-maxlen[3],master.origin.y+yy,"K",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
}
// achievement item
Class DemolitionistMenuAchievementItem : DemolitionistMenuListItem
{
SWWMAchievementInfo a;
TextureID AchievementUnknown, BaseBox, BarTex[3];
bool ShouldObscure;
bool bHidden;
int width;
BrokenLines l;
String oldstr;
DemolitionistMenuAchievementItem Init( DemolitionistMenu master, SWWMAchievementInfo a, int width = 0 )
{
Super.Init(master,"");
self.a = a;
self.width = width;
AchievementUnknown = TexMan.CheckForTexture("graphics/Achievements/HiddenAchievement.png",TexMan.Type_Any);
BaseBox = TexMan.CheckForTexture("graphics/Achievements/NoAchievement.png",TexMan.Type_Any);
BarTex[0] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementBase.png",TexMan.Type_Any);
BarTex[1] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementProgress.png",TexMan.Type_Any);
BarTex[2] = TexMan.CheckForTexture("graphics/Achievements/BarAchievementDone.png",TexMan.Type_Any);
ShouldObscure = (swwm_filterachievements==1);
Update();
return self;
}
// cache state/progress to not call it every frame
void Update()
{
a.state = master.shnd.achievementstate.At(a.basename).ToInt();
if ( !a.maxval ) return;
a.val = master.shnd.achievementprogress.At(a.basename).ToInt();
if ( !a.bitfield ) return;
int val = 0;
for ( int i=0; i<a.maxval; i++ )
val += !!(a.val&(1<<i));
a.val = val;
}
override int GetWidth()
{
return width;
}
override int GetHeight()
{
return 50; // hardcoded
}
override void Drawer( Vector2 pos, bool selected, int cliptop, int clipbottom, int clipleft, int clipright )
{
if ( bHidden ) return;
bool completed = !!a.state;
bool hasprogress = (a.maxval && a.val);
double xx = master.origin.x+pos.x;
double yy = master.origin.y+pos.y;
Screen.DrawTexture(BaseBox,false,xx+1,yy+1,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_FillColor,(!completed&&!hasprogress&&ShouldObscure)?Color(8,8,8):Color(16,16,16));
Screen.DrawTexture((!completed&&!hasprogress&&ShouldObscure)?AchievementUnknown:a.icon,false,xx,yy,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_Desaturate,(!completed)*255,DTA_ColorOverlay,completed?Color(0,0,0,0):(hasprogress||!ShouldObscure)?Color(96,0,0,0):Color(192,0,0,0));
Screen.DrawTexture(BarTex[0],false,xx+1,yy+36,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright,DTA_FillColor,Color(0,0,0));
String str;
if ( a.maxval && (!ShouldObscure || hasprogress) )
{
int val = clamp(a.val,0,a.maxval);
if ( val < a.maxval ) Screen.DrawTexture(BarTex[0],false,xx,yy+35,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
Screen.DrawTexture(BarTex[completed?2:1],false,xx,yy+35,DTA_DestWidthF,width*(val/double(a.maxval)),DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
if ( completed ) str = String.Format("%s / %s",SWWMUtility.ThousandsNum(a.maxval),SWWMUtility.ThousandsNum(a.maxval));
else str = String.Format("%s / %s",SWWMUtility.ThousandsNum(val),SWWMUtility.ThousandsNum(a.maxval));
int ox = (width-smallfont2.StringWidth(str))/2;
Screen.DrawText(smallfont2,completed?Font.CR_GREEN:Font.CR_WHITE,xx+ox,yy+37,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
else Screen.DrawTexture(BarTex[completed?2:0],false,xx,yy+35,DTA_DestWidthF,width,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
str = a.hasformat?String.Format(StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TXT"),a.maxval):StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TXT");
if ( str != oldstr )
{
if ( l ) l.Destroy();
l = smallfont2.BreakLines(str,width-40);
oldstr = str;
}
str = StringTable.Localize("$SWWM_ACHIEVEMENT_"..a.basename.."_TAG");
if ( !completed && !hasprogress && ShouldObscure ) SWWMUtility.ObscureText(str,(gametic/3)+ypos*2+1);
int oy = (32-(14+(9*l.Count())))/2;
Screen.DrawText(smallfont,completed?Font.CR_GREEN:Font.CR_DARKGRAY,xx+36,yy+oy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
for ( int i=0; i<l.Count(); i++ )
{
str = l.StringAt(i);
if ( !completed && !hasprogress && ShouldObscure ) SWWMUtility.ObscureText(str,(gametic/3)+ypos*2+2+i);
Screen.DrawText(smallfont2,completed?Font.CR_WHITE:Font.CR_BLACK,xx+40,yy+oy+14+i*9,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright);
}
}
}

View file

@ -9,3 +9,39 @@ Class DemolitionistStoreTab : DemolitionistMenuTab
return Super.Init(master);
}
}
// store item (buy/sell)
Class DemolitionistMenuStoreItem : DemolitionistMenuListItem
{
Class<Inventory> inv;
int col;
bool bSell;
int width; // set in post after list init, used for positioning the price tag
DemolitionistMenuStoreItem Init( DemolitionistMenu master, Class<Inventory> i, bool bSell = false )
{
Super.Init(master,"");
inv = i;
col = Font.CR_WHITE;
let def = GetDefaultByType(i);
if ( i is 'Weapon' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPGold'):Font.CR_GOLD;
else if ( i is 'MagAmmo' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPTan'):Font.CR_TAN;
else if ( (i is 'BackpackItem') || (i is 'HammerspaceEmbiggener') ) col = Font.CR_DARKBROWN;
else if ( i is 'Ammo' ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPBrown'):Font.CR_BROWN;
else if ( (i is 'PowerupGiver') || (i is 'AmmoFabricator') || def.bBIGPOWERUP ) col = SWWMUtility.IsVIPItemClass(i)?Font.FindFontColor('VIPPurple'):Font.CR_PURPLE;
else if ( (i is 'Health') || (i is 'HealthPickup') || (i is 'SWWMHealth') ) col = Font.CR_RED;
else if ( (i is 'Armor') || (i is 'SWWMSpareArmor') ) col = Font.CR_GREEN;
self.bSell = bSell;
return self;
}
int GetPrice()
{
return 0;
}
int GetUnits()
{
return 0;
}
}

View file

@ -4,6 +4,7 @@
// this can be accessed from a section of the knowledge base
Class SWWMFullHistory : Thinker
{
String lastmap;
Array<MsgLine> msg;
static clearscope SWWMFullHistory Get()
@ -20,7 +21,17 @@ Class SWWMFullHistory : Thinker
fh = new("SWWMFullHistory");
fh.ChangeStatNum(STAT_STATIC);
}
MsgLine m = new("MsgLine");
MsgLine m;
if ( level.mapname != fh.lastmap )
{
// push a map change label
m = new("MsgLine");
m.str = level.levelname;
m.type = -1;
fh.lastmap = level.mapname;
fh.msg.Push(m);
}
m = new("MsgLine");
m.str = str;
m.tic = tic;
m.type = type;