1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

- Fixed GCC compiler warnings

- Implemented move heroes to next scenario partially
This commit is contained in:
beegee1 2013-12-20 13:07:58 +00:00
parent 6b3ca831c1
commit 68bdf71db6
14 changed files with 222 additions and 198 deletions

View File

@ -301,7 +301,7 @@ FuzzyHelper::TacticalAdvantage::~TacticalAdvantage()
}
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec)
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec & vec)
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
{
if (vec.empty()) //no possibilities found
return sptr(Goals::Invalid());
@ -455,4 +455,4 @@ float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
{
logAi->debugStream() << boost::format("Cannot evaluate goal %s") % g.name();
return -1e10;
}
}

View File

@ -74,6 +74,6 @@ public:
ui64 estimateBankDanger (int ID);
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
Goals::TSubgoal chooseSolution (Goals::TGoalVec & vec);
Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
//shared_ptr<AbstractGoal> chooseSolution (std::vector<shared_ptr<AbstractGoal>> & vec);
};

View File

@ -503,7 +503,7 @@ std::string VisitTile::completeMessage() const
TSubgoal VisitTile::whatToDoToAchieve()
{
auto ret = fh->chooseSolution (getAllPossibleSubgoals());
auto ret = fh->chooseSolution(getAllPossibleSubgoals());
if (ret->hero)
{

View File

@ -311,7 +311,7 @@ const CGPathNode * CCallback::getPathInfo( int3 tile )
return &cl->pathInfo->nodes[tile.x][tile.y][tile.z];
}
const int CCallback::getDistance( int3 tile )
int CCallback::getDistance( int3 tile )
{
CGPath ret;
if (getPath2 (tile, ret))

View File

@ -108,7 +108,7 @@ public:
//client-specific functionalities (pathfinding)
virtual const CGPathNode *getPathInfo(int3 tile); //uses main, client pathfinder info
virtual const int getDistance(int3 tile);
virtual int getDistance(int3 tile);
virtual bool getPath2(int3 dest, CGPath &ret); //uses main, client pathfinder info
virtual void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1);

View File

@ -3557,7 +3557,7 @@ void CBonusSelection::updateBonusSelection()
boost::algorithm::replace_first(desc, "%s", replacement);
}
break;
case CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO:
case CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO:
{
auto superhero = ourCampaign->camp->scenarios[bonDescs[i].info2].strongestHero(PlayerColor(bonDescs[i].info1));
if (!superhero) logGlobal->warnStream() << "No superhero! How could it be transfered?";

View File

@ -171,20 +171,8 @@ void CMapHandler::roadsRiverTerrainInit()
for (int j=0-frameH;j<(int)sizes.y+frameH;j++)
ttiles[i][j].resize(sizes.z, 0, 0);
}
/*
//FIXME: unused?
// prepare the map
for (int i=0; i<sizes.x; i++) //by width
{
for (int j=0; j<sizes.y;j++) //by height
{
for (int k=0; k<sizes.z; ++k) //by levels
{
TerrainTile2 &pom(ttiles[i][j][k]);
}
}
}*/
}
void CMapHandler::borderAndTerrainBitmapInit()
{
CDefHandler * bord = CDefHandler::giveDef("EDG.DEF");

View File

@ -36,13 +36,10 @@ struct TerrainTile2
template <typename T> class PseudoV
{
public:
int offset;
std::vector<T> inver;
PseudoV(){};
PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill)
PseudoV() : offset(0) { }
PseudoV(std::vector<T> &src, int rest, int before, int after, const T& fill) : offset(before)
{
inver.resize(before + rest + after);
offset=before;
for(int i=0; i<before;i++)
inver[i] = fill;
for(int i=0;i<src.size();i++)
@ -67,6 +64,10 @@ public:
{
return inver.size();
}
private:
int offset;
std::vector<T> inver;
};
class CMapHandler

View File

@ -1099,14 +1099,127 @@ void CGameState::initHeroPlaceholders()
{
if (scenarioOps->campState)
{
logGlobal->debugStream() << "\tReplacing hero placeholders";
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campHeroReplacements = campaignHeroesToReplace();
//Replace placeholders with heroes from previous missions
logGlobal->debugStream() << "\tSetting up heroes";
placeCampaignHeroes(campHeroReplacements);
auto campaignScenario = getCampaignScenarioForCrossoverHeroes();
if(campaignScenario)
{
logGlobal->debugStream() << "\tPrepare crossover heroes";
auto crossoverHeroes = prepareCrossoverHeroes(campaignScenario);
logGlobal->debugStream() << "\tGenerate list of hero placeholders";
auto campaignHeroReplacements = generateCampaignHeroesToReplace(crossoverHeroes);
logGlobal->debugStream() << "\tReplace placeholders with heroes";
placeCampaignHeroes(campaignHeroReplacements);
}
}
}
const CCampaignScenario * CGameState::getCampaignScenarioForCrossoverHeroes() const
{
const CCampaignScenario * campaignScenario = nullptr;
auto campaignState = scenarioOps->campState;
auto bonus = campaignState->getBonusForCurrentMap();
if (bonus->type == CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO)
{
campaignScenario = &campaignState->camp->scenarios[bonus->info2];
}
else
{
if(!campaignState->mapsConquered.empty())
{
campaignScenario = &campaignState->camp->scenarios[campaignState->mapsConquered.back()];
}
}
return campaignScenario;
}
std::vector<CGHeroInstance *> CGameState::prepareCrossoverHeroes(const CCampaignScenario * campaignScenario)
{
auto crossoverHeroes = campaignScenario->crossoverHeroes; //TODO check if hero instances need to be copied
const auto & travelOptions = campaignScenario->travelOptions;
if (!(travelOptions.whatHeroKeeps & 1))
{
//trimming experience
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->initExp();
}
}
if (!(travelOptions.whatHeroKeeps & 2))
{
//trimming prim skills
for(CGHeroInstance * cgh : crossoverHeroes)
{
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
{
auto sel = Selector::type(Bonus::PRIMARY_SKILL)
.And(Selector::subtype(g))
.And(Selector::sourceType(Bonus::HERO_BASE_SKILL));
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
}
}
}
if (!(travelOptions.whatHeroKeeps & 4))
{
//trimming sec skills
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->secSkills = cgh->type->secSkillsInit;
}
}
if (!(travelOptions.whatHeroKeeps & 8))
{
//trimming spells
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->spells.clear();
cgh->eraseArtSlot(ArtifactPosition(ArtifactPosition::SPELLBOOK)); // spellbook will also be removed
}
}
if (!(travelOptions.whatHeroKeeps & 16))
{
//trimming artifacts
for(CGHeroInstance * hero : crossoverHeroes)
{
size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
for (size_t i=0; i<totalArts; i++ )
{
auto artifactPosition = ArtifactPosition(i);
if(artifactPosition == ArtifactPosition::SPELLBOOK) continue; // do not handle spellbook this way
const ArtSlotInfo *info = hero->getSlot(artifactPosition);
if(!info) continue;
const CArtifactInstance *art = info->artifact;
if(!art) continue;
int id = art->artType->id;
assert( 8*18 > id );//number of arts that fits into h3m format
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
if(!takeable) hero->eraseArtSlot(ArtifactPosition(i));
}
}
}
//trimming creatures
for(CGHeroInstance * cgh : crossoverHeroes)
{
vstd::erase_if(cgh->stacks, [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
{
CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) );
});
}
return std::move(crossoverHeroes);
}
void CGameState::placeStartingHeroes()
{
logGlobal->debugStream() << "\tGiving starting hero";
@ -2587,92 +2700,85 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
return ret;
}
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignHeroesToReplace()
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes)
{
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > ret;
auto replaceHero = [&](ObjectInstanceID objId, CGHeroInstance * ghi)
{
ret.push_back(std::make_pair(ghi, objId));
// ghi->tempOwner = getHumanPlayerInfo()[0]->color;
// ghi->id = objId;
// gs->map->objects[objId] = ghi;
// gs->map->heroes.push_back(ghi);
};
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroReplacements;
auto campaign = scenarioOps->campState;
if(auto bonus = campaign->getBonusForCurrentMap())
//selecting heroes by type
for(int g = 0; g < map->objects.size(); ++g)
{
std::vector<CGHeroInstance*> Xheroes;
if (bonus->type == CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO)
CGObjectInstance * obj = map->objects[g];
if (obj->ID == Obj::HERO_PLACEHOLDER)
{
Xheroes = campaign->camp->scenarios[bonus->info2].crossoverHeroes;
}
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
//selecting heroes by type
for(int g=0; g<map->objects.size(); ++g)
{
CGObjectInstance * obj = map->objects[g];
if (obj->ID == Obj::HERO_PLACEHOLDER)
const ObjectInstanceID gid = ObjectInstanceID(g);
if(hp->subID != 0xFF) //select by type
{
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
const ObjectInstanceID gid = ObjectInstanceID(g);
if(hp->subID != 0xFF) //select by type
bool found = false;
for(auto ghi : crossoverHeroes)
{
bool found = false;
for(auto ghi : Xheroes)
if (ghi->subID == hp->subID)
{
if (ghi->subID == hp->subID)
{
found = true;
replaceHero(gid, ghi);
Xheroes -= ghi;
break;
}
}
if (!found)
{
auto nh = new CGHeroInstance();
nh->initHero(HeroTypeID(hp->subID));
replaceHero(gid, nh);
found = true;
campaignHeroReplacements.push_back(std::make_pair(ghi, gid));
crossoverHeroes -= ghi;
break;
}
}
}
}
//selecting heroes by power
std::sort(Xheroes.begin(), Xheroes.end(), [](const CGHeroInstance * a, const CGHeroInstance * b)
{
return a->getHeroStrength() > b->getHeroStrength();
}); //sort, descending strength
for(int g=0; g<map->objects.size(); ++g)
{
CGObjectInstance * obj = map->objects[g];
if (obj->ID == Obj::HERO_PLACEHOLDER)
{
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
const ObjectInstanceID gid = ObjectInstanceID(g);
if (hp->subID == 0xFF) //select by power
if(!found)
{
if(Xheroes.size() > hp->power - 1)
replaceHero(gid, Xheroes[hp->power - 1]);
else
{
logGlobal->warnStream() << "Warning, no hero to replace!";
map->removeBlockVisTiles(hp, true);
delete hp;
map->objects[g] = nullptr;
}
//we don't have to remove hero from Xheroes because it would destroy the order and duplicates shouldn't happen
auto nh = new CGHeroInstance();
nh->initHero(HeroTypeID(hp->subID));
campaignHeroReplacements.push_back(std::make_pair(nh, gid));
}
//TODO delete hero placeholder
}
}
}
return ret;
//selecting heroes by power
std::sort(crossoverHeroes.begin(), crossoverHeroes.end(), [](const CGHeroInstance * a, const CGHeroInstance * b)
{
return a->getHeroStrength() > b->getHeroStrength();
}); //sort, descending strength
// sort hero placeholders descending power
std::vector<CGHeroPlaceholder *> heroPlaceholders;
for(int g = 0; g < map->objects.size(); ++g)
{
CGObjectInstance * obj = map->objects[g];
if(obj->ID == Obj::HERO_PLACEHOLDER)
{
CGHeroPlaceholder * hp = dynamic_cast<CGHeroPlaceholder*>(obj);
if(hp->subID == 0xFF) //select by power
{
heroPlaceholders.push_back(hp);
}
}
}
std::sort(heroPlaceholders.begin(), heroPlaceholders.end(), [](const CGHeroPlaceholder * a, const CGHeroPlaceholder * b)
{
return a->power > b->power;
});
for(int i = 0; i < heroPlaceholders.size(); ++i)
{
auto heroPlaceholder = heroPlaceholders[i];
if(crossoverHeroes.size() > i)
{
campaignHeroReplacements.push_back(std::make_pair(crossoverHeroes[i], heroPlaceholder->id));
}
else
{
map->removeBlockVisTiles(heroPlaceholder, true);
delete heroPlaceholder;
map->objects[heroPlaceholder->id.getNum()] = nullptr;
}
}
return campaignHeroReplacements;
}
void CGameState::placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements)

