Implement StaffHireNewAction game action.

This commit is contained in:
Matt 2019-03-11 13:44:34 +01:00
parent 25eb403c78
commit f96a1a1b5f
8 changed files with 385 additions and 335 deletions

View File

@ -206,13 +206,17 @@ static void window_staff_list_mouseup(rct_window* w, rct_widgetindex widgetIndex
break;
case WIDX_STAFF_LIST_HIRE_BUTTON:
{
int32_t staffType = _windowStaffListSelectedTab;
STAFF_TYPE staffType = static_cast<STAFF_TYPE>(_windowStaffListSelectedTab);
if (staffType == STAFF_TYPE_ENTERTAINER)
{
uint8_t costume = window_staff_list_get_random_entertainer_costume();
staffType += costume;
ENTERTAINER_COSTUME costume = static_cast<ENTERTAINER_COSTUME>(
window_staff_list_get_random_entertainer_costume());
staff_hire_new_member(staffType, costume);
}
else
{
staff_hire_new_member(staffType, ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT);
}
hire_new_staff_member(staffType);
break;
}
case WIDX_STAFF_LIST_SHOW_PATROL_AREA_BUTTON:

View File

@ -94,7 +94,7 @@ static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = {
nullptr,
game_command_callback_place_banner,
nullptr,
game_command_callback_hire_new_staff_member,
nullptr,
game_command_callback_pickup_guest,
game_command_callback_pickup_staff
};
@ -1290,7 +1290,7 @@ GAME_COMMAND_POINTER* new_game_command_table[GAME_COMMAND_COUNT] = {
game_command_raise_water,
game_command_lower_water,
game_command_set_brakes_speed,
game_command_hire_new_staff_member,
nullptr,
game_command_set_staff_patrol,
game_command_fire_staff_member,
nullptr,

View File

@ -48,7 +48,7 @@ enum GAME_COMMAND
GAME_COMMAND_RAISE_WATER,
GAME_COMMAND_LOWER_WATER,
GAME_COMMAND_SET_BRAKES_SPEED,
GAME_COMMAND_HIRE_NEW_STAFF_MEMBER,
GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, // GA
GAME_COMMAND_SET_STAFF_PATROL,
GAME_COMMAND_FIRE_STAFF_MEMBER,
GAME_COMMAND_SET_STAFF_ORDERS, // GA

View File

@ -43,6 +43,7 @@
#include "SignSetStyleAction.hpp"
#include "SmallSceneryPlaceAction.hpp"
#include "SmallSceneryRemoveAction.hpp"
#include "StaffHireNewAction.hpp"
#include "StaffSetColourAction.hpp"
#include "StaffSetCostumeAction.hpp"
#include "StaffSetNameAction.hpp"
@ -99,5 +100,6 @@ namespace GameActions
Register<PauseToggleAction>();
Register<LoadOrQuitAction>();
Register<WaterSetHeightAction>();
Register<StaffHireNewAction>();
}
} // namespace GameActions

View File

