mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Implemented support for "coast visitable" objects:
- objects marked as coast visitable can be visited from land even when placed in water - added isBlockedVisitable and isCoastVisitable method to CGObjectInstance - implemented json config for these properties in banks
This commit is contained in:
parent
a84ccb37c2
commit
f7b27da00e
@ -266,7 +266,7 @@ bool isBlockVisitObj(const int3 & pos)
|
|||||||
{
|
{
|
||||||
if(auto obj = cb->getTopObj(pos))
|
if(auto obj = cb->getTopObj(pos))
|
||||||
{
|
{
|
||||||
if(obj->blockVisit) //we can't stand on that object
|
if(obj->isBlockedVisitable()) //we can't stand on that object
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ bool isBlockVisitObj(const int3 & pos)
|
|||||||
{
|
{
|
||||||
if(auto obj = cb->getTopObj(pos))
|
if(auto obj = cb->getTopObj(pos))
|
||||||
{
|
{
|
||||||
if(obj->blockVisit) //we can't stand on that object
|
if(obj->isBlockedVisitable()) //we can't stand on that object
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ namespace Goals
|
|||||||
|
|
||||||
// picking up resources does not yield any exploration at all.
|
// picking up resources does not yield any exploration at all.
|
||||||
// if it blocks the way to some explorable tile AIPathfinder will take care of it
|
// if it blocks the way to some explorable tile AIPathfinder will take care of it
|
||||||
if(obj && obj->blockVisit)
|
if(obj && obj->isBlockedVisitable())
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -640,6 +640,8 @@
|
|||||||
"shipwreck" : {
|
"shipwreck" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"resetDuration" : 0,
|
"resetDuration" : 0,
|
||||||
|
"blockedVisitable" : true,
|
||||||
|
"coastVisitable" : true,
|
||||||
"name" : "Shipwreck",
|
"name" : "Shipwreck",
|
||||||
"aiValue" : 2000,
|
"aiValue" : 2000,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
@ -732,6 +734,7 @@
|
|||||||
"derelictShip" : {
|
"derelictShip" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"resetDuration" : 0,
|
"resetDuration" : 0,
|
||||||
|
"blockedVisitable" : true,
|
||||||
"name" : "Derelict Ship",
|
"name" : "Derelict Ship",
|
||||||
"aiValue" : 4000,
|
"aiValue" : 4000,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
|
@ -1900,7 +1900,7 @@ std::vector<CGObjectInstance*> CGameState::guardingCreatures (int3 pos) const
|
|||||||
{
|
{
|
||||||
for (CGObjectInstance* obj : posTile.visitableObjects)
|
for (CGObjectInstance* obj : posTile.visitableObjects)
|
||||||
{
|
{
|
||||||
if(obj->blockVisit)
|
if(obj->isBlockedVisitable())
|
||||||
{
|
{
|
||||||
if (obj->ID == Obj::MONSTER) // Monster
|
if (obj->ID == Obj::MONSTER) // Monster
|
||||||
guards.push_back(obj);
|
guards.push_back(obj);
|
||||||
|
@ -30,6 +30,8 @@ void CBankInstanceConstructor::initTypeData(const JsonNode & input)
|
|||||||
|
|
||||||
levels = input["levels"].Vector();
|
levels = input["levels"].Vector();
|
||||||
bankResetDuration = static_cast<si32>(input["resetDuration"].Float());
|
bankResetDuration = static_cast<si32>(input["resetDuration"].Float());
|
||||||
|
blockVisit = input["blockedVisitable"].Bool();
|
||||||
|
coastVisitable = input["coastVisitable"].Bool();
|
||||||
}
|
}
|
||||||
|
|
||||||
BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRandomGenerator & rng) const
|
BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRandomGenerator & rng) const
|
||||||
@ -58,6 +60,8 @@ BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRan
|
|||||||
void CBankInstanceConstructor::randomizeObject(CBank * bank, CRandomGenerator & rng) const
|
void CBankInstanceConstructor::randomizeObject(CBank * bank, CRandomGenerator & rng) const
|
||||||
{
|
{
|
||||||
bank->resetDuration = bankResetDuration;
|
bank->resetDuration = bankResetDuration;
|
||||||
|
bank->blockVisit = blockVisit;
|
||||||
|
bank->coastVisitable = coastVisitable;
|
||||||
|
|
||||||
si32 totalChance = 0;
|
si32 totalChance = 0;
|
||||||
for(const auto & node : levels)
|
for(const auto & node : levels)
|
||||||
|
@ -80,12 +80,18 @@ class CBankInstanceConstructor : public CDefaultObjectTypeHandler<CBank>
|
|||||||
BankConfig generateConfig(const JsonNode & conf, CRandomGenerator & rng) const;
|
BankConfig generateConfig(const JsonNode & conf, CRandomGenerator & rng) const;
|
||||||
|
|
||||||
JsonVector levels;
|
JsonVector levels;
|
||||||
|
|
||||||
|
// all banks of this type will be reset N days after clearing,
|
||||||
|
si32 bankResetDuration = 0;
|
||||||
|
|
||||||
|
// bank is only visitable from adjacent tile
|
||||||
|
bool blockVisit;
|
||||||
|
// bank is visitable from land even when bank is on water tile
|
||||||
|
bool coastVisitable;
|
||||||
protected:
|
protected:
|
||||||
void initTypeData(const JsonNode & input) override;
|
void initTypeData(const JsonNode & input) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// all banks of this type will be reset N days after clearing,
|
|
||||||
si32 bankResetDuration = 0;
|
|
||||||
|
|
||||||
void randomizeObject(CBank * object, CRandomGenerator & rng) const override;
|
void randomizeObject(CBank * object, CRandomGenerator & rng) const override;
|
||||||
|
|
||||||
@ -97,6 +103,8 @@ public:
|
|||||||
{
|
{
|
||||||
h & levels;
|
h & levels;
|
||||||
h & bankResetDuration;
|
h & bankResetDuration;
|
||||||
|
h & blockVisit;
|
||||||
|
h & coastVisitable;
|
||||||
h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this);
|
h & static_cast<CDefaultObjectTypeHandler<CBank>&>(*this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -43,6 +43,11 @@ void CBank::initObj(CRandomGenerator & rand)
|
|||||||
VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, rand);
|
VLC->objtypeh->getHandlerFor(ID, subID)->configureObject(this, rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CBank::isCoastVisitable() const
|
||||||
|
{
|
||||||
|
return coastVisitable;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CBank::getHoverText(PlayerColor player) const
|
std::string CBank::getHoverText(PlayerColor player) const
|
||||||
{
|
{
|
||||||
// TODO: record visited players
|
// TODO: record visited players
|
||||||
|
@ -21,6 +21,7 @@ class DLL_LINKAGE CBank : public CArmedInstance
|
|||||||
std::unique_ptr<BankConfig> bc;
|
std::unique_ptr<BankConfig> bc;
|
||||||
ui32 daycounter;
|
ui32 daycounter;
|
||||||
ui32 resetDuration;
|
ui32 resetDuration;
|
||||||
|
bool coastVisitable;
|
||||||
|
|
||||||
void setPropertyDer(ui8 what, ui32 val) override;
|
void setPropertyDer(ui8 what, ui32 val) override;
|
||||||
void doVisit(const CGHeroInstance * hero) const;
|
void doVisit(const CGHeroInstance * hero) const;
|
||||||
@ -35,6 +36,7 @@ public:
|
|||||||
std::string getHoverText(PlayerColor player) const override;
|
std::string getHoverText(PlayerColor player) const override;
|
||||||
void newTurn(CRandomGenerator & rand) const override;
|
void newTurn(CRandomGenerator & rand) const override;
|
||||||
bool wasVisited (PlayerColor player) const override;
|
bool wasVisited (PlayerColor player) const override;
|
||||||
|
bool isCoastVisitable() const override;
|
||||||
void onHeroVisit(const CGHeroInstance * h) const override;
|
void onHeroVisit(const CGHeroInstance * h) const override;
|
||||||
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
|
||||||
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
void blockingDialogAnswered(const CGHeroInstance *hero, ui32 answer) const override;
|
||||||
@ -45,6 +47,7 @@ public:
|
|||||||
h & daycounter;
|
h & daycounter;
|
||||||
h & bc;
|
h & bc;
|
||||||
h & resetDuration;
|
h & resetDuration;
|
||||||
|
h & coastVisitable;
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class CBankInstanceConstructor;
|
friend class CBankInstanceConstructor;
|
||||||
|
@ -122,6 +122,11 @@ TerrainId CGHeroInstance::getNativeTerrain() const
|
|||||||
return nativeTerrain;
|
return nativeTerrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGHeroInstance::isCoastVisitable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
BattleField CGHeroInstance::getBattlefield() const
|
BattleField CGHeroInstance::getBattlefield() const
|
||||||
{
|
{
|
||||||
return BattleField::NONE;
|
return BattleField::NONE;
|
||||||
|
@ -286,6 +286,7 @@ public:
|
|||||||
|
|
||||||
void updateFrom(const JsonNode & data) override;
|
void updateFrom(const JsonNode & data) override;
|
||||||
|
|
||||||
|
bool isCoastVisitable() const override;
|
||||||
BattleField getBattlefield() const override;
|
BattleField getBattlefield() const override;
|
||||||
protected:
|
protected:
|
||||||
void setPropertyDer(ui8 what, ui32 val) override;//synchr
|
void setPropertyDer(ui8 what, ui32 val) override;//synchr
|
||||||
|
@ -282,6 +282,16 @@ bool CGObjectInstance::isVisitable() const
|
|||||||
return appearance->isVisitable();
|
return appearance->isVisitable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGObjectInstance::isBlockedVisitable() const
|
||||||
|
{
|
||||||
|
return blockVisit;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGObjectInstance::isCoastVisitable() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGObjectInstance::passableFor(PlayerColor color) const
|
bool CGObjectInstance::passableFor(PlayerColor color) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -34,8 +34,6 @@ public:
|
|||||||
ObjectInstanceID id;
|
ObjectInstanceID id;
|
||||||
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
|
/// Defines appearance of object on map (animation, blocked tiles, blit order, etc)
|
||||||
std::shared_ptr<const ObjectTemplate> appearance;
|
std::shared_ptr<const ObjectTemplate> appearance;
|
||||||
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
|
||||||
bool blockVisit;
|
|
||||||
|
|
||||||
std::string instanceName;
|
std::string instanceName;
|
||||||
std::string typeName;
|
std::string typeName;
|
||||||
@ -49,6 +47,8 @@ public:
|
|||||||
|
|
||||||
/// "center" tile from which the sight distance is calculated
|
/// "center" tile from which the sight distance is calculated
|
||||||
int3 getSightCenter() const;
|
int3 getSightCenter() const;
|
||||||
|
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
||||||
|
bool blockVisit;
|
||||||
|
|
||||||
PlayerColor getOwner() const override
|
PlayerColor getOwner() const override
|
||||||
{
|
{
|
||||||
@ -68,7 +68,15 @@ public:
|
|||||||
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
bool coveringAt(int x, int y) const; //returns true if object covers with picture location (x, y) (h3m pos)
|
||||||
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
std::set<int3> getBlockedPos() const; //returns set of positions blocked by this object
|
||||||
std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
std::set<int3> getBlockedOffsets() const; //returns set of relative positions blocked by this object
|
||||||
bool isVisitable() const; //returns true if object is visitable
|
|
||||||
|
/// returns true if object is visitable
|
||||||
|
bool isVisitable() const;
|
||||||
|
|
||||||
|
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
||||||
|
virtual bool isBlockedVisitable() const;
|
||||||
|
|
||||||
|
/// If true this object can be visited by hero standing on the coast
|
||||||
|
virtual bool isCoastVisitable() const;
|
||||||
|
|
||||||
virtual BattleField getBattlefield() const;
|
virtual BattleField getBattlefield() const;
|
||||||
|
|
||||||
|
@ -246,7 +246,6 @@ public:
|
|||||||
{
|
{
|
||||||
h & static_cast<IQuestObject&>(*this);
|
h & static_cast<IQuestObject&>(*this);
|
||||||
h & static_cast<CGObjectInstance&>(*this);
|
h & static_cast<CGObjectInstance&>(*this);
|
||||||
h & blockVisit;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1294,6 +1294,11 @@ CGBoat::CGBoat()
|
|||||||
layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
|
layer = EPathfindingLayer::EEPathfindingLayer::SAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGBoat::isCoastVisitable() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void CGSirens::initObj(CRandomGenerator & rand)
|
void CGSirens::initObj(CRandomGenerator & rand)
|
||||||
{
|
{
|
||||||
blockVisit = true;
|
blockVisit = true;
|
||||||
|
@ -359,6 +359,7 @@ public:
|
|||||||
std::array<std::string, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
|
std::array<std::string, PlayerColor::PLAYER_LIMIT_I> flagAnimations;
|
||||||
|
|
||||||
CGBoat();
|
CGBoat();
|
||||||
|
bool isCoastVisitable() const override;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
|
@ -313,7 +313,7 @@ int3 CMap::guardingCreaturePosition (int3 pos) const
|
|||||||
{
|
{
|
||||||
for (CGObjectInstance* obj : posTile.visitableObjects)
|
for (CGObjectInstance* obj : posTile.visitableObjects)
|
||||||
{
|
{
|
||||||
if(obj->blockVisit)
|
if(obj->isBlockedVisitable())
|
||||||
{
|
{
|
||||||
if (obj->ID == Obj::MONSTER) // Monster
|
if (obj->ID == Obj::MONSTER) // Monster
|
||||||
return pos;
|
return pos;
|
||||||
|
@ -42,7 +42,7 @@ namespace PathfinderUtil
|
|||||||
{
|
{
|
||||||
for(const CGObjectInstance * obj : tinfo.visitableObjects)
|
for(const CGObjectInstance * obj : tinfo.visitableObjects)
|
||||||
{
|
{
|
||||||
if(obj->blockVisit)
|
if(obj->isBlockedVisitable())
|
||||||
return EPathAccessibility::BLOCKVIS;
|
return EPathAccessibility::BLOCKVIS;
|
||||||
else if(obj->passableFor(player))
|
else if(obj->passableFor(player))
|
||||||
return EPathAccessibility::ACCESSIBLE;
|
return EPathAccessibility::ACCESSIBLE;
|
||||||
|
@ -157,7 +157,7 @@ void DestinationActionRule::process(
|
|||||||
}
|
}
|
||||||
else if(destination.isGuardianTile)
|
else if(destination.isGuardianTile)
|
||||||
action = EPathNodeAction::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
else if(destination.nodeObject->blockVisit && !(pathfinderConfig->options.useCastleGate && destination.nodeObject->ID == Obj::TOWN))
|
else if(destination.nodeObject->isBlockedVisitable() && !(pathfinderConfig->options.useCastleGate && destination.nodeObject->ID == Obj::TOWN))
|
||||||
action = EPathNodeAction::BLOCKING_VISIT;
|
action = EPathNodeAction::BLOCKING_VISIT;
|
||||||
|
|
||||||
if(action == EPathNodeAction::NORMAL)
|
if(action == EPathNodeAction::NORMAL)
|
||||||
@ -301,7 +301,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
|||||||
if(!destination.isNodeObjectVisitable())
|
if(!destination.isNodeObjectVisitable())
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
|
|
||||||
if(destination.nodeObject->ID != Obj::BOAT && !destination.nodeHero)
|
if(!destination.nodeHero && !destination.nodeObject->isCoastVisitable())
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
}
|
}
|
||||||
else if(destination.isNodeObjectVisitable() && destination.nodeObject->ID == Obj::BOAT)
|
else if(destination.isNodeObjectVisitable() && destination.nodeObject->ID == Obj::BOAT)
|
||||||
|
@ -2294,7 +2294,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
||||||
if (((!t.terType->isPassable() || (t.blocked && !t.visitable && !canFly))
|
if (((!t.terType->isPassable() || (t.blocked && !t.visitable && !canFly))
|
||||||
&& complain("Cannot move hero, destination tile is blocked!"))
|
&& complain("Cannot move hero, destination tile is blocked!"))
|
||||||
|| ((!h->boat && !canWalkOnSea && !canFly && t.terType->isWater() && (t.visitableObjects.size() < 1 || (t.visitableObjects.back()->ID != Obj::BOAT && t.visitableObjects.back()->ID != Obj::HERO))) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276)
|
|| ((!h->boat && !canWalkOnSea && !canFly && t.terType->isWater() && (t.visitableObjects.size() < 1 || !t.visitableObjects.back()->isCoastVisitable())) //hero is not on boat/water walking and dst water tile doesn't contain boat/hero (objs visitable from land) -> we test back cause boat may be on top of another object (#276)
|
||||||
&& complain("Cannot move hero, destination tile is on water!"))
|
&& complain("Cannot move hero, destination tile is on water!"))
|
||||||
|| ((h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand() && t.blocked)
|
|| ((h->boat && h->boat->layer == EPathfindingLayer::SAIL && t.terType->isLand() && t.blocked)
|
||||||
&& complain("Cannot disembark hero, tile is blocked!"))
|
&& complain("Cannot disembark hero, tile is blocked!"))
|
||||||
@ -2369,10 +2369,10 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
{
|
{
|
||||||
for (CGObjectInstance *obj : t.visitableObjects)
|
for (CGObjectInstance *obj : t.visitableObjects)
|
||||||
{
|
{
|
||||||
if(h->boat && !obj->blockVisit && !h->boat->onboardVisitAllowed)
|
if(h->boat && !obj->isBlockedVisitable() && !h->boat->onboardVisitAllowed)
|
||||||
return doMove(TryMoveHero::SUCCESS, this->IGNORE_GUARDS, DONT_VISIT_DEST, REMAINING_ON_TILE);
|
return doMove(TryMoveHero::SUCCESS, this->IGNORE_GUARDS, DONT_VISIT_DEST, REMAINING_ON_TILE);
|
||||||
|
|
||||||
if (obj != h && obj->blockVisit && !obj->passableFor(h->tempOwner))
|
if (obj != h && obj->isBlockedVisitable() && !obj->passableFor(h->tempOwner))
|
||||||
{
|
{
|
||||||
EVisitDest visitDest = VISIT_DEST;
|
EVisitDest visitDest = VISIT_DEST;
|
||||||
if(h->boat && !h->boat->onboardVisitAllowed)
|
if(h->boat && !h->boat->onboardVisitAllowed)
|
||||||
|
Loading…
Reference in New Issue
Block a user