Browse Source

* fixed #282, #295 and partially #299

mateuszb 15 năm trước cách đây
mục cha
commit
b0a587ff08
4 tập tin đã thay đổi với 62 bổ sung8 xóa
  1. 39 4
      client/CBattleInterface.cpp
  2. 13 0
      client/CBattleInterface.h
  3. 2 1
      client/CSpellWindow.cpp
  4. 8 3
      server/CGameHandler.cpp

+ 39 - 4
client/CBattleInterface.cpp

@@ -114,6 +114,33 @@ CBattleAnimation::CBattleAnimation(CBattleInterface * _owner)
 : owner(_owner), ID(_owner->animIDhelper++)
 {}
 
+//Dummy animation
+
+
+bool CDummyAnim::init()
+{
+	return true;
+}
+
+void CDummyAnim::nextFrame()
+{
+	counter++;
+	if(counter > howMany)
+		endAnim();
+}
+
+void CDummyAnim::endAnim()
+{
+	CBattleAnimation::endAnim();
+
+	delete this;
+}
+
+CDummyAnim::CDummyAnim(CBattleInterface * _owner, int howManyFrames) : CBattleAnimation(_owner), howMany(howManyFrames), counter(0)
+{
+}
+
+
 //effect animation
 bool CSpellEffectAnim::init()
 {
@@ -1480,12 +1507,16 @@ void CBattleInterface::show(SDL_Surface * to)
 	//double loop because dead stacks should be printed first
 	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
 	{
+		if(creAnims.find(j->second.ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
+			continue;
 		if(creAnims[j->second.ID]->getType() != 5 && j->second.position >= 0) //don't show turrets here
 			stackAliveByHex[j->second.position].push_back(j->second.ID);
 	}
 	std::vector<int> stackDeadByHex[BFIELD_SIZE];
 	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
 	{
+		if(creAnims.find(j->second.ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
+			continue;
 		if(creAnims[j->second.ID]->getType() == 5)
 			stackDeadByHex[j->second.position].push_back(j->second.ID);
 	}
@@ -2601,6 +2632,9 @@ void CBattleInterface::spellCast(SpellCast * sc)
 			displayEffect(spell.mainEffectAnim, LOCPLINT->cb->battleGetStackByID(*it, false)->position);
 		}
 		break;
+	case 66: case 67: case 68: case 69: //summon elemental
+		addNewAnim(new CDummyAnim(this, 2));
+		break;
 	} //switch(sc->id)
 
 	//support for resistance
@@ -2699,14 +2733,15 @@ void CBattleInterface::castThisSpell(int spellID)
 	{
 		spellSelMode = 4;
 	}
+	if(CGI->spellh->spells[spellID].range[ castingHero->getSpellSchoolLevel(&CGI->spellh->spells[spellID]) ] == "X") //spell has no range
+	{
+		spellSelMode = -1;
+	}
 	if(spellSelMode == -1) //user does not have to select location
 	{
 		spellToCast->destinationTile = -1;
 		LOCPLINT->cb->battleMakeAction(spellToCast);
-		delete spellToCast;
-		spellToCast = NULL;
-		spellDestSelectMode = false;
-		CGI->curh->changeGraphic(1, 6);
+		endCastingSpell();
 	}
 	else
 	{

+ 13 - 0
client/CBattleInterface.h

@@ -73,6 +73,19 @@ public:
 	CBattleAnimation(CBattleInterface * _owner);
 };
 
+class CDummyAnim : public CBattleAnimation
+{
+private:
+	int counter;
+	int howMany;
+public:
+	bool init();
+	void nextFrame();
+	void endAnim();
+
+	CDummyAnim(CBattleInterface * _owner, int howManyFrames);
+};
+
 class CSpellEffectAnim : public CBattleAnimation
 {
 private:

+ 2 - 1
client/CSpellWindow.cpp

@@ -669,8 +669,9 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
 		//we will cast a spell
 		if(LOCPLINT->battleInt && LOCPLINT->cb->battleCanCastSpell() && LOCPLINT->cb->getSpellCost(&CGI->spellh->spells[mySpell], owner->myHero) <= owner->myHero->mana) //if battle window is open
 		{
-			LOCPLINT->battleInt->castThisSpell(mySpell);
+			int spell = mySpell;
 			owner->fexitb();
+			LOCPLINT->battleInt->castThisSpell(spell);
 		}
 	}
 }

+ 8 - 3
server/CGameHandler.cpp

@@ -2721,13 +2721,15 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 				complain("catapult tried to attack non-catapultable hex!");
 				break;
 			}
+			int wallInitHP = gs->curB->si.wallState[attackedPart];
+			int dmgAlreadyDealt = 0; //in successive iterations damage is dealt but not yet substracted from wall's HPs
 			for(int g=0; g<sbi.shots; ++g)
 			{
-				if(gs->curB->si.wallState[attackedPart] == 3) //it's not destroyed
+				if(wallInitHP + dmgAlreadyDealt == 3) //it's not destroyed
 					continue;
 				
 				CatapultAttack ca; //package for clients
-				std::pair< std::pair< ui8, si16 >, ui8> attack;
+				std::pair< std::pair< ui8, si16 >, ui8> attack; //<< attackedPart , destination tile >, damageDealt >
 				attack.first.first = attackedPart;
 				attack.first.second = ba.destinationTile;
 				attack.second = 0;
@@ -2765,10 +2767,13 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 					{
 						if(dmgRand <= dmgChance[v])
 						{
-							attack.second = v;
+							attack.second = std::min(3 - dmgAlreadyDealt - wallInitHP, v);
+							dmgAlreadyDealt += attack.second;
 							break;
 						}
 					}
+
+					//removing creatures in turrets / keep if one is destroyed
 					if(attack.second > 0 && (attackedPart == 0 || attackedPart == 1 || attackedPart == 6))
 					{
 						int posRemove = -1;