diff --git a/src/d_main.cpp b/src/d_main.cpp index bddac2704..7a36d0c86 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -780,7 +780,7 @@ void D_Display () viewwindowx + viewwidth, viewwindowy + viewheight); // [ZZ] execute event hook that we just started the frame - E_RenderFrame(); + //E_RenderFrame(); // Renderer->RenderView(&players[consoleplayer]); @@ -901,7 +901,7 @@ void D_Display () NetUpdate (); // send out any new accumulation // normal update // draw ZScript UI stuff - E_RenderOverlay(); + //E_RenderOverlay(); C_DrawConsole (hw2d); // draw console M_Drawer (); // menu is drawn even on top of everything FStat::PrintStat (); diff --git a/src/d_player.h b/src/d_player.h index 92f05c346..ce1c8093d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -156,12 +156,12 @@ public: double ViewBob; // Former class properties that were moved into the object to get rid of the meta class. - FName SoundClass; // Sound class - FName Face; // Doom status bar face (when used) - FName Portrait; - FName Slot[10]; - FName InvulMode; - FName HealingRadiusType; + FNameNoInit SoundClass; // Sound class + FNameNoInit Face; // Doom status bar face (when used) + FNameNoInit Portrait; + FNameNoInit Slot[10]; + FNameNoInit InvulMode; + FNameNoInit HealingRadiusType; double HexenArmor[5]; BYTE ColorRangeStart; // Skin color range BYTE ColorRangeEnd; diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 5d4ec59c9..211c73e82 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -1529,6 +1529,17 @@ bool PClassPointer::isCompatible(PType *type) return (other != nullptr && other->ClassRestriction->IsDescendantOf(ClassRestriction)); } +//========================================================================== +// +// PClassPointer :: SetPointer +// +//========================================================================== + +void PClassPointer::SetPointer(void *base, unsigned offset, TArray *special) const +{ + // Class pointers do not get added to FlatPointers because they are released from the GC. +} + //========================================================================== // // PClassPointer :: IsMatch diff --git a/src/dobjtype.h b/src/dobjtype.h index cc0a17da8..0151e6c11 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -401,6 +401,7 @@ public: bool isCompatible(PType *type); + void SetPointer(void *base, unsigned offset, TArray *special = NULL) const override; virtual bool IsMatch(intptr_t id1, intptr_t id2) const; virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const; }; diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index af180a4ea..fa9f63afa 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -230,7 +230,7 @@ bool AWeapon::CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo, int am int enough, enoughmask; int lAmmoUse1; - if ((dmflags & DF_INFINITE_AMMO) || (Owner->player->cheats & CF_INFINITEAMMO)) + if ((dmflags & DF_INFINITE_AMMO) || (Owner->FindInventory (PClass::FindActor(NAME_PowerInfiniteAmmo), true) != nullptr)) { return true; } @@ -311,7 +311,7 @@ DEFINE_ACTION_FUNCTION(AWeapon, CheckAmmo) bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse) { - if (!((dmflags & DF_INFINITE_AMMO) || (Owner->player->cheats & CF_INFINITEAMMO))) + if (!((dmflags & DF_INFINITE_AMMO) || (Owner->FindInventory (PClass::FindActor(NAME_PowerInfiniteAmmo), true) != nullptr))) { if (checkEnough && !CheckAmmo (altFire ? AltFire : PrimaryFire, false, false, ammouse)) { diff --git a/src/g_level.cpp b/src/g_level.cpp index c34a80bb7..0842f3ec8 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1365,7 +1365,7 @@ void G_FinishTravel () for (int i = 0; i < pawnsnum; i++) { // [ZZ] fire the enter hook. - E_PlayerEntered(pawns[i]->player - players, true); + E_PlayerEntered(int(pawns[i]->player - players), true); // FBehavior::StaticStartTypedScripts(SCRIPT_Return, pawns[i], true); } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 75e765d80..382775fce 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -351,7 +351,7 @@ void cht_DoCheat (player_t *player, int cheat) // player is now alive. // fire E_PlayerRespawned and start the ACS SCRIPT_Respawn. - E_PlayerRespawned(player - players); + E_PlayerRespawned(int(player - players)); // FBehavior::StaticStartTypedScripts(SCRIPT_Respawn, player->mo, true); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 9d8e5f4f3..a8dac6b54 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -270,6 +270,7 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) void DMenu::Close () { + if (DMenu::CurrentMenu == nullptr) return; // double closing can happen in the save menu. assert(DMenu::CurrentMenu == this); DMenu::CurrentMenu = mParentMenu; Destroy(); @@ -1283,7 +1284,7 @@ DMenuItemBase * CreateOptionMenuItemSubmenu(const char *label, FName cmd, int ce DMenuItemBase * CreateOptionMenuItemControl(const char *label, FName cmd, FKeyBindings *bindings) { - auto c = PClass::FindClass("OptionMenuItemControl"); + auto c = PClass::FindClass("OptionMenuItemControlBase"); auto p = c->CreateNew(); VMValue params[] = { p, FString(label), cmd.GetIndex(), bindings }; auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); diff --git a/src/namedef.h b/src/namedef.h index a010fbb8a..ebd9f3e8e 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -203,6 +203,8 @@ xx(CallTryPickup) xx(QuestItem25) xx(QuestItem28) xx(QuestItem29) +xx(PowerDoubleFiringSpeed) +xx(PowerInfiniteAmmo) xx(AcolyteBlue) xx(SpectralLightningV1) diff --git a/src/p_3dfloors.cpp b/src/p_3dfloors.cpp index fa7b66d65..b699fadbd 100644 --- a/src/p_3dfloors.cpp +++ b/src/p_3dfloors.cpp @@ -773,7 +773,7 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li int highestfloorterrain = -1; FTextureID lowestceilingpic; sector_t *lowestceilingsec = NULL, *highestfloorsec = NULL; - secplane_t *highestfloorplanes[2] = { NULL, NULL }; + secplane_t *highestfloorplanes[2] = { &open.frontfloorplane, &open.backfloorplane }; highestfloorpic.SetInvalid(); lowestceilingpic.SetInvalid(); @@ -800,13 +800,19 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li lowestceilingsec = j == 0 ? linedef->frontsector : linedef->backsector; } - if(ff_top > highestfloor && delta1 <= delta2 && (!restrict || thing->Z() >= ff_top)) + if(delta1 <= delta2 && (!restrict || thing->Z() >= ff_top)) { - highestfloor = ff_top; - highestfloorpic = *rover->top.texture; - highestfloorterrain = rover->model->GetTerrain(rover->top.isceiling); - highestfloorsec = j == 0 ? linedef->frontsector : linedef->backsector; - highestfloorplanes[j] = rover->top.plane; + if (ff_top > highestfloor) + { + highestfloor = ff_top; + highestfloorpic = *rover->top.texture; + highestfloorterrain = rover->model->GetTerrain(rover->top.isceiling); + highestfloorsec = j == 0 ? linedef->frontsector : linedef->backsector; + } + if (ff_top > highestfloorplanes[j]->ZatPoint(x, y)) + { + highestfloorplanes[j] = rover->top.plane; + } } if(ff_top > lowestfloor[j] && ff_top <= thing->Z() + thing->MaxStepHeight) lowestfloor[j] = ff_top; } @@ -818,18 +824,18 @@ void P_LineOpening_XFloors (FLineOpening &open, AActor * thing, const line_t *li open.floorpic = highestfloorpic; open.floorterrain = highestfloorterrain; open.bottomsec = highestfloorsec; - if (highestfloorplanes[0]) - { - open.frontfloorplane = *highestfloorplanes[0]; - if (open.frontfloorplane.fC() < 0) open.frontfloorplane.FlipVert(); - } - if (highestfloorplanes[1]) - { - open.backfloorplane = *highestfloorplanes[1]; - if (open.backfloorplane.fC() < 0) open.backfloorplane.FlipVert(); - } } - + if (highestfloorplanes[0] != &open.frontfloorplane) + { + open.frontfloorplane = *highestfloorplanes[0]; + if (open.frontfloorplane.fC() < 0) open.frontfloorplane.FlipVert(); + } + if (highestfloorplanes[1] != &open.backfloorplane) + { + open.backfloorplane = *highestfloorplanes[1]; + if (open.backfloorplane.fC() < 0) open.backfloorplane.FlipVert(); + } + if(lowestceiling < open.top) { open.top = lowestceiling; diff --git a/src/p_actionfunctions.cpp b/src/p_actionfunctions.cpp index 40629bfcb..15e82a56c 100644 --- a/src/p_actionfunctions.cpp +++ b/src/p_actionfunctions.cpp @@ -1410,26 +1410,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_RadiusDamageSelf) return 0; } -//========================================================================== -// -// Execute a line special / script -// -//========================================================================== -DEFINE_ACTION_FUNCTION(AActor, A_CallSpecial) -{ - PARAM_SELF_PROLOGUE(AActor); - PARAM_INT (special); - PARAM_INT_DEF (arg1); - PARAM_INT_DEF (arg2); - PARAM_INT_DEF (arg3); - PARAM_INT_DEF (arg4); - PARAM_INT_DEF (arg5); - - bool res = !!P_ExecuteSpecial(special, NULL, self, false, arg1, arg2, arg3, arg4, arg5); - - ACTION_RETURN_BOOL(res); -} - //========================================================================== // // The ultimate code pointer: Fully customizable missiles! diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 043c0a783..47789c0cb 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -612,7 +612,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) ClientObituary (this, inflictor, source, dmgflags); // [ZZ] fire player death hook - E_PlayerDied(player - players); + E_PlayerDied(int(player - players)); // Death script execution, care of Skull Tag FBehavior::StaticStartTypedScripts (SCRIPT_Death, this, true); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 5375085dd..6f44cedcd 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2841,7 +2841,7 @@ FUNC(LS_SetPlayerProperty) // Add or remove a power if (arg2 >= PROP_INVULNERABILITY && arg2 <= PROP_SPEED) { - static ENamedName powers[11] = + static ENamedName powers[13] = { NAME_PowerInvulnerable, NAME_PowerStrength, @@ -2853,7 +2853,9 @@ FUNC(LS_SetPlayerProperty) NAME_PowerFlight, NAME_None, NAME_None, - NAME_PowerSpeed + NAME_PowerSpeed, + NAME_PowerInfiniteAmmo, + NAME_PowerDoubleFiringSpeed }; int power = arg2 - PROP_INVULNERABILITY; @@ -3715,3 +3717,27 @@ int P_ExecuteSpecial(int num, } return 0; } + +//========================================================================== +// +// Execute a line special / script +// +//========================================================================== +DEFINE_ACTION_FUNCTION(FLevelLocals, ExecuteSpecial) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + PARAM_INT(special); + PARAM_OBJECT(activator, AActor); + PARAM_POINTER(linedef, line_t); + PARAM_BOOL(lineside); + PARAM_INT_DEF(arg1); + PARAM_INT_DEF(arg2); + PARAM_INT_DEF(arg3); + PARAM_INT_DEF(arg4); + PARAM_INT_DEF(arg5); + + bool res = !!P_ExecuteSpecial(special, linedef, activator, lineside, arg1, arg2, arg3, arg4, arg5); + + ACTION_RETURN_BOOL(res); +} + diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 3d7098d70..c1e68f3b3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -144,7 +144,6 @@ IMPLEMENT_POINTERS_START(AActor) IMPLEMENT_POINTER(LastHeard) IMPLEMENT_POINTER(master) IMPLEMENT_POINTER(Poisoner) - IMPLEMENT_POINTER(DamageFunc) IMPLEMENT_POINTER(alternative) IMPLEMENT_POINTERS_END @@ -5514,7 +5513,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags) { // [ZZ] fire non-hub ENTER event // level.time is a hack to make sure that we don't call it on dummy player initialization during hub return. - if (!level.time) E_PlayerEntered(p - players, false); + if (!level.time) E_PlayerEntered(int(p - players), false); FBehavior::StaticStartTypedScripts (SCRIPT_Enter, p->mo, true); } else if (state == PST_REBORN) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index bf6c79a82..8b8e93f6a 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -1381,7 +1381,7 @@ void DPSprite::Tick() Tics--; // [BC] Apply double firing speed. - if ((Flags & PSPF_POWDOUBLE) && Tics && (Owner->cheats & CF_DOUBLEFIRINGSPEED)) + if ((Flags & PSPF_POWDOUBLE) && Tics && (Owner->mo->FindInventory (PClass::FindActor(NAME_PowerDoubleFiringSpeed), true))) Tics--; if (!Tics) diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 8f465e081..a3208598d 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -832,7 +832,10 @@ void CopyPlayer(player_t *dst, player_t *src, const char *name) else { dst->userinfo.TransferFrom(uibackup); + // The player class must come from the save, so that the menu reflects the currently playing one. + dst->userinfo.PlayerClassChanged(src->mo->GetClass()->DisplayName); } + // Validate the skin dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass)); diff --git a/src/p_trace.cpp b/src/p_trace.cpp index 3597535e5..818372e74 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -41,6 +41,7 @@ #include "r_defs.h" #include "p_spec.h" #include "g_levellocals.h" +#include "p_terrain.h" //========================================================================== // @@ -135,6 +136,13 @@ static void GetPortalTransition(DVector3 &pos, sector_t *&sec) } } +static bool isLiquid(F3DFloor *ff) +{ + if (ff->flags & FF_SWIMMABLE) return true; + auto terrain = ff->model->GetTerrain(ff->flags & FF_INVERTPLANES ? sector_t::floor : sector_t::ceiling); + return Terrains[terrain].IsLiquid && Terrains[terrain].Splash != -1; +} + //========================================================================== // // Trace entry point @@ -300,9 +308,9 @@ void FTraceInfo::Setup3DFloors() if (!(rover->flags&FF_EXISTS)) continue; - if (rover->flags&FF_SWIMMABLE && Results->Crossed3DWater == NULL) + if (Results->Crossed3DWater == NULL) { - if (Check3DFloorPlane(rover, false)) + if (Check3DFloorPlane(rover, false) && isLiquid(rover)) { // only consider if the plane is above the actual floor. if (rover->top.plane->ZatPoint(Results->HitPos) > bf) @@ -767,7 +775,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) { for (auto rover : CurSector->e->XFloor.ffloors) { - if ((rover->flags & FF_EXISTS) && (rover->flags&FF_SWIMMABLE)) + if ((rover->flags & FF_EXISTS) && isLiquid(rover)) { if (Check3DFloorPlane(rover, false)) { diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index a13c24e63..fc71160ae 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1854,7 +1854,7 @@ public: intptr_t v1i = intptr_t(ParsedLines[i].v1); intptr_t v2i = intptr_t(ParsedLines[i].v2); - if (v1i >= level.vertexes.Size() || v2i >= level.vertexes.Size() || v1i < 0 || v2i < 0) + if ((unsigned)v1i >= level.vertexes.Size() || (unsigned)v2i >= level.vertexes.Size()) { I_Error ("Line %d has invalid vertices: %zd and/or %zd.\nThe map only contains %u vertices.", i+skipped, v1i, v2i, level.vertexes.Size()); } diff --git a/src/p_user.cpp b/src/p_user.cpp index d5e8afdaf..dbdf08002 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1233,8 +1233,6 @@ const char *APlayerPawn::GetSoundClass() const return skins[player->userinfo.GetSkin()].name; } - // [GRB] - auto pclass = GetClass(); return SoundClass != NAME_None? SoundClass.GetChars() : "player"; } diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 5e2454ed2..0666fce8b 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -737,7 +737,11 @@ class Actor : Thinker native native void A_VileChase(); native void A_BossDeath(); native void A_Detonate(); - native bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0); + bool A_CallSpecial(int special, int arg1=0, int arg2=0, int arg3=0, int arg4=0, int arg5=0) + { + return Level.ExecuteSpecial(special, self, null, false, arg1, arg2, arg3, arg4, arg5); + } + native void A_ActiveSound(); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index bffee91f0..7b872f472 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -469,6 +469,7 @@ struct LevelLocals native native String GetUDMFString(int type, int index, Name key); native int GetUDMFInt(int type, int index, Name key); native double GetUDMFFloat(int type, int index, Name key); + native bool ExecuteSpecial(int special, Actor activator, line linedef, bool lineside, int arg1 = 0, int arg2 = 0, int arg3 = 0, int arg4 = 0, int arg5 = 0); } diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index d355a5e14..828113ac8 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -1767,7 +1767,7 @@ class PowerProtection : Powerup { if (passive && damage > 0) { - newdamage = max(1, ApplyDamageFactors(GetClass(), damageType, damage, damage / 4)); + newdamage = max(0, ApplyDamageFactors(GetClass(), damageType, damage, damage / 4)); if (Owner != null && newdamage < damage) Owner.A_PlaySound(ActiveSound, CHAN_AUTO, 1.0, false, ATTN_NONE); } } diff --git a/wadsrc/static/zscript/shared/movingcamera.txt b/wadsrc/static/zscript/shared/movingcamera.txt index 15fdd0836..c6af13b42 100644 --- a/wadsrc/static/zscript/shared/movingcamera.txt +++ b/wadsrc/static/zscript/shared/movingcamera.txt @@ -311,7 +311,7 @@ class PathFollower : Actor while ( (spec = InterpolationSpecial(iterator.Next ())) ) { - A_CallSpecial(spec.special, spec.args[0], spec.args[1], spec.args[2], spec.args[3], spec.args[4]); + Level.ExecuteSpecial(spec.special, null, null, false, spec.args[0], spec.args[1], spec.args[2], spec.args[3], spec.args[4]); } }