@ -0,0 +1,345 @@
/*****************************************************************************
* Copyright (c) 2014-2019 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
#pragma once
#include "../Cheats.h"
#include "../Context.h"
#include "../core/MemoryStream.h"
#include "../drawing/Drawing.h"
#include "../interface/Window.h"
#include "../localisation/Localisation.h"
#include "../localisation/StringIds.h"
#include "../management/Finance.h"
#include "../ride/Ride.h"
#include "../scenario/Scenario.h"
#include "../ui/UiContext.h"
#include "../ui/WindowManager.h"
#include "../world/Entrance.h"
#include "../world/Park.h"
#include "../world/Sprite.h"
#include "GameAction.h"
static constexpr const rct_string_id staffNames[] = {
STR_HANDYMAN_X,
STR_MECHANIC_X,
STR_SECURITY_GUARD_X,
STR_ENTERTAINER_X,
};
/* rct2: 0x009929FC */
static constexpr const PeepSpriteType spriteTypes[] = {
PEEP_SPRITE_TYPE_HANDYMAN,
PEEP_SPRITE_TYPE_MECHANIC,
PEEP_SPRITE_TYPE_SECURITY,
PEEP_SPRITE_TYPE_ENTERTAINER_PANDA,
};
class StaffHireNewActionResult final : public GameActionResult
{
public:
StaffHireNewActionResult()
: GameActionResult(GA_ERROR::OK, 0)
{
}
StaffHireNewActionResult(GA_ERROR error, rct_string_id message)
: GameActionResult(error, STR_CANT_HIRE_NEW_STAFF, message)
{
}
uint32_t peepSriteIndex = SPRITE_INDEX_NULL;
};
DEFINE_GAME_ACTION(StaffHireNewAction, GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, StaffHireNewActionResult)
{
private:
bool _autoPosition = false;
uint8_t _staffType = STAFF_TYPE::STAFF_TYPE_COUNT;
uint8_t _entertainerType = ENTERTAINER_COSTUME::ENTERTAINER_COSTUME_COUNT;
public:
StaffHireNewAction() = default;
StaffHireNewAction(bool autoPosition, STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType)
: _autoPosition(autoPosition)
, _staffType(staffType)
, _entertainerType(entertainerType)
{
}
uint16_t GetActionFlags() const override
{
return GameAction::GetActionFlags();
}
void Serialise(DataSerialiser & stream) override
{
GameAction::Serialise(stream);
stream << DS_TAG(_autoPosition) << DS_TAG(_staffType) << DS_TAG(_entertainerType);
}
GameActionResult::Ptr Query() const override
{
return QueryExecute(false);
}
GameActionResult::Ptr Execute() const override
{
return QueryExecute(true);
}
private:
GameActionResult::Ptr QueryExecute(bool execute) const
{
auto res = std::make_unique<StaffHireNewActionResult>();
res->ExpenditureType = RCT_EXPENDITURE_TYPE_WAGES;
if (_staffType >= STAFF_TYPE_COUNT)
{
// Invalid staff type.
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS);
}
if (gSpriteListCount[SPRITE_LIST_NULL] < 400)
{
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME);
}
if (_staffType == STAFF_TYPE_ENTERTAINER)
{
if (_entertainerType >= ENTERTAINER_COSTUME_COUNT)
{
// Invalid entertainer costume
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS);
}
uint32_t availableCostumes = staff_get_available_entertainer_costumes();
if (!(availableCostumes & (1 << _entertainerType)))
{
// Entertainer costume unavailable
return MakeResult(GA_ERROR::INVALID_PARAMETERS, STR_INVALID_SELECTION_OF_OBJECTS);
}
}
// Look for a free slot in the staff modes.
int32_t staffIndex;
for (staffIndex = 0; staffIndex < STAFF_MAX_COUNT; ++staffIndex)
{
if (!(gStaffModes[staffIndex] & 1))
break;
}
if (staffIndex == STAFF_MAX_COUNT)
{
// Too many staff members exist already.
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_STAFF_IN_GAME);
}
Peep* newPeep = &(create_sprite(GetFlags())->peep);
if (newPeep == nullptr)
{
// Too many staff members exist already.
return MakeResult(GA_ERROR::NO_FREE_ELEMENTS, STR_TOO_MANY_PEOPLE_IN_GAME);
}
if (execute == false)
{
// In query we just want to see if we can obtain a sprite slot.
sprite_remove((rct_sprite*)newPeep);
}
else
{
move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP * 2);
newPeep->sprite_identifier = 1;
newPeep->window_invalidate_flags = 0;
newPeep->action = PEEP_ACTION_NONE_2;
newPeep->special_sprite = 0;
newPeep->action_sprite_image_offset = 0;
newPeep->no_action_frame_num = 0;
newPeep->action_sprite_type = PEEP_ACTION_SPRITE_TYPE_NONE;
newPeep->path_check_optimisation = 0;
newPeep->type = PEEP_TYPE_STAFF;
newPeep->outside_of_park = 0;
newPeep->peep_flags = 0;
newPeep->paid_to_enter = 0;
newPeep->paid_on_rides = 0;
newPeep->paid_on_food = 0;
newPeep->paid_on_souvenirs = 0;
if (_staffType == STAFF_TYPE_HANDYMAN)
newPeep->staff_orders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS;
else if (_staffType == STAFF_TYPE_MECHANIC)
newPeep->staff_orders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES;
else
newPeep->staff_orders = 0;
uint16_t idSearchSpriteIndex;
Peep* idSearchPeep;
// We search for the first available id for a given staff type
uint32_t newStaffId = 0;
for (;;)
{
bool found = false;
++newStaffId;
FOR_ALL_STAFF (idSearchSpriteIndex, idSearchPeep)
{
if (idSearchPeep->staff_type != _staffType)
continue;
if (idSearchPeep->id == newStaffId)
{
found = true;
break;
}
}
if (!found)
break;
}
newPeep->id = newStaffId;
newPeep->staff_type = _staffType;
PeepSpriteType spriteType = spriteTypes[_staffType];
if (_staffType == STAFF_TYPE_ENTERTAINER)
{
spriteType = static_cast<PeepSpriteType>(PEEP_SPRITE_TYPE_ENTERTAINER_PANDA + _entertainerType);
}
newPeep->name_string_idx = staffNames[_staffType];
newPeep->sprite_type = spriteType;
const rct_sprite_bounds* spriteBounds = g_peep_animation_entries[spriteType].sprite_bounds;
newPeep->sprite_width = spriteBounds->sprite_width;
newPeep->sprite_height_negative = spriteBounds->sprite_height_negative;
newPeep->sprite_height_positive = spriteBounds->sprite_height_positive;
if (_autoPosition == true)
{
AutoPositionNewStaff(newPeep);
}
else
{
// NOTE: This state is required for the window to act.
newPeep->state = PEEP_STATE_PICKED;
sprite_move(newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep);
invalidate_sprite_2((rct_sprite*)newPeep);
}
// Staff uses this
newPeep->time_in_park = gDateMonthsElapsed;
newPeep->pathfind_goal.x = 0xFF;
newPeep->pathfind_goal.y = 0xFF;
newPeep->pathfind_goal.z = 0xFF;
newPeep->pathfind_goal.direction = 0xFF;
uint8_t colour = staff_get_colour(_staffType);
newPeep->tshirt_colour = colour;
newPeep->trousers_colour = colour;
// Staff energy determines their walking speed
newPeep->energy = 0x60;
newPeep->energy_target = 0x60;
newPeep->staff_mowing_timeout = 0;
peep_update_name_sort(newPeep);
newPeep->staff_id = newStaffId;
gStaffModes[staffIndex] = STAFF_MODE_WALK;
for (int32_t newStaffIndex = 0; newStaffIndex < STAFF_PATROL_AREA_SIZE; newStaffIndex++)
{
gStaffPatrolAreas[newStaffIndex * STAFF_PATROL_AREA_SIZE + newStaffId] = 0;
}
res->peepSriteIndex = newPeep->sprite_index;
}
return res;
}
void AutoPositionNewStaff(Peep * newPeep) const
{
// Find a location to place new staff member
newPeep->state = PEEP_STATE_FALLING;
int16_t x, y, z;
uint32_t count = 0;
uint16_t sprite_index;
Peep* guest = nullptr;
TileElement* guest_tile = nullptr;
// Count number of walking guests
FOR_ALL_GUESTS (sprite_index, guest)
{
if (guest->state == PEEP_STATE_WALKING)
{
// Check the walking guest's tile. Only count them if they're on a path tile.
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
if (guest_tile != nullptr)
++count;
}
}
if (count > 0)
{
// Place staff at a random guest
uint32_t rand = scenario_rand_max(count);
FOR_ALL_GUESTS (sprite_index, guest)
{
if (guest->state == PEEP_STATE_WALKING)
{
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
if (guest_tile != nullptr)
{
if (rand == 0)
break;
--rand;
}
}
}
x = guest->x;
y = guest->y;
z = guest->z;
}
else
{
// No walking guests; pick random park entrance
if (gParkEntrances.size() > 0)
{
auto rand = scenario_rand_max((uint32_t)gParkEntrances.size());
const auto& entrance = gParkEntrances[rand];
auto dir = entrance.direction;
x = entrance.x;
y = entrance.y;
z = entrance.z;
x += 16 + ((dir & 1) == 0 ? ((dir & 2) ? 32 : -32) : 0);
y += 16 + ((dir & 1) == 1 ? ((dir & 2) ? -32 : 32) : 0);
}
else
{
// User must pick a location
newPeep->state = PEEP_STATE_PICKED;
x = newPeep->x;
y = newPeep->y;
z = newPeep->z;
}
}
sprite_move(x, y, z + 16, (rct_sprite*)newPeep);
invalidate_sprite_2((rct_sprite*)newPeep);
}
};

