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
|
//TODO:HypotheticBattle::addObstacle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HypotheticBattle::updateObstacle(const ObstacleChanges& changes)
|
||||||
|
{
|
||||||
|
//TODO:HypotheticBattle::updateObstacle
|
||||||
|
}
|
||||||
|
|
||||||
void HypotheticBattle::removeObstacle(uint32_t id)
|
void HypotheticBattle::removeObstacle(uint32_t id)
|
||||||
{
|
{
|
||||||
//TODO:HypotheticBattle::removeObstacle
|
//TODO:HypotheticBattle::removeObstacle
|
||||||
|
@@ -98,6 +98,7 @@ public:
|
|||||||
void setWallState(int partOfWall, si8 state) override;
|
void setWallState(int partOfWall, si8 state) override;
|
||||||
|
|
||||||
void addObstacle(const ObstacleChanges & changes) override;
|
void addObstacle(const ObstacleChanges & changes) override;
|
||||||
|
void updateObstacle(const ObstacleChanges& changes) override;
|
||||||
void removeObstacle(uint32_t id) override;
|
void removeObstacle(uint32_t id) override;
|
||||||
|
|
||||||
uint32_t nextUnitId() const override;
|
uint32_t nextUnitId() const override;
|
||||||
|
@@ -1535,6 +1535,9 @@ 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::UPDATE:
|
||||||
|
battleState->updateObstacle(change);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logNetwork->error("Unknown obstacle operation %d", (int)change.operation);
|
logNetwork->error("Unknown obstacle operation %d", (int)change.operation);
|
||||||
break;
|
break;
|
||||||
|
@@ -809,17 +809,6 @@ void BattleInfo::moveUnit(uint32_t id, BattleHex destination)
|
|||||||
logGlobal->error("Cannot find stack %d", id);
|
logGlobal->error("Cannot find stack %d", id);
|
||||||
return;
|
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;
|
sta->position = destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1029,6 +1018,26 @@ void BattleInfo::addObstacle(const ObstacleChanges & changes)
|
|||||||
obstacles.push_back(obstacle);
|
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)
|
void BattleInfo::removeObstacle(uint32_t id)
|
||||||
{
|
{
|
||||||
for(int i=0; i < obstacles.size(); ++i)
|
for(int i=0; i < obstacles.size(); ++i)
|
||||||
|
@@ -109,6 +109,7 @@ public:
|
|||||||
void setWallState(int partOfWall, si8 state) override;
|
void setWallState(int partOfWall, si8 state) override;
|
||||||
|
|
||||||
void addObstacle(const ObstacleChanges & changes) override;
|
void addObstacle(const ObstacleChanges & changes) override;
|
||||||
|
void updateObstacle(const ObstacleChanges& changes) override;
|
||||||
void removeObstacle(uint32_t id) override;
|
void removeObstacle(uint32_t id) override;
|
||||||
|
|
||||||
void addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool forceAdd);
|
void addOrUpdateUnitBonus(CStack * sta, const Bonus & value, bool forceAdd);
|
||||||
|
@@ -155,8 +155,8 @@ void SpellCreatedObstacle::fromInfo(const ObstacleChanges & info)
|
|||||||
{
|
{
|
||||||
uniqueID = info.id;
|
uniqueID = info.id;
|
||||||
|
|
||||||
if(info.operation != ObstacleChanges::EOperation::ADD)
|
if(info.operation != ObstacleChanges::EOperation::ADD && info.operation != ObstacleChanges::EOperation::UPDATE)
|
||||||
logGlobal->error("ADD operation expected");
|
logGlobal->error("ADD or UPDATE operation expected");
|
||||||
|
|
||||||
JsonDeserializer deser(nullptr, info.data);
|
JsonDeserializer deser(nullptr, info.data);
|
||||||
deser.serializeStruct("obstacle", *this);
|
deser.serializeStruct("obstacle", *this);
|
||||||
@@ -173,6 +173,7 @@ void SpellCreatedObstacle::serializeJson(JsonSerializeFormat & handler)
|
|||||||
handler.serializeInt("casterSide", casterSide);
|
handler.serializeInt("casterSide", casterSide);
|
||||||
|
|
||||||
handler.serializeBool("hidden", hidden);
|
handler.serializeBool("hidden", hidden);
|
||||||
|
handler.serializeBool("revealed", revealed);
|
||||||
handler.serializeBool("passable", passable);
|
handler.serializeBool("passable", passable);
|
||||||
handler.serializeBool("trigger", trigger);
|
handler.serializeBool("trigger", trigger);
|
||||||
handler.serializeBool("trap", trap);
|
handler.serializeBool("trap", trap);
|
||||||
|
@@ -87,5 +87,6 @@ public:
|
|||||||
virtual void setWallState(int partOfWall, si8 state) = 0;
|
virtual void setWallState(int partOfWall, si8 state) = 0;
|
||||||
|
|
||||||
virtual void addObstacle(const ObstacleChanges & changes) = 0;
|
virtual void addObstacle(const ObstacleChanges & changes) = 0;
|
||||||
|
virtual void updateObstacle(const ObstacleChanges & changes) = 0;
|
||||||
virtual void removeObstacle(uint32_t id) = 0;
|
virtual void removeObstacle(uint32_t id) = 0;
|
||||||
};
|
};
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include "../lib/serializer/CTypeList.h"
|
#include "../lib/serializer/CTypeList.h"
|
||||||
#include "../lib/serializer/Connection.h"
|
#include "../lib/serializer/Connection.h"
|
||||||
#include "../lib/serializer/Cast.h"
|
#include "../lib/serializer/Cast.h"
|
||||||
|
#include "../lib/serializer/JsonSerializer.h"
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <boost/thread/xtime.hpp>
|
#include <boost/thread/xtime.hpp>
|
||||||
@@ -4857,7 +4858,28 @@ bool CGameHandler::handleDamageFromObstacle(const CStack * curStack, bool stackI
|
|||||||
battleCast.applyEffects(spellEnv, true);
|
battleCast.applyEffects(spellEnv, true);
|
||||||
|
|
||||||
if(oneTimeObstacle)
|
if(oneTimeObstacle)
|
||||||
|
{
|
||||||
removeObstacle(*obstacle);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,7 @@ public:
|
|||||||
MOCK_METHOD2(setWallState, void(int, si8));
|
MOCK_METHOD2(setWallState, void(int, si8));
|
||||||
MOCK_METHOD1(addObstacle, void(const ObstacleChanges &));
|
MOCK_METHOD1(addObstacle, void(const ObstacleChanges &));
|
||||||
MOCK_METHOD1(removeObstacle, void(uint32_t));
|
MOCK_METHOD1(removeObstacle, void(uint32_t));
|
||||||
|
MOCK_METHOD1(updateObstacle, void(const ObstacleChanges &));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user