1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-04 13:42:55 +01:00

Continue work on ride JSON loading

This commit is contained in:
Ted John
2017-12-20 16:31:06 +00:00
committed by Gymnasiast
parent 01067eebad
commit afbdb6dfc7
4 changed files with 239 additions and 40 deletions

View File

@@ -57,12 +57,36 @@ namespace ObjectJsonHelpers
defaultValue;
}
sint32 GetInteger(const json_t * obj, const std::string &name, const sint32 &defaultValue)
{
auto value = json_object_get(obj, name.c_str());
if (json_is_integer(value))
{
sint64 val = json_integer_value(value);
if (val >= std::numeric_limits<sint32>::min() &&
val <= std::numeric_limits<sint32>::max())
{
return static_cast<sint32>(val);
}
}
return defaultValue;
}
float GetFloat(const json_t * obj, const std::string &name, const float &defaultValue)
{
auto value = json_object_get(obj, name.c_str());
return json_is_number(value) ?
json_number_value(value) :
defaultValue;
}
std::vector<std::string> GetJsonStringArray(const json_t * arr)
{
std::vector<std::string> result;
if (json_is_array(arr))
{
auto count = json_array_size(arr);
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
auto element = json_string_value(json_array_get(arr, i));
@@ -76,6 +100,26 @@ namespace ObjectJsonHelpers
return result;
}
std::vector<sint32> GetJsonIntegerArray(const json_t * arr)
{
std::vector<sint32> result;
if (json_is_array(arr))
{
auto count = json_array_size(arr);
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
auto element = json_integer_value(json_array_get(arr, i));
result.push_back(element);
}
}
else if (json_is_integer(arr))
{
result.push_back(json_integer_value(arr));
}
return result;
}
uint8 ParseCursor(const std::string &s, uint8 defaultValue)
{
static const std::unordered_map<std::string, uint8> LookupTable

View File

@@ -32,7 +32,10 @@ namespace ObjectJsonHelpers
bool GetBoolean(const json_t * obj, const std::string &name, bool defaultValue = false);
std::string GetString(const json_t * value);
std::string GetString(const json_t * obj, const std::string &name, const std::string &defaultValue = "");
sint32 GetInteger(const json_t * obj, const std::string &name, const sint32 &defaultValue = 0);
float GetFloat(const json_t * obj, const std::string &name, const float &defaultValue = 0);
std::vector<std::string> GetJsonStringArray(const json_t * arr);
std::vector<sint32> GetJsonIntegerArray(const json_t * arr);
uint8 ParseCursor(const std::string &s, uint8 defaultValue);
rct_object_entry ParseObjectEntry(const std::string & s);
void LoadStrings(const json_t * root, StringTable &stringTable);

View File

@@ -14,6 +14,8 @@
*****************************************************************************/
#pragma endregion
#pragma warning(disable : 4706) // assignment within conditional expression
#include <algorithm>
#include <unordered_map>
#include "../core/IStream.hpp"
@@ -541,7 +543,183 @@ uint8 RideObject::CalculateNumHorizontalFrames(const rct_ride_entry_vehicle * ve
return numHorizontalFrames;
}
static uint8 ParseRideType(const std::string &s)
void RideObject::ReadJson(IReadObjectContext * context, const json_t * root)
{
auto properties = json_object_get(root, "properties");
auto rideTypes = ObjectJsonHelpers::GetJsonStringArray(json_object_get(properties, "type"));
for (size_t i = 0; i < std::min<size_t>(MAX_RIDE_TYPES_PER_RIDE_ENTRY, rideTypes.size()); i++)
{
_legacyType.ride_type[i] = ParseRideType(rideTypes[i]);
}
auto rideCategories = ObjectJsonHelpers::GetJsonStringArray(json_object_get(properties, "category"));
for (size_t i = 0; i < std::min<size_t>(MAX_CATEGORIES_PER_RIDE, rideCategories.size()); i++)
{
_legacyType.category[0] = ParseRideCategory(rideCategories[i]);
}
_legacyType.max_height = ObjectJsonHelpers::GetInteger(properties, "maxHeight");
if (IsRideTypeShopOrFacility(_legacyType.ride_type[0]))
{
// Standard car info for a shop
auto &car = _legacyType.vehicles[0];
car.spacing = 544;
car.sprite_flags = VEHICLE_SPRITE_FLAG_FLAT;
car.sprite_width = 1;
car.sprite_height_negative = 1;
car.sprite_height_positive = 1;
car.flags = VEHICLE_ENTRY_FLAG_SPINNING;
car.car_visual = VEHICLE_VISUAL_FLAT_RIDE_OR_CAR_RIDE;
car.friction_sound_id = 0xFF;
car.sound_range = 0xFF;
car.draw_order = 6;
// Shop item
auto rideSells = ObjectJsonHelpers::GetJsonStringArray(json_object_get(json_object_get(root, "properties"), "sells"));
_legacyType.shop_item = SHOP_ITEM_NONE;
_legacyType.shop_item_secondary = SHOP_ITEM_NONE;
if (rideSells.size() >= 1)
{
_legacyType.shop_item = ParseShopItem(rideSells[0]);
}
if (rideSells.size() >= 2)
{
_legacyType.shop_item_secondary = ParseShopItem(rideSells[1]);
}
}
else
{
ReadJsonVehicleInfo(context, properties);
auto ratingMultiplier = json_object_get(properties, "ratingMultipler");
if (ratingMultiplier != nullptr)
{
_legacyType.excitement_multiplier = ObjectJsonHelpers::GetInteger(ratingMultiplier, "excitement");
_legacyType.intensity_multiplier = ObjectJsonHelpers::GetInteger(ratingMultiplier, "intensity");
_legacyType.nausea_multiplier = ObjectJsonHelpers::GetInteger(ratingMultiplier, "nausea");
}
auto availableTrackPieces = ObjectJsonHelpers::GetJsonStringArray(json_object_get(properties, "availableTrackPieces"));
}
_legacyType.flags |= ObjectJsonHelpers::GetFlags<uint32>(properties, {
{ "noInversions", RIDE_ENTRY_FLAG_NO_INVERSIONS },
{ "noBanking", RIDE_ENTRY_FLAG_NO_BANKED_TRACK },
{ "playDepartSound", RIDE_ENTRY_FLAG_PLAY_DEPART_SOUND },
{ "", RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_1 },
{ "", RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_1 },
{ "", RIDE_ENTRY_FLAG_ALTERNATIVE_ROTATION_MODE_2 },
{ "", RIDE_ENTRY_FLAG_7 },
{ "playSplashSound", RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND },
{ "playSplashSoundSlide", RIDE_ENTRY_FLAG_PLAY_SPLASH_SOUND_SLIDE },
{ "hasShelter", RIDE_ENTRY_FLAG_COVERED_RIDE },
{ "limitAirTimeBonus", RIDE_ENTRY_FLAG_LIMIT_AIRTIME_BONUS },
{ "separateRide", RIDE_ENTRY_FLAG_SEPARATE_RIDE },
{ "disableBreakdown", RIDE_ENTRY_FLAG_CANNOT_BREAK_DOWN },
{ "", RIDE_ENTRY_FLAG_16 },
{ "", RIDE_ENTRY_FLAG_18 },
{ "disablePainting", RIDE_ENTRY_FLAG_DISABLE_COLOUR_TAB },
{ "", RIDE_ENTRY_FLAG_ALTERNATIVE_SWING_MODE_2 } });
ObjectJsonHelpers::LoadStrings(root, GetStringTable());
ObjectJsonHelpers::LoadImages(root, GetImageTable());
}
void RideObject::ReadJsonVehicleInfo(IReadObjectContext * context, const json_t * properties)
{
_legacyType.min_cars_in_train = json_integer_value(json_object_get(properties, "minCarsPerTrain"));
_legacyType.max_cars_in_train = json_integer_value(json_object_get(properties, "maxCarsPerTrain"));
_legacyType.cars_per_flat_ride = json_integer_value(json_object_get(properties, "carsPerFlatRide"));
_legacyType.zero_cars = json_integer_value(json_object_get(properties, "numEmptyCars"));
// Train formation from car indices
_legacyType.default_vehicle = json_integer_value(json_object_get(properties, "defaultCar"));
_legacyType.tab_vehicle = json_integer_value(json_object_get(properties, "tabCar"));
auto tabScale = ObjectJsonHelpers::GetFloat(properties, "tabScale");
if (tabScale != 0 && ObjectJsonHelpers::GetFloat(properties, "tabScale") <= 0.5f)
{
_legacyType.flags |= RIDE_ENTRY_FLAG_VEHICLE_TAB_SCALE_HALF;
}
auto headCars = ObjectJsonHelpers::GetJsonIntegerArray(json_object_get(properties, "headCars"));
if (headCars.size() >= 1)
{
_legacyType.front_vehicle = headCars[0];
}
if (headCars.size() >= 2)
{
_legacyType.second_vehicle = headCars[1];
}
if (headCars.size() >= 3)
{
_legacyType.third_vehicle = headCars[2];
}
if (headCars.size() >= 4)
{
// More than 3 head cars not supported yet!
}
auto tailCars = ObjectJsonHelpers::GetJsonIntegerArray(json_object_get(properties, "tailCars"));
if (tailCars.size() >= 1)
{
_legacyType.rear_vehicle = tailCars[0];
}
if (tailCars.size() >= 2)
{
// More than 1 tail car not supported yet!
}
ReadJsonCars(json_object_get(properties, "cars"));
}
std::vector<rct_ride_entry_vehicle> RideObject::ReadJsonCars(const json_t * jCars)
{
std::vector<rct_ride_entry_vehicle> cars;
json_t * jCar;
size_t index;
json_array_foreach(jCars, index, jCar)
{
auto car = ReadJsonCar(jCar);
cars.push_back(car);
}
return cars;
}
rct_ride_entry_vehicle RideObject::ReadJsonCar(const json_t * jCar)
{
rct_ride_entry_vehicle car = { 0 };
car.rotation_frame_mask = ObjectJsonHelpers::GetInteger(jCar, "rotationFrameMask");
car.spacing = ObjectJsonHelpers::GetInteger(jCar, "spacing");
car.car_friction = ObjectJsonHelpers::GetInteger(jCar, "friction");
car.num_seats = ObjectJsonHelpers::GetInteger(jCar, "numSeats");
car.no_seating_rows = ObjectJsonHelpers::GetInteger(jCar, "numSeatRows");
car.powered_acceleration = ObjectJsonHelpers::GetInteger(jCar, "poweredAcceleration");
car.powered_max_speed = ObjectJsonHelpers::GetInteger(jCar, "poweredMaxSpeed");
car.effect_visual = ObjectJsonHelpers::GetInteger(jCar, "effectVisual");
car.draw_order = ObjectJsonHelpers::GetInteger(jCar, "drawOrder");
return car;
}
bool RideObject::IsRideTypeShopOrFacility(uint8 rideType)
{
switch (rideType)
{
case RIDE_TYPE_TOILETS:
case RIDE_TYPE_SHOP:
case RIDE_TYPE_DRINK_STALL:
case RIDE_TYPE_FOOD_STALL:
case RIDE_TYPE_INFORMATION_KIOSK:
case RIDE_TYPE_CASH_MACHINE:
case RIDE_TYPE_FIRST_AID:
return true;
default:
return false;
}
}
uint8 RideObject::ParseRideType(const std::string &s)
{
static const std::unordered_map<std::string, uint8> LookupTable
{
@@ -634,7 +812,7 @@ static uint8 ParseRideType(const std::string &s)
RIDE_TYPE_NULL;
}
static uint8 ParseRideCategory(const std::string &s)
uint8 RideObject::ParseRideCategory(const std::string &s)
{
static const std::unordered_map<std::string, uint8> LookupTable
{
@@ -651,7 +829,7 @@ static uint8 ParseRideCategory(const std::string &s)
RIDE_CATEGORY_TRANSPORT;
}
static uint8 ParseShopItem(const std::string &s)
uint8 RideObject::ParseShopItem(const std::string &s)
{
static const std::unordered_map<std::string, uint8> LookupTable
{
@@ -698,38 +876,3 @@ static uint8 ParseShopItem(const std::string &s)
result->second :
SHOP_ITEM_NONE;
}
void RideObject::ReadJson(IReadObjectContext * context, const json_t * root)
{
auto rideTypes = ObjectJsonHelpers::GetJsonStringArray(json_object_get(json_object_get(root, "properties"), "type"));
for (size_t i = 0; i < std::min<size_t>(MAX_RIDE_TYPES_PER_RIDE_ENTRY, rideTypes.size()); i++)
{
_legacyType.ride_type[i] = ParseRideType(rideTypes[i]);
}
auto rideCategories = ObjectJsonHelpers::GetJsonStringArray(json_object_get(json_object_get(root, "properties"), "category"));
for (size_t i = 0; i < std::min<size_t>(MAX_CATEGORIES_PER_RIDE, rideCategories.size()); i++)
{
_legacyType.category[0] = ParseRideCategory(rideCategories[i]);
}
// Shop item
auto rideSells = ObjectJsonHelpers::GetJsonStringArray(json_object_get(json_object_get(root, "properties"), "sells"));
_legacyType.shop_item = SHOP_ITEM_NONE;
_legacyType.shop_item_secondary = SHOP_ITEM_NONE;
if (rideSells.size() >= 1)
{
_legacyType.shop_item = ParseShopItem(rideSells[0]);
}
if (rideSells.size() >= 2)
{
_legacyType.shop_item_secondary = ParseShopItem(rideSells[1]);
}
rct_ride_entry_vehicle * vehicle0 = &_legacyType.vehicles[0];
vehicle0->sprite_flags |= VEHICLE_SPRITE_FLAG_FLAT;
vehicle0->base_image_id = 0;
ObjectJsonHelpers::LoadStrings(root, GetStringTable());
ObjectJsonHelpers::LoadImages(root, GetImageTable());
}

View File

@@ -16,9 +16,9 @@
#pragma once
#include "Object.h"
#include <vector>
#include "../ride/Ride.h"
#include "Object.h"
class RideObject final : public Object
{
@@ -50,6 +50,15 @@ private:
void ReadLegacyVehicle(IReadObjectContext * context, IStream * stream, rct_ride_entry_vehicle * vehicle);
void PerformFixes();
void ReadJsonVehicleInfo(IReadObjectContext * context, const json_t * properties);
std::vector<rct_ride_entry_vehicle> ReadJsonCars(const json_t * jCars);
rct_ride_entry_vehicle ReadJsonCar(const json_t * jCar);
static uint8 CalculateNumVerticalFrames(const rct_ride_entry_vehicle * vehicleEntry);
static uint8 CalculateNumHorizontalFrames(const rct_ride_entry_vehicle * vehicleEntry);
static bool IsRideTypeShopOrFacility(uint8 rideType);
static uint8 ParseRideType(const std::string &s);
static uint8 ParseRideCategory(const std::string &s);
static uint8 ParseShopItem(const std::string &s);
};