mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* fixed defending creature in battle end window (slot id was used instead of creature id)
* redone casualties calculacion * redone battle-end checking (now it works always) * further fixes/checkings around netcode
This commit is contained in:
parent
6233066b91
commit
5e0986f9d8
@ -1449,10 +1449,10 @@ CBattleReslutWindow::CBattleReslutWindow(const BattleResult &br, SDL_Rect & pos,
|
||||
int bestPower = 0;
|
||||
for(std::map<si32,std::pair<ui32,si32> >::const_iterator it = owner->army2->slots.begin(); it!=owner->army2->slots.end(); ++it)
|
||||
{
|
||||
if( CGI->creh->creatures[it->first].AIValue > bestPower)
|
||||
if( CGI->creh->creatures[it->second.first].AIValue > bestPower)
|
||||
{
|
||||
bestPower = CGI->creh->creatures[it->first].AIValue;
|
||||
bestMonsterID = it->first;
|
||||
bestPower = CGI->creh->creatures[it->second.first].AIValue;
|
||||
bestMonsterID = it->second.first;
|
||||
}
|
||||
}
|
||||
SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &genRect(64, 58, 391, 38));
|
||||
|
@ -253,8 +253,8 @@ std::vector<int> BattleInfo::getPath(int start, int dest, bool*accessibility)
|
||||
return path;
|
||||
}
|
||||
|
||||
CStack::CStack(CCreature * C, int A, int O, int I, bool AO)
|
||||
:creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints)
|
||||
CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
|
||||
:creature(C),amount(A), baseAmount(A), owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints), slot(S)
|
||||
{
|
||||
}
|
||||
void CGameState::applyNL(IPack * pack)
|
||||
@ -552,27 +552,6 @@ void CGameState::applyNL(IPack * pack)
|
||||
at->amount = br->newAmount;
|
||||
at->firstHPleft = br->newHP;
|
||||
at->alive = !br->killed();
|
||||
|
||||
if(br->killedAmount>0) //setting casualities
|
||||
{
|
||||
bool found = false;
|
||||
for(std::set<std::pair<ui32,si32> >::iterator it = curB->cas[1 - at->attackerOwned].begin(); it!=curB->cas[1 - at->attackerOwned].end(); ++it)
|
||||
{
|
||||
if(it->first == at->creature->idNumber)
|
||||
{
|
||||
found = true;
|
||||
std::pair<ui32,si32> mod = *it;
|
||||
mod.second += br->killedAmount;
|
||||
|
||||
curB->cas[1 - at->attackerOwned].insert(it, mod);
|
||||
curB->cas[1 - at->attackerOwned].erase(it);
|
||||
}
|
||||
}
|
||||
if(!found)
|
||||
{
|
||||
curB->cas[1 - at->attackerOwned].insert(std::make_pair(at->creature->idNumber, br->killedAmount));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3006:
|
||||
@ -1341,3 +1320,38 @@ int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
|
||||
|
||||
return (float)damageBase * (float)attacker->amount * dmgBonusMultiplier;
|
||||
}
|
||||
|
||||
void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualties )
|
||||
{
|
||||
for(int i=0; i<stacks.size();i++)//setting casualties
|
||||
{
|
||||
if(!stacks[i]->alive)
|
||||
{
|
||||
casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount));
|
||||
}
|
||||
else if(stacks[i]->amount != stacks[i]->baseAmount)
|
||||
{
|
||||
casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount - stacks[i]->amount));
|
||||
}
|
||||
}
|
||||
//if(br->killedAmount>0)
|
||||
//{
|
||||
// bool found = false;
|
||||
// for(std::set<std::pair<ui32,si32> >::iterator it = curB->cas[1 - at->attackerOwned].begin(); it!=curB->cas[1 - at->attackerOwned].end(); ++it)
|
||||
// {
|
||||
// if(it->first == at->creature->idNumber)
|
||||
// {
|
||||
// found = true;
|
||||
// std::pair<ui32,si32> mod = *it;
|
||||
// mod.second += br->killedAmount;
|
||||
|
||||
// curB->cas[1 - at->attackerOwned].insert(it, mod);
|
||||
// curB->cas[1 - at->attackerOwned].erase(it);
|
||||
// }
|
||||
// }
|
||||
// if(!found)
|
||||
// {
|
||||
// curB->cas[1 - at->attackerOwned].insert(std::make_pair(at->creature->idNumber, br->killedAmount));
|
||||
// }
|
||||
//}
|
||||
}
|
14
CGameState.h
14
CGameState.h
@ -58,11 +58,10 @@ struct DLL_EXPORT BattleInfo
|
||||
si32 hero1, hero2;
|
||||
CCreatureSet army1, army2;
|
||||
std::vector<CStack*> stacks;
|
||||
std::set<std::pair<ui32,si32> > cas[2]; //first => casualties of attackers - set of pairs crid<>number
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2 & cas[0] & cas[1];
|
||||
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
|
||||
}
|
||||
CStack * getStack(int stackID);
|
||||
CStack * getStackT(int tileID);
|
||||
@ -75,6 +74,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
|
||||
void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties);
|
||||
};
|
||||
|
||||
class DLL_EXPORT CStack
|
||||
@ -82,15 +82,15 @@ class DLL_EXPORT CStack
|
||||
public:
|
||||
ui32 ID; //unique ID of stack
|
||||
CCreature * creature;
|
||||
ui32 amount;
|
||||
ui32 amount, baseAmount;
|
||||
ui32 firstHPleft; //HP of first creature in stack
|
||||
ui8 owner;
|
||||
ui8 owner, slot; //owner - player colour (255 for neutrals), slot - position in garrison (255 for neutrals/called creatures)
|
||||
ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
|
||||
ui16 position; //position on battlefield
|
||||
ui8 alive; //true if it is alive
|
||||
|
||||
CStack(CCreature * C, int A, int O, int I, bool AO);
|
||||
CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1){};
|
||||
CStack(CCreature * C, int A, int O, int I, bool AO, int S);
|
||||
CStack() : creature(NULL),amount(-1),owner(255), alive(true), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1){};
|
||||
|
||||
template <typename Handler> void save(Handler &h, const int version)
|
||||
{
|
||||
@ -104,7 +104,7 @@ public:
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & ID & amount & firstHPleft & owner & attackerOwned & position & alive;
|
||||
h & ID & amount & baseAmount & firstHPleft & owner & attackerOwned & position & alive;
|
||||
if(h.saving)
|
||||
save(h,version);
|
||||
else
|
||||
|
@ -56,13 +56,16 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
|
||||
std::cout<< "Critical problem: No endpoints found!" << std::endl;
|
||||
goto connerror1;
|
||||
}
|
||||
int i=0;
|
||||
while(pom != end)
|
||||
{
|
||||
std::cout << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
|
||||
std::cout << "\t" << i << ": " << (boost::asio::ip::tcp::endpoint&)*pom << std::endl;
|
||||
pom++;
|
||||
}
|
||||
i=0;
|
||||
while(endpoint_iterator != end)
|
||||
{
|
||||
std::cout << "Trying connection to " << (boost::asio::ip::tcp::endpoint&)*endpoint_iterator << " (" << i++ << ")" << std::endl;
|
||||
socket->connect(*endpoint_iterator, error);
|
||||
if(!error)
|
||||
{
|
||||
@ -71,18 +74,20 @@ CConnection::CConnection(std::string host, std::string port, std::string Name, s
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Problem with connecting. " << std::endl;
|
||||
std::cout << "Problem with connecting: " << std::endl << error << std::endl;
|
||||
}
|
||||
endpoint_iterator++;
|
||||
}
|
||||
|
||||
//we shouldn't be here - error handling
|
||||
connerror1:
|
||||
std::cout << "Something went wrong... checking for error info" << std::endl;
|
||||
if(error)
|
||||
std::cout << error <<std::endl;
|
||||
else
|
||||
std::cout << "No error info. " << std::endl;
|
||||
delete io_service;
|
||||
delete socket;
|
||||
//delete socket;
|
||||
throw std::string("Can't establish connection :(");
|
||||
}
|
||||
CConnection::CConnection(
|
||||
@ -99,7 +104,12 @@ CConnection::CConnection(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp
|
||||
boost::system::error_code error = asio::error::host_not_found;
|
||||
socket = new tcp::socket(*io_service);
|
||||
acceptor->accept(*socket,error);
|
||||
if (error){ delete socket; throw "Can't establish connection :("; }
|
||||
if (error)
|
||||
{
|
||||
std::cout << "Error on accepting: " << std::endl << error << std::endl;
|
||||
delete socket;
|
||||
throw "Can't establish connection :(";
|
||||
}
|
||||
init();
|
||||
}
|
||||
int CConnection::write(const void * data, unsigned size)
|
||||
|
@ -271,32 +271,11 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
|
||||
BattleSetActiveStack sas;
|
||||
sas.stack = stacks[i]->ID;
|
||||
sendAndApply(&sas);
|
||||
|
||||
//wait for response about battle action
|
||||
|
||||
boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
|
||||
while(!battleMadeAction.data)
|
||||
battleMadeAction.cond.wait(lock);
|
||||
battleMadeAction.data = false;
|
||||
}
|
||||
//checking winning condition
|
||||
bool hasStack[2]; //hasStack[0] - true if attacker has a living stack; defender similarily
|
||||
hasStack[0] = hasStack[1] = false;
|
||||
for(int b = 0; b<stacks.size(); ++b)
|
||||
{
|
||||
if(stacks[b]->alive)
|
||||
{
|
||||
hasStack[1-stacks[b]->attackerOwned] = true;
|
||||
}
|
||||
}
|
||||
if(!hasStack[0] || !hasStack[1]) //somebody has won
|
||||
{
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = 0;
|
||||
br->winner = hasStack[1]; //fleeing side loses
|
||||
br->casualties[0] = gs->curB->cas[0]; //setting casualities
|
||||
br->casualties[1] = gs->curB->cas[1]; //as above - second side ;]
|
||||
battleResult.set(br);
|
||||
checkForBattleEnd(stacks);
|
||||
}
|
||||
}
|
||||
|
||||
@ -887,8 +866,7 @@ upgend:
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = 1;
|
||||
br->winner = !ba.side; //fleeing side loses
|
||||
br->casualties[0] = gs->curB->cas[0]; //setting casualities
|
||||
br->casualties[1] = gs->curB->cas[1]; //as above - second side ;]
|
||||
gs->curB->calculateCasualties(br->casualties);
|
||||
battleResult.set(br);
|
||||
break;
|
||||
}
|
||||
@ -1204,7 +1182,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
curB->activeStack = -1;
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
|
||||
{
|
||||
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true));
|
||||
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true,i->first));
|
||||
stacks[stacks.size()-1]->ID = stacks.size()-1;
|
||||
}
|
||||
//initialization of positions
|
||||
@ -1258,7 +1236,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
break;
|
||||
}
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
|
||||
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false));
|
||||
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false, i->first));
|
||||
switch(army2.slots.size()) //for defender
|
||||
{
|
||||
case 0:
|
||||
@ -1332,3 +1310,25 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
|
||||
bs.info = curB;
|
||||
sendAndApply(&bs);
|
||||
}
|
||||
|
||||
void CGameHandler::checkForBattleEnd( std::vector<CStack*> &stacks )
|
||||
{
|
||||
//checking winning condition
|
||||
bool hasStack[2]; //hasStack[0] - true if attacker has a living stack; defender similarily
|
||||
hasStack[0] = hasStack[1] = false;
|
||||
for(int b = 0; b<stacks.size(); ++b)
|
||||
{
|
||||
if(stacks[b]->alive)
|
||||
{
|
||||
hasStack[1-stacks[b]->attackerOwned] = true;
|
||||
}
|
||||
}
|
||||
if(!hasStack[0] || !hasStack[1]) //somebody has won
|
||||
{
|
||||
BattleResult *br = new BattleResult;
|
||||
br->result = 0;
|
||||
br->winner = hasStack[1]; //fleeing side loses
|
||||
gs->curB->calculateCasualties(br->casualties);
|
||||
battleResult.set(br);
|
||||
}
|
||||
}
|
@ -54,6 +54,8 @@ class CGameHandler
|
||||
void changeSecSkill(int ID, ui16 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
|
||||
|
||||
void checkForBattleEnd( std::vector<CStack*> &stacks );
|
||||
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
|
||||
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user