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

Standartize metadata for all objects on Adventure Map #7084

Merged
merged 54 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
05c5444
Standartize metadata for all objects on Adventure Map
ihhub Apr 30, 2023
41bf335
Code style fix
ihhub Apr 30, 2023
139afb0
Update copyright year
ihhub Apr 30, 2023
1435df6
Address some issues
ihhub Apr 30, 2023
cf5d01d
Add default
ihhub Apr 30, 2023
62592ac
Remove extra comments
ihhub Apr 30, 2023
239a413
Avoid implicit casting
ihhub Apr 30, 2023
6164fb8
Make IWYU happy
ihhub Apr 30, 2023
095bd3b
Update logic
ihhub Apr 30, 2023
d57a2ae
Merge branch 'master' into quantity_eradication
ihhub Apr 30, 2023
1fa11b5
Fix compilation and code style
ihhub Apr 30, 2023
811d21a
Fix clang-tidy suggestions
ihhub Apr 30, 2023
1d6b8d0
Simplify logic
ihhub Apr 30, 2023
8801280
Fix styling
ihhub Apr 30, 2023
c95d8bf
Add more fixes
ihhub Apr 30, 2023
4ee0198
Add more checks
ihhub Apr 30, 2023
67739b8
More fixes
ihhub Apr 30, 2023
66b9ade
Fix Shipwreck survivor old save conversion
ihhub Apr 30, 2023
6b63b05
Remove unused code
ihhub Apr 30, 2023
2b3fcdf
Fix clang-tidy complaint
ihhub Apr 30, 2023
19b7706
Make IWYU happy
ihhub Apr 30, 2023
5c8aab5
Fix broken mines
ihhub Apr 30, 2023
89e496e
Merge branch 'master' into quantity_eradication
ihhub May 1, 2023
da0fa77
Remove any metadata from other objects which we don't update
ihhub May 1, 2023
b90d388
Fix metadata for heroes
ihhub May 1, 2023
fe18654
Fix code style
ihhub May 1, 2023
71cc388
Fix Gold Mines loaded from old save files
ihhub May 1, 2023
1557967
Add more checks and simplify logic
ihhub May 1, 2023
a9bbafe
Fix OBJ_SHIPWRECK from old save files
ihhub May 1, 2023
f64933f
Add an extra assertion
ihhub May 1, 2023
6da5e37
Fix missing retrieved Wagon resources
ihhub May 1, 2023
d9831de
Fix View World crash
ihhub May 1, 2023
913709a
Fix gold mine income and old Abandoned map loading
ihhub May 1, 2023
a070079
Fix broken Mines and Derelict Ship assertions
ihhub May 1, 2023
8482cdc
Add TODO comments
ihhub May 1, 2023
d1bc09d
Fix Abandoned Map loading logic
ihhub May 1, 2023
d06ac6c
Fix broken Mines
ihhub May 1, 2023
bba3f32
Remove extra space
ihhub May 1, 2023
ecdf0b2
Remove extra empty line
ihhub May 1, 2023
16abbc9
Fix displaying 0 resources while picking up
ihhub May 2, 2023
889a5fc
Address given comments
ihhub May 2, 2023
8f18c28
Fix erased objects
ihhub May 2, 2023
e8fc1cf
Erase metadata for event
ihhub May 2, 2023
3b07b9e
Fix Ultimate Artifact metadata
ihhub May 2, 2023
f024d3f
Add more checks and comments
ihhub May 3, 2023
a6507c5
Remove unused method
ihhub May 3, 2023
9a3ab43
Code cleanup
ihhub May 3, 2023
649250b
Fix Skeleton artifact bug
ihhub May 3, 2023
96c3378
Fix Genie's Lamp crash
ihhub May 3, 2023
9fdc6df
Fix Daemon Cave after battle conditions
ihhub May 3, 2023
809c462
Fix Tree of Knowledge unknown resource warning log
ihhub May 3, 2023
31b7c6d
Do not show extra logs for unknown resources of 0 quantity
ihhub May 4, 2023
ab5d49b
Address comments
ihhub May 4, 2023
eec9c1b
Fix spelling
ihhub May 5, 2023
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
46 changes: 29 additions & 17 deletions src/engine/serialize.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2019 - 2022 *
* Copyright (C) 2019 - 2023 *
* *
* Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 *
* Copyright (C) 2012 by Andrey Afletdinov <fheroes2@gmail.com> *
Expand All @@ -25,12 +25,14 @@
#define H2SERIALIZE_H

