mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- removed usage of Graphics in several places (Components and hero window).
minor: - fixed several deprecation warnings in video player - config file may have multiple upgrades for creatures
This commit is contained in:
		| @@ -316,38 +316,35 @@ void CBattleOptionsWindow::bExitf() | ||||
| CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect & pos, CBattleInterface * _owner) | ||||
| : owner(_owner) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	this->pos = pos; | ||||
| 	background = BitmapHandler::loadBitmap("CPRESULT.BMP", true); | ||||
| 	graphics->blueToPlayersAdv(background, owner->curInt->playerID); | ||||
| 	SDL_Surface * pom = SDL_ConvertSurface(background, screen->format, screen->flags); | ||||
| 	SDL_FreeSurface(background); | ||||
| 	background = pom; | ||||
| 	exit = new CAdventureMapButton (std::string(), std::string(), boost::bind(&CBattleResultWindow::bExitf,this), 384 + pos.x, 505 + pos.y, "iok6432.def", SDLK_RETURN); | ||||
| 	CPicture * bg = new CPicture("CPRESULT"); | ||||
| 	bg->colorize(owner->curInt->playerID); | ||||
|  | ||||
| 	exit = new CAdventureMapButton ("", "", boost::bind(&CBattleResultWindow::bExitf,this), 384, 505, "iok6432.def", SDLK_RETURN); | ||||
| 	exit->borderColor = Colors::MetallicGold; | ||||
| 	exit->borderEnabled = true; | ||||
|  | ||||
| 	if(br.winner==0) //attacker won | ||||
| 	{ | ||||
| 		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 59, 124, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 408, 124, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 		new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[410]); | ||||
| 		new CLabel(408, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[411]); | ||||
| 	} | ||||
| 	else //if(br.winner==1) | ||||
| 	{ | ||||
| 		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 59, 124, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 412, 124, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 		new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[411]); | ||||
| 		new CLabel(412, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[410]); | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[407], 232, 302, FONT_BIG, Colors::Jasmine, background); | ||||
| 	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[408], 232, 332, FONT_BIG, Colors::Cornsilk, background); | ||||
| 	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[409], 237, 428, FONT_BIG, Colors::Cornsilk, background); | ||||
| 	new CLabel(232, 302, FONT_BIG, CENTER, Colors::Jasmine,  CGI->generaltexth->allTexts[407]); | ||||
| 	new CLabel(232, 332, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[408]); | ||||
| 	new CLabel(232, 428, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[409]); | ||||
|  | ||||
| 	std::string attackerName, defenderName; | ||||
|  | ||||
| 	if(owner->attackingHeroInstance) //a hero attacked | ||||
| 	{ | ||||
| 		SDL_Rect temp_rect = genRect(64, 58, 21, 38); | ||||
| 		SDL_BlitSurface(graphics->portraitLarge[owner->attackingHeroInstance->portrait], NULL, background, &temp_rect); | ||||
| 		new CAnimImage("PortraitsLarge", owner->attackingHeroInstance->portrait, 0, 21, 38); | ||||
| 		//setting attackerName | ||||
| 		attackerName = owner->attackingHeroInstance->name; | ||||
| 	} | ||||
| @@ -363,15 +360,13 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
| 				bestMonsterID = it->second->type->idNumber; | ||||
| 			} | ||||
| 		} | ||||
| 		SDL_Rect temp_rect = genRect(64, 58, 21, 38); | ||||
| 		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect); | ||||
| 		new CAnimImage("TWCRPORT", bestMonsterID, 0, 21, 38); | ||||
| 		//setting attackerName | ||||
| 		attackerName =  CGI->creh->creatures[bestMonsterID]->namePl; | ||||
| 	} | ||||
| 	if(owner->defendingHeroInstance) //a hero defended | ||||
| 	{ | ||||
| 		SDL_Rect temp_rect = genRect(64, 58, 392, 38); | ||||
| 		SDL_BlitSurface(graphics->portraitLarge[owner->defendingHeroInstance->portrait], NULL, background, &temp_rect); | ||||
| 		new CAnimImage("PortraitsLarge", owner->defendingHeroInstance->portrait, 0, 392, 38); | ||||
| 		//setting defenderName | ||||
| 		defenderName = owner->defendingHeroInstance->name; | ||||
| 	} | ||||
| @@ -387,21 +382,22 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
| 				bestMonsterID = it->second->type->idNumber; | ||||
| 			} | ||||
| 		} | ||||
| 		SDL_Rect temp_rect = genRect(64, 58, 392, 38); | ||||
| 		SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect); | ||||
| 		new CAnimImage("TWCRPORT", bestMonsterID, 0, 392, 38); | ||||
| 		//setting defenderName | ||||
| 		defenderName =  CGI->creh->creatures[bestMonsterID]->namePl; | ||||
| 	} | ||||
|  | ||||
| 	//printing attacker and defender's names | ||||
| 	CSDL_Ext::printAt(attackerName, 89, 37, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 	CSDL_Ext::printTo(defenderName, 381, 53, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 	new CLabel( 89, 37, FONT_SMALL, TOPLEFT, Colors::Cornsilk, attackerName); | ||||
|  | ||||
| 	new CLabel( 381, 53, FONT_SMALL, BOTTOMRIGHT, Colors::Cornsilk, defenderName); | ||||
|  | ||||
| 	//printing casualities | ||||
| 	for(int step = 0; step < 2; ++step) | ||||
| 	{ | ||||
| 		if(br.casualties[step].size()==0) | ||||
| 		{ | ||||
| 			CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 360 + 97*step, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 			new CLabel( 235, 360 + 97*step, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[523]); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| @@ -409,10 +405,10 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
| 			int yPos = 344 + step*97; | ||||
| 			for(std::map<ui32,si32>::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it) | ||||
| 			{ | ||||
| 				blitAt(graphics->smallImgs[it->first], xPos, yPos, background); | ||||
| 				new CAnimImage("CPRSMALL", it->first+2, 0, xPos, yPos); | ||||
| 				std::ostringstream amount; | ||||
| 				amount<<it->second; | ||||
| 				CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 				new CLabel( xPos+16, yPos + 42, FONT_SMALL, CENTER, Colors::Cornsilk, amount.str()); | ||||
| 				xPos += 42; | ||||
| 			} | ||||
| 		} | ||||
| @@ -440,7 +436,8 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
| 			boost::algorithm::replace_first(str,"%s",ourHero->name); | ||||
| 			boost::algorithm::replace_first(str,"%d",boost::lexical_cast<std::string>(br.exp[weAreAttacker?0:1])); | ||||
| 		} | ||||
| 		CSDL_Ext::printAtMiddleWB(str, 235, 235, FONT_SMALL, 55, Colors::Cornsilk, background); | ||||
| 		 | ||||
| 		new CTextBox(str, Rect(69, 203, 330, 68), 0, FONT_SMALL, CENTER, Colors::Cornsilk); | ||||
| 	} | ||||
| 	else // we lose | ||||
| 	{ | ||||
| @@ -450,21 +447,21 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
| 			{ | ||||
| 				CCS->musich->playMusic(musicBase::loseCombat); | ||||
| 				CCS->videoh->open(VIDEO_LOSE_BATTLE_START); | ||||
| 				CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[311]); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 1: //flee | ||||
| 			{ | ||||
| 				CCS->musich->playMusic(musicBase::retreatBattle); | ||||
| 				CCS->videoh->open(VIDEO_RETREAT_START); | ||||
| 				CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[310]); | ||||
| 				break; | ||||
| 			} | ||||
| 		case 2: //surrender | ||||
| 			{ | ||||
| 				CCS->musich->playMusic(musicBase::surrenderBattle); | ||||
| 				CCS->videoh->open(VIDEO_SURRENDER); | ||||
| 				CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 220, FONT_SMALL, Colors::Cornsilk, background); | ||||
| 				new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[309]); | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| @@ -473,7 +470,6 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect | ||||
|  | ||||
| CBattleResultWindow::~CBattleResultWindow() | ||||
| { | ||||
| 	SDL_FreeSurface(background); | ||||
| } | ||||
|  | ||||
| void CBattleResultWindow::activate() | ||||
| @@ -489,13 +485,13 @@ void CBattleResultWindow::deactivate() | ||||
|  | ||||
| void CBattleResultWindow::show(SDL_Surface * to) | ||||
| { | ||||
| 	CIntObject::show(to); | ||||
| 	//evaluating to | ||||
| 	if(!to) | ||||
| 		to = screen; | ||||
|  | ||||
| 	CCS->videoh->update(107, 70, background, false, true); | ||||
| 	CCS->videoh->update(pos.x + 107, pos.y + 70, screen, false, true); | ||||
|  | ||||
| 	SDL_BlitSurface(background, NULL, to, &pos); | ||||
| 	exit->showAll(to); | ||||
| } | ||||
|  | ||||
| @@ -759,4 +755,4 @@ CStackQueue::StackBox::~StackBox() | ||||
| void CStackQueue::StackBox::hover( bool on ) | ||||
| { | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -88,7 +88,6 @@ public: | ||||
| class CBattleResultWindow : public CIntObject | ||||
| { | ||||
| private: | ||||
| 	SDL_Surface *background; | ||||
| 	CAdventureMapButton *exit; | ||||
| 	CBattleInterface *owner; | ||||
| public: | ||||
|   | ||||
| @@ -837,7 +837,9 @@ void CInfoBar::showAll(SDL_Surface * to) | ||||
| 	{ | ||||
| 		CPicture bg("ADSTATOT.bmp"); | ||||
| 		bg.convertToScreenBPP(); | ||||
| 		blitAt(graphics->flags->ourImages[enemyTurnInfo.color].bitmap, 20, 51, bg); | ||||
| 		CAnimImage ai("CREST58", enemyTurnInfo.color, 0, 20, 51); | ||||
| 		ai.showAll(&*bg); | ||||
|  | ||||
| 		int hourglassFrame = enemyTurnInfo.progress * hourglass->ourImages.size(); | ||||
| 		static int sandFrame = 0; | ||||
| 		vstd::amin(hourglassFrame, hourglass->ourImages.size()-1); | ||||
| @@ -933,7 +935,10 @@ void CInfoBar::showComp(const CComponent * comp, int time/*=5000*/) | ||||
|  | ||||
| 	SDL_Surface * b = BitmapHandler::loadBitmap("ADSTATOT.bmp"); | ||||
| 	blitAt(b,pos.x+8,pos.y+11); | ||||
| 	blitAt(comp->getImg(),pos.x+52,pos.y+54); | ||||
|  | ||||
| 	CComponent* tempComp = (CComponent*)comp; //evil. TODO: remove need to move component | ||||
| 	tempComp->moveTo(Point(pos.x+52, pos.y+54)); | ||||
| 	tempComp->showAll(screen); | ||||
| 	printAtMiddle(comp->subtitle,pos.x+91,pos.y+158,FONT_SMALL,Colors::Cornsilk); | ||||
| 	printAtMiddleWB(comp->description,pos.x+94,pos.y+31,FONT_SMALL,26,Colors::Cornsilk); | ||||
| 	SDL_FreeSurface(b); | ||||
|   | ||||
| @@ -123,9 +123,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState) | ||||
| 		const CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second; | ||||
| 		if (bid < EBuilding::DWELL_FIRST) | ||||
| 		{ | ||||
| 			std::vector<CComponent*> comps(1, | ||||
| 			new CComponent(CComponent::building, bld->tid, bld->bid, | ||||
| 			               LOCPLINT->castleInt->bicons->ourImages[bld->bid].bitmap, false)); | ||||
| 			std::vector<CComponent*> comps(1, new CComponent(CComponent::building, bld->tid, bld->bid)); | ||||
|  | ||||
| 			CRClickPopup::createAndPush(bld->Description(), comps); | ||||
| 		} | ||||
| @@ -271,7 +269,7 @@ CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstanc | ||||
| 	{ | ||||
| 		if(creature->cost[i]) | ||||
| 		{ | ||||
| 			resPicture.push_back(new CPicture(graphics->resources32->ourImages[i].bitmap, 0, 0, false)); | ||||
| 			resPicture.push_back(new CAnimImage("RESOURCE", i, 0, 0, 0)); | ||||
| 			resAmount.push_back(new CLabel(0,0, FONT_SMALL, CENTER, Colors::Cornsilk, boost::lexical_cast<std::string>(creature->cost[i]))); | ||||
| 		} | ||||
| 	} | ||||
| @@ -303,12 +301,12 @@ void CHeroGSlot::hover (bool on) | ||||
| 	std::string temp; | ||||
| 	if(hero) | ||||
| 	{ | ||||
| 		if(highlight)//view NNN | ||||
| 		if(selection)//view NNN | ||||
| 		{ | ||||
| 			temp = CGI->generaltexth->tcommands[4]; | ||||
| 			boost::algorithm::replace_first(temp,"%s",hero->name); | ||||
| 		} | ||||
| 		else if(other->hero && other->highlight)//exchange | ||||
| 		else if(other->hero && other->selection)//exchange | ||||
| 		{ | ||||
| 			temp = CGI->generaltexth->tcommands[7]; | ||||
| 			boost::algorithm::replace_first(temp,"%s",hero->name); | ||||
| @@ -330,7 +328,7 @@ void CHeroGSlot::hover (bool on) | ||||
| 	} | ||||
| 	else //we are empty slot | ||||
| 	{ | ||||
| 		if(other->highlight && other->hero) //move NNNN | ||||
| 		if(other->selection && other->hero) //move NNNN | ||||
| 		{ | ||||
| 			temp = CGI->generaltexth->tcommands[6]; | ||||
| 			boost::algorithm::replace_first(temp,"%s",other->hero->name); | ||||
| @@ -352,12 +350,12 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState) | ||||
| 		owner->garr->splitting = false; | ||||
| 		owner->garr->highlighted = NULL; | ||||
|  | ||||
| 		if(hero && highlight) | ||||
| 		if(hero && selection) | ||||
| 		{ | ||||
| 			setHighlight(false); | ||||
| 			LOCPLINT->openHeroWindow(hero); | ||||
| 		} | ||||
| 		else if(other->hero && other->highlight) | ||||
| 		else if(other->hero && other->selection) | ||||
| 		{ | ||||
| 			bool allow = true; | ||||
| 			if(upg) //moving hero out of town - check if it is allowed | ||||
| @@ -394,20 +392,10 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState) | ||||
|  | ||||
| void CHeroGSlot::deactivate() | ||||
| { | ||||
| 	highlight = false; | ||||
| 	delChildNUll(selection, true); | ||||
| 	CIntObject::deactivate(); | ||||
| } | ||||
|  | ||||
| void CHeroGSlot::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	if(hero) //there is hero | ||||
| 		blitAt(graphics->portraitLarge[hero->portrait],pos,to); | ||||
| 	else if(!upg && owner->showEmpty) //up garrison | ||||
| 		blitAt(graphics->flags->ourImages[LOCPLINT->castleInt->town->getOwner()].bitmap,pos,to); | ||||
| 	if(highlight) | ||||
| 		blitAt(graphics->bigImgs[-1],pos,to); | ||||
| } | ||||
|  | ||||
| CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner) | ||||
| { | ||||
| 	used = LCLICK | HOVER; | ||||
| @@ -416,9 +404,10 @@ CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSl | ||||
| 	pos.y += y; | ||||
| 	pos.w = 58; | ||||
| 	pos.h = 64; | ||||
| 	hero = h; | ||||
| 	upg = updown; | ||||
| 	highlight = false; | ||||
| 	selection = nullptr; | ||||
| 	image = nullptr; | ||||
| 	set(h); | ||||
| } | ||||
|  | ||||
| CHeroGSlot::~CHeroGSlot() | ||||
| @@ -427,7 +416,17 @@ CHeroGSlot::~CHeroGSlot() | ||||
|  | ||||
| void CHeroGSlot::setHighlight( bool on ) | ||||
| { | ||||
| 	highlight = on; | ||||
| 	if (active && selection) | ||||
| 		selection->deactivate(); | ||||
|  | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	delChildNUll(selection, true); | ||||
| 	if (on) | ||||
| 		selection = new CAnimImage("TWCRPORT", 1, 0); | ||||
|  | ||||
| 	if (active && selection) | ||||
| 		selection->activate(); | ||||
|  | ||||
| 	if(owner->garrisonedHero->hero && owner->visitingHero->hero) //two heroes in town | ||||
| 	{ | ||||
| 		for(size_t i = 0; i<owner->garr->splitButtons.size(); i++) //splitting enabled when slot higlighted | ||||
| @@ -435,6 +434,26 @@ void CHeroGSlot::setHighlight( bool on ) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CHeroGSlot::set(const CGHeroInstance *newHero) | ||||
| { | ||||
| 	if (active && image) | ||||
| 		image->deactivate(); | ||||
|  | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	if (image) | ||||
| 		delChild(image); | ||||
| 	hero = newHero; | ||||
| 	if (newHero) | ||||
| 		image = new CAnimImage("PortraitsLarge", newHero->portrait, 0, 0, 0); | ||||
| 	else if(!upg && owner->showEmpty) //up garrison | ||||
| 		image = new CAnimImage("CREST58", LOCPLINT->castleInt->town->getOwner(), 0, 0, 0); | ||||
| 	else  | ||||
| 		image = NULL; | ||||
|  | ||||
| 	if (active && image) | ||||
| 		image->activate(); | ||||
| } | ||||
|  | ||||
| template <class ptr> | ||||
| class SORTHELP | ||||
| { | ||||
| @@ -797,9 +816,7 @@ void CCastleBuildings::enterBlacksmith(int ArtifactID) | ||||
|  | ||||
| void CCastleBuildings::enterBuilding(int building) | ||||
| { | ||||
| 	std::vector<CComponent*> comps(1, | ||||
| 		new CComponent(CComponent::building, town->subID,building,  | ||||
| 		               LOCPLINT->castleInt->bicons->ourImages[building].bitmap, false)); | ||||
| 	std::vector<CComponent*> comps(1, new CComponent(CComponent::building, town->subID, building)); | ||||
|  | ||||
| 	LOCPLINT->showInfoDialog( | ||||
| 		CGI->buildh->buildings[town->subID].find(building)->second->Description(),comps); | ||||
| @@ -836,9 +853,7 @@ void CCastleBuildings::enterDwelling(int level) | ||||
|  | ||||
| void CCastleBuildings::enterFountain(int building) | ||||
| { | ||||
| 	std::vector<CComponent*> comps(1, | ||||
| 		new CComponent(CComponent::building,town->subID,building, | ||||
| 		               LOCPLINT->castleInt->bicons->ourImages[building].bitmap,false)); | ||||
| 	std::vector<CComponent*> comps(1, new CComponent(CComponent::building,town->subID,building)); | ||||
|  | ||||
| 	std::string descr = CGI->buildh->buildings[town->subID].find(building)->second->Description(); | ||||
| 	if ( building == 21)//we need description for mystic pond as well | ||||
| @@ -918,6 +933,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos): | ||||
| 	town(Town) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	LOCPLINT->castleInt = this; | ||||
| 	used |= KEYBOARD; | ||||
|  | ||||
| 	builds = new CCastleBuildings(town); | ||||
| @@ -953,7 +969,6 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos): | ||||
| 	vstd::amax(townlist->from, 0); | ||||
| 	vstd::amin(townlist->from, LOCPLINT->towns.size() - townlist->SIZE); | ||||
|  | ||||
| 	LOCPLINT->castleInt = this; | ||||
| 	recreateIcons(); | ||||
| 	CCS->musich->playMusic(CCS->musich->townMusics[town->subID], -1); | ||||
| 	 | ||||
| @@ -1277,13 +1292,13 @@ HeroSlots::HeroSlots(const CGTownInstance * Town, Point garrPos, Point visitPos, | ||||
|  | ||||
| void HeroSlots::update() | ||||
| { | ||||
| 	garrisonedHero->hero = town->garrisonHero; | ||||
| 	visitingHero->hero = town->visitingHero; | ||||
| 	garrisonedHero->set(town->garrisonHero); | ||||
| 	visitingHero->set(town->visitingHero); | ||||
| } | ||||
|  | ||||
| void HeroSlots::splitClicked() | ||||
| { | ||||
| 	if(!!town->visitingHero && town->garrisonHero && (visitingHero->highlight || garrisonedHero->highlight)) | ||||
| 	if(!!town->visitingHero && town->garrisonHero && (visitingHero->selection || garrisonedHero->selection)) | ||||
| 	{ | ||||
| 		LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id); | ||||
| 	} | ||||
| @@ -1468,7 +1483,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin | ||||
| 	{ | ||||
| 		if(building->resources[i]) | ||||
| 		{ | ||||
| 			resPicture.push_back(new CPicture(graphics->resources32->ourImages[i].bitmap, 0, 0, false)); | ||||
| 			resPicture.push_back(new CAnimImage("RESOURCE", i)); | ||||
| 			resAmount.push_back(new CLabel(0,0, FONT_SMALL, CENTER, Colors::Cornsilk,  | ||||
| 			                        boost::lexical_cast<std::string>(building->resources[i]))); | ||||
| 		} | ||||
| @@ -1836,7 +1851,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i | ||||
| 	else | ||||
| 		buy->block(true); | ||||
|  | ||||
| 	gold = new CPicture(graphics->resources32->ourImages[6].bitmap,148,244, false); | ||||
| 	new CAnimImage("RESOURCE", 6, 0, 148, 244); | ||||
| } | ||||
|  | ||||
| void CBlacksmithDialog::close() | ||||
|   | ||||
| @@ -66,7 +66,7 @@ class CDwellingInfoBox : public CIntObject | ||||
| 	CLabel *available; | ||||
| 	CLabel *costPerTroop; | ||||
| 	 | ||||
| 	std::vector<CPicture *> resPicture; | ||||
| 	std::vector<CAnimImage *> resPicture; | ||||
| 	std::vector<CLabel *> resAmount; | ||||
| public: | ||||
| 	CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level); | ||||
| @@ -81,14 +81,16 @@ public: | ||||
| 	HeroSlots *owner; | ||||
| 	const CGHeroInstance *hero; | ||||
| 	int upg; //0 - up garrison, 1 - down garrison | ||||
| 	bool highlight; //indicates id the slot is highlighted | ||||
|  | ||||
| 	CAnimImage *image; | ||||
| 	CAnimImage *selection; //selection border. NULL if not selected | ||||
| 	 | ||||
| 	void setHighlight(bool on); | ||||
| 	void set(const CGHeroInstance *newHero); | ||||
|  | ||||
| 	void hover (bool on); | ||||
| 	void clickLeft(tribool down, bool previousState); | ||||
| 	void deactivate(); | ||||
| 	void showAll(SDL_Surface * to); | ||||
| 	CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner); //c-tor | ||||
| 	~CHeroGSlot(); //d-tor | ||||
| }; | ||||
| @@ -282,7 +284,7 @@ class CBuildWindow: public CIntObject | ||||
| 	CTextBox * buildingState; | ||||
| 	CGStatusBar *statusBar; | ||||
|  | ||||
| 	std::vector<CPicture *> resPicture; | ||||
| 	std::vector<CAnimImage *> resPicture; | ||||
| 	std::vector<CLabel *> resAmount; | ||||
|  | ||||
| 	std::string getTextForState(int state); | ||||
| @@ -384,7 +386,6 @@ class CBlacksmithDialog : public CIntObject | ||||
| 	CPicture *background; | ||||
| 	CPicture *animBG; | ||||
| 	CCreatureAnim * anim; | ||||
| 	CPicture * gold; | ||||
| 	CLabel * title; | ||||
| 	CLabel * costText; | ||||
| 	CLabel * costValue; | ||||
|   | ||||
| @@ -123,6 +123,7 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::func | ||||
| void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *StackNode, const CGHeroInstance *HeroOwner) | ||||
| { | ||||
| 	creatureArtifact = NULL; //may be set later | ||||
| 	artifactImage = NULL; | ||||
| 	stack = Stack; | ||||
| 	c = stack->type; | ||||
| 	if(!StackNode) | ||||
| @@ -207,7 +208,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode * | ||||
| 	luck = new MoraleLuckBox(false, genRect(42, 42, 387, 100)); | ||||
| 	luck->set(stack); | ||||
|  | ||||
| 	new CPicture(graphics->pskillsm->ourImages[4].bitmap, 387, 51, false); //exp icon - Print it always? | ||||
| 	new CAnimImage("PSKIL42", 4, 0, 387, 51); //exp icon - Print it always? | ||||
| 	if (type) //not in fort window | ||||
| 	{ | ||||
| 		if (GameConstants::STACK_EXP) | ||||
| @@ -259,7 +260,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode * | ||||
|  | ||||
| 		if (GameConstants::STACK_ARTIFACT) | ||||
| 		{ | ||||
| 			creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); | ||||
| 			setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); | ||||
| 			if (type > BATTLE) //artifact buttons inactive in battle | ||||
| 			{ | ||||
| 				//TODO: disable buttons if no artifact is equipped | ||||
| @@ -390,12 +391,6 @@ void CCreatureWindow::showAll(SDL_Surface * to) | ||||
|  | ||||
| 	BOOST_FOREACH(CBonusItem* b, bonusItems) | ||||
| 		b->showAll (to); | ||||
|  | ||||
| 	if (GameConstants::STACK_ARTIFACT) | ||||
| 	{ | ||||
| 		if (creatureArtifact) | ||||
| 			blitAt(graphics->artDefs->ourImages[creatureArtifact->artType->id].bitmap, 466 + pos.x, 100 + pos.y, to); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CCreatureWindow::show(SDL_Surface * to) | ||||
| @@ -411,10 +406,24 @@ void CCreatureWindow::sliderMoved(int newpos) | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
| void CCreatureWindow::setArt(const CArtifactInstance *creatureArtifact) | ||||
| { | ||||
| 	creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); | ||||
| 	if (creatureArtifact) | ||||
| 	{ | ||||
| 		if (artifactImage == NULL) | ||||
| 			addChild(artifactImage = new CAnimImage("ARTIFACT", creatureArtifact->artType->id, 0, 466, 100), true); | ||||
| 		else | ||||
| 			artifactImage->setFrame(creatureArtifact->artType->id); | ||||
| 	} | ||||
| 	else | ||||
| 		delChildNUll(artifactImage); | ||||
| } | ||||
|  | ||||
| void CCreatureWindow::scrollArt(int dir) | ||||
| { | ||||
| 	//TODO: get next artifact | ||||
| 	creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); | ||||
| 	setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); | ||||
| } | ||||
|  | ||||
| void CCreatureWindow::passArtifactToHero() | ||||
| @@ -432,13 +441,11 @@ void CCreatureWindow::passArtifactToHero() | ||||
|  | ||||
| void CCreatureWindow::artifactRemoved (const ArtifactLocation &artLoc) | ||||
| { | ||||
| 	creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders) | ||||
| 	redraw(); | ||||
| 	setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); //TODO: select next from the list (for Commanders) | ||||
| } | ||||
| void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc) | ||||
| { | ||||
| 	creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders) | ||||
| 	redraw(); | ||||
| 	setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); //TODO: select next from the list (for Commanders) | ||||
| } | ||||
|  | ||||
| void CCreatureWindow::clickRight(tribool down, bool previousState) | ||||
|   | ||||
| @@ -62,6 +62,9 @@ public: | ||||
| 	CAdventureMapButton *dismiss, *upgrade, *ok; | ||||
| 	CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection | ||||
| 	CAdventureMapButton * passArtToHero; | ||||
| 	CAnimImage *artifactImage; | ||||
|  | ||||
| 	void setArt(const CArtifactInstance *creatureArtifact); | ||||
|  | ||||
| 	void artifactRemoved (const ArtifactLocation &artLoc); | ||||
| 	void artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc); | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| #include "StdInc.h" | ||||
|  | ||||
| #include "CAnimation.h" | ||||
| #include "CAdvmapInterface.h" | ||||
| #include "../CCallback.h" | ||||
| #include "CGameInfo.h" | ||||
| @@ -69,38 +70,37 @@ void CHeroSwitcher::clickLeft(tribool down, bool previousState) | ||||
| { | ||||
| 	if(!down) | ||||
| 	{ | ||||
| 		const CGHeroInstance * buf = LOCPLINT->getWHero(id); | ||||
| 		if(!buf) | ||||
| 			return; | ||||
| 		GH.popIntTotally(getOwner()); | ||||
| 		const CGHeroInstance * buf = hero; | ||||
| 		GH.popIntTotally(parent); | ||||
| 		GH.pushInt(new CHeroWindow(buf)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| CHeroWindow * CHeroSwitcher::getOwner() | ||||
| CHeroSwitcher::CHeroSwitcher(Point _pos, const CGHeroInstance * _hero): | ||||
| 	hero(_hero) | ||||
| { | ||||
| 	return dynamic_cast<CHeroWindow*>(parent); | ||||
| } | ||||
|  | ||||
| CHeroSwitcher::CHeroSwitcher(int serial) | ||||
| { | ||||
| 	pos = Rect(612, 87 + serial * 54, 48, 32)  +  pos; | ||||
| 	id = serial; | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	pos += _pos; | ||||
| 	used = LCLICK; | ||||
|  | ||||
| 	image = new CAnimImage("PortraitsSmall", hero->portrait); | ||||
| 	pos.w = image->pos.w; | ||||
| 	pos.h = image->pos.h; | ||||
| } | ||||
|  | ||||
| CHeroWindow::CHeroWindow(const CGHeroInstance *hero) | ||||
| 	:  heroWArt(this, hero) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	garr = NULL; | ||||
| 	garr = nullptr; | ||||
| 	curHero = hero; | ||||
| 	player = LOCPLINT->playerID;//hero->tempOwner; | ||||
| 	listSelection = nullptr; | ||||
|  | ||||
| 	background = new CPicture("HeroScr4.BMP"); | ||||
| 	background->colorizeAndConvert(player); | ||||
| 	background->colorize(LOCPLINT->playerID); | ||||
| 	pos = background->center(); | ||||
|  | ||||
| 	new CAnimImage("CREST58", LOCPLINT->playerID, 0, 606, 8); | ||||
|  | ||||
| 	//artifs = new CArtifactsOfHero(pos.topLeft(), true); | ||||
| 	ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660); | ||||
| @@ -116,15 +116,13 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero) | ||||
|  | ||||
| 	tacticsButton = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, 539, 483, SDLK_b); | ||||
|  | ||||
|  | ||||
| 	//right list of heroes | ||||
| 	for(int g=0; g<8; ++g) | ||||
| 		heroListMi.push_back(new CHeroSwitcher(g)); | ||||
| 	 | ||||
| 	flags = CDefHandler::giveDefEss("CREST58.DEF"); | ||||
| 	for(int i=0; i < std::min(LOCPLINT->cb->howManyHeroes(false), 8); i++) | ||||
| 		heroList.push_back(new CHeroSwitcher(Point(612, 87 + i * 54), LOCPLINT->cb->getHeroBySerial(i, false))); | ||||
|  | ||||
| 	//areas | ||||
| 	portraitArea = new LRClickableAreaWText(Rect(18, 18, 58, 64)); | ||||
| 	portraitImage = new CAnimImage("PortraitsLarge", 0, 0, 19, 19); | ||||
|  | ||||
| 	for(int v=0; v<GameConstants::PRIMARY_SKILLS; ++v) | ||||
| 	{ | ||||
| @@ -135,6 +133,8 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero) | ||||
| 		primSkillAreas.push_back(area); | ||||
| 	} | ||||
|  | ||||
| 	specImage = new CAnimImage("UN44", 0, 0, 18, 180); | ||||
|  | ||||
| 	specArea = new LRClickableAreaWText(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]); | ||||
| 	expArea = new LRClickableAreaWText(Rect(18, 228, 136, 42), CGI->generaltexth->heroscrn[9]); | ||||
| 	morale = new MoraleLuckBox(true, Rect(175,179,53,45)); | ||||
| @@ -145,33 +145,22 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero) | ||||
| 	{ | ||||
| 		Rect r = Rect(i%2 == 0  ?  18  :  162,  276 + 48 * (i/2),  136,  42); | ||||
| 		secSkillAreas.push_back(new LRClickableAreaWTextComp(r, CComponent::secskill)); | ||||
| 		secSkillImages.push_back(new CAnimImage("SECSKILL", 0, 0, r.x, r.y)); | ||||
| 	} | ||||
|  | ||||
| 	//////////////////////////////////////////////////////////////////////////??????????????? | ||||
| // 	pos.x += 65; | ||||
| // 	pos.y += 8; | ||||
| // 	 | ||||
|  | ||||
| 	//primary skills & exp and mana | ||||
| 	new CPicture(graphics->pskillsm->ourImages[0].bitmap, 32, 111, false); | ||||
| 	new CPicture(graphics->pskillsm->ourImages[1].bitmap, 102, 111, false); | ||||
| 	new CPicture(graphics->pskillsm->ourImages[2].bitmap, 172, 111, false); | ||||
| 	new CPicture(graphics->pskillsm->ourImages[5].bitmap, 242, 111, false); | ||||
| 	new CPicture(graphics->pskillsm->ourImages[4].bitmap, 20, 230, false); | ||||
| 	new CPicture(graphics->pskillsm->ourImages[3].bitmap, 162, 230, false); | ||||
| 	new CAnimImage("PSKIL42", 0, 0, 32, 111, false); | ||||
| 	new CAnimImage("PSKIL42", 1, 0, 102, 111, false); | ||||
| 	new CAnimImage("PSKIL42", 2, 0, 172, 111, false); | ||||
| 	new CAnimImage("PSKIL42", 3, 0, 162, 230, false); | ||||
| 	new CAnimImage("PSKIL42", 4, 0, 20, 230, false); | ||||
| 	new CAnimImage("PSKIL42", 5, 0, 242, 111, false); | ||||
|  | ||||
| 	update(hero); | ||||
| } | ||||
|  | ||||
| CHeroWindow::~CHeroWindow() | ||||
| { | ||||
| 	delete flags;	 | ||||
| 	//SDL_FreeSurface(curBack); | ||||
| 	//curBack = NULL; | ||||
| 	curHero = NULL; | ||||
|  | ||||
| 	//artifs->dispose(); | ||||
| } | ||||
|  | ||||
| void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= false*/) | ||||
| {	 | ||||
| 	if(!hero) //something strange... no hero? it shouldn't happen | ||||
| @@ -181,9 +170,9 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
| 	} | ||||
|  | ||||
| 	assert(hero == curHero); | ||||
| 	//assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes | ||||
| 	 | ||||
|  | ||||
| 	specArea->text = CGI->generaltexth->hTxts[curHero->subID].longBonus; | ||||
| 	specImage->setFrame(curHero->subID); | ||||
|  | ||||
| 	tacticsButton->callback.clear(); | ||||
| 	tacticsButton->callback2.clear(); | ||||
| @@ -191,6 +180,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
| 	dismissButton->hoverTexts[0] = boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->name % curHero->type->heroClass->name); | ||||
| 	portraitArea->hoverText = boost::str(boost::format(CGI->generaltexth->allTexts[15]) % curHero->name % curHero->type->heroClass->name); | ||||
| 	portraitArea->text = curHero->getBiography(); | ||||
| 	portraitImage->setFrame(curHero->portrait); | ||||
|  | ||||
| 	{ | ||||
| 		CAdventureMapButton * split = NULL; | ||||
| @@ -210,8 +200,12 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
| 			arts->setHero(curHero); | ||||
| 			artSets.push_back(arts); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 		int serial = LOCPLINT->cb->getHeroSerial(curHero, false); | ||||
| 		delChildNUll(listSelection); | ||||
| 		if (serial >= 0) | ||||
| 			listSelection = new CPicture("HPSYYY", 612, 33 + serial * 54); | ||||
| 	} | ||||
|  | ||||
| 	//primary skills support | ||||
| 	for(size_t g=0; g<primSkillAreas.size(); ++g) | ||||
| @@ -228,6 +222,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals | ||||
| 		secSkillAreas[g]->bonusValue = level; | ||||
| 		secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1]; | ||||
| 		secSkillAreas[g]->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[21]) % CGI->generaltexth->levels[level-1] % CGI->generaltexth->skillName[skill]); | ||||
| 		secSkillImages[g]->setFrame(skill*3 + level + 2); | ||||
| 	} | ||||
|  | ||||
| 	//printing experience - original format does not support ui64 | ||||
| @@ -296,8 +291,6 @@ void CHeroWindow::questlog() | ||||
| void CHeroWindow::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	CIntObject::showAll(to); | ||||
| 	//blitting portrait | ||||
| 	blitAtLoc(graphics->portraitLarge[curHero->portrait], 19, 19, to); | ||||
| 	  | ||||
| 	//printing hero's name | ||||
| 	printAtMiddleLoc(curHero->name, 190, 38, FONT_BIG, Colors::Jasmine, to); | ||||
| @@ -345,42 +338,14 @@ void CHeroWindow::showAll(SDL_Surface * to) | ||||
| 	 	printAtMiddleLoc(primarySkill.str(), 53 + 70 * m, 166, FONT_SMALL, Colors::Cornsilk, to); | ||||
| 	} | ||||
| 	  | ||||
| 	blitAtLoc(flags->ourImages[player].bitmap, 606, 8, to); | ||||
| 	  | ||||
| 	//hero list blitting | ||||
| 	  | ||||
| 	for(int slotPos=0, g=0; g<LOCPLINT->wanderingHeroes.size(); ++g) | ||||
| 	{ | ||||
| 	 	const CGHeroInstance * cur = LOCPLINT->wanderingHeroes[g]; | ||||
| 	 	if (cur->inTownGarrison) | ||||
| 	 		// Only display heroes that are not in garrison | ||||
| 	 		continue; | ||||
| 	  | ||||
| 	 	blitAtLoc(graphics->portraitSmall[cur->portrait], 611, 87+slotPos*54, to); | ||||
| 	 	//printing yellow border | ||||
| 	 	if(cur->name == curHero->name) | ||||
| 	 	{ | ||||
| 	 		for(int f=0; f<graphics->portraitSmall[cur->portrait]->w; ++f) | ||||
| 	 		{ | ||||
| 	 			for(int h=0; h<graphics->portraitSmall[cur->portrait]->h; ++h) | ||||
| 	 				if(f==0 || h==0 || f==graphics->portraitSmall[cur->portrait]->w-1 || h==graphics->portraitSmall[cur->portrait]->h-1) | ||||
| 	 					CSDL_Ext::SDL_PutPixelWithoutRefresh(to, pos.x + 611+f, pos.y + 87+slotPos*54+h, 240, 220, 120); | ||||
| 	 		} | ||||
| 	 	} | ||||
| 	  | ||||
| 	 	slotPos ++; | ||||
| 	} | ||||
| 	  | ||||
| 	//secondary skills | ||||
| 	for(size_t v=0; v<std::min(secSkillAreas.size(), curHero->secSkills.size()); ++v) | ||||
| 	{ | ||||
| 	 	blitAtLoc(graphics->abils44->ourImages[curHero->secSkills[v].first*3+3+curHero->secSkills[v].second-1].bitmap, v%2 ? 161 : 18, 276 + 48 * (v/2), to); | ||||
| 	 	printAtLoc(CGI->generaltexth->levels[curHero->secSkills[v].second-1], v%2 ? 212 : 68, 280 + 48 * (v/2), FONT_SMALL, Colors::Cornsilk, to); | ||||
| 	 	printAtLoc(CGI->generaltexth->skillName[curHero->secSkills[v].first], v%2 ? 212 : 68, 300 + 48 * (v/2), FONT_SMALL, Colors::Cornsilk, to); | ||||
| 	} | ||||
| 	  | ||||
| 	//printing special ability | ||||
| 	blitAtLoc(graphics->un44->ourImages[curHero->subID].bitmap, 18, 180, to); | ||||
| 	printAtLoc(CGI->generaltexth->jktexts[5].substr(1, CGI->generaltexth->jktexts[5].size()-2), 69, 183, FONT_SMALL, Colors::Jasmine, to); | ||||
| 	printAtLoc(CGI->generaltexth->hTxts[curHero->subID].bonusName, 69, 205, FONT_SMALL, Colors::Cornsilk, to); | ||||
| 	  | ||||
|   | ||||
| @@ -29,13 +29,12 @@ class CArtifactsOfHero; | ||||
| /// Button which switches hero selection | ||||
| class CHeroSwitcher : public CIntObject | ||||
| { | ||||
| 	const CGHeroInstance * hero; | ||||
| 	CAnimImage *image; | ||||
| public: | ||||
| 	int id; | ||||
|  | ||||
| 	CHeroWindow * getOwner(); | ||||
| 	virtual void clickLeft(tribool down, bool previousState); | ||||
|  | ||||
| 	CHeroSwitcher(int serial); | ||||
| 	CHeroSwitcher(Point pos, const CGHeroInstance * hero); | ||||
| }; | ||||
|  | ||||
| //helper class for calculating values of hero bonuses without bonuses from picked up artifact | ||||
| @@ -51,45 +50,45 @@ public: | ||||
|  | ||||
| class CHeroWindow: public CWindowWithGarrison, public CWindowWithArtifacts | ||||
| { | ||||
| 	enum ELabel {}; | ||||
| 	std::map<ELabel, CLabel*> labels; | ||||
| 	CPicture *background; | ||||
| 	CGStatusBar * ourBar; //heroWindow's statusBar | ||||
|  | ||||
| 	//general graphics | ||||
| 	CDefEssential *flags; | ||||
|  | ||||
| 	//buttons | ||||
| 	//CAdventureMapButton * gar4button; //splitting | ||||
| 	std::vector<CHeroSwitcher *> heroListMi; //new better list of heroes | ||||
| 	std::vector<CHeroSwitcher *> heroList; //list of heroes | ||||
| 	CPicture * listSelection; //selection border | ||||
|  | ||||
| 	//clickable areas | ||||
| 	LRClickableAreaWText * portraitArea; | ||||
| 	CAnimImage * portraitImage; | ||||
|  | ||||
| 	std::vector<LRClickableAreaWTextComp *> primSkillAreas; | ||||
| 	LRClickableAreaWText * expArea; | ||||
| 	LRClickableAreaWText * spellPointsArea; | ||||
| 	LRClickableAreaWText * specArea;//speciality | ||||
| 	CAnimImage *specImage; | ||||
| 	MoraleLuckBox * morale, * luck; | ||||
| 	std::vector<LRClickableAreaWTextComp *> secSkillAreas; | ||||
| 	std::vector<CAnimImage *> secSkillImages; | ||||
| 	CHeroWithMaybePickedArtifact heroWArt; | ||||
|  | ||||
| public: | ||||
| 	const CGHeroInstance * curHero; | ||||
| 	CAdventureMapButton * quitButton, * dismissButton, * questlogButton; //general | ||||
| 		 | ||||
| 	CHighlightableButton *tacticsButton; //garrison / formation handling; | ||||
| 	CHighlightableButtonsGroup *formations; | ||||
| 	int player; | ||||
|  | ||||
| public: | ||||
| 	const CGHeroInstance * curHero; | ||||
|  | ||||
| 	CHeroWindow(const CGHeroInstance *hero); //c-tor | ||||
| 	~CHeroWindow(); //d-tor | ||||
|  | ||||
| 	void update(const CGHeroInstance * hero, bool redrawNeeded = false); //sets main displayed hero | ||||
| 	void showAll(SDL_Surface * to); //shows and activates adv. map interface | ||||
| //		void redrawCurBack(); //redraws curBAck from scratch | ||||
| 		void quit(); //stops displaying hero window and disposes | ||||
| 	void showAll(SDL_Surface * to); | ||||
|  | ||||
| 	void quit(); //stops displaying hero window and disposes | ||||
| 	void dismissCurrent(); //dissmissed currently displayed hero (curHero) | ||||
| 	void questlog(); //show quest log in hero window | ||||
| 		void switchHero(); //changes displayed hero | ||||
| 	void switchHero(); //changes displayed hero | ||||
|  | ||||
| 	//friends | ||||
| 	friend void CArtPlace::clickLeft(tribool down, bool previousState); | ||||
|   | ||||
| @@ -24,11 +24,9 @@ | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| extern SDL_Surface * screen; | ||||
| //extern SDL_Surface * screen; | ||||
|  | ||||
| using namespace NMessage; | ||||
|  | ||||
| const int COMPONENT_TO_SUBTITLE = 5; | ||||
| const int COMPONENT_TO_SUBTITLE = 17; | ||||
| const int BETWEEN_COMPS_ROWS = 10; | ||||
| const int BEFORE_COMPONENTS = 30; | ||||
| const int SIDE_MARGIN = 30; | ||||
| @@ -41,14 +39,38 @@ template <typename T, typename U> std::pair<T,U> max(const std::pair<T,U> &x, co | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| namespace NMessage | ||||
| //One image component + subtitles below it | ||||
| class ComponentResolved : public CIntObject | ||||
| { | ||||
| 	std::vector<std::vector<SDL_Surface*> > * txt; | ||||
| public: | ||||
| 	CComponent *comp; | ||||
|  | ||||
| 	//blit component with image centered at this position | ||||
| 	void showAll(SDL_Surface * to); | ||||
|  | ||||
| 	//ComponentResolved(); //c-tor | ||||
| 	ComponentResolved(CComponent *Comp); //c-tor | ||||
| 	~ComponentResolved(); //d-tor | ||||
| }; | ||||
| // Full set of components for blitting on dialog box | ||||
| struct ComponentsToBlit | ||||
| { | ||||
| 	std::vector< std::vector<ComponentResolved*> > comps; | ||||
| 	int w, h; | ||||
|  | ||||
| 	void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret); | ||||
| 	ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor | ||||
| 	~ComponentsToBlit(); //d-tor | ||||
| }; | ||||
|  | ||||
| namespace | ||||
| { | ||||
| 	CDefHandler * ok, *cancel; | ||||
| 	std::vector<std::vector<SDL_Surface*> > piecesOfBox; //in colors of all players | ||||
| 	SDL_Surface * background = NULL; | ||||
| } | ||||
|  | ||||
|  | ||||
| void CMessage::init() | ||||
| { | ||||
| 	{ | ||||
| @@ -72,14 +94,13 @@ void CMessage::init() | ||||
| 			} | ||||
| 			delete bluePieces; | ||||
| 		} | ||||
| 		NMessage::background = BitmapHandler::loadBitmap("DIBOXBCK.BMP"); | ||||
| 		background = BitmapHandler::loadBitmap("DIBOXBCK.BMP"); | ||||
| 		SDL_SetColorKey(background,SDL_SRCCOLORKEY,SDL_MapRGB(background->format,0,255,255)); | ||||
| 	} | ||||
| 	ok = CDefHandler::giveDef("IOKAY.DEF"); | ||||
| 	cancel = CDefHandler::giveDef("ICANCEL.DEF"); | ||||
| } | ||||
|  | ||||
|  | ||||
| void CMessage::dispose() | ||||
| { | ||||
| 	for (int i=0;i<GameConstants::PLAYER_LIMIT;i++) | ||||
| @@ -93,7 +114,8 @@ void CMessage::dispose() | ||||
| 	delete ok; | ||||
| 	delete cancel; | ||||
| } | ||||
| SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor) //draws box for window | ||||
|  | ||||
| SDL_Surface * CMessage::drawDialogBox(int w, int h, int playerColor) | ||||
| { | ||||
| 	//prepare surface | ||||
| 	SDL_Surface * ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask); | ||||
| @@ -319,37 +341,7 @@ std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::st | ||||
| 	} //ends for(int i=0; i<brtext->size();i++) | ||||
| 	return txtg; | ||||
| } | ||||
| //CSimpleWindow * CMessage::genWindow(std::string text, int player, bool centerOnMouse, int Lmar, int Rmar, int Tmar, int Bmar) | ||||
| //{ | ||||
| // 	CSimpleWindow * ret = new CSimpleWindow(); | ||||
| // 	int fontHeight; | ||||
| // 	std::vector<std::string> brtext = breakText(text,32); | ||||
| // 	std::vector<std::vector<SDL_Surface*> > * txtg = drawText(&brtext, fontHeight); | ||||
| // 	std::pair<int,int> txts = getMaxSizes(txtg, fontHeight); | ||||
| // 	ret->bitmap = drawBox1(txts.first+Lmar+Rmar,txts.second+Tmar+Bmar,player); | ||||
| // 	ret->pos.h = ret->bitmap->h; | ||||
| // 	ret->pos.w = ret->bitmap->w; | ||||
| // 	if (centerOnMouse)  | ||||
| // 	{ | ||||
| // 		ret->pos.x = GH.current->motion.x - ret->pos.w/2; | ||||
| // 		ret->pos.y = GH.current->motion.y - ret->pos.h/2; | ||||
| // 		// Put the window back on screen if necessary | ||||
| // 		vstd::amax(ret->pos.x, 0); | ||||
| // 		vstd::amax(ret->pos.y, 0); | ||||
| // 		vstd::amin(ret->pos.x, conf.cc.resx - ret->pos.w); | ||||
| // 		vstd::amin(ret->pos.y, conf.cc.resy - ret->pos.h); | ||||
| // 	}  | ||||
| // 	else  | ||||
| // 	{ | ||||
| // 		// Center on screen | ||||
| // 		ret->pos.x = screen->w/2 - (ret->pos.w/2); | ||||
| // 		ret->pos.y = screen->h/2 - (ret->pos.h/2); | ||||
| // 	} | ||||
| // 	int curh = ret->bitmap->h/2 - (fontHeight*txtg->size())/2; | ||||
| // 	blitTextOnSur(txtg,fontHeight,curh,ret->bitmap); | ||||
| // 	delete txtg; | ||||
| // 	return ret; | ||||
| //} | ||||
|  | ||||
| SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ ) | ||||
| { | ||||
| 	int curh; | ||||
| @@ -367,7 +359,7 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_ | ||||
| 		+ 5 // to sibtitle | ||||
| 		+ (*txtg)[0][0]->h | ||||
| 		+ 30; | ||||
| 	SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player); | ||||
| 	SDL_Surface *ret = drawDialogBox(boxs.first,boxs.second,player); | ||||
| 	blitTextOnSur(txtg,fontHeight,curh,ret); | ||||
| 	curh += imgToBmp; | ||||
| 	blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret); | ||||
| @@ -380,8 +372,6 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_ | ||||
| void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) | ||||
| { | ||||
| 	SDL_Surface * _or = NULL; | ||||
| 	//const Font &f = *graphics->fonts[FONT_MEDIUM]; | ||||
| 	//int fontHeight = f.height; | ||||
|  | ||||
| 	if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components | ||||
| 		_or = FNT_RenderText(FONT_MEDIUM,CGI->generaltexth->allTexts[4],Colors::Cornsilk); | ||||
| @@ -405,7 +395,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) | ||||
|  | ||||
| 	ComponentsToBlit comps(ret->components,500,_or); | ||||
| 	if (ret->components.size()) | ||||
| 		winSize.second += 30 + comps.h; //space to first component | ||||
| 		winSize.second += 10 + comps.h; //space to first component | ||||
|  | ||||
| 	int bw = 0; | ||||
| 	if (ret->buttons.size()) | ||||
| @@ -426,12 +416,11 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) | ||||
|  | ||||
| 	vstd::amin(winSize.first, screen->w - 150); | ||||
|  | ||||
| 	ret->bitmap = drawBox1 (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player); | ||||
| 	ret->bitmap = drawDialogBox (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player); | ||||
| 	ret->pos.h=ret->bitmap->h; | ||||
| 	ret->pos.w=ret->bitmap->w; | ||||
| 	ret->center(); | ||||
|  | ||||
|  | ||||
| 	int curh = SIDE_MARGIN; | ||||
| 	int xOffset = (ret->pos.w - ret->text->pos.w)/2; | ||||
|  | ||||
| @@ -463,10 +452,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player) | ||||
| 		} | ||||
| 	} | ||||
| 	for(size_t i=0; i<ret->components.size(); i++) | ||||
| 	{ | ||||
| 		ret->components[i]->pos.x += ret->pos.x; | ||||
| 		ret->components[i]->pos.y += ret->pos.y; | ||||
| 	} | ||||
| 		ret->components[i]->moveBy(Point(ret->pos.x, ret->pos.y)); | ||||
|  | ||||
| 	if(_or) | ||||
| 		SDL_FreeSurface(_or); | ||||
| @@ -534,29 +520,43 @@ void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int | ||||
| 	CSDL_Ext::blitSurface(box[3], NULL, ret, &dstR); | ||||
| } | ||||
|  | ||||
| ComponentResolved::ComponentResolved() | ||||
| ComponentResolved::ComponentResolved( CComponent *Comp ): | ||||
| 	comp(Comp) | ||||
| { | ||||
| 	comp = NULL; | ||||
| 	img = NULL; | ||||
| 	txt = NULL; | ||||
| 	txtFontHeight = 0; | ||||
| } | ||||
| 	//Temporary assign ownership on comp | ||||
| 	if (parent) | ||||
| 		parent->removeChild(this); | ||||
| 	if (comp->parent) | ||||
| 	{ | ||||
| 		comp->parent->addChild(this); | ||||
| 		comp->parent->removeChild(comp); | ||||
| 	} | ||||
|  | ||||
| ComponentResolved::ComponentResolved( CComponent *Comp ) | ||||
| { | ||||
| 	comp = Comp; | ||||
| 	img = comp->getImg(); | ||||
| 	std::vector<std::string> brtext = CMessage::breakText(comp->subtitle,14); //text  | ||||
| 	txt = CMessage::drawText(&brtext,txtFontHeight,FONT_SMALL); | ||||
| 	addChild(comp); | ||||
| 	defActions = 255 - DISPOSE; | ||||
| 	pos.x = pos.y = 0; | ||||
|  | ||||
| 	int textHeight = 0; | ||||
| 	std::vector<std::string> textLines = CMessage::breakText(comp->subtitle, 14); //text | ||||
| 	txt = CMessage::drawText(&textLines, textHeight, FONT_SMALL); | ||||
|  | ||||
| 	//calculate dimensions | ||||
| 	std::pair<int,int> textSize = CMessage::getMaxSizes(txt, txtFontHeight); | ||||
| 	comp->pos.w = std::max(textSize.first, img->w); //bigger of: subtitle width and image width | ||||
| 	comp->pos.h = img->h + COMPONENT_TO_SUBTITLE + textSize.second; | ||||
| 	std::pair<int,int> textSize = CMessage::getMaxSizes(txt, textHeight); | ||||
| 	pos.w = std::max<int>(textSize.first, comp->pos.w); //bigger of: subtitle width and image width | ||||
|  | ||||
| 	pos.h = comp->pos.h + COMPONENT_TO_SUBTITLE + textSize.second; | ||||
|  | ||||
| 	comp->moveTo(Point((pos.w - comp->pos.w)/2, 0)); | ||||
| } | ||||
|  | ||||
| ComponentResolved::~ComponentResolved() | ||||
| { | ||||
| 	if (parent) | ||||
| 	{ | ||||
| 		removeChild(comp); | ||||
| 		parent->addChild(comp); | ||||
| 	} | ||||
|  | ||||
| 	for(size_t i = 0; i < txt->size(); i++) | ||||
| 		for(size_t j = 0; j < (*txt)[i].size(); j++) | ||||
| 			if((*txt)[i][j]) | ||||
| @@ -564,6 +564,22 @@ ComponentResolved::~ComponentResolved() | ||||
| 	delete txt; | ||||
| } | ||||
|  | ||||
| void ComponentResolved::showAll(SDL_Surface *to) | ||||
| { | ||||
| 	tlog0 << "Blitting at "<< pos.x << " " << pos.y << "\n"; | ||||
| 	int fontHeight; | ||||
| 	if (graphics->fontsTrueType[FONT_SMALL]) | ||||
| 		fontHeight = TTF_FontHeight(graphics->fontsTrueType[FONT_SMALL]); | ||||
| 	else | ||||
| 		fontHeight = graphics->fonts[FONT_SMALL]->height; | ||||
|  | ||||
| 	CIntObject::showAll(to); | ||||
| 	comp->showAll(to); | ||||
|  | ||||
| 	int textY = pos.y + comp->pos.h + COMPONENT_TO_SUBTITLE; | ||||
| 	CMessage::blitTextOnSur(txt, fontHeight, textY, to, pos.x + pos.w/2 ); | ||||
| } | ||||
|  | ||||
| ComponentsToBlit::~ComponentsToBlit() | ||||
| { | ||||
| 	for(size_t i=0; i<comps.size(); i++) | ||||
| @@ -586,12 +602,12 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, | ||||
| 	{ | ||||
| 		ComponentResolved *cur = new ComponentResolved(SComps[i]); | ||||
|  | ||||
| 		int toadd = (cur->comp->pos.w + 12 + (_or ? _or->w : 0)); | ||||
| 		int toadd = (cur->pos.w + 12 + (_or ? _or->w : 0)); | ||||
| 		if (curw + toadd > maxw) | ||||
| 		{ | ||||
| 			curr++; | ||||
| 			vstd::amax(w,curw); | ||||
| 			curw = cur->comp->pos.w; | ||||
| 			curw = cur->pos.w; | ||||
| 			comps.resize(curr+1); | ||||
| 		} | ||||
| 		else | ||||
| @@ -605,10 +621,11 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, | ||||
|  | ||||
| 	for(size_t i=0;i<comps.size();i++) | ||||
| 	{ | ||||
| 		int maxh = 0; | ||||
| 		int maxHeight = 0; | ||||
| 		for(size_t j=0;j<comps[i].size();j++) | ||||
| 			vstd::amax(maxh,comps[i][j]->comp->pos.h); | ||||
| 		h += maxh + BETWEEN_COMPS_ROWS; | ||||
| 			vstd::amax(maxHeight, comps[i][j]->pos.h); | ||||
|  | ||||
| 		h += maxHeight + BETWEEN_COMPS_ROWS; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -616,44 +633,33 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh, | ||||
| { | ||||
| 	for (size_t i=0;i<comps.size();i++)//for each row | ||||
| 	{ | ||||
| 		int totalw=0, maxh=0; | ||||
| 		int totalw=0, maxHeight=0; | ||||
| 		for(size_t j=0;j<(comps)[i].size();j++)//find max height & total width in this row | ||||
| 		{ | ||||
| 			ComponentResolved *cur = (comps)[i][j]; | ||||
| 			totalw += cur->comp->pos.w; | ||||
| 			vstd::amax(maxh,cur->comp->getImg()->h);//subtitles height will added later | ||||
| 		} | ||||
| 		if(_or) | ||||
| 		{ | ||||
| 			totalw += (inter*2+_or->w) * ((comps)[i].size() - 1); | ||||
| 		} | ||||
| 		else//add space between comps in this row | ||||
| 		{ | ||||
| 			totalw += (inter) * ((comps)[i].size() - 1); | ||||
| 			totalw += cur->pos.w; | ||||
| 			vstd::amax(maxHeight, cur->pos.h); | ||||
| 		} | ||||
|  | ||||
| 		int startHeight = curh; | ||||
| 		int middleh = curh + maxh/2;//axis for image aligment | ||||
| 		int curw = (ret->w/2)-(totalw/2); | ||||
| 		//add space between comps in this row | ||||
| 		if(_or) | ||||
| 			totalw += (inter*2+_or->w) * ((comps)[i].size() - 1); | ||||
| 		else | ||||
| 			totalw += (inter) * ((comps)[i].size() - 1); | ||||
|  | ||||
| 		int middleh = curh + maxHeight/2;//axis for image aligment | ||||
| 		int curw = ret->w/2 - totalw/2; | ||||
|  | ||||
| 		for(size_t j=0;j<(comps)[i].size();j++) | ||||
| 		{ | ||||
| 			ComponentResolved *cur = (comps)[i][j]; | ||||
| 			cur->moveTo(Point(curw, curh)); | ||||
|  | ||||
| 			//blit img | ||||
| 			int imgX = curw + ( cur->comp->pos.w - cur->comp->getImg()->w ) / 2; | ||||
| 			int imgY = startHeight; | ||||
| 			blitAt(cur->img, imgX, imgY, ret); | ||||
| 			cur->comp->pos.x = imgX; | ||||
| 			cur->comp->pos.y = imgY; | ||||
|  | ||||
| 			//blit subtitle | ||||
| 			int textX = imgX + cur->comp->getImg()->w/2; | ||||
| 			int textY = startHeight + cur->comp->getImg()->h + COMPONENT_TO_SUBTITLE; | ||||
| 			CMessage::blitTextOnSur(cur->txt, cur->txtFontHeight, textY, ret, textX ); | ||||
| 			//blit component | ||||
| 			cur->showAll(ret); | ||||
| 			curw += cur->pos.w; | ||||
|  | ||||
| 			//if there is subsequent component blit "or" | ||||
| 			curw += cur->comp->pos.w; | ||||
| 			if(j<((comps)[i].size()-1)) | ||||
| 			{ | ||||
| 				if(_or) | ||||
| @@ -664,8 +670,7 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh, | ||||
| 				} | ||||
| 				curw+=inter; | ||||
| 			} | ||||
| 			vstd::amax(curh, textY); | ||||
| 		} | ||||
| 		curh += BETWEEN_COMPS_ROWS; | ||||
| 		curh += maxHeight + BETWEEN_COMPS_ROWS; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "FontBase.h" | ||||
| #include "UIFramework/Geometries.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
| @@ -15,59 +16,39 @@ | ||||
|   | ||||
| struct SDL_Surface; | ||||
| enum EWindowType {infoOnly, infoOK, yesOrNO}; | ||||
| class CPreGame; | ||||
| class MapSel; | ||||
| class CSimpleWindow; | ||||
| class CInfoWindow; | ||||
| class CDefHandler; | ||||
| class CComponent; | ||||
| class CSelWindow; | ||||
| class CSelectableComponent; | ||||
| namespace NMessage | ||||
| { | ||||
| 	extern CDefHandler * ok, *cancel; | ||||
| 	extern std::vector<std::vector<SDL_Surface*> > piecesOfBox; //in colors of all players | ||||
| 	extern SDL_Surface * background ; | ||||
| } | ||||
|  | ||||
| struct ComponentResolved | ||||
| { | ||||
| 	CComponent *comp; | ||||
|  | ||||
| 	SDL_Surface *img; | ||||
| 	std::vector<std::vector<SDL_Surface*> > * txt; | ||||
| 	int txtFontHeight; | ||||
|  | ||||
| 	ComponentResolved(); //c-tor | ||||
| 	ComponentResolved(CComponent *Comp); //c-tor | ||||
| 	~ComponentResolved(); //d-tor | ||||
| }; | ||||
|  | ||||
| struct ComponentsToBlit | ||||
| { | ||||
| 	std::vector< std::vector<ComponentResolved*> > comps; | ||||
| 	int w, h; | ||||
|  | ||||
| 	void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret); | ||||
| 	ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor | ||||
| 	~ComponentsToBlit(); //d-tor | ||||
| }; | ||||
| class ComponentResolved; | ||||
|  | ||||
| /// Class which draws formatted text messages and generates chat windows | ||||
| class CMessage | ||||
| { | ||||
| public: | ||||
|  | ||||
| 	//Function usd only in CMessage.cpp | ||||
| 	static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight); | ||||
| 	static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext, int &fontHeigh, EFonts font = FONT_MEDIUM); | ||||
| 	static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2 | ||||
| 	static void drawIWindow(CInfoWindow * ret, std::string text, int player); | ||||
| 	static CSimpleWindow * genWindow(std::string text, int player, bool centerOnMouse=false, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins | ||||
| 	static SDL_Surface * drawBox1(int w, int h, int playerColor=1); | ||||
|  | ||||
| 	/// Draw border on exiting surface | ||||
| 	static void drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0); | ||||
| 	static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55); | ||||
|  | ||||
| 	/// Draw simple dialog box (borders and background only) | ||||
| 	static SDL_Surface * drawDialogBox(int w, int h, int playerColor=1); | ||||
|  | ||||
| 	/// Draw simple dialog box and blit bitmap with text on it | ||||
| 	static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charPerline=30, int imgToBmp=55); | ||||
|  | ||||
|  | ||||
| 	static void drawIWindow(CInfoWindow * ret, std::string text, int player); | ||||
|  | ||||
| 	/// split text in lines | ||||
| 	static std::vector<std::string> breakText(std::string text, size_t maxLineSize=30, const boost::function<int(char)> &charMetric = boost::function<int(char)>(), bool allowLeadingWhitespace = false); | ||||
| 	static std::vector<std::string> breakText(std::string text, size_t maxLineWidth, EFonts font); | ||||
|  | ||||
| 	/// constructor | ||||
| 	static void init(); | ||||
| 	/// destructor | ||||
| 	static void dispose(); | ||||
| }; | ||||
|   | ||||
| @@ -1766,7 +1766,7 @@ void InfoCard::clickRight( tribool down, bool previousState ) | ||||
|  | ||||
| void InfoCard::showTeamsPopup() | ||||
| { | ||||
| 	SDL_Surface *bmp = CMessage::drawBox1(256, 90 + 50 * SEL->current->mapHeader->howManyTeams); | ||||
| 	SDL_Surface *bmp = CMessage::drawDialogBox(256, 90 + 50 * SEL->current->mapHeader->howManyTeams); | ||||
| 	CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[657], 128, 30, FONT_MEDIUM, Colors::Jasmine, bmp); //{Team Alignments} | ||||
|  | ||||
| 	for(int i = 0; i < SEL->current->mapHeader->howManyTeams; i++) | ||||
| @@ -2390,7 +2390,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) | ||||
|  | ||||
| 	if(val == -1  ||  which == BONUS) //random or bonus box | ||||
| 	{ | ||||
| 		bmp = CMessage::drawBox1(256, 190); | ||||
| 		bmp = CMessage::drawDialogBox(256, 190); | ||||
| 		std::string *description = NULL; | ||||
|  | ||||
| 		switch(which) | ||||
| @@ -2462,7 +2462,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) | ||||
| 	} | ||||
| 	else if(which == TOWN) | ||||
| 	{ | ||||
| 		bmp = CMessage::drawBox1(256, 319); | ||||
| 		bmp = CMessage::drawDialogBox(256, 319); | ||||
| 		title = &CGI->generaltexth->allTexts[80]; | ||||
|  | ||||
| 		CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[79], 135, 137, FONT_MEDIUM, Colors::Jasmine, bmp); | ||||
| @@ -2491,7 +2491,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) | ||||
| 	else if(val >= 0) | ||||
| 	{ | ||||
| 		const CHero *h = CGI->heroh->heroes[val]; | ||||
| 		bmp = CMessage::drawBox1(320, 255); | ||||
| 		bmp = CMessage::drawDialogBox(320, 255); | ||||
| 		title = &CGI->generaltexth->allTexts[77]; | ||||
|  | ||||
| 		CSDL_Ext::printAtMiddle(*title, 167, 36, FONT_MEDIUM, Colors::Jasmine, bmp); | ||||
|   | ||||
| @@ -629,7 +629,8 @@ static si64 lod_seek(URLContext *context, si64 pos, int whence) | ||||
| 	return -1;//video->offset; | ||||
| } | ||||
|  | ||||
| static URLProtocol lod_protocol = { | ||||
| static URLProtocol lod_protocol = | ||||
| { | ||||
| 	protocol_name, | ||||
| 	lod_open, | ||||
| 	lod_read, | ||||
| @@ -653,6 +654,9 @@ CVideoPlayer::CVideoPlayer() | ||||
| 	av_register_all(); | ||||
|  | ||||
| 	// Register our protocol 'lod' so we can directly read from mmaped memory | ||||
| 	// TODO: URL protocol marked as deprecated in favor of avioContext | ||||
| 	// VCMI should to it if URL protocol will be removed from ffmpeg or | ||||
| 	// when new avioContext will be available in all distros (ETA: late 2012) | ||||
| #ifdef WITH_AV_REGISTER_PROTOCOL2 | ||||
| 	av_register_protocol2(&lod_protocol, sizeof(lod_protocol)); | ||||
| #else | ||||
| @@ -682,40 +686,39 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay) | ||||
|  | ||||
| 	data = vidh.extract(fname, length); | ||||
|  | ||||
| 	if (data) { | ||||
| 	std::string filePath; | ||||
| 	if (data) | ||||
| 	{ | ||||
| 		filePath.resize(100); | ||||
| 		// Create our URL name with the 'lod' protocol as a prefix and a | ||||
| 		// back pointer to our object. Should be 32 and 64 bits compatible. | ||||
| 		char url[100]; | ||||
| 		sprintf(url, "%s:0x%016llx", protocol_name, (unsigned long long)(uintptr_t)this); | ||||
|  | ||||
| #if LIBAVFORMAT_VERSION_MAJOR < 54 | ||||
| 		int avfopen = av_open_input_file(&format, url, NULL, 0, NULL); | ||||
| #else | ||||
| 		int avfopen = avformat_open_input(&format, url, NULL, NULL); | ||||
| #endif | ||||
| 		if (avfopen != 0) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} else { | ||||
| 		// File is not in a container | ||||
| #if LIBAVFORMAT_VERSION_MAJOR < 54 | ||||
| 		int avfopen = av_open_input_file(&format, (GameConstants::DATA_DIR + "/Data/video/" + fname).c_str(), NULL, 0, NULL); | ||||
| #else | ||||
| 		int avfopen = avformat_open_input(&format, (GameConstants::DATA_DIR + "/Data/video/" + fname).c_str(), NULL, NULL); | ||||
| #endif | ||||
| 		if (avfopen != 0) { | ||||
| 			// tlog1 << "Video file not found: " GameConstants::DATA_DIR + "/Data/video/" + fname << std::endl; | ||||
| 			return false; | ||||
| 		} | ||||
| 		sprintf(&filePath[0], "%s:0x%016llx", protocol_name, (unsigned long long)(uintptr_t)this); | ||||
| 	} | ||||
| 	else | ||||
| 		filePath = GameConstants::DATA_DIR + "/Data/video/" + fname; | ||||
|  | ||||
| #if LIBAVFORMAT_VERSION_MAJOR < 53 | ||||
| 	int avfopen = av_open_input_file(&format, filePath.c_str(), NULL, 0, NULL); | ||||
| #else | ||||
| 	int avfopen = avformat_open_input(&format, filePath.c_str(), NULL, NULL); | ||||
| #endif | ||||
|  | ||||
| 	if (avfopen != 0) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 	// Retrieve stream information | ||||
| #if LIBAVCODEC_VERSION_MAJOR < 53 | ||||
| 	if (av_find_stream_info(format) < 0) | ||||
| #else | ||||
| 	if (avformat_find_stream_info(format, NULL) < 0) | ||||
| #endif | ||||
| 		return false; | ||||
|  | ||||
| 	// Find the first video stream | ||||
| 	stream = -1; | ||||
| 	for(ui32 i=0; i<format->nb_streams; i++) { | ||||
| 	for(ui32 i=0; i<format->nb_streams; i++) | ||||
| 	{ | ||||
| #if LIBAVCODEC_VERSION_MAJOR < 53 | ||||
| 		if (format->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO) | ||||
| #else | ||||
| @@ -737,13 +740,19 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay) | ||||
| 	// Find the decoder for the video stream | ||||
| 	codec = avcodec_find_decoder(codecContext->codec_id); | ||||
|  | ||||
| 	if (codec == NULL) { | ||||
| 	if (codec == NULL) | ||||
| 	{ | ||||
| 		// Unsupported codec | ||||
| 		return false; | ||||
| 	} | ||||
|    | ||||
| 	// Open codec | ||||
| 	if (avcodec_open(codecContext, codec) <0 ) { | ||||
| #if LIBAVCODEC_VERSION_MAJOR < 53 | ||||
| 	if ( avcodec_open(codecContext, codec) < 0 ) | ||||
| #else | ||||
| 	if ( avcodec_open2(codecContext, codec, NULL) < 0 ) | ||||
| #endif | ||||
| 	{ | ||||
| 		// Could not open codec | ||||
| 		codec = NULL; | ||||
| 		return false; | ||||
| @@ -753,10 +762,13 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay) | ||||
| 	frame = avcodec_alloc_frame(); | ||||
|  | ||||
| 	// Allocate a place to put our YUV image on that screen | ||||
| 	if (useOverlay) { | ||||
| 	if (useOverlay) | ||||
| 	{ | ||||
| 		overlay = SDL_CreateYUVOverlay(codecContext->width, codecContext->height, | ||||
| 									   SDL_YV12_OVERLAY, screen); | ||||
| 	} else { | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		dest = CSDL_Ext::newSurface(codecContext->width, codecContext->height); | ||||
| 		destRect.x = destRect.y = 0; | ||||
| 		destRect.w = codecContext->width; | ||||
| @@ -767,11 +779,14 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay) | ||||
| 		return false; | ||||
|  | ||||
| 	// Convert the image into YUV format that SDL uses | ||||
| 	if (overlay) { | ||||
| 	if (overlay) | ||||
| 	{ | ||||
| 		sws = sws_getContext(codecContext->width, codecContext->height,  | ||||
| 							 codecContext->pix_fmt, codecContext->width, codecContext->height,  | ||||
| 							 PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); | ||||
| 	} else { | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
|  | ||||
| 		PixelFormat screenFormat = PIX_FMT_NONE; | ||||
| 		switch(screen->format->BytesPerPixel) | ||||
| @@ -806,22 +821,30 @@ bool CVideoPlayer::nextFrame() | ||||
| 	if (sws == NULL) | ||||
| 		return false; | ||||
|  | ||||
| 	while(!frameFinished) { | ||||
| 	while(!frameFinished) | ||||
| 	{ | ||||
|  | ||||
| 		int ret = av_read_frame(format, &packet); | ||||
| 		if (ret < 0) { | ||||
| 		if (ret < 0) | ||||
| 		{ | ||||
| 			// Error. It's probably an end of file. | ||||
| 			if (doLoop && !gotError) { | ||||
| 			if (doLoop && !gotError) | ||||
| 			{ | ||||
| 				// Rewind | ||||
| 				if (av_seek_frame(format, stream, 0, 0) < 0) | ||||
| 					break; | ||||
| 				gotError = true; | ||||
| 			} else { | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				break; | ||||
| 			} | ||||
| 		} else { | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// Is this a packet from the video stream? | ||||
| 			if (packet.stream_index == stream) { | ||||
| 			if (packet.stream_index == stream) | ||||
| 			{ | ||||
| 				// Decode video frame | ||||
| #ifdef WITH_AVCODEC_DECODE_VIDEO2 | ||||
| 				avcodec_decode_video2(codecContext, frame, &frameFinished, &packet); | ||||
| @@ -831,7 +854,8 @@ bool CVideoPlayer::nextFrame() | ||||
| #endif | ||||
|  | ||||
| 				// Did we get a video frame? | ||||
| 				if (frameFinished) { | ||||
| 				if (frameFinished) | ||||
| 				{ | ||||
| 					AVPicture pict; | ||||
|  | ||||
| 					if (overlay) { | ||||
| @@ -849,7 +873,9 @@ bool CVideoPlayer::nextFrame() | ||||
| 								  0, codecContext->height, pict.data, pict.linesize); | ||||
|  | ||||
| 						SDL_UnlockYUVOverlay(overlay); | ||||
| 					} else { | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						pict.data[0] = (ui8 *)dest->pixels; | ||||
| 						pict.linesize[0] = dest->pitch; | ||||
|  | ||||
| @@ -894,7 +920,8 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo | ||||
| 		refreshCount = refreshWait; | ||||
| 		if (nextFrame()) | ||||
| 			show(x,y,dst,update); | ||||
| 		else { | ||||
| 		else | ||||
| 		{ | ||||
| 			open(fname); | ||||
| 			nextFrame();			 | ||||
| 			 | ||||
| @@ -904,7 +931,8 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo | ||||
| 			show(x, y--, dst, update); | ||||
| 		} | ||||
| 	}  | ||||
| 	else { | ||||
| 	else | ||||
| 	{ | ||||
| 		redraw(x, y, dst, update); | ||||
| 	} | ||||
|  | ||||
| @@ -914,35 +942,45 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo | ||||
| void CVideoPlayer::close() | ||||
| { | ||||
| 	fname = "";	 | ||||
| 	if (sws) { | ||||
| 	if (sws) | ||||
| 	{ | ||||
| 		sws_freeContext(sws); | ||||
| 		sws = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (overlay) { | ||||
| 	if (overlay) | ||||
| 	{ | ||||
| 		SDL_FreeYUVOverlay(overlay); | ||||
| 		overlay = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (dest) { | ||||
| 	if (dest) | ||||
| 	{ | ||||
| 		SDL_FreeSurface(dest); | ||||
| 		dest = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (frame) { | ||||
| 	if (frame) | ||||
| 	{ | ||||
| 		av_free(frame); | ||||
| 		frame = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (codec) { | ||||
| 	if (codec) | ||||
| 	{ | ||||
| 		avcodec_close(codecContext); | ||||
| 		codec = NULL; | ||||
| 		codecContext = NULL; | ||||
| 	} | ||||
|  | ||||
| 	if (format) { | ||||
| 	if (format) | ||||
| 	{ | ||||
| #if LIBAVCODEC_VERSION_MAJOR < 53 | ||||
| 		av_close_input_file(format); | ||||
| 		format = NULL; | ||||
| #else | ||||
| 		avformat_close_input(&format); | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -956,7 +994,8 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey) | ||||
| 	pos.x = x; | ||||
| 	pos.y = y; | ||||
|  | ||||
| 	while(nextFrame()) { | ||||
| 	while(nextFrame()) | ||||
| 	{ | ||||
| 		 | ||||
| 		if(stopOnKey && keyDown()) | ||||
| 			return false; | ||||
|   | ||||
| @@ -674,106 +674,18 @@ void CInfoPopup::init(int x, int y) | ||||
| 	vstd::amin(pos.y, screen->h - bitmap->h); | ||||
| } | ||||
|  | ||||
| void CComponent::init(Etype Type, int Subtype, int Val) | ||||
| CComponent::CComponent(Etype Type, int Subtype, int Val): | ||||
| 	image(nullptr) | ||||
| { | ||||
| 	std::ostringstream oss; | ||||
| 	switch (Type) | ||||
| 	{ | ||||
| 	case artifact: | ||||
| 		description = CGI->arth->artifacts[Subtype]->Description(); | ||||
| 		subtitle = CGI->arth->artifacts[Subtype]->Name(); | ||||
| 		break; | ||||
| 	case primskill: | ||||
| 		oss << std::showpos << Val << " "; | ||||
| 		if(Subtype < 4) | ||||
| 		{ | ||||
| 			description = CGI->generaltexth->arraytxt[2+Subtype]; | ||||
| 			oss << CGI->generaltexth->primarySkillNames[Subtype]; | ||||
| 		} | ||||
| 		else if(Subtype == 5) //spell points | ||||
| 		{ | ||||
| 			description = CGI->generaltexth->allTexts[149]; | ||||
| 			oss <<  CGI->generaltexth->allTexts[387]; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			tlog1 << "Wrong subtype=" << Subtype << std::endl; | ||||
| 		} | ||||
| 		subtitle = oss.str(); | ||||
| 		break; | ||||
| 	case building: | ||||
| 		description = CGI->buildh->buildings[Subtype][Val]->Description(); | ||||
| 		subtitle = CGI->buildh->buildings[Subtype][Val]->Name(); | ||||
| 		break; | ||||
| 	case secskill44: case secskill: | ||||
| 		subtitle += CGI->generaltexth->levels[Val-1] + " " + CGI->generaltexth->skillName[Subtype]; | ||||
| 		description = CGI->generaltexth->skillInfoTexts[Subtype][Val-1]; | ||||
| 		break; | ||||
| 	case morale: | ||||
| 		description = CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)]; | ||||
| 		break; | ||||
| 	case luck: | ||||
| 		description = CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)]; | ||||
| 		break; | ||||
| 	case resource: | ||||
| 		description = CGI->generaltexth->allTexts[242]; | ||||
| 		oss << Val; | ||||
| 		subtitle = oss.str(); | ||||
| 		break; | ||||
| 	case spell: | ||||
| 		description = CGI->spellh->spells[Subtype]->descriptions[Val]; | ||||
| 		subtitle = CGI->spellh->spells[Subtype]->name; | ||||
| 		break; | ||||
| 	case creature: | ||||
| 		subtitle = (Val? boost::lexical_cast<std::string>(Val) + " " : "") + CGI->creh->creatures[Subtype]->*(Val != 1 ? &CCreature::namePl : &CCreature::nameSing); | ||||
| 		break; | ||||
| 	case experience: | ||||
| 		description = CGI->generaltexth->allTexts[241]; | ||||
| 		oss << Val ; | ||||
| 		if(Subtype && Val==1) | ||||
| 		{ | ||||
| 			subtitle = CGI->generaltexth->allTexts[442]; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			subtitle = oss.str(); | ||||
| 		} | ||||
| 		break; | ||||
| 	case hero: | ||||
| 		subtitle = description = CGI->heroh->heroes[Subtype]->name; | ||||
| 		break; | ||||
| 	case flag: | ||||
| 		subtitle = CGI->generaltexth->capColors[Subtype]; | ||||
| 		break; | ||||
| 	} | ||||
| 	type = Type; | ||||
| 	subtype = Subtype; | ||||
| 	val = Val; | ||||
| 	if(!img) | ||||
| 	{ | ||||
| 		free = false; | ||||
| 		if(type == CComponent::building) | ||||
| 			setSurface(graphics->buildingPics[subtype],val); | ||||
| 	} | ||||
| 	SDL_Surface * temp = this->getImg(); | ||||
| 	if(!temp) | ||||
| 	{ | ||||
| 		tlog1 << "Error: cannot find graphic for component with id=" << type << " subid=" << subtype << " val=" << val << std::endl; | ||||
| 		return; | ||||
| 	} | ||||
| 	pos.w = temp->w; | ||||
| 	pos.h = temp->h; | ||||
| } | ||||
| CComponent::CComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur, bool freeSur) | ||||
| { | ||||
| 	img = sur; | ||||
| 	free = freeSur; | ||||
| 	used |= RCLICK; | ||||
| 	init(Type,Subtype,Val); | ||||
| } | ||||
|  | ||||
| CComponent::CComponent(const Component &c) | ||||
| CComponent::CComponent(const Component &c): | ||||
| 	image(nullptr) | ||||
| { | ||||
| 	img = NULL; | ||||
| 	used |= RCLICK; | ||||
|  | ||||
| 	if(c.id == Component::EXPERIENCE) | ||||
| 		init(experience,c.subtype,c.val); | ||||
| 	else if(c.id == Component::SPELL) | ||||
| @@ -785,84 +697,143 @@ CComponent::CComponent(const Component &c) | ||||
| 		subtitle += CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2); | ||||
| } | ||||
|  | ||||
| CComponent::CComponent() | ||||
| CComponent::CComponent(): | ||||
| 	image(nullptr) | ||||
| { | ||||
| 	img = NULL; | ||||
| 	used |= RCLICK; | ||||
| } | ||||
|  | ||||
| CComponent::~CComponent() | ||||
| void CComponent::init(Etype Type, int Subtype, int Val) | ||||
| { | ||||
| 	if (free && img) | ||||
| 		SDL_FreeSurface(img); | ||||
| } | ||||
|  | ||||
| SDL_Surface * CComponent::setSurface(std:: string defname, int imagepos) | ||||
| { | ||||
| 	if (img) | ||||
| 		tlog1<<"CComponent::setSurface: Warning - surface is already set!\n"; | ||||
| 	CDefEssential * def = CDefHandler::giveDefEss(defname); | ||||
|  | ||||
| 	free = true; | ||||
| 	img = def->ourImages[imagepos].bitmap; | ||||
| 	img->refcount++;//to preserve surface whed def is deleted | ||||
| 	delete def; | ||||
| 	return img; | ||||
| 	type = Type; | ||||
| 	subtype = Subtype; | ||||
| 	val = Val; | ||||
|  | ||||
| 	subtitle = getSubtitle(); | ||||
| 	description = getDescription(); | ||||
| 	setSurface(getFileName(), getIndex()); | ||||
|  | ||||
| 	pos.w = image->pos.w; | ||||
| 	pos.h = image->pos.h; | ||||
| } | ||||
|  | ||||
| //NOTE: whole method can be removed after 0.89+1 release | ||||
| void CComponent::show(SDL_Surface * to) | ||||
| { | ||||
| 	blitAt(getImg(),pos.x,pos.y,to); | ||||
| 	//In some places components position set manually instead of moveBy - it should be fixed | ||||
| 	if (pos.x != image->pos.x | ||||
| 	 || pos.y != image->pos.y) | ||||
| 	{ | ||||
| 		tlog0 << "Error: Component position may be broken. Please report\n"; | ||||
| 		image->moveTo(pos.topLeft()); | ||||
| 		CIntObject::showAll(to); | ||||
| 	} | ||||
| 	else | ||||
| 		CIntObject::show(to); | ||||
| } | ||||
|  | ||||
| SDL_Surface * CComponent::getImg() const | ||||
| std::string CComponent::getFileName() | ||||
| { | ||||
| 	switch(type) | ||||
| 	{ | ||||
| 	case primskill:  return "PSKILL"; | ||||
| 	case secskill:   return "SECSK82"; | ||||
| 	case resource:   return "RESOUR82"; | ||||
| 	case creature:   return "TWCRPORT"; | ||||
| 	case artifact:   return "ARTIFACT"; | ||||
| 	case experience: return "PSKILL"; | ||||
| 	case secskill44: return "SECSKILL"; | ||||
| 	case spell:      return "SPELLSCR"; | ||||
| 	case morale:     return "IMRL82"; | ||||
| 	case luck:       return "ILCK82"; | ||||
| 	case building:   return graphics->buildingPics[subtype]; | ||||
| 	case hero:       return "PortraitsLarge"; | ||||
| 	case flag:       return "TWCRPORT"; | ||||
| 	} | ||||
| 	assert(0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| size_t CComponent::getIndex() | ||||
| { | ||||
| 	switch(type) | ||||
| 	{ | ||||
| 	case primskill:  return subtype; | ||||
| 	case secskill:   return subtype*3 + 3 + val - 1; | ||||
| 	case resource:   return subtype; | ||||
| 	case creature:   return subtype+2; | ||||
| 	case artifact:   return subtype; | ||||
| 	case experience: return 4; | ||||
| 	case secskill44: return subtype*3 + 3 + val - 1; | ||||
| 	case spell:      return subtype; | ||||
| 	case morale:     return val+3; | ||||
| 	case luck:       return val+3; | ||||
| 	case building:   return val; | ||||
| 	case hero:       return subtype; | ||||
| 	case flag:       return subtype; | ||||
| 	} | ||||
| 	assert(0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| std::string CComponent::getDescription() | ||||
| { | ||||
| 	if (img) | ||||
| 		return img; | ||||
| 	switch (type) | ||||
| 	{ | ||||
| 	case artifact: | ||||
| 		return graphics->artDefs->ourImages[subtype].bitmap; | ||||
| 	case primskill: | ||||
| 		return graphics->pskillsb->ourImages[subtype].bitmap; | ||||
| 	case secskill44: | ||||
| 		return graphics->abils44->ourImages[subtype*3 + 3 + val - 1].bitmap; | ||||
| 	case secskill: | ||||
| 		return graphics->abils82->ourImages[subtype*3 + 3 + val - 1].bitmap; | ||||
| 	case resource: | ||||
| 		return graphics->resources->ourImages[subtype].bitmap; | ||||
| 	case experience: | ||||
| 		return graphics->pskillsb->ourImages[4].bitmap; | ||||
| 	case morale: | ||||
| 		return graphics->morale82->ourImages[val+3].bitmap; | ||||
| 	case luck: | ||||
| 		return graphics->luck82->ourImages[val+3].bitmap; | ||||
| 	case spell: | ||||
| 		return graphics->spellscr->ourImages[subtype].bitmap; | ||||
| 	case building: | ||||
| 		assert(0); //img should have been set | ||||
| 		//return setSurface(graphics->buildingPics[subtype],val); | ||||
| 	case creature: | ||||
| 		return graphics->bigImgs[subtype]; | ||||
| 	case hero: | ||||
| 		return graphics->portraitLarge[subtype]; | ||||
| 	case flag: | ||||
| 		return graphics->flags->ourImages[subtype].bitmap; | ||||
| 	case primskill:  return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill | ||||
| 	                                     : CGI->generaltexth->allTexts[149]; //mana | ||||
| 	case secskill:   return CGI->generaltexth->skillInfoTexts[subtype][val-1]; | ||||
| 	case resource:   return CGI->generaltexth->allTexts[242]; | ||||
| 	case creature:   return ""; | ||||
| 	case artifact:   return  CGI->arth->artifacts[subtype]->Description(); | ||||
| 	case experience: return CGI->generaltexth->allTexts[241]; | ||||
| 	case secskill44: return CGI->generaltexth->skillInfoTexts[subtype][val-1]; | ||||
| 	case spell:      return CGI->spellh->spells[subtype]->descriptions[val]; | ||||
| 	case morale:     return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)]; | ||||
| 	case luck:       return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)]; | ||||
| 	case building:   return CGI->buildh->buildings[subtype][val]->Description(); | ||||
| 	case hero:       return CGI->heroh->heroes[subtype]->name; | ||||
| 	case flag:       return ""; | ||||
| 	} | ||||
| 	return NULL; | ||||
| 	assert(0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| std::string CComponent::getSubtitle() | ||||
| { | ||||
| 	//FIXME: some of these are horrible (e.g creature) | ||||
| 	switch(type) | ||||
| 	{ | ||||
| 	case primskill:  return boost::str(boost::format("%+d %s") % val % (subtype < 4 ? CGI->generaltexth->primarySkillNames[subtype] : CGI->generaltexth->allTexts[387])); | ||||
| 	case secskill:   return CGI->generaltexth->levels[val-1] + " " + CGI->generaltexth->skillName[subtype]; | ||||
| 	case resource:   return boost::lexical_cast<std::string>(val); | ||||
| 	case creature:   return (val? boost::lexical_cast<std::string>(val) + " " : "") + CGI->creh->creatures[subtype]->*(val != 1 ? &CCreature::namePl : &CCreature::nameSing); | ||||
| 	case artifact:   return CGI->arth->artifacts[subtype]->Name(); | ||||
| 	case experience: return (subtype && val==1) ? CGI->generaltexth->allTexts[442] : boost::lexical_cast<std::string>(val); | ||||
| 	case secskill44: return CGI->generaltexth->levels[val-1] + " " + CGI->generaltexth->skillName[subtype]; | ||||
| 	case spell:      return CGI->spellh->spells[subtype]->name; | ||||
| 	case morale:     return ""; | ||||
| 	case luck:       return ""; | ||||
| 	case building:   return CGI->buildh->buildings[subtype][val]->Name(); | ||||
| 	case hero:       return CGI->heroh->heroes[subtype]->name; | ||||
| 	case flag:       return CGI->generaltexth->capColors[subtype]; | ||||
| 	} | ||||
| 	assert(0); | ||||
| 	return ""; | ||||
| } | ||||
|  | ||||
| void CComponent::setSurface(std::string defName, int imgPos) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	delChildNUll(image); | ||||
| 	image = new CAnimImage(defName, imgPos); | ||||
| } | ||||
|  | ||||
| void CComponent::clickRight(tribool down, bool previousState) | ||||
| { | ||||
| 	if(description.size()) | ||||
| 		adventureInt->handleRightClick(description,down); | ||||
| } | ||||
| void CComponent::activate() | ||||
| { | ||||
| 	activateRClick(); | ||||
| } | ||||
| void CComponent::deactivate() | ||||
| { | ||||
| 	deactivateRClick(); | ||||
| } | ||||
|  | ||||
| void CSelectableComponent::clickLeft(tribool down, bool previousState) | ||||
| { | ||||
| @@ -872,35 +843,30 @@ void CSelectableComponent::clickLeft(tribool down, bool previousState) | ||||
| 			onSelect(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CSelectableComponent::init() | ||||
| { | ||||
| 	selected = false; | ||||
| } | ||||
| CSelectableComponent::CSelectableComponent(const Component &c, boost::function<void()> OnSelect) | ||||
| :CComponent(c),onSelect(OnSelect) | ||||
|  | ||||
| CSelectableComponent::CSelectableComponent(const Component &c, boost::function<void()> OnSelect): | ||||
| 	CComponent(c),onSelect(OnSelect) | ||||
| { | ||||
| 	used |= LCLICK | KEYBOARD; | ||||
| 	init(); | ||||
| } | ||||
| CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect) | ||||
| :CComponent(Type,Sub,Val),onSelect(OnSelect) | ||||
|  | ||||
| CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect): | ||||
| 	CComponent(Type,Sub,Val),onSelect(OnSelect) | ||||
| { | ||||
| 	used |= LCLICK | KEYBOARD; | ||||
| 	init(); | ||||
| } | ||||
|  | ||||
| CSelectableComponent::~CSelectableComponent() | ||||
| { | ||||
| } | ||||
| void CSelectableComponent::activate() | ||||
| { | ||||
| 	activateKeys(); | ||||
| 	CComponent::activate(); | ||||
| 	activateLClick(); | ||||
| } | ||||
| void CSelectableComponent::deactivate() | ||||
| { | ||||
| 	deactivateKeys(); | ||||
| 	CComponent::deactivate(); | ||||
| 	deactivateLClick(); | ||||
| } | ||||
|  | ||||
| void CSelectableComponent::select(bool on) | ||||
| { | ||||
| 	if(on != selected) | ||||
| @@ -913,12 +879,13 @@ void CSelectableComponent::select(bool on) | ||||
| 		return; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CSelectableComponent::show(SDL_Surface * to) | ||||
| { | ||||
| 	blitAt(getImg(),pos.x,pos.y,to); | ||||
| 	CComponent::show(to); | ||||
| 	if(selected) | ||||
| 	{ | ||||
| 		CSDL_Ext::drawBorder(to, Rect::around(Rect(pos.x, pos.y, getImg()->w, getImg()->h)), int3(239,215,123)); | ||||
| 		CSDL_Ext::drawBorder(to, Rect::around(Rect(pos.x, pos.y, image->pos.w, image->pos.h)), int3(239,215,123)); | ||||
| 	} | ||||
|  | ||||
| 	printAtMiddleWB(subtitle,pos.x+pos.w/2,pos.y+pos.h+25,FONT_SMALL,12,Colors::Cornsilk,to); | ||||
| @@ -932,9 +899,10 @@ void CSelWindow::selectionChange(unsigned to) | ||||
| 		if (!pom) | ||||
| 			continue; | ||||
| 		pom->select(i==to); | ||||
| 		blitAt(pom->getImg(),pom->pos.x-pos.x,pom->pos.y-pos.y,bitmap); | ||||
| 	} | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
| CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| @@ -965,9 +933,6 @@ CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, con | ||||
| 			comps[i]->assignedKeys.insert(SDLK_1+i); | ||||
| 	} | ||||
| 	CMessage::drawIWindow(this, Text, player); | ||||
|  | ||||
| 	BOOST_FOREACH(CComponent *c, components) | ||||
| 		c->subtitle = "";//workaround - erase subtitles since they were hard-blitted by function drawing window | ||||
| } | ||||
|  | ||||
| void CSelWindow::madeChoice() | ||||
| @@ -1971,8 +1936,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u | ||||
|  | ||||
| 	for(int i=0;i<comps.size();i++) | ||||
| 	{ | ||||
| 		comps[i]->pos.x = curx+pos.x; | ||||
| 		comps[i]->pos.y = 326+pos.y; | ||||
| 		comps[i]->moveTo(Point(pos.x + curx, pos.y + 326)); | ||||
| 		if( i < (comps.size()-1) ) | ||||
| 		{ | ||||
| 			curx += 44+21; //skill width + margin to "or" | ||||
| @@ -2021,7 +1985,10 @@ void CLevelWindow::show(SDL_Surface * to) | ||||
| 	blitAt(graphics->portraitLarge[heroPortrait],170+pos.x,66+pos.y,to); | ||||
| 	ok->showAll(to); | ||||
| 	for(int i=0;i<comps.size();i++) | ||||
| 	{ | ||||
| 		comps[i]->showAll(to); | ||||
| 		comps[i]->show(to); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CMinorResDataBar::show(SDL_Surface * to) | ||||
| @@ -5552,17 +5519,16 @@ void CPuzzleWindow::show(SDL_Surface * to) | ||||
|  | ||||
| void CTransformerWindow::CItem::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	SDL_Surface * backgr = graphics->bigImgs[parent->army->getCreature(id)->idNumber]; | ||||
| 	blitAt(backgr, pos.x, pos.y, to); | ||||
| 	CIntObject::showAll(to); | ||||
| 	printAtMiddle(boost::lexical_cast<std::string>(size),pos.x+28, pos.y+76,FONT_SMALL,Colors::Cornsilk,to);//stack size | ||||
| } | ||||
|  | ||||
| void CTransformerWindow::CItem::move() | ||||
| { | ||||
| 	if (left) | ||||
| 		pos.x += 289; | ||||
| 		moveBy(Point(289, 0)); | ||||
| 	else | ||||
| 		pos.x -= 289; | ||||
| 		moveBy(Point(-289, 0)); | ||||
| 	left = !left; | ||||
| } | ||||
|  | ||||
| @@ -5578,6 +5544,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState) | ||||
| CTransformerWindow::CItem::CItem(CTransformerWindow * _parent, int _size, int _id): | ||||
| 	id(_id), size(_size), parent(_parent) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	used = LCLICK; | ||||
| 	left = true; | ||||
| 	pos.w = 58; | ||||
| @@ -5585,6 +5552,7 @@ CTransformerWindow::CItem::CItem(CTransformerWindow * _parent, int _size, int _i | ||||
|  | ||||
| 	pos.x += 45  + (id%3)*83 + id/6*83; | ||||
| 	pos.y += 109 + (id/3)*98; | ||||
| 	icon = new CAnimImage("TWCRPORT", parent->army->getCreature(id)->idNumber); | ||||
| } | ||||
|  | ||||
| CTransformerWindow::CItem::~CItem() | ||||
| @@ -5713,11 +5681,13 @@ void CUniversityWindow::CItem::showAll(SDL_Surface * to) | ||||
| 	printAtMiddleLoc  (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, Colors::Cornsilk,to);//Name | ||||
| 	printAtMiddleLoc  (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, Colors::Cornsilk,to);//Level(always basic) | ||||
|  | ||||
| 	CPicture::showAll(to); | ||||
| 	CIntObject::showAll(to); | ||||
| } | ||||
|  | ||||
| CUniversityWindow::CItem::CItem(CUniversityWindow * _parent, int _ID, int X, int Y): | ||||
| 	CPicture (graphics->abils44->ourImages[_ID*3+3].bitmap,X,Y,false),ID(_ID), parent(_parent) | ||||
| 	CAnimImage ("SECSKILL", ID*3+3, 0, X, Y), | ||||
| 	ID(_ID), | ||||
| 	parent(_parent) | ||||
| { | ||||
| 	used = LCLICK | RCLICK | HOVER; | ||||
| } | ||||
| @@ -6194,6 +6164,7 @@ CThievesGuildWindow::~CThievesGuildWindow() | ||||
|  | ||||
| void MoraleLuckBox::set(const IBonusBearer *node) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL; | ||||
| 	const int textId[] = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:} | ||||
| 	const int noneTxtId = 108; //Russian version uses same text for neutral morale\luck | ||||
| 	const int neutralDescr[] = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat. | ||||
| @@ -6205,7 +6176,6 @@ void MoraleLuckBox::set(const IBonusBearer *node) | ||||
| 	int mrlt = -9; | ||||
| 	TModDescr mrl; | ||||
|  | ||||
|  | ||||
| 	if (node) | ||||
| 	{ | ||||
| 		node->getModifiersWDescr(mrl, bonusType[morale]); | ||||
| @@ -6233,23 +6203,21 @@ void MoraleLuckBox::set(const IBonusBearer *node) | ||||
| 				text += "\n" + mrl[it].second; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MoraleLuckBox::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	CDefEssential *def; | ||||
| 	 | ||||
| 	std::string imageName; | ||||
| 	if (small) | ||||
| 		def = morale ? graphics->morale30 : graphics->luck30; | ||||
| 		imageName = morale ? "IMRL30": "ILCK30"; | ||||
| 	else | ||||
| 		def = morale ? graphics->morale42 : graphics->luck42; | ||||
| 	SDL_Surface *img = def->ourImages[bonusValue + 3].bitmap; | ||||
|  | ||||
| 	blitAt(img, Rect(img).centerIn(pos), to); //put img in the center of our pos | ||||
| 		imageName = morale ? "IMRL42" : "ILCK42"; | ||||
| 	delChildNUll(image); | ||||
| 	image = new CAnimImage(imageName, bonusValue + 3); | ||||
| 	image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon | ||||
| } | ||||
|  | ||||
| MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small) | ||||
| 	:morale(Morale), | ||||
| 	 small(Small) | ||||
| MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small): | ||||
| 	image(NULL), | ||||
| 	morale(Morale), | ||||
| 	small(Small) | ||||
| { | ||||
| 	bonusValue = 0; | ||||
| 	pos = r + pos; | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| #pragma once | ||||
|  | ||||
|  | ||||
| #include "CAnimation.h" | ||||
| #include "FunctionList.h" | ||||
| #include "../lib/ResourceSet.h" | ||||
| #include "../lib/GameConstants.h" | ||||
| @@ -161,6 +161,15 @@ public: | ||||
| /// common popup window component | ||||
| class CComponent : public virtual CIntObject | ||||
| { | ||||
| 	size_t getIndex(); | ||||
| 	std::string getFileName(); | ||||
| 	std::string getDescription(); | ||||
| 	std::string getSubtitle(); | ||||
|  | ||||
| protected: | ||||
| 	CAnimImage *image; //our image | ||||
| 	void setSurface(std::string defName, int imgPos); | ||||
|  | ||||
| public: | ||||
| 	enum Etype | ||||
| 	{ | ||||
| @@ -172,22 +181,14 @@ public: | ||||
| 	std::string description; //r-click | ||||
| 	std::string subtitle; //TODO: comment me | ||||
|  | ||||
| 	SDL_Surface *img; //our image | ||||
| 	bool free; //should surface be freed on delete | ||||
|  | ||||
| 	SDL_Surface * setSurface(std::string defName, int imgPos); | ||||
|  | ||||
| 	void init(Etype Type, int Subtype, int Val); | ||||
| 	CComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur=NULL, bool freeSur=false); //c-tor | ||||
| 	virtual void init(Etype Type, int Subtype, int Val); | ||||
| 	CComponent(Etype Type, int Subtype, int Val); //c-tor | ||||
| 	CComponent(const Component &c); //c-tor | ||||
| 	CComponent();; //c-tor | ||||
| 	virtual ~CComponent(); //d-tor | ||||
| 	CComponent(); //c-tor | ||||
|  | ||||
| 	void clickRight(tribool down, bool previousState); //call-in | ||||
| 	SDL_Surface * getImg() const; | ||||
| 	virtual void show(SDL_Surface * to); | ||||
| 	virtual void activate(); | ||||
| 	virtual void deactivate(); | ||||
|  | ||||
| 	void show(SDL_Surface * to); | ||||
| }; | ||||
|  | ||||
| class CSelectableComponent : public CComponent, public CKeyShortcut | ||||
| @@ -202,8 +203,6 @@ public: | ||||
| 	CSelectableComponent(const Component &c, boost::function<void()> OnSelect = 0); //c-tor | ||||
| 	~CSelectableComponent(); //d-tor | ||||
| 	virtual void show(SDL_Surface * to); | ||||
| 	void activate(); | ||||
| 	void deactivate(); | ||||
| 	void select(bool on); | ||||
| }; | ||||
|  | ||||
| @@ -777,12 +776,12 @@ public: | ||||
|  | ||||
| class MoraleLuckBox : public LRClickableAreaWTextComp | ||||
| { | ||||
| 	CAnimImage *image; | ||||
| public: | ||||
| 	bool morale; //true if morale, false if luck | ||||
| 	bool small; | ||||
|  | ||||
| 	void set(const IBonusBearer *node); | ||||
| 	void showAll(SDL_Surface * to); | ||||
|  | ||||
| 	MoraleLuckBox(bool Morale, const Rect &r, bool Small=false); | ||||
| 	~MoraleLuckBox(); | ||||
| @@ -1022,6 +1021,7 @@ public: | ||||
| 		bool left;//position of the item | ||||
| 		int size; //size of creature stack | ||||
| 		CTransformerWindow * parent; | ||||
| 		CAnimImage *icon; | ||||
|  | ||||
| 		void move(); | ||||
| 		void showAll(SDL_Surface * to); | ||||
| @@ -1047,7 +1047,7 @@ public: | ||||
|  | ||||
| class CUniversityWindow : public CIntObject | ||||
| { | ||||
| 	class CItem : public CPicture | ||||
| 	class CItem : public CAnimImage | ||||
| 	{ | ||||
| 	public: | ||||
| 		int ID;//id of selected skill | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| //  faction: its faction (0 to 8) | ||||
|  | ||||
| // The following properties are optional: | ||||
| //  upgrade:            number of the creature to upgrade to | ||||
| //  upgrades:           id of the creatures to upgrade to | ||||
| //  projectile_defname: if the creature is a shooter, graphics for the projectile | ||||
| //  projectile_spin:    if the creature is a shooter, indicate whether the projectile spins | ||||
| //  turret_shooter:     indicates whether the shooter appears in the castle turrets | ||||
| @@ -23,7 +23,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Pikeman" ], | ||||
| 				"faction": 0, | ||||
| 				"upgrade": 1, | ||||
| 				"upgrades": [1], | ||||
| 				"ability_add": [ [ "CHARGE_IMMUNITY", 0, 0, 0 ] ], 		//pikeman immunity to Champion charge bonus | ||||
| 				"defname": "CPKMAN.DEF" | ||||
| 			}, | ||||
| @@ -42,7 +42,7 @@ | ||||
| 				"level": 2, | ||||
| 				"name": [ "Archer", "LightCrossbowman" ], | ||||
| 				"faction": 0, | ||||
| 				"upgrade": 3, | ||||
| 				"upgrades": [3], | ||||
| 				"defname": "CLCBOW.DEF", | ||||
| 				"projectile_defname": "PLCBOWX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -65,7 +65,7 @@ | ||||
| 				"name": [ "Griffin" ], | ||||
| 				"faction": 0, | ||||
| 				"ability_add": [ [ "ADDITIONAL_RETALIATION", 1, 0, 0 ] ], 	//griffins retaliate twice | ||||
| 				"upgrade": 5, | ||||
| 				"upgrades": [5], | ||||
| 				"defname": "CGRIFF.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -83,7 +83,7 @@ | ||||
| 				"level": 4, | ||||
| 				"name": [ "Swordsman" ], | ||||
| 				"faction": 0, | ||||
| 				"upgrade": 7, | ||||
| 				"upgrades": [7], | ||||
| 				"defname": "CSWORD.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -100,7 +100,7 @@ | ||||
| 				"level": 5, | ||||
| 				"name": [ "Monk" ], | ||||
| 				"faction": 0, | ||||
| 				"upgrade": 9, | ||||
| 				"upgrades": [9], | ||||
| 				"defname": "CMONKK.DEF", | ||||
| 				"projectile_defname": "CPRZEAX.DEF", | ||||
| 				"projectile_spin": false | ||||
| @@ -121,7 +121,7 @@ | ||||
| 				"level": 6, | ||||
| 				"name": [ "Cavalier" ], | ||||
| 				"faction": 0, | ||||
| 				"upgrade": 11, | ||||
| 				"upgrades": [11], | ||||
| 				"defname": "CCAVLR.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -140,7 +140,7 @@ | ||||
| 				"faction": 0, | ||||
| 				"ability_add": [ [ "HATE", 50, 55, 0 ],					//angels hate archdevils | ||||
| 							   	 [ "HATE", 50, 54, 0 ] ],			   	 	//angels hate devils | ||||
| 				"upgrade": 13, | ||||
| 				"upgrades": [13], | ||||
| 				"defname": "CANGEL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -162,7 +162,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Centaur" ], | ||||
| 				"faction": 1, | ||||
| 				"upgrade": 15, | ||||
| 				"upgrades": [15], | ||||
| 				"defname": "CCENTR.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -180,7 +180,7 @@ | ||||
| 				"name": [ "Dwarf" ], | ||||
| 				"faction": 1, | ||||
| 				"ability_add": [ [ "MAGIC_RESISTANCE", 20, 0, 0 ] ], 		//dwarf's magic resistance 20% | ||||
| 				"upgrade": 17, | ||||
| 				"upgrades": [17], | ||||
| 				"defname": "CDWARF.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -198,7 +198,7 @@ | ||||
| 				"level": 3, | ||||
| 				"name": [ "WoodElf" ], | ||||
| 				"faction": 1, | ||||
| 				"upgrade": 19, | ||||
| 				"upgrades": [19], | ||||
| 				"defname": "CELF.DEF", | ||||
| 				"projectile_defname": "PELFX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -221,7 +221,7 @@ | ||||
| 				"name": [ "Pegasus" ], | ||||
| 				"faction": 1, | ||||
| 				"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ENEMY", 2, 0, 0 ] ],	//pegasus makes spell cost higher for enemy mage | ||||
| 				"upgrade": 21, | ||||
| 				"upgrades": [21], | ||||
| 				"defname": "CPEGAS.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -240,7 +240,7 @@ | ||||
| 				"name": [ "Treefolk" ], | ||||
| 				"faction": 1, | ||||
| 				"ability_add": [ [ "SPELL_AFTER_ATTACK", 100, 72, 0 ] ],   //dendroids cast bind | ||||
| 				"upgrade": 23, | ||||
| 				"upgrades": [23], | ||||
| 				"defname": "CTREE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -260,7 +260,7 @@ | ||||
| 				"faction": 1, | ||||
| 				"ability_add": [ [ "SPELL_RESISTANCE_AURA", 0, 55, 0 ],	//unicorn | ||||
| 							   	 [ "SPELL_AFTER_ATTACK", 20, 62, 0 ] ],	//unicorns cast blind with 20% probability | ||||
| 				"upgrade": 25, | ||||
| 				"upgrades": [25], | ||||
| 				"defname": "CUNICO.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -282,7 +282,7 @@ | ||||
| 				"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ],			//green dragon is a dragon | ||||
| 							   	 [ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ],  	//green dragon's breath | ||||
| 				 				 [ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ], 	//green dragon's spell immunity | ||||
| 				"upgrade": 27, | ||||
| 				"upgrades": [27], | ||||
| 				"defname": "CGDRAG.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -302,7 +302,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "ApprenticeGremlin" ], | ||||
| 				"faction": 2, | ||||
| 				"upgrade": 29, | ||||
| 				"upgrades": [29], | ||||
| 				"defname": "CGREMA.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -322,7 +322,7 @@ | ||||
| 				"name": [ "StoneGargoyle" ], | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ],  	  		//stone gargoyles are non-living | ||||
| 				"upgrade": 31, | ||||
| 				"upgrades": [31], | ||||
| 				"defname": "CGARGO.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -342,7 +342,7 @@ | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "SPELL_DAMAGE_REDUCTION", 50, -1, 0 ],		//stone golems reduce dmg from spells | ||||
| 							   [ "NON_LIVING", 0, 0, 0 ] ],  			//stone golems are non-living | ||||
| 				"upgrade": 33, | ||||
| 				"upgrades": [33], | ||||
| 				"defname": "CSGOLE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -362,7 +362,7 @@ | ||||
| 				"name": [ "Mage" ], | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ] ],   	//mages reduce spell cost | ||||
| 				"upgrade": 35, | ||||
| 				"upgrades": [35], | ||||
| 				"defname": "CMAGE.DEF", | ||||
| 				"projectile_defname": "PMAGEX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -374,7 +374,7 @@ | ||||
| 				"level": 4, | ||||
| 				"name": [ "ArchMage" ], | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]],		//archmages reduce spell cost			   | ||||
| 				"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]],		//archmages reduce spell cost | ||||
| 				"defname": "CAMAGE.DEF", | ||||
| 				"projectile_defname": "PMAGEX.DEF", | ||||
| 				"projectile_spin": false | ||||
| @@ -387,7 +387,7 @@ | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "HATE", 50, 53, 0 ],				  	//master genies hate efreets | ||||
| 							   [ "HATE", 50, 52, 0 ] ],				  	//genies hate efreet sultans | ||||
| 				"upgrade": 37, | ||||
| 				"upgrades": [37], | ||||
| 				"defname": "CGENIE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -410,7 +410,7 @@ | ||||
| 				"name": [ "NagaSentinel" ], | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ],		//nagas block retaliation | ||||
| 				"upgrade": 39, | ||||
| 				"upgrades": [39], | ||||
| 				"defname": "CNAGA.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -429,7 +429,7 @@ | ||||
| 				"name": [ "LesserTitan" ], | ||||
| 				"faction": 2, | ||||
| 				"ability_add": [ ["MIND_IMMUNITY", 0, 0, 0] ],			//giants are immune to mind spells | ||||
| 				"upgrade": 41, | ||||
| 				"upgrades": [41], | ||||
| 				"defname": "CLTITA.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -450,7 +450,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Imp" ], | ||||
| 				"faction": 3, | ||||
| 				"upgrade": 43, | ||||
| 				"upgrades": [43], | ||||
| 				"defname": "CIMP.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -468,7 +468,7 @@ | ||||
| 				"level": 2, | ||||
| 				"name": [ "Gog" ], | ||||
| 				"faction": 3, | ||||
| 				"upgrade": 45, | ||||
| 				"upgrades": [45], | ||||
| 				"defname": "CGOG.DEF", | ||||
| 				"projectile_defname": "CPRGOGX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -491,7 +491,7 @@ | ||||
| 				"level": 3, | ||||
| 				"name": [ "HellHound" ], | ||||
| 				"faction": 3, | ||||
| 				"upgrade": 47, | ||||
| 				"upgrades": [47], | ||||
| 				"ability_remove": [ "FLYING" ], | ||||
| 				"defname": "CHHOUN.DEF" | ||||
| 			}, | ||||
| @@ -512,7 +512,7 @@ | ||||
| 				"level": 4, | ||||
| 				"name": [ "Single-HornedDemon" ], | ||||
| 				"faction": 3, | ||||
| 				"upgrade": 49, | ||||
| 				"upgrades": [49], | ||||
| 				"defname": "COHDEM.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -529,7 +529,7 @@ | ||||
| 				"level": 5, | ||||
| 				"name": [ "PitFiend" ], | ||||
| 				"faction": 3, | ||||
| 				"upgrade": 51, | ||||
| 				"upgrades": [51], | ||||
| 				"defname": "CPFIEN.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -538,7 +538,7 @@ | ||||
| 				"level": 5, | ||||
| 				"name": [ "PitFoe" ], | ||||
| 				"faction": 3, | ||||
| 				"ability_add": [ [ "DAEMON_SUMMONING", 50, 48, 0 ],  | ||||
| 				"ability_add": [ [ "DAEMON_SUMMONING", 50, 48, 0 ], | ||||
| 								[ "CASTS", 1, 0, 0] ],		//pit lord | ||||
| 				"defname": "CPFOE.DEF" | ||||
| 			}, | ||||
| @@ -552,7 +552,7 @@ | ||||
| 							   	 [ "HATE", 50, 36, 0 ], | ||||
| 								 [ "FLYING", 0, 0, 0 ],  					//efreeti hate master genies | ||||
| 								 [ "FIRE_IMMUNITY", 0, 0, 0 ] ], 			//efreeti hate genies | ||||
| 				"upgrade": 53, | ||||
| 				"upgrades": [53], | ||||
| 				"defname": "CEFREE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -578,7 +578,7 @@ | ||||
| 							   	 [ "HATE", 50, 12, 0 ], | ||||
| 								 [ "ENEMY_LUCK_DECREASING", 1, 0, 0 ],	//devils				//devils hate archangles | ||||
| 								 [ "BLOCKS_RETALIATION", 0, 0, 0 ] ], 	 	//devils			//devils hate angels | ||||
| 				"upgrade": 55, | ||||
| 				"upgrades": [55], | ||||
| 				"defname": "CDEVIL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -599,7 +599,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Skeleton" ], | ||||
| 				"faction": 4, | ||||
| 				"upgrade": 57, | ||||
| 				"upgrades": [57], | ||||
| 				"defname": "CSKELE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -616,7 +616,7 @@ | ||||
| 				"level": 2, | ||||
| 				"name": [ "Zombie" ], | ||||
| 				"faction": 4, | ||||
| 				"upgrade": 59, | ||||
| 				"upgrades": [59], | ||||
| 				"defname": "CZOMBI.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -634,7 +634,7 @@ | ||||
| 				"name": [ "Wight" ], | ||||
| 				"faction": 4, | ||||
| 				"ability_add": [ [ "FULL_HP_REGENERATION", 0, 1, 0 ] ],			//wight | ||||
| 				"upgrade": 61, | ||||
| 				"upgrades": [61], | ||||
| 				"defname": "CWIGHT.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -654,7 +654,7 @@ | ||||
| 				"name": [ "Vampire" ], | ||||
| 				"faction": 4, | ||||
| 				"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ],		//vampires		//vampire lords | ||||
| 				"upgrade": 63, | ||||
| 				"upgrades": [63], | ||||
| 				"defname": "CVAMP.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -674,7 +674,7 @@ | ||||
| 				"name": [ "Lich" ], | ||||
| 				"faction": 4, | ||||
| 				"ability_add": [ [ "SPELL_LIKE_ATTACK", 0, 76, 0 ] ],		//liches | ||||
| 				"upgrade": 65, | ||||
| 				"upgrades": [65], | ||||
| 				"defname": "CLICH.DEF", | ||||
| 				"projectile_defname": "PLICH.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -698,7 +698,7 @@ | ||||
| 				"name": [ "BlackKnight" ], | ||||
| 				"faction": 4, | ||||
| 				"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 42, 0 ] ], 	//black knights | ||||
| 				"upgrade": 67, | ||||
| 				"upgrades": [67], | ||||
| 				"defname": "CBKNIG.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -718,7 +718,7 @@ | ||||
| 				"name": [ "BoneDragon" ], | ||||
| 				"faction": 4, | ||||
| 				"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ] ],			//bone dragon is a dragon | ||||
| 				"upgrade": 69, | ||||
| 				"upgrades": [69], | ||||
| 				"defname": "CNDRGN.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -738,7 +738,7 @@ | ||||
| 				"name": [ "Troglodyte" ], | ||||
| 				"faction": 5, | ||||
| 				"ability_add": [ [ "SPELL_IMMUNITY", 0, 62, 0 ] ],	  	   	//troglodytes are immune to blind | ||||
| 				"upgrade": 71, | ||||
| 				"upgrades": [71], | ||||
| 				"defname": "CTROGL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -757,7 +757,7 @@ | ||||
| 				"name": [ "Harpy" ], | ||||
| 				"faction": 5, | ||||
| 				"ability_add": [ [ "RETURN_AFTER_STRIKE", 0, 0, 0 ] ],	   	//Harpies return after attack | ||||
| 				"upgrade": 73, | ||||
| 				"upgrades": [73], | ||||
| 				"defname": "CHARPY.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -776,7 +776,7 @@ | ||||
| 				"level": 3, | ||||
| 				"name": [ "Beholder" ], | ||||
| 				"faction": 5, | ||||
| 				"upgrade": 75, | ||||
| 				"upgrades": [75], | ||||
| 				"defname": "CBEHOL.DEF", | ||||
| 				"projectile_defname": "SMBALX.DEF", | ||||
| 				"projectile_spin": false | ||||
| @@ -785,7 +785,7 @@ | ||||
| 			{ | ||||
| 				"id": 75, | ||||
| 				"level": 3, | ||||
| 				"name": [ "EvilEye", "M75" ],  | ||||
| 				"name": [ "EvilEye", "M75" ], | ||||
| 				"faction": 5, | ||||
| 				"defname": "CEVEYE.DEF", | ||||
| 				"projectile_defname": "SMBALX.DEF", | ||||
| @@ -798,7 +798,7 @@ | ||||
| 				"name": [ "Medusa", "Medusae" ], | ||||
| 				"faction": 5, | ||||
| 				"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 70, 2000 ] ],  	//medusas			//minotaurs | ||||
| 				"upgrade": 77, | ||||
| 				"upgrades": [77], | ||||
| 				"defname": "CMEDUS.DEF", | ||||
| 				"projectile_defname": "PMEDUSX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -822,7 +822,7 @@ | ||||
| 				"name": [ "Minotaur" ], | ||||
| 				"faction": 5, | ||||
| 				"ability_add": [ [ "SELF_MORALE", 0, 0, 0 ] ], | ||||
| 				"upgrade": 79, | ||||
| 				"upgrades": [79], | ||||
| 				"defname": "CMINOT.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -840,7 +840,7 @@ | ||||
| 				"level": 6, | ||||
| 				"name": [ "Manticore" ], | ||||
| 				"faction": 5, | ||||
| 				"upgrade": 81, | ||||
| 				"upgrades": [81], | ||||
| 				"defname": "CMCORE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -861,7 +861,7 @@ | ||||
| 				"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ],			//red dragon is a dragon | ||||
| 							   	 [ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ],  	//Red Dragon has breath attack | ||||
| 								 [ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ],   	//red dragon's spell immunity | ||||
| 				"upgrade": 83, | ||||
| 				"upgrades": [83], | ||||
| 				"defname": "CRDRGN.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -883,7 +883,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Goblin" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 85, | ||||
| 				"upgrades": [85], | ||||
| 				"defname": "CGOBLI.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -900,7 +900,7 @@ | ||||
| 				"level": 2, | ||||
| 				"name": [ "GoblinWolfRider" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 87, | ||||
| 				"upgrades": [87], | ||||
| 				"defname": "CBWLFR.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -918,7 +918,7 @@ | ||||
| 				"level": 3, | ||||
| 				"name": [ "Orc" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 89, | ||||
| 				"upgrades": [89], | ||||
| 				"defname": "CORC.DEF", | ||||
| 				"projectile_defname": "PORCHX.DEF", | ||||
| 				"projectile_spin": true, | ||||
| @@ -940,7 +940,7 @@ | ||||
| 				"level": 4, | ||||
| 				"name": [ "Ogre" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 91, | ||||
| 				"upgrades": [91], | ||||
| 				"defname": "COGRE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -960,7 +960,7 @@ | ||||
| 				"level": 5, | ||||
| 				"name": [ "Roc" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 93, | ||||
| 				"upgrades": [93], | ||||
| 				"defname": "CROC.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -979,7 +979,7 @@ | ||||
| 				"level": 6, | ||||
| 				"name": [ "Cyclops" ], | ||||
| 				"faction": 6, | ||||
| 				"upgrade": 95, | ||||
| 				"upgrades": [95], | ||||
| 				"defname": "CCYCLR.DEF", | ||||
| 				"projectile_defname": "PCYCLBX.DEF", | ||||
| 				"projectile_spin": true | ||||
| @@ -1001,7 +1001,7 @@ | ||||
| 				"name": [ "YoungBehemoth" ], | ||||
| 				"faction": 6, | ||||
| 				"ability_add": [ [ "ENEMY_DEFENCE_REDUCTION", 40, 0, 0 ] ],		//behemots | ||||
| 				"upgrade": 97, | ||||
| 				"upgrades": [97], | ||||
| 				"defname": "CYBEHE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1019,7 +1019,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Gnoll" ], | ||||
| 				"faction": 7, | ||||
| 				"upgrade": 99, | ||||
| 				"upgrades": [99], | ||||
| 				"defname": "CGNOLL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1036,7 +1036,7 @@ | ||||
| 				"level": 2, | ||||
| 				"name": [ "PrimitiveLizardman" ], | ||||
| 				"faction": 7, | ||||
| 				"upgrade": 101, | ||||
| 				"upgrades": [101], | ||||
| 				"defname": "CPLIZA.DEF", | ||||
| 				"projectile_defname": "PPLIZAX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -1058,7 +1058,7 @@ | ||||
| 				"level": 5, | ||||
| 				"name": [ "CopperGorgon" ], | ||||
| 				"faction": 7, | ||||
| 				"upgrade": 103, | ||||
| 				"upgrades": [103], | ||||
| 				"defname": "CCGORG.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1077,7 +1077,7 @@ | ||||
| 				"name": [ "Dragonflies", "DragonFly", "SerpentFly" ], | ||||
| 				"faction": 7, | ||||
| 				"ability_add": [ [ "SPELL_AFTER_ATTACK", 100, 78, 0 ] ],  	//serpent fly | ||||
| 				"upgrade": 105, | ||||
| 				"upgrades": [105], | ||||
| 				"defname": "CDRFLY.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1097,7 +1097,7 @@ | ||||
| 				"name": [ "Basilisk" ], | ||||
| 				"faction": 7, | ||||
| 				"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 70, 0 ] ],   	//basilisks | ||||
| 				"upgrade": 107, | ||||
| 				"upgrades": [107], | ||||
| 				"defname": "CBASIL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1115,7 +1115,7 @@ | ||||
| 				"level": 6, | ||||
| 				"name": [ "Wyvern" ], | ||||
| 				"faction": 7, | ||||
| 				"upgrade": 109, | ||||
| 				"upgrades": [109], | ||||
| 				"defname": "CWYVER.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1135,7 +1135,7 @@ | ||||
| 				"faction": 7, | ||||
| 				"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ], 	   	//hydras | ||||
| 							   [ "ATTACKS_ALL_ADJACENT", 0, 0, 0 ] ],   	//hydras | ||||
| 				"upgrade": 111, | ||||
| 				"upgrades": [111], | ||||
| 				"defname": "CHYDRA.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1162,7 +1162,7 @@ | ||||
| 							   [ "NON_LIVING", 0, 0, 0 ], | ||||
| 							   [ "MORE_DAMAGE_FROM_SPELL", 100, 19, 0 ],		//air elementals are vulnerable to chain lightning | ||||
| 							   [ "MORE_DAMAGE_FROM_SPELL", 100, 17, 0 ] ],	  	//air elementals are vulnerable to lightning bolt		//air elementals are non-living | ||||
| 				"upgrade": 127, | ||||
| 				"upgrades": [127], | ||||
| 				"defname": "CAELEM.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1179,7 +1179,7 @@ | ||||
| 								 [ "SPELL_IMMUNITY", 0, 17, 0 ],			//earth elementals are immune to lightning bolt | ||||
| 								 [ "NON_LIVING", 0, 0, 0 ], | ||||
| 								 [ "MORE_DAMAGE_FROM_SPELL", 100, 23, 0 ] ],		//earth elementals are vulnerable to meteor shower | ||||
| 				"upgrade": 125, | ||||
| 				"upgrades": [125], | ||||
| 				"defname": "CEELEM.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1196,7 +1196,7 @@ | ||||
| 							   [ "MORE_DAMAGE_FROM_SPELL", 100, 20, 0 ],		//fire elementals are vulnerable to frost ring | ||||
| 							   [ "MORE_DAMAGE_FROM_SPELL", 100, 16, 0 ],		//fire elementals are vulnerable to ice bolt | ||||
| 							   [ "FIRE_IMMUNITY", 0, 0, 0 ] ],			//fire elementals are immune to fire spells | ||||
| 				"upgrade": 129, | ||||
| 				"upgrades": [129], | ||||
| 				"defname": "CFELEM.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1217,7 +1217,7 @@ | ||||
| 								 [ "MORE_DAMAGE_FROM_SPELL", 100, 21, 0 ],		//water elementals are vulnerable to fireball | ||||
| 								 [ "MORE_DAMAGE_FROM_SPELL", 100, 13, 0 ],		//water elementals are vulnerable to fire wall | ||||
| 								 [ "DOUBLE_WIDE", 0, 0, 0 ] ], | ||||
| 				"upgrade": 123, | ||||
| 				"upgrades": [123], | ||||
| 				"defname": "CWELEM.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1246,7 +1246,7 @@ | ||||
| 				"level": 1, | ||||
| 				"name": [ "Pixie", "Pixies" ], | ||||
| 				"faction": 8, | ||||
| 				"upgrade": 119, | ||||
| 				"upgrades": [119], | ||||
| 				"defname": "CPIXIE.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1265,7 +1265,7 @@ | ||||
| 				"faction": 8, | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ],				//magic elementals shouldn't get morale | ||||
| 				"ability_remove": [ "DOUBLE_WIDE" ], | ||||
| 				"upgrade": 121, | ||||
| 				"upgrades": [121], | ||||
| 				"defname": "CPSYEL.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1285,11 +1285,11 @@ | ||||
| 				"level": 3, | ||||
| 				"name": [ "IceElemental" ], | ||||
| 				"faction": 8, | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],				 | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ], | ||||
| 							   	 [ "DOUBLE_WIDE", 0, 0, 0 ],					//ice elemental should be treated as double-wide | ||||
| 								 [ "CREATURE_ENCHANT_POWER", 6, 0, 0 ], | ||||
| 								 [ "CASTS", 3, 0, 0 ], | ||||
| 								 [ "SPELLCASTER", 2, 32, 0 ]], 				 | ||||
| 								 [ "SPELLCASTER", 2, 32, 0 ]], | ||||
| 				"defname": "CICEE.DEF", | ||||
| 				"projectile_defname": "PICEE.DEF", | ||||
| 				"projectile_spin": false | ||||
| @@ -1315,7 +1315,7 @@ | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],						//storm elementals shouldn't get morale | ||||
| 								[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ], | ||||
| 								[ "CASTS", 3, 0, 0 ], | ||||
| 								[ "SPELLCASTER", 2, 30, 0 ]],				 | ||||
| 								[ "SPELLCASTER", 2, 30, 0 ]], | ||||
| 				"defname": "CSTORM.DEF", | ||||
| 				"projectile_defname": "CPRGTIX.DEF", | ||||
| 				"projectile_spin": false, | ||||
| @@ -1326,11 +1326,11 @@ | ||||
| 				"id": 129, | ||||
| 				"level": 4, | ||||
| 				"name": [ "ElectricityElemental" ], | ||||
| 				"faction": 8,									 | ||||
| 				"faction": 8, | ||||
| 				"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ,					//energy elementals shouldn't get morale //Crystal Dragons do not fly | ||||
| 								[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ], | ||||
| 								[ "CASTS", 3, 0, 0 ], | ||||
| 								[ "SPELLCASTER", 2, 31, 0 ]],						 | ||||
| 								[ "SPELLCASTER", 2, 31, 0 ]], | ||||
| 				"defname": "CNRG.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1339,7 +1339,7 @@ | ||||
| 				"level": 7, | ||||
| 				"name": [ "Firebird" ], | ||||
| 				"faction": 8, | ||||
| 				"upgrade": 131, | ||||
| 				"upgrades": [131], | ||||
| 				"defname": "CFBIRD.DEF" | ||||
| 			}, | ||||
|  | ||||
| @@ -1426,7 +1426,7 @@ | ||||
| 				"level": 4, | ||||
| 				"name": [ "Sharpshooter" ], | ||||
| 				"faction": -1, | ||||
| 				"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],			 | ||||
| 				"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ], | ||||
| 							   	 [ "NO_DISTANCE_PENALTY", 0, 0, 0 ] ],			//Sharpshooter | ||||
| 				"defname": "CSHARP.DEF", | ||||
| 				"projectile_defname": "PELFX.DEF", | ||||
| @@ -1982,7 +1982,7 @@ | ||||
| 			} | ||||
| 		], | ||||
|  | ||||
| 	// something hacking	 | ||||
| 	// something hacking | ||||
| 	"unused_creatures": [ 122, 124, 126, 128, 145, 146, 147, 148, 149, 160, | ||||
| 						  161, 162, 163, 174, 175, 176, 177, 178, 179, 180, | ||||
| 						  181, 182, 183, 184, 185, 186, 187, 188, 189, 190, | ||||
|   | ||||
| @@ -437,9 +437,10 @@ void CCreatureHandler::loadCreatures() | ||||
| 		c->faction = creature["faction"].Float(); | ||||
| 		c->animDefName = creature["defname"].String(); | ||||
|  | ||||
| 		value = &creature["upgrade"]; | ||||
| 		if (!value->isNull()) | ||||
| 			c->upgrades.insert(value->Float()); | ||||
| 		BOOST_FOREACH(const JsonNode &value, creature["upgrades"].Vector()) | ||||
| 		{ | ||||
| 			c->upgrades.insert(value.Float()); | ||||
| 		} | ||||
|  | ||||
| 		value = &creature["projectile_defname"]; | ||||
| 		if (!value->isNull()) | ||||
| @@ -472,7 +473,8 @@ void CCreatureHandler::loadCreatures() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	BOOST_FOREACH(const JsonNode &creature, config["unused_creatures"].Vector()) { | ||||
| 	BOOST_FOREACH(const JsonNode &creature, config["unused_creatures"].Vector()) | ||||
| 	{ | ||||
| 		notUsedMonsters += creature.Float(); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -1148,13 +1148,21 @@ int CPlayerSpecificInfoCallback::getMyColor() const | ||||
| 	return player; | ||||
| } | ||||
|  | ||||
| int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero) const | ||||
| int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const | ||||
| { | ||||
| 	//boost::shared_lock<boost::shared_mutex> lock(*gs->mx); | ||||
| 	for (size_t i=0; i<gs->players[player].heroes.size();i++) | ||||
| 	if (hero->inTownGarrison && !includeGarrisoned) | ||||
| 		return -1; | ||||
|  | ||||
| 	size_t index = 0; | ||||
| 	auto & heroes = gs->players[player].heroes; | ||||
|  | ||||
| 	for (auto curHero= heroes.begin(); curHero!=heroes.end(); curHero++) | ||||
| 	{ | ||||
| 		if (gs->players[player].heroes[i]==hero) | ||||
| 			return i; | ||||
| 		if (includeGarrisoned || !(*curHero)->inTownGarrison) | ||||
| 			index++; | ||||
|  | ||||
| 		if (*curHero == hero) | ||||
| 			return index; | ||||
| 	} | ||||
| 	return -1; | ||||
| } | ||||
|   | ||||
| @@ -226,7 +226,7 @@ public: | ||||
| 	int getMyColor() const; | ||||
|  | ||||
| 	std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible | ||||
| 	int getHeroSerial(const CGHeroInstance * hero)const; | ||||
| 	int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const; | ||||
| 	const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns) | ||||
| 	const CGHeroInstance* getHeroBySerial(int serialId, bool includeGarrisoned=true) const; // serial id is [0, number of heroes) | ||||
| 	std::vector <const CGHeroInstance *> getHeroesInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible | ||||
|   | ||||
		Reference in New Issue
	
	Block a user