From dc091a1ce1099c929740447d2e147441a8c0ebe6 Mon Sep 17 00:00:00 2001 From: mateuszb Date: Tue, 5 Feb 2013 23:16:13 +0000 Subject: [PATCH] * some work on hero crossover; still buggy --- client/VCMI_client.vcxproj | 13 +++++++ lib/CGameState.cpp | 75 +++++++++++++++++++------------------- lib/CGameState.h | 24 ++---------- lib/IGameCallback.cpp | 26 ------------- lib/IGameCallback.h | 1 - server/CGameHandler.cpp | 16 ++++---- server/CGameHandler.h | 2 +- 7 files changed, 62 insertions(+), 95 deletions(-) diff --git a/client/VCMI_client.vcxproj b/client/VCMI_client.vcxproj index 71ec7df31..40eec740b 100644 --- a/client/VCMI_client.vcxproj +++ b/client/VCMI_client.vcxproj @@ -92,6 +92,19 @@ + + C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;$(SolutionDir)..\include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib;$(SolutionDir)..\libs\$(PlatformShortName);$(VCMI_Out);$(LibraryPath) + + + C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;$(SolutionDir)..\include;$(IncludePath) + + + C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;$(SolutionDir)..\include;$(IncludePath) + + + C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Include;$(SolutionDir)..\include;$(IncludePath) + /MP4 %(AdditionalOptions) diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 2abf5819b..3c33245de 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -588,6 +588,9 @@ std::pair CGameState::pickObject (CGObjectInstance *obj) { for(ui32 i=0;iobjects.size();i++) { + if(!map->objects[i]) + continue; + if(map->objects[i]->ID==Obj::RANDOM_TOWN && dynamic_cast(map->objects[i].get())->identifier == info->identifier) { @@ -853,13 +856,6 @@ void CGameState::init(StartInfo * si) return ret; }; - auto replaceHero = [&](int objId, CGHeroInstance * ghi) - { - ghi->id = objId; - gs->map->objects[objId] = ghi; - gs->map->heroes.push_back(ghi); - }; - tlog0 << "\tUsing random seed: "<< si->seedToBeUsed << std::endl; ran.seed((boost::int32_t)si->seedToBeUsed); scenarioOps = new StartInfo(*si); @@ -995,7 +991,7 @@ void CGameState::init(StartInfo * si) //remove tiles with holes for(ui32 no=0; noobjects.size(); ++no) - if(map->objects[no]->ID == Obj::HOLE) + if(map->objects[no] && map->objects[no]->ID == Obj::HOLE) allowedPos -= map->objects[no]->pos; if(allowedPos.size()) @@ -1023,6 +1019,9 @@ void CGameState::init(StartInfo * si) tlog4 << "\tRandomizing objects"; BOOST_FOREACH(CGObjectInstance *obj, map->objects) { + if(!obj) + continue; + randomizeObject(obj); obj->hoverName = VLC->generaltexth->names[obj->ID]; @@ -1095,6 +1094,14 @@ void CGameState::init(StartInfo * si) tlog4 << "\tReplacing hero placeholders"; if (scenarioOps->campState) { + auto replaceHero = [&](int objId, CGHeroInstance * ghi) + { + ghi->tempOwner = getHumanPlayerInfo()[0]->color; + ghi->id = objId; + gs->map->objects[objId] = ghi; + gs->map->heroes.push_back(ghi); + }; + auto campaign = scenarioOps->campState; auto bonus = campaign->getBonusForCurrentMap(); @@ -1158,7 +1165,12 @@ void CGameState::init(StartInfo * si) if(Xheroes.size() > hp->power - 1) replaceHero(g, Xheroes[hp->power - 1]); else - tlog2 << "Warning, no hero to replace!\n"; + { + tlog3 << "Warning, no hero to replace!\n"; + map->removeBlockVisTiles(hp, true); + delete hp; + map->objects[g] = NULL; + } //we don't have to remove hero from Xheroes because it would destroy the order and duplicates shouldn't happen } } @@ -1235,15 +1247,18 @@ void CGameState::init(StartInfo * si) tlog2 << "Warning - hero with uninitialized owner!\n"; continue; } - CGHeroInstance * vhi = (map->heroes[i]); - vhi->initHero(); - players.find(vhi->getOwner())->second.heroes.push_back(vhi); - hids.erase(vhi->subID); + CGHeroInstance * vhi = map->heroes[i]; + if(vhi->sex == 0xff) //campaign heroes already come initialized -- I hope this will skip them + { + vhi->initHero(); + players.find(vhi->getOwner())->second.heroes.push_back(vhi); + hids.erase(vhi->subID); + } } for (ui32 i=0; iobjects.size();i++) //prisons { - if (map->objects[i]->ID == Obj::PRISON) + if (map->objects[i] && map->objects[i]->ID == Obj::PRISON) hids.erase(map->objects[i]->subID); } @@ -1337,7 +1352,7 @@ void CGameState::init(StartInfo * si) BOOST_FOREACH(CGObjectInstance *obj, map->objects) { - if( !vstd::contains(k->second.players, obj->tempOwner)) continue; //not a flagged object + if(!obj || !vstd::contains(k->second.players, obj->tempOwner)) continue; //not a flagged object boost::unordered_set tiles; obj->getSightTiles(tiles); @@ -1521,10 +1536,14 @@ void CGameState::init(StartInfo * si) objCaller->preInit(); BOOST_FOREACH(CGObjectInstance *obj, map->objects) { - obj->initObj(); + if(obj) + obj->initObj(); } BOOST_FOREACH(CGObjectInstance *obj, map->objects) { + if(!obj) + continue; + switch (obj->ID) { case Obj::QUEST_GUARD: @@ -1542,7 +1561,7 @@ void CGameState::init(StartInfo * si) for(auto k=players.begin(); k!=players.end(); ++k) { - if(k->first==255) + if(k->first==GameConstants::NEUTRAL_PLAYER) continue; //init visiting and garrisoned heroes @@ -2590,30 +2609,10 @@ void CGameState::giveHeroArtifact(CGHeroInstance *h, int aid) ai->putAt(ArtifactLocation(h, ai->firstAvailableSlot(h))); } -int3 CPath::startPos() const -{ - return nodes[nodes.size()-1].coord; -} -void CPath::convert(ui8 mode) //mode=0 -> from 'manifest' to 'object' -{ - if (mode==0) - { - for (ui32 i=0;i nodes; //just get node by node - - int3 startPos() const; // start point - int3 endPos() const; //destination point - void convert(ui8 mode); //mode=0 -> from 'manifest' to 'object' -}; - struct DLL_LINKAGE CGPath { std::vector nodes; //just get node by node diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 2437a0dc6..6130f4edf 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -424,32 +424,6 @@ std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) cons ret.push_back(obj->getHoverText()); return ret; } -bool CGameInfoCallback::verifyPath(CPath * path, bool blockSea) const -{ - for (size_t i=0; i < path->nodes.size(); ++i) - { - const TerrainTile *t = getTile(path->nodes[i].coord); //current tile - ERROR_RET_VAL_IF(!t, "Path contains not visible tile: " << path->nodes[i].coord << "!", false); - if (t->blocked && !t->visitable) - return false; //path is wrong - one of the tiles is blocked - - if (blockSea) - { - if (i==0) - continue; - - const TerrainTile *prev = getTile(path->nodes[i-1].coord); //tile of previous node on the path - if (( t->terType == ETerrainType::WATER && prev->terType != ETerrainType::WATER) - || (t->terType != ETerrainType::WATER && prev->terType == ETerrainType::WATER) - || prev->terType == ETerrainType::ROCK - ) - return false; - } - - - } - return true; -} bool CGameInfoCallback::isVisible(int3 pos, int Player) const { diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 36f40c9e8..4f2d35437 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -101,7 +101,6 @@ public: bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const; int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg - bool verifyPath(CPath * path, bool blockSea)const; const CGHeroInstance* getSelectedHero(int player) const; //NULL if no hero is selected const CGHeroInstance* getSelectedHero() const; //of current (active) player diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 9497b94fb..a232d2acc 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1170,7 +1170,7 @@ void CGameHandler::newTurn() { BOOST_FOREACH (auto obj, gs->map->objects) { - if (obj->ID == Obj::PRISON) //give imprisoned hero 0 exp to level him up. easiest to do at this point + if (obj && obj->ID == Obj::PRISON) //give imprisoned hero 0 exp to level him up. easiest to do at this point { changePrimSkill (obj->id, PrimarySkill::EXPERIENCE, 0); } @@ -5006,7 +5006,7 @@ void CGameHandler::winLoseHandle(ui8 players ) } } -void CGameHandler::checkLossVictory( ui8 player ) +void CGameHandler::checkLossVictory( TPlayerColor player ) { const PlayerState *p = gs->getPlayer(player); if(p->status) //player already won / lost @@ -5046,11 +5046,11 @@ void CGameHandler::checkLossVictory( ui8 player ) } else //player lost -> all his objects become unflagged (neutral) { - std::vector > hlp = p->heroes; - for (std::vector >::const_iterator i = hlp.begin(); i != hlp.end(); i++) //eliminate heroes + auto hlp = p->heroes; + for (auto i = hlp.cbegin(); i != hlp.cend(); i++) //eliminate heroes removeObject((*i)->id); - for (std::vector >::const_iterator i = gs->map->objects.begin(); i != gs->map->objects.end(); i++) //unflag objs + for (auto i = gs->map->objects.cbegin(); i != gs->map->objects.cend(); i++) //unflag objs { if(*i && (*i)->tempOwner == player) setOwner((**i).id,GameConstants::NEUTRAL_PLAYER); @@ -5060,7 +5060,7 @@ void CGameHandler::checkLossVictory( ui8 player ) winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<human) { end2 = true; @@ -5069,7 +5069,7 @@ void CGameHandler::checkLossVictory( ui8 player ) std::vector hes; BOOST_FOREACH(CGHeroInstance * ghi, gs->map->heroes) { - if (ghi->tempOwner == vic) + if (ghi->tempOwner == player) { hes.push_back(ghi); } @@ -5194,7 +5194,7 @@ void CGameHandler::getLossVicMessage( ui8 player, si8 standard, bool victory, In bool CGameHandler::dig( const CGHeroInstance *h ) { - for (std::vector >::const_iterator i = gs->map->objects.begin(); i != gs->map->objects.end(); i++) //unflag objs + for (auto i = gs->map->objects.cbegin(); i != gs->map->objects.cend(); i++) //unflag objs { if(*i && (*i)->ID == Obj::HOLE && (*i)->pos == h->getPosition()) { diff --git a/server/CGameHandler.h b/server/CGameHandler.h index b120917ab..f262fc1a3 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -107,7 +107,7 @@ public: int moveStack(int stack, BattleHex dest); //returned value - travelled distance void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero void runBattle(); - void checkLossVictory(ui8 player); + void checkLossVictory(TPlayerColor player); void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all void getLossVicMessage(ui8 player, si8 standard, bool victory, InfoWindow &out) const;