#include <algorithm>
#include <array>
#include <cstdint>
#include <cstdio>
#include <iterator>
#include <list>
#include <map>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
Expand Down Expand Up @@ -112,25 +114,25 @@ class StreamBase
put8( ch );
}

StreamBase & operator>>( bool & );
StreamBase & operator>>( char & );
StreamBase & operator>>( uint8_t & );
StreamBase & operator>>( uint16_t & );
StreamBase & operator>>( int16_t & );
StreamBase & operator>>( uint32_t & );
StreamBase & operator>>( int32_t & );
StreamBase & operator>>( std::string & );
StreamBase & operator>>( bool & v );
StreamBase & operator>>( char & v );
StreamBase & operator>>( uint8_t & v );
StreamBase & operator>>( uint16_t & v );
StreamBase & operator>>( int16_t & v );
StreamBase & operator>>( uint32_t & v );
StreamBase & operator>>( int32_t & v );
StreamBase & operator>>( std::string & v );

StreamBase & operator>>( fheroes2::Point & point_ );

StreamBase & operator<<( const bool );
StreamBase & operator<<( const char );
StreamBase & operator<<( const uint8_t );
StreamBase & operator<<( const uint16_t );
StreamBase & operator<<( const int16_t );
StreamBase & operator<<( const uint32_t );
StreamBase & operator<<( const int32_t );
StreamBase & operator<<( const std::string & );
StreamBase & operator<<( const bool v );
StreamBase & operator<<( const char v );
StreamBase & operator<<( const uint8_t v );
StreamBase & operator<<( const uint16_t v );
StreamBase & operator<<( const int16_t v );
StreamBase & operator<<( const uint32_t v );
StreamBase & operator<<( const int32_t v );
StreamBase & operator<<( const std::string & v );

StreamBase & operator<<( const fheroes2::Point & point_ );

Expand Down Expand Up @@ -206,6 +208,16 @@ class StreamBase
return *this;
}

template <class Type, size_t Count>
StreamBase & operator<<( const std::array<Type, Count> & data )
{
put32( static_cast<uint32_t>( data.size() ) );
for ( const auto & value : data ) {
*this << value;
}
return *this;
}

protected:
size_t flags;

