/* Will return false when we've hit the edge of the grid */ static bool getTileHeightCallback(Vector2i pos, int32_t dist, void *data) { HeightCallbackHelp_t *help = (HeightCallbackHelp_t *)data; #ifdef TEST_RAY Vector3i effect; #endif /* Are we still on the grid? */ if (clipXY(pos.x, pos.y)) { bool HasTallStructure = blockTile(map_coord(pos.x), map_coord(pos.y), AUX_MAP) & AIR_BLOCKED; if (dist > TILE_UNITS || HasTallStructure) { // Only do it the current tile is > TILE_UNITS away from the starting tile. Or.. // there is a tall structure on the current tile and the current tile is not the starting tile. /* Get height at this intersection point */ int height = map_Height(pos.x, pos.y), heightDiff; uint16_t newPitch; if (HasTallStructure) { height += TALLOBJECT_ADJUST; } if (height <= help->height) { heightDiff = 0; } else { heightDiff = height - help->height; } /* Work out the angle to this point from start point */ newPitch = iAtan2(heightDiff, dist); /* Is this the steepest we've found? */ if (angleDelta(newPitch - help->pitch) > 0) { /* Yes, then keep a record of it */ help->pitch = newPitch; } //--- #ifdef TEST_RAY effect.x = pos.x; effect.y = height; effect.z = pos.y; addEffect(&effect, EFFECT_EXPLOSION, EXPLOSION_TYPE_SMALL, false, NULL, 0); #endif } /* Not at edge yet - so exit */ return true; } /* We've hit edge of grid - so exit!! */ return false; }
// Check if the map tile at a location blocks a droid bool fpathBaseBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion, int mapIndex, FPATH_MOVETYPE moveType) { /* All tiles outside of the map and on map border are blocking. */ if (x < 1 || y < 1 || x > mapWidth - 1 || y > mapHeight - 1) { return true; } /* Check scroll limits (used in campaign to partition the map. */ if (propulsion != PROPULSION_TYPE_LIFT && (x < scrollMinX + 1 || y < scrollMinY + 1 || x >= scrollMaxX - 1 || y >= scrollMaxY - 1)) { // coords off map - auto blocking tile return true; } unsigned aux = auxTile(x, y, mapIndex); int auxMask = 0; switch (moveType) { case FMT_MOVE: auxMask = AUXBITS_NONPASSABLE; break; // do not wish to shoot our way through enemy buildings, but want to go through friendly gates (without shooting them) case FMT_ATTACK: auxMask = AUXBITS_OUR_BUILDING; break; // move blocked by friendly building, assuming we do not want to shoot it up en route case FMT_BLOCK: auxMask = AUXBITS_BLOCKING; break; // Do not wish to tunnel through closed gates or buildings. } unsigned unitbits = prop2bits(propulsion); // TODO - cache prop2bits to psDroid, and pass in instead of propulsion type if ((unitbits & FEATURE_BLOCKED) != 0 && (aux & auxMask) != 0) { return true; // move blocked by building, and we cannot or do not want to shoot our way through anything } // the MAX hack below is because blockTile() range does not include player-specific versions... return (blockTile(x, y, MAX(0, mapIndex - MAX_PLAYERS)) & unitbits) != 0; // finally check if move is blocked by propulsion related factors }
// Check if the map tile at a location blocks a droid BOOL fpathBaseBlockingTile(SDWORD x, SDWORD y, PROPULSION_TYPE propulsion, int mapIndex, FPATH_MOVETYPE moveType) { uint8_t aux, unitbits = prop2bits(propulsion); // TODO - cache prop2bits to psDroid, and pass in instead of propulsion type /* All tiles outside of the map and on map border are blocking. */ if (x < 1 || y < 1 || x > mapWidth - 1 || y > mapHeight - 1) { return true; } /* Check scroll limits (used in campaign to partition the map. */ if (propulsion != PROPULSION_TYPE_LIFT && (x < scrollMinX + 1 || y < scrollMinY + 1 || x >= scrollMaxX - 1 || y >= scrollMaxY - 1)) { // coords off map - auto blocking tile return true; } aux = auxTile(x, y, mapIndex); if ((unitbits & FEATURE_BLOCKED) && ((moveType == FMT_MOVE && (aux & AUXBITS_ANY_BUILDING)) // do not wish to shoot our way through enemy buildings || (aux & AUXBITS_OUR_BUILDING))) // move blocked by friendly building, assuming we do not want to shoot it up en route { return true; // move blocked by building, and we cannot or do not want to shoot our way through anything } // the MAX hack below is because blockTile() range does not include player-specific versions... return (blockTile(x, y, MAX(0, mapIndex - MAX_PLAYERS)) & unitbits); // finally check if move is blocked by propulsion related factors }