diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b75b679c44..af1f04f49f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1205,10 +1205,17 @@ if( MSVC ) set_target_properties(zdoom PROPERTIES LINK_FLAGS "/MANIFEST:NO /DELAYLOAD:\"fmodex${X64}.dll\" /DELAYLOAD:\"openal32.dll\" /DELAYLOAD:\"libmpg123-0.dll\" /DELAYLOAD:\"libsndfile-1.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:\"$\"\;\#1 + COMMENT "Adding manifest..." + ) + endif( NO_GENERATOR_EXPRESSIONS ) create_default_target_launcher( zdoom WORKING_DIRECTORY ${ZDOOM_OUTPUT_DIR} ) endif( MSVC ) diff --git a/src/actor.h b/src/actor.h index 04e4d722e0..81b0a8b7b4 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. @@ -356,8 +372,11 @@ enum 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 --- +}; +// --- 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 @@ -386,10 +405,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) @@ -418,7 +433,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 @@ -472,6 +487,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 @@ -842,7 +877,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; @@ -868,13 +903,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; @@ -920,7 +955,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 2800c01c5d..f93625612f 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 4a436c0a88..7d3a5f0ee8 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/farchive.h b/src/farchive.h index 329b448db8..87ebf999b0 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/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 6583d15108..6fcd50341d 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1223,11 +1223,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 c9ad986885..4da6eb67bd 100644 --- a/src/g_shared/a_morph.cpp +++ b/src/g_shared/a_morph.cpp @@ -225,7 +225,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; @@ -439,7 +439,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 83d0d46954..0f847fa417 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 3d9e4ed10f..2688249ea9 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 d9e049b2ba..86674c149d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3350,7 +3350,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 ddfa0e2ec1..46c2b9f4c9 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 540aa119e0..3e17a85f35 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 1da7c9135e..b76919a7de 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1592,7 +1592,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; @@ -4922,7 +4922,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 9bec4ed55e..abfe888ec5 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 @@ -3991,7 +3991,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 95a52f8a8b..632f53bc38 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -86,7 +86,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)) { @@ -429,7 +429,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 @@ -468,7 +468,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 dbf4cbeb55..5da0b89926 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/tflags.h b/src/tflags.h new file mode 100644 index 0000000000..20caba2271 --- /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 diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index d98bb48573..10a64812eb 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2002,10 +2002,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) @@ -3745,7 +3745,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); @@ -4008,19 +4008,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); @@ -4029,9 +4029,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 2e86b60247..a471e9985a 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), @@ -306,7 +306,7 @@ static FFlagDef ActorFlags[]= DEFINE_DUMMY_FLAG(EXPLODEONDEATH), // seems useless }; -static FFlagDef InventoryFlags[] = +static FFlagDef InventoryFlagDefs[] = { // Inventory flags DEFINE_FLAG(IF, QUIET, AInventory, ItemFlags), @@ -333,7 +333,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), @@ -360,7 +360,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), @@ -368,7 +368,7 @@ static FFlagDef PlayerPawnFlags[] = DEFINE_FLAG(PPF, CROUCHABLEMORPH, APlayerPawn, PlayerFlags), }; -static FFlagDef PowerSpeedFlags[] = +static FFlagDef PowerSpeedFlagDefs[] = { // PowerSpeed flags DEFINE_FLAG(PSF, NOTRAIL, APowerSpeed, SpeedFlags), @@ -376,11 +376,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)) @@ -467,11 +467,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 27ceeb698e..183cf27091 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -1050,7 +1050,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, }; @@ -1310,13 +1310,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; } //==========================================================================