Skip to content

Commit

Permalink
Fix a bug when picking up an object whose type does not match its spr…
Browse files Browse the repository at this point in the history
…ite on the map (#9326)
  • Loading branch information
Districh-ru authored Dec 11, 2024
1 parent 80d8371 commit bf9b9af
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 15 deletions.
44 changes: 30 additions & 14 deletions src/fheroes2/heroes/heroes_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,18 +221,29 @@ namespace
I.setRedraw( Interface::REDRAW_RADAR );
}

void runActionObjectFadeOutAnumation( const Maps::Tile & tile, const MP2::MapObjectType objectType )
void runActionObjectFadeOutAnimation( const Maps::Tile & tile, const MP2::MapObjectType objectType )
{
uint32_t objectUID = 0;

if ( Maps::getObjectTypeByIcn( tile.getMainObjectPart().icnType, tile.getMainObjectPart().icnIndex ) == objectType ) {
// There are original hacked maps (or made with exploitation of the original Editor's bugs) that have wrong object type in relation to its image sprite.
// So, we also search for object ID by checking if the object is an action type because one tile can have only one action object.
MP2::MapObjectType actualObjectType = MP2::OBJ_NONE;
const bool isActionObject = MP2::isInGameActionObject( objectType );

if ( const MP2::MapObjectType mainObjectType = Maps::getObjectTypeByIcn( tile.getMainObjectPart().icnType, tile.getMainObjectPart().icnIndex );
mainObjectType == objectType || ( isActionObject && MP2::isInGameActionObject( mainObjectType ) ) ) {
objectUID = tile.getMainObjectPart()._uid;

actualObjectType = mainObjectType;
}
else {
// In maps made by the original map editor the action object can be in the ground layer.
for ( auto iter = tile.getGroundObjectParts().rbegin(); iter != tile.getGroundObjectParts().rend(); ++iter ) {
if ( Maps::getObjectTypeByIcn( iter->icnType, iter->icnIndex ) == objectType ) {
if ( const MP2::MapObjectType partObjectType = Maps::getObjectTypeByIcn( iter->icnType, iter->icnIndex );
partObjectType == objectType || ( isActionObject && MP2::isInGameActionObject( partObjectType ) ) ) {
objectUID = iter->_uid;

actualObjectType = partObjectType;
break;
}
}
Expand All @@ -243,6 +254,12 @@ namespace
Interface::AdventureMap & I = Interface::AdventureMap::Get();
I.getGameArea().runSingleObjectAnimation( std::make_shared<Interface::ObjectFadingOutInfo>( objectUID, tile.GetIndex(), objectType ) );

// If there is a map bug the Object Animation destructor is not able to properly remove this object from the map.
if ( actualObjectType != objectType && actualObjectType != MP2::OBJ_NONE ) {
// Remove an object by its actual sprite type.
removeObjectFromTileByType( tile, actualObjectType );
}

// Update radar in the place of the removed object.
I.getRadar().SetRenderArea( { Maps::GetPoint( tile.GetIndex() ), { 1, 1 } } );
I.setRedraw( Interface::REDRAW_RADAR );
Expand All @@ -259,7 +276,7 @@ namespace
if ( remove && recruit == troop.GetCount() ) {
Game::PlayPickupSound();

runActionObjectFadeOutAnumation( tile, tile.getMainObjectType() );
runActionObjectFadeOutAnimation( tile, tile.getMainObjectType() );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -453,7 +470,7 @@ namespace

assert( tile.getMainObjectType() == MP2::OBJ_MONSTER );

runActionObjectFadeOutAnumation( tile, MP2::OBJ_MONSTER );
runActionObjectFadeOutAnimation( tile, MP2::OBJ_MONSTER );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -723,8 +740,6 @@ namespace

Maps::Tile & tile = world.getTile( dst_index );

Interface::AdventureMap & I = Interface::AdventureMap::Get();

if ( objectType == MP2::OBJ_BOTTLE ) {
const MapSign * sign = dynamic_cast<MapSign *>( world.GetMapObject( dst_index ) );
fheroes2::showStandardTextMessage( MP2::StringObject( objectType ), ( sign ? sign->message : "No message provided" ), Dialog::OK );
Expand All @@ -741,6 +756,7 @@ namespace
else {
const auto resource = funds.getFirstValidResource();

Interface::AdventureMap & I = Interface::AdventureMap::Get();
I.getStatusPanel().SetResource( resource.first, resource.second );
I.setRedraw( Interface::REDRAW_STATUS );
}
Expand All @@ -750,7 +766,7 @@ namespace

Game::PlayPickupSound();

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -950,7 +966,7 @@ namespace

Game::PlayPickupSound();

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -1571,7 +1587,7 @@ namespace

Game::PlayPickupSound();

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -1754,7 +1770,7 @@ namespace

assert( tile.getMainObjectType() == MP2::OBJ_ARTIFACT );

runActionObjectFadeOutAnumation( tile, MP2::OBJ_ARTIFACT );
runActionObjectFadeOutAnimation( tile, MP2::OBJ_ARTIFACT );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -1858,7 +1874,7 @@ namespace

Game::PlayPickupSound();

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );

resetObjectMetadata( tile );
}
Expand Down Expand Up @@ -3308,7 +3324,7 @@ namespace
_( "In a dazzling display of daring, you break into the local jail and free the hero imprisoned there, who, in return, pledges loyalty to your cause." ),
Dialog::OK );

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );

// TODO: add hero fading in animation together with jail animation.
Heroes * prisoner = world.FromJailHeroes( dst_index );
Expand Down Expand Up @@ -3563,7 +3579,7 @@ namespace

AudioManager::PlaySound( M82::KILLFADE );

runActionObjectFadeOutAnumation( tile, objectType );
runActionObjectFadeOutAnimation( tile, objectType );
}
else {
fheroes2::showStandardTextMessage(
Expand Down
19 changes: 18 additions & 1 deletion src/fheroes2/maps/maps_tiles_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2260,7 +2260,24 @@ namespace Maps
assert( isFirstLoad );

if ( tile.isWater() ) {
tile.setMainObjectType( MP2::OBJ_SEA_CHEST );
// On original map "Alteris 2" there is a treasure chest placed on the water and there might be other maps with such bug.
// If there is a bug then remove of the MP2::OBJ_TREASURE_CHEST will return 'true' and we can replace it with a Sea Chest object.
if ( removeObjectFromTileByType( tile, MP2::OBJ_TREASURE_CHEST ) ) {
const auto & objects = Maps::getObjectsByGroup( Maps::ObjectGroup::ADVENTURE_WATER );

for ( size_t i = 0; i < objects.size(); ++i ) {
if ( objects[i].objectType == MP2::OBJ_SEA_CHEST ) {
const auto & objectInfo = Maps::getObjectInfo( Maps::ObjectGroup::ADVENTURE_WATER, static_cast<int32_t>( i ) );
setObjectOnTile( tile, objectInfo, true );

break;
}
}
}
else {
tile.setMainObjectType( MP2::OBJ_SEA_CHEST );
}

updateObjectInfoTile( tile, isFirstLoad );
return;
}
Expand Down

0 comments on commit bf9b9af

Please sign in to comment.