mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Battles: attacking, shooting, killing.
This commit is contained in:
parent
92971e0df0
commit
15ff21e84c
@ -461,6 +461,8 @@ void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby, bool b
|
||||
show();
|
||||
CSDL_Ext::update();
|
||||
SDL_framerateDelay(LOCPLINT->mainFPSmng);
|
||||
if((animCount+1)%4)
|
||||
creAnims[ID]->incrementFrame();
|
||||
}
|
||||
|
||||
printConsoleAttacked(ID, dmg, killed, IDby);
|
||||
@ -614,6 +616,8 @@ void CBattleInterface::stackIsAttacked(int ID, int dmg, int killed, int IDby, bo
|
||||
show();
|
||||
CSDL_Ext::update();
|
||||
SDL_framerateDelay(LOCPLINT->mainFPSmng);
|
||||
if((animCount+1)%4)
|
||||
creAnims[ID]->incrementFrame();
|
||||
}
|
||||
creAnims[ID]->setType(2);
|
||||
|
||||
@ -680,22 +684,22 @@ void CBattleInterface::stackAttacking(int ID, int dest)
|
||||
switch(BattleInfo::mutualPosition(aStack.position, dest)) //attack direction
|
||||
{
|
||||
case 0:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
case 1:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(10);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
break;
|
||||
case 2:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
case 3:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(13);
|
||||
break;
|
||||
case 4:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(13);
|
||||
break;
|
||||
case 5:
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(11);
|
||||
attackingInfo->maxframe = creAnims[ID]->framesInGroup(12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -705,12 +709,13 @@ void CBattleInterface::newRound(int number)
|
||||
console->addText(CGI->generaltexth->allTexts[412]);
|
||||
}
|
||||
|
||||
void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack)
|
||||
void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional)
|
||||
{
|
||||
BattleAction * ba = new BattleAction(); //to be deleted by engine
|
||||
BattleAction * ba = new BattleAction(); //is deleted in CPlayerInterface::activeStack()
|
||||
ba->actionType = action;
|
||||
ba->destinationTile = tile;
|
||||
ba->stackNumber = stack;
|
||||
ba->additionalInfo = additional;
|
||||
givenCommand->setn(ba);
|
||||
myTurn = false;
|
||||
activeStack = -1;
|
||||
@ -737,7 +742,16 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
}
|
||||
else if(LOCPLINT->cb->battleGetStackByID(atCre)->owner != attackingHeroInstance->tempOwner) //attacking
|
||||
{
|
||||
giveCommand(6,whichOne,activeStack);
|
||||
std::vector<int> n = BattleInfo::neighbouringTiles(whichOne);
|
||||
for(int i=0;i<n.size();i++)
|
||||
{
|
||||
//TODO: now we are using first available tile, but in the future we should add possibility of choosing from which tile we want to attack
|
||||
if(vstd::contains(shadedHexes,n[i]))
|
||||
{
|
||||
giveCommand(6,n[i],activeStack,whichOne);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1151,9 +1165,20 @@ void CBattleHex::mouseMoved(SDL_MouseMotionEvent &sEvent)
|
||||
{
|
||||
if(std::find(myInterface->shadedHexes.begin(),myInterface->shadedHexes.end(),myNumber) == myInterface->shadedHexes.end())
|
||||
{
|
||||
CGI->curh->changeGraphic(1,0);
|
||||
CStack *shere = LOCPLINT->cb->battleGetStackByPos(myNumber);
|
||||
if(shere)
|
||||
{
|
||||
if(shere->owner == LOCPLINT->playerID) //our stack
|
||||
CGI->curh->changeGraphic(1,5);
|
||||
else if(LOCPLINT->cb->battleGetStackByID(myInterface->activeStack)->creature->isShooting()) //we can shoot enemy
|
||||
CGI->curh->changeGraphic(1,3);
|
||||
else //unavailable enemy
|
||||
CGI->curh->changeGraphic(1,0);
|
||||
}
|
||||
else //empty unavailable tile
|
||||
CGI->curh->changeGraphic(1,0);
|
||||
}
|
||||
else
|
||||
else //available tile
|
||||
{
|
||||
if(LOCPLINT->cb->battleGetStackByID(myInterface->activeStack)->creature->isFlying())
|
||||
CGI->curh->changeGraphic(1,2);
|
||||
@ -1199,6 +1224,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
if(hovered && strictHovered && stID!=-1)
|
||||
{
|
||||
CStack myst = *LOCPLINT->cb->battleGetStackByID(stID); //stack info
|
||||
if(!myst.alive) return;
|
||||
StackState *pom = NULL;
|
||||
if(down)
|
||||
{
|
||||
@ -1210,6 +1236,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
|
||||
pom->defenseBonus = h->primSkills[1];
|
||||
pom->luck = h->getCurrentLuck();
|
||||
pom->morale = h->getCurrentMorale();
|
||||
pom->currentHealth = myst.firstHPleft;
|
||||
}
|
||||
(new CCreInfoWindow(myst.creature->idNumber,0,pom,boost::function<void()>(),boost::function<void()>()))
|
||||
->activate();
|
||||
|
@ -112,7 +112,7 @@ private:
|
||||
};
|
||||
std::list<SProjectileInfo> projectiles;
|
||||
void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield
|
||||
void giveCommand(ui8 action, ui16 tile, ui32 stack);
|
||||
void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
|
||||
public:
|
||||
CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2); //c-tor
|
||||
~CBattleInterface(); //d-tor
|
||||
|
@ -20,6 +20,7 @@ class CGObjectInstance;
|
||||
class CCreatureSet;
|
||||
class CArmedInstance;
|
||||
struct BattleResult;
|
||||
struct BattleAttack;
|
||||
class CObstacle
|
||||
{
|
||||
int ID;
|
||||
@ -61,13 +62,12 @@ 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(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 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 BattleAction activeStack(int stackID)=0; //called when it's turn of that stack
|
||||
virtual void battleEnd(BattleResult *br){};
|
||||
virtual void battleStackMoved(int ID, int dest, bool startMoving, bool endMoving)=0;
|
||||
virtual void battleStackAttacking(int ID, int dest)=0;
|
||||
virtual void battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting)=0;
|
||||
virtual void battleAttack(BattleAttack *ba){};
|
||||
virtual void battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting)=0;
|
||||
//
|
||||
|
||||
|
129
CGameState.cpp
129
CGameState.cpp
@ -405,6 +405,23 @@ void CGameState::apply(IPack * pack)
|
||||
curB->getStack(br->stack)->position = br->tile;
|
||||
break;
|
||||
}
|
||||
case 3005:
|
||||
{
|
||||
BattleStackAttacked *br = static_cast<BattleStackAttacked*>(pack);
|
||||
CStack * at = curB->getStack(br->stackAttacked);
|
||||
at->amount = br->newAmount;
|
||||
at->firstHPleft = br->newHP;
|
||||
at->alive = !br->killed();
|
||||
break;
|
||||
}
|
||||
case 3006:
|
||||
{
|
||||
BattleAttack *br = static_cast<BattleAttack*>(pack);
|
||||
mx->unlock();
|
||||
apply(&br->bsa);
|
||||
mx->lock();
|
||||
break;
|
||||
}
|
||||
//case 1002://set hover name
|
||||
// {
|
||||
// SetHoverName * shn = static_cast<SetHoverName*>(pack);
|
||||
@ -921,65 +938,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
}
|
||||
|
||||
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 || !curB->stacks[numberOfStackAtEnd]->alive)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -990,7 +949,7 @@ int CGameState::battleGetStack(int pos)
|
||||
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)
|
||||
(!curB->stacks[g]->attackerOwned && curB->stacks[g]->position-1 == pos)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -999,7 +958,7 @@ int CGameState::battleGetStack(int pos)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int CGameState::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
{
|
||||
int attackDefenseBonus = attacker->creature->attack - defender->creature->defence;
|
||||
int damageBase = 0;
|
||||
@ -1037,50 +996,4 @@ int CGameState::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
}
|
||||
|
||||
return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
|
||||
}
|
||||
|
||||
std::vector<int> CGameState::battleGetRange(int ID)
|
||||
{/*
|
||||
std::vector<int> additionals;
|
||||
|
||||
//adding enemies' positions
|
||||
for(int c=0; c<curB->stacks.size(); ++c)
|
||||
{
|
||||
if(curB->stacks[c]->alive && curB->stacks[c]->owner != owner)
|
||||
{
|
||||
for(int g=0; g<ret.size(); ++g)
|
||||
{
|
||||
if(CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position) != -1)
|
||||
{
|
||||
additionals.push_back(curB->stacks[c]->position);
|
||||
}
|
||||
if(curB->stacks[c]->creature->isDoubleWide() && curB->stacks[c]->attackerOwned && CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position-1) != -1)
|
||||
{
|
||||
additionals.push_back(curB->stacks[c]->position-1);
|
||||
}
|
||||
if(curB->stacks[c]->creature->isDoubleWide() && !curB->stacks[c]->attackerOwned && CBattleHex::mutualPosition(ret[g], curB->stacks[c]->position+1) != -1)
|
||||
{
|
||||
additionals.push_back(curB->stacks[c]->position+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for(int g=0; g<additionals.size(); ++g)
|
||||
{
|
||||
ret.push_back(additionals[g]);
|
||||
}
|
||||
|
||||
std::sort(ret.begin(), ret.end());
|
||||
std::vector<int>::iterator nend = std::unique(ret.begin(), ret.end());
|
||||
|
||||
std::vector<int> ret2;
|
||||
|
||||
for(std::vector<int>::iterator it = ret.begin(); it != nend; ++it)
|
||||
{
|
||||
ret2.push_back(*it);
|
||||
}
|
||||
|
||||
return ret2;*/
|
||||
return std::vector<int>();
|
||||
}
|
||||
|
||||
}
|
@ -73,6 +73,7 @@ struct DLL_EXPORT BattleInfo
|
||||
|
||||
static signed char mutualPosition(int hex1, int hex2); //returns info about mutual position of given hexes (-1 - they're distant, 0 - left top, 1 - right top, 2 - right, 3 - right bottom, 4 - left bottom, 5 - left)
|
||||
static std::vector<int> neighbouringTiles(int hex);
|
||||
static int calculateDmg(const CStack* attacker, const CStack* defender); //TODO: add additional conditions and require necessary data
|
||||
};
|
||||
|
||||
class DLL_EXPORT CStack
|
||||
@ -138,8 +139,6 @@ private:
|
||||
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:
|
||||
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||
|
||||
|
17
CMT.cpp
17
CMT.cpp
@ -150,7 +150,22 @@ int main(int argc, _TCHAR* argv[])
|
||||
THC std::cout<<"\tCallback and console: "<<pomtime.getDif()<<std::endl;
|
||||
THC std::cout<<"Handlers initialization (together): "<<tmh.getDif()<<std::endl;
|
||||
std::ofstream lll("client_log.txt");
|
||||
CConnection *c = new CConnection("localhost","3030",NAME,lll);
|
||||
|
||||
CConnection *c=NULL;
|
||||
while(!c)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::cout << "Establishing connection...\t";
|
||||
c = new CConnection("localhost","3030",NAME,lll);
|
||||
std::cout << "done!" <<std::endl;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cout << "\nCannot establish connection! Retrying within 3 seconds" <<std::endl;
|
||||
SDL_Delay(3000);
|
||||
}
|
||||
}
|
||||
THC std::cout<<"\tConnecting to the server: "<<tmh.getDif()<<std::endl;
|
||||
CClient cl(c,options);
|
||||
boost::thread t(boost::bind(&CClient::run,&cl));
|
||||
|
@ -1076,10 +1076,10 @@ void CPlayerInterface::yourTurn()
|
||||
}
|
||||
for(int i=0;i<objsToBlit.size();i++)
|
||||
objsToBlit[i]->show();
|
||||
pim->unlock();
|
||||
CGI->curh->draw1();
|
||||
CSDL_Ext::update(screen);
|
||||
CGI->curh->draw2();
|
||||
pim->unlock();
|
||||
SDL_framerateDelay(mainFPSmng);
|
||||
}
|
||||
adventureInt->hide();
|
||||
@ -1969,14 +1969,14 @@ void CPlayerInterface::battleNewRound(int round) //called at the beggining of ea
|
||||
dynamic_cast<CBattleInterface*>(curint)->newRound(round);
|
||||
}
|
||||
|
||||
void CPlayerInterface::actionStarted(BattleAction action)//occurs BEFORE 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)->givenCommand = -1;
|
||||
}
|
||||
//void CPlayerInterface::actionStarted(BattleAction action)//occurs BEFORE 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)->givenCommand = -1;
|
||||
//}
|
||||
|
||||
BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack
|
||||
{
|
||||
@ -2014,17 +2014,18 @@ void CPlayerInterface::battleStackMoved(int ID, int dest, bool startMoving, bool
|
||||
boost::unique_lock<boost::mutex> un(*pim);
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackMoved(ID, dest, startMoving, endMoving);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackAttacking(int ID, int dest)
|
||||
void CPlayerInterface::battleAttack(BattleAttack *ba)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackAttacking(ID, dest);
|
||||
boost::unique_lock<boost::mutex> un(*pim);
|
||||
if(ba->shot())
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ba->stackAttacking,cb->battleGetPos(ba->bsa.stackAttacked));
|
||||
else
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackAttacking( ba->stackAttacking, cb->battleGetPos(ba->bsa.stackAttacked) );
|
||||
if(ba->killed())
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackKilled(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot());
|
||||
else
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot());
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackIsAttacked(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ID, dmg, killed, IDby, byShooting);
|
||||
}
|
||||
|
||||
void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting)
|
||||
{
|
||||
dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby, byShooting);
|
||||
@ -2970,7 +2971,8 @@ CCreInfoWindow::CCreInfoWindow
|
||||
int hlp = log10f(c->defence)+2;
|
||||
pom[hlp-1] = ' '; pom[hlp] = '(';
|
||||
SDL_itoa(c->defence+State->defenseBonus,pom+hlp+1,10);
|
||||
pom[hlp+2+(int)log10f(State->defenseBonus+c->defence)] = ')';
|
||||
hlp += 2+(int)log10f(State->defenseBonus+c->defence);
|
||||
pom[hlp] = ')'; pom[hlp+1] = '\0';
|
||||
}
|
||||
printToWR(pom,276,80,GEOR13,zwykly,bitmap);
|
||||
|
||||
@ -2995,8 +2997,13 @@ CCreInfoWindow::CCreInfoWindow
|
||||
SDL_itoa(c->hitPoints,pom,10);
|
||||
printToWR(pom,276,137,GEOR13,zwykly,bitmap);
|
||||
|
||||
//remaining health - TODO: show during the battles
|
||||
//printAt(CGI->preth->zelp[440].first,155,143,GEOR13,zwykly,bitmap);
|
||||
//remaining health
|
||||
if(State)
|
||||
{
|
||||
printAt(CGI->preth->zelp[440].first,155,143,GEOR13,zwykly,bitmap);
|
||||
SDL_itoa(State->currentHealth,pom,10);
|
||||
printToWR(pom,276,156,GEOR13,zwykly,bitmap);
|
||||
}
|
||||
|
||||
//speed
|
||||
printAt(CGI->preth->zelp[441].first,155,162,GEOR13,zwykly,bitmap);
|
||||
|
@ -336,13 +336,12 @@ public:
|
||||
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
|
||||
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(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 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
|
||||
BattleAction activeStack(int stackID); //called when it's turn of that stack
|
||||
void battleEnd(BattleResult *br);
|
||||
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, bool byShooting);
|
||||
void battleAttack(BattleAttack *ba);
|
||||
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
|
||||
|
||||
|
@ -394,6 +394,14 @@ void CClient::process(int what)
|
||||
gs->apply(&br);
|
||||
break;
|
||||
}
|
||||
case 3006:
|
||||
{
|
||||
BattleAttack ba;
|
||||
*serv >> ba;
|
||||
gs->apply(&ba);
|
||||
LOCPLINT->battleAttack(&ba);
|
||||
break;
|
||||
}
|
||||
case 9999:
|
||||
break;
|
||||
default:
|
||||
|
16
global.h
16
global.h
@ -89,4 +89,20 @@ const int MAX_BUILDING_PER_TURN = 1;
|
||||
delete e; \
|
||||
}
|
||||
|
||||
|
||||
namespace vstd
|
||||
{
|
||||
template <typename Container, typename Item>
|
||||
bool contains(const Container & c, const Item &i)
|
||||
{
|
||||
return std::find(c.begin(),c.end(),i) != c.end();
|
||||
}
|
||||
template <typename Container, typename Item>
|
||||
typename Container::iterator find(const Container & c, const Item &i)
|
||||
{
|
||||
return std::find(c.begin(),c.end(),i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //GLOBAL_H
|
||||
|
@ -304,7 +304,7 @@ struct BattleResult : public CPack<BattleResult>//3003
|
||||
struct BattleStackMoved : public CPack<BattleStackMoved>//3004
|
||||
{
|
||||
ui32 stack, tile;
|
||||
ui8 flags;
|
||||
ui8 flags; // 1 - start moving, 2 - end moving
|
||||
|
||||
|
||||
|
||||
@ -323,6 +323,47 @@ struct BattleStackMoved : public CPack<BattleStackMoved>//3004
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
|
||||
{
|
||||
ui32 stackAttacked;
|
||||
ui32 newAmount, newHP, killedAmount, damageAmount;
|
||||
ui8 flags; //1 - is stack killed
|
||||
|
||||
|
||||
BattleStackAttacked(){flags = 0; type = 3005;};
|
||||
bool killed() //if target stack was killed
|
||||
{
|
||||
return flags & 1;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & stackAttacked & newAmount & newHP & flags & killedAmount & damageAmount;
|
||||
}
|
||||
};
|
||||
|
||||
struct BattleAttack : public CPack<BattleAttack>//3006
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
ui32 stackAttacking;
|
||||
ui8 flags;
|
||||
|
||||
|
||||
|
||||
BattleAttack(){flags = 0; type = 3006;};
|
||||
bool shot()//distance attack - decrease number of shots
|
||||
{
|
||||
return flags & 1;
|
||||
}
|
||||
bool killed() //if target stack was killed
|
||||
{
|
||||
return bsa.killed();
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & bsa & stackAttacking & flags;
|
||||
}
|
||||
};
|
||||
|
||||
struct ShowInInfobox : public CPack<ShowInInfobox> //107
|
||||
{
|
||||
ShowInInfobox(){type = 107;};
|
||||
|
@ -18,7 +18,9 @@
|
||||
#include "boost/date_time/posix_time/posix_time_types.hpp" //no i/o just types
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#ifndef _MSC_VER
|
||||
#include <boost/thread/xtime.hpp>
|
||||
#endif
|
||||
extern bool end2;
|
||||
#include "../lib/BattleAction.h"
|
||||
#ifdef min
|
||||
@ -335,7 +337,36 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
//delete curB;
|
||||
//curB = NULL;
|
||||
}
|
||||
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
|
||||
{
|
||||
bat.stackAttacking = att->ID;
|
||||
bat.bsa.stackAttacked = def->ID;
|
||||
bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def);//counting dealt damage
|
||||
|
||||
//applying damages
|
||||
bat.bsa.killedAmount = bat.bsa.damageAmount / def->creature->hitPoints;
|
||||
unsigned damageFirst = bat.bsa.damageAmount % def->creature->hitPoints;
|
||||
|
||||
if( def->firstHPleft <= damageFirst )
|
||||
{
|
||||
bat.bsa.killedAmount++;
|
||||
bat.bsa.newHP = def->firstHPleft + def->creature->hitPoints - damageFirst;
|
||||
}
|
||||
else
|
||||
{
|
||||
bat.bsa.newHP = def->firstHPleft - damageFirst;
|
||||
}
|
||||
|
||||
if(def->amount <= bat.bsa.killedAmount) //stack killed
|
||||
{
|
||||
bat.bsa.newAmount = 0;
|
||||
bat.bsa.flags |= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bat.bsa.newAmount = def->amount - bat.bsa.killedAmount;
|
||||
}
|
||||
}
|
||||
void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
try
|
||||
@ -585,80 +616,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
{
|
||||
case 2: //walk
|
||||
{
|
||||
CStack *curStack = gs->curB->getStack(ba.stackNumber),
|
||||
*stackAtEnd = gs->curB->getStackT(ba.destinationTile);
|
||||
|
||||
//initing necessary tables
|
||||
bool accessibility[187];
|
||||
if(curStack->creature->isDoubleWide())
|
||||
{
|
||||
gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned,curStack->ID);
|
||||
//accessibility[curStack->attackerOwned ? curStack->position+1 : curStack->position-1]=true;//OUR second tile is for US accessible
|
||||
}
|
||||
else
|
||||
gs->curB->getAccessibilityMap(accessibility,curStack->ID);
|
||||
//accessibility[curStack->position] = true; //OUR tile is for US accessible
|
||||
|
||||
//if(!stackAtEnd && !accessibility[dest])
|
||||
// return false;
|
||||
|
||||
//if(dists[dest] > curStack->creature->speed && !(stackAtEnd && dists[dest] == curStack->creature->speed+1)) //we can attack a stack if we can go to adjacent hex
|
||||
// return false;
|
||||
|
||||
std::vector<int> path = gs->curB->getPath(curStack->position,ba.destinationTile,accessibility);
|
||||
int tilesToMove = std::max((int)path.size()-curStack->creature->speed, 0);
|
||||
for(int v=path.size()-1; v>=tilesToMove; --v)
|
||||
{
|
||||
if(v!=0 || !stackAtEnd) //it's not the last step or the last tile is free
|
||||
{
|
||||
//inform clients about move
|
||||
BattleStackMoved sm;
|
||||
sm.stack = curStack->ID;
|
||||
sm.tile = path[v];
|
||||
if(v==path.size()-1)//move start - set flag
|
||||
sm.flags |= 1;
|
||||
if(v==0 || (stackAtEnd && v==1)) //move end - set flag
|
||||
sm.flags |= 2;
|
||||
sendAndApply(&sm);
|
||||
}
|
||||
else //if it's last step and we should attack unit at the end
|
||||
{
|
||||
//LOCPLINT->battleStackAttacking(ID, path[v]);
|
||||
////counting dealt damage
|
||||
//int finalDmg = calculateDmg(curStack, curB->stacks[numberOfStackAtEnd]);
|
||||
|
||||
////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, 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());
|
||||
moveStack(ba.stackNumber,ba.destinationTile);
|
||||
break;
|
||||
}
|
||||
case 3: //defend
|
||||
@ -677,13 +635,29 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
}
|
||||
case 6: //walk or attack
|
||||
{
|
||||
//battleMoveCreatureStack(ba.stackNumber, ba.destinationTile);
|
||||
//battleAttackCreatureStack(ba.stackNumber, ba.destinationTile);
|
||||
moveStack(ba.stackNumber,ba.destinationTile);
|
||||
CStack *curStack = gs->curB->getStack(ba.stackNumber),
|
||||
*stackAtEnd = gs->curB->getStackT(ba.additionalInfo);
|
||||
|
||||
if((curStack->position != ba.destinationTile) || //we wasn't able to reach destination tile
|
||||
(BattleInfo::mutualPosition(ba.destinationTile,ba.additionalInfo)<0) ) //destination tile is not neighbouring with enemy stack
|
||||
return;
|
||||
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,stackAtEnd);
|
||||
sendAndApply(&bat);
|
||||
break;
|
||||
}
|
||||
case 7: //shoot
|
||||
{
|
||||
//battleShootCreatureStack(ba.stackNumber, ba.destinationTile);
|
||||
CStack *curStack = gs->curB->getStack(ba.stackNumber),
|
||||
*destStack= gs->curB->getStackT(ba.destinationTile);
|
||||
|
||||
BattleAttack bat;
|
||||
prepareAttack(bat,curStack,destStack);
|
||||
bat.flags |= 1;
|
||||
|
||||
sendAndApply(&bat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -717,6 +691,39 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
||||
end2 = true;
|
||||
}
|
||||
}
|
||||
void CGameHandler::moveStack(int stack, int dest)
|
||||
{
|
||||
CStack *curStack = gs->curB->getStack(stack),
|
||||
*stackAtEnd = gs->curB->getStackT(dest);
|
||||
|
||||
//initing necessary tables
|
||||
bool accessibility[187];
|
||||
if(curStack->creature->isDoubleWide())
|
||||
gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned,curStack->ID);
|
||||
else
|
||||
gs->curB->getAccessibilityMap(accessibility,curStack->ID);
|
||||
|
||||
if((stackAtEnd && stackAtEnd->alive) || !accessibility[dest])
|
||||
return;
|
||||
|
||||
//if(dists[dest] > curStack->creature->speed && !(stackAtEnd && dists[dest] == curStack->creature->speed+1)) //we can attack a stack if we can go to adjacent hex
|
||||
// return false;
|
||||
|
||||
std::vector<int> path = gs->curB->getPath(curStack->position,dest,accessibility);
|
||||
int tilesToMove = std::max((int)path.size()-curStack->creature->speed, 0);
|
||||
for(int v=path.size()-1; v>=tilesToMove; --v)
|
||||
{
|
||||
//inform clients about move
|
||||
BattleStackMoved sm;
|
||||
sm.stack = curStack->ID;
|
||||
sm.tile = path[v];
|
||||
if(v==path.size()-1) //move start - set flag
|
||||
sm.flags |= 1;
|
||||
if(v==0) //move end - set flag
|
||||
sm.flags |= 2;
|
||||
sendAndApply(&sm);
|
||||
}
|
||||
}
|
||||
CGameHandler::CGameHandler(void)
|
||||
{
|
||||
gs = NULL;
|
||||
@ -898,10 +905,13 @@ void CGameHandler::run()
|
||||
{
|
||||
boost::posix_time::time_duration p;
|
||||
p= boost::posix_time::seconds(1);
|
||||
#ifdef _MSC_VER
|
||||
cTurn.timed_wait(lock,p);
|
||||
#else
|
||||
boost::xtime time={0,0};
|
||||
time.sec = static_cast<boost::xtime::xtime_sec_t>(p.total_seconds());
|
||||
cTurn.wait(lock);
|
||||
//cTurn.timed_wait(lock,time);
|
||||
cTurn.timed_wait(lock,time);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class CGameHandler
|
||||
|
||||
void handleCPPObjS(std::map<int,CCPPObjectScript*> * mapa, CCPPObjectScript * script);
|
||||
void changePrimSkill(int ID, int which, int val, bool abs=false);
|
||||
void moveStack(int stack, int dest);
|
||||
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user