瀏覽代碼

improvements in battles

mateuszb 17 年之前
父節點
當前提交
88a29416da
共有 7 個文件被更改,包括 96 次插入9 次删除
  1. 4 0
      CBattleInterface.cpp
  2. 1 0
      CBattleInterface.h
  3. 6 0
      CGameInterface.h
  4. 76 7
      CGameState.cpp
  5. 3 2
      CGameState.h
  6. 5 0
      CPlayerInterface.cpp
  7. 1 0
      CPlayerInterface.h

+ 4 - 0
CBattleInterface.cpp

@@ -361,6 +361,10 @@ void CBattleInterface::stackRemoved(CStack stack)
 	creAnims.erase(stack.ID);
 }
 
+void CBattleInterface::stackKilled(int ID)
+{
+}
+
 void CBattleInterface::stackActivated(int number)
 {
 	givenCommand = NULL;

+ 1 - 0
CBattleInterface.h

@@ -112,6 +112,7 @@ public:
 	//call-ins
 	void newStack(CStack stack); //new stack appeared on battlefield
 	void stackRemoved(CStack stack); //stack disappeared from batlefiled
+	void stackKilled(int ID); //stack has been killed (but corpses remain)
 	void stackActivated(int number); //active stack has been changed
 	void stackMoved(int number, int destHex, bool startMoving, bool endMoving); //stack with id number moved to destHex
 	void stackIsAttacked(int ID); //called when stack id attacked

+ 6 - 0
CGameInterface.h

@@ -70,6 +70,9 @@ public:
 	virtual BattleAction activeStack(int stackID)=0; //called when it's turn of that stack
 	virtual void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CArmedInstance *hero1, CArmedInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner){};
 	virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving)=0;
+	virtual void battleStackAttacking(int ID, int dest)=0;
+	virtual void battleStackIsAttacked(int ID)=0;
+	virtual void battleStackKilled(int ID)=0;
 	//
 
 };
@@ -86,6 +89,9 @@ public:
 	virtual void heroKilled(const CGHeroInstance*){};
 	virtual void heroCreated(const CGHeroInstance*){};
 	virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving){};
+	virtual void battleStackAttacking(int ID, int dest){};
+	virtual void battleStackIsAttacked(int ID){};
+	virtual void battleStackKilled(int ID){};
 	virtual BattleAction activeStack(int stackID) {BattleAction ba; ba.actionType = 3; ba.stackNumber = stackID; return ba;};
 };
 #endif //CGAMEINTERFACE_H

+ 76 - 7
CGameState.cpp

@@ -264,24 +264,31 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 	//first checks
 	if(curB->stackActionPerformed) //because unit cannot be moved more than once
 		return false;
-	bool stackAtEnd = false; //true if there is a stack at the end of the path (we should attack it)
+
 	unsigned char owner = -1; //owner moved of unit
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
-		if(curB->stacks[g]->position == dest)
+		if(curB->stacks[g]->ID == ID)
 		{
-			stackAtEnd = true;
+			owner = curB->stacks[g]->owner;
 			break;
 		}
 	}
+
+	bool stackAtEnd = false; //true if there is a stack at the end of the path (we should attack it)
+	int numberOfStackAtEnd = -1;
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
-		if(curB->stacks[g]->ID == ID)
+		if(curB->stacks[g]->position == dest 
+			|| (curB->stacks[g]->creature->isDoubleWide() && curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == dest)
+			|| (curB->stacks[g]->creature->isDoubleWide() && !curB->stacks[g]->attackerOwned && curB->stacks[g]->position+1 == dest))
 		{
-			owner = curB->stacks[g]->owner;
+			stackAtEnd = true;
+			numberOfStackAtEnd = g;
 			break;
 		}
 	}
+
 	//selecting moved stack
 	CStack * curStack = NULL;
 	for(int y=0; y<curB->stacks.size(); ++y)
