mirror of https://github.com/OpenRCT2/OpenRCT2.git
Merge pull request #16731 from IntelOrca/plugin/patrol-areas
Implement #13620: [Plugin] Add support for patrol areas to Staff
This commit is contained in:
commit
9ef7a4c13b
|
@ -15,6 +15,7 @@
|
|||
- Feature: [#16097] The Looping Roller Coaster can now draw all elements from the LIM Launched Roller Coaster.
|
||||
- Feature: [#16132, #16389] The Corkscrew, Twister and Vertical Drop Roller Coasters can now draw inline twists.
|
||||
- Feature: [#16144] [Plugin] Add ImageManager to API.
|
||||
- Feature: [#16731] [Plugin] New API for fetching and manipulating a staff member's patrol area.
|
||||
- Improved: [#3517] Cheats are now saved with the park.
|
||||
- Improved: [#10150] Ride stations are now properly checked if they’re sheltered.
|
||||
- Improved: [#10664, #16072] Visibility status can be modified directly in the Tile Inspector's list.
|
||||
|
|
|
@ -1511,10 +1511,47 @@ declare global {
|
|||
* The enabled jobs the staff can do, e.g. sweep litter, water plants, inspect rides etc.
|
||||
*/
|
||||
orders: number;
|
||||
|
||||
/**
|
||||
* Gets the patrol area for the staff member.
|
||||
*/
|
||||
readonly patrolArea: PatrolArea;
|
||||
}
|
||||
|
||||
type StaffType = "handyman" | "mechanic" | "security" | "entertainer";
|
||||
|
||||
interface PatrolArea {
|
||||
/**
|
||||
* Gets or sets the map coodinates for all individual tiles in the staff member's patrol area.
|
||||
*
|
||||
* Note: fetching all the staff member's patrol area tiles can degrade performance.
|
||||
*/
|
||||
tiles: CoordsXY[];
|
||||
|
||||
/**
|
||||
* Clears all tiles from the staff member's patrol area.
|
||||
*/
|
||||
clear(): void;
|
||||
|
||||
/**
|
||||
* Adds the given array of coordinates or a map range to the staff member's patrol area.
|
||||
* @param coords An array of map coordinates, or a map range.
|
||||
*/
|
||||
add(coords: CoordsXY[] | MapRange): void;
|
||||
|
||||
/**
|
||||
* Removes the given array of coordinates or a map range from the staff member's patrol area.
|
||||
* @param coords An array of map coordinates, or a map range.
|
||||
*/
|
||||
remove(coords: CoordsXY[] | MapRange): void;
|
||||
|
||||
/**
|
||||
* Checks whether a single coordinate is within the staff member's patrol area.
|
||||
* @param coords An map coordinate.
|
||||
*/
|
||||
contains(coord: CoordsXY): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents litter entity.
|
||||
*/
|
||||
|
|
|
@ -65,7 +65,6 @@ public:
|
|||
void SetPatrolArea(const CoordsXY& coords, bool value);
|
||||
void SetPatrolArea(const MapRange& range, bool value);
|
||||
bool HasPatrolArea() const;
|
||||
std::vector<TileCoordsXY> GetPatrolArea();
|
||||
void SetPatrolArea(const std::vector<TileCoordsXY>& area);
|
||||
|
||||
private:
|
||||
|
|
|
@ -334,6 +334,14 @@ namespace OpenRCT2::Scripting
|
|||
return result;
|
||||
}
|
||||
|
||||
template<> MapRange inline FromDuk(const DukValue& d)
|
||||
{
|
||||
MapRange range;
|
||||
range.Point1 = FromDuk<CoordsXY>(d["leftTop"]);
|
||||
range.Point2 = FromDuk<CoordsXY>(d["rightBottom"]);
|
||||
return range.Normalise();
|
||||
}
|
||||
|
||||
template<> DukValue inline ToDuk(duk_context* ctx, const CoordsXY& coords)
|
||||
{
|
||||
DukObject dukCoords(ctx);
|
||||
|
|
|
@ -421,6 +421,7 @@ void ScriptEngine::Initialise()
|
|||
# endif
|
||||
ScScenario::Register(ctx);
|
||||
ScScenarioObjective::Register(ctx);
|
||||
ScPatrolArea::Register(ctx);
|
||||
ScStaff::Register(ctx);
|
||||
|
||||
dukglue_register_global(ctx, std::make_shared<ScCheats>(), "cheats");
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
# include "ScStaff.hpp"
|
||||
|
||||
# include "../../../entity/PatrolArea.h"
|
||||
# include "../../../entity/Staff.h"
|
||||
|
||||
namespace OpenRCT2::Scripting
|
||||
|
@ -26,6 +27,7 @@ namespace OpenRCT2::Scripting
|
|||
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::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");
|
||||
}
|
||||
|
||||
|
@ -122,6 +124,11 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<ScPatrolArea> ScStaff::patrolArea_get() const
|
||||
{
|
||||
return std::make_shared<ScPatrolArea>(_id);
|
||||
}
|
||||
|
||||
uint8_t ScStaff::orders_get() const
|
||||
{
|
||||
auto peep = GetStaff();
|
||||
|
@ -138,6 +145,131 @@ namespace OpenRCT2::Scripting
|
|||
}
|
||||
}
|
||||
|
||||
ScPatrolArea::ScPatrolArea(EntityId id)
|
||||
: _staffId(id)
|
||||
{
|
||||
}
|
||||
|
||||
void ScPatrolArea::Register(duk_context* ctx)
|
||||
{
|
||||
dukglue_register_property(ctx, &ScPatrolArea::tiles_get, &ScPatrolArea::tiles_set, "tiles");
|
||||
dukglue_register_method(ctx, &ScPatrolArea::clear, "clear");
|
||||
dukglue_register_method(ctx, &ScPatrolArea::add, "add");
|
||||
dukglue_register_method(ctx, &ScPatrolArea::remove, "remove");
|
||||
dukglue_register_method(ctx, &ScPatrolArea::contains, "contains");
|
||||
}
|
||||
|
||||
Staff* ScPatrolArea::GetStaff() const
|
||||
{
|
||||
return GetEntity<Staff>(_staffId);
|
||||
}
|
||||
|
||||
void ScPatrolArea::ModifyArea(const DukValue& coordsOrRange, bool value) const
|
||||
{
|
||||
auto staff = GetStaff();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
if (coordsOrRange.is_array())
|
||||
{
|
||||
auto dukCoords = coordsOrRange.as_array();
|
||||
for (const auto& dukCoord : dukCoords)
|
||||
{
|
||||
auto coord = FromDuk<CoordsXY>(dukCoord);
|
||||
staff->SetPatrolArea(coord, value);
|
||||
map_invalidate_tile_full(coord);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto mapRange = FromDuk<MapRange>(coordsOrRange);
|
||||
for (int32_t y = mapRange.GetTop(); y <= mapRange.GetBottom(); y += COORDS_XY_STEP)
|
||||
{
|
||||
for (int32_t x = mapRange.GetLeft(); x <= mapRange.GetRight(); x += COORDS_XY_STEP)
|
||||
{
|
||||
CoordsXY coord(x, y);
|
||||
staff->SetPatrolArea(coord, value);
|
||||
map_invalidate_tile_full(coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
}
|
||||
}
|
||||
|
||||
DukValue ScPatrolArea::tiles_get() const
|
||||
{
|
||||
auto ctx = GetContext()->GetScriptEngine().GetContext();
|
||||
|
||||
duk_push_array(ctx);
|
||||
|
||||
auto staff = GetStaff();
|
||||
if (staff != nullptr && staff->PatrolInfo != nullptr)
|
||||
{
|
||||
auto tiles = staff->PatrolInfo->ToVector();
|
||||
|
||||
duk_uarridx_t index = 0;
|
||||
for (const auto& tile : tiles)
|
||||
{
|
||||
auto dukCoord = ToDuk(ctx, tile.ToCoordsXY());
|
||||
dukCoord.push();
|
||||
duk_put_prop_index(ctx, -2, index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return DukValue::take_from_stack(ctx, -1);
|
||||
}
|
||||
|
||||
void ScPatrolArea::tiles_set(const DukValue& value)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
|
||||
auto staff = GetStaff();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
staff->ClearPatrolArea();
|
||||
if (value.is_array())
|
||||
{
|
||||
ModifyArea(value, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScPatrolArea::clear()
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
|
||||
auto staff = GetStaff();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
staff->ClearPatrolArea();
|
||||
UpdateConsolidatedPatrolAreas();
|
||||
}
|
||||
}
|
||||
|
||||
void ScPatrolArea::add(const DukValue& coordsOrRange)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
ModifyArea(coordsOrRange, true);
|
||||
}
|
||||
|
||||
void ScPatrolArea::remove(const DukValue& coordsOrRange)
|
||||
{
|
||||
ThrowIfGameStateNotMutable();
|
||||
ModifyArea(coordsOrRange, false);
|
||||
}
|
||||
|
||||
bool ScPatrolArea::contains(const DukValue& coord) const
|
||||
{
|
||||
auto staff = GetStaff();
|
||||
if (staff != nullptr)
|
||||
{
|
||||
auto pos = FromDuk<CoordsXY>(coord);
|
||||
return staff->IsLocationInPatrol(pos);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace OpenRCT2::Scripting
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,29 @@
|
|||
|
||||
namespace OpenRCT2::Scripting
|
||||
{
|
||||
class ScPatrolArea
|
||||
{
|
||||
private:
|
||||
EntityId _staffId;
|
||||
|
||||
public:
|
||||
ScPatrolArea(EntityId id);
|
||||
|
||||
static void Register(duk_context* ctx);
|
||||
|
||||
private:
|
||||
Staff* GetStaff() const;
|
||||
void ModifyArea(const DukValue& coordsOrRange, bool value) const;
|
||||
|
||||
DukValue tiles_get() const;
|
||||
void tiles_set(const DukValue& value);
|
||||
|
||||
void clear();
|
||||
void add(const DukValue& coordsOrRange);
|
||||
void remove(const DukValue& coordsOrRange);
|
||||
bool contains(const DukValue& coord) const;
|
||||
};
|
||||
|
||||
class ScStaff : public ScPeep
|
||||
{
|
||||
public:
|
||||
|
@ -34,6 +57,8 @@ namespace OpenRCT2::Scripting
|
|||
uint8_t costume_get() const;
|
||||
void costume_set(uint8_t value);
|
||||
|
||||
std::shared_ptr<ScPatrolArea> patrolArea_get() const;
|
||||
|
||||
uint8_t orders_get() const;
|
||||
void orders_set(uint8_t value);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue