diff --git a/src/basedef.h b/src/basedef.h index 000b79393..2dffc4494 100644 --- a/src/basedef.h +++ b/src/basedef.h @@ -104,6 +104,13 @@ static inline bool isDead(const BASE_OBJECT* psObj) return (psObj->died > NOT_CURRENT_LIST); } +static inline int objPosDiffSq(Vector3uw pos1, Vector3uw pos2) +{ + const int xdiff = pos1.x - pos2.x; + const int ydiff = pos1.y - pos2.y; + return (xdiff * xdiff + ydiff * ydiff); +} + // Must be #included __AFTER__ the definition of BASE_OBJECT #include "baseobject.h" diff --git a/src/droid.c b/src/droid.c index 9a8770333..a5382e555 100644 --- a/src/droid.c +++ b/src/droid.c @@ -4795,3 +4795,16 @@ void checkDroid(const DROID *droid, const char *const location, const char *func } } } + +int droidSqDist(DROID *psDroid, BASE_OBJECT *psObj) +{ + PROPULSION_STATS *psPropStats = asPropulsionStats + psDroid->asBits[COMP_PROPULSION].nStat; + Vector2i dPos = { map_coord(psDroid->pos.x), map_coord(psDroid->pos.y) }; + Vector2i rPos = { map_coord(psObj->pos.x), map_coord(psObj->pos.y) }; + + if (!fpathCheck(dPos, rPos, psPropStats->propulsionType)) + { + return -1; + } + return objPosDiffSq(psDroid->pos, psObj->pos); +} diff --git a/src/droid.h b/src/droid.h index 00f6700f8..2789fc5fc 100644 --- a/src/droid.h +++ b/src/droid.h @@ -556,9 +556,12 @@ static inline void setSaveDroidBase(DROID *psSaveDroid, STRUCTURE *psNewBase) void checkDroid(const DROID *droid, const char * const location_description, const char * function, const int recurse); -/* assert if droid is bad */ +/** assert if droid is bad */ #define CHECK_DROID(droid) checkDroid(droid, AT_MACRO, __FUNCTION__, max_check_object_recursion) +/** If droid can get to given object using its current propulsion, return the square distance. Otherwise return -1. */ +int droidSqDist(DROID *psDroid, BASE_OBJECT *psObj); + // Minimum damage a weapon will deal to its target #define MIN_WEAPON_DAMAGE 1 diff --git a/src/order.c b/src/order.c index 5f94d7d21..150fc397a 100644 --- a/src/order.c +++ b/src/order.c @@ -171,7 +171,6 @@ a defined range*/ BASE_OBJECT * checkForRepairRange(DROID *psDroid,DROID *psTarget) { DROID *psCurr; - SDWORD xdiff, ydiff; ASSERT( psDroid->droidType == DROID_REPAIR || psDroid->droidType == DROID_CYBORG_REPAIR, "checkForRepairRange:Invalid droid type" ); @@ -204,16 +203,10 @@ BASE_OBJECT * checkForRepairRange(DROID *psDroid,DROID *psTarget) for (; psCurr != NULL; psCurr = psCurr->psNext) { //check for damage - if (droidIsDamaged(psCurr) && - visibleObject((BASE_OBJECT *)psDroid, (BASE_OBJECT *)psCurr, false)) + if (droidIsDamaged(psCurr) && visibleObject((BASE_OBJECT *)psDroid, (BASE_OBJECT *)psCurr, false) + && droidSqDist(psDroid, (BASE_OBJECT *)psCurr) < REPAIR_MAXDIST * REPAIR_MAXDIST) { - //check for within range - xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psCurr->pos.x; - ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psCurr->pos.y; - if ( (xdiff*xdiff) + (ydiff*ydiff) < REPAIR_MAXDIST*REPAIR_MAXDIST) - { - return (BASE_OBJECT *)psCurr; - } + return (BASE_OBJECT *)psCurr; } } return NULL; @@ -224,7 +217,6 @@ a defined range*/ BASE_OBJECT * checkForDamagedStruct(DROID *psDroid, STRUCTURE *psTarget) { STRUCTURE *psCurr; - SDWORD xdiff, ydiff; ASSERT(psDroid->droidType == DROID_CONSTRUCT || psDroid->droidType == DROID_CYBORG_CONSTRUCT, "Invalid unit type"); @@ -247,19 +239,11 @@ BASE_OBJECT * checkForDamagedStruct(DROID *psDroid, STRUCTURE *psTarget) for (; psCurr != NULL; psCurr = psCurr->psNext) { //check for damage - if (psCurr->status == SS_BUILT && - structIsDamaged(psCurr) && - !checkDroidsDemolishing(psCurr) && - visibleObject((BASE_OBJECT *)psDroid, (BASE_OBJECT *)psCurr, false)) + if (psCurr->status == SS_BUILT && structIsDamaged(psCurr) && !checkDroidsDemolishing(psCurr) + && visibleObject((BASE_OBJECT *)psDroid, (BASE_OBJECT *)psCurr, false) + && droidSqDist(psDroid, (BASE_OBJECT *)psCurr) < REPAIR_MAXDIST * REPAIR_MAXDIST) { - //check for within range - xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psCurr->pos.x; - ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psCurr->pos.y; - //check for repair distance and not construct_dist - this allows for structures being up to 3 tiles across - if ((xdiff*xdiff) + (ydiff*ydiff) < REPAIR_MAXDIST*REPAIR_MAXDIST) - { - return (BASE_OBJECT *)psCurr; - } + return (BASE_OBJECT *)psCurr; } } return NULL; @@ -892,9 +876,7 @@ void orderUpdateDroid(DROID *psDroid) ASSERT( psRepairFac != NULL, "orderUpdateUnit: invalid repair facility pointer" ); - xdiff = (SDWORD)psDroid->pos.x - (SDWORD)psDroid->psTarget->pos.x; - ydiff = (SDWORD)psDroid->pos.y - (SDWORD)psDroid->psTarget->pos.y; - if (xdiff*xdiff + ydiff*ydiff < (TILE_UNITS*8)*(TILE_UNITS*8)) + if (objPosDiffSq(psDroid->pos, psDroid->psTarget->pos) < (TILE_UNITS * 8) * (TILE_UNITS * 8)) { /* action droid to wait */ actionDroid(psDroid, DACTION_WAITFORREPAIR); @@ -1271,7 +1253,7 @@ void orderUpdateDroid(DROID *psDroid) static void orderCmdGroupBase(DROID_GROUP *psGroup, DROID_ORDER_DATA *psData) { DROID *psCurr, *psChosen; - SDWORD xdiff,ydiff, currdist, mindist; + SDWORD currdist, mindist; ASSERT( psGroup != NULL, "cmdUnitOrderGroupBase: invalid unit group" ); @@ -1283,9 +1265,7 @@ static void orderCmdGroupBase(DROID_GROUP *psGroup, DROID_ORDER_DATA *psData) mindist = SDWORD_MAX; for(psCurr = psGroup->psList; psCurr; psCurr=psCurr->psGrpNext) { - xdiff = (SDWORD)psCurr->pos.x - (SDWORD)psData->psObj->pos.x; - ydiff = (SDWORD)psCurr->pos.y - (SDWORD)psData->psObj->pos.y; - currdist = xdiff*xdiff + ydiff*ydiff; + currdist = objPosDiffSq(psCurr->pos, psData->psObj->pos); if (currdist < mindist) { psChosen = psCurr;