mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
CGSubterraneanGate: fix pairing and always assign all gates to channel
Before gates on underground layer didn't had any channel assigned and of course any function that attempt to check -1 channel caused crash. Also I find out that at point postInit executed It's possible to get mutable gamestate via gameState() callback so we don't need to pass it there.
This commit is contained in:
parent
f3cdadf142
commit
17f3f94ca6
@ -1867,7 +1867,7 @@ void CGameState::initMapObjects()
|
||||
}
|
||||
}
|
||||
}
|
||||
CGSubterraneanGate::postInit(gs); //pairing subterranean gates
|
||||
CGSubterraneanGate::postInit(); //pairing subterranean gates
|
||||
|
||||
map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized
|
||||
}
|
||||
|
@ -996,13 +996,13 @@ void CGSubterraneanGate::initObj()
|
||||
type = BOTH;
|
||||
}
|
||||
|
||||
void CGSubterraneanGate::postInit( CGameState * gs ) //matches subterranean gates into pairs
|
||||
void CGSubterraneanGate::postInit() //matches subterranean gates into pairs
|
||||
{
|
||||
//split on underground and surface gates
|
||||
std::vector<CGSubterraneanGate *> gatesSplit[2]; //surface and underground gates
|
||||
for(auto & obj : cb->gameState()->map->objects)
|
||||
{
|
||||
auto hlp = dynamic_cast<CGSubterraneanGate *>(gs->getObjInstance(obj->id));
|
||||
auto hlp = dynamic_cast<CGSubterraneanGate *>(cb->gameState()->getObjInstance(obj->id));
|
||||
if(hlp)
|
||||
gatesSplit[hlp->pos.z].push_back(hlp);
|
||||
}
|
||||
@ -1013,6 +1013,15 @@ void CGSubterraneanGate::postInit( CGameState * gs ) //matches subterranean gate
|
||||
return a->pos < b->pos;
|
||||
});
|
||||
|
||||
auto assignToChannel = [&](CGSubterraneanGate * obj)
|
||||
{
|
||||
if(obj->channel == TeleportChannelID())
|
||||
{ // if object not linked to channel then create new channel
|
||||
obj->channel = TeleportChannelID(cb->gameState()->map->teleportChannels.size());
|
||||
addToChannel(cb->gameState()->map->teleportChannels, obj);
|
||||
}
|
||||
};
|
||||
|
||||
for(size_t i = 0; i < gatesSplit[0].size(); i++)
|
||||
{
|
||||
CGSubterraneanGate * objCurrent = gatesSplit[0][i];
|
||||
@ -1022,7 +1031,7 @@ void CGSubterraneanGate::postInit( CGameState * gs ) //matches subterranean gate
|
||||
for(int j = 0; j < gatesSplit[1].size(); j++)
|
||||
{
|
||||
CGSubterraneanGate *checked = gatesSplit[1][j];
|
||||
if(!checked)
|
||||
if(checked->channel != TeleportChannelID())
|
||||
continue;
|
||||
si32 hlp = checked->pos.dist2dSQ(objCurrent->pos);
|
||||
if(hlp < best.second)
|
||||
@ -1032,18 +1041,17 @@ void CGSubterraneanGate::postInit( CGameState * gs ) //matches subterranean gate
|
||||
}
|
||||
}
|
||||
|
||||
if(objCurrent->channel == TeleportChannelID())
|
||||
{ // if object not linked to channel then create new channel
|
||||
objCurrent->channel = TeleportChannelID(gs->map->teleportChannels.size());
|
||||
addToChannel(cb->gameState()->map->teleportChannels, objCurrent);
|
||||
}
|
||||
|
||||
assignToChannel(objCurrent);
|
||||
if(best.first >= 0) //found pair
|
||||
{
|
||||
gatesSplit[1][best.first]->channel = objCurrent->channel;
|
||||
addToChannel(cb->gameState()->map->teleportChannels, gatesSplit[1][best.first]);
|
||||
}
|
||||
}
|
||||
|
||||
// we should assign empty channels to underground gates if they don't have matching overground gates
|
||||
for(size_t i = 0; i < gatesSplit[1].size(); i++)
|
||||
assignToChannel(gatesSplit[1][i]);
|
||||
}
|
||||
|
||||
void CGWhirlpool::onHeroVisit( const CGHeroInstance * h ) const
|
||||
|
@ -315,7 +315,7 @@ class DLL_LINKAGE CGSubterraneanGate : public CGMonolith
|
||||
public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||
void initObj() override;
|
||||
static void postInit(CGameState * gs);
|
||||
static void postInit();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user