1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* fixed crash on clicking on the map frame

* battle settings will be stored
* fixed calculating battle casualties
* fixed crash when clicking on enemy stack without moving mouse when we receive action
* fixed issue when splitting stack to the hero with only one creatures
This commit is contained in:
Michał W. Urbańczyk 2009-09-24 13:23:52 +00:00
parent 4677d3a338
commit 307c20e7dc
14 changed files with 225 additions and 176 deletions

View File

@ -1029,7 +1029,7 @@ void CGeniusAI::battleEnd(BattleResult *br)
case 2: std::cout << "It's a draw." << std::endl;break;
};
cout << "lost ";
for(std::set<std::pair<ui32,si32> >::iterator i = br->casualties[0].begin(); i !=br->casualties[0].end();i++)
for(std::map<ui32,si32>::iterator i = br->casualties[0].begin(); i !=br->casualties[0].end();i++)
cout << i->second << " " << VLC->creh->creatures[i->first].namePl << endl;
delete m_battleLogic;

View File

@ -471,7 +471,7 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
if ((down==false) || indeterminate(down))
return;
int3 mp = whichTileIsIt();
if ((mp.x<0) || (mp.y<0))
if (mp.x<0 || mp.y<0 || mp.x >= LOCPLINT->cb->getMapSize().x || mp.y >= LOCPLINT->cb->getMapSize().y)
return;
std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mp), //blocking objects at tile
@ -660,11 +660,20 @@ void CTerrainRect::clickRight(tribool down, bool previousState)
}
void CTerrainRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
{
int3 pom=LOCPLINT->adventureInt->verifyPos(whichTileIsIt(sEvent.x,sEvent.y));
if (pom!=curHoveredTile)
int3 tHovered = whichTileIsIt(sEvent.x,sEvent.y);
int3 pom = LOCPLINT->adventureInt->verifyPos(tHovered);
if(tHovered != pom) //tile outside the map
{
CGI->curh->changeGraphic(0, 0);
return;
}
if (pom != curHoveredTile)
curHoveredTile=pom;
else
return;
std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(pom);
if (temp.size())
{

View File

@ -47,7 +47,6 @@ extern SDL_Surface * screen;
extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
extern SDL_Color zwykly;
BattleSettings CBattleInterface::settings;
CondSh<bool> CBattleInterface::animsAreDisplayed;
struct CMP_stack2
@ -481,7 +480,7 @@ void CDefenceAnim::nextFrame()
if(!owner->creAnims[stackID]->onLastFrameInGroup())
{
if( owner->creAnims[stackID]->getType() == 5 && (owner->animCount+1)%(4/CBattleInterface::settings.animSpeed)==0
if( owner->creAnims[stackID]->getType() == 5 && (owner->animCount+1)%(4/LOCPLINT->sysOpts.animSpeed)==0
&& !owner->creAnims[stackID]->onLastFrameInGroup() )
{
owner->creAnims[stackID]->incrementFrame();
@ -694,7 +693,7 @@ void CBattleMoveStart::nextFrame()
}
else
{
if((owner->animCount+1)%(4/CBattleInterface::settings.animSpeed)==0)
if((owner->animCount+1)%(4/LOCPLINT->sysOpts.animSpeed)==0)
owner->creAnims[stackID]->incrementFrame();
}
}
@ -1047,7 +1046,7 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
//create stack queue
bool embedQueue = screen->h < 700;
queue = new CStackQueue(embedQueue);
if(!embedQueue && settings.showQueue)
if(!embedQueue && LOCPLINT->sysOpts.showQueue)
{
pos.y += queue->pos.h / 2; //center whole window
queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
@ -1306,21 +1305,24 @@ CBattleInterface::~CBattleInterface()
void CBattleInterface::setPrintCellBorders(bool set)
{
settings.printCellBorders = set;
LOCPLINT->sysOpts.printCellBorders = set;
LOCPLINT->sysOpts.settingsChanged();
redrawBackgroundWithHexes(activeStack);
GH.totalRedraw();
}
void CBattleInterface::setPrintStackRange(bool set)
{
settings.printStackRange = set;
LOCPLINT->sysOpts.printStackRange = set;
LOCPLINT->sysOpts.settingsChanged();
redrawBackgroundWithHexes(activeStack);
GH.totalRedraw();
}
void CBattleInterface::setPrintMouseShadow(bool set)
{
settings.printMouseShadow = set;
LOCPLINT->sysOpts.printMouseShadow = set;
LOCPLINT->sysOpts.settingsChanged();
}
void CBattleInterface::activate()
@ -1345,7 +1347,7 @@ void CBattleInterface::activate()
attackingHero->activate();
if(defendingHero)
defendingHero->activate();
if(settings.showQueue)
if(LOCPLINT->sysOpts.showQueue)
queue->activate();
LOCPLINT->cingconsole->activate();
@ -1373,7 +1375,7 @@ void CBattleInterface::deactivate()
attackingHero->deactivate();
if(defendingHero)
defendingHero->deactivate();
if(settings.showQueue)
if(LOCPLINT->sysOpts.showQueue)
queue->deactivate();
LOCPLINT->cingconsole->deactivate();
@ -1399,7 +1401,7 @@ void CBattleInterface::show(SDL_Surface * to)
{
//showing background
blitAt(background, pos.x, pos.y, to);
if(settings.printCellBorders)
if(LOCPLINT->sysOpts.printCellBorders)
{
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, to, &pos);
}
@ -1436,7 +1438,7 @@ void CBattleInterface::show(SDL_Surface * to)
std::set<ui16> shaded = spToCast.rangeInHexes(b, schoolLevel);
for(std::set<ui16>::iterator it = shaded.begin(); it != shaded.end(); ++it) //for spells with range greater then one hex
{
if(settings.printMouseShadow && (*it % BFIELD_WIDTH != 0) && (*it % BFIELD_WIDTH != 16))
if(LOCPLINT->sysOpts.printMouseShadow && (*it % BFIELD_WIDTH != 0) && (*it % BFIELD_WIDTH != 16))
{
int x = 14 + ((*it/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(*it%BFIELD_WIDTH) + pos.x;
int y = 86 + 42 * (*it/BFIELD_WIDTH) + pos.y;
@ -1444,7 +1446,7 @@ void CBattleInterface::show(SDL_Surface * to)
}
}
}
else if(settings.printMouseShadow) //when not casting spell
else if(LOCPLINT->sysOpts.printMouseShadow) //when not casting spell
{
int x = 14 + ((b/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(b%BFIELD_WIDTH) + pos.x;
int y = 86 + 42 * (b/BFIELD_WIDTH) + pos.y;
@ -1479,7 +1481,7 @@ void CBattleInterface::show(SDL_Surface * to)
int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH) + pos.x + shift.first;
int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH) + pos.y + shift.second;
std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages; //reference to animation of obstacle
blitAt(images[((animCount+1)/(4/settings.animSpeed))%images.size()].bitmap, x, y, to);
blitAt(images[((animCount+1)/(4/LOCPLINT->sysOpts.animSpeed))%images.size()].bitmap, x, y, to);
}
//showing hero animations
@ -1597,7 +1599,7 @@ void CBattleInterface::show(SDL_Surface * to)
Rect posWithQueue = Rect(pos.x, pos.y, 800, 600);
if(settings.showQueue)
if(LOCPLINT->sysOpts.showQueue)
{
if(!queue->embedded)
{
@ -1622,10 +1624,12 @@ void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
{
if(key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
{
if(settings.showQueue) //hide queue
if(LOCPLINT->sysOpts.showQueue) //hide queue
hideQueue();
else
showQueue();
LOCPLINT->sysOpts.settingsChanged();
}
else if(key.keysym.sym == SDLK_ESCAPE && spellDestSelectMode)
{
@ -2154,9 +2158,20 @@ void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack, si32 addit
ba->destinationTile = tile;
ba->stackNumber = stack;
ba->additionalInfo = additional;
givenCommand->setn(ba);
//some basic validations
switch(action)
{
case 6:
assert(LOCPLINT->cb->battleGetStackByPos(additional)); //stack to attack must exist
case 2: case 7: case 9:
assert(tile < BFIELD_SIZE);
break;
}
myTurn = false;
activeStack = -1;
givenCommand->setn(ba);
}
bool CBattleInterface::isTileAttackable(const int & number) const
@ -2616,20 +2631,23 @@ void CBattleInterface::displayEffect(ui32 effect, int destTile)
void CBattleInterface::setAnimSpeed(int set)
{
settings.animSpeed = set;
LOCPLINT->sysOpts.animSpeed = set;
LOCPLINT->sysOpts.settingsChanged();
}
int CBattleInterface::getAnimSpeed() const
{
return settings.animSpeed;
return LOCPLINT->sysOpts.animSpeed;
LOCPLINT->sysOpts.settingsChanged();
}
void CBattleInterface::activateStack()
{
activeStack = stackToActivate;
queue->update();
stackToActivate = -1;
myTurn = true;
queue->update();
GH.fakeMouseMove();
redrawBackgroundWithHexes(activeStack);
bWait->block(vstd::contains(LOCPLINT->cb->battleGetStackByID(activeStack)->state,WAITING)); //block waiting button if stack has been already waiting
@ -2648,7 +2666,7 @@ void CBattleInterface::activateStack()
float CBattleInterface::getAnimSpeedMultiplier() const
{
switch(settings.animSpeed)
switch(LOCPLINT->sysOpts.animSpeed)
{
case 1:
return 3.5f;
@ -2679,7 +2697,7 @@ void CBattleInterface::showAliveStack(int ID, const std::map<int, CStack> & stac
const CStack &curStack = stacks.find(ID)->second;
int animType = creAnims[ID]->getType();
int affectingSpeed = settings.animSpeed;
int affectingSpeed = LOCPLINT->sysOpts.animSpeed;
if(animType == 1 || animType == 2) //standing stacks should not stand faster :)
affectingSpeed = 2;
if(animType == 3 || animType == 7 || animType == 8 || animType == 9 || animType == 10 || animType == 11 || animType == 12 || animType == 13) //defend & attack should be slower
@ -2836,10 +2854,10 @@ void CBattleInterface::redrawBackgroundWithHexes(int activeStack)
//preparating background graphic with hexes and shaded hexes
blitAt(background, 0, 0, backgroundWithHexes);
if(settings.printCellBorders)
if(LOCPLINT->sysOpts.printCellBorders)
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, backgroundWithHexes, NULL);
if(settings.printStackRange)
if(LOCPLINT->sysOpts.printStackRange)
{
for(size_t m=0; m<shadedHexes.size(); ++m) //rows
{
@ -2946,9 +2964,9 @@ void CBattleInterface::endAction(const BattleAction* action)
void CBattleInterface::hideQueue()
{
settings.showQueue = false;
//if(queue->active)
queue->deactivate();
LOCPLINT->sysOpts.showQueue = false;
queue->deactivate();
if(!queue->embedded)
{
@ -2959,9 +2977,9 @@ void CBattleInterface::hideQueue()
void CBattleInterface::showQueue()
{
settings.showQueue = true;
//if(!queue->active)
queue->activate();
LOCPLINT->sysOpts.showQueue = true;
queue->activate();
if(!queue->embedded)
{
@ -2970,6 +2988,75 @@ void CBattleInterface::showQueue()
}
}
void CBattleInterface::startAction(const BattleAction* action)
{
const CStack *stack = LOCPLINT->cb->battleGetStackByID(action->stackNumber);
if(stack)
{
queue->update();
}
else
{
assert(action->actionType == 1); //only cast spell is valid action without acting stack number
}
if(action->actionType == 2
|| (action->actionType == 6 && action->destinationTile != stack->position))
{
moveStarted = true;
if(creAnims[action->stackNumber]->framesInGroup(20))
{
pendingAnims.push_back(std::make_pair(new CBattleMoveStart(this, action->stackNumber), false));
}
}
deactivate();
char txt[400];
if(action->actionType == 1)
{
if(action->side)
defendingHero->setPhase(4);
else
attackingHero->setPhase(4);
return;
}
if(!stack)
{
tlog1<<"Something wrong with stackNumber in actionStarted. Stack number: "<<action->stackNumber<<std::endl;
return;
}
int txtid = 0;
switch(action->actionType)
{
case 3: //defend
txtid = 120;
break;
case 8: //wait
txtid = 136;
break;
case 11: //bad morale
txtid = -34; //negative -> no separate singular/plural form
displayEffect(30,stack->position);
break;
}
if(txtid > 0 && stack->amount != 1)
txtid++; //move to plural text
else if(txtid < 0)
txtid = -txtid;
if(txtid)
{
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->amount != 1) ? stack->creature->namePl.c_str() : stack->creature->nameSing.c_str(), 0);
console->addText(txt);
}
}
void CBattleHero::show(SDL_Surface *to)
{
//animation of flag
@ -3441,7 +3528,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
{
int xPos = 235 - (br.casualties[step].size()*32 + (br.casualties[step].size() - 1)*10)/2; //increment by 42 with each picture
int yPos = 344 + step*97;
for(std::set<std::pair<ui32,si32> >::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
for(std::map<ui32,si32>::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
{
blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
std::ostringstream amount;
@ -3554,11 +3641,11 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt
graphics->blueToPlayersAdv(background, LOCPLINT->playerID);
viewGrid = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintCellBorders, owner, true), boost::bind(&CBattleInterface::setPrintCellBorders, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[427].first)(3,CGI->generaltexth->zelp[427].first), CGI->generaltexth->zelp[427].second, false, "sysopchk.def", NULL, 185, 140, false);
viewGrid->select(owner->settings.printCellBorders);
viewGrid->select(LOCPLINT->sysOpts.printCellBorders);
movementShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintStackRange, owner, true), boost::bind(&CBattleInterface::setPrintStackRange, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[428].first)(3,CGI->generaltexth->zelp[428].first), CGI->generaltexth->zelp[428].second, false, "sysopchk.def", NULL, 185, 173, false);
movementShadow->select(owner->settings.printStackRange);
movementShadow->select(LOCPLINT->sysOpts.printStackRange);
mouseShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintMouseShadow, owner, true), boost::bind(&CBattleInterface::setPrintMouseShadow, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[429].first)(3,CGI->generaltexth->zelp[429].first), CGI->generaltexth->zelp[429].second, false, "sysopchk.def", NULL, 185, 207, false);
mouseShadow->select(owner->settings.printMouseShadow);
mouseShadow->select(LOCPLINT->sysOpts.printMouseShadow);
animSpeeds = new CHighlightableButtonsGroup(0);
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[422].first),CGI->generaltexth->zelp[422].second, "sysopb9.def",188, 309, 1);
@ -3891,13 +3978,4 @@ CStackQueue::StackBox::~StackBox()
void CStackQueue::StackBox::hover( bool on )
{
}
BattleSettings::BattleSettings()
{
printCellBorders = true;
printStackRange = true;
animSpeed = 2;
printMouseShadow = true;
showQueue = true;
}

View File

@ -314,21 +314,6 @@ public:
void show(SDL_Surface * to = 0);
};
struct BattleSettings
{
BattleSettings();
bool printCellBorders; //if true, cell borders will be printed
bool printStackRange; //if true,range of active stack will be printed
int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
bool printMouseShadow; //if true, hex under mouse will be shaded
bool showQueue;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & printCellBorders & printStackRange & animSpeed & printMouseShadow & showQueue;
}
};
struct SBattleEffect
{
int x, y; //position on the screen
@ -442,7 +427,6 @@ public:
~CBattleInterface(); //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling
static BattleSettings settings;
void setPrintCellBorders(bool set); //if true, cell borders will be printed
void setPrintStackRange(bool set); //if true,range of active stack will be printed
void setPrintMouseShadow(bool set); //if true, hex under mouse will be shaded
@ -480,6 +464,7 @@ public:
void clickRight(tribool down, bool previousState);
//call-ins
void startAction(const BattleAction* action);
void newStack(int stackID); //new stack appeared on battlefield
void stackRemoved(int stackID); //stack disappeared from batlefiled
//void stackKilled(int ID, int dmg, int killed, int IDby, bool byShooting); //stack has been killed (but corpses remain)
@ -500,7 +485,6 @@ public:
void endAction(const BattleAction* action);
void hideQueue();
void showQueue();
friend class CBattleHex;
friend class CBattleResultWindow;
friend class CPlayerInterface;

View File

@ -1024,60 +1024,7 @@ void CPlayerInterface::actionStarted(const BattleAction* action)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
curAction = new BattleAction(*action);
if( (action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber))) )
{
battleInt->moveStarted = true;
if(battleInt->creAnims[action->stackNumber]->framesInGroup(20))
{
battleInt->pendingAnims.push_back(std::make_pair(new CBattleMoveStart(battleInt, action->stackNumber), false));
}
}
battleInt->deactivate();
const CStack *stack = cb->battleGetStackByID(action->stackNumber);
char txt[400];
if(action->actionType == 1)
{
if(action->side)
battleInt->defendingHero->setPhase(4);
else
battleInt->attackingHero->setPhase(4);
return;
}
if(!stack)
{
tlog1<<"Something wrong with stackNumber in actionStarted. Stack number: "<<action->stackNumber<<std::endl;
return;
}
int txtid = 0;
switch(action->actionType)
{
case 3: //defend
txtid = 120;
break;
case 8: //wait
txtid = 136;
break;
case 11: //bad morale
txtid = -34; //negative -> no separate singular/plural form
battleInt->displayEffect(30,stack->position);
break;
}
if(txtid > 0 && stack->amount != 1)
txtid++; //move to plural text
else if(txtid < 0)
txtid = -txtid;
if(txtid)
{
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->amount != 1) ? stack->creature->namePl.c_str() : stack->creature->nameSing.c_str(), 0);
LOCPLINT->battleInt->console->addText(txt);
}
battleInt->startAction(action);
}
void CPlayerInterface::actionFinished(const BattleAction* action)
@ -1377,7 +1324,6 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
{
h & playerID & serialID;
h & sysOpts;
h & CBattleInterface::settings;
}
void CPlayerInterface::serialize( COSer<CSaveFile> &h, const int version )
@ -1632,7 +1578,24 @@ void SystemOptions::settingsChanged()
void SystemOptions::apply()
{
CGI->musich->setVolume(musicVolume);
CGI->soundh->setVolume(soundVolume);
if(CGI->musich->getVolume() != musicVolume)
CGI->musich->setVolume(musicVolume);
if(CGI->soundh->getVolume() != soundVolume)
CGI->soundh->setVolume(soundVolume);
settingsChanged();
}
SystemOptions::SystemOptions()
{
heroMoveSpeed = 2;
mapScrollingSpeed = 2;
musicVolume = 88;
soundVolume = 88;
printCellBorders = true;
printStackRange = true;
animSpeed = 2;
printMouseShadow = true;
showQueue = true;
}

View File

@ -74,32 +74,33 @@ namespace boost
struct SystemOptions
{
ui8 heroMoveSpeed; //speed of player's hero movement
//TODO: enemy hero speed
ui8 heroMoveSpeed;/*, enemyMoveSpeed*/ //speed of player's hero movement
ui8 mapScrollingSpeed; //map scrolling speed
ui8 musicVolume, soundVolume;
//TODO: rest of system options
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroMoveSpeed & mapScrollingSpeed & musicVolume & soundVolume;
}
SystemOptions()
{
heroMoveSpeed = 2;
mapScrollingSpeed = 2;
musicVolume = 88;
soundVolume = 88;
}
//battle settings
ui8 printCellBorders; //if true, cell borders will be printed
ui8 printStackRange; //if true,range of active stack will be printed
ui8 animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
ui8 printMouseShadow; //if true, hex under mouse will be shaded
ui8 showQueue;
SystemOptions();
void setHeroMoveSpeed(int newSpeed); //set for the member above
void setMapScrollingSpeed(int newSpeed); //set the member above
void setMusicVolume(int newVolume);
void setSoundVolume(int newVolume);
void settingsChanged(); //updates file with "default" settings for next running of application
void apply();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroMoveSpeed & mapScrollingSpeed & musicVolume & soundVolume;
h & printCellBorders & printStackRange & animSpeed & printMouseShadow & showQueue;
}
};
extern SystemOptions GDefaultOptions; //defined and inited in CMT.cpp, stores default settings loaded with application

View File

@ -292,16 +292,7 @@ void CGuiHandler::handleMouseMotion(SDL_Event *sEvent)
hlp[i]->hovered = true;
}
//sending active, MotionInterested objects mouseMoved() call
std::list<CIntObject*> miCopy = motioninterested;
for(std::list<CIntObject*>::iterator i=miCopy.begin(); i != miCopy.end();i++)
{
if ((*i)->strongInterest || isItIn(&(*i)->pos,sEvent->motion.x,sEvent->motion.y))
{
(*i)->mouseMoved(sEvent->motion);
}
}
handleMoveInterested(sEvent->motion);
}
void CGuiHandler::simpleRedraw()
@ -312,6 +303,29 @@ void CGuiHandler::simpleRedraw()
objsToBlit.back()->show(screen); //blit active interface/window
}
void CGuiHandler::handleMoveInterested( const SDL_MouseMotionEvent & motion )
{
//sending active, MotionInterested objects mouseMoved() call
std::list<CIntObject*> miCopy = motioninterested;
for(std::list<CIntObject*>::iterator i=miCopy.begin(); i != miCopy.end();i++)
{
if ((*i)->strongInterest || isItIn(&(*i)->pos, motion.x, motion.y))
{
(*i)->mouseMoved(motion);
}
}
}
void CGuiHandler::fakeMouseMove()
{
SDL_MouseMotionEvent sme = {SDL_MOUSEMOTION, 0, 0, 0, 0, 0, 0};
int x, y;
sme.state = SDL_GetMouseState(&x, &y);
sme.x = x;
sme.y = y;
handleMoveInterested(sme);
}
void CIntObject::activateLClick()
{
GH.lclickable.push_front(this);

View File

@ -453,9 +453,9 @@ public:
void updateTime(); //handles timeInterested
void handleEvents(); //takes events from queue and calls interested objects
void handleEvent(SDL_Event *sEvent);
void handleMouseMotion(SDL_Event *sEvent);
void handleMoveInterested( const SDL_MouseMotionEvent & motion );
void fakeMouseMove();
ui8 defActionsDef; //default auto actions
ui8 captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
std::list<CIntObject *> createdObj; //stack of objs being created

View File

@ -222,7 +222,8 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
refr = true;
delete pom2;
}
else {
else
{
// Only allow certain moves if troops aren't removable.
if (owner->removableUnits
|| (upg == 0 && (owner->highlighted->upg == 1 && !creature))
@ -244,12 +245,13 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
int last = -1;
if(upg != owner->highlighted->upg) //not splitting within same army
{
if(owner->highlighted->getObj()->army.slots.size() == 1
if(owner->highlighted->getObj()->army.slots.size() == 1 //we're splitting away the last stack
&& owner->highlighted->getObj()->needsLastStack() )
{
last = 0;
}
if(getObj()->army.slots.size() == 1
if(getObj()->army.slots.size() == 1 //destination army can't be emptied, unless we're rebalancing two stacks of same creature
&& owner->highlighted->creature == creature
&& getObj()->needsLastStack() )
{
last += 2;
@ -276,7 +278,8 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState)
owner->highlighted->ID,ID);
}
}
else { // Highlight
else // Highlight
{
if(creature)
owner->highlighted = this;
show(screen2);
@ -2829,24 +2832,24 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
std::swap(backToMap->imgs[0][0], backToMap->imgs[0][1]);
heroMoveSpeed = new CHighlightableButtonsGroup(0);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[349].first),CGI->generaltexth->zelp[349].second, "sysopb1.def", 187, 134, 1);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[350].first),CGI->generaltexth->zelp[350].second, "sysopb2.def", 235, 134, 2);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[351].first),CGI->generaltexth->zelp[351].second, "sysopb3.def", 283, 134, 4);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[352].first),CGI->generaltexth->zelp[352].second, "sysopb4.def", 331, 134, 8);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[349].second),CGI->generaltexth->zelp[349].second, "sysopb1.def", 187, 134, 1);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[350].second),CGI->generaltexth->zelp[350].second, "sysopb2.def", 235, 134, 2);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[351].second),CGI->generaltexth->zelp[351].second, "sysopb3.def", 283, 134, 4);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[352].second),CGI->generaltexth->zelp[352].second, "sysopb4.def", 331, 134, 8);
heroMoveSpeed->select(owner->sysOpts.heroMoveSpeed, 1);
heroMoveSpeed->onChange = boost::bind(&SystemOptions::setHeroMoveSpeed, &owner->sysOpts, _1);
mapScrollSpeed = new CHighlightableButtonsGroup(0);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[357].first),CGI->generaltexth->zelp[357].second, "sysopb9.def", 187, 267, 1);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[358].first),CGI->generaltexth->zelp[358].second, "sysob10.def", 251, 267, 2);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[359].first),CGI->generaltexth->zelp[359].second, "sysob11.def", 315, 267, 4);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[357].second),CGI->generaltexth->zelp[357].second, "sysopb9.def", 187, 267, 1);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[358].second),CGI->generaltexth->zelp[358].second, "sysob10.def", 251, 267, 2);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[359].second),CGI->generaltexth->zelp[359].second, "sysob11.def", 315, 267, 4);
mapScrollSpeed->select(owner->sysOpts.mapScrollingSpeed, 1);
mapScrollSpeed->onChange = boost::bind(&SystemOptions::setMapScrollingSpeed, &owner->sysOpts, _1);
musicVolume = new CHighlightableButtonsGroup(0, true);
for(int i=0; i<10; ++i)
{
musicVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[326+i].first),CGI->generaltexth->zelp[326+i].second, "syslb.def", 188 + 19*i, 416, i*11);
musicVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[326+i].second),CGI->generaltexth->zelp[326+i].second, "syslb.def", 188 + 19*i, 416, i*11);
}
musicVolume->select(CGI->musich->getVolume(), 1);
musicVolume->onChange = boost::bind(&SystemOptions::setMusicVolume, &owner->sysOpts, _1);
@ -2854,7 +2857,7 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
effectsVolume = new CHighlightableButtonsGroup(0, true);
for(int i=0; i<10; ++i)
{
effectsVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[336+i].first),CGI->generaltexth->zelp[336+i].second, "syslb.def", 188 + 19*i, 482, i*11);
effectsVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[336+i].second),CGI->generaltexth->zelp[336+i].second, "syslb.def", 188 + 19*i, 482, i*11);
}
effectsVolume->select(CGI->soundh->getVolume(), 1);
effectsVolume->onChange = boost::bind(&SystemOptions::setSoundVolume, &owner->sysOpts, _1);

