mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Fix bug: LandMine is not exploding to enemies. (#630)
* The reason is, the mine has attribute hidden=true; when enemy unit moves, the code in BattleInfo.cpp MoveUnit() (line 817) will update the revealed to true; then in the CGameHandler.cpp handleDamageFromObstacle() (line 4846) is checking , and the condition battleIsObstacleVisibleForSide() will return true, so the effect will not be triggerred. Resolution: 1. Remove the "revealed=true" in moveUnit(), and in handleDamageFromObstacle, remove the "const" restrict for obstacle, and then update revealed to true; 2. After the takeDamage function, add a pack "BattleObstaclesChanged" to update the obstacle to be "revealed=true".
This commit is contained in:
@@ -371,6 +371,11 @@ void HypotheticBattle::addObstacle(const ObstacleChanges & changes)
|
||||
//TODO:HypotheticBattle::addObstacle
|
||||
}
|
||||
|
||||
void HypotheticBattle::updateObstacle(const ObstacleChanges& changes)
|
||||
{
|
||||
//TODO:HypotheticBattle::updateObstacle
|
||||
}
|
||||
|
||||
void HypotheticBattle::removeObstacle(uint32_t id)
|
||||
{
|
||||
//TODO:HypotheticBattle::removeObstacle
|
||||
|
@@ -98,6 +98,7 @@ public:
|
||||
void setWallState(int partOfWall, si8 state) override;
|
||||
|
||||
void addObstacle(const ObstacleChanges & changes) override;
|
||||
void updateObstacle(const ObstacleChanges& changes) override;
|
||||
void removeObstacle(uint32_t id) override;
|
||||
|
||||
uint32_t nextUnitId() const override;
|
||||
|
@@ -1535,6 +1535,9 @@ DLL_LINKAGE void BattleObstaclesChanged::applyBattle(IBattleState * battleState)
|
||||
case BattleChanges::EOperation::ADD:
|
||||
battleState->addObstacle(change);
|
||||
break;
|
||||
case BattleChanges::EOperation::UPDATE:
|
||||
battleState->updateObstacle(change);
|
||||
break;
|
||||
default:
|
||||
logNetwork->error("Unknown obstacle operation %d", (int)change.operation);
|
||||
break;
|
||||
|
@@ -809,17 +809,6 @@ void BattleInfo::moveUnit(uint32_t id, BattleHex destination)
|
||||
logGlobal->error("Cannot find stack %d", id);
|
||||
return;
|
||||
}
|
||||
|
||||
for(auto & oi : obstacles)
|
||||
{
|
||||
if((oi->obstacleType == CObstacleInstance::SPELL_CREATED) && vstd::contains(oi->getAffectedTiles(), destination))
|
||||
{
|
||||
SpellCreatedObstacle * obstacle = dynamic_cast<SpellCreatedObstacle*>(oi.get());
|
||||
assert(obstacle);
|
||||
if(obstacle->casterSide != sta->unitSide() && obstacle->hidden)
|
||||
obstacle->revealed = true;
|
||||
}
|
||||
}
|
||||
sta->position = destination;
|
||||
}
|
||||
|
||||
@@ -1029,6 +1018,26 @@ void BattleInfo::addObstacle(const ObstacleChanges & changes)
|
||||
obstacles.push_back(obstacle);
|
||||
}
|
||||
|
||||
void BattleInfo::updateObstacle(const ObstacleChanges& changes)
|
||||
{
|
||||
std::shared_ptr<SpellCreatedObstacle> changedObstacle = std::make_shared<SpellCreatedObstacle>();
|
||||
changedObstacle->fromInfo(changes);
|
||||
|
||||
for(int i = 0; i < obstacles.size(); ++i)
|
||||
{
|
||||
if(obstacles[i]->uniqueID == changes.id) // update this obstacle
|
||||
{
|
||||
SpellCreatedObstacle * spellObstacle = dynamic_cast<SpellCreatedObstacle *>(obstacles[i].get());
|
||||
assert(spellObstacle);
|
||||
|
||||
// Currently we only support to update the "revealed" property
|
||||
spellObstacle->revealed = changedObstacle->revealed;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattleInfo::removeObstacle(uint32_t id)
|
||||
{
|
||||
for(int i=0; i < obstacles.size(); ++i)
|
||||
|
@@ -109,6 +109,7 @@ public:
|
||||
void setWallState(int partOfWall, si8 state) override;
|
||||
|
||||
void addObstacle(const ObstacleChanges & changes) override;
|
||||
void updateObstacle(const ObstacleChanges& changes) override;
|
||||
void removeObstacle(uint32_t id) override;
|
||||
|
||||
void addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool forceAdd);
|
||||
|
@@ -155,8 +155,8 @@ void SpellCreatedObstacle::fromInfo(const ObstacleChanges & info)
|
||||
{
|
||||
uniqueID = info.id;
|
||||
|
||||
if(info.operation != ObstacleChanges::EOperation::ADD)
|
||||
logGlobal->error("ADD operation expected");
|
||||
if(info.operation != ObstacleChanges::EOperation::ADD && info.operation != ObstacleChanges::EOperation::UPDATE)
|
||||
logGlobal->error("ADD or UPDATE operation expected");
|
||||
|
||||
JsonDeserializer deser(nullptr, info.data);
|
||||
deser.serializeStruct("obstacle", *this);
|
||||
@@ -173,6 +173,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
|
||||
handler.serializeInt("casterSide", casterSide);
|
||||
|
||||
handler.serializeBool("hidden", hidden);
|
||||
handler.serializeBool("revealed", revealed);
|
||||
handler.serializeBool("passable", passable);
|
||||
handler.serializeBool("trigger", trigger);
|
||||
handler.serializeBool("trap", trap);
|
||||
|
@@ -87,5 +87,6 @@ public:
|
||||
virtual void setWallState(int partOfWall, si8 state) = 0;
|
||||
|
||||
virtual void addObstacle(const ObstacleChanges & changes) = 0;
|
||||
virtual void updateObstacle(const ObstacleChanges & changes) = 0;
|
||||
virtual void removeObstacle(uint32_t id) = 0;
|
||||
};
|
||||
|
@@ -47,6 +47,7 @@
|
||||
#include "../lib/serializer/CTypeList.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/serializer/Cast.h"
|
||||
#include "../lib/serializer/JsonSerializer.h"
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <boost/thread/xtime.hpp>
|
||||
@@ -4857,8 +4858,29 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
|
||||
battleCast.applyEffects(spellEnv, 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)
|
||||
|
@@ -47,6 +47,7 @@ public:
|
||||
MOCK_METHOD2(setWallState, void(int, si8));
|
||||
MOCK_METHOD1(addObstacle, void(const ObstacleChanges &));
|
||||
MOCK_METHOD1(removeObstacle, void(uint32_t));
|
||||
MOCK_METHOD1(updateObstacle, void(const ObstacleChanges &));
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user