mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* loading AI dll for neutrals
* hopefully fixed reported by Zamolxis garrison bugs * fixed calculating hero level * fixed gicing starting exp for heroes
This commit is contained in:
		| @@ -24,6 +24,7 @@ using namespace CSDL_Ext; | ||||
|  | ||||
| CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname) | ||||
| { | ||||
| 	char temp[50]; | ||||
| 	dllname = "AI/"+dllname; | ||||
| 	CGlobalAI * ret=NULL; | ||||
| 	CGlobalAI*(*getAI)(); | ||||
| @@ -34,26 +35,18 @@ CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname) | ||||
| 	if (!dll) | ||||
| 	{ | ||||
| 		tlog1 << "Cannot open AI library ("<<dllname<<"). Throwing..."<<std::endl; | ||||
| 	#ifdef _MSC_VER | ||||
| 		throw new std::exception("Cannot open AI library"); | ||||
| 	#endif | ||||
| 		throw new std::exception(); | ||||
| 		throw new std::string("Cannot open AI library"); | ||||
| 	} | ||||
| 	//int len = dllname.size()+1; | ||||
| 	getName = (void(*)(char*))GetProcAddress(dll,"GetAiName"); | ||||
| 	getAI = (CGlobalAI*(*)())GetProcAddress(dll,"GetNewAI"); | ||||
| 	getName(temp); | ||||
| #else | ||||
| 	; //TODO: handle AI library on Linux | ||||
| #endif | ||||
| 	char * temp = new char[50]; | ||||
| #if _WIN32 | ||||
| 	getName(temp); | ||||
| #endif | ||||
| 	tlog0 << "Loaded .dll with AI named " << temp << std::endl; | ||||
| 	delete temp; | ||||
| #if _WIN32 | ||||
| 	ret = getAI(); | ||||
| 	ret->init(cb); | ||||
| #else | ||||
| 	//ret = new CEmptyAI(); | ||||
| #endif | ||||
|   | ||||
| @@ -124,8 +124,19 @@ void CGarrisonSlot::hover (bool on) | ||||
| 		{ | ||||
| 			if(owner->highlighted) | ||||
| 			{ | ||||
| 				const CArmedInstance *highl = owner->highlighted->getObj();  | ||||
| 				if(  highl->needsLastStack()		//we are moving stack from hero's | ||||
| 				  && highl->army.slots.size() == 1	//it's only stack | ||||
| 				  && owner->highlighted->upg != upg	//we're moving it to the other garrison | ||||
| 				  ) | ||||
| 				{ | ||||
| 					temp = CGI->townh->tcommands[5]; //cannot move last stack! | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					temp = CGI->townh->tcommands[6]; | ||||
| 					boost::algorithm::replace_first(temp,"%s",owner->highlighted->creature->nameSing); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| @@ -1935,7 +1946,7 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj) | ||||
| 			hw->garInt->recreateSlots(); | ||||
| 			hw->garInt->show(); | ||||
| 		} | ||||
| 		if(castleInt) //opened town window - redraw town garrsion slots (change is within hero garr) | ||||
| 		if(castleInt) //opened town window - redraw town garrison slots (change is within hero garr) | ||||
| 		{ | ||||
| 			castleInt->garr->highlighted = NULL; | ||||
| 			castleInt->garr->recreateSlots(); | ||||
|   | ||||
							
								
								
									
										24
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								ChangeLog
									
									
									
									
									
								
							| @@ -1,3 +1,27 @@ | ||||
| 0.64 -> 0.next (???)  [as for r639] | ||||
| GENERAL: | ||||
| * move some settings to the config/settings.txt file | ||||
| * partial support for new screen resolutions | ||||
| * /Data and /Sprites subfolders can be used for adding files not present in .lod archives  | ||||
| * fixed crashbug occuring when hero levelled above 15 level | ||||
|  | ||||
| BATTLES | ||||
| * magic arrow *really* works | ||||
| * war machines support partially added | ||||
| * queue of stacks narrowed | ||||
| * spell effect animation displaying improvements | ||||
| * several reported bugs fixed | ||||
| * new spells supported: | ||||
| 	a) Haste  | ||||
| 	b) lightning bolt  | ||||
| 	c) ice bolt | ||||
| 	d) slow  | ||||
| 	e) implosion | ||||
|  | ||||
| GENERAL: | ||||
| * started making external settings file (will be used for support for non 800x600 screen resolutions)  | ||||
| And a lot of minor fixes | ||||
|  | ||||
| 0.63 -> 0.64 (Nov 01 2008) | ||||
| GENERAL: | ||||
| * sprites from /Sprites folder are handled correctly | ||||
|   | ||||
| @@ -110,9 +110,11 @@ CClient::CClient(CConnection *con, StartInfo *si) | ||||
| 	c << *si; | ||||
| 	c >> pom8; | ||||
| 	if(pom8) throw "Server cannot open the map!"; | ||||
| 	c << ui8(si->playerInfos.size()); | ||||
| 	c << ui8(si->playerInfos.size()+1); //number of players + neutral | ||||
| 	for(int i=0;i<si->playerInfos.size();i++) | ||||
| 		c << ui8(si->playerInfos[i].color); | ||||
| 		c << ui8(si->playerInfos[i].color); //players | ||||
| 	c << ui8(255); // neutrals | ||||
|  | ||||
|  | ||||
| 	ui32 seed, sum; | ||||
| 	std::string mapname; | ||||
| @@ -142,21 +144,20 @@ CClient::CClient(CConnection *con, StartInfo *si) | ||||
| 	CGI->mh->init(); | ||||
| 	tlog0 <<"Initializing mapHandler (together): "<<tmh.getDif()<<std::endl; | ||||
|  | ||||
| 	for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces | ||||
| 	for (int i=0; i<CGI->state->scenarioOps->playerInfos.size();i++) //initializing interfaces for players | ||||
| 	{  | ||||
| 		ui8 color = gs->scenarioOps->playerInfos[i].color; | ||||
| 		CCallback *cb = new CCallback(gs,color,this); | ||||
| 		if(!gs->scenarioOps->playerInfos[i].human) | ||||
| 		{ | ||||
| 			playerint[color] = static_cast<CGameInterface*>(CAIHandler::getNewAI(cb,conf.cc.defaultAI)); | ||||
| 		} | ||||
| 		else  | ||||
| 		{ | ||||
| 			gs->currentPlayer = color; | ||||
| 			playerint[color] = new CPlayerInterface(color,i); | ||||
| 			playerint[color]->init(cb); | ||||
| 		} | ||||
| 		gs->currentPlayer = color; | ||||
| 		playerint[color]->init(cb); | ||||
| 	} | ||||
| 	playerint[255] =  CAIHandler::getNewAI(cb,conf.cc.defaultAI); | ||||
| 	playerint[255]->init(new CCallback(gs,255,this)); | ||||
|  | ||||
| } | ||||
| CClient::~CClient(void) | ||||
| { | ||||
| @@ -166,11 +167,12 @@ void CClient::process(int what) | ||||
| 	static BattleAction curbaction; | ||||
| 	switch (what) | ||||
| 	{ | ||||
| 	case 100: //one of our interaces has turn | ||||
| 	case 100: //one of our interfaces has turn | ||||
| 		{ | ||||
| 			ui8 player; | ||||
| 			*serv >> player;//who? | ||||
| 			tlog5 << "It's turn of "<<(unsigned)player<<" player."<<std::endl; | ||||
| 			gs->currentPlayer = player; | ||||
| 			boost::thread(boost::bind(&CGameInterface::yourTurn,playerint[player])); | ||||
| 			break; | ||||
| 		} | ||||
| @@ -343,9 +345,10 @@ void CClient::process(int what) | ||||
| 				//std::for_each(th->fowRevealed.begin(),th->fowRevealed.end(),boost::bind(&CGameInterface::tileRevealed,playerint[player],_1)); | ||||
| 			} | ||||
|  | ||||
| 			//notify interfacesabout move | ||||
| 			//notify interfaces about move | ||||
| 			for(std::map<ui8, CGameInterface*>::iterator i=playerint.begin();i!=playerint.end();i++) | ||||
| 			{ | ||||
| 				if(i->first >= PLAYER_LIMIT) continue; | ||||
| 				if(gs->players[i->first].fogOfWarMap[th->start.x-1][th->start.y][th->start.z] || gs->players[i->first].fogOfWarMap[th->end.x-1][th->end.y][th->end.z]) | ||||
| 				{ | ||||
| 					i->second->heroMoved(hmd); | ||||
| @@ -546,17 +549,7 @@ void CClient::process(int what) | ||||
| 			tlog5 << "Active stack: " << sas.stack <<std::endl; | ||||
| 			gs->apply(&sas); | ||||
| 			int owner = gs->curB->getStack(sas.stack)->owner; | ||||
| 			if(owner >= PLAYER_LIMIT) //ugly workaround to skip neutral creatures - should be replaced with AI | ||||
| 			{ | ||||
| 				BattleAction ba; | ||||
| 				ba.stackNumber = sas.stack; | ||||
| 				ba.actionType = 3; | ||||
| 				*serv << ui16(3002) << ba; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,owner)); | ||||
| 			} | ||||
| 			boost::thread(boost::bind(&CClient::waitForMoveAndSend,this,owner)); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 3003: | ||||
|   | ||||
| @@ -338,7 +338,7 @@ unsigned int CHeroHandler::level(unsigned int experience) | ||||
| 	for(int i=expPerLevel.size()-1; i>=0; --i) | ||||
| 	{ | ||||
| 		if(experience>=expPerLevel[i]) | ||||
| 			return i+add; | ||||
| 			return 1+i+add; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|   | ||||
| @@ -561,7 +561,7 @@ CGHeroInstance::CGHeroInstance() | ||||
| 	mana = movement = portrait = level = -1; | ||||
| 	isStanding = true; | ||||
| 	moveDir = 4; | ||||
| 	exp = 0; | ||||
| 	exp = 0xffffffff; | ||||
| 	visitedTown = NULL; | ||||
| 	type = NULL; | ||||
| 	secSkills.push_back(std::make_pair(-1, -1)); | ||||
| @@ -618,7 +618,7 @@ void CGHeroInstance::initHero() | ||||
| 		name = type->name; | ||||
| 	if (!biography.length()) | ||||
| 		biography = type->biography;		 | ||||
| 	if (exp == -1) | ||||
| 	if (exp == 0xffffffff) | ||||
| 	{ | ||||
| 		exp=40+  (ran())  % 50; | ||||
| 		level = 1; | ||||
| @@ -662,6 +662,10 @@ CGHeroInstance::~CGHeroInstance() | ||||
| { | ||||
| } | ||||
|  | ||||
| bool CGHeroInstance::needsLastStack() const | ||||
| { | ||||
| 	return true; | ||||
| } | ||||
| CGTownInstance::~CGTownInstance() | ||||
| {} | ||||
|  | ||||
| @@ -674,6 +678,13 @@ int CGTownInstance::spellsAtLevel(int level, bool checkGuild) const | ||||
| 		ret++;  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| bool CGTownInstance::needsLastStack() const | ||||
| { | ||||
| 	if(garrisonHero) | ||||
| 		return true; | ||||
| 	else return false; | ||||
| } | ||||
| CGObjectInstance::CGObjectInstance(const CGObjectInstance & right) | ||||
| { | ||||
| 	pos = right.pos; | ||||
|   | ||||
| @@ -75,6 +75,7 @@ class  DLL_EXPORT CArmedInstance: public CGObjectInstance | ||||
| { | ||||
| public: | ||||
| 	CCreatureSet army; //army | ||||
| 	virtual bool needsLastStack() const=0; //true if last stack cannot be taken | ||||
| }; | ||||
|  | ||||
| class DLL_EXPORT CGHeroInstance : public CArmedInstance | ||||
| @@ -112,6 +113,7 @@ public: | ||||
| 	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<ui32> spells; //known spells (spell IDs) | ||||
|  | ||||
| 	bool needsLastStack()const; | ||||
| 	virtual bool isHero() const; | ||||
| 	unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const; | ||||
| 	unsigned int getLowestCreatureSpeed(); | ||||
| @@ -165,6 +167,7 @@ public: | ||||
| 	std::set<CCastleEvent> events; | ||||
|  | ||||
|  | ||||
| 	bool needsLastStack() const; | ||||
| 	int getSightDistance() const; //returns sight distance | ||||
| 	int fortLevel() const; //0 - none, 1 - fort, 2 - citadel, 3 - castle | ||||
| 	int hallLevel() const; // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol | ||||
|   | ||||
							
								
								
									
										2
									
								
								map.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								map.cpp
									
									
									
									
									
								
							| @@ -1054,7 +1054,7 @@ void Mapa::loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i ) | ||||
| 		if(readChar(bufor,i))//true if hore's experience is greater than 0 | ||||
| 		{	nhi->exp = readNormalNr(bufor,i); i+=4;	} | ||||
| 		else | ||||
| 			nhi->exp = -1; | ||||
| 			nhi->exp = 0xffffffff; | ||||
| 	} | ||||
| 	else | ||||
| 	{	nhi->exp = readNormalNr(bufor,i); i+=4;	} | ||||
|   | ||||
| @@ -518,50 +518,50 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c) | ||||
| 					c >> what >> id1 >> p1 >> id2 >> p2; | ||||
| 					CArmedInstance *s1 = static_cast<CArmedInstance*>(gs->map->objects[id1]), | ||||
| 						*s2 = static_cast<CArmedInstance*>(gs->map->objects[id2]); | ||||
| 					CCreatureSet *S1 = &s1->army, *S2 = &s2->army; | ||||
| 					CCreatureSet temp1 = s1->army, temp2 = s2->army, | ||||
| 						&S1 = temp1, &S2 = (s1!=s2)?(temp2):(temp1); | ||||
| 					 | ||||
| 					if(what==1) //swap | ||||
| 					{ | ||||
| 						int pom = S2->slots[p2].first; | ||||
| 						S2->slots[p2].first = S1->slots[p1].first; | ||||
| 						S1->slots[p1].first = pom; | ||||
| 						int pom2 = S2->slots[p2].second; | ||||
| 						S2->slots[p2].second = S1->slots[p1].second; | ||||
| 						S1->slots[p1].second = pom2; | ||||
| 						std::swap(S1.slots[p1],S2.slots[p2]); | ||||
|  | ||||
| 						if(!S1->slots[p1].second) | ||||
| 							S1->slots.erase(p1); | ||||
| 						if(!S2->slots[p2].second) | ||||
| 							S2->slots.erase(p2); | ||||
| 						if(!S1.slots[p1].second) | ||||
| 							S1.slots.erase(p1); | ||||
| 						if(!S2.slots[p2].second) | ||||
| 							S2.slots.erase(p2); | ||||
| 					} | ||||
| 					else if(what==2)//merge | ||||
| 					{ | ||||
| 						if(S1->slots[p1].first != S2->slots[p2].first) break; //not same creature | ||||
| 						S2->slots[p2].second += S1->slots[p1].second; | ||||
| 						S1->slots[p1].first = NULL; | ||||
| 						S1->slots[p1].second = 0; | ||||
| 						S1->slots.erase(p1); | ||||
| 						if(S1.slots[p1].first != S2.slots[p2].first) break; //not same creature | ||||
| 						S2.slots[p2].second += S1.slots[p1].second; | ||||
| 						S1.slots.erase(p1); | ||||
| 					} | ||||
| 					else if(what==3) //split | ||||
| 					{ | ||||
| 						si32 val; | ||||
| 						c >> val; | ||||
| 						if(S2->slots.find(p2) != S2->slots.end()) break; //slot not free | ||||
| 						S2->slots[p2].first = S1->slots[p1].first; | ||||
| 						S2->slots[p2].second = val; | ||||
| 						S1->slots[p1].second -= val; | ||||
| 						if(!S1->slots[p1].second) //if we've moved all creatures | ||||
| 							S1->slots.erase(p1);  | ||||
| 						if(	vstd::contains(S2.slots,p2)		//dest. slot not free | ||||
| 						  || !vstd::contains(S1.slots,p1)	//no creatures to split | ||||
| 						  || S1.slots[p1].second < val		//not enough creatures | ||||
| 						  || val<1							//val must be positive | ||||
| 						)  | ||||
| 							break;  | ||||
| 						S2.slots[p2].first = S1.slots[p1].first; | ||||
| 						S2.slots[p2].second = val; | ||||
| 						S1.slots[p1].second -= val; | ||||
| 						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())) | ||||
| 					if((s1->needsLastStack() && !S1.slots.size()) //it's not allowed to take last stack from hero army! | ||||
| 					  || (s2->needsLastStack() && !S2.slots.size()) | ||||
| 					) | ||||
| 					{ | ||||
| 						break; | ||||
| 						break; //leave without applying changes to garrison | ||||
| 					} | ||||
| 					SetGarrisons sg; | ||||
| 					sg.garrs[id1] = *S1; | ||||
| 					sg.garrs[id1] = S1; | ||||
| 					if(s1 != s2) | ||||
| 						sg.garrs[id2] = *S2; | ||||
| 						sg.garrs[id2] = S2; | ||||
| 					sendAndApply(&sg); | ||||
| 					break; | ||||
| 				} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user