1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00

begin simple map generator

This commit is contained in:
IntelOrca
2014-09-25 02:39:17 +01:00
parent f708a70976
commit 03048edfed
11 changed files with 316 additions and 3 deletions

View File

@@ -33,6 +33,8 @@
<ClInclude Include="..\src\intro.h" />
<ClInclude Include="..\src\language.h" />
<ClInclude Include="..\src\map.h" />
<ClInclude Include="..\src\mapgen.h" />
<ClInclude Include="..\src\map_helpers.h" />
<ClInclude Include="..\src\marketing.h" />
<ClInclude Include="..\src\mixer.h" />
<ClInclude Include="..\src\news_item.h" />
@@ -85,6 +87,8 @@
<ClCompile Include="..\src\intro.c" />
<ClCompile Include="..\src\language.c" />
<ClCompile Include="..\src\map.c" />
<ClCompile Include="..\src\mapgen.c" />
<ClCompile Include="..\src\map_helpers.c" />
<ClCompile Include="..\src\marketing.c" />
<ClCompile Include="..\src\mixer.cpp" />
<ClCompile Include="..\src\news_item.c" />

View File

@@ -168,6 +168,18 @@
<ClInclude Include="..\src\window_scenery.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\hook.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mixer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\mapgen.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\src\map_helpers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\game.c">
@@ -398,6 +410,21 @@
<ClCompile Include="..\src\window_credits.c">
<Filter>Windows</Filter>
</ClCompile>
<ClCompile Include="..\libspeex\resample.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\hook.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\mixer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\mapgen.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\map_helpers.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\openrct2.exe">

View File

@@ -12,5 +12,6 @@
<LocalDebuggerCommand>$(TargetDir)\openrct2.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>$(TargetDir)</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
<LocalDebuggerCommandArguments>gen</LocalDebuggerCommandArguments>
</PropertyGroup>
</Project>

View File

