-
-
Notifications
You must be signed in to change notification settings - Fork 385
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang-Tidy
found issue(s) with the introduced code (1/2)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang-Tidy
found issue(s) with the introduced code (2/2)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang-Tidy
found issue(s) with the introduced code (1/1)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang-Tidy
found issue(s) with the introduced code (1/1)
79e57c3
to
cac83d6
Compare
cac83d6
to
14e8178
Compare
…andom-map-generator # Conflicts: # src/fheroes2/editor/editor_interface.cpp
aa973d6
to
a7d0fc0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clang-Tidy
found issue(s) with the introduced code (1/1)
NodeCache( int32_t width, int32_t height ) | ||
: mapSize( width ) | ||
, outOfBounds( -1 ) | ||
, data( width * height ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performing an implicit widening conversion to type std::vector::size_type
(aka unsigned long
) of a multiplication performed in type int
{ | ||
const fheroes2::Point tilePos = tile.GetCenter(); | ||
const auto & objectInfo = Maps::getObjectInfo( groupType, type ); | ||
if ( canFitObject( data, objectInfo, tilePos, true ) && putObjectOnMap( mapFormat, tile, groupType, static_cast<uint32_t>( type ) ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
narrowing conversion from uint32_t
(aka unsigned int
) to signed type int32_t
(aka int
) is implementation-defined
// Step 4. We're ready to save the result; reset the current world first | ||
world.generateForEditor( width ); | ||
mapFormat.tiles.clear(); | ||
mapFormat.tiles.resize( width * height ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
performing an implicit widening conversion to type std::vector::size_type
(aka unsigned long
) of a multiplication performed in type int
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @idshibanov , I left multiple comments and suggestions here. Could you please take a look at them once you have time?
src/fheroes2/maps/map_generator.cpp
Outdated
const std::vector<int> playerStartingTerrain = { Ground::GRASS, Ground::DIRT, Ground::SNOW, Ground::LAVA, Ground::WASTELAND }; | ||
const std::vector<int> neutralTerrain = { Ground::GRASS, Ground::DIRT, Ground::SNOW, Ground::LAVA, Ground::WASTELAND, Ground::BEACH, Ground::SWAMP, Ground::DESERT }; | ||
|
||
std::vector<fheroes2::Point> directionOffsets = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 }, { -1, -1 }, { 1, -1 }, { 1, 1 }, { -1, 1 } }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be std::array<>
as well. Plus it can be const.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason array doesn't play nicely with Point class allocation. I get no suitable constructor exists to convert from "int" to "fheroes2::PointBase2D<int32_t>"
src/fheroes2/maps/map_generator.cpp
Outdated
} | ||
} | ||
|
||
bool putObjectOnMap( Map_Format::MapFormat & mapFormat, Tiles & tile, const ObjectGroup groupType, const int32_t objectIndex ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is the same as EditorInterface::_setObjectOnTile() method. We should reuse the existing code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar situation as in previous comment. For example this call doesn't recalculate passabilities after every call.
src/fheroes2/maps/map_generator.cpp
Outdated
return false; | ||
} | ||
|
||
bool placeCastle( Map_Format::MapFormat & mapFormat, NodeCache & data, Region & region, int targetX, int targetY ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
placeCastle and placeMine have the same code as editor_interface.cpp
file. In the future we might even change the code there. We need to avoid using code duplication.
We can move existing functions from editor_interface.cpp
file to a new file. We can call it as editor_map_helper.h|cpp
and use the functions here and in editor_interface.cpp
file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this is the worst case of duplication, but can't think of a clean way to extract it. I'd have to pass 2-3 function callbacks into it for object placement check, action object check an additional marking call for the generator. Editor version also have to handle error messages for the user feedback but generator just tries another time.
{ | ||
const auto & node = Rand::Get( region._nodes ); | ||
Maps::Tiles & mineTile = world.GetTiles( node.index ); | ||
const int32_t mineType = fheroes2::getMineObjectInfoId( resource, mineTile.GetGround() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use ObjectInfo from mapFormat
which already contains mineType. See EditorPanel::getMineObjectProperties() for this matter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how getMineObjectProperties
would help here. I'm going in opposite direction - not having ObjectInfo I need to find out which index contains what I need. ObjectInfo groups have arbitrary order and no enums to support it, so I had to make this function.
@@ -153,6 +153,11 @@ namespace Interface | |||
int32_t _selectedTile{ -1 }; | |||
int32_t _tileUnderCursor{ -1 }; | |||
|
|||
#if defined( WITH_DEBUG ) | |||
uint32_t _playerCount = 2; |
There was a problem hiding this comment.
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?
if ( Dialog::SelectCount( "Pick player count", 2, 6, newCount ) ) { | ||
_playerCount = newCount; | ||
} | ||
newCount = _regionSizeLimit; |
There was a problem hiding this comment.
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? :)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @idshibanov , I left few more comments here. Also, some comments are still valid form the previous review. Could you please take a look at them?
@@ -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" /> |
There was a problem hiding this comment.
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.
rmgConfig.playerCount = _playerCount; | ||
rmgConfig.regionSizeLimit = _regionSizeLimit; | ||
|
||
if ( Maps::Generator::generateWorld( _mapFormat, rmgConfig ) ) { |
There was a problem hiding this comment.
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?
if ( Dialog::SelectCount( "Pick player count", 2, 6, newCount ) ) { | ||
_playerCount = newCount; | ||
} | ||
newCount = _regionSizeLimit; |
There was a problem hiding this comment.
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.
@@ -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 ); |
There was a problem hiding this comment.
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.
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | ||
***************************************************************************/ | ||
#pragma once | ||
#include <cstdint> |
There was a problem hiding this comment.
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 separate file header inclusion list.
namespace | ||
{ | ||
// ObjectInfo ObjctGroup based indicies do not match old objects | ||
const int neutralCOLOR = 6; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
COLOR part should be Color :)
Debug feature only. Basic editor usage with F5/F6 keybinds to assist with mapmaking. More to come soon™.