Browse Source

implemented VISIONS spell (partially)
(-) todo: agressivnes

AlexVinS 10 years ago
parent
commit
b846b717a1

+ 2 - 2
client/windows/InfoWindows.cpp

@@ -411,7 +411,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town):
 	CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position))
 {
 	InfoAboutTown iah;
-	LOCPLINT->cb->getTownInfo(town, iah);
+	LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero?
 
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	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))
 {
 	InfoAboutHero iah;
-	LOCPLINT->cb->getHeroInfo(hero, iah);
+	LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero?
 
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	new CHeroTooltip(Point(9, 10), iah);

+ 22 - 0
config/spells/adventure.json

@@ -55,13 +55,35 @@
 				"effects" : {
 					"visionsMonsters" : {
 						"val" : 2
+					},
+					"visionsHeroes" :{
+						"type" : "VISIONS",
+						"subtype" : 1,
+						"duration" : "ONE_DAY",
+						"val" : 2,
+						"valueType" : "INDEPENDENT_MAX"					
 					}
+					
 				}			
 			},
 			"expert":{
 				"effects" : {
 					"visionsMonsters" : {
 						"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"					
 					}
 				}			
 			}

+ 21 - 4
lib/CGameInfoCallback.cpp

@@ -201,14 +201,23 @@ int CGameInfoCallback::howManyTowns(PlayerColor Player) const
 	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
 	bool detailed = hasAccess(town->tempOwner);
 
 	//TODO vision support
 	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);
+	}		
 	else if(town->ID == Obj::GARRISON || town->ID == Obj::GARRISON2)
 		dest.initFromArmy(static_cast<const CArmedInstance *>(town), detailed);
 	else
@@ -233,15 +242,23 @@ std::vector<const CGObjectInstance*> CGameInfoCallback::getGuardingCreatures (in
 	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);
 
 	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);
 
-	//TODO vision support
-	dest.initFromHero(h, hasAccess(h->tempOwner));
+	bool accessFlag = 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;
 }
 

+ 2 - 2
lib/CGameInfoCallback.h

@@ -69,7 +69,7 @@ public:
 	const CGHeroInstance* getHero(ObjectInstanceID objid) const;
 	const CGHeroInstance* getHeroWithSubid(int subid) 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 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;
@@ -99,7 +99,7 @@ public:
 	std::vector<const CGHeroInstance *> getAvailableHeroes(const CGObjectInstance * townOrTavern) const; //heroes that can be recruited
 	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
-	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;
 
 	//from gs

+ 21 - 0
lib/mapObjects/CGHeroInstance.cpp

@@ -1343,3 +1343,24 @@ void CGHeroInstance::levelUpAutomatically()
 		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);	
+}
+

+ 2 - 0
lib/mapObjects/CGHeroInstance.h

@@ -193,6 +193,8 @@ public:
 	void Updatespecialty();
 	void recreateSecondarySkillsBonuses();
 	void updateSkill(SecondarySkill which, int val);
+	
+	bool hasVisions(const CGObjectInstance * target, const int subtype) const;
 
 	CGHeroInstance();
 	virtual ~CGHeroInstance();

+ 1 - 15
lib/mapObjects/MiscObjects.cpp

@@ -101,22 +101,8 @@ std::string CGCreature::getHoverText(PlayerColor player) 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;
-	
-	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)
+	if(hero->hasVisions(this, 0))
 	{
 		MetaString ms;
 		ms << stacks.begin()->second->count;