mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Further part of external dwellings handling. Still not done.
Redone MetaString.
This commit is contained in:
		| @@ -262,7 +262,8 @@ void InfoWindow::applyCl( CClient *cl ) | |||||||
| 	{ | 	{ | ||||||
| 		comps.push_back(&components[i]); | 		comps.push_back(&components[i]); | ||||||
| 	} | 	} | ||||||
| 	std::string str = toString(text); | 	std::string str; | ||||||
|  | 	text.toString(str); | ||||||
|  |  | ||||||
| 	if(vstd::contains(cl->playerint,player)) | 	if(vstd::contains(cl->playerint,player)) | ||||||
| 		cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundID)soundID); | 		cl->playerint[player]->showInfoDialog(str,comps,(soundBase::soundID)soundID); | ||||||
| @@ -282,7 +283,9 @@ void HeroLevelUp::applyCl( CClient *cl ) | |||||||
|  |  | ||||||
| void BlockingDialog::applyCl( CClient *cl ) | void BlockingDialog::applyCl( CClient *cl ) | ||||||
| { | { | ||||||
| 	std::string str = toString(text); | 	std::string str; | ||||||
|  | 	text.toString(str); | ||||||
|  |  | ||||||
| 	if(vstd::contains(cl->playerint,player)) | 	if(vstd::contains(cl->playerint,player)) | ||||||
| 		cl->playerint[player]->showBlockingDialog(str,components,id,(soundBase::soundID)soundID,selection(),cancel()); | 		cl->playerint[player]->showBlockingDialog(str,components,id,(soundBase::soundID)soundID,selection(),cancel()); | ||||||
| 	else | 	else | ||||||
| @@ -452,7 +455,7 @@ void PlayerMessage::applyCl(CClient *cl) | |||||||
| void ShowInInfobox::applyCl(CClient *cl) | void ShowInInfobox::applyCl(CClient *cl) | ||||||
| { | { | ||||||
| 	SComponent sc(c); | 	SComponent sc(c); | ||||||
| 	sc.description = toString(text); | 	text.toString(sc.description); | ||||||
| 	if(cl->playerint[player]->human) | 	if(cl->playerint[player]->human) | ||||||
| 	{ | 	{ | ||||||
| 		static_cast<CPlayerInterface*>(cl->playerint[player])->showComp(sc); | 		static_cast<CPlayerInterface*>(cl->playerint[player])->showComp(sc); | ||||||
|   | |||||||
| @@ -66,6 +66,15 @@ public: | |||||||
| 	si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought | 	si32 maxAmount(const std::vector<si32> &res) const; //how many creatures can be bought | ||||||
| 	static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion | 	static int getQuantityID(const int & quantity); //0 - a few, 1 - several, 2 - pack, 3 - lots, 4 - horde, 5 - throng, 6 - swarm, 7 - zounds, 8 - legion | ||||||
|  |  | ||||||
|  | 	template<typename RanGen> | ||||||
|  | 	int getRandomAmount(RanGen &ranGen) | ||||||
|  | 	{ | ||||||
|  | 		if(ammMax == ammMin) | ||||||
|  | 			return ammMax; | ||||||
|  | 		else | ||||||
|  | 			return ammMin + (ranGen() % (ammMax - ammMin)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | 	template <typename Handler> void serialize(Handler &h, const int version) | ||||||
| 	{ | 	{ | ||||||
| 		h & namePl & nameSing & nameRef | 		h & namePl & nameSing & nameRef | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ void CDefObjInfoHandler::load() | |||||||
| 		{ | 		{ | ||||||
| 			nobj->blockMap[o] = 0xff; | 			nobj->blockMap[o] = 0xff; | ||||||
| 			nobj->visitMap[o] = 0x00; | 			nobj->visitMap[o] = 0x00; | ||||||
| 			nobj->coverageMap[0] = 0x00; | 			nobj->coverageMap[o] = 0x00; | ||||||
| 		} | 		} | ||||||
| 		inp>>mapStr; | 		inp>>mapStr; | ||||||
| 		std::reverse(mapStr.begin(), mapStr.end()); | 		std::reverse(mapStr.begin(), mapStr.end()); | ||||||
|   | |||||||
| @@ -305,6 +305,15 @@ void CGeneralTextHandler::load() | |||||||
| 		creGens.push_back(temp); | 		creGens.push_back(temp); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	tlog5 << "\t\tReading CRGN4 \n"; | ||||||
|  | 	buf = bitmaph->getTextFile("CRGEN4.TXT"); | ||||||
|  | 	it=0; | ||||||
|  | 	while (it<buf.length()-1) | ||||||
|  | 	{ | ||||||
|  | 		loadToIt(temp,buf,it,3); | ||||||
|  | 		creGens4.push_back(temp); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	buf = bitmaph->getTextFile("GENRLTXT.TXT"); | 	buf = bitmaph->getTextFile("GENRLTXT.TXT"); | ||||||
| 	std::string tmp; | 	std::string tmp; | ||||||
| 	andame = buf.size(); | 	andame = buf.size(); | ||||||
|   | |||||||
| @@ -53,6 +53,7 @@ public: | |||||||
| 	//objects | 	//objects | ||||||
| 	std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i | 	std::vector<std::string> names; //vector of objects; i-th object in vector has subnumber i | ||||||
| 	std::vector<std::string> creGens; //names of creatures' generators | 	std::vector<std::string> creGens; //names of creatures' generators | ||||||
|  | 	std::vector<std::string> creGens4; //names of multiple creatures' generators | ||||||
| 	std::vector<std::string> advobtxt; | 	std::vector<std::string> advobtxt; | ||||||
| 	std::vector<std::string> xtrainfo; | 	std::vector<std::string> xtrainfo; | ||||||
| 	std::vector<std::string> restypes; | 	std::vector<std::string> restypes; | ||||||
|   | |||||||
| @@ -908,12 +908,24 @@ void CGDwelling::initObj() | |||||||
| 	switch(ID) | 	switch(ID) | ||||||
| 	{ | 	{ | ||||||
| 	case 17: | 	case 17: | ||||||
| 		creatures.resize(1); | 		{ | ||||||
| 		creatures[0].second.push_back(VLC->objh->cregens[subID]); | 			int crid = VLC->objh->cregens[subID]; | ||||||
|  | 			CCreature *crs = &VLC->creh->creatures[crid]; | ||||||
|  |  | ||||||
|  | 			creatures.resize(1); | ||||||
|  | 			creatures[0].second.push_back(crid); | ||||||
|  | 			hoverName = VLC->generaltexth->creGens[subID]; | ||||||
|  | 			if(crs->level > 4) | ||||||
|  | 			{ | ||||||
|  | 				army.slots[0].first = crs->idNumber; | ||||||
|  | 				army.slots[0].second = crs->getRandomAmount(ran); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 	case 20: | 	case 20: | ||||||
| 		creatures.resize(4); | 		creatures.resize(4); | ||||||
| 		if(subID == 1) // Elemental Conflux  | 		if(subID == 0) // Elemental Conflux  | ||||||
| 		{ | 		{ | ||||||
| 			creatures[0].second.push_back(32);  //Stone Golem | 			creatures[0].second.push_back(32);  //Stone Golem | ||||||
| 			creatures[1].second.push_back(33);  //Iron Golem   | 			creatures[1].second.push_back(33);  //Iron Golem   | ||||||
| @@ -931,7 +943,9 @@ void CGDwelling::initObj() | |||||||
| 		{ | 		{ | ||||||
| 			assert(0); | 			assert(0); | ||||||
| 		} | 		} | ||||||
|  | 		hoverName = VLC->generaltexth->creGens4[subID]; | ||||||
| 		break; | 		break; | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 		assert(0); | 		assert(0); | ||||||
| 		break; | 		break; | ||||||
| @@ -940,14 +954,29 @@ void CGDwelling::initObj() | |||||||
|  |  | ||||||
| void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const | void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const | ||||||
| { | { | ||||||
|  | 	if(h->tempOwner != tempOwner  &&  army) //object is guarded | ||||||
|  | 	{ | ||||||
|  | 		BlockingDialog bd; | ||||||
|  | 		bd.player = h->tempOwner; | ||||||
|  | 		bd.flags = BlockingDialog::ALLOW_CANCEL; | ||||||
|  | 		bd.text.addTxt(MetaString::GENERAL_TXT, 421); //Much to your dismay, the %s is guarded by %s %s. Do you wish to fight the guards? | ||||||
|  | 		bd.text.addReplacement(MetaString::CREGENS, subID); | ||||||
|  | 		bd.text.addReplacement(MetaString::ARRAY_TXT, 176 + CCreature::getQuantityID(army.slots.begin()->second.second)*3); | ||||||
|  | 		bd.text.addReplacement(MetaString::CRE_PL_NAMES, creatures[0].second[0]); | ||||||
|  | 		cb->showBlockingDialog(&bd, boost::bind(&CGDwelling::wantsFight, this, h, _1)); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	if(h->tempOwner != tempOwner) | 	if(h->tempOwner != tempOwner) | ||||||
| 		cb->setOwner(id, h->tempOwner); | 		cb->setOwner(id, h->tempOwner); | ||||||
|  |  | ||||||
| 	OpenWindow ow; | 	BlockingDialog bd; | ||||||
| 	ow.id1 = id; | 	bd.player = h->tempOwner; | ||||||
| 	ow.id2 = id; | 	bd.flags = BlockingDialog::ALLOW_CANCEL; | ||||||
| 	ow.window = OpenWindow::RECRUITMENT_FIRST; | 	bd.text.addTxt(MetaString::ADVOB_TXT, 35); //{%s}	Would you like to recruit %s? | ||||||
| 	cb->sendAndApply(&ow); | 	bd.text.addReplacement(MetaString::CREGENS, subID); | ||||||
|  | 	bd.text.addReplacement(MetaString::CRE_PL_NAMES, creatures[0].second[0]); | ||||||
|  | 	cb->showBlockingDialog(&bd, boost::bind(&CGDwelling::heroAcceptsCreatures, this, h, _1)); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CGDwelling::newTurn() const | void CGDwelling::newTurn() const | ||||||
| @@ -974,10 +1003,88 @@ void CGDwelling::newTurn() const | |||||||
| 		cb->sendAndApply(&sac); | 		cb->sendAndApply(&sac); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) const | ||||||
|  | { | ||||||
|  | 	if(!answer) | ||||||
|  | 		return; | ||||||
|  |  | ||||||
|  | 	int crid = creatures[0].second[0]; | ||||||
|  | 	CCreature *crs = &VLC->creh->creatures[crid]; | ||||||
|  |  | ||||||
|  | 	if(crs->level == 1) //first level - creatures are for free | ||||||
|  | 	{ | ||||||
|  | 		if(creatures[0].first) //there are available creatures | ||||||
|  | 		{ | ||||||
|  | 			int slot = h->army.getSlotFor(crid); | ||||||
|  | 			if(slot < 0) //no available slot | ||||||
|  | 			{ | ||||||
|  | 				InfoWindow iw; | ||||||
|  | 				iw.player = h->tempOwner; | ||||||
|  | 				iw.text.addTxt(MetaString::GENERAL_TXT, 425);//The %s would join your hero, but there aren't enough provisions to support them. | ||||||
|  | 				iw.text.addReplacement(MetaString::CRE_PL_NAMES, crid); | ||||||
|  | 				cb->showInfoDialog(&iw); | ||||||
|  | 			} | ||||||
|  | 			else //give creatures | ||||||
|  | 			{ | ||||||
|  | 				SetAvailableCreatures sac; | ||||||
|  | 				sac.tid = id; | ||||||
|  | 				sac.creatures = creatures; | ||||||
|  | 				sac.creatures[0].first = 0; | ||||||
|  |  | ||||||
|  | 				SetGarrisons sg; | ||||||
|  | 				sg.garrs[h->id] = h->army; | ||||||
|  | 				sg.garrs[h->id].slots[slot].first = crid; | ||||||
|  | 				sg.garrs[h->id].slots[slot].second += creatures[0].first; | ||||||
|  |  | ||||||
|  | 				InfoWindow iw; | ||||||
|  | 				iw.player = h->tempOwner; | ||||||
|  | 				iw.text.addTxt(MetaString::GENERAL_TXT, 423); //%d %s join your army. | ||||||
|  | 				iw.text.addReplacement(creatures[0].first); | ||||||
|  | 				iw.text.addReplacement(MetaString::CRE_PL_NAMES, crid); | ||||||
|  |  | ||||||
|  | 				cb->showInfoDialog(&iw); | ||||||
|  | 				cb->sendAndApply(&sac); | ||||||
|  | 				cb->sendAndApply(&sg); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		else //there no creatures | ||||||
|  | 		{ | ||||||
|  | 			InfoWindow iw; | ||||||
|  | 			iw.text.addTxt(MetaString::GENERAL_TXT, 422); //There are no %s here to recruit. | ||||||
|  | 			iw.text.addReplacement(MetaString::CRE_PL_NAMES, crid); | ||||||
|  | 			iw.player = h->tempOwner; | ||||||
|  | 			cb->sendAndApply(&iw); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	else if(ID == 17) | ||||||
|  | 	{ | ||||||
|  | 		OpenWindow ow; | ||||||
|  | 		ow.id1 = id; | ||||||
|  | 		ow.id2 = id; | ||||||
|  | 		ow.window = OpenWindow::RECRUITMENT_FIRST; | ||||||
|  | 		cb->sendAndApply(&ow); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CGDwelling::wantsFight( const CGHeroInstance *h, ui32 answer ) const | ||||||
|  | { | ||||||
|  | 	if(answer) | ||||||
|  | 		cb->startBattleI(h->id,army,pos,boost::bind(&CGDwelling::fightOver, this, h, _1)); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void CGDwelling::fightOver(const CGHeroInstance *h, BattleResult *result) const | ||||||
|  | { | ||||||
|  | 	if (result->winner == 0) | ||||||
|  | 	{ | ||||||
|  | 		onHeroVisit(h); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| int CGTownInstance::getSightRadious() const //returns sight distance | int CGTownInstance::getSightRadious() const //returns sight distance | ||||||
| { | { | ||||||
| 	return 5; | 	return 5; | ||||||
| } | } | ||||||
|  |  | ||||||
| int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - castle | int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - castle | ||||||
| { | { | ||||||
| 	if((builtBuildings.find(9))!=builtBuildings.end()) | 	if((builtBuildings.find(9))!=builtBuildings.end()) | ||||||
| @@ -988,6 +1095,7 @@ int CGTownInstance::fortLevel() const //0 - none, 1 - fort, 2 - citadel, 3 - cas | |||||||
| 		return 1; | 		return 1; | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol | int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol | ||||||
| { | { | ||||||
| 	if ((builtBuildings.find(13))!=builtBuildings.end()) | 	if ((builtBuildings.find(13))!=builtBuildings.end()) | ||||||
| @@ -1109,10 +1217,8 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const | |||||||
| } | } | ||||||
|  |  | ||||||
| void CGTownInstance::initObj() | void CGTownInstance::initObj() | ||||||
| { | {  | ||||||
| 	MetaString ms; | 	hoverName = name + ", " + town->Name(); | ||||||
| 	ms << name << ", " << town->Name(); |  | ||||||
| 	hoverName = toString(ms); |  | ||||||
|  |  | ||||||
| 	creatures.resize(CREATURES_PER_TOWN); | 	creatures.resize(CREATURES_PER_TOWN); | ||||||
| 	for (int i = 0; i < CREATURES_PER_TOWN; i++) | 	for (int i = 0; i < CREATURES_PER_TOWN; i++) | ||||||
| @@ -1485,8 +1591,8 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const | |||||||
| 		{ | 		{ | ||||||
| 			BlockingDialog ynd(true,false); | 			BlockingDialog ynd(true,false); | ||||||
| 			ynd.player = h->tempOwner; | 			ynd.player = h->tempOwner; | ||||||
| 			ynd.text << std::pair<ui8,ui32>(11,86);  | 			ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, 86);  | ||||||
| 			ynd.text.replacements.push_back(VLC->creh->creatures[subID].namePl); | 			ynd.text.addReplacement(MetaString::CRE_PL_NAMES, subID); | ||||||
| 			cb->showBlockingDialog(&ynd,boost::bind(&CGCreature::joinDecision,this,h,0,_1)); | 			cb->showBlockingDialog(&ynd,boost::bind(&CGCreature::joinDecision,this,h,0,_1)); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| @@ -1566,7 +1672,7 @@ void CGCreature::initObj() | |||||||
| 	int pom = CCreature::getQuantityID(army.slots.find(0)->second.second); | 	int pom = CCreature::getQuantityID(army.slots.find(0)->second.second); | ||||||
| 	pom = 174 + 3*pom + 1; | 	pom = 174 + 3*pom + 1; | ||||||
| 	ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID); | 	ms << std::pair<ui8,ui32>(6,pom) << " " << std::pair<ui8,ui32>(7,subID); | ||||||
| 	hoverName = toString(ms); | 	ms.toString(hoverName); | ||||||
| } | } | ||||||
|  |  | ||||||
| int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const | int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const | ||||||
| @@ -1719,7 +1825,7 @@ void CGCreature::flee( const CGHeroInstance * h ) const | |||||||
| 	BlockingDialog ynd(true,false); | 	BlockingDialog ynd(true,false); | ||||||
| 	ynd.player = h->tempOwner; | 	ynd.player = h->tempOwner; | ||||||
| 	ynd.text << std::pair<ui8,ui32>(11,91);  | 	ynd.text << std::pair<ui8,ui32>(11,91);  | ||||||
| 	ynd.text.replacements.push_back(VLC->creh->creatures[subID].namePl); | 	ynd.text.addReplacement(MetaString::CRE_PL_NAMES, subID); | ||||||
| 	cb->showBlockingDialog(&ynd,boost::bind(&CGCreature::fleeDecision,this,h,_1)); | 	cb->showBlockingDialog(&ynd,boost::bind(&CGCreature::fleeDecision,this,h,_1)); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1778,7 +1884,7 @@ void CGMine::initObj() | |||||||
| 		tempOwner = NEUTRAL_PLAYER;	 | 		tempOwner = NEUTRAL_PLAYER;	 | ||||||
| 	else | 	else | ||||||
| 		ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner) << ")"; | 		ms << " (" << std::pair<ui8,ui32>(6,23+tempOwner) << ")"; | ||||||
| 	hoverName = toString(ms); | 	ms.toString(hoverName); | ||||||
| } | } | ||||||
|  |  | ||||||
| void CGResource::initObj() | void CGResource::initObj() | ||||||
| @@ -1839,7 +1945,7 @@ void CGResource::collectRes( int player ) const | |||||||
| 	sii.player = player; | 	sii.player = player; | ||||||
| 	sii.c = Component(2,subID,amount,0); | 	sii.c = Component(2,subID,amount,0); | ||||||
| 	sii.text << std::pair<ui8,ui32>(11,113); | 	sii.text << std::pair<ui8,ui32>(11,113); | ||||||
| 	sii.text.replacements.push_back(VLC->generaltexth->restypes[subID]); | 	sii.text.addReplacement(MetaString::RES_NAMES, subID); | ||||||
| 	cb->showCompInfo(&sii); | 	cb->showCompInfo(&sii); | ||||||
| 	cb->removeObject(id); | 	cb->removeObject(id); | ||||||
| } | } | ||||||
| @@ -2140,7 +2246,7 @@ void CGPickable::onHeroVisit( const CGHeroInstance * h ) const | |||||||
| 				iw.player = h->tempOwner; | 				iw.player = h->tempOwner; | ||||||
| 				iw.components.push_back(Component(4,val1,1,0)); | 				iw.components.push_back(Component(4,val1,1,0)); | ||||||
| 				iw.text << std::pair<ui8,ui32>(11,145); | 				iw.text << std::pair<ui8,ui32>(11,145); | ||||||
| 				iw.text.replacements.push_back(VLC->arth->artifacts[val1].Name()); | 				iw.text.addReplacement(MetaString::ART_NAMES, val1); | ||||||
| 				cb->showInfoDialog(&iw); | 				cb->showInfoDialog(&iw); | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| @@ -2193,18 +2299,18 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const | |||||||
| 	if(h->getSecSkillLevel(ability)) //you alredy know this skill | 	if(h->getSecSkillLevel(ability)) //you alredy know this skill | ||||||
| 	{ | 	{ | ||||||
| 		iw.text << std::pair<ui8,ui32>(11,172); | 		iw.text << std::pair<ui8,ui32>(11,172); | ||||||
| 		iw.text.replacements.push_back(VLC->generaltexth->skillName[ability]); | 		iw.text.addReplacement(MetaString::SEC_SKILL_NAME, ability); | ||||||
| 	} | 	} | ||||||
| 	else if(h->secSkills.size() >= SKILL_PER_HERO) //already all skills slots used | 	else if(h->secSkills.size() >= SKILL_PER_HERO) //already all skills slots used | ||||||
| 	{ | 	{ | ||||||
| 		iw.text << std::pair<ui8,ui32>(11,173); | 		iw.text << std::pair<ui8,ui32>(11,173); | ||||||
| 		iw.text.replacements.push_back(VLC->generaltexth->skillName[ability]); | 		iw.text.addReplacement(MetaString::SEC_SKILL_NAME, ability); | ||||||
| 	} | 	} | ||||||
| 	else //give sec skill | 	else //give sec skill | ||||||
| 	{ | 	{ | ||||||
| 		iw.components.push_back(Component(1, ability, 1, 0)); | 		iw.components.push_back(Component(1, ability, 1, 0)); | ||||||
| 		iw.text << std::pair<ui8,ui32>(11,171); | 		iw.text << std::pair<ui8,ui32>(11,171); | ||||||
| 		iw.text.replacements.push_back(VLC->generaltexth->skillName[ability]); | 		iw.text.addReplacement(MetaString::SEC_SKILL_NAME, ability); | ||||||
| 		cb->changeSecSkill(h->id,ability,1,true); | 		cb->changeSecSkill(h->id,ability,1,true); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -2260,7 +2366,7 @@ void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const | |||||||
| 		gbonus.bonus.type = HeroBonus::LUCK; | 		gbonus.bonus.type = HeroBonus::LUCK; | ||||||
| 		gbonus.bonus.val = rand()%5 - 1; | 		gbonus.bonus.val = rand()%5 - 1; | ||||||
| 		gbonus.bdescr <<  std::pair<ui8,ui32>(6,69); | 		gbonus.bdescr <<  std::pair<ui8,ui32>(6,69); | ||||||
| 		gbonus.bdescr.replacements.push_back((gbonus.bonus.val<0 ? "-" : "+") + boost::lexical_cast<std::string>(gbonus.bonus.val)); | 		gbonus.bdescr.addReplacement((gbonus.bonus.val<0 ? "-" : "+") + boost::lexical_cast<std::string>(gbonus.bonus.val)); | ||||||
| 		break; | 		break; | ||||||
| 	case 38: //idol of fortune | 	case 38: //idol of fortune | ||||||
| 		messageID = 62; | 		messageID = 62; | ||||||
| @@ -2596,14 +2702,14 @@ void CGEvent::giveContents( const CGHeroInstance *h, bool afterBattle ) const | |||||||
| 			if(iw.components.front().val == 1) | 			if(iw.components.front().val == 1) | ||||||
| 			{ | 			{ | ||||||
| 				iw.text.addTxt(MetaString::ADVOB_TXT,185);//A %s joins %s's army. | 				iw.text.addTxt(MetaString::ADVOB_TXT,185);//A %s joins %s's army. | ||||||
| 				iw.text.replacements.push_back(VLC->creh->creatures[iw.components.front().subtype].nameSing); | 				iw.text.addReplacement(MetaString::CRE_SING_NAMES, iw.components.front().subtype); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| 				iw.text.addTxt(MetaString::ADVOB_TXT,186);//%s join %s's army. | 				iw.text.addTxt(MetaString::ADVOB_TXT,186);//%s join %s's army. | ||||||
| 				iw.text.replacements.push_back(VLC->creh->creatures[iw.components.front().subtype].namePl); | 				iw.text.addReplacement(MetaString::CRE_PL_NAMES, iw.components.front().subtype); | ||||||
| 			} | 			} | ||||||
| 			iw.text.replacements.push_back(h->name); | 			iw.text.addReplacement(h->name); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| @@ -2661,7 +2767,7 @@ void CGEvent::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHero | |||||||
| 	if(afterBattle) | 	if(afterBattle) | ||||||
| 	{ | 	{ | ||||||
| 		iw.text.addTxt(MetaString::ADVOB_TXT,text);//%s has lost treasure. | 		iw.text.addTxt(MetaString::ADVOB_TXT,text);//%s has lost treasure. | ||||||
| 		iw.text.replacements.push_back(h->name); | 		iw.text.addReplacement(h->name); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @@ -2677,7 +2783,7 @@ void CGEvent::getText( InfoWindow &iw, bool &afterBattle, int val, int positive, | |||||||
| 	if(afterBattle) | 	if(afterBattle) | ||||||
| 	{ | 	{ | ||||||
| 		iw.text.addTxt(MetaString::ADVOB_TXT,val < 0 ? negative : positive); //%s's luck takes a turn for the worse / %s's luck increases | 		iw.text.addTxt(MetaString::ADVOB_TXT,val < 0 ? negative : positive); //%s's luck takes a turn for the worse / %s's luck increases | ||||||
| 		iw.text.replacements.push_back(h->name); | 		iw.text.addReplacement(h->name); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @@ -2927,7 +3033,7 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const | |||||||
| 		if(ID == 105  &&  artOrRes == 1)  | 		if(ID == 105  &&  artOrRes == 1)  | ||||||
| 		{ | 		{ | ||||||
| 			txtid++; | 			txtid++; | ||||||
| 			iw.text.replacements.push_back(VLC->arth->artifacts[bonusType].Name()); | 			iw.text.addReplacement(MetaString::ART_NAMES, bonusType); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -3057,7 +3163,7 @@ void CGOnceVisitable::searchTomb(const CGHeroInstance *h, ui32 accept) const | |||||||
| 		{ | 		{ | ||||||
| 			iw.text.addTxt(MetaString::ADVOB_TXT,162); | 			iw.text.addTxt(MetaString::ADVOB_TXT,162); | ||||||
| 			iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0)); | 			iw.components.push_back(Component(Component::ARTIFACT,bonusType,0,0)); | ||||||
| 			iw.text.replacements.push_back(VLC->arth->artifacts[bonusType].Name()); | 			iw.text.addReplacement(MetaString::ART_NAMES, bonusType); | ||||||
|  |  | ||||||
| 			cb->giveHeroArtifact(bonusType,h->id,-2); | 			cb->giveHeroArtifact(bonusType,h->id,-2); | ||||||
| 		} | 		} | ||||||
|   | |||||||
| @@ -297,6 +297,9 @@ public: | |||||||
| 	void initObj(); | 	void initObj(); | ||||||
| 	void onHeroVisit(const CGHeroInstance * h) const; | 	void onHeroVisit(const CGHeroInstance * h) const; | ||||||
| 	void newTurn() const; | 	void newTurn() const; | ||||||
|  | 	void heroAcceptsCreatures(const CGHeroInstance *h, ui32 answer) const; | ||||||
|  | 	void fightOver(const CGHeroInstance *h, BattleResult *result) const; | ||||||
|  | 	void wantsFight(const CGHeroInstance *h, ui32 answer) const; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class DLL_EXPORT CGTownInstance : public CGDwelling | class DLL_EXPORT CGTownInstance : public CGDwelling | ||||||
|   | |||||||
| @@ -19,10 +19,11 @@ | |||||||
| #include "../StartInfo.h" | #include "../StartInfo.h" | ||||||
| #include "NetPacks.h" | #include "NetPacks.h" | ||||||
| #include <boost/foreach.hpp> | #include <boost/foreach.hpp> | ||||||
|  | #include <boost/lexical_cast.hpp> | ||||||
| #include <boost/thread.hpp> | #include <boost/thread.hpp> | ||||||
| #include <boost/thread/shared_mutex.hpp> | #include <boost/thread/shared_mutex.hpp> | ||||||
|  |  | ||||||
| #include "RegisterTypes.cpp" | #include "RegisterTypes.cpp" | ||||||
|  |  | ||||||
| boost::rand48 ran; | boost::rand48 ran; | ||||||
|  |  | ||||||
| #ifdef min | #ifdef min | ||||||
| @@ -89,83 +90,111 @@ public: | |||||||
|  |  | ||||||
| } *applierGs = NULL; | } *applierGs = NULL; | ||||||
|  |  | ||||||
| std::string DLL_EXPORT toString(MetaString &ms) | void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst) const | ||||||
| { | { | ||||||
| 	std::string ret; | 	int type = txt.first, ser = txt.second; | ||||||
| 	for(size_t i=0;i<ms.message.size();++i) |  | ||||||
|  | 	if(type == ART_NAMES) | ||||||
| 	{ | 	{ | ||||||
| 		if(ms.message[i]>0) | 		dst = VLC->arth->artifacts[ser].Name(); | ||||||
|  | 	} | ||||||
|  | 	else if(type == CRE_PL_NAMES) | ||||||
|  | 	{ | ||||||
|  | 		dst = VLC->creh->creatures[ser].namePl; | ||||||
|  | 	} | ||||||
|  | 	else if(type == MINE_NAMES) | ||||||
|  | 	{ | ||||||
|  | 		dst = VLC->generaltexth->mines[ser].first; | ||||||
|  | 	} | ||||||
|  | 	else if(type == MINE_EVNTS) | ||||||
|  | 	{ | ||||||
|  | 		dst = VLC->generaltexth->mines[ser].second; | ||||||
|  | 	} | ||||||
|  | 	else if(type == SPELL_NAME) | ||||||
|  | 	{ | ||||||
|  | 		dst = VLC->spellh->spells[ser].name; | ||||||
|  | 	} | ||||||
|  | 	else if(type == CRE_SING_NAMES) | ||||||
|  | 	{ | ||||||
|  | 		dst = VLC->creh->creatures[ser].nameSing; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		std::vector<std::string> *vec; | ||||||
|  | 		switch(type) | ||||||
| 		{ | 		{ | ||||||
| 			ret += ms.strings[ms.message[i]-1]; | 		case GENERAL_TXT: | ||||||
|  | 			vec = &VLC->generaltexth->allTexts; | ||||||
|  | 			break; | ||||||
|  | 		case XTRAINFO_TXT: | ||||||
|  | 			vec = &VLC->generaltexth->xtrainfo; | ||||||
|  | 			break; | ||||||
|  | 		case OBJ_NAMES: | ||||||
|  | 			vec = &VLC->generaltexth->names; | ||||||
|  | 			break; | ||||||
|  | 		case RES_NAMES: | ||||||
|  | 			vec = &VLC->generaltexth->restypes; | ||||||
|  | 			break; | ||||||
|  | 		case ARRAY_TXT: | ||||||
|  | 			vec = &VLC->generaltexth->arraytxt; | ||||||
|  | 			break; | ||||||
|  | 		case CREGENS: | ||||||
|  | 			vec = &VLC->generaltexth->creGens; | ||||||
|  | 			break; | ||||||
|  | 		case ADVOB_TXT: | ||||||
|  | 			vec = &VLC->generaltexth->advobtxt; | ||||||
|  | 			break; | ||||||
|  | 		case ART_EVNTS: | ||||||
|  | 			vec = &VLC->generaltexth->artifEvents; | ||||||
|  | 			break; | ||||||
|  | 		case SEC_SKILL_NAME: | ||||||
|  | 			vec = &VLC->generaltexth->skillName; | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 		else | 		dst = (*vec)[ser]; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | DLL_EXPORT void MetaString::toString(std::string &dst) const | ||||||
|  | { | ||||||
|  | 	size_t exSt = 0, loSt = 0, nums = 0; | ||||||
|  | 	dst.clear(); | ||||||
|  |  | ||||||
|  | 	for(size_t i=0;i<message.size();++i) | ||||||
|  | 	{//TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER | ||||||
|  | 		switch(message[i]) | ||||||
| 		{ | 		{ | ||||||
| 			std::vector<std::string> *vec; | 		case TEXACT_STRING: | ||||||
| 			int type = ms.texts[-ms.message[i]-1].first, | 			dst += exactStrings[exSt++]; | ||||||
| 				ser = ms.texts[-ms.message[i]-1].second; | 			break; | ||||||
| 			if(type == 5) | 		case TLOCAL_STRING: | ||||||
| 			{ | 			{ | ||||||
| 				ret += VLC->arth->artifacts[ser].Name(); | 				std::string hlp; | ||||||
| 				continue; | 				getLocalString(localStrings[loSt++], hlp); | ||||||
|  | 				dst += hlp; | ||||||
| 			} | 			} | ||||||
| 			else if(type == 7) | 			break; | ||||||
|  | 		case TNUMBER: | ||||||
|  | 			dst += boost::lexical_cast<std::string>(numbers[nums++]); | ||||||
|  | 			break; | ||||||
|  | 		case TREPLACE_ESTRING: | ||||||
|  | 			dst.replace(dst.find("%s"), 2, exactStrings[exSt++]); | ||||||
|  | 			break; | ||||||
|  | 		case TREPLACE_LSTRING: | ||||||
| 			{ | 			{ | ||||||
| 				ret += VLC->creh->creatures[ser].namePl; | 				std::string hlp; | ||||||
| 				continue; | 				getLocalString(localStrings[loSt++], hlp); | ||||||
| 			} | 				dst.replace(dst.find("%s"), 2, hlp); | ||||||
| 			else if(type == 9) |  | ||||||
| 			{ |  | ||||||
| 				ret += VLC->generaltexth->mines[ser].first; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			else if(type == 10) |  | ||||||
| 			{ |  | ||||||
| 				ret += VLC->generaltexth->mines[ser].second; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			else if(type == MetaString::SPELL_NAME) |  | ||||||
| 			{ |  | ||||||
| 				ret += VLC->spellh->spells[ser].name; |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				switch(type) |  | ||||||
| 				{ |  | ||||||
| 				case 1: |  | ||||||
| 					vec = &VLC->generaltexth->allTexts; |  | ||||||
| 					break; |  | ||||||
| 				case 2: |  | ||||||
| 					vec = &VLC->generaltexth->xtrainfo; |  | ||||||
| 					break; |  | ||||||
| 				case 3: |  | ||||||
| 					vec = &VLC->generaltexth->names; |  | ||||||
| 					break; |  | ||||||
| 				case 4: |  | ||||||
| 					vec = &VLC->generaltexth->restypes; |  | ||||||
| 					break; |  | ||||||
| 				case 6: |  | ||||||
| 					vec = &VLC->generaltexth->arraytxt; |  | ||||||
| 					break; |  | ||||||
| 				case 8: |  | ||||||
| 					vec = &VLC->generaltexth->creGens; |  | ||||||
| 					break; |  | ||||||
| 				case 11: |  | ||||||
| 					vec = &VLC->generaltexth->advobtxt; |  | ||||||
| 					break; |  | ||||||
| 				case 12: |  | ||||||
| 					vec = &VLC->generaltexth->artifEvents; |  | ||||||
| 					break; |  | ||||||
| 				} |  | ||||||
| 				ret += (*vec)[ser]; |  | ||||||
| 			} | 			} | ||||||
|  | 			break; | ||||||
|  | 		case TREPLACE_NUMBER: | ||||||
|  | 			dst.replace(dst.find("%d"), 2, boost::lexical_cast<std::string>(numbers[nums++])); | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			tlog1 << "MetaString processing error!\n"; | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	for(size_t i=0; i < ms.replacements.size(); ++i) |  | ||||||
| 	{ |  | ||||||
| 		ret.replace(ret.find("%s"),2,ms.replacements[i]); |  | ||||||
| 	} |  | ||||||
| 	return ret; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) | static CGObjectInstance * createObject(int id, int subid, int3 pos, int owner) | ||||||
|   | |||||||
| @@ -50,9 +50,6 @@ struct CPack; | |||||||
| class CSpell; | class CSpell; | ||||||
|  |  | ||||||
|  |  | ||||||
| std::string DLL_EXPORT toString(MetaString &ms); |  | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace boost | namespace boost | ||||||
| { | { | ||||||
| 	class shared_mutex; | 	class shared_mutex; | ||||||
|   | |||||||
| @@ -66,44 +66,77 @@ struct Query : public CPackForClient | |||||||
| 	ui32 id; | 	ui32 id; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| struct MetaString : public CPack //2001 helper for object scrips | struct MetaString : public CPack //2001 helper for object scrips | ||||||
| { | { | ||||||
|  | private: | ||||||
|  | 	enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER}; | ||||||
|  | public: | ||||||
| 	enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,  | 	enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,  | ||||||
| 		MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME}; | 		MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES}; | ||||||
| 	std::vector<std::string> strings; |  | ||||||
| 	std::vector<std::pair<ui8,ui32> > texts; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt | 	std::vector<ui8> message; //vector of EMessage | ||||||
| 	std::vector<si32> message; |  | ||||||
| 	std::vector<std::string> replacements; | 	std::vector<std::pair<ui8,ui32> > localStrings; //pairs<text handler type, text number>; types: 1 - generaltexthandler->all; 2 - objh->xtrainfo; 3 - objh->names; 4 - objh->restypes; 5 - arth->artifacts[id].name; 6 - generaltexth->arraytxt; 7 - creh->creatures[os->subID].namePl; 8 - objh->creGens; 9 - objh->mines[ID].first; 10 - objh->mines[ID].second; 11 - objh->advobtxt | ||||||
|  | 	std::vector<std::string> exactStrings; | ||||||
|  | 	std::vector<si32> numbers; | ||||||
|  |  | ||||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | 	template <typename Handler> void serialize(Handler &h, const int version) | ||||||
| 	{ | 	{ | ||||||
| 		h & strings & texts & message & replacements; | 		h & exactStrings & localStrings & message & numbers; | ||||||
| 	} | 	} | ||||||
| 	void addTxt(ui8 type, ui32 serial) | 	void addTxt(ui8 type, ui32 serial) | ||||||
| 	{ | 	{ | ||||||
| 		*this << std::make_pair(type,serial); | 		message.push_back(TLOCAL_STRING); | ||||||
|  | 		localStrings.push_back(std::pair<ui8,ui32>(type, serial)); | ||||||
| 	} | 	} | ||||||
| 	MetaString& operator<<(const std::pair<ui8,ui32> &txt) | 	MetaString& operator<<(const std::pair<ui8,ui32> &txt) | ||||||
| 	{ | 	{ | ||||||
| 		message.push_back(-((si32)texts.size())-1); | 		message.push_back(TLOCAL_STRING); | ||||||
| 		texts.push_back(txt); | 		localStrings.push_back(txt); | ||||||
| 		return *this; | 		return *this; | ||||||
| 	} | 	} | ||||||
| 	MetaString& operator<<(const std::string &txt) | 	MetaString& operator<<(const std::string &txt) | ||||||
| 	{ | 	{ | ||||||
| 		message.push_back(strings.size()+1); | 		message.push_back(TEXACT_STRING); | ||||||
| 		strings.push_back(txt); | 		exactStrings.push_back(txt); | ||||||
| 		return *this; | 		return *this; | ||||||
| 	} | 	} | ||||||
|  | 	MetaString& operator<<(int txt) | ||||||
|  | 	{ | ||||||
|  | 		message.push_back(TNUMBER); | ||||||
|  | 		numbers.push_back(txt); | ||||||
|  | 		return *this; | ||||||
|  | 	} | ||||||
|  | 	void addReplacement(ui8 type, ui32 serial) | ||||||
|  | 	{ | ||||||
|  | 		message.push_back(TREPLACE_LSTRING); | ||||||
|  | 		localStrings.push_back(std::pair<ui8,ui32>(type, serial)); | ||||||
|  | 	} | ||||||
|  | 	void addReplacement(const std::string &txt) | ||||||
|  | 	{ | ||||||
|  | 		message.push_back(TREPLACE_ESTRING); | ||||||
|  | 		exactStrings.push_back(txt); | ||||||
|  | 	} | ||||||
|  | 	void addReplacement(int txt) | ||||||
|  | 	{ | ||||||
|  | 		message.push_back(TREPLACE_NUMBER); | ||||||
|  | 		numbers.push_back(txt); | ||||||
|  | 	} | ||||||
| 	void clear() | 	void clear() | ||||||
| 	{ | 	{ | ||||||
| 		strings.clear(); | 		exactStrings.clear(); | ||||||
| 		texts.clear(); | 		localStrings.clear(); | ||||||
| 		message.clear(); | 		message.clear(); | ||||||
| 		replacements.clear(); | 		numbers.clear(); | ||||||
| 	} | 	} | ||||||
|  | 	DLL_EXPORT void toString(std::string &dst) const; | ||||||
|  | 	void getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst) const; | ||||||
|  |  | ||||||
| 	MetaString(){type = 2001;}; | 	MetaString() | ||||||
|  | 	{ | ||||||
|  | 		type = 2001; | ||||||
|  | 	} | ||||||
| };  | };  | ||||||
|  |  | ||||||
| /***********************************************************************************************************/ | /***********************************************************************************************************/ | ||||||
|   | |||||||
| @@ -179,7 +179,7 @@ DLL_EXPORT void GiveBonus::applyGs( CGameState *gs ) | |||||||
|  |  | ||||||
| 	std::string &descr = h->bonuses.back().description; | 	std::string &descr = h->bonuses.back().description; | ||||||
|  |  | ||||||
| 	if(!bdescr.texts.size()  | 	if(!bdescr.message.size()  | ||||||
| 		&& bonus.source == HeroBonus::OBJECT  | 		&& bonus.source == HeroBonus::OBJECT  | ||||||
| 		&& (bonus.type == HeroBonus::LUCK || bonus.type == HeroBonus::MORALE || bonus.type == HeroBonus::MORALE_AND_LUCK) | 		&& (bonus.type == HeroBonus::LUCK || bonus.type == HeroBonus::MORALE || bonus.type == HeroBonus::MORALE_AND_LUCK) | ||||||
| 		&& gs->map->objects[bonus.id]->ID == 26) //it's morale/luck bonus from an event without description | 		&& gs->map->objects[bonus.id]->ID == 26) //it's morale/luck bonus from an event without description | ||||||
| @@ -189,7 +189,7 @@ DLL_EXPORT void GiveBonus::applyGs( CGameState *gs ) | |||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		descr = toString(bdescr); | 		bdescr.toString(descr); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -461,7 +461,7 @@ DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs ) | |||||||
|  |  | ||||||
| DLL_EXPORT void SetHoverName::applyGs( CGameState *gs ) | DLL_EXPORT void SetHoverName::applyGs( CGameState *gs ) | ||||||
| { | { | ||||||
| 	gs->map->objects[id]->hoverName = toString(name); | 	name.toString(gs->map->objects[id]->hoverName); | ||||||
| } | } | ||||||
|  |  | ||||||
| DLL_EXPORT void HeroLevelUp::applyGs( CGameState *gs ) | DLL_EXPORT void HeroLevelUp::applyGs( CGameState *gs ) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user