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

Change the logic to handle the future map loading #8342

Merged
merged 7 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
72 changes: 53 additions & 19 deletions src/fheroes2/editor/editor_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,16 +472,20 @@ namespace Interface
if ( isCursorOverGamearea && _editorPanel.getBrushArea().width == 0 ) {
if ( _editorPanel.isTerrainEdit() ) {
// Fill the selected area in terrain edit mode.
const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

const int groundId = _editorPanel.selectedGroundType();
Maps::setTerrainOnTiles( _selectedTile, _tileUnderCursor, groundId );

action.commit();
}
else if ( _editorPanel.isEraseMode() ) {
// Erase objects in the selected area.
const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

Maps::eraseObjectsOnTiles( _selectedTile, _tileUnderCursor, _editorPanel.getEraseTypes() );

action.commit();
}
}

Expand Down Expand Up @@ -667,7 +671,7 @@ namespace Interface

const int groundId = _editorPanel.selectedGroundType();

const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

if ( brushSize.width > 0 ) {
const fheroes2::Point indices = getBrushAreaIndicies( brushSize, tileIndex );
Expand All @@ -684,37 +688,47 @@ namespace Interface
}

_redraw |= mapUpdateFlags;

action.commit();
}
else if ( _editorPanel.isRoadDraw() ) {
const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

if ( Maps::updateRoadOnTile( tile, true ) ) {
_redraw |= mapUpdateFlags;

action.commit();
}
}
else if ( _editorPanel.isStreamDraw() ) {
const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

if ( Maps::updateStreamOnTile( tile, true ) ) {
_redraw |= mapUpdateFlags;

action.commit();
}
}
else if ( _editorPanel.isEraseMode() ) {
const fheroes2::Rect brushSize = _editorPanel.getBrushArea();
assert( brushSize.width == brushSize.height );

const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

if ( brushSize.width > 1 ) {
const fheroes2::Point indices = getBrushAreaIndicies( brushSize, tileIndex );

if ( Maps::eraseObjectsOnTiles( indices.x, indices.y, _editorPanel.getEraseTypes() ) ) {
_redraw |= mapUpdateFlags;

action.commit();
}
}
else {
if ( Maps::eraseOjects( tile, _editorPanel.getEraseTypes() ) ) {
_redraw |= mapUpdateFlags;

action.commit();
}

if ( brushSize.width == 0 ) {
Expand Down Expand Up @@ -990,9 +1004,11 @@ namespace Interface
return;
}

const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

setObjectOnTile( tile, Maps::ObjectGroup::LANDSCAPE_TOWN_BASEMENTS, basementId );
if ( !setObjectOnTile( tile, Maps::ObjectGroup::LANDSCAPE_TOWN_BASEMENTS, basementId ) ) {
return;
}

// Since the whole object consists of multiple "objects" we have to put the same ID for all of them.
// Every time an object is being placed on a map the counter is going to be increased by 1.
Expand All @@ -1002,17 +1018,25 @@ namespace Interface

Maps::setLastObjectUID( objectId );

setObjectOnTile( tile, groupType, type );
if ( !setObjectOnTile( tile, groupType, type ) ) {
return;
}

// Add flags.
assert( tile.GetIndex() > 0 && tile.GetIndex() < world.w() * world.h() - 1 );
Maps::setLastObjectUID( objectId );

setObjectOnTile( world.GetTiles( tile.GetIndex() - 1 ), Maps::ObjectGroup::LANDSCAPE_FLAGS, color * 2 );
if ( !setObjectOnTile( world.GetTiles( tile.GetIndex() - 1 ), Maps::ObjectGroup::LANDSCAPE_FLAGS, color * 2 ) ) {
return;
}

Maps::setLastObjectUID( objectId );

setObjectOnTile( world.GetTiles( tile.GetIndex() + 1 ), Maps::ObjectGroup::LANDSCAPE_FLAGS, color * 2 + 1 );
if ( !setObjectOnTile( world.GetTiles( tile.GetIndex() + 1 ), Maps::ObjectGroup::LANDSCAPE_FLAGS, color * 2 + 1 ) ) {
return;
}

action.commit();
}
else if ( groupType == Maps::ObjectGroup::ADVENTURE_MINES ) {
int32_t type = -1;
Expand Down Expand Up @@ -1042,11 +1066,14 @@ namespace Interface
return;
}

const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

setObjectOnTile( tile, groupType, type );
if ( !setObjectOnTile( tile, groupType, type ) ) {
return;
}

// TODO: Place owner flag according to the color state.
action.commit();
}
else if ( groupType == Maps::ObjectGroup::ADVENTURE_DWELLINGS ) {
const auto & objectInfo = getObjectInfo( groupType, _editorPanel.getSelectedObjectType() );
Expand Down Expand Up @@ -1125,26 +1152,33 @@ namespace Interface
}
}

void EditorInterface::setObjectOnTile( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex )
bool EditorInterface::setObjectOnTile( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex )
{
const auto & objectInfo = getObjectInfo( groupType, objectIndex );
if ( objectInfo.empty() ) {
// Check your logic as you are trying to insert an empty object!
assert( 0 );
return;
return false;
}

_redraw |= mapUpdateFlags;

if ( !Maps::setObjectOnTile( tile, objectInfo, true ) ) {
return false;
}

Maps::setObjectOnTile( tile, objectInfo, true );
Maps::addObjectToMap( _mapFormat, tile.GetIndex(), groupType, static_cast<uint32_t>( objectIndex ) );

_redraw |= mapUpdateFlags;
return true;
}

