mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
vcmi: specialize native terrain entity
Specialize native terrain entity for all object that have native terrain. Allow creatures to take global bonuses into account when checking for native terrain.
This commit is contained in:
parent
6d9859932b
commit
0f5f4c69ec
@ -162,6 +162,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
|
||||
${MAIN_LIB_DIR}/vstd/StringUtils.cpp
|
||||
|
||||
${MAIN_LIB_DIR}/BasicTypes.cpp
|
||||
${MAIN_LIB_DIR}/BattleFieldHandler.cpp
|
||||
${MAIN_LIB_DIR}/CAndroidVMHelper.cpp
|
||||
${MAIN_LIB_DIR}/CArtHandler.cpp
|
||||
|
@ -28,6 +28,7 @@ class DLL_LINKAGE WithNativeTerrain
|
||||
public:
|
||||
virtual Identifier<ETerrainId> getNativeTerrain() const = 0;
|
||||
virtual FactionID getFaction() const = 0;
|
||||
virtual bool isItNativeTerrain(Identifier<ETerrainId> terrain) const;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE Entity
|
||||
|
20
lib/BasicTypes.cpp
Normal file
20
lib/BasicTypes.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* BasicTypes.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "GameConstants.h"
|
||||
|
||||
#include <vcmi/Entity.h>
|
||||
|
||||
bool INativeTerrainProvider::isItNativeTerrain(TerrainId terrain) const
|
||||
{
|
||||
auto native = getNativeTerrain();
|
||||
return native == terrain || native == ETerrainId::ANY_TERRAIN;
|
||||
}
|
@ -348,9 +348,9 @@ TerrainId CCreature::getNativeTerrain() const
|
||||
|
||||
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
||||
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
|
||||
return hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
||||
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
||||
? TerrainId(ETerrainId::ANY_TERRAIN)
|
||||
: VLC->factions()->getByIndex(faction)->getNativeTerrain();
|
||||
: VLC->factions()->getById(getFaction())->getNativeTerrain();
|
||||
}
|
||||
|
||||
void CCreature::updateFrom(const JsonNode & data)
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include "serializer/JsonSerializeFormat.h"
|
||||
#include "NetPacksBase.h"
|
||||
|
||||
#include <vcmi/FactionService.h>
|
||||
#include <vcmi/Faction.h>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
@ -912,6 +915,31 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
|
||||
}
|
||||
}
|
||||
|
||||
FactionID CStackInstance::getFaction() const
|
||||
{
|
||||
if(type)
|
||||
return type->getFaction();
|
||||
|
||||
return FactionID::NEUTRAL;
|
||||
}
|
||||
|
||||
const IBonusBearer* CStackInstance::getBonusBearer() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TerrainId CStackInstance::getNativeTerrain() const
|
||||
{
|
||||
const std::string cachingStringNoTerrainPenalty = "type_NO_TERRAIN_PENALTY_sANY";
|
||||
static const auto selectorNoTerrainPenalty = Selector::typeSubtype(Bonus::NO_TERRAIN_PENALTY, static_cast<int>(ETerrainId::ANY_TERRAIN));
|
||||
|
||||
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
||||
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
|
||||
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
||||
? TerrainId(ETerrainId::ANY_TERRAIN)
|
||||
: VLC->factions()->getById(getFaction())->getNativeTerrain();
|
||||
}
|
||||
|
||||
CCommanderInstance::CCommanderInstance()
|
||||
{
|
||||
init();
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "CArtHandler.h"
|
||||
#include "CCreatureHandler.h"
|
||||
|
||||
#include <vcmi/Entity.h>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class JsonNode;
|
||||
@ -61,7 +63,7 @@ public:
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CArtifactSet
|
||||
class DLL_LINKAGE CStackInstance : public CBonusSystemNode, public CStackBasicDescriptor, public CArtifactSet, public WithBonuses, public WithNativeTerrain
|
||||
{
|
||||
protected:
|
||||
const CArmedInstance *_armyObj; //stack must be part of some army, army must be part of some object
|
||||
@ -92,6 +94,12 @@ public:
|
||||
std::string bonusToString(const std::shared_ptr<Bonus>& bonus, bool description) const override; // how would bonus description look for this particular type of node
|
||||
std::string bonusToGraphics(const std::shared_ptr<Bonus> & bonus) const; //file name of graphics from StackSkills , in future possibly others
|
||||
|
||||
//WithBonuses
|
||||
const IBonusBearer* getBonusBearer() const override;
|
||||
//WithNativeTerrain
|
||||
FactionID getFaction() const override;
|
||||
TerrainId getNativeTerrain() const override;
|
||||
|
||||
virtual ui64 getPower() const;
|
||||
CCreature::CreatureQuantityId getQuantityID() const;
|
||||
std::string getQuantityTXT(bool capitalized = true) const;
|
||||
|
@ -78,7 +78,7 @@ void CStack::localInit(BattleInfo * battleInfo)
|
||||
attachTo(*army);
|
||||
attachTo(const_cast<CCreature&>(*type));
|
||||
}
|
||||
nativeTerrain = type->getNativeTerrain(); //save nativeTerrain in the variable on the battle start to avoid dead lock
|
||||
nativeTerrain = getNativeTerrain(); //save nativeTerrain in the variable on the battle start to avoid dead lock
|
||||
CUnitState::localInit(this); //it causes execution of the CStack::isOnNativeTerrain where nativeTerrain will be considered
|
||||
position = initialPosition;
|
||||
}
|
||||
@ -338,6 +338,11 @@ int32_t CStack::unitBaseAmount() const
|
||||
return baseAmount;
|
||||
}
|
||||
|
||||
const IBonusBearer* CStack::getBonusBearer() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
bool CStack::unitHasAmmoCart(const battle::Unit * unit) const
|
||||
{
|
||||
for(const CStack * st : battle->stacks)
|
||||
|
@ -84,6 +84,8 @@ public:
|
||||
|
||||
void spendMana(ServerCallback * server, const int spellCost) const override;
|
||||
|
||||
const IBonusBearer* getBonusBearer() const override;
|
||||
|
||||
PlayerColor getOwner() const override
|
||||
{
|
||||
return this->owner;
|
||||
|
@ -413,6 +413,11 @@ int32_t CUnitState::creatureIconIndex() const
|
||||
return unitType()->getIconIndex();
|
||||
}
|
||||
|
||||
FactionID CUnitState::getFaction() const
|
||||
{
|
||||
return unitType()->getFaction();
|
||||
}
|
||||
|
||||
int32_t CUnitState::getCasterUnitId() const
|
||||
{
|
||||
return static_cast<int32_t>(unitId());
|
||||
|
@ -247,6 +247,8 @@ public:
|
||||
void localInit(const IUnitEnvironment * env_);
|
||||
void serializeJson(JsonSerializeFormat & handler);
|
||||
|
||||
FactionID getFaction() const override;
|
||||
|
||||
void afterAttack(bool ranged, bool counter);
|
||||
|
||||
void afterNewRound();
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include "../serializer/JsonDeserializer.h"
|
||||
#include "../serializer/JsonSerializer.h"
|
||||
|
||||
#include <vcmi/Faction.h>
|
||||
#include <vcmi/FactionService.h>
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
namespace battle
|
||||
@ -43,6 +46,24 @@ std::string Unit::getDescription() const
|
||||
return fmt.str();
|
||||
}
|
||||
|
||||
//TODO: deduplicate these functions
|
||||
const IBonusBearer* Unit::getBonusBearer() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TerrainId Unit::getNativeTerrain() const
|
||||
{
|
||||
const std::string cachingStringNoTerrainPenalty = "type_NO_TERRAIN_PENALTY_sANY";
|
||||
static const auto selectorNoTerrainPenalty = Selector::typeSubtype(Bonus::NO_TERRAIN_PENALTY, static_cast<int>(ETerrainId::ANY_TERRAIN));
|
||||
|
||||
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
|
||||
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
|
||||
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
|
||||
? TerrainId(ETerrainId::ANY_TERRAIN)
|
||||
: VLC->factions()->getById(getFaction())->getNativeTerrain();
|
||||
}
|
||||
|
||||
std::vector<BattleHex> Unit::getSurroundingHexes(BattleHex assumedPosition) const
|
||||
{
|
||||
BattleHex hex = (assumedPosition != BattleHex::INVALID) ? assumedPosition : getPosition(); //use hypothetical position
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vcmi/Entity.h>
|
||||
#include <vcmi/spells/Caster.h>
|
||||
|
||||
#include "../HeroBonus.h"
|
||||
@ -40,7 +41,7 @@ namespace BattlePhases
|
||||
|
||||
class CUnitState;
|
||||
|
||||
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer
|
||||
class DLL_LINKAGE Unit : public IUnitInfo, public spells::Caster, public virtual IBonusBearer, public WithBonuses, public WithNativeTerrain
|
||||
{
|
||||
public:
|
||||
virtual ~Unit();
|
||||
@ -126,6 +127,11 @@ public:
|
||||
|
||||
int getRawSurrenderCost() const;
|
||||
|
||||
//WithBonuses
|
||||
const IBonusBearer* getBonusBearer() const override;
|
||||
//WithNativeTerrain
|
||||
TerrainId getNativeTerrain() const override;
|
||||
|
||||
//NOTE: save could possibly be const, but this requires heavy changes to Json serialization,
|
||||
//also this method should be called only after modifying object
|
||||
virtual void save(JsonNode & data) = 0;
|
||||
|
@ -84,6 +84,16 @@ ui32 CGHeroInstance::getTileCost(const TerrainTile & dest, const TerrainTile & f
|
||||
return static_cast<ui32>(ret);
|
||||
}
|
||||
|
||||
FactionID CGHeroInstance::getFaction() const
|
||||
{
|
||||
return FactionID(type->heroClass->faction);
|
||||
}
|
||||
|
||||
const IBonusBearer* CGHeroInstance::getBonusBearer() const
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
TerrainId CGHeroInstance::getNativeTerrain() const
|
||||
{
|
||||
// NOTE: in H3 neutral stacks will ignore terrain penalty only if placed as topmost stack(s) in hero army.
|
||||
@ -96,7 +106,7 @@ TerrainId CGHeroInstance::getNativeTerrain() const
|
||||
|
||||
for(const auto & stack : stacks)
|
||||
{
|
||||
TerrainId stackNativeTerrain = stack.second->type->getNativeTerrain(); //consider terrain bonuses e.g. Lodestar.
|
||||
TerrainId stackNativeTerrain = stack.second->getNativeTerrain(); //consider terrain bonuses e.g. Lodestar.
|
||||
|
||||
if(stackNativeTerrain == ETerrainId::NONE)
|
||||
continue;
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator, public CArtifactSet, public spells::Caster
|
||||
class DLL_LINKAGE CGHeroInstance : public CArmedInstance, public IBoatGenerator, public CArtifactSet, public spells::Caster, public WithBonuses, public WithNativeTerrain
|
||||
{
|
||||
// We serialize heroes into JSON for crossover
|
||||
friend class CCampaignState;
|
||||
@ -156,7 +156,9 @@ public:
|
||||
bool needsLastStack()const override;
|
||||
|
||||
ui32 getTileCost(const TerrainTile & dest, const TerrainTile & from, const TurnInfo * ti) const; //move cost - applying pathfinding skill, road and terrain modifiers. NOT includes diagonal move penalty, last move levelling
|
||||
TerrainId getNativeTerrain() const;
|
||||
//WithNativeTerrain
|
||||
FactionID getFaction() const override;
|
||||
TerrainId getNativeTerrain() const override;
|
||||
int getLowestCreatureSpeed() const;
|
||||
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
|
||||
si32 getManaNewTurn() const; //calculate how much mana this hero is going to have the next day
|
||||
@ -246,6 +248,9 @@ public:
|
||||
std::string nodeName() const override;
|
||||
si32 manaLimit() const override;
|
||||
|
||||
///WithBonuses
|
||||
const IBonusBearer* getBonusBearer() const override;
|
||||
|
||||
CBonusSystemNode * whereShouldBeAttachedOnSiege(const bool isBattleOutsideTown) const;
|
||||
CBonusSystemNode * whereShouldBeAttachedOnSiege(CGameState * gs);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user