mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* swapping artifacts (needs testing)
* various improvements and fixes for interface * put changelog into ChangeLog
This commit is contained in:
		| @@ -2,6 +2,7 @@ | ||||
| #include "CAdvmapInterface.h" | ||||
| #include "client/CBitmapHandler.h" | ||||
| #include "CPlayerInterface.h" | ||||
| #include "CCastleInterface.h" | ||||
| #include "hch/CPreGameTextHandler.h" | ||||
| #include "hch/CGeneralTextHandler.h" | ||||
| #include "hch/CDefHandler.h" | ||||
| @@ -1098,6 +1099,8 @@ void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * c | ||||
| 			{ | ||||
| 				LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+(i)); | ||||
| 				delete pom; | ||||
| 				if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt) | ||||
| 					LOCPLINT->castleInt->showAll(0,true); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|   | ||||
| @@ -456,7 +456,7 @@ void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby, bool b | ||||
| 		} | ||||
| 	} | ||||
| 	creAnims[ID]->setType(5); //death | ||||
| 	for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i) | ||||
| 	for(int i=0; i<creAnims[ID]->framesInGroup(5); ++i) | ||||
| 	{ | ||||
| 		show(); | ||||
| 		CSDL_Ext::update(); | ||||
|   | ||||
| @@ -136,20 +136,24 @@ void CCallback::endTurn() | ||||
| } | ||||
| UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	return gs->getUpgradeInfo(const_cast<CArmedInstance*>(obj),stackPos); | ||||
| } | ||||
|  | ||||
| const StartInfo * CCallback::getStartInfo() | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	return gs->scenarioOps; | ||||
| } | ||||
|  | ||||
| int CCallback::howManyTowns() | ||||
| { | ||||
| 	return gs->players[gs->currentPlayer].towns.size(); | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	return gs->players[player].towns.size(); | ||||
| } | ||||
| const CGTownInstance * CCallback::getTownInfo(int val, bool mode) //mode = 0 -> val = serial; mode = 1 -> val = ID | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	if (!mode) | ||||
| 		return gs->players[gs->currentPlayer].towns[val]; | ||||
| 	else  | ||||
| @@ -293,6 +297,7 @@ std::vector < const CGHeroInstance *> CCallback::getHeroesInfo(bool onlyOur) | ||||
|  | ||||
| bool CCallback::isVisible(int3 pos) | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	return isVisible(pos,player); | ||||
| } | ||||
|  | ||||
| @@ -312,6 +317,7 @@ int CCallback::getHeroSerial(const CGHeroInstance * hero) | ||||
| } | ||||
| const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	if(!obj) | ||||
| 		return NULL; | ||||
| 	if(obj->ID == 34) | ||||
| @@ -325,7 +331,6 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance | ||||
| { | ||||
| 	if(s1->tempOwner != player   ||   s2->tempOwner != player) | ||||
| 		return -1; | ||||
|  | ||||
| 	*cl->serv << ui16(502) << ui8(1) << s1->id << ui8(p1) << s2->id << ui8(p2); | ||||
| 	return 0; | ||||
| } | ||||
| @@ -362,31 +367,35 @@ int CCallback::getMySerial() | ||||
| 	return gs->players[player].serial; | ||||
| } | ||||
|  | ||||
| bool CCallback::swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2) | ||||
| bool CCallback::swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2) | ||||
| { | ||||
| 	if(!hero1 || !hero2) //incorrect data | ||||
| 	if(player!=hero1->tempOwner || player!=hero2->tempOwner) | ||||
| 		return false; | ||||
| 	CGHeroInstance * Uhero1 = const_cast<CGHeroInstance *>(hero1); | ||||
| 	CGHeroInstance * Uhero2 = const_cast<CGHeroInstance *>(hero2); | ||||
|  | ||||
| 	if(worn1 && worn2) | ||||
| 	{ | ||||
| 		std::swap(Uhero1->artifWorn[pos1], Uhero2->artifWorn[pos2]); | ||||
| 	} | ||||
| 	else if(worn1 && !worn2) | ||||
| 	{ | ||||
| 		std::swap(Uhero1->artifWorn[pos1], Uhero2->artifacts[pos2]); | ||||
| 	} | ||||
| 	else if(!worn1 && worn2) | ||||
| 	{ | ||||
| 		std::swap(Uhero1->artifacts[pos1], Uhero2->artifWorn[pos2]); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		std::swap(Uhero1->artifacts[pos1], Uhero2->artifacts[pos2]); | ||||
| 	} | ||||
| 	 | ||||
| 	*cl->serv << ui16(509) << hero1->id << pos1 << hero2->id << pos2; | ||||
| 	return true; | ||||
| 	//if(!hero1 || !hero2) //incorrect data | ||||
| 	//	return false; | ||||
| 	//CGHeroInstance * Uhero1 = const_cast<CGHeroInstance *>(hero1); | ||||
| 	//CGHeroInstance * Uhero2 = const_cast<CGHeroInstance *>(hero2); | ||||
|  | ||||
| 	//if(worn1 && worn2) | ||||
| 	//{ | ||||
| 	//	std::swap(Uhero1->artifWorn[pos1], Uhero2->artifWorn[pos2]); | ||||
| 	//} | ||||
| 	//else if(worn1 && !worn2) | ||||
| 	//{ | ||||
| 	//	std::swap(Uhero1->artifWorn[pos1], Uhero2->artifacts[pos2]); | ||||
| 	//} | ||||
| 	//else if(!worn1 && worn2) | ||||
| 	//{ | ||||
| 	//	std::swap(Uhero1->artifacts[pos1], Uhero2->artifWorn[pos2]); | ||||
| 	//} | ||||
| 	//else | ||||
| 	//{ | ||||
| 	//	std::swap(Uhero1->artifacts[pos1], Uhero2->artifacts[pos2]); | ||||
| 	//} | ||||
| 	// | ||||
| 	//return true; | ||||
| } | ||||
|  | ||||
| bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID) | ||||
| @@ -401,7 +410,6 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID) | ||||
| 			return false; //lack of resources | ||||
|  | ||||
| 	*cl->serv << ui16(504) << town->id << buildingID; | ||||
| //TODO: check if we are allowed to build | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| @@ -431,6 +439,7 @@ CStack* CCallback::battleGetStackByID(int ID) | ||||
|  | ||||
| CStack* CCallback::battleGetStackByPos(int pos) | ||||
| { | ||||
| 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	return battleGetStackByID(battleGetStack(pos)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -34,7 +34,7 @@ public: | ||||
| 	virtual int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type) | ||||
| 	virtual int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack | ||||
| 	virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly | ||||
| 	virtual bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2)=0; //swaps artifacts between two given heroes | ||||
| 	virtual bool swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes | ||||
| 	virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0; | ||||
| 	virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; | ||||
| 	virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made | ||||
| @@ -106,7 +106,7 @@ public: | ||||
| 	int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2); //first goes to the second | ||||
| 	int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val); | ||||
| 	bool dismissHero(const CGHeroInstance * hero); | ||||
| 	bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2); | ||||
| 	bool swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2); | ||||
| 	bool buildBuilding(const CGTownInstance *town, si32 buildingID); | ||||
| 	void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount); | ||||
| 	bool dismissCreature(const CArmedInstance *obj, int stackPos); | ||||
|   | ||||
| @@ -334,6 +334,7 @@ public: | ||||
| CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate) | ||||
| :hslotup(241,387,0,Town->garrisonHero,this),hslotdown(241,483,1,Town->visitingHero,this) | ||||
| { | ||||
| 	subInt = NULL; | ||||
| 	hall = NULL; | ||||
| 	townInt = BitmapHandler::loadBitmap("TOWNSCRN.bmp"); | ||||
| 	cityBg = BitmapHandler::loadBitmap(getBgName(Town->subID)); | ||||
| @@ -623,6 +624,11 @@ void CCastleInterface::show(SDL_Surface * to) | ||||
| } | ||||
| void CCastleInterface::activate() | ||||
| { | ||||
| 	if(subInt) | ||||
| 	{ | ||||
| 		subInt->activate(); | ||||
| 		return; | ||||
| 	} | ||||
| 	showing = true; | ||||
| 	townlist->activate(); | ||||
| 	garr->activate(); | ||||
| @@ -637,6 +643,11 @@ void CCastleInterface::activate() | ||||
| } | ||||
| void CCastleInterface::deactivate() | ||||
| { | ||||
| 	if(subInt) | ||||
| 	{ | ||||
| 		subInt->deactivate(); | ||||
| 		return; | ||||
| 	} | ||||
| 	showing = false; | ||||
| 	townlist->deactivate(); | ||||
| 	garr->deactivate(); | ||||
| @@ -980,6 +991,7 @@ CHallInterface::~CHallInterface() | ||||
| } | ||||
| void CHallInterface::close() | ||||
| { | ||||
| 	LOCPLINT->castleInt->subInt = NULL; | ||||
| 	deactivate(); | ||||
| 	delete this; | ||||
| 	LOCPLINT->castleInt->activate(); | ||||
| @@ -1392,6 +1404,7 @@ void CMageGuildScreen::close() | ||||
| { | ||||
| 	deactivate(); | ||||
| 	delete this; | ||||
| 	LOCPLINT->castleInt->subInt = NULL; | ||||
| 	LOCPLINT->castleInt->activate(); | ||||
| 	LOCPLINT->castleInt->showAll(); | ||||
| } | ||||
| @@ -1430,7 +1443,7 @@ void CMageGuildScreen::Scroll::clickRight (tribool down) | ||||
| 			(LOCPLINT->playerID, | ||||
| 			spell->descriptions[0], | ||||
| 			static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap, | ||||
| 			spell->name); | ||||
| 			spell->name,30,30); | ||||
| 		vinya->pos.x = screen->w/2 - vinya->bitmap->w/2; | ||||
| 		vinya->pos.y = screen->h/2 - vinya->bitmap->h/2; | ||||
| 		vinya->activate(); | ||||
|   | ||||
| @@ -48,7 +48,6 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) | ||||
| 			nobj->defInfo->handler=NULL; | ||||
| 			nobj->defInfo->blockMap[5] = 253; | ||||
| 			nobj->defInfo->visitMap[5] = 2; | ||||
| 			nobj->artifacts.resize(20); | ||||
| 			nobj->artifWorn[16] = 3; | ||||
| 			nobj->portrait = subid; | ||||
| 			nobj->primSkills.resize(4); | ||||
| @@ -463,6 +462,14 @@ void CGameState::applyNL(IPack * pack) | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	case 509: | ||||
| 		{ | ||||
| 			SetHeroArtifacts *sha = static_cast<SetHeroArtifacts*>(pack); | ||||
| 			CGHeroInstance *h = getHero(sha->hid); | ||||
| 			h->artifacts = sha->artifacts; | ||||
| 			h->artifWorn = sha->artifWorn; | ||||
| 			break; | ||||
| 		} | ||||
| 	case 1001://set object property | ||||
| 		{ | ||||
| 			SetObjectProperty *p = static_cast<SetObjectProperty*>(pack); | ||||
|   | ||||
| @@ -458,8 +458,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) | ||||
|  | ||||
| 	for(int g=0; g<artWorn.size(); ++g) | ||||
| 	{ | ||||
| 		artWorn[g]->myNumber = g; | ||||
| 		artWorn[g]->backNumber = -1; | ||||
| 		artWorn[g]->slotID = g; | ||||
| 		char * hll = new char[200]; | ||||
| 		sprintf(hll, CGI->generaltexth->heroscrn[1].c_str(), (artWorn[g]->ourArt ? artWorn[g]->ourArt->name.c_str() : "")); | ||||
| 		artWorn[g]->hoverText = std::string(hll); | ||||
| @@ -477,7 +476,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) | ||||
| 		add->pos.y = 365; | ||||
| 		add->pos.h = add->pos.w = 44; | ||||
| 		if(s<hero->artifacts.size() && hero->artifacts[s]) | ||||
| 			add->text = hero->getArt(s)->description; | ||||
| 			add->text = hero->getArt(19+s)->description; | ||||
| 		else | ||||
| 			add->text = std::string(); | ||||
| 		add->ourWindow = this; | ||||
| @@ -500,8 +499,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) | ||||
| 		add->neck = true; | ||||
| 		add->shoulders = true; | ||||
| 		add->head = true; | ||||
| 		add->myNumber = -1; | ||||
| 		add->backNumber = s; | ||||
| 		add->slotID = 19+s; | ||||
| 		backpack.push_back(add); | ||||
| 	} | ||||
| 	activeArtPlace = NULL; | ||||
| @@ -890,15 +888,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down) | ||||
| 			//chceck if swap is possible | ||||
| 			if(this->fitsHere(ourWindow->activeArtPlace->ourArt) && ourWindow->activeArtPlace->fitsHere(this->ourArt)) | ||||
| 			{ | ||||
| 				//swap artifacts | ||||
|  | ||||
| 				LOCPLINT->cb->swapArifacts( | ||||
| 					ourWindow->curHero, | ||||
| 					this->myNumber>=0, | ||||
| 					this->myNumber>=0 ? this->myNumber : (this->backNumber + ourWindow->backpackPos)%ourWindow->curHero->artifacts.size(), | ||||
| 					ourWindow->curHero, | ||||
| 					ourWindow->activeArtPlace->myNumber>=0, | ||||
| 					ourWindow->activeArtPlace->myNumber>=0 ? ourWindow->activeArtPlace->myNumber : (ourWindow->activeArtPlace->backNumber + ourWindow->backpackPos)%ourWindow->curHero->artifacts.size()); | ||||
| 				LOCPLINT->cb->swapArifacts(ourWindow->curHero,slotID,ourWindow->curHero,ourWindow->activeArtPlace->slotID); | ||||
|  | ||||
| 				const CArtifact * pmh = ourArt; | ||||
| 				ourArt = ourWindow->activeArtPlace->ourArt; | ||||
|   | ||||
| @@ -64,8 +64,7 @@ public: | ||||
| 	bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4, | ||||
| 		misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso, | ||||
| 		lHand, rHand, neck, shoulders, head; //my types | ||||
| 	int myNumber; | ||||
| 	int backNumber; //number of artifact if this is backpack artplace | ||||
| 	ui16 slotID; //0   	head	1 	shoulders		2 	neck		3 	right hand		4 	left hand		5 	torso		6 	right ring		7 	left ring		8 	feet		9 	misc. slot 1		10 	misc. slot 2		11 	misc. slot 3		12 	misc. slot 4		13 	ballista (war machine 1)		14 	ammo cart (war machine 2)		15 	first aid tent (war machine 3)		16 	catapult		17 	spell book		18 	misc. slot 5		19+ 	backpack slots | ||||
|  | ||||
| 	bool clicked; | ||||
| 	CHeroWindow * ourWindow; | ||||
|   | ||||
							
								
								
									
										10
									
								
								CMessage.cpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								CMessage.cpp
									
									
									
									
									
								
							| @@ -222,6 +222,8 @@ std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> > | ||||
| 			lw+=(*txtg)[i][j]->w; | ||||
| 			ret.second+=(*txtg)[i][j]->h; | ||||
| 		} | ||||
| 		if(!(*txtg)[i].size()) | ||||
| 			ret.second+=19; | ||||
| 		if (ret.first<lw) | ||||
| 			ret.first=lw; | ||||
| 	} | ||||
| @@ -381,7 +383,7 @@ std::vector< std::vector<SComponent*> > * CMessage::breakComps(std::vector<SComp | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline) | ||||
| SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ ) | ||||
| { | ||||
| 	int curh; | ||||
| 	std::vector<std::string> * tekst = breakText(text,charperline); | ||||
| @@ -392,17 +394,19 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_S | ||||
| 	boxs.second = | ||||
| 		(curh=45) //top margin | ||||
| 		+ txts.second //text total height | ||||
| 		+ 55 //text <=> img | ||||
| 		+ imgToBmp //text <=> img | ||||
| 		+ bitmap->h | ||||
| 		+ 5 // to sibtitle | ||||
| 		+ (*txtg)[0][0]->h | ||||
| 		+ 30; | ||||
| 	SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player); | ||||
| 	blitTextOnSur(txtg,curh,ret); | ||||
| 	curh += 55; | ||||
| 	curh += imgToBmp; | ||||
| 	blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret); | ||||
| 	curh += bitmap->h + 5; | ||||
| 	CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+(  ((*txtg)[0][0]->h) / 2  ),GEOR13,zwykly,ret); | ||||
| 	delete tekst; | ||||
| 	delete txtg; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -39,7 +39,7 @@ public: | ||||
| 	static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly, | ||||
| 								std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL); | ||||
| 	static SDL_Surface * drawBox1(int w, int h, int playerColor=1); | ||||
| 	static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30); | ||||
| 	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, int line=30, bool userBreak=true, bool ifor=true); //line - chars per line | ||||
| 	CMessage(); | ||||
| 	static void init(); | ||||
|   | ||||
| @@ -575,7 +575,7 @@ void CInfoPopup::close() | ||||
| 	delete this; | ||||
| 	if(LOCPLINT->curint == LOCPLINT->adventureInt) | ||||
| 		LOCPLINT->adventureInt->show(); | ||||
| 	else if(LOCPLINT->curint == LOCPLINT->castleInt) | ||||
| 	else if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt) | ||||
| 		LOCPLINT->castleInt->showAll(); | ||||
| } | ||||
| void CInfoPopup::show(SDL_Surface * to) | ||||
| @@ -3167,25 +3167,38 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState | ||||
| 	{ | ||||
| 		if(Upg && ui) | ||||
| 		{ | ||||
| 			bool enough = true; | ||||
| 			for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++) //calculate upgrade cost | ||||
| 			{ | ||||
| 				if(LOCPLINT->cb->getResourceAmount(i->first) < i->second*creatureCount) | ||||
| 					enough = false; | ||||
| 				upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*creatureCount));  | ||||
| 			} | ||||
|  | ||||
| 			CFunctionList<void()> fs[2]; | ||||
| 			fs[0] += Upg; | ||||
| 			fs[0] += boost::bind(&CCreInfoWindow::close,this); | ||||
|  | ||||
| 			CCastleInterface *pom; | ||||
| 			if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn | ||||
| 			if(enough) | ||||
| 			{ | ||||
| 				fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true); | ||||
| 				CFunctionList<void()> fs[2]; | ||||
| 				fs[0] += Upg; | ||||
| 				fs[0] += boost::bind(&CCreInfoWindow::close,this); | ||||
|  | ||||
| 				CCastleInterface *pom; | ||||
| 				if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn | ||||
| 				{ | ||||
| 					fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true); | ||||
| 				} | ||||
| 				fs[1] += boost::bind(&CCreInfoWindow::activate,this); | ||||
| 				CFunctionList<void()> cfl; | ||||
| 				cfl = boost::bind(&CCreInfoWindow::deactivate,this); | ||||
| 				cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],boost::ref(upgResCost),fs[0],fs[1],false,false); | ||||
| 				upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,cfl,pos.x+76,pos.y+237,"IVIEWCR.DEF"); | ||||
| 			} | ||||
| 			fs[1] += boost::bind(&CCreInfoWindow::activate,this); | ||||
| 			CFunctionList<void()> cfl; | ||||
| 			cfl = boost::bind(&CCreInfoWindow::deactivate,this); | ||||
| 			cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],boost::ref(upgResCost),fs[0],fs[1],false,false); | ||||
| 			upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,cfl,pos.x+76,pos.y+237,"IVIEWCR.DEF"); | ||||
| 			else | ||||
| 			{ | ||||
| 				upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,boost::function<void()>(),pos.x+76,pos.y+237,"IVIEWCR.DEF"); | ||||
| 				upgrade->callback.funcs.clear(); | ||||
| 				upgrade->bitmapOffset = 2; | ||||
| 			} | ||||
|  | ||||
| 		} | ||||
| 		if(Dsm) | ||||
| 		{ | ||||
|   | ||||
							
								
								
									
										196
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										196
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -0,0 +1,196 @@ | ||||
| 0.61 -> 0.62 | ||||
| General: | ||||
| * threading and minor changes. | ||||
| * support for heroes starting in town garrisons | ||||
| * upgrading creatures | ||||
| * working gaining levels for heroes (including dialog with skill selection) | ||||
| * added fast graphical cursor | ||||
| * showing creature amount in the CCreInfoWindow | ||||
|  | ||||
| Castles: | ||||
| * icon in infobox showing that there is hero in town garrison | ||||
| * fort/citadel/castle screen | ||||
| * taking last stack from the heroes army should be impossible (or at least harder) | ||||
| * fixed reading forbidden structures | ||||
| * randomizing spells in towns | ||||
| * viewing hero window in the town screen | ||||
| * possibility of moving hero into the garrison | ||||
| * partially done mage guild screen  | ||||
|  | ||||
| Adventure Interface: | ||||
| * hopefully fixed problems with wrong town defs (village/fort/capitol) | ||||
|  | ||||
| Hero Window: | ||||
| * bugfix: splitting stacks works in hero window | ||||
| * removed bug causing significant increase of CPU consumption | ||||
|  | ||||
| Battles: | ||||
| * shooting | ||||
| * removed some displaying problems | ||||
| * showing last group of frames in creature animation won't crash | ||||
| * added start moving and end moving animations | ||||
| * fixed moving two-hex creatures | ||||
| * showing/hiding graphic cursor | ||||
| * a part of using graphic cursor | ||||
| * slightly optimized showing of battle interface | ||||
| * animation of getting hit / death by shooting is displayed when it should be | ||||
| * improved pathfinding in battles, removed problems with displaying movement, adventure map interface won't be called during battles. | ||||
|  | ||||
| PreGame: | ||||
| * updates settings when selecting new map after changing sorting criteria | ||||
| * if sorting not by name, name will be used as a secondary criteria | ||||
| * when filter is applied a first available map is selected automatically | ||||
| * slider position updated after sorting in pregame | ||||
|  | ||||
| 0.6 -> 0.61 (Jun 15 2008) | ||||
| Improvements: | ||||
| * improved attacking in the battles | ||||
| * it's possible to kill hostile stack | ||||
| * animations won't go in the same phase | ||||
| * Better pathfinder | ||||
| * "%s" substitutions in Right-click information in town hall | ||||
| * windmill won't give wood | ||||
| * hover text for heroes | ||||
| * support for ZSoft-style PCX files in /Data | ||||
| * Splitting: when moving slider to the right so that 0 is left in old slot the army is moved | ||||
| * in the townlist in castle selected town will by placed on the 2nd place (not 3rd) | ||||
| * stack at the limit of unit's range can now be attacked | ||||
| * range of unit is now properly displayed | ||||
| * battle log is scrolled down when new event occurs | ||||
| * console is closed when application exits | ||||
|  | ||||
| Bugfixes: | ||||
| * stack at the limit of unit's range can now be attacked | ||||
| * good background for the town hall screen in Stronghold | ||||
| * fixed typo in hall.txt | ||||
| * VCMI won't crash when r-click neutral stack during the battle | ||||
| * water won't blink behind shipyard in the Castle | ||||
| * fixed several memory leaks | ||||
| * properly displaying two-hex creatures in recruit/split/info window | ||||
| * corrupted map file won't cause crash on initializing main menu | ||||
|  | ||||
| 0.59 -> 0.6 (Jun 1 2008) | ||||
| * partially done attacking in battles | ||||
| * screen isn't now refreshed while blitting creature info window | ||||
| * r-click creature info windows in battles | ||||
| * no more divison by 0 in slider | ||||
| * "plural" reference names for Conflux creatures (starting armies of Conflux heroes should now be working) | ||||
| * fixed estate problems | ||||
| * fixed blinking mana vortex | ||||
| * grail increases creature growths | ||||
| * new pathfinder | ||||
| * several minor improvements | ||||
|  | ||||
| 0.58 -> 0.59 (May 24 2008 - closed, test release) | ||||
| * fixed memory leak in battles | ||||
| * blitting creature animations to rects in the recruitment window | ||||
| * fixed wrong creatures def names | ||||
| * better battle pathfinder and unit reversing | ||||
| * improved slider ( #58 ) | ||||
| * fixed problems with horde buildings (won't block original dwellings) | ||||
| * giving primary skill when hero get level (but there is still no dialog) | ||||
| * if an upgraded creature is available it'll be shown as the first in a recruitment window | ||||
| * creature levels not messed in Fortress | ||||
| * war machines are added to the hero's inventory, not to the garrison | ||||
| * support for H3-style PCX graphics in Data/ | ||||
| * VCMI won't crash when is unable to initialize audio system | ||||
| * fixed displaying wrong town defs | ||||
| * improvements in recruitment window (slider won't allow to select more creatures than we can afford) | ||||
| * creature info window (only r-click) | ||||
| * callback for buttons/lists based on boost::function | ||||
| * a lot of minor improvements | ||||
|  | ||||
| 0.55 -> 0.58 (Apr 20 2008 - closed, test release) | ||||
| Towns: | ||||
| * recruiting creatures | ||||
| * working creature growths (including castle and horde building influences) | ||||
| * towns give income | ||||
| * town hall screen | ||||
| * building buildings (requirements and cost are handled) | ||||
| * hints for structures | ||||
| * updating town infobox | ||||
| Garrisons: | ||||
| * merging stacks | ||||
| * splitting stacks | ||||
| Battles: | ||||
| * starting battles | ||||
| * displaying terrain, animations of heroes, units, grid, range of units, battle menu with console, amounts of units in stacks | ||||
| * leaving battle by pressing flee button | ||||
| * moving units in battles and displaying thier ranges | ||||
| * defend command for units | ||||
| General: | ||||
| * a number of minor fixes and improvements | ||||
|  | ||||
| 0.54 -> 0.55 (Feb 29 2008) | ||||
| * Sprites/ folder works for h3sprite.lod same as Data/ for h3bitmap.lod (but it's still experimental) | ||||
| * randomization quantity of creatures on the map | ||||
| * fix of Pandora's Box handling | ||||
| * reading disposed/predefined heroes | ||||
| * new command - "get txt" - VCMI will extract all .txt files from h3bitmap.lod to the Extracted_txts/ folder. | ||||
| * more detailed logs | ||||
| * reported problems with hero flags resolved | ||||
| * heroes cannot occupy the same tile | ||||
| * hints for most of creature generators | ||||
| * some minor stuff | ||||
|  | ||||
| 0.53b -> 0.54 (Feb 23 2008 - first public release) | ||||
| * given hero is placed in the town entrance | ||||
| * some objects such as river delta won't be blitted "on" hero | ||||
| * tiles under FoW are inaccessible | ||||
| * giving random hero on RoE maps | ||||
| * improved protection against hero duplication | ||||
| * fixed starting values of primary abilities of random heroes on RoE/AB maps | ||||
| * right click popups with infoboxes for heroes/towns lists | ||||
| * new interface coloring (many thanks to GrayFace ;]) | ||||
| * fixed bug in object flag's coloring | ||||
| * added hints in town lists | ||||
| * eliminated square from city hints | ||||
|  | ||||
| 0.53 - 0.53b (Feb 20 2008) | ||||
| * added giving default buildings in towns | ||||
| * town infobox won't crash on empty town | ||||
|  | ||||
| 0.52 - 0.53 (Feb 18 2008): | ||||
| * hopefully the last bugfix of Pandora's Box | ||||
| * fixed blockmaps of generated heroes | ||||
| * disposed hero cannot be chosen in scenario settings (unless he is in prison) | ||||
| * fixed town randomization | ||||
| * fixed hero randomization | ||||
| * fixed displaying heroes in preGame | ||||
| * fixed selecting/deselecting artifact slots in hero window | ||||
| * much faster pathfinder | ||||
| * memory usage and load time significantly decreased | ||||
| * it's impossible to select empty artifact slot in hero window | ||||
| * fixed problem with FoW displaying on minimap on L-sized maps | ||||
| * fixed crashbug in hero list connected with heroes dismissing | ||||
| * mostly done town infobox | ||||
| * town daily income is properly calculated | ||||
|  | ||||
| 0.51 - 0.52 (Feb 7 2008): | ||||
| * [feature] giving starting hero | ||||
| * [feature] VCMI will try to use files from /Data folder instead of those from h3bitmap.lod | ||||
| * [feature] picked artifacts are added to hero's backpack | ||||
| * [feature] possibility of choosing player to play | ||||
| * [bugfix] ZELP.TXT file *should* be handled correctly even it is non-english | ||||
| * [bugfix] fixed crashbug in reading defs with negativ left/right margins | ||||
| * [bugfix] improved randomization | ||||
| * [bugfix] pathfinder can't be cheated (what caused errors) | ||||
|  | ||||
| 0.5 - 0.51 (Feb 3 2008): | ||||
| * close button properly closes (same does 'q' key) | ||||
| * two players can't have selected same hero | ||||
| * double click on "Show Available Scenarios" won't reset options | ||||
| * fixed possible crashbug in town/hero lists | ||||
| * fixed crashbug in initializing game caused by wrong prisons handling | ||||
| * fixed crashbug on reading hero's custom artifacts in RoE maps | ||||
| * fixed crashbug on reading custom Pandora's Box in RoE maps | ||||
| * fixed crashbug on reading blank Quest Guards | ||||
| * better console messages | ||||
| * map reading speed up (though it's still slow, especially on bigger maps) | ||||
|  | ||||
| to 0.5 (Feb 2 2008 - first closed release): | ||||
| * Main menu and New game screens | ||||
| * Scenario selection, part of advanced options support | ||||
| * Partially done adventure map, town and hero interfaces | ||||
| * Moving hero | ||||
| * Interactions with several objects (mines, resources, mills, and others) | ||||
|   | ||||
| @@ -360,6 +360,15 @@ void CClient::process(int what) | ||||
| 				playerint[t->tempOwner]->heroInGarrisonChange(t); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 509: | ||||
| 		{ | ||||
| 			SetHeroArtifacts sha; | ||||
| 			*serv >> sha; | ||||
| 			std::cout << "Setting artifacts of hero " << sha.hid << std::endl; | ||||
| 			gs->apply(&sha); | ||||
| 			//TODO: inform interfaces | ||||
| 			break; | ||||
| 		} | ||||
| 	case 1001: | ||||
| 		{ | ||||
| 			SetObjectProperty sop; | ||||
|   | ||||
							
								
								
									
										9
									
								
								config/mageBg.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								config/mageBg.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| TPMAGECS.bmp | ||||
| TPMAGERM.bmp | ||||
| TPMAGETW.bmp | ||||
| TPMAGEIN.bmp | ||||
| TPMAGENC.bmp | ||||
| TPMAGEDN.bmp | ||||
| TPMAGEST.bmp | ||||
| TPMAGEFR.bmp | ||||
| TPMAGEEL.bmp | ||||
| @@ -237,11 +237,45 @@ int CGHeroInstance::getSecSkillLevel(const int & ID) const | ||||
| 			return secSkills[i].second; | ||||
| 	return -1; | ||||
| } | ||||
| ui32 CGHeroInstance::getArtAtPos(ui16 pos) const | ||||
| { | ||||
| 	if(pos<19) | ||||
| 		if(vstd::contains(artifWorn,pos)) | ||||
| 			return artifWorn.find(pos)->second; | ||||
| 		else | ||||
| 			return -1; | ||||
| 	else | ||||
| 		if(pos-19 < artifacts.size()) | ||||
| 			return artifacts[pos-19]; | ||||
| 		else  | ||||
| 			return -1; | ||||
| } | ||||
| void CGHeroInstance::setArtAtPos(ui16 pos, int art) | ||||
| { | ||||
| 	if(art<0) | ||||
| 	{ | ||||
| 		if(pos<19) | ||||
| 			artifWorn.erase(pos); | ||||
| 		else | ||||
| 			artifacts -= artifacts[pos]; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if(pos<19) | ||||
| 			artifWorn[pos] = art; | ||||
| 		else | ||||
| 			if(pos-19 < artifacts.size()) | ||||
| 				artifacts[pos-19] = art; | ||||
| 			else | ||||
| 				artifacts.push_back(art); | ||||
| 	} | ||||
| } | ||||
| const CArtifact * CGHeroInstance::getArt(int pos) | ||||
| { | ||||
| 	if(artifWorn.find(pos)!=artifWorn.end()) | ||||
| 		return &VLC->arth->artifacts[artifWorn[pos]]; | ||||
| 	else  | ||||
| 	int id = getArtAtPos(pos); | ||||
| 	if(id>=0) | ||||
| 		return &VLC->arth->artifacts[id]; | ||||
| 	else | ||||
| 		return NULL; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -107,8 +107,8 @@ public: | ||||
| 	bool inTownGarrison; // if hero is in town garrison  | ||||
| 	CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison | ||||
|  | ||||
| 	std::vector<int> artifacts; //hero's artifacts from bag | ||||
| 	std::map<int,int> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | ||||
| 	std::vector<ui32> artifacts; //hero's artifacts from bag | ||||
| 	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | ||||
| 	std::set<int> spells; //known spells (spell IDs) | ||||
|  | ||||
| 	virtual bool isHero() const; | ||||
| @@ -125,6 +125,8 @@ public: | ||||
| 	int getCurrentLuck() const; | ||||
| 	int getCurrentMorale() const; | ||||
| 	int getSecSkillLevel(const int & ID) const; //-1 - no skill | ||||
| 	ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact | ||||
| 	void setArtAtPos(ui16 pos, int art); | ||||
| 	const CArtifact * getArt(int pos); | ||||
| 	CGHeroInstance(); | ||||
| 	virtual ~CGHeroInstance(); | ||||
|   | ||||
| @@ -164,6 +164,18 @@ struct SetHeroesInTown : public CPack<SetHeroesInTown> //508 | ||||
| 		h & tid & visiting & garrison; | ||||
| 	} | ||||
| };   | ||||
| struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509 | ||||
| { | ||||
| 	SetHeroArtifacts(){type = 509;}; | ||||
| 	si32 hid; | ||||
| 	std::vector<ui32> artifacts; //hero's artifacts from bag | ||||
| 	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & hid & artifacts & artifWorn; | ||||
| 	} | ||||
| };   | ||||
| struct NewTurn : public CPack<NewTurn> //101 | ||||
| { | ||||
| 	struct Hero | ||||
|   | ||||
| @@ -501,6 +501,11 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c) | ||||
| 						if(!S1->slots[p1].second) //if we've moved all creatures | ||||
| 							S1->slots.erase(p1);  | ||||
| 					} | ||||
| 					if((s1->ID==34 && !S1->slots.size()) //it's not allowed to take last stack from hero army! | ||||
| 						|| (s2->ID==34 && !S2->slots.size())) | ||||
| 					{ | ||||
| 						break; | ||||
| 					} | ||||
| 					SetGarrisons sg; | ||||
| 					sg.garrs[id1] = *S1; | ||||
| 					if(s1 != s2) | ||||
| @@ -732,6 +737,53 @@ upgend: | ||||
| 					} | ||||
| 					break; | ||||
| 				} | ||||
| 			case 509: | ||||
| 				{ | ||||
| 					si32 hid1, hid2; | ||||
| 					ui16 slot1, slot2; | ||||
| 					c >> hid1 >> slot1 >> hid2 >> slot2; | ||||
| 					CGHeroInstance *h1 = gs->getHero(hid1), *h2 = gs->getHero(hid2); | ||||
| 					if((distance(h1->pos,h2->pos) > 1.0)   ||   (h1->tempOwner != h2->tempOwner)) | ||||
| 						break; | ||||
| 					int a1=h1->getArtAtPos(slot1), a2=h2->getArtAtPos(slot2); | ||||
|  | ||||
| 					h2->setArtAtPos(slot2,a1); | ||||
| 					h1->setArtAtPos(slot1,a2); | ||||
| // 					if(std::max(slot1,slot2) < 19) | ||||
| // 					{ | ||||
| // 						if(vstd::contains(h1->artifWorn,slot1) && vstd::contains(h1->artifWorn,slot2)) | ||||
| // 							std::swap(h1->artifWorn[slot1],h2->artifWorn[slot2]); | ||||
| // 						if(vstd::contains(h1->artifWorn,slot1)) | ||||
| // 						{ | ||||
| // 							h2->artifWorn[slot2] = h1->artifWorn[slot1]; | ||||
| // 							h1->artifWorn.erase(slot1); | ||||
| // 						} | ||||
| // 						else if(vstd::contains(h2->artifWorn,slot2)) | ||||
| // 						{ | ||||
| // 							h1->artifWorn[slot1] = h2->artifWorn[slot2]; | ||||
| // 							h2->artifWorn.erase(slot2); | ||||
| // 						} | ||||
| // 						else | ||||
| // 						{ | ||||
| // 							std::cout << "Warning, wrong artifact swap command!" << std::endl; | ||||
| // 						} | ||||
| // 					} | ||||
| // 					else | ||||
| // 					{ | ||||
| // 					} | ||||
| 					SetHeroArtifacts sha; | ||||
| 					sha.hid = hid1; | ||||
| 					sha.artifacts = h1->artifacts; | ||||
| 					sha.artifWorn = h1->artifWorn; | ||||
| 					sendAndApply(&sha); | ||||
| 					if(hid1 != hid2) | ||||
| 					{ | ||||
| 						sha.hid = hid2; | ||||
| 						sha.artifacts = h2->artifacts; | ||||
| 						sha.artifWorn = h2->artifWorn; | ||||
| 						sendAndApply(&sha); | ||||
| 					} | ||||
| 				} | ||||
| 			case 2001: | ||||
| 				{ | ||||
| 					ui32 qid, answer; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user