mirror of https://github.com/OpenRCT2/OpenRCT2.git
Moved ride create command to new game action system.
This commit is contained in:
parent
fbd793083c
commit
3657122b3b
|
@ -190,10 +190,10 @@ namespace GameActions
|
|||
}
|
||||
|
||||
// Call callback for asynchronous events
|
||||
const std::function<void()>& cb = action->GetCallback();
|
||||
const GameActionCallback_t& cb = action->GetCallback();
|
||||
if (cb)
|
||||
{
|
||||
cb();
|
||||
cb(action, result);
|
||||
}
|
||||
|
||||
if (result.Error != GA_ERROR::OK && !(flags & GAME_COMMAND_FLAG_GHOST))
|
||||
|
|
|
@ -23,11 +23,10 @@ extern "C" {
|
|||
#include "IGameAction.h"
|
||||
|
||||
typedef IGameAction *(*GameActionFactory)();
|
||||
using GameActionCallback = std::function<void(GameActionResult)>;
|
||||
|
||||
template<uint32 _TYPE, uint16 _ACTFLAGS>
|
||||
struct GameAction : public IGameAction
|
||||
{
|
||||
{
|
||||
public:
|
||||
constexpr static uint32 Type = _TYPE;
|
||||
constexpr static uint16 ActionFlags = _ACTFLAGS;
|
||||
|
@ -36,7 +35,7 @@ private:
|
|||
uint32 _playerId; // Callee
|
||||
uint32 _flags; // GAME_COMMAND_FLAGS
|
||||
uint32 _networkId;
|
||||
std::function<void()> _callback;
|
||||
GameActionCallback_t _callback;
|
||||
|
||||
public:
|
||||
GameAction() : _playerId(0), _flags(0), _networkId(0)
|
||||
|
@ -79,12 +78,12 @@ public:
|
|||
return Type;
|
||||
}
|
||||
|
||||
virtual void SetCallback(const std::function<void()>& cb)
|
||||
virtual void SetCallback(const GameActionCallback_t& cb)
|
||||
{
|
||||
_callback = cb;
|
||||
}
|
||||
|
||||
virtual const std::function<void()>& GetCallback() const
|
||||
virtual const GameActionCallback_t& GetCallback() const
|
||||
{
|
||||
return _callback;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "PlaceParkEntranceAction.hpp"
|
||||
#include "SetParkEntranceFeeAction.hpp"
|
||||
#include "RideCreateAction.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
@ -70,10 +71,6 @@ extern "C"
|
|||
{
|
||||
auto gameAction = SetParkEntranceFeeAction();
|
||||
gameAction.Fee = (money16)value;
|
||||
gameAction.SetCallback([]()
|
||||
{
|
||||
log_info("GameAction Callback executed");
|
||||
});
|
||||
GameActions::Execute(&gameAction);
|
||||
}
|
||||
|
||||
|
@ -84,4 +81,39 @@ extern "C"
|
|||
GameActions::Execute(&gameAction);
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
#pragma region RideCreateAction
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4800
|
||||
*/
|
||||
void ride_construct_new(ride_list_item listItem)
|
||||
{
|
||||
auto gameAction = RideCreateAction();
|
||||
gameAction.rideType = listItem.type;
|
||||
gameAction.rideSubType = listItem.entry_index;
|
||||
gameAction.SetCallback([](const IGameAction *ga, GameActionResult& res)
|
||||
{
|
||||
if (res.Error != GA_ERROR::OK)
|
||||
return;
|
||||
|
||||
ride_construct(static_cast<RideCreateGameActionResult&>(res).RideIndex());
|
||||
});
|
||||
|
||||
GameActions::Execute(&gameAction);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B3F0F
|
||||
*/
|
||||
void game_command_create_ride(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp)
|
||||
{
|
||||
ride_list_item tmp;
|
||||
tmp.ride_type_and_entry = (uint16)*edx;
|
||||
ride_construct_new(tmp);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "GameAction.h"
|
||||
#include "PlaceParkEntranceAction.hpp"
|
||||
#include "SetParkEntranceFeeAction.hpp"
|
||||
#include "RideCreateAction.hpp"
|
||||
|
||||
namespace GameActions {
|
||||
|
||||
|
@ -8,6 +9,7 @@ void Register()
|
|||
{
|
||||
Register<SetParkEntranceFeeAction>();
|
||||
Register<PlaceParkEntranceAction>();
|
||||
Register<RideCreateAction>();
|
||||
}
|
||||
|
||||
}
|
|
@ -69,12 +69,14 @@ struct GameActionResult
|
|||
rct_xyz32 Position = { 0 };
|
||||
money32 Cost = 0;
|
||||
uint16 ExpenditureType = 0;
|
||||
void * Tag = nullptr;
|
||||
uint64 Results[4];
|
||||
|
||||
GameActionResult();
|
||||
GameActionResult(GA_ERROR error, rct_string_id message);
|
||||
};
|
||||
|
||||
typedef std::function<void(const struct IGameAction*, GameActionResult&)> GameActionCallback_t;
|
||||
|
||||
/**
|
||||
* Represents an action that changes the state of the game. Can be serialised and
|
||||
* deserialised into a stream.
|
||||
|
@ -101,8 +103,8 @@ public:
|
|||
virtual void SetPlayer(uint32 playerId) abstract;
|
||||
virtual uint32 GetPlayer() const abstract;
|
||||
|
||||
virtual void SetCallback(const std::function<void()>& cb) abstract;
|
||||
virtual const std::function<void()>& GetCallback() const abstract;
|
||||
virtual void SetCallback(const GameActionCallback_t& cb) abstract;
|
||||
virtual const GameActionCallback_t& GetCallback() const abstract;
|
||||
|
||||
virtual void SetNetworkId(uint32_t id) abstract;
|
||||
virtual uint32 GetNetworkId() const abstract;
|
||||
|
|
|
@ -0,0 +1,288 @@
|
|||
#pragma region Copyright (c) 2014-2016 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../core/MemoryStream.h"
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../localisation/date.h"
|
||||
#include "../cheats.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../world/park.h"
|
||||
#include "../rct1.h"
|
||||
#include "../ride/ride_data.h"
|
||||
#include "../ride/ride.h"
|
||||
}
|
||||
|
||||
struct RideCreateGameActionResult : public GameActionResult {
|
||||
RideCreateGameActionResult() {}
|
||||
RideCreateGameActionResult(GA_ERROR error, rct_string_id message) : GameActionResult(error, message) {}
|
||||
|
||||
sint32& RideIndex()
|
||||
{
|
||||
return reinterpret_cast<sint32&>(Results[0]);
|
||||
}
|
||||
|
||||
uint32& RideColor()
|
||||
{
|
||||
return reinterpret_cast<uint32&>(Results[1]);
|
||||
}
|
||||
};
|
||||
|
||||
struct RideCreateAction : public GameAction<GAME_COMMAND_CREATE_RIDE, GA_FLAGS::ALLOW_WHILE_PAUSED>
|
||||
{
|
||||
public:
|
||||
sint32 rideType;
|
||||
sint32 rideSubType;
|
||||
|
||||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
stream << rideType << rideSubType;
|
||||
}
|
||||
|
||||
GameActionResult Query() const override
|
||||
{
|
||||
if (rideType >= RIDE_TYPE_COUNT)
|
||||
{
|
||||
return RideCreateGameActionResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE);
|
||||
}
|
||||
|
||||
return GameActionResult();
|
||||
}
|
||||
|
||||
GameActionResult Execute() const override
|
||||
{
|
||||
RideCreateGameActionResult res;
|
||||
|
||||
rct_ride *ride;
|
||||
rct_ride_entry *rideEntry;
|
||||
sint32 rideIndex, rideEntryIndex;
|
||||
sint32 subType = rideSubType;
|
||||
|
||||
if (subType == RIDE_ENTRY_INDEX_NULL)
|
||||
{
|
||||
uint8 *availableRideEntries = get_ride_entry_indices_for_ride_type(rideType);
|
||||
for (uint8 *rei = availableRideEntries; *rei != RIDE_ENTRY_INDEX_NULL; rei++) {
|
||||
rideEntry = get_ride_entry(*rei);
|
||||
|
||||
// Can happen in select-by-track-type mode
|
||||
if (!ride_entry_is_invented(*rei))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry)) {
|
||||
subType = *rei;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (subType == RIDE_ENTRY_INDEX_NULL)
|
||||
{
|
||||
subType = availableRideEntries[0];
|
||||
if (subType == RIDE_ENTRY_INDEX_NULL) {
|
||||
return RideCreateGameActionResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rideEntryIndex = subType;
|
||||
rideIndex = ride_get_empty_slot();
|
||||
|
||||
if (subType >= 128)
|
||||
{
|
||||
return RideCreateGameActionResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_RIDE_TYPE);
|
||||
}
|
||||
|
||||
if (rideIndex == -1)
|
||||
{
|
||||
return RideCreateGameActionResult(GA_ERROR::DISALLOWED, STR_TOO_MANY_RIDES);
|
||||
}
|
||||
|
||||
res.RideIndex() = rideIndex;
|
||||
res.RideColor() = ride_get_random_colour_preset_index(rideType) | (ride_get_unused_preset_vehicle_colour(rideType, subType) << 8);
|
||||
|
||||
ride = get_ride(rideIndex);
|
||||
rideEntry = get_ride_entry(rideEntryIndex);
|
||||
if (rideEntry == (rct_ride_entry *)-1)
|
||||
{
|
||||
log_warning("Invalid request for ride %u", rideIndex);
|
||||
return RideCreateGameActionResult(GA_ERROR::UNKNOWN, STR_UNKNOWN_OBJECT_TYPE);
|
||||
}
|
||||
|
||||
ride->type = rideType;
|
||||
ride->subtype = rideEntryIndex;
|
||||
ride_set_colour_preset(ride, res.RideColor() & 0xFF);
|
||||
ride->overall_view = 0xFFFF;
|
||||
|
||||
// Ride name
|
||||
if (rideEntryIndex == RIDE_ENTRY_INDEX_NULL)
|
||||
{
|
||||
ride_set_name_to_track_default(ride, rideEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_set_name_to_default(ride, rideEntry);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < RCT12_MAX_STATIONS_PER_RIDE; i++) {
|
||||
ride->station_starts[i] = 0xFFFF;
|
||||
ride->entrances[i] = 0xFFFF;
|
||||
ride->exits[i] = 0xFFFF;
|
||||
ride->train_at_station[i] = 255;
|
||||
ride->queue_time[i] = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_VEHICLES_PER_RIDE; i++) {
|
||||
ride->vehicles[i] = SPRITE_INDEX_NULL;
|
||||
}
|
||||
|
||||
ride->status = RIDE_STATUS_CLOSED;
|
||||
ride->lifecycle_flags = 0;
|
||||
ride->vehicle_change_timeout = 0;
|
||||
ride->num_stations = 0;
|
||||
ride->num_vehicles = 1;
|
||||
ride->proposed_num_vehicles = 32;
|
||||
ride->max_trains = 32;
|
||||
ride->num_cars_per_train = 1;
|
||||
ride->proposed_num_cars_per_train = 12;
|
||||
ride->min_waiting_time = 10;
|
||||
ride->max_waiting_time = 60;
|
||||
ride->depart_flags = RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH | 3;
|
||||
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_MUSIC_ON_DEFAULT) {
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC;
|
||||
}
|
||||
ride->music = RideData4[ride->type].default_music;
|
||||
|
||||
const rct_ride_properties rideProperties = RideProperties[ride->type];
|
||||
ride->operation_option = (rideProperties.min_value * 3 + rideProperties.max_value) / 4;
|
||||
|
||||
ride->lift_hill_speed = RideLiftData[ride->type].minimum_speed;
|
||||
|
||||
ride->measurement_index = 255;
|
||||
ride->excitement = (ride_rating)-1;
|
||||
ride->cur_num_customers = 0;
|
||||
ride->num_customers_timeout = 0;
|
||||
ride->chairlift_bullwheel_rotation = 0;
|
||||
|
||||
ride->price = 0;
|
||||
ride->price_secondary = 0;
|
||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) {
|
||||
ride->price = RideData4[ride->type].price;
|
||||
ride->price_secondary = RideData4[ride->type].price_secondary;
|
||||
|
||||
if (rideEntry->shop_item == SHOP_ITEM_NONE) {
|
||||
if (!(gParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) && !gCheatsUnlockAllPrices) {
|
||||
ride->price = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ride->price = DefaultShopItemPrice[rideEntry->shop_item];
|
||||
}
|
||||
if (rideEntry->shop_item_secondary != SHOP_ITEM_NONE) {
|
||||
ride->price_secondary = DefaultShopItemPrice[rideEntry->shop_item_secondary];
|
||||
}
|
||||
|
||||
if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST) {
|
||||
ride->price = 0;
|
||||
}
|
||||
|
||||
if (ride->type == RIDE_TYPE_TOILETS) {
|
||||
if (shop_item_has_common_price(SHOP_ITEM_ADMISSION)) {
|
||||
money32 price = ride_get_common_price(ride);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rideEntry->shop_item != SHOP_ITEM_NONE) {
|
||||
if (shop_item_has_common_price(rideEntry->shop_item)) {
|
||||
money32 price = shop_item_get_common_price(ride, rideEntry->shop_item);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rideEntry->shop_item_secondary != SHOP_ITEM_NONE) {
|
||||
if (shop_item_has_common_price(rideEntry->shop_item_secondary)) {
|
||||
money32 price = shop_item_get_common_price(ride, rideEntry->shop_item_secondary);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price_secondary = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the on-ride photo price, whether the ride has one or not (except shops).
|
||||
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP) && shop_item_has_common_price(SHOP_ITEM_PHOTO)) {
|
||||
money32 price = shop_item_get_common_price(ride, SHOP_ITEM_PHOTO);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price_secondary = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(ride->num_customers, 0, sizeof(ride->num_customers));
|
||||
ride->value = 0xFFFF;
|
||||
ride->satisfaction = 255;
|
||||
ride->satisfaction_time_out = 0;
|
||||
ride->satisfaction_next = 0;
|
||||
ride->popularity = 255;
|
||||
ride->popularity_time_out = 0;
|
||||
ride->popularity_next = 0;
|
||||
ride->window_invalidate_flags = 0;
|
||||
ride->total_customers = 0;
|
||||
ride->total_profit = 0;
|
||||
ride->num_riders = 0;
|
||||
ride->slide_in_use = 0;
|
||||
ride->maze_tiles = 0;
|
||||
ride->build_date = gDateMonthsElapsed;
|
||||
ride->music_tune_id = 255;
|
||||
|
||||
ride->breakdown_reason = 255;
|
||||
ride->upkeep_cost = (money16)-1;
|
||||
ride->reliability = 0x64FF;
|
||||
ride->unreliability_factor = 1;
|
||||
ride->inspection_interval = RIDE_INSPECTION_EVERY_30_MINUTES;
|
||||
ride->last_inspection = 0;
|
||||
ride->downtime = 0;
|
||||
memset(ride->downtime_history, 0, sizeof(ride->downtime_history));
|
||||
ride->no_primary_items_sold = 0;
|
||||
ride->no_secondary_items_sold = 0;
|
||||
ride->last_crash_type = RIDE_CRASH_TYPE_NONE;
|
||||
ride->income_per_hour = MONEY32_UNDEFINED;
|
||||
ride->profit = MONEY32_UNDEFINED;
|
||||
ride->connected_message_throttle = 0;
|
||||
ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN;
|
||||
ride->num_block_brakes = 0;
|
||||
ride->guests_favourite = 0;
|
||||
|
||||
ride->num_circuits = 1;
|
||||
ride->mode = ride_get_default_mode(ride);
|
||||
ride->min_max_cars_per_train = (rideEntry->min_cars_in_train << 4) | rideEntry->max_cars_in_train;
|
||||
ride_set_vehicle_colours_to_random_preset(ride, 0xFF & (res.RideColor() >> 8));
|
||||
window_invalidate_by_class(WC_RIDE_LIST);
|
||||
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
gCommandPosition.x = (uint16)0x8000;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
|
@ -82,7 +82,7 @@ uint32 gCurrentTicks;
|
|||
GAME_COMMAND_CALLBACK_POINTER* game_command_callback = 0;
|
||||
GAME_COMMAND_CALLBACK_POINTER* game_command_callback_table[] = {
|
||||
0,
|
||||
game_command_callback_ride_construct_new,
|
||||
0,
|
||||
game_command_callback_ride_construct_placed_front,
|
||||
game_command_callback_ride_construct_placed_back,
|
||||
game_command_callback_ride_remove_track_piece,
|
||||
|
|
|
@ -76,7 +76,7 @@ typedef struct IGameAction IGameAction;
|
|||
#include "NetworkServerAdvertiser.h"
|
||||
#include "NetworkUser.h"
|
||||
#include "TcpSocket.h"
|
||||
|
||||
#include "../actions/IGameAction.h"
|
||||
|
||||
enum {
|
||||
NETWORK_TICK_FLAG_CHECKSUMS = 1 << 0,
|
||||
|
@ -169,7 +169,7 @@ public:
|
|||
std::vector<std::unique_ptr<NetworkGroup>> group_list;
|
||||
NetworkKey _key;
|
||||
std::vector<uint8> _challenge;
|
||||
std::map<uint32, std::function<void()>> _gameActionCallbacks;
|
||||
std::map<uint32, GameActionCallback_t> _gameActionCallbacks;
|
||||
NetworkUserManager _userManager;
|
||||
|
||||
std::string ServerName;
|
||||
|
|
|
@ -205,6 +205,7 @@ static void ride_call_closest_mechanic(sint32 rideIndex);
|
|||
static void ride_call_mechanic(sint32 rideIndex, rct_peep *mechanic, sint32 forInspection);
|
||||
static void ride_chairlift_update(Ride *ride);
|
||||
static void ride_entrance_exit_connected(Ride* ride, sint32 ride_idx);
|
||||
static void ride_set_name_to_vehicle_default(rct_ride * ride, rct_ride_entry * rideEntry);
|
||||
static sint32 ride_get_new_breakdown_problem(Ride *ride);
|
||||
static void ride_inspection_update(Ride *ride);
|
||||
static void ride_mechanic_status_update(sint32 rideIndex, sint32 mechanicStatus);
|
||||
|
@ -213,10 +214,7 @@ static void ride_shop_connected(Ride* ride, sint32 ride_idx);
|
|||
static void ride_spiral_slide_update(Ride *ride);
|
||||
static void ride_update(sint32 rideIndex);
|
||||
static void ride_update_vehicle_colours(sint32 rideIndex);
|
||||
static void ride_set_vehicle_colours_to_random_preset(Ride *ride, uint8 preset_index);
|
||||
void loc_6DDF9C(Ride *ride, rct_map_element *mapElement);
|
||||
static void ride_set_name_to_track_default(Ride * ride, rct_ride_entry * rideEntry);
|
||||
static void ride_set_name_to_vehicle_default(Ride * ride, rct_ride_entry * rideEntry);
|
||||
|
||||
|
||||
Ride *get_ride(sint32 index)
|
||||
|
@ -1016,33 +1014,6 @@ static rct_window *ride_create_or_find_construction_window(sint32 rideIndex)
|
|||
return w;
|
||||
}
|
||||
|
||||
static sint32 ride_create_ride(ride_list_item listItem)
|
||||
{
|
||||
sint32 eax, ebx, ecx, edx, esi, edi, ebp;
|
||||
edx = listItem.ride_type_and_entry;
|
||||
eax = 0;
|
||||
ecx = 0;
|
||||
ebx = GAME_COMMAND_FLAG_APPLY;
|
||||
edi = 0;
|
||||
esi = GAME_COMMAND_CREATE_RIDE;
|
||||
ebp = 0;
|
||||
|
||||
gGameCommandErrorTitle = STR_CANT_CREATE_NEW_RIDE_ATTRACTION;
|
||||
|
||||
game_do_command_p(esi, &eax, &ebx, &ecx, &edx, &esi, &edi, &ebp);
|
||||
return ebx == MONEY32_UNDEFINED ? -1 : edi;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4800
|
||||
*/
|
||||
void ride_construct_new(ride_list_item listItem)
|
||||
{
|
||||
game_command_callback = game_command_callback_ride_construct_new;
|
||||
ride_create_ride(listItem);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B4857
|
||||
|
@ -3134,7 +3105,7 @@ static bool ride_does_vehicle_colour_exist(uint8 ride_sub_type, vehicle_colour *
|
|||
return true;
|
||||
}
|
||||
|
||||
static sint32 ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_sub_type)
|
||||
sint32 ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_sub_type)
|
||||
{
|
||||
if (ride_sub_type >= 128)
|
||||
{
|
||||
|
@ -3167,7 +3138,7 @@ static sint32 ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_
|
|||
*
|
||||
* rct2: 0x006DE52C
|
||||
*/
|
||||
static void ride_set_vehicle_colours_to_random_preset(Ride *ride, uint8 preset_index)
|
||||
void ride_set_vehicle_colours_to_random_preset(Ride *ride, uint8 preset_index)
|
||||
{
|
||||
rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
|
||||
vehicle_colour_preset_list *presetList = rideEntry->vehicle_preset_list;
|
||||
|
@ -5814,7 +5785,7 @@ static void ride_stop_peeps_queuing(sint32 rideIndex)
|
|||
}
|
||||
}
|
||||
|
||||
static sint32 ride_get_empty_slot()
|
||||
sint32 ride_get_empty_slot()
|
||||
{
|
||||
for (sint32 i = 0; i < MAX_RIDES; i++) {
|
||||
Ride *ride = get_ride(i);
|
||||
|
@ -5825,7 +5796,7 @@ static sint32 ride_get_empty_slot()
|
|||
return -1;
|
||||
}
|
||||
|
||||
static sint32 ride_get_default_mode(Ride *ride)
|
||||
sint32 ride_get_default_mode(Ride *ride)
|
||||
{
|
||||
const rct_ride_entry *rideEntry = get_ride_entry(ride->subtype);
|
||||
const uint8 *availableModes = RideAvailableModes;
|
||||
|
@ -5876,7 +5847,7 @@ static bool ride_name_exists(char *name)
|
|||
*
|
||||
* Based on rct2: 0x006B4776
|
||||
*/
|
||||
static sint32 ride_get_random_colour_preset_index(uint8 ride_type)
|
||||
sint32 ride_get_random_colour_preset_index(uint8 ride_type)
|
||||
{
|
||||
if (ride_type >= 128)
|
||||
{
|
||||
|
@ -5901,7 +5872,7 @@ static sint32 ride_get_random_colour_preset_index(uint8 ride_type)
|
|||
*
|
||||
* Based on rct2: 0x006B4776
|
||||
*/
|
||||
static void ride_set_colour_preset(Ride *ride, uint8 index)
|
||||
void ride_set_colour_preset(Ride *ride, uint8 index)
|
||||
{
|
||||
const track_colour_preset_list * colourPresets = &RideColourPresets[ride->type];
|
||||
track_colour colours = { COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK };
|
||||
|
@ -5916,7 +5887,7 @@ static void ride_set_colour_preset(Ride *ride, uint8 index)
|
|||
ride->colour_scheme_type = 0;
|
||||
}
|
||||
|
||||
static money32 ride_get_common_price(Ride *forRide)
|
||||
money32 ride_get_common_price(Ride *forRide)
|
||||
{
|
||||
Ride *ride;
|
||||
sint32 i;
|
||||
|
@ -5930,7 +5901,7 @@ static money32 ride_get_common_price(Ride *forRide)
|
|||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
static money32 shop_item_get_common_price(Ride *forRide, sint32 shopItem)
|
||||
money32 shop_item_get_common_price(Ride *forRide, sint32 shopItem)
|
||||
{
|
||||
rct_ride_entry *rideEntry;
|
||||
Ride *ride;
|
||||
|
@ -5989,243 +5960,6 @@ money32 ride_create_command(sint32 type, sint32 subType, sint32 flags, uint8 *ou
|
|||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B3F0F
|
||||
*/
|
||||
static money32 ride_create(sint32 type, sint32 subType, sint32 flags, sint32 *outRideIndex, sint32 *outRideColour)
|
||||
{
|
||||
Ride *ride;
|
||||
rct_ride_entry *rideEntry;
|
||||
sint32 rideIndex, rideEntryIndex;
|
||||
|
||||
if (type >= RIDE_TYPE_COUNT)
|
||||
{
|
||||
log_warning("Invalid request for ride type %u", type);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
|
||||
if (subType == RIDE_ENTRY_INDEX_NULL) {
|
||||
uint8 *availableRideEntries = get_ride_entry_indices_for_ride_type(type);
|
||||
for (uint8 *rei = availableRideEntries; *rei != RIDE_ENTRY_INDEX_NULL; rei++) {
|
||||
rideEntry = get_ride_entry(*rei);
|
||||
|
||||
// Can happen in select-by-track-type mode
|
||||
if (!ride_entry_is_invented(*rei) && !gCheatsIgnoreResearchStatus)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry)) {
|
||||
subType = *rei;
|
||||
goto foundRideEntry;
|
||||
}
|
||||
}
|
||||
subType = availableRideEntries[0];
|
||||
if (subType == RIDE_ENTRY_INDEX_NULL) {
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
foundRideEntry:
|
||||
rideEntryIndex = subType;
|
||||
rideIndex = ride_get_empty_slot();
|
||||
if (subType >= 128)
|
||||
{
|
||||
log_warning("Invalid request for ride entry %u", subType);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
if (rideIndex == -1) {
|
||||
gGameCommandErrorText = STR_TOO_MANY_RIDES;
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
*outRideIndex = rideIndex;
|
||||
|
||||
// Ride/vehicle colour is calculated before applying to ensure
|
||||
// correct colour is passed over the network.
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY) && !(flags & GAME_COMMAND_FLAG_NETWORKED)) {
|
||||
*outRideColour =
|
||||
ride_get_random_colour_preset_index(type) |
|
||||
(ride_get_unused_preset_vehicle_colour(type, subType) << 8);
|
||||
}
|
||||
|
||||
if (!(flags & GAME_COMMAND_FLAG_APPLY)) {
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
gCommandPosition.x = 0x8000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ride = get_ride(rideIndex);
|
||||
rideEntry = get_ride_entry(rideEntryIndex);
|
||||
if (rideEntry == (rct_ride_entry *)-1)
|
||||
{
|
||||
log_warning("Invalid request for ride %u", rideIndex);
|
||||
return MONEY32_UNDEFINED;
|
||||
}
|
||||
ride->type = type;
|
||||
ride->subtype = rideEntryIndex;
|
||||
ride_set_colour_preset(ride, *outRideColour & 0xFF);
|
||||
ride->overall_view.xy = RCT_XY8_UNDEFINED;
|
||||
|
||||
// Ride name
|
||||
if (rideEntryIndex == RIDE_ENTRY_INDEX_NULL)
|
||||
{
|
||||
ride_set_name_to_track_default(ride, rideEntry);
|
||||
}
|
||||
else
|
||||
{
|
||||
ride_set_name_to_default(ride, rideEntry);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_STATIONS; i++) {
|
||||
ride->station_starts[i].xy = RCT_XY8_UNDEFINED;
|
||||
ride->entrances[i].xy = RCT_XY8_UNDEFINED;
|
||||
ride->exits[i].xy = RCT_XY8_UNDEFINED;
|
||||
ride->train_at_station[i] = 255;
|
||||
ride->queue_time[i] = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < MAX_VEHICLES_PER_RIDE; i++) {
|
||||
ride->vehicles[i] = SPRITE_INDEX_NULL;
|
||||
}
|
||||
|
||||
ride->status = RIDE_STATUS_CLOSED;
|
||||
ride->lifecycle_flags = 0;
|
||||
ride->vehicle_change_timeout = 0;
|
||||
ride->num_stations = 0;
|
||||
ride->num_vehicles = 1;
|
||||
ride->proposed_num_vehicles = 32;
|
||||
ride->max_trains = 32;
|
||||
ride->num_cars_per_train = 1;
|
||||
ride->proposed_num_cars_per_train = 12;
|
||||
ride->min_waiting_time = 10;
|
||||
ride->max_waiting_time = 60;
|
||||
ride->depart_flags = RIDE_DEPART_WAIT_FOR_MINIMUM_LENGTH | WAIT_FOR_LOAD_FULL;
|
||||
if (RideData4[ride->type].flags & RIDE_TYPE_FLAG4_MUSIC_ON_DEFAULT) {
|
||||
ride->lifecycle_flags |= RIDE_LIFECYCLE_MUSIC;
|
||||
}
|
||||
ride->music = RideData4[ride->type].default_music;
|
||||
|
||||
const rct_ride_properties rideProperties = RideProperties[ride->type];
|
||||
ride->operation_option = (rideProperties.min_value * 3 + rideProperties.max_value) / 4;
|
||||
|
||||
ride->lift_hill_speed = RideLiftData[ride->type].minimum_speed;
|
||||
|
||||
ride->measurement_index = 255;
|
||||
ride->excitement = (ride_rating)-1;
|
||||
ride->cur_num_customers = 0;
|
||||
ride->num_customers_timeout = 0;
|
||||
ride->chairlift_bullwheel_rotation = 0;
|
||||
|
||||
ride->price = 0;
|
||||
ride->price_secondary = 0;
|
||||
if (!(gParkFlags & PARK_FLAGS_NO_MONEY)) {
|
||||
ride->price = RideData4[ride->type].price;
|
||||
ride->price_secondary = RideData4[ride->type].price_secondary;
|
||||
|
||||
if (rideEntry->shop_item == SHOP_ITEM_NONE) {
|
||||
if (!(gParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) && !gCheatsUnlockAllPrices) {
|
||||
ride->price = 0;
|
||||
}
|
||||
} else {
|
||||
ride->price = DefaultShopItemPrice[rideEntry->shop_item];
|
||||
}
|
||||
if (rideEntry->shop_item_secondary != SHOP_ITEM_NONE) {
|
||||
ride->price_secondary = DefaultShopItemPrice[rideEntry->shop_item_secondary];
|
||||
}
|
||||
|
||||
if (gScenarioObjectiveType == OBJECTIVE_BUILD_THE_BEST) {
|
||||
ride->price = 0;
|
||||
}
|
||||
|
||||
if (ride->type == RIDE_TYPE_TOILETS) {
|
||||
if (shop_item_has_common_price(SHOP_ITEM_ADMISSION)) {
|
||||
money32 price = ride_get_common_price(ride);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rideEntry->shop_item != SHOP_ITEM_NONE) {
|
||||
if (shop_item_has_common_price(rideEntry->shop_item)) {
|
||||
money32 price = shop_item_get_common_price(ride, rideEntry->shop_item);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rideEntry->shop_item_secondary != SHOP_ITEM_NONE) {
|
||||
if (shop_item_has_common_price(rideEntry->shop_item_secondary)) {
|
||||
money32 price = shop_item_get_common_price(ride, rideEntry->shop_item_secondary);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price_secondary = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set the on-ride photo price, whether the ride has one or not (except shops).
|
||||
if (!ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_IS_SHOP) && shop_item_has_common_price(SHOP_ITEM_PHOTO)) {
|
||||
money32 price = shop_item_get_common_price(ride, SHOP_ITEM_PHOTO);
|
||||
if (price != MONEY32_UNDEFINED) {
|
||||
ride->price_secondary = (money16)price;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(ride->num_customers, 0, sizeof(ride->num_customers));
|
||||
ride->value = 0xFFFF;
|
||||
ride->satisfaction = 255;
|
||||
ride->satisfaction_time_out = 0;
|
||||
ride->satisfaction_next = 0;
|
||||
ride->popularity = 255;
|
||||
ride->popularity_time_out = 0;
|
||||
ride->popularity_next = 0;
|
||||
ride->window_invalidate_flags = 0;
|
||||
ride->total_customers = 0;
|
||||
ride->total_profit = 0;
|
||||
ride->num_riders = 0;
|
||||
ride->slide_in_use = 0;
|
||||
ride->maze_tiles = 0;
|
||||
ride->build_date = gDateMonthsElapsed;
|
||||
ride->music_tune_id = 255;
|
||||
|
||||
ride->breakdown_reason = 255;
|
||||
ride->upkeep_cost = (money16)-1;
|
||||
ride->reliability = RIDE_INITIAL_RELIABILITY;
|
||||
ride->unreliability_factor = 1;
|
||||
ride->inspection_interval = RIDE_INSPECTION_EVERY_30_MINUTES;
|
||||
ride->last_inspection = 0;
|
||||
ride->downtime = 0;
|
||||
memset(ride->downtime_history, 0, sizeof(ride->downtime_history));
|
||||
ride->no_primary_items_sold = 0;
|
||||
ride->no_secondary_items_sold = 0;
|
||||
ride->last_crash_type = RIDE_CRASH_TYPE_NONE;
|
||||
ride->income_per_hour = MONEY32_UNDEFINED;
|
||||
ride->profit = MONEY32_UNDEFINED;
|
||||
ride->connected_message_throttle = 0;
|
||||
ride->entrance_style = RIDE_ENTRANCE_STYLE_PLAIN;
|
||||
ride->num_block_brakes = 0;
|
||||
ride->guests_favourite = 0;
|
||||
|
||||
ride->num_circuits = 1;
|
||||
ride->mode = ride_get_default_mode(ride);
|
||||
ride->min_max_cars_per_train = (rideEntry->min_cars_in_train << 4) | rideEntry->max_cars_in_train;
|
||||
ride_set_vehicle_colours_to_random_preset(ride, 0xFF & (*outRideColour >> 8));
|
||||
window_invalidate_by_class(WC_RIDE_LIST);
|
||||
|
||||
// Log ride creation
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER) {
|
||||
int ebp = 1;
|
||||
game_log_multiplayer_command(GAME_COMMAND_CREATE_RIDE, 0, 0, 0, &rideIndex, 0, &ebp);
|
||||
}
|
||||
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_RIDE_CONSTRUCTION;
|
||||
gCommandPosition.x = 0x8000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ride_set_name_to_default(Ride * ride, rct_ride_entry * rideEntry)
|
||||
{
|
||||
if (!(rideEntry->flags & RIDE_ENTRY_FLAG_SEPARATE_RIDE) || rideTypeShouldLoseSeparateFlag(rideEntry)) {
|
||||
|
@ -6235,7 +5969,7 @@ void ride_set_name_to_default(Ride * ride, rct_ride_entry * rideEntry)
|
|||
}
|
||||
}
|
||||
|
||||
static void ride_set_name_to_track_default(Ride *ride, rct_ride_entry * rideEntry)
|
||||
void ride_set_name_to_track_default(Ride *ride, rct_ride_entry * rideEntry)
|
||||
{
|
||||
char rideNameBuffer[256];
|
||||
ride_name_args name_args;
|
||||
|
@ -6312,22 +6046,6 @@ rct_ride_name get_ride_naming(uint8 rideType, rct_ride_entry * rideEntry)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* rct2: 0x006B3F0F
|
||||
*/
|
||||
void game_command_create_ride(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp)
|
||||
{
|
||||
*ebx = ride_create(*edx & 0xFF, (*edx >> 8) & 0xFF, *ebx, edi, eax);
|
||||
}
|
||||
|
||||
void game_command_callback_ride_construct_new(sint32 eax, sint32 ebx, sint32 ecx, sint32 edx, sint32 esi, sint32 edi, sint32 ebp)
|
||||
{
|
||||
sint32 rideIndex = edi;
|
||||
if (rideIndex != -1)
|
||||
ride_construct(rideIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Network client callback when placing ride pieces
|
||||
|
|
|
@ -1021,6 +1021,8 @@ extern sint32 gRideRemoveTrackPieceCallbackType;
|
|||
|
||||
extern uint8 gLastEntranceStyle;
|
||||
|
||||
sint32 ride_get_empty_slot();
|
||||
sint32 ride_get_default_mode(Ride *ride);
|
||||
sint32 ride_get_count();
|
||||
sint32 ride_get_total_queue_length(Ride *ride);
|
||||
sint32 ride_get_max_queue_time(Ride *ride);
|
||||
|
@ -1050,6 +1052,8 @@ sint32 ride_get_total_time(Ride *ride);
|
|||
sint32 ride_can_have_multiple_circuits(Ride *ride);
|
||||
track_colour ride_get_track_colour(Ride *ride, sint32 colourScheme);
|
||||
vehicle_colour ride_get_vehicle_colour(Ride *ride, sint32 vehicleIndex);
|
||||
sint32 ride_get_unused_preset_vehicle_colour(uint8 ride_type, uint8 ride_sub_type);
|
||||
void ride_set_vehicle_colours_to_random_preset(Ride *ride, uint8 preset_index);
|
||||
rct_ride_entry *get_ride_entry_by_ride(Ride *ride);
|
||||
uint8 *get_ride_entry_indices_for_ride_type(uint8 rideType);
|
||||
void reset_type_to_ride_entry_index_map();
|
||||
|
@ -1073,6 +1077,10 @@ void ride_set_name(sint32 rideIndex, const char *name);
|
|||
void game_command_set_ride_name(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
void game_command_set_ride_setting(sint32 *eax, sint32 *ebx, sint32 *ecx, sint32 *edx, sint32 *esi, sint32 *edi, sint32 *ebp);
|
||||
sint32 ride_get_refund_price(sint32 ride_id);
|
||||
sint32 ride_get_random_colour_preset_index(uint8 ride_type);
|
||||
void ride_set_colour_preset(Ride *ride, uint8 index);
|
||||
money32 ride_get_common_price(Ride *forRide);
|
||||
money32 shop_item_get_common_price(Ride *forRide, sint32 shopItem);
|
||||
bool shop_item_is_photo(sint32 shopItem);
|
||||
bool shop_item_has_common_price(sint32 shopItem);
|
||||
rct_ride_name get_ride_naming(uint8 rideType, rct_ride_entry * rideEntry);
|
||||
|
|
Loading…
Reference in New Issue