From bb3d2fa5350cbb3b37147be73ac45a5d9c6fd3d5 Mon Sep 17 00:00:00 2001 From: GitExl Date: Tue, 23 Sep 2014 12:10:39 +0200 Subject: [PATCH 1/4] Add CanRaiseActor ACS function. --- src/p_acs.cpp | 21 +++++++++++++++++++++ src/p_local.h | 1 + src/p_things.cpp | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index fd41d6e51d..86ab02272b 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4369,6 +4369,7 @@ enum EACSFunctions ACSF_GetArmorInfo, ACSF_DropInventory, ACSF_PickActor, + ACSF_CanRaiseActor, /* Zandronum's - these must be skipped when we reach 99! -100:ResetMap(0), @@ -5626,6 +5627,26 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) } break; + case ACSF_CanRaiseActor: + if (argCount >= 1) { + if (args[0] == 0) { + actor = SingleActorFromTID(args[0], activator); + if (actor != NULL) { + return P_Thing_CanRaise(actor); + } + } + + FActorIterator iterator(args[0]); + bool canraiseall = false; + while ((actor = iterator.Next())) + { + canraiseall = !P_Thing_CanRaise(actor) | canraiseall; + } + + return !canraiseall; + } + break; + default: break; } diff --git a/src/p_local.h b/src/p_local.h index 939018734a..8ba1dd40bb 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -171,6 +171,7 @@ int P_Thing_Damage (int tid, AActor *whofor0, int amount, FName type); void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob); void P_RemoveThing(AActor * actor); bool P_Thing_Raise(AActor *thing); +bool P_Thing_CanRaise(AActor *thing); const PClass *P_GetSpawnableType(int spawnnum); // diff --git a/src/p_things.cpp b/src/p_things.cpp index e62c65ae78..2a93ee31e0 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -445,6 +445,40 @@ bool P_Thing_Raise(AActor *thing) return true; } +bool P_Thing_CanRaise(AActor *thing) +{ + FState * RaiseState = thing->GetRaiseState(); + if (RaiseState == NULL) + { + return false; + } + + AActor *info = thing->GetDefault(); + + // Check against real height and radius + int oldflags = thing->flags; + fixed_t oldheight = thing->height; + fixed_t oldradius = thing->radius; + + thing->flags |= MF_SOLID; + thing->height = info->height; + thing->radius = info->radius; + + bool check = P_CheckPosition (thing, thing->x, thing->y); + + // Restore checked properties + thing->flags = oldflags; + thing->radius = oldradius; + thing->height = oldheight; + + if (!check) + { + return false; + } + + return true; +} + void P_Thing_SetVelocity(AActor *actor, fixed_t vx, fixed_t vy, fixed_t vz, bool add, bool setbob) { if (actor != NULL) From a2f7b86a0f460c88821ddfb2463d2c9de252cbd2 Mon Sep 17 00:00:00 2001 From: fdari Date: Sun, 28 Sep 2014 11:52:37 +0200 Subject: [PATCH 2/4] IsPointerEqual (ACS and Decorate) Decorate: IsPointerEqual(int aaptr_selector1, int aaptr_selector2) ACS: IsPointerEqual(int aaptr_selector1, int aaptr_selector2, int tid1 = 0, int tid2 = 0) Compare the pointers values returned by two pointer select operations. Returns true if they both resolve to the same value. Null values can be explicitly tested using IsPointerEqual(AAPTR_NULL, ...) ACS: IsPointerEqual(int aaptr1, int aaptr2, int tid1 = 0, int tid2 = 0) This function lets you compare pointers from other actors than the activator, using tids. Tid1 determines the actor used to resolve aaptr1, Tid2 does the same for aaptr2. If tid1 and tid2 are equal, the same actor will be used for resolving both pointers (that could always happen randomly; this way you know it will happen). --- src/namedef.h | 1 + src/p_acs.cpp | 17 +++++++++++++++ src/thingdef/thingdef_function.cpp | 35 +++++++++++++++++++++++++++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/namedef.h b/src/namedef.h index 1e7fbd0d3a..5c65ab6559 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -299,6 +299,7 @@ xx(ACS_NamedExecuteWithResult) xx(CallACS) xx(Sqrt) xx(CheckClass) +xx(IsPointerEqual) // Various actor names which are used internally xx(MapSpot) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 983728c8dc..9fa5079ff2 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4373,6 +4373,7 @@ enum EACSFunctions ACSF_GetArmorInfo, ACSF_DropInventory, ACSF_PickActor, + ACSF_IsPointerEqual, /* Zandronum's - these must be skipped when we reach 99! -100:ResetMap(0), @@ -5630,6 +5631,22 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) } break; + case ACSF_IsPointerEqual: + { + int tid1 = 0, tid2 = 0; + switch (argCount) + { + case 4: tid2 = args[3]; + case 3: tid1 = args[2]; + } + + actor = SingleActorFromTID(tid1, activator); + AActor * actor2 = tid2 == tid1 ? actor : SingleActorFromTID(tid2, activator); + + return COPY_AAPTR(actor, args[0]) == COPY_AAPTR(actor2, args[1]); + } + break; + default: break; } diff --git a/src/thingdef/thingdef_function.cpp b/src/thingdef/thingdef_function.cpp index 9bf80dcaaf..fcc9360170 100644 --- a/src/thingdef/thingdef_function.cpp +++ b/src/thingdef/thingdef_function.cpp @@ -260,4 +260,37 @@ class FxGlobalFunctionCall_CheckClass : public FxGlobalFunctionCall } }; -GLOBALFUNCTION_ADDER(CheckClass); \ No newline at end of file +GLOBALFUNCTION_ADDER(CheckClass); + +//========================================================================== +// +// Function: ispointerequal +// +//========================================================================== + +class FxGlobalFunctionCall_IsPointerEqual : public FxGlobalFunctionCall +{ + public: + GLOBALFUNCTION_DEFINE(IsPointerEqual); + + FxExpression *Resolve(FCompileContext& ctx) + { + CHECKRESOLVED(); + + if (!ResolveArgs(ctx, 2, 2, true)) + return NULL; + + ValueType = VAL_Int; + return this; + } + + ExpVal EvalExpression(AActor *self) + { + ExpVal ret; + ret.Type = VAL_Int; + ret.Int = COPY_AAPTR(self, (*ArgList)[0]->EvalExpression(self).GetInt()) == COPY_AAPTR(self, (*ArgList)[1]->EvalExpression(self).GetInt()); + return ret; + } +}; + +GLOBALFUNCTION_ADDER(IsPointerEqual); \ No newline at end of file From c4f0f95ec8bc0320f0d50be2b55bdc55bc016843 Mon Sep 17 00:00:00 2001 From: fdari Date: Sun, 28 Sep 2014 15:06:52 +0200 Subject: [PATCH 3/4] Get linetarget (aim target) from any actor (not just player): AAPTR_LINETARGET --- src/actorptrselect.cpp | 7 +++++++ src/actorptrselect.h | 3 ++- wadsrc/static/actors/constants.txt | 31 +++++++++++++++--------------- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/actorptrselect.cpp b/src/actorptrselect.cpp index f1f50eeb5e..774067550d 100644 --- a/src/actorptrselect.cpp +++ b/src/actorptrselect.cpp @@ -56,6 +56,13 @@ AActor *COPY_AAPTR(AActor *origin, int selector) case AAPTR_TRACER: return origin->tracer; case AAPTR_FRIENDPLAYER: return origin->FriendPlayer ? AAPTR_RESOLVE_PLAYERNUM(origin->FriendPlayer - 1) : NULL; + + case AAPTR_GET_LINETARGET: + { + AActor *gettarget = NULL; + P_BulletSlope(origin, &gettarget); + return gettarget; + } } } diff --git a/src/actorptrselect.h b/src/actorptrselect.h index 46e1aa54d6..bfc88fb3c0 100644 --- a/src/actorptrselect.h +++ b/src/actorptrselect.h @@ -36,12 +36,13 @@ enum AAPTR AAPTR_PLAYER8 = 0x2000, AAPTR_FRIENDPLAYER = 0x4000, + AAPTR_GET_LINETARGET = 0x8000, AAPTR_PLAYER_SELECTORS = AAPTR_PLAYER_GETTARGET|AAPTR_PLAYER_GETCONVERSATION, AAPTR_GENERAL_SELECTORS = - AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER, + AAPTR_TARGET|AAPTR_MASTER|AAPTR_TRACER|AAPTR_FRIENDPLAYER|AAPTR_GET_LINETARGET, AAPTR_STATIC_SELECTORS = AAPTR_PLAYER1|AAPTR_PLAYER2|AAPTR_PLAYER3|AAPTR_PLAYER4| diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 3419561f8b..428f92d148 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -279,24 +279,25 @@ Const Int BLOCKF_USE = 128; // Pointer constants, bitfield-enabled Const Int AAPTR_DEFAULT = 0; -Const Int AAPTR_NULL = 1; -Const Int AAPTR_TARGET = 2; -Const Int AAPTR_MASTER = 4; -Const Int AAPTR_TRACER = 8; +Const Int AAPTR_NULL = 0x1; +Const Int AAPTR_TARGET = 0x2; +Const Int AAPTR_MASTER = 0x4; +Const Int AAPTR_TRACER = 0x8; -Const Int AAPTR_PLAYER_GETTARGET = 16; -Const Int AAPTR_PLAYER_GETCONVERSATION = 32; +Const Int AAPTR_PLAYER_GETTARGET = 0x10; +Const Int AAPTR_PLAYER_GETCONVERSATION = 0x20; -Const Int AAPTR_PLAYER1 = 64; -Const Int AAPTR_PLAYER2 = 128; -Const Int AAPTR_PLAYER3 = 256; -Const Int AAPTR_PLAYER4 = 512; -Const Int AAPTR_PLAYER5 = 1024; -Const Int AAPTR_PLAYER6 = 2048; -Const Int AAPTR_PLAYER7 = 4096; -Const Int AAPTR_PLAYER8 = 8192; +Const Int AAPTR_PLAYER1 = 0x40; +Const Int AAPTR_PLAYER2 = 0x80; +Const Int AAPTR_PLAYER3 = 0x100; +Const Int AAPTR_PLAYER4 = 0x200; +Const Int AAPTR_PLAYER5 = 0x400; +Const Int AAPTR_PLAYER6 = 0x800; +Const Int AAPTR_PLAYER7 = 0x1000; +Const Int AAPTR_PLAYER8 = 0x2000; -Const Int AAPTR_FRIENDPLAYER = 16384; +Const Int AAPTR_FRIENDPLAYER = 0x4000; +Const Int AAPTR_LINETARGET = 0x8000; // Pointer operation flags From 770547e6618588a47c1c5d4b65bd3603cd59873b Mon Sep 17 00:00:00 2001 From: Teemu Piippo Date: Sun, 28 Sep 2014 17:17:19 +0300 Subject: [PATCH 4/4] - added udmf key midtex3dimpassible which causes the midtex to behave like a finite-height impassible line; practically this means the mid texture lets projectiles pass through it. --- specs/udmf_zdoom.txt | 51 +++++++++++++++++++++++--------------------- src/doomdata.h | 1 + src/namedef.h | 3 ++- src/p_3dmidtex.cpp | 7 ++++++ src/p_udmf.cpp | 11 +++++++++- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 1128b2e55d..cbb5b902ce 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -92,30 +92,33 @@ Note: All fields default to false unless mentioned otherwise. linedef { - alpha = ; // Translucency of this line, default is 1.0 - renderstyle = ; // Render style, can be "translucent" or "add", - // default is "translucent". - playeruseback = ; // New SPAC flag, true = player can use from back side. - anycross = ; // New SPAC flag, true = any non-projectile - // crossing will trigger this line - monsteractivate = ; // Monsters can trigger this line. - // For compatibility only because this flag's - // semantics can not be fully reproduced with - // explicit trigger flags. - blockplayers = ; // Line blocks players' movement. - blockeverything = ; // Line blocks everything. - firstsideonly = ; // Line can only be triggered from the front side. - zoneboundary = ; // Line is a boundary for sound reverb zones. - clipmidtex = ; // Line's mid textures are clipped to floor and ceiling. - wrapmidtex = ; // Line's mid textures are wrapped. - midtex3d = ; // Actors can walk on mid texture. - checkswitchrange = ;// Switches can only be activated when vertically reachable. - blockprojectiles = ;// Line blocks all projectiles - blockuse = ; // Line blocks all use actions - blocksight = ; // Line blocks monster line of sight - blockhitscan = ; // Line blocks hitscan attacks - locknumber = ; // Line special is locked - arg0str = ; // Alternate string-based version of arg0 + alpha = ; // Translucency of this line, default is 1.0 + renderstyle = ; // Render style, can be "translucent" or "add", + // default is "translucent". + playeruseback = ; // New SPAC flag, true = player can use from back side. + anycross = ; // New SPAC flag, true = any non-projectile + // crossing will trigger this line + monsteractivate = ; // Monsters can trigger this line. + // For compatibility only because this flag's + // semantics can not be fully reproduced with + // explicit trigger flags. + blockplayers = ; // Line blocks players' movement. + blockeverything = ; // Line blocks everything. + firstsideonly = ; // Line can only be triggered from the front side. + zoneboundary = ; // Line is a boundary for sound reverb zones. + clipmidtex = ; // Line's mid textures are clipped to floor and ceiling. + wrapmidtex = ; // Line's mid textures are wrapped. + midtex3d = ; // Actors can walk on mid texture. + midtex3dimpassible = ;// Used in conjuction with midtex3d - causes the mid + // texture to behave like an impassible line (projectiles + // pass through it). + checkswitchrange = ; // Switches can only be activated when vertically reachable. + blockprojectiles = ; // Line blocks all projectiles + blockuse = ; // Line blocks all use actions + blocksight = ; // Line blocks monster line of sight + blockhitscan = ; // Line blocks hitscan attacks + locknumber = ; // Line special is locked + arg0str = ; // Alternate string-based version of arg0 transparent = ; // true = line is a Strife transparent line (alpha 0.25) diff --git a/src/doomdata.h b/src/doomdata.h index 215c2a263c..f190be37d1 100644 --- a/src/doomdata.h +++ b/src/doomdata.h @@ -162,6 +162,7 @@ enum ELineFlags ML_BLOCKUSE = 0x02000000, // blocks all use actions through this line ML_BLOCKSIGHT = 0x04000000, // blocks monster line of sight ML_BLOCKHITSCAN = 0x08000000, // blocks hitscan attacks + ML_3DMIDTEX_IMPASS = 0x10000000, // [TP] if 3D midtex, behaves like a height-restricted ML_BLOCKING }; diff --git a/src/namedef.h b/src/namedef.h index 1e7fbd0d3a..4706fa5008 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -419,6 +419,7 @@ xx(Passuse) xx(Repeatspecial) xx(Conversation) xx(Locknumber) +xx(Midtex3dimpassible) xx(Playercross) xx(Playeruse) @@ -597,4 +598,4 @@ xx(NeverSwitchOnPickup) xx(MoveBob) xx(StillBob) xx(PlayerClass) -xx(Wi_NoAutostartMap) \ No newline at end of file +xx(Wi_NoAutostartMap) diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index ccb6f0359d..ac6d7aca79 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -258,6 +258,13 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, fixed_t *ptextop, f bool P_LineOpening_3dMidtex(AActor *thing, const line_t *linedef, FLineOpening &open, bool restrict) { + // [TP] Impassible-like 3dmidtextures do not block missiles + if ((linedef->flags & ML_3DMIDTEX_IMPASS) + && (thing->flags & MF_MISSILE || thing->BounceFlags & BOUNCE_MBF)) + { + return false; + } + fixed_t tt, tb; open.abovemidtex = false; diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 7588199b4d..473cdcd814 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1030,11 +1030,16 @@ public: Flag(ld->flags, ML_BLOCKHITSCAN, key); continue; - // [Dusk] lock number + // [TP] Locks the special with a key case NAME_Locknumber: ld->locknumber = CheckInt(key); continue; + // [TP] Causes a 3d midtex to behave like an impassible line + case NAME_Midtex3dimpassible: + Flag(ld->flags, ML_3DMIDTEX_IMPASS, key); + continue; + default: break; } @@ -1081,6 +1086,10 @@ public: { ld->args[1] = -FName(arg1str); } + if ((ld->flags & ML_3DMIDTEX_IMPASS) && !(ld->flags & ML_3DMIDTEX)) // [TP] + { + Printf ("Line %d has midtex3dimpassible without midtex3d.\n", index); + } } //===========================================================================