mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-15 11:03:00 +01:00
Scripting: tailor costume assignment to each staff type
In order to transition staff costumes to objects, we must further disentangle staff from regular peeps. This has many advantages, such as making custom entertainers or even handymen costumes. However, this means putting some restrictions on what costumes can be assigned to staff in the mean while. We are aware of plug-ins allowing staff to be decorated like normal peeps, though, e.g. using @Manticore-007's Peep Editor. Splitting staff from peeps will mean breaking such functionality. We can do our very best to reverting 'invalid' staff to their normal outfits instead of them outright disappearing. However, in the mean time, we should disallow peep costumes from being assigned to staff to prevent further disappointment down the line. Once we get to actually adding custom staff costumes, I plan to add a new plug-in API to get available costumes for a particular staff type. This would apply to entertainers, but also other staff types. This should make it easier for plug-in authors to tap into custom costumes in the future.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
0.4.12 (in development)
|
||||
------------------------------------------------------------------------
|
||||
- Feature: [#21714] [Plugin] Costume assignment is now tailored to each staff type.
|
||||
|
||||
0.4.11 (2024-05-05)
|
||||
------------------------------------------------------------------------
|
||||
|
||||
29
distribution/openrct2.d.ts
vendored
29
distribution/openrct2.d.ts
vendored
@@ -3095,6 +3095,24 @@ declare global {
|
||||
readonly item: GuestItemType;
|
||||
}
|
||||
|
||||
type StaffCostume =
|
||||
"none" |
|
||||
"handyman" |
|
||||
"mechanic" |
|
||||
"security1" |
|
||||
"security2" |
|
||||
"panda" |
|
||||
"tiger" |
|
||||
"elephant" |
|
||||
"roman" |
|
||||
"gorilla" |
|
||||
"snowman" |
|
||||
"knight" |
|
||||
"astronaut" |
|
||||
"bandit" |
|
||||
"sheriff" |
|
||||
"pirate";
|
||||
|
||||
/**
|
||||
* Represents a staff member.
|
||||
*/
|
||||
@@ -3105,14 +3123,19 @@ declare global {
|
||||
staffType: StaffType;
|
||||
|
||||
/**
|
||||
* Colour of the staff member. Not applicable for entertainers.
|
||||
* Colour of the staff member. Not applicable to entertainers.
|
||||
*/
|
||||
colour: number;
|
||||
|
||||
/**
|
||||
* The entertainer's costume, only applicable for entertainers.
|
||||
* Array of costumes available to this particular staff member.
|
||||
*/
|
||||
costume: number;
|
||||
readonly availableCostumes: StaffCostume[];
|
||||
|
||||
/**
|
||||
* The staff member's costume.
|
||||
*/
|
||||
costume: StaffCostume | string | number;
|
||||
|
||||
/**
|
||||
* The enabled jobs the staff can do, e.g. sweep litter, water plants, inspect rides etc.
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
{
|
||||
std::sort(_map.begin(), _map.end(), [](const auto& a, const auto& b) { return a.second < b.second; });
|
||||
|
||||
if constexpr (ValueIndexable())
|
||||
if (ValueIndexable() && _map.size() > 1)
|
||||
{
|
||||
_continiousValueIndex = true;
|
||||
T cur{};
|
||||
|
||||
@@ -947,18 +947,6 @@ bool Staff::DoPathFinding()
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Staff::GetCostume() const
|
||||
{
|
||||
return EnumValue(SpriteType) - EnumValue(PeepSpriteType::EntertainerPanda);
|
||||
}
|
||||
|
||||
void Staff::SetCostume(uint8_t value)
|
||||
{
|
||||
auto costume = static_cast<EntertainerCostume>(value);
|
||||
SpriteType = EntertainerCostumeToSprite(costume);
|
||||
UpdateAction();
|
||||
}
|
||||
|
||||
void Staff::SetHireDate(int32_t hireDate)
|
||||
{
|
||||
HireDate = hireDate;
|
||||
|
||||
@@ -51,8 +51,6 @@ public:
|
||||
bool IsLocationInPatrol(const CoordsXY& loc) const;
|
||||
bool IsLocationOnPatrolEdge(const CoordsXY& loc) const;
|
||||
bool DoPathFinding();
|
||||
uint8_t GetCostume() const;
|
||||
void SetCostume(uint8_t value);
|
||||
void SetHireDate(int32_t hireDate);
|
||||
int32_t GetHireDate() const;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace OpenRCT2
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 85;
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 86;
|
||||
|
||||
// Versions marking breaking changes.
|
||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace OpenRCT2::Scripting
|
||||
dukglue_set_base_class<ScPeep, ScStaff>(ctx);
|
||||
dukglue_register_property(ctx, &ScStaff::staffType_get, &ScStaff::staffType_set, "staffType");
|
||||
dukglue_register_property(ctx, &ScStaff::colour_get, &ScStaff::colour_set, "colour");
|
||||
dukglue_register_property(ctx, &ScStaff::availableCostumes_get, nullptr, "availableCostumes");
|
||||
dukglue_register_property(ctx, &ScStaff::costume_get, &ScStaff::costume_set, "costume");
|
||||
dukglue_register_property(ctx, &ScStaff::patrolArea_get, nullptr, "patrolArea");
|
||||
dukglue_register_property(ctx, &ScStaff::orders_get, &ScStaff::orders_set, "orders");
|
||||
@@ -108,24 +109,117 @@ namespace OpenRCT2::Scripting
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t ScStaff::costume_get() const
|
||||
static const DukEnumMap<PeepSpriteType> availableHandymanCostumes({
|
||||
{ "handyman", PeepSpriteType::Handyman },
|
||||
});
|
||||
|
||||
static const DukEnumMap<PeepSpriteType> availableMechanicCostumes({
|
||||
{ "mechanic", PeepSpriteType::Mechanic },
|
||||
});
|
||||
|
||||
static const DukEnumMap<PeepSpriteType> availableSecurityCostumes({
|
||||
{ "security1", PeepSpriteType::Security },
|
||||
{ "security2", PeepSpriteType::SecurityAlt },
|
||||
});
|
||||
|
||||
static const DukEnumMap<PeepSpriteType> availableEntertainerCostumes({
|
||||
{ "none", PeepSpriteType::Normal },
|
||||
{ "panda", PeepSpriteType::EntertainerPanda },
|
||||
{ "tiger", PeepSpriteType::EntertainerTiger },
|
||||
{ "elephant", PeepSpriteType::EntertainerElephant },
|
||||
{ "roman", PeepSpriteType::EntertainerRoman },
|
||||
{ "gorilla", PeepSpriteType::EntertainerGorilla },
|
||||
{ "snowman", PeepSpriteType::EntertainerSnowman },
|
||||
{ "knight", PeepSpriteType::EntertainerKnight },
|
||||
{ "astronaut", PeepSpriteType::EntertainerAstronaut },
|
||||
{ "bandit", PeepSpriteType::EntertainerBandit },
|
||||
{ "sheriff", PeepSpriteType::EntertainerSheriff },
|
||||
{ "pirate", PeepSpriteType::EntertainerPirate },
|
||||
});
|
||||
|
||||
static const DukEnumMap<PeepSpriteType>& costumesByStaffType(StaffType staffType)
|
||||
{
|
||||
auto peep = GetStaff();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Entertainer)
|
||||
switch (staffType)
|
||||
{
|
||||
return peep->GetCostume();
|
||||
case StaffType::Handyman:
|
||||
return availableHandymanCostumes;
|
||||
case StaffType::Mechanic:
|
||||
return availableMechanicCostumes;
|
||||
case StaffType::Security:
|
||||
return availableSecurityCostumes;
|
||||
case StaffType::Entertainer:
|
||||
default:
|
||||
return availableEntertainerCostumes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScStaff::costume_set(uint8_t value)
|
||||
std::vector<std::string> ScStaff::availableCostumes_get() const
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
std::vector<std::string> availableCostumes{};
|
||||
auto peep = GetStaff();
|
||||
if (peep != nullptr)
|
||||
{
|
||||
peep->SetCostume(value);
|
||||
for (auto& costume : costumesByStaffType(peep->AssignedStaffType))
|
||||
{
|
||||
availableCostumes.push_back(std::string(costume.first));
|
||||
}
|
||||
}
|
||||
return availableCostumes;
|
||||
}
|
||||
|
||||
std::string ScStaff::costume_get() const
|
||||
{
|
||||
auto peep = GetStaff();
|
||||
if (peep == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto& availableCostumes = costumesByStaffType(peep->AssignedStaffType);
|
||||
|
||||
auto costume = availableCostumes.find(peep->SpriteType);
|
||||
if (costume != availableCostumes.end())
|
||||
{
|
||||
return std::string(costume->first);
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ScStaff::costume_set(const DukValue& value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
|
||||
auto peep = GetStaff();
|
||||
if (peep == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto& availableCostumes = costumesByStaffType(peep->AssignedStaffType);
|
||||
|
||||
// Split by type passed so as to not break old plugins
|
||||
if (value.type() == DukValue::Type::STRING)
|
||||
{
|
||||
std::string newCostume = value.as_string();
|
||||
auto newSpriteType = availableCostumes.TryGet(newCostume);
|
||||
if (newSpriteType != std::nullopt)
|
||||
{
|
||||
peep->SpriteType = *newSpriteType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (value.type() == DukValue::Type::NUMBER)
|
||||
{
|
||||
auto newSpriteType = PeepSpriteType(value.as_uint() + EnumValue(PeepSpriteType::EntertainerPanda));
|
||||
if (availableCostumes.find(newSpriteType) != availableCostumes.end())
|
||||
{
|
||||
peep->SpriteType = newSpriteType;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw DukException() << "Invalid costume for this staff member";
|
||||
}
|
||||
|
||||
std::shared_ptr<ScPatrolArea> ScStaff::patrolArea_get() const
|
||||
|
||||
@@ -56,8 +56,9 @@ namespace OpenRCT2::Scripting
|
||||
uint8_t colour_get() const;
|
||||
void colour_set(uint8_t value);
|
||||
|
||||
uint8_t costume_get() const;
|
||||
void costume_set(uint8_t value);
|
||||
std::vector<std::string> availableCostumes_get() const;
|
||||
std::string costume_get() const;
|
||||
void costume_set(const DukValue& value);
|
||||
|
||||
std::shared_ptr<ScPatrolArea> patrolArea_get() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user