1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-26 03:52:01 +02:00

* it's possible to revisit object under hero by pressing Space

* splitting window allows to rebalance two stack with the same creatures
* slightly improved sliders
* minor improvements
This commit is contained in:
Michał W. Urbańczyk 2009-03-26 23:05:40 +00:00
parent 21155f3b35
commit cebd5db8b2
12 changed files with 314 additions and 238 deletions

View File

@ -309,8 +309,9 @@ void CSlider::mouseMoved (const SDL_MouseMotionEvent & sEvent)
if( std::abs(sEvent.y-(pos.y+pos.h/2)) > pos.h/2+40 || std::abs(sEvent.x-(pos.x+pos.w/2)) > pos.w/2 )
return;
float v = sEvent.x - pos.x - 24;
v/= (pos.w - 48);
v*=amount;
v/= (pos.w - 48);
v += 0.5f;
if(v!=value)
{
moveTo(v);
@ -371,11 +372,11 @@ void CSlider::clickLeft (tribool down)
{
if(down)
{
float pw = LOCPLINT->current->motion.x-pos.x-16;
float rw = pw / ((float)(pos.w-32));
float pw = LOCPLINT->current->motion.x-pos.x-24;
float rw = pw / ((float)(pos.w-48));
if (rw>1) return;
if (rw<0) return;
moveTo(rw*amount);
moveTo(rw*amount+0.5f);
return;
}
if(moving)

View File

@ -1535,6 +1535,17 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
case SDLK_DOWN:
Dir = DOWN;
break;
case SDLK_SPACE: //space - try to revisit current object with selected hero
{
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance*>(selection);
if(h && key.state == SDL_PRESSED)
{
LOCPLINT->pim->unlock();
LOCPLINT->cb->moveHero(h,h->pos);
LOCPLINT->pim->lock();
}
}
return;
default:
return;
}

View File

@ -1412,6 +1412,9 @@ void CGameState::getNeighbours(int3 tile, std::vector<int3> &vec, const boost::l
int CGameState::getMovementCost(const CGHeroInstance *h, int3 src, int3 dest, int remainingMovePoints, bool checkLast)
{
if(src == dest) //same tile
return 0;
TerrainTile &s = map->terrain[src.x][src.y][src.z],
&d = map->terrain[dest.x][dest.y][dest.z];

View File

@ -88,7 +88,7 @@ CHeroWindow::CHeroWindow(int playerColor):
primSkillAreas[v]->pos.y = pos.y + 111;
primSkillAreas[v]->pos.w = 42;
primSkillAreas[v]->pos.h = 42;
primSkillAreas[v]->text = CGI->generaltexth->arraytxt[2+v].substr(1, CGI->generaltexth->arraytxt[2+v].size()-2);
primSkillAreas[v]->text = CGI->generaltexth->arraytxt[2+v];
primSkillAreas[v]->type = v;
primSkillAreas[v]->bonus = -1; // to be initilized when hero is being set
primSkillAreas[v]->baseType = 0;

View File

@ -21,6 +21,11 @@ extern SDL_Surface * screen;
extern TTF_Font * TNRB16, *TNR, *GEOR13;
using namespace NMessage;
const int COMPONENT_TO_SUBTITLE = 5;
const int BETWEEN_COMPS_ROWS = 10;
const int BEFORE_COMPONENTS = 30;
template <typename T, typename U> std::pair<T,U> max(const std::pair<T,U> &x, const std::pair<T,U> &y)
{
std::pair<T,U> ret;
@ -36,11 +41,7 @@ namespace NMessage
SDL_Surface * background = NULL;
}
CMessage::CMessage()
{
//if (!NMessage::background)
// init();
}
void CMessage::init()
{
{
@ -160,26 +161,6 @@ std::vector<std::string> * CMessage::breakText(std::string text, size_t line, bo
}
return ret;
}
std::pair<int, int> CMessage::getMaxSizes(std::vector< std::vector<SComponent*> > * komp)
{
std::pair<int,int> ret;
for (size_t i=0;i<komp->size();i++)
{
int sumaw=0;
int maxh=0;
for(size_t j=0;j<(*komp)[i].size();j++)
{
sumaw += (*komp)[i][j]->getImg()->w;
if (maxh < (*komp)[i][j]->getImg()->h)
maxh = (*komp)[i][j]->getImg()->h;
}
if(sumaw>ret.first)
ret.first = sumaw;
ret.second+=maxh;
}
return ret;
}
std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg)
{
@ -201,15 +182,16 @@ std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> >
}
return ret;
}
SDL_Surface * CMessage::blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret)
SDL_Surface * CMessage::blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret, int xCenterPos)
{
for (size_t i=0; i<txtg->size();i++)
{
int lw=0;
int lw=0; //line width
for (size_t j=0;j<(*txtg)[i].size();j++)
lw+=(*txtg)[i][j]->w; //lw - laczna szerokosc linii
int pw = ret->w/2;
pw -= lw/2; //poczatek tekstu (x)
lw+=(*txtg)[i][j]->w;
int pw = (xCenterPos < 0) ? ret->w/2 : xCenterPos;
pw -= lw/2; //x coord for the start of the text
int tw = pw;
for (size_t j=0;j<(*txtg)[i].size();j++) //blit text
@ -217,84 +199,15 @@ SDL_Surface * CMessage::blitTextOnSur(std::vector<std::vector<SDL_Surface*> > *
blitAt((*txtg)[i][j],tw,curh+i*19,ret);
tw+=(*txtg)[i][j]->w;
SDL_FreeSurface((*txtg)[i][j]);
(*txtg)[i][j] = NULL;
}
}
curh+=txtg->size()*19;
return ret;
}
SDL_Surface * CMessage::blitCompsOnSur(std::vector<SComponent*> & comps, int maxw, int inter, int & curh, SDL_Surface * ret)
{
std::vector<std::string> * brdtext;
if (comps.size())
{
brdtext = breakText(comps[0]->subtitle,12,true,true);
}
else
{
brdtext = NULL;
}
comps[0]->pos.x = (ret->w/2) - ((comps[0]->getImg()->w)/2);
comps[0]->pos.y = curh;
blitAt(comps[0]->getImg(),comps[0]->pos.x,comps[0]->pos.y,ret);
curh += comps[0]->getImg()->h + 5; //obrazek + przerwa
for (size_t i=0; i < brdtext->size(); ++i) //descr.
{
SDL_Surface * tesu = TTF_RenderText_Blended(GEOR13,(*brdtext)[i].c_str(),zwykly);
blitAt(tesu,((comps[0]->getImg()->w - tesu->w)/2)+comps[0]->pos.x,curh,ret);
curh+=tesu->h;
SDL_FreeSurface(tesu);
}
return ret;
}
SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * _or, std::vector< std::vector<SComponent*> > * komp, int inter, int &curh, SDL_Surface *ret)
{
for (size_t i=0;i<komp->size();i++)
{
int totalw=0, maxh=0;
for(size_t j=0;j<(*komp)[i].size();j++)
{
totalw+=(*komp)[i][j]->getImg()->w;
if(maxh<(*komp)[i][j]->getImg()->h)
{
maxh=(*komp)[i][j]->getImg()->h;
}
}
if(_or)
{
totalw += (inter*2+_or->w) * ((*komp)[i].size() - 1);
}
else
{
totalw += (inter) * ((*komp)[i].size() - 1);
}
curh+=maxh/2;
int curw = (ret->w/2)-(totalw/2);
for(size_t j=0;j<(*komp)[i].size();j++)
{
blitAt((*komp)[i][j]->getImg(),curw,curh-((*komp)[i][j]->getImg()->h/2),ret);
(*komp)[i][j]->pos.x = curw;
(*komp)[i][j]->pos.y = curh-((*komp)[i][j]->getImg()->h/2);
CSDL_Ext::printAtMiddle((*komp)[i][j]->subtitle,curw+(*komp)[i][j]->getImg()->w/2,curh+((*komp)[i][j]->getImg()->h/2)+10,GEOR13,zwykly,ret);
curw += (*komp)[i][j]->getImg()->w;
if(j<((*komp)[i].size()-1))
{
if(_or)
{
curw+=inter;
blitAt(_or,curw,curh-(_or->h/2),ret);
curw+=_or->w;
}
curw+=inter;
}
}
curh+=maxh/2;
curh += 20; //todo: check subtitle length
}
return ret;
}
std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::string> * brtext)
std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::string> * brtext, TTF_Font *font)
{
if(!font) font = TNRB16;
std::vector<std::vector<SDL_Surface*> > * txtg = new std::vector<std::vector<SDL_Surface*> >();
txtg->resize(brtext->size());
for (size_t i=0; i<brtext->size();i++) //foreach line
@ -314,7 +227,7 @@ std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::st
if (!br)
z++;
if (z)
(*txtg)[i].push_back(TTF_RenderText_Blended(TNRB16,(*brtext)[i].substr(0,z).c_str(),zwykly));
(*txtg)[i].push_back(TTF_RenderText_Blended(font,(*brtext)[i].substr(0,z).c_str(),zwykly));
(*brtext)[i].erase(0,z);
z=0;
if ( ((*brtext)[i].length()==0) || ((*brtext)[i][z]!='{') )
@ -324,7 +237,7 @@ std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::st
while( ((*brtext)[i][++z]) != ('}') )
{}
//tyemp = (*brtext)[i].substr(1,z-1); //od 1 bo pomijamy otwierajaca klamre
(*txtg)[i].push_back(TTF_RenderText_Blended(TNRB16,(*brtext)[i].substr(1,z-1).c_str(),tytulowy));
(*txtg)[i].push_back(TTF_RenderText_Blended(font,(*brtext)[i].substr(1,z-1).c_str(),tytulowy));
(*brtext)[i].erase(0,z+1); //z+1 bo dajemy zamykajaca klamre
} //ends while((*brtext)[i].length())
} //ends for(int i=0; i<brtext->size();i++)
@ -345,26 +258,6 @@ CSimpleWindow * CMessage::genWindow(std::string text, int player, int Lmar, int
delete txtg;
return ret;
}
std::vector< std::vector<SComponent*> > * CMessage::breakComps(std::vector<SComponent*> & comps,int maxw, SDL_Surface* _or)
{
std::vector< std::vector<SComponent*> > * ret = new std::vector< std::vector<SComponent*> >();
ret->resize(1);
int rvi = 0;
int curw = 0;
for(size_t i=0;i<comps.size();i++)
{
curw += (comps[i]->getImg()->w + 12 + (_or ? _or->w : 0));
if (curw > maxw)
{
curw = 0;
rvi++;
ret->resize(rvi+1);
}
(*ret)[rvi].push_back(comps[i]);
}
return ret;
}
SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ )
{
int curh;
@ -392,19 +285,34 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
return ret;
}
void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline)
{
std::vector<std::string> * brtext = breakText(text,charperline,true,true);
SDL_Surface * _or = NULL;
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
std::vector<std::string> * brtext = breakText(text,charperline,true,true); //text
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(brtext);
std::pair<int,int> txts = getMaxSizes(txtg);
ComponentsToBlit comps(ret->components,500,_or);
if(ret->buttons.size())
txts.second += 20 + //before button
ok->ourImages[0].bitmap->h; //button
if (ret->components.size())
txts.second += 30 //space to first component
+ ret->components[0]->getImg()->h
+ 5 //img <-> subtitle
+ 20; //subtitle //TODO: check how much place will be needed for subtitle
{
txts.second += 30 + comps.h; //space to first component
}
amax(txts.first,comps.w);
ret->bitmap = drawBox1(txts.first+70,txts.second+70,0);
ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w;
@ -412,22 +320,11 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int
ret->pos.y=screen->h/2-(ret->pos.h/2);
int curh = 30; //gorny margines
blitTextOnSur(txtg,curh,ret->bitmap);
if (ret->components.size())
{
curh += 30;
if(ret->components.size()==1)
{
blitCompsOnSur(ret->components,200,0,curh,ret->bitmap);
}
else
{
SDL_Surface * _or = 0;
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
std::vector< std::vector<SComponent*> > * komp = breakComps(reinterpret_cast<std::vector<SComponent*>&>(ret->components),500,_or);
blitCompsOnSur(_or,komp,10,curh,ret->bitmap);
delete komp;
}
curh += BEFORE_COMPONENTS;
comps.blitCompsOnSur(_or, 10, curh, ret->bitmap);
}
if(ret->buttons.size())
{
@ -450,38 +347,8 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int
}
delete brtext;
delete txtg;
}
CSelWindow * CMessage::genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner)
{
//CSelWindow * ret = new CSelWindow();
//std::vector<std::string> * tekst = breakText(text,charperline);
//std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst);
//std::pair<int,int> txts = getMaxSizes(txtg);
//txts.first+=45; //side margins
//int curh = 50; //top margin
////std::pair<int,int> txts2 = getMaxSizes(komp);
//ret->pos.h = txts.second //wys. tekstu
// //+ txts2.second //wys komponentow
// + 20 //podpis pod komponentami
// + 55 //gorny margines
// + 60 //text <=> comps
// + 20 //comps <=> button
// + ok->ourImages[0].bitmap->h //button
// + 30; //bottom margin
//ret->pos.w = std::max(txts.first,txts.second);
//ret->bitmap = drawBox1(ret->pos.w,ret->pos.h,player);
//blitTextOnSur(txtg,curh,ret->bitmap);
//curh += 50;
//blitCompsOnSur(_or,komp,10,curh,ret->bitmap);
//curh += 30; //to buttton
//ret->buttons[0]->pos.x = (ret->bitmap->w/2) - (ret->buttons[0]->imgs[0][0]->w/2);
//ret->buttons[0]->pos.y = curh;
//ret->buttons[0]->show();
//curh += ret->buttons[0]->imgs[0][0]->h;
//SDL_FreeSurface(_or);
//delete komp;
//delete tekst;
return NULL;
if(_or)
SDL_FreeSurface(_or);
}
SDL_Surface * CMessage::genMessage
@ -513,7 +380,6 @@ SDL_Surface * CMessage::genMessage
if (title.length())
{
//SDL_Surface * titleText = TTF_RenderText_Shaded(TNRB16,title.c_str(),tytulowy,tlo);
SDL_Surface * titleText = TTF_RenderText_Blended(TNRB16,title.c_str(),tytulowy);
//draw title
@ -526,7 +392,6 @@ SDL_Surface * CMessage::genMessage
{
int by = 37+i*21;
if (title.length()) by+=40;
//SDL_Surface * tresc = TTF_RenderText_Shaded(TNRB16,(*tekst)[i].c_str(),zwykly,tlo);
SDL_Surface * tresc = TTF_RenderText_Blended(TNRB16,(*tekst)[i].c_str(),zwykly);
SDL_Rect trescRect = genRect(tresc->h,tresc->w,((ret->w/2)-(tresc->w/2)),by);
SDL_BlitSurface(tresc,NULL,ret,&trescRect);
@ -577,4 +442,128 @@ void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int
(piecesOfBox[playerColor][2],NULL,ret,&genRect(piecesOfBox[playerColor][2]->h,piecesOfBox[playerColor][2]->w,x+0,y+h-piecesOfBox[playerColor][2]->h));
SDL_BlitSurface
(piecesOfBox[playerColor][3],NULL,ret,&genRect(piecesOfBox[playerColor][3]->h,piecesOfBox[playerColor][3]->w,x+w-piecesOfBox[playerColor][3]->w,y+h-piecesOfBox[playerColor][3]->h));
}
ComponentResolved::ComponentResolved()
{
comp = NULL;
img = NULL;
txt = NULL;
}
ComponentResolved::ComponentResolved( SComponent *Comp )
{
comp = Comp;
img = comp->getImg();
std::vector<std::string> * brtext = CMessage::breakText(comp->subtitle,11,true,true); //text
txt = CMessage::drawText(brtext,GEOR13);
delete brtext;
comp->pos.w = img->w;
comp->pos.h = img->h + COMPONENT_TO_SUBTITLE + CMessage::getMaxSizes(txt).second;
}
ComponentResolved::~ComponentResolved()
{
for(size_t i = 0; i < txt->size(); i++)
for(size_t j = 0; j < (*txt)[i].size(); j++)
if((*txt)[i][j])
SDL_FreeSurface((*txt)[i][j]);
delete txt;
}
ComponentsToBlit::~ComponentsToBlit()
{
for(size_t i=0; i<comps.size(); i++)
for(size_t j = 0; j < comps[i].size(); j++)
delete comps[i][j];
}
ComponentsToBlit::ComponentsToBlit(std::vector<SComponent*> & SComps, int maxw, SDL_Surface* _or)
{
w = h = 0;
if(!SComps.size())
return;
comps.resize(1);
int curw = 0;
int curr = 0;
for(size_t i=0;i<SComps.size();i++)
{
int toadd = (SComps[i]->getImg()->w + 12 + (_or ? _or->w : 0));
if (curw + toadd > maxw)
{
amax(w,curw);
curw = SComps[i]->getImg()->w;
comps.resize(curr+1);
}
else
{
curw += toadd;
}
comps[curr].push_back(new ComponentResolved(SComps[i]));
}
for(size_t i=0;i<comps.size();i++)
{
int maxh = 0;
for(size_t j=0;j<comps.size();j++)
amax(maxh,comps[i][j]->comp->pos.h);
h += maxh + BETWEEN_COMPS_ROWS;
}
}
void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret )
{
for (size_t i=0;i<comps.size();i++)
{
int totalw=0, maxh=0;
for(size_t j=0;j<(comps)[i].size();j++)
{
ComponentResolved *cur = (comps)[i][j];
totalw += cur->comp->pos.w;
amax(maxh,cur->comp->pos.h);
}
if(_or)
{
totalw += (inter*2+_or->w) * ((comps)[i].size() - 1);
}
else
{
totalw += (inter) * ((comps)[i].size() - 1);
}
curh+=maxh/2;
int curw = (ret->w/2)-(totalw/2);
for(size_t j=0;j<(comps)[i].size();j++)
{
ComponentResolved *cur = (comps)[i][j];
//blit img
int hlp = curh-(cur->comp->pos.h)/2;
blitAt(cur->img,curw,hlp,ret);
cur->comp->pos.x = curw;
cur->comp->pos.y = hlp;
//blit subtitle
hlp += cur->img->h + COMPONENT_TO_SUBTITLE;
CMessage::blitTextOnSur(cur->txt, hlp, ret, cur->comp->pos.x + cur->comp->pos.w/2 );
//if there is subsequent component blit "or"
curw += cur->img->w;
if(j<((comps)[i].size()-1))
{
if(_or)
{
curw+=inter;
blitAt(_or,curw,curh-(_or->h/2),ret);
curw+=_or->w;
}
curw+=inter;
}
}
curh+=maxh/2;
}
}