Expand Down
64 changes: 36 additions & 28 deletions src/fheroes2/ai/ai_hero_action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
#include "math_base.h"
#include "monster.h"
#include "mp2.h"
#include "pairs.h"
#include "payment.h"
#include "players.h"
#include "puzzle.h"
Expand Down Expand Up @@ -516,8 +515,9 @@ namespace
{
Maps::Tiles & tile = world.GetTiles( dst_index );

if ( objectType != MP2::OBJ_BOTTLE )
if ( objectType != MP2::OBJ_BOTTLE ) {
hero.GetKingdom().AddFundsResource( getFundsFromTile( tile ) );
}

tile.RemoveObjectSprite();
resetObjectInfoOnTile( tile );
Expand All @@ -529,7 +529,10 @@ namespace
void AIToTreasureChest( Heroes & hero, const MP2::MapObjectType objectType, int32_t dst_index )
{
Maps::Tiles & tile = world.GetTiles( dst_index );
uint32_t gold = getGoldAmountFromTile( tile );
const Funds funds = getFundsFromTile( tile );

assert( funds.gold > 0 || funds.GetValidItemsCount() == 0 );
uint32_t gold = funds.gold;

Kingdom & kingdom = hero.GetKingdom();

Expand Down Expand Up @@ -608,7 +611,9 @@ namespace
if ( !hero.isFriends( getColorFromTile( tile ) ) ) {
auto removeObjectProtection = [&tile]() {
// Clear any metadata related to spells
tile.clearAdditionalMetadata();
if ( tile.GetObject( false ) == MP2::OBJ_MINES ) {
removeMineSpellFromTile( tile );
}
};

auto captureObject = [&hero, &tile, &removeObjectProtection]() {
Expand Down Expand Up @@ -659,10 +664,7 @@ namespace
void AIToObjectResource( Heroes & hero, const MP2::MapObjectType objectType, int32_t dst_index )
{
Maps::Tiles & tile = world.GetTiles( dst_index );
const ResourceCount & rc = getResourcesFromTile( tile );

if ( rc.isValid() )
hero.GetKingdom().AddFundsResource( Funds( rc ) );
hero.GetKingdom().AddFundsResource( getFundsFromTile( tile ) );

if ( MP2::isCaptureObject( objectType ) )
AIToCaptureObject( hero, objectType, dst_index );
Expand All @@ -677,7 +679,6 @@ namespace
{
Maps::Tiles & tile = world.GetTiles( dst_index );

// artifact
if ( doesTileContainValuableItems( tile ) ) {
const Artifact & art = getArtifactFromTile( tile );

Expand Down Expand Up @@ -919,7 +920,7 @@ namespace

void AIToWitchsHut( Heroes & hero, int32_t dst_index )
{
const Skill::Secondary & skill = getSecondarySkillFromTile( world.GetTiles( dst_index ) );
const Skill::Secondary & skill = getSecondarySkillFromWitchsHut( world.GetTiles( dst_index ) );

// check full
if ( skill.isValid() && !hero.HasMaxSecondarySkill() && !hero.HasSecondarySkill( skill.Skill() ) )
Expand Down Expand Up @@ -1074,7 +1075,10 @@ namespace
void AIToPoorMoraleObject( Heroes & hero, const MP2::MapObjectType objectType, int32_t dst_index )
{
Maps::Tiles & tile = world.GetTiles( dst_index );
uint32_t gold = getGoldAmountFromTile( tile );
const Funds funds = getFundsFromTile( tile );
assert( funds.gold > 0 || funds.GetValidItemsCount() == 0 );

uint32_t gold = funds.gold;
bool complete = false;

if ( gold ) {
Expand All @@ -1084,10 +1088,15 @@ namespace
if ( res.AttackerWins() ) {
hero.IncreaseExperience( res.GetExperienceAttacker() );
complete = true;
const Artifact & art = getArtifactFromTile( tile );

if ( art.isValid() && !hero.PickupArtifact( art ) )
Artifact art;
if ( isArtifactObject( objectType ) ) {
art = getArtifactFromTile( tile );
}

if ( art.isValid() && !hero.PickupArtifact( art ) ) {
gold = GoldInsteadArtifact( objectType );
}

hero.GetKingdom().AddFundsResource( Funds( Resource::GOLD, gold ) );
}
Expand Down Expand Up @@ -1162,14 +1171,14 @@ namespace
const Maps::Tiles & tile = world.GetTiles( dst_index );

if ( !hero.isVisited( tile ) ) {
const Funds & funds = getFundsFromTile( tile );
const Funds & payment = getTreeOfKnowledgeRequirement( tile );

if ( 0 == funds.GetValidItemsCount() || hero.GetKingdom().AllowPayment( funds ) ) {
if ( 0 == payment.GetValidItemsCount() || hero.GetKingdom().AllowPayment( payment ) ) {
const int level = hero.GetLevel();
assert( level > 0 );
const uint32_t experience = Heroes::GetExperienceFromLevel( level ) - Heroes::GetExperienceFromLevel( level - 1 );

hero.GetKingdom().OddFundsResource( funds );
hero.GetKingdom().OddFundsResource( payment );
hero.SetVisited( dst_index );
hero.IncreaseExperience( experience );
}
Expand All @@ -1188,7 +1197,7 @@ namespace
Battle::Result res = Battle::Loader( hero.GetArmy(), army, dst_index );
if ( res.AttackerWins() ) {
hero.IncreaseExperience( res.GetExperienceAttacker() );
hero.GetKingdom().AddFundsResource( Funds( Resource::GOLD, 2500 ) );
hero.GetKingdom().AddFundsResource( getFundsFromTile( tile ) );
}
else {
AIBattleLose( hero, res, true );
Expand Down Expand Up @@ -1383,26 +1392,25 @@ namespace
Maps::Tiles & tile = world.GetTiles( dst_index );

if ( !hero.IsFullBagArtifacts() ) {
uint32_t cond = tile.QuantityVariant();
Artifact art = getArtifactFromTile( tile );
const Maps::ArtifactCaptureCondition condition = getArtifactCaptureCondition( tile );
const Artifact art = getArtifactFromTile( tile );

bool result = false;

// 1,2,3 - gold, gold + res
if ( 0 < cond && cond < 4 ) {
const Funds payment = getFundsFromTile( tile );
if ( condition == Maps::ArtifactCaptureCondition::PAY_2000_GOLD || condition == Maps::ArtifactCaptureCondition::PAY_2500_GOLD_AND_3_RESOURCES
|| condition == Maps::ArtifactCaptureCondition::PAY_3000_GOLD_AND_5_RESOURCES ) {
const Funds payment = getArtifactResourceRequirement( tile );

if ( hero.GetKingdom().AllowPayment( payment ) ) {
result = true;
hero.GetKingdom().OddFundsResource( payment );
}
}
// 4,5 - bypass wisdom and leadership requirement
else if ( 3 < cond && cond < 6 ) {
else if ( condition == Maps::ArtifactCaptureCondition::HAVE_WISDOM_SKILL || condition == Maps::ArtifactCaptureCondition::HAVE_LEADERSHIP_SKILL ) {
// TODO: do we need to check this condition?
result = true;
}
// 6 - 50 rogues, 7 - 1 genie, 8,9,10,11,12,13 - 1 monster level4
else if ( 5 < cond && cond < 14 ) {
else if ( condition >= Maps::ArtifactCaptureCondition::FIGHT_50_ROGUES && condition <= Maps::ArtifactCaptureCondition::FIGHT_1_BONE_DRAGON ) {
Army army( tile );

// new battle
Expand Down Expand Up @@ -1588,9 +1596,9 @@ namespace AI
break;

// pickup object
case MP2::OBJ_RESOURCE:
case MP2::OBJ_BOTTLE:
case MP2::OBJ_CAMPFIRE:
case MP2::OBJ_RESOURCE:
AIToPickupResource( hero, objectType, dst_index );
break;

Expand All @@ -1602,8 +1610,8 @@ namespace AI
AIToArtifact( hero, dst_index );
break;

case MP2::OBJ_MAGIC_GARDEN:
case MP2::OBJ_LEAN_TO:
case MP2::OBJ_MAGIC_GARDEN:
case MP2::OBJ_WINDMILL:
case MP2::OBJ_WATER_WHEEL:
AIToObjectResource( hero, objectType, dst_index );
Expand Down
39 changes: 22 additions & 17 deletions src/fheroes2/ai/normal/ai_normal_hero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,25 +231,26 @@ namespace
return doesTileContainValuableItems( tile );

case MP2::OBJ_ARTIFACT: {
const uint32_t variants = tile.QuantityVariant();

if ( hero.IsFullBagArtifacts() )
return false;

// 1,2,3 - 2000g, 2500g+3res, 3000g+5res
if ( 1 <= variants && 3 >= variants )
return kingdom.AllowPayment( getFundsFromTile( tile ) );
const Maps::ArtifactCaptureCondition condition = getArtifactCaptureCondition( tile );

if ( condition == Maps::ArtifactCaptureCondition::PAY_2000_GOLD || condition == Maps::ArtifactCaptureCondition::PAY_2500_GOLD_AND_3_RESOURCES
|| condition == Maps::ArtifactCaptureCondition::PAY_3000_GOLD_AND_5_RESOURCES ) {
return kingdom.AllowPayment( getArtifactResourceRequirement( tile ) );
}

// 4,5 - need to have skill wisdom or leadership
if ( 3 < variants && 6 > variants )
return hero.HasSecondarySkill( getSecondarySkillFromTile( tile ).Skill() );
if ( condition == Maps::ArtifactCaptureCondition::HAVE_WISDOM_SKILL || condition == Maps::ArtifactCaptureCondition::HAVE_LEADERSHIP_SKILL ) {
return hero.HasSecondarySkill( getArtifactSecondarySkillRequirement( tile ).Skill() );
}

// 6 - 50 rogues, 7 - 1 gin, 8,9,10,11,12,13 - 1 monster level4
if ( 5 < variants && 14 > variants ) {
if ( condition >= Maps::ArtifactCaptureCondition::FIGHT_50_ROGUES && condition <= Maps::ArtifactCaptureCondition::FIGHT_1_BONE_DRAGON ) {
return isHeroStrongerThan( tile, objectType, ai, heroArmyStrength, AI::ARMY_ADVANTAGE_LARGE );
}

// It is a normal artifact.
// No conditions to capture an artifact exist.
return true;
}

Expand Down Expand Up @@ -303,7 +304,7 @@ namespace

// One time visit Secondary Skill object.
case MP2::OBJ_WITCHS_HUT: {
const Skill::Secondary & skill = getSecondarySkillFromTile( tile );
const Skill::Secondary & skill = getSecondarySkillFromWitchsHut( tile );
const int skillType = skill.Skill();

if ( !skill.isValid() || hero.HasMaxSecondarySkill() || hero.HasSecondarySkill( skillType ) ) {
Expand All @@ -325,9 +326,9 @@ namespace

case MP2::OBJ_TREE_OF_KNOWLEDGE:
if ( !hero.isVisited( tile ) ) {
const ResourceCount & rc = getResourcesFromTile( tile );
const Funds & rc = getTreeOfKnowledgeRequirement( tile );
// If the payment is required do not waste all resources from the kingdom. Use them wisely.
if ( !rc.isValid() || kingdom.AllowPayment( Funds( rc ) * 5 ) ) {
if ( rc.GetValidItemsCount() == 0 || kingdom.AllowPayment( rc * 5 ) ) {
return true;
}
}
Expand Down Expand Up @@ -504,8 +505,9 @@ namespace
break;

case MP2::OBJ_DAEMON_CAVE:
if ( doesTileContainValuableItems( tile ) && 4 != tile.QuantityVariant() )
if ( doesTileContainValuableItems( tile ) && getDaemonCaveBonusType( tile ) != Maps::DaemonCaveCaptureBonus::PAY_2500_GOLD ) {
return isHeroStrongerThan( tile, objectType, ai, heroArmyStrength, AI::ARMY_ADVANTAGE_MEDIUM );
}
break;

case MP2::OBJ_MONSTER:
Expand Down Expand Up @@ -887,7 +889,7 @@ namespace AI
if ( getColorFromTile( tile ) == hero.GetColor() ) {
return -valueToIgnore; // don't even attempt to go here
}
const int resource = getResourcesFromTile( tile ).first;
const int resource = getDailyIncomeObjectResources( tile ).getFirstValidResource().first;
const double value = 20.0 * getResourcePriorityModifier( resource );
return ( resource == Resource::GOLD ) ? value * 100.0 : value;
}
Expand Down Expand Up @@ -921,7 +923,10 @@ namespace AI
return 1000.0 * art.getArtifactValue();
}

return getGoldAmountFromTile( tile );
const Funds funds = getFundsFromTile( tile );
assert( funds.gold > 0 || funds.GetValidItemsCount() == 0 );

return funds.gold;
}

case MP2::OBJ_DAEMON_CAVE:
Expand Down Expand Up @@ -1469,7 +1474,7 @@ namespace AI
if ( getColorFromTile( tile ) == hero.GetColor() ) {
return -dangerousTaskPenalty; // don't even attempt to go here
}
return ( getResourcesFromTile( tile ).first == Resource::GOLD ) ? tenTiles : fiveTiles;
return ( getDailyIncomeObjectResources( tile ).gold > 0 ) ? tenTiles : fiveTiles;
}
case MP2::OBJ_CAMPFIRE:
case MP2::OBJ_FLOTSAM:
Expand Down
Loading