Skip to content

Commit

Permalink
Moved GetTerrainHeightsAroundParty2 to OutdoorTerrain
Browse files Browse the repository at this point in the history
  • Loading branch information
captainurist committed Nov 10, 2024
1 parent 5b2be4b commit e1a2cae
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 51 deletions.
52 changes: 3 additions & 49 deletions src/Engine/Graphics/Outdoor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,7 +685,7 @@ void OutdoorLocation::ArrangeSpriteObjects() {
for (int i = 0; i < (signed int)pSpriteObjects.size(); ++i) {
if (pSpriteObjects[i].uObjectDescID) {
if (!(pSpriteObjects[i].uAttributes & SPRITE_DROPPED_BY_PLAYER) && !pSpriteObjects[i].IsUnpickable()) {
pSpriteObjects[i].vPosition.z = GetTerrainHeightsAroundParty2(pSpriteObjects[i].vPosition);
pSpriteObjects[i].vPosition.z = pOutdoor->pTerrain.heightByPos(pSpriteObjects[i].vPosition);
}
if (pSpriteObjects[i].containing_item.uItemID != ITEM_NULL) {
if (pSpriteObjects[i].containing_item.uItemID != ITEM_POTION_BOTTLE &&
Expand Down Expand Up @@ -931,7 +931,7 @@ float ODM_GetFloorLevel(const Vec3f &pos, bool *pIsOnWater, int *faceId) {
std::array<float, 20> odm_floor_level{}; // idb
current_BModel_id[0] = -1;
current_Face_id[0] = -1;
odm_floor_level[0] = GetTerrainHeightsAroundParty2(pos);
odm_floor_level[0] = pOutdoor->pTerrain.heightByPos(pos);
*pIsOnWater = pOutdoor->pTerrain.isWaterByPos(pos);

int surface_count = 1;
Expand Down Expand Up @@ -1538,7 +1538,7 @@ void ODM_ProcessPartyActions() {
pParty->uFlags &= ~(PARTY_FLAG_BURNING | PARTY_FLAG_WATER_DAMAGE);

if (partyDrowningFlag) {
int pTerrainHeight = GetTerrainHeightsAroundParty2(pParty->pos);
int pTerrainHeight = pOutdoor->pTerrain.heightByPos(pParty->pos);
if (pParty->pos.z <= pTerrainHeight + 1) {
pParty->uFlags |= PARTY_FLAG_WATER_DAMAGE;
}
Expand Down Expand Up @@ -2071,52 +2071,6 @@ int GridCellToWorldPosX(int a1) { return (a1 - 64) << 9; }
//----- (0047F476) --------------------------------------------------------
int GridCellToWorldPosY(int a1) { return (64 - a1) << 9; }

//----- (0048257A) --------------------------------------------------------
int GetTerrainHeightsAroundParty2(const Vec3f &pos) {
// int result; // eax@9
int originz; // ebx@11
int lz; // eax@11
int rz; // ecx@11
int rpos; // [sp+10h] [bp-8h]@11
int lpos; // [sp+24h] [bp+Ch]@11

// TODO(captainurist): this function had some code that would push the party -60 units down when on a water tile AND
// not water-walking, but this isn't enabled in the game. I tried it, and it actually looks
// good, as if the party is actually a bit submerged and swimming. The only problem is that
// party would be jerked up upon coming ashore, and this just looks ugly. Find a way to
// reimplement this properly.

Vec2i gridPos = WorldPosToGrid(pos);

OutdoorTileGeometry tile = pOutdoor->pTerrain.tileGeometryByGrid(gridPos);

if (tile.v00.z != tile.v10.z || tile.v10.z != tile.v11.z || tile.v11.z != tile.v01.z) {
// On a slope.
if (std::abs(tile.v00.y - pos.y) >= std::abs(pos.x - tile.v00.x)) {
originz = tile.v01.z;
lz = tile.v11.z;
rz = tile.v00.z;
lpos = pos.x - tile.v00.x;
rpos = pos.y - tile.v11.y;
} else {
originz = tile.v10.z;
lz = tile.v00.z;
rz = tile.v11.z;
lpos = tile.v11.x - pos.x;
rpos = tile.v00.y - pos.y;
}

assert(lpos >= 0 && lpos < 512);
assert(rpos >= 0 && rpos < 512);

// (x >> 9) is basically (x / 512) but with consistent rounding towards -inf.
return originz + ((rpos * (rz - originz)) >> 9) + ((lpos * (lz - originz)) >> 9);
} else {
// On flat terrain.
return tile.v00.z;
}
}

//----- (00436A6D) --------------------------------------------------------
double OutdoorLocation::GetPolygonMinZ(RenderVertexSoft *pVertices, unsigned int unumverts) {
double result = FLT_MAX;
Expand Down
1 change: 0 additions & 1 deletion src/Engine/Graphics/Outdoor.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ Vec2i WorldPosToGrid(Vec3f worldPos);
int GridCellToWorldPosX(int);
int GridCellToWorldPosY(int);
void sub_481ED9_MessWithODMRenderParams();
int GetTerrainHeightsAroundParty2(const Vec3f &pos);
void TeleportToStartingPoint(MapStartPoint point); // idb

extern MapStartPoint uLevel_StartingPointType;
45 changes: 45 additions & 0 deletions src/Engine/Graphics/OutdoorTerrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,51 @@ int OutdoorTerrain::heightByGrid(Vec2i gridPos) {
return 32 * pHeightmap[gridPos.y * 128 + gridPos.x];
}

int OutdoorTerrain::heightByPos(const Vec3f &pos) {
// TODO(captainurist): This should return float. But we'll need to retrace.
int originz; // ebx@11
int lz; // eax@11
int rz; // ecx@11
int rpos; // [sp+10h] [bp-8h]@11
int lpos; // [sp+24h] [bp+Ch]@11

// TODO(captainurist): this function had some code that would push the party -60 units down when on a water tile AND
// not water-walking, but this isn't enabled in the game. I tried it, and it actually looks
// good, as if the party is actually a bit submerged and swimming. The only problem is that
// party would be jerked up upon coming ashore, and this just looks ugly. Find a way to
// reimplement this properly.

Vec2i gridPos = WorldPosToGrid(pos);

OutdoorTileGeometry tile = pOutdoor->pTerrain.tileGeometryByGrid(gridPos);

if (tile.v00.z != tile.v10.z || tile.v10.z != tile.v11.z || tile.v11.z != tile.v01.z) {
// On a slope.
if (std::abs(tile.v00.y - pos.y) >= std::abs(pos.x - tile.v00.x)) {
originz = tile.v01.z;
lz = tile.v11.z;
rz = tile.v00.z;
lpos = pos.x - tile.v00.x;
rpos = pos.y - tile.v11.y;
} else {
originz = tile.v10.z;
lz = tile.v00.z;
rz = tile.v11.z;
lpos = tile.v11.x - pos.x;
rpos = tile.v00.y - pos.y;
}

assert(lpos >= 0 && lpos < 512);
assert(rpos >= 0 && rpos < 512);

// (x >> 9) is basically (x / 512) but with consistent rounding towards -inf.
return originz + ((rpos * (rz - originz)) >> 9) + ((lpos * (lz - originz)) >> 9);
} else {
// On flat terrain.
return tile.v00.z;
}
}

int OutdoorTerrain::tileIdByGrid(Vec2i gridPos) const {
if (gridPos.x < 0 || gridPos.x > 127 || gridPos.y < 0 || gridPos.y > 127)
return 0;
Expand Down
5 changes: 5 additions & 0 deletions src/Engine/Graphics/OutdoorTerrain.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ class OutdoorTerrain {

int heightByGrid(Vec2i gridPos);

/**
* @offset 0x0048257A
*/
int heightByPos(const Vec3f &pos);

/**
* @param gridPos Grid coordinates.
* @return Tile id at `gridPos` that can then be used to get tile data from `TileTable`.
Expand Down
2 changes: 1 addition & 1 deletion src/Engine/Spells/CastSpellInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2904,7 +2904,7 @@ void CastSpellInfoHelpers::castSpell() {
}
for (unsigned i = 0; i < 50; i++) {
Vec3f rand(grng->random(4096) - 2048, grng->random(4096) - 2048, 0);
int terr_height = GetTerrainHeightsAroundParty2(pParty->pos + rand);
int terr_height = pOutdoor->pTerrain.heightByPos(pParty->pos + rand);
SpriteObject::dropItemAt(SPRITE_SPELL_EARTH_ROCK_BLAST,
{rand.x + pParty->pos.x, rand.y + pParty->pos.y, terr_height + 16.0f}, grng->random(500) + 500);
}
Expand Down

0 comments on commit e1a2cae

Please sign in to comment.