mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #15816 from ZehMatt/refactor/15630
Close #15630: Refactor TrackDesign
This commit is contained in:
commit
084b752fb8
|
@ -81,7 +81,7 @@ static void window_install_track_design(rct_window* w);
|
|||
*/
|
||||
rct_window* window_install_track_open(const utf8* path)
|
||||
{
|
||||
_trackDesign = track_design_open(path);
|
||||
_trackDesign = TrackDesignImport(path);
|
||||
if (_trackDesign == nullptr)
|
||||
{
|
||||
context_show_error(STR_UNABLE_TO_LOAD_FILE, STR_NONE, {});
|
||||
|
@ -422,7 +422,7 @@ static void window_install_track_text_input(rct_window* w, rct_widgetindex widge
|
|||
|
||||
static void window_install_track_update_preview()
|
||||
{
|
||||
track_design_draw_preview(_trackDesign.get(), _trackDesignPreviewPixels.data());
|
||||
TrackDesignDrawPreview(_trackDesign.get(), _trackDesignPreviewPixels.data());
|
||||
}
|
||||
|
||||
static void window_install_track_design(rct_window* w)
|
||||
|
|
|
@ -5325,7 +5325,8 @@ static void window_ride_measurements_design_save(rct_window* w)
|
|||
|
||||
if (gTrackDesignSaveMode)
|
||||
{
|
||||
auto errMessage = _trackDesign->CreateTrackDesignScenery();
|
||||
TrackDesignState tds{};
|
||||
auto errMessage = _trackDesign->CreateTrackDesignScenery(tds);
|
||||
if (errMessage != STR_NONE)
|
||||
{
|
||||
context_show_error(STR_CANT_SAVE_TRACK_DESIGN, errMessage, {});
|
||||
|
|
|
@ -133,7 +133,7 @@ static void window_track_place_clear_mini_preview()
|
|||
*/
|
||||
rct_window* window_track_place_open(const track_design_file_ref* tdFileRef)
|
||||
{
|
||||
_trackDesign = track_design_open(tdFileRef->path);
|
||||
_trackDesign = TrackDesignImport(tdFileRef->path);
|
||||
if (_trackDesign == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
|
@ -197,7 +197,7 @@ static void window_track_place_mouseup(rct_window* w, rct_widgetindex widgetInde
|
|||
window_track_place_draw_mini_preview(_trackDesign.get());
|
||||
break;
|
||||
case WIDX_MIRROR:
|
||||
track_design_mirror(_trackDesign.get());
|
||||
TrackDesignMirror(_trackDesign.get());
|
||||
_currentTrackPieceDirection = (0 - _currentTrackPieceDirection) & 3;
|
||||
w->Invalidate();
|
||||
_windowTrackPlaceLast.SetNull();
|
||||
|
@ -268,8 +268,7 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI
|
|||
// Check if tool map position has changed since last update
|
||||
if (mapCoords == _windowTrackPlaceLast)
|
||||
{
|
||||
place_virtual_track(
|
||||
_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(PreviewRideId), { mapCoords, 0 });
|
||||
TrackDesignPreviewDrawOutlines(_trackDesign.get(), GetOrAllocateRide(PreviewRideId), { mapCoords, 0 });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -309,7 +308,7 @@ static void window_track_place_toolupdate(rct_window* w, rct_widgetindex widgetI
|
|||
widget_invalidate(w, WIDX_PRICE);
|
||||
}
|
||||
|
||||
place_virtual_track(_trackDesign.get(), PTD_OPERATION_DRAW_OUTLINES, true, GetOrAllocateRide(PreviewRideId), trackLoc);
|
||||
TrackDesignPreviewDrawOutlines(_trackDesign.get(), GetOrAllocateRide(PreviewRideId), trackLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -413,7 +412,7 @@ static void window_track_place_clear_provisional()
|
|||
auto ride = get_ride(_window_track_place_ride_index);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
place_virtual_track(_trackDesign.get(), PTD_OPERATION_REMOVE_GHOST, true, ride, _windowTrackPlaceLastValid);
|
||||
TrackDesignPreviewRemoveGhosts(_trackDesign.get(), ride, _windowTrackPlaceLastValid);
|
||||
_window_track_place_last_was_valid = false;
|
||||
}
|
||||
}
|
||||
|
@ -426,7 +425,7 @@ void TrackPlaceClearProvisionalTemporarily()
|
|||
auto ride = get_ride(_window_track_place_ride_index);
|
||||
if (ride != nullptr)
|
||||
{
|
||||
place_virtual_track(_trackDesign.get(), PTD_OPERATION_REMOVE_GHOST, true, ride, _windowTrackPlaceLastValid);
|
||||
TrackDesignPreviewRemoveGhosts(_trackDesign.get(), ride, _windowTrackPlaceLastValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -471,9 +470,7 @@ static int32_t window_track_place_get_base_z(const CoordsXY& loc)
|
|||
if (surfaceElement->GetWaterHeight() > 0)
|
||||
z = std::max(z, surfaceElement->GetWaterHeight());
|
||||
|
||||
return z
|
||||
+ place_virtual_track(
|
||||
_trackDesign.get(), PTD_OPERATION_GET_PLACE_Z, true, GetOrAllocateRide(PreviewRideId), { loc, z });
|
||||
return z + TrackDesignGetZPlacement(_trackDesign.get(), GetOrAllocateRide(PreviewRideId), { loc, z });
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -186,10 +186,10 @@ private:
|
|||
|
||||
bool LoadDesignPreview(utf8* path)
|
||||
{
|
||||
_loadedTrackDesign = track_design_open(path);
|
||||
_loadedTrackDesign = TrackDesignImport(path);
|
||||
if (_loadedTrackDesign != nullptr)
|
||||
{
|
||||
track_design_draw_preview(_loadedTrackDesign.get(), _trackDesignPreviewPixels.data());
|
||||
TrackDesignDrawPreview(_loadedTrackDesign.get(), _trackDesignPreviewPixels.data());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -21,12 +21,6 @@
|
|||
#include "RideSetSettingAction.h"
|
||||
#include "RideSetVehicleAction.h"
|
||||
|
||||
static int32_t place_virtual_track(
|
||||
const TrackDesign& td6, uint8_t ptdOperation, bool placeScenery, Ride* ride, const CoordsXYZ& loc)
|
||||
{
|
||||
return place_virtual_track(const_cast<TrackDesign*>(&td6), ptdOperation, placeScenery, ride, loc);
|
||||
}
|
||||
|
||||
TrackDesignAction::TrackDesignAction(const CoordsXYZD& location, const TrackDesign& td)
|
||||
: _loc(location)
|
||||
, _td(td)
|
||||
|
@ -95,26 +89,36 @@ GameActions::Result::Ptr TrackDesignAction::Query() const
|
|||
return MakeResult(GameActions::Status::Unknown, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE);
|
||||
}
|
||||
|
||||
money32 cost = 0;
|
||||
|
||||
bool placeScenery = true;
|
||||
cost = place_virtual_track(_td, PTD_OPERATION_PLACE_QUERY, placeScenery, ride, _loc);
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
flags |= GAME_COMMAND_FLAG_GHOST;
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_REPLAY)
|
||||
flags |= GAME_COMMAND_FLAG_REPLAY;
|
||||
|
||||
auto queryRes = TrackDesignPlace(const_cast<TrackDesign*>(&_td), flags, placeScenery, ride, _loc);
|
||||
if (_trackDesignPlaceStateSceneryUnavailable)
|
||||
{
|
||||
placeScenery = false;
|
||||
cost = place_virtual_track(_td, PTD_OPERATION_PLACE_QUERY, placeScenery, ride, _loc);
|
||||
queryRes = TrackDesignPlace(const_cast<TrackDesign*>(&_td), flags, placeScenery, ride, _loc);
|
||||
}
|
||||
|
||||
rct_string_id error_reason = gGameCommandErrorText;
|
||||
auto gameAction = RideDemolishAction(ride->id, RIDE_MODIFY_DEMOLISH);
|
||||
gameAction.SetFlags(GetFlags());
|
||||
|
||||
GameActions::ExecuteNested(&gameAction);
|
||||
if (cost == MONEY32_UNDEFINED)
|
||||
|
||||
if (queryRes->Error != GameActions::Status::Ok)
|
||||
{
|
||||
return MakeResult(GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, error_reason);
|
||||
res->Error = queryRes->Error;
|
||||
res->ErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
|
||||
res->ErrorMessage = queryRes->ErrorMessage;
|
||||
res->ErrorMessageArgs = queryRes->ErrorMessageArgs;
|
||||
return res;
|
||||
}
|
||||
res->Cost = cost;
|
||||
|
||||
res->Cost = queryRes->Cost;
|
||||
res->SetData(ride_id_t{ RIDE_ID_NULL });
|
||||
|
||||
return res;
|
||||
|
@ -157,42 +161,52 @@ GameActions::Result::Ptr TrackDesignAction::Execute() const
|
|||
return MakeResult(GameActions::Status::Unknown, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, STR_NONE);
|
||||
}
|
||||
|
||||
money32 cost = 0;
|
||||
|
||||
// Query first, this is required again to determine if scenery is available.
|
||||
bool placeScenery = true;
|
||||
cost = place_virtual_track(_td, PTD_OPERATION_PLACE_QUERY, placeScenery, ride, _loc);
|
||||
|
||||
uint32_t flags = 0;
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
flags |= GAME_COMMAND_FLAG_GHOST;
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_REPLAY)
|
||||
flags |= GAME_COMMAND_FLAG_REPLAY;
|
||||
|
||||
auto queryRes = TrackDesignPlace(const_cast<TrackDesign*>(&_td), flags, placeScenery, ride, _loc);
|
||||
if (_trackDesignPlaceStateSceneryUnavailable)
|
||||
{
|
||||
placeScenery = false;
|
||||
cost = place_virtual_track(_td, PTD_OPERATION_PLACE_QUERY, placeScenery, ride, _loc);
|
||||
queryRes = TrackDesignPlace(const_cast<TrackDesign*>(&_td), flags, placeScenery, ride, _loc);
|
||||
}
|
||||
|
||||
if (cost != MONEY32_UNDEFINED)
|
||||
if (queryRes->Error != GameActions::Status::Ok)
|
||||
{
|
||||
uint8_t operation;
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_GHOST)
|
||||
{
|
||||
operation = PTD_OPERATION_PLACE_GHOST;
|
||||
}
|
||||
else
|
||||
{
|
||||
operation = PTD_OPERATION_PLACE;
|
||||
}
|
||||
if (GetFlags() & GAME_COMMAND_FLAG_REPLAY)
|
||||
{
|
||||
operation |= PTD_OPERATION_FLAG_IS_REPLAY;
|
||||
}
|
||||
cost = place_virtual_track(_td, operation, placeScenery, ride, _loc);
|
||||
}
|
||||
|
||||
if (cost == MONEY32_UNDEFINED)
|
||||
{
|
||||
rct_string_id error_reason = gGameCommandErrorText;
|
||||
auto gameAction = RideDemolishAction(ride->id, RIDE_MODIFY_DEMOLISH);
|
||||
gameAction.SetFlags(GetFlags());
|
||||
|
||||
GameActions::ExecuteNested(&gameAction);
|
||||
return MakeResult(GameActions::Status::Disallowed, STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE, error_reason);
|
||||
|
||||
res->Error = queryRes->Error;
|
||||
res->ErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
|
||||
res->ErrorMessage = queryRes->ErrorMessage;
|
||||
res->ErrorMessageArgs = queryRes->ErrorMessageArgs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Execute.
|
||||
flags |= GAME_COMMAND_FLAG_APPLY;
|
||||
|
||||
auto execRes = TrackDesignPlace(const_cast<TrackDesign*>(&_td), flags, placeScenery, ride, _loc);
|
||||
if (execRes->Error != GameActions::Status::Ok)
|
||||
{
|
||||
auto gameAction = RideDemolishAction(ride->id, RIDE_MODIFY_DEMOLISH);
|
||||
gameAction.SetFlags(GetFlags());
|
||||
GameActions::ExecuteNested(&gameAction);
|
||||
|
||||
res->Error = execRes->Error;
|
||||
res->ErrorTitle = STR_RIDE_CONSTRUCTION_CANT_CONSTRUCT_THIS_HERE;
|
||||
res->ErrorMessage = execRes->ErrorMessage;
|
||||
res->ErrorMessageArgs = execRes->ErrorMessageArgs;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (entryIndex != OBJECT_ENTRY_INDEX_NULL)
|
||||
|
@ -250,7 +264,7 @@ GameActions::Result::Ptr TrackDesignAction::Execute() const
|
|||
gameAction.SetFlags(GetFlags());
|
||||
r = GameActions::ExecuteNested(&gameAction);
|
||||
}
|
||||
res->Cost = cost;
|
||||
res->Cost = execRes->Cost;
|
||||
res->SetData(ride_id_t{ ride->id });
|
||||
|
||||
return res;
|
||||
|
|
|
@ -963,8 +963,9 @@ std::unique_ptr<TrackDesign> Ride::SaveToTrackDesign() const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
auto tds = TrackDesignState{};
|
||||
auto td = std::make_unique<TrackDesign>();
|
||||
auto errMessage = td->CreateTrackDesign(*this);
|
||||
auto errMessage = td->CreateTrackDesign(tds, *this);
|
||||
if (errMessage != STR_NONE)
|
||||
{
|
||||
context_show_error(STR_CANT_SAVE_TRACK_DESIGN, errMessage, {});
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../actions/GameActionResult.h"
|
||||
#include "../common.h"
|
||||
#include "../object/Object.h"
|
||||
#include "../rct12/RCT12.h"
|
||||
|
@ -19,6 +20,20 @@ struct Ride;
|
|||
|
||||
#define TRACK_PREVIEW_IMAGE_SIZE (370 * 217)
|
||||
|
||||
struct TrackDesignState
|
||||
{
|
||||
CoordsXYZ PreviewMin;
|
||||
CoordsXYZ PreviewMax;
|
||||
CoordsXYZ Origin;
|
||||
uint8_t PlaceOperation{};
|
||||
int16_t PlaceZ{};
|
||||
int16_t PlaceSceneryZ{};
|
||||
bool EntranceExitPlaced{};
|
||||
bool HasScenery{};
|
||||
bool PlaceScenery{};
|
||||
bool IsReplay{};
|
||||
};
|
||||
|
||||
/* Track Entrance entry */
|
||||
struct TrackDesignEntranceElement
|
||||
{
|
||||
|
@ -134,14 +149,14 @@ struct TrackDesign
|
|||
std::string name;
|
||||
|
||||
public:
|
||||
rct_string_id CreateTrackDesign(const Ride& ride);
|
||||
rct_string_id CreateTrackDesignScenery();
|
||||
rct_string_id CreateTrackDesign(TrackDesignState& tds, const Ride& ride);
|
||||
rct_string_id CreateTrackDesignScenery(TrackDesignState& tds);
|
||||
void Serialise(DataSerialiser& stream);
|
||||
|
||||
private:
|
||||
uint8_t _saveDirection;
|
||||
rct_string_id CreateTrackDesignTrack(const Ride& ride);
|
||||
rct_string_id CreateTrackDesignMaze(const Ride& ride);
|
||||
rct_string_id CreateTrackDesignTrack(TrackDesignState& tds, const Ride& ride);
|
||||
rct_string_id CreateTrackDesignMaze(TrackDesignState& tds, const Ride& ride);
|
||||
CoordsXYE MazeGetFirstElement(const Ride& ride);
|
||||
};
|
||||
|
||||
|
@ -206,16 +221,20 @@ extern bool _trackDesignPlaceStateSceneryUnavailable;
|
|||
extern bool gTrackDesignSaveMode;
|
||||
extern ride_id_t gTrackDesignSaveRideIndex;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<TrackDesign> track_design_open(const utf8* path);
|
||||
[[nodiscard]] std::unique_ptr<TrackDesign> TrackDesignImport(const utf8* path);
|
||||
|
||||
void track_design_mirror(TrackDesign* td6);
|
||||
void TrackDesignMirror(TrackDesign* td6);
|
||||
|
||||
money32 place_virtual_track(TrackDesign* td6, uint8_t ptdOperation, bool placeScenery, Ride* ride, const CoordsXYZ& coords);
|
||||
GameActions::Result::Ptr TrackDesignPlace(
|
||||
TrackDesign* td6, uint32_t flags, bool placeScenery, Ride* ride, const CoordsXYZ& coords);
|
||||
void TrackDesignPreviewRemoveGhosts(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords);
|
||||
void TrackDesignPreviewDrawOutlines(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords);
|
||||
int32_t TrackDesignGetZPlacement(TrackDesign* td6, Ride* ride, const CoordsXYZ& coords);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Track design preview
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
void track_design_draw_preview(TrackDesign* td6, uint8_t* pixels);
|
||||
void TrackDesignDrawPreview(TrackDesign* td6, uint8_t* pixels);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Track design saving
|
||||
|
|
|
@ -75,7 +75,7 @@ public:
|
|||
public:
|
||||
std::tuple<bool, TrackRepositoryItem> Create(int32_t, const std::string& path) const override
|
||||
{
|
||||
auto td6 = track_design_open(path.c_str());
|
||||
auto td6 = TrackDesignImport(path.c_str());
|
||||
if (td6 != nullptr)
|
||||
{
|
||||
TrackRepositoryItem item;
|
||||
|
|
Loading…
Reference in New Issue