mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	moved battle obstacle handling into separate class
This commit is contained in:
		| @@ -14,6 +14,7 @@ | ||||
| #include "CBattleInterfaceClasses.h" | ||||
| #include "CCreatureAnimation.h" | ||||
| #include "CBattleProjectileController.h" | ||||
| #include "CBattleObstacleController.h" | ||||
| #include "CBattleSiegeController.h" | ||||
|  | ||||
| #include "../CBitmapHandler.h" | ||||
| @@ -335,48 +336,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet *army1, const CCreatureSet | ||||
|  | ||||
| 	backgroundWithHexes = CSDL_Ext::newSurface(background->w, background->h, screen); | ||||
|  | ||||
| 	//preparing obstacle defs | ||||
| 	auto obst = curInt->cb->battleGetAllObstacles(); | ||||
| 	for(auto & elem : obst) | ||||
| 	{ | ||||
| 		if(elem->obstacleType == CObstacleInstance::USUAL) | ||||
| 		{ | ||||
| 			std::string animationName = elem->getInfo().animation; | ||||
|  | ||||
| 			auto cached = animationsCache.find(animationName); | ||||
|  | ||||
| 			if(cached == animationsCache.end()) | ||||
| 			{ | ||||
| 				auto animation = std::make_shared<CAnimation>(animationName); | ||||
| 				animationsCache[animationName] = animation; | ||||
| 				obstacleAnimations[elem->uniqueID] = animation; | ||||
| 				animation->preload(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				obstacleAnimations[elem->uniqueID] = cached->second; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (elem->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			std::string animationName = elem->getInfo().animation; | ||||
|  | ||||
| 			auto cached = animationsCache.find(animationName); | ||||
|  | ||||
| 			if(cached == animationsCache.end()) | ||||
| 			{ | ||||
| 				auto animation = std::make_shared<CAnimation>(); | ||||
| 				animation->setCustom(animationName, 0, 0); | ||||
| 				animationsCache[animationName] = animation; | ||||
| 				obstacleAnimations[elem->uniqueID] = animation; | ||||
| 				animation->preload(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				obstacleAnimations[elem->uniqueID] = cached->second; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	obstacleController.reset(new CBattleObstacleController(this)); | ||||
|  | ||||
| 	for(auto hex : bfield) | ||||
| 		addChild(hex.get()); | ||||
| @@ -2625,45 +2585,7 @@ Rect CBattleInterface::hexPosition(BattleHex hex) const | ||||
|  | ||||
| void CBattleInterface::obstaclePlaced(const CObstacleInstance & oi) | ||||
| { | ||||
| 	//so when multiple obstacles are added, they show up one after another | ||||
| 	waitForAnims(); | ||||
|  | ||||
| 	//soundBase::soundID sound; // FIXME(v.markovtsev): soundh->playSound() is commented in the end => warning | ||||
|  | ||||
| 	std::string defname; | ||||
|  | ||||
| 	switch(oi.obstacleType) | ||||
| 	{ | ||||
| 	case CObstacleInstance::SPELL_CREATED: | ||||
| 		{ | ||||
| 			auto &spellObstacle = dynamic_cast<const SpellCreatedObstacle&>(oi); | ||||
| 			defname = spellObstacle.appearAnimation; | ||||
| 			//TODO: sound | ||||
| 			//soundBase::QUIKSAND | ||||
| 			//soundBase::LANDMINE | ||||
| 			//soundBase::FORCEFLD | ||||
| 			//soundBase::fireWall | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		logGlobal->error("I don't know how to animate appearing obstacle of type %d", (int)oi.obstacleType); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	auto animation = std::make_shared<CAnimation>(defname); | ||||
| 	animation->preload(); | ||||
|  | ||||
| 	auto first = animation->getImage(0, 0); | ||||
| 	if(!first) | ||||
| 		return; | ||||
|  | ||||
| 	//we assume here that effect graphics have the same size as the usual obstacle image | ||||
| 	// -> if we know how to blit obstacle, let's blit the effect in the same place | ||||
| 	Point whereTo = getObstaclePosition(first, oi); | ||||
| 	addNewAnim(new CEffectAnimation(this, animation, whereTo.x, whereTo.y)); | ||||
|  | ||||
| 	//TODO we need to wait after playing sound till it's finished, otherwise it overlaps and sounds really bad | ||||
| 	//CCS->soundh->playSound(sound); | ||||
| 	obstacleController->obstaclePlaced(oi); | ||||
| } | ||||
|  | ||||
| const CGHeroInstance *CBattleInterface::currentHero() const | ||||
| @@ -2772,7 +2694,9 @@ void CBattleInterface::showBackground(SDL_Surface *to) | ||||
| 	else | ||||
| 	{ | ||||
| 		showBackgroundImage(to); | ||||
| 		showAbsoluteObstacles(to); | ||||
| 		obstacleController->showAbsoluteObstacles(to); | ||||
| 		if ( siegeController ) | ||||
| 			siegeController->showAbsoluteObstacles(to); | ||||
| 	} | ||||
| 	showHighlightedHexes(to); | ||||
| } | ||||
| @@ -2786,22 +2710,6 @@ void CBattleInterface::showBackgroundImage(SDL_Surface *to) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleInterface::showAbsoluteObstacles(SDL_Surface * to) | ||||
| { | ||||
| 	//Blit absolute obstacles | ||||
| 	for(auto & oi : curInt->cb->battleGetAllObstacles()) | ||||
| 	{ | ||||
| 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			auto img = getObstacleImage(*oi); | ||||
| 			if(img) | ||||
| 				img->draw(to, pos.x + oi->getInfo().width, pos.y + oi->getInfo().height); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if ( siegeController ) | ||||
| 		siegeController->showAbsoluteObstacles(to); | ||||
| } | ||||
|  | ||||
| void CBattleInterface::showHighlightedHexes(SDL_Surface *to) | ||||
| { | ||||
| @@ -2902,7 +2810,7 @@ void CBattleInterface::showBattlefieldObjects(SDL_Surface *to) | ||||
| 	{ | ||||
| 		if (siegeController) | ||||
| 			siegeController->showPiecesOfWall(to, hex.walls); | ||||
| 		showObstacles(to, hex.obstacles); | ||||
| 		obstacleController->showObstacles(to, hex.obstacles); | ||||
| 		showAliveStacks(to, hex.alive); | ||||
| 		showBattleEffects(to, hex.effects); | ||||
| 	}; | ||||
| @@ -3039,19 +2947,6 @@ void CBattleInterface::showStacks(SDL_Surface *to, std::vector<const CStack *> s | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleInterface::showObstacles(SDL_Surface * to, std::vector<std::shared_ptr<const CObstacleInstance>> & obstacles) | ||||
| { | ||||
| 	for(auto & obstacle : obstacles) | ||||
| 	{ | ||||
| 		auto img = getObstacleImage(*obstacle); | ||||
| 		if(img) | ||||
| 		{ | ||||
| 			Point p = getObstaclePosition(img, *obstacle); | ||||
| 			img->draw(to, p.x, p.y); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleInterface::showBattleEffects(SDL_Surface *to, const std::vector<const BattleEffect *> &battleEffects) | ||||
| { | ||||
| 	for (auto & elem : battleEffects) | ||||
| @@ -3180,19 +3075,8 @@ BattleObjectsByHex CBattleInterface::sortObjectsByHex() | ||||
| 	} | ||||
|  | ||||
| 	// Sort obstacles | ||||
| 	{ | ||||
| 		std::map<BattleHex, std::shared_ptr<const CObstacleInstance>> backgroundObstacles; | ||||
| 		for (auto &obstacle : curInt->cb->battleGetAllObstacles()) { | ||||
| 			if (obstacle->obstacleType != CObstacleInstance::ABSOLUTE_OBSTACLE | ||||
| 				&& obstacle->obstacleType != CObstacleInstance::MOAT) { | ||||
| 				backgroundObstacles[obstacle->pos] = obstacle; | ||||
| 			} | ||||
| 		} | ||||
| 		for (auto &op : backgroundObstacles) | ||||
| 		{ | ||||
| 			sorted.beforeAll.obstacles.push_back(op.second); | ||||
| 		} | ||||
| 	} | ||||
| 	obstacleController->sortObjectsByHex(sorted); | ||||
|  | ||||
| 	// Sort wall parts | ||||
| 	if (siegeController) | ||||
| 		siegeController->sortObjectsByHex(sorted); | ||||
| @@ -3237,58 +3121,6 @@ void CBattleInterface::updateBattleAnimations() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| std::shared_ptr<IImage> CBattleInterface::getObstacleImage(const CObstacleInstance & oi) | ||||
| { | ||||
| 	int frameIndex = (animCount+1) *25 / getAnimSpeed(); | ||||
| 	std::shared_ptr<CAnimation> animation; | ||||
|  | ||||
| 	if(oi.obstacleType == CObstacleInstance::USUAL || oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 	{ | ||||
| 		animation = obstacleAnimations[oi.uniqueID]; | ||||
| 	} | ||||
| 	else if(oi.obstacleType == CObstacleInstance::SPELL_CREATED) | ||||
| 	{ | ||||
| 		const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(&oi); | ||||
| 		if(!spellObstacle) | ||||
| 			return std::shared_ptr<IImage>(); | ||||
|  | ||||
| 		std::string animationName = spellObstacle->animation; | ||||
|  | ||||
| 		auto cacheIter = animationsCache.find(animationName); | ||||
|  | ||||
| 		if(cacheIter == animationsCache.end()) | ||||
| 		{ | ||||
| 			logAnim->trace("Creating obstacle animation %s", animationName); | ||||
|  | ||||
| 			animation = std::make_shared<CAnimation>(animationName); | ||||
| 			animation->preload(); | ||||
| 			animationsCache[animationName] = animation; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			animation = cacheIter->second; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(animation) | ||||
| 	{ | ||||
| 		frameIndex %= animation->size(0); | ||||
| 		return animation->getImage(frameIndex, 0); | ||||
| 	} | ||||
|  | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| Point CBattleInterface::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle) | ||||
| { | ||||
| 	int offset = obstacle.getAnimationYOffset(image->height()); | ||||
|  | ||||
| 	Rect r = hexPosition(obstacle.pos); | ||||
| 	r.y += 42 - image->height() + offset; | ||||
|  | ||||
| 	return r.topLeft(); | ||||
| } | ||||
|  | ||||
| void CBattleInterface::redrawBackgroundWithHexes(const CStack *activeStack) | ||||
| { | ||||
| 	attackableHexes.clear(); | ||||
| @@ -3308,16 +3140,7 @@ void CBattleInterface::redrawBackgroundWithHexes(const CStack *activeStack) | ||||
| 	//prepare background graphic with hexes and shaded hexes | ||||
| 	blitAt(background, 0, 0, backgroundWithHexes); | ||||
|  | ||||
| 	//draw absolute obstacles (cliffs and so on) | ||||
| 	for(auto & oi : curInt->cb->battleGetAllObstacles()) | ||||
| 	{ | ||||
| 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			auto img = getObstacleImage(*oi); | ||||
| 			if(img) | ||||
| 				img->draw(backgroundWithHexes, oi->getInfo().width, oi->getInfo().height); | ||||
| 		} | ||||
| 	} | ||||
| 	obstacleController->redrawBackgroundWithHexes(); | ||||
|  | ||||
| 	if (settings["battle"]["stackRange"].Bool()) | ||||
| 	{ | ||||
|   | ||||
| @@ -60,6 +60,7 @@ class IImage; | ||||
|  | ||||
| class CBattleProjectileController; | ||||
| class CBattleSiegeController; | ||||
| class CBattleObstacleController; | ||||
|  | ||||
| /// Small struct which contains information about the id of the attacked stack, the damage dealt,... | ||||
| struct StackAttackedInfo | ||||
| @@ -139,9 +140,6 @@ private: | ||||
| 	const CGHeroInstance *attackingHeroInstance, *defendingHeroInstance; | ||||
| 	std::map<int32_t, std::shared_ptr<CCreatureAnimation>> creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID) | ||||
|  | ||||
| 	std::map<std::string, std::shared_ptr<CAnimation>> animationsCache; | ||||
| 	std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations; | ||||
|  | ||||
| 	std::map<int, bool> creDir; // <creatureID, if false reverse creature's animation> //TODO: move it to battle callback | ||||
| 	ui8 animCount; | ||||
| 	const CStack *activeStack; //number of active stack; nullptr - no one | ||||
| @@ -200,7 +198,6 @@ private: | ||||
| 	void showBackground(SDL_Surface *to); | ||||
|  | ||||
| 	void showBackgroundImage(SDL_Surface *to); | ||||
| 	void showAbsoluteObstacles(SDL_Surface *to); | ||||
| 	void showHighlightedHexes(SDL_Surface *to); | ||||
| 	void showHighlightedHex(SDL_Surface *to, BattleHex hex, bool darkBorder = false); | ||||
| 	void showInterface(SDL_Surface *to); | ||||
| @@ -209,17 +206,12 @@ private: | ||||
|  | ||||
| 	void showAliveStacks(SDL_Surface *to, std::vector<const CStack *> stacks); | ||||
| 	void showStacks(SDL_Surface *to, std::vector<const CStack *> stacks); | ||||
| 	void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance>> &obstacles); | ||||
|  | ||||
| 	void showBattleEffects(SDL_Surface *to, const std::vector<const BattleEffect *> &battleEffects); | ||||
|  | ||||
| 	BattleObjectsByHex sortObjectsByHex(); | ||||
| 	void updateBattleAnimations(); | ||||
|  | ||||
| 	std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi); | ||||
|  | ||||
| 	Point getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle); | ||||
|  | ||||
| 	void redrawBackgroundWithHexes(const CStack *activeStack); | ||||
| 	/** End of battle screen blitting methods */ | ||||
|  | ||||
| @@ -227,6 +219,7 @@ private: | ||||
| public: | ||||
| 	std::unique_ptr<CBattleProjectileController> projectilesController; | ||||
| 	std::unique_ptr<CBattleSiegeController> siegeController; | ||||
| 	std::unique_ptr<CBattleObstacleController> obstacleController; | ||||
|  | ||||
| 	static CondSh<bool> animsAreDisplayed; //for waiting with the end of battle for end of anims | ||||
| 	static CondSh<BattleAction *> givenCommand; //data != nullptr if we have i.e. moved current unit | ||||
| @@ -356,4 +349,5 @@ public: | ||||
| 	friend class CClickableHex; | ||||
| 	friend class CBattleProjectileController; | ||||
| 	friend class CBattleSiegeController; | ||||
| 	friend class CBattleObstacleController; | ||||
| }; | ||||
|   | ||||
| @@ -9,4 +9,207 @@ | ||||
|  */ | ||||
| #include "StdInc.h" | ||||
| #include "CBattleObstacleController.h" | ||||
| #include "CBattleInterface.h" | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../../CCallback.h" | ||||
| #include "../../lib/battle/CObstacleInstance.h" | ||||
| #include "../../lib/ObstacleHandler.h" | ||||
| #include "../gui/CAnimation.h" | ||||
|  | ||||
| CBattleObstacleController::CBattleObstacleController(CBattleInterface * owner): | ||||
| 	owner(owner) | ||||
| { | ||||
| 	auto obst = owner->curInt->cb->battleGetAllObstacles(); | ||||
| 	for(auto & elem : obst) | ||||
| 	{ | ||||
| 		if(elem->obstacleType == CObstacleInstance::USUAL) | ||||
| 		{ | ||||
| 			std::string animationName = elem->getInfo().animation; | ||||
|  | ||||
| 			auto cached = animationsCache.find(animationName); | ||||
|  | ||||
| 			if(cached == animationsCache.end()) | ||||
| 			{ | ||||
| 				auto animation = std::make_shared<CAnimation>(animationName); | ||||
| 				animationsCache[animationName] = animation; | ||||
| 				obstacleAnimations[elem->uniqueID] = animation; | ||||
| 				animation->preload(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				obstacleAnimations[elem->uniqueID] = cached->second; | ||||
| 			} | ||||
| 		} | ||||
| 		else if (elem->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			std::string animationName = elem->getInfo().animation; | ||||
|  | ||||
| 			auto cached = animationsCache.find(animationName); | ||||
|  | ||||
| 			if(cached == animationsCache.end()) | ||||
| 			{ | ||||
| 				auto animation = std::make_shared<CAnimation>(); | ||||
| 				animation->setCustom(animationName, 0, 0); | ||||
| 				animationsCache[animationName] = animation; | ||||
| 				obstacleAnimations[elem->uniqueID] = animation; | ||||
| 				animation->preload(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				obstacleAnimations[elem->uniqueID] = cached->second; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::obstaclePlaced(const CObstacleInstance & oi) | ||||
| { | ||||
| 	//so when multiple obstacles are added, they show up one after another | ||||
| 	owner->waitForAnims(); | ||||
|  | ||||
| 	//soundBase::soundID sound; // FIXME(v.markovtsev): soundh->playSound() is commented in the end => warning | ||||
|  | ||||
| 	std::string defname; | ||||
|  | ||||
| 	switch(oi.obstacleType) | ||||
| 	{ | ||||
| 	case CObstacleInstance::SPELL_CREATED: | ||||
| 		{ | ||||
| 			auto &spellObstacle = dynamic_cast<const SpellCreatedObstacle&>(oi); | ||||
| 			defname = spellObstacle.appearAnimation; | ||||
| 			//TODO: sound | ||||
| 			//soundBase::QUIKSAND | ||||
| 			//soundBase::LANDMINE | ||||
| 			//soundBase::FORCEFLD | ||||
| 			//soundBase::fireWall | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		logGlobal->error("I don't know how to animate appearing obstacle of type %d", (int)oi.obstacleType); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	auto animation = std::make_shared<CAnimation>(defname); | ||||
| 	animation->preload(); | ||||
|  | ||||
| 	auto first = animation->getImage(0, 0); | ||||
| 	if(!first) | ||||
| 		return; | ||||
|  | ||||
| 	//we assume here that effect graphics have the same size as the usual obstacle image | ||||
| 	// -> if we know how to blit obstacle, let's blit the effect in the same place | ||||
| 	Point whereTo = getObstaclePosition(first, oi); | ||||
| 	owner->addNewAnim(new CEffectAnimation(owner, animation, whereTo.x, whereTo.y)); | ||||
|  | ||||
| 	//TODO we need to wait after playing sound till it's finished, otherwise it overlaps and sounds really bad | ||||
| 	//CCS->soundh->playSound(sound); | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::showAbsoluteObstacles(SDL_Surface * to) | ||||
| { | ||||
| 	//Blit absolute obstacles | ||||
| 	for(auto & oi : owner->curInt->cb->battleGetAllObstacles()) | ||||
| 	{ | ||||
| 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			auto img = getObstacleImage(*oi); | ||||
| 			if(img) | ||||
| 				img->draw(to, owner->pos.x + oi->getInfo().width, owner->pos.y + oi->getInfo().height); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::showObstacles(SDL_Surface * to, std::vector<std::shared_ptr<const CObstacleInstance>> & obstacles) | ||||
| { | ||||
| 	for(auto & obstacle : obstacles) | ||||
| 	{ | ||||
| 		auto img = getObstacleImage(*obstacle); | ||||
| 		if(img) | ||||
| 		{ | ||||
| 			Point p = getObstaclePosition(img, *obstacle); | ||||
| 			img->draw(to, p.x, p.y); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::sortObjectsByHex(BattleObjectsByHex & sorted) | ||||
| { | ||||
| 	std::map<BattleHex, std::shared_ptr<const CObstacleInstance>> backgroundObstacles; | ||||
| 	for (auto &obstacle : owner->curInt->cb->battleGetAllObstacles()) { | ||||
| 		if (obstacle->obstacleType != CObstacleInstance::ABSOLUTE_OBSTACLE | ||||
| 			&& obstacle->obstacleType != CObstacleInstance::MOAT) { | ||||
| 			backgroundObstacles[obstacle->pos] = obstacle; | ||||
| 		} | ||||
| 	} | ||||
| 	for (auto &op : backgroundObstacles) | ||||
| 	{ | ||||
| 		sorted.beforeAll.obstacles.push_back(op.second); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|  | ||||
| std::shared_ptr<IImage> CBattleObstacleController::getObstacleImage(const CObstacleInstance & oi) | ||||
| { | ||||
| 	int frameIndex = (owner->animCount+1) *25 / owner->getAnimSpeed(); | ||||
| 	std::shared_ptr<CAnimation> animation; | ||||
|  | ||||
| 	if(oi.obstacleType == CObstacleInstance::USUAL || oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 	{ | ||||
| 		animation = obstacleAnimations[oi.uniqueID]; | ||||
| 	} | ||||
| 	else if(oi.obstacleType == CObstacleInstance::SPELL_CREATED) | ||||
| 	{ | ||||
| 		const SpellCreatedObstacle * spellObstacle = dynamic_cast<const SpellCreatedObstacle *>(&oi); | ||||
| 		if(!spellObstacle) | ||||
| 			return std::shared_ptr<IImage>(); | ||||
|  | ||||
| 		std::string animationName = spellObstacle->animation; | ||||
|  | ||||
| 		auto cacheIter = animationsCache.find(animationName); | ||||
|  | ||||
| 		if(cacheIter == animationsCache.end()) | ||||
| 		{ | ||||
| 			logAnim->trace("Creating obstacle animation %s", animationName); | ||||
|  | ||||
| 			animation = std::make_shared<CAnimation>(animationName); | ||||
| 			animation->preload(); | ||||
| 			animationsCache[animationName] = animation; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			animation = cacheIter->second; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(animation) | ||||
| 	{ | ||||
| 		frameIndex %= animation->size(0); | ||||
| 		return animation->getImage(frameIndex, 0); | ||||
| 	} | ||||
|  | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| Point CBattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle) | ||||
| { | ||||
| 	int offset = obstacle.getAnimationYOffset(image->height()); | ||||
|  | ||||
| 	Rect r = owner->hexPosition(obstacle.pos); | ||||
| 	r.y += 42 - image->height() + offset; | ||||
|  | ||||
| 	return r.topLeft(); | ||||
| } | ||||
|  | ||||
| void CBattleObstacleController::redrawBackgroundWithHexes() | ||||
| { | ||||
| 	//draw absolute obstacles (cliffs and so on) | ||||
| 	for(auto & oi : owner->curInt->cb->battleGetAllObstacles()) | ||||
| 	{ | ||||
| 		if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE) | ||||
| 		{ | ||||
| 			auto img = getObstacleImage(*oi); | ||||
| 			if(img) | ||||
| 				img->draw(owner->backgroundWithHexes, oi->getInfo().width, oi->getInfo().height); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,33 @@ | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| struct SDL_Surface; | ||||
| struct BattleObjectsByHex; | ||||
| class IImage; | ||||
| class CAnimation; | ||||
| class CBattleInterface; | ||||
| class CObstacleInstance; | ||||
| struct Point; | ||||
|  | ||||
| class CBattleObstacleController | ||||
| { | ||||
| 	std::map<std::string, std::shared_ptr<CAnimation>> animationsCache; | ||||
|  | ||||
| 	CBattleInterface * owner; | ||||
|  | ||||
| 	std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations; | ||||
| public: | ||||
| 	CBattleObstacleController(CBattleInterface * owner); | ||||
|  | ||||
| 	void obstaclePlaced(const CObstacleInstance & oi); | ||||
| 	void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance>> &obstacles); | ||||
| 	void showAbsoluteObstacles(SDL_Surface *to); | ||||
|  | ||||
| 	void sortObjectsByHex(BattleObjectsByHex & sorted); | ||||
|  | ||||
| 	std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi); | ||||
|  | ||||
| 	Point getObstaclePosition(std::shared_ptr<IImage> image, const CObstacleInstance & obstacle); | ||||
|  | ||||
| 	void redrawBackgroundWithHexes(); | ||||
| }; | ||||
|   | ||||
| @@ -145,7 +145,9 @@ void CBattleSiegeController::printPartOfWall(SDL_Surface *to, int what) | ||||
| } | ||||
|  | ||||
|  | ||||
| CBattleSiegeController::CBattleSiegeController(CBattleInterface * owner, const CGTownInstance *siegeTown) | ||||
| CBattleSiegeController::CBattleSiegeController(CBattleInterface * owner, const CGTownInstance *siegeTown): | ||||
| 	owner(owner), | ||||
| 	town(siegeTown) | ||||
| { | ||||
| 	owner->background = BitmapHandler::loadBitmap( getSiegeName(0), false ); | ||||
| 	ui8 siegeLevel = owner->curInt->cb->battleGetSiegeLevel(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user