mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* next part of shooting in battles (there will be more of them)
* now compiles under MSVC * small refactoring / cleaning / fixing / etc.
This commit is contained in:
parent
8209e7d090
commit
016e766fbb
@ -11,6 +11,8 @@
|
||||
#include "hch/CGeneralTextHandler.h"
|
||||
#include <queue>
|
||||
#include <sstream>
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
|
||||
extern SDL_Surface * screen;
|
||||
extern TTF_Font * GEOR13;
|
||||
@ -123,6 +125,22 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
|
||||
if(g->second.creature->isShooting() && CGI->creh->idToProjectile[g->second.creature->idNumber] != std::string())
|
||||
{
|
||||
idToProjectile[g->second.creature->idNumber] = CGI->spriteh->giveDef(CGI->creh->idToProjectile[g->second.creature->idNumber]);
|
||||
|
||||
if(idToProjectile[g->second.creature->idNumber]->ourImages.size() > 2) //add symmetric images
|
||||
{
|
||||
for(int k = idToProjectile[g->second.creature->idNumber]->ourImages.size()-2; k > 1; --k)
|
||||
{
|
||||
Cimage ci;
|
||||
ci.bitmap = CSDL_Ext::rotate01(idToProjectile[g->second.creature->idNumber]->ourImages[k].bitmap);
|
||||
ci.groupNumber = 0;
|
||||
ci.imName = std::string();
|
||||
idToProjectile[g->second.creature->idNumber]->ourImages.push_back(ci);
|
||||
}
|
||||
}
|
||||
for(int s=0; s<idToProjectile[g->second.creature->idNumber]->ourImages.size(); ++s) //alpha transforming
|
||||
{
|
||||
CSDL_Ext::alphaTransform(idToProjectile[g->second.creature->idNumber]->ourImages[s].bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -413,7 +431,7 @@ void CBattleInterface::stackRemoved(CStack stack)
|
||||
creAnims.erase(stack.ID);
|
||||
}
|
||||
|
||||
void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby)
|
||||
void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
creAnims[ID]->setType(5); //death
|
||||
for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i)
|
||||
@ -608,7 +626,7 @@ void CBattleInterface::stackMoved(int number, int destHex, bool startMoving, boo
|
||||
creAnims[number]->pos.y = coords.second;
|
||||
}
|
||||
|
||||
void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby)
|
||||
void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
creAnims[ID]->setType(3); //getting hit
|
||||
for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i)
|
||||
@ -673,54 +691,28 @@ void CBattleInterface::stackAttacking(int ID, int dest)
|
||||
attackingInfo->frame = 0;
|
||||
attackingInfo->ID = ID;
|
||||
attackingInfo->reversing = false;
|
||||
attackingInfo->shooting = false;
|
||||
|
||||
if(aStack.creature->isDoubleWide())
|
||||
switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
|
||||
{
|
||||
switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 1:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 2:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
case 3:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 4:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 5:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //else for if(aStack.creature->isDoubleWide())
|
||||
{
|
||||
switch(CBattleHex::mutualPosition(aStack.position, dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 1:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 2:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
case 3:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 4:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 5:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 1:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
break;
|
||||
case 2:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
case 3:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 4:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 5:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -763,6 +755,74 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::stackIsShooting(int ID, int dest)
|
||||
{
|
||||
//projectile
|
||||
float projectileAngle; //in radians; if positive, projectiles goes up
|
||||
float straightAngle = 0.2f; //maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
||||
int fromHex = LOCPLINT->cb->battleGetPos(ID);
|
||||
projectileAngle = atan2(float(abs(dest - fromHex)/17), float(abs(dest - fromHex)%17));
|
||||
if(fromHex < dest)
|
||||
projectileAngle = -projectileAngle;
|
||||
|
||||
SProjectileInfo spi;
|
||||
spi.creID = LOCPLINT->cb->battleGetStackByID(ID).creature->idNumber;
|
||||
|
||||
spi.step = 0;
|
||||
spi.frameNum = 0;
|
||||
spi.spin = CGI->creh->idToProjectileSpin[spi.creID];
|
||||
|
||||
std::pair<int, int> xycoord = CBattleHex::getXYUnitAnim(LOCPLINT->cb->battleGetPos(ID), true, &LOCPLINT->cb->battleGetCreature(ID));
|
||||
std::pair<int, int> destcoord = CBattleHex::getXYUnitAnim(dest, false, &LOCPLINT->cb->battleGetCreature(ID));
|
||||
destcoord.first += 250; destcoord.second += 210; //TODO: find a better place to shoot
|
||||
|
||||
if(projectileAngle > straightAngle) //upper shot
|
||||
{
|
||||
spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).upperRightMissleOffsetX;
|
||||
spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).upperRightMissleOffsetY;
|
||||
}
|
||||
else if(projectileAngle < -straightAngle) //lower shot
|
||||
{
|
||||
spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).lowerRightMissleOffsetX;
|
||||
spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).lowerRightMissleOffsetY;
|
||||
}
|
||||
else //straight shot
|
||||
{
|
||||
spi.x = xycoord.first + 200 + LOCPLINT->cb->battleGetCreature(ID).rightMissleOffsetX;
|
||||
spi.y = xycoord.second + 150 - LOCPLINT->cb->battleGetCreature(ID).rightMissleOffsetY;
|
||||
}
|
||||
spi.lastStep = sqrt((float)((destcoord.first - spi.x)*(destcoord.first - spi.x) + (destcoord.second - spi.y) * (destcoord.second - spi.y))) / 40;
|
||||
spi.dx = (destcoord.first - spi.x) / spi.lastStep;
|
||||
spi.dy = (destcoord.second - spi.y) / spi.lastStep;
|
||||
//set starting frame
|
||||
if(spi.spin)
|
||||
{
|
||||
spi.frameNum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
spi.frameNum = ((M_PI/2.0f - projectileAngle) / (2.0f *M_PI) + 1/((float)(2*(idToProjectile[spi.creID]->ourImages.size()-1)))) * (idToProjectile[spi.creID]->ourImages.size()-1);
|
||||
}
|
||||
//set delay
|
||||
spi.animStartDelay = CGI->creh->creatures[spi.creID].attackClimaxFrame;
|
||||
projectiles.push_back(spi);
|
||||
|
||||
//attack aniamtion
|
||||
attackingInfo = new CAttHelper;
|
||||
attackingInfo->dest = dest;
|
||||
attackingInfo->frame = 0;
|
||||
attackingInfo->ID = ID;
|
||||
attackingInfo->reversing = false;
|
||||
attackingInfo->shooting = true;
|
||||
if(projectileAngle > straightAngle) //upper shot
|
||||
attackingInfo->shootingGroup = 14;
|
||||
else if(projectileAngle < -straightAngle) //lower shot
|
||||
attackingInfo->shootingGroup = 15;
|
||||
else //straight shot
|
||||
attackingInfo->shootingGroup = 16;
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(attackingInfo->shootingGroup);
|
||||
}
|
||||
|
||||
void CBattleInterface::showRange(SDL_Surface * to, int ID)
|
||||
{
|
||||
std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
|
||||
@ -780,52 +840,59 @@ void CBattleInterface::attackingShowHelper()
|
||||
if(attackingInfo->frame == 0)
|
||||
{
|
||||
CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
|
||||
if(aStack.creature->isDoubleWide())
|
||||
if(attackingInfo->shooting)
|
||||
{
|
||||
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 1:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 2:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
case 3:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 4:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 5:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
}
|
||||
creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup);
|
||||
}
|
||||
else //else for if(aStack.creature->isDoubleWide())
|
||||
else
|
||||
{
|
||||
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
||||
if(aStack.creature->isDoubleWide())
|
||||
{
|
||||
case 0:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 1:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 2:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
case 3:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 4:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 5:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 1:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 2:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
case 3:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 4:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 5:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else //else for if(aStack.creature->isDoubleWide())
|
||||
{
|
||||
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 1:
|
||||
creAnims[attackingInfo->ID]->setType(10);
|
||||
break;
|
||||
case 2:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
case 3:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 4:
|
||||
creAnims[attackingInfo->ID]->setType(12);
|
||||
break;
|
||||
case 5:
|
||||
creAnims[attackingInfo->ID]->setType(11);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -912,6 +979,43 @@ void CBattleInterface::printConsoleAttacked(int ID, int dmg, int killed, int IDb
|
||||
|
||||
void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
||||
{
|
||||
if(to == NULL)
|
||||
to = screen;
|
||||
std::list< std::list<SProjectileInfo>::iterator > toBeDeleted;
|
||||
for(std::list<SProjectileInfo>::iterator it=projectiles.begin(); it!=projectiles.end(); ++it)
|
||||
{
|
||||
if(it->animStartDelay>0)
|
||||
{
|
||||
--(it->animStartDelay);
|
||||
continue;
|
||||
}
|
||||
SDL_Rect dst;
|
||||
dst.h = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->h;
|
||||
dst.w = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->w;
|
||||
dst.x = it->x;
|
||||
dst.y = it->y;
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(idToProjectile[it->creID]->ourImages[it->frameNum].bitmap, NULL, to, &dst);
|
||||
//actualizing projectile
|
||||
++it->step;
|
||||
if(it->step == it->lastStep)
|
||||
{
|
||||
toBeDeleted.insert(toBeDeleted.end(), it);
|
||||
}
|
||||
else
|
||||
{
|
||||
it->x += it->dx;
|
||||
it->y += it->dy;
|
||||
if(it->spin)
|
||||
{
|
||||
++(it->frameNum);
|
||||
it->frameNum %= idToProjectile[it->creID]->ourImages.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
for(std::list< std::list<SProjectileInfo>::iterator >::iterator it = toBeDeleted.begin(); it!= toBeDeleted.end(); ++it)
|
||||
{
|
||||
projectiles.erase(*it);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleHero::show(SDL_Surface *to)
|
||||
|
@ -93,6 +93,8 @@ private:
|
||||
int dest; //atacked hex
|
||||
int frame, maxframe; //frame of animation, number of frames of animation
|
||||
bool reversing;
|
||||
bool shooting;
|
||||
int shootingGroup; //if shooting is true, print this animation group
|
||||
} * attackingInfo;
|
||||
void attackingShowHelper();
|
||||
void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
|
||||
@ -105,9 +107,10 @@ private:
|
||||
int creID; //ID of creature that shot this projectile
|
||||
int frameNum; //frame to display form projectile animation
|
||||
bool spin; //if true, frameNum will be increased
|
||||
int animStartDelay; //how many times projectile must be attempted to be shown till it's really show (decremented after hit)
|
||||
};
|
||||
std::list<SProjectileInfo> projectiles;
|
||||
void projectileShowHelper(SDL_Surface * to); //prints projectiles present on the battlefield
|
||||
void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield
|
||||
|
||||
public:
|
||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
||||
@ -140,13 +143,14 @@ public:
|
||||
//call-ins
|
||||
void newStack(CStack stack); //new stack appeared on battlefield
|
||||
void stackRemoved(CStack stack); //stack disappeared from batlefiled
|
||||
void stackKilled(int ID, int dmg, int killed, int IDby); //stack has been killed (but corpses remain)
|
||||
void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //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, int dmg, int killed, int IDby); //called when stack id attacked by stack with id IDby
|
||||
void stackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting); //called when stack id attacked by stack with id IDby
|
||||
void stackAttacking(int ID, int dest); //called when stack with id ID is attacking something on hex dest
|
||||
void newRound(int number); //caled when round is ended; number is the number of round
|
||||
void hexLclicked(int whichOne); //hex only call-in
|
||||
void stackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest
|
||||
|
||||
friend class CBattleHex;
|
||||
};
|
||||
|
@ -14,9 +14,15 @@
|
||||
#include "CPlayerInterface.h"
|
||||
#include "hch/CBuildingHandler.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||
|
||||
#ifndef _MSC_VER
|
||||
}
|
||||
#endif
|
||||
|
||||
int CCallback::lowestSpeed(CGHeroInstance * chi)
|
||||
{
|
||||
@ -770,18 +776,7 @@ int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield
|
||||
}
|
||||
int CCallback::battleGetStack(int pos)
|
||||
{
|
||||
for(int g=0; g<CGI->state->curB->stacks.size(); ++g)
|
||||
{
|
||||
if(CGI->state->curB->stacks[g]->position == pos ||
|
||||
( CGI->state->curB->stacks[g]->creature->isDoubleWide() &&
|
||||
( (CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position-1 == pos) ||
|
||||
(!CGI->state->curB->stacks[g]->attackerOwned && CGI->state->curB->stacks[g]->position+1 == pos)
|
||||
)
|
||||
)
|
||||
)
|
||||
return CGI->state->curB->stacks[g]->ID;
|
||||
}
|
||||
return -1;
|
||||
return CGI->state->battleGetStack(pos);
|
||||
}
|
||||
|
||||
CStack CCallback::battleGetStackByID(int ID)
|
||||
|
162
CGameState.cpp
162
CGameState.cpp
@ -239,6 +239,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
||||
}
|
||||
case 7: //shoot
|
||||
{
|
||||
battleShootCreatureStack(ba.stackNumber, ba.destinationTile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -430,43 +431,7 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
{
|
||||
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;
|
||||
int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]);
|
||||
|
||||
//applying damages
|
||||
int cresKilled = finalDmg / curB->stacks[numberOfStackAtEnd]->creature->hitPoints;
|
||||
@ -487,12 +452,12 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed
|
||||
{
|
||||
curB->stacks[numberOfStackAtEnd]->amount = 0;
|
||||
LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore) , ID);
|
||||
LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore) , ID, false);
|
||||
curB->stacks[numberOfStackAtEnd]->alive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID);
|
||||
LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, false);
|
||||
}
|
||||
|
||||
//damage applied
|
||||
@ -520,6 +485,125 @@ bool CGameState::battleAttackCreatureStack(int ID, int dest)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CGameState::battleShootCreatureStack(int ID, int dest)
|
||||
{
|
||||
CStack * curStack = NULL;
|
||||
for(int y=0; y<curB->stacks.size(); ++y)
|
||||
{
|
||||
if(curB->stacks[y]->ID == ID)
|
||||
{
|
||||
curStack = curB->stacks[y];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!curStack)
|
||||
return false;
|
||||
int IDOfStackAtEnd = battleGetStack(dest);
|
||||
int numberOfStackAtEnd = -1;
|
||||
for(int v=0; v<curB->stacks.size(); ++v)
|
||||
{
|
||||
if(curB->stacks[v]->ID == IDOfStackAtEnd)
|
||||
{
|
||||
numberOfStackAtEnd = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(IDOfStackAtEnd == -1 || curB->stacks[numberOfStackAtEnd]->owner == curStack->owner)
|
||||
return false;
|
||||
|
||||
LOCPLINT->battleStackIsShooting(ID, dest);
|
||||
|
||||
//counting dealt damage
|
||||
int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]);
|
||||
|
||||
//applying damages
|
||||
int cresKilled = finalDmg / curB->stacks[ID]->creature->hitPoints;
|
||||
int damageFirst = finalDmg % curB->stacks[ID]->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;
|
||||
}
|
||||
|
||||
int cresInstackBefore = curB->stacks[numberOfStackAtEnd]->amount;
|
||||
curB->stacks[numberOfStackAtEnd]->amount -= cresKilled;
|
||||
if(curB->stacks[numberOfStackAtEnd]->amount<=0) //stack killed
|
||||
{
|
||||
curB->stacks[numberOfStackAtEnd]->amount = 0;
|
||||
LOCPLINT->battleStackKilled(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, true);
|
||||
curB->stacks[numberOfStackAtEnd]->alive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, true);
|
||||
}
|
||||
|
||||
//damage applied
|
||||
return true;
|
||||
}
|
||||
|
||||
int CGameState::battleGetStack(int pos)
|
||||
{
|
||||
for(int g=0; g<curB->stacks.size(); ++g)
|
||||
{
|
||||
if(curB->stacks[g]->position == pos ||
|
||||
( curB->stacks[g]->creature->isDoubleWide() &&
|
||||
( (curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == pos) ||
|
||||
(!curB->stacks[g]->attackerOwned && curB->stacks[g]->position+1 == pos)
|
||||
)
|
||||
)
|
||||
)
|
||||
return curB->stacks[g]->ID;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CGameState::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
{
|
||||
int attackDefenseBonus = attacker->creature->attack - defender->creature->defence;
|
||||
int damageBase = 0;
|
||||
if(attacker->creature->damageMax == attacker->creature->damageMin) //constant damage
|
||||
{
|
||||
damageBase = attacker->creature->damageMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
damageBase = rand()%(attacker->creature->damageMax - attacker->creature->damageMin) + attacker->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;
|
||||
}
|
||||
}
|
||||
|
||||
return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
|
||||
}
|
||||
|
||||
std::vector<int> CGameState::battleGetRange(int ID)
|
||||
{
|
||||
int initialPlace=-1; //position of unit
|
||||
|
@ -100,6 +100,9 @@ private:
|
||||
void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2);
|
||||
bool battleMoveCreatureStack(int ID, int dest);
|
||||
bool battleAttackCreatureStack(int ID, int dest);
|
||||
bool battleShootCreatureStack(int ID, int dest);
|
||||
int battleGetStack(int pos); //returns ID of stack at given tile
|
||||
static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data
|
||||
std::vector<int> battleGetRange(int ID); //called by std::vector<int> CCallback::battleGetAvailableHexes(int ID);
|
||||
public:
|
||||
friend class CCallback;
|
||||
|
8
CLua.cpp
8
CLua.cpp
@ -2,14 +2,22 @@
|
||||
#include "CLua.h"
|
||||
#include "CLuaHandler.h"
|
||||
#include "hch/CHeroHandler.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lobject.h"
|
||||
#include "lgc.h"
|
||||
#include "lapi.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "CGameInfo.h"
|
||||
#include "CGameState.h"
|
||||
#include <sstream>
|
||||
|
9
CLua.h
9
CLua.h
@ -1,8 +1,17 @@
|
||||
#pragma once
|
||||
#include "global.h"
|
||||
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lstate.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
}
|
||||
#endif
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
class CLua;
|
||||
|
@ -1,10 +1,17 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
}
|
||||
#endif
|
||||
|
||||
//#include <luabind/luabind.hpp>
|
||||
//#include <luabind/function.hpp>
|
||||
//#include <luabind/class.hpp>
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define CMESSAGE_H
|
||||
|
||||
#include "global.h"
|
||||
#include "SDL_ttf.h"
|
||||
#include <SDL_ttf.h>
|
||||
#include "SDL.h"
|
||||
#include "CPreGame.h"
|
||||
|
||||
|
@ -2080,14 +2080,19 @@ void CPlayerInterface::battleStackAttacking(int ID, int dest)
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackAttacking(ID, dest);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby)
|
||||
void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby);
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby, byShooting);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby)
|
||||
void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby);
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby, byShooting);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackIsShooting(int ID, int dest)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ID, dest);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showComp(SComponent comp)
|
||||
|
@ -341,8 +341,9 @@ public:
|
||||
void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CArmedInstance *hero1, CArmedInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner);
|
||||
void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving);
|
||||
void battleStackAttacking(int ID, int dest);
|
||||
void battleStackIsAttacked(int ID, int dmg, int killed, int IDby);
|
||||
void battleStackKilled(int ID, int dmg, int killed, int IDby);
|
||||
void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting);
|
||||
void battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting);
|
||||
void battleStackIsShooting(int ID, int dest); //called when stack with id ID is shooting to hex dest
|
||||
|
||||
|
||||
//-------------//
|
||||
|
Loading…
Reference in New Issue
Block a user