Browse Source

Fixed Death Stare of Commanders, additional tweaks.

DjWarmonger 12 years ago
parent
commit
c8bb363a45

+ 8 - 0
lib/BattleState.cpp

@@ -918,6 +918,14 @@ ui32 CStack::Speed( int turn /*= 0*/ , bool useBind /* = false*/) const
 	return speed;
 }
 
+ui32 CStack::level() const
+{
+	if (base)
+		return base->getLevel(); //creatture or commander
+	else
+		return std::max(1, (int)getCreature()->level); //war machine, clone etc
+}
+
 si32 CStack::magicResistance() const
 {
 	si32 magicResistance;

+ 1 - 0
lib/BattleState.h

@@ -169,6 +169,7 @@ public:
 	bool canMove(int turn = 0) const; //if stack can move
 	bool canBeHealed() const; //for first aid tent - only harmed stacks that are not war machines
 	ui32 Speed(int turn = 0, bool useBind = false) const; //get speed of creature with all modificators
+	ui32 level() const;
 	si32 magicResistance() const; //include aura of resistance
 	static void stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse);
 	std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast

+ 1 - 0
lib/CArtHandler.cpp

@@ -676,6 +676,7 @@ CArtifactInstance * CArtifactInstance::createScroll( const CSpell *s)
 void CArtifactInstance::init()
 {
 	id = ArtifactInstanceID();
+	id = static_cast<ArtifactInstanceID>(ArtifactID::NONE); //to be randomized
 	setNodeType(ARTIFACT_INSTANCE);
 }
 

+ 10 - 0
lib/CCreatureSet.cpp

@@ -513,6 +513,11 @@ int CStackInstance::getExpRank() const
 	}
 }
 
+int CStackInstance::getLevel() const
+{
+	return std::max (1, (int)type->level);
+}
+
 si32 CStackInstance::magicResistance() const
 {
 	si32 val = valOfBonuses(Selector::type(Bonus::MAGIC_RESISTANCE));
@@ -717,6 +722,11 @@ int CCommanderInstance::getExpRank() const
 	return VLC->heroh->level (experience);
 }
 
+int CCommanderInstance::getLevel() const
+{
+	return std::max (1, getExpRank());
+}
+
 void CCommanderInstance::levelUp ()
 {
 	level++;

+ 2 - 0
lib/CCreatureSet.h

@@ -63,6 +63,7 @@ public:
 	int getQuantityID() const;
 	std::string getQuantityTXT(bool capitalized = true) const;
 	virtual int getExpRank() const;
+	virtual int getLevel() const; //different for regular stack and commander
 	si32 magicResistance() const;
 	CreatureID getCreatureID() const; //-1 if not available
 	std::string getName() const; //plural or singular
@@ -104,6 +105,7 @@ public:
 
 	ui64 getPower() const {return 0;};
 	int getExpRank() const;
+	int getLevel() const OVERRIDE; 
 	ArtBearer::ArtBearer bearerType() const OVERRIDE; //from CArtifactSet
 
 	template <typename Handler> void serialize(Handler &h, const int version)

+ 3 - 1
lib/CObjectHandler.cpp

@@ -3842,9 +3842,11 @@ void CGArtifact::initObj()
 	}
 	if(ID == Obj::SPELL_SCROLL)
 		subID = 1;
-
+	
 	assert(storedArtifact->artType);
 	assert(storedArtifact->getParentNodes().size());
+
+	//assert(storedArtifact->artType->id == subID); //this does not stop desync
 }
 
 void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const

+ 2 - 2
lib/Mapping/MapFormatH3M.cpp

@@ -677,7 +677,7 @@ CArtifactInstance * CMapLoaderH3M::createArtifact(int aid, int spellID /*= -1*/)
 	}
 	else //FIXME: create combined artifact instance for random combined artifacts, just in case
 	{
-		a = new CArtifactInstance();
+		a = new CArtifactInstance(); //random, empty
 	}
 
 	map->addNewArtifactInstance(a);
@@ -1092,7 +1092,7 @@ void CMapLoaderH3M::readObjects()
 		case Obj::RANDOM_RELIC_ART:
 		case Obj::SPELL_SCROLL:
 			{
-				int artID = -1;
+				int artID = ArtifactID::NONE; //random, set later
 				int spellID = -1;
 				CGArtifact * art = new CGArtifact();
 				nobj = art;

+ 3 - 3
server/CGameHandler.cpp

@@ -5357,7 +5357,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 		return;
 	}
 
-	if (attacker->hasBonusOfType(Bonus::DEATH_STARE)) // spell id 79
+	if (attacker->hasBonusOfType(Bonus::DEATH_STARE) && bat.bsa.size())
 	{
 		// mechanics of Death Stare as in H3:
 		// each gorgon have 10% chance to kill (counted separately in H3) -> binomial distribution
@@ -5374,10 +5374,10 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 		int maxToKill = (attacker->count * chanceToKill + 99) / 100;
 		vstd::amin(staredCreatures, maxToKill);
 
-		staredCreatures += attacker->type->level * attacker->valOfBonuses(Bonus::DEATH_STARE, 1);
+		staredCreatures += (attacker->level() * attacker->valOfBonuses(Bonus::DEATH_STARE, 1)) / gs->curB->battleGetStackByID(bat.bsa[0].stackAttacked)->level();
 		if (staredCreatures)
 		{
-			if (bat.bsa.size() && bat.bsa[0].newAmount > 0) //TODO: death stare was not originally available for multiple-hex attacks, but...
+			if (bat.bsa[0].newAmount > 0) //TODO: death stare was not originally available for multiple-hex attacks, but...
 			handleSpellCasting(SpellID::DEATH_STARE, 0, gs->curB->battleGetStackByID(bat.bsa[0].stackAttacked)->position,
 				!attacker->attackerOwned, attacker->owner, NULL, NULL, staredCreatures, ECastingMode::AFTER_ATTACK_CASTING, attacker);
 		}