mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* fixes for moving War Machines
* automatic merging same creatures stacks if needed when moving hero to town garrison * minor improvements
This commit is contained in:
parent
a9617b3dfd
commit
df87b34662
@ -199,27 +199,28 @@ void AdventureMapButton::hover (bool on)
|
||||
}
|
||||
}
|
||||
|
||||
void AdventureMapButton::activate()
|
||||
{
|
||||
// if (active) return;
|
||||
// active=true;
|
||||
activateLClick();
|
||||
activateRClick();
|
||||
activateHover();
|
||||
activateKeys();
|
||||
}
|
||||
void AdventureMapButton::deactivate()
|
||||
{
|
||||
// if (!active) return;
|
||||
// active=false;
|
||||
deactivateLClick();
|
||||
deactivateRClick();
|
||||
deactivateHover();
|
||||
deactivateKeys();
|
||||
}
|
||||
//void AdventureMapButton::activate()
|
||||
//{
|
||||
//// if (active) return;
|
||||
//// active=true;
|
||||
// activateLClick();
|
||||
// activateRClick();
|
||||
// activateHover();
|
||||
// activateKeys();
|
||||
//}
|
||||
//void AdventureMapButton::deactivate()
|
||||
//{
|
||||
//// if (!active) return;
|
||||
//// active=false;
|
||||
// deactivateLClick();
|
||||
// deactivateRClick();
|
||||
// deactivateHover();
|
||||
// deactivateKeys();
|
||||
//}
|
||||
|
||||
void AdventureMapButton::init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key)
|
||||
{
|
||||
used = LCLICK | RCLICK | HOVER | KEYBOARD;
|
||||
callback = Callback;
|
||||
blocked = actOnDown = false;
|
||||
type=2;
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
int curimg; //curently displayed image from imgs
|
||||
virtual void show(SDL_Surface * to);
|
||||
virtual void showAll(SDL_Surface * to);
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
//virtual void activate()=0;
|
||||
//virtual void deactivate()=0;
|
||||
CButtonBase(); //c-tor
|
||||
virtual ~CButtonBase(); //d-tor
|
||||
};
|
||||
@ -63,8 +63,8 @@ public:
|
||||
virtual void clickLeft(tribool down, bool previousState);
|
||||
void hover (bool on);
|
||||
void block(ui8 on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
|
||||
void activate(); // makes button active
|
||||
void deactivate(); // makes button inactive (but doesn't delete)
|
||||
//void activate(); // makes button active
|
||||
//void deactivate(); // makes button inactive (but doesn't delete)
|
||||
|
||||
AdventureMapButton(); //c-tor
|
||||
AdventureMapButton( const std::map<int,std::string> &, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, int key=0, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
|
||||
|
@ -571,7 +571,7 @@ void CTerrainRect::clickRight(tribool down, bool previousState)
|
||||
if(!objs.size())
|
||||
return;
|
||||
|
||||
const CGObjectInstance * obj = objs.front();
|
||||
const CGObjectInstance * obj = objs.back();
|
||||
switch(obj->ID)
|
||||
{
|
||||
case HEROI_TYPE:
|
||||
@ -1728,6 +1728,8 @@ void CAdvMapInt::centerOn(int3 on)
|
||||
LOCPLINT->adventureInt->position = on;
|
||||
LOCPLINT->adventureInt->updateScreen=true;
|
||||
updateMinimap=true;
|
||||
underground.curimg = on.z; //change underground switch button image
|
||||
underground.redraw();
|
||||
}
|
||||
void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
|
@ -270,7 +270,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
|
||||
else if(other->hero && other->highlight)
|
||||
{
|
||||
bool allow = true;
|
||||
if(upg) //moving hero out of town - check if it is allowed
|
||||
if(!upg) //moving hero out of town - check if it is allowed
|
||||
{
|
||||
if(!hero && LOCPLINT->cb->howManyHeroes(false) >= 8)
|
||||
{
|
||||
@ -505,7 +505,7 @@ CCastleInterface::~CCastleInterface()
|
||||
SDL_FreeSurface(townInt);
|
||||
SDL_FreeSurface(cityBg);
|
||||
delete exit;
|
||||
delete split;
|
||||
//delete split;
|
||||
delete hall;
|
||||
delete fort;
|
||||
delete garr;
|
||||
@ -749,7 +749,7 @@ void CCastleInterface::showAll( SDL_Surface * to/*=NULL*/)
|
||||
if(screen->w != 800 || screen->h !=600)
|
||||
CMessage::drawBorder(LOCPLINT->playerID,to,828,628,pos.x-14,pos.y-15);
|
||||
exit->show(to);
|
||||
split->show(to);
|
||||
//split->show(to);
|
||||
}
|
||||
|
||||
void CCastleInterface::townChange()
|
||||
@ -796,7 +796,7 @@ void CCastleInterface::activate()
|
||||
garr->activate();
|
||||
LOCPLINT->statusbar = statusbar;
|
||||
exit->activate();
|
||||
split->activate();
|
||||
//split->activate();
|
||||
for(size_t i=0;i<buildings.size();i++) //XXX pls use iterators or at() but not []
|
||||
{
|
||||
buildings[i]->activate();
|
||||
@ -812,7 +812,7 @@ void CCastleInterface::deactivate()
|
||||
townlist->deactivate();
|
||||
garr->deactivate();
|
||||
exit->deactivate();
|
||||
split->deactivate();
|
||||
//split->deactivate();
|
||||
for(size_t i=0;i<buildings.size();i++) //XXX iterators
|
||||
{
|
||||
buildings[i]->deactivate();
|
||||
|
@ -386,6 +386,9 @@ CGarrisonInt::~CGarrisonInt()
|
||||
}
|
||||
delete sdown;
|
||||
}
|
||||
|
||||
for(size_t i = 0; i<splitButtons.size(); i++)
|
||||
delete splitButtons[i];
|
||||
}
|
||||
|
||||
void CGarrisonInt::show(SDL_Surface * to)
|
||||
@ -459,9 +462,6 @@ void CGarrisonInt::activeteSlots()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i<splitButtons.size(); i++)
|
||||
splitButtons[i]->activate();
|
||||
}
|
||||
void CGarrisonInt::createSlots()
|
||||
{
|
||||
@ -3424,6 +3424,12 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(ourArt) //to prevent selecting empty slots (bugfix to what GrayFace reported)
|
||||
{
|
||||
if(ourArt->id == 3) //catapult cannot be highlighted
|
||||
{
|
||||
std::vector<SComponent *> catapult(1, new SComponent(SComponent::artifact, 3, 0));
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[312], catapult); //The Catapult must be equipped.
|
||||
return;
|
||||
}
|
||||
clicked = true;
|
||||
ourOwner->commonInfo->activeArtPlace = this;
|
||||
}
|
||||
@ -3432,8 +3438,24 @@ void CArtPlace::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if(slotID >= 19) //we are an backpack slot - remove active artifact and put it to the last free pos in backpack
|
||||
{ //TODO: putting artifacts in the middle of backpack (pushing following arts)
|
||||
|
||||
LOCPLINT->cb->swapArtifacts(ourOwner->commonInfo->activeArtPlace->ourOwner->curHero, ourOwner->commonInfo->activeArtPlace->slotID, ourOwner->curHero, ourOwner->curHero->artifacts.size()+19);
|
||||
const CArtifact *cur = ourOwner->commonInfo->activeArtPlace->ourArt;
|
||||
assert(cur); //there is highlighted slot, it must contain an art
|
||||
switch(cur->id)
|
||||
{
|
||||
case 3:
|
||||
//should not happen, catapult cannot be selected
|
||||
break;
|
||||
case 4: case 5: case 6:
|
||||
{
|
||||
std::string text = CGI->generaltexth->allTexts[153];
|
||||
boost::algorithm::replace_first(text, "%s", cur->Name());
|
||||
LOCPLINT->showInfoDialog(text);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOCPLINT->cb->swapArtifacts(ourOwner->commonInfo->activeArtPlace->ourOwner->curHero, ourOwner->commonInfo->activeArtPlace->slotID, ourOwner->curHero, ourOwner->curHero->artifacts.size()+19);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//check if swap is possible
|
||||
else if(this->fitsHere(ourOwner->commonInfo->activeArtPlace->ourArt) && ourOwner->commonInfo->activeArtPlace->fitsHere(this->ourArt))
|
||||
@ -3495,8 +3517,12 @@ bool CArtPlace::fitsHere(const CArtifact * art)
|
||||
{
|
||||
if(!art)
|
||||
return true; //you can have no artifact somewhere
|
||||
if(slotID > 18 || vstd::contains(art->possibleSlots,slotID)) //backpack or right slot
|
||||
if(slotID > 18 && art->id >= 3 && art->id <= 6 //everything can bee placed in backpack exept of War Machines
|
||||
|| vstd::contains(art->possibleSlots,slotID))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
CArtPlace::~CArtPlace()
|
||||
@ -4075,7 +4101,7 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
|
||||
ourBar = new CStatusBar(pos.x + 3, pos.y + 577, "TSTATBAR.bmp", 726);
|
||||
|
||||
//garrison interface
|
||||
garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(69,131), heroInst[0],heroInst[1], true);
|
||||
garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(69,131), heroInst[0],heroInst[1], true, true);
|
||||
|
||||
garr->splitButtons.push_back(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+10,pos.y+132,"TSBTNS.DEF"));
|
||||
garr->splitButtons.push_back(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+740,pos.y+132,"TSBTNS.DEF"));
|
||||
|
53
int3.h
53
int3.h
@ -15,20 +15,28 @@
|
||||
*/
|
||||
|
||||
class CCreature;
|
||||
|
||||
//a few typedefs for CCreatureSet
|
||||
typedef si32 TSlot, TQuantity;
|
||||
typedef ui32 TCreature;
|
||||
typedef std::pair<TCreature, TQuantity> TStack;
|
||||
typedef std::map<TSlot, TStack> TSlots;
|
||||
|
||||
class CCreatureSet //seven combined creatures
|
||||
{
|
||||
public:
|
||||
std::map<si32, std::pair<ui32,si32> > slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
|
||||
bool formation; //false - wide, true - tight
|
||||
bool setCreature (si32 slot, ui32 type, si32 quantity) //slots 0 to 6
|
||||
TSlots slots; //slots[slot_id]=> pair(creature_id,creature_quantity)
|
||||
ui8 formation; //false - wide, true - tight
|
||||
|
||||
bool setCreature (TSlot slot, TCreature type, TQuantity quantity) //slots 0 to 6
|
||||
{
|
||||
slots[slot] = std::pair<ui32, si32>(type, quantity); //brutal force
|
||||
slots[slot] = TStack(type, quantity); //brutal force
|
||||
if (slots.size() > 7) return false;
|
||||
else return true;
|
||||
}
|
||||
si32 getSlotFor(ui32 creature, ui32 slotsAmount=7) const //returns -1 if no slot available
|
||||
TSlot getSlotFor(TCreature creature, ui32 slotsAmount=7) const //returns -1 if no slot available
|
||||
{
|
||||
for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
for(TSlots::const_iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
{
|
||||
if(i->second.first == creature)
|
||||
{
|
||||
@ -44,6 +52,37 @@ public:
|
||||
}
|
||||
return -1; //no slot available
|
||||
}
|
||||
bool mergableStacks(std::pair<TSlot, TSlot> &out, TSlot preferable = -1) //looks for two same stacks, returns slot positions
|
||||
{
|
||||
//try to match creature to our preferred stack
|
||||
if(preferable >= 0 && slots.find(preferable) != slots.end())
|
||||
{
|
||||
TCreature id = slots[preferable].first;
|
||||
for(TSlots::const_iterator j=slots.begin(); j!=slots.end(); ++j)
|
||||
{
|
||||
if(id == j->second.first)
|
||||
{
|
||||
out.first = preferable;
|
||||
out.second = j->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(TSlots::const_iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
{
|
||||
for(TSlots::const_iterator j=slots.begin(); j!=slots.end(); ++j)
|
||||
{
|
||||
if(i->second.first == j->second.first)
|
||||
{
|
||||
out.first = i->first;
|
||||
out.second = j->first;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & slots & formation;
|
||||
@ -54,7 +93,7 @@ public:
|
||||
}
|
||||
void sweep()
|
||||
{
|
||||
for(std::map<si32,std::pair<ui32,si32> >::iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
for(TSlots::iterator i=slots.begin(); i!=slots.end(); ++i)
|
||||
{
|
||||
if(!i->second.second)
|
||||
{
|
||||
|
@ -2097,6 +2097,7 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
|
||||
|| dp.turns > turn
|
||||
|| (dp.turns >= turn && dp.moveRemains < remains)) //this route is faster
|
||||
{
|
||||
assert(&dp != cp->theNodeBefore); //two tiles can't point to each other
|
||||
dp.moveRemains = remains;
|
||||
dp.turns = turn;
|
||||
dp.theNodeBefore = cp;
|
||||
|
@ -2162,10 +2162,21 @@ bool CGameHandler::garrisonSwap( si32 tid )
|
||||
int pos = csn.getSlotFor(cso.slots.begin()->second.first);
|
||||
if(pos<0)
|
||||
{
|
||||
complain("Cannot make garrison swap, not enough free slots!");
|
||||
return false;
|
||||
//try to merge two other stacks to make place
|
||||
std::pair<TSlot, TSlot> toMerge;
|
||||
if(csn.mergableStacks(toMerge, cso.slots.begin()->first))
|
||||
{
|
||||
//merge
|
||||
csn.slots[toMerge.second].second += csn.slots[toMerge.first].second;
|
||||
csn.slots[toMerge.first] = cso.slots.begin()->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
complain("Cannot make garrison swap, not enough free slots!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(csn.slots.find(pos)!=csn.slots.end()) //add creatures to the existing stack
|
||||
else if(csn.slots.find(pos) != csn.slots.end()) //add creatures to the existing stack
|
||||
{
|
||||
csn.slots[pos].second += cso.slots.begin()->second.second;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user