Quellcode durchsuchen

* support for new objects:
- magic plains
- fiery fields
- rock lands
- magic clouds
- lucid pools
- holy ground
- clover field
- evil fog

mateuszb vor 16 Jahren
Ursprung
Commit
1c2edcf496
5 geänderte Dateien mit 124 neuen und 26 gelöschten Zeilen
  1. 10 23
      client/CSpellWindow.cpp
  2. 3 1
      client/CSpellWindow.h
  3. 11 1
      hch/CObjectHandler.cpp
  4. 2 1
      lib/HeroBonus.h
  5. 98 0
      server/CGameHandler.cpp

+ 10 - 23
client/CSpellWindow.cpp

@@ -77,10 +77,11 @@ void SpellbookInteractiveArea::deactivate()
 	Hoverable::deactivate();
 }
 
-CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * myHero, bool openOnBattleSpells):
+CSpellWindow::CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, bool openOnBattleSpells):
 	battleSpellsOnly(openOnBattleSpells),
 	selectedTab(4),
-	spellSite(0)
+	spellSite(0),
+	myHero(_myHero)
 {
 	//initializing castable spells
 	for(ui32 v=0; v<CGI->spellh->spells.size(); ++v)
@@ -444,31 +445,17 @@ void CSpellWindow::show(SDL_Surface *to)
 
 		blitAt(spells->ourImages[spellAreas[b]->mySpell].bitmap, spellAreas[b]->pos.x, spellAreas[b]->pos.y, to);
 
-		Uint8 bestSchool = -1, bestslvl = 0;
+		Uint8 bestSchool = -1,
+			bestslvl =  myHero->getSpellSchoolLevel( &CGI->spellh->spells[spellAreas[b]->mySpell] );
+
 		if(CGI->spellh->spells[spellAreas[b]->mySpell].air)
-			if(schoolLvls[0] >= bestslvl)
-			{
-				bestSchool = 0;
-				bestslvl = schoolLvls[0];
-			}
+			bestSchool = 0;
 		if(CGI->spellh->spells[spellAreas[b]->mySpell].fire)
-			if(schoolLvls[1] >= bestslvl)
-			{
-				bestSchool = 1;
-				bestslvl = schoolLvls[1];
-			}
+			bestSchool = 1;
 		if(CGI->spellh->spells[spellAreas[b]->mySpell].water)
-			if(schoolLvls[2] >= bestslvl)
-			{
-				bestSchool = 2;
-				bestslvl = schoolLvls[2];
-			}
+			bestSchool = 2;
 		if(CGI->spellh->spells[spellAreas[b]->mySpell].earth)
-			if(schoolLvls[3] >= bestslvl)
-			{
-				bestSchool = 3;
-				bestslvl = schoolLvls[3];
-			}
+			bestSchool = 3;
 
 		//printing border (indicates level of magic school)
 		blitAt(schoolBorders[bestSchool]->ourImages[bestslvl].bitmap, spellAreas[b]->pos.x, spellAreas[b]->pos.y, to);

+ 3 - 1
client/CSpellWindow.h

@@ -77,13 +77,15 @@ private:
 	std::set<ui32> mySpells; //all spels in this spellbook
 	Uint8 schoolLvls[4]; //levels of magic for different schools: [0]: air, [1]: fire, [2]: water, [3]: earth; 0 - none, 1 - beginner, 2 - medium, 3 - expert
 
+	const CGHeroInstance * myHero; //hero whose spells are presented
+
 	void computeSpellsPerArea(); //recalculates spellAreas::mySpell
 
 	void turnPageLeft();
 	void turnPageRight();
 
 public:
-	CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * myHero, bool openOnBattleSpells = true); //c-tor
+	CSpellWindow(const SDL_Rect & myRect, const CGHeroInstance * _myHero, bool openOnBattleSpells = true); //c-tor
 	~CSpellWindow(); //d-tor
 
 	void fexitb();

+ 11 - 1
hch/CObjectHandler.cpp

@@ -828,7 +828,6 @@ int CGHeroInstance::getTotalStrength() const
 
 ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell) const
 {
-	//TODO: skill level may be different on special terrain
 	ui8 skill = 0; //skill level
 
 	if(spell->fire)
@@ -840,6 +839,17 @@ ui8 CGHeroInstance::getSpellSchoolLevel(const CSpell * spell) const
 	if(spell->earth)
 		skill = std::max(skill,getSecSkillLevel(17));
 
+	//bonuses (eg. from special terrains)
+	skill = std::max<ui8>(skill, valOfBonuses(HeroBonus::MAGIC_SCHOOL_SKILL, 0)); //any school bonus
+	if(spell->fire)
+		skill = std::max<ui8>(skill, valOfBonuses(HeroBonus::MAGIC_SCHOOL_SKILL, 1));
+	if(spell->air)
+		skill = std::max<ui8>(skill, valOfBonuses(HeroBonus::MAGIC_SCHOOL_SKILL, 2));
+	if(spell->water)
+		skill = std::max<ui8>(skill, valOfBonuses(HeroBonus::MAGIC_SCHOOL_SKILL, 4));
+	if(spell->earth)
+		skill = std::max<ui8>(skill, valOfBonuses(HeroBonus::MAGIC_SCHOOL_SKILL, 8));
+
 	return skill;
 }
 

