mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
* moving units and some minor improvements
This commit is contained in:
parent
137f62798b
commit
fc4e0215fb
@ -14,7 +14,7 @@ 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), activeStack(-1)
|
||||
: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), curStackActed(false)
|
||||
{
|
||||
//initializing armies
|
||||
this->army1 = army1;
|
||||
@ -181,14 +181,8 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
}
|
||||
showRange(to, activeStack);
|
||||
|
||||
//showing menu background
|
||||
blitAt(menu, 0, 556, to);
|
||||
|
||||
@ -281,75 +275,33 @@ void CBattleInterface::stackRemoved(CStack stack)
|
||||
|
||||
void CBattleInterface::stackActivated(int number)
|
||||
{
|
||||
curStackActed = false;
|
||||
activeStack = number;
|
||||
}
|
||||
|
||||
void CBattleInterface::stackMoved(int number, int destHex)
|
||||
{
|
||||
int curStackPos = LOCPLINT->cb->battleGetPos(number);
|
||||
for(int i=0; i<6; ++i)
|
||||
{
|
||||
//creAnims[number]->setType(0);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::hexLclicked(int whichOne)
|
||||
{
|
||||
if((whichOne%17)!=0 && (whichOne%17)!=16)
|
||||
{
|
||||
LOCPLINT->cb->battleMoveCreature(activeStack, whichOne);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::showRange(SDL_Surface * to, int initialPlace, int radius)
|
||||
void CBattleInterface::showRange(SDL_Surface * to, int ID)
|
||||
{
|
||||
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;
|
||||
int curNext = -1; //for bfs loop only (helper var)
|
||||
while(!hexq.empty()) //bfs loop
|
||||
std::vector<int> shadedHexes = LOCPLINT->cb->battleGetAvailableHexes(ID);
|
||||
for(int i=0; i<shadedHexes.size(); ++i)
|
||||
{
|
||||
int curHex = hexq.front();
|
||||
hexq.pop();
|
||||
curNext = curHex - ( (curHex/17)%2 ? 17 : 18 );
|
||||
if((curNext > 0) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex - ( (curHex/17)%2 ? 16 : 17 );
|
||||
if((curNext > 0) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex - 1;
|
||||
if((curNext > 0) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + 1;
|
||||
if((curNext < 187) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + ( (curHex/17)%2 ? 16 : 17 );
|
||||
if((curNext < 187) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + ( (curHex/17)%2 ? 17 : 18 );
|
||||
if((curNext < 187) && bfield[curNext].accesible && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<187; ++i)
|
||||
{
|
||||
if(dists[i]<=radius)
|
||||
{
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(CBattleInterface::cellShade, NULL, to, &bfield[i].pos);
|
||||
}
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(CBattleInterface::cellShade, NULL, to, &bfield[shadedHexes[i]].pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,10 +56,10 @@ private:
|
||||
CBattleHero * attackingHero, * defendingHero;
|
||||
CCreatureSet * army1, * army2; //fighting armies
|
||||
CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
|
||||
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order like in BattleInfo's stacks)
|
||||
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
|
||||
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
|
||||
void showRange(SDL_Surface * to, int ID); //show helper funtion ot mark range of a unit
|
||||
|
||||
public:
|
||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
||||
@ -70,6 +70,7 @@ public:
|
||||
CBattleHex bfield[187]; //11 lines, 17 hexes on each
|
||||
std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
|
||||
static SDL_Surface * cellBorder, * cellShade;
|
||||
bool curStackActed; //true if we have i.e. moved current unit
|
||||
|
||||
//button handle funcs:
|
||||
void bOptionsf();
|
||||
@ -92,5 +93,6 @@ public:
|
||||
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
|
||||
void turnEnded(); //caled when current unit cannot get new orders
|
||||
void hexLclicked(int whichOne); //hex only call-in
|
||||
};
|
||||
|
@ -540,6 +540,15 @@ int CCallback::battleGetBattlefieldType()
|
||||
return CGI->mh->ttiles[CGI->state->curB->tile.x][CGI->state->curB->tile.y][CGI->state->curB->tile.z].terType;
|
||||
}
|
||||
|
||||
int CCallback::battleGetPos(int stack)
|
||||
{
|
||||
for(int g=0; g<CGI->state->curB->stacks.size(); ++g)
|
||||
{
|
||||
if(CGI->state->curB->stacks[g]->ID == stack)
|
||||
return CGI->state->curB->stacks[g]->position;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<int, CStack> CCallback::battleGetStacks()
|
||||
{
|
||||
std::map<int, CStack> ret;
|
||||
@ -568,6 +577,11 @@ bool CCallback::battleMoveCreature(int ID, int dest)
|
||||
return CGI->state->battleMoveCreatureStack(ID, dest); //everything finished successfully
|
||||
}
|
||||
|
||||
std::vector<int> CCallback::battleGetAvailableHexes(int ID)
|
||||
{
|
||||
return CGI->state->battleGetRange(ID);
|
||||
}
|
||||
|
||||
int3 CScriptCallback::getPos(CGObjectInstance * ob)
|
||||
{
|
||||
return ob->pos;
|
||||
|
@ -11,7 +11,7 @@ class CGObjectInstance;
|
||||
class SComponent;
|
||||
class IChosen;
|
||||
class CSelectableComponent;
|
||||
struct Action;
|
||||
struct BattleAction;
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
class ICallback
|
||||
@ -98,10 +98,11 @@ public:
|
||||
int battleGetObstaclesAtTile(int tile); //returns bitfield
|
||||
int battleGetStack(int pos); //returns ID of stack on the tile
|
||||
int battleGetPos(int stack); //returns position (tile ID) of stack
|
||||
int battleMakeAction(Action* action);//perform action with an active stack (or custom action)
|
||||
int battleMakeAction(BattleAction* 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
|
||||
std::vector<int> battleGetAvailableHexes(int ID); //reutrns numbers of hexes reachable by creature with id ID
|
||||
|
||||
|
||||
//friends
|
||||
|
@ -15,11 +15,11 @@ class CObstacle
|
||||
int position;
|
||||
//TODO: add some kind of the blockmap
|
||||
};
|
||||
struct Action
|
||||
struct BattleAction
|
||||
{
|
||||
bool side; //who made this action: false - left, true - right player
|
||||
int stackNumber;//stack ID, -1 left hero, -2 right hero,
|
||||
int actionType; // 0 = Cancel Action 1 = Hero cast a spell 2 = Walk 3 = Defend 4 = Retreat from the battle 5 = Surrender 6 = Walk and Attack 7 = Shoot 8 = Wait 9 = Catapult 10 = Monster casts a spell (i.e. Faerie Dragons)
|
||||
int actionType; // 0 = Cancel BattleAction 1 = Hero cast a spell 2 = Walk 3 = Defend 4 = Retreat from the battle 5 = Surrender 6 = Walk and Attack 7 = Shoot 8 = Wait 9 = Catapult 10 = Monster casts a spell (i.e. Faerie Dragons)
|
||||
int destinationTile;
|
||||
int additionalInfo; // e.g. spell number if type is 1 || 10
|
||||
};
|
||||
@ -46,8 +46,8 @@ public:
|
||||
virtual void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
|
||||
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning
|
||||
virtual void battleNewRound(int round){}; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
virtual void actionStarted(Action action){};//occurs BEFORE every action taken by any stack or by the hero
|
||||
virtual void actionFinished(Action action){};//occurs AFTER every action taken by any stack or by the hero
|
||||
virtual void actionStarted(BattleAction action){};//occurs BEFORE every action taken by any stack or by the hero
|
||||
virtual void actionFinished(BattleAction 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;
|
||||
|
@ -28,6 +28,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
||||
curB->side1=(hero1)?(hero1->tempOwner):(-1);
|
||||
curB->side2=(hero2)?(hero2->tempOwner):(-1);
|
||||
curB->round = -2;
|
||||
curB->stackActionPerformed = false;
|
||||
for(std::map<int,std::pair<CCreature*,int> >::iterator i = army1->slots.begin(); i!=army1->slots.end(); i++)
|
||||
{
|
||||
stacks.push_back(new CStack(i->second.first,i->second.second,0, stacks.size()));
|
||||
@ -176,6 +177,7 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
||||
for(int i=0;i<stacks.size();i++)
|
||||
{
|
||||
curB->activeStack = i;
|
||||
curB->stackActionPerformed = false;
|
||||
if(stacks[i]->alive) //niech interfejs ruszy oddzialem
|
||||
{
|
||||
unsigned char owner = (stacks[i]->owner)?(hero2->tempOwner):(hero1->tempOwner);
|
||||
@ -210,6 +212,9 @@ void CGameState::battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, C
|
||||
|
||||
bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
{
|
||||
//first checks
|
||||
if(curB->stackActionPerformed) //because unit cannot be moved more than once
|
||||
return false;
|
||||
//selecting moved stack
|
||||
CStack * curStack = NULL;
|
||||
for(int y=0; y<curB->stacks.size(); ++y)
|
||||
@ -245,14 +250,14 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
{
|
||||
int curHex = hexq.front();
|
||||
hexq.pop();
|
||||
curNext = curHex - ( (curHex/17)%2 ? 17 : 18 );
|
||||
curNext = curHex - ( (curHex/17)%2 ? 18 : 17 );
|
||||
if((curNext > 0) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
predecessor[curNext] = curHex;
|
||||
}
|
||||
curNext = curHex - ( (curHex/17)%2 ? 16 : 17 );
|
||||
curNext = curHex - ( (curHex/17)%2 ? 17 : 16 );
|
||||
if((curNext > 0) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
@ -301,6 +306,94 @@ bool CGameState::battleMoveCreatureStack(int ID, int dest)
|
||||
for(int v=path.size()-1; v>=0; --v)
|
||||
{
|
||||
LOCPLINT->battleStackMoved(ID, path[v]);
|
||||
curStack->position = path[v];
|
||||
}
|
||||
curB->stackActionPerformed = true;
|
||||
LOCPLINT->actionFinished(BattleAction());
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<int> CGameState::battleGetRange(int ID)
|
||||
{
|
||||
int initialPlace=-1; //position of unit
|
||||
int radius=-1; //range of unit
|
||||
for(int g=0; g<curB->stacks.size(); ++g)
|
||||
{
|
||||
if(curB->stacks[g]->ID == ID)
|
||||
{
|
||||
initialPlace = curB->stacks[g]->position;
|
||||
radius = curB->stacks[g]->creature->speed;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool accessibility[187]; //accesibility of hexes
|
||||
for(int k=0; k<187; k++)
|
||||
accessibility[k] = true;
|
||||
for(int g=0; g<curB->stacks.size(); ++g)
|
||||
{
|
||||
accessibility[curB->stacks[g]->position] = false;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
int curNext = -1; //for bfs loop only (helper var)
|
||||
while(!hexq.empty()) //bfs loop
|
||||
{
|
||||
int curHex = hexq.front();
|
||||
hexq.pop();
|
||||
curNext = curHex - ( (curHex/17)%2 ? 18 : 17 );
|
||||
if((curNext > 0) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex - ( (curHex/17)%2 ? 17 : 16 );
|
||||
if((curNext > 0) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //top right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex - 1;
|
||||
if((curNext > 0) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + 1;
|
||||
if((curNext < 187) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + ( (curHex/17)%2 ? 16 : 17 );
|
||||
if((curNext < 187) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom left
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
curNext = curHex + ( (curHex/17)%2 ? 17 : 18 );
|
||||
if((curNext < 187) && accessibility[curNext] && (dists[curHex] + 1 < dists[curNext]) && (curNext)%17!=0 && (curNext)%17!=16) //bottom right
|
||||
{
|
||||
hexq.push(curNext);
|
||||
dists[curNext] = dists[curHex] + 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> ret;
|
||||
|
||||
for(int i=0; i<187; ++i)
|
||||
{
|
||||
if(dists[i]<=radius)
|
||||
{
|
||||
ret.push_back(i);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@ struct BattleInfo
|
||||
CGHeroInstance *hero1, *hero2;
|
||||
CCreatureSet * army1, * army2;
|
||||
std::vector<CStack*> stacks;
|
||||
bool stackActionPerformed; //true if current stack has been moved
|
||||
};
|
||||
|
||||
class CStack
|
||||
@ -88,6 +89,7 @@ private:
|
||||
}
|
||||
void battle(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CArmedInstance *hero1, CArmedInstance *hero2);
|
||||
bool battleMoveCreatureStack(int ID, int dest);
|
||||
std::vector<int> battleGetRange(int ID); //called by std::vector<int> CCallback::battleGetAvailableHexes(int ID);
|
||||
public:
|
||||
friend CCallback;
|
||||
friend CPathfinder;;
|
||||
|
@ -1889,19 +1889,20 @@ void CPlayerInterface::battleNewRound(int round) //called at the beggining of ea
|
||||
{
|
||||
}
|
||||
|
||||
void CPlayerInterface::actionStarted(Action action)//occurs BEFORE every action taken by any stack or by the hero
|
||||
void CPlayerInterface::actionStarted(BattleAction action)//occurs BEFORE every action taken by any stack or by the hero
|
||||
{
|
||||
}
|
||||
|
||||
void CPlayerInterface::actionFinished(Action action)//occurs AFTER every action taken by any stack or by the hero
|
||||
void CPlayerInterface::actionFinished(BattleAction action)//occurs AFTER every action taken by any stack or by the hero
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->curStackActed = true;
|
||||
}
|
||||
|
||||
void CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack
|
||||
{
|
||||
unsigned char showCount = 0;
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackActivated(stackID);
|
||||
while(true)
|
||||
while(!dynamic_cast<CBattleInterface*>(curint)->curStackActed) //while current unit can perform an action
|
||||
{
|
||||
++showCount;
|
||||
SDL_Event sEvent;
|
||||
|
@ -314,8 +314,8 @@ public:
|
||||
void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side); //called by engine when battle starts; side=0 - left, side=1 - right
|
||||
void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
|
||||
void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
|
||||
void actionStarted(Action action);//occurs BEFORE every action taken by any stack or by the hero
|
||||
void actionFinished(Action action);//occurs AFTER every action taken by any stack or by the hero
|
||||
void actionStarted(BattleAction action);//occurs BEFORE every action taken by any stack or by the hero
|
||||
void actionFinished(BattleAction 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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user