diff --git a/language.def_base b/language.def_base index a267ff45f..7431f0e58 100644 --- a/language.def_base +++ b/language.def_base @@ -1133,6 +1133,10 @@ BT_DEATHKINGS_FUN = "A Very Anticlimactic Boss Rehash"; // eviternity BT_ARCHANGELUS = "Archangelus, Celestial Agent"; BT_ARCHANGELUS_FUN = "Big Fucking Angel Dude"; +// boss oneliners +BOSSLINE_IOS = "\crIcon of Sin\c-: !oremoR nhoJ ,em llik tsum uoy emag eht niw oT"; +BOSSLINE_DSPARIL = "\cgD'Sparil\c-: .hself ruoy erutrot lliw I"; +BOSSLINE_ARCHANGELUS = "\cfArchangelus\c-: Foolish mortal, only your death is eternal!"; // targetter SWWM_OVERKILL = "Overkill"; SWWM_MULTIKILL = "Multi Kill"; diff --git a/language.es_base b/language.es_base index ff447b665..756e96a4d 100644 --- a/language.es_base +++ b/language.es_base @@ -1011,6 +1011,10 @@ BT_DEATHKINGS_FUN = "Un Refrito de Jefes muy Anticlimático"; // eviternity BT_ARCHANGELUS = "Archangelus, Agente Celestial"; BT_ARCHANGELUS_FUN = "Un Putísimo Ángel Enorme"; +// boss oneliners +BOSSLINE_IOS = "\crIcono del Pecado\c-: !oremoR nhoJ ,ím a emratam sebed ogeuj le ranag araP¡"; +BOSSLINE_DSPARIL = "\cgD'Sparil\c-: .senrac sut érarutroT"; +BOSSLINE_ARCHANGELUS = "\cfArchangelus\c-: Mortal insensato, ¡solo tu muerte es eterna!"; // targetter SWWM_OVERKILL = "Sobremuerte"; SWWM_MULTIKILL = "Racha"; diff --git a/language.version b/language.version index f7310fa56..380b00e4c 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw1.1.31 \cu(Thu 21 Oct 22:46:05 CEST 2021)\c-"; -SWWM_SHORTVER="\cw1.1.31 \cu(2021-10-21 22:46:05)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw1.1.31 \cu(Thu 21 Oct 23:25:47 CEST 2021)\c-"; +SWWM_SHORTVER="\cw1.1.31 \cu(2021-10-21 23:25:47)\c-"; diff --git a/zscript/handler/swwm_handler_playerevents.zsc b/zscript/handler/swwm_handler_playerevents.zsc index c12552fcd..f6c1b59d3 100644 --- a/zscript/handler/swwm_handler_playerevents.zsc +++ b/zscript/handler/swwm_handler_playerevents.zsc @@ -96,8 +96,15 @@ extend Class SWWMHandler s.favweapon = -1; for ( Inventory i=p.mo.Inv; i; i=i.inv ) { - if ( i is 'Weapon' ) - s.GotWeapon(Weapon(i).GetClass()); + if ( !(i is 'Weapon') ) continue; + // skip dual weapons if their sister weapon amount isn't 2 + String cn = i.GetClassName(); + if ( cn.Left(4) ~== "Dual" ) + { + let ss = Weapon(i).SisterWeapon; + if ( !ss || (ss.Amount == 1) ) continue; + } + s.GotWeapon(Weapon(i).GetClass()); } } else if ( (s.lastcluster != level.cluster) || !(level.clusterflags&LevelLocals.CLUSTER_HUB) || (level.info.flags2&LEVEL2_RESETINVENTORY && !e.IsReturn) ) diff --git a/zscript/handler/swwm_handler_process.zsc b/zscript/handler/swwm_handler_process.zsc index e081686c6..828fdc5a3 100644 --- a/zscript/handler/swwm_handler_process.zsc +++ b/zscript/handler/swwm_handler_process.zsc @@ -568,6 +568,11 @@ 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.Left(16) ~== "swwmremoteliner." ) { if ( consoleplayer == e.Args[0] ) return; diff --git a/zscript/handler/swwm_handler_uitick.zsc b/zscript/handler/swwm_handler_uitick.zsc index 5d8621d8a..24e159bf4 100644 --- a/zscript/handler/swwm_handler_uitick.zsc +++ b/zscript/handler/swwm_handler_uitick.zsc @@ -13,7 +13,7 @@ extend Class SWWMHandler if ( !swwm_nomapmsg ) { // angry about phase two - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYAEVIB"; msg.seqcnt = 2; msg.delay = 20; @@ -30,7 +30,7 @@ extend Class SWWMHandler int whichboss = WhichVanillaBossMap(); if ( bossmap == MAP_DE1M8 ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYAPHOBOS"; msg.seqcnt = 4; msg.delay = 40; @@ -38,7 +38,7 @@ extend Class SWWMHandler } else if ( bossmap == MAP_DE2M8 ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYADEIMOS"; msg.seqcnt = 4; msg.delay = 40; @@ -46,7 +46,7 @@ extend Class SWWMHandler } else if ( bossmap == MAP_DE3M8 ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYADIS"; msg.seqcnt = 4; msg.delay = 40; @@ -54,7 +54,7 @@ extend Class SWWMHandler } else if ( bossmap == MAP_DE4M8 ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYATHY"; msg.seqcnt = 4; msg.delay = 40; @@ -62,7 +62,7 @@ extend Class SWWMHandler } else if ( bossmap == MAP_DMAP07 ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYADIMPLE"; msg.seqcnt = 5; msg.delay = 40; @@ -80,7 +80,7 @@ extend Class SWWMHandler } if ( rampancy ) { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYARAMPANCY"; msg.seqcnt = 4; msg.delay = 250; @@ -88,7 +88,7 @@ extend Class SWWMHandler } else { - let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); + let msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); msg.seqname = "SAYAIOS"; msg.seqcnt = 5; msg.delay = 40; diff --git a/zscript/handler/swwm_handler_vanillaboss.zsc b/zscript/handler/swwm_handler_vanillaboss.zsc index 0ae29c5eb..9f3037f37 100644 --- a/zscript/handler/swwm_handler_vanillaboss.zsc +++ b/zscript/handler/swwm_handler_vanillaboss.zsc @@ -3,6 +3,45 @@ Class EndgameBossMarker : Inventory {} Class BossMarker : Inventory {} +Class IconMessage : Inventory +{ + override void DoEffect() + { + if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) ) + { + Console.MidPrint(smallfont,StringTable.Localize("$BOSSLINE_IOS")); + DepleteOrDestroy(); + return; + } + } +} + +Class ArchangelusMessage : Inventory +{ + override void DoEffect() + { + if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) ) + { + Console.MidPrint(smallfont,StringTable.Localize("$BOSSLINE_ARCHANGELUS")); + DepleteOrDestroy(); + return; + } + } +} + +Class DSparilMessage : Inventory +{ + override void DoEffect() + { + if ( Owner.InStateSequence(Owner.CurState,Owner.SeeState) ) + { + Console.MidPrint(smallfont,StringTable.Localize("$BOSSLINE_DSPARIL")); + DepleteOrDestroy(); + return; + } + } +} + extend Class SWWMHandler { String bosstag; @@ -179,7 +218,10 @@ extend Class SWWMHandler e.Thing.GiveInventory('EndgameBossMarker',1); } if ( e.Thing is 'BossEye' ) + { bossviewactor = e.Thing; + e.Thing.GiveInventory('IconMessage',1); + } bosstag = "$BT_IOS"; } else if ( bossmap == MAP_DLVL08 ) @@ -237,6 +279,7 @@ extend Class SWWMHandler bosstag = "$BT_DSPARIL2"; e.Thing.GiveInventory('BossMarker',1); e.Thing.GiveInventory('EndgameBossMarker',1); + e.Thing.GiveInventory('DSparilMessage',1); } } else if ( bossmap == MAP_HMAP38 ) @@ -321,8 +364,19 @@ extend Class SWWMHandler } else if ( bossmap == MAP_EVMAP30 ) { - if ( e.Thing.GetClassName() == "ArchangelusA" ) + if ( e.Thing.GetClassName() == "Archangelus" ) { + bossactors.Push(e.Thing); + bossviewactor = e.Thing; + bosstag = "$BT_ARCHANGELUS"; + e.Thing.GiveInventory('ArchangelusMessage',1); + } + else if ( e.Thing.GetClassName() == "ArchangelusA" ) + { + // first phase + bossactors.Clear(); + bossviewactor = null; + initialized = false; bossactors.Push(e.Thing); if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 5; if ( trk ) trk.bBOSS = true; @@ -334,6 +388,7 @@ extend Class SWWMHandler { // second phase bossactors.Clear(); + bossviewactor = null; initialized = false; bossactors.Push(e.Thing); if ( upgrademe ) e.Thing.StartHealth = e.Thing.Health *= 5; diff --git a/zscript/handler/swwm_handler_worldthings.zsc b/zscript/handler/swwm_handler_worldthings.zsc index ba7ab0c43..9cc86f8de 100644 --- a/zscript/handler/swwm_handler_worldthings.zsc +++ b/zscript/handler/swwm_handler_worldthings.zsc @@ -120,6 +120,18 @@ extend Class SWWMHandler let t = new("UglyBoyGetsFuckedUp"); t.ChangeStatNum(Thinker.STAT_USER); } + // Archangelus death + if ( e.Thing.GetClassName() == "ArchangelusB" ) + { + // kill all other monsters + let ti = ThinkerIterator.Create("Actor"); + Actor a; + while ( a = Actor(ti.Next()) ) + { + if ( (a != e.Thing) && (a.Health > 0) && (a.bBossSpawned || a.bCOUNTKILL) ) + a.DamageMobj(e.Thing,e.Thing,a.Health,'EndMii',DMG_FORCED|DMG_THRUSTLESS); + } + } if ( swwm_partytime ) { let pt = Actor.Spawn("PartyTime",e.Thing.pos); diff --git a/zscript/hud/swwm_hud.zsc b/zscript/hud/swwm_hud.zsc index 2d6bb9967..c8da33fd3 100644 --- a/zscript/hud/swwm_hud.zsc +++ b/zscript/hud/swwm_hud.zsc @@ -13,9 +13,7 @@ Class SWWMStatusBar : BaseStatusBar GenericAmmoTex[3], MiniBox, AutoPage, PauseTex, bgtex; HUDFont mTewiFont, mMiniwiFont, mMPlusFont, mk6x8Font; - // "Full History" contains all messages since session start, nothing is flushed - // this can be accessed from a section of the knowledge base - Array MainQueue, PickupQueue, FullHistory; + Array MainQueue, PickupQueue; // sorted arrays of various elements Array intpoints; @@ -56,7 +54,7 @@ Class SWWMStatusBar : BaseStatusBar String midstr; int midtic, midtype; - bool koraxhack, mainframehack; + bool koraxhack, mainframehack, bosshack; int puzzlecnt, realpuzzlecnt; SWWMWeaponTooltip ctip; @@ -167,7 +165,7 @@ Class SWWMStatusBar : BaseStatusBar m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); m.seqname = "SAYAGREETA"; m.seqcnt = 3; - m.delay = 120; + m.delay = 150; AttachMessage(m,-1232); m2 = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_KIRINSNAME"),StringTable.Localize("$SWWM_KIRINNAME"),"Kirin"); m2.seqname = "SAYAGREETB"; @@ -211,7 +209,7 @@ Class SWWMStatusBar : BaseStatusBar m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); m.seqname = "SAYABLOODA"; m.seqcnt = 2; - m.delay = 120; + m.delay = 220; AttachMessage(m,-1232); m2 = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_IBUKISNAME"),StringTable.Localize("$SWWM_IBUKINAME"),"Ibuki"); m2.seqname = "SAYABLOODB"; @@ -243,7 +241,7 @@ Class SWWMStatusBar : BaseStatusBar m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); m.seqname = "SAYAGAMEA"; m.seqcnt = 2; - m.delay = 120; + m.delay = 200; AttachMessage(m,-1232); m2 = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_IBUKISNAME"),StringTable.Localize("$SWWM_IBUKINAME"),"Ibuki"); m2.seqname = "SAYAGAMEB"; @@ -268,7 +266,7 @@ Class SWWMStatusBar : BaseStatusBar m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_KIRINSNAME"),StringTable.Localize("$SWWM_KIRINNAME"),"Kirin"); m.seqname = "KIRINWORSHIPA"; m.seqcnt = 1; - m.delay = 120; + m.delay = 150; AttachMessage(m,-1232); m2 = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); m2.seqname = "KIRINWORSHIPB"; @@ -302,7 +300,7 @@ Class SWWMStatusBar : BaseStatusBar m = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_SAYASNAME"),StringTable.Localize("$SWWM_SAYANAME"),"Saya"); m.seqname = "SAYAMASTERSA"; m.seqcnt = 2; - m.delay = 120; + m.delay = 150; m.enddelay = 60; AttachMessage(m,-1232); m2 = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_IBUKISNAME"),StringTable.Localize("$SWWM_IBUKINAME"),"Ibuki"); @@ -588,6 +586,15 @@ Class SWWMStatusBar : BaseStatusBar mainframehack = false; return true; } + if ( (msg == StringTable.Localize("$BOSSLINE_IOS")) + || (msg == StringTable.Localize("$BOSSLINE_ARCHANGELUS")) + || (msg == StringTable.Localize("$BOSSLINE_DSPARIL")) ) + { + bosshack = true; + Console.Printf(msg); + bosshack = false; + return true; + } if ( !fnt || (fnt == smallfont) ) { midstr = msg; @@ -618,12 +625,17 @@ Class SWWMStatusBar : BaseStatusBar printlevel = PRINT_CHAT; outline = "\cmKorax\c-: "..outline; } - if ( mainframehack ) + else if ( mainframehack ) { // same here, hi yholl printlevel = PRINT_CHAT; outline = "\cmAI Mainframe\c-: "..outline; } + else if ( bosshack ) + { + // no need to attach name, these are done specifically for this + printlevel = PRINT_CHAT; + } let m = new("MsgLine"); m.str = outline.Left(outline.Length()-1); // strip newline m.type = printlevel; @@ -631,7 +643,7 @@ Class SWWMStatusBar : BaseStatusBar m.rep = 1; // append chat messages to full history if ( (printlevel == PRINT_CHAT) || (printlevel == PRINT_TEAMCHAT) ) - FullHistory.Push(m); + EventHandler.SendNetworkEvent("swwmstoremessage."..m.str,m.tic,m.type,consoleplayer); // ignore during intermission if ( gamestate != GS_LEVEL ) return false; if ( (printlevel < PRINT_LOW) || (printlevel > PRINT_TEAMCHAT) ) return true; // we couldn't care less about these @@ -836,6 +848,17 @@ Class SWWMStatusBar : BaseStatusBar qsort_playerscore(a,p+1,h); } + // separated so they can be auto-ticked by the demolitionist menu + void TickInterpolators() + { + HealthInter.Update(CPlayer.health); + if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); + int s1, s2; + [s1, s2] = SWWMCredits.Get(CPlayer); + ScoreInter.Update(s1); + if ( ScoreInter.GetValue() >= ScoreInter.mCurrentValue ) ScoreInter2.Update(s2); + } + override void Tick() { Super.Tick(); @@ -858,12 +881,7 @@ Class SWWMStatusBar : BaseStatusBar i--; } // update interpolators - HealthInter.Update(CPlayer.health); - if ( !hnd ) hnd = SWWMHandler(EventHandler.Find("SWWMHandler")); - int s1, s2; - [s1, s2] = SWWMCredits.Get(CPlayer); - ScoreInter.Update(s1); - if ( ScoreInter.GetValue() >= ScoreInter.mCurrentValue ) ScoreInter2.Update(s2); + TickInterpolators(); let d = Demolitionist(CPlayer.mo); if ( d ) { @@ -1239,7 +1257,7 @@ Class SWWMStatusBar : BaseStatusBar Vector2 vpos = SWWMUtility.NDCToViewport(projdata,ndc); Font fnt = LangFont(mMiniwiFont); int mtime = thesight?70:35; - double alph = clamp(((s.updated+mtime)-level.maptime)/35.,0.,1.); + double alph = clamp(((s.updated+mtime)-(level.maptime+fractic))/35.,0.,1.); alph *= clamp(1.5-1.5*(tdir.length()/(thesight?1200.:800.)),0.,1.); tag = s.tag; Screen.DrawText(fnt,s.vipitem?Font.CR_PURPLE:s.scoreitem?Font.CR_GOLD:Font.CR_GREEN,(vpos.x-hsd.x*fnt.StringWidth(tag)/2.)/hsd.x,(vpos.y-hsd.y*fnt.GetHeight()/2.)/hsd.y,tag,DTA_VirtualWidthF,ssd.x,DTA_VirtualHeightF,ssd.y,DTA_KeepRatio,true,DTA_Alpha,alph,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); @@ -1273,7 +1291,7 @@ Class SWWMStatusBar : BaseStatusBar } int mtime = 35; if ( thesight && (targ.lasthealth > 0) ) mtime += 105; - double alph = clamp(((targ.updated+mtime)-level.maptime)/35.,0.,1.); + double alph = clamp(((targ.updated+mtime)-(level.maptime+fractic))/35.,0.,1.); Vector2 barsiz = TexMan.GetScaledSize(EnemyBTex); barsiz.x *= hsb.x; barsiz.y *= hsb.y; @@ -2460,7 +2478,7 @@ Class SWWMStatusBar : BaseStatusBar // draw nametags below them double yy; double nalph = 0.; - int tagtime = (ntagtic+70)-level.totaltime; + double tagtime = (ntagtic+70)-(level.totaltime+fractic); if ( (ntagstr != "") && (tagtime > 0) ) { nalph = clamp(tagtime/20.,0.,1.); @@ -2484,7 +2502,7 @@ Class SWWMStatusBar : BaseStatusBar { String cstr = PickupQueue[i].str; if ( PickupQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",PickupQueue[i].rep); - int curtime = (PickupQueue[i].tic+35*swwm_pickduration)-level.totaltime; + double curtime = (PickupQueue[i].tic+35*swwm_pickduration)-(level.totaltime+fractic); double alph = clamp(curtime/20.,0.,1.); BrokenLines l = fnt.BreakLines(cstr,int(ss.x*.75)); int maxlen = 0; @@ -2516,7 +2534,7 @@ Class SWWMStatusBar : BaseStatusBar double ssp = (midtype&1)?.5:1.; double hsp = (midtype&1)?2.:1.; int col = (midtype&2)?msgmidcolor2:msgmidcolor; - int curtime = (midtic+int(35*con_midtime))-level.totaltime; + double curtime = (midtic+int(GameTicRate*con_midtime))-(level.totaltime+fractic); double alph = clamp(curtime/20.,0.,1.); BrokenLines l = fnt.BreakLines(midstr,int(ss.x*ssp)); int h = fnt.GetHeight(); @@ -2550,9 +2568,9 @@ Class SWWMStatusBar : BaseStatusBar else if ( MainQueue[i].type == PRINT_TEAMCHAT ) col = msg4color; String cstr = MainQueue[i].str; if ( MainQueue[i].rep > 1 ) cstr.AppendFormat(" (x%d)",MainQueue[i].rep); - int curtime = MainQueue[i].tic-level.totaltime; - if ( MainQueue[i].type < PRINT_CHAT ) curtime += 35*swwm_msgduration; - else curtime += 35*swwm_chatduration; + double curtime = MainQueue[i].tic-(level.totaltime+fractic); + if ( MainQueue[i].type < PRINT_CHAT ) curtime += GameTicRate*swwm_msgduration; + else curtime += GameTicRate*swwm_chatduration; double alph = clamp(curtime/20.,0.,1.); BrokenLines l = fnt.BreakLines(cstr,smol?211:361); for ( int j=0; j level.maptime) ) { - Screen.Dim("Red",clamp((demo.revivefail-level.maptime)/60.,0.,.2),0,0,Screen.GetWidth(),Screen.GetHeight()); + Screen.Dim("Red",clamp((demo.revivefail-(level.maptime+fractic))/60.,0.,.2),0,0,Screen.GetWidth(),Screen.GetHeight()); str = StringTable.Localize("$SWWM_REFAIL"); fnt = LangFont(mTewiFont); len = fnt.StringWidth(str); diff --git a/zscript/hud/swwm_hudextra.zsc b/zscript/hud/swwm_hudextra.zsc index 304bdc12b..48059c812 100644 --- a/zscript/hud/swwm_hudextra.zsc +++ b/zscript/hud/swwm_hudextra.zsc @@ -101,8 +101,10 @@ Class SWWMOneLiner : HUDMessageBase } int h = fnt.GetHeight(); int fh = h*l.Count(); - double alph = clamp((curtime/20.)+1.,0.,1.); - alph *= clamp((lifespan-curtime)/10.,0.,1.); + double fractic = SWWMStatusBar(statusbar)?SWWMStatusBar(statusbar).fractic:0; + double fcurtime = curtime-fractic; + double alph = clamp((fcurtime/20.)+1.,0.,1.); + alph *= clamp((lifespan-fcurtime)/10.,0.,1.); Screen.Dim("Black",alph*.8,int((Screen.GetWidth()-(maxlen+12)*hs.x)/2.),int(bottom-(margin+2+fh)*hs.y),int((maxlen+12)*hs.x),int((fh+4)*hs.y)); int yy = margin+fh; for ( int i=0; i 100 ) return; - double alph = clamp(tics/20.,0.,1.); + double fractic = SWWMStatusBar(statusbar)?SWWMStatusBar(statusbar).fractic:0; + double ftics = tics-fractic; + double alph = clamp(ftics/20.,0.,1.); double x = (Screen.GetWidth()-(newsmallfont.StringWidth(str)*CleanXFac*2))/2; double y = int(Screen.GetHeight()*.75)-(newsmallfont.GetHeight()*CleanYFac*2)/2; Screen.DrawText(newsmallfont,Font.CR_GREEN,x,y,str,DTA_ScaleX,CleanXFac*2,DTA_ScaleY,CleanYFac*2,DTA_Alpha,alph); @@ -296,7 +304,9 @@ Class SWWMWeaponTooltip : HUDMessageBase else hs.x = swwm_hudscale; hs.y = hs.x; Vector2 ss = (Screen.GetWidth()/hs.x,Screen.GetHeight()/hs.y); - double alpha = (tics seqcnt) ) return; - let bar = SWWMStatusBar(StatusBar); - if ( bar ) - { - let l = new("MsgLine"); - l.str = chrname..": "..txt; - l.tic = level.totaltime; - l.rep = 1; - l.type = PRINT_CHAT; - bar.FullHistory.Push(l); - } + EventHandler.SendNetworkEvent("swwmstoremessage."..chrname..": "..txt,level.totaltime,PRINT_CHAT,consoleplayer); } private void DrawText() @@ -417,7 +418,7 @@ Class SWWMDirectMessage : HUDMessageBase } } - private void DrawAvatar() + private void DrawAvatar( double fractic ) { int blinkframe = -1; switch ( blinktics ) @@ -437,7 +438,7 @@ Class SWWMDirectMessage : HUDMessageBase if ( blinkframe >= 0 ) Screen.DrawTexture(Blink[blinkframe],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); if ( talkframe >= 0 ) Screen.DrawTexture(Talk[talkframe],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true); } - Screen.DrawTexture(Noiz[(gametic/2)%4],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Multiply); + Screen.DrawTexture(Noiz[int(((gametic+fractic)/GameTicRate)*15)%4],false,origin.x+2,origin.y+2,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_LegacyRenderStyle,STYLE_Multiply); } private int TotalLength() @@ -567,8 +568,9 @@ Class SWWMDirectMessage : HUDMessageBase { if ( (seqnum < 0) || (seqnum > (seqcnt+1)) ) return; double alph = 1.; - if ( seqnum == 0 ) alph = fadein/15.; - else if ( seqnum == (seqcnt+1) ) alph = 1.-fadeout/30.; + double fractic = SWWMStatusBar(statusbar)?SWWMStatusBar(statusbar).fractic:0; + if ( seqnum == 0 ) alph = (fadein+fractic)/15.; + else if ( seqnum == (seqcnt+1) ) alph = 1.-(fadeout+fractic)/30.; if ( swwm_hudscale <= 0 ) hs = StatusBar.GetHUDScale(); else hs.x = swwm_hudscale; hs.y = hs.x; @@ -576,7 +578,7 @@ Class SWWMDirectMessage : HUDMessageBase origin = (int(ss.x-270)/2,swwm_hudmargin+70); Screen.DrawTexture(MessageBox,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alph); if ( (seqnum < 1) || (seqnum > seqcnt) ) return; - DrawAvatar(); + DrawAvatar(fractic); DrawText(); } } diff --git a/zscript/kbase/swwm_kbase.zsc b/zscript/kbase/swwm_kbase.zsc index b32beedf6..3daaa7b9c 100644 --- a/zscript/kbase/swwm_kbase.zsc +++ b/zscript/kbase/swwm_kbase.zsc @@ -70,6 +70,8 @@ Class DemolitionistMenu : GenericMenu // trading SWWMTradeHistory tradelib; Array playerlist; + // chat history instance + SWWMFullHistory fullhistory; // chat history total line count (includes breaks) int chatlines; // temporary bottom messages, such as "not enough money" @@ -328,8 +330,8 @@ Class DemolitionistMenu : GenericMenu break; } let bar = SWWMStatusBar(StatusBar); - if ( bar && (bar.FullHistory.Size() > 0) ) - tabs.Push(TAB_CHAT); + fullhistory = SWWMFullHistory.Get(); + if ( fullhistory ) tabs.Push(TAB_CHAT); int lasttab = swwm_lasttab; for ( int i=0; i=0; i-- ) { - int col = (bar.FullHistory[i].type==PRINT_TEAMCHAT)?msg4color:msg3color; - int thour = (bar.FullHistory[i].tic/(3600*GameTicRate)); - int tmin = (bar.FullHistory[i].tic/(60*GameTicRate))%60; - int tsec = (bar.FullHistory[i].tic/GameTicRate)%60; + int col = (FullHistory.msg[i].type==PRINT_TEAMCHAT)?msg4color:msg3color; + int thour = (FullHistory.msg[i].tic/(3600*GameTicRate)); + int tmin = (FullHistory.msg[i].tic/(60*GameTicRate))%60; + int tsec = (FullHistory.msg[i].tic/GameTicRate)%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); + BrokenLines l = fnt.BreakLines(FullHistory.msg[i].str,626-margin); double by = yy-13*l.Count(); if ( by < 17 ) { @@ -3742,11 +3744,11 @@ Class DemolitionistMenu : GenericMenu yy = by; } // scrollbar - if ( bar.FullHistory.Size() > 1 ) + if ( FullHistory.msg.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; + int szr = FullHistory.msg.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); } diff --git a/zscript/swwm_player.zsc b/zscript/swwm_player.zsc index cb5f8537d..e74c3020a 100644 --- a/zscript/swwm_player.zsc +++ b/zscript/swwm_player.zsc @@ -2745,10 +2745,11 @@ Class Demolitionist : PlayerPawn } Super.AddInventory(item); if ( !player ) return; - if ( !bInDefaultInventory ) + String cn = item.GetClassName(); + if ( !bInDefaultInventory && (level.maptime > 0) && (!(item is 'SWWMWeapon') || !(cn.Left(4) ~== "Dual")) ) // dual weapons are ignored here, as they're handled separately { // add lore if any - SWWMLoreLibrary.Add(player,item.GetClassName()); + SWWMLoreLibrary.Add(player,cn); // weapon get oneliner if ( (item is 'Weapon') && !(item is 'SWWMGesture') && !(item is 'SWWMItemGesture') && mystats && !mystats.GotWeapon(Weapon(item).GetClass()) && CheckLocalView() ) SWWMHandler.AddOneliner("getweapon",2); diff --git a/zscript/swwm_thinkers_hud.zsc b/zscript/swwm_thinkers_hud.zsc index fa3a7cc4e..ba21a87a8 100644 --- a/zscript/swwm_thinkers_hud.zsc +++ b/zscript/swwm_thinkers_hud.zsc @@ -1,5 +1,33 @@ // thinkers related to the hud +// "Full History" contains all messages since session start, nothing is flushed +// this can be accessed from a section of the knowledge base +Class SWWMFullHistory : Thinker +{ + Array msg; + + static clearscope SWWMFullHistory Get() + { + let fh = SWWMFullHistory(ThinkerIterator.Create("SWWMFullHistory",STAT_STATIC).Next()); + return fh; + } + + static 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 = new("MsgLine"); + m.str = str; + m.tic = tic; + m.type = type; + fh.msg.Push(m); + } +} + Enum EScoreObjType { ST_Score, diff --git a/zscript/weapons/swwm_splode.zsc b/zscript/weapons/swwm_splode.zsc index b899247c8..30309db80 100644 --- a/zscript/weapons/swwm_splode.zsc +++ b/zscript/weapons/swwm_splode.zsc @@ -80,6 +80,10 @@ Class ExplodiumGun : SWWMWeapon // autoswitch if enabled if ( !Owner.player.GetNeverSwitch() ) Owner.player.PendingWeapon = SisterWeapon; + // add the oneliner + let demo = Demolitionist(Owner); + if ( demo && demo.mystats && !demo.mystats.GotWeapon(SisterWeapon.GetClass()) && Owner.CheckLocalView() ) + SWWMHandler.AddOneliner("getweapon",2); item.bPickupGood = true; } return true;