Moved ride create command to new game action system.

This commit is contained in:
ZehM4tt 2017-07-18 01:05:37 +02:00 committed by Michał Janiszewski
parent fbd793083c
commit 3657122b3b
10 changed files with 358 additions and 309 deletions

View File

@ -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))

View File

@ -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;
}

View File

@ -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
}

View File

@ -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>();
}
}

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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,

View File

@ -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;

View File

@ -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

View File

@ -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);