浏览代码

Exploded mines now send ACTIVATE flag to client to play effect

Ivan Savenko 2 年之前
父节点
当前提交
52fc5b3c39

+ 2 - 21
client/battle/BattleObstacleController.cpp

@@ -72,10 +72,6 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi)
 
 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)
 	{
 		auto spellObstacle = dynamic_cast<const SpellCreatedObstacle*>(oi.get());
@@ -83,7 +79,6 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 		if (!spellObstacle)
 		{
 			logGlobal->error("I don't know how to animate appearing obstacle of type %d", (int)oi->obstacleType);
-			obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin());
 			continue;
 		}
 
@@ -92,10 +87,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 
 		auto first = animation->getImage(0, 0);
 		if(!first)
-		{
-			obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin());
 			continue;
-		}
 
 		//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
@@ -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
 		owner.waitForAnimationCondition(EAnimationEvents::ACTION, false);
 
-		obstaclesBeingPlaced.erase(obstaclesBeingPlaced.begin());
 		loadObstacleImage(*spellObstacle);
 	}
 }
@@ -150,19 +141,9 @@ std::shared_ptr<IImage> BattleObstacleController::getObstacleImage(const CObstac
 	int frameIndex = (owner.animCount+1) *25 / owner.getAnimSpeed();
 	std::shared_ptr<CAnimation> animation;
 
+	// obstacle is not loaded yet, don't show anything
 	if (obstacleAnimations.count(oi.uniqueID) == 0)
-	{
-		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);
-		}
-	}
+		return nullptr;
 
 	animation = obstacleAnimations[oi.uniqueID];
 	assert(animation);

+ 0 - 4
client/battle/BattleObstacleController.h

@@ -35,10 +35,6 @@ class BattleObstacleController
 	/// list of all obstacles that are currently being rendered
 	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);
 
 	std::shared_ptr<IImage> getObstacleImage(const CObstacleInstance & oi);

+ 1 - 1
client/battle/BattleStacksController.cpp