View File

@ -1054,11 +1054,11 @@ std::pair<ui32, si32> CGHeroInstance::calculateNecromancy (BattleResult &battleR
if (necromancyLevel > 0) {
double necromancySkill = necromancyLevel*0.1
+ valOfBonuses(HeroBonus::SECONDARY_SKILL_PREMY, 12)/100.0;
const std::set<std::pair<ui32, si32> > &casualties = battleResult.casualties[!battleResult.winner];
const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
ui32 raisedUnits = 0;
// Get lost enemy hit points convertible to units.
for (std::set<std::pair<ui32, si32> >::const_iterator it = casualties.begin(); it != casualties.end(); it++)
for (std::map<ui32,si32>::const_iterator it = casualties.begin(); it != casualties.end(); it++)
raisedUnits += VLC->creh->creatures[it->first].hitPoints*it->second;
raisedUnits *= necromancySkill;
@ -1071,7 +1071,8 @@ std::pair<ui32, si32> CGHeroInstance::calculateNecromancy (BattleResult &battleR
// Make room for new units.
int slot = army.getSlotFor(raisedUnitType->idNumber);
if (slot == -1) {
if (slot == -1)
{
// If there's no room for unit, try it's upgraded version 2/3rds the size.
raisedUnitType = &VLC->creh->creatures[*raisedUnitType->upgrades.begin()];
raisedUnits = (raisedUnits*2)/3;

View File

@ -2493,18 +2493,14 @@ ui32 BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender, co
return range.first;
}
void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualties ) const
void BattleInfo::calculateCasualties( std::map<ui32,si32> *casualties ) const
{
for(unsigned 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));
}
const CStack * const st = stacks[i];
si32 killed = (st->alive() ? st->baseAmount - st->amount : st->baseAmount);
amax(killed, 0);
casualties[!st->attackerOwned][st->creature->idNumber] += killed;
}
}

