mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Next step of code refactoring:
- refactoring of CBattleFieldController code (except for 2 arcane methods) - introduced class CCanvas for encapsulated rendering surface - battleint rendering is now partially done with CCanvas - removed unused includes of CBitmapHandler
This commit is contained in:
		| @@ -2,13 +2,13 @@ set(client_SRCS | ||||
| 		StdInc.cpp | ||||
| 		../CCallback.cpp | ||||
|  | ||||
| 		battle/CBattleActionsController.cpp | ||||
| 		battle/CBattleAnimations.cpp | ||||
| 		battle/CBattleControlPanel.cpp | ||||
| 		battle/CBattleInterfaceClasses.cpp | ||||
| 		battle/CBattleInterface.cpp | ||||
| 		battle/CBattleActionsController.cpp | ||||
| 		battle/CBattleEffectsController.cpp | ||||
| 		battle/CBattleFieldController.cpp | ||||
| 		battle/CBattleInterfaceClasses.cpp | ||||
| 		battle/CBattleInterface.cpp | ||||
| 		battle/CBattleObstacleController.cpp | ||||
| 		battle/CBattleProjectileController.cpp | ||||
| 		battle/CBattleSiegeController.cpp | ||||
| @@ -16,6 +16,7 @@ set(client_SRCS | ||||
| 		battle/CCreatureAnimation.cpp | ||||
|  | ||||
| 		gui/CAnimation.cpp | ||||
| 		gui/CCanvas.cpp | ||||
| 		gui/CCursorHandler.cpp | ||||
| 		gui/CGuiHandler.cpp | ||||
| 		gui/CIntObject.cpp | ||||
| @@ -83,13 +84,13 @@ set(client_SRCS | ||||
| set(client_HEADERS | ||||
| 		StdInc.h | ||||
|  | ||||
| 		battle/CBattleActionsController.h | ||||
| 		battle/CBattleAnimations.h | ||||
| 		battle/CBattleControlPanel.h | ||||
| 		battle/CBattleEffectsController.h | ||||
| 		battle/CBattleFieldController.h | ||||
| 		battle/CBattleInterfaceClasses.h | ||||
| 		battle/CBattleInterface.h | ||||
| 		battle/CBattleActionsController.h | ||||
| 		battle/CBattleFieldController.h | ||||
| 		battle/CBattleObstacleController.h | ||||
| 		battle/CBattleProjectileController.h | ||||
| 		battle/CBattleSiegeController.h | ||||
| @@ -97,6 +98,7 @@ set(client_HEADERS | ||||
| 		battle/CCreatureAnimation.h | ||||
|  | ||||
| 		gui/CAnimation.h | ||||
| 		gui/CCanvas.h | ||||
| 		gui/CCursorHandler.h | ||||
| 		gui/CGuiHandler.h | ||||
| 		gui/CIntObject.h | ||||
|   | ||||
| @@ -29,7 +29,6 @@ | ||||
| #include "../lib/VCMI_Lib.h" | ||||
| #include "../CCallback.h" | ||||
| #include "../lib/CGeneralTextHandler.h" | ||||
| #include "CBitmapHandler.h" | ||||
| #include "../lib/CGameState.h" | ||||
| #include "../lib/JsonNode.h" | ||||
| #include "../lib/vcmi_endian.h" | ||||
|   | ||||
| @@ -16,7 +16,6 @@ | ||||
| #include "../widgets/Buttons.h" | ||||
| #include "../widgets/Images.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../../lib/CGeneralTextHandler.h" | ||||
| #include "../../lib/mapObjects/CGHeroInstance.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
| @@ -18,7 +18,6 @@ class CBattleConsole; | ||||
|  | ||||
| class CBattleControlPanel : public CIntObject | ||||
| { | ||||
|  | ||||
| 	CBattleInterface * owner; | ||||
|  | ||||
| 	std::shared_ptr<CPicture> menu; | ||||
| @@ -39,8 +38,6 @@ class CBattleControlPanel : public CIntObject | ||||
| 	void bOptionsf(); | ||||
| 	void bSurrenderf(); | ||||
| 	void bFleef(); | ||||
| 	void reallyFlee(); //performs fleeing without asking player | ||||
| 	void reallySurrender(); //performs surrendering without asking player | ||||
| 	void bAutofightf(); | ||||
| 	void bSpellf(); | ||||
| 	void bWaitf(); | ||||
| @@ -50,6 +47,9 @@ class CBattleControlPanel : public CIntObject | ||||
| 	void bTacticNextStack(); | ||||
| 	void bTacticPhaseEnd(); | ||||
|  | ||||
| 	void reallyFlee(); //performs fleeing without asking player | ||||
| 	void reallySurrender(); //performs surrendering without asking player | ||||
|  | ||||
| public: | ||||
| 	std::shared_ptr<CBattleConsole> console; | ||||
|  | ||||
|   | ||||
| @@ -15,10 +15,10 @@ | ||||
| #include "CBattleSiegeController.h" | ||||
| #include "CBattleStacksController.h" | ||||
| #include "CBattleObstacleController.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../../CCallback.h" | ||||
| #include "../gui/SDL_Extensions.h" | ||||
| #include "../gui/CAnimation.h" | ||||
| #include "../gui/CCanvas.h" | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../gui/CCursorHandler.h" | ||||
| @@ -29,8 +29,6 @@ | ||||
|  | ||||
| CBattleFieldController::CBattleFieldController(CBattleInterface * owner): | ||||
| 	owner(owner), | ||||
| 	previouslyHoveredHex(-1), | ||||
| 	currentlyHoveredHex(-1), | ||||
| 	attackingHex(-1) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | ||||
| @@ -38,58 +36,31 @@ CBattleFieldController::CBattleFieldController(CBattleInterface * owner): | ||||
| 	pos.h = owner->pos.h; | ||||
|  | ||||
| 	//preparing cells and hexes | ||||
| 	cellBorder = BitmapHandler::loadBitmap("CCELLGRD.BMP"); | ||||
| 	CSDL_Ext::alphaTransform(cellBorder); | ||||
| 	cellShade = BitmapHandler::loadBitmap("CCELLSHD.BMP"); | ||||
| 	CSDL_Ext::alphaTransform(cellShade); | ||||
|  | ||||
| 	cellBorder = IImage::createFromFile("CCELLGRD.BMP"); | ||||
| 	cellShade = IImage::createFromFile("CCELLSHD.BMP"); | ||||
|  | ||||
| 	if(!owner->siegeController) | ||||
| 	{ | ||||
| 		auto bfieldType = owner->curInt->cb->battleGetBattlefieldType(); | ||||
|  | ||||
| 		if(bfieldType == BattleField::NONE) | ||||
| 		{ | ||||
| 			logGlobal->error("Invalid battlefield returned for current battle"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			background = BitmapHandler::loadBitmap(bfieldType.getInfo()->graphics, false); | ||||
| 		} | ||||
| 			background = IImage::createFromFile(bfieldType.getInfo()->graphics); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		std::string backgroundName = owner->siegeController->getBattleBackgroundName(); | ||||
| 		background = BitmapHandler::loadBitmap(backgroundName, false); | ||||
| 		background = IImage::createFromFile(backgroundName); | ||||
| 	} | ||||
|  | ||||
| 	//preparing graphic with cell borders | ||||
| 	cellBorders = CSDL_Ext::newSurface(background->w, background->h, cellBorder); | ||||
| 	//copying palette | ||||
| 	for (int g=0; g<cellBorder->format->palette->ncolors; ++g) //we assume that cellBorders->format->palette->ncolors == 256 | ||||
| 	{ | ||||
| 		cellBorders->format->palette->colors[g] = cellBorder->format->palette->colors[g]; | ||||
| 	} | ||||
| 	//palette copied | ||||
| 	for (int i=0; i<GameConstants::BFIELD_HEIGHT; ++i) //rows | ||||
| 	{ | ||||
| 		for (int j=0; j<GameConstants::BFIELD_WIDTH-2; ++j) //columns | ||||
| 		{ | ||||
| 			int x = 58 + (i%2==0 ? 22 : 0) + 44*j; | ||||
| 			int y = 86 + 42 *i; | ||||
| 			for (int cellX = 0; cellX < cellBorder->w; ++cellX) | ||||
| 			{ | ||||
| 				for (int cellY = 0; cellY < cellBorder->h; ++cellY) | ||||
| 				{ | ||||
| 					if (y+cellY < cellBorders->h && x+cellX < cellBorders->w) | ||||
| 						* ((Uint8*)cellBorders->pixels + (y+cellY) *cellBorders->pitch + (x+cellX)) |= *((Uint8*)cellBorder->pixels + cellY *cellBorder->pitch + cellX); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	cellBorders = std::make_shared<CCanvas>(Point(background->width(), background->height())); | ||||
|  | ||||
| 	backgroundWithHexes = CSDL_Ext::newSurface(background->w, background->h, screen); | ||||
| 	for (int i=0; i<GameConstants::BFIELD_SIZE; ++i) | ||||
| 		cellBorders->draw(cellBorder, hexPositionLocal(i).topLeft()); | ||||
|  | ||||
| 	backgroundWithHexes = std::make_shared<CCanvas>(Point(background->width(), background->height())); | ||||
|  | ||||
| 	for (int h = 0; h < GameConstants::BFIELD_SIZE; ++h) | ||||
| 	{ | ||||
| @@ -99,38 +70,25 @@ CBattleFieldController::CBattleFieldController(CBattleInterface * owner): | ||||
| 		hex->myInterface = owner; | ||||
| 		bfield.push_back(hex); | ||||
| 	} | ||||
|  | ||||
| 	//for(auto hex : bfield) | ||||
| 	//	addChild(hex.get()); | ||||
| } | ||||
|  | ||||
| CBattleFieldController::~CBattleFieldController() | ||||
| { | ||||
| 	SDL_FreeSurface(background); | ||||
| 	SDL_FreeSurface(cellBorders); | ||||
| 	SDL_FreeSurface(backgroundWithHexes); | ||||
| 	SDL_FreeSurface(cellBorder); | ||||
| 	SDL_FreeSurface(cellShade); | ||||
| } | ||||
|  | ||||
| void CBattleFieldController::showBackgroundImage(SDL_Surface *to) | ||||
| { | ||||
| 	blitAt(background, owner->pos.x, owner->pos.y, to); | ||||
| 	background->draw(to, owner->pos.x, owner->pos.y); | ||||
|  | ||||
| 	if (settings["battle"]["cellBorders"].Bool()) | ||||
| 	{ | ||||
| 		CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, nullptr, to, &owner->pos); | ||||
| 	} | ||||
| 		cellBorders->copyTo(to, owner->pos.topLeft()); | ||||
| } | ||||
|  | ||||
| void CBattleFieldController::showBackgroundImageWithHexes(SDL_Surface *to) | ||||
| { | ||||
| 	blitAt(backgroundWithHexes, owner->pos.x, owner->pos.y, to); | ||||
| 	backgroundWithHexes->copyTo(to, owner->pos.topLeft()); | ||||
| } | ||||
|  | ||||
| void CBattleFieldController::redrawBackgroundWithHexes() | ||||
| { | ||||
| 	const CStack *activeStack = owner->stacksController->getActiveStack(); | ||||
| 	attackableHexes.clear(); | ||||
| 	std::vector<BattleHex> attackableHexes; | ||||
| 	if (activeStack) | ||||
| 		occupyableHexes = owner->curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes); | ||||
|  | ||||
| @@ -140,8 +98,7 @@ void CBattleFieldController::redrawBackgroundWithHexes() | ||||
| 		stackCountOutsideHexes[i] = (accessibility[i] == EAccessibility::ACCESSIBLE); | ||||
|  | ||||
| 	//prepare background graphic with hexes and shaded hexes | ||||
| 	blitAt(background, 0, 0, backgroundWithHexes); | ||||
|  | ||||
| 	backgroundWithHexes->draw(background, Point(0,0)); | ||||
| 	owner->obstacleController->redrawBackgroundWithHexes(backgroundWithHexes); | ||||
|  | ||||
| 	if (settings["battle"]["stackRange"].Bool()) | ||||
| @@ -150,125 +107,142 @@ void CBattleFieldController::redrawBackgroundWithHexes() | ||||
| 		hexesToShade.insert(hexesToShade.end(), attackableHexes.begin(), attackableHexes.end()); | ||||
| 		for (BattleHex hex : hexesToShade) | ||||
| 		{ | ||||
| 			int i = hex.getY(); //row | ||||
| 			int j = hex.getX()-1; //column | ||||
| 			int x = 58 + (i%2==0 ? 22 : 0) + 44*j; | ||||
| 			int y = 86 + 42 *i; | ||||
| 			SDL_Rect temp_rect = genRect(cellShade->h, cellShade->w, x, y); | ||||
| 			CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, nullptr, backgroundWithHexes, &temp_rect); | ||||
| 			backgroundWithHexes->draw(cellShade, hexPositionLocal(hex).topLeft()); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(settings["battle"]["cellBorders"].Bool()) | ||||
| 		CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, nullptr, backgroundWithHexes, nullptr); | ||||
| 		backgroundWithHexes->draw(cellBorders, Point(0, 0)); | ||||
| } | ||||
|  | ||||
| void CBattleFieldController::showHighlightedHex(SDL_Surface *to, BattleHex hex, bool darkBorder) | ||||
| void CBattleFieldController::showHighlightedHex(std::shared_ptr<CCanvas> to, BattleHex hex, bool darkBorder) | ||||
| { | ||||
| 	int x = 14 + (hex.getY() % 2 == 0 ? 22 : 0) + 44 *(hex.getX()) + owner->pos.x; | ||||
| 	int y = 86 + 42 *hex.getY() + owner->pos.y; | ||||
| 	SDL_Rect temp_rect = genRect (cellShade->h, cellShade->w, x, y); | ||||
| 	CSDL_Ext::blit8bppAlphaTo24bpp (cellShade, nullptr, to, &temp_rect); | ||||
| 	Point hexPos = hexPosition(hex).topLeft(); | ||||
|  | ||||
| 	to->draw(cellShade, hexPos); | ||||
| 	if(!darkBorder && settings["battle"]["cellBorders"].Bool()) | ||||
| 		CSDL_Ext::blit8bppAlphaTo24bpp(cellBorder, nullptr, to, &temp_rect); //redraw border to make it light green instead of shaded | ||||
| 		to->draw(cellBorder, hexPos); | ||||
| } | ||||
|  | ||||
| std::set<BattleHex> CBattleFieldController::getHighlightedHexesStackRange() | ||||
| { | ||||
| 	std::set<BattleHex> result; | ||||
|  | ||||
| 	if ( !owner->stacksController->getActiveStack()) | ||||
| 		return result; | ||||
|  | ||||
| 	if ( !settings["battle"]["stackRange"].Bool()) | ||||
| 		return result; | ||||
|  | ||||
| 	auto hoveredHex = getHoveredHex(); | ||||
|  | ||||
| 	std::set<BattleHex> set = owner->curInt->cb->battleGetAttackedHexes(owner->stacksController->getActiveStack(), hoveredHex, attackingHex); | ||||
| 	for(BattleHex hex : set) | ||||
| 		result.insert(hex); | ||||
|  | ||||
| 	// display the movement shadow of the stack at b (i.e. stack under mouse) | ||||
| 	const CStack * const shere = owner->curInt->cb->battleGetStackByPos(hoveredHex, false); | ||||
| 	if(shere && shere != owner->stacksController->getActiveStack() && shere->alive()) | ||||
| 	{ | ||||
| 		std::vector<BattleHex> v = owner->curInt->cb->battleGetAvailableHexes(shere, true, nullptr); | ||||
| 		for(BattleHex hex : v) | ||||
| 			result.insert(hex); | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::set<BattleHex> CBattleFieldController::getHighlightedHexesSpellRange() | ||||
| { | ||||
| 	std::set<BattleHex> result; | ||||
| 	auto hoveredHex = getHoveredHex(); | ||||
|  | ||||
| 	if(!settings["battle"]["mouseShadow"].Bool()) | ||||
| 		return result; | ||||
|  | ||||
| 	const spells::Caster *caster = nullptr; | ||||
| 	const CSpell *spell = nullptr; | ||||
|  | ||||
| 	spells::Mode mode = spells::Mode::HERO; | ||||
|  | ||||
| 	if(owner->actionsController->spellcastingModeActive())//hero casts spell | ||||
| 	{ | ||||
| 		spell = owner->actionsController->selectedSpell().toSpell(); | ||||
| 		caster = owner->getActiveHero(); | ||||
| 	} | ||||
| 	else if(owner->stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell | ||||
| 	{ | ||||
| 		spell = SpellID(owner->stacksController->activeStackSpellToCast()).toSpell(); | ||||
| 		caster = owner->stacksController->getActiveStack(); | ||||
| 		mode = spells::Mode::CREATURE_ACTIVE; | ||||
| 	} | ||||
|  | ||||
| 	if(caster && spell) //when casting spell | ||||
| 	{ | ||||
| 		// printing shaded hex(es) | ||||
| 		spells::BattleCast event(owner->curInt->cb.get(), caster, mode, spell); | ||||
| 		auto shaded = spell->battleMechanics(&event)->rangeInHexes(hoveredHex); | ||||
|  | ||||
| 		for(BattleHex shadedHex : shaded) | ||||
| 		{ | ||||
| 			if((shadedHex.getX() != 0) && (shadedHex.getX() != GameConstants::BFIELD_WIDTH - 1)) | ||||
| 				result.insert(shadedHex); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(owner->active) //always highlight pointed hex | ||||
| 	{ | ||||
| 		if(hoveredHex.getX() != 0 && hoveredHex.getX() != GameConstants::BFIELD_WIDTH - 1) | ||||
| 			result.insert(hoveredHex); | ||||
| 	} | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| void CBattleFieldController::showHighlightedHexes(SDL_Surface *to) | ||||
| { | ||||
| 	bool delayedBlit = false; //workaround for blitting enemy stack hex without mouse shadow with stack range on | ||||
| 	if(owner->stacksController->getActiveStack() && settings["battle"]["stackRange"].Bool()) | ||||
| 	{ | ||||
| 		std::set<BattleHex> set = owner->curInt->cb->battleGetAttackedHexes(owner->stacksController->getActiveStack(), currentlyHoveredHex, attackingHex); | ||||
| 		for(BattleHex hex : set) | ||||
| 			if(hex != currentlyHoveredHex) | ||||
| 				showHighlightedHex(to, hex, false); | ||||
| 	auto canvas = std::make_shared<CCanvas>(to); | ||||
|  | ||||
| 		// display the movement shadow of the stack at b (i.e. stack under mouse) | ||||
| 		const CStack * const shere = owner->curInt->cb->battleGetStackByPos(currentlyHoveredHex, false); | ||||
| 		if(shere && shere != owner->stacksController->getActiveStack() && shere->alive()) | ||||
| 		{ | ||||
| 			std::vector<BattleHex> v = owner->curInt->cb->battleGetAvailableHexes(shere, true, nullptr); | ||||
| 			for(BattleHex hex : v) | ||||
| 			{ | ||||
| 				if(hex != currentlyHoveredHex) | ||||
| 					showHighlightedHex(to, hex, false); | ||||
| 				else if(!settings["battle"]["mouseShadow"].Bool()) | ||||
| 					delayedBlit = true; //blit at the end of method to avoid graphic artifacts | ||||
| 				else | ||||
| 					showHighlightedHex(to, hex, true); //blit now and blit 2nd time later for darker shadow - avoids graphic artifacts | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	std::set<BattleHex> hoveredStack = getHighlightedHexesStackRange(); | ||||
| 	std::set<BattleHex> hoveredMouse = getHighlightedHexesSpellRange(); | ||||
|  | ||||
| 	for(int b=0; b<GameConstants::BFIELD_SIZE; ++b) | ||||
| 	{ | ||||
| 		if(bfield[b]->strictHovered && bfield[b]->hovered) | ||||
| 		bool stack = hoveredStack.count(b); | ||||
| 		bool mouse = hoveredMouse.count(b); | ||||
|  | ||||
| 		if ( stack && mouse ) | ||||
| 		{ | ||||
| 			if(previouslyHoveredHex == -1) | ||||
| 				previouslyHoveredHex = b; //something to start with | ||||
| 			if(currentlyHoveredHex == -1) | ||||
| 				currentlyHoveredHex = b; //something to start with | ||||
|  | ||||
| 			if(currentlyHoveredHex != b) //repair hover info | ||||
| 			{ | ||||
| 				previouslyHoveredHex = currentlyHoveredHex; | ||||
| 				currentlyHoveredHex = b; | ||||
| 			} | ||||
| 			if(settings["battle"]["mouseShadow"].Bool() || delayedBlit) | ||||
| 			{ | ||||
| 				const spells::Caster *caster = nullptr; | ||||
| 				const CSpell *spell = nullptr; | ||||
|  | ||||
| 				spells::Mode mode = spells::Mode::HERO; | ||||
|  | ||||
| 				if(owner->actionsController->spellcastingModeActive())//hero casts spell | ||||
| 				{ | ||||
| 					spell = owner->actionsController->selectedSpell().toSpell(); | ||||
| 					caster = owner->getActiveHero(); | ||||
| 				} | ||||
| 				else if(owner->stacksController->activeStackSpellToCast() != SpellID::NONE)//stack casts spell | ||||
| 				{ | ||||
| 					spell = SpellID(owner->stacksController->activeStackSpellToCast()).toSpell(); | ||||
| 					caster = owner->stacksController->getActiveStack(); | ||||
| 					mode = spells::Mode::CREATURE_ACTIVE; | ||||
| 				} | ||||
|  | ||||
| 				if(caster && spell) //when casting spell | ||||
| 				{ | ||||
| 					// printing shaded hex(es) | ||||
| 					spells::BattleCast event(owner->curInt->cb.get(), caster, mode, spell); | ||||
| 					auto shaded = spell->battleMechanics(&event)->rangeInHexes(currentlyHoveredHex); | ||||
|  | ||||
| 					for(BattleHex shadedHex : shaded) | ||||
| 					{ | ||||
| 						if((shadedHex.getX() != 0) && (shadedHex.getX() != GameConstants::BFIELD_WIDTH - 1)) | ||||
| 							showHighlightedHex(to, shadedHex, true); | ||||
| 					} | ||||
| 				} | ||||
| 				else if(owner->active || delayedBlit) //always highlight pointed hex, keep this condition last in this method for correct behavior | ||||
| 				{ | ||||
| 					if(currentlyHoveredHex.getX() != 0 | ||||
| 					 && currentlyHoveredHex.getX() != GameConstants::BFIELD_WIDTH - 1) | ||||
| 						showHighlightedHex(to, currentlyHoveredHex, true); //keep true for OH3 behavior: hovered hex frame "thinner" | ||||
| 				} | ||||
| 			} | ||||
| 			// area where enemy stack can move AND affected by mouse cursor - create darker highlight by blitting twice | ||||
| 			showHighlightedHex(canvas, b, true); | ||||
| 			showHighlightedHex(canvas, b, true); | ||||
| 		} | ||||
| 		if ( !stack && mouse ) | ||||
| 		{ | ||||
| 			showHighlightedHex(canvas, b, true); | ||||
| 		} | ||||
| 		if ( stack && !mouse ) | ||||
| 		{ | ||||
| 			showHighlightedHex(canvas, b, false); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| Rect CBattleFieldController::hexPositionLocal(BattleHex hex) const | ||||
| { | ||||
| 	int x = 14 + ((hex.getY())%2==0 ? 22 : 0) + 44*hex.getX(); | ||||
| 	int y = 86 + 42 *hex.getY(); | ||||
| 	int w = cellShade->width(); | ||||
| 	int h = cellShade->height(); | ||||
| 	return Rect(x, y, w, h); | ||||
| } | ||||
|  | ||||
| Rect CBattleFieldController::hexPosition(BattleHex hex) const | ||||
| { | ||||
| 	int x = 14 + ((hex.getY())%2==0 ? 22 : 0) + 44*hex.getX() + owner->pos.x; | ||||
| 	int y = 86 + 42 *hex.getY() + owner->pos.y; | ||||
| 	int w = cellShade->w; | ||||
| 	int h = cellShade->h; | ||||
| 	return Rect(x, y, w, h); | ||||
| 	return hexPositionLocal(hex) + owner->pos.topLeft(); | ||||
| } | ||||
|  | ||||
| bool CBattleFieldController::isPixelInHex(Point const & position) | ||||
| { | ||||
| 	assert(cellShade); | ||||
| 	return CSDL_Ext::SDL_GetPixel(cellShade, position.x, position.y) != 0; | ||||
| 	return !cellShade->isTransparent(position); | ||||
| } | ||||
|  | ||||
| BattleHex CBattleFieldController::getHoveredHex() | ||||
|   | ||||
| @@ -17,32 +17,39 @@ struct Rect; | ||||
| struct Point; | ||||
|  | ||||
| class CClickableHex; | ||||
| class CCanvas; | ||||
| class CStack; | ||||
| class IImage; | ||||
| class CBattleInterface; | ||||
|  | ||||
| class CBattleFieldController : public CIntObject | ||||
| { | ||||
| 	CBattleInterface * owner; | ||||
|  | ||||
| 	SDL_Surface *background; | ||||
| 	SDL_Surface *backgroundWithHexes; | ||||
| 	SDL_Surface *cellBorders; | ||||
| 	SDL_Surface *cellBorder; | ||||
| 	SDL_Surface *cellShade; | ||||
| 	std::shared_ptr<IImage> background; | ||||
| 	std::shared_ptr<IImage> cellBorder; | ||||
| 	std::shared_ptr<IImage> cellShade; | ||||
|  | ||||
| 	BattleHex previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago | ||||
| 	BattleHex currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon) | ||||
| 	std::shared_ptr<CCanvas> cellBorders; | ||||
|  | ||||
| 	/// Canvas that contains background, hex grid (if enabled), absolute obstacles and movement range of active stack | ||||
| 	std::shared_ptr<CCanvas> backgroundWithHexes; | ||||
|  | ||||
| 	//BattleHex previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago | ||||
| 	//BattleHex currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon) | ||||
| 	BattleHex attackingHex; //hex from which the stack would perform attack with current cursor | ||||
|  | ||||
| 	std::vector<BattleHex> occupyableHexes; //hexes available for active stack | ||||
| 	std::vector<BattleHex> attackableHexes; //hexes attackable by active stack | ||||
| 	std::array<bool, GameConstants::BFIELD_SIZE> stackCountOutsideHexes; // hexes that when in front of a unit cause it's amount box to move back | ||||
|  | ||||
| 	std::vector<std::shared_ptr<CClickableHex>> bfield; //11 lines, 17 hexes on each | ||||
|  | ||||
| 	void showHighlightedHex(std::shared_ptr<CCanvas> to, BattleHex hex, bool darkBorder); | ||||
|  | ||||
| 	std::set<BattleHex> getHighlightedHexesStackRange(); | ||||
| 	std::set<BattleHex> getHighlightedHexesSpellRange(); | ||||
| public: | ||||
| 	CBattleFieldController(CBattleInterface * owner); | ||||
| 	~CBattleFieldController(); | ||||
|  | ||||
| 	void showBackgroundImage(SDL_Surface *to); | ||||
| 	void showBackgroundImageWithHexes(SDL_Surface *to); | ||||
| @@ -50,8 +57,8 @@ public: | ||||
| 	void redrawBackgroundWithHexes(); | ||||
|  | ||||
| 	void showHighlightedHexes(SDL_Surface *to); | ||||
| 	void showHighlightedHex(SDL_Surface *to, BattleHex hex, bool darkBorder); | ||||
|  | ||||
| 	Rect hexPositionLocal(BattleHex hex) const; | ||||
| 	Rect hexPosition(BattleHex hex) const; | ||||
| 	bool isPixelInHex(Point const & position); | ||||
|  | ||||
|   | ||||
| @@ -22,7 +22,6 @@ | ||||
| #include "CBattleControlPanel.h" | ||||
| #include "CBattleStacksController.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CMT.h" | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
| #include "CBattleStacksController.h" | ||||
| #include "CBattleControlPanel.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CMusicHandler.h" | ||||
|   | ||||
| @@ -18,6 +18,7 @@ | ||||
| #include "../../lib/battle/CObstacleInstance.h" | ||||
| #include "../../lib/ObstacleHandler.h" | ||||
| #include "../gui/CAnimation.h" | ||||
| #include "../gui/CCanvas.h" | ||||
|  | ||||
| CBattleObstacleController::CBattleObstacleController(CBattleInterface * owner): | ||||
| 	owner(owner) | ||||
| @@ -196,7 +197,7 @@ Point CBattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> ima | ||||
| 	return r.topLeft(); | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::redrawBackgroundWithHexes(SDL_Surface * to) | ||||
| void CBattleObstacleController::redrawBackgroundWithHexes(std::shared_ptr<CCanvas> to) | ||||
| { | ||||
| 	//draw absolute obstacles (cliffs and so on) | ||||
| 	for(auto & oi : owner->curInt->cb->battleGetAllObstacles()) | ||||
| @@ -205,7 +206,7 @@ void CBattleObstacleController::redrawBackgroundWithHexes(SDL_Surface * to) | ||||
| 		{ | ||||
| 			auto img = getObstacleImage(*oi); | ||||
| 			if(img) | ||||
| 				img->draw(to, oi->getInfo().width, oi->getInfo().height); | ||||
| 				to->draw(img, Point(oi->getInfo().width, oi->getInfo().height)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,7 @@ struct SDL_Surface; | ||||
| struct BattleObjectsByHex; | ||||
| struct BattleHex; | ||||
| class IImage; | ||||
| class CCanvas; | ||||
| class CAnimation; | ||||
| class CBattleInterface; | ||||
| class CObstacleInstance; | ||||
| @@ -38,5 +39,5 @@ public: | ||||
|  | ||||
| 	void showBattlefieldObjects(SDL_Surface *to, const BattleHex & location ); | ||||
|  | ||||
| 	void redrawBackgroundWithHexes(SDL_Surface * to); | ||||
| 	void redrawBackgroundWithHexes(std::shared_ptr<CCanvas> to); | ||||
| }; | ||||
|   | ||||
| @@ -98,6 +98,8 @@ public: | ||||
| 	void exportBitmap(const boost::filesystem::path & path) const override; | ||||
| 	void playerColored(PlayerColor player) override; | ||||
| 	void setFlagColor(PlayerColor player) override; | ||||
| 	bool isTransparent(const Point & coords) const override; | ||||
| 	Point dimensions() const override; | ||||
| 	int width() const override; | ||||
| 	int height() const override; | ||||
|  | ||||
| @@ -745,6 +747,16 @@ int SDLImage::height() const | ||||
| 	return fullSize.y; | ||||
| } | ||||
|  | ||||
| bool SDLImage::isTransparent(const Point & coords) const | ||||
| { | ||||
| 	return CSDL_Ext::isTransparent(surf, coords.x, coords.y); | ||||
| } | ||||
|  | ||||
| Point SDLImage::dimensions() const | ||||
| { | ||||
| 	return fullSize; | ||||
| } | ||||
|  | ||||
| void SDLImage::horizontalFlip() | ||||
| { | ||||
| 	margins.y = fullSize.y - surf->h - margins.y; | ||||
|   | ||||
| @@ -53,6 +53,10 @@ public: | ||||
| 	//set special color for flag | ||||
| 	virtual void setFlagColor(PlayerColor player)=0; | ||||
|  | ||||
| 	//test transparency of specific pixel | ||||
| 	virtual bool isTransparent(const Point & coords) const = 0; | ||||
|  | ||||
| 	virtual Point dimensions() const = 0; | ||||
| 	virtual int width() const=0; | ||||
| 	virtual int height() const=0; | ||||
|  | ||||
|   | ||||
							
								
								
									
										46
									
								
								client/gui/CCanvas.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								client/gui/CCanvas.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * CCanvas.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #include "StdInc.h" | ||||
| #include "CCanvas.h" | ||||
|  | ||||
| #include "SDL_Extensions.h" | ||||
| #include "Geometries.h" | ||||
| #include "CAnimation.h" | ||||
|  | ||||
| CCanvas::CCanvas(SDL_Surface * surface): | ||||
| 	surface(surface) | ||||
| { | ||||
| 	surface->refcount++; | ||||
| } | ||||
|  | ||||
| CCanvas::CCanvas(const Point & size) | ||||
| { | ||||
| 	surface = CSDL_Ext::newSurface(size.x, size.y); | ||||
| } | ||||
|  | ||||
| CCanvas::~CCanvas() | ||||
| { | ||||
| 	SDL_FreeSurface(surface); | ||||
| } | ||||
|  | ||||
| void CCanvas::draw(std::shared_ptr<IImage> image, const Point & pos) | ||||
| { | ||||
| 	image->draw(surface, pos.x, pos.y); | ||||
| } | ||||
|  | ||||
| void CCanvas::draw(std::shared_ptr<CCanvas> image, const Point & pos) | ||||
| { | ||||
| 	image->copyTo(surface, pos); | ||||
| } | ||||
|  | ||||
| void CCanvas::copyTo(SDL_Surface * to, const Point & pos) | ||||
| { | ||||
| 	blitAt(to, pos.x, pos.y, surface); | ||||
| } | ||||
							
								
								
									
										35
									
								
								client/gui/CCanvas.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								client/gui/CCanvas.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * CCanvas.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| struct SDL_Surface; | ||||
| struct Point; | ||||
| class IImage; | ||||
|  | ||||
| /// Class that represents surface for drawing on | ||||
| class CCanvas | ||||
| { | ||||
| 	SDL_Surface * surface; | ||||
| public: | ||||
| 	// constructs canvas using existing surface. Caller maintains ownership on the surface | ||||
| 	CCanvas(SDL_Surface * surface); | ||||
|  | ||||
| 	CCanvas(const Point & size); | ||||
| 	~CCanvas(); | ||||
|  | ||||
| 	// renders image onto this canvas | ||||
| 	void draw(std::shared_ptr<IImage> image, const Point & pos); | ||||
|  | ||||
| 	// renders another canvas onto this canvas | ||||
| 	void draw(std::shared_ptr<CCanvas> image, const Point & pos); | ||||
|  | ||||
| 	// for compatibility, copies content of this canvas onto SDL_Surface | ||||
| 	void copyTo(SDL_Surface * to, const Point & pos); | ||||
| }; | ||||
| @@ -18,7 +18,6 @@ | ||||
|  | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CMusicHandler.h" | ||||
| #include "../CVideoHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
| @@ -21,7 +21,6 @@ | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CMusicHandler.h" | ||||
| #include "../CVideoHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
| @@ -12,7 +12,6 @@ | ||||
| #include "CSelectionBase.h" | ||||
| #include "OptionsTab.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CServerHandler.h" | ||||
| #include "../gui/CAnimation.h" | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
|  | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../CServerHandler.h" | ||||
| #include "../gui/CAnimation.h" | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
|  | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CMusicHandler.h" | ||||
| #include "../CVideoHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
| @@ -37,7 +37,6 @@ | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../../CCallback.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../Client.h" | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../gui/CAnimation.h" | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../gui/CCursorHandler.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CGameInfo.h" | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
| #include "CKingdomInterface.h" | ||||
| #include "GUIClasses.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CMT.h" | ||||
|   | ||||
| @@ -12,7 +12,6 @@ | ||||
|  | ||||
| #include "CAdvmapInterface.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../Graphics.h" | ||||
|   | ||||
| @@ -23,7 +23,6 @@ | ||||
| #include "../battle/CBattleInterface.h" | ||||
| #include "../battle/CBattleInterfaceClasses.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../Graphics.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
| #include "CreatureCostBox.h" | ||||
| #include "InfoWindows.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CMessage.h" | ||||
| #include "../CMusicHandler.h" | ||||
|   | ||||
| @@ -12,7 +12,6 @@ | ||||
|  | ||||
| #include "CAdvmapInterface.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| #include "../Graphics.h" | ||||
| #include "../CGameInfo.h" | ||||
| #include "../CPlayerInterface.h" | ||||
|   | ||||
		Reference in New Issue
	
	Block a user