View File

@ -59,6 +59,7 @@ class CGGarrison;
class CGameInfo;
struct QuestInfo;
class CQuest;
class CCampaignScenario;
namespace boost
{
@ -445,7 +446,8 @@ public:
}
private:
// Init game state
// ----- initialization -----
void initNewGame();
void initCampaign();
void initDuel();
@ -456,6 +458,12 @@ private:
void randomizeObject(CGObjectInstance *cur);
void initPlayerStates();
void initHeroPlaceholders();
const CCampaignScenario * getCampaignScenarioForCrossoverHeroes() const;
std::vector<CGHeroInstance *> prepareCrossoverHeroes(const CCampaignScenario * campaignScenario);
// returns heroes and placeholders in where heroes will be put
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > generateCampaignHeroesToReplace(std::vector<CGHeroInstance *> & crossoverHeroes);
void placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
void placeStartingHeroes();
void initStartingResources();
@ -467,20 +475,23 @@ private:
void initMapObjects();
void initVisitingAndGarrisonedHeroes();
// Victory / Loss condition checks
// ----- victory, loss condition checks -----
EVictoryLossCheckResult checkForVictory(PlayerColor player) const; //checks if given player is winner
EVictoryLossCheckResult checkForLoss(PlayerColor player) const; //checks if given player is loser
PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game
// Bonus system handling
// ----- bonus system handling -----
void buildBonusSystemTree();
void attachArmedObjects();
void buildGlobalTeamPlayerTree();
void deserializationFix();
// ---- misc helpers -----
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroesToReplace(); //returns heroes and placeholders in where heroes will be put; may remove some placeholders
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
int pickHero(PlayerColor owner);