View File

@ -22,19 +22,36 @@ namespace NMessage
extern SDL_Surface * background ;
}
struct ComponentResolved
{
SComponent *comp;
SDL_Surface *img;
std::vector<std::vector<SDL_Surface*> > * txt;
ComponentResolved();
ComponentResolved(SComponent *Comp);
~ComponentResolved();
};
struct ComponentsToBlit
{
std::vector< std::vector<ComponentResolved*> > comps;
int w, h;
void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<SComponent*> & SComps, int maxw, SDL_Surface* _or);
~ComponentsToBlit();
};
class CMessage
{
public:
static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg);
static std::pair<int, int> getMaxSizes(std::vector< std::vector<SComponent*> > * komp);
static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext);
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret);
static SDL_Surface * blitCompsOnSur(std::vector<SComponent*> & comps, int maxw, int inter, int & curh, SDL_Surface * ret);
static SDL_Surface * blitCompsOnSur(SDL_Surface *_or, std::vector< std::vector<SComponent*> > *komp, int inter, int &curh, SDL_Surface *ret);
static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext, TTF_Font *font = NULL);
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2
static void drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline);
static std::vector< std::vector<SComponent*> > * breakComps(std::vector<SComponent*> &comps, int maxw, SDL_Surface* _or=NULL);
static CSelWindow * genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner);
static CSimpleWindow * genWindow(std::string text, int player, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins
static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly,
std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL);
@ -42,7 +59,6 @@ public:
static void drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55);
static std::vector<std::string> * breakText(std::string text, size_t line=30, bool userBreak=true, bool ifor=true); //line - chars per line
CMessage();
static void init();
static void dispose();
};