@@ -408,12 +415,74 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
 	{
 		if(v!=0 || !stackAtEnd) //it's not the last step
 		{
-			LOCPLINT->battleStackMoved(ID, path[v], v==path.size()-1, v==0);
+			LOCPLINT->battleStackMoved(ID, path[v], v==path.size()-1, v==0 || (stackAtEnd && v==1) );
 			curStack->position = path[v];
 		}
 		else //if it's last step and we should attack unit at the end
 		{
 			LOCPLINT->battleStackAttacking(ID, path[v]);
+			//counting dealt damage
+			int numberOfCres = curStack->amount; //number of attacking creatures
+			int attackDefenseBonus = curStack->creature->attack - curB->stacks[numberOfStackAtEnd]->creature->defence;
+			int damageBase = 0;
+			if(curStack->creature->damageMax == curStack->creature->damageMin) //constant damage
+			{
+				damageBase = curStack->creature->damageMin;
+			}
+			else
+			{
+				damageBase = rand()%(curStack->creature->damageMax - curStack->creature->damageMin) + curStack->creature->damageMin + 1;
+			}
+
+			float dmgBonusMultiplier = 1.0;
+			if(attackDefenseBonus < 0) //decreasing dmg
+			{
+				if(0.02f * (-attackDefenseBonus) > 0.3f)
+				{
+					dmgBonusMultiplier += -0.3f;
+				}
+				else
+				{
+					dmgBonusMultiplier += 0.02f * attackDefenseBonus;
+				}
+			}
+			else //increasing dmg
+			{
+				if(0.05f * attackDefenseBonus > 4.0f)
+				{
+					dmgBonusMultiplier += 4.0f;
+				}
+				else
+				{
+					dmgBonusMultiplier += 0.05f * attackDefenseBonus;
+				}
+			}
+
+			int finalDmg = (float)damageBase * (float)curStack->amount * dmgBonusMultiplier;
+
+			//applying damages
+			int cresKilled = finalDmg / curB->stacks[numberOfStackAtEnd]->creature->hitPoints;
+			int damageFirst = finalDmg % curB->stacks[numberOfStackAtEnd]->creature->hitPoints;
+
+			if( curB->stacks[numberOfStackAtEnd]->firstHPleft <= damageFirst )
+			{
+				curB->stacks[numberOfStackAtEnd]->amount -= 1;
+				curB->stacks[numberOfStackAtEnd]->firstHPleft += curB->stacks[numberOfStackAtEnd]->creature->hitPoints - damageFirst;
+			}
+			else
+			{
+				curB->stacks[numberOfStackAtEnd]->firstHPleft -= damageFirst;
+			}
+
+			curB->stacks[numberOfStackAtEnd]->amount -= cresKilled;
+			if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed
+			{
+				curB->stacks[numberOfStackAtEnd]->amount = 0;
+				curB->stacks[numberOfStackAtEnd]->alive = false;
+				LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID);
+			}
+
+			//damage applied
 		}
 	}
 	curB->stackActionPerformed = true;
@@ -470,7 +539,7 @@ std::vector<int> CGameState::battleGetRange(int ID)
 		accessibility[k] = true;
 	for(int g=0; g<curB->stacks.size(); ++g)
 	{
-		if(curB->stacks[g]->owner == owner && curB->stacks[g]->ID != ID) //we don't want to lock enemy's positions or current unit's position
+		if(curB->stacks[g]->ID != ID) //we don't want to lock current unit's position
 		{
 			accessibility[curB->stacks[g]->position] = false;
 			if(curB->stacks[g]->creature->isDoubleWide()) //if it's a double hex creature

+ 3 - 2
CGameState.h

@@ -44,12 +44,13 @@ public:
 	int ID; //unique ID of stack
 	CCreature * creature;
 	int amount;
+	int firstHPleft; //HP of first creature in stack
 	int owner;
 	bool attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	int position; //position on battlefield
 	bool alive; //true if it is alive
-	CStack(CCreature * C, int A, int O, int I, bool AO):creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO){};
-	CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true){};
+	CStack(CCreature * C, int A, int O, int I, bool AO):creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints){};
+	CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1){};
 };
 
 class CGameState

+ 5 - 0
CPlayerInterface.cpp

@@ -2078,6 +2078,11 @@ void CPlayerInterface::battleStackIsAttacked(int ID)
 	dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID);
 }
 
+void CPlayerInterface::battleStackKilled(int ID)
+{
+	dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID);
+}
+
 void CPlayerInterface::showComp(SComponent comp)
 {
 	adventureInt->infoBar.showComp(&comp,4000);

+ 1 - 0
CPlayerInterface.h

@@ -342,6 +342,7 @@ public:
 	void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving);
 	void battleStackAttacking(int ID, int dest);
 	void battleStackIsAttacked(int ID);
+	void battleStackKilled(int ID);
 
 
 	//-------------//