From 841fe5b9cb0538a9479a9c6bd830f28ba4178099 Mon Sep 17 00:00:00 2001 From: Charles Pigott Date: Thu, 1 Jan 2015 18:30:23 +0000 Subject: [PATCH 10/14] Add addition operator to xyz and use it --- src/coaster.cpp | 36 +++++++++----------- src/coaster.h | 2 +- src/fence_build.cpp | 4 +-- src/geometry.h | 36 ++++++++++++++++++++ src/map.cpp | 2 +- src/map.h | 4 +-- src/path_build.cpp | 12 +++---- src/person.cpp | 98 ++++++++++++++++++++++++++--------------------------- src/ride_gui.cpp | 30 ++++++++-------- src/ride_type.cpp | 2 +- src/viewport.cpp | 8 ++--- 11 files changed, 132 insertions(+), 102 deletions(-) diff --git a/src/coaster.cpp b/src/coaster.cpp index e88d6e6..e3556b1 100644 --- a/src/coaster.cpp +++ b/src/coaster.cpp @@ -238,22 +238,19 @@ const ImageData *DisplayCoasterCar::GetSprite(const SpriteStorage *sprites, View /** * Set the position and orientation of the car. It requests repainting of voxels. - * @param xvoxel %Voxel in x direction. - * @param yvoxel %Voxel in y direction. - * @param zvoxel %Voxel in z direction. - * @param xpos X position within the voxel (may be outside the \c 0..255 boundary). - * @param ypos Y position within the voxel (may be outside the \c 0..255 boundary). - * @param zpos Z position within the voxel (may be outside the \c 0..255 boundary). + * @param vox_pos %Voxel position of car. + * @param pix_pos Position within the voxel (may be outside the \c 0..255 boundary). * @param pitch Pitch of the car. * @param roll Roll of the car. * @param yaw Yaw of the car. */ -void DisplayCoasterCar::Set(int16 xvoxel, int16 yvoxel, int8 zvoxel, int16 xpos, int16 ypos, int16 zpos, uint8 pitch, uint8 roll, uint8 yaw) +void DisplayCoasterCar::Set(const XYZPoint16 &vox_pos, const XYZPoint16 &pix_pos, uint8 pitch, uint8 roll, uint8 yaw) { - bool change_voxel = this->vox_pos.x != xvoxel || this->vox_pos.y != yvoxel || this->vox_pos.z != zvoxel; + bool change_voxel = this->vox_pos != vox_pos; - if (!change_voxel && this->x_pos == xpos && this->y_pos == ypos && this->z_pos == zpos && - this->pitch == pitch && this->roll == roll && this->yaw == yaw) return; // Nothing changed. + if (!change_voxel && this->pix_pos == pix_pos && this->pitch == pitch && this->roll == roll && this->yaw == yaw) { + return; // Nothing changed. + } if (this->yaw != 0xff && change_voxel) { /* Valid data, and changing voxel -> remove self from the old voxel. */ @@ -263,14 +260,8 @@ void DisplayCoasterCar::Set(int16 xvoxel, int16 yvoxel, int8 zvoxel, int16 xpos, } /* Update voxel and orientation. */ - this->vox_pos.x = xvoxel; - this->vox_pos.y = yvoxel; - this->vox_pos.z = zvoxel; - - this->x_pos = xpos; - this->y_pos = ypos; - this->z_pos = zpos; - + this->vox_pos = vox_pos; + this->pix_pos = pix_pos; this->pitch = pitch; this->roll = roll; this->yaw = yaw; @@ -509,9 +500,14 @@ void CoasterTrain::OnAnimate(int delay) xpos_front &= 0xFFFFFF00; ypos_front &= 0xFFFFFF00; zpos_front &= 0xFFFFFF00; + XYZPoint16 back( xpos_back >> 8, ypos_back >> 8, zpos_back >> 8); + XYZPoint16 front(xpos_front >> 8, ypos_front >> 8, zpos_front >> 8); + + XYZPoint16 back_pix( xpos_middle - xpos_back, ypos_middle - ypos_back, zpos_middle - zpos_back); + XYZPoint16 front_pix(xpos_middle - xpos_front, ypos_middle - ypos_front, zpos_middle - zpos_front); - car.back.Set( xpos_back >> 8, ypos_back >> 8, zpos_back >> 8, xpos_middle - xpos_back, ypos_middle - ypos_back, zpos_middle - zpos_back, pitch, roll, yaw); - car.front.Set(xpos_front >> 8, ypos_front >> 8, zpos_front >> 8, xpos_middle - xpos_front, ypos_middle - ypos_front, zpos_middle - zpos_front, pitch, roll, yaw); + car.back.Set (back, back_pix, pitch, roll, yaw); + car.front.Set(front, front_pix, pitch, roll, yaw); position += this->coaster->car_type->inter_car_length; } } diff --git a/src/coaster.h b/src/coaster.h index 10a7b7f..8768538 100644 --- a/src/coaster.h +++ b/src/coaster.h @@ -123,7 +123,7 @@ public: virtual const ImageData *GetSprite(const SpriteStorage *sprites, ViewOrientation orient, const Recolouring **recolour) const override; - void Set(int16 xvoxel, int16 yvoxel, int8 zvoxel, int16 xpos, int16 ypos, int16 zpos, uint8 pitch, uint8 roll, uint8 yaw); + void Set(const XYZPoint16 &vox_pos, const XYZPoint16 &pix_pos, uint8 pitch, uint8 roll, uint8 yaw); void PreRemove(); const CarType *car_type; ///< Car type data. diff --git a/src/fence_build.cpp b/src/fence_build.cpp index 7e5849d..70a4270 100644 --- a/src/fence_build.cpp +++ b/src/fence_build.cpp @@ -85,7 +85,7 @@ void FenceBuildManager::SetCursors() int32 extra_z = 0; if ((slope & TSB_TOP) == 0 && IsRaisedEdge(edge, slope)) { extra_z = 1; - v = _world.GetCreateVoxel(XYZPoint16(fdata.voxel_pos.x, fdata.voxel_pos.y, fdata.voxel_pos.z + extra_z), true); + v = _world.GetCreateVoxel(fdata.voxel_pos + XYZPoint16(0, 0, extra_z), true); assert(v != nullptr); } const SpriteStorage *ss = _sprite_manager.GetSprites(vp->tile_width); @@ -148,7 +148,7 @@ void FenceBuildManager::OnMouseButtonEvent(Viewport *vp, uint8 state) assert(v != nullptr); } v->SetFenceType(edge, this->selected_fence_type); - vp->MarkVoxelDirty(XYZPoint16(c->cursor_pos.x, c->cursor_pos.y, c->cursor_pos.z + extra_z)); + vp->MarkVoxelDirty(c->cursor_pos + XYZPoint16(0, 0, extra_z)); } } diff --git a/src/geometry.h b/src/geometry.h index 2354159..46a6f59 100644 --- a/src/geometry.h +++ b/src/geometry.h @@ -86,11 +86,33 @@ struct XYZPoint { this->z = z; } + /** + * Get the 2D coordinates of the 3D point. + * @return X & Y coordinates. + */ + Point Get2D() const + { + return Point(this->x, this->y); + } + typedef CT CoordType; ///< Type of the coordinate value. CT x; ///< X coordinate. CT y; ///< Y coordinate. CT z; ///< Z coordinate. + + /** + * Add a 3D point to this one. + * @param q Second point to add. + * @return All 3 dimensions added to each other. + */ + inline XYZPoint operator+=(const XYZPoint &q) + { + this->x += q.x; + this->y += q.y; + this->z += q.z; + return *this; + } }; typedef XYZPoint XYZPoint32; ///< 32 bit 3D point. @@ -121,6 +143,20 @@ inline bool operator!=(const XYZPoint &p, const XYZPoint &q) } /** + * Add two 3D points together. + * @param p First point to add. + * @param q Second point to add. + * @return All 3 dimensions added to each other. + * @note Takes a copy of the lhs. + */ +template +inline XYZPoint operator+(XYZPoint p, const XYZPoint &q) +{ + p += q; + return p; +} + +/** * An area in 2D. * @tparam PT Base point type. * @tparam SZ Size type. diff --git a/src/map.cpp b/src/map.cpp index 5b3ebf1..6f4d6be 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -707,6 +707,6 @@ void WorldAdditions::MarkDirty(Viewport *vp) for (const auto &iter : this->modified_stacks) { const Point32 pt = iter.first; const VoxelStack *vstack = iter.second; - if (vstack != nullptr) vp->MarkVoxelDirty(XYZPoint16(pt.x, pt.x, vstack->base), vstack->height); + if (vstack != nullptr) vp->MarkVoxelDirty(XYZPoint16(pt.x, pt.y, vstack->base), vstack->height); } } diff --git a/src/map.h b/src/map.h index c1fdaa9..23a4f3a 100644 --- a/src/map.h +++ b/src/map.h @@ -356,9 +356,7 @@ public: bool added; ///< Whether the voxel object has been added to a voxel. XYZPoint16 vox_pos; ///< %Voxel position of the object. - int16 x_pos; ///< X position of the person inside the voxel (0..255). - int16 y_pos; ///< Y position of the person inside the voxel (0..255). - int16 z_pos; ///< Z position of the person inside the voxel (0..255). + XYZPoint16 pix_pos; ///< Position of the object inside the voxel (0..255, but may be outside). }; /** diff --git a/src/path_build.cpp b/src/path_build.cpp index d6887a6..b924f80 100644 --- a/src/path_build.cpp +++ b/src/path_build.cpp @@ -280,7 +280,7 @@ static uint8 CanBuildPathFromEdge(const XYZPoint16 &voxel_pos, TileEdge edge) if (ps == _path_up_from_edge[edge]) return 1 << TSL_UP; } if (voxel_pos.z > 0) { - v = _world.GetVoxel(XYZPoint16(voxel_pos.x, voxel_pos.y, voxel_pos.z - 1)); + v = _world.GetVoxel(voxel_pos + XYZPoint16(0, 0, -1)); if (v != nullptr && HasValidPath(v) && GetImplodedPathSlope(v) == _path_down_from_edge[edge]) return 1 << TSL_DOWN; } @@ -487,12 +487,12 @@ void PathBuildManager::MoveCursor(TileEdge edge, bool move_up) const Voxel *v_top, *v_bot; if (move_up) { /* Exit of current tile is at the top. */ - v_top = (this->pos.z > WORLD_Z_SIZE - 2) ? nullptr : _world.GetVoxel(XYZPoint16(this->pos.x + dxy.x, this->pos.y + dxy.y, this->pos.z + 1)); - v_bot = _world.GetVoxel(XYZPoint16(this->pos.x + dxy.x, this->pos.y + dxy.y, this->pos.z)); + v_top = (this->pos.z > WORLD_Z_SIZE - 2) ? nullptr : _world.GetVoxel(this->pos + XYZPoint16(dxy.x, dxy.y, 1)); + v_bot = _world.GetVoxel(this->pos + XYZPoint16(dxy.x, dxy.y, 0)); } else { /* Exit of current tile is at the bottom. */ - v_top = _world.GetVoxel(XYZPoint16(this->pos.x + dxy.x, this->pos.y + dxy.y, this->pos.z)); - v_bot = (this->pos.z == 0) ? nullptr : _world.GetVoxel(XYZPoint16(this->pos.x + dxy.x, this->pos.y + dxy.y, this->pos.z - 1)); + v_top = _world.GetVoxel(this->pos + XYZPoint16(dxy.x, dxy.y, 0)); + v_bot = (this->pos.z == 0) ? nullptr : _world.GetVoxel(this->pos + XYZPoint16(dxy.x, dxy.y, -1)); } /* Try to find a voxel with a path. */ @@ -780,7 +780,7 @@ void PathBuildManager::ComputeNewLongPath(const Point32 &mousexy) default: NOT_REACHED(); } - XYZPoint16 path_pos = XYZPoint16(0, 0, 0); + XYZPoint16 path_pos(0, 0, 0); path_pos.y = this->pos.y * 256 + 128; int32 lambda_y = path_pos.y - mousexy.y; // Distance to constant Y plane at current tile cursor. path_pos.x = this->pos.x * 256 + 128; diff --git a/src/person.cpp b/src/person.cpp index 750ac31..fb9dacf 100644 --- a/src/person.cpp +++ b/src/person.cpp @@ -191,19 +191,19 @@ void Person::Activate(const Point16 &start, PersonType person_type) this->AddSelf(_world.GetCreateVoxel(this->vox_pos, false)); if (start.x == 0) { - this->x_pos = 0; - this->y_pos = 128 - this->offset; + this->pix_pos.x = 0; + this->pix_pos.y = 128 - this->offset; } else if (start.x == _world.GetXSize() - 1) { - this->x_pos = 255; - this->y_pos = 128 + this->offset; + this->pix_pos.x = 255; + this->pix_pos.y = 128 + this->offset; } else if (start.y == 0) { - this->x_pos = 128 + this->offset; - this->y_pos = 0; + this->pix_pos.x = 128 + this->offset; + this->pix_pos.y = 0; } else { - this->x_pos = 128 - this->offset; - this->y_pos = 255; + this->pix_pos.x = 128 - this->offset; + this->pix_pos.y = 255; } - this->z_pos = GetZHeight(this->vox_pos, this->x_pos, this->y_pos); + this->pix_pos.z = GetZHeight(this->vox_pos, this->pix_pos.x, this->pix_pos.y); this->DecideMoveDirection(); } @@ -366,16 +366,16 @@ static const WalkInformation *_center_path_tile[4][4] = { */ TileEdge Person::GetCurrentEdge() const { - assert(this->x_pos >= 0 && this->x_pos <= 255); - assert(this->y_pos >= 0 && this->y_pos <= 255); + assert(this->pix_pos.x >= 0 && this->pix_pos.x <= 255); + assert(this->pix_pos.y >= 0 && this->pix_pos.y <= 255); - int x = (this->x_pos < 128) ? this->x_pos : 255 - this->x_pos; - int y = (this->y_pos < 128) ? this->y_pos : 255 - this->y_pos; + int x = (this->pix_pos.x < 128) ? this->pix_pos.x : 255 - this->pix_pos.x; + int y = (this->pix_pos.y < 128) ? this->pix_pos.y : 255 - this->pix_pos.y; if (x < y) { - return (this->x_pos < 128) ? EDGE_NE : EDGE_SW; + return (this->pix_pos.x < 128) ? EDGE_NE : EDGE_SW; } else { - return (this->y_pos < 128) ? EDGE_NW : EDGE_SE; + return (this->pix_pos.y < 128) ? EDGE_NW : EDGE_SE; } } @@ -405,7 +405,7 @@ RideVisitDesire Guest::ComputeExitDesire(TileEdge current_edge, XYZPoint16 cur_p } Point16 dxy = _tile_dxy[exit_edge]; - if (!ri->CanBeVisited(XYZPoint16(cur_pos.x + dxy.x, cur_pos.y + dxy.y, cur_pos.z), exit_edge)) return RVD_NO_VISIT; // Ride cannot be entered here. + if (!ri->CanBeVisited(cur_pos + XYZPoint16(dxy.x, dxy.y, 0), exit_edge)) return RVD_NO_VISIT; // Ride cannot be entered here. RideVisitDesire rvd = this->WantToVisit(ri); if ((rvd == RVD_MAY_VISIT || rvd == RVD_MUST_VISIT) && this->ride == nullptr) { @@ -452,9 +452,9 @@ void Guest::ExitRide(RideInstance *ri, TileEdge entry) assert(this->ride == ri); XYZPoint32 exit_pos = ri->GetExit(this->id, entry); - this->vox_pos.x = exit_pos.x >> 8; this->x_pos = exit_pos.x & 0xff; - this->vox_pos.y = exit_pos.y >> 8; this->y_pos = exit_pos.y & 0xff; - this->vox_pos.z = exit_pos.z >> 8; this->z_pos = exit_pos.z & 0xff; + this->vox_pos.x = exit_pos.x >> 8; this->pix_pos.x = exit_pos.x & 0xff; + this->vox_pos.y = exit_pos.y >> 8; this->pix_pos.y = exit_pos.y & 0xff; + this->vox_pos.z = exit_pos.z >> 8; this->pix_pos.z = exit_pos.z & 0xff; this->activity = GA_WANDER; this->AddSelf(_world.GetCreateVoxel(this->vox_pos, false)); this->DecideMoveDirection(); @@ -487,16 +487,16 @@ uint8 Guest::GetExitDirections(const Voxel *v, TileEdge start_edge, bool *seen_w /* Being at a path tile, make extra sure we don't leave the path. */ for (TileEdge exit_edge = EDGE_BEGIN; exit_edge != EDGE_COUNT; exit_edge++) { - int z; // Decide z position of the exit. + int extra_z; // Decide z position of the exit. if (GB(bot_exits, exit_edge, 1) != 0) { - z = this->vox_pos.z; + extra_z = 0; } else if (GB(top_exits, exit_edge, 1) != 0) { - z = this->vox_pos.z + 1; + extra_z = 1; } else { continue; } - RideVisitDesire rvd = ComputeExitDesire(start_edge, XYZPoint16(this->vox_pos.x, this->vox_pos.y, z), exit_edge, seen_wanted_ride); + RideVisitDesire rvd = ComputeExitDesire(start_edge, this->vox_pos + XYZPoint16(0, 0, extra_z), exit_edge, seen_wanted_ride); switch (rvd) { case RVD_NO_RIDE: break; // A path is one of the options. @@ -833,20 +833,20 @@ AnimateResult Person::OnAnimate(int delay) uint16 index = this->frame_index; const AnimationFrame *frame = &this->frames[index]; - this->x_pos += frame->dx; - this->y_pos += frame->dy; + this->pix_pos.x += frame->dx; + this->pix_pos.y += frame->dy; bool reached = false; // Set to true when we are beyond the limit! if ((this->walk->limit_type & (1 << WLM_END_LIMIT)) == WLM_X_COND) { - if (frame->dx > 0) reached |= this->x_pos > x_limit; - if (frame->dx < 0) reached |= this->x_pos < x_limit; + if (frame->dx > 0) reached |= this->pix_pos.x > x_limit; + if (frame->dx < 0) reached |= this->pix_pos.x < x_limit; - if (y_limit >= 0) this->y_pos += sign(y_limit - this->y_pos); // Also slowly move the other axis in the right direction. + if (y_limit >= 0) this->pix_pos.y += sign(y_limit - this->pix_pos.y); // Also slowly move the other axis in the right direction. } else { - if (frame->dy > 0) reached |= this->y_pos > y_limit; - if (frame->dy < 0) reached |= this->y_pos < y_limit; + if (frame->dy > 0) reached |= this->pix_pos.y > y_limit; + if (frame->dy < 0) reached |= this->pix_pos.y < y_limit; - if (x_limit >= 0) this->x_pos += sign(x_limit - this->x_pos); // Also slowly move the other axis in the right direction. + if (x_limit >= 0) this->pix_pos.x += sign(x_limit - this->pix_pos.x); // Also slowly move the other axis in the right direction. } if (!reached) { @@ -856,7 +856,7 @@ AnimateResult Person::OnAnimate(int delay) this->frame_index = index; this->frame_time = this->frames[index].duration; - this->z_pos = GetZHeight(this->vox_pos, this->x_pos, this->y_pos); + this->pix_pos.z = GetZHeight(this->vox_pos, this->pix_pos.x, this->pix_pos.y); return OAR_OK; } @@ -873,39 +873,39 @@ AnimateResult Person::OnAnimate(int delay) TileEdge exit_edge = INVALID_EDGE; this->RemoveSelf(_world.GetCreateVoxel(this->vox_pos, false)); - if (this->x_pos < 0) { + if (this->pix_pos.x < 0) { dx--; this->vox_pos.x--; - this->x_pos += 256; + this->pix_pos.x += 256; exit_edge = EDGE_NE; - } else if (this->x_pos > 255) { + } else if (this->pix_pos.x > 255) { dx++; this->vox_pos.x++; - this->x_pos -= 256; + this->pix_pos.x -= 256; exit_edge = EDGE_SW; } - if (this->y_pos < 0) { + if (this->pix_pos.y < 0) { dy--; this->vox_pos.y--; - this->y_pos += 256; + this->pix_pos.y += 256; exit_edge = EDGE_NW; - } else if (this->y_pos > 255) { + } else if (this->pix_pos.y > 255) { dy++; this->vox_pos.y++; - this->y_pos -= 256; + this->pix_pos.y -= 256; exit_edge = EDGE_SE; } - assert(this->x_pos >= 0 && this->x_pos < 256); - assert(this->y_pos >= 0 && this->y_pos < 256); + assert(this->pix_pos.x >= 0 && this->pix_pos.x < 256); + assert(this->pix_pos.y >= 0 && this->pix_pos.y < 256); AnimateResult ar = this->EdgeOfWorldOnAnimate(); if (ar != OAR_CONTINUE) return ar; /* Handle raising of z position. */ - if (this->z_pos > 128) { + if (this->pix_pos.z > 128) { dz++; this->vox_pos.z++; - this->z_pos = 0; + this->pix_pos.z = 0; } /* At bottom of the voxel. */ Voxel *v = _world.GetCreateVoxel(this->vox_pos, false); @@ -927,7 +927,7 @@ AnimateResult Person::OnAnimate(int delay) } else if (this->vox_pos.z > 0) { // Maybe a path below this voxel? dz--; this->vox_pos.z--; - this->z_pos = 255; + this->pix_pos.z = 255; Voxel *w = _world.GetCreateVoxel(this->vox_pos, false); if (w != nullptr && HasValidPath(w)) { this->AddSelf(w); @@ -937,9 +937,9 @@ AnimateResult Person::OnAnimate(int delay) } /* Restore the person at the previous tile (ie reverse movement). */ - if (dx != 0) { this->vox_pos.x -= dx; this->x_pos = (dx > 0) ? 255 : 0; } - if (dy != 0) { this->vox_pos.y -= dy; this->y_pos = (dy > 0) ? 255 : 0; } - if (dz != 0) { this->vox_pos.z -= dz; this->z_pos = (dz > 0) ? 255 : 0; } + if (dx != 0) { this->vox_pos.x -= dx; this->pix_pos.x = (dx > 0) ? 255 : 0; } + if (dy != 0) { this->vox_pos.y -= dy; this->pix_pos.y = (dy > 0) ? 255 : 0; } + if (dz != 0) { this->vox_pos.z -= dz; this->pix_pos.z = (dz > 0) ? 255 : 0; } this->AddSelf(_world.GetCreateVoxel(this->vox_pos, false)); this->DecideMoveDirection(); @@ -949,7 +949,7 @@ AnimateResult Person::OnAnimate(int delay) if (this->vox_pos.z > 0) { dz--; this->vox_pos.z--; - this->z_pos = 255; + this->pix_pos.z = 255; v = _world.GetCreateVoxel(this->vox_pos, false); } if (v != nullptr && HasValidPath(v)) { diff --git a/src/ride_gui.cpp b/src/ride_gui.cpp index 7140453..f95c57a 100644 --- a/src/ride_gui.cpp +++ b/src/ride_gui.cpp @@ -381,7 +381,7 @@ bool ShopPlacementManager::CanPlaceShop(const ShopType *selected_shop, const XYZ /* 2. Is the shop just above non-flat ground? */ if (pos.z > 0) { - vx = _world.GetVoxel(XYZPoint16(pos.x, pos.y, pos.z - 1)); + vx = _world.GetVoxel(pos + XYZPoint16(0, 0, -1)); if (vx != nullptr && vx->GetInstance() == SRI_FREE && vx->GetGroundType() != GTP_INVALID && vx->GetGroundSlope() != SL_FLAT) return true; } @@ -421,33 +421,33 @@ RidePlacementResult ShopPlacementManager::ComputeShopVoxel(XYZPoint32 world_pos) default: NOT_REACHED(); } - XYZPoint16 pos; + XYZPoint16 vox_pos; /* Move to the top voxel of the world. */ - pos.z = WORLD_Z_SIZE - 1; - int dz = pos.z * 256 - world_pos.z; + vox_pos.z = WORLD_Z_SIZE - 1; + int dz = vox_pos.z * 256 - world_pos.z; world_pos.x += dx * dz / 2; world_pos.y += dy * dz / 2; - while (pos.z >= 0) { - pos.x = world_pos.x / 256; - pos.y = world_pos.y / 256; - if (IsVoxelstackInsideWorld(pos.x, pos.y) && this->CanPlaceShop(st, pos)) { + while (vox_pos.z >= 0) { + vox_pos.x = world_pos.x / 256; + vox_pos.y = world_pos.y / 256; + if (IsVoxelstackInsideWorld(vox_pos.x, vox_pos.y) && this->CanPlaceShop(st, vox_pos)) { /* Position of the shop the same as previously? */ - if (si->vox_pos != pos || si->orientation != this->orientation) { - si->SetRide((this->orientation + vp->orientation) & 3, pos); + if (si->vox_pos != vox_pos || si->orientation != this->orientation) { + si->SetRide((this->orientation + vp->orientation) & 3, vox_pos); return RPR_CHANGED; } return RPR_SAMEPOS; } else { /* Since z gets smaller, we subtract dx and dy, thus the checks reverse. */ - if (pos.x < 0 && dx > 0) break; - if (pos.x >= _world.GetXSize() && dx < 0) break; - if (pos.y < 0 && dy > 0) break; - if (pos.y >= _world.GetYSize() && dy < 0) break; + if (vox_pos.x < 0 && dx > 0) break; + if (vox_pos.x >= _world.GetXSize() && dx < 0) break; + if (vox_pos.y < 0 && dy > 0) break; + if (vox_pos.y >= _world.GetYSize() && dy < 0) break; } world_pos.x -= 128 * dx; world_pos.y -= 128 * dy; - pos.z--; + vox_pos.z--; } return RPR_FAIL; } diff --git a/src/ride_type.cpp b/src/ride_type.cpp index 3f3c20a..c9b9140 100644 --- a/src/ride_type.cpp +++ b/src/ride_type.cpp @@ -626,7 +626,7 @@ RideInstance *RideExistsAtBottom(XYZPoint16 pos, TileEdge edge) if (vx == nullptr || vx->GetInstance() < SRI_FULL_RIDES) { /* No ride here, check the voxel below. */ if (pos.z == 0) return nullptr; - vx = _world.GetVoxel(XYZPoint16(pos.x, pos.y, pos.z - 1)); + vx = _world.GetVoxel(pos + XYZPoint16(0, 0, -1)); } if (vx == nullptr || vx->GetInstance() < SRI_FULL_RIDES) return nullptr; return _rides_manager.GetRideInstance(vx->GetInstance()); diff --git a/src/viewport.cpp b/src/viewport.cpp index 0c19258..46a18f3 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -1106,8 +1106,8 @@ void SpriteCollector::CollectVoxel(const Voxel *voxel, const XYZPoint16 &voxel_p DrawData dd; const ImageData *anim_spr = vo->GetSprite(this->sprites, this->orient, &dd.recolour); if (anim_spr != nullptr) { - int x_off = ComputeX(vo->x_pos, vo->y_pos); - int y_off = ComputeY(vo->x_pos, vo->y_pos, vo->z_pos); + int x_off = ComputeX(vo->pix_pos.x, vo->pix_pos.y); + int y_off = ComputeY(vo->pix_pos.x, vo->pix_pos.y, vo->pix_pos.z); dd.level = slice; dd.z_height = voxel_pos.z; dd.order = SO_PERSON; @@ -1270,8 +1270,8 @@ void PixelFinder::CollectVoxel(const Voxel *voxel, const XYZPoint16 &voxel_pos, assert(pers != nullptr && pers->walk != nullptr); AnimationType anim_type = pers->walk->anim_type; const ImageData *anim_spr = this->sprites->GetAnimationSprite(anim_type, pers->frame_index, pers->type, this->orient); - int x_off = ComputeX(pers->x_pos, pers->y_pos); - int y_off = ComputeY(pers->x_pos, pers->y_pos, pers->z_pos); + int x_off = ComputeX(pers->pix_pos.x, pers->pix_pos.y); + int y_off = ComputeY(pers->pix_pos.x, pers->pix_pos.y, pers->pix_pos.z); DrawData dd; dd.level = slice; dd.z_height = voxel_pos.z; -- 2.2.1