1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-09-16 09:26:28 +02:00

improvements in battles

This commit is contained in:
mateuszb
2008-05-30 11:53:04 +00:00
parent 21a8d87796
commit 88a29416da
7 changed files with 100 additions and 13 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -264,17 +264,9 @@ 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)
{
stackAtEnd = true;
break;
}
}
for(int g=0; g<curB->stacks.size(); ++g)
{
if(curB->stacks[g]->ID == ID)
{
@@ -282,6 +274,21 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
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]->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))
{
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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);
//-------------//