mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-29 23:07:48 +02:00
implemented VISIONS spell (partially)
(-) todo: agressivnes
This commit is contained in:
@@ -411,7 +411,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town):
|
|||||||
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
|
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
|
||||||
{
|
{
|
||||||
InfoAboutTown iah;
|
InfoAboutTown iah;
|
||||||
LOCPLINT->cb->getTownInfo(town, iah);
|
LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero?
|
||||||
|
|
||||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
new CTownTooltip(Point(9, 10), iah);
|
new CTownTooltip(Point(9, 10), iah);
|
||||||
@@ -421,7 +421,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero):
|
|||||||
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position))
|
CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position))
|
||||||
{
|
{
|
||||||
InfoAboutHero iah;
|
InfoAboutHero iah;
|
||||||
LOCPLINT->cb->getHeroInfo(hero, iah);
|
LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero?
|
||||||
|
|
||||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
new CHeroTooltip(Point(9, 10), iah);
|
new CHeroTooltip(Point(9, 10), iah);
|
||||||
|
|||||||
@@ -55,13 +55,35 @@
|
|||||||
"effects" : {
|
"effects" : {
|
||||||
"visionsMonsters" : {
|
"visionsMonsters" : {
|
||||||
"val" : 2
|
"val" : 2
|
||||||
|
},
|
||||||
|
"visionsHeroes" :{
|
||||||
|
"type" : "VISIONS",
|
||||||
|
"subtype" : 1,
|
||||||
|
"duration" : "ONE_DAY",
|
||||||
|
"val" : 2,
|
||||||
|
"valueType" : "INDEPENDENT_MAX"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"expert":{
|
"expert":{
|
||||||
"effects" : {
|
"effects" : {
|
||||||
"visionsMonsters" : {
|
"visionsMonsters" : {
|
||||||
"val" : 3
|
"val" : 3
|
||||||
|
},
|
||||||
|
"visionsHeroes" :{
|
||||||
|
"type" : "VISIONS",
|
||||||
|
"subtype" : 1,
|
||||||
|
"duration" : "ONE_DAY",
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "INDEPENDENT_MAX"
|
||||||
|
},
|
||||||
|
"visionsTowns" :{
|
||||||
|
"type" : "VISIONS",
|
||||||
|
"subtype" : 2,
|
||||||
|
"duration" : "ONE_DAY",
|
||||||
|
"val" : 3,
|
||||||
|
"valueType" : "INDEPENDENT_MAX"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,14 +201,23 @@ int CGameInfoCallback::howManyTowns(PlayerColor Player) const
|
|||||||
return gs->players[Player].towns.size();
|
return gs->players[Player].towns.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameInfoCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest ) const
|
bool CGameInfoCallback::getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject/* = nullptr*/) const
|
||||||
{
|
{
|
||||||
ERROR_RET_VAL_IF(!isVisible(town, player), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
ERROR_RET_VAL_IF(!isVisible(town, player), "Town is not visible!", false); //it's not a town or it's not visible for layer
|
||||||
bool detailed = hasAccess(town->tempOwner);
|
bool detailed = hasAccess(town->tempOwner);
|
||||||
|
|
||||||
//TODO vision support
|
//TODO vision support
|
||||||
if(town->ID == Obj::TOWN)
|
if(town->ID == Obj::TOWN)
|
||||||
|
{
|
||||||
|
if(!detailed && nullptr != selectedObject)
|
||||||
|
{
|
||||||
|
const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);
|
||||||
|
if(nullptr != selectedHero)
|
||||||
|
detailed = selectedHero->hasVisions(town, 1);
|
||||||
|
}
|
||||||
|
|
||||||
dest.initFromTown(static_cast<const CGTownInstance *>(town), detailed);
|
dest.initFromTown(static_cast<const CGTownInstance *>(town), detailed);
|
||||||
|
}
|
||||||
else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2)
|
else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2)
|
||||||
dest.initFromArmy(static_cast<const CArmedInstance *>(town), detailed);
|
dest.initFromArmy(static_cast<const CArmedInstance *>(town), detailed);
|
||||||
else
|
else
|
||||||
@@ -233,15 +242,23 @@ std::vector<const CGObjectInstance*> CGameInfoCallback::getGuardingCreatures (in
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameInfoCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest ) const
|
bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject/* = nullptr*/) const
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero);
|
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(hero);
|
||||||
|
|
||||||
ERROR_RET_VAL_IF(!h, "That's not a hero!", false);
|
ERROR_RET_VAL_IF(!h, "That's not a hero!", false);
|
||||||
ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false);
|
ERROR_RET_VAL_IF(!isVisible(h->getPosition(false)), "That hero is not visible!", false);
|
||||||
|
|
||||||
//TODO vision support
|
bool accessFlag = hasAccess(h->tempOwner);
|
||||||
dest.initFromHero(h, hasAccess(h->tempOwner));
|
|
||||||
|
if(!accessFlag && nullptr != selectedObject)
|
||||||
|
{
|
||||||
|
const CGHeroInstance * selectedHero = dynamic_cast<const CGHeroInstance *>(selectedObject);
|
||||||
|
if(nullptr != selectedHero)
|
||||||
|
accessFlag = selectedHero->hasVisions(hero, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dest.initFromHero(h, accessFlag);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public:
|
|||||||
const CGHeroInstance* getHero(ObjectInstanceID objid) const;
|
const CGHeroInstance* getHero(ObjectInstanceID objid) const;
|
||||||
const CGHeroInstance* getHeroWithSubid(int subid) const;
|
const CGHeroInstance* getHeroWithSubid(int subid) const;
|
||||||
int getHeroCount(PlayerColor player, bool includeGarrisoned) const;
|
int getHeroCount(PlayerColor player, bool includeGarrisoned) const;
|
||||||
bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
|
bool getHeroInfo(const CGObjectInstance * hero, InfoAboutHero & dest, const CGObjectInstance * selectedObject = nullptr) 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
|
||||||
const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
|
const CArtifactInstance * getArtInstance(ArtifactInstanceID aid) const;
|
||||||
@@ -99,7 +99,7 @@ public:
|
|||||||
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
|
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
|
||||||
std::string getTavernGossip(const CGObjectInstance * townOrTavern) const;
|
std::string getTavernGossip(const CGObjectInstance * townOrTavern) const;
|
||||||
EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
EBuildingState::EBuildingState canBuildStructure(const CGTownInstance *t, BuildingID ID);//// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
|
||||||
virtual bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
|
virtual bool getTownInfo(const CGObjectInstance * town, InfoAboutTown & dest, const CGObjectInstance * selectedObject = nullptr) const;
|
||||||
const CTown *getNativeTown(PlayerColor color) const;
|
const CTown *getNativeTown(PlayerColor color) const;
|
||||||
|
|
||||||
//from gs
|
//from gs
|
||||||
|
|||||||
@@ -1343,3 +1343,24 @@ void CGHeroInstance::levelUpAutomatically()
|
|||||||
levelUp(proposedSecondarySkills);
|
levelUp(proposedSecondarySkills);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGHeroInstance::hasVisions(const CGObjectInstance * target, const int subtype) const
|
||||||
|
{
|
||||||
|
//VISIONS spell support
|
||||||
|
|
||||||
|
const std::string cached = boost::to_string((boost::format("type_%d__subtype_%d") % Bonus::VISIONS % subtype));
|
||||||
|
|
||||||
|
const int visionsMultiplier = valOfBonuses(Selector::typeSubtype(Bonus::VISIONS,subtype), cached);
|
||||||
|
|
||||||
|
int visionsRange = visionsMultiplier * getPrimSkillLevel(PrimarySkill::SPELL_POWER);
|
||||||
|
|
||||||
|
if (visionsMultiplier > 0)
|
||||||
|
vstd::amax(visionsRange, 3); //minimum range is 3 tiles, but only if VISIONS bonus present
|
||||||
|
|
||||||
|
const int distance = target->pos.dist2d(getPosition(false));
|
||||||
|
|
||||||
|
logGlobal->debug(boost::to_string(boost::format("Visions: dist %d, mult %d, range %d") % distance % visionsMultiplier % visionsRange));
|
||||||
|
|
||||||
|
return (distance < visionsRange) && (target->pos.z == pos.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,6 +194,8 @@ public:
|
|||||||
void recreateSecondarySkillsBonuses();
|
void recreateSecondarySkillsBonuses();
|
||||||
void updateSkill(SecondarySkill which, int val);
|
void updateSkill(SecondarySkill which, int val);
|
||||||
|
|
||||||
|
bool hasVisions(const CGObjectInstance * target, const int subtype) const;
|
||||||
|
|
||||||
CGHeroInstance();
|
CGHeroInstance();
|
||||||
virtual ~CGHeroInstance();
|
virtual ~CGHeroInstance();
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -101,22 +101,8 @@ std::string CGCreature::getHoverText(PlayerColor player) const
|
|||||||
|
|
||||||
std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
|
||||||
{
|
{
|
||||||
//VISIONS spell support
|
|
||||||
|
|
||||||
static const std::string cached = boost::to_string((boost::format("type_%d__subtype_0") % Bonus::VISIONS));
|
|
||||||
|
|
||||||
std::string hoverName;
|
std::string hoverName;
|
||||||
|
if(hero->hasVisions(this, 0))
|
||||||
const int visionsMultiplier = hero->valOfBonuses(Selector::typeSubtype(Bonus::VISIONS,0), cached);
|
|
||||||
|
|
||||||
int visionsRadius = visionsMultiplier * hero->getPrimSkillLevel(PrimarySkill::SPELL_POWER);
|
|
||||||
|
|
||||||
if (visionsMultiplier > 0)
|
|
||||||
vstd::amin(visionsRadius, 3); //minimum range is 3 tiles, but only if VISIONS bonus present
|
|
||||||
|
|
||||||
const bool inVisionsRange = (pos.dist2d(hero->pos) < visionsRadius) && (pos.z == hero->pos.z);
|
|
||||||
|
|
||||||
if(inVisionsRange)
|
|
||||||
{
|
{
|
||||||
MetaString ms;
|
MetaString ms;
|
||||||
ms << stacks.begin()->second->count;
|
ms << stacks.begin()->second->count;
|
||||||
|
|||||||
Reference in New Issue
Block a user