Browse Source

Splitting stacks

Michał W. Urbańczyk 17 years ago
parent
commit
06f278717c
5 changed files with 190 additions and 11 deletions
  1. 36 1
      CCallback.cpp
  2. 9 7
      CCastleInterface.cpp
  3. 2 1
      CCastleInterface.h
  4. 116 0
      CPlayerInterface.cpp
  5. 27 2
      CPlayerInterface.h

+ 36 - 1
CCallback.cpp

@@ -575,7 +575,42 @@ int CCallback::mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s
 }
 int CCallback::splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)
 {
-	return -1;
+	if(!val)
+		return -1;
+	CCreatureSet *S1 = const_cast<CCreatureSet*>(getGarrison(s1)), *S2 = const_cast<CCreatureSet*>(getGarrison(s2));
+	if ((S1->slots[p1].second<p2) && (true /*we are allowed to*/))
+	{
+		return -1;
+	}
+
+	S2->slots[p2].first = S1->slots[p1].first;
+	S2->slots[p2].second = val;
+	S1->slots[p1].second -= val;
+
+
+	if(s1->tempOwner<PLAYER_LIMIT)
+	{
+		for(int b=0; b<CGI->playerint.size(); ++b)
+		{
+			if(CGI->playerint[b]->playerID == s1->tempOwner)
+			{
+				CGI->playerint[b]->garrisonChanged(s1);
+				break;
+			}
+		}
+	}
+	if((s2->tempOwner<PLAYER_LIMIT) && (s2 != s1))
+	{
+		for(int b=0; b<CGI->playerint.size(); ++b)
+		{
+			if(CGI->playerint[b]->playerID == s2->tempOwner)
+			{
+				CGI->playerint[b]->garrisonChanged(s2);
+				break;
+			}
+		}
+	}
+	return 0;
 }
 
 bool CCallback::dismissHero(const CGHeroInstance *hero)

+ 9 - 7
CCastleInterface.cpp

@@ -204,11 +204,18 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
 	hall = CGI->spriteh->giveDef("ITMTL.DEF");
 	fort = CGI->spriteh->giveDef("ITMCL.DEF");
 	flag =  CGI->spriteh->giveDef("CREST58.DEF");
+	hBuild = NULL;
+	count=0;
+	town = Town;
+
+	//garrison
+	garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
+
 	townlist = new CTownList<CCastleInterface>(3,&genRect(128,48,744,414),744,414,744,526);
 	exit = new AdventureMapButton<CCastleInterface>
 		(CGI->townh->tcommands[8],"",&CCastleInterface::close,744,544,"TSBTNS.DEF",this,false,NULL,false);
-	split = new AdventureMapButton<CCastleInterface>
-		(CGI->townh->tcommands[3],"",&CCastleInterface::splitF,744,382,"TSBTNS.DEF",this,false,NULL,false);
+	split = new AdventureMapButton<CGarrisonInt>
+		(CGI->townh->tcommands[3],"",&CGarrisonInt::splitClick,744,382,"TSBTNS.DEF",garr,false,NULL,false);
 	statusbar = new CStatusBar(8,555,"TSTATBAR.bmp",732);
 
 	townlist->owner = this;
@@ -217,9 +224,6 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
 	townlist->selected = getIndexOf(townlist->items,Town);
 	if((townlist->selected+1) > townlist->SIZE)
 		townlist->from = townlist->selected -  townlist->SIZE + 1;
-	hBuild = NULL;
-	count=0;
-	town = Town;
 
 	CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
 	exit->bitmapOffset = 4;
@@ -229,8 +233,6 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
 	recreateBuildings();
 
 
-	//garrison
-	garr = new CGarrisonInt(305,387,4,32,townInt,243,13,town,town->visitingHero);
 
 	if(Activate)
 	{

+ 2 - 1
CCastleInterface.h

@@ -44,7 +44,8 @@ public:
 	CTownList<CCastleInterface> * townlist;
 
 	CGarrisonInt * garr;
-	AdventureMapButton<CCastleInterface> * exit, *split;
+	AdventureMapButton<CCastleInterface> * exit;
+	AdventureMapButton<CGarrisonInt>*split;
 
 	std::vector<CBuildingRect*> buildings; //building id, building def, structure struct, border, filling
 

+ 116 - 0
CPlayerInterface.cpp

@@ -121,6 +121,15 @@ void CGarrisonSlot::clickLeft(tribool down)
 				owner->highlighted = NULL;
 				show();
 			}
+			else if( !creature && owner->splitting)//split
+			{
+				owner->p2 = ID;
+				owner->pb = upg;
+				owner->splitting = false;
+				LOCPLINT->curint->deactivate();
+				CSplitWindow * spw = new CSplitWindow(owner->highlighted->creature->idNumber,owner->highlighted->count, owner);
+				spw->activate();
+			}
 			else if(creature != owner->highlighted->creature) //swap
 			{
 				LOCPLINT->cb->swapCreatures(
@@ -196,6 +205,8 @@ void CGarrisonSlot::show()
 	{
 		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,ekran,&jakis2);
+		if(owner->splitting)
+			blitAt(CGI->creh->bigImgs[-1],pos);
 		if(owner->update)
 			SDL_UpdateRect(ekran,pos.x,pos.y,pos.w,pos.h);
 	}
@@ -333,6 +344,7 @@ void CGarrisonInt::deleteSlots()
 }
 void CGarrisonInt::recreateSlots()
 {
+	splitting = false;
 	deactiveteSlots();
 	deleteSlots();
 	createSlots();
@@ -340,10 +352,28 @@ void CGarrisonInt::recreateSlots()
 	activeteSlots();
 	show();
 }
