From 78538ed9efa1dbd5efa7162f7674aa661649d6ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 14:53:39 +0100 Subject: [PATCH 01/12] - missed an else. --- src/info.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.cpp b/src/info.cpp index 84d8e26be..580abbf1a 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -868,7 +868,7 @@ void FMapInfoParser::ParseDamageDefinition() dtd.DefaultFactor = sc.Float; if (dtd.DefaultFactor == 0) dtd.ReplaceFactor = true; } - if (sc.Compare("OBITUARY")) + else if (sc.Compare("OBITUARY")) { sc.MustGetStringName("="); sc.MustGetString(); From cc598dfddeb5ba507249041e95ca9d10498b8929 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 15:16:03 +0100 Subject: [PATCH 02/12] - fixed: To get the final error handling from the serializer, Close must be called before the destructor gets invoked. - added line feeds to all error messages in the serializer. --- src/g_level.cpp | 1 + src/serializer.cpp | 62 ++++++++++++++++++++++++---------------------- src/serializer.h | 1 + 3 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 01911f742..b0de51b43 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1624,6 +1624,7 @@ void G_UnSnapshotLevel (bool hubLoad) } } } + arc.Close(); } // No reason to keep the snapshot around once the level's been entered. level.info->Snapshot.Clean(); diff --git a/src/serializer.cpp b/src/serializer.cpp index a577056af..fd9af832c 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -486,6 +486,8 @@ bool FSerializer::OpenReader(FCompressedBuffer *input) void FSerializer::Close() { + if (w == nullptr && r == nullptr) return; // double close? This should skip the I_Error at the bottom. + if (w != nullptr) { delete w; @@ -590,7 +592,7 @@ bool FSerializer::BeginObject(const char *name) } else { - Printf(TEXTCOLOR_RED "Object expected for '%s'", name); + Printf(TEXTCOLOR_RED "Object expected for '%s'\n", name); mErrors++; return false; } @@ -656,7 +658,7 @@ bool FSerializer::BeginArray(const char *name) } else { - Printf(TEXTCOLOR_RED "Array expected for '%s'", name); + Printf(TEXTCOLOR_RED "Array expected for '%s'\n", name); mErrors++; return false; } @@ -748,7 +750,7 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe else { assert(false && "Integer expected"); - Printf(TEXTCOLOR_RED "Integer expected for '%s[%d]'", key, i); + Printf(TEXTCOLOR_RED "Integer expected for '%s[%d]'\n", key, i); mErrors++; } } @@ -756,7 +758,7 @@ FSerializer &FSerializer::Args(const char *key, int *args, int *defargs, int spe else { assert(false && "array expected"); - Printf(TEXTCOLOR_RED "array expected for '%s'", key); + Printf(TEXTCOLOR_RED "array expected for '%s'\n", key); mErrors++; } } @@ -800,7 +802,7 @@ FSerializer &FSerializer::ScriptNum(const char *key, int &num) else { assert(false && "Integer expected"); - Printf(TEXTCOLOR_RED "Integer expected for '%s'", key); + Printf(TEXTCOLOR_RED "Integer expected for '%s'\n", key); mErrors++; } } @@ -1005,7 +1007,7 @@ void FSerializer::ReadObjects(bool hubtravel) PClass *cls = PClass::FindClass(clsname); if (cls == nullptr) { - Printf("Unknown object class '%s' in savegame", clsname.GetChars()); + Printf(TEXTCOLOR_RED "Unknown object class '%s' in savegame\n", clsname.GetChars()); founderrors = true; r->mDObjects[i] = RUNTIME_CLASS(AActor)->CreateNew(); // make sure we got at least a valid pointer for the duration of the loading process. r->mDObjects[i]->Destroy(); // but we do not want to keep this around, so destroy it right away. @@ -1041,7 +1043,7 @@ void FSerializer::ReadObjects(bool hubtravel) catch (CRecoverableError &err) { // In case something in here throws an error, let's continue and deal with it later. - Printf(TEXTCOLOR_RED "'%s'\n while restoring %s", err.GetMessage(), obj ? obj->GetClass()->TypeName.GetChars() : "invalid object"); + Printf(TEXTCOLOR_RED "'%s'\n while restoring %s\n", err.GetMessage(), obj ? obj->GetClass()->TypeName.GetChars() : "invalid object"); mErrors++; } } @@ -1055,7 +1057,7 @@ void FSerializer::ReadObjects(bool hubtravel) assert(!founderrors); if (founderrors) { - Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame"); + Printf(TEXTCOLOR_RED "Failed to restore all objects in savegame\n"); mErrors++; } } @@ -1064,7 +1066,7 @@ void FSerializer::ReadObjects(bool hubtravel) // nuke all objects we created here. for (auto obj : r->mDObjects) { - obj->Destroy(); + if (!(obj->ObjectFlags & OF_EuthanizeMe)) obj->Destroy(); } r->mDObjects.Clear(); @@ -1182,7 +1184,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, bool &value, bool *def } else { - Printf(TEXTCOLOR_RED "boolean type expected for '%s'", key); + Printf(TEXTCOLOR_RED "boolean type expected for '%s'\n", key); arc.mErrors++; } } @@ -1218,7 +1220,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int64_t &value, int64_ } else { - Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); + Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key); arc.mErrors++; } } @@ -1254,7 +1256,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint64_t &value, uint6 } else { - Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); + Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key); arc.mErrors++; } } @@ -1291,7 +1293,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, int32_t &value, int32_ } else { - Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); + Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key); arc.mErrors++; } } @@ -1327,7 +1329,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, uint32_t &value, uint3 } else { - Printf(TEXTCOLOR_RED "integer type expected for '%s'", key); + Printf(TEXTCOLOR_RED "integer type expected for '%s'\n", key); arc.mErrors++; } } @@ -1405,7 +1407,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, double &value, double } else { - Printf(TEXTCOLOR_RED "float type expected for '%s'", key); + Printf(TEXTCOLOR_RED "float type expected for '%s'\n", key); arc.mErrors++; } } @@ -1548,7 +1550,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe } else { - Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'", key); + Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'\n", key); value.SetNull(); arc.mErrors++; } @@ -1564,7 +1566,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe else { assert(false && "not a texture"); - Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'", key); + Printf(TEXTCOLOR_RED "object does not represent a texture for '%s'\n", key); value.SetNull(); arc.mErrors++; } @@ -1649,7 +1651,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, DObject *&value, DObje else { assert(false && "invalid object reference"); - Printf(TEXTCOLOR_RED "Invalid object reference for '%s'", key); + Printf(TEXTCOLOR_RED "Invalid object reference for '%s'\n", key); value = nullptr; arc.mErrors++; if (retcode) *retcode = false; @@ -1698,7 +1700,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FName &value, FName *d } else { - Printf(TEXTCOLOR_RED "String expected for '%s'", key); + Printf(TEXTCOLOR_RED "String expected for '%s'\n", key); arc.mErrors++; value = NAME_None; } @@ -1746,7 +1748,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDynamicCol } } assert(false && "not a colormap"); - Printf(TEXTCOLOR_RED "object does not represent a colormap for '%s'", key); + Printf(TEXTCOLOR_RED "object does not represent a colormap for '%s'\n", key); cm = &NormalLight; } } @@ -1787,7 +1789,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FSoundID &sid, FSoundI } else { - Printf(TEXTCOLOR_RED "string type expected for '%s'", key); + Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key); sid = 0; arc.mErrors++; } @@ -1836,7 +1838,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor } else { - Printf(TEXTCOLOR_RED "string type expected for '%s'", key); + Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key); clst = nullptr; arc.mErrors++; } @@ -1884,7 +1886,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&cl } else { - Printf(TEXTCOLOR_RED "string type expected for '%s'", key); + Printf(TEXTCOLOR_RED "string type expected for '%s'\n", key); clst = nullptr; arc.mErrors++; } @@ -1960,20 +1962,20 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState { // this can actually happen by changing the DECORATE so treat it as a warning, not an error. state = nullptr; - Printf(TEXTCOLOR_ORANGE "Invalid state '%s+%d' for '%s'", cls.GetString(), ndx.GetInt(), key); + Printf(TEXTCOLOR_ORANGE "Invalid state '%s+%d' for '%s'\n", cls.GetString(), ndx.GetInt(), key); } } else { assert(false && "not a state"); - Printf(TEXTCOLOR_RED "data does not represent a state for '%s'", key); + Printf(TEXTCOLOR_RED "data does not represent a state for '%s'\n", key); arc.mErrors++; } } else if (!retcode) { assert(false && "not an array"); - Printf(TEXTCOLOR_RED "array type expected for '%s'", key); + Printf(TEXTCOLOR_RED "array type expected for '%s'\n", key); arc.mErrors++; } } @@ -2028,7 +2030,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDial } else { - Printf(TEXTCOLOR_RED "integer expected for '%s'", key); + Printf(TEXTCOLOR_RED "integer expected for '%s'\n", key); arc.mErrors++; node = nullptr; } @@ -2077,7 +2079,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FString *&p } else { - Printf(TEXTCOLOR_RED "string expected for '%s'", key); + Printf(TEXTCOLOR_RED "string expected for '%s'\n", key); pstr = nullptr; arc.mErrors++; } @@ -2119,7 +2121,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FString &pstr, FString } else { - Printf(TEXTCOLOR_RED "string expected for '%s'", key); + Printf(TEXTCOLOR_RED "string expected for '%s'\n", key); pstr = ""; arc.mErrors++; } @@ -2168,7 +2170,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr } else { - Printf(TEXTCOLOR_RED "string expected for '%s'", key); + Printf(TEXTCOLOR_RED "string expected for '%s'\n", key); pstr = nullptr; arc.mErrors++; } diff --git a/src/serializer.h b/src/serializer.h index 4f0d90cec..7527eeb3c 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -64,6 +64,7 @@ public: ~FSerializer() { + mErrors = 0; // The destructor may not throw an exception so silence the error checker. Close(); } bool OpenWriter(bool pretty = true); From e9364fccb86f1d06df48a04050a65d5ab6fb0b4b Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Mon, 27 Feb 2017 12:02:46 -0500 Subject: [PATCH 03/12] - Fixed: voxels were not properly remapped after "restart" ccmd --- src/d_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_main.cpp b/src/d_main.cpp index b430c7f04..77e0edda0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2692,6 +2692,7 @@ void D_DoomMain (void) // These calls from inside V_Init2 are still necessary C_NewModeAdjust(); M_InitVideoModesMenu(); + Renderer->RemapVoxels(); D_StartTitle (); // start up intro loop setmodeneeded = false; // This may be set to true here, but isn't needed for a restart } From 4bcbd5c0117b52d0e4c767d21c3299df3621536a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 18:35:29 +0100 Subject: [PATCH 04/12] - clear WF_WEAPONBOBBING in P_FireWeapon, because otherwise the first frame of the fire animation will be drawn in the current bobbing position and not centered. --- src/p_pspr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 8b8e93f6a..47675699a 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -536,6 +536,7 @@ void P_FireWeapon (player_t *player, FState *state) return; } + player->WeaponState &= ~WF_WEAPONBOBBING; player->mo->PlayAttacking (); weapon->bAltFire = false; if (state == nullptr) @@ -572,6 +573,7 @@ void P_FireWeaponAlt (player_t *player, FState *state) return; } + player->WeaponState &= ~WF_WEAPONBOBBING; player->mo->PlayAttacking (); weapon->bAltFire = true; From f82ab889b21980e0d2c1588aca92bb047f409125 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 18:44:58 +0100 Subject: [PATCH 05/12] - added ACS strarg function which can convert a string into a string argument for ACS specials. --- src/p_acs.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index ad66627f5..4a2ca3fd9 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4367,6 +4367,7 @@ enum EACSFunctions ACSF_SetTranslation, ACSF_GetActorFloorTexture, ACSF_GetActorFloorTerrain, + ACSF_StrArg, // OpenGL stuff @@ -6087,7 +6088,8 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) break; } - + case ACSF_StrArg: + return -FName(FBehavior::StaticLookupString(args[0])); default: break; From 321c846d0123a35c6a3374eb177b47f7e8a15e8c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 19:46:27 +0100 Subject: [PATCH 06/12] - added StealthAlpha actor property for defining a minimum visibility value of a stealth monster. --- src/info.cpp | 2 ++ src/info.h | 1 + src/p_mobj.cpp | 5 +++-- src/scripting/thingdef_properties.cpp | 10 ++++++++++ 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/info.cpp b/src/info.cpp index 580abbf1a..7cac3569d 100644 --- a/src/info.cpp +++ b/src/info.cpp @@ -258,6 +258,7 @@ PClassActor::PClassActor() FastSpeed = -1.; RDFactor = 1.; SelfDamageFactor = 1.; + StealthAlpha = 0.; CameraHeight = INT_MIN; DropItems = NULL; @@ -319,6 +320,7 @@ void PClassActor::DeriveData(PClass *newclass) newa->FastSpeed = FastSpeed; newa->RDFactor = RDFactor; newa->SelfDamageFactor = SelfDamageFactor; + newa->StealthAlpha = StealthAlpha; newa->CameraHeight = CameraHeight; newa->HowlSound = HowlSound; newa->BloodType = BloodType; diff --git a/src/info.h b/src/info.h index a9f79182f..6d6329f88 100644 --- a/src/info.h +++ b/src/info.h @@ -301,6 +301,7 @@ public: double RDFactor; // Radius damage factor double SelfDamageFactor; double CameraHeight; // Height of camera when used as such + double StealthAlpha; // Minmum alpha for MF_STEALTH. FSoundID HowlSound; // Sound being played when electrocuted or poisoned FName BloodType; // Blood replacement type FName BloodType2; // Bloopsplatter replacement type diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index f85f2c9eb..d218d24de 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -322,6 +322,7 @@ DEFINE_FIELD(PClassActor, WoundHealth) DEFINE_FIELD(PClassActor, FastSpeed) DEFINE_FIELD(PClassActor, RDFactor) DEFINE_FIELD(PClassActor, SelfDamageFactor) +DEFINE_FIELD(PClassActor, StealthAlpha) DEFINE_FIELD(PClassActor, CameraHeight) DEFINE_FIELD(PClassActor, HowlSound) DEFINE_FIELD(PClassActor, BloodType) @@ -4100,9 +4101,9 @@ void AActor::Tick () else if (visdir < 0) { Alpha -= 1.5/TICRATE; - if (Alpha < 0) + if (Alpha < GetClass()->StealthAlpha) { - Alpha = 0; + Alpha = GetClass()->StealthAlpha; visdir = 0; } } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index 6537e2482..cf70b19ae 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -1440,6 +1440,16 @@ DEFINE_PROPERTY(selfdamagefactor, F, Actor) static_cast(info)->SelfDamageFactor = i; } +//========================================================================== +// +//========================================================================== +DEFINE_PROPERTY(stealthalpha, F, Actor) +{ + PROP_DOUBLE_PARM(i, 0); + assert(info->IsKindOf(RUNTIME_CLASS(PClassActor))); + static_cast(info)->StealthAlpha = i; +} + //========================================================================== // //========================================================================== From ac4074a69a685810bfba58e76c8a76effd4d2149 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 19:51:37 +0100 Subject: [PATCH 07/12] - allow sprites and particles simultaneously for puffs. --- src/p_mobj.cpp | 2 +- wadsrc/static/menudef.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index d218d24de..88bb1d40a 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6009,7 +6009,7 @@ AActor *P_SpawnPuff (AActor *source, PClassActor *pufftype, const DVector3 &pos1 if (cl_pufftype && updown != 3 && (puff->flags4 & MF4_ALLOWPARTICLES)) { P_DrawSplash2 (32, pos, particledir, updown, 1); - puff->renderflags |= RF_INVISIBLE; + if (cl_pufftype == 1) puff->renderflags |= RF_INVISIBLE; } if ((flags & PF_HITTHING) && puff->SeeSound) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 954567d0f..b66b381ba 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -638,6 +638,7 @@ OptionValue PuffTypes { 0.0, "$OPTVAL_SPRITES" 1.0, "$OPTVAL_PARTICLES" + 2.0, "$OPTVAL_SPRITESPARTICLES" } OptionValue Wipes From e511f7f84b96963557947e99325523ef8bf56548 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 20:07:21 +0100 Subject: [PATCH 08/12] - added a damage type parameter to MDK CCMD. --- src/d_net.cpp | 13 +++++++++---- src/d_protocol.h | 3 ++- src/m_cheat.cpp | 21 +++++++++++++++++++-- src/m_cheat.h | 1 + src/version.h | 2 +- 5 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 10ff7d0fc..6ba77bc2a 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2380,6 +2380,11 @@ void Net_DoCommand (int type, BYTE **stream, int player) SprayDecal(players[player].mo, s); break; + case DEM_MDK: + s = ReadString(stream); + cht_DoMDK(&players[player], s); + break; + case DEM_PAUSE: if (gamestate == GS_LEVEL) { @@ -2666,13 +2671,12 @@ void Net_DoCommand (int type, BYTE **stream, int player) case DEM_NETEVENT: { - const char *ename = ReadString(stream); + s = ReadString(stream); int argn = ReadByte(stream); int arg[3] = { 0, 0, 0 }; for (int i = 0; i < 3; i++) arg[i] = ReadLong(stream); - E_Console(player, ename, arg[0], arg[1], arg[2]); - delete[] ename; + E_Console(player, s, arg[0], arg[1], arg[2]); } break; @@ -2723,7 +2727,7 @@ void Net_SkipCommand (int type, BYTE **stream) break; case DEM_NETEVENT: - skip = strlen((char *)(*stream)) + 13; + skip = strlen((char *)(*stream)) + 14; break; case DEM_SUMMON2: @@ -2747,6 +2751,7 @@ void Net_SkipCommand (int type, BYTE **stream) case DEM_SPRAY: case DEM_MORPHEX: case DEM_KILLCLASSCHEAT: + case DEM_MDK: skip = strlen ((char *)(*stream)) + 1; break; diff --git a/src/d_protocol.h b/src/d_protocol.h index 27af1dae2..f95e3fc81 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -159,7 +159,8 @@ enum EDemoCommand DEM_SETSLOTPNUM, // 67 Byte: player number, the rest is the same as DEM_SETSLOT DEM_REMOVE, // 68 DEM_FINISHGAME, // 69 - DEM_NETEVENT // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int + DEM_NETEVENT, // 70 String: Event name, Byte: Arg count; each arg is a 4-byte int + DEM_MDK // 71 String: Damage type }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index c78ab5dde..652385df2 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -55,6 +55,22 @@ // writes some bytes to the network data stream, and the network code // later calls us. +void cht_DoMDK(player_t *player, const char *mod) +{ + if (player->mo == NULL) + { + Printf("What do you want to kill outside of a game?\n"); + } + else if (!deathmatch) + { + // Don't allow this in deathmatch even with cheats enabled, because it's + // a very very cheap kill. + P_LineAttack(player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE, + P_AimLineAttack(player->mo, player->mo->Angles.Yaw, PLAYERMISSILERANGE), TELEFRAG_DAMAGE, + mod, NAME_BulletPuff); + } +} + void cht_DoCheat (player_t *player, int cheat) { static const char * const BeholdPowers[9] = @@ -671,6 +687,7 @@ CCMD (mdk) if (CheckCheatmode ()) return; - Net_WriteByte (DEM_GENERICCHEAT); - Net_WriteByte (CHT_MDK); + const char *name = argv.argc() > 1 ? argv[1] : ""; + Net_WriteByte (DEM_MDK); + Net_WriteString(name); } diff --git a/src/m_cheat.h b/src/m_cheat.h index baab5a451..729c3bff6 100644 --- a/src/m_cheat.h +++ b/src/m_cheat.h @@ -31,6 +31,7 @@ class player_t; class PClassActor; +void cht_DoMDK(player_t *player, const char *mod); void cht_DoCheat (player_t *player, int cheat); void cht_Give (player_t *player, const char *item, int amount=1); void cht_Take (player_t *player, const char *item, int amount=1); diff --git a/src/version.h b/src/version.h index a03c6a21e..d0910f8b4 100644 --- a/src/version.h +++ b/src/version.h @@ -57,7 +57,7 @@ const char *GetVersionString(); // Version identifier for network games. // Bump it every time you do a release unless you're certain you // didn't change anything that will affect sync. -#define NETGAMEVERSION 232 +#define NETGAMEVERSION 233 // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to From 1ff401649845990fd154007b459839b907ea4157 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 20:42:12 +0100 Subject: [PATCH 09/12] - added ACS math functions floor, ceil and round. --- src/p_acs.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4a2ca3fd9..baf15c110 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4368,6 +4368,9 @@ enum EACSFunctions ACSF_GetActorFloorTexture, ACSF_GetActorFloorTerrain, ACSF_StrArg, + ACSF_Floor, + ACSF_Ceil, + ACSF_Round, // OpenGL stuff @@ -6091,6 +6094,15 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) case ACSF_StrArg: return -FName(FBehavior::StaticLookupString(args[0])); + case ACSF_Floor: + return args[0] & ~0xffff; + + case ACSF_Ceil: + return (args[0] & ~0xffff) + 0x10000; + + case ACSF_Round: + return (args[0] + 32768) & ~0xffff; + default: break; } From d5d383ee93326c160a3a3f0d7454b5247f936375 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 21:31:59 +0100 Subject: [PATCH 10/12] - added Floor_Stop and Ceiling_Stop action specials. --- src/actionspecials.h | 2 ++ src/p_ceiling.cpp | 15 +++++++++++++++ src/p_floor.cpp | 15 +++++++++++++++ src/p_lnspec.cpp | 16 ++++++++++++++++ src/p_spec.h | 2 ++ 5 files changed, 50 insertions(+) diff --git a/src/actionspecials.h b/src/actionspecials.h index 233bb8958..173a07b2d 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -260,5 +260,7 @@ DEFINE_SPECIAL(Stairs_BuildUpDoomSync, 271, 4, 4, 4) DEFINE_SPECIAL(Stairs_BuildDownDoomSync, 272, 4, 4, 4) DEFINE_SPECIAL(Stairs_BuildUpDoomCrush, 273, 5, 5, 5) DEFINE_SPECIAL(Door_AnimatedClose, 274, 4, 4, 4) +DEFINE_SPECIAL(Floor_Stop, 275, 1, 1, 1) +DEFINE_SPECIAL(Ceiling_Stop, 276, 1, 1, 1) #undef DEFINE_SPECIAL diff --git a/src/p_ceiling.cpp b/src/p_ceiling.cpp index 7bf1f9099..b978fd0d3 100644 --- a/src/p_ceiling.cpp +++ b/src/p_ceiling.cpp @@ -582,3 +582,18 @@ bool EV_CeilingCrushStop (int tag, bool remove) return rtn; } + +bool EV_StopCeiling(int tag) +{ + FSectorTagIterator it(tag); + while (int sec = it.Next()) + { + if (level.sectors[sec].ceilingdata) + { + SN_StopSequence(&level.sectors[sec], CHAN_CEILING); + level.sectors[sec].ceilingdata->Destroy(); + level.sectors[sec].ceilingdata = nullptr; + } + } + return true; +} diff --git a/src/p_floor.cpp b/src/p_floor.cpp index 2fd205a9d..1bd0c53fc 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -561,6 +561,21 @@ bool EV_FloorCrushStop (int tag) return true; } +// same as above but stops any floor mover that was active on the given sector. +bool EV_StopFloor(int tag) +{ + FSectorTagIterator it(tag); + while (int sec = it.Next()) + { + if (level.sectors[sec].floordata) + { + SN_StopSequence(&level.sectors[sec], CHAN_FLOOR); + level.sectors[sec].floordata->Destroy(); + level.sectors[sec].floordata = nullptr; + } + } + return true; +} //========================================================================== // // BUILD A STAIRCASE! diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index ee70dcee5..ff72b3baa 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -563,6 +563,13 @@ FUNC(LS_Generic_Floor) } +FUNC(LS_Floor_Stop) +// Floor_Stop (tag) +{ + return EV_StopFloor(arg0); +} + + FUNC(LS_Stairs_BuildDown) // Stair_BuildDown (tag, speed, height, delay, reset) { @@ -860,6 +867,13 @@ FUNC(LS_Ceiling_LowerByTexture) return EV_DoCeiling (DCeiling::ceilLowerByTexture, ln, arg0, SPEED(arg1), 0, 0, CRUSH(arg3), 0, CHANGE(arg4)); } +FUNC(LS_Ceiling_Stop) +// Ceiling_Stop (tag) +{ + return EV_StopCeiling(arg0); +} + + FUNC(LS_Generic_Ceiling) // Generic_Ceiling (tag, speed, height, target, change/model/direct/crush) { @@ -3614,6 +3628,8 @@ static lnSpecFunc LineSpecials[] = /* 272 */ LS_Stairs_BuildDownDoomSync, /* 273 */ LS_Stairs_BuildUpDoomCrush, /* 274 */ LS_Door_AnimatedClose, + /* 275 */ LS_Floor_Stop, + /* 276 */ LS_Ceiling_Stop, }; diff --git a/src/p_spec.h b/src/p_spec.h index b00e5cacf..930ae5143 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -451,6 +451,7 @@ bool P_CreateCeiling(sector_t *sec, DCeiling::ECeiling type, line_t *line, int t bool EV_DoCeiling (DCeiling::ECeiling type, line_t *line, int tag, double speed, double speed2, double height, int crush, int silent, int change, DCeiling::ECrushMode hexencrush = DCeiling::ECrushMode::crushDoom); bool EV_CeilingCrushStop (int tag, bool remove); +bool EV_StopCeiling(int tag); void P_ActivateInStasisCeiling (int tag); @@ -564,6 +565,7 @@ bool EV_DoFloor(DFloor::EFloor floortype, line_t *line, int tag, double speed, double height, int crush, int change, bool hexencrush, bool hereticlower = false); bool EV_FloorCrushStop (int tag); +bool EV_StopFloor(int tag); bool EV_DoDonut (int tag, line_t *line, double pillarspeed, double slimespeed); class DElevator : public DMover From 3700dea3361361999d6b4102a0551faa42783c53 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 27 Feb 2017 22:05:20 +0100 Subject: [PATCH 11/12] Revert "- the UDMF health key for actors was not correctly implemented. This addresses the problem by adding a second one and documenting 'Health' as implemented." This reverts commit e4e023e59a516aa8d74b7db02b27dbe6c45fa542. (This was nonsense.) --- specs/udmf_zdoom.txt | 4 ++-- src/dobjtype.cpp | 14 ++++++++++++-- src/dobjtype.h | 5 ++++- src/namedef.h | 1 - src/p_udmf.cpp | 16 ---------------- 5 files changed, 18 insertions(+), 22 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 553c75360..f4af55f2d 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -263,8 +263,8 @@ Note: All fields default to false unless mentioned otherwise. gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, // negative values are used as their absolute. Default = 1.0. - health = ; // Set per-actor health as an absolute value. Default = actor default. - healthfactor = ; // Set per-actor health as a factor to the original. Default = 1. + health = ; // Set per-actor health. Positive values are multiplied with the class's property, + // negative values are used as their absolute. Default = 1. renderstyle = ; // Set per-actor render style, overriding the class default. Possible values can be "normal", // "none", "add" or "additive", "subtract" or "subtractive", "stencil", "translucentstencil", diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 75193b868..97d154a3b 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3160,7 +3160,6 @@ void PClass::InitializeDefaults() optr->ObjNext = nullptr; optr->SetClass(this); - // Copy the defaults from the parent but leave the DObject part alone because it contains important data. if (ParentClass->Defaults != nullptr) { @@ -3174,6 +3173,13 @@ void PClass::InitializeDefaults() { memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject)); } + + if (MetaSize != 0) + { + Meta = (BYTE*)ClassDataAllocator.Alloc(MetaSize); + memset(Meta, 0, MetaSize); + if (ParentClass->MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize); + } } if (bRuntimeClass) @@ -3183,10 +3189,14 @@ void PClass::InitializeDefaults() if (Defaults != nullptr) ParentClass->InitializeSpecials(Defaults, ParentClass->Defaults); for (const PField *field : Fields) { - if (!(field->Flags & VARF_Native)) + if (!(field->Flags & VARF_Native) && !(field->Flags & VARF_Meta)) { field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits); } + if (!(field->Flags & VARF_Native) && (field->Flags & VARF_Meta)) + { + field->Type->SetDefaultValue(Meta, unsigned(field->Offset), &MetaInits); + } } } } diff --git a/src/dobjtype.h b/src/dobjtype.h index 0151e6c11..24951c9d8 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -560,8 +560,9 @@ class PClass : public PNativeStruct protected: // We unravel _WITH_META here just as we did for PType. TArray SpecialInits; + TArray MetaInits; void Derive(PClass *newclass, FName name); - void InitializeSpecials(void *addr, void *defaults) const; + void InitializeSpecials(void *addr, void *defaults, TArray* PClass::*Inits); void SetSuper(); public: void WriteValue(FSerializer &ar, const char *key,const void *addr) const override; @@ -582,6 +583,8 @@ public: const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default const size_t *ArrayPointers; // dynamic arrays containing object pointers. BYTE *Defaults; + BYTE *Meta; // Per-class static script data + unsigned MetaSize; bool bRuntimeClass; // class was defined at run-time, not compile-time bool bExported; // This type has been declared in a script bool bDecorateClass; // may be subject to some idiosyncracies due to DECORATE backwards compatibility diff --git a/src/namedef.h b/src/namedef.h index 28de56818..bb42fc76d 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -46,7 +46,6 @@ xx(Shadow) xx(Subtract) xx(Subtractive) xx(FillColor) -xx(HealthFactor) // Healingradius types xx(Mana) diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index b9300f654..27293b918 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -515,7 +515,6 @@ public: FString arg0str, arg1str; memset(th, 0, sizeof(*th)); - double healthfactor = 1; th->Gravity = 1; th->RenderStyle = STYLE_Count; th->Alpha = -1; @@ -739,52 +738,38 @@ public: break; case NAME_Alpha: - CHECK_N(Zd | Zdt) th->Alpha = CheckFloat(key); break; case NAME_FillColor: - CHECK_N(Zd | Zdt) th->fillcolor = CheckInt(key); break; case NAME_Health: - CHECK_N(Zd | Zdt) th->health = CheckInt(key); break; - case NAME_HealthFactor: - CHECK_N(Zd | Zdt) - healthfactor = CheckFloat(key); - break; - case NAME_Score: - CHECK_N(Zd | Zdt) th->score = CheckInt(key); break; case NAME_Pitch: - CHECK_N(Zd | Zdt) th->pitch = (short)CheckInt(key); break; case NAME_Roll: - CHECK_N(Zd | Zdt) th->roll = (short)CheckInt(key); break; case NAME_ScaleX: - CHECK_N(Zd | Zdt) th->Scale.X = CheckFloat(key); break; case NAME_ScaleY: - CHECK_N(Zd | Zdt) th->Scale.Y = CheckFloat(key); break; case NAME_Scale: - CHECK_N(Zd | Zdt) th->Scale.X = th->Scale.Y = CheckFloat(key); break; @@ -808,7 +793,6 @@ public: { th->args[1] = -FName(arg1str); } - th->health = int(th->health * healthfactor); // Thing specials are only valid in namespaces with Hexen-type specials // and in ZDoomTranslated - which will use the translator on them. if (namespc == NAME_ZDoomTranslated) From 4a87a598fb0926ff36d4740879af859f78a91b56 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 28 Feb 2017 00:59:09 +0100 Subject: [PATCH 12/12] - do floatification of the UDMF Health property as it should have been. --- specs/udmf_zdoom.txt | 2 +- src/dobjtype.cpp | 14 ++------------ src/dobjtype.h | 5 +---- src/doomdata.h | 2 +- src/p_mobj.cpp | 10 +++++----- src/p_setup.cpp | 4 ++-- src/p_udmf.cpp | 4 ++-- 7 files changed, 14 insertions(+), 27 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index f4af55f2d..eeb3c2a56 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -263,7 +263,7 @@ Note: All fields default to false unless mentioned otherwise. gravity = ; // Set per-actor gravity. Positive values are multiplied with the class's property, // negative values are used as their absolute. Default = 1.0. - health = ; // Set per-actor health. Positive values are multiplied with the class's property, + health = ; // Set per-actor health. Positive values are multiplied with the class's property, // negative values are used as their absolute. Default = 1. renderstyle = ; // Set per-actor render style, overriding the class default. Possible values can be "normal", diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 97d154a3b..75193b868 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -3160,6 +3160,7 @@ void PClass::InitializeDefaults() optr->ObjNext = nullptr; optr->SetClass(this); + // Copy the defaults from the parent but leave the DObject part alone because it contains important data. if (ParentClass->Defaults != nullptr) { @@ -3173,13 +3174,6 @@ void PClass::InitializeDefaults() { memset(Defaults + sizeof(DObject), 0, Size - sizeof(DObject)); } - - if (MetaSize != 0) - { - Meta = (BYTE*)ClassDataAllocator.Alloc(MetaSize); - memset(Meta, 0, MetaSize); - if (ParentClass->MetaSize > 0) memcpy(Meta, ParentClass->Meta, ParentClass->MetaSize); - } } if (bRuntimeClass) @@ -3189,14 +3183,10 @@ void PClass::InitializeDefaults() if (Defaults != nullptr) ParentClass->InitializeSpecials(Defaults, ParentClass->Defaults); for (const PField *field : Fields) { - if (!(field->Flags & VARF_Native) && !(field->Flags & VARF_Meta)) + if (!(field->Flags & VARF_Native)) { field->Type->SetDefaultValue(Defaults, unsigned(field->Offset), &SpecialInits); } - if (!(field->Flags & VARF_Native) && (field->Flags & VARF_Meta)) - { - field->Type->SetDefaultValue(Meta, unsigned(field->Offset), &MetaInits); - } } } } diff --git a/src/dobjtype.h b/src/dobjtype.h index 24951c9d8..0151e6c11 100644 --- a/src/dobjtype.h +++ b/src/dobjtype.h @@ -560,9 +560,8 @@ class PClass : public PNativeStruct protected: // We unravel _WITH_META here just as we did for PType. TArray SpecialInits; - TArray MetaInits; void Derive(PClass *newclass, FName name); - void InitializeSpecials(void *addr, void *defaults, TArray* PClass::*Inits); + void InitializeSpecials(void *addr, void *defaults) const; void SetSuper(); public: void WriteValue(FSerializer &ar, const char *key,const void *addr) const override; @@ -583,8 +582,6 @@ public: const size_t *FlatPointers; // object pointers defined by this class and all its superclasses; not initialized by default const size_t *ArrayPointers; // dynamic arrays containing object pointers. BYTE *Defaults; - BYTE *Meta; // Per-class static script data - unsigned MetaSize; bool bRuntimeClass; // class was defined at run-time, not compile-time bool bExported; // This type has been declared in a script bool bDecorateClass; // may be subject to some idiosyncracies due to DECORATE backwards compatibility diff --git a/src/doomdata.h b/src/doomdata.h index eca7dcd4a..39f0d184a 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -359,7 +359,7 @@ struct FMapThing double Alpha; DWORD fillcolor; DVector2 Scale; - int health; + double Health; int score; short pitch; short roll; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 88bb1d40a..f38ac12bb 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5930,13 +5930,13 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj->LevelSpawned (); } - if (mthing->health > 0) - mobj->health *= mthing->health; + if (mthing->Health > 0) + mobj->health = int(mobj->health * mthing->Health); else - mobj->health = -mthing->health; - if (mthing->health == 0) + mobj->health = -int(mthing->Health); + if (mthing->Health == 0) mobj->CallDie(NULL, NULL); - else if (mthing->health != 1) + else if (mthing->Health != 1) mobj->StartHealth = mobj->health; return mobj; diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 308054a8b..76e8b6b34 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1741,7 +1741,7 @@ void P_LoadThings (MapData * map) mti[i].ClassFilter = 0xffff; // Doom map format doesn't have class flags so spawn for all player classes mti[i].RenderStyle = STYLE_Count; mti[i].Alpha = -1; - mti[i].health = 1; + mti[i].Health = 1; mti[i].FloatbobPhase = -1; mti[i].pos.X = LittleShort(mt->x); @@ -1837,7 +1837,7 @@ void P_LoadThings2 (MapData * map) mti[i].Gravity = 1; mti[i].RenderStyle = STYLE_Count; mti[i].Alpha = -1; - mti[i].health = 1; + mti[i].Health = 1; mti[i].FloatbobPhase = -1; } delete[] mtp; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 27293b918..4d5e00e48 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -518,7 +518,7 @@ public: th->Gravity = 1; th->RenderStyle = STYLE_Count; th->Alpha = -1; - th->health = 1; + th->Health = 1; th->FloatbobPhase = -1; sc.MustGetToken('{'); while (!sc.CheckToken('}')) @@ -746,7 +746,7 @@ public: break; case NAME_Health: - th->health = CheckInt(key); + th->Health = CheckFloat(key); break; case NAME_Score: