diff --git a/src/events.cpp b/src/events.cpp index 91e66b82bb..1baa9b1d3f 100755 --- a/src/events.cpp +++ b/src/events.cpp @@ -515,6 +515,14 @@ bool E_CheckReplacement( PClassActor *replacee, PClassActor **replacement ) return final; } +void E_NewGame() +{ + for (DStaticEventHandler* handler = E_FirstEventHandler; handler; handler = handler->next) + { + handler->NewGame(); + } +} + // normal event loopers (non-special, argument-less) DEFINE_EVENT_LOOPER(RenderFrame) DEFINE_EVENT_LOOPER(WorldLightning) @@ -668,6 +676,8 @@ DEFINE_EMPTY_HANDLER(DStaticEventHandler, NetworkProcess); DEFINE_EMPTY_HANDLER(DStaticEventHandler, CheckReplacement); +DEFINE_EMPTY_HANDLER(DStaticEventHandler, NewGame) + // =========================================== // // Event handlers @@ -1154,6 +1164,18 @@ void DStaticEventHandler::CheckReplacement( PClassActor *replacee, PClassActor * } } +void DStaticEventHandler::NewGame() +{ + IFVIRTUAL(DStaticEventHandler, NewGame) + { + // don't create excessive DObjects if not going to be processed anyway + if (func == DStaticEventHandler_NewGame_VMPtr) + return; + VMValue params[1] = { (DStaticEventHandler*)this }; + VMCall(func, params, 1, nullptr, 0); + } +} + // void DStaticEventHandler::OnDestroy() { diff --git a/src/events.h b/src/events.h index 54d9755667..456db6c10e 100755 --- a/src/events.h +++ b/src/events.h @@ -72,6 +72,9 @@ void E_Console(int player, FString name, int arg1, int arg2, int arg3, bool manu // called when looking up the replacement for an actor class bool E_CheckReplacement(PClassActor* replacee, PClassActor** replacement); +// called on new game +void E_NewGame(); + // send networked event. unified function. bool E_SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual); @@ -172,6 +175,9 @@ public: // void CheckReplacement(PClassActor* replacee, PClassActor** replacement, bool* final); + + // + void NewGame(); }; class DEventHandler : public DStaticEventHandler { diff --git a/src/g_level.cpp b/src/g_level.cpp index 86567ea847..36843919bb 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -527,6 +527,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel) gamestate = GS_LEVEL; } G_DoLoadLevel (0, false); + if(!savegamerestore) + { + E_NewGame(); + } } // diff --git a/src/hwrenderer/utility/hw_clock.cpp b/src/hwrenderer/utility/hw_clock.cpp index 40c61924b5..a34b1fdb13 100644 --- a/src/hwrenderer/utility/hw_clock.cpp +++ b/src/hwrenderer/utility/hw_clock.cpp @@ -169,7 +169,7 @@ void CheckBench() AppendRenderTimes(compose); AppendLightStats(compose); //AppendMissingTextureStats(compose); - compose.AppendFormat("%llu fps\n\n", screen->GetLastFPS()); + compose.AppendFormat("%llu fps\n\n", (unsigned long long)screen->GetLastFPS()); FILE *f = fopen("benchmarks.txt", "at"); if (f != NULL) diff --git a/src/p_local.h b/src/p_local.h index 08c1288477..d1a81a9925 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -453,6 +453,7 @@ enum EDmgFlags DMG_NO_PROTECT = 256, DMG_USEANGLE = 512, DMG_NO_PAIN = 1024, + DMG_EXPLOSION = 2048, }; diff --git a/src/p_map.cpp b/src/p_map.cpp index dacc7ae8bc..58c0bb706d 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4754,11 +4754,18 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, // We must pass the unreplaced puff type here puff = P_SpawnPuff(t1, pufftype, bleedpos, trace.SrcAngleFromTarget, trace.SrcAngleFromTarget - 90, 2, puffFlags | PF_HITTHING, trace.Actor); - - if (nointeract) - { - return puff; - } + } + if (victim != NULL) + { + victim->linetarget = trace.Actor; + victim->attackAngleFromSource = trace.SrcAngleFromTarget; + // With arbitrary portals this cannot be calculated so using the actual attack angle is the only option. + victim->angleFromSource = trace.unlinked ? victim->attackAngleFromSource : t1->AngleTo(trace.Actor); + victim->unlinked = trace.unlinked; + } + if (nointeract) + { + return puff; } // Allow puffs to inflict poison damage, so that hitscans can poison, too. @@ -4833,14 +4840,7 @@ AActor *P_LineAttack(AActor *t1, DAngle angle, double distance, P_TraceBleed(newdam > 0 ? newdam : damage, trace.HitPos, trace.Actor, trace.SrcAngleFromTarget, pitch); } } - if (victim != NULL) - { - victim->linetarget = trace.Actor; - victim->attackAngleFromSource = trace.SrcAngleFromTarget; - // With arbitrary portals this cannot be calculated so using the actual attack angle is the only option. - victim->angleFromSource = trace.unlinked? victim->attackAngleFromSource : t1->AngleTo(trace.Actor); - victim->unlinked = trace.unlinked; - } + } if (trace.Crossed3DWater || trace.CrossedWater) { @@ -6177,7 +6177,7 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom { //[MC] Don't count actors saved by buddha if already at 1 health. int prehealth = thing->health; - newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); + newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod, DMG_EXPLOSION); if (thing->health < prehealth) count++; } else if (thing->player == NULL && (!(flags & RADF_NOIMPACTDAMAGE) && !(thing->flags7 & MF7_DONTTHRUST))) @@ -6229,7 +6229,7 @@ int P_RadiusAttack(AActor *bombspot, AActor *bombsource, int bombdamage, int bom { // OK to damage; target is in direct path //[MC] Don't count actors saved by buddha if already at 1 health. int prehealth = thing->health; - int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod); + int newdam = P_DamageMobj(thing, bombspot, bombsource, damage, bombmod, DMG_EXPLOSION); P_TraceBleed(newdam > 0 ? newdam : damage, thing, bombspot); if (thing->health < prehealth) count++; } diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 3eb98b8083..fcb075e0f7 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -942,6 +942,8 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) arc.ReadObjects(hubload); } + arc("multiplayer", multiplayer); + arc("level.flags", level.flags) ("level.flags2", level.flags2) ("level.fadeto", level.fadeto) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index c8fcb1f090..d6fc442c6d 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -10291,9 +10291,14 @@ FxWhileLoop::~FxWhileLoop() FxExpression *FxWhileLoop::DoResolve(FCompileContext &ctx) { CHECKRESOLVED(); - SAFE_RESOLVE(Condition, ctx); + SAFE_RESOLVE_OPT(Condition, ctx); SAFE_RESOLVE_OPT(Code, ctx); + if (Condition == nullptr) + { + Condition = new FxConstant(true, ScriptPosition); + } + if (Condition->ValueType != TypeBool) { Condition = new FxBoolCast(Condition); diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index 0b1338d379..b4a5807f9e 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -227,7 +227,7 @@ void DFrameBuffer::DrawRateStuff () int textScale = active_con_scale(); - chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2llu ms (%3llu fps)", howlong, LastCount); + chars = mysnprintf (fpsbuff, countof(fpsbuff), "%2llu ms (%3llu fps)", (unsigned long long)howlong, (unsigned long long)LastCount); rate_x = Width / textScale - ConFont->StringWidth(&fpsbuff[0]); Clear (rate_x * textScale, 0, Width, ConFont->GetHeight() * textScale, GPalette.BlackIndex, 0); DrawText (ConFont, CR_WHITE, rate_x, 0, (char *)&fpsbuff[0], diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 156763a27e..dc394a0d20 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -939,6 +939,7 @@ enum EDmgFlags DMG_NO_PROTECT = 256, DMG_USEANGLE = 512, DMG_NO_PAIN = 1024, + DMG_EXPLOSION = 2048, } enum EReplace diff --git a/wadsrc/static/zscript/events.txt b/wadsrc/static/zscript/events.txt index 9a908f0603..d2d8ed3240 100755 --- a/wadsrc/static/zscript/events.txt +++ b/wadsrc/static/zscript/events.txt @@ -339,6 +339,9 @@ class StaticEventHandler : Object native play version("2.4") // virtual native void CheckReplacement(ReplaceEvent e); + // + virtual native void NewGame(); + // this value will be queried on Register() to decide the relative order of this handler to every other. // this is most useful in UI systems. // default is 0. diff --git a/wadsrc/static/zscript/hexen/blastradius.txt b/wadsrc/static/zscript/hexen/blastradius.txt index 3dd355b7cf..0f50948922 100644 --- a/wadsrc/static/zscript/hexen/blastradius.txt +++ b/wadsrc/static/zscript/hexen/blastradius.txt @@ -89,7 +89,7 @@ extend class Actor if (victim.bTouchy) { // Touchy objects die when blasted victim.bArmed = false; // Disarm - victim.DamageMobj(self, self, victim.health, 'Melee', DMG_FORCED); + victim.DamageMobj(self, self, victim.health, 'Melee', DMG_FORCED|DMG_EXPLOSION); } } diff --git a/wadsrc/static/zscript/statscreen/statscreen.txt b/wadsrc/static/zscript/statscreen/statscreen.txt index 2dcb2de727..a8d8e25ed1 100644 --- a/wadsrc/static/zscript/statscreen/statscreen.txt +++ b/wadsrc/static/zscript/statscreen/statscreen.txt @@ -400,7 +400,7 @@ class StatusScreen abstract play version("2.5") // //==================================================================== - void End () + virtual void End () { CurState = LeavingIntermission;