mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* started making morale/luck system
* basic calculation of hero/stack morale * displaying morale in hero window * redone checking if attack is possible (should fix some problems with attacking with 2-hex creatures, at least on server side) * std::list serialization * version set to 0.7b
This commit is contained in:
		| @@ -583,6 +583,13 @@ void CGameState::applyNL(IPack * pack) | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 	case 115: | ||||
| 		{ | ||||
| 			GiveBonus *rh = static_cast<GiveBonus*>(pack); | ||||
| 			CGHeroInstance *h = getHero(rh->hid); | ||||
| 			h->bonuses.push_back(CGHeroInstance::Bonus(rh->bduration,rh->btype,rh->bval,rh->bid,toString(rh->bdescr))); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 500: | ||||
| 		{ | ||||
| 			RemoveObject *rh = static_cast<RemoveObject*>(pack); | ||||
|   | ||||
| @@ -101,6 +101,12 @@ CHeroWindow::CHeroWindow(int playerColor): | ||||
| 	expArea->pos.h = 42; | ||||
| 	expArea->hoverText = CGI->generaltexth->heroscrn[9]; | ||||
|  | ||||
| 	morale = new LRClickableAreaWTextComp(); | ||||
| 	morale->pos = genRect(45,53,pos.x+240,pos.y+187); | ||||
|  | ||||
| 	luck = new LRClickableAreaWTextComp(); | ||||
| 	luck->pos = genRect(45,53,pos.x+298,pos.y+187); | ||||
|  | ||||
| 	spellPointsArea = new LRClickableAreaWText(); | ||||
| 	spellPointsArea->pos.x = pos.x+227; | ||||
| 	spellPointsArea->pos.y = pos.y  +  236; | ||||
| @@ -161,6 +167,8 @@ CHeroWindow::~CHeroWindow() | ||||
|  | ||||
| 	delete portraitArea; | ||||
| 	delete expArea; | ||||
| 	delete luck; | ||||
| 	delete morale; | ||||
| 	delete spellPointsArea; | ||||
| 	for(size_t v=0; v<primSkillAreas.size(); ++v) | ||||
| 	{ | ||||
| @@ -339,6 +347,18 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero) | ||||
| 	formations->select(hero->army.formation,true); | ||||
| 	formations->onChange = boost::bind(&CCallback::setFormation, LOCPLINT->cb, Hero, _1); | ||||
|  | ||||
| 	std::vector<std::pair<int,std::string> > mrl = hero->getCurrentMoraleModifiers(); | ||||
| 	int mrlv = hero->getCurrentMorale(); | ||||
| 	int mrlt = (mrlv>0)-(mrlv<0); //signum: -1 - bad morale, 0 - neutral, 1 - good | ||||
| 	morale->hoverText = CGI->generaltexth->heroscrn[4 - mrlt]; | ||||
| 	morale->baseType = SComponent::morale; | ||||
| 	morale->bonus = mrlv; | ||||
| 	morale->text = CGI->generaltexth->arraytxt[88]; | ||||
| 	boost::algorithm::replace_first(morale->text,"%s",CGI->generaltexth->arraytxt[86-mrlt]); | ||||
| 	for(int it=0; it < mrl.size(); it++) | ||||
| 		morale->text += mrl[it].second; | ||||
|  | ||||
|  | ||||
| 	pos.x += 65; | ||||
| 	pos.y += 8; | ||||
|  | ||||
| @@ -385,6 +405,8 @@ void CHeroWindow::activate() | ||||
| 	portraitArea->activate(); | ||||
| 	expArea->activate(); | ||||
| 	spellPointsArea->activate(); | ||||
| 	morale->activate(); | ||||
| 	luck->activate(); | ||||
|  | ||||
| 	garInt->activate(); | ||||
| 	LOCPLINT->statusbar = ourBar; | ||||
| @@ -430,6 +452,8 @@ void CHeroWindow::deactivate() | ||||
| 	portraitArea->deactivate(); | ||||
| 	expArea->deactivate(); | ||||
| 	spellPointsArea->deactivate(); | ||||
| 	morale->activate(); | ||||
| 	luck->activate(); | ||||
|  | ||||
| 	garInt->deactivate(); | ||||
|  | ||||
| @@ -830,10 +854,6 @@ void LClickableArea::clickLeft(boost::logic::tribool down) | ||||
| 	//{ | ||||
| 	//	LOCPLINT->showInfoDialog("TEST TEST AAA", std::vector<SComponent*>()); | ||||
| 	//} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| void RClickableArea::activate() | ||||
| @@ -850,10 +870,6 @@ void RClickableArea::clickRight(boost::logic::tribool down) | ||||
| 	//{ | ||||
| 	//	LOCPLINT->showInfoDialog("TEST TEST AAA", std::vector<SComponent*>()); | ||||
| 	//} | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| void LRClickableAreaWText::clickLeft(boost::logic::tribool down) | ||||
|   | ||||
| @@ -105,6 +105,8 @@ class CHeroWindow: public IShowActivable, public virtual CIntObject | ||||
| 	std::vector<LRClickableAreaWTextComp *> primSkillAreas; | ||||
| 	LRClickableAreaWText * expArea; | ||||
| 	LRClickableAreaWText * spellPointsArea; | ||||
| 	LRClickableAreaWTextComp * luck; | ||||
| 	LRClickableAreaWTextComp * morale; | ||||
| 	std::vector<LRClickableAreaWTextComp *> secSkillAreas; | ||||
| public: | ||||
| 	AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general | ||||
|   | ||||
| @@ -168,7 +168,7 @@ void CGarrisonSlot::clickRight (tribool down) | ||||
| 			pom->attackBonus = h->getPrimSkillLevel(0); | ||||
| 			pom->defenseBonus = h->getPrimSkillLevel(1); | ||||
| 			pom->luck = h->getCurrentLuck(); | ||||
| 			pom->morale = h->getCurrentMorale(); | ||||
| 			pom->morale = h->getCurrentMorale(ID); | ||||
| 		} | ||||
| 		(new CCreInfoWindow(creature->idNumber,0,count,pom,boost::function<void()>(),boost::function<void()>(),NULL)) | ||||
| 				->activate(); | ||||
| @@ -723,6 +723,9 @@ SDL_Surface * SComponent::getImg() | ||||
| 	case experience: | ||||
| 		return graphics->pskillsb->ourImages[4].bitmap; | ||||
| 		break; | ||||
| 	case morale: | ||||
| 		return graphics->morale82->ourImages[val+3].bitmap; | ||||
| 		break; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| @@ -1197,7 +1200,14 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details) | ||||
| { | ||||
| 	boost::unique_lock<boost::recursive_mutex> un(*pim); | ||||
|  | ||||
| 	adventureInt->centerOn(details.ho->pos); //centering screen on hero | ||||
| 	int3 buff = details.ho->pos; | ||||
| 	buff.x-=11; | ||||
| 	buff.y-=9; | ||||
| 	buff = repairScreenPos(buff); | ||||
| 	LOCPLINT->adventureInt->position = buff; //actualizing screen pos | ||||
|  | ||||
| 	if(adventureInt == curint) | ||||
| 		adventureInt->minimap.draw(); | ||||
|  | ||||
| 	if(details.style>0) | ||||
| 		return; | ||||
|   | ||||
| @@ -224,7 +224,7 @@ class SComponent : public ClickableR | ||||
| public: | ||||
| 	enum Etype | ||||
| 	{ | ||||
| 		primskill, secskill, resource, creature, artifact, experience, secskill44, spell | ||||
| 		primskill, secskill, resource, creature, artifact, experience, secskill44, spell, morale, luck | ||||
| 	} type; | ||||
| 	int subtype; | ||||
| 	int val; | ||||
|   | ||||
							
								
								
									
										18
									
								
								CPreGame.cpp
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								CPreGame.cpp
									
									
									
									
									
								
							| @@ -839,6 +839,7 @@ int MapSel::countWL() | ||||
| void MapSel::printMaps(int from, int to, int at, bool abs) | ||||
| { | ||||
| 	if (!slid->positionsAmnt) return; //no maps to print | ||||
| 	slid->capacity = (CPG->fromnewgame == 2  ?  16  : 18); | ||||
| 	if(slid->positionsAmnt < slid->capacity) | ||||
| 		from = 0; | ||||
| 	int help=-1; | ||||
| @@ -928,7 +929,7 @@ void MapSel::printMaps(int from, int to, int at, bool abs) | ||||
| 		else | ||||
| 			tlog2 << "Warning: " << curVector()[(i-at)+from].filename << " has wrong version!\n"; | ||||
|  | ||||
| 		if(CPG->fromnewgame) | ||||
| 		if(CPG->fromnewgame == 1) | ||||
| 		{ | ||||
| 			if (!(curVector()[(i-at)+from].name.length())) | ||||
| 				curVector()[(i-at)+from].name = "Unnamed"; | ||||
| @@ -998,7 +999,7 @@ void MapSel::show() | ||||
| 	//blit bg | ||||
| 	blitAt(bg,3,6); | ||||
| 	CSDL_Ext::printAt("Map Sizes",55,60,GEOR13); | ||||
| 	CSDL_Ext::printAt(CGI->generaltexth->arraytxt[CPG->fromnewgame ? 229 : 230],110,25,TNRB16); //Select a Scenario to Play : Load a Saved Game | ||||
| 	CSDL_Ext::printAt(CGI->generaltexth->arraytxt[CPG->fromnewgame==1 ? 229 : 230],110,25,TNRB16); //Select a Scenario to Play : Load a Saved Game | ||||
| 	//size buttons | ||||
| 	small.show(); | ||||
| 	medium.show(); | ||||
| @@ -1318,7 +1319,7 @@ void MapSel::printSelectedInfo() | ||||
|  | ||||
| 	SDL_BlitSurface(CPG->ourScenSel->scenInf,&genRect(399,337,17,23),screen,&genRect(399,337,413,29)); | ||||
| 	SDL_BlitSurface(CPG->ourScenSel->scenInf,&genRect(50,91,18,447),screen,&genRect(50,91,414,453)); | ||||
| 	if(CPG->fromnewgame) | ||||
| 	if(CPG->fromnewgame==1) | ||||
| 	{ | ||||
| 		SDL_BlitSurface(CPG->ourScenSel->bScens.imgs->ourImages[0].bitmap,NULL,screen,&CPG->ourScenSel->bScens.pos); | ||||
| 		SDL_BlitSurface(CPG->ourScenSel->bOptions.imgs->ourImages[0].bitmap,NULL,screen,&CPG->ourScenSel->bOptions.pos); | ||||
| @@ -1471,7 +1472,7 @@ std::string MapSel::gdiff(std::string ss) | ||||
|  | ||||
| CMapInfo & MapSel::selectedMap() | ||||
| { | ||||
| 	if(CPG->fromnewgame) | ||||
| 	if(CPG->fromnewgame==1) | ||||
| 		return ourMaps[selected]; | ||||
| 	else | ||||
| 		return ourGames[selected]; | ||||
| @@ -1480,7 +1481,7 @@ CMapInfo & MapSel::selectedMap() | ||||
| std::vector<CMapInfo> & MapSel::curVector() | ||||
| { | ||||
|  | ||||
| 	if (CPG->fromnewgame)  | ||||
| 	if (CPG->fromnewgame==1)  | ||||
| 		return ourMaps; | ||||
| 	else | ||||
| 		return ourGames; | ||||
| @@ -1581,7 +1582,7 @@ void CPreGame::showScenSel() | ||||
| 	SDL_BlitSurface(ourScenSel->bHard.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bHard.pos); | ||||
| 	SDL_BlitSurface(ourScenSel->bExpert.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bExpert.pos); | ||||
| 	SDL_BlitSurface(ourScenSel->bImpossible.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bImpossible.pos); | ||||
| 	SDL_BlitSurface((fromnewgame ? ourScenSel->bBegin : ourScenSel->bLoad).imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBegin.pos); | ||||
| 	SDL_BlitSurface((fromnewgame==1 ? ourScenSel->bBegin : ourScenSel->bLoad).imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBegin.pos); | ||||
| 	SDL_BlitSurface(ourScenSel->bBack.imgs->ourImages[0].bitmap,NULL,screen,&ourScenSel->bBack.pos); | ||||
| 	//blitAt(ourScenSel->bScens.imgs->ourImages[0].bitmap,ourScenSel->bScens.pos.x,ourScenSel->bScens.pos.y); | ||||
| 	//blitAt(ourScenSel->bRandom.imgs->ourImages[0].bitmap,414,105); | ||||
| @@ -1592,7 +1593,7 @@ void CPreGame::showScenSel() | ||||
| 	//add buttons info | ||||
| 	if(first) | ||||
| 	{ | ||||
| 		if(fromnewgame) | ||||
| 		if(fromnewgame==1) | ||||
| 		{ | ||||
| 			btns.push_back(&ourScenSel->bEasy); | ||||
| 			btns.push_back(&ourScenSel->bNormal); | ||||
| @@ -1605,7 +1606,7 @@ void CPreGame::showScenSel() | ||||
| 		} | ||||
| 		else | ||||
| 			ourScenSel->mapsel.show(); | ||||
| 		btns.push_back(&(fromnewgame ? ourScenSel->bBegin : ourScenSel->bLoad)); | ||||
| 		btns.push_back(&(fromnewgame==1 ? ourScenSel->bBegin : ourScenSel->bLoad)); | ||||
| 		btns.push_back(&ourScenSel->bBack); | ||||
|  | ||||
| 		ourScenSel->selectedDiff=1; | ||||
| @@ -2468,6 +2469,7 @@ ScenSel::ScenSel() | ||||
| 	else  | ||||
| 		background = BitmapHandler::loadBitmap("ZPIC1001.bmp"); | ||||
|  | ||||
| 	savenameStrip = BitmapHandler::loadBitmap("GSSTRIP.bmp"); | ||||
| 	scenInf = BitmapHandler::loadBitmap("GSELPOP1.bmp"); | ||||
| 	randMap = BitmapHandler::loadBitmap("RANMAPBK.bmp"); | ||||
| 	options = BitmapHandler::loadBitmap("ADVOPTBK.bmp"); | ||||
|   | ||||
| @@ -221,7 +221,7 @@ public: | ||||
| 	bool listShowed; | ||||
| 	//RanSel ransel; | ||||
| 	MapSel mapsel; | ||||
| 	SDL_Surface * background, *scenInf, *scenList, *randMap, *options ; | ||||
| 	SDL_Surface * background, *savenameStrip, *scenInf, *scenList, *randMap, *options ; | ||||
| 	Button bScens, bOptions, bRandom, bBegin, bLoad, bBack; | ||||
| 	IntSelBut	bEasy, bNormal, bHard, bExpert, bImpossible; | ||||
| 	Button * pressed; | ||||
| @@ -244,7 +244,7 @@ public: | ||||
| 	StartInfo ret; | ||||
| 	bool run; | ||||
| 	bool first; //hasn't we showed the scensel | ||||
| 	bool fromnewgame; | ||||
| 	int fromnewgame; //1 - new game; 0 - load game; 2 - save game | ||||
| 	std::vector<Slider *> interested; | ||||
| 	CMusicHandler * mush; | ||||
| 	std::vector<HighButton *> btns; | ||||
|   | ||||
| @@ -206,6 +206,14 @@ void CClient::process(int what) | ||||
| 			gs->apply(&sav); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 115: | ||||
| 		{ | ||||
| 			GiveBonus gb; | ||||
| 			*serv >> gb; | ||||
| 			tlog5 << "Hero receives bonus\n"; | ||||
| 			gs->apply(&gb); | ||||
| 			break; | ||||
| 		} | ||||
| 	case 500: | ||||
| 		{ | ||||
| 			RemoveObject rh; | ||||
|   | ||||
							
								
								
									
										2
									
								
								global.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								global.h
									
									
									
									
									
								
							| @@ -19,7 +19,7 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte) | ||||
| #define THC | ||||
| #endif | ||||
|  | ||||
| #define NAME_VER ("VCMI 0.7") | ||||
| #define NAME_VER ("VCMI 0.7b") | ||||
| #define CONSOLE_LOGGING_LEVEL 5 | ||||
| #define FILE_LOGGING_LEVEL 6 | ||||
|  | ||||
|   | ||||
| @@ -330,11 +330,6 @@ int CGHeroInstance::getCurrentLuck() const | ||||
| 	//TODO: write it | ||||
| 	return 0; | ||||
| } | ||||
| int CGHeroInstance::getCurrentMorale() const | ||||
| { | ||||
| 	//TODO: write it | ||||
| 	return 0; | ||||
| } | ||||
| int CGHeroInstance::getPrimSkillLevel(int id) const | ||||
| { | ||||
| 	return primSkills[id]; | ||||
| @@ -601,6 +596,60 @@ void CGHeroInstance::initObj() | ||||
| 	blockVisit = true; | ||||
| } | ||||
|  | ||||
| int CGHeroInstance::getCurrentMorale( int stack, bool town ) const | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	std::vector<std::pair<int,std::string> > mods = getCurrentMoraleModifiers(stack,town); | ||||
| 	for(int i=0; i < mods.size(); i++) | ||||
| 		ret += mods[i].first; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentMoraleModifiers( int stack/*=-1*/, bool town/*=false*/ ) const | ||||
| { | ||||
| 	//TODO: check if stack is undead/mechanic/elemental => always neutrl morale | ||||
| 	std::vector<std::pair<int,std::string> > ret; | ||||
|  | ||||
| 	//various morale bonuses (from buildings, artifacts, etc) | ||||
| 	for(std::list<Bonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++) | ||||
| 		if(i->type == 2) | ||||
| 			ret.push_back(std::make_pair(i->val, i->description)); | ||||
|  | ||||
| 	//leadership | ||||
| 	if(getSecSkillLevel(6))  | ||||
| 		ret.push_back(std::make_pair(getSecSkillLevel(6),VLC->generaltexth->arraytxt[104+getSecSkillLevel(6)])); | ||||
|  | ||||
|  | ||||
| 	//number of alignments and presence of undead | ||||
| 	if(stack>=0) | ||||
| 	{ | ||||
| 		std::set<si8> factions; | ||||
| 		for(std::map<si32,std::pair<ui32,si32> >::const_iterator i=army.slots.begin(); i!=army.slots.end(); i++) | ||||
| 			factions.insert(VLC->creh->creatures[i->second.first].faction); | ||||
|  | ||||
| 		if(factions.size() == 1) | ||||
| 			ret.push_back(std::pair<int,std::string>(1,VLC->generaltexth->arraytxt[115])); //All troops of one alignment +1 | ||||
| 		else | ||||
| 		{ | ||||
| 			if(VLC->generaltexth->arraytxt[114].length() <= 100) | ||||
| 			{ | ||||
| 				char buf[150]; | ||||
| 				std::sprintf(buf,VLC->generaltexth->arraytxt[114].c_str(),factions.size(),2-factions.size()); | ||||
| 				ret.push_back(std::pair<int,std::string>(2-factions.size(),buf)); //Troops of %d alignments %d | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				ret.push_back(std::pair<int,std::string>(2-factions.size(),"")); //Troops of %d alignments %d | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if(vstd::contains(factions,4)) | ||||
| 			ret.push_back(std::pair<int,std::string>(-1,VLC->generaltexth->arraytxt[116])); //Undead in group -1 | ||||
| 	} | ||||
|  | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| int CGTownInstance::getSightDistance() const //returns sight distance | ||||
| { | ||||
| 	return 10; | ||||
| @@ -1151,10 +1200,8 @@ void CGResource::collectRes( int player ) const | ||||
|  | ||||
| void CGResource::fightForRes(ui32 refusedFight, const CGHeroInstance *h) const | ||||
| { | ||||
| 	if(refusedFight) | ||||
| 		return; | ||||
|  | ||||
| 	cb->startBattleI(h->id,army,pos,boost::bind(&CGResource::endBattle,this,_1,h)); | ||||
| 	if(!refusedFight) | ||||
| 		cb->startBattleI(h->id,army,pos,boost::bind(&CGResource::endBattle,this,_1,h)); | ||||
| } | ||||
|  | ||||
| void CGResource::endBattle( BattleResult *result, const CGHeroInstance *h ) const | ||||
| @@ -1308,15 +1355,51 @@ void CGArtifact::initObj() | ||||
|  | ||||
| void CGArtifact::onHeroVisit( const CGHeroInstance * h ) const | ||||
| { | ||||
| 	cb->giveHeroArtifact(subID,h->id,-2); | ||||
| 	cb->removeObject(id); | ||||
| 	InfoWindow iw; | ||||
| 	iw.player = h->tempOwner; | ||||
| 	iw.components.push_back(Component(4,subID,0,0)); | ||||
| 	iw.text << std::pair<ui8,ui32>(12,subID); | ||||
| 	cb->showInfoDialog(&iw); | ||||
| 	if(!army.slots.size()) | ||||
| 	{ | ||||
| 		InfoWindow iw; | ||||
| 		iw.player = h->tempOwner; | ||||
| 		iw.components.push_back(Component(4,subID,0,0)); | ||||
| 		if(message.length()) | ||||
| 			iw.text <<  message; | ||||
| 		else | ||||
| 			iw.text << std::pair<ui8,ui32>(12,subID); | ||||
| 		cb->showInfoDialog(&iw); | ||||
| 		pick(h); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		if(message.size()) | ||||
| 		{ | ||||
| 			YesNoDialog ynd; | ||||
| 			ynd.player = h->getOwner(); | ||||
| 			ynd.text << message; | ||||
| 			cb->showYesNoDialog(&ynd,boost::bind(&CGArtifact::fightForArt,this,_1,h)); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			fightForArt(0,h); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CGArtifact::pick(const CGHeroInstance * h) const | ||||
| { | ||||
| 	cb->giveHeroArtifact(subID,h->id,-2); | ||||
| 	cb->removeObject(id); | ||||
| } | ||||
|  | ||||
| void CGArtifact::fightForArt( ui32 refusedFight, const CGHeroInstance *h ) const | ||||
| { | ||||
| 	if(!refusedFight) | ||||
| 		cb->startBattleI(h->id,army,pos,boost::bind(&CGArtifact::endBattle,this,_1,h)); | ||||
| } | ||||
|  | ||||
| void CGArtifact::endBattle( BattleResult *result, const CGHeroInstance *h ) const | ||||
| { | ||||
| 	if(result->winner == 0) //attacker won | ||||
| 		pick(h); | ||||
| } | ||||
| void CGPickable::initObj() | ||||
| { | ||||
| 	blockVisit = true; | ||||
| @@ -1453,4 +1536,14 @@ void CGWitchHut::onHeroVisit( const CGHeroInstance * h ) const | ||||
| 	} | ||||
|  | ||||
| 	cb->showInfoDialog(&iw); | ||||
| } | ||||
|  | ||||
| void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CGDwelling::initObj() | ||||
| { | ||||
|  | ||||
| } | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <vector> | ||||
| #include <set> | ||||
| #include <map> | ||||
| #include <list> | ||||
| #include "CCreatureHandler.h" | ||||
| #ifndef _MSC_VER | ||||
| #include "CHeroHandler.h" | ||||
| @@ -165,18 +166,41 @@ public: | ||||
| 	si32 movement; //remaining movement points | ||||
| 	si32 identifier; //from the map file | ||||
| 	ui8 sex; | ||||
| 	struct DLL_EXPORT Patrol | ||||
| 	{ | ||||
| 		Patrol(){patrolling=false;patrolRadious=-1;}; | ||||
| 		bool patrolling; | ||||
| 		int patrolRadious; | ||||
| 	} patrol; | ||||
| 	ui8 inTownGarrison; // if hero is in town garrison  | ||||
| 	CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison | ||||
| 	std::vector<ui32> artifacts; //hero's artifacts from bag | ||||
| 	std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 | ||||
| 	std::set<ui32> spells; //known spells (spell IDs) | ||||
|  | ||||
| 	struct DLL_EXPORT Patrol | ||||
| 	{ | ||||
| 		Patrol(){patrolling=false;patrolRadious=-1;}; | ||||
| 		ui8 patrolling; | ||||
| 		si32 patrolRadious; | ||||
| 		template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 		{ | ||||
| 			h & patrolling & patrolRadious; | ||||
| 		} | ||||
| 	} patrol; | ||||
|  | ||||
| 	struct DLL_EXPORT Bonus | ||||
| 	{ | ||||
| 		ui8 duration; //0 - Permanent, 1 - OneBattle, 2 - OneDay, 3 - OneWeek | ||||
| 		ui8 type; //0 - none, 1 - movement; 2 - morale; 3 - luck | ||||
| 		si32 val; | ||||
| 		ui32 id; | ||||
| 		std::string description; | ||||
|  | ||||
| 		Bonus(ui8 Dur, ui8 Type, si32 Val, ui32 ID, std::string Desc) | ||||
| 			:duration(Dur), type(Type), val(Val), id(ID), description(Desc) | ||||
| 		{} | ||||
| 		Bonus(){}; | ||||
| 		template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 		{ | ||||
| 			h & duration & type & val & id; | ||||
| 		} | ||||
| 	}; | ||||
| 	std::list<Bonus> bonuses; | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
|  | ||||
| @@ -184,7 +208,7 @@ public: | ||||
| 	{ | ||||
| 		h & static_cast<CArmedInstance&>(*this); | ||||
| 		h & exp & level & name & biography & portrait & mana & primSkills & secSkills & movement | ||||
| 			& identifier & sex & inTownGarrison & artifacts & artifWorn & spells; | ||||
| 			& identifier & sex & inTownGarrison & artifacts & artifWorn & spells & patrol & bonuses; | ||||
|  | ||||
| 		ui8 standardType = (VLC->heroh->heroes[subID] == type); | ||||
| 		h & standardType; | ||||
| @@ -207,7 +231,8 @@ public: | ||||
| 	si32 manaLimit() const; //maximum mana value for this hero (basically 10*knowledge) | ||||
| 	bool canWalkOnSea() const; | ||||
| 	int getCurrentLuck() const; | ||||
| 	int getCurrentMorale() const; | ||||
| 	int getCurrentMorale(int stack=-1, bool town=false) const; //if stack - position of creature, if -1 then morale for hero is calculated; town - if bonuses from town (tavern) should be considered | ||||
| 	std::vector<std::pair<int,std::string> > getCurrentMoraleModifiers(int stack=-1, bool town=false) const; //args as above | ||||
| 	int getPrimSkillLevel(int id) const; | ||||
| 	ui8 getSecSkillLevel(const int & ID) const; //0 - no skill | ||||
| 	int maxMovePoints(bool onLand) const; | ||||
| @@ -217,6 +242,7 @@ public: | ||||
| 	int getSpellSecLevel(int spell) const; //returns level of secondary ability (fire, water, earth, air magic) known to this hero and applicable to given spell; -1 if error | ||||
| 	static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest | ||||
|  | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	void initHero();  | ||||
| @@ -452,6 +478,9 @@ public: | ||||
| 	std::string message; | ||||
| 	ui32 spell; //if it's spell scroll | ||||
| 	void onHeroVisit(const CGHeroInstance * h) const; | ||||
| 	void fightForArt(ui32 refusedFight, const CGHeroInstance *h) const; | ||||
| 	void endBattle(BattleResult *result, const CGHeroInstance *h) const; | ||||
| 	void pick( const CGHeroInstance * h ) const; | ||||
| 	void initObj();	 | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| @@ -583,6 +612,21 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| class DLL_EXPORT CGDwelling : public CGObjectInstance //teleports and subterranean gates | ||||
| { | ||||
| public: | ||||
| 	static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids | ||||
| 	void onHeroVisit(const CGHeroInstance * h) const; | ||||
| 	void initObj();	 | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & static_cast<CGObjectInstance&>(*this); | ||||
| 	} | ||||
| }; | ||||
|  | ||||
|  | ||||
|  | ||||
| class DLL_EXPORT CObjectHandler | ||||
| { | ||||
| public: | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include <set> | ||||
| #include <list> | ||||
|  | ||||
| #include <boost/type_traits/is_fundamental.hpp> | ||||
| #include <boost/type_traits/is_enum.hpp> | ||||
| @@ -263,6 +264,15 @@ public: | ||||
| 		for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++) | ||||
| 			*this << *i; | ||||
| 	} | ||||
| 	template <typename T> | ||||
| 	void saveSerializable(const std::list<T> &data) | ||||
| 	{ | ||||
| 		std::list<T> &d = const_cast<std::list<T> &>(data); | ||||
| 		boost::uint32_t length = d.size(); | ||||
| 		*this << length; | ||||
| 		for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++) | ||||
| 			*this << *i; | ||||
| 	} | ||||
| 	void saveSerializable(const std::string &data) | ||||
| 	{ | ||||
| 		*this << ui32(data.length()); | ||||
| @@ -383,6 +393,18 @@ public: | ||||
| 			data.insert(ins); | ||||
| 		} | ||||
| 	} | ||||
| 	template <typename T> | ||||
| 	void loadSerializable(std::list<T> &data) | ||||
| 	{ | ||||
| 		boost::uint32_t length; | ||||
| 		*this >> length; | ||||
| 		T ins; | ||||
| 		for(ui32 i=0;i<length;i++) | ||||
| 		{ | ||||
| 			*this >> ins; | ||||
| 			data.push_back(ins); | ||||
| 		} | ||||
| 	} | ||||
| 	template <typename T1, typename T2> | ||||
| 	void loadSerializable(std::pair<T1,T2> &data) | ||||
| 	{ | ||||
|   | ||||
| @@ -33,6 +33,41 @@ template <typename T> struct Query | ||||
| { | ||||
| 	ui32 id; | ||||
| }; | ||||
|  | ||||
| struct MetaString : public CPack<MetaString> //2001 helper for object scrips | ||||
| { | ||||
| 	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<si32> message; | ||||
| 	std::vector<std::string> replacements; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & strings & texts & message & replacements; | ||||
| 	} | ||||
|  | ||||
| 	MetaString& operator<<(const std::pair<ui8,ui32> &txt) | ||||
| 	{ | ||||
| 		message.push_back(-((si32)texts.size())-1); | ||||
| 		texts.push_back(txt); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	MetaString& operator<<(const std::string &txt) | ||||
| 	{ | ||||
| 		message.push_back(strings.size()+1); | ||||
| 		strings.push_back(txt); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	void clear() | ||||
| 	{ | ||||
| 		strings.clear(); | ||||
| 		texts.clear(); | ||||
| 		message.clear(); | ||||
| 	} | ||||
|  | ||||
| 	MetaString(){type = 2001;}; | ||||
| };  | ||||
|  | ||||
| struct SetResources : public CPack<SetResources> //104 | ||||
| { | ||||
| 	SetResources(){res.resize(RESOURCE_QUANTITY);type = 104;}; | ||||
| @@ -155,6 +190,23 @@ struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113 | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| struct GiveBonus :  public CPack<GiveBonus> //115 | ||||
| { | ||||
| 	GiveBonus(){type = 115;}; | ||||
|  | ||||
| 	ui8 bduration; | ||||
| 	ui8 btype; | ||||
| 	si32 bval; | ||||
| 	ui32 bid; | ||||
| 	ui32 hid; | ||||
| 	MetaString bdescr; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & bduration & btype & bval & bid & hid & bdescr; | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| struct RemoveObject : public CPack<RemoveObject> //500 | ||||
| { | ||||
| 	RemoveObject(){type = 500;}; | ||||
| @@ -295,39 +347,6 @@ struct NewTurn : public CPack<NewTurn> //101 | ||||
| //		h & sac; | ||||
| //	} | ||||
| //};   | ||||
| struct MetaString : public CPack<MetaString> //2001 helper for object scrips | ||||
| { | ||||
| 	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<si32> message; | ||||
| 	std::vector<std::string> replacements; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & strings & texts & message & replacements; | ||||
| 	} | ||||
|  | ||||
| 	MetaString& operator<<(const std::pair<ui8,ui32> &txt) | ||||
| 	{ | ||||
| 		message.push_back(-((si32)texts.size())-1); | ||||
| 		texts.push_back(txt); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	MetaString& operator<<(const std::string &txt) | ||||
| 	{ | ||||
| 		message.push_back(strings.size()+1); | ||||
| 		strings.push_back(txt); | ||||
| 		return *this; | ||||
| 	} | ||||
| 	void clear() | ||||
| 	{ | ||||
| 		strings.clear(); | ||||
| 		texts.clear(); | ||||
| 		message.clear(); | ||||
| 	} | ||||
|  | ||||
| 	MetaString(){type = 2001;}; | ||||
| };  | ||||
| struct Component : public CPack<Component> //2002 helper for object scrips informations | ||||
| { | ||||
| 	ui16 id, subtype; //ids: 0 - primskill; 1 - secskill; 2 - resource; 3 - creature; 4 - artifact; 5 - experience (sub==0 exp points; sub==1 levels) | ||||
|   | ||||
| @@ -1136,20 +1136,37 @@ upgend: | ||||
| 								tlog3<<"We cannot move this stack to its destination "<<curStack->creature->namePl<<std::endl; | ||||
| 							} | ||||
|  | ||||
| 							if( (BattleInfo::mutualPosition(ba.destinationTile, ba.additionalInfo) < 0 //destination tile is not neighbouring with enemy stack | ||||
| 									&& !curStack->creature->isDoubleWide()) | ||||
| 								|| (curStack->creature->isDoubleWide() | ||||
| 									&& (BattleInfo::mutualPosition(ba.destinationTile, ba.additionalInfo) < 0) | ||||
| 									&& (BattleInfo::mutualPosition(ba.destinationTile + (curStack->attackerOwned ? -1 : 1), ba.additionalInfo) < 0)) | ||||
| 							  )  | ||||
| 							if(!stackAtEnd) | ||||
| 							{ | ||||
| 								tlog3 << "There is no stack on " << ba.additionalInfo << " tile (no attack)!"; | ||||
| 								break; | ||||
| 							} | ||||
|  | ||||
| 							ui16 curpos = curStack->position,  | ||||
| 								enemypos = stackAtEnd->position; | ||||
|  | ||||
|  | ||||
| 							if( !( | ||||
| 								(BattleInfo::mutualPosition(curpos, enemypos) >= 0)						//front <=> front | ||||
| 								|| (curStack->creature->isDoubleWide()									//back <=> front | ||||
| 									&& BattleInfo::mutualPosition(curpos + (curStack->attackerOwned ? -1 : 1), enemypos) >= 0) | ||||
| 								|| (stackAtEnd->creature->isDoubleWide()									//front <=> back | ||||
| 									&& BattleInfo::mutualPosition(curpos, enemypos + (stackAtEnd->attackerOwned ? -1 : 1)) >= 0) | ||||
| 								|| (stackAtEnd->creature->isDoubleWide() && curStack->creature->isDoubleWide()//back <=> back | ||||
| 									&& BattleInfo::mutualPosition(curpos + (curStack->attackerOwned ? -1 : 1), enemypos + (stackAtEnd->attackerOwned ? -1 : 1)) >= 0) | ||||
| 								) | ||||
| 							) | ||||
| 							{ | ||||
| 								tlog3 << "Attack cannot be performed!"; | ||||
| 								sendDataToClients(ui16(3008)); //end movement and attack | ||||
| 								break; | ||||
| 							} | ||||
|  | ||||
| 							//attack | ||||
| 							BattleAttack bat; | ||||
| 							prepareAttack(bat,curStack,stackAtEnd); | ||||
| 							sendAndApply(&bat); | ||||
|  | ||||
| 							//counterattack | ||||
| 							if(!vstd::contains(curStack->abilities,NO_ENEMY_RETALIATION) | ||||
| 								&& stackAtEnd->alive() | ||||
| @@ -1161,6 +1178,7 @@ upgend: | ||||
| 								sendAndApply(&bat); | ||||
| 							} | ||||
|  | ||||
| 							//second attack | ||||
| 							if(vstd::contains(curStack->abilities,TWICE_ATTACK) | ||||
| 								&& curStack->alive() | ||||
| 								&& stackAtEnd->alive()  ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user