@@ -187,7 +187,7 @@ void BattleStacksController::stackReset(const CStack * stack)
 void BattleStacksController::stackAdded(const CStack * stack, bool instant)
 {
 	// 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
 

+ 7 - 3
config/spells/other.json

@@ -57,7 +57,7 @@
 		"targetType" : "NO_TARGET",
 
 		"sounds": {
-			"cast": "" // no casting sound, only obstacle placement sound
+			"cast": "", // no casting sound, only obstacle placement sound
 		},
 		"levels" : {
 			"base":{
@@ -75,12 +75,16 @@
 						"attacker" :{
 							"animation" : "C09SPF1",
 							"appearAnimation" : "C09SPF0",
-							"appearSound" : "LANDMINE"
+							"appearSound" : "LANDMINE",
+							"triggerAnimation" : "C09SPF3",
+							"triggerSound" : "LANDKILL"
 						},
 						"defender" :{
 							"animation" : "C09SPF1",
 							"appearAnimation" : "C09SPF0",
-							"appearSound" : "LANDMINE"
+							"appearSound" : "LANDMINE",
+							"triggerAnimation" : "C09SPF3",
+							"triggerSound" : "LANDKILL"
 						}
 					},
 					"damage":{

+ 3 - 1
lib/NetPacksBase.h

@@ -278,7 +278,9 @@ public:
 		ADD,
 		RESET_STATE,
 		UPDATE,
-		REMOVE
+		REMOVE,
+		ACTIVATE_AND_UPDATE,
+		ACTIVATE_AND_REMOVE
 	};
 
 	JsonNode data;

+ 1 - 0
lib/NetPacksLib.cpp

@@ -1663,6 +1663,7 @@ DLL_LINKAGE void BattleObstaclesChanged::applyBattle(IBattleState * battleState)
 		case BattleChanges::EOperation::ADD:
 			battleState->addObstacle(change);
 			break;
+		case BattleChanges::EOperation::ACTIVATE_AND_UPDATE:
 		case BattleChanges::EOperation::UPDATE:
 			battleState->updateObstacle(change);
 			break;

+ 3 - 2
lib/ObstacleHandler.h

@@ -32,7 +32,7 @@ public:
 	Obstacle obstacle;
 	si32 iconIndex;
 	std::string identifier;
-	std::string appearSound, appearAnimation, animation, dissapearAnimation;
+	std::string appearSound, appearAnimation, triggerAnimation, triggerSound, animation;
 	std::vector<TerrainId> allowedTerrains;
 	std::vector<std::string> allowedSpecialBfields;
 	
@@ -63,7 +63,8 @@ public:
 		h & animation;
 		h & appearSound;
 		h & appearAnimation;
-		h & dissapearAnimation;
+		h & triggerSound;
+		h & triggerAnimation;
 		h & allowedTerrains;
 		h & allowedSpecialBfields;
 		h & isAbsoluteObstacle;

+ 2 - 0
lib/battle/CObstacleInstance.cpp

@@ -178,6 +178,8 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
 
 	handler.serializeString("appearSound", appearSound);
 	handler.serializeString("appearAnimation", appearAnimation);
+	handler.serializeString("triggerSound", triggerSound);
+	handler.serializeString("triggerAnimation", triggerAnimation);
 	handler.serializeString("animation", animation);
 
 	handler.serializeInt("animationYOffset", animationYOffset);

+ 2 - 0
lib/battle/CObstacleInstance.h

@@ -81,6 +81,8 @@ struct DLL_LINKAGE SpellCreatedObstacle : CObstacleInstance
 
 	std::string appearSound;
 	std::string appearAnimation;
+	std::string triggerSound;
+	std::string triggerAnimation;
 	std::string animation;
 
 	int animationYOffset;

+ 4 - 0
lib/spells/effects/Obstacle.cpp

@@ -43,6 +43,8 @@ void ObstacleSideOptions::serializeJson(JsonSerializeFormat & handler)
 
 	handler.serializeString("appearSound", appearSound);
 	handler.serializeString("appearAnimation", appearAnimation);
+	handler.serializeString("triggerSound", triggerSound);
+	handler.serializeString("triggerAnimation", triggerAnimation);
 	handler.serializeString("animation", animation);
 
 	handler.serializeInt("offsetY", offsetY);
@@ -316,6 +318,8 @@ void Obstacle::placeObstacles(ServerCallback * server, const Mechanics * m, cons
 
 		obstacle.appearSound = options.appearSound;
 		obstacle.appearAnimation = options.appearAnimation;
+		obstacle.triggerSound = options.triggerSound;
+		obstacle.triggerAnimation = options.triggerAnimation;
 		obstacle.animation = options.animation;
 
 		obstacle.animationYOffset = options.offsetY;

+ 2 - 0
lib/spells/effects/Obstacle.h

@@ -31,6 +31,8 @@ public:
 
 	std::string appearSound;
 	std::string appearAnimation;
+	std::string triggerSound;
+	std::string triggerAnimation;
 	std::string animation;
 
 	int offsetY;

+ 20 - 24
server/CGameHandler.cpp

@@ -5459,33 +5459,29 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
 					if(!sp)
 						COMPLAIN_RET("Invalid obstacle instance");
 
-					spells::BattleCast battleCast(gs->curB, &caster, spells::Mode::HERO, sp);
-					battleCast.applyEffects(spellEnv, spells::Target(1, spells::Destination(curStack)), true);
-
-					if(oneTimeObstacle)
-					{
-						removeObstacle(*obstacle);
-				}
+					// 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
-					{
-						// 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;
+						changeInfo.operation = ObstacleChanges::EOperation::ACTIVATE_AND_UPDATE;
 
-						SpellCreatedObstacle changedObstacle;
-						changedObstacle.uniqueID = spellObstacle->uniqueID;
-						changedObstacle.revealed = true;
+					SpellCreatedObstacle changedObstacle;
+					changedObstacle.uniqueID = spellObstacle->uniqueID;
+					changedObstacle.revealed = true;
 
-						changeInfo.data.clear();
-						JsonSerializer ser(nullptr, changeInfo.data);
-						ser.serializeStruct("obstacle", changedObstacle);
+					changeInfo.data.clear();
+					JsonSerializer ser(nullptr, changeInfo.data);
+					ser.serializeStruct("obstacle", changedObstacle);
 
-						BattleObstaclesChanged bocp;
-						bocp.changes.emplace_back(changeInfo);
-						sendAndApply(&bocp);
-			}
-		}
+					BattleObstaclesChanged bocp;
+					bocp.changes.emplace_back(changeInfo);
+					sendAndApply(&bocp);
+
+					spells::BattleCast battleCast(gs->curB, &caster, spells::Mode::HERO, sp);
+					battleCast.applyEffects(spellEnv, spells::Target(1, spells::Destination(curStack)), true);
+				}
 			}
 		}
 		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)
 {
 	BattleObstaclesChanged obsRem;
-	obsRem.changes.emplace_back(obstacle.uniqueID, BattleChanges::EOperation::REMOVE);
+	obsRem.changes.emplace_back(obstacle.uniqueID, ObstacleChanges::EOperation::REMOVE);
 	sendAndApply(&obsRem);
 }