mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Various changes, including exprank limiter and development towards Tactics secondary skill support.
This commit is contained in:
parent
9f90ef58ca
commit
fcdc3f0bdd
@ -1111,3 +1111,37 @@ CBattleCallback::ESpellCastProblem CBattleCallback::battleCanCastThisSpell( cons
|
|||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
si8 CBattleCallback::battleGetTacticDist()
|
||||||
|
{
|
||||||
|
if (!gs->curB)
|
||||||
|
{
|
||||||
|
tlog1 << "battleGetTacticDist called when no battle!\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gs->curB->sides[gs->curB->tacticsSide] == player)
|
||||||
|
{
|
||||||
|
return gs->curB->tacticDistance;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui8 CBattleCallback::battleGetMySide()
|
||||||
|
{
|
||||||
|
if (!gs->curB)
|
||||||
|
{
|
||||||
|
tlog1 << "battleGetMySide called when no battle!\n";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gs->curB->sides[1] == player;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBattleCallback::battleMakeTacticAction( BattleAction * action )
|
||||||
|
{
|
||||||
|
MakeAction ma;
|
||||||
|
ma.ba = *action;
|
||||||
|
sendRequest(&ma);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -105,6 +105,9 @@ public:
|
|||||||
virtual si8 battleHasDistancePenalty(const CStack * stack, THex destHex) =0; //checks if given stack has distance penalty
|
virtual si8 battleHasDistancePenalty(const CStack * stack, THex destHex) =0; //checks if given stack has distance penalty
|
||||||
virtual si8 battleHasWallPenalty(const CStack * stack, THex destHex) =0; //checks if given stack has wall penalty
|
virtual si8 battleHasWallPenalty(const CStack * stack, THex destHex) =0; //checks if given stack has wall penalty
|
||||||
virtual si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) =0; //checks if teleportation of given stack to given position can take place
|
virtual si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) =0; //checks if teleportation of given stack to given position can take place
|
||||||
|
virtual si8 battleGetTacticDist() =0; //returns tactic distance for calling player or 0 if player is not in tactic phase
|
||||||
|
virtual ui8 battleGetMySide() =0; //return side of player in battle (attacker/defender)
|
||||||
|
virtual bool battleMakeTacticAction(BattleAction * action) =0; // performs tactic phase actions
|
||||||
};
|
};
|
||||||
|
|
||||||
class ICallback : public virtual IBattleCallback
|
class ICallback : public virtual IBattleCallback
|
||||||
@ -234,6 +237,9 @@ public:
|
|||||||
si8 battleHasDistancePenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has distance penalty
|
si8 battleHasDistancePenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has distance penalty
|
||||||
si8 battleHasWallPenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has wall penalty
|
si8 battleHasWallPenalty(const CStack * stack, THex destHex) OVERRIDE; //checks if given stack has wall penalty
|
||||||
si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) OVERRIDE; //checks if teleportation of given stack to given position can take place
|
si8 battleCanTeleportTo(const CStack * stack, THex destHex, int telportLevel) OVERRIDE; //checks if teleportation of given stack to given position can take place
|
||||||
|
si8 battleGetTacticDist() OVERRIDE; //returns tactic distance for calling player or 0 if player is not in tactic phase
|
||||||
|
ui8 battleGetMySide() OVERRIDE; //return side of player in battle (attacker/defender)
|
||||||
|
bool battleMakeTacticAction(BattleAction * action) OVERRIDE; // performs tactic phase actions
|
||||||
|
|
||||||
friend class CCallback;
|
friend class CCallback;
|
||||||
friend class CClient;
|
friend class CClient;
|
||||||
|
@ -104,7 +104,7 @@ bool CBattleAnimation::isEarliest(bool perStackConcurrency)
|
|||||||
if(perStackConcurrency && stAnim && thAnim && stAnim->stack->ID != thAnim->stack->ID)
|
if(perStackConcurrency && stAnim && thAnim && stAnim->stack->ID != thAnim->stack->ID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(sen && thSen && perStackConcurrency)
|
if(sen && thSen && sen != thSen && perStackConcurrency)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CReverseAnim * revAnim = dynamic_cast<CReverseAnim *>(stAnim);
|
CReverseAnim * revAnim = dynamic_cast<CReverseAnim *>(stAnim);
|
||||||
@ -1214,6 +1214,13 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
|||||||
console->pos.y = 560 + pos.y;
|
console->pos.y = 560 + pos.y;
|
||||||
console->pos.w = 406;
|
console->pos.w = 406;
|
||||||
console->pos.h = 38;
|
console->pos.h = 38;
|
||||||
|
if(curInt->cb->battleGetTacticDist())
|
||||||
|
{
|
||||||
|
btactNext = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bTacticNextStack,this), 213 + pos.x, 560 + pos.y, "icm011.def", SDLK_SPACE);
|
||||||
|
btactEnd = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
|
||||||
|
bDefence->block(true);
|
||||||
|
bWait->block(true);
|
||||||
|
}
|
||||||
|
|
||||||
//loading hero animations
|
//loading hero animations
|
||||||
if(hero1) // attacking hero
|
if(hero1) // attacking hero
|
||||||
@ -1331,6 +1338,20 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
|||||||
{
|
{
|
||||||
children.push_back(&bfield[i]);
|
children.push_back(&bfield[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(curInt->cb->battleGetTacticDist())
|
||||||
|
{
|
||||||
|
BOOST_FOREACH(const CStack *s, curInt->cb->battleGetStacks())
|
||||||
|
{
|
||||||
|
if(s->owner == curInt->playerID)
|
||||||
|
{
|
||||||
|
active = 1;
|
||||||
|
stackActivated(s);
|
||||||
|
active = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CBattleInterface::~CBattleInterface()
|
CBattleInterface::~CBattleInterface()
|
||||||
@ -3387,6 +3408,18 @@ void CBattleInterface::waitForAnims()
|
|||||||
LOCPLINT->pim->lock();
|
LOCPLINT->pim->lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::bEndTacticPhase()
|
||||||
|
{
|
||||||
|
BattleAction endt = BattleAction::makeEndOFTacticPhase(curInt->cb->battleGetMySide());
|
||||||
|
curInt->cb->battleMakeTacticAction(&endt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::bTacticNextStack()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleHero::show(SDL_Surface *to)
|
void CBattleHero::show(SDL_Surface *to)
|
||||||
{
|
{
|
||||||
//animation of flag
|
//animation of flag
|
||||||
|
@ -379,7 +379,7 @@ class CBattleInterface : public CIntObject
|
|||||||
private:
|
private:
|
||||||
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
|
SDL_Surface * background, * menu, * amountNormal, * amountNegative, * amountPositive, * amountEffNeutral, * cellBorders, * backgroundWithHexes;
|
||||||
AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell,
|
AdventureMapButton * bOptions, * bSurrender, * bFlee, * bAutofight, * bSpell,
|
||||||
* bWait, * bDefence, * bConsoleUp, * bConsoleDown;
|
* bWait, * bDefence, * bConsoleUp, * bConsoleDown, *btactNext, *btactEnd;
|
||||||
CBattleConsole * console;
|
CBattleConsole * console;
|
||||||
CBattleHero * attackingHero, * defendingHero; //fighting heroes
|
CBattleHero * attackingHero, * defendingHero; //fighting heroes
|
||||||
CStackQueue *queue;
|
CStackQueue *queue;
|
||||||
@ -479,6 +479,8 @@ public:
|
|||||||
void bDefencef();
|
void bDefencef();
|
||||||
void bConsoleUpf();
|
void bConsoleUpf();
|
||||||
void bConsoleDownf();
|
void bConsoleDownf();
|
||||||
|
void bTacticNextStack();
|
||||||
|
void bEndTacticPhase();
|
||||||
//end of button handle funcs
|
//end of button handle funcs
|
||||||
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
|
//napisz tu klase odpowiadajaca za wyswietlanie bitwy i obsluge uzytkownika, polecenia ma przekazywac callbackiem
|
||||||
void activate();
|
void activate();
|
||||||
|
@ -1705,14 +1705,14 @@ void CRecruitmentWindow::Cancel()
|
|||||||
void CRecruitmentWindow::sliderMoved(int to)
|
void CRecruitmentWindow::sliderMoved(int to)
|
||||||
{
|
{
|
||||||
buy->block(!to);
|
buy->block(!to);
|
||||||
|
redraw();
|
||||||
}
|
}
|
||||||
void CRecruitmentWindow::clickLeft(tribool down, bool previousState)
|
void CRecruitmentWindow::clickLeft(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
int curx = 192 + 51 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
|
|
||||||
for(int i=0;i<creatures.size();i++)
|
for(int i=0;i<creatures.size();i++)
|
||||||
{
|
{
|
||||||
const int sCREATURE_WIDTH = CREATURE_WIDTH; // gcc -O0 workaround
|
const int sCREATURE_WIDTH = CREATURE_WIDTH; // gcc -O0 workaround
|
||||||
if(isItIn(&genRect(132,sCREATURE_WIDTH,pos.x+curx,pos.y+64),GH.current->motion.x,GH.current->motion.y))
|
if(isItIn(&(Rect(creatures[i].pos) + pos),GH.current->motion.x,GH.current->motion.y))
|
||||||
{
|
{
|
||||||
which = i;
|
which = i;
|
||||||
int newAmount = std::min(amounts[i],creatures[i].amount);
|
int newAmount = std::min(amounts[i],creatures[i].amount);
|
||||||
@ -1725,18 +1725,9 @@ void CRecruitmentWindow::clickLeft(tribool down, bool previousState)
|
|||||||
slider->moveTo(newAmount);
|
slider->moveTo(newAmount);
|
||||||
else
|
else
|
||||||
slider->moveTo(slider->value);
|
slider->moveTo(slider->value);
|
||||||
curx = 192 + 51 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
|
redraw();
|
||||||
for(int j=0;j<creatures.size();j++)
|
|
||||||
{
|
|
||||||
if(which==j)
|
|
||||||
drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(255,0,0));
|
|
||||||
else
|
|
||||||
drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(239,215,123));
|
|
||||||
curx += TOTAL_CREATURE_WIDTH;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
curx += TOTAL_CREATURE_WIDTH;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CRecruitmentWindow::clickRight(tribool down, bool previousState)
|
void CRecruitmentWindow::clickRight(tribool down, bool previousState)
|
||||||
@ -1758,106 +1749,85 @@ void CRecruitmentWindow::clickRight(tribool down, bool previousState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRecruitmentWindow::activate()
|
void CRecruitmentWindow::showAll( SDL_Surface * to )
|
||||||
{
|
{
|
||||||
activateLClick();
|
CIntObject::showAll(to);
|
||||||
activateRClick();
|
|
||||||
buy->activate();
|
|
||||||
max->activate();
|
|
||||||
cancel->activate();
|
|
||||||
slider->activate();
|
|
||||||
GH.statusbar = bar;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRecruitmentWindow::deactivate()
|
|
||||||
{
|
|
||||||
deactivateLClick();
|
|
||||||
deactivateRClick();
|
|
||||||
buy->deactivate();
|
|
||||||
max->deactivate();
|
|
||||||
cancel->deactivate();
|
|
||||||
slider->deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CRecruitmentWindow::show(SDL_Surface * to)
|
|
||||||
{
|
|
||||||
blitAt(bitmap,pos.x,pos.y,to);
|
|
||||||
buy->show(to);
|
|
||||||
max->show(to);
|
|
||||||
cancel->show(to);
|
|
||||||
slider->show(to);
|
|
||||||
|
|
||||||
char pom[15];
|
char pom[15];
|
||||||
SDL_itoa(creatures[which].amount-slider->value,pom,10); //available
|
SDL_itoa(creatures[which].amount-slider->value,pom,10); //available
|
||||||
printAtMiddle(pom,pos.x+205,pos.y+253,FONT_SMALL,zwykly,to);
|
printAtMiddleLoc(pom,205,253,FONT_SMALL,zwykly,to);
|
||||||
SDL_itoa(slider->value,pom,10); //recruit
|
SDL_itoa(slider->value,pom,10); //recruit
|
||||||
printAtMiddle(pom,pos.x+279,pos.y+253,FONT_SMALL,zwykly,to);
|
printAtMiddleLoc(pom,279,253,FONT_SMALL,zwykly,to);
|
||||||
printAtMiddle(CGI->generaltexth->allTexts[16] + " " + CGI->creh->creatures[creatures[which].ID]->namePl,pos.x+243,pos.y+32,FONT_BIG,tytulowy,to); //eg "Recruit Dragon flies"
|
printAtMiddleLoc(CGI->generaltexth->allTexts[16] + " " + CGI->creh->creatures[creatures[which].ID]->namePl,243,32,FONT_BIG,tytulowy,to); //eg "Recruit Dragon flies"
|
||||||
|
|
||||||
int curx = pos.x+122-creatures[which].res.size()*24;
|
int curx = 122-creatures[which].res.size()*24;
|
||||||
for(int i=creatures[which].res.size()-1; i>=0; i--)// decrement used to make gold displayed as first res
|
for(int i=creatures[which].res.size()-1; i>=0; i--)// decrement used to make gold displayed as first res
|
||||||
{
|
{
|
||||||
blitAt(graphics->resources32->ourImages[creatures[which].res[i].first].bitmap,curx,pos.y+243,to);
|
blitAtLoc(graphics->resources32->ourImages[creatures[which].res[i].first].bitmap,curx,243,to);
|
||||||
blitAt(graphics->resources32->ourImages[creatures[which].res[i].first].bitmap,curx+258,pos.y+243,to);
|
blitAtLoc(graphics->resources32->ourImages[creatures[which].res[i].first].bitmap,curx+258,243,to);
|
||||||
SDL_itoa(creatures[which].res[i].second,pom,10);
|
SDL_itoa(creatures[which].res[i].second,pom,10);
|
||||||
printAtMiddle(pom,curx+15,pos.y+287,FONT_SMALL,zwykly,to);
|
printAtMiddleLoc(pom,curx+15,287,FONT_SMALL,zwykly,to);
|
||||||
SDL_itoa(creatures[which].res[i].second * slider->value,pom,10);
|
SDL_itoa(creatures[which].res[i].second * slider->value,pom,10);
|
||||||
printAtMiddle(pom,curx+15+258,pos.y+287,FONT_SMALL,zwykly,to);
|
printAtMiddleLoc(pom,curx+15+258,287,FONT_SMALL,zwykly,to);
|
||||||
curx+=32+16;//size of bitmap + distance between them
|
curx+=32+16;//size of bitmap + distance between them
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i=0; i<creatures.size(); ++i)
|
for(int j=0;j<creatures.size();j++)
|
||||||
creatures[i].pic->show(to);
|
{
|
||||||
|
if(which==j)
|
||||||
bar->show(to);
|
drawBorder(*bitmap,creatures[j].pos,int3(255,0,0));
|
||||||
|
else
|
||||||
|
drawBorder(*bitmap,creatures[j].pos,int3(239,215,123));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> &Recruit, int y_offset)
|
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> &Recruit, int y_offset)
|
||||||
:recruit(Recruit), dwelling(Dwelling), level(Level), dst(Dst)
|
:recruit(Recruit), dwelling(Dwelling), level(Level), dst(Dst)
|
||||||
{
|
{
|
||||||
|
used = LCLICK | RCLICK;
|
||||||
|
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||||
|
|
||||||
which = 0;
|
which = 0;
|
||||||
SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPRCRT.bmp");
|
|
||||||
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
|
bitmap = new CPicture("TPRCRT.bmp");
|
||||||
bitmap = SDL_ConvertSurface(hhlp,screen->format,0);
|
bitmap->colorizeAndConvert(LOCPLINT->playerID);
|
||||||
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
|
bitmap->center();
|
||||||
SDL_FreeSurface(hhlp);
|
pos = (bitmap->pos += Point(0, y_offset));
|
||||||
pos.x = screen->w/2 - bitmap->w/2;
|
|
||||||
pos.y = screen->h/2 - bitmap->h/2+y_offset;
|
bar = new CGStatusBar(8, 370, "APHLFTRT.bmp", 471);
|
||||||
pos.w = bitmap->w;
|
max = new AdventureMapButton(CGI->generaltexth->zelp[553],boost::bind(&CRecruitmentWindow::Max,this),134,313,"IRCBTNS.DEF",SDLK_m);
|
||||||
pos.h = bitmap->h;
|
buy = new AdventureMapButton(CGI->generaltexth->zelp[554],boost::bind(&CRecruitmentWindow::Buy,this),212,313,"IBY6432.DEF",SDLK_RETURN);
|
||||||
bar = new CStatusBar(pos.x+8, pos.y+370, "APHLFTRT.bmp", 471);
|
cancel = new AdventureMapButton(CGI->generaltexth->zelp[555],boost::bind(&CRecruitmentWindow::Cancel,this),290,313,"ICN6432.DEF",SDLK_ESCAPE);
|
||||||
max = new AdventureMapButton(CGI->generaltexth->zelp[553],boost::bind(&CRecruitmentWindow::Max,this),pos.x+134,pos.y+313,"IRCBTNS.DEF",SDLK_m);
|
slider = new CSlider(176,279,135,0,0,0,0,true);
|
||||||
buy = new AdventureMapButton(CGI->generaltexth->zelp[554],boost::bind(&CRecruitmentWindow::Buy,this),pos.x+212,pos.y+313,"IBY6432.DEF",SDLK_RETURN);
|
slider->moved = boost::bind(&CRecruitmentWindow::sliderMoved,this, _1);
|
||||||
cancel = new AdventureMapButton(CGI->generaltexth->zelp[555],boost::bind(&CRecruitmentWindow::Cancel,this),pos.x+290,pos.y+313,"ICN6432.DEF",SDLK_ESCAPE);
|
|
||||||
slider = new CSlider(pos.x+176,pos.y+279,135,boost::bind(&CRecruitmentWindow::sliderMoved,this, _1),0,0,0,true);
|
|
||||||
|
|
||||||
initCres();
|
initCres();
|
||||||
|
|
||||||
printAtMiddle(CGI->generaltexth->allTexts[346],113,232,FONT_SMALL,zwykly,bitmap); //cost per troop t
|
printAtMiddle(CGI->generaltexth->allTexts[346],113,232,FONT_SMALL,zwykly,*bitmap); //cost per troop t
|
||||||
printAtMiddle(CGI->generaltexth->allTexts[465],205,233,FONT_SMALL,zwykly,bitmap); //available t
|
printAtMiddle(CGI->generaltexth->allTexts[465],205,233,FONT_SMALL,zwykly,*bitmap); //available t
|
||||||
printAtMiddle(CGI->generaltexth->allTexts[16],279,233,FONT_SMALL,zwykly,bitmap); //recruit t
|
printAtMiddle(CGI->generaltexth->allTexts[16],279,233,FONT_SMALL,zwykly,*bitmap); //recruit t
|
||||||
printAtMiddle(CGI->generaltexth->allTexts[466],371,232,FONT_SMALL,zwykly,bitmap); //total cost t
|
printAtMiddle(CGI->generaltexth->allTexts[466],371,232,FONT_SMALL,zwykly,*bitmap); //total cost t
|
||||||
drawBorder(bitmap,172,222,67,42,int3(239,215,123));
|
drawBorder(*bitmap,172,222,67,42,int3(239,215,123));
|
||||||
drawBorder(bitmap,246,222,67,42,int3(239,215,123));
|
drawBorder(*bitmap,246,222,67,42,int3(239,215,123));
|
||||||
drawBorder(bitmap,64,222,99,76,int3(239,215,123));
|
drawBorder(*bitmap,64,222,99,76,int3(239,215,123));
|
||||||
drawBorder(bitmap,322,222,99,76,int3(239,215,123));
|
drawBorder(*bitmap,322,222,99,76,int3(239,215,123));
|
||||||
drawBorder(bitmap,133,312,66,34,int3(173,142,66));
|
drawBorder(*bitmap,133,312,66,34,int3(173,142,66));
|
||||||
drawBorder(bitmap,211,312,66,34,int3(173,142,66));
|
drawBorder(*bitmap,211,312,66,34,int3(173,142,66));
|
||||||
drawBorder(bitmap,289,312,66,34,int3(173,142,66));
|
drawBorder(*bitmap,289,312,66,34,int3(173,142,66));
|
||||||
|
|
||||||
//border for creatures
|
//border for creatures
|
||||||
int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
|
int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
|
||||||
for(int i=0;i<creatures.size();i++)
|
for(int i=0;i<creatures.size();i++)
|
||||||
{
|
{
|
||||||
creatures[i].pos.x = curx;
|
creatures[i].pos.x = curx-1;
|
||||||
creatures[i].pos.y = 65;
|
creatures[i].pos.y = 65 - 1;
|
||||||
creatures[i].pos.w = 100;
|
creatures[i].pos.w = 100 + 2;
|
||||||
creatures[i].pos.h = 130;
|
creatures[i].pos.h = 130 + 2;
|
||||||
if(which==i)
|
// if(which==i)
|
||||||
drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(255,0,0));
|
// drawBorder(*bitmap,curx-1,64,CREATURE_WIDTH,132,int3(255,0,0));
|
||||||
else
|
// else
|
||||||
drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(239,215,123));
|
// drawBorder(*bitmap,curx-1,64,CREATURE_WIDTH,132,int3(239,215,123));
|
||||||
creatures[i].pic = new CCreaturePic(pos.x+curx, pos.y+65, CGI->creh->creatures[creatures[i].ID]);
|
creatures[i].pic = new CCreaturePic(curx, 65, CGI->creh->creatures[creatures[i].ID]);
|
||||||
curx += TOTAL_CREATURE_WIDTH;
|
curx += TOTAL_CREATURE_WIDTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1871,18 +1841,13 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co
|
|||||||
|
|
||||||
CRecruitmentWindow::~CRecruitmentWindow()
|
CRecruitmentWindow::~CRecruitmentWindow()
|
||||||
{
|
{
|
||||||
cleanCres();
|
|
||||||
delete max;
|
|
||||||
delete buy;
|
|
||||||
delete cancel;
|
|
||||||
SDL_FreeSurface(bitmap);
|
|
||||||
delete slider;
|
|
||||||
delete bar;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRecruitmentWindow::initCres()
|
void CRecruitmentWindow::initCres()
|
||||||
{
|
{
|
||||||
cleanCres();
|
creatures.clear();
|
||||||
|
amounts.clear();
|
||||||
|
|
||||||
for(int i=0; i<dwelling->creatures.size(); i++)
|
for(int i=0; i<dwelling->creatures.size(); i++)
|
||||||
{
|
{
|
||||||
if(level >= 0 && i != level)
|
if(level >= 0 && i != level)
|
||||||
@ -1907,16 +1872,6 @@ void CRecruitmentWindow::initCres()
|
|||||||
slider->setAmount(std::min(amounts[which],creatures[which].amount));
|
slider->setAmount(std::min(amounts[which],creatures[which].amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRecruitmentWindow::cleanCres()
|
|
||||||
{
|
|
||||||
for(int i=0;i<creatures.size();i++)
|
|
||||||
{
|
|
||||||
delete creatures[i].pic;
|
|
||||||
}
|
|
||||||
creatures.clear();
|
|
||||||
amounts.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int val)
|
CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int val)
|
||||||
{
|
{
|
||||||
last = Last;
|
last = Last;
|
||||||
@ -6556,7 +6511,7 @@ void MoraleLuckBox::set(const CBonusSystemNode *node)
|
|||||||
text += CGI->generaltexth->arraytxt[noneTxtId];
|
text += CGI->generaltexth->arraytxt[noneTxtId];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (node->nodeType == CBonusSystemNode::STACK &&
|
if (node->nodeType == CBonusSystemNode::STACK_INSTANCE &&
|
||||||
(node->hasBonusOfType (Bonus::UNDEAD) || node->hasBonusOfType(Bonus::BLOCK_MORALE) || node->hasBonusOfType(Bonus::NON_LIVING))) //it's a creature window
|
(node->hasBonusOfType (Bonus::UNDEAD) || node->hasBonusOfType(Bonus::BLOCK_MORALE) || node->hasBonusOfType(Bonus::NON_LIVING))) //it's a creature window
|
||||||
{
|
{
|
||||||
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
|
||||||
|
@ -471,8 +471,8 @@ public:
|
|||||||
boost::function<void(int,int)> recruit; //void (int ID, int amount) <-- call to recruit creatures
|
boost::function<void(int,int)> recruit; //void (int ID, int amount) <-- call to recruit creatures
|
||||||
CSlider *slider; //for selecting amount
|
CSlider *slider; //for selecting amount
|
||||||
AdventureMapButton *max, *buy, *cancel;
|
AdventureMapButton *max, *buy, *cancel;
|
||||||
SDL_Surface *bitmap; //background
|
CPicture *bitmap; //background
|
||||||
CStatusBar *bar;
|
CGStatusBar *bar;
|
||||||
int which; //which creature is active
|
int which; //which creature is active
|
||||||
|
|
||||||
const CGDwelling *dwelling;
|
const CGDwelling *dwelling;
|
||||||
@ -486,11 +486,7 @@ public:
|
|||||||
void sliderMoved(int to);
|
void sliderMoved(int to);
|
||||||
void clickLeft(tribool down, bool previousState);
|
void clickLeft(tribool down, bool previousState);
|
||||||
void clickRight(tribool down, bool previousState);
|
void clickRight(tribool down, bool previousState);
|
||||||
void activate();
|
void showAll(SDL_Surface * to);
|
||||||
void deactivate();
|
|
||||||
void show(SDL_Surface * to);
|
|
||||||
void showAll(SDL_Surface * to){show(to);};
|
|
||||||
void cleanCres();
|
|
||||||
void initCres();
|
void initCres();
|
||||||
CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor
|
CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> & Recruit, int y_offset = 0); //creatures - pairs<creature_ID,amount> //c-tor
|
||||||
~CRecruitmentWindow(); //d-tor
|
~CRecruitmentWindow(); //d-tor
|
||||||
|
@ -69,4 +69,12 @@ BattleAction BattleAction::makeMove(const CStack *stack, THex dest)
|
|||||||
ba.stackNumber = stack->ID;
|
ba.stackNumber = stack->ID;
|
||||||
ba.destinationTile = dest;
|
ba.destinationTile = dest;
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BattleAction BattleAction::makeEndOFTacticPhase(ui8 side)
|
||||||
|
{
|
||||||
|
BattleAction ba;
|
||||||
|
ba.side = side;
|
||||||
|
ba.actionType = END_TACTIC_PHASE;
|
||||||
|
return ba;
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@ struct DLL_EXPORT BattleAction
|
|||||||
ui32 stackNumber;//stack ID, -1 left hero, -2 right hero,
|
ui32 stackNumber;//stack ID, -1 left hero, -2 right hero,
|
||||||
enum ActionType
|
enum ActionType
|
||||||
{
|
{
|
||||||
INVALID = -1, NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
|
END_TACTIC_PHASE = -2, INVALID = -1, NO_ACTION = 0, HERO_SPELL, WALK, DEFEND, RETREAT, SURRENDER, WALK_AND_ATTACK, SHOOT, WAIT, CATAPULT, MONSTER_SPELL, BAD_MORALE, STACK_HEAL
|
||||||
};
|
};
|
||||||
ui8 actionType; //use ActionType enum for values
|
ui8 actionType; //use ActionType enum for values
|
||||||
//10 = Monster casts a spell (i.e. Faerie Dragons) 11 - Bad morale freeze 12 - stacks heals another stack
|
//10 = Monster casts a spell (i.e. Faerie Dragons) 11 - Bad morale freeze 12 - stacks heals another stack
|
||||||
@ -39,5 +39,6 @@ struct DLL_EXPORT BattleAction
|
|||||||
static BattleAction makeMeleeAttack(const CStack *stack, const CStack * attacked, THex attackFrom = THex::INVALID);
|
static BattleAction makeMeleeAttack(const CStack *stack, const CStack * attacked, THex attackFrom = THex::INVALID);
|
||||||
static BattleAction makeShotAttack(const CStack *shooter, const CStack *target);
|
static BattleAction makeShotAttack(const CStack *shooter, const CStack *target);
|
||||||
static BattleAction makeMove(const CStack *stack, THex dest);
|
static BattleAction makeMove(const CStack *stack, THex dest);
|
||||||
|
static BattleAction makeEndOFTacticPhase(ui8 side);
|
||||||
};
|
};
|
||||||
#endif // __BATTLEACTION_H__
|
#endif // __BATTLEACTION_H__
|
||||||
|
@ -315,11 +315,15 @@ std::vector<THex> BattleInfo::getAccessibility(const CStack * stack, bool addOcc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < BFIELD_SIZE ; ++i) {
|
for (int i=0; i < BFIELD_SIZE ; ++i)
|
||||||
if(
|
{
|
||||||
( ( !addOccupiable && dist[i] <= stack->Speed() && ac[i] ) || ( addOccupiable && dist[i] <= stack->Speed() && isAccessible(i, ac, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), true) ) )//we can reach it
|
bool rangeFits = tacticDistance
|
||||||
|| (vstd::contains(occupyable, i) && ( dist[ i + (stack->attackerOwned ? 1 : -1 ) ] <= stack->Speed() ) &&
|
? isInTacticRange(i)
|
||||||
ac[i + (stack->attackerOwned ? 1 : -1 )] ) //it's occupyable and we can reach adjacent hex
|
: dist[i] <= stack->Speed();
|
||||||
|
|
||||||
|
if( ( !addOccupiable && rangeFits && ac[i] )
|
||||||
|
|| ( addOccupiable && rangeFits && isAccessible(i, ac, stack->doubleWide(), stack->attackerOwned, stack->hasBonusOfType(Bonus::FLYING), true) )//we can reach it
|
||||||
|
|| (vstd::contains(occupyable, i) && (!tacticDistance && dist[ i + (stack->attackerOwned ? 1 : -1 ) ] <= stack->Speed() ) && ac[i + (stack->attackerOwned ? 1 : -1 )] ) //it's occupyable and we can reach adjacent hex
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ret.push_back(i);
|
ret.push_back(i);
|
||||||
@ -501,17 +505,17 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
|
|||||||
{
|
{
|
||||||
if(shooting)
|
if(shooting)
|
||||||
{
|
{
|
||||||
additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 1) / 100.0f;
|
additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::ARCHERY) / 100.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 22) / 100.0f;
|
additiveBonus += attackerHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::OFFENCE) / 100.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(defendingHero)
|
if(defendingHero)
|
||||||
{
|
{
|
||||||
multBonus *= (std::max(0, 100-defendingHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 23))) / 100.0f;
|
multBonus *= (std::max(0, 100-defendingHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::ARMORER))) / 100.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
//handling hate effect
|
//handling hate effect
|
||||||
@ -838,7 +842,7 @@ ui32 BattleInfo::calculateSpellBonus(ui32 baseDamage, const CSpell * sp, const C
|
|||||||
//applying sorcery secondary skill
|
//applying sorcery secondary skill
|
||||||
if(caster)
|
if(caster)
|
||||||
{
|
{
|
||||||
ret *= (100.f + caster->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 25)) / 100.0f; //sorcery
|
ret *= (100.f + caster->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::SORCERY)) / 100.0f;
|
||||||
ret *= (100.f + caster->valOfBonuses(Bonus::SPELL_DAMAGE) + caster->valOfBonuses(Bonus::SPECIFIC_SPELL_DAMAGE, sp->id)) / 100.0f;
|
ret *= (100.f + caster->valOfBonuses(Bonus::SPELL_DAMAGE) + caster->valOfBonuses(Bonus::SPECIFIC_SPELL_DAMAGE, sp->id)) / 100.0f;
|
||||||
|
|
||||||
if(sp->air)
|
if(sp->air)
|
||||||
@ -1588,12 +1592,28 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int terType, const
|
|||||||
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
curB->addNewBonus(makeFeature(Bonus::PRIMARY_SKILL, Bonus::ONE_BATTLE, PrimarySkill::DEFENSE, 1, Bonus::TERRAIN_NATIVE)->addLimiter(nativeTerrain));
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int tacticLvls[2] = {0};
|
||||||
|
for(int i = 0; i < ARRAY_COUNT(tacticLvls); i++)
|
||||||
|
{
|
||||||
|
if(heroes[i])
|
||||||
|
tacticLvls[i] += heroes[i]->getSecSkillLevel(CGHeroInstance::TACTICS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(int diff = tacticLvls[0] - tacticLvls[1])
|
||||||
|
{
|
||||||
|
curB->tacticsSide = diff < 0;
|
||||||
|
curB->tacticDistance = std::abs(diff)*2 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return curB;
|
return curB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BattleInfo::isInTacticRange( THex dest ) const
|
||||||
|
{
|
||||||
|
|
||||||
|
return ((tacticsSide && dest.getX() > 0 && dest.getX() <= tacticDistance)
|
||||||
|
|| (!tacticsSide && dest.getX() < BFIELD_WIDTH - 1 && dest.getX() >= BFIELD_WIDTH - tacticDistance - 1));
|
||||||
|
}
|
||||||
|
|
||||||
CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
|
CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
|
||||||
: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
|
: base(Base), ID(I), owner(O), slot(S), attackerOwned(AO),
|
||||||
@ -1602,11 +1622,13 @@ CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)
|
|||||||
assert(base);
|
assert(base);
|
||||||
type = base->type;
|
type = base->type;
|
||||||
count = baseAmount = base->count;
|
count = baseAmount = base->count;
|
||||||
|
nodeType = STACK_BATTLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CStack::CStack()
|
CStack::CStack()
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
|
nodeType = STACK_BATTLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S)
|
CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S)
|
||||||
@ -1614,6 +1636,7 @@ CStack::CStack(const CStackBasicDescriptor *stack, int O, int I, bool AO, int S)
|
|||||||
{
|
{
|
||||||
type = stack->type;
|
type = stack->type;
|
||||||
count = baseAmount = stack->count;
|
count = baseAmount = stack->count;
|
||||||
|
nodeType = STACK_BATTLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStack::init()
|
void CStack::init()
|
||||||
|
@ -63,12 +63,16 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
|||||||
SiegeInfo si;
|
SiegeInfo si;
|
||||||
si32 battlefieldType;
|
si32 battlefieldType;
|
||||||
|
|
||||||
|
ui8 tacticsSide; //which side is requested to play tactics phase
|
||||||
|
ui8 tacticDistance; //how many hexes we can go forward (1 = only hexes adjacent to margin line)
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & sides & round & activeStack & siege & town & tile & stacks & belligerents & obstacles
|
h & sides & round & activeStack & siege & town & tile & stacks & belligerents & obstacles
|
||||||
& castSpells & si & battlefieldType;
|
& castSpells & si & battlefieldType;
|
||||||
h & heroes;
|
h & heroes;
|
||||||
h & usedSpellsHistory;
|
h & usedSpellsHistory;
|
||||||
|
h & tacticsSide & tacticDistance;
|
||||||
h & static_cast<CBonusSystemNode&>(*this);
|
h & static_cast<CBonusSystemNode&>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +121,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
|
|||||||
si8 battleMaxSpellLevel() const; //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, SPELL_LEVELS is returned
|
si8 battleMaxSpellLevel() const; //calculates maximum spell level possible to be cast on battlefield - takes into account artifacts of both heroes; if no effects are set, SPELL_LEVELS is returned
|
||||||
void localInit();
|
void localInit();
|
||||||
static BattleInfo * setupBattle( int3 tile, int terrain, int terType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
|
static BattleInfo * setupBattle( int3 tile, int terrain, int terType, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town );
|
||||||
|
bool isInTacticRange( THex dest ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT CStack : public CBonusSystemNode, public CStackBasicDescriptor
|
class DLL_EXPORT CStack : public CBonusSystemNode, public CStackBasicDescriptor
|
||||||
|
@ -585,23 +585,23 @@ void CArtHandler::addBonuses()
|
|||||||
giveArtBonus(53,Bonus::SIGHT_RADIOUS,+1);//Spyglass
|
giveArtBonus(53,Bonus::SIGHT_RADIOUS,+1);//Spyglass
|
||||||
|
|
||||||
//necromancy bonus
|
//necromancy bonus
|
||||||
giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5,12, Bonus::ADDITIVE_VALUE);//Amulet of the Undertaker
|
giveArtBonus(54,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Amulet of the Undertaker
|
||||||
giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10,12, Bonus::ADDITIVE_VALUE);//Vampire's Cowl
|
giveArtBonus(55,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Vampire's Cowl
|
||||||
giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15,12, Bonus::ADDITIVE_VALUE);//Dead Man's Boots
|
giveArtBonus(56,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::NECROMANCY, Bonus::ADDITIVE_VALUE);//Dead Man's Boots
|
||||||
|
|
||||||
giveArtBonus(57,Bonus::MAGIC_RESISTANCE,+5);//Garniture of Interference
|
giveArtBonus(57,Bonus::MAGIC_RESISTANCE,+5);//Garniture of Interference
|
||||||
giveArtBonus(58,Bonus::MAGIC_RESISTANCE,+10);//Surcoat of Counterpoise
|
giveArtBonus(58,Bonus::MAGIC_RESISTANCE,+10);//Surcoat of Counterpoise
|
||||||
giveArtBonus(59,Bonus::MAGIC_RESISTANCE,+15);//Boots of Polarity
|
giveArtBonus(59,Bonus::MAGIC_RESISTANCE,+15);//Boots of Polarity
|
||||||
|
|
||||||
//archery bonus
|
//archery bonus
|
||||||
giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5,1, Bonus::ADDITIVE_VALUE);//Bow of Elven Cherrywood
|
giveArtBonus(60,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bow of Elven Cherrywood
|
||||||
giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,1, Bonus::ADDITIVE_VALUE);//Bowstring of the Unicorn's Mane
|
giveArtBonus(61,Bonus::SECONDARY_SKILL_PREMY,+10,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Bowstring of the Unicorn's Mane
|
||||||
giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,1, Bonus::ADDITIVE_VALUE);//Angel Feather Arrows
|
giveArtBonus(62,Bonus::SECONDARY_SKILL_PREMY,+15,CGHeroInstance::ARCHERY, Bonus::ADDITIVE_VALUE);//Angel Feather Arrows
|
||||||
|
|
||||||
//eagle eye bonus
|
//eagle eye bonus
|
||||||
giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5,11, Bonus::ADDITIVE_VALUE);//Bird of Perception
|
giveArtBonus(63,Bonus::SECONDARY_SKILL_PREMY,+5, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Bird of Perception
|
||||||
giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10,11, Bonus::ADDITIVE_VALUE);//Stoic Watchman
|
giveArtBonus(64,Bonus::SECONDARY_SKILL_PREMY,+10, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Stoic Watchman
|
||||||
giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15,11, Bonus::ADDITIVE_VALUE);//Emblem of Cognizance
|
giveArtBonus(65,Bonus::SECONDARY_SKILL_PREMY,+15, CGHeroInstance::EAGLE_EYE, Bonus::ADDITIVE_VALUE);//Emblem of Cognizance
|
||||||
|
|
||||||
//reducing cost of surrendering
|
//reducing cost of surrendering
|
||||||
giveArtBonus(66,Bonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal
|
giveArtBonus(66,Bonus::SURRENDER_DISCOUNT,+10);//Statesman's Medal
|
||||||
|
@ -939,7 +939,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
|
|||||||
loadToIt (curVal, src, it, 4);
|
loadToIt (curVal, src, it, 4);
|
||||||
if (curVal == 1)
|
if (curVal == 1)
|
||||||
{
|
{
|
||||||
b.limiter.reset (new ExpRankLimiter(i));
|
b.limiter.reset (new RankRangeLimiter(i));
|
||||||
bl.push_back(new Bonus(b));
|
bl.push_back(new Bonus(b));
|
||||||
break; //never turned off it seems
|
break; //never turned off it seems
|
||||||
}
|
}
|
||||||
@ -954,7 +954,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
|
|||||||
if (curVal > lastVal) //threshold, add last bonus
|
if (curVal > lastVal) //threshold, add last bonus
|
||||||
{
|
{
|
||||||
b.val = lastVal;
|
b.val = lastVal;
|
||||||
b.limiter.reset (new ExpRankLimiter(i));
|
b.limiter.reset (new RankRangeLimiter(i));
|
||||||
bl.push_back(new Bonus(b));
|
bl.push_back(new Bonus(b));
|
||||||
lastLev = i; //start new range from here, i = previous rank
|
lastLev = i; //start new range from here, i = previous rank
|
||||||
}
|
}
|
||||||
|
@ -422,7 +422,7 @@ void CStackInstance::init()
|
|||||||
type = NULL;
|
type = NULL;
|
||||||
idRand = -1;
|
idRand = -1;
|
||||||
_armyObj = NULL;
|
_armyObj = NULL;
|
||||||
nodeType = STACK;
|
nodeType = STACK_INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CStackInstance::getQuantityID() const
|
int CStackInstance::getQuantityID() const
|
||||||
|
@ -690,13 +690,11 @@ int CGHeroInstance::maxMovePoints(bool onLand) const
|
|||||||
double modifier = 0;
|
double modifier = 0;
|
||||||
if(onLand)
|
if(onLand)
|
||||||
{
|
{
|
||||||
//logistics:
|
modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, LOGISTICS) / 100.0f;
|
||||||
modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 2) / 100.0f;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//navigation:
|
modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, NAVIGATION) / 100.0f;
|
||||||
modifier = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 5) / 100.0f;
|
|
||||||
}
|
}
|
||||||
return int(base + base*modifier) + bonus;
|
return int(base + base*modifier) + bonus;
|
||||||
}
|
}
|
||||||
@ -1215,20 +1213,21 @@ void CGHeroInstance::updateSkill(int which, int val)
|
|||||||
case 27: //First Aid
|
case 27: //First Aid
|
||||||
skillVal = 25 + 25*val; break;
|
skillVal = 25 + 25*val; break;
|
||||||
}
|
}
|
||||||
if (skillVal) //we don't need bonuses of other types here
|
|
||||||
|
|
||||||
|
int skillValType = skillVal ? Bonus::BASE_NUMBER : Bonus::INDEPENDENT_MIN;
|
||||||
|
if(Bonus * b = bonuses.getFirst(Selector::typeSybtype(Bonus::SECONDARY_SKILL_PREMY, which) && Selector::sourceType(Bonus::SECONDARY_SKILL))) //only local hero bonus
|
||||||
{
|
{
|
||||||
Bonus * b = bonuses.getFirst(Selector::typeSybtype(Bonus::SECONDARY_SKILL_PREMY, which) && Selector::sourceType(Bonus::SECONDARY_SKILL));
|
b->val = skillVal;
|
||||||
if (b) //only local hero bonus
|
b->valType = skillValType;
|
||||||
{
|
|
||||||
b->val = skillVal;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Bonus *bonus = new Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, Bonus::BASE_NUMBER);
|
|
||||||
bonus->source = Bonus::SECONDARY_SKILL;
|
|
||||||
addNewBonus(bonus);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bonus *bonus = new Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, id, skillVal, ID, which, skillValType);
|
||||||
|
bonus->source = Bonus::SECONDARY_SKILL;
|
||||||
|
addNewBonus(bonus);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
|
void CGHeroInstance::setPropertyDer( ui8 what, ui32 val )
|
||||||
{
|
{
|
||||||
@ -1312,7 +1311,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b
|
|||||||
// Hero knows necromancy.
|
// Hero knows necromancy.
|
||||||
if (necromancyLevel > 0)
|
if (necromancyLevel > 0)
|
||||||
{
|
{
|
||||||
double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, 12)/100.0;
|
double necromancySkill = valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, NECROMANCY)/100.0;
|
||||||
amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
|
amin(necromancySkill, 1.0); //it's impossible to raise more creatures than all...
|
||||||
const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
|
const std::map<ui32,si32> &casualties = battleResult.casualties[!battleResult.winner];
|
||||||
ui32 raisedUnits = 0;
|
ui32 raisedUnits = 0;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include "CHeroHandler.h"
|
#include "CHeroHandler.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
|
#include "BattleState.h"
|
||||||
|
|
||||||
#define FOREACH_CONST_PARENT(pname) TCNodes parents; getParents(parents); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
|
#define FOREACH_CONST_PARENT(pname) TCNodes parents; getParents(parents); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
|
||||||
#define FOREACH_PARENT(pname) TNodes parents; getParents(parents); BOOST_FOREACH(CBonusSystemNode *pname, parents)
|
#define FOREACH_PARENT(pname) TNodes parents; getParents(parents); BOOST_FOREACH(CBonusSystemNode *pname, parents)
|
||||||
@ -29,6 +30,8 @@ int DLL_EXPORT BonusList::totalValue() const
|
|||||||
int additive = 0;
|
int additive = 0;
|
||||||
int indepMax = 0;
|
int indepMax = 0;
|
||||||
bool hasIndepMax = false;
|
bool hasIndepMax = false;
|
||||||
|
int indepMin = 0;
|
||||||
|
bool hasIndepMin = false;
|
||||||
|
|
||||||
BOOST_FOREACH(Bonus *i, *this)
|
BOOST_FOREACH(Bonus *i, *this)
|
||||||
{
|
{
|
||||||
@ -57,16 +60,33 @@ int DLL_EXPORT BonusList::totalValue() const
|
|||||||
amax(indepMax, i->val);
|
amax(indepMax, i->val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case Bonus::INDEPENDENT_MIN:
|
||||||
|
if (!indepMin)
|
||||||
|
{
|
||||||
|
indepMin = i->val;
|
||||||
|
hasIndepMin = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
amax(indepMin, i->val);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int modifiedBase = base + (base * percentToBase) / 100;
|
int modifiedBase = base + (base * percentToBase) / 100;
|
||||||
modifiedBase += additive;
|
modifiedBase += additive;
|
||||||
int valFirst = (modifiedBase * (100 + percentToAll)) / 100;
|
int valFirst = (modifiedBase * (100 + percentToAll)) / 100;
|
||||||
|
|
||||||
|
if(hasIndepMin && hasIndepMax)
|
||||||
|
assert(indepMin < indepMax);
|
||||||
if (hasIndepMax)
|
if (hasIndepMax)
|
||||||
return std::max(valFirst, indepMax);
|
amax(valFirst, indepMax);
|
||||||
else
|
if (hasIndepMax)
|
||||||
return valFirst;
|
amin(valFirst, indepMin);
|
||||||
|
|
||||||
|
return valFirst;
|
||||||
}
|
}
|
||||||
const DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &selector) const
|
const DLL_EXPORT Bonus * BonusList::getFirst(const CSelector &selector) const
|
||||||
{
|
{
|
||||||
@ -600,15 +620,29 @@ namespace Selector
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CStackInstance * retreiveStackInstance(const CBonusSystemNode *node)
|
||||||
|
{
|
||||||
|
switch(node->nodeType)
|
||||||
|
{
|
||||||
|
case CBonusSystemNode::STACK_INSTANCE:
|
||||||
|
return (static_cast<const CStackInstance *>(node));
|
||||||
|
case CBonusSystemNode::STACK_BATTLE:
|
||||||
|
return (static_cast<const CStack*>(node))->base;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const CCreature * retrieveCreature(const CBonusSystemNode *node)
|
const CCreature * retrieveCreature(const CBonusSystemNode *node)
|
||||||
{
|
{
|
||||||
switch(node->nodeType)
|
switch(node->nodeType)
|
||||||
{
|
{
|
||||||
case CBonusSystemNode::CREATURE:
|
case CBonusSystemNode::CREATURE:
|
||||||
return (static_cast<const CCreature *>(node));
|
return (static_cast<const CCreature *>(node));
|
||||||
case CBonusSystemNode::STACK:
|
|
||||||
return (static_cast<const CStackInstance *>(node))->type;
|
|
||||||
default:
|
default:
|
||||||
|
const CStackInstance *csi = retreiveStackInstance(node);
|
||||||
|
if(csi)
|
||||||
|
return csi->type;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -655,24 +689,11 @@ bool ILimiter::limit(const Bonus *b, const CBonusSystemNode &node) const /*retur
|
|||||||
|
|
||||||
bool CCreatureTypeLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
bool CCreatureTypeLimiter::limit(const Bonus *b, const CBonusSystemNode &node) const
|
||||||
{
|
{
|
||||||
switch (node.nodeType)
|
const CCreature *c = retrieveCreature(&node);
|
||||||
{
|
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
||||||
case CBonusSystemNode::STACK:
|
//drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
||||||
{
|
|
||||||
const CCreature *c = (static_cast<const CStackInstance *>(&node))->type;
|
|
||||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
|
||||||
} //drop bonus if it's not our creature and (we dont check upgrades or its not our upgrade)
|
|
||||||
break;
|
|
||||||
case CBonusSystemNode::CREATURE:
|
|
||||||
{
|
|
||||||
const CCreature *c = (static_cast<const CCreature *>(&node));
|
|
||||||
return c != creature && (!includeUpgrades || !creature->isMyUpgrade(c));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/)
|
CCreatureTypeLimiter::CCreatureTypeLimiter(const CCreature &Creature, ui8 IncludeUpgrades /*= true*/)
|
||||||
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
:creature(&Creature), includeUpgrades(IncludeUpgrades)
|
||||||
{
|
{
|
||||||
@ -773,12 +794,15 @@ bool CreatureAlignmentLimiter::limit(const Bonus *b, const CBonusSystemNode &nod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpRankLimiter::ExpRankLimiter(ui8 Rank)
|
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
|
||||||
:rank(Rank)
|
:minRank(Min), maxRank(Max)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RankRangeLimiter::RankRangeLimiter(ui8 Min, ui8 Max)
|
bool RankRangeLimiter::limit( const Bonus *b, const CBonusSystemNode &node ) const
|
||||||
:min(Min), max(Max)
|
|
||||||
{
|
{
|
||||||
|
const CStackInstance *csi = retreiveStackInstance(&node);
|
||||||
|
if(csi)
|
||||||
|
return csi->getExpRank() < minRank || csi->getExpRank() > maxRank;
|
||||||
|
return true;
|
||||||
}
|
}
|
@ -213,7 +213,8 @@ struct DLL_EXPORT Bonus
|
|||||||
BASE_NUMBER,
|
BASE_NUMBER,
|
||||||
PERCENT_TO_ALL,
|
PERCENT_TO_ALL,
|
||||||
PERCENT_TO_BASE,
|
PERCENT_TO_BASE,
|
||||||
INDEPENDENT_MAX //used for SPELL bonus
|
INDEPENDENT_MAX, //used for SPELL bonus
|
||||||
|
INDEPENDENT_MIN //used for SECONDARY_SKILL_PREMY bonus
|
||||||
};
|
};
|
||||||
|
|
||||||
ui16 duration; //uses BonusDuration values
|
ui16 duration; //uses BonusDuration values
|
||||||
@ -433,7 +434,7 @@ public:
|
|||||||
|
|
||||||
enum ENodeTypes
|
enum ENodeTypes
|
||||||
{
|
{
|
||||||
UNKNOWN, STACK, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO
|
UNKNOWN, STACK_INSTANCE, STACK_BATTLE, SPECIALITY, ARTIFACT, CREATURE, ARTIFACT_INSTANCE, HERO
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -618,29 +619,17 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT ExpRankLimiter : public ILimiter //applies to creatures with Rank >= rank
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ui8 rank;
|
|
||||||
|
|
||||||
ExpRankLimiter(ui8 Rank);
|
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & rank;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLL_EXPORT RankRangeLimiter : public ILimiter //applies to creatures with min <= Rank <= max
|
class DLL_EXPORT RankRangeLimiter : public ILimiter //applies to creatures with min <= Rank <= max
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ui8 min, max;
|
ui8 minRank, maxRank;
|
||||||
|
|
||||||
RankRangeLimiter(ui8 Min, ui8 Max);
|
RankRangeLimiter(ui8 Min, ui8 Max = 255);
|
||||||
|
bool limit(const Bonus *b, const CBonusSystemNode &node) const OVERRIDE;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & min & max;
|
h & minRank & maxRank;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -243,8 +243,10 @@ DLL_EXPORT void RemoveObject::applyGs( CGameState *gs )
|
|||||||
if(obj->ID==HEROI_TYPE)
|
if(obj->ID==HEROI_TYPE)
|
||||||
{
|
{
|
||||||
CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
|
CGHeroInstance *h = static_cast<CGHeroInstance*>(obj);
|
||||||
|
PlayerState *p = gs->getPlayer(h->tempOwner);
|
||||||
gs->map->heroes -= h;
|
gs->map->heroes -= h;
|
||||||
gs->getPlayer(h->tempOwner)->heroes -= h;
|
p->heroes -= h;
|
||||||
|
h->detachFrom(p);
|
||||||
h->tempOwner = 255; //no one owns beaten hero
|
h->tempOwner = 255; //no one owns beaten hero
|
||||||
|
|
||||||
if(CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown))
|
if(CGTownInstance *t = const_cast<CGTownInstance *>(h->visitedTown))
|
||||||
@ -972,6 +974,12 @@ DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
|||||||
{
|
{
|
||||||
CStack *st = gs->curB->getStack(ba.stackNumber);
|
CStack *st = gs->curB->getStack(ba.stackNumber);
|
||||||
|
|
||||||
|
if(ba.actionType == BattleAction::END_TACTIC_PHASE)
|
||||||
|
{
|
||||||
|
gs->curB->tacticDistance = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(ba.actionType != BattleAction::HERO_SPELL) //don't check for stack if it's custom action by hero
|
if(ba.actionType != BattleAction::HERO_SPELL) //don't check for stack if it's custom action by hero
|
||||||
{
|
{
|
||||||
assert(st);
|
assert(st);
|
||||||
@ -1100,6 +1108,8 @@ DLL_EXPORT void BattleSpellCast::applyGs( CGameState *gs )
|
|||||||
csi->setArmyObj(h);
|
csi->setArmyObj(h);
|
||||||
CStack * summonedStack = gs->curB->generateNewStack(*csi, gs->curB->stacks.size(), !side, 255, pos);
|
CStack * summonedStack = gs->curB->generateNewStack(*csi, gs->curB->stacks.size(), !side, 255, pos);
|
||||||
summonedStack->state.insert(SUMMONED);
|
summonedStack->state.insert(SUMMONED);
|
||||||
|
summonedStack->attachTo(csi);
|
||||||
|
summonedStack->postInit();
|
||||||
//summonedStack->addNewBonus( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
//summonedStack->addNewBonus( makeFeature(HeroBonus::SUMMONED, HeroBonus::ONE_BATTLE, 0, 0, HeroBonus::BONUS_FROM_HERO) );
|
||||||
gs->curB->stacks.push_back(summonedStack);
|
gs->curB->stacks.push_back(summonedStack);
|
||||||
}
|
}
|
||||||
|
@ -352,10 +352,12 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
ui8 loser = sides[!battleResult.data->winner];
|
ui8 loser = sides[!battleResult.data->winner];
|
||||||
|
|
||||||
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
|
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
|
||||||
|
|
||||||
|
|
||||||
sendAndApply(battleResult.data);
|
sendAndApply(battleResult.data);
|
||||||
|
|
||||||
//Eagle Eye secondary skill handling
|
//Eagle Eye secondary skill handling
|
||||||
const CGHeroInstance *vistoriousHero = gs->curB->heroes[battleResult.data->winner];
|
/*const CGHeroInstance *vistoriousHero = gs->curB->heroes[battleResult.data->winner];
|
||||||
if(0 && vistoriousHero)
|
if(0 && vistoriousHero)
|
||||||
{
|
{
|
||||||
if(int eagleEyeLevel = vistoriousHero->getSecSkillLevel(CGHeroInstance::EAGLE_EYE))
|
if(int eagleEyeLevel = vistoriousHero->getSecSkillLevel(CGHeroInstance::EAGLE_EYE))
|
||||||
@ -403,7 +405,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if(!duel)
|
if(!duel)
|
||||||
{
|
{
|
||||||
@ -617,7 +619,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
|
|||||||
tlog1 << "Ended handling connection\n";
|
tlog1 << "Ended handling connection\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int CGameHandler::moveStack(int stack, int dest)
|
int CGameHandler::moveStack(int stack, THex dest)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -627,6 +629,11 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
assert(curStack);
|
assert(curStack);
|
||||||
assert(dest < BFIELD_SIZE);
|
assert(dest < BFIELD_SIZE);
|
||||||
|
|
||||||
|
if (gs->curB->tacticDistance)
|
||||||
|
{
|
||||||
|
assert(gs->curB->isInTacticRange(dest));
|
||||||
|
}
|
||||||
|
|
||||||
//initing necessary tables
|
//initing necessary tables
|
||||||
bool accessibility[BFIELD_SIZE];
|
bool accessibility[BFIELD_SIZE];
|
||||||
std::vector<THex> accessible = gs->curB->getAccessibility(curStack, false);
|
std::vector<THex> accessible = gs->curB->getAccessibility(curStack, false);
|
||||||
@ -645,12 +652,12 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
if(curStack->attackerOwned)
|
if(curStack->attackerOwned)
|
||||||
{
|
{
|
||||||
if(accessibility[dest+1])
|
if(accessibility[dest+1])
|
||||||
dest+=1;
|
dest += THex::RIGHT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(accessibility[dest-1])
|
if(accessibility[dest-1])
|
||||||
dest-=1;
|
dest += THex::LEFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,9 +682,11 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
|
|
||||||
ret = path.second;
|
ret = path.second;
|
||||||
|
|
||||||
|
int creSpeed = gs->curB->tacticDistance ? BFIELD_SIZE : curStack->Speed();
|
||||||
|
|
||||||
if(curStack->hasBonusOfType(Bonus::FLYING))
|
if(curStack->hasBonusOfType(Bonus::FLYING))
|
||||||
{
|
{
|
||||||
if(path.second <= curStack->Speed() && path.first.size() > 0)
|
if(path.second <= creSpeed && path.first.size() > 0)
|
||||||
{
|
{
|
||||||
//inform clients about move
|
//inform clients about move
|
||||||
BattleStackMoved sm;
|
BattleStackMoved sm;
|
||||||
@ -691,7 +700,7 @@ int CGameHandler::moveStack(int stack, int dest)
|
|||||||
}
|
}
|
||||||
else //for non-flying creatures
|
else //for non-flying creatures
|
||||||
{
|
{
|
||||||
int tilesToMove = std::max((int)(path.first.size() - curStack->Speed()), 0);
|
int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
|
||||||
for(int v=path.first.size()-1; v>=tilesToMove; --v)
|
for(int v=path.first.size()-1; v>=tilesToMove; --v)
|
||||||
{
|
{
|
||||||
//inform clients about move
|
//inform clients about move
|
||||||
@ -3099,8 +3108,15 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
{
|
{
|
||||||
tlog1 << "\tMaking action of type " << ba.actionType << std::endl;
|
tlog1 << "\tMaking action of type " << ba.actionType << std::endl;
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
switch(ba.actionType)
|
switch(ba.actionType)
|
||||||
{
|
{
|
||||||
|
case BattleAction::END_TACTIC_PHASE: //wait
|
||||||
|
{
|
||||||
|
sendAndApply(&StartAction(ba));
|
||||||
|
sendAndApply(&EndAction());
|
||||||
|
break;
|
||||||
|
}
|
||||||
case BattleAction::WALK: //walk
|
case BattleAction::WALK: //walk
|
||||||
{
|
{
|
||||||
sendAndApply(&StartAction(ba)); //start movement
|
sendAndApply(&StartAction(ba)); //start movement
|
||||||
@ -4844,12 +4860,8 @@ void CGameHandler::runBattle()
|
|||||||
|
|
||||||
//tactic round
|
//tactic round
|
||||||
{
|
{
|
||||||
if( (gs->curB->heroes[0] && gs->curB->heroes[0]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) ||
|
while(gs->curB->tacticDistance)
|
||||||
( gs->curB->heroes[1] && gs->curB->heroes[1]->getSecSkillLevel(CGHeroInstance::TACTICS)>0) )//someone has tactics
|
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||||
{
|
|
||||||
//TODO: tactic round (round -1)
|
|
||||||
NEW_ROUND;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//spells opening battle
|
//spells opening battle
|
||||||
|
@ -104,7 +104,7 @@ public:
|
|||||||
|
|
||||||
bool isAllowedExchange(int id1, int id2);
|
bool isAllowedExchange(int id1, int id2);
|
||||||
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
|
||||||
int moveStack(int stack, int dest); //returned value - travelled distance
|
int moveStack(int stack, THex dest); //returned value - travelled distance
|
||||||
void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
|
void startBattle(const CArmedInstance *armies[2], int3 tile, const CGHeroInstance *heroes[2], bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
|
||||||
void runBattle();
|
void runBattle();
|
||||||
void checkLossVictory(ui8 player);
|
void checkLossVictory(ui8 player);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include "../lib/map.h"
|
#include "../lib/map.h"
|
||||||
#include "../lib/CGameState.h"
|
#include "../lib/CGameState.h"
|
||||||
#include "../lib/BattleState.h"
|
#include "../lib/BattleState.h"
|
||||||
|
#include "../lib/BattleAction.h"
|
||||||
|
|
||||||
|
|
||||||
#define PLAYER_OWNS(id) (gh->getPlayerAt(c)==gh->getOwner(id))
|
#define PLAYER_OWNS(id) (gh->getPlayerAt(c)==gh->getOwner(id))
|
||||||
@ -209,6 +210,15 @@ bool MakeAction::applyGh( CGameHandler *gh )
|
|||||||
{
|
{
|
||||||
if(!GS(gh)->curB) ERROR_AND_RETURN;
|
if(!GS(gh)->curB) ERROR_AND_RETURN;
|
||||||
if(gh->connections[GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner] != c) ERROR_AND_RETURN;
|
if(gh->connections[GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner] != c) ERROR_AND_RETURN;
|
||||||
|
|
||||||
|
if(GS(gh)->curB->tacticDistance)
|
||||||
|
{
|
||||||
|
if(ba.actionType != BattleAction::WALK && ba.actionType != BattleAction::END_TACTIC_PHASE)
|
||||||
|
ERROR_AND_RETURN;
|
||||||
|
if(gh->connections[GS(gh)->curB->sides[GS(gh)->curB->tacticsSide]] != c)
|
||||||
|
ERROR_AND_RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
return gh->makeBattleAction(ba);
|
return gh->makeBattleAction(ba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user