mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
progress in battles
This commit is contained in:
parent
ac82c2fe5a
commit
d5a5a04811
@ -8,12 +8,13 @@
|
||||
#include "hch\CDefHandler.h"
|
||||
#include "CCallback.h"
|
||||
#include "CGameState.h"
|
||||
#include <queue>
|
||||
|
||||
extern SDL_Surface * screen;
|
||||
SDL_Surface * CBattleInterface::cellBorder, * CBattleInterface::cellShade;
|
||||
|
||||
CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2)
|
||||
: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0)
|
||||
: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1)
|
||||
{
|
||||
//initializing armies
|
||||
this->army1 = army1;
|
||||
@ -79,7 +80,14 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
|
||||
int x = 14 + ((h/17)%2==0 ? 22 : 0) + 44*(h%17);
|
||||
int y = 86 + 42 * (h/17);
|
||||
bfield[h].pos = genRect(cellShade->h, cellShade->w, x, y);
|
||||
bfield[h].accesible = true;
|
||||
}
|
||||
//locking occupied positions on batlefield
|
||||
for(std::map<int, CStack>::iterator it = stacks.begin(); it!=stacks.end(); ++it) //stacks gained at top of this function
|
||||
{
|
||||
bfield[it->second.position].accesible = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CBattleInterface::~CBattleInterface()
|
||||
@ -142,6 +150,7 @@ void CBattleInterface::deactivate()
|
||||
|
||||
void CBattleInterface::show(SDL_Surface * to)
|
||||
{
|
||||
std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks(); //used in a few places
|
||||
++animCount;
|
||||
if(!to) //"evaluating" to
|
||||
to = screen;
|
||||
@ -170,6 +179,15 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &genRect(cellShade->h, cellShade->w, x, y));
|
||||
}
|
||||
}
|
||||
//showing selected unit's range
|
||||
for(std::map<int, CCreatureAnimation*>::iterator j=creAnims.begin(); j!=creAnims.end(); ++j)
|
||||
{
|
||||
if(j->first == activeStack) //print range of selected unit //TODO: check if it is to be done
|
||||
{
|
||||
showRange(to, stacks[j->first].position, LOCPLINT->cb->battleGetCreature(j->first).speed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//showing menu background
|
||||
blitAt(menu, 0, 556, to);
|
||||
|
||||
@ -191,11 +209,10 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
defendingHero->show(to);
|
||||
|
||||
//showing units //a lot of work...
|
||||
std::map<int, CStack> stacks = LOCPLINT->cb->battleGetStacks();
|
||||
for(std::map<int, CCreatureAnimation*>::iterator j=creAnims.begin(); j!=creAnims.end(); ++j)
|
||||
{
|
||||
std::pair <int, int> coords = CBattleHex::getXYUnitAnim(stacks[j->first].position, stacks[j->first].owner == attackingHeroInstance->tempOwner);
|
||||
j->second->nextFrame(to, coords.first, coords.second, stacks[j->first].owner == attackingHeroInstance->tempOwner, animCount%2==0);
|
||||
j->second->nextFrame(to, coords.first, coords.second, stacks[j->first].owner == attackingHeroInstance->tempOwner, animCount%2==0, j->first==activeStack);
|
||||
}
|
||||
//units shown
|
||||
|
||||
@ -261,6 +278,67 @@ void CBattleInterface::stackRemoved(CStack stack)
|
||||
creAnims.erase(stack.ID);
|
||||
}
|
||||
|
||||
void CBattleInterface::stackActivated(int number)
|
||||
{
|
||||
activeStack = number;
|
||||
}
|
||||
|
||||
void CBattleInterface::stackMoved(int number, int destHex)
|
||||
{
|
||||
}
|
||||
|
||||
void CBattleInterface::showRange(SDL_Surface * to, int initialPlace, int radius)
|
||||
{
|
||||
int dists[187]; //calculated distances
|
||||
std::queue<int> hexq; //bfs queue
|
||||
hexq.push(initialPlace);
|
||||
for(int g=0; g<187; ++g)
|
||||
dists[g] = 100000000;
|
||||
dists[initialPlace] = 0;
|
||||
while(!hexq.empty()) //bfs loop
|
||||
{
|
||||
int curHex = hexq.front();
|
||||
hexq.pop();
|
||||
if((curHex - 18 > 0) && bfield[curHex-18].accesible && (dists[curHex] + 1 < dists[curHex-18]) && (curHex-18)%17!=0 && (curHex-18)%17!=16) //top left
|
||||
{
|
||||
hexq.push(curHex - 18);
|
||||
dists[curHex-18] = dists[curHex] + 1;
|
||||
}
|
||||
if((curHex - 17 > 0) && bfield[curHex-17].accesible && (dists[curHex] + 1 < dists[curHex-17]) && (curHex-17)%17!=0 && (curHex-17)%17!=16) //top right
|
||||
{
|
||||
hexq.push(curHex - 17);
|
||||
dists[curHex-17] = dists[curHex] + 1;
|
||||
}
|
||||
if((curHex - 1 > 0) && bfield[curHex-1].accesible && (dists[curHex] + 1 < dists[curHex-1]) && (curHex-1)%17!=0 && (curHex-1)%17!=16) //left
|
||||
{
|
||||
hexq.push(curHex - 1);
|
||||
dists[curHex-1] = dists[curHex] + 1;
|
||||
}
|
||||
if((curHex + 1 < 187) && bfield[curHex+1].accesible && (dists[curHex] + 1 < dists[curHex+1]) && (curHex+1)%17!=0 && (curHex+1)%17!=16) //right
|
||||
{
|
||||
hexq.push(curHex + 1);
|
||||
dists[curHex+1] = dists[curHex] + 1;
|
||||
}
|
||||
if((curHex + 17 < 187) && bfield[curHex+17].accesible && (dists[curHex] + 1 < dists[curHex+17]) && (curHex+17)%17!=0 && (curHex+17)%17!=16) //bottom left
|
||||
{
|
||||
hexq.push(curHex + 17);
|
||||
dists[curHex+17] = dists[curHex] + 1;
|
||||
}
|
||||
if((curHex + 18 < 187) && bfield[curHex+18].accesible && (dists[curHex] + 1 < dists[curHex+18]) && (curHex+18)%17!=0 && (curHex+18)%17!=16) //bottom right
|
||||
{
|
||||
hexq.push(curHex + 18);
|
||||
dists[curHex+18] = dists[curHex] + 1;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<187; ++i)
|
||||
{
|
||||
if(dists[i]<=radius)
|
||||
{
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(CBattleInterface::cellShade, NULL, to, &bfield[i].pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleHero::show(SDL_Surface *to)
|
||||
{
|
||||
int tick=-1;
|
||||
|
@ -54,6 +54,8 @@ private:
|
||||
CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
|
||||
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order like in BattleInfo's stacks)
|
||||
unsigned char animCount;
|
||||
int activeStack; //number of active stack; -1 - no one
|
||||
void showRange(SDL_Surface * to, int initialPlace, int radius); //show helper funtion ot mark range of a unit
|
||||
|
||||
public:
|
||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
||||
@ -82,6 +84,8 @@ public:
|
||||
void show(SDL_Surface * to);
|
||||
|
||||
//call-ins
|
||||
void newStack(CStack stack);
|
||||
void stackRemoved(CStack stack);
|
||||
void newStack(CStack stack); //new stack appeared on battlefield
|
||||
void stackRemoved(CStack stack); //stack disappeared from batlefiled
|
||||
void stackActivated(int number); //active stack has been changed
|
||||
void stackMoved(int number, int destHex); //stack with id number moved to destHex
|
||||
};
|
||||
|
@ -550,6 +550,20 @@ std::map<int, CStack> CCallback::battleGetStacks()
|
||||
return ret;
|
||||
}
|
||||
|
||||
CCreature CCallback::battleGetCreature(int number)
|
||||
{
|
||||
return *(CGI->state->curB->stacks[number]->creature);
|
||||
}
|
||||
|
||||
bool CCallback::battleMoveCreature(int ID, int dest)
|
||||
{
|
||||
//checking parameters
|
||||
if(dest<0 || dest > 187 || ID<0 || ID>=CGI->state->curB->stacks.size())
|
||||
return false;
|
||||
|
||||
return CGI->state->battleMoveCreatureStack(ID, dest); //everything finished successfully
|
||||
}
|
||||
|
||||
int3 CScriptCallback::getPos(CGObjectInstance * ob)
|
||||
{
|
||||
return ob->pos;
|
||||
|
@ -100,6 +100,8 @@ public:
|
||||
int battleGetPos(int stack); //returns position (tile ID) of stack
|
||||
int battleMakeAction(Action* action);//perform action with an active stack (or custom action)
|
||||
std::map<int, CStack> battleGetStacks(); //returns stacks on battlefield
|
||||
CCreature battleGetCreature(int number); //returns type of creature by given number of stack
|
||||
bool battleMoveCreature(int ID, int dest); //moves creature with id ID to dest if possible
|
||||
|
||||
|
||||
//friends
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
virtual void actionFinished(Action action){};//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void activeStack(int stackID){}; //called when it's turn of that stack
|
||||
virtual void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner){};
|
||||
virtual void battleStackMoved(int ID, int dest)=0;
|
||||
//
|
||||
|
||||
};
|
||||
@ -65,5 +66,6 @@ public:
|
||||
virtual void yourTurn(){};
|
||||
virtual void heroKilled(const CGHeroInstance*){};
|
||||
virtual void heroCreated(const CGHeroInstance*){};
|
||||
virtual void battleStackMoved(int ID, int dest){};
|
||||
};
|
||||
#endif //CGAMEINTERFACE_H
|
@ -4,7 +4,7 @@
|
||||
#include <algorithm>
|
||||
#include "SDL_Thread.h"
|
||||
#include "SDL_Extensions.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
|
||||
class CMP_stack
|
||||
@ -207,3 +207,79 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
||||
delete curB;
|
||||
curB = NULL;
|
||||
}
|
||||
|
||||
bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
{
|
||||
//initing necessary tables
|
||||
bool accessibility[187]; //accesibility of hexes
|
||||
for(int k=0; k<187; k++)
|
||||
accessibility[k] = true;
|
||||
for(int g=0; g<CGI->state->curB->stacks.size(); ++g)
|
||||
{
|
||||
accessibility[CGI->state->curB->stacks[g]->position] = false;
|
||||
}
|
||||
int predecessor[187]; //for getting the Path
|
||||
for(int b=0; b<187; ++b)
|
||||
predecessor[b] = -1;
|
||||
//bfsing
|
||||
int dists[187]; //calculated distances
|
||||
std::queue<int> hexq; //bfs queue
|
||||
hexq.push(CGI->state->curB->stacks[ID]->position);
|
||||
for(int g=0; g<187; ++g)
|
||||
dists[g] = 100000000;
|
||||
dists[hexq.front()] = 0;
|
||||
while(!hexq.empty()) //bfs loop
|
||||
{
|
||||
int curHex = hexq.front();
|
||||
hexq.pop();
|
||||
if((curHex - 18 > 0) && accessibility[curHex-18] && (dists[curHex] + 1 < dists[curHex-18]) && (curHex-18)%17!=0 && (curHex-18)%17!=16) //top left
|
||||
{
|
||||
hexq.push(curHex - 18);
|
||||
dists[curHex-18] = dists[curHex] + 1;
|
||||
predecessor[curHex-18] = curHex;
|
||||
}
|
||||
if((curHex - 17 > 0) && accessibility[curHex-17] && (dists[curHex] + 1 < dists[curHex-17]) && (curHex-17)%17!=0 && (curHex-17)%17!=16) //top right
|
||||
{
|
||||
hexq.push(curHex - 17);
|
||||
dists[curHex-17] = dists[curHex] + 1;
|
||||
predecessor[curHex-17] = curHex;
|
||||
}
|
||||
if((curHex - 1 > 0) && accessibility[curHex-1] && (dists[curHex] + 1 < dists[curHex-1]) && (curHex-1)%17!=0 && (curHex-1)%17!=16) //left
|
||||
{
|
||||
hexq.push(curHex - 1);
|
||||
dists[curHex-1] = dists[curHex] + 1;
|
||||
predecessor[curHex-1] = curHex;
|
||||
}
|
||||
if((curHex + 1 < 187) && accessibility[curHex+1] && (dists[curHex] + 1 < dists[curHex+1]) && (curHex+1)%17!=0 && (curHex+1)%17!=16) //right
|
||||
{
|
||||
hexq.push(curHex + 1);
|
||||
dists[curHex+1] = dists[curHex] + 1;
|
||||
predecessor[curHex+1] = curHex;
|
||||
}
|
||||
if((curHex + 17 < 187) && accessibility[curHex+17] && (dists[curHex] + 1 < dists[curHex+17]) && (curHex+17)%17!=0 && (curHex+17)%17!=16) //bottom left
|
||||
{
|
||||
hexq.push(curHex + 17);
|
||||
dists[curHex+17] = dists[curHex] + 1;
|
||||
predecessor[curHex+17] = curHex;
|
||||
}
|
||||
if((curHex + 18 < 187) && accessibility[curHex+18] && (dists[curHex] + 1 < dists[curHex+18]) && (curHex+18)%17!=0 && (curHex+18)%17!=16) //bottom right
|
||||
{
|
||||
hexq.push(curHex + 18);
|
||||
dists[curHex+18] = dists[curHex] + 1;
|
||||
predecessor[curHex+18] = curHex;
|
||||
}
|
||||
}
|
||||
//following the Path
|
||||
std::vector<int> path;
|
||||
int curElem = dest;
|
||||
while(curElem!=CGI->state->curB->stacks[ID]->position)
|
||||
{
|
||||
path.push_back(curElem);
|
||||
curElem = predecessor[curElem];
|
||||
}
|
||||
for(int v=path.size()-1; v>=0; --v)
|
||||
{
|
||||
LOCPLINT->battleStackMoved(ID, path[v]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -87,6 +87,7 @@ private:
|
||||
return NULL;
|
||||
}
|
||||
void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2);
|
||||
bool battleMoveCreatureStack(int ID, int dest);
|
||||
public:
|
||||
friend CCallback;
|
||||
friend CPathfinder;;
|
||||
|
@ -1900,6 +1900,7 @@ void CPlayerInterface::actionFinished(Action action)//occurs AFTER every action
|
||||
void CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack
|
||||
{
|
||||
unsigned char showCount = 0;
|
||||
((CBattleInterface*)curint)->stackActivated(stackID);
|
||||
while(true)
|
||||
{
|
||||
++showCount;
|
||||
@ -1934,6 +1935,11 @@ void CPlayerInterface::battleEnd(CCreatureSet * army1, CCreatureSet * army2, CGH
|
||||
{
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackMoved(int ID, int dest)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackMoved(ID, dest);
|
||||
}
|
||||
|
||||
void CPlayerInterface::showComp(SComponent comp)
|
||||
{
|
||||
adventureInt->infoBar.showComp(&comp,4000);
|
||||
|
@ -318,6 +318,7 @@ public:
|
||||
void actionFinished(Action action);//occurs AFTER every action taken by any stack or by the hero
|
||||
void activeStack(int stackID); //called when it's turn of that stack
|
||||
void battleEnd(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, std::vector<int> capturedArtifacts, int expForWinner, bool winner);
|
||||
void battleStackMoved(int ID, int dest);
|
||||
|
||||
|
||||
//-------------//
|
||||
|
@ -743,7 +743,7 @@ int CCreatureAnimation::readNormalNr (int pos, int bytCon, unsigned char * str,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker, bool incrementFrame)
|
||||
int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker, bool incrementFrame, bool yellowBorder)
|
||||
{
|
||||
if(dest->format->BytesPerPixel<3)
|
||||
return -1; //not enough depth
|
||||
@ -842,7 +842,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker
|
||||
int yB = ftcp/(FullWidth+add) + y;
|
||||
if(xB>=0 && yB>=0 && xB<dest->w && yB<dest->h)
|
||||
{
|
||||
putPixel(dest, xB + yB*dest->w, palette[FDef[BaseOffset+k]], FDef[BaseOffset+k]);
|
||||
putPixel(dest, xB + yB*dest->w, palette[FDef[BaseOffset+k]], FDef[BaseOffset+k], yellowBorder);
|
||||
}
|
||||
ftcp++; //increment pos
|
||||
if ((TotalRowLength+k+1)>=SpriteWidth)
|
||||
@ -859,7 +859,7 @@ int CCreatureAnimation::nextFrame(SDL_Surface *dest, int x, int y, bool attacker
|
||||
int yB = ftcp/(FullWidth+add) + y;
|
||||
if(xB>=0 && yB>=0 && xB<dest->w && yB<dest->h)
|
||||
{
|
||||
putPixel(dest, xB + yB*dest->w, palette[SegmentType], SegmentType);
|
||||
putPixel(dest, xB + yB*dest->w, palette[SegmentType], SegmentType, yellowBorder);
|
||||
}
|
||||
ftcp++; //increment pos
|
||||
}
|
||||
@ -931,7 +931,7 @@ CCreatureAnimation::~CCreatureAnimation()
|
||||
delete [] RLEntries;
|
||||
}
|
||||
|
||||
void CCreatureAnimation::putPixel(SDL_Surface * dest, const int & ftcp, const BMPPalette & color, const unsigned char & palc) const
|
||||
void CCreatureAnimation::putPixel(SDL_Surface * dest, const int & ftcp, const BMPPalette & color, const unsigned char & palc, const bool & yellowBorder) const
|
||||
{
|
||||
if(palc!=0)
|
||||
{
|
||||
@ -942,13 +942,13 @@ void CCreatureAnimation::putPixel(SDL_Surface * dest, const int & ftcp, const BM
|
||||
p[1] = color.G;
|
||||
p[2] = color.R;
|
||||
}
|
||||
else if(palc == 6 || palc == 7) //dark yellow border
|
||||
else if(yellowBorder && (palc == 6 || palc == 7)) //dark yellow border
|
||||
{
|
||||
p[0] = 0;
|
||||
p[1] = 0xff;
|
||||
p[2] = 0xff;
|
||||
}
|
||||
else if(palc == 5) //yellow border
|
||||
else if(yellowBorder && (palc == 5)) //yellow border
|
||||
{
|
||||
p[0] = color.B;
|
||||
p[1] = color.G;
|
||||
|
@ -82,7 +82,7 @@ private:
|
||||
char id[2];
|
||||
std::string defName, curDir;
|
||||
int readNormalNr (int pos, int bytCon, unsigned char * str=NULL, bool cyclic=false);
|
||||
void putPixel(SDL_Surface * dest, const int & ftcp, const BMPPalette & color, const unsigned char & palc) const;
|
||||
void putPixel(SDL_Surface * dest, const int & ftcp, const BMPPalette & color, const unsigned char & palc, const bool & yellowBorder) const;
|
||||
|
||||
////////////
|
||||
|
||||
@ -97,7 +97,7 @@ public:
|
||||
void setType(int type); //sets type of animation and cleares framecount
|
||||
int getType() const; //returns type of animation
|
||||
|
||||
int nextFrame(SDL_Surface * dest, int x, int y, bool attacker, bool incrementFrame = true); //0 - success, any other - error //print next
|
||||
int nextFrame(SDL_Surface * dest, int x, int y, bool attacker, bool incrementFrame = true, bool yellowBorder = false); //0 - success, any other - error //print next
|
||||
};
|
||||
|
||||
#endif //CCREATUREHANDLER_H
|
Loading…
x
Reference in New Issue
Block a user