mirror of
https://github.com/vcmi/vcmi.git
synced 2026-05-16 09:28:24 +02:00
Fixes for code review issues
This commit is contained in:
@@ -563,19 +563,19 @@ void CBattleInterface::deactivate()
|
|||||||
|
|
||||||
void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
||||||
{
|
{
|
||||||
if (key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
|
if(key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
|
||||||
{
|
{
|
||||||
if (settings["battle"]["showQueue"].Bool()) //hide queue
|
if(settings["battle"]["showQueue"].Bool()) //hide queue
|
||||||
hideQueue();
|
hideQueue();
|
||||||
else
|
else
|
||||||
showQueue();
|
showQueue();
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (key.keysym.sym == SDLK_f && key.state == SDL_PRESSED)
|
else if(key.keysym.sym == SDLK_f && key.state == SDL_PRESSED)
|
||||||
{
|
{
|
||||||
enterCreatureCastingMode();
|
enterCreatureCastingMode();
|
||||||
}
|
}
|
||||||
else if (key.keysym.sym == SDLK_ESCAPE)
|
else if(key.keysym.sym == SDLK_ESCAPE)
|
||||||
{
|
{
|
||||||
if(!battleActionsStarted)
|
if(!battleActionsStarted)
|
||||||
CCS->soundh->stopSound(battleIntroSoundChannel);
|
CCS->soundh->stopSound(battleIntroSoundChannel);
|
||||||
@@ -788,14 +788,14 @@ void CBattleInterface::bOptionsf()
|
|||||||
|
|
||||||
void CBattleInterface::bSurrenderf()
|
void CBattleInterface::bSurrenderf()
|
||||||
{
|
{
|
||||||
if (spellDestSelectMode) //we are casting a spell
|
if(spellDestSelectMode) //we are casting a spell
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int cost = curInt->cb->battleGetSurrenderCost();
|
int cost = curInt->cb->battleGetSurrenderCost();
|
||||||
if (cost >= 0)
|
if(cost >= 0)
|
||||||
{
|
{
|
||||||
std::string enemyHeroName = curInt->cb->battleGetEnemyHero().name;
|
std::string enemyHeroName = curInt->cb->battleGetEnemyHero().name;
|
||||||
if (enemyHeroName.empty())
|
if(enemyHeroName.empty())
|
||||||
{
|
{
|
||||||
logGlobal->warn("Surrender performed without enemy hero, should not happen!");
|
logGlobal->warn("Surrender performed without enemy hero, should not happen!");
|
||||||
enemyHeroName = "#ENEMY#";
|
enemyHeroName = "#ENEMY#";
|
||||||
@@ -1462,14 +1462,9 @@ void CBattleInterface::displayEffect(ui32 effect, BattleHex destTile)
|
|||||||
addNewAnim(new CEffectAnimation(this, customAnim, destTile));
|
addNewAnim(new CEffectAnimation(this, customAnim, destTile));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::displaySpellCast(SpellID spellID, BattleHex destinationTile)
|
void CBattleInterface::displaySpellAnimationQueue(const CSpell::TAnimationQueue & q, BattleHex destinationTile)
|
||||||
{
|
{
|
||||||
const CSpell * spell = spellID.toSpell();
|
for(const CSpell::TAnimation & animation : q)
|
||||||
|
|
||||||
if(spell == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(const CSpell::TAnimation & animation : spell->animationInfo.cast)
|
|
||||||
{
|
{
|
||||||
if(animation.pause > 0)
|
if(animation.pause > 0)
|
||||||
addNewAnim(new CDummyAnimation(this, animation.pause));
|
addNewAnim(new CDummyAnimation(this, animation.pause));
|
||||||
@@ -1478,37 +1473,28 @@ void CBattleInterface::displaySpellCast(SpellID spellID, BattleHex destinationTi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CBattleInterface::displaySpellCast(SpellID spellID, BattleHex destinationTile)
|
||||||
|
{
|
||||||
|
const CSpell * spell = spellID.toSpell();
|
||||||
|
|
||||||
|
if(spell)
|
||||||
|
displaySpellAnimationQueue(spell->animationInfo.cast, destinationTile);
|
||||||
|
}
|
||||||
|
|
||||||
void CBattleInterface::displaySpellEffect(SpellID spellID, BattleHex destinationTile)
|
void CBattleInterface::displaySpellEffect(SpellID spellID, BattleHex destinationTile)
|
||||||
{
|
{
|
||||||
const CSpell *spell = spellID.toSpell();
|
const CSpell *spell = spellID.toSpell();
|
||||||
|
|
||||||
if(spell == nullptr)
|
if(spell)
|
||||||
return;
|
displaySpellAnimationQueue(spell->animationInfo.affect, destinationTile);
|
||||||
|
|
||||||
for(const CSpell::TAnimation & animation : spell->animationInfo.affect)
|
|
||||||
{
|
|
||||||
if(animation.pause > 0)
|
|
||||||
addNewAnim(new CDummyAnimation(this, animation.pause));
|
|
||||||
else
|
|
||||||
addNewAnim(new CEffectAnimation(this, animation.resourceName, destinationTile, false, animation.verticalPosition == VerticalPosition::BOTTOM));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::displaySpellHit(SpellID spellID, BattleHex destinationTile)
|
void CBattleInterface::displaySpellHit(SpellID spellID, BattleHex destinationTile)
|
||||||
{
|
{
|
||||||
const CSpell * spell = spellID.toSpell();
|
const CSpell * spell = spellID.toSpell();
|
||||||
|
|
||||||
if(spell == nullptr)
|
if(spell)
|
||||||
return;
|
displaySpellAnimationQueue(spell->animationInfo.hit, destinationTile);
|
||||||
|
|
||||||
for(const CSpell::TAnimation & animation : spell->animationInfo.hit)
|
|
||||||
{
|
|
||||||
if(animation.pause > 0)
|
|
||||||
addNewAnim(new CDummyAnimation(this, animation.pause));
|
|
||||||
else
|
|
||||||
addNewAnim(new CEffectAnimation(this, animation.resourceName, destinationTile, false, animation.verticalPosition == VerticalPosition::BOTTOM));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
||||||
@@ -1704,13 +1690,12 @@ void CBattleInterface::enterCreatureCastingMode()
|
|||||||
spells::Target target;
|
spells::Target target;
|
||||||
target.emplace_back();
|
target.emplace_back();
|
||||||
|
|
||||||
|
|
||||||
spells::BattleCast cast(curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
|
spells::BattleCast cast(curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
|
||||||
|
|
||||||
auto m = spell->battleMechanics(&cast);
|
auto m = spell->battleMechanics(&cast);
|
||||||
spells::detail::ProblemImpl ignored;
|
spells::detail::ProblemImpl ignored;
|
||||||
|
|
||||||
const bool isCastingPossible = m->canBeCastAt(ignored, target);
|
const bool isCastingPossible = m->canBeCastAt(target, ignored);
|
||||||
|
|
||||||
if (isCastingPossible)
|
if (isCastingPossible)
|
||||||
{
|
{
|
||||||
@@ -2543,7 +2528,7 @@ bool CBattleInterface::isCastingPossibleHere(const CStack *sactive, const CStack
|
|||||||
auto m = sp->battleMechanics(&cast);
|
auto m = sp->battleMechanics(&cast);
|
||||||
spells::detail::ProblemImpl problem; //todo: display problem in status bar
|
spells::detail::ProblemImpl problem; //todo: display problem in status bar
|
||||||
|
|
||||||
isCastingPossible = m->canBeCastAt(problem, target);
|
isCastingPossible = m->canBeCastAt(target, problem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ public:
|
|||||||
|
|
||||||
void displayEffect(ui32 effect, BattleHex destTile); //displays custom effect on the battlefield
|
void displayEffect(ui32 effect, BattleHex destTile); //displays custom effect on the battlefield
|
||||||
|
|
||||||
|
void displaySpellAnimationQueue(const CSpell::TAnimationQueue & q, BattleHex destinationTile);
|
||||||
void displaySpellCast(SpellID spellID, BattleHex destinationTile); //displays spell`s cast animation
|
void displaySpellCast(SpellID spellID, BattleHex destinationTile); //displays spell`s cast animation
|
||||||
void displaySpellEffect(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation
|
void displaySpellEffect(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation
|
||||||
void displaySpellHit(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation
|
void displaySpellHit(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation
|
||||||
|
|||||||
@@ -111,12 +111,14 @@ void CBuildingRect::hover(bool on)
|
|||||||
|
|
||||||
void CBuildingRect::clickLeft(tribool down, bool previousState)
|
void CBuildingRect::clickLeft(tribool down, bool previousState)
|
||||||
{
|
{
|
||||||
if( previousState && getBuilding() && area && !down && (parent->selectedBuilding==this))
|
if(previousState && getBuilding() && area && !down && (parent->selectedBuilding==this))
|
||||||
if (!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
|
{
|
||||||
|
if(!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y)) //inside building image
|
||||||
{
|
{
|
||||||
auto building = getBuilding();
|
auto building = getBuilding();
|
||||||
parent->buildingClicked(building->bid, building->subId, building->upgrade);
|
parent->buildingClicked(building->bid, building->subId, building->upgrade);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBuildingRect::clickRight(tribool down, bool previousState)
|
void CBuildingRect::clickRight(tribool down, bool previousState)
|
||||||
@@ -606,8 +608,7 @@ void CCastleBuildings::recreate()
|
|||||||
|
|
||||||
const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b)
|
const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b)
|
||||||
{
|
{
|
||||||
return build->getDistance(a->building->bid)
|
return build->getDistance(a->building->bid) < build->getDistance(b->building->bid);
|
||||||
< build->getDistance(b->building->bid);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
buildings.push_back(std::make_shared<CBuildingRect>(this, town, toAdd));
|
buildings.push_back(std::make_shared<CBuildingRect>(this, town, toAdd));
|
||||||
|
|||||||
@@ -32,20 +32,20 @@ public:
|
|||||||
using PostHandler = std::function<void(const E &)>;
|
using PostHandler = std::function<void(const E &)>;
|
||||||
using BusTag = const void *;
|
using BusTag = const void *;
|
||||||
|
|
||||||
std::unique_ptr<EventSubscription> subscribeBefore(BusTag tag, PreHandler && cb)
|
std::unique_ptr<EventSubscription> subscribeBefore(BusTag tag, PreHandler && handler)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::shared_mutex> lock(mutex);
|
boost::unique_lock<boost::shared_mutex> lock(mutex);
|
||||||
|
|
||||||
auto storage = std::make_shared<PreHandlerStorage>(std::move(cb));
|
auto storage = std::make_shared<PreHandlerStorage>(std::move(handler));
|
||||||
preHandlers[tag].push_back(storage);
|
preHandlers[tag].push_back(storage);
|
||||||
return make_unique<PreSubscription>(tag, storage);
|
return make_unique<PreSubscription>(tag, storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EventSubscription> subscribeAfter(BusTag tag, PostHandler && cb)
|
std::unique_ptr<EventSubscription> subscribeAfter(BusTag tag, PostHandler && handler)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::shared_mutex> lock(mutex);
|
boost::unique_lock<boost::shared_mutex> lock(mutex);
|
||||||
|
|
||||||
auto storage = std::make_shared<PostHandlerStorage>(std::move(cb));
|
auto storage = std::make_shared<PostHandlerStorage>(std::move(handler));
|
||||||
postHandlers[tag].push_back(storage);
|
postHandlers[tag].push_back(storage);
|
||||||
return make_unique<PostSubscription>(tag, storage);
|
return make_unique<PostSubscription>(tag, storage);
|
||||||
}
|
}
|
||||||
@@ -84,18 +84,18 @@ private:
|
|||||||
class HandlerStorage
|
class HandlerStorage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit HandlerStorage(T && cb_)
|
explicit HandlerStorage(T && handler_)
|
||||||
: cb(cb_)
|
: handler(handler_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
void operator()(E & event)
|
void operator()(E & event)
|
||||||
{
|
{
|
||||||
cb(event);
|
handler(event);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
T cb;
|
T handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
using PreHandlerStorage = HandlerStorage<PreHandler>;
|
using PreHandlerStorage = HandlerStorage<PreHandler>;
|
||||||
@@ -104,8 +104,8 @@ private:
|
|||||||
class PreSubscription : public EventSubscription
|
class PreSubscription : public EventSubscription
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PreSubscription(BusTag tag_, std::shared_ptr<PreHandlerStorage> cb_)
|
PreSubscription(BusTag tag_, std::shared_ptr<PreHandlerStorage> handler_)
|
||||||
: cb(cb_),
|
: handler(handler_),
|
||||||
tag(tag_)
|
tag(tag_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -113,18 +113,18 @@ private:
|
|||||||
virtual ~PreSubscription()
|
virtual ~PreSubscription()
|
||||||
{
|
{
|
||||||
auto registry = E::getRegistry();
|
auto registry = E::getRegistry();
|
||||||
registry->unsubscribe(tag, cb, registry->preHandlers);
|
registry->unsubscribe(tag, handler, registry->preHandlers);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
BusTag tag;
|
BusTag tag;
|
||||||
std::shared_ptr<PreHandlerStorage> cb;
|
std::shared_ptr<PreHandlerStorage> handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PostSubscription : public EventSubscription
|
class PostSubscription : public EventSubscription
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PostSubscription(BusTag tag_, std::shared_ptr<PostHandlerStorage> cb_)
|
PostSubscription(BusTag tag_, std::shared_ptr<PostHandlerStorage> handler_)
|
||||||
: cb(cb_),
|
: handler(handler_),
|
||||||
tag(tag_)
|
tag(tag_)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -132,11 +132,11 @@ private:
|
|||||||
virtual ~PostSubscription()
|
virtual ~PostSubscription()
|
||||||
{
|
{
|
||||||
auto registry = E::getRegistry();
|
auto registry = E::getRegistry();
|
||||||
registry->unsubscribe(tag, cb, registry->postHandlers);
|
registry->unsubscribe(tag, handler, registry->postHandlers);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
BusTag tag;
|
BusTag tag;
|
||||||
std::shared_ptr<PostHandlerStorage> cb;
|
std::shared_ptr<PostHandlerStorage> handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_mutex mutex;
|
boost::shared_mutex mutex;
|
||||||
|
|||||||
+4
-4
@@ -697,7 +697,7 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
|
|||||||
|
|
||||||
for(const TModID & dep : mod.dependencies)
|
for(const TModID & dep : mod.dependencies)
|
||||||
{
|
{
|
||||||
if (!vstd::contains(input, dep))
|
if(!vstd::contains(input, dep))
|
||||||
{
|
{
|
||||||
logMod->error("Error: Mod %s requires missing %s!", mod.name, dep);
|
logMod->error("Error: Mod %s requires missing %s!", mod.name, dep);
|
||||||
return false;
|
return false;
|
||||||
@@ -706,14 +706,14 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
|
|||||||
|
|
||||||
for(const TModID & conflicting : mod.conflicts)
|
for(const TModID & conflicting : mod.conflicts)
|
||||||
{
|
{
|
||||||
if (vstd::contains(input, conflicting))
|
if(vstd::contains(input, conflicting))
|
||||||
{
|
{
|
||||||
logMod->error("Error: Mod %s conflicts with %s!", mod.name, allMods.at(conflicting).name);
|
logMod->error("Error: Mod %s conflicts with %s!", mod.name, allMods.at(conflicting).name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasCircularDependency(id))
|
if(hasCircularDependency(id))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -757,7 +757,7 @@ std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> modsT
|
|||||||
}
|
}
|
||||||
boost::range::sort(modsToResolve);
|
boost::range::sort(modsToResolve);
|
||||||
return modsToResolve;
|
return modsToResolve;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> CModHandler::getModList(std::string path)
|
std::vector<std::string> CModHandler::getModList(std::string path)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -560,21 +560,23 @@ R CTownHandler::getMappedValue(const K key, const R defval, const std::map<K, R>
|
|||||||
|
|
||||||
template<typename R>
|
template<typename R>
|
||||||
R CTownHandler::getMappedValue(const JsonNode & node, const R defval, const std::map<std::string, R> & map, bool required)
|
R CTownHandler::getMappedValue(const JsonNode & node, const R defval, const std::map<std::string, R> & map, bool required)
|
||||||
{
|
{
|
||||||
if(!node.isNull() && node.getType() == JsonNode::JsonType::DATA_STRING)
|
if(!node.isNull() && node.getType() == JsonNode::JsonType::DATA_STRING)
|
||||||
return getMappedValue<R, std::string>(node.String(), defval, map, required);
|
return getMappedValue<R, std::string>(node.String(), defval, map, required);
|
||||||
return defval;
|
return defval;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building)
|
void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building)
|
||||||
{
|
{
|
||||||
std::shared_ptr<Bonus> b;
|
std::shared_ptr<Bonus> b;
|
||||||
static TPropagatorPtr playerPropagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::ENodeTypes::PLAYER);
|
static TPropagatorPtr playerPropagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::ENodeTypes::PLAYER);
|
||||||
|
|
||||||
if(building->subId == BuildingSubID::NONE)
|
if(building->subId == BuildingSubID::NONE)
|
||||||
{
|
{
|
||||||
if(building->bid == BuildingID::TAVERN)
|
if(building->bid == BuildingID::TAVERN)
|
||||||
|
{
|
||||||
b = createBonus(building, Bonus::MORALE, +1);
|
b = createBonus(building, Bonus::MORALE, +1);
|
||||||
|
}
|
||||||
else if(building->bid == BuildingID::GRAIL
|
else if(building->bid == BuildingID::GRAIL
|
||||||
&& building->town->faction != nullptr
|
&& building->town->faction != nullptr
|
||||||
&& boost::algorithm::ends_with(building->town->faction->identifier, ":cove"))
|
&& boost::algorithm::ends_with(building->town->faction->identifier, ":cove"))
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ void ScriptImpl::resolveHost()
|
|||||||
else if(sourcePathId.getType() == EResType::LUA)
|
else if(sourcePathId.getType() == EResType::LUA)
|
||||||
host = owner->lua;
|
host = owner->lua;
|
||||||
else
|
else
|
||||||
throw std::runtime_error("Unknown script language in:"+sourcePath);
|
throw std::runtime_error("Unknown script language in:" + sourcePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
PoolImpl::PoolImpl(const Environment * ENV)
|
PoolImpl::PoolImpl(const Environment * ENV)
|
||||||
@@ -217,7 +217,8 @@ std::vector<JsonNode> ScriptHandler::loadLegacyData(size_t dataSize)
|
|||||||
return std::vector<JsonNode>();
|
return std::vector<JsonNode>();
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptPtr ScriptHandler::loadFromJson(vstd::CLoggerBase * logger, const std::string & scope, const JsonNode & json, const std::string & identifier) const
|
ScriptPtr ScriptHandler::loadFromJson(vstd::CLoggerBase * logger, const std::string & scope,
|
||||||
|
const JsonNode & json, const std::string & identifier) const
|
||||||
{
|
{
|
||||||
ScriptPtr ret = std::make_shared<ScriptImpl>(this);
|
ScriptPtr ret = std::make_shared<ScriptImpl>(this);
|
||||||
|
|
||||||
|
|||||||
@@ -1407,12 +1407,10 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
|
|||||||
{
|
{
|
||||||
auto st = battleGetUnitByPos(tile, true);
|
auto st = battleGetUnitByPos(tile, true);
|
||||||
if(st && battleMatchOwner(st, attacker)) //only hostile stacks - does it work well with Berserk?
|
if(st && battleMatchOwner(st, attacker)) //only hostile stacks - does it work well with Berserk?
|
||||||
{
|
|
||||||
at.hostileCreaturePositions.insert(tile);
|
at.hostileCreaturePositions.insert(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(attacker->hasBonusOfType(Bonus::WIDE_BREATH))
|
if(attacker->hasBonusOfType(Bonus::WIDE_BREATH))
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> hexes = destinationTile.neighbouringTiles();
|
std::vector<BattleHex> hexes = destinationTile.neighbouringTiles();
|
||||||
@@ -1429,15 +1427,13 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
|
|||||||
//friendly stacks can also be damaged by Dragon Breath
|
//friendly stacks can also be damaged by Dragon Breath
|
||||||
auto st = battleGetUnitByPos(tile, true);
|
auto st = battleGetUnitByPos(tile, true);
|
||||||
if(st && st != attacker)
|
if(st && st != attacker)
|
||||||
{
|
|
||||||
at.friendlyCreaturePositions.insert(tile);
|
at.friendlyCreaturePositions.insert(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else if(attacker->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH))
|
else if(attacker->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH))
|
||||||
{
|
{
|
||||||
int pos = BattleHex::mutualPosition(destinationTile, hex);
|
int pos = BattleHex::mutualPosition(destinationTile, hex);
|
||||||
if (pos > -1) //only adjacent hexes are subject of dragon breath calculation
|
if(pos > -1) //only adjacent hexes are subject of dragon breath calculation
|
||||||
{
|
{
|
||||||
std::vector<BattleHex> hexes; //only one, in fact
|
std::vector<BattleHex> hexes; //only one, in fact
|
||||||
int pseudoVector = destinationTile.hex - hex;
|
int pseudoVector = destinationTile.hex - hex;
|
||||||
@@ -1462,7 +1458,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
|
|||||||
{
|
{
|
||||||
//friendly stacks can also be damaged by Dragon Breath
|
//friendly stacks can also be damaged by Dragon Breath
|
||||||
auto st = battleGetUnitByPos(tile, true);
|
auto st = battleGetUnitByPos(tile, true);
|
||||||
if (st != nullptr)
|
if(st != nullptr)
|
||||||
at.friendlyCreaturePositions.insert(tile);
|
at.friendlyCreaturePositions.insert(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -850,7 +850,7 @@ void CGTownInstance::updateBonusingBuildings() //update to version 792
|
|||||||
//firstly, update subtype for the Bonusing objects, which are already stored in the bonusing list
|
//firstly, update subtype for the Bonusing objects, which are already stored in the bonusing list
|
||||||
for(auto building : bonusingBuildings) //no garrison bonuses here, only week and visiting bonuses
|
for(auto building : bonusingBuildings) //no garrison bonuses here, only week and visiting bonuses
|
||||||
{
|
{
|
||||||
switch (this->town->faction->index)
|
switch(this->town->faction->index)
|
||||||
{
|
{
|
||||||
case ETownType::CASTLE:
|
case ETownType::CASTLE:
|
||||||
building->setBuildingSubtype(BuildingSubID::STABLES);
|
building->setBuildingSubtype(BuildingSubID::STABLES);
|
||||||
@@ -1264,13 +1264,13 @@ void CGTownInstance::recreateBuildingsBonuses()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(auto bonus : building->buildingBonuses)
|
for(auto bonus : building->buildingBonuses)
|
||||||
{
|
{
|
||||||
if(bonus->propagator != nullptr && bonus->propagator->getPropagatorType() == ALL_CREATURES)
|
if(bonus->propagator != nullptr && bonus->propagator->getPropagatorType() == ALL_CREATURES)
|
||||||
VLC->creh->addBonusForAllCreatures(bonus);
|
VLC->creh->addBonusForAllCreatures(bonus);
|
||||||
else
|
else
|
||||||
addNewBonus(bonus);
|
addNewBonus(bonus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGTownInstance::setVisitingHero(CGHeroInstance *h)
|
void CGTownInstance::setVisitingHero(CGHeroInstance *h)
|
||||||
@@ -1353,11 +1353,11 @@ int CGTownInstance::getTownLevel() const
|
|||||||
// count all buildings that are not upgrades
|
// count all buildings that are not upgrades
|
||||||
int level = 0;
|
int level = 0;
|
||||||
|
|
||||||
for (const auto & bid : builtBuildings)
|
for(const auto & bid : builtBuildings)
|
||||||
{
|
{
|
||||||
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
|
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
|
||||||
level++;
|
level++;
|
||||||
}
|
}
|
||||||
return level;
|
return level;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1685,7 +1685,7 @@ void COPWBonus::setProperty(ui8 what, ui32 val)
|
|||||||
void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
||||||
{
|
{
|
||||||
ObjectInstanceID heroID = h->id;
|
ObjectInstanceID heroID = h->id;
|
||||||
if (town->hasBuilt(bID))
|
if(town->hasBuilt(bID))
|
||||||
{
|
{
|
||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
iw.player = h->tempOwner;
|
iw.player = h->tempOwner;
|
||||||
@@ -1693,7 +1693,7 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
|||||||
switch (this->bType)
|
switch (this->bType)
|
||||||
{
|
{
|
||||||
case BuildingSubID::STABLES:
|
case BuildingSubID::STABLES:
|
||||||
if (!h->hasBonusFrom(Bonus::OBJECT, Obj::STABLES)) //does not stack with advMap Stables
|
if(!h->hasBonusFrom(Bonus::OBJECT, Obj::STABLES)) //does not stack with advMap Stables
|
||||||
{
|
{
|
||||||
GiveBonus gb;
|
GiveBonus gb;
|
||||||
gb.bonus = Bonus(Bonus::ONE_WEEK, Bonus::LAND_MOVEMENT, Bonus::OBJECT, 600, 94, VLC->generaltexth->arraytxt[100]);
|
gb.bonus = Bonus(Bonus::ONE_WEEK, Bonus::LAND_MOVEMENT, Bonus::OBJECT, 600, 94, VLC->generaltexth->arraytxt[100]);
|
||||||
@@ -1712,9 +1712,9 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::MANA_VORTEX:
|
case BuildingSubID::MANA_VORTEX:
|
||||||
if (visitors.empty())
|
if(visitors.empty())
|
||||||
{
|
{
|
||||||
if (h->mana < h->manaLimit() * 2)
|
if(h->mana < h->manaLimit() * 2)
|
||||||
cb->setManaPoints (heroID, 2 * h->manaLimit());
|
cb->setManaPoints (heroID, 2 * h->manaLimit());
|
||||||
//TODO: investigate line below
|
//TODO: investigate line below
|
||||||
//cb->setObjProperty (town->id, ObjProperty::VISITED, true);
|
//cb->setObjProperty (town->id, ObjProperty::VISITED, true);
|
||||||
@@ -1750,36 +1750,36 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
|||||||
InfoWindow iw;
|
InfoWindow iw;
|
||||||
PrimarySkill::PrimarySkill what = PrimarySkill::NONE;
|
PrimarySkill::PrimarySkill what = PrimarySkill::NONE;
|
||||||
|
|
||||||
switch (bType)
|
switch(bType)
|
||||||
{
|
{
|
||||||
case BuildingSubID::KNOWLEDGE_VISITING_BONUS: //wall of knowledge
|
case BuildingSubID::KNOWLEDGE_VISITING_BONUS: //wall of knowledge
|
||||||
what = PrimarySkill::KNOWLEDGE;
|
what = PrimarySkill::KNOWLEDGE;
|
||||||
val = 1;
|
val = 1;
|
||||||
iw.components.push_back (Component(Component::PRIM_SKILL, 3, 1, 0));
|
iw.components.push_back(Component(Component::PRIM_SKILL, 3, 1, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::SPELL_POWER_VISITING_BONUS: //order of fire
|
case BuildingSubID::SPELL_POWER_VISITING_BONUS: //order of fire
|
||||||
what = PrimarySkill::SPELL_POWER;
|
what = PrimarySkill::SPELL_POWER;
|
||||||
val = 1;
|
val = 1;
|
||||||
iw.components.push_back (Component(Component::PRIM_SKILL, 2, 1, 0));
|
iw.components.push_back(Component(Component::PRIM_SKILL, 2, 1, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::ATTACK_VISITING_BONUS: //hall of Valhalla
|
case BuildingSubID::ATTACK_VISITING_BONUS: //hall of Valhalla
|
||||||
what = PrimarySkill::ATTACK;
|
what = PrimarySkill::ATTACK;
|
||||||
val = 1;
|
val = 1;
|
||||||
iw.components.push_back (Component(Component::PRIM_SKILL, 0, 1, 0));
|
iw.components.push_back(Component(Component::PRIM_SKILL, 0, 1, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::EXPERIENCE_VISITING_BONUS: //academy of battle scholars
|
case BuildingSubID::EXPERIENCE_VISITING_BONUS: //academy of battle scholars
|
||||||
what = PrimarySkill::EXPERIENCE;
|
what = PrimarySkill::EXPERIENCE;
|
||||||
val = static_cast<int>(h->calculateXp(1000));
|
val = static_cast<int>(h->calculateXp(1000));
|
||||||
iw.components.push_back (Component(Component::EXPERIENCE, 0, val, 0));
|
iw.components.push_back(Component(Component::EXPERIENCE, 0, val, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::DEFENSE_VISITING_BONUS: //cage of warlords
|
case BuildingSubID::DEFENSE_VISITING_BONUS: //cage of warlords
|
||||||
what = PrimarySkill::DEFENSE;
|
what = PrimarySkill::DEFENSE;
|
||||||
val = 1;
|
val = 1;
|
||||||
iw.components.push_back (Component(Component::PRIM_SKILL, 1, 1, 0));
|
iw.components.push_back(Component(Component::PRIM_SKILL, 1, 1, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BuildingSubID::CUSTOM_VISITING_BONUS:
|
case BuildingSubID::CUSTOM_VISITING_BONUS:
|
||||||
@@ -1791,6 +1791,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(what != PrimarySkill::NONE)
|
if(what != PrimarySkill::NONE)
|
||||||
{
|
{
|
||||||
iw.player = cb->getOwner(heroID);
|
iw.player = cb->getOwner(heroID);
|
||||||
@@ -1799,7 +1800,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
|
|||||||
cb->changePrimSkill (cb->getHero(heroID), what, val);
|
cb->changePrimSkill (cb->getHero(heroID), what, val);
|
||||||
town->addHeroToStructureVisitors(h, indexOnTV);
|
town->addHeroToStructureVisitors(h, indexOnTV);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTownBonus::applyBonuses(CGHeroInstance * h, const BonusList & bonuses) const
|
void CTownBonus::applyBonuses(CGHeroInstance * h, const BonusList & bonuses) const
|
||||||
|
|||||||
@@ -207,11 +207,11 @@ void CObjectClassesHandler::loadObjectEntry(const std::string & identifier, cons
|
|||||||
return str.compare(obj->subObjects[id]->subTypeName) == 0;
|
return str.compare(obj->subObjects[id]->subTypeName) == 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (overrideForce) // DO NOT override mod handlers by default
|
if(overrideForce) // DO NOT override mod handlers by default
|
||||||
{
|
{
|
||||||
obj->subObjects[id] = handler;
|
obj->subObjects[id] = handler;
|
||||||
obj->subIds[convertedId] = id;
|
obj->subIds[convertedId] = id;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logGlobal->warn("Don't override handler %s in object %s(%d)::%s(%d) subTypeName : %s"
|
logGlobal->warn("Don't override handler %s in object %s(%d)::%s(%d) subTypeName : %s"
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ bool BattleSpellMechanics::canBeCast(Problem & problem) const
|
|||||||
return effects->applicable(problem, this);
|
return effects->applicable(problem, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BattleSpellMechanics::canBeCastAt(Problem & problem, const Target & target) const
|
bool BattleSpellMechanics::canBeCastAt(const Target & target, Problem & problem) const
|
||||||
{
|
{
|
||||||
if(!canBeCast(problem))
|
if(!canBeCast(problem))
|
||||||
return false;
|
return false;
|
||||||
@@ -618,7 +618,7 @@ std::vector<Destination> BattleSpellMechanics::getPossibleDestinations(size_t in
|
|||||||
|
|
||||||
detail::ProblemImpl ingored;
|
detail::ProblemImpl ingored;
|
||||||
|
|
||||||
if(canBeCastAt(ingored, tmp))
|
if(canBeCastAt(tmp, ingored))
|
||||||
ret.emplace_back(dest);
|
ret.emplace_back(dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public:
|
|||||||
void applyEffects(ServerCallback * server, const Target & targets, bool indirect, bool ignoreImmunity) const override;
|
void applyEffects(ServerCallback * server, const Target & targets, bool indirect, bool ignoreImmunity) const override;
|
||||||
|
|
||||||
bool canBeCast(Problem & problem) const override;
|
bool canBeCast(Problem & problem) const override;
|
||||||
bool canBeCastAt(Problem & problem, const Target & target) const override;
|
bool canBeCastAt(const Target & target, Problem & problem) const override;
|
||||||
|
|
||||||
void cast(ServerCallback * server, const Target & target) override final;
|
void cast(ServerCallback * server, const Target & target) override final;
|
||||||
void castEval(ServerCallback * server, const Target & target) override final;
|
void castEval(ServerCallback * server, const Target & target) override final;
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public:
|
|||||||
virtual std::vector<const CStack *> getAffectedStacks(const Target & target) const = 0;
|
virtual std::vector<const CStack *> getAffectedStacks(const Target & target) const = 0;
|
||||||
|
|
||||||
virtual bool canBeCast(Problem & problem) const = 0;
|
virtual bool canBeCast(Problem & problem) const = 0;
|
||||||
virtual bool canBeCastAt(Problem & problem, const Target & target) const = 0;
|
virtual bool canBeCastAt(const Target & target, Problem & problem) const = 0;
|
||||||
|
|
||||||
virtual void applyEffects(ServerCallback * server, const Target & targets, bool indirect, bool ignoreImmunity) const = 0;
|
virtual void applyEffects(ServerCallback * server, const Target & targets, bool indirect, bool ignoreImmunity) const = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ const std::vector<ServicesProxy::CustomRegType> ServicesProxy::REGISTER_CUSTOM =
|
|||||||
{"creatures", LuaMethodWrapper<Services, decltype(&Services::creatures), &Services::creatures>::invoke, false},
|
{"creatures", LuaMethodWrapper<Services, decltype(&Services::creatures), &Services::creatures>::invoke, false},
|
||||||
{"factions", LuaMethodWrapper<Services, decltype(&Services::factions), &Services::factions>::invoke, false},
|
{"factions", LuaMethodWrapper<Services, decltype(&Services::factions), &Services::factions>::invoke, false},
|
||||||
{"heroClasses", LuaMethodWrapper<Services, decltype(&Services::heroClasses), &Services::heroClasses>::invoke, false},
|
{"heroClasses", LuaMethodWrapper<Services, decltype(&Services::heroClasses), &Services::heroClasses>::invoke, false},
|
||||||
{"heroTypes", LuaMethodWrapper<Services,decltype(&Services::heroTypes), &Services::heroTypes>::invoke, false},
|
{"heroTypes", LuaMethodWrapper<Services, decltype(&Services::heroTypes), &Services::heroTypes>::invoke, false},
|
||||||
{"spells", LuaMethodWrapper<Services, decltype(&Services::spells), &Services::spells>::invoke, false},
|
{"spells", LuaMethodWrapper<Services, decltype(&Services::spells), &Services::spells>::invoke, false},
|
||||||
{"skills", LuaMethodWrapper<Services,decltype(&Services::skills), &Services::skills>::invoke, false},
|
{"skills", LuaMethodWrapper<Services, decltype(&Services::skills), &Services::skills>::invoke, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
VCMI_REGISTER_CORE_SCRIPT_API(ArtifactServiceProxy, "Artifacts");
|
VCMI_REGISTER_CORE_SCRIPT_API(ArtifactServiceProxy, "Artifacts");
|
||||||
|
|||||||
@@ -5631,9 +5631,9 @@ void CGameHandler::attackCasting(bool ranged, Bonus::BonusType attackMode, const
|
|||||||
|
|
||||||
auto m = spell->battleMechanics(¶meters);
|
auto m = spell->battleMechanics(¶meters);
|
||||||
|
|
||||||
spells::detail::ProblemImpl ingored;
|
spells::detail::ProblemImpl ignored;
|
||||||
|
|
||||||
if(!m->canBeCastAt(ingored, target))
|
if(!m->canBeCastAt(target, ignored))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
//check if spell should be cast (probability handling)
|
//check if spell should be cast (probability handling)
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ TEST_F(CGameStateTest, issue2765)
|
|||||||
|
|
||||||
auto m = age->battleMechanics(&cast);
|
auto m = age->battleMechanics(&cast);
|
||||||
|
|
||||||
EXPECT_FALSE(m->canBeCastAt(problemMock, target));
|
EXPECT_FALSE(m->canBeCastAt(target, problemMock));
|
||||||
|
|
||||||
EXPECT_TRUE(cast.castIfPossible(this, target));//should be possible, but with no effect (change to aimed cast check?)
|
EXPECT_TRUE(cast.castIfPossible(this, target));//should be possible, but with no effect (change to aimed cast check?)
|
||||||
|
|
||||||
@@ -397,7 +397,7 @@ TEST_F(CGameStateTest, battleResurrection)
|
|||||||
|
|
||||||
EXPECT_TRUE(m->canBeCast(problemMock));
|
EXPECT_TRUE(m->canBeCast(problemMock));
|
||||||
|
|
||||||
EXPECT_TRUE(m->canBeCastAt(problemMock, target));
|
EXPECT_TRUE(m->canBeCastAt(target, problemMock));
|
||||||
|
|
||||||
cast.cast(this, target);
|
cast.cast(this, target);
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public:
|
|||||||
MOCK_CONST_METHOD1(getAffectedStacks, std::vector<const CStack *>(const Target &));
|
MOCK_CONST_METHOD1(getAffectedStacks, std::vector<const CStack *>(const Target &));
|
||||||
|
|
||||||
MOCK_CONST_METHOD1(canBeCast, bool(Problem &));
|
MOCK_CONST_METHOD1(canBeCast, bool(Problem &));
|
||||||
MOCK_CONST_METHOD2(canBeCastAt, bool(Problem &, const Target &));
|
MOCK_CONST_METHOD2(canBeCastAt, bool(const Target &, Problem &));
|
||||||
|
|
||||||
MOCK_CONST_METHOD4(applyEffects, void(ServerCallback *, const Target &, bool, bool));
|
MOCK_CONST_METHOD4(applyEffects, void(ServerCallback *, const Target &, bool, bool));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user