From 7d56311152068f6bb7a62546c91898ddf058c692 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 23 Jun 2013 18:45:17 +0200 Subject: [PATCH] - added Ryan Cordell's A_CheckRange submission. --- src/thingdef/thingdef_codeptr.cpp | 62 +++++++++++++++++++++++++++++++ wadsrc/static/actors/actor.txt | 1 + 2 files changed, 63 insertions(+) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index e7b26cb49..be91cdf2c 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -2501,6 +2501,68 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckSightOrRange) ACTION_JUMP(jump); } +//=========================================================================== +// +// A_CheckRange +// Jumps if this actor is out of range of all players. +// +//=========================================================================== +static bool DoCheckRange(AActor *self, AActor *camera, double range) +{ + if (camera == NULL) + { + return false; + } + // Check distance first, since it's cheaper than checking sight. + double dx = self->x - camera->x; + double dy = self->y - camera->y; + double dz; + fixed_t eyez = (camera->z + camera->height - (camera->height>>2)); // same eye height as P_CheckSight + if (eyez > self->z + self->height){ + dz = self->z + self->height - eyez; + } + else if (eyez < self->z){ + dz = self->z - eyez; + } + else{ + dz = 0; + } + if ((dx*dx) + (dy*dy) + (dz*dz) <= range){ + // Within range + return true; + } + return false; +} + +DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckRange) +{ + ACTION_PARAM_START(2); + double range = EvalExpressionF(ParameterIndex+0, self); + ACTION_PARAM_STATE(jump, 1); + + ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! + + range = range * range * (double(FRACUNIT) * FRACUNIT); // no need for square roots + for (int i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + { + // Always check from each player. + if (DoCheckRange(self, players[i].mo, range)) + { + return; + } + // If a player is viewing from a non-player, check that too. + if (players[i].camera != NULL && players[i].camera->player == NULL && + DoCheckRange(self, players[i].camera, range)) + { + return; + } + } + } + ACTION_JUMP(jump); +} + //=========================================================================== // diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 12c625596..c2fa8a0c7 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -302,6 +302,7 @@ ACTOR Actor native //: Thinker action native A_SetDamageType(name damagetype); action native A_CheckSightOrRange(float distance, state label); + action native A_CheckRange(float distance, state label); 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);