View File

@ -12,6 +12,7 @@
#include "../Context.h"
#include "../Game.h"
#include "../Input.h"
#include "../actions/StaffHireNewAction.hpp"
#include "../actions/StaffSetOrdersAction.hpp"
#include "../audio/audio.h"
#include "../config/Config.h"
@ -81,286 +82,6 @@ void staff_reset_modes()
staff_update_greyed_patrol_areas();
}
static inline void staff_autoposition_new_staff_member(Peep* newPeep)
{
// Find a location to place new staff member
newPeep->state = PEEP_STATE_FALLING;
int16_t x, y, z;
uint32_t count = 0;
uint16_t sprite_index;
Peep* guest = nullptr;
TileElement* guest_tile = nullptr;
// Count number of walking guests
FOR_ALL_GUESTS (sprite_index, guest)
{
if (guest->state == PEEP_STATE_WALKING)
{
// Check the walking guest's tile. Only count them if they're on a path tile.
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
if (guest_tile != nullptr)
++count;
}
}
if (count > 0)
{
// Place staff at a random guest
uint32_t rand = scenario_rand_max(count);
FOR_ALL_GUESTS (sprite_index, guest)
{
if (guest->state == PEEP_STATE_WALKING)
{
guest_tile = map_get_path_element_at(guest->next_x / 32, guest->next_y / 32, guest->next_z);
if (guest_tile != nullptr)
{
if (rand == 0)
break;
--rand;
}
}
}
x = guest->x;
y = guest->y;
z = guest->z;
}
else
{
// No walking guests; pick random park entrance
if (gParkEntrances.size() > 0)
{
auto rand = scenario_rand_max((uint32_t)gParkEntrances.size());
const auto& entrance = gParkEntrances[rand];
auto dir = entrance.direction;
x = entrance.x;
y = entrance.y;
z = entrance.z;
x += 16 + ((dir & 1) == 0 ? ((dir & 2) ? 32 : -32) : 0);
y += 16 + ((dir & 1) == 1 ? ((dir & 2) ? -32 : 32) : 0);
}
else
{
// User must pick a location
newPeep->state = PEEP_STATE_PICKED;
x = newPeep->x;
y = newPeep->y;
z = newPeep->z;
}
}
sprite_move(x, y, z + 16, (rct_sprite*)newPeep);
invalidate_sprite_2((rct_sprite*)newPeep);
}
static money32 staff_hire_new_staff_member(
uint8_t staff_type, uint8_t flags, int16_t command_x, int16_t command_y, int16_t command_z, int32_t autoposition,
int32_t* newPeep_sprite_index)
{
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_WAGES;
gCommandPosition.x = command_x;
gCommandPosition.y = command_y;
gCommandPosition.z = command_z;
if (gSpriteListCount[SPRITE_LIST_NULL] < 400)
{
gGameCommandErrorText = STR_TOO_MANY_PEOPLE_IN_GAME;
return MONEY32_UNDEFINED;
}
// Staff type matches STAFF_TYPE enum, but ENTERTAINER onwards will match
// the ENTERTAINER_COSTUME enum
uint8_t entertainerType = ENTERTAINER_COSTUME_PANDA;
if (staff_type >= STAFF_TYPE_ENTERTAINER)
{
entertainerType = staff_type - STAFF_TYPE_ENTERTAINER;
if (entertainerType >= ENTERTAINER_COSTUME_COUNT)
{
// Invalid entertainer costume
return MONEY32_UNDEFINED;
}
uint32_t availableCostumes = staff_get_available_entertainer_costumes();
if (!(availableCostumes & (1 << entertainerType)))
{
// Entertainer costume unavailable
return MONEY32_UNDEFINED;
}
staff_type = STAFF_TYPE_ENTERTAINER;
}
int32_t i;
for (i = 0; i < STAFF_MAX_COUNT; ++i)
{
if (!(gStaffModes[i] & 1))
break;
}
if (i == STAFF_MAX_COUNT)
{
gGameCommandErrorText = STR_TOO_MANY_STAFF_IN_GAME;
return MONEY32_UNDEFINED;
}
if (flags & GAME_COMMAND_FLAG_APPLY)
{
int32_t newStaffId = i;
const rct_sprite_bounds* spriteBounds;
Peep* newPeep = &(create_sprite(flags)->peep);
if (newPeep == nullptr)
{
gGameCommandErrorText = STR_TOO_MANY_PEOPLE_IN_GAME;
return MONEY32_UNDEFINED;
}
if (flags == 0)
{
sprite_remove((rct_sprite*)newPeep);
}
else
{
move_sprite_to_list((rct_sprite*)newPeep, SPRITE_LIST_PEEP * 2);
newPeep->sprite_identifier = 1;
newPeep->window_invalidate_flags = 0;
newPeep->action = PEEP_ACTION_NONE_2;
newPeep->special_sprite = 0;
newPeep->action_sprite_image_offset = 0;
newPeep->no_action_frame_num = 0;
newPeep->action_sprite_type = PEEP_ACTION_SPRITE_TYPE_NONE;
newPeep->path_check_optimisation = 0;
newPeep->type = PEEP_TYPE_STAFF;
newPeep->outside_of_park = 0;
newPeep->peep_flags = 0;
newPeep->paid_to_enter = 0;
newPeep->paid_on_rides = 0;
newPeep->paid_on_food = 0;
newPeep->paid_on_souvenirs = 0;
if (staff_type == STAFF_TYPE_HANDYMAN)
newPeep->staff_orders = STAFF_ORDERS_SWEEPING | STAFF_ORDERS_WATER_FLOWERS | STAFF_ORDERS_EMPTY_BINS;
else if (staff_type == STAFF_TYPE_MECHANIC)
newPeep->staff_orders = STAFF_ORDERS_INSPECT_RIDES | STAFF_ORDERS_FIX_RIDES;
else
newPeep->staff_orders = 0;
uint16_t idSearchSpriteIndex;
Peep* idSearchPeep;
// We search for the first available id for a given staff type
uint32_t newStaffIndex = 0;
for (;;)
{
bool found = false;
++newStaffIndex;
FOR_ALL_STAFF (idSearchSpriteIndex, idSearchPeep)
{
if (idSearchPeep->staff_type != staff_type)
continue;
if (idSearchPeep->id == newStaffIndex)
{
found = true;
break;
}
}
if (!found)
break;
}
newPeep->id = newStaffIndex;
newPeep->staff_type = staff_type;
static constexpr const rct_string_id staffNames[] = {
STR_HANDYMAN_X,
STR_MECHANIC_X,
STR_SECURITY_GUARD_X,
STR_ENTERTAINER_X,
};
/* rct2: 0x009929FC */
static constexpr const PeepSpriteType spriteTypes[] = {
PEEP_SPRITE_TYPE_HANDYMAN,
PEEP_SPRITE_TYPE_MECHANIC,
PEEP_SPRITE_TYPE_SECURITY,
PEEP_SPRITE_TYPE_ENTERTAINER_PANDA,
};
PeepSpriteType sprite_type = spriteTypes[staff_type];
if (staff_type == STAFF_TYPE_ENTERTAINER)
{
sprite_type = static_cast<PeepSpriteType>(PEEP_SPRITE_TYPE_ENTERTAINER_PANDA + entertainerType);
}
newPeep->name_string_idx = staffNames[staff_type];
newPeep->sprite_type = sprite_type;
spriteBounds = g_peep_animation_entries[sprite_type].sprite_bounds;
newPeep->sprite_width = spriteBounds->sprite_width;
newPeep->sprite_height_negative = spriteBounds->sprite_height_negative;
newPeep->sprite_height_positive = spriteBounds->sprite_height_positive;
if (autoposition)
{
staff_autoposition_new_staff_member(newPeep);
}
else
{
newPeep->state = PEEP_STATE_PICKED;
sprite_move(newPeep->x, newPeep->y, newPeep->z, (rct_sprite*)newPeep);
invalidate_sprite_2((rct_sprite*)newPeep);
}
newPeep->time_in_park = gDateMonthsElapsed;
newPeep->pathfind_goal.x = 0xFF;
newPeep->pathfind_goal.y = 0xFF;
newPeep->pathfind_goal.z = 0xFF;
newPeep->pathfind_goal.direction = 0xFF;
uint8_t colour = staff_get_colour(staff_type);
newPeep->tshirt_colour = colour;
newPeep->trousers_colour = colour;
// Staff energy determines their walking speed
newPeep->energy = 0x60;
newPeep->energy_target = 0x60;
newPeep->staff_mowing_timeout = 0;
peep_update_name_sort(newPeep);
newPeep->staff_id = newStaffId;
gStaffModes[newStaffId] = STAFF_MODE_WALK;
for (i = 0; i < STAFF_PATROL_AREA_SIZE; i++)
{
gStaffPatrolAreas[newStaffId * STAFF_PATROL_AREA_SIZE + i] = 0;
}
}
*newPeep_sprite_index = newPeep->sprite_index;
}
return 0;
}
/**
*
* rct2: 0x006BEFA1
*/
void game_command_hire_new_staff_member(
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, [[maybe_unused]] int32_t* esi, int32_t* edi,
[[maybe_unused]] int32_t* ebp)
{
*ebx = staff_hire_new_staff_member(
(*ebx & 0xFF00) >> 8, *ebx & 0xFF, *eax & 0xFFFF, *ecx & 0xFFFF, *edx & 0xFFFF, (*ebx & 0xFF0000) >> 16, edi);
}
/**
*
* rct2: 0x006C09D1
@ -449,42 +170,39 @@ void game_command_fire_staff_member(
}
/**
* Hires a new staff member of the given type. If the hire cannot be completed (eg. the maximum number of staff is reached or
* there are too many peeps) it returns SPRITE_INDEX_NULL.
* Hires a new staff member of the given type.
*/
uint16_t hire_new_staff_member(uint8_t staffType)
bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType)
{
gGameCommandErrorTitle = STR_CANT_HIRE_NEW_STAFF;
int32_t command_x, ebx, command_y, command_z, esi, new_sprite_index, ebp;
command_y = command_z = esi = new_sprite_index = ebp = 0;
command_x = 0x8000;
int32_t autoposition = gConfigGeneral.auto_staff_placement;
bool autoPosition = gConfigGeneral.auto_staff_placement;
if (gInputPlaceObjectModifier & PLACE_OBJECT_MODIFIER_SHIFT_Z)
{
autoposition = autoposition ^ 1;
autoPosition = autoPosition ^ 1;
}
ebx = autoposition << 16 | staffType << 8 | GAME_COMMAND_FLAG_APPLY;
auto hireStaffAction = StaffHireNewAction(autoPosition, staffType, entertainerType);
hireStaffAction.SetCallback([=](const GameAction*, const StaffHireNewActionResult* res) -> void {
if (res->Error != GA_ERROR::OK)
return;
game_command_callback = game_command_callback_hire_new_staff_member;
int32_t result = game_do_command_p(
GAME_COMMAND_HIRE_NEW_STAFF_MEMBER, &command_x, &ebx, &command_y, &command_z, &esi, &new_sprite_index, &ebp);
if ((staffType == STAFF_TYPE_HANDYMAN) && gConfigGeneral.handymen_mow_default)
{
Peep* newPeep = GET_PEEP(res->peepSriteIndex);
uint8_t newOrders = newPeep->staff_orders | STAFF_ORDERS_MOWING;
if (result == MONEY32_UNDEFINED)
return SPRITE_INDEX_NULL;
auto staffSetOrdersAction = StaffSetOrdersAction(res->peepSriteIndex, newOrders);
GameActions::Execute(&staffSetOrdersAction);
}
if ((staffType == STAFF_TYPE_HANDYMAN) && gConfigGeneral.handymen_mow_default)
{
Peep* newPeep = GET_PEEP(new_sprite_index);
uint8_t newOrders = newPeep->staff_orders | STAFF_ORDERS_MOWING;
// Open window for new staff.
Peep* peep = &get_sprite(res->peepSriteIndex)->peep;
auto intent = Intent(WC_PEEP);
intent.putExtra(INTENT_EXTRA_PEEP, peep);
context_open_intent(&intent);
});
auto staffSetOrdersAction = StaffSetOrdersAction(new_sprite_index, newOrders);
GameActions::Execute(&staffSetOrdersAction);
}
return new_sprite_index;
auto res = GameActions::Execute(&hireStaffAction);
return res->Error == GA_ERROR::OK;
}
/**

View File

@ -25,7 +25,7 @@ enum STAFF_MODE
STAFF_MODE_PATROL = 3
};
enum STAFF_TYPE
enum STAFF_TYPE : uint8_t
{
STAFF_TYPE_HANDYMAN,
STAFF_TYPE_MECHANIC,
@ -45,7 +45,7 @@ enum STAFF_ORDERS
STAFF_ORDERS_FIX_RIDES = (1 << 1)
};
enum ENTERTAINER_COSTUME
enum ENTERTAINER_COSTUME : uint8_t
{
ENTERTAINER_COSTUME_PANDA,
ENTERTAINER_COSTUME_TIGER,
@ -86,7 +86,7 @@ void game_command_pickup_staff(
void staff_reset_modes();
void staff_set_name(uint16_t spriteIndex, const char* name);
uint16_t hire_new_staff_member(uint8_t staffType);
bool staff_hire_new_member(STAFF_TYPE staffType, ENTERTAINER_COSTUME entertainerType);
void staff_update_greyed_patrol_areas();
bool staff_is_location_in_patrol(Peep* mechanic, int32_t x, int32_t y);
bool staff_is_location_on_patrol_edge(Peep* mechanic, int32_t x, int32_t y);

View File

@ -55,25 +55,6 @@ void game_command_callback_pickup_guest(
}
}
void game_command_callback_hire_new_staff_member(
[[maybe_unused]] int32_t eax, [[maybe_unused]] int32_t ebx, [[maybe_unused]] int32_t ecx, [[maybe_unused]] int32_t edx,
[[maybe_unused]] int32_t esi, int32_t edi, [[maybe_unused]] int32_t ebp)
{
int32_t sprite_index = edi;
if (sprite_index == SPRITE_INDEX_NULL)
{
rct_window* window = window_find_by_class(WC_STAFF_LIST);
window_invalidate(window);
}
else
{
Peep* peep = &get_sprite(sprite_index)->peep;
auto intent = Intent(WC_PEEP);
intent.putExtra(INTENT_EXTRA_PEEP, peep);
context_open_intent(&intent);
}
}
void game_command_callback_pickup_staff(
int32_t eax, int32_t ebx, int32_t ecx, [[maybe_unused]] int32_t edx, [[maybe_unused]] int32_t esi,
[[maybe_unused]] int32_t edi, [[maybe_unused]] int32_t ebp)