1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-15 01:24:45 +02:00

Fix crash, fix invisible boat blocking the tile

This commit is contained in:
Tomasz Zieliński
2023-08-01 18:51:33 +02:00
parent e484066772
commit f6247164ad
5 changed files with 26 additions and 15 deletions

View File

@ -1382,9 +1382,8 @@ void HeroRecruited::applyGs(CGameState * gs) const
auto * boat = dynamic_cast<CGBoat *>(obj); auto * boat = dynamic_cast<CGBoat *>(obj);
if (boat) if (boat)
{ {
h->boat = boat; gs->map->removeBlockVisTiles(boat);
h->attachTo(*boat); h->attachToBoat(boat);
boat->hero = h;
} }
} }
@ -1419,9 +1418,8 @@ void GiveHero::applyGs(CGameState * gs) const
auto * boat = dynamic_cast<CGBoat *>(obj); auto * boat = dynamic_cast<CGBoat *>(obj);
if (boat) if (boat)
{ {
h->boat = boat; gs->map->removeBlockVisTiles(boat);
h->attachTo(*boat); h->attachToBoat(boat);
boat->hero = h;
} }
} }

View File

@ -857,8 +857,7 @@ void CGameState::initHeroes()
map->objects.emplace_back(boat); map->objects.emplace_back(boat);
map->addBlockVisTiles(boat); map->addBlockVisTiles(boat);
boat->hero = hero; hero->attachToBoat(boat);
hero->boat = boat;
} }
} }

View File

@ -484,9 +484,12 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const
if (cb->gameState()->map->getTile(boatPos).isWater()) if (cb->gameState()->map->getTile(boatPos).isWater())
{ {
smp.val = movementPointsLimit(false); smp.val = movementPointsLimit(false);
//Create a new boat for hero if (!boat)
cb->createObject(boatPos, Obj::BOAT, getBoatType().getNum()); {
boatId = cb->getTopObj(boatPos)->id; //Create a new boat for hero
cb->createObject(boatPos, Obj::BOAT, getBoatType().getNum());
boatId = cb->getTopObj(boatPos)->id;
}
} }
else else
{ {
@ -1119,6 +1122,15 @@ int CGHeroInstance::maxSpellLevel() const
return std::min(GameConstants::SPELL_LEVELS, valOfBonuses(Selector::type()(BonusType::MAX_LEARNABLE_SPELL_LEVEL))); return std::min(GameConstants::SPELL_LEVELS, valOfBonuses(Selector::type()(BonusType::MAX_LEARNABLE_SPELL_LEVEL)));
} }
void CGHeroInstance::attachToBoat(CGBoat* newBoat)
{
assert(newBoat);
boat = newBoat;
attachTo(const_cast<CGBoat&>(*boat));
const_cast<CGBoat*>(boat)->hero = this;
}
void CGHeroInstance::deserializationFix() void CGHeroInstance::deserializationFix()
{ {
artDeserializationFix(this); artDeserializationFix(this);

View File

@ -282,6 +282,7 @@ public:
void getCastDescription(const spells::Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override; void getCastDescription(const spells::Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override;
void spendMana(ServerCallback * server, const int spellCost) const override; void spendMana(ServerCallback * server, const int spellCost) const override;
void attachToBoat(CGBoat* newBoat);
void boatDeserializationFix(); void boatDeserializationFix();
void deserializationFix(); void deserializationFix();

View File

@ -237,18 +237,19 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
gameHandler->complain("Hero is not available for hiring!"); gameHandler->complain("Hero is not available for hiring!");
return false; return false;
} }
const auto targetPos = mapObject->visitablePos();
HeroRecruited hr; HeroRecruited hr;
hr.tid = mapObject->id; hr.tid = mapObject->id;
hr.hid = recruitedHero->subID; hr.hid = recruitedHero->subID;
hr.player = player; hr.player = player;
hr.tile = recruitedHero->convertFromVisitablePos(mapObject->visitablePos()); hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
if(gameHandler->getTile(hr.tile)->isWater()) if(gameHandler->getTile(hr.tile)->isWater() && !recruitedHero->boat)
{ {
//Create a new boat for hero //Create a new boat for hero
gameHandler->createObject(mapObject->visitablePos(), Obj::BOAT, recruitedHero->getBoatType().getNum()); gameHandler->createObject(targetPos , Obj::BOAT, recruitedHero->getBoatType().getNum());
hr.boatId = gameHandler->getTopObj(hr.tile)->id; hr.boatId = gameHandler->getTopObj(targetPos)->id;
} }
// apply netpack -> this will remove hired hero from pool // apply netpack -> this will remove hired hero from pool