View File

@ -154,7 +154,7 @@ struct DLL_EXPORT BattleInfo
static std::vector<int> neighbouringTiles(int hex);
static ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge); //charge - number of hexes travelled before attack (for champion's jousting)
static std::pair<ui32, ui32> calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge); //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
void calculateCasualties(std::set<std::pair<ui32,si32> > *casualties) const;
void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
std::set<CStack*> getAttackedCreatures(const CSpell * s, const CGHeroInstance * caster, int destinationTile); //calculates stack affected by given spell
static int calculateSpellDuration(const CSpell * spell, const CGHeroInstance * caster);
CStack * generateNewStack(const CGHeroInstance * owner, int creatureID, int amount, int stackID, bool attackerOwned, int slot, int /*TerrainTile::EterrainType*/ terrain, int position) const; //helper for CGameHandler::setupBattle and spells addign new stacks to the battlefield

View File

@ -807,7 +807,7 @@ struct BattleResult : public CPackForClient//3003
ui8 result; //0 - normal victory; 1 - escape; 2 - surrender
ui8 winner; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
std::set<std::pair<ui32,si32> > casualties[2]; //first => casualties of attackers - set of pairs crid<>number
std::map<ui32,si32> casualties[2]; //first => casualties of attackers - map crid => number
ui32 exp[2]; //exp for attacker and defender
std::set<ui32> artifacts; //artifacts taken from loser to winner

View File

@ -95,7 +95,7 @@ static void giveExp(BattleResult &r)
{
r.exp[0] = 0;
r.exp[1] = 0;
for(std::set<std::pair<ui32,si32> >::iterator i = r.casualties[!r.winner].begin(); i!=r.casualties[!r.winner].end(); i++)
for(std::map<ui32,si32>::iterator i = r.casualties[!r.winner].begin(); i!=r.casualties[!r.winner].end(); i++)
{
r.exp[r.winner] += VLC->creh->creatures[i->first].hitPoints * i->second;
}
@ -1406,7 +1406,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
&& complain("Cannot move hero, destination tile is on water!")
|| (h->boat && t.tertype != TerrainTile::water && t.blocked)
&& complain("Cannot disembark hero, tile is blocked!")
|| (!h->movement && dst != h->pos)
|| (h->movement < cost && dst != h->pos)
&& complain("Hero don't have any movement points left!")
|| states.checkFlag(h->tempOwner, &PlayerStatus::engagedIntoBattle)
&& complain("Cannot move hero during the battle"))