1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-02-03 04:05:49 +01:00

Update title sequence scripting part

This commit is contained in:
Hielke Morsink
2022-06-19 12:40:02 +02:00
parent 1fc2312abd
commit 239dcb1677

View File

@@ -24,9 +24,28 @@
# include <openrct2/title/TitleSequence.h>
# include <openrct2/title/TitleSequenceManager.h>
# include <openrct2/title/TitleSequencePlayer.h>
# include <type_traits>
# include <variant>
namespace OpenRCT2::Scripting
{
enum class TitleScript : uint8_t
{
Undefined = 0xFF,
Wait = 0,
Location,
Rotate,
Zoom,
Follow,
Restart,
Load,
End,
Speed,
Loop,
EndLoop,
LoadSc,
};
static const DukEnumMap<TitleScript> TitleScriptMap({
{ "load", TitleScript::Load },
{ "location", TitleScript::Location },
@@ -45,43 +64,59 @@ namespace OpenRCT2::Scripting
return ToDuk(ctx, TitleScriptMap[value]);
}
template<> DukValue ToDuk(duk_context* ctx, const TitleCommand& value)
template<> DukValue ToDuk(duk_context* ctx, const OpenRCT2::Title::TitleCommand& value)
{
using namespace OpenRCT2::Title;
DukObject obj(ctx);
obj.Set("type", ToDuk(ctx, value.Type));
switch (value.Type)
{
case TitleScript::Load:
obj.Set("index", value.SaveIndex);
break;
case TitleScript::Location:
obj.Set("x", value.Location.X);
obj.Set("y", value.Location.Y);
break;
case TitleScript::Rotate:
obj.Set("rotations", value.Rotations);
break;
case TitleScript::Zoom:
obj.Set("zoom", value.Zoom);
break;
case TitleScript::Follow:
if (value.Follow.SpriteIndex.IsNull())
obj.Set("id", nullptr);
else
obj.Set("id", value.Follow.SpriteIndex.ToUnderlying());
break;
case TitleScript::Speed:
obj.Set("speed", value.Speed);
break;
case TitleScript::Wait:
obj.Set("duration", value.Milliseconds);
break;
case TitleScript::LoadSc:
obj.Set("scenario", String::ToStringView(value.Scenario, sizeof(value.Scenario)));
break;
default:
break;
}
std::visit(
[&obj](auto&& value) {
using T = std::decay<decltype(value)>::type;
if constexpr (std::is_same_v<T, LoadParkCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Load]);
obj.Set("index", value.SaveIndex);
}
else if constexpr (std::is_same_v<T, SetLocationCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Location]);
obj.Set("x", value.Location.X);
obj.Set("y", value.Location.Y);
}
else if constexpr (std::is_same_v<T, RotateViewCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Rotate]);
obj.Set("rotations", value.Rotations);
}
else if constexpr (std::is_same_v<T, SetZoomCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Zoom]);
obj.Set("zoom", value.Zoom);
}
else if constexpr (std::is_same_v<T, FollowEntityCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Follow]);
if (value.Follow.SpriteIndex.IsNull())
obj.Set("id", nullptr);
else
obj.Set("id", value.Follow.SpriteIndex.ToUnderlying());
}
else if constexpr (std::is_same_v<T, SetSpeedCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Speed]);
obj.Set("speed", value.Speed);
}
else if constexpr (std::is_same_v<T, WaitCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::Wait]);
obj.Set("duration", value.Milliseconds);
}
else if constexpr (std::is_same_v<T, LoadScenarioCommand>)
{
obj.Set("type", TitleScriptMap[TitleScript::LoadSc]);
obj.Set("scenario", String::ToStringView(value.Scenario, sizeof(value.Scenario)));
}
},
value);
return obj.Take();
}
@@ -92,48 +127,55 @@ namespace OpenRCT2::Scripting
throw DukException() << "Invalid title command id";
}
template<> TitleCommand FromDuk(const DukValue& value)
template<> OpenRCT2::Title::TitleCommand FromDuk(const DukValue& value)
{
using namespace OpenRCT2::Title;
auto type = FromDuk<TitleScript>(value["type"]);
TitleCommand command{};
command.Type = type;
switch (type)
{
case TitleScript::Load:
command.SaveIndex = value["index"].as_int();
command = LoadParkCommand{ static_cast<uint8_t>(value["index"].as_int()) };
break;
case TitleScript::Location:
command.Location.X = value["x"].as_int();
command.Location.Y = value["y"].as_int();
command = SetLocationCommand{
static_cast<uint8_t>(value["x"].as_int()),
static_cast<uint8_t>(value["y"].as_int()),
};
break;
case TitleScript::Rotate:
command.Rotations = value["rotations"].as_int();
command = RotateViewCommand{ static_cast<uint8_t>(value["rotations"].as_int()) };
break;
case TitleScript::Zoom:
command.Zoom = value["zoom"].as_int();
command = SetZoomCommand{ static_cast<uint8_t>(value["zoom"].as_int()) };
break;
case TitleScript::Follow:
{
auto dukId = value["id"];
if (dukId.type() == DukValue::Type::NUMBER)
{
command.Follow.SpriteIndex = EntityId::FromUnderlying(dukId.as_int());
command = FollowEntityCommand{ EntityId::FromUnderlying(dukId.as_int()) };
}
else
{
command.Follow.SpriteIndex = EntityId::GetNull();
command = FollowEntityCommand{ EntityId::GetNull() };
}
break;
}
case TitleScript::Speed:
command.Speed = value["speed"].as_int();
command = SetSpeedCommand{ static_cast<uint8_t>(value["speed"].as_int()) };
break;
case TitleScript::Wait:
command.Milliseconds = value["duration"].as_int();
command = WaitCommand{ static_cast<uint16_t>(value["duration"].as_int()) };
break;
case TitleScript::LoadSc:
String::Set(command.Scenario, sizeof(command.Scenario), value["scenario"].as_c_string());
{
auto loadScenarioCommand = LoadScenarioCommand{};
String::Set(
loadScenarioCommand.Scenario, sizeof(loadScenarioCommand.Scenario), value["scenario"].as_c_string());
command = loadScenarioCommand;
break;
}
default:
break;
}
@@ -164,7 +206,7 @@ namespace OpenRCT2::Scripting
if (value == _fileName)
return;
auto seq = LoadTitleSequence(_titleSequencePath);
auto seq = OpenRCT2::Title::LoadTitleSequence(_titleSequencePath);
if (seq != nullptr)
{
// Check if name already in use
@@ -183,27 +225,27 @@ namespace OpenRCT2::Scripting
void delete_()
{
auto seq = LoadTitleSequence(_titleSequencePath);
auto seq = OpenRCT2::Title::LoadTitleSequence(_titleSequencePath);
if (seq != nullptr)
{
auto index = GetIndex(*seq, _fileName);
if (index)
{
TitleSequenceRemovePark(*seq, *index);
TitleSequenceSave(*seq);
OpenRCT2::Title::TitleSequenceRemovePark(*seq, *index);
OpenRCT2::Title::TitleSequenceSave(*seq);
}
}
}
void load()
{
auto seq = LoadTitleSequence(_titleSequencePath);
auto seq = OpenRCT2::Title::LoadTitleSequence(_titleSequencePath);
if (seq != nullptr)
{
auto index = GetIndex(*seq, _fileName);
if (index)
{
auto handle = TitleSequenceGetParkHandle(*seq, *index);
auto handle = OpenRCT2::Title::TitleSequenceGetParkHandle(*seq, *index);
auto isScenario = ParkImporter::ExtensionIsScenario(handle->HintPath);
try
{
@@ -246,7 +288,7 @@ namespace OpenRCT2::Scripting
}
private:
static std::optional<size_t> GetIndex(const TitleSequence& seq, const std::string_view needle)
static std::optional<size_t> GetIndex(const OpenRCT2::Title::TitleSequence& seq, const std::string_view needle)
{
for (size_t i = 0; i < seq.Saves.size(); i++)
{
@@ -327,7 +369,7 @@ namespace OpenRCT2::Scripting
std::vector<std::shared_ptr<ScTitleSequencePark>> parks_get() const
{
std::vector<std::shared_ptr<ScTitleSequencePark>> result;
auto titleSeq = LoadTitleSequence(_path);
auto titleSeq = OpenRCT2::Title::LoadTitleSequence(_path);
if (titleSeq != nullptr)
{
for (size_t i = 0; i < titleSeq->Saves.size(); i++)
@@ -344,7 +386,7 @@ namespace OpenRCT2::Scripting
auto ctx = scriptEngine.GetContext();
std::vector<DukValue> result;
auto titleSeq = LoadTitleSequence(_path);
auto titleSeq = OpenRCT2::Title::LoadTitleSequence(_path);
if (titleSeq != nullptr)
{
for (const auto& command : titleSeq->Commands)
@@ -357,23 +399,23 @@ namespace OpenRCT2::Scripting
void commands_set(const std::vector<DukValue>& value)
{
std::vector<TitleCommand> commands;
std::vector<OpenRCT2::Title::TitleCommand> commands;
for (const auto& v : value)
{
auto command = FromDuk<TitleCommand>(v);
auto command = FromDuk<OpenRCT2::Title::TitleCommand>(v);
commands.push_back(std::move(command));
}
auto titleSeq = LoadTitleSequence(_path);
auto titleSeq = OpenRCT2::Title::LoadTitleSequence(_path);
titleSeq->Commands = commands;
TitleSequenceSave(*titleSeq);
OpenRCT2::Title::TitleSequenceSave(*titleSeq);
}
void addPark(const std::string& path, const std::string& fileName)
{
auto titleSeq = LoadTitleSequence(_path);
TitleSequenceAddPark(*titleSeq, path.c_str(), fileName.c_str());
TitleSequenceSave(*titleSeq);
auto titleSeq = OpenRCT2::Title::LoadTitleSequence(_path);
OpenRCT2::Title::TitleSequenceAddPark(*titleSeq, path.c_str(), fileName.c_str());
OpenRCT2::Title::TitleSequenceSave(*titleSeq);
}
std::shared_ptr<ScTitleSequence> clone(const std::string& name) const