Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Random terrain generation #8600

Draft
wants to merge 21 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions VisualStudio/fheroes2/sources.props
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
<ClCompile Include="src\fheroes2\maps\ground.cpp" />
<ClCompile Include="src\fheroes2\maps\map_format_helper.cpp" />
<ClCompile Include="src\fheroes2\maps\map_format_info.cpp" />
<ClCompile Include="src\fheroes2\maps\map_generator.cpp" />
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should rename these files into random_map_generator.h|cpp to highlight randomness. Or at least map_random_generator.h|cpp if we keep the format.

<ClCompile Include="src\fheroes2\maps\map_object_info.cpp" />
<ClCompile Include="src\fheroes2\maps\maps.cpp" />
<ClCompile Include="src\fheroes2\maps\maps_fileinfo.cpp" />
Expand Down Expand Up @@ -408,6 +409,7 @@
<ClInclude Include="src\fheroes2\maps\ground.h" />
<ClInclude Include="src\fheroes2\maps\map_format_helper.h" />
<ClInclude Include="src\fheroes2\maps\map_format_info.h" />
<ClInclude Include="src\fheroes2\maps\map_generator.h" />
<ClInclude Include="src\fheroes2\maps\map_object_info.h" />
<ClInclude Include="src\fheroes2\maps\maps.h" />
<ClInclude Include="src\fheroes2\maps\maps_fileinfo.h" />
Expand Down
2 changes: 1 addition & 1 deletion fheroes2-vs2019.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
<Import Project="VisualStudio\fheroes2\Release.props" />
</ImportGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>
idshibanov marked this conversation as resolved.
Show resolved Hide resolved
29 changes: 29 additions & 0 deletions src/fheroes2/editor/editor_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "interface_radar.h"
#include "localevent.h"
#include "map_format_helper.h"
#include "map_generator.h"
#include "map_object_info.h"
#include "maps.h"
#include "maps_tiles.h"
Expand Down Expand Up @@ -770,6 +771,34 @@ namespace Interface
else if ( HotKeyPressEvent( Game::HotKeyEvent::WORLD_VIEW_WORLD ) ) {
eventViewWorld();
}
#if defined( WITH_DEBUG )
else if ( HotKeyPressEvent( Game::HotKeyEvent::EDITOR_RANDOM_MAP_GENERATION ) ) {
fheroes2::ActionCreator action( _historyManager, _mapFormat );

Maps::Generator::Configuration rmgConfig;
rmgConfig.playerCount = _playerCount;
idshibanov marked this conversation as resolved.
Show resolved Hide resolved
rmgConfig.regionSizeLimit = _regionSizeLimit;
idshibanov marked this conversation as resolved.
Show resolved Hide resolved

if ( Maps::Generator::generateWorld( _mapFormat, rmgConfig ) ) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Essentially, we are generating map so would generateMap be a better name?

_redraw |= mapUpdateFlags;

action.commit();
}
else {
_warningMessage.reset( _( "Not able to generate a map with given parameters." ) );
}
}
else if ( HotKeyPressEvent( Game::HotKeyEvent::EDITOR_RANDOM_MAP_CONFIGURATION ) ) {
uint32_t newCount = _playerCount;
if ( Dialog::SelectCount( "Pick player count", 2, 6, newCount ) ) {
_playerCount = newCount;
}
newCount = _regionSizeLimit;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that region size is an understandable entity for map makers. Can we come up with something more user friendly metric? :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with renaming it but can't think of more suitable name.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we attach the number of regions to the number of players minus the size of water on map? I assume we don't generate water area for now which is easier. In this case we won't need this parameter.

if ( Dialog::SelectCount( "Limit region size", 100, 10000, newCount ) ) {
_regionSizeLimit = newCount;
}
}
#endif
// map scrolling control
else if ( HotKeyPressEvent( Game::HotKeyEvent::WORLD_SCROLL_LEFT ) ) {
_gameArea.SetScroll( SCROLL_LEFT );
Expand Down
5 changes: 5 additions & 0 deletions src/fheroes2/editor/editor_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ namespace Interface
int32_t _selectedTile{ -1 };
int32_t _tileUnderCursor{ -1 };

#if defined( WITH_DEBUG )
uint32_t _playerCount = 2;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we store Configuration object instead of these 2 members?

uint32_t _regionSizeLimit = 600;
#endif

std::function<void( const int32_t )> _cursorUpdater;

fheroes2::HistoryManager _historyManager;
Expand Down
7 changes: 7 additions & 0 deletions src/fheroes2/game/game_hotkeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ namespace
hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_TO_GAME_MAIN_MENU )]
= { Game::HotKeyCategory::EDITOR, gettext_noop( "hotkey|open game main menu" ), fheroes2::Key::KEY_M };

