From 6dff8da503b900ad4a501af12a238ef5b8bbcf9f Mon Sep 17 00:00:00 2001 From: Benjamin Moir Date: Tue, 20 Jan 2015 12:05:00 +1030 Subject: [PATCH 01/16] Added +NODECAL and +FORCEDECAL actor flags Added FHF_NOIMPACTDECAL for LineAttack --- src/actor.h | 4 ++-- src/p_acs.cpp | 7 +++++-- src/p_local.h | 3 ++- src/p_map.cpp | 8 ++++++-- src/thingdef/thingdef_data.cpp | 4 ++++ 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/actor.h b/src/actor.h index 0ab589107..9b6b29a98 100644 --- a/src/actor.h +++ b/src/actor.h @@ -353,8 +353,8 @@ enum MF7_HITTARGET = 0x00004000, // The actor the projectile dies on is set to target, provided it's targetable anyway. MF7_HITMASTER = 0x00008000, // Same as HITTARGET, except it's master instead of target. MF7_HITTRACER = 0x00010000, // Same as HITTARGET, but for tracer. - - + MF7_NODECAL = 0x00020000, // [ZK] Forces puff to have no impact decal + MF7_FORCEDECAL = 0x00040000, // [ZK] Forces P_LineAttack to use the puff's decal, even if the player's weapon has a decal defined // --- mobj.renderflags --- diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 4b9a8bbab..d4f4be30c 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -113,8 +113,9 @@ FRandom pr_acs ("ACS"); #define NOT_FLOOR 8 #define NOT_CEILING 16 -// LineAtack flags +// LineAttack flags #define FHF_NORANDOMPUFFZ 1 +#define FHF_NOIMPACTDECAL 2 // SpawnDecal flags #define SDF_ABSANGLE 1 @@ -5398,7 +5399,9 @@ int DLevelScript::CallFunction(int argCount, int funcIndex, SDWORD *args, const fixed_t range = argCount > 6 && args[6]? args[6] : MISSILERANGE; int flags = argCount > 7 && args[7]? args[7] : 0; - int fhflags = (flags & FHF_NORANDOMPUFFZ)? LAF_NORANDOMPUFFZ : 0; + int fhflags = 0; + if (flags & FHF_NORANDOMPUFFZ) fhflags |= LAF_NORANDOMPUFFZ; + if (flags & FHF_NOIMPACTDECAL) fhflags |= LAF_NOIMPACTDECAL; if (args[0] == 0) { diff --git a/src/p_local.h b/src/p_local.h index fe7958807..873bad5e9 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -459,7 +459,8 @@ enum // P_AimLineAttack flags enum // P_LineAttack flags { LAF_ISMELEEATTACK = 1, - LAF_NORANDOMPUFFZ = 2 + LAF_NORANDOMPUFFZ = 2, + LAF_NOIMPACTDECAL = 4 }; AActor *P_LineAttack (AActor *t1, angle_t angle, fixed_t distance, int pitch, int damage, FName damageType, const PClass *pufftype, int flags = 0, AActor **victim = NULL, int *actualdamage = NULL); diff --git a/src/p_map.cpp b/src/p_map.cpp index 68d0b21f0..923387d95 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3714,13 +3714,17 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, } // [RH] Spawn a decal - if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon) + if (trace.HitType == TRACE_HitWall && trace.Line->special != Line_Horizon && !(flags & LAF_NOIMPACTDECAL) && !(puffDefaults->flags7 & MF7_NODECAL)) { // [TN] If the actor or weapon has a decal defined, use that one. if (t1->DecalGenerator != NULL || (t1->player != NULL && t1->player->ReadyWeapon != NULL && t1->player->ReadyWeapon->DecalGenerator != NULL)) { - SpawnShootDecal(t1, trace); + // [ZK] If puff has FORCEDECAL set, do not use the weapon's decal + if (puffDefaults->flags7 & MF7_FORCEDECAL && puff != NULL && puff->DecalGenerator) + SpawnShootDecal(puff, trace); + else + SpawnShootDecal(t1, trace); } // Else, look if the bulletpuff has a decal defined. diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index fbe28fb5b..db479464f 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -253,6 +253,10 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF7, HITTARGET, AActor, flags7), DEFINE_FLAG(MF7, HITMASTER, AActor, flags7), DEFINE_FLAG(MF7, HITTRACER, AActor, flags7), + + // [ZK] Decal flags + DEFINE_FLAG(MF7, NODECAL, AActor, flags7), + DEFINE_FLAG(MF7, FORCEDECAL, AActor, flags7), // Effect flags DEFINE_FLAG(FX, VISIBILITYPULSE, AActor, effects), From 087d564343d07c6f1062964b57bfb7ebb02fec18 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Fri, 3 Apr 2015 12:16:27 -0500 Subject: [PATCH 02/16] - Added MORPH_UNDOALWAYS for morph powerups. --- src/g_shared/a_artifacts.cpp | 2 +- src/g_shared/a_morph.h | 1 + src/thingdef/thingdef_parse.cpp | 1 + wadsrc/static/actors/constants.txt | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_shared/a_artifacts.cpp b/src/g_shared/a_artifacts.cpp index 14b270435..8ac35f840 100644 --- a/src/g_shared/a_artifacts.cpp +++ b/src/g_shared/a_artifacts.cpp @@ -1922,7 +1922,7 @@ void APowerMorph::EndEffect( ) if (!bNoCallUndoMorph) { int savedMorphTics = Player->morphTics; - P_UndoPlayerMorph (Player, Player); + P_UndoPlayerMorph (Player, Player, 0, !!(Player->MorphStyle & MORPH_UNDOALWAYS)); // Abort if unmorph failed; in that case, // set the usual retry timer and return. diff --git a/src/g_shared/a_morph.h b/src/g_shared/a_morph.h index e86332b3d..9272901dd 100644 --- a/src/g_shared/a_morph.h +++ b/src/g_shared/a_morph.h @@ -24,6 +24,7 @@ enum MORPH_UNDOBYDEATHFORCED = 0x00000400, // Actor (if unmorphed when killed) forces unmorph (not very useful with UNDOBYDEATHSAVES) MORPH_UNDOBYDEATHSAVES = 0x00000800, // Actor (if unmorphed when killed) regains their health and doesn't die MORPH_UNDOBYTIMEOUT = 0x00001000, // Player unmorphs once countdown expires + MORPH_UNDOALWAYS = 0x00002000, // Powerups must always unmorph, no matter what. MORPH_STANDARDUNDOING = MORPH_UNDOBYTOMEOFPOWER | MORPH_UNDOBYCHAOSDEVICE | MORPH_UNDOBYTIMEOUT, }; diff --git a/src/thingdef/thingdef_parse.cpp b/src/thingdef/thingdef_parse.cpp index 88e6084b6..61922feaf 100644 --- a/src/thingdef/thingdef_parse.cpp +++ b/src/thingdef/thingdef_parse.cpp @@ -526,6 +526,7 @@ static int ParseMorphStyle (FScanner &sc) { "MRF_UNDOBYDEATH", MORPH_UNDOBYDEATH}, { "MRF_UNDOBYDEATHFORCED", MORPH_UNDOBYDEATHFORCED}, { "MRF_UNDOBYDEATHSAVES", MORPH_UNDOBYDEATHSAVES}, + { "MRF_UNDOALWAYS", MORPH_UNDOALWAYS }, { NULL, 0 } }; diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index e6434a08e..2ded98bc7 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -140,6 +140,7 @@ const int MRF_NEWTIDBEHAVIOUR = 256; const int MRF_UNDOBYDEATH = 512; const int MRF_UNDOBYDEATHFORCED = 1024; const int MRF_UNDOBYDEATHSAVES = 2048; +const int MRF_UNDOALWAYS = 4096; // Flags for A_RailAttack and A_CustomRailgun const int RGF_SILENT = 1; From 830a7ee003069cc998277edb2c5e93a31f74829f Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 4 Apr 2015 19:19:17 +0300 Subject: [PATCH 03/16] - added TFlags --- src/farchive.h | 7 ++++ src/tflags.h | 110 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/tflags.h diff --git a/src/farchive.h b/src/farchive.h index 329b448db..87ebf999b 100644 --- a/src/farchive.h +++ b/src/farchive.h @@ -37,6 +37,7 @@ #include #include "dobject.h" #include "r_state.h" +#include "tflags.h" class FFile { @@ -333,4 +334,10 @@ FArchive &operator<< (FArchive &arc, side_t *&side); +template +FArchive& operator<< (FArchive& arc, TFlags& flag) +{ + return flag.Serialize (arc); +} + #endif //__FARCHIVE_H__ diff --git a/src/tflags.h b/src/tflags.h new file mode 100644 index 000000000..20caba227 --- /dev/null +++ b/src/tflags.h @@ -0,0 +1,110 @@ +/* +** tflags.h +** +**--------------------------------------------------------------------------- +** Copyright 2015 Teemu Piippo +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +#pragma once +#include "doomtype.h" + +/* + * TFlags + * + * A Qt-inspired type-safe flagset type. + * + * T is the enum type of individual flags, + * TT is the underlying integer type used (defaults to DWORD) + */ +template +class TFlags +{ + struct ZeroDummy {}; + +public: + typedef TFlags Self; + typedef T EnumType; + typedef TT IntType; + + TFlags(){} + TFlags (const Self& other) : Value (other.GetValue()) {} + TFlags (T value) : Value (static_cast (value)) {} + + // This allows initializing the flagset with 0, as 0 implicitly converts into a null pointer. + TFlags (ZeroDummy*) : Value (0) {} + + // Relation operators + Self operator| (Self other) const { return Self::FromInt (Value | other.GetValue()); } + Self operator& (Self other) const { return Self::FromInt (Value & other.GetValue()); } + Self operator^ (Self other) const { return Self::FromInt (Value ^ other.GetValue()); } + Self operator| (T value) const { return Self::FromInt (Value | value); } + Self operator& (T value) const { return Self::FromInt (Value & value); } + Self operator^ (T value) const { return Self::FromInt (Value ^ value); } + Self operator~() const { return Self::FromInt (~Value); } + + // Assignment operators + Self& operator= (Self other) { Value = other.GetValue(); return *this; } + Self& operator|= (Self other) { Value |= other.GetValue(); return *this; } + Self& operator&= (Self other) { Value &= other.GetValue(); return *this; } + Self& operator^= (Self other) { Value ^= other.GetValue(); return *this; } + Self& operator= (T value) { Value = value; return *this; } + Self& operator|= (T value) { Value |= value; return *this; } + Self& operator&= (T value) { Value &= value; return *this; } + Self& operator^= (T value) { Value ^= value; return *this; } + + // Access the value of the flagset + TT GetValue() const { return Value; } + operator TT() const { return Value; } + + // Serialize to FArchive + FArchive& Serialize (FArchive& arc) + { + arc << Value; + return arc; + } + + // Set the value of the flagset manually with an integer. + // Please think twice before using this. + static Self FromInt (TT value) { return Self (static_cast (value)); } + +private: + TT Value; +}; + +/* + * Additional operators for TFlags types. + */ +#define DEFINE_TFLAGS_OPERATORS(T) \ +inline T operator| (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T::EnumType b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator| (T::EnumType a, T b) { return T::FromInt (T::IntType (a) | T::IntType (b)); } \ +inline T operator& (T::EnumType a, T b) { return T::FromInt (T::IntType (a) & T::IntType (b)); } \ +inline T operator^ (T::EnumType a, T b) { return T::FromInt (T::IntType (a) ^ T::IntType (b)); } \ +inline T operator~ (T::EnumType a) { return T::FromInt (~T::IntType (a)); } \ No newline at end of file From ca012bc9be9a2165b4dcf86588d0767da4ba5ea8 Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sat, 4 Apr 2015 19:40:43 +0300 Subject: [PATCH 04/16] - adapted AActor to use TFlags --- src/actor.h | 84 +++++++++++++++++++--------- src/b_func.cpp | 2 +- src/d_dehacked.cpp | 12 ++-- src/fragglescript/t_func.cpp | 7 ++- src/g_shared/a_morph.cpp | 4 +- src/g_shared/a_movingcamera.cpp | 4 +- src/g_shared/a_sharedglobal.h | 2 +- src/p_acs.cpp | 2 +- src/p_buildmap.cpp | 2 +- src/p_enemy.cpp | 2 +- src/p_map.cpp | 4 +- src/p_mobj.cpp | 4 +- src/p_things.cpp | 6 +- src/r_main.cpp | 2 +- src/thingdef/thingdef_codeptr.cpp | 42 +++++++------- src/thingdef/thingdef_data.cpp | 26 ++++----- src/thingdef/thingdef_properties.cpp | 14 ++--- 17 files changed, 127 insertions(+), 92 deletions(-) diff --git a/src/actor.h b/src/actor.h index 862858b32..402253a7b 100644 --- a/src/actor.h +++ b/src/actor.h @@ -39,6 +39,7 @@ #include "s_sound.h" #include "memarena.h" #include "g_level.h" +#include "tflags.h" struct subsector_t; // @@ -105,10 +106,9 @@ struct subsector_t; // Any questions? // -enum -{ // --- mobj.flags --- - +enum ActorFlag +{ MF_SPECIAL = 0x00000001, // call P_SpecialThing when touched MF_SOLID = 0x00000002, MF_SHOOTABLE = 0x00000004, @@ -152,8 +152,13 @@ enum MF_STEALTH = 0x40000000, // [RH] Andy Baker's stealth monsters MF_ICECORPSE = 0x80000000, // a frozen corpse (for blasting) [RH] was 0x800000 -// --- mobj.flags2 --- + // --- dummies for unknown/unimplemented Strife flags --- + MF_STRIFEx8000000 = 0, // seems related to MF_SHADOW +}; +// --- mobj.flags2 --- +enum ActorFlag2 +{ MF2_DONTREFLECT = 0x00000001, // this projectile cannot be reflected MF2_WINDTHRUST = 0x00000002, // gets pushed around by the wind specials MF2_DONTSEEKINVISIBLE=0x00000004, // For seeker missiles: Don't home in on invisible/shadow targets @@ -191,9 +196,11 @@ enum // args should not be taken from the mapthing definition MF2_SEEKERMISSILE = 0x40000000, // is a seeker (for reflection) MF2_REFLECTIVE = 0x80000000, // reflects missiles +}; // --- mobj.flags3 --- - +enum ActorFlag3 +{ MF3_FLOORHUGGER = 0x00000001, // Missile stays on floor MF3_CEILINGHUGGER = 0x00000002, // Missile stays on ceiling MF3_NORADIUSDMG = 0x00000004, // Actor does not take radius damage @@ -226,9 +233,11 @@ enum MF3_WARNBOT = 0x20000000, // Missile warns bot MF3_PUFFONACTORS = 0x40000000, // Puff appears even when hit bleeding actors MF3_HUNTPLAYERS = 0x80000000, // Used with TIDtoHate, means to hate players too +}; // --- mobj.flags4 --- - +enum ActorFlag4 +{ MF4_NOHATEPLAYERS = 0x00000001, // Ignore player attacks MF4_QUICKTORETALIATE= 0x00000002, // Always switch targets when hurt MF4_NOICEDEATH = 0x00000004, // Actor never enters an ice death, not even the generic one @@ -262,9 +271,12 @@ enum MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim MF4_FRIGHTENED = 0x40000000, // Monster runs away from player MF4_BOSSSPAWNED = 0x80000000, // Spawned by a boss spawn cube - +}; + // --- mobj.flags5 --- +enum ActorFlag5 +{ MF5_DONTDRAIN = 0x00000001, // cannot be drained health from. /* = 0x00000002, reserved for use by scripting branch */ MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. @@ -298,9 +310,11 @@ enum MF5_INCONVERSATION = 0x20000000, // Actor is having a conversation MF5_PAINLESS = 0x40000000, // Actor always inflicts painless damage. MF5_MOVEWITHSECTOR = 0x80000000, // P_ChangeSector() will still process this actor if it has MF_NOBLOCKMAP +}; // --- mobj.flags6 --- - +enum ActorFlag6 +{ MF6_NOBOSSRIP = 0x00000001, // For rippermissiles: Don't rip through bosses. MF6_THRUSPECIES = 0x00000002, // Actors passes through other of the same species. MF6_MTHRUSPECIES = 0x00000004, // Missile passes through actors of its shooter's species. @@ -333,9 +347,11 @@ enum MF6_NOTAUTOAIMED = 0x20000000, // Do not subject actor to player autoaim. MF6_NOTONAUTOMAP = 0x40000000, // will not be shown on automap with the 'scanner' powerup. MF6_RELATIVETOFLOOR = 0x80000000, // [RC] Make flying actors be affected by lifts. +}; // --- mobj.flags7 --- - +enum ActorFlag7 +{ MF7_NEVERTARGET = 0x00000001, // can not be targetted at all, even if monster friendliness is considered. MF7_NOTELESTOMP = 0x00000002, // cannot telefrag under any circumstances (even when set by MAPINFO) MF7_ALWAYSTELEFRAG = 0x00000004, // will unconditionally be telefragged when in the way. Overrides all other settings. @@ -354,11 +370,11 @@ enum MF7_HITMASTER = 0x00008000, // Same as HITTARGET, except it's master instead of target. MF7_HITTRACER = 0x00010000, // Same as HITTARGET, but for tracer. MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly - - +}; // --- mobj.renderflags --- - +enum ActorRenderFlag +{ RF_XFLIP = 0x0001, // Flip sprite horizontally RF_YFLIP = 0x0002, // Flip sprite vertically RF_ONESIDED = 0x0004, // Wall/floor sprite is visible from front only @@ -387,10 +403,6 @@ enum RF_FORCEYBILLBOARD = 0x10000, // [BB] OpenGL only: draw with y axis billboard, i.e. anchored to the floor (overrides gl_billboard_mode setting) RF_FORCEXYBILLBOARD = 0x20000, // [BB] OpenGL only: draw with xy axis billboard, i.e. unanchored (overrides gl_billboard_mode setting) - -// --- dummies for unknown/unimplemented Strife flags --- - - MF_STRIFEx8000000 = 0, // seems related to MF_SHADOW }; #define TRANSLUC25 (FRACUNIT/4) @@ -419,7 +431,7 @@ enum replace_t ALLOW_REPLACE = 1 }; -enum EBounceFlags +enum ActorBounceFlag { BOUNCE_Walls = 1<<0, // bounces off of walls BOUNCE_Floors = 1<<1, // bounces off of floors @@ -473,6 +485,26 @@ enum EBounceFlags }; +// [TP] Flagset definitions +typedef TFlags ActorFlags; +typedef TFlags ActorFlags2; +typedef TFlags ActorFlags3; +typedef TFlags ActorFlags4; +typedef TFlags ActorFlags5; +typedef TFlags ActorFlags6; +typedef TFlags ActorFlags7; +typedef TFlags ActorRenderFlags; +typedef TFlags ActorBounceFlags; +DEFINE_TFLAGS_OPERATORS (ActorFlags) +DEFINE_TFLAGS_OPERATORS (ActorFlags2) +DEFINE_TFLAGS_OPERATORS (ActorFlags3) +DEFINE_TFLAGS_OPERATORS (ActorFlags4) +DEFINE_TFLAGS_OPERATORS (ActorFlags5) +DEFINE_TFLAGS_OPERATORS (ActorFlags6) +DEFINE_TFLAGS_OPERATORS (ActorFlags7) +DEFINE_TFLAGS_OPERATORS (ActorRenderFlags) +DEFINE_TFLAGS_OPERATORS (ActorBounceFlags) + // Used to affect the logic for thing activation through death, USESPECIAL and BUMPSPECIAL // "thing" refers to what has the flag and the special, "trigger" refers to what used or bumped it enum EThingSpecialActivationType @@ -838,7 +870,7 @@ public: BYTE frame; // sprite frame to draw fixed_t scaleX, scaleY; // Scaling values; FRACUNIT is normal size FRenderStyle RenderStyle; // Style to draw this actor with - DWORD renderflags; // Different rendering flags + ActorRenderFlags renderflags; // Different rendering flags FTextureID picnum; // Draw this instead of sprite if valid DWORD effects; // [RH] see p_effect.h fixed_t alpha; @@ -864,13 +896,13 @@ public: FState *state; SDWORD Damage; // For missiles and monster railgun int projectileKickback; - DWORD flags; - DWORD flags2; // Heretic flags - DWORD flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable - DWORD flags4; // [RH] Even more flags! - DWORD flags5; // OMG! We need another one. - DWORD flags6; // Shit! Where did all the flags go? - DWORD flags7; // WHO WANTS TO BET ON 8!? + ActorFlags flags; + ActorFlags2 flags2; // Heretic flags + ActorFlags3 flags3; // [RH] Hexen/Heretic actor-dependant behavior made flaggable + ActorFlags4 flags4; // [RH] Even more flags! + ActorFlags5 flags5; // OMG! We need another one. + ActorFlags6 flags6; // Shit! Where did all the flags go? + ActorFlags7 flags7; // WHO WANTS TO BET ON 8!? // [BB] If 0, everybody can see the actor, if > 0, only members of team (VisibleToTeam-1) can see it. DWORD VisibleToTeam; @@ -916,7 +948,7 @@ public: BYTE boomwaterlevel; // splash information for non-swimmable water sectors BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack. SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0) - WORD BounceFlags; // which bouncing type? + ActorBounceFlags BounceFlags; // which bouncing type? DWORD SpawnFlags; // Increased to DWORD because of Doom 64 fixed_t meleerange; // specifies how far a melee attack reaches. fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore diff --git a/src/b_func.cpp b/src/b_func.cpp index 2800c01c5..f93625612 100644 --- a/src/b_func.cpp +++ b/src/b_func.cpp @@ -544,7 +544,7 @@ angle_t DBot::FireRox (AActor *enemy, ticcmd_t *cmd) // creating side-effects during gameplay. bool FCajunMaster::SafeCheckPosition (AActor *actor, fixed_t x, fixed_t y, FCheckPosition &tm) { - int savedFlags = actor->flags; + ActorFlags savedFlags = actor->flags; actor->flags &= ~MF_PICKUP; bool res = P_CheckPosition (actor, x, y, tm); actor->flags = savedFlags; diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 4a436c0a8..7d3a5f0ee 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1135,31 +1135,31 @@ static int PatchThing (int thingy) // triggering line effects and can teleport when the missile flag is removed. info->flags2 &= ~MF2_NOTELEPORT; } - info->flags = value[0]; + info->flags = ActorFlags::FromInt (value[0]); } if (vchanged[1]) { - info->flags2 = value[1]; + info->flags2 = ActorFlags2::FromInt (value[1]); if (info->flags2 & 0x00000004) // old BOUNCE1 { - info->flags2 &= ~4; + info->flags2 &= ActorFlags2::FromInt (~4); info->BounceFlags = BOUNCE_DoomCompat; } // Damage types that once were flags but now are not if (info->flags2 & 0x20000000) { info->DamageType = NAME_Ice; - info->flags2 &= ~0x20000000; + info->flags2 &= ActorFlags2::FromInt (~0x20000000); } if (info->flags2 & 0x10000) { info->DamageType = NAME_Fire; - info->flags2 &= ~0x10000; + info->flags2 &= ActorFlags2::FromInt (~0x10000); } if (info->flags2 & 1) { info->gravity = FRACUNIT/4; - info->flags2 &= ~1; + info->flags2 &= ActorFlags2::FromInt (~1); } } if (vchanged[2]) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 0bddcd7fd..165c51c66 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1216,11 +1216,14 @@ void FParser::SF_ObjFlag(void) if(mo && flagnum<26) // nullptr check { + DWORD tempflags = mo->flags; + // remove old bit - mo->flags &= ~(1 << flagnum); + tempflags &= ~(1 << flagnum); // make the new flag - mo->flags |= (!!intvalue(t_argv[2])) << flagnum; + tempflags |= (!!intvalue(t_argv[2])) << flagnum; + mo->flags = ActorFlags::FromInt (tempflags); } } t_return.type = svt_int; diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index e3433f12e..0d3513e37 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -228,7 +228,7 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, mo->angle = pmo->angle; mo->player = player; mo->reactiontime = 18; - mo->flags = pmo->special2 & ~MF_JUSTHIT; + mo->flags = ActorFlags::FromInt (pmo->special2) & ~MF_JUSTHIT; mo->velx = 0; mo->vely = 0; player->velx = 0; @@ -438,7 +438,7 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) actor->SetOrigin (beast->x, beast->y, beast->z); actor->flags |= MF_SOLID; beast->flags &= ~MF_SOLID; - int beastflags6 = beast->flags6; + ActorFlags6 beastflags6 = beast->flags6; beast->flags6 &= ~MF6_TOUCHY; if (!force && !P_TestMobjLocation (actor)) { // Didn't fit diff --git a/src/g_shared/a_movingcamera.cpp b/src/g_shared/a_movingcamera.cpp index 83d0d4695..0f847fa41 100644 --- a/src/g_shared/a_movingcamera.cpp +++ b/src/g_shared/a_movingcamera.cpp @@ -603,9 +603,9 @@ void AActorMover::Deactivate (AActor *activator) if (tracer != NULL) { tracer->UnlinkFromWorld (); - tracer->flags = special1; + tracer->flags = ActorFlags::FromInt (special1); tracer->LinkToWorld (); - tracer->flags2 = special2; + tracer->flags2 = ActorFlags2::FromInt (special2); } } } diff --git a/src/g_shared/a_sharedglobal.h b/src/g_shared/a_sharedglobal.h index 3d9e4ed10..2688249ea 100644 --- a/src/g_shared/a_sharedglobal.h +++ b/src/g_shared/a_sharedglobal.h @@ -202,7 +202,7 @@ public: TObjPtr UnmorphedMe; int UnmorphTime, MorphStyle; const PClass *MorphExitFlash; - DWORD FlagsSave; + ActorFlags FlagsSave; }; class AMapMarker : public AActor diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 8894bc936..aaf965994 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3387,7 +3387,7 @@ int DLevelScript::DoSpawn (int type, fixed_t x, fixed_t y, fixed_t z, int tid, i actor = Spawn (info, x, y, z, ALLOW_REPLACE); if (actor != NULL) { - DWORD oldFlags2 = actor->flags2; + ActorFlags2 oldFlags2 = actor->flags2; actor->flags2 |= MF2_PASSMOBJ; if (force || P_TestMobjLocation (actor)) { diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index c6fffd87c..0890e33d4 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -894,5 +894,5 @@ void ACustomSprite::BeginPlay () if (cstat & 8) renderflags |= RF_YFLIP; // set face/wall/floor flags - renderflags |= ((cstat >> 4) & 3) << 12; + renderflags |= ActorRenderFlags::FromInt (((cstat >> 4) & 3) << 12); } diff --git a/src/p_enemy.cpp b/src/p_enemy.cpp index 540aa119e..3e17a85f3 100644 --- a/src/p_enemy.cpp +++ b/src/p_enemy.cpp @@ -2573,7 +2573,7 @@ static bool P_CheckForResurrection(AActor *self, bool usevilestates) fixed_t oldheight = corpsehit->height; fixed_t oldradius = corpsehit->radius; - int oldflags = corpsehit->flags; + ActorFlags oldflags = corpsehit->flags; corpsehit->flags |= MF_SOLID; corpsehit->height = corpsehit->GetDefault()->height; diff --git a/src/p_map.cpp b/src/p_map.cpp index 1ad1728ce..b16ddb179 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1590,7 +1590,7 @@ bool P_CheckPosition(AActor *thing, fixed_t x, fixed_t y, bool actorsonly) bool P_TestMobjLocation(AActor *mobj) { - int flags; + ActorFlags flags; flags = mobj->flags; mobj->flags &= ~MF_PICKUP; @@ -4916,7 +4916,7 @@ EXTERN_CVAR(Int, cl_bloodtype) bool P_AdjustFloorCeil(AActor *thing, FChangePosition *cpos) { - int flags2 = thing->flags2 & MF2_PASSMOBJ; + ActorFlags2 flags2 = thing->flags2 & MF2_PASSMOBJ; FCheckPosition tm; if ((thing->flags2 & MF2_PASSMOBJ) && (thing->flags3 & MF3_ISMONSTER)) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 76afec801..ab658f193 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -481,7 +481,7 @@ bool AActor::SetState (FState *newstate, bool nofunction) } state = newstate; tics = GetTics(newstate); - renderflags = (renderflags & ~RF_FULLBRIGHT) | newstate->GetFullbright(); + renderflags = (renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (newstate->GetFullbright()); newsprite = newstate->sprite; if (newsprite != SPR_FIXED) { // okay to change sprite and/or frame @@ -3940,7 +3940,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t actor->sprite = st->sprite; actor->frame = st->GetFrame(); - actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | st->GetFullbright(); + actor->renderflags = (actor->renderflags & ~RF_FULLBRIGHT) | ActorRenderFlags::FromInt (st->GetFullbright()); actor->touching_sectorlist = NULL; // NULL head of sector list // phares 3/13/98 if (G_SkillProperty(SKILLP_FastMonsters)) actor->Speed = actor->GetClass()->Meta.GetMetaFixed(AMETA_FastSpeed, actor->Speed); diff --git a/src/p_things.cpp b/src/p_things.cpp index 423ecd042..acae5fe5c 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -97,7 +97,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, if (mobj != NULL) { - DWORD oldFlags2 = mobj->flags2; + ActorFlags2 oldFlags2 = mobj->flags2; mobj->flags2 |= MF2_PASSMOBJ; if (P_TestMobjLocation (mobj)) { @@ -440,7 +440,7 @@ bool P_Thing_Raise(AActor *thing, AActor *raiser) // [RH] Check against real height and radius fixed_t oldheight = thing->height; fixed_t oldradius = thing->radius; - int oldflags = thing->flags; + ActorFlags oldflags = thing->flags; thing->flags |= MF_SOLID; thing->height = info->height; // [RH] Use real height @@ -479,7 +479,7 @@ bool P_Thing_CanRaise(AActor *thing) AActor *info = thing->GetDefault(); // Check against real height and radius - int oldflags = thing->flags; + ActorFlags oldflags = thing->flags; fixed_t oldheight = thing->height; fixed_t oldradius = thing->radius; diff --git a/src/r_main.cpp b/src/r_main.cpp index dbf4cbeb5..5da0b8992 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -790,7 +790,7 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) P_FindParticleSubsectors (); WallCycles.Clock(); - DWORD savedflags = camera->renderflags; + ActorRenderFlags savedflags = camera->renderflags; // Never draw the player unless in chasecam mode if (!r_showviewer) { diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index cb59f8a1f..3bb6061ba 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2023,10 +2023,10 @@ static bool InitSpawnedItem(AActor *self, AActor *mo, int flags) mo->RenderStyle = self->RenderStyle; } - if (flags & SIXF_TRANSFERSPRITEFRAME) - { - mo->sprite = self->sprite; - mo->frame = self->frame; + if (flags & SIXF_TRANSFERSPRITEFRAME) + { + mo->sprite = self->sprite; + mo->frame = self->frame; } if (flags & SIXF_TRANSFERROLL) @@ -3766,7 +3766,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag) } else { - DWORD *flagp = (DWORD*) (((char*)self) + fd->structoffset); + ActorFlags *flagp = (ActorFlags*) (((char*)self) + fd->structoffset); // If these 2 flags get changed we need to update the blockmap and sector links. bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR); @@ -4029,19 +4029,19 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetPitch) ref->SetPitch(pitch, !!(flags & SPF_INTERPOLATE)); } -//=========================================================================== -// -// [Nash] A_SetRoll -// -// Set actor's roll (in degrees). -// -//=========================================================================== - -DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) -{ - ACTION_PARAM_START(3); - ACTION_PARAM_ANGLE(roll, 0); - ACTION_PARAM_INT(flags, 1); +//=========================================================================== +// +// [Nash] A_SetRoll +// +// Set actor's roll (in degrees). +// +//=========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_ANGLE(roll, 0); + ACTION_PARAM_INT(flags, 1); ACTION_PARAM_INT(ptr, 2); AActor *ref = COPY_AAPTR(self, ptr); @@ -4050,9 +4050,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetRoll) { ACTION_SET_RESULT(false); return; - } - ref->SetRoll(roll, !!(flags & SPF_INTERPOLATE)); -} + } + ref->SetRoll(roll, !!(flags & SPF_INTERPOLATE)); +} //=========================================================================== // diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index e91c2ee65..cce1e623e 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -60,7 +60,7 @@ static TArray variables; #define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0 } #define DEFINE_DUMMY_FLAG(name) { DEPF_UNUSED, #name, -1, 0 } -static FFlagDef ActorFlags[]= +static FFlagDef ActorFlagDefs[]= { DEFINE_FLAG(MF, PICKUP, APlayerPawn, flags), DEFINE_FLAG(MF, SPECIAL, APlayerPawn, flags), @@ -302,7 +302,7 @@ static FFlagDef ActorFlags[]= DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless }; -static FFlagDef InventoryFlags[] = +static FFlagDef InventoryFlagDefs[] = { // Inventory flags DEFINE_FLAG(IF, QUIET, AInventory, ItemFlags), @@ -329,7 +329,7 @@ static FFlagDef InventoryFlags[] = DEFINE_DEPRECATED_FLAG(PICKUPFLASH), DEFINE_DEPRECATED_FLAG(INTERHUBSTRIP),}; -static FFlagDef WeaponFlags[] = +static FFlagDef WeaponFlagDefs[] = { // Weapon flags DEFINE_FLAG(WIF, NOAUTOFIRE, AWeapon, WeaponFlags), @@ -356,7 +356,7 @@ static FFlagDef WeaponFlags[] = DEFINE_DUMMY_FLAG(ALLOW_WITH_RESPAWN_INVUL), }; -static FFlagDef PlayerPawnFlags[] = +static FFlagDef PlayerPawnFlagDefs[] = { // PlayerPawn flags DEFINE_FLAG(PPF, NOTHRUSTWHENINVUL, APlayerPawn, PlayerFlags), @@ -364,7 +364,7 @@ static FFlagDef PlayerPawnFlags[] = DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags), }; -static FFlagDef PowerSpeedFlags[] = +static FFlagDef PowerSpeedFlagDefs[] = { // PowerSpeed flags DEFINE_FLAG(PSF, NOTRAIL, APowerSpeed, SpeedFlags), @@ -372,11 +372,11 @@ static FFlagDef PowerSpeedFlags[] = static const struct FFlagList { const PClass *Type; FFlagDef *Defs; int NumDefs; } FlagLists[] = { - { RUNTIME_CLASS(AActor), ActorFlags, countof(ActorFlags) }, - { RUNTIME_CLASS(AInventory), InventoryFlags, countof(InventoryFlags) }, - { RUNTIME_CLASS(AWeapon), WeaponFlags, countof(WeaponFlags) }, - { RUNTIME_CLASS(APlayerPawn), PlayerPawnFlags,countof(PlayerPawnFlags) }, - { RUNTIME_CLASS(APowerSpeed), PowerSpeedFlags,countof(PowerSpeedFlags) }, + { RUNTIME_CLASS(AActor), ActorFlagDefs, countof(ActorFlagDefs) }, + { RUNTIME_CLASS(AInventory), InventoryFlagDefs, countof(InventoryFlagDefs) }, + { RUNTIME_CLASS(AWeapon), WeaponFlagDefs, countof(WeaponFlagDefs) }, + { RUNTIME_CLASS(APlayerPawn), PlayerPawnFlagDefs, countof(PlayerPawnFlagDefs) }, + { RUNTIME_CLASS(APowerSpeed), PowerSpeedFlagDefs, countof(PowerSpeedFlagDefs) }, }; #define NUM_FLAG_LISTS (countof(FlagLists)) @@ -463,11 +463,11 @@ FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2) const char *GetFlagName(unsigned int flagnum, int flagoffset) { - for(unsigned i = 0; i < countof(ActorFlags); i++) + for(unsigned i = 0; i < countof(ActorFlagDefs); i++) { - if (ActorFlags[i].flagbit == flagnum && ActorFlags[i].structoffset == flagoffset) + if (ActorFlagDefs[i].flagbit == flagnum && ActorFlagDefs[i].structoffset == flagoffset) { - return ActorFlags[i].name; + return ActorFlagDefs[i].name; } } return "(unknown)"; // return something printable diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 4ddf951ac..79e8bc72c 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1062,7 +1062,7 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor) DEFINE_PROPERTY(bouncetype, S, Actor) { static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", "Grenade", "Classic", NULL }; - static const int flags[] = { BOUNCE_None, + static const ActorBounceFlag flags[] = { BOUNCE_None, BOUNCE_Doom, BOUNCE_Heretic, BOUNCE_Hexen, BOUNCE_DoomCompat, BOUNCE_HereticCompat, BOUNCE_HexenCompat, BOUNCE_Grenade, BOUNCE_Classic, }; @@ -1322,13 +1322,13 @@ DEFINE_PROPERTY(species, S, Actor) //========================================================================== DEFINE_PROPERTY(clearflags, 0, Actor) { - defaults->flags = - defaults->flags3 = - defaults->flags4 = - defaults->flags5 = - defaults->flags6 = - defaults->flags7 = 0; + defaults->flags = 0; defaults->flags2 &= MF2_ARGSDEFINED; // this flag must not be cleared + defaults->flags3 = 0; + defaults->flags4 = 0; + defaults->flags5 = 0; + defaults->flags6 = 0; + defaults->flags7 = 0; } //========================================================================== From 1799ae91c92f24b03036c29ee7570f4679902a5f Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Tue, 7 Apr 2015 11:14:02 -0500 Subject: [PATCH 05/16] - Allow teleport fogs to set the teleporting actors as their targets, so modders can create interactions between the two. - Fixed: P_MoveThing had source and destination fog spawning backwards. - Fixed a case where the NOTELEPORT flag would be ignored on A_Teleport. - Added pointer selection to A_Teleport. Defaults to AAPTR_DEFAULT (calling actor). State jumps will only be done by the calling actor. --- src/p_mobj.cpp | 4 +- src/p_things.cpp | 6 +-- src/thingdef/thingdef_codeptr.cpp | 82 ++++++++++++++++++++----------- wadsrc/static/actors/actor.txt | 2 +- 4 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2571413c8..bbf6e16bf 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2699,10 +2699,10 @@ void P_NightmareRespawn (AActor *mobj) mo->PrevZ = z; // Do not interpolate Z position if we changed it since spawning. // spawn a teleport fog at old spot because of removal of the body? - P_SpawnTeleportFog(mobj, mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, true); + P_SpawnTeleportFog(mobj, mobj->x, mobj->y, mobj->z + TELEFOGHEIGHT, true, true); // spawn a teleport fog at the new spot - P_SpawnTeleportFog(mobj, x, y, z + TELEFOGHEIGHT, false); + P_SpawnTeleportFog(mobj, x, y, z + TELEFOGHEIGHT, false, true); // remove the old monster mobj->Destroy (); diff --git a/src/p_things.cpp b/src/p_things.cpp index faf1091d5..982a57f16 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -94,7 +94,7 @@ bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, mobj->angle = (angle != ANGLE_MAX ? angle : spot->angle); if (fog) { - P_SpawnTeleportFog(mobj, spot->x, spot->y, spot->z + TELEFOGHEIGHT, false); + P_SpawnTeleportFog(mobj, spot->x, spot->y, spot->z + TELEFOGHEIGHT, false, true); } if (mobj->flags & MF_SPECIAL) mobj->flags |= MF_DROPPED; // Don't respawn @@ -132,8 +132,8 @@ bool P_MoveThing(AActor *source, fixed_t x, fixed_t y, fixed_t z, bool fog) { if (fog) { - P_SpawnTeleportFog(source, x, y, z); - P_SpawnTeleportFog(source, oldx, oldy, oldz, false); + P_SpawnTeleportFog(source, x, y, z, false, true); + P_SpawnTeleportFog(source, oldx, oldy, oldz, true, true); } source->PrevX = x; source->PrevY = y; diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index cb59f8a1f..3d218083e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3077,8 +3077,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Respawn) if (flags & RSF_FOG) { - P_SpawnTeleportFog(self, oldx, oldy, oldz, true); - P_SpawnTeleportFog(self, self->x, self->y, self->z, false); + P_SpawnTeleportFog(self, oldx, oldy, oldz, true, true); + P_SpawnTeleportFog(self, self->x, self->y, self->z, false, true); } if (self->CountsAsKill()) { @@ -4249,9 +4249,9 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetUserArray) //=========================================================================== // -// A_Teleport(optional state teleportstate, optional class targettype, -// optional class fogtype, optional int flags, optional fixed mindist, -// optional fixed maxdist) +// A_Teleport([state teleportstate, [class targettype, +// [class fogtype, [int flags, [fixed mindist, +// [fixed maxdist]]]]]]) // // Attempts to teleport to a targettype at least mindist away and at most // maxdist away (0 means unlimited). If successful, spawn a fogtype at old @@ -4274,13 +4274,25 @@ enum T_Flags DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) { - ACTION_PARAM_START(6); + ACTION_PARAM_START(7); ACTION_PARAM_STATE(TeleportState, 0); ACTION_PARAM_CLASS(TargetType, 1); ACTION_PARAM_CLASS(FogType, 2); ACTION_PARAM_INT(Flags, 3); ACTION_PARAM_FIXED(MinDist, 4); ACTION_PARAM_FIXED(MaxDist, 5); + ACTION_PARAM_INT(ptr, 6); + + AActor *ref = COPY_AAPTR(self, ptr); + + if (!ref) + { + ACTION_SET_RESULT(false); + return; + } + + if (ref->flags2 & MF2_NOTELEPORT) + return; // Randomly choose not to teleport like A_Srcr2Decide. if (Flags & TF_RANDOMDECIDE) @@ -4290,7 +4302,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) 192, 120, 120, 120, 64, 64, 32, 16, 0 }; - unsigned int chanceindex = self->health / ((self->SpawnHealth()/8 == 0) ? 1 : self->SpawnHealth()/8); + unsigned int chanceindex = ref->health / ((ref->SpawnHealth()/8 == 0) ? 1 : ref->SpawnHealth()/8); if (chanceindex >= countof(chance)) { @@ -4301,37 +4313,42 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) } DSpotState *state = DSpotState::GetSpotState(); - if (state == NULL) return; + if (state == NULL) + return; - if (!TargetType) TargetType = PClass::FindClass("BossSpot"); + if (!TargetType) + TargetType = PClass::FindClass("BossSpot"); - AActor * spot = state->GetSpotWithMinMaxDistance(TargetType, self->x, self->y, MinDist, MaxDist); - if (spot == NULL) return; + AActor * spot = state->GetSpotWithMinMaxDistance(TargetType, ref->x, ref->y, MinDist, MaxDist); + if (spot == NULL) + return; - fixed_t prevX = self->x; - fixed_t prevY = self->y; - fixed_t prevZ = self->z; + fixed_t prevX = ref->x; + fixed_t prevY = ref->y; + fixed_t prevZ = ref->z; fixed_t aboveFloor = spot->z - spot->floorz; fixed_t finalz = spot->floorz + aboveFloor; - if (spot->z + self->height > spot->ceilingz) - finalz = spot->ceilingz - self->height; + if (spot->z + ref->height > spot->ceilingz) + finalz = spot->ceilingz - ref->height; else if (spot->z < spot->floorz) finalz = spot->floorz; //Take precedence and cooperate with telefragging first. - bool teleResult = P_TeleportMove(self, spot->x, spot->y, finalz, Flags & TF_TELEFRAG); + bool teleResult = P_TeleportMove(ref, spot->x, spot->y, finalz, Flags & TF_TELEFRAG); - if (Flags & TF_FORCED) + if (!teleResult && (Flags & TF_FORCED)) { //If for some reason the original move didn't work, regardless of telefrag, force it to move. - self->SetOrigin(spot->x, spot->y, finalz); + ref->SetOrigin(spot->x, spot->y, finalz); teleResult = true; } + AActor *fog1 = NULL, *fog2 = NULL; if (teleResult) { + //If a fog type is defined in the parameter, or the user wants to use the actor's predefined fogs, //and if there's no desire to be fogless, spawn a fog based upon settings. if (FogType || (Flags & TF_USEACTORFOG)) @@ -4339,31 +4356,40 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) if (!(Flags & TF_NOSRCFOG)) { if (Flags & TF_USEACTORFOG) - P_SpawnTeleportFog(self, prevX, prevY, prevZ, true); + P_SpawnTeleportFog(ref, prevX, prevY, prevZ, true, true); else - Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE); + { + fog1 = Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE); + if (fog1 != NULL) + fog1->target = ref; + } } if (!(Flags & TF_NODESTFOG)) { if (Flags & TF_USEACTORFOG) - P_SpawnTeleportFog(self, self->x, self->y, self->z, false); + P_SpawnTeleportFog(ref, ref->x, ref->y, ref->z, false, true); else - Spawn(FogType, self->x, self->y, self->z, ALLOW_REPLACE); + { + fog2 = Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE); + if (fog2 != NULL) + fog2->target = ref; + } } + } if (Flags & TF_USESPOTZ) - self->z = spot->z; + ref->z = spot->z; else - self->z = self->floorz; + ref->z = ref->floorz; if (!(Flags & TF_KEEPANGLE)) - self->angle = spot->angle; + ref->angle = spot->angle; if (!(Flags & TF_KEEPVELOCITY)) - self->velx = self->vely = self->velz = 0; + ref->velx = ref->vely = ref->velz = 0; - if (!(Flags & TF_NOJUMP)) + if (!(Flags & TF_NOJUMP)) //The state jump should only happen with the calling actor. { ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! if (TeleportState == NULL) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 7d8fad5bf..0bd9ed31a 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -248,7 +248,7 @@ ACTOR Actor native //: Thinker action native A_CheckCeiling(state label); action native A_PlayerSkinCheck(state label); action native A_BasicAttack(int meleedamage, sound meleesound, class missiletype, float missileheight); - action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0); + action native A_Teleport(state teleportstate = "", class targettype = "BossSpot", class fogtype = "TeleportFog", int flags = 0, float mindist = 0, float maxdist = 0, int ptr = AAPTR_DEFAULT); action native A_Warp(int ptr_destination, float xofs = 0, float yofs = 0, float zofs = 0, float angle = 0, int flags = 0, state success_state = ""); action native A_ThrowGrenade(class itemtype, float zheight = 0, float xyvel = 0, float zvel = 0, bool useammo = true); action native A_Weave(int xspeed, int yspeed, float xdist, float ydist); From a6287a47068689f0732c5658d566e5940d3ab4e9 Mon Sep 17 00:00:00 2001 From: arezey Date: Sun, 12 Apr 2015 02:11:51 +0300 Subject: [PATCH 06/16] Fix compilation with CMake on Windows when some other building tool than msbuild is used. --- src/CMakeLists.txt | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6e43c0d46..98507327e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1158,10 +1158,17 @@ if( MSVC ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\"") endif( ZDOOM_GENERATE_MAPFILE ) - add_custom_command(TARGET zdoom POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#1 - COMMENT "Adding manifest..." - ) + if( NO_GENERATOR_EXPRESSIONS ) + add_custom_command(TARGET zdoom POST_BUILD + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$(TargetDir)$(TargetFileName)\"\;\#1 + COMMENT "Adding manifest..." + ) + else( NO_GENERATOR_EXPRESSIONS ) + add_custom_command(TARGET zdoom POST_BUILD + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:$ + COMMENT "Adding manifest..." + ) + endif( NO_GENERATOR_EXPRESSIONS ) create_default_target_launcher( zdoom WORKING_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) endif( MSVC ) From 810a1dc28d8dfdf5ab141bb6492d775324ea2bbf Mon Sep 17 00:00:00 2001 From: arezey Date: Sun, 12 Apr 2015 02:44:12 +0300 Subject: [PATCH 07/16] Fixed the way mt.exe is invoked --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98507327e..f50b90dc9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1165,7 +1165,7 @@ if( MSVC ) ) else( NO_GENERATOR_EXPRESSIONS ) add_custom_command(TARGET zdoom POST_BUILD - COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:$ + COMMAND "mt.exe" -manifest \"${CMAKE_CURRENT_SOURCE_DIR}\\win32\\zdoom.exe.manifest\" -outputresource:\"$\"\;\#1 COMMENT "Adding manifest..." ) endif( NO_GENERATOR_EXPRESSIONS ) From 43053b89a5cc3cd4ce717a129005c29433e0db61 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Sun, 26 Apr 2015 10:06:13 -0500 Subject: [PATCH 08/16] - Set the morphing and unmorphing actor as target for the teleport fog. This will allow for better interactions on what should happen between the morphee without needing to make monster AI needing to search for them in particular or rely upon TIDs. --- src/g_shared/a_morph.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/g_shared/a_morph.cpp b/src/g_shared/a_morph.cpp index e3433f12e..c42523997 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -105,7 +105,7 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i morphed->flags |= actor->flags & (MF_SHADOW|MF_NOGRAVITY); morphed->flags2 |= actor->flags2 & MF2_FLY; morphed->flags3 |= actor->flags3 & MF3_GHOST; - Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); + AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); actor->player = NULL; actor->flags &= ~(MF_SOLID|MF_SHOOTABLE); actor->flags |= MF_UNMORPHED; @@ -156,6 +156,8 @@ bool P_MorphPlayer (player_t *activator, player_t *p, const PClass *spawntype, i p->camera = morphed; } morphed->ScoreIcon = actor->ScoreIcon; // [GRB] + if (eflash) + eflash->target = p->mo; return true; } @@ -310,9 +312,11 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag, } angle = mo->angle >> ANGLETOFINESHIFT; + AActor *eflash = NULL; if (exit_flash != NULL) { - Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE); + eflash = Spawn(exit_flash, pmo->x + 20*finecosine[angle], pmo->y + 20*finesine[angle], pmo->z + TELEFOGHEIGHT, ALLOW_REPLACE); + if (eflash) eflash->target = mo; } mo->SetupWeaponSlots(); // Use original class's weapon slots. beastweap = player->ReadyWeapon; @@ -411,7 +415,9 @@ bool P_MorphMonster (AActor *actor, const PClass *spawntype, int duration, int s actor->flags &= ~(MF_SOLID|MF_SHOOTABLE); actor->flags |= MF_UNMORPHED; actor->renderflags |= RF_INVISIBLE; - Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); + AActor *eflash = Spawn(((enter_flash) ? enter_flash : RUNTIME_CLASS(ATeleportFog)), actor->x, actor->y, actor->z + TELEFOGHEIGHT, ALLOW_REPLACE); + if (eflash) + eflash->target = morphed; return true; } @@ -471,7 +477,9 @@ bool P_UndoMonsterMorph (AMorphedMonster *beast, bool force) DObject::StaticPointerSubstitution (beast, actor); const PClass *exit_flash = beast->MorphExitFlash; beast->Destroy (); - Spawn(exit_flash, beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE); + AActor *eflash = Spawn(exit_flash, beast->x, beast->y, beast->z + TELEFOGHEIGHT, ALLOW_REPLACE); + if (eflash) + eflash->target = actor; return true; } From 9880af1b0c66324dcc058e4c07115b12d099e3e9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 30 Apr 2015 09:18:13 +0200 Subject: [PATCH 09/16] - this line got lost during conflict resolution. --- src/actor.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/actor.h b/src/actor.h index 855bc5942..04e4d722e 100644 --- a/src/actor.h +++ b/src/actor.h @@ -355,6 +355,7 @@ enum MF7_HITTRACER = 0x00010000, // Same as HITTARGET, but for tracer. MF7_FLYCHEAT = 0x00020000, // must be part of the actor so that it can be tracked properly MF7_NODECAL = 0x00040000, // [ZK] Forces puff to have no impact decal + MF7_FORCEDECAL = 0x00080000, // [ZK] Forces puff's decal to override the weapon's. // --- mobj.renderflags --- RF_XFLIP = 0x0001, // Flip sprite horizontally From 50a3f8a3d2eed2b463457f2cdceef866ed8e8d07 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 30 Apr 2015 12:31:47 +0200 Subject: [PATCH 10/16] - fixed copy/paste error. --- src/thingdef/thingdef_codeptr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 10a64812e..b0147113e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -4349,7 +4349,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_Teleport) P_SpawnTeleportFog(ref, ref->x, ref->y, ref->z, false, true); else { - fog2 = Spawn(FogType, prevX, prevY, prevZ, ALLOW_REPLACE); + fog2 = Spawn(FogType, ref->x, ref->y, ref->z, ALLOW_REPLACE); if (fog2 != NULL) fog2->target = ref; } From cda4fece1b41b0675feed62cb270640aa3933873 Mon Sep 17 00:00:00 2001 From: Edoardo Prezioso Date: Thu, 30 Apr 2015 12:35:29 +0200 Subject: [PATCH 11/16] - Fixed compiler errors and warnings from TFlags. --- src/d_dehacked.cpp | 4 ++-- src/p_interaction.cpp | 2 +- src/p_mobj.cpp | 18 +++++++++--------- src/tflags.h | 3 ++- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 7d3a5f0ee..a994f7603 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -1180,8 +1180,8 @@ static int PatchThing (int thingy) else info->renderflags &= ~RF_INVISIBLE; } - DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags, info->flags2, - info->flags, info->flags2); + DPrintf ("Bits: %d,%d (0x%08x,0x%08x)\n", info->flags.GetValue(), info->flags2.GetValue(), + info->flags.GetValue(), info->flags2.GetValue()); } else if (stricmp (Line1, "ID #") == 0) { diff --git a/src/p_interaction.cpp b/src/p_interaction.cpp index 36f50a897..e25dcf7ac 100644 --- a/src/p_interaction.cpp +++ b/src/p_interaction.cpp @@ -660,7 +660,7 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags) FState *diestate = NULL; int gibhealth = GibHealth(); - int iflags4 = inflictor == NULL ? 0 : inflictor->flags4; + ActorFlags4 iflags4 = inflictor == NULL ? ActorFlags4::FromInt(0) : inflictor->flags4; bool extremelydead = ((health < gibhealth || iflags4 & MF4_EXTREMEDEATH) && !(iflags4 & MF4_NOEXTREMEDEATH)); // Special check for 'extreme' damage type to ensure that it gets recorded properly as an extreme death for subsequent checks. diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index abfe888ec..588bc2dcc 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6465,35 +6465,35 @@ void PrintMiscActorInfo(AActor *query) "OptFuzzy", "Stencil", "Translucent", "Add", "Shaded", "TranslucentStencil", "Shadow", "Subtract", "AddStencil", "AddShaded"}; - Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags); + Printf("%s @ %p has the following flags:\n flags: %x", query->GetTag(), query, query->flags.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags & 1<flags2); + Printf("\n flags2: %x", query->flags2.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags2 & 1<flags3); + Printf("\n flags3: %x", query->flags3.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags3 & 1<flags4); + Printf("\n flags4: %x", query->flags4.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags4 & 1<flags5); + Printf("\n flags5: %x", query->flags5.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags5 & 1<flags6); + Printf("\n flags6: %x", query->flags6.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags6 & 1<flags7); + Printf("\n flags7: %x", query->flags7.GetValue()); for (flagi = 0; flagi <= 31; flagi++) if (query->flags7 & 1<BounceFlags, FIXED2FLOAT(query->bouncefactor), + query->BounceFlags.GetValue(), FIXED2FLOAT(query->bouncefactor), FIXED2FLOAT(query->wallbouncefactor)); /*for (flagi = 0; flagi < 31; flagi++) if (query->BounceFlags & 1<alpha), query->renderflags); + FIXED2FLOAT(query->alpha), query->renderflags.GetValue()); /*for (flagi = 0; flagi < 31; flagi++) if (query->renderflags & 1< Date: Thu, 30 Apr 2015 12:44:19 +0200 Subject: [PATCH 12/16] - Plug some lemon leaks during xlat generation. Found with Address Sanitizer. --- tools/lemon/lemon.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/lemon/lemon.c b/tools/lemon/lemon.c index f4a08f789..5e8f03a8b 100644 --- a/tools/lemon/lemon.c +++ b/tools/lemon/lemon.c @@ -437,7 +437,8 @@ struct acttab { #define acttab_yylookahead(X,N) ((X)->aAction[N].lookahead) /* Free all memory associated with the given acttab */ -void acttab_free(acttab *p){ +void acttab_free(acttab **pp){ + acttab *p = *pp; free( p->aAction ); free( p->aLookahead ); free( p ); @@ -2506,12 +2507,14 @@ struct lemon *gp; ErrorMsg(ps.filename,0,"Can't allocate %d of memory to hold this file.", filesize+1); gp->errorcnt++; + fclose(fp); return; } if( fread(filebuf,1,filesize,fp)!=filesize ){ ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.", filesize); free(filebuf); + fclose(fp); gp->errorcnt++; return; } @@ -3081,9 +3084,11 @@ struct lemon *lemp; in = fopen(tpltname,"rb"); if( in==0 ){ fprintf(stderr,"Can't open the template file \"%s\".\n",templatename); + free(tpltname); lemp->errorcnt++; return 0; } + free(tpltname); return in; } @@ -3942,6 +3947,7 @@ int mhflag; /* Output in makeheaders format if true */ /* Append any addition code the user desires */ tplt_print(out,lemp,lemp->extracode,lemp->extracodeln,&lineno); + acttab_free(&pActtab); fclose(in); fclose(out); return; From 97e63b13199cedd82ee8c1afb9755b744c5432b3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 30 Apr 2015 12:53:44 +0200 Subject: [PATCH 13/16] - split up FBehavior constructor to better be able to weed out broken ACS modules. Please note that this WILL break old savegames from mods which put ACS sources or unrelated data in the ACS namespace! --- src/p_acs.cpp | 38 ++++++++++++++++++++++++++++---------- src/p_acs.h | 3 ++- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 86674c149..f53eddaf0 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1409,7 +1409,17 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader *fr, int len) } } - return new FBehavior (lumpnum, fr, len); + FBehavior * behavior = new FBehavior (); + if (behavior->Init(lumpnum, fr, len)) + { + return behavior; + } + else + { + delete behavior; + Printf("%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); + return NULL; + } } bool FBehavior::StaticCheckAllGood () @@ -1668,11 +1678,8 @@ static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset) return offset; } -FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) +FBehavior::FBehavior() { - BYTE *object; - int i; - NumScripts = 0; NumFunctions = 0; NumArrays = 0; @@ -1684,11 +1691,21 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) Chunks = NULL; Data = NULL; Format = ACS_Unknown; - LumpNum = lumpnum; + LumpNum = -1; memset (MapVarStore, 0, sizeof(MapVarStore)); ModuleName[0] = 0; FunctionProfileData = NULL; +} + + +bool FBehavior::Init(int lumpnum, FileReader * fr, int len) +{ + BYTE *object; + int i; + + LumpNum = lumpnum; + // Now that everything is set up, record this module as being among the loaded modules. // We need to do this before resolving any imports, because an import might (indirectly) // need to resolve exports in this module. The only things that can be exported are @@ -1699,7 +1716,6 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) // 1. If not, corrupt modules cause memory leaks // 2. Corrupt modules won't be reported when a level is being loaded if this function quits before // adding it to the list. - LibraryID = StaticModules.Push (this) << LIBRARYID_SHIFT; if (fr == NULL) len = Wads.LumpLength (lumpnum); @@ -1711,7 +1727,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) // has 24 bytes if it is completely empty. An empty SPTR chunk adds 8 bytes.) if (len < 32) { - return; + return false; } object = new BYTE[len]; @@ -1727,7 +1743,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) if (object[0] != 'A' || object[1] != 'C' || object[2] != 'S') { delete[] object; - return; + return false; } switch (object[3]) @@ -1743,8 +1759,9 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) break; default: delete[] object; - return; + return false; } + LibraryID = StaticModules.Push (this) << LIBRARYID_SHIFT; if (fr == NULL) { @@ -2135,6 +2152,7 @@ FBehavior::FBehavior (int lumpnum, FileReader * fr, int len) } DPrintf ("Loaded %d scripts, %d functions\n", NumScripts, NumFunctions); + return true; } FBehavior::~FBehavior () diff --git a/src/p_acs.h b/src/p_acs.h index 88016f0db..d5971e349 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -283,8 +283,9 @@ enum ACSFormat { ACS_Old, ACS_Enhanced, ACS_LittleEnhanced, ACS_Unknown }; class FBehavior { public: - FBehavior (int lumpnum, FileReader * fr=NULL, int len=0); + FBehavior (); ~FBehavior (); + bool Init(int lumpnum, FileReader * fr = NULL, int len = 0); bool IsGood (); BYTE *FindChunk (DWORD id) const; From 4316740ee917c930bff6a2364936c7ed272259a2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 30 Apr 2015 12:59:26 +0200 Subject: [PATCH 14/16] - some color coding of error messages during ACS loading. (not that I expect that the people these are meant for will read them anyway...) --- src/p_acs.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index f53eddaf0..5cd5774f4 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1391,7 +1391,7 @@ void FBehavior::StaticLoadDefaultModules () } else { - Printf ("Could not find autoloaded ACS library %s\n", sc.String); + Printf (TEXTCOLOR_RED "Could not find autoloaded ACS library %s\n", sc.String); } } } @@ -1417,7 +1417,7 @@ FBehavior *FBehavior::StaticLoadModule (int lumpnum, FileReader *fr, int len) else { delete behavior; - Printf("%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); + Printf(TEXTCOLOR_RED "%s: invalid ACS module", Wads.GetLumpFullName(lumpnum)); return NULL; } } @@ -2044,7 +2044,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) int lump = Wads.CheckNumForName (&parse[i], ns_acslibrary); if (lump < 0) { - Printf ("Could not find ACS library %s.\n", &parse[i]); + Printf (TEXTCOLOR_RED "Could not find ACS library %s.\n", &parse[i]); } else { @@ -2085,7 +2085,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) func->ImportNum = i+1; if (realfunc->ArgCount != func->ArgCount) { - Printf ("Function %s in %s has %d arguments. %s expects it to have %d.\n", + Printf (TEXTCOLOR_ORANGE "Function %s in %s has %d arguments. %s expects it to have %d.\n", (char *)(chunk + 2) + chunk[3+j], lib->ModuleName, realfunc->ArgCount, ModuleName, func->ArgCount); Format = ACS_Unknown; @@ -2138,7 +2138,7 @@ bool FBehavior::Init(int lumpnum, FileReader * fr, int len) if (lib->ArrayStore[impNum].ArraySize != expectedSize) { Format = ACS_Unknown; - Printf ("The array %s in %s has %u elements, but %s expects it to only have %u.\n", + Printf (TEXTCOLOR_ORANGE "The array %s in %s has %u elements, but %s expects it to only have %u.\n", parse, lib->ModuleName, lib->ArrayStore[impNum].ArraySize, ModuleName, expectedSize); } @@ -2311,7 +2311,7 @@ void FBehavior::LoadScriptsDirectory () { if (Scripts[i].Number == Scripts[i+1].Number) { - Printf("%s appears more than once.\n", + Printf(TEXTCOLOR_ORANGE "%s appears more than once.\n", ScriptPresentation(Scripts[i].Number).GetChars()); // Make the closed version the first one. if (Scripts[i+1].Type == SCRIPT_Closed) @@ -2508,7 +2508,7 @@ bool FBehavior::IsGood () if (funcdef->Address == 0 && funcdef->ImportNum == 0) { DWORD *chunk = (DWORD *)FindChunk (MAKE_ID('F','N','A','M')); - Printf ("Could not find ACS function %s for use in %s.\n", + Printf (TEXTCOLOR_RED "Could not find ACS function %s for use in %s.\n", (char *)(chunk + 2) + chunk[3+i], ModuleName); bad = true; } @@ -2519,7 +2519,7 @@ bool FBehavior::IsGood () { if (Imports[i] == NULL) { - Printf ("Not all the libraries used by %s could be found.\n", ModuleName); + Printf (TEXTCOLOR_RED "Not all the libraries used by %s could be found.\n", ModuleName); return false; } } From 492ef1b7168d2f6055dd29d7cf5f1f510ea44e1e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 30 Apr 2015 08:15:48 -0500 Subject: [PATCH 15/16] - Added A_JumpIfHigherOrLower. - (int ptr = AAPTR_TARGET, state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true) - Jumps if the pointer of the calling actor is higher or lower than itself, adding offsethigh or offsetlow depending on the circumstance. - includeHeight works twofold. - Includes the height of the calling actor if the pointer is higher to truly determine if they are completely above them or not. - Includes the height of the pointer if the pointer is lower. - Disable it to only check z differences without adding height. --- src/thingdef/thingdef_codeptr.cpp | 37 +++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 1 + 2 files changed, 38 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index b0147113e..722cae8ce 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5844,6 +5844,43 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ResetHealth) } } +//=========================================================================== +// A_JumpIfHigherOrLower +// +// Jumps if a target, master, or tracer is higher or lower than the calling +// actor. Can also specify how much higher/lower the actor needs to be than +// itself. Can also take into account the height of the actor in question, +// depending on which it's checking. This means adding height of the +// calling actor's self if the pointer is higher, or height of the pointer +// if its lower. +//=========================================================================== + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) +{ + ACTION_PARAM_START(6); + ACTION_PARAM_INT(ptr, 0); + ACTION_PARAM_STATE(high, 1); + ACTION_PARAM_STATE(low, 2); + ACTION_PARAM_FIXED(offsethigh, 3); + ACTION_PARAM_FIXED(offsetlow, 4); + ACTION_PARAM_BOOL(includeHeight, 5); + + AActor *mobj = COPY_AAPTR(self, ptr); + + + if (!mobj || (mobj == self)) //AAPTR_DEFAULT is completely useless in this regard. + { + return; + } + ACTION_SET_RESULT(false); //No inventory jump chains please. + + if ((high) && (mobj->z > ((includeHeight ? self->height : 0) + self->z + offsethigh))) + ACTION_JUMP(high); + else if ((low) && (mobj->z + (includeHeight ? mobj->height : 0)) < (self->z + offsetlow)) + ACTION_JUMP(low); +} + + //=========================================================================== // // A_SetRipperLevel(int level) diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 5d3fcf2ec..25e5ab1b5 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -330,6 +330,7 @@ ACTOR Actor native //: Thinker action native A_SetFloatBobPhase(int bob); action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT); action native A_ResetHealth(int ptr = AAPTR_DEFAULT); + action native A_JumpIfHigherOrLower(int ptr = AAPTR_TARGET, state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true); action native A_SetRipperLevel(int level); action native A_SetRipMin(int min); action native A_SetRipMax(int max); From 1ecc048441681c52cd63baabf4335b51f65b2768 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 30 Apr 2015 08:28:41 -0500 Subject: [PATCH 16/16] - Change the pointer to be at the end instead of the start. --- src/thingdef/thingdef_codeptr.cpp | 12 ++++++------ wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 722cae8ce..21dc93036 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5858,12 +5858,12 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ResetHealth) DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_JumpIfHigherOrLower) { ACTION_PARAM_START(6); - ACTION_PARAM_INT(ptr, 0); - ACTION_PARAM_STATE(high, 1); - ACTION_PARAM_STATE(low, 2); - ACTION_PARAM_FIXED(offsethigh, 3); - ACTION_PARAM_FIXED(offsetlow, 4); - ACTION_PARAM_BOOL(includeHeight, 5); + ACTION_PARAM_STATE(high, 0); + ACTION_PARAM_STATE(low, 1); + ACTION_PARAM_FIXED(offsethigh, 2); + ACTION_PARAM_FIXED(offsetlow, 3); + ACTION_PARAM_BOOL(includeHeight, 4); + ACTION_PARAM_INT(ptr, 5); AActor *mobj = COPY_AAPTR(self, ptr); diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 25e5ab1b5..b7fea4189 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -330,7 +330,7 @@ ACTOR Actor native //: Thinker action native A_SetFloatBobPhase(int bob); action native A_SetHealth(int health, int ptr = AAPTR_DEFAULT); action native A_ResetHealth(int ptr = AAPTR_DEFAULT); - action native A_JumpIfHigherOrLower(int ptr = AAPTR_TARGET, state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true); + action native A_JumpIfHigherOrLower(state high, state low, float offsethigh = 0, float offsetlow = 0, bool includeHeight = true, int ptr = AAPTR_TARGET); action native A_SetRipperLevel(int level); action native A_SetRipMin(int min); action native A_SetRipMax(int max);