From 68246051548602182df480cc280384246b5b2b07 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 00:06:18 +0200 Subject: [PATCH 01/29] - added pickup sprite and editor number for Heretic's gold wand. --- wadsrc/static/actors/heretic/hereticweaps.txt | 6 +++++- wadsrc/static/language.enu | 1 + wadsrc/static/sprites/GWANA0.png | Bin 0 -> 315 bytes 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 wadsrc/static/sprites/GWANA0.png diff --git a/wadsrc/static/actors/heretic/hereticweaps.txt b/wadsrc/static/actors/heretic/hereticweaps.txt index 972fba5fb..ca85437e0 100644 --- a/wadsrc/static/actors/heretic/hereticweaps.txt +++ b/wadsrc/static/actors/heretic/hereticweaps.txt @@ -110,7 +110,7 @@ ACTOR StaffPuff2 // Gold wand ---------------------------------------------------------------- -ACTOR GoldWand : HereticWeapon +ACTOR GoldWand : HereticWeapon 9042 { Game Heretic +BLOODSPLATTER @@ -120,6 +120,7 @@ ACTOR GoldWand : HereticWeapon Weapon.AmmoType "GoldWandAmmo" Weapon.SisterWeapon "GoldWandPowered" Weapon.YAdjust 5 + Inventory.PickupMessage "$TXT_WPNGOLDWAND" Obituary "$OB_MPGOLDWAND" Tag "$TAG_GOLDWAND" @@ -127,6 +128,9 @@ ACTOR GoldWand : HereticWeapon States { + Spawn: + GWAN A -1 + Stop Ready: GWND A 1 A_WeaponReady Loop diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index a92e22dfe..17b56f6f3 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1242,6 +1242,7 @@ TXT_AMMOPHOENIXROD2 = "INFERNO ORB"; // Weapons +TXT_WPNGOLDWAND = "GOLD WAND"; TXT_WPNMACE = "FIREMACE"; TXT_WPNCROSSBOW = "ETHEREAL CROSSBOW"; TXT_WPNBLASTER = "DRAGON CLAW"; diff --git a/wadsrc/static/sprites/GWANA0.png b/wadsrc/static/sprites/GWANA0.png new file mode 100644 index 0000000000000000000000000000000000000000..f887f04c65d070bff04ff7b7d19354a91daf471a GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^oItG3!3-o{y_}Q+q&U)x9Fu@FNJvdwaFREWjtcMz zaTO2{U}9oYQBiSobF;RwUYRbHnwn~EZf+>eXDiR==jT^bQ`6nuZEtTM78Yh;VBn=H z9B(Y0ZY`galXGW^Ot`+dj*d=ANlCT0dVjQWY;3HAgv6iSmcQ>-e_Wr?2DF8-B*-tA z!Qt7BG$5zi)5S5QB5v-v>s(HTJZulntlQjPyyt)Rt(Uz@NeXY-pZasH6v=wIj`#bC zCijIYoDSljvR^bvgo?~$IH9z-mqB9Pas!oy(8XriulxT_V_huC%^ Date: Fri, 24 Oct 2014 04:46:43 -0400 Subject: [PATCH 02/29] Added Inventory.AlwaysRespawn flag. --- src/g_shared/a_pickups.cpp | 2 +- src/g_shared/a_pickups.h | 1 + src/thingdef/thingdef_data.cpp | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/g_shared/a_pickups.cpp b/src/g_shared/a_pickups.cpp index a16a1316f..fc3e863a2 100644 --- a/src/g_shared/a_pickups.cpp +++ b/src/g_shared/a_pickups.cpp @@ -499,7 +499,7 @@ bool AInventory::ShouldRespawn () { if ((ItemFlags & IF_BIGPOWERUP) && !(dmflags2 & DF2_RESPAWN_SUPER)) return false; if (ItemFlags & IF_NEVERRESPAWN) return false; - return !!(dmflags & DF_ITEMS_RESPAWN); + return !!((dmflags & DF_ITEMS_RESPAWN) || (ItemFlags & IF_ALWAYSRESPAWN)); } //=========================================================================== diff --git a/src/g_shared/a_pickups.h b/src/g_shared/a_pickups.h index 72548776a..8616393e7 100644 --- a/src/g_shared/a_pickups.h +++ b/src/g_shared/a_pickups.h @@ -135,6 +135,7 @@ enum IF_NEVERRESPAWN = 1<<20, // Never, ever respawns IF_NOSCREENFLASH = 1<<21, // No pickup flash on the player's screen IF_TOSSED = 1<<22, // Was spawned by P_DropItem (i.e. as a monster drop) + IF_ALWAYSRESPAWN = 1<<23, // Always respawn, regardless of dmflag }; diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 013415cc7..5c52c45e3 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -311,6 +311,7 @@ static FFlagDef InventoryFlags[] = DEFINE_FLAG(IF, NEVERRESPAWN, AInventory, ItemFlags), DEFINE_FLAG(IF, NOSCREENFLASH, AInventory, ItemFlags), DEFINE_FLAG(IF, TOSSED, AInventory, ItemFlags), + DEFINE_FLAG(IF, ALWAYSRESPAWN, AInventory, ItemFlags), DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),}; From 9402bcf6cd654091f9ae2fdb848b04f9654d08dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 22:47:40 +0200 Subject: [PATCH 03/29] - fixed: The targeter must reset its HUD sprites when being reactivated during the blinking phase. --- src/g_shared/a_artifacts.cpp | 12 ++++++++++++ src/g_shared/a_artifacts.h | 1 + 2 files changed, 13 insertions(+) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 8891c8674..7fd15fa21 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1296,6 +1296,18 @@ void APowerTargeter::InitEffect () PositionAccuracy (); } +bool APowerTargeter::HandlePickup(AInventory *item) +{ + if (Super::HandlePickup(item)) + { + InitEffect(); // reset the HUD sprites + return true; + } + return false; +} + + + void APowerTargeter::DoEffect () { Super::DoEffect (); diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index 0efd64ab8..a216cf74c 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -173,6 +173,7 @@ protected: void EndEffect (); void PositionAccuracy (); void Travelled (); + bool HandlePickup(AInventory *item); }; class APowerFrightener : public APowerup From e662e4321ac114fc507da48075ea9e66a990419e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 22:56:10 +0200 Subject: [PATCH 04/29] - fixed: Creating an OPL MIDI device can fail if no GENMIDI lump is found, and an exception is thrown. We need to handle this exception to prevent an abort. --- src/sound/music_midistream.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 15f4caec8..5cb04ed0e 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -38,6 +38,7 @@ #include "templates.h" #include "doomdef.h" #include "m_swap.h" +#include "doomerrors.h" // MACROS ------------------------------------------------------------------ @@ -277,7 +278,16 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const return new TimidityMIDIDevice; case MDEV_OPL: - return new OPLMIDIDevice; + try + { + return new OPLMIDIDevice; + } + catch (CRecoverableError &err) + { + // The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found. + Printf("Unable to create OPL MIDI device: %s\nFalling back to FModEx playback", err.GetMessage()); + return new FMODMIDIDevice; + } case MDEV_TIMIDITY: return new TimidityPPMIDIDevice; From 15b1c712578351fa523597216fbebcdf9de682a9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 23:02:02 +0200 Subject: [PATCH 05/29] - use proper CheckCheatMode semantics for throwing players out of chasecam mode if DF2_CHASECAM gets unset. --- src/d_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 030387118..255994fb5 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -466,7 +466,7 @@ CUSTOM_CVAR (Int, dmflags2, 0, CVAR_SERVERINFO) } // Come out of chasecam mode if we're not allowed to use chasecam. - if (!(dmflags2 & DF2_CHASECAM) && !G_SkillProperty (SKILLP_DisableCheats) && !sv_cheats) + if (!(dmflags2 & DF2_CHASECAM) && CheckCheatmode(false)) { // Take us out of chasecam mode only. if (p->cheats & CF_CHASECAM) From 6f7b83faa1383be3eee2ca841c67850568093c65 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 23:12:38 +0200 Subject: [PATCH 06/29] - fixed: EV_DoFloor was a bit too selective about which movement types were allowed to crush. Changed so that the crush parameter is always used. Also changed all non-crushing calls to explicitly pass -1 as crush damage instead of relying on EV_DoFloor to ignore the passed value. --- src/g_strife/a_alienspectres.cpp | 4 ++-- src/g_strife/a_crusader.cpp | 2 +- src/g_strife/a_strifestuff.cpp | 2 +- src/p_enemy.cpp | 8 +++---- src/p_floor.cpp | 4 +--- src/p_lnspec.cpp | 36 ++++++++++++++++---------------- 6 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/g_strife/a_alienspectres.cpp b/src/g_strife/a_alienspectres.cpp index 4626891bb..2b9f499e9 100644 --- a/src/g_strife/a_alienspectres.cpp +++ b/src/g_strife/a_alienspectres.cpp @@ -106,7 +106,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) switch (self->GetClass()->TypeName) { case NAME_AlienSpectre1: - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 999, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 999, FRACUNIT, 0, -1, 0, false); log = 95; break; @@ -180,7 +180,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_AlienSpectreDeath) { // Another Sigil piece. Woohoo! log = 83; } - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, -1, 0, false); break; default: diff --git a/src/g_strife/a_crusader.cpp b/src/g_strife/a_crusader.cpp index 6d34182f4..7ef0b24a1 100644 --- a/src/g_strife/a_crusader.cpp +++ b/src/g_strife/a_crusader.cpp @@ -80,6 +80,6 @@ DEFINE_ACTION_FUNCTION(AActor, A_CrusaderDeath) { if (CheckBossDeath (self)) { - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 667, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 667, FRACUNIT, 0, -1, 0, false); } } diff --git a/src/g_strife/a_strifestuff.cpp b/src/g_strife/a_strifestuff.cpp index d51b618b7..95b0030a0 100644 --- a/src/g_strife/a_strifestuff.cpp +++ b/src/g_strife/a_strifestuff.cpp @@ -548,7 +548,7 @@ void APowerCoupling::Die (AActor *source, AActor *inflictor, int dmgflags) P_NoiseAlert (source, this); } EV_DoDoor (DDoor::doorClose, NULL, players[i].mo, 225, 2*FRACUNIT, 0, 0, 0); - EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToHighest, NULL, 44, FRACUNIT, 0, -1, 0, false); players[i].mo->GiveInventoryType (QuestItemClasses[5]); S_Sound (CHAN_VOICE, "svox/voc13", 1, ATTN_NORM); players[i].SetLogNumber (13); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 00e2a3dc2..20b61200f 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -3275,13 +3275,13 @@ DEFINE_ACTION_FUNCTION(AActor, A_BossDeath) { if (type == NAME_Fatso) { - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, -1, 0, false); return; } if (type == NAME_Arachnotron) { - EV_DoFloor (DFloor::floorRaiseByTexture, NULL, 667, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorRaiseByTexture, NULL, 667, FRACUNIT, 0, -1, 0, false); return; } } @@ -3290,11 +3290,11 @@ DEFINE_ACTION_FUNCTION(AActor, A_BossDeath) switch (level.flags & LEVEL_SPECACTIONSMASK) { case LEVEL_SPECLOWERFLOOR: - EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToLowest, NULL, 666, FRACUNIT, 0, -1, 0, false); return; case LEVEL_SPECLOWERFLOORTOHIGHEST: - EV_DoFloor (DFloor::floorLowerToHighest, NULL, 666, FRACUNIT, 0, 0, 0, false); + EV_DoFloor (DFloor::floorLowerToHighest, NULL, 666, FRACUNIT, 0, -1, 0, false); return; case LEVEL_SPECOPENDOOR: diff --git a/src/p_floor.cpp b/src/p_floor.cpp index f63087619..9a5a6eaf8 100644 --- a/src/p_floor.cpp +++ b/src/p_floor.cpp @@ -320,7 +320,7 @@ manual_floor: rtn = true; floor = new DFloor (sec); floor->m_Type = floortype; - floor->m_Crush = -1; + floor->m_Crush = crush; floor->m_Hexencrush = hexencrush; floor->m_Speed = speed; floor->m_ResetCount = 0; // [RH] @@ -374,7 +374,6 @@ manual_floor: break; case DFloor::floorRaiseAndCrushDoom: - floor->m_Crush = crush; case DFloor::floorRaiseToLowestCeiling: floor->m_Direction = 1; newheight = sec->FindLowestCeilingSurrounding (&spot); @@ -406,7 +405,6 @@ manual_floor: break; case DFloor::floorRaiseAndCrush: - floor->m_Crush = crush; floor->m_Direction = 1; newheight = sec->FindLowestCeilingPoint (&spot) - 8*FRACUNIT; floor->m_FloorDestDist = sec->floorplane.PointToDist (spot, newheight); diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 14bcd430c..0d74b4d42 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -281,43 +281,43 @@ FUNC(LS_Generic_Door) FUNC(LS_Floor_LowerByValue) // Floor_LowerByValue (tag, speed, height) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, 0, false); } FUNC(LS_Floor_LowerToLowest) // Floor_LowerToLowest (tag, speed) { - return EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_LowerToHighest) // Floor_LowerToHighest (tag, speed, adjust, hereticlower) { - return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, 0, 0, false, arg3==1); + return EV_DoFloor (DFloor::floorLowerToHighest, ln, arg0, SPEED(arg1), (arg2-128)*FRACUNIT, -1, 0, false, arg3==1); } FUNC(LS_Floor_LowerToNearest) // Floor_LowerToNearest (tag, speed) { - return EV_DoFloor (DFloor::floorLowerToNearest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerToNearest, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_RaiseByValue) // Floor_RaiseByValue (tag, speed, height) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2, -1, 0, false); } FUNC(LS_Floor_RaiseToHighest) // Floor_RaiseToHighest (tag, speed) { - return EV_DoFloor (DFloor::floorRaiseToHighest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseToHighest, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_RaiseToNearest) // Floor_RaiseToNearest (tag, speed) { - return EV_DoFloor (DFloor::floorRaiseToNearest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseToNearest, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_RaiseAndCrush) @@ -335,13 +335,13 @@ FUNC(LS_Floor_RaiseAndCrushDoom) FUNC(LS_Floor_RaiseByValueTimes8) // FLoor_RaiseByValueTimes8 (tag, speed, height) { - return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, 0, false); } FUNC(LS_Floor_LowerByValueTimes8) // Floor_LowerByValueTimes8 (tag, speed, height) { - return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerByValue, ln, arg0, SPEED(arg1), FRACUNIT*arg2*8, -1, 0, false); } FUNC(LS_Floor_CrushStop) @@ -353,51 +353,51 @@ FUNC(LS_Floor_CrushStop) FUNC(LS_Floor_LowerInstant) // Floor_LowerInstant (tag, unused, height) { - return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0, arg2*FRACUNIT*8, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, 0, false); } FUNC(LS_Floor_RaiseInstant) // Floor_RaiseInstant (tag, unused, height) { - return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0, arg2*FRACUNIT*8, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseInstant, ln, arg0, 0, arg2*FRACUNIT*8, -1, 0, false); } FUNC(LS_Floor_MoveToValueTimes8) // Floor_MoveToValueTimes8 (tag, speed, height, negative) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*8*(arg3?-1:1), 0, 0, false); + arg2*FRACUNIT*8*(arg3?-1:1), -1, 0, false); } FUNC(LS_Floor_MoveToValue) // Floor_MoveToValue (tag, speed, height, negative) { return EV_DoFloor (DFloor::floorMoveToValue, ln, arg0, SPEED(arg1), - arg2*FRACUNIT*(arg3?-1:1), 0, 0, false); + arg2*FRACUNIT*(arg3?-1:1), -1, 0, false); } FUNC(LS_Floor_RaiseToLowestCeiling) // Floor_RaiseToLowestCeiling (tag, speed) { - return EV_DoFloor (DFloor::floorRaiseToLowestCeiling, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseToLowestCeiling, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_RaiseByTexture) // Floor_RaiseByTexture (tag, speed) { - return EV_DoFloor (DFloor::floorRaiseByTexture, ln, arg0, SPEED(arg1), 0, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseByTexture, ln, arg0, SPEED(arg1), 0, -1, 0, false); } FUNC(LS_Floor_RaiseByValueTxTy) // Floor_RaiseByValueTxTy (tag, speed, height) { - return EV_DoFloor (DFloor::floorRaiseAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, 0, false); + return EV_DoFloor (DFloor::floorRaiseAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, -1, 0, false); } FUNC(LS_Floor_LowerToLowestTxTy) // Floor_LowerToLowestTxTy (tag, speed) { - return EV_DoFloor (DFloor::floorLowerAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, 0, 0, false); + return EV_DoFloor (DFloor::floorLowerAndChange, ln, arg0, SPEED(arg1), arg2*FRACUNIT, -1, 0, false); } FUNC(LS_Floor_Waggle) @@ -1764,7 +1764,7 @@ FUNC(LS_FloorAndCeiling_LowerRaise) // more or less unintuitive value for the fourth arg to trigger Boom's broken behavior if (arg3 != 1998 || !res) // (1998 for the year in which Boom was released... :P) { - res |= EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, 0, 0, false); + res |= EV_DoFloor (DFloor::floorLowerToLowest, ln, arg0, SPEED(arg1), 0, -1, 0, false); } return res; } From e28234a8b847e2701a596caf40261a8d615e0c29 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 24 Oct 2014 23:19:57 +0200 Subject: [PATCH 07/29] - replaced pistol pickup sprite. --- wadsrc/static/sprites/pista0.png | Bin 407 -> 377 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/wadsrc/static/sprites/pista0.png b/wadsrc/static/sprites/pista0.png index b3d9cd09a5831dadb93984064d0c877f46592bbc..9e3a4a05242a9e3fb25cab0c3fcce08d02cb0797 100644 GIT binary patch delta 350 zcmV-k0iphv1Nj1wB!38JazSDM000O8000hEbPJ#W003Q3OjJbx|Nj6002dDj8yg!7 z3kxG7BPS;(H$NvYHyisOeMaiNpvD_qMu71&Ziv>1XMl2slL;|neWoY4{!@=aqU7(JZzL$< wJ7{$A$RyGtU?l6rG)?QWv}qgE5s+H)1hJ0@AUrJvGynhq07*qoM6N<$f>dLHj{pDw delta 361 zcmV-v0ha#x0+$1jB!7)iOjJbxFE2MYHzy}29~TQRFE1-24?8Ew- zcV9nOS64qT7Yi2$Q$H_TTU$RX8(&K|BO@b2GaF}9Gh<_8Z*Omli;IJ6OGigXM>8Ws zFB=yh2TL~_BP$PsgM*WklS@lWYey%`%gZk}9~Tb?r>Cc%pCq4ue}7Xy9~&DRcXxN6 zgJU-%6ZpA2p#T5?0d!JMQvg8b*k+L-7k{KlL_t(|UX{s3a>Fnb0ML(OnIQ;e?){Hf zH>-F?o4oCV#g|SW7M(NBpqTlxd4GPJh2V;+sv_r7vW+mwqy2u^G Date: Sat, 25 Oct 2014 00:01:04 +0200 Subject: [PATCH 08/29] - fixed some bad logic operations. --- src/c_cvars.cpp | 7 ++++--- src/p_interaction.cpp | 2 +- src/p_map.cpp | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index 19187353f..ce4e88632 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -500,9 +500,10 @@ UCVarValue FBaseCVar::FromString (const char *value, ECVarType type) goodv = false; break; default: - if (value[i] < '0' && value[i] > '9' && - value[i] < 'A' && value[i] > 'F' && - value[i] < 'a' && value[i] > 'f') + if (value[i] < '0' || + (value[i] > '9' && value[i] < 'A') || + (value[i] > 'F' && value[i] < 'a') || + value[i] > 'f') { goodv = false; } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 6aa1a28f6..fad7a42e5 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1672,7 +1672,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, target->health -= damage; if (target->health <= 0) { // Death - if (player->cheats & CF_BUDDHA) + if (player->cheats & CF_BUDDHA && damage < TELEFRAG_DAMAGE) { // [SP] Save the player... player->health = target->health = 1; } diff --git a/src/p_map.cpp b/src/p_map.cpp index e7c477955..3a4187c9a 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -198,7 +198,7 @@ void P_GetFloorCeilingZ(FCheckPosition &tmf, int flags) if (ff_top > tmf.floorz) { - if (ff_top <= tmf.z || (!(flags && FFCF_3DRESTRICT) && (tmf.thing != NULL && ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight))) + if (ff_top <= tmf.z || (!(flags & FFCF_3DRESTRICT) && (tmf.thing != NULL && ff_bottom < tmf.z && ff_top < tmf.z + tmf.thing->MaxStepHeight))) { tmf.dropoffz = tmf.floorz = ff_top; tmf.floorpic = *rover->top.texture; @@ -2157,7 +2157,7 @@ bool P_CheckMove(AActor *thing, fixed_t x, fixed_t y) { // too big a step up return false; } - else if ((thing->flags & MF_MISSILE) && !(thing->flags6 && MF6_STEPMISSILE) && tm.floorz > newz) + else if ((thing->flags & MF_MISSILE) && !(thing->flags6 & MF6_STEPMISSILE) && tm.floorz > newz) { // [RH] Don't let normal missiles climb steps return false; } From b6f4862024d8c9b09145731892a11d9f39aa3548 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 00:05:52 +0200 Subject: [PATCH 09/29] - fixed: A_Warp didn't initialize oldx/y/z in all situations. --- src/thingdef/thingdef_codeptr.cpp | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d17bbc75f..1fb3827db 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4348,12 +4348,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) ACTION_PARAM_INT(flags, 5); ACTION_PARAM_STATE(success_state, 6); - fixed_t - - oldx, - oldy, - oldz; - AActor *reference = COPY_AAPTR(self, destination_selector); if (!reference) @@ -4362,6 +4356,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) return; } + fixed_t oldx = self->x; + fixed_t oldy = self->y; + fixed_t oldz = self->z; + if (!(flags & WARPF_ABSOLUTEANGLE)) { angle += (flags & WARPF_USECALLERANGLE) ? self->angle : reference->angle; @@ -4371,20 +4369,16 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Warp) if (!(flags & WARPF_ABSOLUTEOFFSET)) { angle_t fineangle = angle >> ANGLETOFINESHIFT; - oldx = xofs; + fixed_t xofs1 = xofs; // (borrowed from A_SpawnItemEx, assumed workable) // in relative mode negative y values mean 'left' and positive ones mean 'right' // This is the inverse orientation of the absolute mode! - xofs = FixedMul(oldx, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); - yofs = FixedMul(oldx, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); + xofs = FixedMul(xofs1, finecosine[fineangle]) + FixedMul(yofs, finesine[fineangle]); + yofs = FixedMul(xofs1, finesine[fineangle]) - FixedMul(yofs, finecosine[fineangle]); } - oldx = self->x; - oldy = self->y; - oldz = self->z; - if (flags & WARPF_TOFLOOR) { // set correct xy From 5ac7e4fc386ed7850a18b9b9d2f1a748553ef062 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 00:30:36 +0200 Subject: [PATCH 10/29] - added HARMFRIENDS flag. --- src/actor.h | 1 + src/p_map.cpp | 31 +++++++++++++++++-------------- src/thingdef/thingdef_data.cpp | 1 + 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/actor.h b/src/actor.h index 9a3c6844a..11d1a6429 100644 --- a/src/actor.h +++ b/src/actor.h @@ -341,6 +341,7 @@ enum MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings. MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag MF7_WEAPONSPAWN = 0x00000010, // subject to DF_NO_COOP_WEAPON_SPAWN dmflag + MF7_HARMFRIENDS = 0x00000020, // is allowed to harm friendly monsters. // --- mobj.renderflags --- diff --git a/src/p_map.cpp b/src/p_map.cpp index 3a4187c9a..43b16a506 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1111,24 +1111,27 @@ bool PIT_CheckThing(AActor *thing, FCheckPosition &tm) // cases where they are clearly supposed to do that if (thing->IsFriend(tm.thing->target)) { - // Friends never harm each other - return false; + // Friends never harm each other, unless the shooter has the HARMFRIENDS set. + if (!(thing->flags7 & MF7_HARMFRIENDS)) return false; } - if (thing->TIDtoHate != 0 && thing->TIDtoHate == tm.thing->target->TIDtoHate) + else { - // [RH] Don't hurt monsters that hate the same thing as you do - return false; - } - if (thing->GetSpecies() == tm.thing->target->GetSpecies() && !(thing->flags6 & MF6_DOHARMSPECIES)) - { - // Don't hurt same species or any relative - - // but only if the target isn't one's hostile. - if (!thing->IsHostile(tm.thing->target)) + if (thing->TIDtoHate != 0 && thing->TIDtoHate == tm.thing->target->TIDtoHate) { - // Allow hurting monsters the shooter hates. - if (thing->tid == 0 || tm.thing->target->TIDtoHate != thing->tid) + // [RH] Don't hurt monsters that hate the same thing as you do + return false; + } + if (thing->GetSpecies() == tm.thing->target->GetSpecies() && !(thing->flags6 & MF6_DOHARMSPECIES)) + { + // Don't hurt same species or any relative - + // but only if the target isn't one's hostile. + if (!thing->IsHostile(tm.thing->target)) { - return false; + // Allow hurting monsters the shooter hates. + if (thing->tid == 0 || tm.thing->target->TIDtoHate != thing->tid) + { + return false; + } } } } diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 5c52c45e3..b8ee13fd5 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -241,6 +241,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF7, NOTELESTOMP, AActor, flags7), DEFINE_FLAG(MF7, ALWAYSTELEFRAG, AActor, flags7), DEFINE_FLAG(MF7, WEAPONSPAWN, AActor, flags7), + DEFINE_FLAG(MF7, HARMFRIENDS, AActor, flags7), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), From 83be901ad6f3254b1cd470ec1bf5faa7e60a36ea Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 00:52:27 +0200 Subject: [PATCH 11/29] - fixed: damage of amount TELEFRAG_DAMAGE should not be reduced by armors absorbing some damage, it'd lose its magic-ness, that is needed to ensure a guaranteed kill. The same applies to autousing health items. --- src/p_interaction.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index fad7a42e5..4a960cc17 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1218,8 +1218,13 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (!(flags & DMG_NO_ARMOR) && player->mo->Inventory != NULL) { int newdam = damage; - player->mo->Inventory->AbsorbDamage (damage, mod, newdam); - damage = newdam; + player->mo->Inventory->AbsorbDamage(damage, mod, newdam); + if (damage < TELEFRAG_DAMAGE) + { + // if we are telefragging don't let the damage value go below that magic value. Some further checks would fail otherwise. + damage = newdam; + } + if (damage <= 0) { // If MF6_FORCEPAIN is set, make the player enter the pain state. @@ -1232,7 +1237,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } } - if (damage >= player->health + if (damage >= player->health && damage < TELEFRAG_DAMAGE && && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) && !player->morphTics) { // Try to use some inventory health From aa338a4dc674128db4899942bc92e03539f8f53f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 01:00:40 +0200 Subject: [PATCH 12/29] - fixed: G_FinishTravel must synchronize the CF_FLY flag with MF2_FLY. --- src/g_level.cpp | 9 +++++++++ src/p_interaction.cpp | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index d84a48776..525f67318 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1183,6 +1183,15 @@ void G_FinishTravel () pawn->AddToHash (); pawn->SetState(pawn->SpawnState); pawn->player->SendPitchLimits(); + // Sync the FLY flags. + if (pawn->flags2 & MF2_FLY) + { + pawn->player->cheats |= CF_FLY; + } + else + { + pawn->player->cheats &= ~CF_FLY; + } for (inv = pawn->Inventory; inv != NULL; inv = inv->Inventory) { diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 4a960cc17..5e1fbd49f 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1237,7 +1237,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, } } - if (damage >= player->health && damage < TELEFRAG_DAMAGE && + if (damage >= player->health && damage < TELEFRAG_DAMAGE && (G_SkillProperty(SKILLP_AutoUseHealth) || deathmatch) && !player->morphTics) { // Try to use some inventory health From 5513966165ce6b773558fecfddf6d05dd42b4dce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 01:15:39 +0200 Subject: [PATCH 13/29] - fixed: Strife's peasants couldn't harm the player because they were defined as friendly. --- wadsrc/static/actors/strife/peasants.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/actors/strife/peasants.txt b/wadsrc/static/actors/strife/peasants.txt index e7bbdadcf..af12b75df 100644 --- a/wadsrc/static/actors/strife/peasants.txt +++ b/wadsrc/static/actors/strife/peasants.txt @@ -9,7 +9,7 @@ ACTOR Peasant : StrifeHumanoid Radius 20 Height 56 Monster - +FRIENDLY + +NEVERTARGET -COUNTKILL +NOSPLASHALERT +FLOORCLIP From 1c500cead6c06d56416f27db414f5f247869c54b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 01:27:34 +0200 Subject: [PATCH 14/29] - fixed: A_Respawn did not restore the flags6 and flags7 fields. --- src/thingdef/thingdef_codeptr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 1fb3827db..2b382f989 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2912,6 +2912,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) self->flags3 = (defs->flags3 & ~(MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS)) | (self->flags3 & (MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS)); self->flags4 = (defs->flags4 & ~MF4_NOHATEPLAYERS) | (self->flags4 & MF4_NOHATEPLAYERS); self->flags5 = defs->flags5; + self->flags6 = defs->flags6; + self->flags7 = defs->flags7; self->SetState (self->SpawnState); self->renderflags &= ~RF_INVISIBLE; From b9800693679a860477713ef06880edd8ee4d0d09 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Fri, 24 Oct 2014 19:31:28 -0500 Subject: [PATCH 15/29] - Added GOD2 and BUDDHA2 cheats. - Ensures that not even telefrag damage can kill the player. - Fixed: Players with NODAMAGE could still hurt and kill themselves via voodoo dolls. --- src/c_cmds.cpp | 18 ++++++++++++++++++ src/d_player.h | 2 ++ src/d_protocol.h | 4 +++- src/m_cheat.cpp | 17 +++++++++++++++++ src/p_interaction.cpp | 15 ++++++++------- wadsrc/static/language.enu | 4 ++++ 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index 89005dbc7..3dd97434e 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -124,6 +124,15 @@ CCMD (god) Net_WriteByte (CHT_GOD); } +CCMD(god2) +{ + if (CheckCheatmode()) + return; + + Net_WriteByte(DEM_GENERICCHEAT); + Net_WriteByte(CHT_GOD2); +} + CCMD (iddqd) { if (CheckCheatmode ()) @@ -142,6 +151,15 @@ CCMD (buddha) Net_WriteByte(CHT_BUDDHA); } +CCMD(buddha2) +{ + if (CheckCheatmode()) + return; + + Net_WriteByte(DEM_GENERICCHEAT); + Net_WriteByte(CHT_BUDDHA2); +} + CCMD (notarget) { if (CheckCheatmode ()) diff --git a/src/d_player.h b/src/d_player.h index ceb1ff894..e5644e8cb 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -205,6 +205,8 @@ typedef enum CF_DOUBLEFIRINGSPEED= 1 << 21, // Player owns a double firing speed artifact CF_EXTREMELYDEAD = 1 << 22, // [RH] Reliably let the status bar know about extreme deaths. CF_INFINITEAMMO = 1 << 23, // Player owns an infinite ammo artifact + CF_BUDDHA2 = 1 << 24, // [MC] Absolute buddha. No voodoo can kill it either. + CF_GODMODE2 = 1 << 25, // [MC] Absolute godmode. No voodoo can kill it either. CF_BUDDHA = 1 << 27, // [SP] Buddha mode - take damage, but don't die CF_NOCLIP2 = 1 << 30, // [RH] More Quake-like noclip } cheat_t; diff --git a/src/d_protocol.h b/src/d_protocol.h index 0d11c7760..da54d3f2b 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -219,7 +219,9 @@ enum ECheatCommand CHT_GIMMIEJ, CHT_GIMMIEZ, CHT_BUDDHA, - CHT_NOCLIP2 + CHT_NOCLIP2, + CHT_BUDDHA2, + CHT_GOD2 }; void StartChunk (int id, BYTE **stream); diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index 5d9d48bea..ac4eb140d 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -99,6 +99,23 @@ void cht_DoCheat (player_t *player, int cheat) msg = GStrings("TXT_BUDDHAOFF"); break; + case CHT_GOD2: + player->cheats ^= CF_GODMODE2; + if (player->cheats & CF_GODMODE2) + msg = GStrings("STSTR_DQD2ON"); + else + msg = GStrings("STSTR_DQD2OFF"); + ST_SetNeedRefresh(); + break; + + case CHT_BUDDHA2: + player->cheats ^= CF_BUDDHA2; + if (player->cheats & CF_BUDDHA2) + msg = GStrings("TXT_BUDDHA2ON"); + else + msg = GStrings("TXT_BUDDHA2OFF"); + break; + case CHT_NOCLIP: player->cheats ^= CF_NOCLIP; if (player->cheats & CF_NOCLIP) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 5e1fbd49f..5ce20f598 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -938,7 +938,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, FState * woundstate = NULL; PainChanceList * pc = NULL; bool justhit = false; - + if (target == NULL || !((target->flags & MF_SHOOTABLE) || (target->flags6 & MF6_VULNERABLE))) { // Shouldn't happen return -1; @@ -1209,8 +1209,10 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (!(flags & DMG_FORCED)) { // check the real player, not a voodoo doll here for invulnerability effects - if (damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) || - (player->cheats & CF_GODMODE))) + if ((damage < TELEFRAG_DAMAGE && ((player->mo->flags2 & MF2_INVULNERABLE) || + (player->cheats & CF_GODMODE))) || + (player->cheats & CF_GODMODE2) || (player->mo->flags5 & MF5_NODAMAGE)) + //Absolutely no hurting if NODAMAGE is involved. Same for GODMODE2. { // player is invulnerable, so don't hurt him return -1; } @@ -1259,9 +1261,8 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // This does not save the player if damage >= TELEFRAG_DAMAGE, still need to // telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor, // but telefragging should still do enough damage to kill the player) - if ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE - // Ignore players that are already dead. - && player->playerstate != PST_DEAD) + // Ignore players that are already dead. + if ((player->cheats & CF_BUDDHA2) || ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE) && player->playerstate != PST_DEAD) { // If this is a voodoo doll we need to handle the real player as well. player->mo->health = target->health = player->health = 1; @@ -1677,7 +1678,7 @@ void P_PoisonDamage (player_t *player, AActor *source, int damage, target->health -= damage; if (target->health <= 0) { // Death - if (player->cheats & CF_BUDDHA && damage < TELEFRAG_DAMAGE) + if ((player->cheats & CF_BUDDHA && damage < TELEFRAG_DAMAGE) || (player->cheats & CF_BUDDHA2)) { // [SP] Save the player... player->health = target->health = 1; } diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 17b56f6f3..a01a03559 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -292,6 +292,8 @@ STSTR_MUS = "Music Change"; STSTR_NOMUS = "IMPOSSIBLE SELECTION"; STSTR_DQDON = "Degreelessness Mode ON"; STSTR_DQDOFF = "Degreelessness Mode OFF"; +STSTR_DQD2ON = "Ultimate Degreelessness Mode ON"; +STSTR_DQD2OFF = "Ultimate Degreelessness Mode OFF"; STSTR_KFAADDED = "Very Happy Ammo Added"; STSTR_FAADDED = "Ammo (no keys) Added"; STSTR_NCON = "No Clipping Mode ON"; @@ -303,6 +305,8 @@ STSTR_CHOPPERS = "... doesn't suck - GM"; STSTR_CLEV = "Changing Level...\n"; TXT_BUDDHAON = "Buddha mode ON"; TXT_BUDDHAOFF = "Buddha mode OFF"; +TXT_BUDDHA2ON = "Ultimate Buddha Mode ON"; +TXT_BUDDHA2OFF = "Ultimate Buddha Mode OFF"; TXT_DEFAULTPICKUPMSG = "You got a pickup"; E1TEXT = From d1dc6fd59aa6ff64fc3b39924b173f3ac7f55172 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Fri, 24 Oct 2014 23:09:39 -0500 Subject: [PATCH 16/29] - Added: BUDDHA and FOILBUDDHA. - Fixed: mugshot didn't take the god2 cheat into account. --- src/actor.h | 2 ++ src/g_shared/sbar_mugshot.cpp | 2 +- src/p_interaction.cpp | 63 +++++++++++++++++++--------------- src/thingdef/thingdef_data.cpp | 2 ++ 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/src/actor.h b/src/actor.h index 11d1a6429..f4d1604e5 100644 --- a/src/actor.h +++ b/src/actor.h @@ -342,6 +342,8 @@ enum MF7_HANDLENODELAY = 0x00000008, // respect NoDelay state flag MF7_WEAPONSPAWN = 0x00000010, // subject to DF_NO_COOP_WEAPON_SPAWN dmflag MF7_HARMFRIENDS = 0x00000020, // is allowed to harm friendly monsters. + MF7_BUDDHA = 0x00000040, // Behaves just like the buddha cheat. + MF7_FOILBUDDHA = 0x00000080, // Similar to FOILINVUL, foils buddha mode. // --- mobj.renderflags --- diff --git a/src/g_shared/sbar_mugshot.cpp b/src/g_shared/sbar_mugshot.cpp index 96dd07265..b8f419ef0 100644 --- a/src/g_shared/sbar_mugshot.cpp +++ b/src/g_shared/sbar_mugshot.cpp @@ -444,7 +444,7 @@ int FMugShot::UpdateState(player_t *player, StateFlags stateflags) if (bNormal) { bool good; - if ((player->cheats & CF_GODMODE) || (player->mo != NULL && player->mo->flags2 & MF2_INVULNERABLE)) + if ((player->cheats & CF_GODMODE) || (player->cheats & CF_GODMODE2) || (player->mo != NULL && player->mo->flags2 & MF2_INVULNERABLE)) { good = SetState((stateflags & ANIMATEDGODMODE) ? "godanimated" : "god"); } diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 5ce20f598..252e8e849 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1322,43 +1322,52 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, if (target->health <= 0) - { // Death - target->special1 = damage; - - // use inflictor's death type if it got one. - if (inflictor && inflictor->DeathType != NAME_None) mod = inflictor->DeathType; - - // check for special fire damage or ice damage deaths - if (mod == NAME_Fire) + { + if ((target->flags7 & MF7_BUDDHA) && (damage < TELEFRAG_DAMAGE) && (!(inflictor->flags3 & MF7_FOILBUDDHA) && !(flags & DMG_FOILBUDDHA))) + { //Make sure FOILINVUL flags work here too for monsters. Or perhaps consider a FOILBUDDHA flag... + target->health = 1; + } + else { - if (player && !player->morphTics) - { // Check for flame death - if (!inflictor || - ((target->health > -50) && (damage > 25)) || - !(inflictor->flags5 & MF5_SPECIALFIREDAMAGE)) + + // Death + target->special1 = damage; + + // use inflictor's death type if it got one. + if (inflictor && inflictor->DeathType != NAME_None) mod = inflictor->DeathType; + + // check for special fire damage or ice damage deaths + if (mod == NAME_Fire) + { + if (player && !player->morphTics) + { // Check for flame death + if (!inflictor || + ((target->health > -50) && (damage > 25)) || + !(inflictor->flags5 & MF5_SPECIALFIREDAMAGE)) + { + target->DamageType = NAME_Fire; + } + } + else { target->DamageType = NAME_Fire; } } else { - target->DamageType = NAME_Fire; + target->DamageType = mod; } - } - else - { - target->DamageType = mod; - } - if (source && source->tracer && (source->flags5 & MF5_SUMMONEDMONSTER)) - { // Minotaur's kills go to his master - // Make sure still alive and not a pointer to fighter head - if (source->tracer->player && (source->tracer->player->mo == source->tracer)) - { - source = source->tracer; + if (source && source->tracer && (source->flags5 & MF5_SUMMONEDMONSTER)) + { // Minotaur's kills go to his master + // Make sure still alive and not a pointer to fighter head + if (source->tracer->player && (source->tracer->player->mo == source->tracer)) + { + source = source->tracer; + } } + target->Die (source, inflictor, flags); + return damage; } - target->Die (source, inflictor, flags); - return damage; } woundstate = target->FindState(NAME_Wound, mod); diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index b8ee13fd5..90c3313a6 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -242,6 +242,8 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF7, ALWAYSTELEFRAG, AActor, flags7), DEFINE_FLAG(MF7, WEAPONSPAWN, AActor, flags7), DEFINE_FLAG(MF7, HARMFRIENDS, AActor, flags7), + DEFINE_FLAG(MF7, BUDDHA, AActor, flags7), + DEFINE_FLAG(MF7, FOILBUDDHA, AActor, flags7), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), From a19620968d92123eac5788492b57fa76fbfb7e0a Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Fri, 24 Oct 2014 23:14:07 -0500 Subject: [PATCH 17/29] - Follow-up of the previous commit. - Cleaned up the DoDamage and DoKill functionality. - Added DMSS_FOILBUDDHA and KILS_FOILBUDDHA. --- src/p_local.h | 1 + src/thingdef/thingdef_codeptr.cpp | 69 ++++++++++++------------------ wadsrc/static/actors/constants.txt | 2 + 3 files changed, 30 insertions(+), 42 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 2dc8c773e..f7e473845 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -559,6 +559,7 @@ enum EDmgFlags DMG_NO_FACTOR = 16, DMG_PLAYERATTACK = 32, DMG_FOILINVUL = 64, + DMG_FOILBUDDHA = 128, }; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 2b382f989..6a1cf6e67 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4831,43 +4831,26 @@ enum DMSS DMSS_AFFECTARMOR = 2, DMSS_KILL = 4, DMSS_NOFACTOR = 8, + DMSS_FOILBUDDHA = 16, }; static void DoDamage(AActor *dmgtarget, AActor *self, int amount, FName DamageType, int flags) { - if ((amount > 0) || (flags & DMSS_KILL)) - { - if (!(dmgtarget->flags2 & MF2_INVULNERABLE) || (flags & DMSS_FOILINVUL)) - { - if (flags & DMSS_KILL) - { - P_DamageMobj(dmgtarget, self, self, dmgtarget->health, DamageType, DMG_NO_FACTOR | DMG_NO_ARMOR | DMG_FOILINVUL); - } - if (flags & DMSS_AFFECTARMOR) - { - if (flags & DMSS_NOFACTOR) - { - P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_FACTOR); - } - else - { - P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL); - } - } - else - { - if (flags & DMSS_NOFACTOR) - { - P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR | DMG_NO_FACTOR); - } - //[MC] DMG_FOILINVUL is needed for making the damage occur on the actor. - else - { - P_DamageMobj(dmgtarget, self, self, amount, DamageType, DMG_FOILINVUL | DMG_NO_ARMOR); - } - } - } - } + int dmgFlags = 0; + if (flags & DMSS_FOILINVUL) + dmgFlags += DMG_FOILINVUL; + if (flags & DMSS_FOILBUDDHA) + dmgFlags += DMG_FOILBUDDHA; + if ((flags & DMSS_KILL) || (flags & DMSS_NOFACTOR)) //Kill implies NoFactor + dmgFlags += DMG_NO_FACTOR; + if (!(flags & DMSS_AFFECTARMOR) || (flags & DMSS_KILL)) //Kill overrides AffectArmor + dmgFlags += DMG_NO_ARMOR; + if (flags & DMSS_KILL) //Kill adds the value of the damage done to it. Allows for more controlled extreme death types. + amount += dmgtarget->health; + + if (amount > 0) + P_DamageMobj(dmgtarget, self, self, amount, DamageType, dmgFlags); //Should wind up passing them through just fine. + else if (amount < 0) { amount = -amount; @@ -4991,30 +4974,32 @@ enum KILS KILS_FOILINVUL = 1 << 0, KILS_KILLMISSILES = 1 << 1, KILS_NOMONSTERS = 1 << 2, + KILS_FOILBUDDHA = 1 << 3, }; static void DoKill(AActor *killtarget, AActor *self, FName damagetype, int flags) { + int dmgFlags = DMG_NO_ARMOR + DMG_NO_FACTOR; + + if (KILS_FOILINVUL) + dmgFlags += DMG_FOILINVUL; + if (KILS_FOILBUDDHA) + dmgFlags += DMG_FOILBUDDHA; + if ((killtarget->flags & MF_MISSILE) && (flags & KILS_KILLMISSILES)) { //[MC] Now that missiles can set masters, lets put in a check to properly destroy projectiles. BUT FIRST! New feature~! //Check to see if it's invulnerable. Disregarded if foilinvul is on, but never works on a missile with NODAMAGE //since that's the whole point of it. - if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && !(killtarget->flags5 & MF5_NODAMAGE)) + if ((!(killtarget->flags2 & MF2_INVULNERABLE) || (flags & KILS_FOILINVUL)) && + (!(killtarget->flags2 & MF7_BUDDHA) || (flags & KILS_FOILBUDDHA)) && !(killtarget->flags5 & MF5_NODAMAGE)) { P_ExplodeMissile(killtarget, NULL, NULL); } } if (!(flags & KILS_NOMONSTERS)) { - if (flags & KILS_FOILINVUL) - { - P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR | DMG_FOILINVUL); - } - else - { - P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, DMG_NO_ARMOR | DMG_NO_FACTOR); - } + P_DamageMobj(killtarget, self, self, killtarget->health, damagetype, dmgFlags); } } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index da289dc50..f806f8224 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -375,12 +375,14 @@ enum const int KILS_FOILINVUL = 1; const int KILS_KILLMISSILES = 2; const int KILS_NOMONSTERS = 4; +const int KILS_FOILBUDDHA = 8; // Flags for A_Damage (Master/Target/Tracer/Children/Siblings/Self) series const int DMSS_FOILINVUL = 1; const int DMSS_AFFECTARMOR = 2; const int DMSS_KILL = 4; const int DMSS_NOFACTOR = 8; +const int DMSS_FOILBUDDHA = 16; // Flags for A_AlertMonsters const int AMF_TARGETEMITTER = 1; From 313245dd77e7bd56cda09da105302e1ce51ded81 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 09:53:23 +0200 Subject: [PATCH 18/29] - added a Buddha powerup --- src/g_shared/a_artifacts.cpp | 36 +++++++++++++++++++++++ src/g_shared/a_artifacts.h | 8 +++++ wadsrc/static/actors/shared/inventory.txt | 5 ++++ 3 files changed, 49 insertions(+) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 7fd15fa21..1fa3ca985 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1396,6 +1396,42 @@ void APowerFrightener::EndEffect () Owner->player->cheats &= ~CF_FRIGHTENING; } +// Buddha Powerup -------------------------------- + +IMPLEMENT_CLASS (APowerBuddha) + +//=========================================================================== +// +// APowerBuddha :: InitEffect +// +//=========================================================================== + +void APowerBuddha::InitEffect () +{ + Super::InitEffect(); + + if (Owner== NULL || Owner->player == NULL) + return; + + Owner->player->cheats |= CF_FRIGHTENING; +} + +//=========================================================================== +// +// APowerBuddha :: EndEffect +// +//=========================================================================== + +void APowerBuddha::EndEffect () +{ + Super::EndEffect(); + + if (Owner== NULL || Owner->player == NULL) + return; + + Owner->player->cheats &= ~CF_FRIGHTENING; +} + // Scanner powerup ---------------------------------------------------------- IMPLEMENT_CLASS (APowerScanner) diff --git a/src/g_shared/a_artifacts.h b/src/g_shared/a_artifacts.h index a216cf74c..4e1823f5a 100644 --- a/src/g_shared/a_artifacts.h +++ b/src/g_shared/a_artifacts.h @@ -184,6 +184,14 @@ protected: void EndEffect (); }; +class APowerBuddha : public APowerup +{ + DECLARE_CLASS (APowerBuddha, APowerup) +protected: + void InitEffect (); + void EndEffect (); +}; + class APowerTimeFreezer : public APowerup { DECLARE_CLASS( APowerTimeFreezer, APowerup ) diff --git a/wadsrc/static/actors/shared/inventory.txt b/wadsrc/static/actors/shared/inventory.txt index e293282b8..e9f57a607 100644 --- a/wadsrc/static/actors/shared/inventory.txt +++ b/wadsrc/static/actors/shared/inventory.txt @@ -271,6 +271,11 @@ ACTOR PowerFrightener : Powerup native Powerup.Duration -60 } +ACTOR PowerBuddha : Powerup native +{ + Powerup.Duration -60 +} + ACTOR PowerScanner : Powerup native { Powerup.Duration -80 From 8edace83c5b089530f6c34814ba08dbb2e748feb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 10:19:14 +0200 Subject: [PATCH 19/29] - made CheatKey and EasyKey vector graphics configurable through MAPINFO. --- src/am_map.cpp | 4 ++-- src/gi.cpp | 3 +++ src/gi.h | 1 + wadsrc/static/mapinfo/common.txt | 5 +++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 904593dfb..29cd60793 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -908,8 +908,8 @@ void AM_StaticInit() if (gameinfo.mMapArrow.IsNotEmpty()) AM_ParseArrow(MapArrow, gameinfo.mMapArrow); if (gameinfo.mCheatMapArrow.IsNotEmpty()) AM_ParseArrow(CheatMapArrow, gameinfo.mCheatMapArrow); - AM_ParseArrow(CheatKey, "maparrows/key.txt"); - AM_ParseArrow(EasyKey, "maparrows/ravenkey.txt"); + AM_ParseArrow(CheatKey, gameinfo.mCheatKey); + AM_ParseArrow(EasyKey, gameinfo.mEasyKey); if (MapArrow.Size() == 0) I_FatalError("No automap arrow defined"); char namebuf[9]; diff --git a/src/gi.cpp b/src/gi.cpp index 4e64dd425..a17e97631 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -290,6 +290,9 @@ void FMapInfoParser::ParseGameInfo() else gameinfo.mCheatMapArrow = ""; } // Insert valid keys here. + GAMEINFOKEY_STRING(mCheatKey, "cheatKey") + GAMEINFOKEY_STRING(mEasyKey, "easyKey") + GAMEINFOKEY_STRING(TitlePage, "titlePage") GAMEINFOKEY_STRING(TitlePage, "titlePage") GAMEINFOKEY_STRINGARRAY(creditPages, "addcreditPage", 8, false) GAMEINFOKEY_STRINGARRAY(creditPages, "CreditPage", 8, true) diff --git a/src/gi.h b/src/gi.h index bbfbe73ff..d8d19a14b 100644 --- a/src/gi.h +++ b/src/gi.h @@ -169,6 +169,7 @@ struct gameinfo_t int TextScreenY; FName DefaultEndSequence; FString mMapArrow, mCheatMapArrow; + FString mEasyKey, mCheatKey; FGIFont mStatscreenMapNameFont; FGIFont mStatscreenFinishedFont; FGIFont mStatscreenEnteringFont; diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index 8e7886987..fc6379d01 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -1,3 +1,8 @@ +Gameinfo +{ + CheatKey = "maparrows/key.txt" + EasyKey = "maparrows/ravenkey.txt" +} Intermission Inter_Titlescreen { From 0d3908a4f38bd9618fa5cbc150808daea0f423c2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 10:44:00 +0200 Subject: [PATCH 20/29] - fixed: Hitscan traces crossing a two sided line right at the height of the back sector's floor or ceiling must not be considered a hit. --- src/p_trace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index d1b9f63ac..26852269a 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -366,7 +366,7 @@ bool FTraceInfo::TraceTraverse (int ptflags) Results->HitTexture = CurSector->GetTexture(sector_t::ceiling); } else if (entersector == NULL || - hitz <= bf || hitz >= bc || + hitz < bf || hitz > bc || in->d.line->flags & WallMask) { // hit the wall Results->HitType = TRACE_HitWall; From cfe97b0f0f596d19bdaea88e4571ee95f25967fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 11:33:28 +0200 Subject: [PATCH 21/29] - Fixed: Killing a morphed monster must trigger A_BossDeath on its unmorphed self. --- src/g_shared/a_morph.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index 2b3a6040d..6014d6fee 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -12,6 +12,7 @@ #include "doomstat.h" #include "g_level.h" #include "farchive.h" +#include "p_enemy.h" static FRandom pr_morphmonst ("MorphMonster"); @@ -527,11 +528,11 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor if (actor->GetClass()->IsDescendantOf(RUNTIME_CLASS(AMorphedMonster))) { AMorphedMonster *fakeme = static_cast(actor); + AActor *realme = fakeme->UnmorphedMe; if ((fakeme->UnmorphTime) && (fakeme->MorphStyle & MORPH_UNDOBYDEATH) && - (fakeme->UnmorphedMe)) + (realme)) { - AActor *realme = fakeme->UnmorphedMe; int realstyle = fakeme->MorphStyle; int realhealth = fakeme->health; if (P_UndoMonsterMorph(fakeme, !!(fakeme->MorphStyle & MORPH_UNDOBYDEATHFORCED))) @@ -542,6 +543,11 @@ bool P_MorphedDeath(AActor *actor, AActor **morphed, int *morphedstyle, int *mor return true; } } + if (realme->flags4 & MF4_BOSSDEATH) + { + realme->health = 0; // make sure that A_BossDeath considers it dead. + CALL_ACTION(A_BossDeath, realme); + } fakeme->flags3 |= MF3_STAYMORPHED; // moved here from AMorphedMonster::Die() return false; } From fc40e9723a2b907e083783705a7b17106773c905 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 11:51:29 +0200 Subject: [PATCH 22/29] - fixed: CHANGELEVEL_RESETINVENTORY may not change the player's health. APlayerPawn::GiveDefaultInventory altered the player_t's health value which was ok as long as this function was only called from G_PlayerReborn. For all other cases this initialization was wrong and G_PlayerReborn should do this itself. --- src/g_game.cpp | 3 +++ src/m_cheat.cpp | 1 - src/p_user.cpp | 3 --- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index a58753b86..8419fc017 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1363,6 +1363,7 @@ void G_PlayerReborn (int player) ::new(p) player_t; memcpy (p->frags, frags, sizeof(p->frags)); + p->health = actor->health; p->fragcount = fragcount; p->killcount = killcount; p->itemcount = itemcount; @@ -1381,6 +1382,8 @@ void G_PlayerReborn (int player) if (gamestate != GS_TITLELEVEL) { + + // [GRB] Give inventory specified in DECORATE actor->GiveDefaultInventory (); p->ReadyWeapon = p->PendingWeapon; } diff --git a/src/m_cheat.cpp b/src/m_cheat.cpp index ac4eb140d..e48b79980 100644 --- a/src/m_cheat.cpp +++ b/src/m_cheat.cpp @@ -340,7 +340,6 @@ void cht_DoCheat (player_t *player, int cheat) player->mo->Translation = TRANSLATION(TRANSLATION_Players, BYTE(player-players)); } player->mo->DamageType = NAME_None; -// player->mo->GiveDefaultInventory(); if (player->ReadyWeapon != NULL) { P_SetPsprite(player, ps_weapon, player->ReadyWeapon->GetUpState()); diff --git a/src/p_user.cpp b/src/p_user.cpp index 51105cd3d..045e61969 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -1203,9 +1203,6 @@ void APlayerPawn::GiveDefaultInventory () { if (player == NULL) return; - // [GRB] Give inventory specified in DECORATE - player->health = GetDefault ()->health; - // HexenArmor must always be the first item in the inventory because // it provides player class based protection that should not affect // any other protection item. From ef5707d73ba453968f61ac10f2bb31f80152697b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 12:12:06 +0200 Subject: [PATCH 23/29] - added a compatibility option for stopping sounds when the owning actor is destroyed. --- src/compatibility.cpp | 1 + src/d_main.cpp | 1 + src/doomdef.h | 1 + src/g_mapinfo.cpp | 1 + src/s_sound.cpp | 2 +- wadsrc/static/menudef.txt | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 351c2672a..7bd28e5d9 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -141,6 +141,7 @@ static FCompatOption Options[] = { "maskedmidtex", COMPATF_MASKEDMIDTEX, SLOT_COMPAT }, { "badangles", COMPATF2_BADANGLES, SLOT_COMPAT2 }, { "floormove", COMPATF2_FLOORMOVE, SLOT_COMPAT2 }, + { "soundcutoff", COMPATF2_SOUNDCUTOFF, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 255994fb5..79c899085 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -620,6 +620,7 @@ CVAR (Flag, compat_polyobj, compatflags, COMPATF_POLYOBJ); CVAR (Flag, compat_maskedmidtex, compatflags, COMPATF_MASKEDMIDTEX); CVAR (Flag, compat_badangles, compatflags2, COMPATF2_BADANGLES); CVAR (Flag, compat_floormove, compatflags2, COMPATF2_FLOORMOVE); +CVAR (Flag, compat_soundcutoff, compatflags2, COMPATF2_SOUNDCUTOFF); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 3e00975cf..767f97661 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -339,6 +339,7 @@ enum COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. + COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 5a451dfaa..b68408237 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1306,6 +1306,7 @@ MapFlagHandlers[] = { "compat_maskedmidtex", MITYPE_COMPATFLAG, COMPATF_MASKEDMIDTEX, 0 }, { "compat_badangles", MITYPE_COMPATFLAG, 0, COMPATF2_BADANGLES }, { "compat_floormove", MITYPE_COMPATFLAG, 0, COMPATF2_FLOORMOVE }, + { "compat_soundcutoff", MITYPE_COMPATFLAG, 0, COMPATF2_SOUNDCUTOFF }, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/s_sound.cpp b/src/s_sound.cpp index 035b71c74..75bd33d47 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -1575,7 +1575,7 @@ void S_RelinkSound (AActor *from, AActor *to) { chan->Actor = to; } - else if (!(chan->ChanFlags & CHAN_LOOP)) + else if (!(chan->ChanFlags & CHAN_LOOP) && !(compatflags2 & COMPATF2_SOUNDCUTOFF)) { chan->Actor = NULL; chan->SourceType = SOURCE_Unattached; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 13565da7f..3d5a3ea3c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1300,6 +1300,7 @@ OptionMenu "CompatibilityOptions" Option "Ignore Y offsets on masked midtextures", "compat_MASKEDMIDTEX", "YesNo" Option "Cannot travel straight NSEW", "compat_badangles", "YesNo" Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + Option "Sounds stop when actor vanishes", "compat_soundcutoff", "YesNo" Class "CompatibilityMenu" } From dcc318fdee62eec607978a8864c780ec4575ab62 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 12:33:08 +0200 Subject: [PATCH 24/29] - print a warning when a state label can't be found. Preferably this would be an error but the oversight had been in the engine for too long so nobody knows --- src/p_states.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_states.cpp b/src/p_states.cpp index cfe455716..3ba0ae14f 100644 --- a/src/p_states.cpp +++ b/src/p_states.cpp @@ -39,6 +39,7 @@ #include "cmdlib.h" #include "i_system.h" #include "c_dispatch.h" +#include "v_text.h" #include "thingdef/thingdef.h" // Each state is owned by an actor. Actors can own any number of @@ -699,6 +700,10 @@ FState *FStateDefinitions::ResolveGotoLabel (AActor *actor, const PClass *mytype { I_Error ("Attempt to get invalid state %s from actor %s.", label, type->TypeName.GetChars()); } + else + { + Printf (TEXTCOLOR_RED "Attempt to get invalid state %s from actor %s.\n", label, type->TypeName.GetChars()); + } delete[] namestart; // free the allocated string buffer return state; } From edd53f22a1d67fcc3d7bf2114543e852bcebc540 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 12:34:46 +0200 Subject: [PATCH 25/29] - fixed: The buddha powerup set the wrong flag. --- src/g_shared/a_artifacts.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 1fa3ca985..4a2d066cd 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1413,7 +1413,7 @@ void APowerBuddha::InitEffect () if (Owner== NULL || Owner->player == NULL) return; - Owner->player->cheats |= CF_FRIGHTENING; + Owner->player->cheats |= CF_BUDDHA; } //=========================================================================== @@ -1429,7 +1429,7 @@ void APowerBuddha::EndEffect () if (Owner== NULL || Owner->player == NULL) return; - Owner->player->cheats &= ~CF_FRIGHTENING; + Owner->player->cheats &= ~CF_BUDDHA; } // Scanner powerup ---------------------------------------------------------- From ad2e16576c078ead9c67219af691f4754d527969 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 13:10:38 +0200 Subject: [PATCH 26/29] - fixed_ P_ExplodeMissile skipped most of its logic when the missile got destroyed by having no death state. Apparently a band-aid fix was applied to this function because AActor::Destroy could not be called on an already destroyed actor again which could happen here due to incorrect ordering of actions. Moving the state change to a later point in this function - after hitting a sky has been checked and decals have been spawned - returns everything to a safe state and ensures that nothing gets skipped. --- src/p_mobj.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a67b96dfb..2b0782b8f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1199,13 +1199,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) if (nextstate == NULL) nextstate = mo->FindState(NAME_Death, NAME_Extreme); } if (nextstate == NULL) nextstate = mo->FindState(NAME_Death); - mo->SetState (nextstate); - if (mo->ObjectFlags & OF_EuthanizeMe) - { - return; - } - if (line != NULL && line->special == Line_Horizon && !(mo->flags3 & MF3_SKYEXPLODE)) { // [RH] Don't explode missiles on horizon lines. @@ -1280,8 +1274,17 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) } } - if (nextstate != NULL) + // play the sound before changing the state, so that AActor::Destroy can call S_RelinkSounds on it and the death state can override it. + if (mo->DeathSound) { + S_Sound (mo, CHAN_VOICE, mo->DeathSound, 1, + (mo->flags3 & MF3_FULLVOLDEATH) ? ATTN_NONE : ATTN_NORM); + } + + mo->SetState (nextstate); + if (!(mo->ObjectFlags & OF_EuthanizeMe)) + { + // The rest only applies if the missile actor still exists. // [RH] Change render style of exploding rockets if (mo->flags5 & MF5_DEHEXPLOSION) { @@ -1314,11 +1317,6 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) mo->flags &= ~MF_MISSILE; - if (mo->DeathSound) - { - S_Sound (mo, CHAN_VOICE, mo->DeathSound, 1, - (mo->flags3 & MF3_FULLVOLDEATH) ? ATTN_NONE : ATTN_NORM); - } } } From 2e1fa70cbf45e3b3bd89c686265aa9753ce41e96 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 13:12:57 +0200 Subject: [PATCH 27/29] - some parentheses to silence GCC. --- src/p_interaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 252e8e849..2ac29e11c 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -1262,7 +1262,7 @@ int P_DamageMobj (AActor *target, AActor *inflictor, AActor *source, int damage, // telefrag him right? ;) (Unfortunately the damage is "absorbed" by armor, // but telefragging should still do enough damage to kill the player) // Ignore players that are already dead. - if ((player->cheats & CF_BUDDHA2) || ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE) && player->playerstate != PST_DEAD) + if (((player->cheats & CF_BUDDHA2) || ((player->cheats & CF_BUDDHA) && damage < TELEFRAG_DAMAGE)) && player->playerstate != PST_DEAD) { // If this is a voodoo doll we need to handle the real player as well. player->mo->health = target->health = player->health = 1; From 9435cdc5c9d18100fa8a8a7cbe37cd705080220b Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sun, 26 Oct 2014 01:09:19 +1300 Subject: [PATCH 28/29] Fixed NULL refrence in P_SpawnBlood --- src/p_mobj.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a67b96dfb..829e172cb 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5018,10 +5018,11 @@ void P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, angle_t dir, int damage, AAc cls = cls->ParentClass; } } + + statedone: + if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE; } -statedone: - if (!(bloodtype <= 1)) th->renderflags |= RF_INVISIBLE; if (bloodtype >= 1) P_DrawSplash2 (40, x, y, z, dir, 2, bloodcolor); } From d4c50b1662706b252ecbdceb95cf61a1d528d7f8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 25 Oct 2014 14:59:30 +0200 Subject: [PATCH 29/29] - fixed: AActor::IsTeammate must consider monsters friendly to a specific player as members of the same team as the owning player. Such monsters cannot be made members of a designated team, though, because their association needs to change if the player changes teams. --- src/actor.h | 3 +++ src/p_enemy.cpp | 2 +- src/p_mobj.cpp | 35 +++++++++++++++++++++++++++-------- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/actor.h b/src/actor.h index f4d1604e5..f1c733ab2 100644 --- a/src/actor.h +++ b/src/actor.h @@ -716,6 +716,9 @@ public: // Transforms the actor into a finely-ground paste virtual bool Grind(bool items); + // Get this actor's team + int GetTeam(); + // Is the other actor on my team? bool IsTeammate (AActor *other); diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 20b61200f..e51d601f3 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -1592,7 +1592,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround, FLookExParams *params) } #endif // [SP] If you don't see any enemies in deathmatch, look for players (but only when friend to a specific player.) - if (actor->FriendPlayer == 0 && (!teamplay || actor->DesignatedTeam == TEAM_NONE)) return result; + if (actor->FriendPlayer == 0 && (!teamplay || actor->GetTeam() == TEAM_NONE)) return result; if (result || !deathmatch) return true; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2b0782b8f..16d83943f 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -5855,22 +5855,41 @@ AActor *P_SpawnPlayerMissile (AActor *source, fixed_t x, fixed_t y, fixed_t z, return NULL; } +int AActor::GetTeam() +{ + if (player) + { + return player->userinfo.GetTeam(); + } + + int myTeam = DesignatedTeam; + + // Check for monsters that belong to a player on the team but aren't part of the team themselves. + if (myTeam == TEAM_NONE && FriendPlayer != 0) + { + myTeam = players[FriendPlayer - 1].userinfo.GetTeam(); + } + return myTeam; + +} + bool AActor::IsTeammate (AActor *other) { if (!other) + { return false; + } else if (!deathmatch && player && other->player) - return true; - int myTeam = DesignatedTeam; - int otherTeam = other->DesignatedTeam; - if (player) - myTeam = player->userinfo.GetTeam(); - if (other->player) - otherTeam = other->player->userinfo.GetTeam(); - if (teamplay && myTeam != TEAM_NONE && myTeam == otherTeam) { return true; } + else if (teamplay) + { + int myTeam = GetTeam(); + int otherTeam = other->GetTeam(); + + return (myTeam != TEAM_NONE && myTeam == otherTeam); + } return false; }