+void CGarrisonInt::splitClick()
+{
+	if(!highlighted)
+		return;
+	splitting = !splitting;
+	show();
+}
+void CGarrisonInt::splitStacks(int am2)
+{
+	LOCPLINT->cb->splitStack(
+		(highlighted->upg)?(odown):(oup),
+		(pb)?(odown):(oup),
+		highlighted->ID,
+		p2,
+		am2);
+
+}
 CGarrisonInt::CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2)
 	:interx(inx),intery(iny),sur(pomsur),highlighted(NULL),sup(NULL),sdown(NULL),oup(s1),odown(s2),
 	offx(OX),offy(OY)
 {
+	splitting = false;
 	set1 = LOCPLINT->cb->getGarrison(s1);
 	set2 = LOCPLINT->cb->getGarrison(s2);
 	ignoreEvent = false;
@@ -2525,4 +2555,90 @@ CRecrutationWindow::~CRecrutationWindow()
 {
 	SDL_FreeSurface(bitmap);
 	delete slider;
+}
+
+CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
+{
+	c=cid;
+	slider = NULL;
+	gar = Owner;
+	bitmap = CGI->bitmaph->loadBitmap("GPUCRDIV.bmp");
+	pos.x = ekran->w/2 - bitmap->w/2;
+	pos.y = ekran->h/2 - bitmap->h/2;
+	pos.w = bitmap->w;
+	pos.h = bitmap->h;
+	ok = new AdventureMapButton<CSplitWindow>("","",&CSplitWindow::split,pos.x+20,pos.y+263,"IOK6432.DEF",this);
+	cancel = new AdventureMapButton<CSplitWindow>("","",&CSplitWindow::close,pos.x+214,pos.y+263,"ICN6432.DEF",this);
+	slider = new CSlider<CSplitWindow>(pos.x+21,pos.y+194,257,this,&CSplitWindow::sliderMoved,1,max,0,true);
+	a1 = max;
+	a2 = 0;
+	anim = new CCreatureAnimation(CGI->creh->creatures[cid].animDefName);
+	anim->setType(1);
+
+	std::string title = CGI->generaltexth->allTexts[256];
+	boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid].namePl);
+	printAtMiddle(title,150,34,GEOR16,tytulowy,bitmap);
+}
+CSplitWindow::~CSplitWindow()
+{
+	SDL_FreeSurface(bitmap);
+}
+void CSplitWindow::activate()
+{
+	LOCPLINT->objsToBlit.push_back(this);
+	KeyInterested::activate();
+	ok->activate();
+	cancel->activate();
+	slider->activate();
+}
+void CSplitWindow::deactivate()
+{
+	LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
+	KeyInterested::deactivate();
+	ok->deactivate();
+	cancel->deactivate();
+	slider->deactivate();
+}
+void CSplitWindow::split()
+{
+	gar->splitStacks(a2);
+	close();
+}
+void CSplitWindow::close()
+{
+	deactivate();
+	delete this;
+	LOCPLINT->curint->activate();
+	
+	CCastleInterface *c = dynamic_cast<CCastleInterface*>(LOCPLINT->curint);
+	if(c) c->showAll();
+}
+void CSplitWindow::sliderMoved(int to)
+{
+	a2 = to;
+	if(slider)
+		a1 = slider->amount - to;
+}
+void CSplitWindow::show(SDL_Surface * to)
+{
+	char pom[15];
+	blitAt(bitmap,pos.x,pos.y,ekran);
+	ok->show();
+	cancel->show();
+	slider->show();
+	itoa(a1,pom,10);
+	printAtMiddle(pom,pos.x+70,pos.y+237,GEOR16,zwykly,ekran);
+	itoa(a2,pom,10);
+	printAtMiddle(pom,pos.x+233,pos.y+237,GEOR16,zwykly,ekran);
+
+
+	blitAt(CGI->creh->backgrounds[CGI->creh->creatures[c].faction],pos.x+20,pos.y+54);
+	anim->nextFrameMiddle(ekran,pos.x+20+70,pos.y+54+55,true,false,false);
+
+	blitAt(CGI->creh->backgrounds[CGI->creh->creatures[c].faction],pos.x+177,pos.y+54);
+	anim->nextFrameMiddle(ekran,pos.x+177+70,pos.y+54+55,true,false,false);
+}
+void CSplitWindow::keyPressed (SDL_KeyboardEvent & key)
+{
+	//TODO: zeby sie dalo recznie wpisywac
 }

+ 27 - 2
CPlayerInterface.h

@@ -260,8 +260,8 @@ public:
 	CGarrisonSlot *highlighted;
 
 	SDL_Surface *sur;
-	int offx, offy;
-	bool ignoreEvent, update, active;
+	int offx, offy, p2;
+	bool ignoreEvent, update, active, splitting, pb;
 
 	const CCreatureSet *set1;
 	const CCreatureSet *set2;
@@ -278,6 +278,9 @@ public:
 	void createSlots();
 	void recreateSlots();
 
+	void splitClick();
+	void splitStacks(int am2);
+
 	CGarrisonInt(int x, int y, int inx, int iny, SDL_Surface *pomsur, int OX, int OY, const CGObjectInstance *s1, const CGObjectInstance *s2=NULL);
 	~CGarrisonInt();
 };
@@ -479,4 +482,26 @@ public:
 	~CRecrutationWindow();
 };
 
+class CSplitWindow : public IShowable, public KeyInterested
+{
+public:
+	CGarrisonInt *gar;
+	CSlider<CSplitWindow> *slider;
+	CCreatureAnimation *anim;
+	AdventureMapButton<CSplitWindow> *ok, *cancel;
+	SDL_Surface *bitmap;
+	int a1, a2, c;
+	bool which;
+
+	CSplitWindow(int cid, int max, CGarrisonInt *Owner);
+	~CSplitWindow();
+	void activate(); 
+	void split();
+	void close();
+	void deactivate();
+	void show(SDL_Surface * to = NULL);
+	void keyPressed (SDL_KeyboardEvent & key);
+	void sliderMoved(int to);
+};
+
 #endif //CPLAYERINTERFACE_H