From cdf1c86fa8122800321b9cb1dff1913c239454a7 Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Thu, 15 Jun 2023 22:23:51 +0200 Subject: [PATCH] Remove full message log (potential buffer overflow). --- README.md | 2 +- language.def_menu | 17 +- language.es_menu | 30 +-- language.version | 4 +- zscript.txt | 1 - zscript/handler/swwm_handler_oneliners.zsc | 2 +- zscript/handler/swwm_handler_process.zsc | 30 +-- zscript/hud/swwm_hud_messages.zsc | 3 - zscript/hud/swwm_hudextra.zsc | 9 +- zscript/kbase/swwm_kbase.zsc | 1 - zscript/kbase/swwm_kbasetab_chat.zsc | 273 --------------------- zscript/swwm_thinkers_player.zsc | 61 ----- 12 files changed, 11 insertions(+), 422 deletions(-) delete mode 100644 zscript/kbase/swwm_kbasetab_chat.zsc diff --git a/README.md b/README.md index 705a9c78c..4621c5e99 100644 --- a/README.md +++ b/README.md @@ -661,7 +661,7 @@ Pretty simplistic so it doesn't get in the way of the action. Some things may be ### Top left corner -Message display. Can be configured to show different numbers of messages depending on whether the chat prompt is open. Chat messages take much longer to expire than others, so there's less of a chance to miss them, as they might pop back up when the less important ones expire. A full chat history can be read at any time in the **Demolitionist Menu** *(if there were any actual messages)*. Repeated messages are compressed with a multiplier suffix. +Message display. Can be configured to show different numbers of messages depending on whether the chat prompt is open. Chat messages take much longer to expire than others, so there's less of a chance to miss them, as they might pop back up when the less important ones expire. Repeated messages are compressed with a multiplier suffix. ### Top right corner diff --git a/language.def_menu b/language.def_menu index cd8154c02..e6356c4c1 100644 --- a/language.def_menu +++ b/language.def_menu @@ -262,7 +262,7 @@ TOOLTIP_SWWM_NOINTERTIPS = "Hides intermission tips, in case you don't want to s TOOLTIP_SWWM_BEEPBOOP = "The Demolitionist will make cute noises whenever pressing any usable line. This might get annoying, so it's optional."; TOOLTIP_SWWM_VOICEAMP = "At their default volume, the Demolitionist's voice lines might be drowned out by in-game audio. This sets an additional amplification level so they're louder than other sounds."; TOOLTIP_NETEVENT_SWWMCLEAREFFECTS = "Fades out any active blood, gore, debris and casings."; -TOOLTIP_SWWM_VOICELOG = "Subtitled player comments will be saved to the Messages tab of the Demolitionist Menu."; +TOOLTIP_SWWM_VOICELOG = "Subtitled player comments will show up in the console."; TOOLTIP_SWWM_SKIPSKILL = "Skips confirmation of skill selection, if you get tired of seeing it every time."; TOOLTIP_SWWM_HUDALLAMMO = "Shows all ammo types in the HUD, rather than only those for currently carried weapons."; TOOLTIP_SWWM_NOINTROEX = "Skips the explosion sequence over the original titlepic."; @@ -413,12 +413,6 @@ SWWM_STORESWAP = "You already own a weapon in the same slot: %s."; SWWM_NOSTORE = "(store is not available)"; SWWM_NOSTOREBUY = "(no items left to buy)"; SWWM_NOSTORESELL = "(no items to be sold)"; -SWWM_CHATTAB = "Messages"; -SWWM_NOCHAT = "(message history is empty)"; -SWWM_CLEARCHAT0 = "Are you sure you want to clear all messages?"; -SWWM_CLEARCHAT1 = "\cfEnter, Left Click\c- to confirm"; -SWWM_CLEARCHAT2 = "\cfBackspace, Right Click\c- to cancel"; -SWWM_CHATCLEARED = "Message history has been cleared."; 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"; @@ -509,14 +503,7 @@ SWWM_HELPTXT = "\n" "\cfArrow Keys:\c- Navigate\n" "\cfEnter, Left Click:\c- Sell\n" -"\cfBackspace, Right Click:\c- Switch to buying\n" -"\n" -"\cxMessages Tab - Controls\c-\n" -"\cx———————————————————————\c-\n" -"\n" -"\cfUp, Down:\c- Scroll\n" -"\cfBackspace, Right Click:\c- Clear messages\n" -"\cfEnter, Left Click:\c- Confirm clear"; +"\cfBackspace, Right Click:\c- Switch to buying"; SWWM_GAMETAB = "Games"; SWWM_PICKGAME = "Choose a game"; SWWM_GAMETITLE_MADCATGAME = "Boot Test"; diff --git a/language.es_menu b/language.es_menu index 1e8686e6f..c59cefd67 100644 --- a/language.es_menu +++ b/language.es_menu @@ -260,7 +260,7 @@ TOOLTIP_SWWM_NOINTERTIPS = "Oculta los consejos de intermisión, por si no quier TOOLTIP_SWWM_BEEPBOOP = "La Demolicionista hará ruiditos adorables cuando pulse cualquier línea utilizable. Esto puede que resulte cansino, así que es opcional."; TOOLTIP_SWWM_VOICEAMP = "A su volumen normal, las voces de la Demolicionista pueden ser ahogadas por el audio del juego. Con esto se le dá un nivel de amplificación extra para que sean más estridentes que otros sonidos."; TOOLTIP_NETEVENT_SWWMCLEAREFFECTS = "Desvanece cualquier sangre, vísceras, escombros y casquillos activos."; -TOOLTIP_SWWM_VOICELOG = "Los comentarios de jugador subtitulados se guardarán en la pestaña de Mensajes del Menú de Demolicionista."; +TOOLTIP_SWWM_VOICELOG = "Los comentarios de jugador subtitulados aparecerán en la consola."; TOOLTIP_SWWM_SKIPSKILL = "Salta la confirmación de selección de dificultad, si te has cansado de verla todo el tiempo."; TOOLTIP_SWWM_HUDALLAMMO = "Muestra todos los tipos de munición en el HUD, en lugar de solo los de las armas obtenidas."; TOOLTIP_SWWM_NOINTROEX = "Salta la secuencia de explosiones sobre la imagen de título original."; @@ -372,12 +372,6 @@ SWWM_STORESWAP = "Ya posees un arma en la misma ranura: %s."; SWWM_NOSTORE = "(tienda no disponible)"; SWWM_NOSTOREBUY = "(no queda nada que comprar)"; SWWM_NOSTORESELL = "(no tienes ítems que vender)"; -SWWM_CHATTAB = "Mensajes"; -SWWM_NOCHAT = "(historial de mensajes vacío)"; -SWWM_CLEARCHAT0 = "¿Seguro que quieres borrar todos los mensajes?"; -SWWM_CLEARCHAT1 = "\cfEnter/Click Izdo.\c- para confirmar"; -SWWM_CLEARCHAT2 = "\cfRetroceso/Click Dcho.\c- para cancelar"; -SWWM_CHATCLEARED = "El historial de mensajes ha sido borrado."; 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"; @@ -468,30 +462,10 @@ SWWM_HELPTXT = "\n" "\cfFlechas:\c- Navegar\n" "\cfEnter/Click Izdo.:\c- Vender\n" -"\cfRetroceso/Click Dcho.:\c- Cambiar a compra\n" -"\n" -"\cxPestaña de Mensajes - Controles\c-\n" -"\cx———————————————————————————————\c-\n" -"\n" -"\cfArriba/Abajo:\c- Scroll\n" -"\cfRetroceso/Click Dcho.:\c- Borrar mensajes\n" -"\cfEnter/Click Izdo.:\c- Confirmar borrado"; +"\cfRetroceso/Click Dcho.:\c- Cambiar a compra"; SWWM_GAMETAB = "Juegos"; SWWM_PICKGAME = "Elige un juego"; SWWM_GAMETITLE_MADCATGAME = "Test de Arranque"; -// Wallbuster menu -SWWM_BUSTERTITLE = "Wallbuster - Menú de Recarga Fácil"; -SWWM_BUSTERKEYS = -"\cfIzq/Dcha:\c- Seleccionar Munición\n" -"\cfAbajo:\c- Agregar Munición\n" -"\cfArriba:\c- Quitar Munición\n" -"\cfAv Pág:\c- Agregar 5 Munición\n" -"\cfRe Pág:\c- Quitar 5 Munición\n" -"\cfRetroceso:\c- Limpiar Munición\n" -"\cfEnter:\c- Iniciar Recarga\n" -"\cfEnter (si vacío):\c- Recarga Automática\n" -"\cfSuprimir:\c- Vaciado Completo\n" -"\cfEsc:\c- Cancelar recarga\n"; // Help menu SWWM_HELP_STORY = "La Historia Hasta Ahora"; SWWM_HELP_STORYDOOM = diff --git a/language.version b/language.version index 1f2b60cb3..6d9357a38 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r790 \cu(Sun 4 Jun 11:56:53 CEST 2023)\c-"; -SWWM_SHORTVER="\cw1.3pre r790 \cu(2023-06-04 11:56:53)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r791 \cu(Thu 15 Jun 22:28:41 CEST 2023)\c-"; +SWWM_SHORTVER="\cw1.3pre r791 \cu(2023-06-15 22:28:41)\c-"; diff --git a/zscript.txt b/zscript.txt index 0de5ffd94..be4c996da 100644 --- a/zscript.txt +++ b/zscript.txt @@ -99,7 +99,6 @@ version "4.10" #include "zscript/kbase/swwm_kbasetab_keychain.zsc" #include "zscript/kbase/swwm_kbasetab_library.zsc" #include "zscript/kbase/swwm_kbasetab_store.zsc" -#include "zscript/kbase/swwm_kbasetab_chat.zsc" #include "zscript/kbase/swwm_kbasetab_help.zsc" #include "zscript/kbase/swwm_kbasetab_secret.zsc" #include "zscript/kbase/swwm_kbasetab_games.zsc" diff --git a/zscript/handler/swwm_handler_oneliners.zsc b/zscript/handler/swwm_handler_oneliners.zsc index 6fe627b5e..3ef346489 100644 --- a/zscript/handler/swwm_handler_oneliners.zsc +++ b/zscript/handler/swwm_handler_oneliners.zsc @@ -150,7 +150,7 @@ extend Class SWWMHandler { let l = SWWMOneLiner.Make(oneliner,onelinerspan); StatusBar.AttachMessage(l,-3473); - SendNetworkEvent("swwmstoremessage.\cd"..(multiplayer?players[consoleplayer].GetUserName():"Demo").."\c*: "..StringTable.Localize(oneliner).."\c*",level.totaltime,PRINT_CHAT,consoleplayer); + if ( swwm_voicelog ) Console.PrintfEx(PRINT_CHAT|PRINT_NONOTIFY,"\cd"..(multiplayer?players[consoleplayer].GetUserName():"Demo").."\c*: "..StringTable.Localize(oneliner).."\c*"); } SendNetworkEvent("swwmremotelinertxt."..oneliner,consoleplayer,onelinerlevel); } diff --git a/zscript/handler/swwm_handler_process.zsc b/zscript/handler/swwm_handler_process.zsc index 1114680af..ea1f4862a 100644 --- a/zscript/handler/swwm_handler_process.zsc +++ b/zscript/handler/swwm_handler_process.zsc @@ -88,20 +88,6 @@ extend Class SWWMHandler bar.ntagtic = level.totaltime; bar.ntagcol = nametagcolor; } - else if ( e.Name ~== "swwmrefreshmessagelog" ) - { - let kbase = DemolitionistMenu(Menu.GetCurrentMenu()); - if ( !kbase ) return; - foreach ( t:kbase.tabs ) - { - if ( !(t is 'DemolitionistChatTab') ) continue; - let ct = DemolitionistChatTab(t); - if ( ct.msglist ) ct.msglist.Destroy(); - break; - } - kbase.tmsg = StringTable.Localize("$SWWM_CHATCLEARED"); - kbase.tmsgtic = Menu.MenuTime()+70; - } } override void NetworkProcess( ConsoleEvent e ) @@ -463,17 +449,6 @@ extend Class SWWMHandler break; } } - else if ( e.Name.Left(17) ~== "swwmstoremessage." ) - { - if ( consoleplayer != e.Args[2] ) return; - SWWMFullHistory.PushMessage(e.Name.Mid(17),e.Args[0],e.Args[1]); - } - else if ( e.Name ~== "swwmclearmessages" ) - { - if ( consoleplayer != e.Args[0] ) return; - SWWMFullHistory.ClearMessages(); - SendInterfaceEvent(consoleplayer,"swwmrefreshmessagelog"); - } else if ( e.Name.Left(16) ~== "swwmremoteliner." ) { if ( consoleplayer == e.Args[0] ) return; @@ -486,10 +461,7 @@ extend Class SWWMHandler if ( swwm_mutevoice >= e.Args[1] ) return; double dist = players[consoleplayer].Camera.Distance3D(players[e.Args[0]].mo); if ( dist < 2000 ) - { - Console.Printf("\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(19))); - if ( swwm_voicelog ) SWWMFullHistory.PushMessage("\cd"..players[e.Args[0]].GetUserName().."\c*: "..StringTable.Localize(e.Name.Mid(19)).."\c*",level.totaltime,PRINT_CHAT); - } + Console.PrintfEx(PRINT_CHAT,"\cx%s\cx: %s\c-",players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(19))); } else if ( e.Name ~== "swwmcleartransaction" ) { diff --git a/zscript/hud/swwm_hud_messages.zsc b/zscript/hud/swwm_hud_messages.zsc index 02bcf65a3..a2873af65 100644 --- a/zscript/hud/swwm_hud_messages.zsc +++ b/zscript/hud/swwm_hud_messages.zsc @@ -221,9 +221,6 @@ extend Class SWWMStatusBar if ( (rprintlevel < PRINT_LOW) || (rprintlevel > PRINT_TEAMCHAT) ) rprintlevel = PRINT_HIGH; // strip trailing newline (all Printf type messages have this) outline.DeleteLastCharacter(); - // append main queue messages to full history - if ( rprintlevel != PRINT_LOW ) - EventHandler.SendNetworkEvent("swwmstoremessage."..outline,level.totaltime,rprintlevel,consoleplayer); let m = new("MsgLine"); m.str = outline; m.type = rprintlevel; diff --git a/zscript/hud/swwm_hudextra.zsc b/zscript/hud/swwm_hudextra.zsc index 80d40a7e4..c77fad0b9 100644 --- a/zscript/hud/swwm_hudextra.zsc +++ b/zscript/hud/swwm_hudextra.zsc @@ -335,17 +335,12 @@ Class SWWMDirectMessage : HUDMessageBase else txt = StringTable.Localize("$SWWM_"..seqname..seqnum); if ( l ) l.Destroy(); l = mSmallFont.BreakLines(txt,220); - // append to the player's chat log (if it's valid) + // if valid, append to the console so the player may re-read this if they want if ( (seqnum < 1) || (seqnum > seqcnt) ) return; // some messages may have newlines in them, split them Array storemsg; txt.Split(storemsg,"\n"); - foreach ( msg:storemsg ) - { - EventHandler.SendNetworkEvent("swwmstoremessage."..chrname.."\c*: "..msg.."\c*",level.totaltime,PRINT_CHAT,consoleplayer); - // stick it into the console as well - Console.PrintfEx(PRINT_CHAT|PRINT_NONOTIFY,chrname.."\c*: "..msg.."\c*"); - } + foreach ( msg:storemsg ) Console.PrintfEx(PRINT_CHAT|PRINT_NONOTIFY,chrname.."\c*: "..msg.."\c*"); } private void DrawText() diff --git a/zscript/kbase/swwm_kbase.zsc b/zscript/kbase/swwm_kbase.zsc index 19af84fd2..96fae8673 100644 --- a/zscript/kbase/swwm_kbase.zsc +++ b/zscript/kbase/swwm_kbase.zsc @@ -185,7 +185,6 @@ Class DemolitionistMenu : GenericMenu 'DemolitionistKeychainTab', 'DemolitionistLibraryTab', 'DemolitionistStoreTab', - 'DemolitionistChatTab', //'DemolitionistGameTab', // disabled until 1.5 'DemolitionistHelpTab', 'DemolitionistSecretTab' diff --git a/zscript/kbase/swwm_kbasetab_chat.zsc b/zscript/kbase/swwm_kbasetab_chat.zsc deleted file mode 100644 index a11445d8b..000000000 --- a/zscript/kbase/swwm_kbasetab_chat.zsc +++ /dev/null @@ -1,273 +0,0 @@ -// all them messages - -Class DemolitionistChatTab : DemolitionistMenuTab -{ - DemolitionistMenuList msglist; - int ofs, maxofs; - double smofs; - bool drag; - bool justopened; - bool bDel; - SWWMFullHistory hist; - - override DemolitionistMenuTab Init( DemolitionistMenu master ) - { - title = StringTable.Localize("$SWWM_CHATTAB"); - hist = SWWMFullHistory.Get(); - justopened = true; - return Super.Init(master); - } - - override void OnDestroy() - { - Super.OnDestroy(); - if ( msglist ) msglist.Destroy(); - } - - override void OnSelect() - { - smofs = ofs; - justopened = true; - } - 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 (master.ws.x-8) ) - { - SetOffset(pos.y); - master.MenuSound("menu/demoscroll"); - drag = true; - } - MenuInput(MK_ENTER); - break; - case MB_RIGHT: - MenuInput(MK_BACK); - 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( double fractic ) - { - if ( bDel ) - { - double fh = master.mSmallFont.GetHeight(); - double yy = int(master.ws.y-fh*4)/2; - String str = StringTable.Localize("$SWWM_CLEARCHAT0"); - double xx = int(master.ws.x-master.mSmallFont.StringWidth(str))/2; - Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); - yy += fh*2; - str = StringTable.Localize("$SWWM_CLEARCHAT1"); - xx = int(master.ws.x-master.mSmallFont.StringWidth(str))/2; - Screen.DrawText(master.mSmallFont,Font.CR_WHITE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); - yy += fh; - str = StringTable.Localize("$SWWM_CLEARCHAT2"); - xx = int(master.ws.x-master.mSmallFont.StringWidth(str))/2; - Screen.DrawText(master.mSmallFont,Font.CR_WHITE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); - return; - } - if ( !hist || !msglist || (msglist.items.Size() <= 0) ) - { - String str = StringTable.Localize("$SWWM_NOCHAT"); - double xx = int(master.ws.x-master.mSmallFont.StringWidth(str))/2; - double yy = int(master.ws.y-master.mSmallFont.GetHeight())/2; - Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); - return; - } - double ssmofs = (smofs~==ofs)?smofs:(smofs*(1.-fractic)+((smofs*.6)+(ofs*.4))*fractic); - double xx = 3; - double yy = 23; - Screen.SetClipRect(int((master.origin.x+3)*master.hs),int((master.origin.y+23)*master.hs),int((master.ws.x-12)*master.hs),int((master.ws.y-46)*master.hs)); - msglist.Drawer((xx,yy-ssmofs)); - Screen.ClearClipRect(); - if ( maxofs <= 0 ) return; - xx = master.ws.x-8; - master.DrawVSeparator(xx,14,master.ws.y-28); - xx += 2; - yy = floor(ssmofs*((master.ws.y-39)/maxofs))+14; - Screen.DrawText(master.mSmallFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,"▮",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); - } -} - -// chat message item -Class DemolitionistMenuChatItem : DemolitionistMenuListItem -{ - BrokenLines l; - int msgtype; - int margin; - String tstamp; - - DemolitionistMenuChatItem Init( DemolitionistMenu master, MsgLine m ) - { - Super.Init(master,""); - msgtype = m.type; - 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 = master.mSmallFont.StringWidth(tstamp); - String nstr = m.str; - if ( m.rep > 1 ) nstr.AppendFormat(" (x%d)",m.rep); - l = master.mSmallFont.BreakLines(nstr,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 ) - { - if ( msgtype == -1 ) - { - // level change label - double xx = int((master.ws.x-14)-master.mSmallFont.StringWidth(label))/2; - Screen.DrawText(master.mSmallFont,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); - return; - } - Screen.DrawText(master.mSmallFont,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); - int col = msg2color; - if ( msgtype == PRINT_MEDIUM ) col = msg1color; - else if ( msgtype == PRINT_CHAT ) col = msg3color; - else if ( msgtype == PRINT_TEAMCHAT ) col = msg4color; - for ( int i=0; i msg; - - static clearscope SWWMFullHistory Get() - { - let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); - return fh; - } - - static play void PushMessage( String str, int tic, int type ) - { - let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); - if ( !fh ) - { - fh = new("SWWMFullHistory"); - fh.ChangeStatNum(STAT_STATIC); - } - MsgLine m; - if ( level.mapname != fh.lastmap ) - { - // push a map change label - m = new("MsgLine"); - m.str = level.levelname; - m.type = -1; // hopefully this won't be used by actual messages - fh.lastmap = level.mapname; - fh.msg.Push(m); - } - // if the last added line is identical to this one, update it with a repetition marker - int last = fh.msg.Size()-1; - if ( (fh.msg[last].str == str) && (fh.msg[last].type == type) ) - { - fh.msg[last].tic = tic; - fh.msg[last].rep++; - return; - } - m = new("MsgLine"); - m.str = str; - m.tic = tic; - m.type = type; - m.rep = 1; - fh.msg.Push(m); - } - - static play void ClearMessages() - { - let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); - if ( !fh ) - { - fh = new("SWWMFullHistory"); - fh.ChangeStatNum(STAT_STATIC); - return; - } - fh.lastmap = ""; - fh.msg.Clear(); - } -} - // Dedicated mission log (for custom maps) Class SWWMMissionLog : SWWMStaticThinker {