mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- bugfixing:
-- fixed #942 and #898 -- removed dublicated code in dwelling loading, #900 is fixed -- fixed roads rendering for #895
This commit is contained in:
		| @@ -1074,6 +1074,7 @@ townList(ADVOPT.tlistSize,ADVOPT.tlistX,ADVOPT.tlistY,ADVOPT.tlistAU,ADVOPT.tlis | ||||
|  | ||||
|  | ||||
| 	setPlayer(LOCPLINT->playerID); | ||||
| 	underground.block(!CGI->mh->map->twoLevel); | ||||
| } | ||||
|  | ||||
| CAdvMapInt::~CAdvMapInt() | ||||
|   | ||||
| @@ -507,7 +507,7 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst | ||||
| 			OwnedObjectInfo &info = visibleObjects[object->subID]; | ||||
| 			if (info.count++ == 0) | ||||
| 			{ | ||||
| 				info.hoverText = CGI->creh->creatures[CGI->objh->cregens[object->subID]]->namePl; | ||||
| 				info.hoverText = CGI->creh->creatures[CGI->objh->cregens.find(object->subID)->second]->namePl; | ||||
| 				info.imageID = object->subID; | ||||
| 			} | ||||
| 		} | ||||
|   | ||||
| @@ -2144,6 +2144,7 @@ void CPlayerInterface::acceptTurn() | ||||
| 	else | ||||
| 		adventureInt->select(towns.front()); | ||||
|  | ||||
| 	adventureInt->updateNextHero(NULL); | ||||
| 	adventureInt->showAll(screen); | ||||
|  | ||||
| 	if(settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed()) | ||||
|   | ||||
| @@ -498,23 +498,43 @@ void CMapHandler::terrainRect( int3 top_tile, ui8 anim, const std::vector< std:: | ||||
| 			sr.h=sr.w=32; | ||||
|  | ||||
| 			//blit terrain with river/road | ||||
| 			if(tile.terbitmap) { //if custom terrain graphic - use it | ||||
| 			if(tile.terbitmap) | ||||
| 			{ //if custom terrain graphic - use it | ||||
| 				SDL_Rect temp_rect = genRect(sr.h, sr.w, 0, 0); | ||||
| 				CSDL_Ext::blitSurface(tile.terbitmap, &temp_rect, extSurf, &sr); | ||||
| 			} else //use default terrain graphic | ||||
| 			} | ||||
| 			else //use default terrain graphic | ||||
| 			{ | ||||
| 				blitterWithRotation(terrainGraphics[tinfo.tertype][tinfo.terview],rtile, extSurf, sr, tinfo.siodmyTajemniczyBajt%4); | ||||
| 			} | ||||
| 			if(tinfo.nuine) //print river if present | ||||
| 			{ | ||||
| 				blitterWithRotationAndAlpha(staticRiverDefs[tinfo.nuine-1]->ourImages[tinfo.rivDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>2)%4); | ||||
| 			if(tinfo.malle) //print road if present | ||||
| 				blitterWithRotationAndAlpha(roadDefs[tinfo.malle-1]->ourImages[tinfo.roadDir].bitmap,rtile, extSurf, sr, (tinfo.siodmyTajemniczyBajt>>4)%4); | ||||
| 			} | ||||
|  | ||||
| 			//Roads are shifted by 16 pixels to bottom. We have to draw both parts separately | ||||
| 			if (pos.y > 0 && map->terrain[pos.x][pos.y-1][pos.z].malle) | ||||
| 			{ //part from top tile | ||||
| 				const TerrainTile &topTile = map->terrain[pos.x][pos.y-1][pos.z]; | ||||
| 				Rect source(0, 16, 32, 16); | ||||
| 				Rect dest(sr.x, sr.y, sr.w, sr.h/2); | ||||
| 				blitterWithRotationAndAlpha(roadDefs[topTile.malle-1]->ourImages[topTile.roadDir].bitmap, source, extSurf, dest, (topTile.siodmyTajemniczyBajt>>4)%4); | ||||
| 			} | ||||
|  | ||||
| 			if(tinfo.malle) //print road from this tile | ||||
| 			{ | ||||
| 				Rect source(0, 0, 32, 32); | ||||
| 				Rect dest(sr.x, sr.y+16, sr.w, sr.h/2); | ||||
| 				blitterWithRotationAndAlpha(roadDefs[tinfo.malle-1]->ourImages[tinfo.roadDir].bitmap, source, extSurf, dest, (tinfo.siodmyTajemniczyBajt>>4)%4); | ||||
| 			} | ||||
|  | ||||
| 			//blit objects | ||||
| 			const std::vector < std::pair<const CGObjectInstance*,SDL_Rect> > &objects = tile.objects; | ||||
| 			for(int h=0; h < objects.size(); ++h) | ||||
| 			{ | ||||
| 				const CGObjectInstance *obj = objects[h].first; | ||||
|                 if (!graphics->getDef(obj)) | ||||
|                     processDef(obj->defInfo); | ||||
| 				if (!graphics->getDef(obj)) | ||||
| 					processDef(obj->defInfo); | ||||
|  | ||||
| 				ui8 color = obj->tempOwner; | ||||
|  | ||||
|   | ||||
| @@ -591,100 +591,69 @@ std::pair<int,int> CGameState::pickObject (CGObjectInstance *obj) | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 6)); | ||||
| 	case 164: //random monster lvl7 | ||||
| 		return std::pair<int,int>(54, VLC->creh->pickRandomMonster(boost::ref(ran), 7)); | ||||
| 	case 216: //random dwelling | ||||
| 		{ | ||||
| 			int faction = ran()%GameConstants::F_NUMBER; | ||||
| 			CGDwelling * dwl = static_cast<CGDwelling*>(obj); | ||||
| 			CCreGen2ObjInfo* info = static_cast<CCreGen2ObjInfo*>(dwl->info); | ||||
| 			if (info->asCastle) | ||||
| 			{ | ||||
| 				for(ui32 i=0;i<map->objects.size();i++) | ||||
| 				{ | ||||
| 					if(map->objects[i]->ID==77 && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 					{ | ||||
| 						randomizeObject(map->objects[i]); //we have to randomize the castle first | ||||
| 						faction = map->objects[i]->subID; | ||||
| 						break; | ||||
| 					} | ||||
| 					else if(map->objects[i]->ID==GameConstants::TOWNI_TYPE && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 					{ | ||||
| 						faction = map->objects[i]->subID; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				while((!(info->castles[0]&(1<<faction)))) | ||||
| 				{ | ||||
| 					if((faction>7) && (info->castles[1]&(1<<(faction-8)))) | ||||
| 						break; | ||||
| 					faction = ran()%GameConstants::F_NUMBER; | ||||
| 				} | ||||
| 			} | ||||
| 			int level = ((info->maxLevel-info->minLevel) ? (ran()%(info->maxLevel-info->minLevel)+info->minLevel) : (info->minLevel)); | ||||
| 			int cid = VLC->townh->towns[faction].basicCreatures[level]; | ||||
| 			for(ui32 i=0;i<VLC->objh->cregens.size();i++) | ||||
| 				if(VLC->objh->cregens[i]==cid) | ||||
| 					return std::pair<int,int>(17,i); | ||||
| 			tlog3 << "Cannot find a dwelling for creature "<< cid << std::endl; | ||||
| 			return std::pair<int,int>(17,0); | ||||
| 			delete dwl->info; | ||||
| 			dwl->info = NULL; | ||||
| 		} | ||||
| 	case 216: //random dwellings | ||||
| 	case 217: | ||||
| 		{ | ||||
| 			int faction = ran()%GameConstants::F_NUMBER; | ||||
| 			CGDwelling * dwl = static_cast<CGDwelling*>(obj); | ||||
| 			CCreGenObjInfo* info = static_cast<CCreGenObjInfo*>(dwl->info); | ||||
| 			if (info->asCastle) | ||||
| 			{ | ||||
| 				for(ui32 i=0;i<map->objects.size();i++) | ||||
| 				{ | ||||
| 					if(map->objects[i]->ID==77 && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 					{ | ||||
| 						randomizeObject(map->objects[i]); //we have to randomize the castle first | ||||
| 						faction = map->objects[i]->subID; | ||||
| 						break; | ||||
| 					} | ||||
| 					else if(map->objects[i]->ID==GameConstants::TOWNI_TYPE && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 					{ | ||||
| 						faction = map->objects[i]->subID; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				while((!(info->castles[0]&(1<<faction)))) | ||||
| 				{ | ||||
| 					if((faction>7) && (info->castles[1]&(1<<(faction-8)))) | ||||
| 						break; | ||||
| 					faction = ran()%GameConstants::F_NUMBER; | ||||
| 				} | ||||
| 			} | ||||
| 			int cid = VLC->townh->towns[faction].basicCreatures[obj->subID]; | ||||
| 			for(ui32 i=0;i<VLC->objh->cregens.size();i++) | ||||
| 				if(VLC->objh->cregens[i]==cid) | ||||
| 					return std::pair<int,int>(17,i); | ||||
| 			tlog3 << "Cannot find a dwelling for creature "<<cid <<std::endl; | ||||
| 			return std::pair<int,int>(17,0); | ||||
| 			delete dwl->info; | ||||
| 			dwl->info = NULL; | ||||
| 		} | ||||
| 	case 218: | ||||
| 		{ | ||||
| 			CGDwelling * dwl = static_cast<CGDwelling*>(obj); | ||||
| 			CCreGen3ObjInfo* info = static_cast<CCreGen3ObjInfo*>(dwl->info); | ||||
| 			int level = ((info->maxLevel-info->minLevel) ? (ran()%(info->maxLevel-info->minLevel)+info->minLevel) : (info->minLevel)); | ||||
| 			int cid = VLC->townh->towns[obj->subID].basicCreatures[level]; | ||||
| 			for(ui32 i=0;i<VLC->objh->cregens.size();i++) | ||||
| 				if(VLC->objh->cregens[i]==cid) | ||||
| 					return std::pair<int,int>(17,i); | ||||
| 			tlog3 << "Cannot find a dwelling for creature "<<cid <<std::endl; | ||||
| 			return std::pair<int,int>(17,0); | ||||
| 			int faction; | ||||
|  | ||||
| 			//if castle alignment available | ||||
| 			if (auto info = dynamic_cast<CCreGenAsCastleInfo*>(dwl->info)) | ||||
| 			{ | ||||
| 				faction = ran()%GameConstants::F_NUMBER; | ||||
| 				if (info->asCastle) | ||||
| 				{ | ||||
| 					for(ui32 i=0;i<map->objects.size();i++) | ||||
| 					{ | ||||
| 						if(map->objects[i]->ID==77 && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 						{ | ||||
| 							randomizeObject(map->objects[i]); //we have to randomize the castle first | ||||
| 							faction = map->objects[i]->subID; | ||||
| 							break; | ||||
| 						} | ||||
| 						else if(map->objects[i]->ID==GameConstants::TOWNI_TYPE && dynamic_cast<CGTownInstance*>(map->objects[i].get())->identifier == info->identifier) | ||||
| 						{ | ||||
| 							faction = map->objects[i]->subID; | ||||
| 							break; | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					while((!(info->castles[0]&(1<<faction)))) | ||||
| 					{ | ||||
| 						if((faction>7) && (info->castles[1]&(1<<(faction-8)))) | ||||
| 							break; | ||||
| 						faction = ran()%GameConstants::F_NUMBER; | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			else // castle alignment fixed | ||||
| 				faction = obj->subID; | ||||
|  | ||||
| 			int level; | ||||
|  | ||||
| 			//if level set to range | ||||
| 			if (auto info = dynamic_cast<CCreGenLeveledInfo*>(dwl->info)) | ||||
| 				level = ((info->maxLevel-info->minLevel) ? (ran()%(info->maxLevel-info->minLevel)+info->minLevel) : (info->minLevel)); | ||||
| 			else // fixed level | ||||
| 				level = obj->subID; | ||||
|  | ||||
| 			delete dwl->info; | ||||
| 			dwl->info = NULL; | ||||
| 			dwl->info = nullptr; | ||||
|  | ||||
| 			std::pair<int,int> result(-1, -1); | ||||
| 			int cid = VLC->townh->towns[faction].basicCreatures[level]; | ||||
|  | ||||
| 			//NOTE: this will pick last dwelling with this creature (Mantis #900) | ||||
| 			//check for block map equality is better but more complex solution | ||||
| 			BOOST_FOREACH(auto &iter, VLC->objh->cregens) | ||||
| 				if (iter.second == cid) | ||||
| 					result = std::pair<int,int>(17, iter.first); | ||||
|  | ||||
| 			tlog3 << "Cannot find a dwelling for creature "<< cid << std::endl; | ||||
| 			return result; | ||||
| 		} | ||||
| 	} | ||||
| 	return std::pair<int,int>(-1,-1); | ||||
|   | ||||
| @@ -155,11 +155,6 @@ static void readBankLevel(const JsonNode &level, BankConfig &bc) | ||||
| void CObjectHandler::loadObjects() | ||||
| { | ||||
| 	tlog5 << "\t\tReading cregens \n"; | ||||
| 	cregens.resize(110); //TODO: hardcoded value - change | ||||
| 	for(size_t i=0; i < cregens.size(); ++i) | ||||
| 	{ | ||||
| 		cregens[i]=-1; | ||||
| 	} | ||||
|  | ||||
| 	const JsonNode config(GameConstants::DATA_DIR + "/config/dwellings.json"); | ||||
| 	BOOST_FOREACH(const JsonNode &dwelling, config["dwellings"].Vector()) | ||||
|   | ||||
| @@ -412,30 +412,25 @@ class DLL_LINKAGE CSpecObjInfo | ||||
| { | ||||
| public: | ||||
| 	virtual ~CSpecObjInfo(){}; | ||||
| 	ui8 player; //owner | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CCreGenObjInfo : public CSpecObjInfo | ||||
| class DLL_LINKAGE CCreGenAsCastleInfo : public virtual CSpecObjInfo | ||||
| { | ||||
| public: | ||||
| 	ui8 player; //owner | ||||
| 	bool asCastle; | ||||
| 	ui32 identifier; | ||||
| 	ui8 castles[2]; //allowed castles | ||||
| }; | ||||
| class DLL_LINKAGE CCreGen2ObjInfo : public CSpecObjInfo | ||||
|  | ||||
| class DLL_LINKAGE CCreGenLeveledInfo : public virtual CSpecObjInfo | ||||
| { | ||||
| public: | ||||
| 	ui8 player; //owner | ||||
| 	bool asCastle; | ||||
| 	ui32 identifier; | ||||
| 	ui8 castles[2]; //allowed castles | ||||
| 	ui8 minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6> | ||||
| }; | ||||
| class DLL_LINKAGE CCreGen3ObjInfo : public CSpecObjInfo | ||||
|  | ||||
| class DLL_LINKAGE CCreGenLeveledCastleInfo : public CCreGenAsCastleInfo, public CCreGenLeveledInfo | ||||
| { | ||||
| public: | ||||
| 	ui8 player; //owner | ||||
| 	ui8 minLevel, maxLevel; //minimal and maximal level of creature in dwelling: <0, 6> | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CGDwelling : public CArmedInstance | ||||
| @@ -1318,7 +1313,7 @@ struct BankConfig | ||||
| class DLL_LINKAGE CObjectHandler | ||||
| { | ||||
| public: | ||||
| 	std::vector<si32> cregens; //type 17. dwelling subid -> creature ID | ||||
| 	std::map<si32, si32> cregens; //type 17. dwelling subid -> creature ID | ||||
| 	std::map <ui32, std::vector < ConstTransitivePtr<BankConfig> > > banksInfo; //[index][preset] | ||||
| 	std::map <ui32, std::string> creBanksNames; //[crebank index] -> name of this creature bank | ||||
| 	std::vector<ui32> resVals; //default values of resources in gold | ||||
|   | ||||
							
								
								
									
										79
									
								
								lib/map.cpp
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								lib/map.cpp
									
									
									
									
									
								
							| @@ -1675,64 +1675,49 @@ void Mapa::readObjects( const ui8 * bufor, int &i) | ||||
| 				grailRadious = read_le_u32(bufor + i); i+=4; | ||||
| 				continue; | ||||
| 			} | ||||
| 		case 217: | ||||
| 		//dwellings | ||||
| 		case 216: //same as castle + level range | ||||
| 		case 217: //same as castle | ||||
| 		case 218: //level range | ||||
| 			{ | ||||
| 				nobj = new CGDwelling(); | ||||
| 				CCreGenObjInfo * spec = new CCreGenObjInfo; | ||||
| 				spec->player = read_le_u32(bufor + i); i+=4; | ||||
| 				spec->identifier =  read_le_u32(bufor + i); i+=4; | ||||
| 				if(!spec->identifier) | ||||
| 				CSpecObjInfo * spec = nullptr; | ||||
| 				switch(defInfo->id) | ||||
| 				{ | ||||
| 					spec->asCastle = false; | ||||
| 					spec->castles[0] = bufor[i]; ++i; | ||||
| 					spec->castles[1] = bufor[i]; ++i; | ||||
| 					break; case 216: spec = new CCreGenLeveledCastleInfo; | ||||
| 					break; case 217: spec = new CCreGenAsCastleInfo; | ||||
| 					break; case 218: spec = new CCreGenLeveledInfo; | ||||
| 				} | ||||
|  | ||||
| 				spec->player = read_le_u32(bufor + i); i+=4; | ||||
| 				//216 and 217 | ||||
| 				if (auto castleSpec = dynamic_cast<CCreGenAsCastleInfo*>(spec)) | ||||
| 				{ | ||||
| 					castleSpec->identifier =  read_le_u32(bufor + i); i+=4; | ||||
| 					if(!castleSpec->identifier) | ||||
| 					{ | ||||
| 						castleSpec->asCastle = false; | ||||
| 						castleSpec->castles[0] = bufor[i]; ++i; | ||||
| 						castleSpec->castles[1] = bufor[i]; ++i; | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						castleSpec->asCastle = true; | ||||
| 					} | ||||
| 				} | ||||
| 				else | ||||
| 					i+=3; //only for 218 | ||||
|  | ||||
| 				//216 and 218 | ||||
| 				if (auto lvlSpec = dynamic_cast<CCreGenLeveledInfo*>(spec)) | ||||
| 				{ | ||||
| 					spec->asCastle = true; | ||||
| 					lvlSpec->minLevel = std::max(bufor[i], ui8(1)); ++i; | ||||
| 					lvlSpec->maxLevel = std::min(bufor[i], ui8(7)); ++i; | ||||
| 				} | ||||
| 				nobj->setOwner(spec->player); | ||||
| 				static_cast<CGDwelling*>(nobj)->info = spec; | ||||
| 				break; | ||||
| 			} | ||||
| 		case 216: | ||||
| 			{ | ||||
| 				nobj = new CGDwelling(); | ||||
| 				CCreGen2ObjInfo * spec = new CCreGen2ObjInfo; | ||||
| 				spec->player = read_le_u32(bufor + i); i+=4; | ||||
| 				spec->identifier =  read_le_u32(bufor + i); i+=4; | ||||
| 				if(!spec->identifier) | ||||
| 				{ | ||||
| 					spec->asCastle = false; | ||||
| 					spec->castles[0] = bufor[i]; ++i; | ||||
| 					spec->castles[1] = bufor[i]; ++i; | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					spec->asCastle = true; | ||||
| 				} | ||||
| 				spec->minLevel = bufor[i]; ++i; | ||||
| 				spec->maxLevel = bufor[i]; ++i; | ||||
| 				nobj->setOwner(spec->player); | ||||
| 				static_cast<CGDwelling*>(nobj)->info = spec; | ||||
| 				break; | ||||
| 			} | ||||
| 		case 218: | ||||
| 			{ | ||||
| 				nobj = new CGDwelling(); | ||||
| 				CCreGen3ObjInfo * spec = new CCreGen3ObjInfo; | ||||
| 				spec->player = bufor[i]; ++i; | ||||
| 				i+=3; | ||||
| 				spec->minLevel = bufor[i]; ++i; | ||||
| 				spec->maxLevel = bufor[i]; ++i; | ||||
| 				if(spec->maxLevel>7) | ||||
| 					spec->maxLevel = 7; | ||||
| 				if(spec->minLevel<1) | ||||
| 					spec->minLevel = 1; | ||||
| 				nobj->setOwner(spec->player); | ||||
| 				static_cast<CGDwelling*>(nobj)->info = spec; | ||||
| 				break; | ||||
| 			} | ||||
| 		case 215: | ||||
| 			{ | ||||
| 				CGQuestGuard *guard = new CGQuestGuard(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user