void EditorInterface::setObjectOnTileAsAction( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex )
{
const fheroes2::ActionCreator action( _historyManager, _mapFormat );
fheroes2::ActionCreator action( _historyManager, _mapFormat );

setObjectOnTile( tile, groupType, objectIndex );
if ( setObjectOnTile( tile, groupType, objectIndex ) ) {
action.commit();
}
}

bool EditorInterface::loadMap( const std::string & filePath )
Expand Down
2 changes: 1 addition & 1 deletion src/fheroes2/editor/editor_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ namespace Interface
// Do nothing.
}

void setObjectOnTile( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex );
bool setObjectOnTile( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex );

void setObjectOnTileAsAction( Maps::Tiles & tile, const Maps::ObjectGroup groupType, const int32_t objectIndex );

Expand Down
16 changes: 5 additions & 11 deletions src/fheroes2/editor/history_manager.cpp
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 @@ -110,23 +110,17 @@ namespace fheroes2
_action = std::make_unique<MapAction>( mapFormat );
}

ActionCreator::~ActionCreator()
void ActionCreator::commit()
{
auto * action = dynamic_cast<MapAction *>( _action.get() );
if ( action == nullptr ) {
// How is it even possible?
// How is it even possible? Did you call this method twice?
assert( 0 );
return;
}
ihhub marked this conversation as resolved.
Show resolved Hide resolved

try {
if ( action->prepare() ) {
_manager.add( std::move( _action ) );
}
}
catch ( ... ) {
// If an exception happens here then something is very wrong with the code.
assert( 0 );
if ( action->prepare() ) {
_manager.add( std::move( _action ) );
}
}
}
12 changes: 10 additions & 2 deletions src/fheroes2/editor/history_manager.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 @@ -52,12 +52,20 @@ namespace fheroes2
public:
explicit ActionCreator( HistoryManager & manager, Maps::Map_Format::MapFormat & mapFormat );

~ActionCreator();
~ActionCreator()
{
if ( _action ) {
// The action wasn't committed. Undo all the changes.
_action->undo();
}
}

ActionCreator( const ActionCreator & ) = delete;

ActionCreator & operator=( const ActionCreator & ) = delete;

void commit();

private:
HistoryManager & _manager;

Expand Down
25 changes: 18 additions & 7 deletions src/fheroes2/maps/map_format_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,17 @@ namespace Maps
{
world.generateForEditor( map.size );

if ( !readAllTiles( map ) ) {
return false;
}

world.updatePassabilities();

return true;
}

bool readAllTiles( const Map_Format::MapFormat & map )
{
assert( static_cast<size_t>( world.w() ) * world.h() == map.tiles.size() );

// We must clear all tiles before writing something on them.
Expand Down Expand Up @@ -90,11 +101,11 @@ namespace Maps

for ( const auto & info : sortedObjects ) {
assert( info.info != nullptr );
readTileObject( world.GetTiles( info.tileIndex ), *info.info );
if ( !readTileObject( world.GetTiles( info.tileIndex ), *info.info ) ) {
return false;
}
}

world.updatePassabilities();

return true;
}

Expand All @@ -120,26 +131,26 @@ namespace Maps
tile.setTerrain( info.terrainIndex, info.terrainFlag & 2, info.terrainFlag & 1 );
}

void readTileObject( Tiles & tile, const Map_Format::ObjectInfo & object )
bool readTileObject( Tiles & tile, const Map_Format::ObjectInfo & object )
{
const auto & objectInfos = getObjectsByGroup( object.group );
if ( object.index >= objectInfos.size() ) {
// This is a bad map format!
assert( 0 );
return;
return false;
}

// Object UID is set through global object UID counter. Therefore, we need to update it before running the operation.
if ( object.id == 0 ) {
// This object UID is not set!
assert( 0 );
return;
return false;
}

setLastObjectUID( object.id - 1 );
// We don't update map passabilities as it is a very expensive process.
// Let's do it once everything is being loaded.
setObjectOnTile( tile, objectInfos[object.index], false );
return setObjectOnTile( tile, objectInfos[object.index], false );
}

void writeTile( const Tiles & tile, Map_Format::TileInfo & info )
Expand Down
3 changes: 2 additions & 1 deletion src/fheroes2/maps/map_format_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@ namespace Maps
enum class ObjectGroup : int32_t;

bool readMapInEditor( const Map_Format::MapFormat & map );
bool readAllTiles( const Map_Format::MapFormat & map );

bool saveMapInEditor( Map_Format::MapFormat & map );

void readTileTerrain( Tiles & tile, const Map_Format::TileInfo & info );
void readTileObject( Tiles & tile, const Map_Format::ObjectInfo & object );
bool readTileObject( Tiles & tile, const Map_Format::ObjectInfo & object );

void writeTile( const Tiles & tile, Map_Format::TileInfo & info );

Expand Down
Loading
Loading