1
0
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:
wolfreak99
2018-02-19 15:11:14 -05:00
committed by Michael Steenbeek
parent d5d9441f52
commit 2d8c473f75
12 changed files with 194 additions and 31 deletions

View File

@@ -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();
}
/**

View File

@@ -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,
};

View File

@@ -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
};

View File

@@ -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

View File

@@ -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>();
}
}

View 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>();
}
};

View File

@@ -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
};

View File

@@ -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",

View File

@@ -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>

View File

@@ -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