+ 2 - 1
lib/HeroBonus.h

@@ -41,7 +41,8 @@ struct DLL_EXPORT HeroBonus
 		WHIRLPOOL_PROTECTION, //hero won't lose army when teleporting through whirlpool
 		SPELL, //hero knows spell, val - skill level (0 - 3), subtype - spell id
 		SPELLS_OF_LEVEL, //hero knows all spells of given level, val - skill level; subtype - level
-		ENEMY_CANT_ESCAPE //for shackles of war
+		ENEMY_CANT_ESCAPE, //for shackles of war
+		MAGIC_SCHOOL_SKILL, //eg. for magic plains terrain, subtype: school of magic (0 - all, 1 - fire, 2 - air, 4 - water, 8 - earth), value - level
 	};
 	enum BonusDuration{PERMANENT, ONE_BATTLE, ONE_DAY, ONE_WEEK};
 	enum BonusSource{ARTIFACT, OBJECT};

+ 98 - 0
server/CGameHandler.cpp

@@ -1056,6 +1056,104 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
 		}
 	}
 
+	//giving terrain premies for heroes & stacks
+
+	int bonusSubtype = -1;
+	switch(terType)
+	{
+	case 9: //magic plains
+		{
+			bonusSubtype = 0;
+		}
+	case 14: //fiery fields
+		{
+			if(bonusSubtype == -1) bonusSubtype = 1;
+		}
+	case 15: //rock lands
+		{
+			if(bonusSubtype == -1) bonusSubtype = 8;
+		}
+	case 16: //magic clouds
+		{
+			if(bonusSubtype == -1) bonusSubtype = 2;
+		}
+	case 17: //lucid pools
+		{
+			if(bonusSubtype == -1) bonusSubtype = 4;
+		}
+
+		{ //common part for cases 9, 14, 15, 16, 17
+			const CGHeroInstance * cHero = NULL;
+			for(int i=0; i<2; ++i)
+			{
+				if(i == 0) cHero = hero1;
+				else cHero = hero2;
+
+				if(cHero == NULL) continue;
+
+				GiveBonus gs;
+				gs.bonus = HeroBonus(HeroBonus::ONE_BATTLE, HeroBonus::MAGIC_SCHOOL_SKILL, HeroBonus::OBJECT, 3, -1, "", bonusSubtype);
+				gs.hid = cHero->id;
+
+				sendAndApply(&gs);
+			}
+
+			break;
+		}
+
+	case 18: //holy ground
+		{
+			for(int g=0; g<stacks.size(); ++g) //+1 morale bonus for good creatures, -1 morale bonus for evil creatures
+			{
+				if(stacks[g]->creature->faction == 0
+					|| stacks[g]->creature->faction == 1
+					|| stacks[g]->creature->faction == 2) 
+				{
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 1, StackFeature::OTHER_SOURCE));
+				}
+				else if(stacks[g]->creature->faction == 3
+					|| stacks[g]->creature->faction == 4
+					|| stacks[g]->creature->faction == 5)
+				{
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, -1, StackFeature::OTHER_SOURCE));
+				}
+			}
+			break;
+		}
+	case 19: //clover field
+		{
+			for(int g=0; g<stacks.size(); ++g)
+			{
+				if(stacks[g]->creature->faction == -1) //+2 luck bonus for neutral creatures
+				{
+					stacks[g]->features.push_back(makeFeature(StackFeature::LUCK_BONUS, StackFeature::WHOLE_BATTLE, 0, 2, StackFeature::OTHER_SOURCE));
+				}
+			}
+			break;
+		}
+	case 20: //evil fog
+		{
+			for(int g=0; g<stacks.size(); ++g) //-1 morale bonus for good creatures, +1 morale bonus for evil creatures
+			{
+				if(stacks[g]->creature->faction == 0
+					|| stacks[g]->creature->faction == 1
+					|| stacks[g]->creature->faction == 2) 
+				{
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, -1, StackFeature::OTHER_SOURCE));
+				}
+				else if(stacks[g]->creature->faction == 3
+					|| stacks[g]->creature->faction == 4
+					|| stacks[g]->creature->faction == 5)
+				{
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 1, StackFeature::OTHER_SOURCE));
+				}
+			}
+			break;
+		}
+	}
+
+	//premies given
+
 	//block engaged players
 	if(hero1->tempOwner<PLAYER_LIMIT)
 		states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);