@@ -78,7 +78,7 @@ void editor_load()
RCT2_CALLPROC_EBPSAFE(0x006837E3);
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, sint16) = 0;
rct2_endupdate();
// rct2_endupdate();
}
/**

142
src/map_helpers.c Normal file
View File

@@ -0,0 +1,142 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "map.h"
#include "map_helpers.h"
int map_smooth(int l, int t, int r, int b)
{
int i, x, y, highest, count, cornerHeights[4], doubleCorner, raisedLand = 0;
rct_map_element *mapElement, *mapElement2;
for (y = t; y < b; y++) {
for (x = l; x < r; x++) {
mapElement = map_get_surface_element_at(x, y);
mapElement->properties.surface.slope = 0;
// Raise to edge height - 2
highest = mapElement->base_height;
highest = max(highest, map_get_surface_element_at(x - 1, y + 0)->base_height);
highest = max(highest, map_get_surface_element_at(x + 1, y + 0)->base_height);
highest = max(highest, map_get_surface_element_at(x + 0, y - 1)->base_height);
highest = max(highest, map_get_surface_element_at(x + 0, y + 1)->base_height);
if (mapElement->base_height < highest - 2) {
raisedLand = 1;
mapElement->base_height = mapElement->clearance_height = highest - 2;
}
// Check corners
doubleCorner = -1;
cornerHeights[0] = map_get_surface_element_at(x - 1, y - 1)->base_height;
cornerHeights[1] = map_get_surface_element_at(x + 1, y - 1)->base_height;
cornerHeights[2] = map_get_surface_element_at(x + 1, y + 1)->base_height;
cornerHeights[3] = map_get_surface_element_at(x - 1, y + 1)->base_height;
highest = mapElement->base_height;
for (i = 0; i < 4; i++)
highest = max(highest, cornerHeights[i]);
if (highest >= mapElement->base_height + 4) {
count = 0;
for (i = 0; i < 4; i++)
if (cornerHeights[i] == highest)
count++;
if (count == 1) {
if (mapElement->base_height < highest - 4) {
mapElement->base_height = mapElement->clearance_height = highest - 4;
raisedLand = 1;
}
if (cornerHeights[0] == highest && cornerHeights[2] <= cornerHeights[0] - 4)
doubleCorner = 0;
else if (cornerHeights[1] == highest && cornerHeights[3] <= cornerHeights[1] - 4)
doubleCorner = 1;
else if (cornerHeights[2] == highest && cornerHeights[0] <= cornerHeights[2] - 4)
doubleCorner = 2;
else if (cornerHeights[3] == highest && cornerHeights[1] <= cornerHeights[3] - 4)
doubleCorner = 3;
} else {
if (mapElement->base_height < highest - 2) {
mapElement->base_height = mapElement->clearance_height = highest - 2;
raisedLand = 1;
}
}
}
if (doubleCorner != -1) {
mapElement->properties.surface.slope |= 16;
switch (doubleCorner) {
case 0:
mapElement->properties.surface.slope |= 2 | 4 | 8;
break;
case 1:
mapElement->properties.surface.slope |= 1 | 2 | 4;
break;
case 2:
mapElement->properties.surface.slope |= 1 | 2 | 8;
break;
case 3:
mapElement->properties.surface.slope |= 1 | 4 | 8;
break;
}
} else {
// Corners
mapElement2 = map_get_surface_element_at(x + 1, y + 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 1;
mapElement2 = map_get_surface_element_at(x - 1, y + 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 8;
mapElement2 = map_get_surface_element_at(x + 1, y - 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 2;
mapElement2 = map_get_surface_element_at(x - 1, y - 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 4;
// Sides
mapElement2 = map_get_surface_element_at(x + 1, y + 0);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 1 | 2;
mapElement2 = map_get_surface_element_at(x - 1, y + 0);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 4 | 8;
mapElement2 = map_get_surface_element_at(x + 0, y - 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 2 | 4;
mapElement2 = map_get_surface_element_at(x + 0, y + 1);
if (mapElement2->base_height > mapElement->base_height)
mapElement->properties.surface.slope |= 1 | 8;
// Raise
if (mapElement->properties.surface.slope == (1 | 2 | 4 | 8)) {
mapElement->properties.surface.slope = 0;
mapElement->base_height = mapElement->clearance_height += 2;
}
}
}
}
return raisedLand;
}

26
src/map_helpers.h Normal file
View File

@@ -0,0 +1,26 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _MAP_HELPERS_H_
#define _MAP_HELPERS_H_
int map_smooth(int l, int t, int r, int b);
#endif

77
src/mapgen.c Normal file
View File

@@ -0,0 +1,77 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "addresses.h"
#include "map.h"
#include "map_helpers.h"
#include "mapgen.h"
static void mapgen_set_water_level(int height);
void mapgen_generate()
{
int x, y, mapSize;
rct_map_element *mapElement;
map_init();
// Not sure how to change map size at the moment, default is 150
mapSize = 150;
for (y = 1; y < mapSize - 1; y++) {
for (x = 1; x < mapSize - 1; x++) {
mapElement = map_get_surface_element_at(x, y);
map_element_set_terrain(mapElement, TERRAIN_SAND);
double a = abs(x - (mapSize / 2)) / (double)(mapSize / 2);
double b = abs(y - (mapSize / 2)) / (double)(mapSize / 2);
a *= 2;
b *= 2;
double c = 1 - ((a*a + b*b) / 2);
c = clamp(0, c, 1);
int height = 2 + rand() % ((int)(c * 22) + 1);
mapElement->base_height = height * 2;
mapElement->clearance_height = mapElement->base_height;
}
}
while (map_smooth(1, 1, mapSize - 1, mapSize - 1)) { }
mapgen_set_water_level(8);
}
static void mapgen_set_water_level(int waterLevel)
{
int x, y, mapSize;
rct_map_element *mapElement;
mapSize = RCT2_GLOBAL(RCT2_ADDRESS_MAP_SIZE, sint16);
for (y = 1; y < mapSize - 1; y++) {
for (x = 1; x < mapSize - 1; x++) {
mapElement = map_get_surface_element_at(x, y);
if (mapElement->base_height <= waterLevel)
mapElement->properties.surface.terrain |= (waterLevel - 5);
}
}
}

26
src/mapgen.h Normal file
View File

@@ -0,0 +1,26 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
*
* This file is part of 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.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef _MAPGEN_H_
#define _MAPGEN_H_
void mapgen_generate();
#endif

View File

@@ -168,8 +168,8 @@ static void osinterface_create_window()
width = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_WIDTH, sint16);
height = RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_RESOLUTION_HEIGHT, sint16);
width = 640;
height = 480;
width = 1024;
height = 768;
}
RCT2_GLOBAL(0x009E2D8C, sint32) = 0;

View File

@@ -39,6 +39,7 @@
#include "intro.h"
#include "language.h"
#include "map.h"
#include "mapgen.h"
#include "mixer.h"
#include "news_item.h"
#include "object.h"
@@ -280,14 +281,19 @@ int rct2_open_file(const char *path)
if (_stricmp(extension, "sv6")) {
game_load_save(path);
return 1;
} else if (!_stricmp(extension, "sc6")) {
// TODO scenario install
rct_scenario_basic scenarioBasic;
strcpy(scenarioBasic.path, path);
scenario_load_and_play_from_path(scenarioBasic.path);
return 1;
} else if (!_stricmp(extension, "td6") || !_stricmp(extension, "td4")) {
// TODO track design install
return 1;
}
return 0;
}
void check_cmdline_arg()
@@ -306,6 +312,9 @@ void check_cmdline_arg()
if (_stricmp(argv[0], "edit") == 0) {
if (argc >= 1)
editor_load_landscape(argv[1]);
} else if (_stricmp(argv[0], "gen") == 0) {
editor_load();
mapgen_generate();
} else {
rct2_open_file(argv[0]);
}

View File

@@ -319,6 +319,7 @@ int scenario_load_and_play_from_path(const char *path)
gfx_invalidate_screen();
RCT2_GLOBAL(0x009DEA66, uint16) = 0;
RCT2_GLOBAL(0x009DEA5C, uint16) = 62000; // (doesn't appear to ever be read)
return 1;
}