From 3e517ad4d0b1d089841cafe50dc4f5dc062250c1 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 24 Oct 2015 11:58:32 +0300 Subject: [PATCH 1/9] Fixed selection of empty items in Video Mode menu See http://forum.zdoom.org/viewtopic.php?t=49794 --- src/menu/optionmenuitems.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index e87e78483..a1fff64c7 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -942,6 +942,14 @@ public: { return mMaxValid >= 0; } + + void Ticker() + { + if (Selectable() && mSelection > mMaxValid) + { + mSelection = mMaxValid; + } + } }; From 75855dc64a133a61cdc559b5520ad127540bf037 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 25 Nov 2015 01:44:19 -0600 Subject: [PATCH 2/9] A_FaceVelocity(offset, flags, ptr) - Changes the caller's angle and pitch according to the direction of velocity they're travelling. - FVF_NOPITCH and FVF_NOANGLE disable changing of pitch/angle respectively and should be counted as mutually exclusive, or the function does nothing. - FVF_INTERPOLATE - Interpolate's the angle and pitch changes. - FVF_RESETPITCH will, if there's no z velocity, reset the pitch to 0. Otherwise, the pitch remains unchanged. --- src/thingdef/thingdef_codeptr.cpp | 51 ++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 1 + wadsrc/static/actors/constants.txt | 9 ++++++ 3 files changed, 61 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 60a2318b4..3e5a4dc10 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5930,4 +5930,55 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) { ACTION_JUMP(block); } +} + +//=========================================================================== +// +// A_FaceVelocity(angle offset, bool pitch, ptr) +// +// Sets the actor('s pointer) to face the direction of travel. +//=========================================================================== +enum FVFlags +{ + FVF_NOPITCH = 1 << 0, + FVF_INTERPOLATE = 1 << 1, + FVF_NOANGLE = 1 << 2, + FVF_RESETPITCH = 1 << 3, +}; +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_FIXED(offset, 0) + ACTION_PARAM_INT(flags, 1); + ACTION_PARAM_INT(ptr, 2); + + AActor *mobj = COPY_AAPTR(self, ptr); + + //Need an actor. + if (!mobj || ((flags & FVF_NOPITCH) && (flags & FVF_NOANGLE))) + { + ACTION_SET_RESULT(false); + return; + } + + //Don't bother calculating this if we don't have any horizontal movement. + if (!(flags & FVF_NOANGLE) && (mobj->velx != 0 || mobj->vely != 0)) + { + fixed_t vx = mobj->x + mobj->velx, vy = mobj->y + mobj->vely; + angle_t angle = R_PointToAngle2(mobj->x, mobj->y, vx, vy) + offset; + mobj->SetAngle(angle, !!(flags & FVF_INTERPOLATE)); + } + + if (!(flags & FVF_NOPITCH)) + { + //Reset pitch to 0 if specified. + if (mobj->velz == 0 && (flags & FVF_RESETPITCH)) + mobj->pitch = 0; + else + { + FVector2 velocity(mobj->velx, mobj->vely); + fixed_t pitch = R_PointToAngle2(0, 0, (fixed_t)velocity.Length(), mobj->velz); + mobj->SetPitch(-pitch, !!(flags & FVF_INTERPOLATE)); + } + } } \ No newline at end of file diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 7dc89f201..22312fed8 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -340,6 +340,7 @@ ACTOR Actor native //: Thinker action native A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_CheckSightOrRange(float distance, state label, bool two_dimension = false); action native A_CheckRange(float distance, state label, bool two_dimension = false); + action native A_FaceVelocity(float offset = 0, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0); action native A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 7f8fbc09e..9667db563 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -495,6 +495,15 @@ enum CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self. }; +//Flags for A_FaceVelocity +enum +{ + FVF_NOPITCH = 1 << 0, + FVF_INTERPOLATE = 1 << 1, + FVF_NOANGLE = 1 << 2, + FVF_RESETPITCH = 1 << 3, +}; + // This is only here to provide one global variable for testing. native int testglobalvar; From ab5b1f479a66912bcbe6e1fca262e6e8386b6f8a Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 25 Nov 2015 21:49:25 -0600 Subject: [PATCH 3/9] Updated A_FaceVelocity. - Now includes anglelimit and pitchlimit. - Anglelimit and pitchlimit only allows the actor to turn this much, similar to A_FaceTarget's limit. FVF_RESETPITCH also respects the pitch limit. - (offset, anglelimit, pitchlimit, flags, ptr) --- src/thingdef/thingdef_codeptr.cpp | 90 ++++++++++++++++++++++++++----- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 3e5a4dc10..f244a8153 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5947,10 +5947,12 @@ enum FVFlags }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) { - ACTION_PARAM_START(3); - ACTION_PARAM_FIXED(offset, 0) - ACTION_PARAM_INT(flags, 1); - ACTION_PARAM_INT(ptr, 2); + ACTION_PARAM_START(5); + ACTION_PARAM_ANGLE(offset, 0); + ACTION_PARAM_ANGLE(anglelimit, 1); + ACTION_PARAM_ANGLE(pitchlimit, 2); + ACTION_PARAM_INT(flags, 3); + ACTION_PARAM_INT(ptr, 4); AActor *mobj = COPY_AAPTR(self, ptr); @@ -5964,21 +5966,83 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) //Don't bother calculating this if we don't have any horizontal movement. if (!(flags & FVF_NOANGLE) && (mobj->velx != 0 || mobj->vely != 0)) { - fixed_t vx = mobj->x + mobj->velx, vy = mobj->y + mobj->vely; - angle_t angle = R_PointToAngle2(mobj->x, mobj->y, vx, vy) + offset; - mobj->SetAngle(angle, !!(flags & FVF_INTERPOLATE)); + const fixed_t vx = mobj->velx + mobj->x, vy = mobj->vely + mobj->y; + angle_t current = mobj->angle; + const angle_t angle = R_PointToAngle2(mobj->x, mobj->y, vx, vy); + //Done because using anglelimit directly causes a signed/unsigned mismatch. + const angle_t limit = anglelimit; + + //Code borrowed from A_Face*. + if (limit > 0 && (absangle(current - angle) > limit)) + { + if (current < angle) + { + // [MC] This may appear backwards, but I assure any who + // reads this, it works. + if (current - angle > ANGLE_180) + current += limit + offset; + else + current -= limit + offset; + mobj->SetAngle(current, !!(flags & FVF_INTERPOLATE)); + } + else if (current > angle) + { + if (angle - current > ANGLE_180) + current -= limit + offset; + else + current += limit + offset; + mobj->SetAngle(current, !!(flags & FVF_INTERPOLATE)); + } + else + mobj->SetAngle(angle + ANGLE_180 + offset, !!(flags & FVF_INTERPOLATE)); + + } + else + mobj->SetAngle(angle + offset, !!(flags & FVF_INTERPOLATE)); } if (!(flags & FVF_NOPITCH)) { - //Reset pitch to 0 if specified. - if (mobj->velz == 0 && (flags & FVF_RESETPITCH)) - mobj->pitch = 0; + fixed_t current = mobj->pitch; + const FVector2 velocity(mobj->velx, mobj->vely); + const fixed_t pitch = R_PointToAngle2(0, 0, (fixed_t)velocity.Length(), -mobj->velz); + if (pitchlimit > 0) + { + // [MC] angle_t for pitchlimit was required because otherwise + // we would wind up with less than desirable turn rates that didn't + // match that of A_SetPitch. We want consistency. Also, I didn't know + // of a better way to convert from angle_t to fixed_t properly so I + // used this instead. + fixed_t plimit = fixed_t(pitchlimit); + + if (abs(current - pitch) > plimit) + { + fixed_t max = 0; + + if (current > pitch) + { + max = MIN(plimit, (current - pitch)); + current -= max; + } + else //if (current > pitch) + { + max = MIN(plimit, (pitch - current)); + current += max; + } + if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) + mobj->SetPitch(current, !!(flags & FVF_INTERPOLATE)); + } + else + { + if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) + mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); + } + + } else { - FVector2 velocity(mobj->velx, mobj->vely); - fixed_t pitch = R_PointToAngle2(0, 0, (fixed_t)velocity.Length(), mobj->velz); - mobj->SetPitch(-pitch, !!(flags & FVF_INTERPOLATE)); + if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) + mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); } } } \ No newline at end of file diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 22312fed8..fc00698e7 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -340,7 +340,7 @@ ACTOR Actor native //: Thinker action native A_CheckBlock(state block, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_CheckSightOrRange(float distance, state label, bool two_dimension = false); action native A_CheckRange(float distance, state label, bool two_dimension = false); - action native A_FaceVelocity(float offset = 0, int flags = 0, int ptr = AAPTR_DEFAULT); + action native A_FaceVelocity(float offset = 0, float anglelimit = 0, float pitchlimit = 0, int flags = 0, int ptr = AAPTR_DEFAULT); action native A_RearrangePointers(int newtarget, int newmaster = AAPTR_DEFAULT, int newtracer = AAPTR_DEFAULT, int flags=0); action native A_TransferPointer(int ptr_source, int ptr_recepient, int sourcefield, int recepientfield=AAPTR_DEFAULT, int flags=0); From a1e31128508c750036209762b51a56cf6a72545e Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 25 Nov 2015 23:15:59 -0600 Subject: [PATCH 4/9] Removed FVF_RESETPITCH. --- src/thingdef/thingdef_codeptr.cpp | 13 ++++--------- wadsrc/static/actors/constants.txt | 1 - 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index f244a8153..4ac378750 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5943,7 +5943,6 @@ enum FVFlags FVF_NOPITCH = 1 << 0, FVF_INTERPOLATE = 1 << 1, FVF_NOANGLE = 1 << 2, - FVF_RESETPITCH = 1 << 3, }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) { @@ -5966,9 +5965,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) //Don't bother calculating this if we don't have any horizontal movement. if (!(flags & FVF_NOANGLE) && (mobj->velx != 0 || mobj->vely != 0)) { - const fixed_t vx = mobj->velx + mobj->x, vy = mobj->vely + mobj->y; angle_t current = mobj->angle; - const angle_t angle = R_PointToAngle2(mobj->x, mobj->y, vx, vy); + const angle_t angle = R_PointToAngle2(0, 0, mobj->velx, mobj->vely); //Done because using anglelimit directly causes a signed/unsigned mismatch. const angle_t limit = anglelimit; @@ -6029,20 +6027,17 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) max = MIN(plimit, (pitch - current)); current += max; } - if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) - mobj->SetPitch(current, !!(flags & FVF_INTERPOLATE)); + mobj->SetPitch(current, !!(flags & FVF_INTERPOLATE)); } else { - if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) - mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); + mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); } } else { - if ((mobj->velz != 0) || (flags & FVF_RESETPITCH)) - mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); + mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); } } } \ No newline at end of file diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index 9667db563..23e9a7116 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -501,7 +501,6 @@ enum FVF_NOPITCH = 1 << 0, FVF_INTERPOLATE = 1 << 1, FVF_NOANGLE = 1 << 2, - FVF_RESETPITCH = 1 << 3, }; // This is only here to provide one global variable for testing. From 7725e9d6410c94bb4ef515cff2996c55b0fc7a6b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 25 Nov 2015 23:17:13 -0600 Subject: [PATCH 5/9] New line. --- 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 4ac378750..182dc4743 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6040,4 +6040,4 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) mobj->SetPitch(pitch, !!(flags & FVF_INTERPOLATE)); } } -} \ No newline at end of file +} From d730b06da702239d36842eb01174b8212248e858 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Thu, 26 Nov 2015 01:33:02 -0600 Subject: [PATCH 6/9] Added A_CheckSpecies(state jump, name species, ptr = AAPTR_DEFAULT) - Performs a state jump if the defined species name for the pointed actor matches the criteria. --- src/thingdef/thingdef_codeptr.cpp | 25 +++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 1 + 2 files changed, 26 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 14440d884..dc9fc9a40 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -5028,6 +5028,31 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_RadiusGive) ACTION_SET_RESULT(given); } +//=========================================================================== +// +// A_CheckSpecies +// +//=========================================================================== +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSpecies) +{ + ACTION_PARAM_START(3); + ACTION_PARAM_STATE(jump, 0); + ACTION_PARAM_NAME(species, 1); + ACTION_PARAM_INT(ptr, 2); + + AActor *mobj = COPY_AAPTR(self, ptr); + + ACTION_SET_RESULT(false); + //Needs at least one state jump to work. + if (!mobj) + { + return; + } + + if (jump && mobj->GetSpecies() == species) + ACTION_JUMP(jump); +} + //========================================================================== // diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index be4b8b416..287840796 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -258,6 +258,7 @@ ACTOR Actor native //: Thinker action native A_GiveToTarget(class itemtype, int amount = 0, int forward_ptr = AAPTR_DEFAULT); action native A_TakeFromTarget(class itemtype, int amount = 0, int flags = 0, int forward_ptr = AAPTR_DEFAULT); action native A_RadiusGive(class itemtype, int distance, int flags, int amount = 0, class filter = "None", name species = "None", int mindist = 0); + action native A_CheckSpecies(state jump, name species = "", int ptr = AAPTR_DEFAULT); action native A_CountdownArg(int argnum, state targstate = ""); action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); From 116e1574473fac7e75b4a0aa74da6a3601164d06 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 20 Jan 2016 15:52:56 -0600 Subject: [PATCH 7/9] Nevermind this. --- src/thingdef/thingdef_codeptr.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 5c6198d46..36f9b6c39 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6125,7 +6125,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_FaceVelocity) fixed_t current = mobj->pitch; const FVector2 velocity(mobj->velx, mobj->vely); const fixed_t pitch = R_PointToAngle2(0, 0, (fixed_t)velocity.Length(), -mobj->velz); - fixedvec2 test; if (pitchlimit > 0) { // [MC] angle_t for pitchlimit was required because otherwise From b22a909829af8869903943c85c45833b2bf788e6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Jan 2016 13:08:23 -0600 Subject: [PATCH 8/9] Add nodelay handling to FastProjectile --- src/g_shared/a_fastprojectile.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/g_shared/a_fastprojectile.cpp b/src/g_shared/a_fastprojectile.cpp index ae7f6a58b..725b858e3 100644 --- a/src/g_shared/a_fastprojectile.cpp +++ b/src/g_shared/a_fastprojectile.cpp @@ -138,6 +138,17 @@ void AFastProjectile::Tick () } } } + if ((flags7 & MF7_HANDLENODELAY) && !(flags2 & MF2_DORMANT)) + { + flags7 &= ~MF7_HANDLENODELAY; + if (state->GetNoDelay()) + { + // For immediately spawned objects with the NoDelay flag set for their + // Spawn state, explicitly call the current state's function. + if (state->CallAction(this, this) && (ObjectFlags & OF_EuthanizeMe)) + return; // freed itself + } + } // Advance the state if (tics != -1) { From 2d40874cfa4800eca6eda4c7c8250cb92fbdc828 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Wed, 27 Jan 2016 13:19:15 -0600 Subject: [PATCH 9/9] Make finishgame CCMD net-aware --- src/d_net.cpp | 5 +++++ src/d_protocol.h | 3 ++- src/statistics.cpp | 3 ++- src/version.h | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 5e8a635d5..640ba4580 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2668,6 +2668,11 @@ void Net_DoCommand (int type, BYTE **stream, int player) players[player].camera = players[player].mo; break; + case DEM_FINISHGAME: + // Simulate an end-of-game action + G_ChangeLevel(NULL, 0, 0); + break; + default: I_Error ("Unknown net command: %d", type); break; diff --git a/src/d_protocol.h b/src/d_protocol.h index 73b042470..ef8fe2662 100644 --- a/src/d_protocol.h +++ b/src/d_protocol.h @@ -164,7 +164,8 @@ enum EDemoCommand DEM_RUNNAMEDSCRIPT, // 65 String: Script name, Byte: Arg count + Always flag; each arg is a 4-byte int DEM_REVERTCAMERA, // 66 DEM_SETSLOTPNUM, // 67 Byte: player number, the rest is the same as DEM_SETSLOT - DEM_REMOVE, // 68 + DEM_REMOVE, // 68 + DEM_FINISHGAME, // 69 }; // The following are implemented by cht_DoCheat in m_cheat.cpp diff --git a/src/statistics.cpp b/src/statistics.cpp index 7ed6e7f8e..d611fdc0c 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -46,6 +46,7 @@ #include "c_console.h" #include "d_gui.h" #include "d_dehacked.h" +#include "d_net.h" #include "g_game.h" #include "m_png.h" #include "m_misc.h" @@ -604,7 +605,7 @@ CCMD(printstats) CCMD(finishgame) { // This CCMD simulates an end-of-game action and exists to end mods that never exit their last level. - G_ChangeLevel(NULL, 0, 0); + Net_WriteByte(DEM_FINISHGAME); } ADD_STAT(statistics) diff --git a/src/version.h b/src/version.h index b8c4facb0..167f8a303 100644 --- a/src/version.h +++ b/src/version.h @@ -61,7 +61,7 @@ const char *GetVersionString(); // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. // Otherwise, it should be safe to leave it alone. -#define DEMOGAMEVERSION 0x21C +#define DEMOGAMEVERSION 0x21D // Minimum demo version we can play. // Bump it whenever you change or remove existing DEM_ commands.