View File

@ -265,6 +265,8 @@ void CConnection::prepareForSendingHeroes()
savedPointers.clear();
disableSmartVectorMemberSerialization();
enableSmartPointerSerializatoin();
//disableSmartPointerSerializatoin();
disableStackSendingByID();
}
void CConnection::enterPregameConnectionMode()

View File

@ -242,7 +242,7 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buff
for (int g=0; g<numOfBonuses; ++g)
{
CScenarioTravel::STravelBonus bonus;
bonus.type = CScenarioTravel::STravelBonus::PLAYER_PREV_SCENARIO;
bonus.type = CScenarioTravel::STravelBonus::HEROES_FROM_PREVIOUS_SCENARIO;
bonus.info1 = buffer[outIt++]; //player color
bonus.info2 = buffer[outIt++]; //from what scenario
@ -322,87 +322,6 @@ bool CCampaignScenario::isNotVoid() const
return mapName.size() > 0;
}
void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> heroes )
{
crossoverHeroes = heroes;
if (!(travelOptions.whatHeroKeeps & 1))
{
//trimming experience
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->initExp();
}
}
if (!(travelOptions.whatHeroKeeps & 2))
{
//trimming prim skills
for(CGHeroInstance * cgh : crossoverHeroes)
{
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
{
auto sel = Selector::type(Bonus::PRIMARY_SKILL)
.And(Selector::subtype(g))
.And(Selector::sourceType(Bonus::HERO_BASE_SKILL));
cgh->getBonusLocalFirst(sel)->val = cgh->type->heroClass->primarySkillInitial[g];
}
}
}
if (!(travelOptions.whatHeroKeeps & 4))
{
//trimming sec skills
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->secSkills = cgh->type->secSkillsInit;
}
}
if (!(travelOptions.whatHeroKeeps & 8))
{
//trimming spells
for(CGHeroInstance * cgh : crossoverHeroes)
{
cgh->spells.clear();
}
}
if (!(travelOptions.whatHeroKeeps & 16))
{
//trimming artifacts
for(CGHeroInstance * hero : crossoverHeroes)
{
size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
for (size_t i=0; i<totalArts; i++ )
{
const ArtSlotInfo *info = hero->getSlot(ArtifactPosition(i));
if (!info)
continue;
const CArtifactInstance *art = info->artifact;
if (!art)//FIXME: check spellbook and catapult behaviour
continue;
int id = art->artType->id;
assert( 8*18 > id );//number of arts that fits into h3m format
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
if (!takeable)
hero->eraseArtSlot(ArtifactPosition(i));
}
}
}
//trimming creatures
for(CGHeroInstance * cgh : crossoverHeroes)
{
vstd::erase_if(cgh->stacks, [&](const std::pair<SlotID, CStackInstance *> & j) -> bool
{
CreatureID::ECreatureID crid = j.second->getCreatureID().toEnum();
return !(travelOptions.monstersKeptByHero[crid / 8] & (1 << (crid % 8)) );
});
}
}
const CGHeroInstance * CCampaignScenario::strongestHero( PlayerColor owner ) const
{
using boost::adaptors::filtered;
@ -431,9 +350,9 @@ bool CScenarioTravel::STravelBonus::isBonusForHero() const
// mapsRemaining.push_back(i);
// }
void CCampaignState::mapConquered( const std::vector<CGHeroInstance*> & heroes )
void CCampaignState::setCurrentMapAsConquered( const std::vector<CGHeroInstance*> & heroes )
{
camp->scenarios[*currentMap].prepareCrossoverHeroes(heroes);
camp->scenarios[*currentMap].crossoverHeroes = heroes;
mapsConquered.push_back(*currentMap);
mapsRemaining -= *currentMap;
camp->scenarios[*currentMap].conquered = true;

View File

@ -59,7 +59,7 @@ public:
struct DLL_LINKAGE STravelBonus
{
enum EBonusType {SPELL, MONSTER, BUILDING, ARTIFACT, SPELL_SCROLL, PRIMARY_SKILL, SECONDARY_SKILL, RESOURCE,
PLAYER_PREV_SCENARIO, HERO};
HEROES_FROM_PREVIOUS_SCENARIO, HERO};
EBonusType type; //uses EBonusType
si32 info1, info2, info3; //purpose depends on type
@ -108,7 +108,7 @@ public:
SScenarioPrologEpilog prolog, epilog;
CScenarioTravel travelOptions;
std::vector<CGHeroInstance *> crossoverHeroes;
std::vector<CGHeroInstance *> crossoverHeroes; // contains all heroes with the same state when the camapign scenario was finished
const CGHeroInstance * strongestHero(PlayerColor owner) const;
void loadPreconditionRegions(ui32 regions);
@ -150,7 +150,7 @@ public:
std::map<ui8, ui8> chosenCampaignBonuses;
//void initNewCampaign(const StartInfo &si);
void mapConquered(const std::vector<CGHeroInstance*> & heroes);
void setCurrentMapAsConquered(const std::vector<CGHeroInstance*> & heroes);
boost::optional<CScenarioTravel::STravelBonus> getBonusForCurrentMap() const;
const CCampaignScenario &getCurrentScenario() const;
ui8 currentBonusID() const;

View File

@ -5108,15 +5108,12 @@ void CGameHandler::checkVictoryLossConditionsForPlayer(PlayerColor player)
if(gs->scenarioOps->campState)
{
std::vector<CGHeroInstance *> hes;
for(CGHeroInstance * ghi : gs->map->heroesOnMap)
std::vector<CGHeroInstance *> heroesBelongingToPlayer;
for(CGHeroInstance * hero : gs->map->heroesOnMap)
{
if (ghi->tempOwner == player)
{
hes.push_back(ghi);
}
if(hero->tempOwner == player) heroesBelongingToPlayer.push_back(hero);
}
gs->scenarioOps->campState->mapConquered(hes);
gs->scenarioOps->campState->setCurrentMapAsConquered(heroesBelongingToPlayer);
//Request clients to change connection mode
PrepareForAdvancingCampaign pfac;