mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-09 01:06:07 +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:
@ -11,6 +11,8 @@
|
|||||||
#include "hch/CGeneralTextHandler.h"
|
#include "hch/CGeneralTextHandler.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
extern SDL_Surface * screen;
|
extern SDL_Surface * screen;
|
||||||
extern TTF_Font * GEOR13;
|
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())
|
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]);
|
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);
|
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
|
creAnims[ID]->setType(5); //death
|
||||||
for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i)
|
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;
|
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
|
creAnims[ID]->setType(3); //getting hit
|
||||||
for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i)
|
for(int i=0; i<creAnims[ID]->framesInGroup(3); ++i)
|
||||||
@ -673,9 +691,8 @@ void CBattleInterface::stackAttacking(int ID, int dest)
|
|||||||
attackingInfo->frame = 0;
|
attackingInfo->frame = 0;
|
||||||
attackingInfo->ID = ID;
|
attackingInfo->ID = ID;
|
||||||
attackingInfo->reversing = false;
|
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:
|
case 0:
|
||||||
@ -697,31 +714,6 @@ void CBattleInterface::stackAttacking(int ID, int dest)
|
|||||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::newRound(int number)
|
void CBattleInterface::newRound(int number)
|
||||||
@ -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)
|
void CBattleInterface::showRange(SDL_Surface * to, int ID)
|
||||||
{
|
{
|
||||||
std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
|
std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
|
||||||
@ -780,6 +840,12 @@ void CBattleInterface::attackingShowHelper()
|
|||||||
if(attackingInfo->frame == 0)
|
if(attackingInfo->frame == 0)
|
||||||
{
|
{
|
||||||
CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
|
CStack aStack = LOCPLINT->cb->battleGetStackByID(attackingInfo->ID); //attacking stack
|
||||||
|
if(attackingInfo->shooting)
|
||||||
|
{
|
||||||
|
creAnims[attackingInfo->ID]->setType(attackingInfo->shootingGroup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if(aStack.creature->isDoubleWide())
|
if(aStack.creature->isDoubleWide())
|
||||||
{
|
{
|
||||||
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
switch(CBattleHex::mutualPosition(aStack.position, attackingInfo->dest)) //attack direction
|
||||||
@ -829,6 +895,7 @@ void CBattleInterface::attackingShowHelper()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if(attackingInfo->frame == (attackingInfo->maxframe - 1))
|
else if(attackingInfo->frame == (attackingInfo->maxframe - 1))
|
||||||
{
|
{
|
||||||
attackingInfo->reversing = true;
|
attackingInfo->reversing = true;
|
||||||
@ -912,6 +979,43 @@ void CBattleInterface::printConsoleAttacked(int ID, int dmg, int killed, int IDb
|
|||||||
|
|
||||||
void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
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)
|
void CBattleHero::show(SDL_Surface *to)
|
||||||
|
@ -93,6 +93,8 @@ private:
|
|||||||
int dest; //atacked hex
|
int dest; //atacked hex
|
||||||
int frame, maxframe; //frame of animation, number of frames of animation
|
int frame, maxframe; //frame of animation, number of frames of animation
|
||||||
bool reversing;
|
bool reversing;
|
||||||
|
bool shooting;
|
||||||
|
int shootingGroup; //if shooting is true, print this animation group
|
||||||
} * attackingInfo;
|
} * attackingInfo;
|
||||||
void attackingShowHelper();
|
void attackingShowHelper();
|
||||||
void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
|
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 creID; //ID of creature that shot this projectile
|
||||||
int frameNum; //frame to display form projectile animation
|
int frameNum; //frame to display form projectile animation
|
||||||
bool spin; //if true, frameNum will be increased
|
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;
|
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:
|
public:
|
||||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
||||||
@ -140,13 +143,14 @@ public:
|
|||||||
//call-ins
|
//call-ins
|
||||||
void newStack(CStack stack); //new stack appeared on battlefield
|
void newStack(CStack stack); //new stack appeared on battlefield
|
||||||
void stackRemoved(CStack stack); //stack disappeared from batlefiled
|
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 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 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 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 newRound(int number); //caled when round is ended; number is the number of round
|
||||||
void hexLclicked(int whichOne); //hex only call-in
|
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;
|
friend class CBattleHex;
|
||||||
};
|
};
|
||||||
|
@ -14,9 +14,15 @@
|
|||||||
#include "CPlayerInterface.h"
|
#include "CPlayerInterface.h"
|
||||||
#include "hch/CBuildingHandler.h"
|
#include "hch/CBuildingHandler.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int CCallback::lowestSpeed(CGHeroInstance * chi)
|
int CCallback::lowestSpeed(CGHeroInstance * chi)
|
||||||
{
|
{
|
||||||
@ -770,18 +776,7 @@ int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield
|
|||||||
}
|
}
|
||||||
int CCallback::battleGetStack(int pos)
|
int CCallback::battleGetStack(int pos)
|
||||||
{
|
{
|
||||||
for(int g=0; g<CGI->state->curB->stacks.size(); ++g)
|
return CGI->state->battleGetStack(pos);
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CStack CCallback::battleGetStackByID(int ID)
|
CStack CCallback::battleGetStackByID(int ID)
|
||||||
|
200
CGameState.cpp
200
CGameState.cpp
@ -239,6 +239,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
|||||||
}
|
}
|
||||||
case 7: //shoot
|
case 7: //shoot
|
||||||
{
|
{
|
||||||
|
battleShootCreatureStack(ba.stackNumber, ba.destinationTile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -430,16 +431,150 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
|||||||
{
|
{
|
||||||
LOCPLINT->battleStackAttacking(ID, path[v]);
|
LOCPLINT->battleStackAttacking(ID, path[v]);
|
||||||
//counting dealt damage
|
//counting dealt damage
|
||||||
int numberOfCres = curStack->amount; //number of attacking creatures
|
int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]);
|
||||||
int attackDefenseBonus = curStack->creature->attack - curB->stacks[numberOfStackAtEnd]->creature->defence;
|
|
||||||
int damageBase = 0;
|
//applying damages
|
||||||
if(curStack->creature->damageMax == curStack->creature->damageMin) //constant damage
|
int cresKilled = finalDmg / curB->stacks[numberOfStackAtEnd]->creature->hitPoints;
|
||||||
|
int damageFirst = finalDmg % curB->stacks[numberOfStackAtEnd]->creature->hitPoints;
|
||||||
|
|
||||||
|
if( curB->stacks[numberOfStackAtEnd]->firstHPleft <= damageFirst )
|
||||||
{
|
{
|
||||||
damageBase = curStack->creature->damageMin;
|
curB->stacks[numberOfStackAtEnd]->amount -= 1;
|
||||||
|
curB->stacks[numberOfStackAtEnd]->firstHPleft += curB->stacks[numberOfStackAtEnd]->creature->hitPoints - damageFirst;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
damageBase = rand()%(curStack->creature->damageMax - curStack->creature->damageMin) + curStack->creature->damageMin + 1;
|
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, false);
|
||||||
|
curB->stacks[numberOfStackAtEnd]->alive = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
//damage applied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curB->stackActionPerformed = true;
|
||||||
|
LOCPLINT->actionFinished(BattleAction());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGameState::battleAttackCreatureStack(int ID, int dest)
|
||||||
|
{
|
||||||
|
int attackedCreaure = -1; //-1 - there is no attacked creature
|
||||||
|
for(int b=0; b<curB->stacks.size(); ++b) //TODO: make upgrades for two-hex cres.
|
||||||
|
{
|
||||||
|
if(curB->stacks[b]->position == dest)
|
||||||
|
{
|
||||||
|
attackedCreaure = curB->stacks[b]->ID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(attackedCreaure == -1)
|
||||||
|
return false;
|
||||||
|
//LOCPLINT->cb->
|
||||||
|
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;
|
float dmgBonusMultiplier = 1.0;
|
||||||
@ -466,58 +601,7 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int finalDmg = (float)damageBase * (float)curStack->amount * dmgBonusMultiplier;
|
return (float)damageBase * (float)attacker->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
curB->stacks[numberOfStackAtEnd]->alive = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOCPLINT->battleStackIsAttacked(curB->stacks[numberOfStackAtEnd]->ID, finalDmg, std::min(cresKilled, cresInstackBefore), ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
//damage applied
|
|
||||||
}
|
|
||||||
}
|
|
||||||
curB->stackActionPerformed = true;
|
|
||||||
LOCPLINT->actionFinished(BattleAction());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CGameState::battleAttackCreatureStack(int ID, int dest)
|
|
||||||
{
|
|
||||||
int attackedCreaure = -1; //-1 - there is no attacked creature
|
|
||||||
for(int b=0; b<curB->stacks.size(); ++b) //TODO: make upgrades for two-hex cres.
|
|
||||||
{
|
|
||||||
if(curB->stacks[b]->position == dest)
|
|
||||||
{
|
|
||||||
attackedCreaure = curB->stacks[b]->ID;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(attackedCreaure == -1)
|
|
||||||
return false;
|
|
||||||
//LOCPLINT->cb->
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int> CGameState::battleGetRange(int ID)
|
std::vector<int> CGameState::battleGetRange(int ID)
|
||||||
|
@ -100,6 +100,9 @@ private:
|
|||||||
void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2);
|
void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2);
|
||||||
bool battleMoveCreatureStack(int ID, int dest);
|
bool battleMoveCreatureStack(int ID, int dest);
|
||||||
bool battleAttackCreatureStack(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);
|
std::vector<int> battleGetRange(int ID); //called by std::vector<int> CCallback::battleGetAvailableHexes(int ID);
|
||||||
public:
|
public:
|
||||||
friend class CCallback;
|
friend class CCallback;
|
||||||
|
8
CLua.cpp
8
CLua.cpp
@ -2,14 +2,22 @@
|
|||||||
#include "CLua.h"
|
#include "CLua.h"
|
||||||
#include "CLuaHandler.h"
|
#include "CLuaHandler.h"
|
||||||
#include "hch/CHeroHandler.h"
|
#include "hch/CHeroHandler.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
#include "lobject.h"
|
#include "lobject.h"
|
||||||
#include "lgc.h"
|
#include "lgc.h"
|
||||||
#include "lapi.h"
|
#include "lapi.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
#include "CGameState.h"
|
#include "CGameState.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
9
CLua.h
9
CLua.h
@ -1,8 +1,17 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lstate.h"
|
#include "lstate.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
class CLua;
|
class CLua;
|
||||||
|
@ -1,10 +1,17 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "lua.h"
|
#include "lua.h"
|
||||||
#include "lualib.h"
|
#include "lualib.h"
|
||||||
#include "lauxlib.h"
|
#include "lauxlib.h"
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//#include <luabind/luabind.hpp>
|
//#include <luabind/luabind.hpp>
|
||||||
//#include <luabind/function.hpp>
|
//#include <luabind/function.hpp>
|
||||||
//#include <luabind/class.hpp>
|
//#include <luabind/class.hpp>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#define CMESSAGE_H
|
#define CMESSAGE_H
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "SDL_ttf.h"
|
#include <SDL_ttf.h>
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "CPreGame.h"
|
#include "CPreGame.h"
|
||||||
|
|
||||||
|
@ -2080,14 +2080,19 @@ void CPlayerInterface::battleStackAttacking(int ID, int dest)
|
|||||||
dynamic_cast<CBattleInterface*>(curint)->stackAttacking(ID, 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)
|
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 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 battleStackMoved(int ID, int dest, bool startMoving, bool endMoving);
|
||||||
void battleStackAttacking(int ID, int dest);
|
void battleStackAttacking(int ID, int dest);
|
||||||
void battleStackIsAttacked(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);
|
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
|
||||||
|
|
||||||
|
|
||||||
//-------------//
|
//-------------//
|
||||||
|
Reference in New Issue
Block a user