mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-18 04:23:20 +01:00
Sync Peep Spawn over network
This commit is contained in:
committed by
Michael Steenbeek
parent
d5d9441f52
commit
2d8c473f75
@@ -177,8 +177,6 @@ static uint32 _currentLine;
|
||||
/** rct2: 0x00F1AD68 */
|
||||
static std::vector<uint8> _mapImageData;
|
||||
|
||||
static sint32 _nextPeepSpawnIndex = 0;
|
||||
|
||||
static void window_map_init_map();
|
||||
static void window_map_centre_on_view_point();
|
||||
static void window_map_show_default_scenario_editor_buttons(rct_window *w);
|
||||
@@ -1360,41 +1358,25 @@ static void window_map_place_park_entrance_tool_down(sint32 x, sint32 y)
|
||||
*/
|
||||
static void window_map_set_peep_spawn_tool_down(sint32 x, sint32 y)
|
||||
{
|
||||
rct_tile_element *tileElement, *surfaceTileElement;
|
||||
rct_tile_element *tileElement;
|
||||
sint32 mapX, mapY, mapZ, direction;
|
||||
|
||||
// Verify footpath exists at location, and retrieve coordinates
|
||||
footpath_get_coordinates_from_pos(x, y, &mapX, &mapY, &direction, &tileElement);
|
||||
if (mapX == 0x8000)
|
||||
return;
|
||||
|
||||
surfaceTileElement = map_get_surface_element_at(mapX >> 5, mapY >> 5);
|
||||
if (surfaceTileElement == nullptr) {
|
||||
return;
|
||||
}
|
||||
if (surfaceTileElement->properties.surface.ownership & 0xF0) {
|
||||
return;
|
||||
}
|
||||
|
||||
mapX = mapX + 16 + (word_981D6C[direction].x * 15);
|
||||
mapY = mapY + 16 + (word_981D6C[direction].y * 15);
|
||||
mapZ = tileElement->base_height / 2;
|
||||
|
||||
sint32 peepSpawnIndex = -1;
|
||||
for (sint32 i = 0; i < MAX_PEEP_SPAWNS; i++) {
|
||||
if (gPeepSpawns[i].x == PEEP_SPAWN_UNDEFINED) {
|
||||
peepSpawnIndex = i;
|
||||
break;
|
||||
}
|
||||
bool result = place_peep_spawn({mapX, mapY, mapZ, (uint8)direction});
|
||||
if (result) {
|
||||
audio_play_sound_at_location(
|
||||
SOUND_PLACE_ITEM,
|
||||
gCommandPosition.x,
|
||||
gCommandPosition.y,
|
||||
gCommandPosition.z
|
||||
);
|
||||
}
|
||||
if (peepSpawnIndex == -1) {
|
||||
peepSpawnIndex = _nextPeepSpawnIndex;
|
||||
_nextPeepSpawnIndex = (peepSpawnIndex + 1) % MAX_PEEP_SPAWNS;
|
||||
}
|
||||
gPeepSpawns[peepSpawnIndex].x = mapX;
|
||||
gPeepSpawns[peepSpawnIndex].y = mapY;
|
||||
gPeepSpawns[peepSpawnIndex].z = mapZ;
|
||||
gPeepSpawns[peepSpawnIndex].direction = direction;
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1008,6 +1008,15 @@ void game_log_multiplayer_command(int command, const int * eax, const int * ebx,
|
||||
format_string(log_msg, 256, STR_LOG_REMOVE_TRACK, args);
|
||||
network_append_server_log(log_msg);
|
||||
}
|
||||
else if (command == GAME_COMMAND_PLACE_PEEP_SPAWN)
|
||||
{
|
||||
char * args[1] = {
|
||||
(char *) player_name
|
||||
};
|
||||
|
||||
format_string(log_msg, 256, STR_LOG_PLACE_PEEP_SPAWN, args);
|
||||
network_append_server_log(log_msg);
|
||||
}
|
||||
}
|
||||
|
||||
void pause_toggle()
|
||||
@@ -1744,4 +1753,5 @@ GAME_COMMAND_POINTER * new_game_command_table[GAME_COMMAND_COUNT] = {
|
||||
game_command_balloon_press,
|
||||
game_command_modify_tile,
|
||||
game_command_edit_scenario_options,
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -93,6 +93,7 @@ enum GAME_COMMAND
|
||||
GAME_COMMAND_BALLOON_PRESS,
|
||||
GAME_COMMAND_MODIFY_TILE,
|
||||
GAME_COMMAND_EDIT_SCENARIO_OPTIONS,
|
||||
GAME_COMMAND_PLACE_PEEP_SPAWN, // GA, TODO: refactor to separate array for just game actions
|
||||
GAME_COMMAND_COUNT
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "RideSetStatus.hpp"
|
||||
#include "RideSetName.hpp"
|
||||
#include "RideDemolishAction.hpp"
|
||||
#include "PlacePeepSpawnAction.hpp"
|
||||
|
||||
#pragma region PlaceParkEntranceAction
|
||||
money32 place_park_entrance(sint16 x, sint16 y, sint16 z, uint8 direction)
|
||||
@@ -232,5 +233,20 @@
|
||||
{
|
||||
Guard::Assert(false, "GAME_COMMAND_SET_STAFF_NAME DEPRECATED");
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region PlacePeepSpawn
|
||||
bool place_peep_spawn(CoordsXYZD location)
|
||||
{
|
||||
auto gameAction = PlacePeepSpawnAction(location);
|
||||
auto result = GameActions::Execute(&gameAction);
|
||||
if (result->Error == GA_ERROR::OK)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#pragma endregion
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "RideSetStatus.hpp"
|
||||
#include "RideSetName.hpp"
|
||||
#include "RideDemolishAction.hpp"
|
||||
#include "PlacePeepSpawnAction.hpp"
|
||||
|
||||
namespace GameActions
|
||||
{
|
||||
@@ -36,5 +37,6 @@ namespace GameActions
|
||||
Register<RideDemolishAction>();
|
||||
Register<GuestSetNameAction>();
|
||||
Register<StaffSetNameAction>();
|
||||
Register<PlacePeepSpawnAction>();
|
||||
}
|
||||
}
|
||||
|
||||
141
src/openrct2/actions/PlacePeepSpawnAction.hpp
Normal file
141
src/openrct2/actions/PlacePeepSpawnAction.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#pragma region Copyright (c) 2014-2017 OpenRCT2 Developers
|
||||
/*****************************************************************************
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* OpenRCT2 is the work of many authors, a full list can be found in contributors.md
|
||||
* For more information, visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* A full copy of the GNU General Public License can be found in licence.txt
|
||||
*****************************************************************************/
|
||||
#pragma endregion
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../core/MemoryStream.h"
|
||||
#include "../localisation/StringIds.h"
|
||||
#include "../OpenRCT2.h"
|
||||
#include "GameAction.h"
|
||||
|
||||
#include "../Cheats.h"
|
||||
#include "../world/Park.h"
|
||||
#include "../world/Footpath.h"
|
||||
|
||||
static sint32 _nextPeepSpawnIndex = 0;
|
||||
|
||||
struct PlacePeepSpawnAction : public GameActionBase<GAME_COMMAND_PLACE_PEEP_SPAWN, GameActionResult>
|
||||
{
|
||||
private:
|
||||
CoordsXYZD _location;
|
||||
|
||||
public:
|
||||
PlacePeepSpawnAction() {}
|
||||
PlacePeepSpawnAction(CoordsXYZD location) :
|
||||
_location(location)
|
||||
{
|
||||
}
|
||||
|
||||
uint16 GetActionFlags() const override
|
||||
{
|
||||
return GameActionBase::GetActionFlags() | GA_FLAGS::EDITOR_ONLY | GA_FLAGS::ALLOW_WHILE_PAUSED;
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _location.x << _location.y << _location.z << _location.direction;
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
{
|
||||
if (!(gScreenFlags & SCREEN_FLAGS_EDITOR) && !gCheatsSandboxMode)
|
||||
{
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::NOT_IN_EDITOR_MODE, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_NONE);
|
||||
}
|
||||
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
gCommandPosition.x = _location.x;
|
||||
gCommandPosition.y = _location.y;
|
||||
gCommandPosition.z = _location.z * 2;
|
||||
|
||||
if (!map_check_free_elements_and_reorganise(3))
|
||||
{
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::NO_FREE_ELEMENTS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_NONE);
|
||||
}
|
||||
|
||||
if (_location.x <= 16 || _location.y <= 16 || _location.x >= (gMapSizeUnits - 16) || _location.y >= (gMapSizeUnits - 16))
|
||||
{
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_OFF_EDGE_OF_MAP);
|
||||
}
|
||||
|
||||
rct_tile_element *mapElement, *surfaceMapElement;
|
||||
// Verify footpath exists at location, and retrieve coordinates
|
||||
mapElement = map_get_path_element_at(_location.x >> 5, _location.y >> 5, _location.z * 2);
|
||||
if (mapElement == NULL) {
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_CAN_ONLY_BE_BUILT_ACROSS_PATHS);
|
||||
}
|
||||
|
||||
// Verify location is unowned
|
||||
surfaceMapElement = map_get_surface_element_at(_location.x >> 5, _location.y >> 5);
|
||||
if (surfaceMapElement == NULL) {
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::UNKNOWN, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_NONE);
|
||||
}
|
||||
if (surfaceMapElement->properties.surface.ownership & 0xF0) {
|
||||
return std::make_unique<GameActionResult>(GA_ERROR::INVALID_PARAMETERS, STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE, STR_ERR_MUST_BE_OUTSIDE_PARK_BOUNDARIES);
|
||||
}
|
||||
|
||||
return std::make_unique<GameActionResult>();
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute() const override
|
||||
{
|
||||
gCommandExpenditureType = RCT_EXPENDITURE_TYPE_LAND_PURCHASE;
|
||||
|
||||
gCommandPosition.x = _location.x;
|
||||
gCommandPosition.y = _location.y;
|
||||
gCommandPosition.z = _location.z * 2;
|
||||
|
||||
// Find empty or next appropriate peep spawn to use
|
||||
sint32 peepSpawnIndex = -1;
|
||||
for (sint32 i = 0; i < MAX_PEEP_SPAWNS; i++) {
|
||||
if (gPeepSpawns[i].x == PEEP_SPAWN_UNDEFINED) {
|
||||
peepSpawnIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If no empty peep spawns exist, use peep spawn next to last one set.
|
||||
if (peepSpawnIndex == -1) {
|
||||
peepSpawnIndex = _nextPeepSpawnIndex;
|
||||
_nextPeepSpawnIndex = (peepSpawnIndex + 1) % MAX_PEEP_SPAWNS;
|
||||
|
||||
// Before the new location is set, clear the old location
|
||||
sint32 prevX = gPeepSpawns[peepSpawnIndex].x;
|
||||
gPeepSpawns[peepSpawnIndex].x = PEEP_SPAWN_UNDEFINED;
|
||||
|
||||
map_invalidate_tile_full(prevX, gPeepSpawns[peepSpawnIndex].y);
|
||||
}
|
||||
|
||||
// Shift the spawn point to the middle of the tile
|
||||
sint32 middleX, middleY;
|
||||
middleX = _location.x + 16 + (word_981D6C[_location.direction].x * 15);
|
||||
middleY = _location.y + 16 + (word_981D6C[_location.direction].y * 15);
|
||||
|
||||
// Set peep spawn
|
||||
gPeepSpawns[peepSpawnIndex].x = middleX;
|
||||
gPeepSpawns[peepSpawnIndex].y = middleY;
|
||||
gPeepSpawns[peepSpawnIndex].z = _location.z;
|
||||
gPeepSpawns[peepSpawnIndex].direction = _location.direction;
|
||||
|
||||
// Invalidate tile
|
||||
map_invalidate_tile_full(_location.x, _location.y);
|
||||
|
||||
return std::make_unique<GameActionResult>();
|
||||
}
|
||||
};
|
||||
@@ -3881,6 +3881,10 @@ enum {
|
||||
STR_TILE_INSPECTOR_ENTRANCE_MAKE_USABLE = 6220,
|
||||
STR_TILE_INSPECTOR_ENTRANCE_MAKE_USABLE_TIP = 6221,
|
||||
|
||||
STR_ERR_CANT_PLACE_PEEP_SPAWN_HERE = 6222,
|
||||
STR_ERR_MUST_BE_OUTSIDE_PARK_BOUNDARIES = 6223,
|
||||
STR_LOG_PLACE_PEEP_SPAWN = 6224,
|
||||
|
||||
// Have to include resource strings (from scenarios and objects) for the time being now that language is partially working
|
||||
STR_COUNT = 32768
|
||||
};
|
||||
|
||||
@@ -176,7 +176,8 @@ const std::vector<NetworkAction> NetworkActions::Actions =
|
||||
GAME_COMMAND_SET_LAND_OWNERSHIP,
|
||||
GAME_COMMAND_BUY_LAND_RIGHTS,
|
||||
GAME_COMMAND_PLACE_PARK_ENTRANCE,
|
||||
GAME_COMMAND_REMOVE_PARK_ENTRANCE
|
||||
GAME_COMMAND_REMOVE_PARK_ENTRANCE,
|
||||
GAME_COMMAND_PLACE_PEEP_SPAWN,
|
||||
}
|
||||
}, {
|
||||
STR_ACTION_PARK_FUNDING, "PERMISSION_PARK_FUNDING",
|
||||
|
||||
@@ -50,7 +50,7 @@ struct GameAction;
|
||||
// This define specifies which version of network stream current build uses.
|
||||
// It is used for making sure only compatible builds get connected, even within
|
||||
// single OpenRCT2 version.
|
||||
#define NETWORK_STREAM_VERSION "30"
|
||||
#define NETWORK_STREAM_VERSION "31"
|
||||
#define NETWORK_STREAM_ID OPENRCT2_VERSION "-" NETWORK_STREAM_VERSION
|
||||
|
||||
#include <array>
|
||||
|
||||
@@ -588,4 +588,6 @@ uint8 tile_element_get_ride_index(const rct_tile_element * tileElement);
|
||||
void FixLandOwnershipTiles(std::initializer_list<TileCoordsXY> tiles);
|
||||
void FixLandOwnershipTilesWithOwnership(std::initializer_list<TileCoordsXY> tiles, uint8 ownership);
|
||||
|
||||
bool place_peep_spawn(CoordsXYZD location);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user