View File

@ -217,16 +217,37 @@ void CGarrisonSlot::clickLeft(tribool down)
refr = true;
delete pom2;
}
else if(!creature
&& (owner->splitting
|| SDL_GetKeyState(NULL)[SDLK_LSHIFT]
|| SDL_GetKeyState(NULL)[SDLK_RSHIFT]))//split
else if((owner->splitting || LOCPLINT->shiftPressed())
&& (!creature
|| (creature == owner->highlighted->creature))
)
{
owner->p2 = ID;
owner->pb = upg;
owner->p2 = ID; //store the second stack pos
owner->pb = upg;//store the second stack owner (up or down army)
owner->splitting = false;
LOCPLINT->curint->deactivate();
CSplitWindow * spw = new CSplitWindow(owner->highlighted->creature->idNumber,owner->highlighted->count, owner);
int totalAmount = owner->highlighted->count;
if(creature)
totalAmount += count;
int last = -1;
if(upg != owner->highlighted->upg) //not splitting within same army
{
if(owner->highlighted->getObj()->army.slots.size() == 1
&& owner->highlighted->getObj()->needsLastStack() )
{
last = 0;
}
if(getObj()->army.slots.size() == 1
&& getObj()->needsLastStack() )
{
last += 2;
}
}
CSplitWindow * spw = new CSplitWindow(owner->highlighted->creature->idNumber, totalAmount, owner, last, count);
spw->activate();
refr = true;
}
@ -293,25 +314,24 @@ void CGarrisonSlot::show()
{
if(creature)
{
char* buf = new char[15];
char buf[15];
SDL_itoa(count,buf,10);
blitAt(graphics->bigImgs[creature->idNumber],pos);
printToWR(buf,pos.x+56,pos.y+62,GEOR16,zwykly);
if(owner->highlighted==this)
if((owner->highlighted==this)
|| (owner->splitting && owner->highlighted->creature == creature))
{
blitAt(graphics->bigImgs[-1],pos);
//if(owner->update)
// updateRect(&pos,screen);
delete [] buf;
}
}
else
else //empty slot
{
SDL_Rect jakis1 = genRect(pos.h,pos.w,owner->offx+ID*(pos.w+owner->interx),owner->offy+upg*(pos.h+owner->intery)),
jakis2 = pos;
SDL_BlitSurface(owner->sur,&jakis1,screen,&jakis2);
if(owner->splitting)
blitAt(graphics->bigImgs[-1],pos);
//if(owner->update)
// SDL_UpdateRect(screen,pos.x,pos.y,pos.w,pos.h);
}
}
CGarrisonInt::~CGarrisonInt()
@ -1260,7 +1280,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
if(adventureInt == curint)
adventureInt->minimap.draw();
if(details.style>0)
if(details.style>0 || details.src == details.dst)
return;
//initializing objects and performing first step of move
@ -2537,6 +2557,11 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CPath * path )
return result;
}
bool CPlayerInterface::shiftPressed() const
{
return SDL_GetKeyState(NULL)[SDLK_LSHIFT] || SDL_GetKeyState(NULL)[SDLK_RSHIFT];
}
CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
{
bg=BitmapHandler::loadBitmap(name);
@ -3355,8 +3380,9 @@ CRecrutationWindow::~CRecrutationWindow()
delete bar;
}
CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int val)
{
last = Last;
which = 1;
c=cid;
slider = NULL;
@ -3370,9 +3396,10 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
pos.h = bitmap->h;
ok = new AdventureMapButton("","",boost::bind(&CSplitWindow::split,this),pos.x+20,pos.y+263,"IOK6432.DEF",SDLK_RETURN);
cancel = new AdventureMapButton("","",boost::bind(&CSplitWindow::close,this),pos.x+214,pos.y+263,"ICN6432.DEF",SDLK_ESCAPE);
slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),1,max,0,true);
a1 = max;
a2 = 0;
int sliderPositions = max - (last>=0) - (last==2);
slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),1,sliderPositions,val,true);
a1 = max-val;
a2 = val;
anim = new CCreaturePic(&CGI->creh->creatures[cid]);
anim->anim->setType(1);
@ -3419,9 +3446,10 @@ void CSplitWindow::close()
}
void CSplitWindow::sliderMoved(int to)
{
a2 = to;
int all = a1+a2;
a2 = to + (last==1 || last==2);
if(slider)
a1 = slider->amount - to;
a1 = all - a2;
}
void CSplitWindow::show(SDL_Surface * to)
{
@ -3453,7 +3481,7 @@ void CSplitWindow::keyPressed (const SDL_KeyboardEvent & key)
else
{
int number = key.keysym.sym - SDLK_0;
if (number < 0 || number > 9) //not a number presses
if (number < 0 || number > 9) //not a number pressed
{
return;
}

View File

@ -563,6 +563,7 @@ public:
//-------------//
bool shiftPressed() const;
void redrawHeroWin(const CGHeroInstance * hero);
void updateWater();
void showComp(SComponent comp); //TODO: comment me
@ -721,8 +722,9 @@ public:
SDL_Surface *bitmap; //background
int a1, a2, c; //TODO: comment me
bool which; //TODO: comment me
int last; //0/1/2 - at least one creature must be in the src/dst/both stacks; -1 - no restrictions
CSplitWindow(int cid, int max, CGarrisonInt *Owner); //c-tor
CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last = -1, int val=0); //c-tor; val - initial amount of second stack
~CSplitWindow(); //d-tor
void activate();
void split();

View File

@ -408,7 +408,6 @@ void Graphics::loadHeroFlags()
{
using namespace boost::assign;
timeHandler th;
// std::vector<CDefHandler *> Graphics::*point; //TODO use me
std::pair<std::vector<CDefHandler *> Graphics::*, std::vector<const char *> > pr[4];
pr[0].first = &Graphics::flags1;
pr[0].second+=("ABF01L.DEF"),("ABF01G.DEF"),("ABF01R.DEF"),("ABF01D.DEF"),("ABF01B.DEF"),

View File

@ -708,8 +708,8 @@ std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentMoraleModifie
if(archangelInArmy)
{
char buf[100];
sprintf(buf,VLC->generaltexth->arraytxt[117].c_str(),VLC->creh->creatures[13].namePl);
ret.push_back(std::pair<int,std::string>(-1,VLC->generaltexth->arraytxt[116])); //%s in group +1
sprintf(buf,VLC->generaltexth->arraytxt[117].c_str(),VLC->creh->creatures[13].namePl.c_str());
ret.push_back(std::pair<int,std::string>(-1,buf)); //%s in group +1
}
}

View File

@ -38,9 +38,6 @@ extern bool end2;
bnr.round = gs->curB->round + 1;\
sendAndApply(&bnr);
#define COMPLAIN(text) sendMessageToAll(text);tlog1<<text<<std::endl;
boost::mutex gsm;
ui32 CGameHandler::QID = 1;
@ -1197,7 +1194,7 @@ void CGameHandler::moveHero(si32 hid, int3 dst, ui8 instant, ui8 asker)
tmh.movePoints = std::max(si32(0),h->movement-cost); //take move points
BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
{
if(obj->blockVisit)
if(obj != h && obj->blockVisit)
{
blockvis = true;
break;
@ -1498,8 +1495,9 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
if(what==1) //swap
{
std::swap(S1.slots[p1],S2.slots[p2]);
std::swap(S1.slots[p1],S2.slots[p2]); //swap slots
//if one of them is empty, remove entry
if(!S1.slots[p1].second)
S1.slots.erase(p1);
if(!S2.slots[p2].second)
@ -1509,7 +1507,7 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
{
if(S1.slots[p1].first != S2.slots[p2].first) //not same creature
{
COMPLAIN("Cannot merge different creatures stacks!");
complain("Cannot merge different creatures stacks!");
return;
}
@ -1518,30 +1516,51 @@ void CGameHandler::arrangeStacks(si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2, s
}
else if(what==3) //split
{
if( vstd::contains(S2.slots,p2) //dest. slot not free
|| !vstd::contains(S1.slots,p1) //no creatures to split
|| S1.slots[p1].second < val //not enough creatures
|| val<1 //val must be positive
)
//general conditions checking
if((!vstd::contains(S1.slots,p1) && complain("no creatures to split"))
|| (val<1 && complain("no creatures to split")) )
{
COMPLAIN("Cannot split that stack!");
return;
return;
}
if(vstd::contains(S2.slots,p2)) //dest. slot not free - it must be "rebalancing"...
{
int total = S1.slots[p1].second + S2.slots[p2].second;
if( (total < val && complain("Cannot split that stack, not enough creatures!"))
|| (S2.slots[p2].first != S1.slots[p1].first && complain("Cannot rebalance different creatures stacks!"))
)
{
return;
}
S2.slots[p2].second = val;
S1.slots[p1].second = total - val;
}
else //split one stack to the two
{
if(S1.slots[p1].second < val)//not enough creatures
{
complain("Cannot split that stack, not enough creatures!");
return;
}
S2.slots[p2].first = S1.slots[p1].first;
S2.slots[p2].second = val;
S1.slots[p1].second -= val;
}
S2.slots[p2].first = S1.slots[p1].first;
S2.slots[p2].second = val;
S1.slots[p1].second -= val;
if(!S1.slots[p1].second) //if we've moved all creatures
S1.slots.erase(p1);
S1.slots.erase(p1);
}
if((s1->needsLastStack() && !S1.slots.size()) //it's not allowed to take last stack from hero army!
|| (s2->needsLastStack() && !S2.slots.size())
)
{
COMPLAIN("Cannot take the last stack!");
complain("Cannot take the last stack!");
return; //leave without applying changes to garrison
}
//apply changes
SetGarrisons sg;
sg.garrs[id1] = S1;
if(s1 != s2)
@ -1578,7 +1597,7 @@ void CGameHandler::disbandCreature(si32 id, ui8 pos)
CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id]);
if(!vstd::contains(s1->army.slots,pos))
{
COMPLAIN("Illegal call to disbandCreature - no such stack in army!");
complain("Illegal call to disbandCreature - no such stack in army!");
return;
}
s1->army.slots.erase(pos);
@ -1594,7 +1613,7 @@ void CGameHandler::buildStructure(si32 tid, si32 bid)
if(gs->canBuildStructure(t,bid) != 7)
{
COMPLAIN("Cannot build that building!");
complain("Cannot build that building!");
return;
}
@ -1797,7 +1816,7 @@ void CGameHandler::garrisonSwap(si32 tid)
}
else
{
COMPLAIN("Cannot swap garrison hero!");
complain("Cannot swap garrison hero!");
}
}
@ -2394,4 +2413,11 @@ void CGameHandler::handleTimeEvents()
gs->map->events.pop_front();
}
}
}
bool CGameHandler::complain( const std::string &problem )
{
sendMessageToAll("Server encountered a problem: " + problem);
tlog1 << problem << std::endl;
return true;
}

View File

@ -133,6 +133,7 @@ public:
void save(const std::string &fname);
void close();
void handleTimeEvents();
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
template <typename Handler> void serialize(Handler &h, const int version)
{