mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Exploded mines now send ACTIVATE flag to client to play effect
This commit is contained in:
		| @@ -72,10 +72,6 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi) | |||||||
|  |  | ||||||
| void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & obstacles) | void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<const CObstacleInstance>> & obstacles) | ||||||
| { | { | ||||||
| 	assert(obstaclesBeingPlaced.empty()); |  | ||||||
| 	for (auto const & oi : obstacles) |  | ||||||
| 		obstaclesBeingPlaced.push_back(oi->uniqueID); |  | ||||||
|  |  | ||||||
| 	for (auto const & oi : obstacles) | 	for (auto const & oi : obstacles) | ||||||
| 	{ | 	{ | ||||||
| 		auto spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(oi.get()); | 		auto spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(oi.get()); | ||||||
| @@ -83,7 +79,6 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr< | |||||||
| 		if (!spellObstacle) | 		if (!spellObstacle) | ||||||
| 		{ | 		{ | ||||||
| 			logGlobal->error("I don't know how to animate appearing obstacle of type %d", (int)oi->obstacleType); | 			logGlobal->error("I don't know how to animate appearing obstacle of type %d", (int)oi->obstacleType); | ||||||
| 			obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin()); |  | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -92,10 +87,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr< | |||||||
|  |  | ||||||
| 		auto first = animation->getImage(0, 0); | 		auto first = animation->getImage(0, 0); | ||||||
| 		if(!first) | 		if(!first) | ||||||
| 		{ |  | ||||||
| 			obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin()); |  | ||||||
| 			continue; | 			continue; | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		//we assume here that effect graphics have the same size as the usual obstacle image | 		//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 | 		// -> if we know how to blit obstacle, let's blit the effect in the same place | ||||||
| @@ -105,7 +97,6 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr< | |||||||
| 		//so when multiple obstacles are added, they show up one after another | 		//so when multiple obstacles are added, they show up one after another | ||||||
| 		owner.waitForAnimationCondition(EAnimationEvents::ACTION, false); | 		owner.waitForAnimationCondition(EAnimationEvents::ACTION, false); | ||||||
|  |  | ||||||
| 		obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin()); |  | ||||||
| 		loadObstacleImage(*spellObstacle); | 		loadObstacleImage(*spellObstacle); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -150,19 +141,9 @@ std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstac | |||||||
| 	int frameIndex = (owner.animCount+1) *25 / owner.getAnimSpeed(); | 	int frameIndex = (owner.animCount+1) *25 / owner.getAnimSpeed(); | ||||||
| 	std::shared_ptr<CAnimation> animation; | 	std::shared_ptr<CAnimation> animation; | ||||||
|  |  | ||||||
|  | 	// obstacle is not loaded yet, don't show anything | ||||||
| 	if (obstacleAnimations.count(oi.uniqueID) == 0) | 	if (obstacleAnimations.count(oi.uniqueID) == 0) | ||||||
| 	{ | 		return nullptr; | ||||||
| 		if (boost::range::find(obstaclesBeingPlaced, oi.uniqueID) != obstaclesBeingPlaced.end()) |  | ||||||
| 		{ |  | ||||||
| 			// obstacle is not loaded yet, don't show anything |  | ||||||
| 			return nullptr; |  | ||||||
| 		} |  | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			assert(0); // how? |  | ||||||
| 			loadObstacleImage(oi); |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	animation = obstacleAnimations[oi.uniqueID]; | 	animation = obstacleAnimations[oi.uniqueID]; | ||||||
| 	assert(animation); | 	assert(animation); | ||||||
|   | |||||||
| @@ -35,10 +35,6 @@ class BattleObstacleController | |||||||
| 	/// list of all obstacles that are currently being rendered | 	/// list of all obstacles that are currently being rendered | ||||||
| 	std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations; | 	std::map<si32, std::shared_ptr<CAnimation>> obstacleAnimations; | ||||||
|  |  | ||||||
| 	/// semi-debug member, contains obstacles that should not yet be visible due to ongoing placement animation |  | ||||||
| 	/// used only for sanity checks to ensure that there are no invisible obstacles |  | ||||||
| 	std::vector<si32> obstaclesBeingPlaced; |  | ||||||
|  |  | ||||||
| 	void loadObstacleImage(const CObstacleInstance & oi); | 	void loadObstacleImage(const CObstacleInstance & oi); | ||||||
|  |  | ||||||
| 	std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi); | 	std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi); | ||||||
|   | |||||||
| @@ -187,7 +187,7 @@ void BattleStacksController::stackReset(const CStack * stack) | |||||||
| void BattleStacksController::stackAdded(const CStack * stack, bool instant) | void BattleStacksController::stackAdded(const CStack * stack, bool instant) | ||||||
| { | { | ||||||
| 	// Tower shooters have only their upper half visible | 	// Tower shooters have only their upper half visible | ||||||
| 	static const int turretCreatureAnimationHeight = 235; | 	static const int turretCreatureAnimationHeight = 225; | ||||||
|  |  | ||||||
| 	stackFacingRight[stack->ID] = stack->side == BattleSide::ATTACKER; // must be set before getting stack position | 	stackFacingRight[stack->ID] = stack->side == BattleSide::ATTACKER; // must be set before getting stack position | ||||||
|  |  | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ | |||||||
| 		"targetType" : "NO_TARGET", | 		"targetType" : "NO_TARGET", | ||||||
|  |  | ||||||
| 		"sounds": { | 		"sounds": { | ||||||
| 			"cast": "" // no casting sound, only obstacle placement sound | 			"cast": "", // no casting sound, only obstacle placement sound | ||||||
| 		}, | 		}, | ||||||
| 		"levels" : { | 		"levels" : { | ||||||
| 			"base":{ | 			"base":{ | ||||||
| @@ -75,12 +75,16 @@ | |||||||
| 						"attacker" :{ | 						"attacker" :{ | ||||||
| 							"animation" : "C09SPF1", | 							"animation" : "C09SPF1", | ||||||
| 							"appearAnimation" : "C09SPF0", | 							"appearAnimation" : "C09SPF0", | ||||||
| 							"appearSound" : "LANDMINE" | 							"appearSound" : "LANDMINE", | ||||||
|  | 							"triggerAnimation" : "C09SPF3", | ||||||
|  | 							"triggerSound" : "LANDKILL" | ||||||
| 						}, | 						}, | ||||||
| 						"defender" :{ | 						"defender" :{ | ||||||
| 							"animation" : "C09SPF1", | 							"animation" : "C09SPF1", | ||||||
| 							"appearAnimation" : "C09SPF0", | 							"appearAnimation" : "C09SPF0", | ||||||
| 							"appearSound" : "LANDMINE" | 							"appearSound" : "LANDMINE", | ||||||
|  | 							"triggerAnimation" : "C09SPF3", | ||||||
|  | 							"triggerSound" : "LANDKILL" | ||||||
| 						} | 						} | ||||||
| 					}, | 					}, | ||||||
| 					"damage":{ | 					"damage":{ | ||||||
|   | |||||||
| @@ -278,7 +278,9 @@ public: | |||||||
| 		ADD, | 		ADD, | ||||||
| 		RESET_STATE, | 		RESET_STATE, | ||||||
| 		UPDATE, | 		UPDATE, | ||||||
| 		REMOVE | 		REMOVE, | ||||||
|  | 		ACTIVATE_AND_UPDATE, | ||||||
|  | 		ACTIVATE_AND_REMOVE | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	JsonNode data; | 	JsonNode data; | ||||||
|   | |||||||
| @@ -1663,6 +1663,7 @@ DLL_LINKAGE void BattleObstaclesChanged::applyBattle(IBattleState * battleState) | |||||||
| 		case BattleChanges::EOperation::ADD: | 		case BattleChanges::EOperation::ADD: | ||||||
| 			battleState->addObstacle(change); | 			battleState->addObstacle(change); | ||||||
| 			break; | 			break; | ||||||
|  | 		case BattleChanges::EOperation::ACTIVATE_AND_UPDATE: | ||||||
| 		case BattleChanges::EOperation::UPDATE: | 		case BattleChanges::EOperation::UPDATE: | ||||||
| 			battleState->updateObstacle(change); | 			battleState->updateObstacle(change); | ||||||
| 			break; | 			break; | ||||||
|   | |||||||
| @@ -32,7 +32,7 @@ public: | |||||||
| 	Obstacle obstacle; | 	Obstacle obstacle; | ||||||
| 	si32 iconIndex; | 	si32 iconIndex; | ||||||
| 	std::string identifier; | 	std::string identifier; | ||||||
| 	std::string appearSound, appearAnimation, animation, dissapearAnimation; | 	std::string appearSound, appearAnimation, triggerAnimation, triggerSound, animation; | ||||||
| 	std::vector<TerrainId> allowedTerrains; | 	std::vector<TerrainId> allowedTerrains; | ||||||
| 	std::vector<std::string> allowedSpecialBfields; | 	std::vector<std::string> allowedSpecialBfields; | ||||||
| 	 | 	 | ||||||
| @@ -63,7 +63,8 @@ public: | |||||||
| 		h & animation; | 		h & animation; | ||||||
| 		h & appearSound; | 		h & appearSound; | ||||||
| 		h & appearAnimation; | 		h & appearAnimation; | ||||||
| 		h & dissapearAnimation; | 		h & triggerSound; | ||||||
|  | 		h & triggerAnimation; | ||||||
| 		h & allowedTerrains; | 		h & allowedTerrains; | ||||||
| 		h & allowedSpecialBfields; | 		h & allowedSpecialBfields; | ||||||
| 		h & isAbsoluteObstacle; | 		h & isAbsoluteObstacle; | ||||||
|   | |||||||
| @@ -178,6 +178,8 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler) | |||||||
|  |  | ||||||
| 	handler.serializeString("appearSound", appearSound); | 	handler.serializeString("appearSound", appearSound); | ||||||
| 	handler.serializeString("appearAnimation", appearAnimation); | 	handler.serializeString("appearAnimation", appearAnimation); | ||||||
|  | 	handler.serializeString("triggerSound", triggerSound); | ||||||
|  | 	handler.serializeString("triggerAnimation", triggerAnimation); | ||||||
| 	handler.serializeString("animation", animation); | 	handler.serializeString("animation", animation); | ||||||
|  |  | ||||||
| 	handler.serializeInt("animationYOffset", animationYOffset); | 	handler.serializeInt("animationYOffset", animationYOffset); | ||||||
|   | |||||||
| @@ -81,6 +81,8 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance | |||||||
|  |  | ||||||
| 	std::string appearSound; | 	std::string appearSound; | ||||||
| 	std::string appearAnimation; | 	std::string appearAnimation; | ||||||
|  | 	std::string triggerSound; | ||||||
|  | 	std::string triggerAnimation; | ||||||
| 	std::string animation; | 	std::string animation; | ||||||
|  |  | ||||||
| 	int animationYOffset; | 	int animationYOffset; | ||||||
|   | |||||||
| @@ -43,6 +43,8 @@ void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler) | |||||||
|  |  | ||||||
| 	handler.serializeString("appearSound", appearSound); | 	handler.serializeString("appearSound", appearSound); | ||||||
| 	handler.serializeString("appearAnimation", appearAnimation); | 	handler.serializeString("appearAnimation", appearAnimation); | ||||||
|  | 	handler.serializeString("triggerSound", triggerSound); | ||||||
|  | 	handler.serializeString("triggerAnimation", triggerAnimation); | ||||||
| 	handler.serializeString("animation", animation); | 	handler.serializeString("animation", animation); | ||||||
|  |  | ||||||
| 	handler.serializeInt("offsetY", offsetY); | 	handler.serializeInt("offsetY", offsetY); | ||||||
| @@ -316,6 +318,8 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons | |||||||
|  |  | ||||||
| 		obstacle.appearSound = options.appearSound; | 		obstacle.appearSound = options.appearSound; | ||||||
| 		obstacle.appearAnimation = options.appearAnimation; | 		obstacle.appearAnimation = options.appearAnimation; | ||||||
|  | 		obstacle.triggerSound = options.triggerSound; | ||||||
|  | 		obstacle.triggerAnimation = options.triggerAnimation; | ||||||
| 		obstacle.animation = options.animation; | 		obstacle.animation = options.animation; | ||||||
|  |  | ||||||
| 		obstacle.animationYOffset = options.offsetY; | 		obstacle.animationYOffset = options.offsetY; | ||||||
|   | |||||||
| @@ -31,6 +31,8 @@ public: | |||||||
|  |  | ||||||
| 	std::string appearSound; | 	std::string appearSound; | ||||||
| 	std::string appearAnimation; | 	std::string appearAnimation; | ||||||
|  | 	std::string triggerSound; | ||||||
|  | 	std::string triggerAnimation; | ||||||
| 	std::string animation; | 	std::string animation; | ||||||
|  |  | ||||||
| 	int offsetY; | 	int offsetY; | ||||||
|   | |||||||
| @@ -5459,33 +5459,29 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI | |||||||
| 					if(!sp) | 					if(!sp) | ||||||
| 						COMPLAIN_RET("Invalid obstacle instance"); | 						COMPLAIN_RET("Invalid obstacle instance"); | ||||||
|  |  | ||||||
|  | 					// For the hidden spell created obstacles, e.g. QuickSand, it should be revealed after taking damage | ||||||
|  | 					ObstacleChanges changeInfo; | ||||||
|  | 					changeInfo.id = spellObstacle->uniqueID; | ||||||
|  | 					if (oneTimeObstacle) | ||||||
|  | 						changeInfo.operation = ObstacleChanges::EOperation::ACTIVATE_AND_REMOVE; | ||||||
|  | 					else | ||||||
|  | 						changeInfo.operation = ObstacleChanges::EOperation::ACTIVATE_AND_UPDATE; | ||||||
|  |  | ||||||
|  | 					SpellCreatedObstacle changedObstacle; | ||||||
|  | 					changedObstacle.uniqueID = spellObstacle->uniqueID; | ||||||
|  | 					changedObstacle.revealed = true; | ||||||
|  |  | ||||||
|  | 					changeInfo.data.clear(); | ||||||
|  | 					JsonSerializer ser(nullptr, changeInfo.data); | ||||||
|  | 					ser.serializeStruct("obstacle", changedObstacle); | ||||||
|  |  | ||||||
|  | 					BattleObstaclesChanged bocp; | ||||||
|  | 					bocp.changes.emplace_back(changeInfo); | ||||||
|  | 					sendAndApply(&bocp); | ||||||
|  |  | ||||||
| 					spells::BattleCast battleCast(gs->curB, &caster, spells::Mode::HERO, sp); | 					spells::BattleCast battleCast(gs->curB, &caster, spells::Mode::HERO, sp); | ||||||
| 					battleCast.applyEffects(spellEnv, spells::Target(1, spells::Destination(curStack)), true); | 					battleCast.applyEffects(spellEnv, spells::Target(1, spells::Destination(curStack)), true); | ||||||
|  |  | ||||||
| 					if(oneTimeObstacle) |  | ||||||
| 					{ |  | ||||||
| 						removeObstacle(*obstacle); |  | ||||||
| 				} | 				} | ||||||
| 					else |  | ||||||
| 					{ |  | ||||||
| 						// For the hidden spell created obstacles, e.g. QuickSand, it should be revealed after taking damage |  | ||||||
| 						ObstacleChanges changeInfo; |  | ||||||
| 						changeInfo.id = spellObstacle->uniqueID; |  | ||||||
| 						changeInfo.operation = ObstacleChanges::EOperation::UPDATE; |  | ||||||
|  |  | ||||||
| 						SpellCreatedObstacle changedObstacle; |  | ||||||
| 						changedObstacle.uniqueID = spellObstacle->uniqueID; |  | ||||||
| 						changedObstacle.revealed = true; |  | ||||||
|  |  | ||||||
| 						changeInfo.data.clear(); |  | ||||||
| 						JsonSerializer ser(nullptr, changeInfo.data); |  | ||||||
| 						ser.serializeStruct("obstacle", changedObstacle); |  | ||||||
|  |  | ||||||
| 						BattleObstaclesChanged bocp; |  | ||||||
| 						bocp.changes.emplace_back(changeInfo); |  | ||||||
| 						sendAndApply(&bocp); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		else if(obstacle->obstacleType == CObstacleInstance::MOAT) | 		else if(obstacle->obstacleType == CObstacleInstance::MOAT) | ||||||
| @@ -7225,7 +7221,7 @@ void CGameHandler::handleCheatCode(std::string & cheat, PlayerColor player, cons | |||||||
| void CGameHandler::removeObstacle(const CObstacleInstance & obstacle) | void CGameHandler::removeObstacle(const CObstacleInstance & obstacle) | ||||||
| { | { | ||||||
| 	BattleObstaclesChanged obsRem; | 	BattleObstaclesChanged obsRem; | ||||||
| 	obsRem.changes.emplace_back(obstacle.uniqueID, BattleChanges::EOperation::REMOVE); | 	obsRem.changes.emplace_back(obstacle.uniqueID, ObstacleChanges::EOperation::REMOVE); | ||||||
| 	sendAndApply(&obsRem); | 	sendAndApply(&obsRem); | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user