Staff: let scripts get and set costumes by name

This commit is contained in:
Aaron van Geffen 2024-04-28 22:51:08 +02:00
parent f280fc56e0
commit abf815e51c
3 changed files with 76 additions and 31 deletions

View File

@ -3105,14 +3105,14 @@ 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.
* The staff member's costume.
*/
costume: number;
costume: number | string;
/**
* The enabled jobs the staff can do, e.g. sweep litter, water plants, inspect rides etc.

View File

@ -108,41 +108,70 @@ 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)
{
switch (staffType)
{
case StaffType::Handyman:
return availableHandymanCostumes;
case StaffType::Mechanic:
return availableMechanicCostumes;
case StaffType::Security:
return availableSecurityCostumes;
case StaffType::Entertainer:
default:
return availableEntertainerCostumes;
}
}
std::string ScStaff::costume_get() const
{
auto peep = GetStaff();
if (peep != nullptr && peep->AssignedStaffType == StaffType::Entertainer)
if (peep == nullptr)
{
return peep->GetCostume();
return nullptr;
}
return 0;
}
// TODO: move elsewhere
static std::array entertainerSpriteTypes = {
PeepSpriteType::EntertainerPanda, PeepSpriteType::EntertainerTiger, PeepSpriteType::EntertainerElephant,
PeepSpriteType::EntertainerRoman, PeepSpriteType::EntertainerGorilla, PeepSpriteType::EntertainerSnowman,
PeepSpriteType::EntertainerKnight, PeepSpriteType::EntertainerAstronaut, PeepSpriteType::EntertainerBandit,
PeepSpriteType::EntertainerSheriff, PeepSpriteType::EntertainerPirate,
};
auto& availableCostumes = costumesByStaffType(peep->AssignedStaffType);
static bool isValidCostumeForStaffType(StaffType staffType, PeepSpriteType spriteType)
{
if (staffType == StaffType::Entertainer)
auto costume = availableCostumes.find(peep->SpriteType);
if (costume != availableCostumes.end())
{
return std::find(entertainerSpriteTypes.begin(), entertainerSpriteTypes.end(), spriteType)
!= entertainerSpriteTypes.end();
return std::string(costume->first);
}
else
{
return (staffType == StaffType::Handyman && spriteType == PeepSpriteType::Handyman)
|| (staffType == StaffType::Mechanic && spriteType == PeepSpriteType::Mechanic)
|| (staffType == StaffType::Security && spriteType == PeepSpriteType::Security);
}
return nullptr;
}
// TODO: accept string value
void ScStaff::costume_set(uint8_t value)
void ScStaff::costume_set(const DukValue& value)
{
ThrowIfGameStateNotMutable();
@ -152,9 +181,25 @@ namespace OpenRCT2::Scripting
return;
}
if (isValidCostumeForStaffType(peep->AssignedStaffType, PeepSpriteType(value)))
auto& availableCostumes = costumesByStaffType(peep->AssignedStaffType);
// Split by type passed so as to not break old plugins
if (value.type() == DukValue::Type::STRING)
{
peep->SetCostume(value);
std::string newCostume = value.as_string();
auto newSpriteType = availableCostumes.TryGet(newCostume);
if (newSpriteType != std::nullopt)
{
peep->SpriteType = *newSpriteType;
}
}
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;
}
}
}

View File

@ -56,8 +56,8 @@ 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::string costume_get() const;
void costume_set(const DukValue& value);
std::shared_ptr<ScPatrolArea> patrolArea_get() const;