1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

* some work on hero crossover; still buggy

This commit is contained in:
mateuszb
2013-02-05 23:16:13 +00:00
parent 3f309f0c5e
commit dc091a1ce1
7 changed files with 62 additions and 95 deletions

View File

@@ -92,6 +92,19 @@
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" /> <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='RD|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='RD|x64'" /> <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='RD|x64'" />
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<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)</IncludePath>
<LibraryPath>C:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.0A\Lib;$(SolutionDir)..\libs\$(PlatformShortName);$(VCMI_Out);$(LibraryPath)</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|Win32'">
<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)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<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)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RD|x64'">
<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)</IncludePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions> <AdditionalOptions>/MP4 %(AdditionalOptions)</AdditionalOptions>

View File

@@ -588,6 +588,9 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj)
{ {
for(ui32 i=0;i<map->objects.size();i++) for(ui32 i=0;i<map->objects.size();i++)
{ {
if(!map->objects[i])
continue;
if(map->objects[i]->ID==Obj::RANDOM_TOWN if(map->objects[i]->ID==Obj::RANDOM_TOWN
&& dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier)
{ {
@@ -853,13 +856,6 @@ void CGameState::init(StartInfo * si)
return ret; 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; tlog0 << "\tUsing random seed: "<< si->seedToBeUsed << std::endl;
ran.seed((boost::int32_t)si->seedToBeUsed); ran.seed((boost::int32_t)si->seedToBeUsed);
scenarioOps = new StartInfo(*si); scenarioOps = new StartInfo(*si);
@@ -995,7 +991,7 @@ void CGameState::init(StartInfo * si)
//remove tiles with holes //remove tiles with holes
for(ui32 no=0; no<map->objects.size(); ++no) for(ui32 no=0; no<map->objects.size(); ++no)
if(map->objects[no]->ID == Obj::HOLE) if(map->objects[no] && map->objects[no]->ID == Obj::HOLE)
allowedPos -= map->objects[no]->pos; allowedPos -= map->objects[no]->pos;
if(allowedPos.size()) if(allowedPos.size())
@@ -1023,6 +1019,9 @@ void CGameState::init(StartInfo * si)
tlog4 << "\tRandomizing objects"; tlog4 << "\tRandomizing objects";
BOOST_FOREACH(CGObjectInstance *obj, map->objects) BOOST_FOREACH(CGObjectInstance *obj, map->objects)
{ {
if(!obj)
continue;
randomizeObject(obj); randomizeObject(obj);
obj->hoverName = VLC->generaltexth->names[obj->ID]; obj->hoverName = VLC->generaltexth->names[obj->ID];
@@ -1095,6 +1094,14 @@ void CGameState::init(StartInfo * si)
tlog4 << "\tReplacing hero placeholders"; tlog4 << "\tReplacing hero placeholders";
if (scenarioOps->campState) 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 campaign = scenarioOps->campState;
auto bonus = campaign->getBonusForCurrentMap(); auto bonus = campaign->getBonusForCurrentMap();
@@ -1158,7 +1165,12 @@ void CGameState::init(StartInfo * si)
if(Xheroes.size() > hp->power - 1) if(Xheroes.size() > hp->power - 1)
replaceHero(g, Xheroes[hp->power - 1]); replaceHero(g, Xheroes[hp->power - 1]);
else 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 //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"; tlog2 << "Warning - hero with uninitialized owner!\n";
continue; continue;
} }
CGHeroInstance * vhi = (map->heroes[i]); CGHeroInstance * vhi = map->heroes[i];
vhi->initHero(); if(vhi->sex == 0xff) //campaign heroes already come initialized -- I hope this will skip them
players.find(vhi->getOwner())->second.heroes.push_back(vhi); {
hids.erase(vhi->subID); vhi->initHero();
players.find(vhi->getOwner())->second.heroes.push_back(vhi);
hids.erase(vhi->subID);
}
} }
for (ui32 i=0; i<map->objects.size();i++) //prisons for (ui32 i=0; i<map->objects.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); hids.erase(map->objects[i]->subID);
} }
@@ -1337,7 +1352,7 @@ void CGameState::init(StartInfo * si)
BOOST_FOREACH(CGObjectInstance *obj, map->objects) 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<int3, ShashInt3> tiles; boost::unordered_set<int3, ShashInt3> tiles;
obj->getSightTiles(tiles); obj->getSightTiles(tiles);
@@ -1521,10 +1536,14 @@ void CGameState::init(StartInfo * si)
objCaller->preInit(); objCaller->preInit();
BOOST_FOREACH(CGObjectInstance *obj, map->objects) BOOST_FOREACH(CGObjectInstance *obj, map->objects)
{ {
obj->initObj(); if(obj)
obj->initObj();
} }
BOOST_FOREACH(CGObjectInstance *obj, map->objects) BOOST_FOREACH(CGObjectInstance *obj, map->objects)
{ {
if(!obj)
continue;
switch (obj->ID) switch (obj->ID)
{ {
case Obj::QUEST_GUARD: case Obj::QUEST_GUARD:
@@ -1542,7 +1561,7 @@ void CGameState::init(StartInfo * si)
for(auto k=players.begin(); k!=players.end(); ++k) for(auto k=players.begin(); k!=players.end(); ++k)
{ {
if(k->first==255) if(k->first==GameConstants::NEUTRAL_PLAYER)
continue; continue;
//init visiting and garrisoned heroes //init visiting and garrisoned heroes
@@ -2590,30 +2609,10 @@ void CGameState::giveHeroArtifact(CGHeroInstance *h, int aid)
ai->putAt(ArtifactLocation(h, ai->firstAvailableSlot(h))); 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.size();i++)
{
nodes[i].coord = CGHeroInstance::convertPosition(nodes[i].coord,true);
}
}
}
int3 CPath::endPos() const
{
return nodes[0].coord;
}
CGPathNode::CGPathNode() CGPathNode::CGPathNode()
:coord(-1,-1,-1) :coord(-1,-1,-1)
{ {
accessible = 0; accessible = NOT_SET;
land = 0; land = 0;
moveRemains = 0; moveRemains = 0;
turns = 255; turns = 255;

View File

@@ -222,26 +222,18 @@ struct UpgradeInfo
UpgradeInfo(){oldID = -1;}; UpgradeInfo(){oldID = -1;};
}; };
struct CPathNode
{
bool accessible; //true if a hero can be on this node
int dist; //distance from the first node of searching; -1 is infinity
CPathNode * theNodeBefore;
int3 coord; //coordiantes
bool visited;
};
struct DLL_LINKAGE CGPathNode struct DLL_LINKAGE CGPathNode
{ {
enum EAccessibility enum EAccessibility
{ {
ACCESSIBLE=1, //tile can be entered and passed NOT_SET = 0,
ACCESSIBLE = 1, //tile can be entered and passed
VISITABLE, //tile can be entered as the last tile in path VISITABLE, //tile can be entered as the last tile in path
BLOCKVIS, //visitable from neighbouring tile but not passable BLOCKVIS, //visitable from neighbouring tile but not passable
BLOCKED //tile can't be entered nor visited BLOCKED //tile can't be entered nor visited
}; };
ui8 accessible; //the enum above EAccessibility accessible;
ui8 land; ui8 land;
ui8 turns; ui8 turns;
ui32 moveRemains; ui32 moveRemains;
@@ -252,16 +244,6 @@ struct DLL_LINKAGE CGPathNode
bool reachable() const; bool reachable() const;
}; };
struct DLL_LINKAGE CPath
{
std::vector<CPathNode> 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 struct DLL_LINKAGE CGPath
{ {
std::vector<CGPathNode> nodes; //just get node by node std::vector<CGPathNode> nodes; //just get node by node

View File

@@ -424,32 +424,6 @@ std::vector < std::string > CGameInfoCallback::getObjDescriptions(int3 pos) cons
ret.push_back(obj->getHoverText()); ret.push_back(obj->getHoverText());
return ret; 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 bool CGameInfoCallback::isVisible(int3 pos, int Player) const
{ {

View File

@@ -101,7 +101,6 @@ public:
bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const; 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 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 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(int player) const; //NULL if no hero is selected
const CGHeroInstance* getSelectedHero() const; //of current (active) player const CGHeroInstance* getSelectedHero() const; //of current (active) player

View File

@@ -1170,7 +1170,7 @@ void CGameHandler::newTurn()
{ {
BOOST_FOREACH (auto obj, gs->map->objects) 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); 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); const PlayerState *p = gs->getPlayer(player);
if(p->status) //player already won / lost 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) else //player lost -> all his objects become unflagged (neutral)
{ {
std::vector<ConstTransitivePtr<CGHeroInstance> > hlp = p->heroes; auto hlp = p->heroes;
for (std::vector<ConstTransitivePtr<CGHeroInstance> >::const_iterator i = hlp.begin(); i != hlp.end(); i++) //eliminate heroes for (auto i = hlp.cbegin(); i != hlp.cend(); i++) //eliminate heroes
removeObject((*i)->id); removeObject((*i)->id);
for (std::vector<ConstTransitivePtr<CGObjectInstance> >::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) if(*i && (*i)->tempOwner == player)
setOwner((**i).id,GameConstants::NEUTRAL_PLAYER); setOwner((**i).id,GameConstants::NEUTRAL_PLAYER);
@@ -5060,7 +5060,7 @@ void CGameHandler::checkLossVictory( ui8 player )
winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<<player)); winLoseHandle(GameConstants::ALL_PLAYERS & ~(1<<player));
} }
if(vic) if(vic && p->human)
{ {
end2 = true; end2 = true;
@@ -5069,7 +5069,7 @@ void CGameHandler::checkLossVictory( ui8 player )
std::vector<CGHeroInstance *> hes; std::vector<CGHeroInstance *> hes;
BOOST_FOREACH(CGHeroInstance * ghi, gs->map->heroes) BOOST_FOREACH(CGHeroInstance * ghi, gs->map->heroes)
{ {
if (ghi->tempOwner == vic) if (ghi->tempOwner == player)
{ {
hes.push_back(ghi); hes.push_back(ghi);
} }
@@ -5194,7 +5194,7 @@ void CGameHandler::getLossVicMessage( ui8 player, si8 standard, bool victory, In
bool CGameHandler::dig( const CGHeroInstance *h ) bool CGameHandler::dig( const CGHeroInstance *h )
{ {
for (std::vector<ConstTransitivePtr<CGObjectInstance> >::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()) if(*i && (*i)->ID == Obj::HOLE && (*i)->pos == h->getPosition())
{ {

View File

@@ -107,7 +107,7 @@ public:
int moveStack(int stack, BattleHex dest); //returned value - travelled distance 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<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
void runBattle(); 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 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; void getLossVicMessage(ui8 player, si8 standard, bool victory, InfoWindow &out) const;