mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-20 21:43:06 +01:00
[Plugin API] Feat: Expose staff statistics (#22184)
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
- Feature: [#20831] The ride selection window now shows object authors if debugging tools are active.
|
||||
- Feature: [#20832] The ride music tab now shows a track listing for the current music style.
|
||||
- Feature: [#22172] [Plugin] Expose ride satisfaction ratings to the plugin API.
|
||||
- Feature: [#22184] [Plugin] Expose staff statistics to the plugin API.
|
||||
- Feature: [#22213] [Plugin] Allow plugins to focus on textboxes in custom windows.
|
||||
- Feature: [#22301] Loading save games or scenarios now indicates loading progress.
|
||||
- Feature: [OpenMusic#54] Added Progressive ride music style (feat. Approaching Nirvana).
|
||||
|
||||
64
distribution/openrct2.d.ts
vendored
64
distribution/openrct2.d.ts
vendored
@@ -3285,7 +3285,7 @@ declare global {
|
||||
/**
|
||||
* Represents a staff member.
|
||||
*/
|
||||
interface Staff extends Peep {
|
||||
interface BaseStaff extends Peep {
|
||||
/**
|
||||
* The type of staff member, e.g. handyman, mechanic.
|
||||
*/
|
||||
@@ -3344,6 +3344,68 @@ declare global {
|
||||
|
||||
type StaffType = "handyman" | "mechanic" | "security" | "entertainer";
|
||||
|
||||
type Staff = Handyman | Mechanic | Security | Entertainer;
|
||||
|
||||
/**
|
||||
* Represents a handyman.
|
||||
*/
|
||||
interface Handyman extends BaseStaff {
|
||||
staffType: "handyman";
|
||||
|
||||
/**
|
||||
* The number of lawns mown by the handyman.
|
||||
*/
|
||||
readonly lawnsMown: number;
|
||||
|
||||
/**
|
||||
* The number of gardens watered by the handyman.
|
||||
*/
|
||||
readonly gardensWatered: number;
|
||||
|
||||
/**
|
||||
* The number of litter swept by the handyman.
|
||||
*/
|
||||
readonly litterSwept: number;
|
||||
|
||||
/**
|
||||
* The number of bins emptied by the handyman.
|
||||
*/
|
||||
readonly binsEmptied: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a mechanic.
|
||||
*/
|
||||
interface Mechanic extends BaseStaff {
|
||||
staffType: "mechanic";
|
||||
|
||||
/**
|
||||
* The number of rides fixed by the mechanic.
|
||||
*/
|
||||
readonly ridesFixed: number;
|
||||
|
||||
/**
|
||||
* The number of inspections performed by the mechanic.
|
||||
*/
|
||||
readonly ridesInspected: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a security guard.
|
||||
*/
|
||||
interface Security extends BaseStaff {
|
||||
staffType: "security";
|
||||
|
||||
/**
|
||||
* The number of vandals stopped by the security guard.
|
||||
*/
|
||||
readonly vandalsStopped: number;
|
||||
}
|
||||
|
||||
interface Entertainer extends BaseStaff {
|
||||
staffType: "entertainer";
|
||||
}
|
||||
|
||||
interface PatrolArea {
|
||||
/**
|
||||
* Gets or sets the map coodinates for all individual tiles in the staff member's patrol area.
|
||||
|
||||
@@ -450,6 +450,9 @@ void ScriptEngine::Initialise()
|
||||
ScScenarioObjective::Register(ctx);
|
||||
ScPatrolArea::Register(ctx);
|
||||
ScStaff::Register(ctx);
|
||||
ScHandyman::Register(ctx);
|
||||
ScMechanic::Register(ctx);
|
||||
ScSecurity::Register(ctx);
|
||||
ScPlugin::Register(ctx);
|
||||
|
||||
dukglue_register_global(ctx, std::make_shared<ScCheats>(), "cheats");
|
||||
|
||||
@@ -46,7 +46,7 @@ namespace OpenRCT2
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 95;
|
||||
static constexpr int32_t OPENRCT2_PLUGIN_API_VERSION = 96;
|
||||
|
||||
// Versions marking breaking changes.
|
||||
static constexpr int32_t API_VERSION_33_PEEP_DEPRECATION = 33;
|
||||
|
||||
@@ -438,6 +438,170 @@ namespace OpenRCT2::Scripting
|
||||
return static_cast<uint8_t>(animationGroup.frame_offsets.size());
|
||||
}
|
||||
|
||||
ScHandyman::ScHandyman(EntityId Id)
|
||||
: ScStaff(Id)
|
||||
{
|
||||
}
|
||||
|
||||
void ScHandyman::Register(duk_context* ctx)
|
||||
{
|
||||
dukglue_set_base_class<ScStaff, ScHandyman>(ctx);
|
||||
dukglue_register_property(ctx, &ScHandyman::lawnsMown_get, nullptr, "lawnsMown");
|
||||
dukglue_register_property(ctx, &ScHandyman::gardensWatered_get, nullptr, "gardensWatered");
|
||||
dukglue_register_property(ctx, &ScHandyman::litterSwept_get, nullptr, "litterSwept");
|
||||
dukglue_register_property(ctx, &ScHandyman::binsEmptied_get, nullptr, "binsEmptied");
|
||||
}
|
||||
|
||||
Staff* ScHandyman::GetHandyman() const
|
||||
{
|
||||
return ::GetEntity<Staff>(_id);
|
||||
}
|
||||
|
||||
DukValue ScHandyman::lawnsMown_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetHandyman();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Handyman)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffLawnsMown);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
DukValue ScHandyman::gardensWatered_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetHandyman();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Handyman)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffGardensWatered);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
DukValue ScHandyman::litterSwept_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetHandyman();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Handyman)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffLitterSwept);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
DukValue ScHandyman::binsEmptied_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetHandyman();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Handyman)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffBinsEmptied);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
ScMechanic::ScMechanic(EntityId Id)
|
||||
: ScStaff(Id)
|
||||
{
|
||||
}
|
||||
|
||||
void ScMechanic::Register(duk_context* ctx)
|
||||
{
|
||||
dukglue_set_base_class<ScStaff, ScMechanic>(ctx);
|
||||
dukglue_register_property(ctx, &ScMechanic::ridesFixed_get, nullptr, "ridesFixed");
|
||||
dukglue_register_property(ctx, &ScMechanic::ridesInspected_get, nullptr, "ridesInspected");
|
||||
}
|
||||
|
||||
Staff* ScMechanic::GetMechanic() const
|
||||
{
|
||||
return ::GetEntity<Staff>(_id);
|
||||
}
|
||||
|
||||
DukValue ScMechanic::ridesFixed_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetMechanic();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Mechanic)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffRidesFixed);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
DukValue ScMechanic::ridesInspected_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetMechanic();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Mechanic)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffRidesInspected);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
ScSecurity::ScSecurity(EntityId Id)
|
||||
: ScStaff(Id)
|
||||
{
|
||||
}
|
||||
|
||||
void ScSecurity::Register(duk_context* ctx)
|
||||
{
|
||||
dukglue_set_base_class<ScStaff, ScSecurity>(ctx);
|
||||
dukglue_register_property(ctx, &ScSecurity::vandalsStopped_get, nullptr, "vandalsStopped");
|
||||
}
|
||||
|
||||
Staff* ScSecurity::GetSecurity() const
|
||||
{
|
||||
return ::GetEntity<Staff>(_id);
|
||||
}
|
||||
|
||||
DukValue ScSecurity::vandalsStopped_get() const
|
||||
{
|
||||
auto& scriptEngine = GetContext()->GetScriptEngine();
|
||||
auto* ctx = scriptEngine.GetContext();
|
||||
auto peep = GetSecurity();
|
||||
if (peep != nullptr && peep->AssignedStaffType == StaffType::Security)
|
||||
{
|
||||
duk_push_uint(ctx, peep->StaffVandalsStopped);
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_push_null(ctx);
|
||||
}
|
||||
return DukValue::take_from_stack(ctx);
|
||||
}
|
||||
|
||||
ScPatrolArea::ScPatrolArea(EntityId id)
|
||||
: _staffId(id)
|
||||
{
|
||||
|
||||
@@ -78,6 +78,53 @@ namespace OpenRCT2::Scripting
|
||||
uint8_t animationLength_get() const;
|
||||
};
|
||||
|
||||
class ScHandyman : public ScStaff
|
||||
{
|
||||
public:
|
||||
ScHandyman(EntityId Id);
|
||||
|
||||
static void Register(duk_context* ctx);
|
||||
|
||||
private:
|
||||
Staff* GetHandyman() const;
|
||||
|
||||
DukValue lawnsMown_get() const;
|
||||
|
||||
DukValue gardensWatered_get() const;
|
||||
|
||||
DukValue litterSwept_get() const;
|
||||
|
||||
DukValue binsEmptied_get() const;
|
||||
};
|
||||
|
||||
class ScMechanic : public ScStaff
|
||||
{
|
||||
public:
|
||||
ScMechanic(EntityId Id);
|
||||
|
||||
static void Register(duk_context* ctx);
|
||||
|
||||
private:
|
||||
Staff* GetMechanic() const;
|
||||
|
||||
DukValue ridesFixed_get() const;
|
||||
|
||||
DukValue ridesInspected_get() const;
|
||||
};
|
||||
|
||||
class ScSecurity : public ScStaff
|
||||
{
|
||||
public:
|
||||
ScSecurity(EntityId Id);
|
||||
|
||||
static void Register(duk_context* ctx);
|
||||
|
||||
private:
|
||||
Staff* GetSecurity() const;
|
||||
|
||||
DukValue vandalsStopped_get() const;
|
||||
};
|
||||
|
||||
} // namespace OpenRCT2::Scripting
|
||||
|
||||
#endif
|
||||
|
||||
@@ -158,7 +158,29 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
for (auto sprite : EntityList<Staff>())
|
||||
{
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
auto staff = GetEntity<Staff>(sprite->Id);
|
||||
if (staff != nullptr)
|
||||
{
|
||||
switch (staff->AssignedStaffType)
|
||||
{
|
||||
case StaffType::Handyman:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScHandyman>(sprite->Id)));
|
||||
break;
|
||||
case StaffType::Mechanic:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScMechanic>(sprite->Id)));
|
||||
break;
|
||||
case StaffType::Security:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScSecurity>(sprite->Id)));
|
||||
break;
|
||||
default:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == "crashed_vehicle_particle")
|
||||
@@ -225,7 +247,29 @@ namespace OpenRCT2::Scripting
|
||||
{
|
||||
for (auto sprite : EntityTileList<Staff>(pos))
|
||||
{
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
auto staff = GetEntity<Staff>(sprite->Id);
|
||||
if (staff != nullptr)
|
||||
{
|
||||
switch (staff->AssignedStaffType)
|
||||
{
|
||||
case StaffType::Handyman:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScHandyman>(sprite->Id)));
|
||||
break;
|
||||
case StaffType::Mechanic:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScMechanic>(sprite->Id)));
|
||||
break;
|
||||
case StaffType::Security:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScSecurity>(sprite->Id)));
|
||||
break;
|
||||
default:
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.push_back(GetObjectAsDukValue(_context, std::make_shared<ScStaff>(sprite->Id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == "crashed_vehicle_particle")
|
||||
@@ -357,7 +401,27 @@ namespace OpenRCT2::Scripting
|
||||
case EntityType::Vehicle:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScVehicle>(spriteId));
|
||||
case EntityType::Staff:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||
{
|
||||
auto staff = GetEntity<Staff>(spriteId);
|
||||
if (staff != nullptr)
|
||||
{
|
||||
switch (staff->AssignedStaffType)
|
||||
{
|
||||
case StaffType::Handyman:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScHandyman>(spriteId));
|
||||
case StaffType::Mechanic:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScMechanic>(spriteId));
|
||||
case StaffType::Security:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScSecurity>(spriteId));
|
||||
default:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScStaff>(spriteId));
|
||||
}
|
||||
}
|
||||
case EntityType::Guest:
|
||||
return GetObjectAsDukValue(_context, std::make_shared<ScGuest>(spriteId));
|
||||
case EntityType::Litter:
|
||||
|
||||
Reference in New Issue
Block a user