#if defined( WITH_DEBUG )
hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_RANDOM_MAP_GENERATION )]
= { Game::HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|generate random map" ), fheroes2::Key::KEY_F5 };
hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::EDITOR_RANDOM_MAP_CONFIGURATION )]
= { Game::HotKeyCategory::WORLD_MAP, gettext_noop( "hotkey|configure random map generator" ), fheroes2::Key::KEY_F6 };
#endif

hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ROLAND )]
= { Game::HotKeyCategory::CAMPAIGN, gettext_noop( "hotkey|roland campaign" ), fheroes2::Key::KEY_1 };
hotKeyEventInfo[hotKeyEventToInt( Game::HotKeyEvent::CAMPAIGN_ARCHIBALD )]
Expand Down
6 changes: 6 additions & 0 deletions src/fheroes2/game/game_hotkeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ namespace Game
EDITOR_REDO_LAST_ACTION,
EDITOR_TO_GAME_MAIN_MENU,

#if defined( WITH_DEBUG )
// This hotkey is only for debug mode as of now.
EDITOR_RANDOM_MAP_GENERATION,
EDITOR_RANDOM_MAP_CONFIGURATION,
#endif

CAMPAIGN_ROLAND,
CAMPAIGN_ARCHIBALD,
CAMPAIGN_PRICE_OF_LOYALTY,
Expand Down
102 changes: 102 additions & 0 deletions src/fheroes2/gui/ui_map_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "maps_tiles.h"
#include "math_base.h"
#include "mp2.h"
#include "resource.h"

namespace
{
Expand Down Expand Up @@ -264,4 +265,105 @@ namespace fheroes2

return 0;
}

constexpr int32_t mineIndexFromGroundType( const int groundType )
{
switch ( groundType ) {
case Maps::Ground::WATER:
// Logically Water is not allowed but let's do this.
assert( 0 );
return 0;
case Maps::Ground::GRASS:
return 1;
case Maps::Ground::SNOW:
return 2;
case Maps::Ground::SWAMP:
return 3;
case Maps::Ground::LAVA:
return 4;
case Maps::Ground::DESERT:
return 5;
case Maps::Ground::DIRT:
return 6;
case Maps::Ground::WASTELAND:
return 7;
case Maps::Ground::BEACH:
return 0;
default:
// Have you added a new ground? Add the logic above!
assert( 0 );
break;
}
return 0;
}

constexpr int32_t sawmillIndexFromGroundType( const int groundType )
{
switch ( groundType ) {
case Maps::Ground::WATER:
// Logically Water is not allowed but let's do this.
assert( 0 );
return 0;
case Maps::Ground::GRASS:
return 0;
case Maps::Ground::SNOW:
return 1;
case Maps::Ground::SWAMP:
return 0;
case Maps::Ground::LAVA:
return 2;
case Maps::Ground::DESERT:
return 3;
case Maps::Ground::DIRT:
return 4;
case Maps::Ground::WASTELAND:
return 5;
case Maps::Ground::BEACH:
return 3;
default:
// Have you added a new ground? Add the logic above!
assert( 0 );
break;
}
return 0;
}

int32_t getMineObjectInfoId( const int resource, const int groundType )
{
// 8 terrain and 5 resources
// 2 abandoned mines: grass & dirt
// Sawmills for different terrains: Grass/Swamp, Snow, Lava, Desert, Dirt, Wasteland.
// 2 alchemists labs: regular and snow

// if you add new mine type update this logic!
assert( Maps::getObjectsByGroup( Maps::ObjectGroup::ADVENTURE_MINES ).size() == 50 );

const int groundIndex = mineIndexFromGroundType( groundType );

switch ( resource ) {
case Resource::ORE:
return groundIndex * 5;
case Resource::SULFUR:
return groundIndex * 5 + 1;
case Resource::CRYSTAL:
return groundIndex * 5 + 2;
case Resource::GEMS:
return groundIndex * 5 + 3;
case Resource::GOLD:
return groundIndex * 5 + 4;
case Resource::WOOD:
return 5 * 8 + 2 + sawmillIndexFromGroundType( groundType );
case Resource::MERCURY:
return groundType == Maps::Ground::SNOW ? 49 : 48;
case Resource::UNKNOWN:
// must be an abandoned mine
return groundType == Maps::Ground::GRASS ? 40 : 41;
default:
// Have you added a new resource type?!
assert( 0 );
break;
}

return 0;
}
}
3 changes: 2 additions & 1 deletion src/fheroes2/gui/ui_map_object.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2023 *
* Copyright (C) 2023 - 2024 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
Expand Down Expand Up @@ -35,4 +35,5 @@ namespace fheroes2
Sprite generateTownObjectImage( const int townType, const int color, const int groundId );

int32_t getTownBasementId( const int groundType );
int32_t getMineObjectInfoId( const int resource, const int groundType );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an empty line to differentiate 2 functions.

}
Loading
Loading