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: [#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: [#14316] Closing the Track Designs Manager window causes broken state.
|
||||
- Fix: [#14667] “Extreme Hawaiian Island” has unpurchaseable land tiles (original bug).
|
||||
|
|
|
@ -577,6 +577,7 @@ declare global {
|
|||
getAllEntities(type: "peep"): Peep[];
|
||||
getAllEntities(type: "guest"): Guest[];
|
||||
getAllEntities(type: "staff"): Staff[];
|
||||
createEntity(type: EntityType, initializer: object): Entity;
|
||||
}
|
||||
|
||||
type TileElementType =
|
||||
|
@ -1469,6 +1470,34 @@ declare global {
|
|||
|
||||
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
|
||||
* 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 "../util/Util.h"
|
||||
# include "../world/EntityList.h"
|
||||
# include "../world/Litter.h"
|
||||
# include "../world/Sprite.h"
|
||||
# include "Duktape.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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
# include "../world/Balloon.h"
|
||||
# include "../world/Duck.h"
|
||||
# include "../world/EntityList.h"
|
||||
# include "../world/Fountain.h"
|
||||
# include "../world/Litter.h"
|
||||
# include "../world/Map.h"
|
||||
# include "../world/MoneyEffect.h"
|
||||
# include "../world/Particle.h"
|
||||
# include "Duktape.hpp"
|
||||
# include "ScEntity.hpp"
|
||||
# include "ScRide.hpp"
|
||||
|
@ -38,13 +42,7 @@ namespace OpenRCT2::Scripting
|
|||
|
||||
DukValue size_get() const
|
||||
{
|
||||
auto ctx = _context;
|
||||
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);
|
||||
return ToDuk(_context, CoordsXY{ gMapSize, gMapSize });
|
||||
}
|
||||
|
||||
int32_t numRides_get() const
|
||||
|
@ -110,7 +108,7 @@ namespace OpenRCT2::Scripting
|
|||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScEntity>(sprite->sprite_index)));
|
||||
}
|
||||
}
|
||||
if (type == "car")
|
||||
else if (type == "car")
|
||||
{
|
||||
for (auto trainHead : TrainManager::View())
|
||||
{
|
||||
|
@ -169,6 +167,77 @@ namespace OpenRCT2::Scripting
|
|||
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)
|
||||
{
|
||||
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::getEntity, "getEntity");
|
||||
dukglue_register_method(ctx, &ScMap::getAllEntities, "getAllEntities");
|
||||
dukglue_register_method(ctx, &ScMap::createEntity, "createEntity");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -193,6 +263,8 @@ namespace OpenRCT2::Scripting
|
|||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||
case EntityType::Guest:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScGuest>(spriteId));
|
||||
case EntityType::Litter:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScLitter>(spriteId));
|
||||
default:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScEntity>(spriteId));
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ namespace OpenRCT2
|
|||
|
||||
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.
|
||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||
|
|
Loading…
Reference in New Issue