diff --git a/src/ai.c b/src/ai.c index fdc034340..a20717820 100644 --- a/src/ai.c +++ b/src/ai.c @@ -247,9 +247,8 @@ BASE_OBJECT *aiSearchSensorTargets(BASE_OBJECT *psObj, int weapon_slot, WEAPON_S // Returns integer representing target priority, -1 if failed SDWORD aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot, UWORD *targetOrigin) { - UDWORD i; SDWORD bestMod = 0,newMod, failure = -1; - BASE_OBJECT *psTarget = NULL, *friendlyObj, *bestTarget = NULL, *targetInQuestion, *tempTarget; + BASE_OBJECT *psTarget = NULL, *friendlyObj, *bestTarget = NULL, *iter, *targetInQuestion, *tempTarget; BOOL electronic = false; STRUCTURE *targetStructure; WEAPON_EFFECT weaponEffect; @@ -281,15 +280,17 @@ SDWORD aiBestNearestTarget(DROID *psDroid, BASE_OBJECT **ppsObj, int weapon_slot bestTarget = aiSearchSensorTargets((BASE_OBJECT *)psDroid, weapon_slot, psWStats, &tmpOrigin); bestMod = targetAttackWeight(bestTarget, (BASE_OBJECT *)psDroid, weapon_slot); } - droidGetNaybors(psDroid); weaponEffect = ((WEAPON_STATS *)(asWeaponStats + psDroid->asWeaps[weapon_slot].nStat))->weaponEffect; electronic = electronicDroid(psDroid); - for (i=0; i< numNaybors; i++) + + // Range was previously 9*TILE_UNITS. Increasing this doesn't seem to help much, though. Not sure why. + gridStartIterate(psDroid->pos.x, psDroid->pos.y, psDroid->sensorRange + 6*TILE_UNITS); + for (iter = gridIterate(); iter != NULL; iter = gridIterate()) { friendlyObj = NULL; - targetInQuestion = asDroidNaybors[i].psObj; + targetInQuestion = iter; /* This is a friendly unit, check if we can reuse its target */ if(aiCheckAlliances(targetInQuestion->player,psDroid->player)) @@ -862,7 +863,7 @@ BOOL aiChooseTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget, int weapon_slot { BASE_OBJECT *psCurr; - gridStartIterate((SDWORD)psObj->pos.x, (SDWORD)psObj->pos.y); + gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS); psCurr = gridIterate(); while (psCurr != NULL) { @@ -922,7 +923,7 @@ BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget) BASE_OBJECT *psCurr, *psTemp = NULL; int tarDist = SDWORD_MAX; - gridStartIterate((SDWORD)psObj->pos.x, (SDWORD)psObj->pos.y); + gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS); psCurr = gridIterate(); while (psCurr != NULL) { @@ -984,7 +985,7 @@ BOOL aiChooseSensorTarget(BASE_OBJECT *psObj, BASE_OBJECT **ppsTarget) BASE_OBJECT *psCurr, *psTemp = NULL; int tarDist = SDWORD_MAX; - gridStartIterate((SDWORD)psObj->pos.x, (SDWORD)psObj->pos.y); + gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS); psCurr = gridIterate(); while (psCurr != NULL) { diff --git a/src/combat.c b/src/combat.c index f30b801ea..fef6f2d98 100644 --- a/src/combat.c +++ b/src/combat.c @@ -445,7 +445,7 @@ void counterBatteryFire(BASE_OBJECT *psAttacker, BASE_OBJECT *psTarget) CHECK_OBJECT(psTarget); - gridStartIterate((SDWORD)psTarget->pos.x, (SDWORD)psTarget->pos.y); + gridStartIterate(psTarget->pos.x, psTarget->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS); for (psViewer = gridIterate(); psViewer != NULL; psViewer = gridIterate()) { STRUCTURE *psStruct; diff --git a/src/droid.c b/src/droid.c index 0d144fa41..deb1b8875 100644 --- a/src/droid.c +++ b/src/droid.c @@ -103,14 +103,9 @@ UDWORD selectedCommander = UBYTE_MAX; /** Height the transporter hovers at above the terrain. */ #define TRANSPORTER_HOVER_HEIGHT 10 -/** How far round a repair droid looks for a damaged droid. */ -#define REPAIR_DIST (TILE_UNITS * 4)//8) - -/* Store for the objects near the droid currently being updated +/* Sorry, Keith. * NAYBOR = neighbour - thanks to Keith for a great abreviation */ -NAYBOR_INFO asDroidNaybors[MAX_NAYBORS]; -UDWORD numNaybors=0; // the structure that was last hit DROID *psLastDroidHit; @@ -677,109 +672,6 @@ void droidBurn(DROID *psDroid) orderDroid( psDroid, DORDER_RUNBURN ); } -/* Add a new object to the naybor list */ -static void addNaybor(BASE_OBJECT *psObj, UDWORD distSqr) -{ - UDWORD pos; - - if (numNaybors == 0) - { - // No objects in the list - asDroidNaybors[0].psObj = psObj; - asDroidNaybors[0].distSqr = distSqr; - numNaybors++; - } - else if (distSqr >= asDroidNaybors[numNaybors-1].distSqr) - { - // Simple case - this is the most distant object - asDroidNaybors[numNaybors].psObj = psObj; - asDroidNaybors[numNaybors].distSqr = distSqr; - numNaybors++; - } - else - { - // Move all the objects further away up the list - for (pos = numNaybors; pos && asDroidNaybors[pos - 1].distSqr > distSqr; pos--) - { - memcpy(asDroidNaybors + pos, asDroidNaybors + (pos - 1), sizeof(NAYBOR_INFO)); - } - - // Insert the object at the correct position - asDroidNaybors[pos].psObj = psObj; - asDroidNaybors[pos].distSqr = distSqr; - numNaybors++; - } -} - - -static DROID *CurrentNaybors = NULL; -static UDWORD nayborTime = 0; - -/* Find all the objects close to the droid */ -void droidGetNaybors(DROID *psDroid) -{ - SDWORD xdiff, ydiff; - UDWORD dx,dy, distSqr; - BASE_OBJECT *psObj; - - CHECK_DROID(psDroid); - - // Ensure only called max of once per droid per game cycle. - if (CurrentNaybors == psDroid && nayborTime == gameTime) - { - return; - } - CurrentNaybors = psDroid; - nayborTime = gameTime; - - // reset the naybor array - numNaybors = 0; - - // search for naybor objects - dx = psDroid->pos.x; - dy = psDroid->pos.y; - - gridStartIterate((SDWORD)dx, (SDWORD)dy); - for (psObj = gridIterate(); psObj != NULL; psObj = gridIterate()) - { - if (psObj != (BASE_OBJECT *)psDroid && !psObj->died) - { - xdiff = dx - (SDWORD)psObj->pos.x; - if (xdiff < 0) - { - xdiff = -xdiff; - } - if (xdiff > NAYBOR_RANGE) - { - continue; - } - - ydiff = dy - (SDWORD)psObj->pos.y; - if (ydiff < 0) - { - ydiff = -ydiff; - } - if (ydiff > NAYBOR_RANGE) - { - continue; - } - - distSqr = xdiff*xdiff + ydiff*ydiff; - if (distSqr > NAYBOR_RANGE*NAYBOR_RANGE) - { - continue; - } - - addNaybor(psObj, distSqr); - if (numNaybors >= MAX_NAYBORS) - { - break; - } - - } - } -} - /* The main update routine for all droids */ void droidUpdate(DROID *psDroid) { diff --git a/src/droid.h b/src/droid.h index 6bdf6f867..74e62b650 100644 --- a/src/droid.h +++ b/src/droid.h @@ -89,11 +89,6 @@ typedef enum HALF_FREE_TILE } PICKTILE; -/* Store for the objects near the droid currently being updated */ -#define MAX_NAYBORS 120 -extern NAYBOR_INFO asDroidNaybors[MAX_NAYBORS]; -extern UDWORD numNaybors; - // the structure that was last hit extern DROID *psLastDroidHit; @@ -103,11 +98,7 @@ extern UWORD aDroidExperience[MAX_PLAYERS][MAX_RECYCLED_DROIDS]; // initialise droid module extern BOOL droidInit(void); -extern void removeDroidBase(DROID *psDel); - -// refresh the naybor list -// this only does anything if the naybor list is out of date -extern void droidGetNaybors(DROID *psDroid); +extern void removeDroidBase(DROID *psDel); extern BOOL loadDroidTemplates(const char *pDroidData, UDWORD bufferSize); extern BOOL loadDroidWeapons(const char *pWeaponData, UDWORD bufferSize); diff --git a/src/mapgrid.cpp b/src/mapgrid.cpp index 77feef0c3..65d3fb1c1 100644 --- a/src/mapgrid.cpp +++ b/src/mapgrid.cpp @@ -102,19 +102,32 @@ void gridRemoveObject(BASE_OBJECT *psObj) //gridCalcCoverage(psObj, (SDWORD)psObj->pos.x, (SDWORD)psObj->pos.y, GRID_REMOVEOBJECT); } +static bool isInRadius(int32_t x, int32_t y, uint32_t radius) +{ + return x*x + y*y <= radius*radius; +} + // initialise the grid system to start iterating through units that // could affect a location (x,y in world coords) -void gridStartIterate(SDWORD x, SDWORD y/*, uint32_t radius*/) +void gridStartIterate(int32_t x, int32_t y, uint32_t radius) { - uint32_t radius = 20*TILE_UNITS; - - gridIterator = pointTreeQuery(gridPointTree, x, y, radius); // Use the C interface, for NULL termination. + gridPointTree->query(x, y, radius); + PointTree::ResultVector::iterator w = gridPointTree->lastQueryResults.begin(), i; + for (i = gridPointTree->lastQueryResults.begin(); i != gridPointTree->lastQueryResults.end(); ++i) + { + BASE_OBJECT *obj = static_cast(*i); + if (isInRadius(obj->pos.x - x, obj->pos.y - y, radius)) // Check that search result is less than radius (since they can be up to a factor of sqrt(2) more). + { + *w = *i; + ++w; + } + } + gridPointTree->lastQueryResults.erase(w, i); // Erase all points that were a bit too far. + gridPointTree->lastQueryResults.push_back(NULL); // NULL-terminate the result. + gridIterator = &gridPointTree->lastQueryResults[0]; /* // In case you are curious. - int len = 0; - for(void **x = gridIterator; *x != NULL; ++x) - ++len; - debug(LOG_WARNING, "gridStartIterate found %d objects", len); + debug(LOG_WARNING, "gridStartIterate(%d, %d, %u) found %u objects", x, y, radius, (unsigned)gridPointTree->lastQueryResults.size() - 1); */ } diff --git a/src/mapgrid.h b/src/mapgrid.h index f3346ca70..3fcc26dd5 100644 --- a/src/mapgrid.h +++ b/src/mapgrid.h @@ -58,8 +58,9 @@ extern void gridGarbageCollect(void); // TODO This function doesn't do anything, should probably be deleted. extern void gridDisplayCoverage(BASE_OBJECT *psObj); -/// Find all objects within radius r = 20*TILE_UNITS. Call gridIterate() to get the search results. -extern void gridStartIterate(int32_t x, int32_t y/*, uint32_t radius*/); +#define PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS (20*TILE_UNITS) +/// Find all objects within radius. Call gridIterate() to get the search results. +extern void gridStartIterate(int32_t x, int32_t y, uint32_t radius); /// Get the next search result from gridStartIterate, or NULL if finished. static inline BASE_OBJECT *gridIterate(void) diff --git a/src/move.c b/src/move.c index 9ec38caed..4dec60dcc 100644 --- a/src/move.c +++ b/src/move.c @@ -903,51 +903,41 @@ static SDWORD moveObjRadius(const BASE_OBJECT* psObj) // see if a Droid has run over a person static void moveCheckSquished(DROID *psDroid, float mx,float my) { - SDWORD i, droidR, rad, radSq; - SDWORD objR; - SDWORD xdiff,ydiff, distSq; - NAYBOR_INFO *psInfo; + SDWORD droidR, rad, radSq; + SDWORD objR; + SDWORD xdiff, ydiff, distSq; + BASE_OBJECT *psObj; droidR = moveObjRadius((BASE_OBJECT *)psDroid); - for(i=0; i<(SDWORD)numNaybors; i++) + gridStartIterate(psDroid->pos.x, psDroid->pos.y, OBJ_MAXRADIUS); + for (psObj = gridIterate(); psObj != NULL; psObj = gridIterate()) { - psInfo = asDroidNaybors + i; - if (psInfo->psObj->type != OBJ_DROID || - ((DROID *)psInfo->psObj)->droidType != DROID_PERSON) + if (psObj->type != OBJ_DROID || ((DROID *)psObj)->droidType != DROID_PERSON) { // ignore everything but people continue; } - ASSERT( psInfo->psObj->type == OBJ_DROID && - ((DROID *)psInfo->psObj)->droidType == DROID_PERSON, - "squished - eerk" ); + ASSERT(psObj->type == OBJ_DROID && ((DROID *)psObj)->droidType == DROID_PERSON, "squished - eerk"); - objR = moveObjRadius(psInfo->psObj); + objR = moveObjRadius(psObj); rad = droidR + objR; radSq = rad*rad; - xdiff = (SDWORD)psDroid->pos.x + mx - psInfo->psObj->pos.x; - ydiff = (SDWORD)psDroid->pos.y + my - psInfo->psObj->pos.y; + xdiff = psDroid->pos.x + mx - psObj->pos.x; + ydiff = psDroid->pos.y + my - psObj->pos.y; distSq = xdiff*xdiff + ydiff*ydiff; if (((2*radSq)/3) > distSq) { - if ( (psDroid->player != psInfo->psObj->player) && - !aiCheckAlliances(psDroid->player, psInfo->psObj->player) ) + if ((psDroid->player != psObj->player) && !aiCheckAlliances(psDroid->player, psObj->player)) { // run over a bloke - kill him - destroyDroid((DROID*)psInfo->psObj); + destroyDroid((DROID *)psObj); scoreUpdateVar(WD_BARBARIANS_MOWED_DOWN); - continue; } } - else if (psInfo->distSqr > OBJ_MAXRADIUS*OBJ_MAXRADIUS) - { - // object is too far away to be hit - break; - } } } @@ -1351,12 +1341,11 @@ static void moveCalcBlockingSlide(DROID *psDroid, float *pmx, float *pmy, SDWORD // Only consider stationery droids static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) { - SDWORD i, droidR, rad, radSq; - SDWORD objR; - SDWORD xdiff,ydiff, distSq; - NAYBOR_INFO *psInfo; - BASE_OBJECT *psObst; - BOOL bLegs; + SDWORD droidR, rad, radSq; + SDWORD objR; + SDWORD xdiff, ydiff, distSq; + BASE_OBJECT *psObj, *psObst; + BOOL bLegs; CHECK_DROID(psDroid); @@ -1368,26 +1357,24 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) droidR = moveObjRadius((BASE_OBJECT *)psDroid); psObst = NULL; - for(i=0; i<(SDWORD)numNaybors; i++) + gridStartIterate(psDroid->pos.x, psDroid->pos.y, OBJ_MAXRADIUS); + for (psObj = gridIterate(); psObj != NULL; psObj = gridIterate()) { - psInfo = asDroidNaybors + i; - if (psInfo->psObj->type == OBJ_DROID) + if (psObj->type == OBJ_DROID) { - if ( ((DROID *)psInfo->psObj)->droidType == DROID_TRANSPORTER ) + if (((DROID *)psObj)->droidType == DROID_TRANSPORTER) { // ignore transporters continue; } - if (bLegs - && ((DROID *)psInfo->psObj)->droidType != DROID_PERSON - && !cyborgDroid((DROID *)psInfo->psObj)) + if (bLegs && ((DROID *)psObj)->droidType != DROID_PERSON + && !cyborgDroid((DROID *)psObj)) { // cyborgs/people only avoid other cyborgs/people continue; } - if (!bLegs && - (((DROID *)psInfo->psObj)->droidType == DROID_PERSON)) + if (!bLegs && ((DROID *)psObj)->droidType == DROID_PERSON) { // everything else doesn't avoid people continue; @@ -1399,12 +1386,12 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) continue; } - objR = moveObjRadius(psInfo->psObj); + objR = moveObjRadius(psObj); rad = droidR + objR; radSq = rad*rad; - xdiff = psDroid->sMove.fx + *pmx - psInfo->psObj->pos.x; - ydiff = psDroid->sMove.fy + *pmy - psInfo->psObj->pos.y; + xdiff = psDroid->sMove.fx + *pmx - psObj->pos.x; + ydiff = psDroid->sMove.fy + *pmy - psObj->pos.y; distSq = xdiff * xdiff + ydiff * ydiff; if ((float)xdiff * *pmx + (float)ydiff * *pmy >= 0) { @@ -1414,7 +1401,7 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) if (radSq > distSq) { - if (psObst != NULL || !aiCheckAlliances(psInfo->psObj->player, psDroid->player)) + if (psObst != NULL || !aiCheckAlliances(psObj->player, psDroid->player)) { // hit more than one droid - stop *pmx = (float)0; @@ -1424,7 +1411,7 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) } else { - psObst = psInfo->psObj; + psObst = psObj; // note the bump time and position if necessary if (psDroid->sMove.bumpTime == 0) @@ -1466,11 +1453,6 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) } } } - else if (psInfo->distSqr > OBJ_MAXRADIUS*OBJ_MAXRADIUS) - { - // object is too far away to be hit - break; - } } if (psObst != NULL) @@ -1484,7 +1466,7 @@ static void moveCalcDroidSlide(DROID *psDroid, float *pmx, float *pmy) // get an obstacle avoidance vector static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY) { - SDWORD i, xdiff, ydiff, absx, absy, dist; + SDWORD xdiff, ydiff, absx, absy, dist; BASE_OBJECT *psObj; SDWORD numObst = 0, distTot = 0; float dirX = 0, dirY = 0; @@ -1495,16 +1477,13 @@ static void moveGetObstacleVector(DROID *psDroid, float *pX, float *pY) ASSERT(psPropStats, "invalid propulsion stats pointer"); - droidGetNaybors(psDroid); - // scan the neighbours for obstacles - for(i = 0; i < (SDWORD)numNaybors; i++) + gridStartIterate(psDroid->pos.x, psDroid->pos.y, AVOID_DIST); + for (psObj = gridIterate(); psObj != NULL; psObj = gridIterate()) { - psObj = asDroidNaybors[i].psObj; - if (psObj->type != OBJ_DROID || - asDroidNaybors[i].distSqr >= AVOID_DIST*AVOID_DIST) + if (psObj->type != OBJ_DROID) { - // object too far away to worry about + // Object wrong type to worry about. continue; } @@ -2220,8 +2199,7 @@ static void moveUpdateGroundModel(DROID *psDroid, SDWORD speed, SDWORD direction return; } - // update the naybors list - droidGetNaybors(psDroid); + // Used to update some kind of weird neighbour list here. moveCheckFinalWaypoint( psDroid, &speed ); @@ -2300,8 +2278,7 @@ static void moveUpdatePersonModel(DROID *psDroid, SDWORD speed, SDWORD direction return; } - // update the naybors list - droidGetNaybors(psDroid); + // Used to update some kind of weird neighbour list here. moveUpdateDroidDirection( psDroid, &speed, direction, PERSON_SPIN_ANGLE, PERSON_SPIN_SPEED, PERSON_TURN_SPEED, &iDroidDir, &fSpeed ); @@ -2425,8 +2402,7 @@ static void moveUpdateVtolModel(DROID *psDroid, SDWORD speed, SDWORD direction) return; } - // update the naybors list - droidGetNaybors(psDroid); + // Used to update some kind of weird neighbour list here. moveCheckFinalWaypoint( psDroid, &speed ); @@ -2534,8 +2510,7 @@ static void moveUpdateJumpCyborgModel(DROID *psDroid, SDWORD speed, SDWORD direc return; } - // update the naybors list - droidGetNaybors(psDroid); + // Used to update some kind of weird neighbour list here. moveUpdateDroidDirection( psDroid, &speed, direction, VTOL_SPIN_ANGLE, psDroid->baseSpeed, psDroid->baseSpeed/3, &iDroidDir, &fSpeed ); @@ -2874,7 +2849,6 @@ static void movePlayAudio( DROID *psDroid, BOOL bStarted, BOOL bStoppedBefore, S // use to pick up oil, etc.. static void checkLocalFeatures(DROID *psDroid) { - SDWORD i; BASE_OBJECT *psObj; static int oilTimer = 0; static bool GenerateDrum = false; @@ -2882,24 +2856,19 @@ static void checkLocalFeatures(DROID *psDroid) // NOTE: Why not do this for AI units also? // only do for players droids. - if (psDroid->player != selectedPlayer) + if (psDroid->player != selectedPlayer || isVtolDroid(psDroid)) // VTOLs can't pick up features! { return; } - droidGetNaybors(psDroid);// update naybor list. - ASSERT( numNaybors <= MAX_NAYBORS, "numNaybors is %d, out of range of %d!", numNaybors, MAX_NAYBORS); // scan the neighbours - for(i=0; i<(SDWORD)numNaybors; i++) +#define DROIDDIST ((TILE_UNITS*5)/2) + gridStartIterate(psDroid->pos.x, psDroid->pos.y, DROIDDIST); + for (psObj = gridIterate(); psObj != NULL; psObj = gridIterate()) { -#define DROIDDIST (((TILE_UNITS*5)/2) * ((TILE_UNITS*5)/2)) - psObj = asDroidNaybors[i].psObj; - if ( psObj->type != OBJ_FEATURE - || ((FEATURE *)psObj)->psStats->subType != FEAT_OIL_DRUM - || asDroidNaybors[i].distSqr >= DROIDDIST - || isVtolDroid(psDroid)) // VTOLs can't pick up features! + if (psObj->type != OBJ_FEATURE || ((FEATURE *)psObj)->psStats->subType != FEAT_OIL_DRUM || psObj->died) { - // object too far away to worry about + // Object is not a living oil drum. continue; } diff --git a/src/projectile.c b/src/projectile.c index feaa3910c..046094411 100644 --- a/src/projectile.c +++ b/src/projectile.c @@ -75,6 +75,7 @@ typedef struct _interval // used to create a specific ID for projectile objects to facilitate tracking them. static const UDWORD ProjectileTrackerID = 0xdead0000; // Watermelon:neighbour global info ripped from droid.c +#define MAX_NAYBORS 120 static PROJ_NAYBOR_INFO asProjNaybors[MAX_NAYBORS]; static UDWORD numProjNaybors = 0; @@ -1933,7 +1934,7 @@ static void projGetNaybors(PROJECTILE *psObj) // reset the naybor array numProjNaybors = 0; - gridStartIterate(psObj->pos.x, psObj->pos.y); + gridStartIterate(psObj->pos.x, psObj->pos.y, PROJ_NAYBOR_RANGE); while ((psTempObj = gridIterate()) != NULL) { if (psTempObj != (BASE_OBJECT *)psObj && !psTempObj->died) diff --git a/src/visibility.c b/src/visibility.c index 10ea8e67b..cd8396ea2 100644 --- a/src/visibility.c +++ b/src/visibility.c @@ -564,9 +564,6 @@ void processVisibility(BASE_OBJECT *psObj) memcpy(currVis, prevVis, sizeof(*prevVis) * MAX_PLAYERS); } - // get all the objects from the grid the droid is in - gridStartIterate(psObj->pos.x, psObj->pos.y); - // Make sure allies can see us if (bMultiPlayer && game.alliance == ALLIANCES_TEAMS) { @@ -604,6 +601,8 @@ void processVisibility(BASE_OBJECT *psObj) } else { + // get all the objects from the grid the droid is in + gridStartIterate(psObj->pos.x, psObj->pos.y, PREVIOUS_DEFAULT_GRID_SEARCH_RADIUS); while (psViewer = gridIterate(), psViewer != NULL) { int val;