mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* possibly fixed bug with the mage guild when no spells available
* events won't be shown and won't block movement * casualties among hero army and neutral creatures are saved * it's possible to build lighthouse * increased thread-safety (may prevent some crashes) * minor fixes
This commit is contained in:
		| @@ -1440,7 +1440,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner) | ||||
| 		int sp = owner->town->spellsAtLevel(i+1,false); | ||||
| 		for(int j=0; j<sp; j++) | ||||
| 		{ | ||||
| 			if(i < owner->town->mageGuildLevel()) | ||||
| 			if(i<owner->town->mageGuildLevel() && owner->town->spells[i].size()<j) | ||||
| 			{ | ||||
| 				spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]])); | ||||
| 				spells[spells.size()-1].pos = positions[i][j]; | ||||
|   | ||||
| @@ -505,6 +505,12 @@ void CGameState::applyNL(IPack * pack) | ||||
| 	case 1001://set object property | ||||
| 		{ | ||||
| 			SetObjectProperty *p = static_cast<SetObjectProperty*>(pack); | ||||
| 			if(p->what == 3) //set creatures amount | ||||
| 			{ | ||||
| 				tlog5 << "Setting creatures amount in " << p->id << std::endl; | ||||
| 				static_cast<CCreatureObjInfo*>(map->objects[p->id]->info)->number = p->val; | ||||
| 				break; | ||||
| 			} | ||||
| 			ui8 CGObjectInstance::*point; | ||||
| 			switch(p->what) | ||||
| 			{ | ||||
| @@ -894,7 +900,12 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed) | ||||
| 	{ | ||||
| 		randomizeObject(map->objects[no]); | ||||
| 		if(map->objects[no]->ID==26) | ||||
| 		{ | ||||
| 			map->objects[no]->defInfo->handler=NULL; | ||||
| 			map->removeBlockVisTiles(map->objects[no]); | ||||
| 			map->objects[no]->defInfo->blockMap[5] = 255; | ||||
| 			map->addBlockVisTiles(map->objects[no]); | ||||
| 		} | ||||
| 		map->objects[no]->hoverName = VLC->objh->names[map->objects[no]->ID]; | ||||
| 	} | ||||
| 	//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl; | ||||
|   | ||||
							
								
								
									
										30
									
								
								CLua.cpp
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								CLua.cpp
									
									
									
									
									
								
							| @@ -791,40 +791,40 @@ void CMonsterS::newObject(int objid) | ||||
| 	switch(VLC->creh->creatures[os->subID].level) | ||||
| 	{ | ||||
| 	case 1: | ||||
| 		amounts[objid] = rand()%31+20; | ||||
| 		cb->setAmount(objid,rand()%31+20); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		amounts[objid] = rand()%16+15; | ||||
| 		cb->setAmount(objid,rand()%16+15); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		amounts[objid] = rand()%16+10; | ||||
| 		cb->setAmount(objid,rand()%16+10); | ||||
| 		break; | ||||
| 	case 4: | ||||
| 		amounts[objid] = rand()%11+10; | ||||
| 		cb->setAmount(objid,rand()%11+10); | ||||
| 		break; | ||||
| 	case 5: | ||||
| 		amounts[objid] = rand()%9+8; | ||||
| 		cb->setAmount(objid,rand()%9+8); | ||||
| 		break; | ||||
| 	case 6: | ||||
| 		amounts[objid] = rand()%8+5; | ||||
| 		cb->setAmount(objid,rand()%8+5); | ||||
| 		break; | ||||
| 	case 7: | ||||
| 		amounts[objid] = rand()%7+3; | ||||
| 		cb->setAmount(objid,rand()%7+3); | ||||
| 		break; | ||||
| 	case 8: | ||||
| 		amounts[objid] = rand()%4+2; | ||||
| 		cb->setAmount(objid,rand()%4+2); | ||||
| 		break; | ||||
| 	case 9: | ||||
| 		amounts[objid] = rand()%3+2; | ||||
| 		cb->setAmount(objid,rand()%3+2); | ||||
| 		break; | ||||
| 	case 10: | ||||
| 		amounts[objid] = rand()%3+1; | ||||
| 		cb->setAmount(objid,rand()%3+1); | ||||
| 		break; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	MetaString ms; | ||||
| 	int pom = CCreature::getQuantityID(amounts[objid]); | ||||
| 	int pom = CCreature::getQuantityID(((CCreatureObjInfo*)(os->info))->number); | ||||
| 	pom = 174 + 3*pom + 1; | ||||
| 	ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,os->subID); | ||||
| 	cb->setHoverName(objid,&ms); | ||||
| @@ -834,7 +834,7 @@ void CMonsterS::onHeroVisit(int objid, int heroID) | ||||
| 	DEFOS; | ||||
| 	CCreatureSet set; | ||||
| 	//TODO: zrobic secik w sposob wyrafinowany | ||||
| 	set.slots[0] = std::pair<ui32,si32>(os->subID,amounts[objid]); | ||||
| 	set.slots[0] = std::pair<ui32,si32>(os->subID,((CCreatureObjInfo*)(os->info))->number); | ||||
| 	cb->startBattle(heroID,set,os->pos,boost::bind(&CMonsterS::endBattleWith,this,os,_1)); | ||||
| } | ||||
| std::vector<int> CMonsterS::yourObjects() //returns IDs of objects which are handled by script | ||||
| @@ -852,7 +852,11 @@ void CMonsterS::endBattleWith(const CGObjectInstance *monster, BattleResult *res | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		//TODO: remove casualties | ||||
| 		int killedAmount=0; | ||||
| 		for(std::set<std::pair<ui32,si32> >::iterator i=result->casualties[1].begin(); i!=result->casualties[1].end(); i++) | ||||
| 			if(i->first == monster->subID) | ||||
| 				killedAmount += i->second; | ||||
| 		cb->setAmount(monster->id,((CCreatureObjInfo*)(monster->info))->number - killedAmount); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								CLua.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								CLua.h
									
									
									
									
									
								
							| @@ -171,7 +171,6 @@ public: | ||||
| class CMonsterS : public CCPPObjectScript | ||||
| { | ||||
| public: | ||||
| 	std::map<int, int> amounts; //monster id -> stack quantity | ||||
| 	CMonsterS(CScriptCallback * CB):CCPPObjectScript(CB){}; | ||||
| 	void newObject(int objid); | ||||
| 	void onHeroVisit(int objid, int heroID); | ||||
|   | ||||
							
								
								
									
										2
									
								
								CMT.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								CMT.cpp
									
									
									
									
									
								
							| @@ -221,7 +221,7 @@ int main(int argc, char** argv) | ||||
| 		while(1) //main SDL events loop | ||||
| 		{ | ||||
| 			SDL_WaitEvent(&ev); | ||||
| 			if(ev.type==SDL_QUIT)  | ||||
| 			if((ev.type==SDL_QUIT)  ||  (ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT))) | ||||
| 			{ | ||||
| 				cl.close(); | ||||
| #ifndef __unix__ | ||||
|   | ||||
| @@ -172,7 +172,10 @@ void CPathfinder::AddNeighbors(vector<Coordinate>* branch) | ||||
| 					bool pass = true; //checking for allowed visiting direction | ||||
| 					for(int b=0; b<CGI->mh->ttiles[i][j][node.z].tileInfo->visitableObjects.size(); ++b) //checking destination tile | ||||
| 					{ | ||||
| 						CGDefInfo * di = CGI->mh->ttiles[i][j][node.z].tileInfo->visitableObjects[b]->defInfo; | ||||
| 						const TerrainTile * pom = CGI->mh->ttiles[i][j][node.z].tileInfo; | ||||
| 						if(!vstd::contains(pom->blockingObjects,pom->visitableObjects[b])) | ||||
| 							break; | ||||
| 						CGDefInfo * di = pom->visitableObjects[b]->defInfo; | ||||
| 						if( (i == node.x-1 && j == node.y-1) && !(di->visitDir & (1<<4)) ) | ||||
| 						{ | ||||
| 							pass = false; break; | ||||
| @@ -208,7 +211,10 @@ void CPathfinder::AddNeighbors(vector<Coordinate>* branch) | ||||
| 					} | ||||
| 					for(int b=0; b<CGI->mh->ttiles[node.x][node.y][node.z].tileInfo->visitableObjects.size(); ++b) //checking source tile | ||||
| 					{ | ||||
| 						CGDefInfo * di = CGI->mh->ttiles[node.x][node.y][node.z].tileInfo->visitableObjects[b]->defInfo; | ||||
| 						const TerrainTile * pom = CGI->mh->ttiles[node.x][node.y][node.z].tileInfo; | ||||
| 						if(!vstd::contains(pom->blockingObjects,pom->visitableObjects[b])) | ||||
| 							break; | ||||
| 						CGDefInfo * di = pom->visitableObjects[b]->defInfo; | ||||
| 						if( (i == node.x-1 && j == node.y-1) && !(di->visitDir & (1<<0)) ) | ||||
| 						{ | ||||
| 							pass = false; break; | ||||
| @@ -269,11 +275,12 @@ void CPathfinder::CalcH(Coordinate* node) | ||||
| 	 * If there is fog of war on the node. | ||||
| 	 *  => Impossible to move there. | ||||
| 	 */ | ||||
| 	if( (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->blocked && !(node->x==End.x && node->y==End.y && CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->visitable)) || | ||||
| 		(CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype==rock) || | ||||
| 		((blockLandSea) && (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype==water)) || | ||||
| 	const TerrainTile *pom = CGI->mh->ttiles[node->x][node->y][node->z].tileInfo; | ||||
| 	if( (pom->blocked && !(node->x==End.x && node->y==End.y && pom->visitable)) || | ||||
| 		(pom->tertype==rock) || | ||||
| 		((blockLandSea) && (pom->tertype==water)) || | ||||
| 		(!CGI->state->players[Hero->tempOwner].fogOfWarMap[node->x][node->y][node->z]) || | ||||
| 		((!blockLandSea) && (CGI->mh->ttiles[node->x][node->y][node->z].tileInfo->tertype!=water))) | ||||
| 		((!blockLandSea) && (pom->tertype!=water))) | ||||
| 	{ | ||||
| 		//Impossible. | ||||
|  | ||||
|   | ||||
| @@ -957,7 +957,7 @@ CPlayerInterface::CPlayerInterface(int Player, int serial) | ||||
| 	playerID=Player; | ||||
| 	serialID=serial; | ||||
| 	human=true; | ||||
| 	pim = new boost::mutex; | ||||
| 	pim = new boost::recursive_mutex; | ||||
| 	showingDialog = new CondSh<bool>(false); | ||||
| } | ||||
| CPlayerInterface::~CPlayerInterface() | ||||
| @@ -1100,7 +1100,7 @@ int getDir(int3 src, int3 dst) | ||||
| } | ||||
| void CPlayerInterface::heroMoved(const HeroMoveDetails & details) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	//initializing objects and performing first step of move | ||||
| 	const CGHeroInstance * ho = details.ho; //object representing this hero | ||||
| 	int3 hp = details.src; | ||||
| @@ -1536,7 +1536,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details) | ||||
| } | ||||
| void CPlayerInterface::heroKilled(const CGHeroInstance* hero) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	graphics->heroWins.erase(hero->ID); | ||||
| 	adventureInt->heroList.updateHList(); | ||||
| } | ||||
| @@ -1721,19 +1721,6 @@ void CPlayerInterface::handleKeyDown(SDL_Event *sEvent) | ||||
| 			LOCPLINT->adventureInt->scrollingDown = true; | ||||
| 			break; | ||||
| 		} | ||||
| 	case (SDLK_F4): | ||||
| 		{ | ||||
| 			if(sEvent->key.keysym.mod & KMOD_LALT) //Alt+F4 | ||||
| 			{ | ||||
| 				exit(0); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	//case (SDLK_q): | ||||
| 	//	{ | ||||
| 	//		exit(0); | ||||
| 	//		break; | ||||
| 	//	} | ||||
| 	case (SDLK_u): | ||||
| 		{ | ||||
| 			adventureInt->underground.clickLeft(true); | ||||
| @@ -1853,7 +1840,7 @@ int3 CPlayerInterface::repairScreenPos(int3 pos) | ||||
| } | ||||
| void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	SDL_FreeSurface(graphics->heroWins[hero->subID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia | ||||
| 	graphics->heroWins[hero->subID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki. | ||||
| 	if (adventureInt->selection == hero) | ||||
| @@ -1863,7 +1850,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int | ||||
|  | ||||
| void CPlayerInterface::receivedResource(int type, int val) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(!curint->subInt) | ||||
| 		adventureInt->resdatabar.draw(); | ||||
| } | ||||
| @@ -1871,7 +1858,7 @@ void CPlayerInterface::receivedResource(int type, int val) | ||||
| void CPlayerInterface::showSelDialog(std::string &text, const std::vector<Component*> &components, ui32 askID) | ||||
| //void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	adventureInt->hide(); //dezaktywacja starego interfejsu | ||||
| 	std::vector<CSelectableComponent*> intComps; | ||||
| 	for(int i=0;i<components.size();i++) | ||||
| @@ -1892,14 +1879,14 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std: | ||||
| 		while(showingDialog->data) | ||||
| 			showingDialog->cond.wait(un); | ||||
| 	} | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	CLevelWindow *lw = new CLevelWindow(hero,pskill,skills,callback); | ||||
| 	curint->deactivate(); | ||||
| 	lw->activate(); | ||||
| } | ||||
| void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	//redraw infowindow | ||||
| 	SDL_FreeSurface(graphics->townWins[town->id]); | ||||
| 	graphics->townWins[town->id] = infoWin(town); | ||||
| @@ -1928,12 +1915,12 @@ void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownIn | ||||
| { | ||||
| 	if(hero->tempOwner != town->tempOwner) | ||||
| 		return; | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	openTownWindow(town); | ||||
| } | ||||
| void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(obj->ID == 34) //hero | ||||
| 	{ | ||||
| 		const CGHeroInstance * hh; | ||||
| @@ -1977,7 +1964,7 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) | ||||
| } | ||||
| void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	switch (buildingID) | ||||
| 	{ | ||||
| 	case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15: | ||||
| @@ -2004,7 +1991,7 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, | ||||
|  | ||||
| void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side) //called by engine when battle starts; side=0 - left, side=1 - right | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	curint->deactivate(); | ||||
| 	curint = new CBattleInterface(army1,army2,hero1,hero2); | ||||
| 	curint->activate(); | ||||
| @@ -2033,7 +2020,7 @@ BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn | ||||
| { | ||||
| 	CBattleInterface *b = dynamic_cast<CBattleInterface*>(curint); | ||||
| 	{ | ||||
| 		boost::unique_lock<boost::mutex> un(*pim); | ||||
| 		boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 		b->stackActivated(stackID); | ||||
| 	} | ||||
| 	//wait till BattleInterface sets its command | ||||
| @@ -2057,7 +2044,7 @@ void CPlayerInterface::battleEnd(BattleResult *br) | ||||
|  | ||||
| void CPlayerInterface::battleResultQuited() | ||||
| { | ||||
| 	//boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	//boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	((CBattleInterface*)curint)->resWindow->deactivate(); | ||||
| 	objsToBlit -= curint; | ||||
| 	delete curint; | ||||
| @@ -2067,12 +2054,12 @@ void CPlayerInterface::battleResultQuited() | ||||
|  | ||||
| void CPlayerInterface::battleStackMoved(int ID, int dest, bool startMoving, bool endMoving) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	dynamic_cast<CBattleInterface*>(curint)->stackMoved(ID, dest, startMoving, endMoving); | ||||
| } | ||||
| void CPlayerInterface::battleAttack(BattleAttack *ba) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(ba->shot()) | ||||
| 		dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ba->stackAttacking,cb->battleGetPos(ba->bsa.stackAttacked)); | ||||
| 	else | ||||
| @@ -2094,7 +2081,7 @@ void CPlayerInterface::battleStackIsShooting(int ID, int dest) | ||||
|  | ||||
| void CPlayerInterface::showComp(SComponent comp) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	adventureInt->infoBar.showComp(&comp,4000); | ||||
| } | ||||
|  | ||||
| @@ -2108,6 +2095,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<Compo | ||||
| void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<SComponent*> & components) | ||||
| { | ||||
| 	showingDialog->set(true); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	curint->deactivate(); //dezaktywacja starego interfejsu | ||||
|  | ||||
| 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom; | ||||
| @@ -2120,6 +2108,7 @@ void CPlayerInterface::showInfoDialog(std::string &text, const std::vector<SComp | ||||
| } | ||||
| void CPlayerInterface::showYesNoDialog(std::string &text, const std::vector<SComponent*> & components, CFunctionList<void()> onYes, CFunctionList<void()> onNo, bool deactivateCur, bool DelComps) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(deactivateCur) | ||||
| 		curint->deactivate(); //dezaktywacja starego interfejsu | ||||
| 	std::vector<std::pair<std::string,CFunctionList<void()> > > pom; | ||||
| @@ -2142,7 +2131,7 @@ void CPlayerInterface::showYesNoDialog(std::string &text, const std::vector<SCom | ||||
|  | ||||
| void CPlayerInterface::showYesNoDialog( std::string &text, const std::vector<Component*> &components, ui32 askID ) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	curint->deactivate(); //dezaktywacja starego interfejsu | ||||
|  | ||||
| 	std::vector<SComponent*> intComps; | ||||
| @@ -2164,20 +2153,24 @@ void CPlayerInterface::showYesNoDialog( std::string &text, const std::vector<Com | ||||
| } | ||||
| void CPlayerInterface::removeObjToBlit(IShowable* obj) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	objsToBlit.erase | ||||
| 		(std::find(objsToBlit.begin(),objsToBlit.end(),obj)); | ||||
| 	//delete obj; | ||||
| } | ||||
| void CPlayerInterface::tileRevealed(int3 pos) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	adventureInt->minimap.showTile(pos); | ||||
| } | ||||
| void CPlayerInterface::tileHidden(int3 pos) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	adventureInt->minimap.hideTile(pos); | ||||
| } | ||||
| void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	adventureInt->heroWindow->setHero(hero); | ||||
| 	this->objsToBlit.push_back(adventureInt->heroWindow); | ||||
| 	curint->deactivate(); | ||||
| @@ -2191,7 +2184,7 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero) | ||||
|  | ||||
| void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(curint->subInt == adventureInt->heroWindow) | ||||
| 	{ | ||||
| 		adventureInt->heroWindow->deactivate(); | ||||
| @@ -2236,7 +2229,7 @@ void CPlayerInterface::updateWater() | ||||
|  | ||||
| void CPlayerInterface::availableCreaturesChanged( const CGTownInstance *town ) | ||||
| { | ||||
| 	boost::unique_lock<boost::mutex> un(*pim); | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
| 	if(curint == castleInt) | ||||
| 	{ | ||||
| 		CFortScreen *fs = dynamic_cast<CFortScreen*>(curint->subInt); | ||||
|   | ||||
| @@ -30,6 +30,7 @@ template <typename T> struct CondSh; | ||||
| namespace boost | ||||
| { | ||||
| 	class mutex; | ||||
| 	class recursive_mutex; | ||||
| }; | ||||
|  | ||||
| class IShowable | ||||
| @@ -316,7 +317,7 @@ class CPlayerInterface : public CGameInterface | ||||
| public: | ||||
| 	//minor interfaces | ||||
| 	CondSh<bool> *showingDialog; | ||||
| 	boost::mutex *pim; | ||||
| 	boost::recursive_mutex *pim; | ||||
| 	bool makingTurn; | ||||
| 	SDL_Event * current; | ||||
| 	CMainInterface *curint; | ||||
|   | ||||
							
								
								
									
										29
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -1,3 +1,32 @@ | ||||
| 0.62 -> 0.63 (Sep 28 2008???) | ||||
| * very significant optimization of battles  | ||||
| * battle summary window | ||||
| * fixed crashbug on exiting battle  | ||||
| * mostly done morketplace  | ||||
| * confirm window is shown before retreat  | ||||
| * it's possible to use other port than 3030 by passing it as an additional argument | ||||
| * removed some redundant warnings | ||||
| * stack queue in battle (shows when 'c' key is pressed)  | ||||
| * partially done spellbook | ||||
| * fixed crashbug with battles on swamps and rough terrain | ||||
| * counterattacks | ||||
| * heroes learn spells in towns | ||||
| * it's possible to attack enemy hero | ||||
| * setting army formation | ||||
| * fixed bug with disappearing head of a hero in adventure map | ||||
| * some objects are no longer accessible from the top  | ||||
| * no tooltips for objects under FoW | ||||
| * working resource silo | ||||
| * neutral monster army disappears when defeated | ||||
| * Alt+F4 quits the game | ||||
| * dead stacks won't be displayed in battle queue  | ||||
| * possibly fixed bug with the mage guild when no spells available | ||||
| * events won't be shown and won't block movement | ||||
| * casualties among hero army and neutral creatures are saved | ||||
| * it's possible to build lighthouse | ||||
| * increased thread-safety (may prevent some crashes) | ||||
| * minor fixes | ||||
|  | ||||
| 0.61 -> 0.62 (Sep 01 2008) | ||||
| General: | ||||
| * restructured to the server-client model | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| 0 | ||||
| TPTHBKCS.BMP | ||||
| 10 11 12 13 | 7 8 9 | 5 22 | 16 | ||||
| 14 15 | 0 1 2 3 | 6 | ||||
| 14 15 | 0 1 2 3 | 6 17 | ||||
| 21 | 18 19 | ||||
| 30 37 | 31 38 | 32 39 | 33 40 | ||||
| 34 41 | 35 42 | 36 43 | ||||
|   | ||||
							
								
								
									
										2
									
								
								global.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								global.h
									
									
									
									
									
								
							| @@ -16,7 +16,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte) | ||||
| #define THC | ||||
| #endif | ||||
|  | ||||
| #define NAME_VER ("VCMI 0.63") | ||||
| #define NAME_VER ("VCMI 0.62b") | ||||
| #define CONSOLE_LOGGING_LEVEL 5 | ||||
| #define FILE_LOGGING_LEVEL 6 | ||||
|  | ||||
|   | ||||
| @@ -286,7 +286,7 @@ struct InfoWindow : public CPack<InfoWindow> //103  - displays simple info windo | ||||
| struct SetObjectProperty : public CPack<SetObjectProperty>//1001 | ||||
| { | ||||
| 	ui32 id; | ||||
| 	ui8 what; //1 - owner; 2 - blockvis | ||||
| 	ui8 what; //1 - owner; 2 - blockvis; 3 - amount (works with creatures stacks) | ||||
| 	ui32 val; | ||||
| 	SetObjectProperty(){type = 1001;}; | ||||
| 	SetObjectProperty(ui32 ID, ui8 What, ui32 Val):id(ID),what(What),val(Val){type = 1001;}; | ||||
|   | ||||
							
								
								
									
										2
									
								
								map.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								map.cpp
									
									
									
									
									
								
							| @@ -500,7 +500,7 @@ void Mapa::removeBlockVisTiles(CGObjectInstance * obj) | ||||
| 				if(!((obj->defInfo->blockMap[fy] >> (7 - fx)) & 1)) | ||||
| 				{ | ||||
| 					curt.blockingObjects -= obj; | ||||
| 					curt.blocked = curt.visitableObjects.size(); | ||||
| 					curt.blocked = curt.blockingObjects.size(); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -458,6 +458,8 @@ void CMapHandler::initObjectRects() | ||||
| } | ||||
| void processDef (CGDefInfo* def) | ||||
| { | ||||
| 	if(def->id == 26) | ||||
| 		return; | ||||
| 	def->handler=CDefHandler::giveDef(def->name); | ||||
| 	def->width = def->handler->ourImages[0].bitmap->w/32; | ||||
| 	def->height = def->handler->ourImages[0].bitmap->h/32; | ||||
|   | ||||
| @@ -241,6 +241,23 @@ void CGameHandler::changePrimSkill(int ID, int which, int val, bool abs) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CCreatureSet takeCasualties(int color, const CCreatureSet &set, BattleInfo *bat) | ||||
| { | ||||
| 	CCreatureSet ret(set); | ||||
| 	for(int i=0; i<bat->stacks.size();i++) | ||||
| 	{ | ||||
| 		CStack *st = bat->stacks[i]; | ||||
| 		if(st->owner==color && vstd::contains(set.slots,st->slot) && st->amount < set.slots.find(st->slot)->second.second) | ||||
| 		{ | ||||
| 			if(st->alive()) | ||||
| 				ret.slots[st->slot].second = st->amount; | ||||
| 			else | ||||
| 				ret.slots.erase(st->slot); | ||||
| 		} | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb) | ||||
| { | ||||
| 	BattleInfo *curB = new BattleInfo; | ||||
| @@ -285,17 +302,35 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile | ||||
| 	if(hero1->tempOwner<PLAYER_LIMIT) | ||||
| 		states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,false); | ||||
| 	if(hero2 && hero2->tempOwner<PLAYER_LIMIT) | ||||
| 		states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,false); | ||||
| 		states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,false);	 | ||||
|  | ||||
| 	//casualties among heroes armies | ||||
| 	SetGarrisons sg; | ||||
| 	if(hero1) | ||||
| 		sg.garrs[hero1->id] = takeCasualties(hero1->tempOwner,hero1->army,gs->curB); | ||||
| 	if(hero2) | ||||
| 		sg.garrs[hero2->id] = takeCasualties(hero2->tempOwner,hero2->army,gs->curB); | ||||
| 	sendAndApply(&sg); | ||||
|  | ||||
| 	//end battle, remove all info, free memory | ||||
| 	sendAndApply(battleResult.data); | ||||
| 	if(cb) | ||||
| 		cb(battleResult.data); | ||||
|  | ||||
| 	//if one hero has lost we will erase him | ||||
| 	if(battleResult.data->winner!=0 && hero1) | ||||
| 	{ | ||||
| 		RemoveObject ro(hero1->id); | ||||
| 		sendAndApply(&ro); | ||||
| 	} | ||||
| 	if(battleResult.data->winner!=1 && hero2) | ||||
| 	{ | ||||
| 		RemoveObject ro(hero2->id); | ||||
| 		sendAndApply(&ro); | ||||
| 	} | ||||
|  | ||||
| 	delete battleResult.data; | ||||
| 	//for(int i=0;i<stacks.size();i++) | ||||
| 	//	delete stacks[i]; | ||||
| 	//delete curB; | ||||
| 	//curB = NULL; | ||||
|  | ||||
| } | ||||
| void prepareAttack(BattleAttack &bat, CStack *att, CStack *def) | ||||
| { | ||||
| @@ -349,7 +384,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c) | ||||
| 					states.setFlag(gs->currentPlayer,&PlayerStatus::makingTurn,false); | ||||
| 					break; | ||||
| 				} | ||||
| 			case 500: | ||||
| 			case 500: //dismiss hero | ||||
| 				{ | ||||
| 					si32 id; | ||||
| 					c >> id; | ||||
| @@ -521,7 +556,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c) | ||||
| 					sendAndApply(&sg); | ||||
| 					break; | ||||
| 				} | ||||
| 			case 503: | ||||
| 			case 503: //disband creature | ||||
| 				{ | ||||
| 					si32 id; | ||||
| 					ui8 pos; | ||||
| @@ -533,7 +568,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c) | ||||
| 					sendAndApply(&sg); | ||||
| 					break; | ||||
| 				} | ||||
| 			case 504: | ||||
| 			case 504: //build structure | ||||
| 				{ | ||||
| 					si32 tid, bid; | ||||
| 					c >> tid >> bid; | ||||
| @@ -1368,7 +1403,7 @@ void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h | ||||
| 	cs.learn = true; | ||||
| 	for(int i=0; i<std::min(t->mageGuildLevel(),h->getSecSkillLevel(7)+4);i++) | ||||
| 	{ | ||||
| 		for(int j=0; j<t->spellsAtLevel(i+1,true); j++) | ||||
| 		for(int j=0; j<t->spellsAtLevel(i+1,true) && j<t->spells[i].size(); j++) | ||||
| 		{ | ||||
| 			if(!vstd::contains(h->spells,t->spells[i][j])) | ||||
| 				cs.spells.insert(t->spells[i][j]); | ||||
|   | ||||
| @@ -33,6 +33,12 @@ void CScriptCallback::removeObject(int objid) | ||||
| 	gh->sendAndApply(&ro); | ||||
| } | ||||
|  | ||||
| void CScriptCallback::setAmount(int objid, ui32 val) | ||||
| { | ||||
| 	SetObjectProperty sop(objid,3,val); | ||||
| 	gh->sendAndApply(&sop); | ||||
| } | ||||
|  | ||||
| void CScriptCallback::setOwner(int objid, ui8 owner) | ||||
| { | ||||
| 	SetObjectProperty sop(objid,1,owner); | ||||
|   | ||||
| @@ -55,6 +55,7 @@ public: | ||||
| 	void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack | ||||
| 	void startBattle(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero | ||||
| 	void startBattle(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army | ||||
| 	void setAmount(int objid, ui32 val); | ||||
|  | ||||
| 	//friends | ||||
| 	friend class CGameHandler; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user