1
0
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:
Michał W. Urbańczyk 2008-09-09 07:05:02 +00:00
parent 6233066b91
commit 5e0986f9d8
6 changed files with 89 additions and 63 deletions

View File

@ -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));

View File

@ -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));
// }
//}
}

View File

@ -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

View File

@ -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)

View File

@ -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);
}
}

View File

@ -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: