mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #15165 from ZehMatt/scripting/createEntity
Add createEntity API to scripting
This commit is contained in:
commit
3ed2f8e98e
|
@ -2,6 +2,7 @@
|
||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
- Feature: [#15084] [Plugin] Add "vehicle.crash" hook.
|
- Feature: [#15084] [Plugin] Add "vehicle.crash" hook.
|
||||||
- Feature: [#15143] Added a shortcut key for Giant Screenshot.
|
- Feature: [#15143] Added a shortcut key for Giant Screenshot.
|
||||||
|
- Feature: [#15165] [Plugin] Add the ability to create entities using "map.createEntity".
|
||||||
- Fix: [#13465] Creating a scenario based on a won save game results in a scenario that’s instantly won.
|
- Fix: [#13465] Creating a scenario based on a won save game results in a scenario that’s instantly won.
|
||||||
- Fix: [#14316] Closing the Track Designs Manager window causes broken state.
|
- Fix: [#14316] Closing the Track Designs Manager window causes broken state.
|
||||||
- Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).
|
- Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).
|
||||||
|
|
|
@ -577,6 +577,7 @@ declare global {
|
||||||
getAllEntities(type: "peep"): Peep[];
|
getAllEntities(type: "peep"): Peep[];
|
||||||
getAllEntities(type: "guest"): Guest[];
|
getAllEntities(type: "guest"): Guest[];
|
||||||
getAllEntities(type: "staff"): Staff[];
|
getAllEntities(type: "staff"): Staff[];
|
||||||
|
createEntity(type: EntityType, initializer: object): Entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TileElementType =
|
type TileElementType =
|
||||||
|
@ -1469,6 +1470,34 @@ declare global {
|
||||||
|
|
||||||
type StaffType = "handyman" | "mechanic" | "security" | "entertainer";
|
type StaffType = "handyman" | "mechanic" | "security" | "entertainer";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents litter entity.
|
||||||
|
*/
|
||||||
|
interface Litter extends Entity {
|
||||||
|
/**
|
||||||
|
* The type of the litter.
|
||||||
|
*/
|
||||||
|
litterType: LitterType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The tick number this entity was created.
|
||||||
|
*/
|
||||||
|
creationTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
type LitterType = "vomit" |
|
||||||
|
"vomit_alt" |
|
||||||
|
"empty_can" |
|
||||||
|
"rubbish" |
|
||||||
|
"burger_box" |
|
||||||
|
"empty_cup" |
|
||||||
|
"empty_box" |
|
||||||
|
"empty_bottle" |
|
||||||
|
"empty_bowl_red" |
|
||||||
|
"empty_drink_carton" |
|
||||||
|
"empty_juice_cup" |
|
||||||
|
"empty_bowl_blue";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Network APIs
|
* Network APIs
|
||||||
* Use `network.status` to determine whether the current game is a client, server or in single player mode.
|
* Use `network.status` to determine whether the current game is a client, server or in single player mode.
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
# include "../peep/Staff.h"
|
# include "../peep/Staff.h"
|
||||||
# include "../util/Util.h"
|
# include "../util/Util.h"
|
||||||
# include "../world/EntityList.h"
|
# include "../world/EntityList.h"
|
||||||
|
# include "../world/Litter.h"
|
||||||
# include "../world/Sprite.h"
|
# include "../world/Sprite.h"
|
||||||
# include "Duktape.hpp"
|
# include "Duktape.hpp"
|
||||||
# include "ScRide.hpp"
|
# include "ScRide.hpp"
|
||||||
|
@ -1244,6 +1245,71 @@ namespace OpenRCT2::Scripting
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const DukEnumMap<Litter::Type> LitterTypeMap({
|
||||||
|
{ "vomit", Litter::Type::Vomit },
|
||||||
|
{ "vomit_alt", Litter::Type::VomitAlt },
|
||||||
|
{ "empty_can", Litter::Type::EmptyCan },
|
||||||
|
{ "rubbish", Litter::Type::Rubbish },
|
||||||
|
{ "burger_box", Litter::Type::BurgerBox },
|
||||||
|
{ "empty_cup", Litter::Type::EmptyCup },
|
||||||
|
{ "empty_box", Litter::Type::EmptyBox },
|
||||||
|
{ "empty_bottle", Litter::Type::EmptyBottle },
|
||||||
|
{ "empty_bowl_red", Litter::Type::EmptyBowlRed },
|
||||||
|
{ "empty_drink_carton", Litter::Type::EmptyDrinkCarton },
|
||||||
|
{ "empty_juice_cup", Litter::Type::EmptyJuiceCup },
|
||||||
|
{ "empty_bowl_blue", Litter::Type::EmptyBowlBlue },
|
||||||
|
});
|
||||||
|
|
||||||
|
class ScLitter : public ScEntity
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScLitter(uint16_t Id)
|
||||||
|
: ScEntity(Id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Register(duk_context* ctx)
|
||||||
|
{
|
||||||
|
dukglue_set_base_class<ScEntity, ScLitter>(ctx);
|
||||||
|
dukglue_register_property(ctx, &ScLitter::litterType_get, &ScLitter::litterType_set, "litterType");
|
||||||
|
dukglue_register_property(ctx, &ScLitter::creationTick_get, nullptr, "creationTick");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Litter* GetLitter() const
|
||||||
|
{
|
||||||
|
return ::GetEntity<Litter>(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string litterType_get() const
|
||||||
|
{
|
||||||
|
auto* litter = GetLitter();
|
||||||
|
auto it = LitterTypeMap.find(litter->SubType);
|
||||||
|
if (it == LitterTypeMap.end())
|
||||||
|
return "";
|
||||||
|
return std::string{ it->first };
|
||||||
|
}
|
||||||
|
|
||||||
|
void litterType_set(const std::string& litterType)
|
||||||
|
{
|
||||||
|
ThrowIfGameStateNotMutable();
|
||||||
|
|
||||||
|
auto it = LitterTypeMap.find(litterType);
|
||||||
|
if (it == LitterTypeMap.end())
|
||||||
|
return;
|
||||||
|
auto* litter = GetLitter();
|
||||||
|
litter->SubType = it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t creationTick_get() const
|
||||||
|
{
|
||||||
|
auto* litter = GetLitter();
|
||||||
|
if (litter == nullptr)
|
||||||
|
return 0;
|
||||||
|
return litter->creationTick;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace OpenRCT2::Scripting
|
} // namespace OpenRCT2::Scripting
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,7 +17,11 @@
|
||||||
# include "../world/Balloon.h"
|
# include "../world/Balloon.h"
|
||||||
# include "../world/Duck.h"
|
# include "../world/Duck.h"
|
||||||
# include "../world/EntityList.h"
|
# include "../world/EntityList.h"
|
||||||
|
# include "../world/Fountain.h"
|
||||||
|
# include "../world/Litter.h"
|
||||||
# include "../world/Map.h"
|
# include "../world/Map.h"
|
||||||
|
# include "../world/MoneyEffect.h"
|
||||||
|
# include "../world/Particle.h"
|
||||||
# include "Duktape.hpp"
|
# include "Duktape.hpp"
|
||||||
# include "ScEntity.hpp"
|
# include "ScEntity.hpp"
|
||||||
# include "ScRide.hpp"
|
# include "ScRide.hpp"
|
||||||
|
@ -38,13 +42,7 @@ namespace OpenRCT2::Scripting
|
||||||
|
|
||||||
DukValue size_get() const
|
DukValue size_get() const
|
||||||
{
|
{
|
||||||
auto ctx = _context;
|
return ToDuk(_context, CoordsXY{ gMapSize, gMapSize });
|
||||||
auto objIdx = duk_push_object(ctx);
|
|
||||||
duk_push_number(ctx, gMapSize);
|
|
||||||
duk_put_prop_string(ctx, objIdx, "x");
|
|
||||||
duk_push_number(ctx, gMapSize);
|
|
||||||
duk_put_prop_string(ctx, objIdx, "y");
|
|
||||||
return DukValue::take_from_stack(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t numRides_get() const
|
int32_t numRides_get() const
|
||||||
|
@ -110,7 +108,7 @@ namespace OpenRCT2::Scripting
|
||||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScEntity>(sprite->sprite_index)));
|
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScEntity>(sprite->sprite_index)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type == "car")
|
else if (type == "car")
|
||||||
{
|
{
|
||||||
for (auto trainHead : TrainManager::View())
|
for (auto trainHead : TrainManager::View())
|
||||||
{
|
{
|
||||||
|
@ -169,6 +167,77 @@ namespace OpenRCT2::Scripting
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename TEntityType, typename TScriptType> DukValue createEntityType(const DukValue& initializer)
|
||||||
|
{
|
||||||
|
TEntityType* entity = CreateEntity<TEntityType>();
|
||||||
|
|
||||||
|
auto entityPos = CoordsXYZ{ AsOrDefault(initializer["x"], 0), AsOrDefault(initializer["y"], 0),
|
||||||
|
AsOrDefault(initializer["z"], 0) };
|
||||||
|
entity->MoveTo(entityPos);
|
||||||
|
|
||||||
|
return GetObjectAsDukValue(_context, std::make_shared<TScriptType>(entity->sprite_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
DukValue createEntity(const std::string& type, const DukValue& initializer)
|
||||||
|
{
|
||||||
|
if (type == "car")
|
||||||
|
{
|
||||||
|
return createEntityType<Vehicle, ScVehicle>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "staff")
|
||||||
|
{
|
||||||
|
return createEntityType<Staff, ScStaff>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "guest")
|
||||||
|
{
|
||||||
|
return createEntityType<Guest, ScGuest>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "steam_particle")
|
||||||
|
{
|
||||||
|
return createEntityType<SteamParticle, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "money_effect")
|
||||||
|
{
|
||||||
|
return createEntityType<MoneyEffect, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "crashed_vehicle_particle")
|
||||||
|
{
|
||||||
|
return createEntityType<VehicleCrashParticle, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "explosion_cloud")
|
||||||
|
{
|
||||||
|
return createEntityType<ExplosionCloud, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "crash_splash")
|
||||||
|
{
|
||||||
|
return createEntityType<CrashSplashParticle, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "explosion_flare")
|
||||||
|
{
|
||||||
|
return createEntityType<ExplosionFlare, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "balloon")
|
||||||
|
{
|
||||||
|
return createEntityType<Balloon, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "duck")
|
||||||
|
{
|
||||||
|
return createEntityType<Duck, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "jumping_fountain")
|
||||||
|
{
|
||||||
|
return createEntityType<JumpingFountain, ScEntity>(initializer);
|
||||||
|
}
|
||||||
|
else if (type == "litter")
|
||||||
|
{
|
||||||
|
return createEntityType<Litter, ScLitter>(initializer);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
duk_error(_context, DUK_ERR_ERROR, "Invalid entity type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void Register(duk_context* ctx)
|
static void Register(duk_context* ctx)
|
||||||
{
|
{
|
||||||
dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size");
|
dukglue_register_property(ctx, &ScMap::size_get, nullptr, "size");
|
||||||
|
@ -179,6 +248,7 @@ namespace OpenRCT2::Scripting
|
||||||
dukglue_register_method(ctx, &ScMap::getTile, "getTile");
|
dukglue_register_method(ctx, &ScMap::getTile, "getTile");
|
||||||
dukglue_register_method(ctx, &ScMap::getEntity, "getEntity");
|
dukglue_register_method(ctx, &ScMap::getEntity, "getEntity");
|
||||||
dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities");
|
dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities");
|
||||||
|
dukglue_register_method(ctx, &ScMap::createEntity, "createEntity");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -193,6 +263,8 @@ namespace OpenRCT2::Scripting
|
||||||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||||
case EntityType::Guest:
|
case EntityType::Guest:
|
||||||
return GetObjectAsDukValue(_context, std::make_shared<ScGuest>(spriteId));
|
return GetObjectAsDukValue(_context, std::make_shared<ScGuest>(spriteId));
|
||||||
|
case EntityType::Litter:
|
||||||
|
return GetObjectAsDukValue(_context, std::make_shared<ScLitter>(spriteId));
|
||||||
default:
|
default:
|
||||||
return GetObjectAsDukValue(_context, std::make_shared<ScEntity>(spriteId));
|
return GetObjectAsDukValue(_context, std::make_shared<ScEntity>(spriteId));
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ namespace OpenRCT2
|
||||||
|
|
||||||
namespace OpenRCT2::Scripting
|
namespace OpenRCT2::Scripting
|
||||||
{
|
{
|
||||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 34;
|
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 35;
|
||||||
|
|
||||||
// Versions marking breaking changes.
|
// Versions marking breaking changes.
|
||||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||||
|
|
Loading…
Reference in New Issue