mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Stacks #4 -> giving creatures still needs to be fixed.
This commit is contained in:
parent
fdb541d81e
commit
848a00bc6f
@ -4,6 +4,7 @@
|
||||
#include <boost/lambda/lambda.hpp>
|
||||
#include <boost/lambda/bind.hpp>
|
||||
#include <boost/lambda/if.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN //excludes rarely used stuff from windows headers - delete this line if something is missing
|
||||
@ -72,8 +73,8 @@ void CBattleLogic::SetCurrentTurn(int turn)
|
||||
|
||||
void CBattleLogic::MakeStatistics(int currentCreatureId)
|
||||
{
|
||||
typedef std::map<int, CStack> map_stacks;
|
||||
map_stacks allStacks = m_cb->battleGetStacks();
|
||||
typedef std::vector<const CStack*> vector_stacks;
|
||||
vector_stacks allStacks = m_cb->battleGetStacks();
|
||||
const CStack *currentStack = m_cb->battleGetStackByID(currentCreatureId);
|
||||
if(currentStack->position < 0) //turret
|
||||
{
|
||||
@ -118,14 +119,13 @@ void CBattleLogic::MakeStatistics(int currentCreatureId)
|
||||
int totalDamage = 0;
|
||||
int totalHitPoints = 0;
|
||||
|
||||
for (map_stacks::const_iterator it = allStacks.begin(); it != allStacks.end(); ++it)
|
||||
BOOST_FOREACH(const CStack *st, allStacks)
|
||||
{
|
||||
const CStack *st = &it->second;
|
||||
const int stackHP = st->valOfBonuses(Bonus::STACK_HEALTH);
|
||||
|
||||
if ((it->second.attackerOwned != 0) != m_bIsAttacker)
|
||||
if ((st->attackerOwned != 0) != m_bIsAttacker)
|
||||
{
|
||||
int id = it->first;
|
||||
int id = st->ID;
|
||||
if (st->count < 1)
|
||||
{
|
||||
continue;
|
||||
|
@ -542,19 +542,19 @@ int CCallback::battleGetPos(int stack)
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::map<int, CStack> CCallback::battleGetStacks()
|
||||
std::vector<const CStack*> CCallback::battleGetStacks()
|
||||
{
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
std::map<int, CStack> ret;
|
||||
std::vector<const CStack*> ret;
|
||||
if(!gs->curB) //there is no battle
|
||||
{
|
||||
tlog2<<"battleGetStacks called when there is no battle!"<<std::endl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(size_t g=0; g<gs->curB->stacks.size(); ++g)
|
||||
{
|
||||
ret[gs->curB->stacks[g]->ID] = *(gs->curB->stacks[g]);
|
||||
}
|
||||
BOOST_FOREACH(const CStack *s, gs->curB->stacks)
|
||||
ret.push_back(s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1037,7 +1037,7 @@ InfoAboutTown::~InfoAboutTown()
|
||||
void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed )
|
||||
{
|
||||
obj = t;
|
||||
army = t->getArmy();
|
||||
army = ArmyDescriptor(t, detailed);
|
||||
built = t->builded;
|
||||
fortLevel = t->fortLevel();
|
||||
name = t->name;
|
||||
@ -1053,21 +1053,14 @@ void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed )
|
||||
details->hallLevel = t->hallLevel();
|
||||
details->garrisonedHero = t->garrisonHero;
|
||||
}
|
||||
/*else
|
||||
{
|
||||
//hide info about hero stacks counts
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i = slots.begin(); i != slots.end(); ++i)
|
||||
{
|
||||
i->second.second = 0;
|
||||
}
|
||||
}*/
|
||||
//TODO: adjust undetailed info about army to our count of thieves guilds
|
||||
}
|
||||
|
||||
void InfoAboutTown::initFromGarrison(const CGGarrison *garr, bool detailed)
|
||||
{
|
||||
obj = garr;
|
||||
fortLevel = 0;
|
||||
army = garr->getArmy();
|
||||
army = ArmyDescriptor(garr, detailed);
|
||||
name = CGI->generaltexth->names[33]; // "Garrison"
|
||||
owner = garr->tempOwner;
|
||||
built = false;
|
||||
|
@ -61,7 +61,7 @@ struct InfoAboutTown
|
||||
CTown *tType;
|
||||
bool built;
|
||||
|
||||
CCreatureSet army; //numbers of creatures are valid only if details
|
||||
ArmyDescriptor army; //numbers of creatures are valid only if details
|
||||
|
||||
InfoAboutTown();
|
||||
~InfoAboutTown();
|
||||
@ -166,7 +166,7 @@ public:
|
||||
virtual const CStack * battleGetStackByPos(int pos, bool onlyAlive = true)=0; //returns stack info by given pos
|
||||
virtual int battleGetPos(int stack)=0; //returns position (tile ID) of stack
|
||||
virtual int battleMakeAction(BattleAction* action)=0;//for casting spells by hero - DO NOT use it for moving active stack
|
||||
virtual std::map<int, CStack> battleGetStacks()=0; //returns stacks on battlefield
|
||||
virtual std::vector<const CStack*> battleGetStacks()=0; //returns stacks on battlefield
|
||||
virtual void getStackQueue( std::vector<const CStack *> &out, int howMany )=0; //returns vector of stack in order of their move sequence
|
||||
virtual CCreature battleGetCreature(int number)=0; //returns type of creature by given number of stack
|
||||
//virtual bool battleMoveCreature(int ID, int dest)=0; //moves creature with id ID to dest if possible
|
||||
@ -297,7 +297,7 @@ public:
|
||||
const CStack * battleGetStackByPos(int pos, bool onlyAlive = true); //returns stack info by given pos
|
||||
int battleGetPos(int stack); //returns position (tile ID) of stack
|
||||
int battleMakeAction(BattleAction* action);//for casting spells by hero - DO NOT use it for moving active stack
|
||||
std::map<int, CStack> battleGetStacks(); //returns stacks on battlefield
|
||||
std::vector<const CStack*> battleGetStacks(); //returns stacks on battlefield
|
||||
void getStackQueue( std::vector<const CStack *> &out, int howMany ); //returns vector of stack in order of their move sequence
|
||||
CCreature battleGetCreature(int number); //returns type of creature by given number of stack
|
||||
std::vector<int> battleGetAvailableHexes(int ID, bool addOccupiable); //reutrns numbers of hexes reachable by creature with id ID
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "../hch/CVideoHandler.h"
|
||||
#include "../hch/CTownHandler.h"
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#ifndef __GNUC__
|
||||
@ -1138,12 +1139,12 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
||||
curInt->battleInt = this;
|
||||
|
||||
//initializing armies
|
||||
this->army1 = *army1;
|
||||
this->army2 = *army2;
|
||||
std::map<int, CStack> stacks = curInt->cb->battleGetStacks();
|
||||
for(std::map<int, CStack>::iterator b=stacks.begin(); b!=stacks.end(); ++b)
|
||||
this->army1 = army1;
|
||||
this->army2 = army2;
|
||||
std::vector<const CStack*> stacks = curInt->cb->battleGetStacks();
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
newStack(b->second.ID);
|
||||
newStack(s->ID);
|
||||
}
|
||||
|
||||
//preparing menu background and terrain
|
||||
@ -1264,34 +1265,33 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
||||
bfield[h].myInterface = this;
|
||||
}
|
||||
//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
|
||||
{
|
||||
if(it->second.position >= 0) //turrets have position < 0
|
||||
bfield[it->second.position].accessible = false;
|
||||
}
|
||||
BOOST_FOREACH(const CStack *s, stacks) //stacks gained at top of this function
|
||||
if(s->position >= 0) //turrets have position < 0
|
||||
bfield[s->position].accessible = false;
|
||||
|
||||
//loading projectiles for units
|
||||
for(std::map<int, CStack>::iterator g = stacks.begin(); g != stacks.end(); ++g)
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
int creID = (g->second.getCreature()->idNumber == 149) ? CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] : g->second.getCreature()->idNumber; //id of creature whose shots should be loaded
|
||||
if(g->second.getCreature()->isShooting() && CGI->creh->idToProjectile.find(creID) != CGI->creh->idToProjectile.end())
|
||||
{
|
||||
idToProjectile[g->second.getCreature()->idNumber] = CDefHandler::giveDef(CGI->creh->idToProjectile.find(creID)->second);
|
||||
int creID = (s->getCreature()->idNumber == 149) ? CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] : s->getCreature()->idNumber; //id of creature whose shots should be loaded
|
||||
if(s->getCreature()->isShooting() && vstd::contains(CGI->creh->idToProjectile, creID))
|
||||
{
|
||||
CDefHandler *&projectile = idToProjectile[s->getCreature()->idNumber];
|
||||
projectile = CDefHandler::giveDef(CGI->creh->idToProjectile[creID]);
|
||||
|
||||
if(idToProjectile[g->second.getCreature()->idNumber]->ourImages.size() > 2) //add symmetric images
|
||||
if(projectile->ourImages.size() > 2) //add symmetric images
|
||||
{
|
||||
for(int k = idToProjectile[g->second.getCreature()->idNumber]->ourImages.size()-2; k > 1; --k)
|
||||
for(int k = projectile->ourImages.size()-2; k > 1; --k)
|
||||
{
|
||||
Cimage ci;
|
||||
ci.bitmap = CSDL_Ext::rotate01(idToProjectile[g->second.getCreature()->idNumber]->ourImages[k].bitmap);
|
||||
ci.bitmap = CSDL_Ext::rotate01(projectile->ourImages[k].bitmap);
|
||||
ci.groupNumber = 0;
|
||||
ci.imName = std::string();
|
||||
idToProjectile[g->second.getCreature()->idNumber]->ourImages.push_back(ci);
|
||||
projectile->ourImages.push_back(ci);
|
||||
}
|
||||
}
|
||||
for(int s=0; s<idToProjectile[g->second.getCreature()->idNumber]->ourImages.size(); ++s) //alpha transforming
|
||||
for(int s=0; s<projectile->ourImages.size(); ++s) //alpha transforming
|
||||
{
|
||||
CSDL_Ext::alphaTransform(idToProjectile[g->second.getCreature()->idNumber]->ourImages[s].bitmap);
|
||||
CSDL_Ext::alphaTransform(projectile->ourImages[s].bitmap);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1467,7 +1467,7 @@ void CBattleInterface::deactivate()
|
||||
|
||||
void CBattleInterface::show(SDL_Surface * to)
|
||||
{
|
||||
std::map<int, CStack> stacks = curInt->cb->battleGetStacks(); //used in a few places
|
||||
std::vector<const CStack*> stacks = curInt->cb->battleGetStacks(); //used in a few places
|
||||
++animCount;
|
||||
if(!to) //"evaluating" to
|
||||
to = screen;
|
||||
@ -1558,20 +1558,20 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
////showing units //a lot of work...
|
||||
std::vector<int> stackAliveByHex[BFIELD_SIZE];
|
||||
//double loop because dead stacks should be printed first
|
||||
for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
if(creAnims.find(j->second.ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
||||
if(creAnims.find(s->ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
||||
continue;
|
||||
if(creAnims[j->second.ID]->getType() != 5 && j->second.position >= 0) //don't show turrets here
|
||||
stackAliveByHex[j->second.position].push_back(j->second.ID);
|
||||
if(creAnims[s->ID]->getType() != 5 && s->position >= 0) //don't show turrets here
|
||||
stackAliveByHex[s->position].push_back(s->ID);
|
||||
}
|
||||
std::vector<int> stackDeadByHex[BFIELD_SIZE];
|
||||
for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
if(creAnims.find(j->second.ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
||||
if(creAnims.find(s->ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
||||
continue;
|
||||
if(creAnims[j->second.ID]->getType() == 5)
|
||||
stackDeadByHex[j->second.position].push_back(j->second.ID);
|
||||
if(creAnims[s->ID]->getType() == 5)
|
||||
stackDeadByHex[s->position].push_back(s->ID);
|
||||
}
|
||||
|
||||
//handle animations
|
||||
@ -1607,11 +1607,11 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
activate();
|
||||
|
||||
//restoring good directions of stacks
|
||||
for(std::map<int, CStack>::const_iterator it = stacks.begin(); it != stacks.end(); ++it)
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
if(creDir[it->second.ID] != bool(it->second.attackerOwned) && it->second.alive())
|
||||
if(creDir[s->ID] != bool(s->attackerOwned) && s->alive())
|
||||
{
|
||||
addNewAnim(new CReverseAnim(this, it->second.ID, it->second.position, false));
|
||||
addNewAnim(new CReverseAnim(this, s->ID, s->position, false));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1631,17 +1631,18 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
creAnims[stackDeadByHex[b][v]]->nextFrame(to, creAnims[stackDeadByHex[b][v]]->pos.x, creAnims[stackDeadByHex[b][v]]->pos.y, creDir[stackDeadByHex[b][v]], animCount, false); //increment always when moving, never if stack died
|
||||
}
|
||||
}
|
||||
std::vector<int> flyingStacks; //flying stacks should be displayed later, over other stacks and obstacles
|
||||
std::vector<const CStack *> flyingStacks; //flying stacks should be displayed later, over other stacks and obstacles
|
||||
for(int b=0; b<BFIELD_SIZE; ++b) //showing alive stacks
|
||||
{
|
||||
for(size_t v=0; v<stackAliveByHex[b].size(); ++v)
|
||||
{
|
||||
int curStackID = stackAliveByHex[b][v];
|
||||
const CStack *s = LOCPLINT->cb->battleGetStackByID(curStackID, false); //TODO: dlaczego brak false psuje?
|
||||
|
||||
if(!stacks[curStackID].hasBonusOfType(Bonus::FLYING) || creAnims[curStackID]->getType() != 0)
|
||||
showAliveStack(curStackID, stacks, to);
|
||||
if(!s->hasBonusOfType(Bonus::FLYING) || creAnims[curStackID]->getType() != 0)
|
||||
showAliveStack(s, to);
|
||||
else
|
||||
flyingStacks.push_back(curStackID);
|
||||
flyingStacks.push_back(s);
|
||||
}
|
||||
|
||||
//showing obstacles
|
||||
@ -1663,7 +1664,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
}
|
||||
|
||||
for(int b=0; b<flyingStacks.size(); ++b) //showing flyign stacks
|
||||
showAliveStack(flyingStacks[b], stacks, to);
|
||||
showAliveStack(flyingStacks[b], to);
|
||||
|
||||
//units shown
|
||||
|
||||
@ -2279,23 +2280,23 @@ void CBattleInterface::stackAttacking(int ID, int dest, int attackedID)
|
||||
void CBattleInterface::newRoundFirst( int round )
|
||||
{
|
||||
//handle regeneration
|
||||
std::map<int, CStack> stacks = curInt->cb->battleGetStacks();
|
||||
for(std::map<int, CStack>::const_iterator it = stacks.begin(); it != stacks.end(); ++it)
|
||||
std::vector<const CStack*> stacks = curInt->cb->battleGetStacks();
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
//don't show animation when no HP is regenerated
|
||||
if (it->second.firstHPleft == it->second.MaxHealth())
|
||||
if (s->firstHPleft == s->MaxHealth())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( it->second.hasBonusOfType(Bonus::HP_REGENERATION) && it->second.alive() )
|
||||
displayEffect(74, it->second.position);
|
||||
if( s->hasBonusOfType(Bonus::HP_REGENERATION) && s->alive() )
|
||||
displayEffect(74, s->position);
|
||||
|
||||
if( it->second.hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0) && it->second.alive() )
|
||||
displayEffect(4, it->second.position);
|
||||
if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 0) && s->alive() )
|
||||
displayEffect(4, s->position);
|
||||
|
||||
if( it->second.hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1) && it->second.alive() )
|
||||
displayEffect(74, it->second.position);
|
||||
if( s->hasBonusOfType(Bonus::FULL_HP_REGENERATION, 1) && s->alive() )
|
||||
displayEffect(74, s->position);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2967,12 +2968,12 @@ void CBattleInterface::endCastingSpell()
|
||||
CGI->curh->changeGraphic(1, 6);
|
||||
}
|
||||
|
||||
void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to)
|
||||
void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
|
||||
{
|
||||
int ID = stack->ID;
|
||||
if(creAnims.find(ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
||||
return;
|
||||
|
||||
const CStack &curStack = stacks.find(ID)->second;
|
||||
int animType = creAnims[ID]->getType();
|
||||
|
||||
int affectingSpeed = curInt->sysOpts.animSpeed;
|
||||
@ -3006,21 +3007,21 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
|
||||
creAnims[ID]->nextFrame(to, creAnims[ID]->pos.x, creAnims[ID]->pos.y, creDir[ID], animCount, incrementFrame, ID==activeStack, ID==mouseHoveredStack); //increment always when moving, never if stack died
|
||||
|
||||
//printing amount
|
||||
if(curStack.count > 0 //don't print if stack is not alive
|
||||
if(stack->count > 0 //don't print if stack is not alive
|
||||
&& (!curInt->curAction
|
||||
|| (curInt->curAction->stackNumber != ID //don't print if stack is currently taking an action
|
||||
&& (curInt->curAction->actionType != 6 || curStack.position != curInt->curAction->additionalInfo) //nor if it's an object of attack
|
||||
&& (curInt->curAction->destinationTile != curStack.position) //nor if it's on destination tile for current action
|
||||
&& (curInt->curAction->actionType != 6 || stack->position != curInt->curAction->additionalInfo) //nor if it's an object of attack
|
||||
&& (curInt->curAction->destinationTile != stack->position) //nor if it's on destination tile for current action
|
||||
)
|
||||
)
|
||||
&& !curStack.hasBonusOfType(Bonus::SIEGE_WEAPON) //and not a war machine...
|
||||
&& !stack->hasBonusOfType(Bonus::SIEGE_WEAPON) //and not a war machine...
|
||||
)
|
||||
{
|
||||
int xAdd = curStack.attackerOwned ? 220 : 202;
|
||||
int xAdd = stack->attackerOwned ? 220 : 202;
|
||||
|
||||
//blitting amoutn background box
|
||||
SDL_Surface *amountBG = NULL;
|
||||
BonusList spellEffects = curStack.getSpellBonuses();
|
||||
BonusList spellEffects = stack->getSpellBonuses();
|
||||
if(!spellEffects.size())
|
||||
{
|
||||
amountBG = amountNormal;
|
||||
@ -3028,7 +3029,7 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
|
||||
else
|
||||
{
|
||||
int pos=0; //determining total positiveness of effects
|
||||
std::vector<si32> spellIds = curStack.activeSpells();
|
||||
std::vector<si32> spellIds = stack->activeSpells();
|
||||
for(std::vector<si32>::const_iterator it = spellIds.begin(); it != spellIds.end(); it++)
|
||||
{
|
||||
pos += CGI->spellh->spells[ *it ].positiveness;
|
||||
@ -3049,7 +3050,7 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
|
||||
SDL_BlitSurface(amountBG, NULL, to, &genRect(amountNormal->h, amountNormal->w, creAnims[ID]->pos.x + xAdd, creAnims[ID]->pos.y + 260));
|
||||
//blitting amount
|
||||
CSDL_Ext::printAtMiddle(
|
||||
makeNumberShort(curStack.count),
|
||||
makeNumberShort(stack->count),
|
||||
creAnims[ID]->pos.x + xAdd + 15,
|
||||
creAnims[ID]->pos.y + 260 + 5,
|
||||
FONT_TINY,
|
||||
@ -3059,7 +3060,7 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleInterface::showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks)
|
||||
void CBattleInterface::showPieceOfWall(SDL_Surface * to, int hex, const std::vector<const CStack*> & stacks)
|
||||
{
|
||||
if(!siegeH)
|
||||
return;
|
||||
@ -3094,18 +3095,20 @@ void CBattleInterface::showPieceOfWall(SDL_Surface * to, int hex, const std::map
|
||||
|
||||
if(posToSeek != -1)
|
||||
{
|
||||
int ID = -1;
|
||||
for(std::map<int, CStack>::const_iterator it = stacks.begin(); it != stacks.end(); ++it)
|
||||
const CStack *turret = NULL;
|
||||
|
||||
BOOST_FOREACH(const CStack *s, stacks)
|
||||
{
|
||||
if(it->second.position == posToSeek)
|
||||
if(s->position == posToSeek)
|
||||
{
|
||||
ID = it->second.ID;
|
||||
turret = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ID != -1)
|
||||
|
||||
if(turret)
|
||||
{
|
||||
showAliveStack(ID, stacks, to);
|
||||
showAliveStack(turret, to);
|
||||
//blitting creature cover
|
||||
switch(posToSeek)
|
||||
{
|
||||
@ -3621,7 +3624,7 @@ void CBattleHex::clickRight(tribool down, bool previousState)
|
||||
if(!myst.alive()) return;
|
||||
if(down)
|
||||
{
|
||||
GH.pushInt(new CCreInfoWindow(*myst.base));
|
||||
GH.pushInt(new CCreInfoWindow(myst));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3746,7 +3749,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
|
||||
{
|
||||
int bestMonsterID = -1;
|
||||
int bestPower = 0;
|
||||
for(TSlots::const_iterator it = owner->army1.Slots().begin(); it!=owner->army1.Slots().end(); ++it)
|
||||
for(TSlots::const_iterator it = owner->army1->Slots().begin(); it!=owner->army1->Slots().end(); ++it)
|
||||
{
|
||||
if( it->second->type->AIValue > bestPower)
|
||||
{
|
||||
@ -3768,7 +3771,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
|
||||
{
|
||||
int bestMonsterID = -1;
|
||||
int bestPower = 0;
|
||||
for(TSlots::const_iterator it = owner->army2.Slots().begin(); it!=owner->army2.Slots().end(); ++it)
|
||||
for(TSlots::const_iterator it = owner->army2->Slots().begin(); it!=owner->army2->Slots().end(); ++it)
|
||||
{
|
||||
if( it->second->type->AIValue > bestPower)
|
||||
{
|
||||
|
@ -384,7 +384,7 @@ private:
|
||||
CBattleConsole * console;
|
||||
CBattleHero * attackingHero, * defendingHero; //fighting heroes
|
||||
CStackQueue *queue;
|
||||
CCreatureSet army1, army2; //copy of initial armies (for result window)
|
||||
const CCreatureSet *army1, *army2; //copy of initial armies (for result window)
|
||||
const CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
|
||||
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
|
||||
std::map< int, CDefHandler * > idToProjectile; //projectiles of creatures (creatureID, defhandler)
|
||||
@ -407,8 +407,8 @@ private:
|
||||
BattleAction * spellToCast; //spell for which player is choosing destination
|
||||
void endCastingSpell(); //ends casting spell (eg. when spell has been cast or canceled)
|
||||
|
||||
void showAliveStack(int ID, const std::map<int, CStack> & stacks, SDL_Surface * to); //helper function for function show
|
||||
void showPieceOfWall(SDL_Surface * to, int hex, const std::map<int, CStack> & stacks); //helper function for show
|
||||
void showAliveStack(const CStack *stack, SDL_Surface * to); //helper function for function show
|
||||
void showPieceOfWall(SDL_Surface * to, int hex, const std::vector<const CStack*> & stacks); //helper function for show
|
||||
void redrawBackgroundWithHexes(int activeStack);
|
||||
void printConsoleAttacked(int ID, int dmg, int killed, int IDby);
|
||||
|
||||
|
@ -2087,7 +2087,7 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
|
||||
: type(Type), dsm(Dsm), dismiss(0), upgrade(0), ok(0)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
init(st.type, &st, st.count);
|
||||
init(st.type, &st, dynamic_cast<const CGHeroInstance*>(st.armyObj), st.count);
|
||||
|
||||
//print abilities text - if r-click popup
|
||||
if(type)
|
||||
@ -2132,31 +2132,25 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
|
||||
}
|
||||
ok = new AdventureMapButton("",CGI->generaltexth->zelp[445].second,boost::bind(&CCreInfoWindow::close,this),216,237,"IOKAY.DEF",SDLK_RETURN);
|
||||
}
|
||||
else
|
||||
{
|
||||
printAtWB(c->abilityText,17,231,FONT_SMALL,35,zwykly,*bitmap);
|
||||
}
|
||||
|
||||
//if we are displying window fo r stack in battle, there are several more things that we need to display
|
||||
if(const CStack *battleStack = dynamic_cast<const CStack*>(&st))
|
||||
{
|
||||
//spell effects
|
||||
int printed=0; //how many effect pics have been printed
|
||||
std::vector<si32> spells = battleStack->activeSpells();
|
||||
BOOST_FOREACH(si32 effect, spells)
|
||||
{
|
||||
blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 127 + 52 * printed, 186, *bitmap);
|
||||
++printed;
|
||||
if(printed >= 3) //we can fit only 3 effects
|
||||
break;
|
||||
}
|
||||
//print current health
|
||||
printLine(5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount)
|
||||
: type(Type), dismiss(0), upgrade(0), ok(0)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
const CCreature *cre = CGI->creh->creatures[Cid];
|
||||
init(cre, NULL, NULL, creatureCount);
|
||||
}
|
||||
|
||||
CCreInfoWindow::CCreInfoWindow(const CStack &st, int Type /*= 0*/)
|
||||
: type(Type), dismiss(0), upgrade(0), ok(0)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
init(st.getCreature(), &st, st.getMyHero(), st.count);
|
||||
}
|
||||
|
||||
void CCreInfoWindow::printLine(int nr, const std::string &text, int baseVal, int val/*=-1*/, bool range/*=false*/)
|
||||
{
|
||||
printAt(text, 155, 48 + nr*19, FONT_SMALL, zwykly, *bitmap);
|
||||
@ -2172,15 +2166,11 @@ void CCreInfoWindow::printLine(int nr, const std::string &text, int baseVal, int
|
||||
printTo(hlp, 276, 61 + nr*19, FONT_SMALL, zwykly, *bitmap);
|
||||
}
|
||||
|
||||
void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int creatureCount)
|
||||
//void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int creatureCount)
|
||||
void CCreInfoWindow::init(const CCreature *cre, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner, int creatureCount)
|
||||
{
|
||||
const CBonusSystemNode *finalNode = NULL;
|
||||
if(stack)
|
||||
finalNode = stack;
|
||||
else
|
||||
finalNode = cre;
|
||||
|
||||
c = cre;
|
||||
if(!stackNode) stackNode = c;
|
||||
|
||||
bitmap = new CPicture("CRSTKPU.bmp");
|
||||
bitmap->colorizeAndConvert(LOCPLINT->playerID);
|
||||
@ -2190,52 +2180,67 @@ void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int
|
||||
|
||||
count = boost::lexical_cast<std::string>(creatureCount);
|
||||
|
||||
|
||||
printAtMiddle(c->namePl,149,30,FONT_SMALL,tytulowy,*bitmap); //creature name
|
||||
|
||||
printLine(0, CGI->generaltexth->primarySkillNames[0], cre->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), finalNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK));
|
||||
printLine(1, CGI->generaltexth->primarySkillNames[1], cre->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), finalNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE));
|
||||
printLine(0, CGI->generaltexth->primarySkillNames[0], cre->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK));
|
||||
printLine(1, CGI->generaltexth->primarySkillNames[1], cre->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE));
|
||||
if(c->shots)
|
||||
printLine(2, CGI->generaltexth->allTexts[198], c->shots);
|
||||
|
||||
//TODO
|
||||
int dmgMultiply = 1;
|
||||
if(stack && stack->hasBonusOfType(Bonus::SIEGE_WEAPON))
|
||||
dmgMultiply += stack->armyObj->Attack();
|
||||
if(heroOwner && stackNode->hasBonusOfType(Bonus::SIEGE_WEAPON))
|
||||
dmgMultiply += heroOwner->Attack();
|
||||
|
||||
printLine(3, CGI->generaltexth->allTexts[199], finalNode->getMinDamage() * dmgMultiply, finalNode->getMaxDamage() * dmgMultiply, true);
|
||||
printLine(4, CGI->generaltexth->allTexts[388], cre->valOfBonuses(Bonus::STACK_HEALTH), finalNode->valOfBonuses(Bonus::STACK_HEALTH));
|
||||
printLine(6, CGI->generaltexth->zelp[441].first, cre->valOfBonuses(Bonus::STACKS_SPEED), finalNode->valOfBonuses(Bonus::STACKS_SPEED));
|
||||
printLine(3, CGI->generaltexth->allTexts[199], stackNode->getMinDamage() * dmgMultiply, stackNode->getMaxDamage() * dmgMultiply, true);
|
||||
printLine(4, CGI->generaltexth->allTexts[388], cre->valOfBonuses(Bonus::STACK_HEALTH), stackNode->valOfBonuses(Bonus::STACK_HEALTH));
|
||||
printLine(6, CGI->generaltexth->zelp[441].first, cre->valOfBonuses(Bonus::STACKS_SPEED), stackNode->valOfBonuses(Bonus::STACKS_SPEED));
|
||||
|
||||
//setting morale
|
||||
morale = new MoraleLuckBox(true);
|
||||
morale->pos = genRect(42, 42, pos.x + 24, pos.y + 189);
|
||||
morale->set(stack);
|
||||
morale->set(stackNode);
|
||||
//setting luck
|
||||
luck = new MoraleLuckBox(false);
|
||||
luck->pos = genRect(42, 42, pos.x + 77, pos.y + 189);
|
||||
luck->set(stack);
|
||||
luck->set(stackNode);
|
||||
|
||||
//luck and morale
|
||||
int luck = 3, morale = 3;
|
||||
if(stack)
|
||||
if(stackNode)
|
||||
{
|
||||
//add modifiers
|
||||
luck += stack->LuckVal();
|
||||
morale += stack->MoraleVal();
|
||||
luck += stackNode->LuckVal();
|
||||
morale += stackNode->MoraleVal();
|
||||
}
|
||||
|
||||
blitAt(graphics->morale42->ourImages[morale].bitmap, 24, 189, *bitmap);
|
||||
blitAt(graphics->luck42->ourImages[luck].bitmap, 77, 189, *bitmap);
|
||||
|
||||
|
||||
if(!type)
|
||||
{
|
||||
printAtWB(c->abilityText,17,231,FONT_SMALL,35,zwykly,*bitmap);
|
||||
}
|
||||
|
||||
//if we are displying window fo r stack in battle, there are several more things that we need to display
|
||||
if(const CStack *battleStack = dynamic_cast<const CStack*>(stackNode))
|
||||
{
|
||||
//spell effects
|
||||
int printed=0; //how many effect pics have been printed
|
||||
std::vector<si32> spells = battleStack->activeSpells();
|
||||
BOOST_FOREACH(si32 effect, spells)
|
||||
{
|
||||
blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 127 + 52 * printed, 186, *bitmap);
|
||||
++printed;
|
||||
if(printed >= 3) //we can fit only 3 effects
|
||||
break;
|
||||
}
|
||||
//print current health
|
||||
printLine(5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
|
||||
}
|
||||
}
|
||||
|
||||
CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount)
|
||||
: type(Type), dismiss(0), upgrade(0), ok(0)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
const CCreature *cre = CGI->creh->creatures[Cid];
|
||||
init(cre, NULL, creatureCount);
|
||||
}
|
||||
|
||||
CCreInfoWindow::~CCreInfoWindow()
|
||||
{
|
||||
|
@ -25,6 +25,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
class CStackBasicDescriptor;
|
||||
class CBonusSystemNode;
|
||||
class CArtifact;
|
||||
class CDefEssential;
|
||||
@ -879,8 +880,9 @@ public:
|
||||
|
||||
AdventureMapButton *dismiss, *upgrade, *ok;
|
||||
CCreInfoWindow(const CStackInstance &st, int Type = 0, boost::function<void()> Upg = 0, boost::function<void()> Dsm = 0, UpgradeInfo *ui = NULL); //c-tor
|
||||
CCreInfoWindow(const CStack &st, int Type = 0); //c-tor
|
||||
CCreInfoWindow(int Cid, int Type, int creatureCount); //c-tor
|
||||
void init(const CCreature *cre, const CStackInstance *stack, int creatureCount);
|
||||
void init(const CCreature *cre, const CBonusSystemNode *stackNode, const CGHeroInstance *heroOwner, int creatureCount);
|
||||
void printLine(int nr, const std::string &text, int baseVal, int val=-1, bool range=false);
|
||||
~CCreInfoWindow(); //d-tor
|
||||
void activate();
|
||||
@ -892,10 +894,21 @@ public:
|
||||
void show(SDL_Surface * to);
|
||||
};
|
||||
|
||||
namespace Arts
|
||||
{
|
||||
enum EPos
|
||||
{
|
||||
PRE_FIRST = -1,
|
||||
HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4,
|
||||
MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5,
|
||||
AFTER_LAST
|
||||
};
|
||||
}
|
||||
|
||||
class CArtPlace: public LRClickableAreaWTextComp
|
||||
{
|
||||
public:
|
||||
ui16 slotID; //0 head 1 shoulders 2 neck 3 right hand 4 left hand 5 torso 6 right ring 7 left ring 8 feet 9 misc. slot 1 10 misc. slot 2 11 misc. slot 3 12 misc. slot 4 13 ballista (war machine 1) 14 ammo cart (war machine 2) 15 first aid tent (war machine 3) 16 catapult 17 spell book 18 misc. slot 5 19+ backpack slots
|
||||
int slotID; //0 head 1 shoulders 2 neck 3 right hand 4 left hand 5 torso 6 right ring 7 left ring 8 feet 9 misc. slot 1 10 misc. slot 2 11 misc. slot 3 12 misc. slot 4 13 ballista (war machine 1) 14 ammo cart (war machine 2) 15 first aid tent (war machine 3) 16 catapult 17 spell book 18 misc. slot 5 19+ backpack slots
|
||||
|
||||
bool marked;
|
||||
bool selectedNo;
|
||||
@ -915,6 +928,7 @@ public:
|
||||
~CArtPlace(); //d-tor
|
||||
};
|
||||
|
||||
|
||||
class CArtifactsOfHero : public CIntObject
|
||||
{
|
||||
CGHeroInstance * curHero; //local copy of hero on which we operate
|
||||
|
@ -53,17 +53,17 @@ SDL_Surface * Graphics::drawHeroInfoWin(const InfoAboutHero &curh)
|
||||
blitAt(graphics->portraitLarge[curh.portrait],11,12,ret); //portrait
|
||||
|
||||
//army
|
||||
for (TSlots::const_iterator i = curh.army.Slots().begin(); i!=curh.army.Slots().end();i++)
|
||||
for (ArmyDescriptor::const_iterator i = curh.army.begin(); i!=curh.army.end();i++)
|
||||
{
|
||||
blitAt(graphics->smallImgs[(*i).second->type->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||
blitAt(graphics->smallImgs[i->second.type->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||
if(curh.details)
|
||||
{
|
||||
SDL_itoa((*i).second->count,buf,10);
|
||||
SDL_itoa((*i).second.count,buf,10);
|
||||
printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
printAtMiddle(VLC->generaltexth->arraytxt[174 + 3*(i->second->count-1)],slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
|
||||
printAtMiddle(VLC->generaltexth->arraytxt[174 + 3*(i->second.count-1)],slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,15 +110,15 @@ SDL_Surface * Graphics::drawTownInfoWin( const InfoAboutTown & curh )
|
||||
int pom = curh.fortLevel - 1; if(pom<0) pom = 3; //fort pic id
|
||||
blitAt(forts->ourImages[pom].bitmap,115,42,ret); //fort
|
||||
|
||||
for (TSlots::const_iterator i=curh.army.Slots().begin(); i!=curh.army.Slots().end();i++)
|
||||
for (ArmyDescriptor::const_iterator i=curh.army.begin(); i!=curh.army.end();i++)
|
||||
{
|
||||
//if(!i->second.second)
|
||||
// continue;
|
||||
blitAt(graphics->smallImgs[(*i).second->type->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||
blitAt(graphics->smallImgs[(*i).second.type->idNumber],slotsPos[(*i).first].first+1,slotsPos[(*i).first].second+1,ret);
|
||||
if(curh.details)
|
||||
{
|
||||
// Show exact creature amount.
|
||||
SDL_itoa((*i).second->count,buf,10);
|
||||
SDL_itoa((*i).second.count,buf,10);
|
||||
printAtMiddle(buf,slotsPos[(*i).first].first+17,slotsPos[(*i).first].second+41,FONT_TINY,zwykly,ret);
|
||||
}
|
||||
else
|
||||
|
@ -308,12 +308,12 @@ void TryMoveHero::applyCl( CClient *cl )
|
||||
}
|
||||
}
|
||||
|
||||
void SetGarrisons::applyCl( CClient *cl )
|
||||
{
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
if(vstd::contains(cl->playerint,cl->getOwner(i->first)))
|
||||
cl->playerint[cl->getOwner(i->first)]->garrisonChanged(cl->getObj(i->first));
|
||||
}
|
||||
// void SetGarrisons::applyCl( CClient *cl )
|
||||
// {
|
||||
// for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
// if(vstd::contains(cl->playerint,cl->getOwner(i->first)))
|
||||
// cl->playerint[cl->getOwner(i->first)]->garrisonChanged(cl->getObj(i->first));
|
||||
// }
|
||||
|
||||
void NewStructures::applyCl( CClient *cl )
|
||||
{
|
||||
|
@ -531,13 +531,12 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
|
||||
//trimming creatures
|
||||
BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
|
||||
{
|
||||
CCreatureSet army = cgh->getArmy();
|
||||
for (TSlots::iterator j = army.slots.begin(); j != army.slots.end(); j++)
|
||||
for (TSlots::const_iterator j = cgh->Slots().begin(); j != cgh->Slots().end(); j++)
|
||||
{
|
||||
if (! (travelOptions.monstersKeptByHero[j->first / 8] & (1 << (j->first%8)) ))
|
||||
if (!(travelOptions.monstersKeptByHero[j->first / 8] & (1 << (j->first%8)) ))
|
||||
{
|
||||
army.slots.erase(j);
|
||||
j = army.slots.begin();
|
||||
cgh->eraseStack(j->first);
|
||||
j = cgh->Slots().begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -777,6 +777,7 @@ const CArtifact * CGHeroInstance::getArt(int pos) const
|
||||
CGHeroInstance::CGHeroInstance()
|
||||
: IBoatGenerator(this)
|
||||
{
|
||||
nodeType = HERO;
|
||||
ID = HEROI_TYPE;
|
||||
tacticFormationEnabled = inTownGarrison = false;
|
||||
mana = movement = portrait = level = -1;
|
||||
@ -3449,28 +3450,27 @@ void CGTeleport::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if (!h->hasBonusOfType(Bonus::WHIRLPOOL_PROTECTION))
|
||||
{
|
||||
CCreatureSet army = h->getArmy();
|
||||
if (army.Slots().size() > 1 || army.Slots().begin()->second->count > 1)
|
||||
if (h->Slots().size() > 1 || h->Slots().begin()->second->count > 1)
|
||||
{ //we can't remove last unit
|
||||
int targetstack = army.Slots().begin()->first; //slot numbers may vary
|
||||
for(TSlots::const_reverse_iterator i = army.Slots().rbegin(); i != army.Slots().rend(); i++)
|
||||
TSlot targetstack = h->Slots().begin()->first; //slot numbers may vary
|
||||
for(TSlots::const_reverse_iterator i = h->Slots().rbegin(); i != h->Slots().rend(); i++)
|
||||
{
|
||||
if (army.getPower(targetstack) > army.getPower(i->first))
|
||||
if (h->getPower(targetstack) > h->getPower(i->first))
|
||||
{
|
||||
targetstack = (i->first);
|
||||
}
|
||||
}
|
||||
std::vector<CStackBasicDescriptor> cresToTake;
|
||||
cresToTake.push_back(CStackBasicDescriptor(army.getStack(targetstack)));
|
||||
cresToTake[0].count * 0.5;
|
||||
amax (cresToTake[0].count, 1);
|
||||
|
||||
TQuantity countToTake = h->getStackCount(targetstack) * 0.5;
|
||||
amax(countToTake, 1);
|
||||
|
||||
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.addTxt (MetaString::ADVOB_TXT, 168);
|
||||
iw.components.push_back (Component(cresToTake[0]));
|
||||
iw.components.push_back (Component(CStackBasicDescriptor(h->getCreature(targetstack), countToTake)));
|
||||
cb->showInfoDialog(&iw);
|
||||
cb->takeCreatures (h->id, cresToTake);
|
||||
cb->changeStackCount(StackLocation(h, targetstack), -countToTake);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4380,7 +4380,7 @@ int CGSeerHut::checkDirection() const
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
|
||||
void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const
|
||||
{
|
||||
if (accept)
|
||||
{
|
||||
@ -4393,7 +4393,7 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
|
||||
}
|
||||
break;
|
||||
case CQuest::MISSION_ARMY:
|
||||
cb->takeCreatures (h->id, m6creatures);
|
||||
cb->takeCreatures(h->id, m6creatures);
|
||||
break;
|
||||
case CQuest::MISSION_RESOURCES:
|
||||
for (int i = 0; i < 7; ++i)
|
||||
@ -4404,7 +4404,7 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
|
||||
default:
|
||||
break;
|
||||
}
|
||||
cb->setObjProperty (id,11,0); //no more mission avaliable
|
||||
cb->setObjProperty(id,11,0); //no more mission avaliable
|
||||
completeQuest(h); //make sure to remove QuestQuard at the very end
|
||||
}
|
||||
}
|
||||
@ -4453,11 +4453,11 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
|
||||
}
|
||||
break;
|
||||
case 10:// creature
|
||||
{
|
||||
CCreatureSet creatures;
|
||||
creatures.setCreature (0, rID, rVal);
|
||||
cb->giveCreatures (id, h, creatures,false);
|
||||
}
|
||||
{
|
||||
CCreatureSet creatures;
|
||||
creatures.setCreature(0, rID, rVal);
|
||||
cb->giveCreatures (id, h, creatures,false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -295,6 +295,11 @@ CCreatureSet::CCreatureSet()
|
||||
formation = false;
|
||||
}
|
||||
|
||||
CCreatureSet::CCreatureSet(const CCreatureSet&)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
CCreatureSet::~CCreatureSet()
|
||||
{
|
||||
clear();
|
||||
@ -322,7 +327,11 @@ CStackInstance * CCreatureSet::detachStack(TSlot slot)
|
||||
CStackInstance *ret = slots[slot];
|
||||
|
||||
if(CArmedInstance *armedObj = castToArmyObj())
|
||||
ret->detachFrom(armedObj);
|
||||
{
|
||||
ret->setArmyObj(NULL); //detaches from current armyobj
|
||||
}
|
||||
|
||||
assert(!ret->armyObj); //we failed detaching?
|
||||
|
||||
slots.erase(slot);
|
||||
return ret;
|
||||
@ -353,6 +362,12 @@ bool CCreatureSet::hasStackAtSlot(TSlot slot) const
|
||||
return vstd::contains(slots, slot);
|
||||
}
|
||||
|
||||
CCreatureSet & CCreatureSet::operator=(const CCreatureSet&cs)
|
||||
{
|
||||
assert(0);
|
||||
return cs;
|
||||
}
|
||||
|
||||
CStackInstance::CStackInstance()
|
||||
: armyObj(_armyObj)
|
||||
{
|
||||
@ -410,10 +425,9 @@ void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj)
|
||||
if(_armyObj)
|
||||
detachFrom(const_cast<CArmedInstance*>(_armyObj));
|
||||
|
||||
_armyObj = ArmyObj;
|
||||
if(ArmyObj)
|
||||
{
|
||||
_armyObj = ArmyObj;
|
||||
|
||||
attachTo(const_cast<CArmedInstance*>(_armyObj));
|
||||
}
|
||||
}
|
||||
@ -446,6 +460,11 @@ bool CStackInstance::valid(bool allowUnrandomized) const
|
||||
return allowUnrandomized;
|
||||
}
|
||||
|
||||
CStackInstance::~CStackInstance()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::CStackBasicDescriptor()
|
||||
{
|
||||
type = NULL;
|
||||
@ -457,6 +476,11 @@ CStackBasicDescriptor::CStackBasicDescriptor(TCreature id, TQuantity Count)
|
||||
{
|
||||
}
|
||||
|
||||
CStackBasicDescriptor::CStackBasicDescriptor(const CCreature *c, TQuantity Count)
|
||||
: type(c), count(Count)
|
||||
{
|
||||
}
|
||||
|
||||
DLL_EXPORT std::ostream & operator<<(std::ostream & str, const CStackInstance & sth)
|
||||
{
|
||||
if(!sth.valid(true))
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
|
||||
CStackBasicDescriptor();
|
||||
CStackBasicDescriptor(TCreature id, TQuantity Count);
|
||||
CStackBasicDescriptor(const CCreature *c, TQuantity Count);
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -57,6 +58,8 @@ public:
|
||||
CStackInstance();
|
||||
CStackInstance(TCreature id, TQuantity count);
|
||||
CStackInstance(const CCreature *cre, TQuantity count);
|
||||
~CStackInstance();
|
||||
|
||||
void setType(int creID);
|
||||
void setType(const CCreature *c);
|
||||
void setArmyObj(const CArmedInstance *ArmyObj);
|
||||
@ -71,6 +74,8 @@ typedef std::map<TSlot, CStackInstance*> TSlots;
|
||||
|
||||
class DLL_EXPORT CCreatureSet //seven combined creatures
|
||||
{
|
||||
CCreatureSet(const CCreatureSet&);;
|
||||
CCreatureSet &operator=(const CCreatureSet&);
|
||||
public:
|
||||
TSlots slots; //slots[slot_id]->> pair(creature_id,creature_quantity)
|
||||
ui8 formation; //false - wide, true - tight
|
||||
|
@ -708,7 +708,7 @@ CStack::CStack()
|
||||
}
|
||||
|
||||
CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S)
|
||||
: ID(I), owner(O), slot(S), attackerOwned(AO), position(-1), counterAttacks(1)
|
||||
: base(NULL), ID(I), owner(O), slot(S), attackerOwned(AO), position(-1), counterAttacks(1)
|
||||
{
|
||||
type = stack->type;
|
||||
count = baseAmount = stack->count;
|
||||
@ -1021,10 +1021,23 @@ std::vector<si32> CStack::activeSpells() const
|
||||
|
||||
CStack::~CStack()
|
||||
{
|
||||
detachFromAll();
|
||||
if(vstd::contains(state, SUMMONED))
|
||||
delNull(base);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CStack::getMyHero() const
|
||||
{
|
||||
if(base)
|
||||
return dynamic_cast<const CGHeroInstance *>(base->armyObj);
|
||||
else //we are attached directly?
|
||||
BOOST_FOREACH(const CBonusSystemNode *n, parents)
|
||||
if(n->nodeType == HERO)
|
||||
dynamic_cast<const CGHeroInstance *>(n);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, std::map<ui32,CGHeroInstance *> &available, const CHeroClass *bannedClass /*= NULL*/) const
|
||||
{
|
||||
CGHeroInstance *ret = NULL;
|
||||
@ -3482,14 +3495,18 @@ int BattleInfo::calculateSpellDuration( const CSpell * spell, const CGHeroInstan
|
||||
|
||||
CStack * BattleInfo::generateNewStack(const CStackInstance &base, int stackID, bool attackerOwned, int slot, int position) const
|
||||
{
|
||||
CStack * ret = new CStack(&base, attackerOwned ? side1 : side2, stackID, attackerOwned, slot);
|
||||
int owner = attackerOwned ? side1 : side2;
|
||||
assert(owner >= PLAYER_LIMIT || base.armyObj && base.armyObj->tempOwner == owner);
|
||||
|
||||
CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
|
||||
ret->position = position;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CStack * BattleInfo::generateNewStack(const CStackBasicDescriptor &base, int stackID, bool attackerOwned, int slot, int position) const
|
||||
{
|
||||
CStack * ret = new CStack(&base, attackerOwned ? side1 : side2, stackID, attackerOwned, slot);
|
||||
int owner = attackerOwned ? side1 : side2;
|
||||
CStack * ret = new CStack(&base, owner, stackID, attackerOwned, slot);
|
||||
ret->position = position;
|
||||
return ret;
|
||||
}
|
||||
@ -4578,7 +4595,7 @@ void InfoAboutHero::initFromHero( const CGHeroInstance *h, bool detailed )
|
||||
hclass = h->type->heroClass;
|
||||
name = h->name;
|
||||
portrait = h->portrait;
|
||||
army = h->getArmy();
|
||||
army = ArmyDescriptor(h, detailed);
|
||||
|
||||
if(detailed)
|
||||
{
|
||||
@ -4594,14 +4611,6 @@ void InfoAboutHero::initFromHero( const CGHeroInstance *h, bool detailed )
|
||||
details->primskills[i] = h->getPrimSkillLevel(i);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//hide info about hero stacks counts using descriptives names ids
|
||||
for(TSlots::const_iterator i = army.Slots().begin(); i != army.Slots().end(); ++i)
|
||||
{
|
||||
army.setStackCount(i->first, i->second->getQuantityID()+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InfoAboutHero::assign( const InfoAboutHero & iah )
|
||||
@ -4621,3 +4630,19 @@ InfoAboutHero & InfoAboutHero::operator=( const InfoAboutHero & iah )
|
||||
}
|
||||
|
||||
|
||||
|
||||
ArmyDescriptor::ArmyDescriptor(const CArmedInstance *army, bool detailed)
|
||||
{
|
||||
for(TSlots::const_iterator i = army->Slots().begin(); i != army->Slots().end(); i++)
|
||||
{
|
||||
if(detailed)
|
||||
(*this)[i->first] = *i->second;
|
||||
else
|
||||
(*this)[i->first] = CStackBasicDescriptor(i->second->type, i->second->getQuantityID());
|
||||
}
|
||||
}
|
||||
|
||||
ArmyDescriptor::ArmyDescriptor()
|
||||
{
|
||||
|
||||
}
|
@ -68,6 +68,13 @@ namespace boost
|
||||
class shared_mutex;
|
||||
}
|
||||
|
||||
//numbers of creatures are exact numbers if detailed else they are quantity ids (0 - a few, 1 - several and so on; additionaly -1 - unknown)
|
||||
struct DLL_EXPORT ArmyDescriptor : public std::map<TSlot, CStackBasicDescriptor>
|
||||
{
|
||||
ArmyDescriptor(const CArmedInstance *army, bool detailed); //not detailed -> quantity ids as count
|
||||
ArmyDescriptor();
|
||||
};
|
||||
|
||||
struct DLL_EXPORT InfoAboutHero
|
||||
{
|
||||
private:
|
||||
@ -83,7 +90,8 @@ public:
|
||||
const CHeroClass *hclass;
|
||||
std::string name;
|
||||
int portrait;
|
||||
CCreatureSet army; //numbers of creatures are exact numbers if detailed else they are quantity ids (0 - a few, 1 - several and so on)
|
||||
|
||||
ArmyDescriptor army;
|
||||
|
||||
InfoAboutHero();
|
||||
InfoAboutHero(const InfoAboutHero & iah);
|
||||
@ -285,6 +293,7 @@ public:
|
||||
BonusList getSpellBonuses() const;
|
||||
void stackEffectToFeature(BonusList & sf, const Bonus & sse);
|
||||
std::vector<si32> activeSpells() const; //returns vector of active spell IDs sorted by time of cast
|
||||
const CGHeroInstance *getMyHero() const; //if stack belongs to hero (directly or was by him summoned) returns hero, NULL otherwise
|
||||
|
||||
static inline Bonus *featureGenerator(Bonus::BonusType type, si16 subtype, si32 value, ui16 turnsRemain, si32 additionalInfo = 0, si32 limit = Bonus::NO_LIMIT)
|
||||
{
|
||||
@ -307,6 +316,12 @@ public:
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
assert(isIndependentNode());
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||
h & ID & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
|
||||
& shots & count;
|
||||
|
||||
TSlot slot = (base ? base->armyObj->findStack(base) : -1);
|
||||
const CArmedInstance *army = (base ? base->armyObj : NULL);
|
||||
if(h.saving)
|
||||
@ -316,13 +331,17 @@ public:
|
||||
else
|
||||
{
|
||||
h & army & slot;
|
||||
base = &army->getStack(slot);
|
||||
if(!army || slot == -1 || !army->hasStackAtSlot(slot))
|
||||
{
|
||||
base = NULL;
|
||||
tlog3 << type->nameSing << " don't have a base stack!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
base = &army->getStack(slot);
|
||||
}
|
||||
}
|
||||
|
||||
h & static_cast<CBonusSystemNode&>(*this);
|
||||
h & static_cast<CStackBasicDescriptor&>(*this);
|
||||
h & ID & baseAmount & firstHPleft & owner & slot & attackerOwned & position & state & counterAttacks
|
||||
& shots & count;
|
||||
}
|
||||
bool alive() const //determines if stack is alive
|
||||
{
|
||||
|
@ -116,6 +116,7 @@ int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, const CSelector &selec
|
||||
{
|
||||
return valOfBonuses(Selector::type(type) && selector);
|
||||
}
|
||||
|
||||
int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/) const
|
||||
{
|
||||
CSelector s = Selector::type(type);
|
||||
@ -124,6 +125,7 @@ int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/)
|
||||
|
||||
return valOfBonuses(s);
|
||||
}
|
||||
|
||||
int CBonusSystemNode::valOfBonuses(const CSelector &selector) const
|
||||
{
|
||||
BonusList hlp;
|
||||
@ -300,8 +302,7 @@ CBonusSystemNode::CBonusSystemNode()
|
||||
|
||||
CBonusSystemNode::~CBonusSystemNode()
|
||||
{
|
||||
while(parents.size())
|
||||
detachFrom(parents.front());
|
||||
detachFromAll();
|
||||
|
||||
if(children.size())
|
||||
{
|
||||
@ -313,13 +314,13 @@ void CBonusSystemNode::attachTo(CBonusSystemNode *parent)
|
||||
{
|
||||
assert(!vstd::contains(parents, parent));
|
||||
parents.push_back(parent);
|
||||
BOOST_FOREACH(Bonus *b, exportedBonuses)
|
||||
propagateBonus(b);
|
||||
|
||||
if(parent->weActAsBonusSourceOnly())
|
||||
{
|
||||
|
||||
}
|
||||
// BOOST_FOREACH(Bonus *b, exportedBonuses)
|
||||
// propagateBonus(b);
|
||||
//
|
||||
// if(parent->weActAsBonusSourceOnly())
|
||||
// {
|
||||
//
|
||||
// }
|
||||
|
||||
parent->newChildAttached(this);
|
||||
}
|
||||
@ -413,6 +414,17 @@ void CBonusSystemNode::childDetached(CBonusSystemNode *child)
|
||||
children -= child;
|
||||
}
|
||||
|
||||
void CBonusSystemNode::detachFromAll()
|
||||
{
|
||||
while(parents.size())
|
||||
detachFrom(parents.front());
|
||||
}
|
||||
|
||||
bool CBonusSystemNode::isIndependentNode() const
|
||||
{
|
||||
return parents.empty() && children.empty();
|
||||
}
|
||||
|
||||
int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
|
||||
{
|
||||
if(obj)
|
||||
@ -466,7 +478,7 @@ std::string Bonus::Description() const
|
||||
str << VLC->creh->creatures[id]->namePl;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return str.str();
|
||||
}
|
||||
|
||||
|
@ -410,6 +410,7 @@ public:
|
||||
|
||||
void attachTo(CBonusSystemNode *parent);
|
||||
void detachFrom(CBonusSystemNode *parent);
|
||||
void detachFromAll();
|
||||
void addNewBonus(Bonus *b); //b will be deleted with destruction of node
|
||||
|
||||
void newChildAttached(CBonusSystemNode *child);
|
||||
@ -419,6 +420,7 @@ public:
|
||||
void removeBonus(Bonus *b);
|
||||
|
||||
TNodesVector &nodesOnWhichWePropagate();
|
||||
bool isIndependentNode() const; //node is independent when it has no parents nor children
|
||||
bool weActAsBonusSourceOnly() const;
|
||||
bool isLimitedOnUs(Bonus *b) const; //if bonus should be removed from list acquired from this node
|
||||
CBonusSystemNode *whereToPropagate(Bonus *b);
|
||||
@ -432,7 +434,7 @@ public:
|
||||
|
||||
enum ENodeTypes
|
||||
{
|
||||
UNKNOWN, STACK, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE
|
||||
UNKNOWN, STACK, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -88,7 +88,7 @@ public:
|
||||
virtual void showThievesGuildWindow(int requestingObjId) =0;
|
||||
virtual void giveResource(int player, int which, int val)=0;
|
||||
virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) =0;
|
||||
virtual void takeCreatures (int objid, TSlots creatures) =0;
|
||||
//virtual void takeCreatures (int objid, TSlots creatures) =0;
|
||||
virtual void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures) =0;
|
||||
virtual bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false) =0;
|
||||
virtual bool changeStackType(const StackLocation &sl, CCreature *c) =0;
|
||||
|
@ -529,19 +529,20 @@ struct TryMoveHero : public CPackForClient //501
|
||||
}
|
||||
};
|
||||
|
||||
struct SetGarrisons : public CPackForClient //502
|
||||
{
|
||||
SetGarrisons(){type = 502;};
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
// struct SetGarrisons : public CPackForClient //502
|
||||
// {
|
||||
// SetGarrisons(){type = 502;};
|
||||
// void applyCl(CClient *cl);
|
||||
// DLL_EXPORT void applyGs(CGameState *gs);
|
||||
//
|
||||
// std::map<ui32,CCreatureSet> garrs;
|
||||
//
|
||||
// template <typename Handler> void serialize(Handler &h, const int version)
|
||||
// {
|
||||
// h & garrs;
|
||||
// }
|
||||
// };
|
||||
|
||||
std::map<ui32,CCreatureSet> garrs;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & garrs;
|
||||
}
|
||||
};
|
||||
struct NewStructures : public CPackForClient //504
|
||||
{
|
||||
NewStructures(){type = 504;};
|
||||
@ -598,7 +599,7 @@ struct SetHeroesInTown : public CPackForClient //508
|
||||
{
|
||||
h & tid & visiting & garrison;
|
||||
}
|
||||
};
|
||||
};
|
||||
struct SetHeroArtifacts : public CPackForClient //509
|
||||
{
|
||||
SetHeroArtifacts(){type = 509;};
|
||||
@ -798,7 +799,7 @@ struct SwapStacks : CGarrisonOperationPack //524
|
||||
struct InsertNewStack : CGarrisonOperationPack //525
|
||||
{
|
||||
StackLocation sl;
|
||||
CStackInstance *stack;
|
||||
CStackBasicDescriptor stack;
|
||||
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
@ -810,7 +811,7 @@ struct InsertNewStack : CGarrisonOperationPack //525
|
||||
};
|
||||
|
||||
//moves creatures from src stack to dst slot, may be used for merging/splittint/moving stacks
|
||||
struct RebalanceStacks : CGarrisonOperationPack //525
|
||||
struct RebalanceStacks : CGarrisonOperationPack //526
|
||||
{
|
||||
StackLocation src, dst;
|
||||
TQuantity count;
|
||||
|
@ -375,23 +375,23 @@ void TryMoveHero::applyGs( CGameState *gs )
|
||||
gs->getPlayerTeam(h->getOwner())->fogOfWarMap[t.x][t.y][t.z] = 1;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
|
||||
{
|
||||
for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
{
|
||||
CArmedInstance *ai = static_cast<CArmedInstance*>(gs->map->objects[i->first]);
|
||||
ai->setToArmy(i->second);
|
||||
if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
|
||||
const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->setToArmy(i->second);
|
||||
else if(ai->ID==HEROI_TYPE)
|
||||
{
|
||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
|
||||
CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown);
|
||||
if(t && h->inTownGarrison)
|
||||
t->setToArmy(i->second);
|
||||
}
|
||||
}
|
||||
}
|
||||
// DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
|
||||
// {
|
||||
// for(std::map<ui32,CCreatureSet>::iterator i = garrs.begin(); i!=garrs.end(); i++)
|
||||
// {
|
||||
// CArmedInstance *ai = static_cast<CArmedInstance*>(gs->map->objects[i->first]);
|
||||
// ai->setToArmy(i->second);
|
||||
// if(ai->ID==TOWNI_TYPE && (static_cast<CGTownInstance*>(ai))->garrisonHero) //if there is a hero in garrison then we must update also his army
|
||||
// const_cast<CGHeroInstance*>((static_cast<CGTownInstance*>(ai))->garrisonHero)->setToArmy(i->second);
|
||||
// else if(ai->ID==HEROI_TYPE)
|
||||
// {
|
||||
// CGHeroInstance *h = static_cast<CGHeroInstance*>(ai);
|
||||
// CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown);
|
||||
// if(t && h->inTownGarrison)
|
||||
// t->setToArmy(i->second);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
||||
{
|
||||
@ -634,11 +634,43 @@ DLL_EXPORT void SwapStacks::applyGs( CGameState *gs )
|
||||
|
||||
DLL_EXPORT void InsertNewStack::applyGs( CGameState *gs )
|
||||
{
|
||||
sl.army->putStack(sl.slot, stack);
|
||||
CStackInstance *s = new CStackInstance(stack.type, stack.count);
|
||||
sl.army->putStack(sl.slot, s);
|
||||
}
|
||||
|
||||
DLL_EXPORT void RebalanceStacks::applyGs( CGameState *gs )
|
||||
{
|
||||
const CCreature *srcType = src.army->getCreature(src.slot);
|
||||
TQuantity srcCount = src.army->getStackCount(src.slot);
|
||||
|
||||
if(srcCount == count) //moving whole stack
|
||||
{
|
||||
if(const CCreature *c = dst.army->getCreature(dst.slot)) //stack at dest -> merge
|
||||
{
|
||||
assert(c == srcType);
|
||||
src.army->eraseStack(src.slot);
|
||||
dst.army->changeStackCount(dst.slot, count);
|
||||
}
|
||||
else //move stack to an empty slot
|
||||
{
|
||||
CStackInstance *stackDetached = src.army->detachStack(src.slot);
|
||||
dst.army->putStack(dst.slot, stackDetached);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(const CCreature *c = dst.army->getCreature(dst.slot)) //stack at dest -> rebalance
|
||||
{
|
||||
assert(c == srcType);
|
||||
src.army->changeStackCount(src.slot, -count);
|
||||
dst.army->changeStackCount(dst.slot, count);
|
||||
}
|
||||
else //split stack to an empty slot
|
||||
{
|
||||
src.army->changeStackCount(src.slot, -count);
|
||||
dst.army->addToSlot(dst.slot, srcType->idNumber, count, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetAvailableArtifacts::applyGs( CGameState *gs )
|
||||
@ -786,7 +818,20 @@ DLL_EXPORT void BattleStart::applyGs( CGameState *gs )
|
||||
info->belligerents[0]->battle = info->belligerents[1]->battle = info;
|
||||
|
||||
BOOST_FOREACH(CStack *s, info->stacks)
|
||||
s->attachTo(const_cast<CStackInstance*>(s->base));
|
||||
{
|
||||
if(s->base) //stack originating from "real" stack in garrison -> attach to it
|
||||
{
|
||||
s->attachTo(const_cast<CStackInstance*>(s->base));
|
||||
}
|
||||
else //attach directly to obj to which stack belongs and creature type
|
||||
{
|
||||
CArmedInstance *army = info->belligerents[!s->attackerOwned];
|
||||
s->attachTo(army);
|
||||
assert(s->type);
|
||||
s->attachTo(const_cast<CCreature*>(s->type));
|
||||
}
|
||||
s->postInit();
|
||||
}
|
||||
}
|
||||
|
||||
DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
|
||||
|
@ -105,7 +105,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<UpdateCampaignState>();
|
||||
s.template registerType<RemoveObject>();
|
||||
s.template registerType<TryMoveHero>();
|
||||
s.template registerType<SetGarrisons>();
|
||||
//s.template registerType<SetGarrisons>();
|
||||
s.template registerType<NewStructures>();
|
||||
s.template registerType<RazeStructures>();
|
||||
s.template registerType<SetAvailableCreatures>();
|
||||
|
@ -310,27 +310,26 @@ void CGameHandler::changeSecSkill( int ID, int which, int val, bool abs/*=false*
|
||||
}
|
||||
}
|
||||
|
||||
static CCreatureSet takeCasualties(int color, const CCreatureSet &set, BattleInfo *bat)
|
||||
void CGameHandler::takeCasualties(const CArmedInstance *army, BattleInfo *bat)
|
||||
{
|
||||
int color = army->tempOwner;
|
||||
if(color == 254)
|
||||
color = 255;
|
||||
color = NEUTRAL_PLAYER;
|
||||
|
||||
CCreatureSet ret(set);
|
||||
for(int i=0; i<bat->stacks.size();i++)
|
||||
BOOST_FOREACH(CStack *st, bat->stacks)
|
||||
{
|
||||
CStack *st = bat->stacks[i];
|
||||
if(vstd::contains(st->state, SUMMONED)) //don't take into account sumoned stacks
|
||||
continue;
|
||||
|
||||
if(st->owner==color && !set.slotEmpty(st->slot) && st->count < set.getStackCount(st->slot))
|
||||
if(st->owner==color && !army->slotEmpty(st->slot) && st->count < army->getStackCount(st->slot))
|
||||
{
|
||||
StackLocation sl(army, st->slot);
|
||||
if(st->alive())
|
||||
ret.setStackCount(st->slot, st->count);
|
||||
changeStackCount(sl, st->count, true);
|
||||
else
|
||||
ret.eraseStack(st->slot);
|
||||
eraseStack(sl);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town)
|
||||
@ -582,18 +581,6 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
if(bEndArmy2 && bEndArmy2->tempOwner<PLAYER_LIMIT)
|
||||
states.setFlag(bEndArmy2->tempOwner, &PlayerStatus::engagedIntoBattle, false);
|
||||
|
||||
//casualties among heroes armies
|
||||
SetGarrisons sg;
|
||||
sg.garrs[bEndArmy1->id] = takeCasualties(bEndArmy1->tempOwner, *bEndArmy1, gs->curB);
|
||||
sg.garrs[bEndArmy2->id] = takeCasualties(bEndArmy2->tempOwner, *bEndArmy2, gs->curB);
|
||||
sendAndApply(&sg);
|
||||
|
||||
ui8 sides[2];
|
||||
sides[0] = gs->curB->side1;
|
||||
sides[1] = gs->curB->side2;
|
||||
|
||||
ui8 loser = sides[!battleResult.data->winner];
|
||||
|
||||
//end battle, remove all info, free memory
|
||||
giveExp(*battleResult.data);
|
||||
if (hero1)
|
||||
@ -602,6 +589,16 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
battleResult.data->exp[1] *= (100+hero2->getSecSkillLevel(21)*5)/100.0f;
|
||||
sendAndApply(battleResult.data);
|
||||
|
||||
//casualties among heroes armies
|
||||
takeCasualties(bEndArmy1, gs->curB);
|
||||
takeCasualties(bEndArmy2, gs->curB);
|
||||
|
||||
ui8 sides[2];
|
||||
sides[0] = gs->curB->side1;
|
||||
sides[1] = gs->curB->side2;
|
||||
|
||||
ui8 loser = sides[!battleResult.data->winner];
|
||||
|
||||
//if one hero has lost we will erase him
|
||||
if(battleResult.data->winner!=0 && hero1)
|
||||
{
|
||||
@ -645,7 +642,6 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
||||
if (slot != -1)
|
||||
{
|
||||
winnerHero->showNecromancyDialog(raisedStack);
|
||||
sendAndApply(&sg);
|
||||
addToSlot(StackLocation(winnerHero, slot), raisedStack.type, raisedStack.count);
|
||||
}
|
||||
}
|
||||
@ -2096,64 +2092,71 @@ void CGameHandler::giveResource(int player, int which, int val)
|
||||
}
|
||||
void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove)
|
||||
{
|
||||
if (creatures.stacksCount() <= 0)
|
||||
return;
|
||||
CCreatureSet heroArmy = h->getArmy();
|
||||
std::set<int> takenSlots;
|
||||
for (TSlots::const_iterator it = creatures.Slots().begin(); it != creatures.Slots().end(); it++)
|
||||
{
|
||||
int slot = heroArmy.getSlotFor(it->second->type->idNumber);
|
||||
if (slot >= 0)
|
||||
{
|
||||
heroArmy.addToSlot(slot, it->second); //move all matching creatures to hero's army
|
||||
takenSlots.insert(it->first); //slot id
|
||||
}
|
||||
}
|
||||
for (std::set<int>::iterator it = takenSlots.begin(); it != takenSlots.end(); it++)
|
||||
creatures.eraseStack(*it); //delete them from used army
|
||||
|
||||
SetGarrisons sg;
|
||||
sg.garrs[h->id] = heroArmy;
|
||||
sg.garrs[objid] = creatures;
|
||||
sendAndApply (&sg);
|
||||
|
||||
if (remove) //show garrison window and let player pick remaining creatures
|
||||
{
|
||||
if (creatures.stacksCount()) //Pandora needs to exist until we close garrison window
|
||||
{
|
||||
showGarrisonDialog (objid, h->id, true, boost::bind(&CGameHandler::removeObject, this, objid));
|
||||
}
|
||||
else
|
||||
removeObject(objid);
|
||||
}
|
||||
else if (creatures.stacksCount())
|
||||
showGarrisonDialog (objid, h->id, true, 0);
|
||||
|
||||
}
|
||||
void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we could use ArmedInstance as well
|
||||
{
|
||||
if (creatures.size() <= 0)
|
||||
return;
|
||||
const CArmedInstance* obj = static_cast<const CArmedInstance*>(getObj(objid));
|
||||
CCreatureSet newArmy = obj->getArmy();
|
||||
while (creatures.size())
|
||||
{
|
||||
int slot = newArmy.getSlotFor(creatures.begin()->second->type->idNumber);
|
||||
if (slot < 0)
|
||||
break;
|
||||
newArmy.slots[slot]->count -= creatures.begin()->second->count;
|
||||
if (newArmy.getStack(slot).count < 1)
|
||||
newArmy.eraseStack(slot);
|
||||
creatures.erase(creatures.begin());
|
||||
}
|
||||
SetGarrisons sg;
|
||||
sg.garrs[objid] = newArmy;
|
||||
sendAndApply(&sg);
|
||||
assert(0);
|
||||
// if (creatures.stacksCount() <= 0)
|
||||
// return;
|
||||
// CCreatureSet heroArmy = h->getArmy();
|
||||
// std::set<int> takenSlots;
|
||||
// for (TSlots::const_iterator it = creatures.Slots().begin(); it != creatures.Slots().end(); it++)
|
||||
// {
|
||||
// int slot = heroArmy.getSlotFor(it->second->type->idNumber);
|
||||
// if (slot >= 0)
|
||||
// {
|
||||
// heroArmy.addToSlot(slot, it->second); //move all matching creatures to hero's army
|
||||
// takenSlots.insert(it->first); //slot id
|
||||
// }
|
||||
// }
|
||||
// for (std::set<int>::iterator it = takenSlots.begin(); it != takenSlots.end(); it++)
|
||||
// creatures.eraseStack(*it); //delete them from used army
|
||||
//
|
||||
// SetGarrisons sg;
|
||||
// sg.garrs[h->id] = heroArmy;
|
||||
// sg.garrs[objid] = creatures;
|
||||
// sendAndApply (&sg);
|
||||
//
|
||||
// if (remove) //show garrison window and let player pick remaining creatures
|
||||
// {
|
||||
// if (creatures.stacksCount()) //Pandora needs to exist until we close garrison window
|
||||
// {
|
||||
// showGarrisonDialog (objid, h->id, true, boost::bind(&CGameHandler::removeObject, this, objid));
|
||||
// }
|
||||
// else
|
||||
// removeObject(objid);
|
||||
// }
|
||||
// else if (creatures.stacksCount())
|
||||
// showGarrisonDialog (objid, h->id, true, 0);
|
||||
}
|
||||
|
||||
void CGameHandler::takeCreatures(int objid, std::vector<CStackBasicDescriptor> creatures)
|
||||
{
|
||||
if (creatures.size() <= 0)
|
||||
return;
|
||||
const CArmedInstance* obj = static_cast<const CArmedInstance*>(getObj(objid));
|
||||
|
||||
BOOST_FOREACH(CStackBasicDescriptor &sbd, creatures)
|
||||
{
|
||||
TQuantity collected = 0;
|
||||
while(collected < sbd.count)
|
||||
{
|
||||
TSlots::const_iterator i = obj->Slots().begin();
|
||||
for(; i != obj->Slots().end(); i++)
|
||||
{
|
||||
if(i->second->type == sbd.type)
|
||||
{
|
||||
TQuantity take = std::min(sbd.count - collected, i->second->count); //collect as much creatures as we can
|
||||
changeStackCount(StackLocation(obj, i->first), take, false);
|
||||
collected += take;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == obj->Slots().end()) //we went through the whole loop and haven't found appropriate creatures
|
||||
{
|
||||
complain("Unexpected failure during taking creatures!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::showCompInfo(ShowInInfobox * comp)
|
||||
@ -2549,18 +2552,25 @@ void CGameHandler::sendToAllClients( CPackForClient * info )
|
||||
|
||||
void CGameHandler::sendAndApply( CPackForClient * info )
|
||||
{
|
||||
gs->apply(info);
|
||||
sendToAllClients(info);
|
||||
gs->apply(info);
|
||||
}
|
||||
|
||||
void CGameHandler::sendAndApply( SetGarrisons * info )
|
||||
void CGameHandler::sendAndApply(CGarrisonOperationPack * info)
|
||||
{
|
||||
sendAndApply((CPackForClient*)info);
|
||||
if(gs->map->victoryCondition.condition == gatherTroop)
|
||||
for(std::map<ui32,CCreatureSet>::const_iterator i = info->garrs.begin(); i != info->garrs.end(); i++)
|
||||
checkLossVictory(getObj(i->first)->tempOwner);
|
||||
winLoseHandle();
|
||||
}
|
||||
|
||||
// void CGameHandler::sendAndApply( SetGarrisons * info )
|
||||
// {
|
||||
// sendAndApply((CPackForClient*)info);
|
||||
// if(gs->map->victoryCondition.condition == gatherTroop)
|
||||
// for(std::map<ui32,CCreatureSet>::const_iterator i = info->garrs.begin(); i != info->garrs.end(); i++)
|
||||
// checkLossVictory(getObj(i->first)->tempOwner);
|
||||
// }
|
||||
|
||||
void CGameHandler::sendAndApply( SetResource * info )
|
||||
{
|
||||
sendAndApply((CPackForClient*)info);
|
||||
@ -2581,6 +2591,7 @@ void CGameHandler::sendAndApply( NewStructures * info )
|
||||
if(gs->map->victoryCondition.condition == buildCity)
|
||||
checkLossVictory(getTown(info->tid)->tempOwner);
|
||||
}
|
||||
|
||||
void CGameHandler::save( const std::string &fname )
|
||||
{
|
||||
{
|
||||
@ -5221,7 +5232,7 @@ bool CGameHandler::insertNewStack(const StackLocation &sl, const CCreature *c, T
|
||||
|
||||
InsertNewStack ins;
|
||||
ins.sl = sl;
|
||||
ins.stack = new CStackInstance(c, count);
|
||||
ins.stack = CStackBasicDescriptor(c, count);
|
||||
sendAndApply(&ins);
|
||||
return true;
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
bool isAllowedExchange(int id1, int id2);
|
||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||
int moveStack(int stack, int dest); //returned value - travelled distance
|
||||
void takeCasualties(const CArmedInstance *army, BattleInfo *bat);
|
||||
void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
|
||||
void checkLossVictory(ui8 player);
|
||||
void winLoseHandle(ui8 players=255); //players: bit field - colours of players to be checked; default: all
|
||||
@ -136,7 +137,6 @@ public:
|
||||
void showThievesGuildWindow(int requestingObjId); //TODO: make something more general?
|
||||
void giveResource(int player, int which, int val);
|
||||
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove);
|
||||
void takeCreatures (int objid, TSlots creatures);
|
||||
void takeCreatures (int objid, std::vector<CStackBasicDescriptor> creatures);
|
||||
bool changeStackType(const StackLocation &sl, CCreature *c);
|
||||
bool changeStackCount(const StackLocation &sl, TQuantity count, bool absoluteValue = false);
|
||||
@ -152,7 +152,6 @@ public:
|
||||
void stopHeroVisitCastle(int obj, int heroID);
|
||||
void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
|
||||
void giveNewArtifact(int hid, int position);
|
||||
void moveArtifact(int hid, int oldPosition, int destPos);
|
||||
bool removeArtifact(CArtifact* art, int hid);
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank = false, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL); //use hero=NULL for no hero
|
||||
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, boost::function<void(BattleResult*)> cb = 0, bool creatureBank = false); //if any of armies is hero, hero will be used
|
||||
@ -223,7 +222,8 @@ public:
|
||||
void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback);
|
||||
void sendToAllClients(CPackForClient * info);
|
||||
void sendAndApply(CPackForClient * info);
|
||||
void sendAndApply(SetGarrisons * info);
|
||||
void sendAndApply(CGarrisonOperationPack * info);
|
||||
//void sendAndApply(SetGarrisons * info);
|
||||
void sendAndApply(SetResource * info);
|
||||
void sendAndApply(SetResources * info);
|
||||
void sendAndApply(NewStructures * info);
|
||||
|
Loading…
Reference in New Issue
Block a user