1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fixes for code review issues

This commit is contained in:
AlexVinS 2021-02-20 04:57:50 +03:00
parent 784f6b973b
commit 483a4689ce
18 changed files with 196 additions and 209 deletions

View File

@ -563,24 +563,24 @@ void CBattleInterface::deactivate()
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();
else
showQueue();
}
else if (key.keysym.sym == SDLK_f && key.state == SDL_PRESSED)
else if(key.keysym.sym == SDLK_f && key.state == SDL_PRESSED)
{
enterCreatureCastingMode();
}
else if (key.keysym.sym == SDLK_ESCAPE)
else if(key.keysym.sym == SDLK_ESCAPE)
{
if(!battleActionsStarted)
CCS->soundh->stopSound(battleIntroSoundChannel);
else
endCastingSpell();
endCastingSpell();
}
}
void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
@ -788,14 +788,14 @@ void CBattleInterface::bOptionsf()
void CBattleInterface::bSurrenderf()
{
if (spellDestSelectMode) //we are casting a spell
if(spellDestSelectMode) //we are casting a spell
return;
int cost = curInt->cb->battleGetSurrenderCost();
if (cost >= 0)
if(cost >= 0)
{
std::string enemyHeroName = curInt->cb->battleGetEnemyHero().name;
if (enemyHeroName.empty())
if(enemyHeroName.empty())
{
logGlobal->warn("Surrender performed without enemy hero, should not happen!");
enemyHeroName = "#ENEMY#";
@ -1462,14 +1462,9 @@ void CBattleInterface::displayEffect(ui32 effect, BattleHex 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();
if(spell == nullptr)
return;
for(const CSpell::TAnimation & animation : spell->animationInfo.cast)
for(const CSpell::TAnimation & animation : q)
{
if(animation.pause > 0)
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)
{
const CSpell *spell = spellID.toSpell();
if(spell == nullptr)
return;
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));
}
if(spell)
displaySpellAnimationQueue(spell->animationInfo.affect, destinationTile);
}
void CBattleInterface::displaySpellHit(SpellID spellID, BattleHex destinationTile)
{
const CSpell * spell = spellID.toSpell();
if(spell == nullptr)
return;
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));
}
if(spell)
displaySpellAnimationQueue(spell->animationInfo.hit, destinationTile);
}
void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
@ -1704,13 +1690,12 @@ void CBattleInterface::enterCreatureCastingMode()
spells::Target target;
target.emplace_back();
spells::BattleCast cast(curInt->cb.get(), caster, spells::Mode::CREATURE_ACTIVE, spell);
auto m = spell->battleMechanics(&cast);
spells::detail::ProblemImpl ignored;
const bool isCastingPossible = m->canBeCastAt(ignored, target);
const bool isCastingPossible = m->canBeCastAt(target, ignored);
if (isCastingPossible)
{
@ -1762,7 +1747,7 @@ void CBattleInterface::reorderPossibleActionsPriority(const CStack * stack, Mous
case PossiblePlayerBattleAction::OBSTACLE:
if(!stack->hasBonusOfType(Bonus::NO_SPELLCAST_BY_DEFAULT) && context == MouseHoveredHexContext::OCCUPIED_HEX)
return 1;
else
else
return 100;//bottom priority
break;
case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
@ -2543,7 +2528,7 @@ bool CBattleInterface::isCastingPossibleHere(const CStack *sactive, const CStack
auto m = sp->battleMechanics(&cast);
spells::detail::ProblemImpl problem; //todo: display problem in status bar
isCastingPossible = m->canBeCastAt(problem, target);
isCastingPossible = m->canBeCastAt(target, problem);
}
}
else
@ -3022,7 +3007,7 @@ void CBattleInterface::show(SDL_Surface *to)
showProjectiles(to);
if(battleActionsStarted)
updateBattleAnimations();
updateBattleAnimations();
SDL_SetClipRect(to, &buf); //restoring previous clip_rect

View File

@ -358,6 +358,7 @@ public:
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 displaySpellEffect(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation
void displaySpellHit(SpellID spellID, BattleHex destinationTile); //displays spell`s affected animation

View File

@ -368,11 +368,11 @@ void CGarrisonSlot::update()
}
CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGarrisonSlot::EGarrisonType Upg, const CStackInstance * creature_)
: ID(IID),
owner(Owner),
myStack(creature_),
creature(creature_ ? creature_->type : nullptr),
upg(Upg)
: ID(IID),
owner(Owner),
myStack(creature_),
creature(creature_ ? creature_->type : nullptr),
upg(Upg)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
@ -381,8 +381,8 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt * Owner, int x, int y, SlotID IID, CGa
std::string imgName = owner->smallIcons ? "cprsmall" : "TWCRPORT";
creatureImage = std::make_shared<CAnimImage>(imgName, 0);
creatureImage->disable();
creatureImage = std::make_shared<CAnimImage>(imgName, 0);
creatureImage->disable();
selectionImage = std::make_shared<CAnimImage>(imgName, 1);
selectionImage->disable();

View File

@ -111,12 +111,14 @@ void CBuildingRect::hover(bool on)
void CBuildingRect::clickLeft(tribool down, bool previousState)
{
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(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
{
auto building = getBuilding();
parent->buildingClicked(building->bid, building->subId, building->upgrade);
}
}
}
}
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)
{
return build->getDistance(a->building->bid)
< build->getDistance(b->building->bid);
return build->getDistance(a->building->bid) < build->getDistance(b->building->bid);
});
buildings.push_back(std::make_shared<CBuildingRect>(this, town, toAdd));
@ -880,9 +881,9 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
else //Mystic Pond produced something;
{
descr += "\n\n" + hasProduced;
boost::algorithm::replace_first(descr,"%s",CGI->generaltexth->restypes[town->bonusValue.first]);
boost::algorithm::replace_first(descr,"%d",boost::lexical_cast<std::string>(town->bonusValue.second));
}
boost::algorithm::replace_first(descr,"%s",CGI->generaltexth->restypes[town->bonusValue.first]);
boost::algorithm::replace_first(descr,"%d",boost::lexical_cast<std::string>(town->bonusValue.second));
}
}
LOCPLINT->showInfoDialog(descr, comps);
}

View File

@ -32,20 +32,20 @@ public:
using PostHandler = std::function<void(const E &)>;
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);
auto storage = std::make_shared<PreHandlerStorage>(std::move(cb));
auto storage = std::make_shared<PreHandlerStorage>(std::move(handler));
preHandlers[tag].push_back(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);
auto storage = std::make_shared<PostHandlerStorage>(std::move(cb));
auto storage = std::make_shared<PostHandlerStorage>(std::move(handler));
postHandlers[tag].push_back(storage);
return make_unique<PostSubscription>(tag, storage);
}
@ -84,18 +84,18 @@ private:
class HandlerStorage
{
public:
explicit HandlerStorage(T && cb_)
: cb(cb_)
explicit HandlerStorage(T && handler_)
: handler(handler_)
{
}
STRONG_INLINE
void operator()(E & event)
{
cb(event);
handler(event);
}
private:
T cb;
T handler;
};
using PreHandlerStorage = HandlerStorage<PreHandler>;
@ -104,8 +104,8 @@ private:
class PreSubscription : public EventSubscription
{
public:
PreSubscription(BusTag tag_, std::shared_ptr<PreHandlerStorage> cb_)
: cb(cb_),
PreSubscription(BusTag tag_, std::shared_ptr<PreHandlerStorage> handler_)
: handler(handler_),
tag(tag_)
{
}
@ -113,18 +113,18 @@ private:
virtual ~PreSubscription()
{
auto registry = E::getRegistry();
registry->unsubscribe(tag, cb, registry->preHandlers);
registry->unsubscribe(tag, handler, registry->preHandlers);
}
private:
BusTag tag;
std::shared_ptr<PreHandlerStorage> cb;
std::shared_ptr<PreHandlerStorage> handler;
};
class PostSubscription : public EventSubscription
{
public:
PostSubscription(BusTag tag_, std::shared_ptr<PostHandlerStorage> cb_)
: cb(cb_),
PostSubscription(BusTag tag_, std::shared_ptr<PostHandlerStorage> handler_)
: handler(handler_),
tag(tag_)
{
}
@ -132,11 +132,11 @@ private:
virtual ~PostSubscription()
{
auto registry = E::getRegistry();
registry->unsubscribe(tag, cb, registry->postHandlers);
registry->unsubscribe(tag, handler, registry->postHandlers);
}
private:
BusTag tag;
std::shared_ptr<PostHandlerStorage> cb;
std::shared_ptr<PostHandlerStorage> handler;
};
boost::shared_mutex mutex;

View File

@ -697,7 +697,7 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
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);
return false;
@ -706,14 +706,14 @@ bool CModHandler::checkDependencies(const std::vector <TModID> & input) const
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);
return false;
}
}
if (hasCircularDependency(id))
if(hasCircularDependency(id))
return false;
}
return true;
@ -732,7 +732,7 @@ std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> modsT
{
logMod->error("Mod '%s' will not work: it depends on mod '%s', which is not installed.", mod.name, dependency);
res = false; //continue iterations, since we should show all errors for the current mod.
}
}
}
return res;
};
@ -745,19 +745,19 @@ std::vector <TModID> CModHandler::resolveDependencies(std::vector <TModID> modsT
brokenMods.push_back(mod);
}
if(!brokenMods.empty())
{
{
vstd::erase_if(modsToResolve, [&](TModID mid)
{
return brokenMods.end() != std::find(brokenMods.begin(), brokenMods.end(), mid);
});
brokenMods.clear();
continue;
}
break;
}
break;
}
boost::range::sort(modsToResolve);
return modsToResolve;
}
}
std::vector<std::string> CModHandler::getModList(std::string path)
{

View File

@ -560,29 +560,31 @@ R CTownHandler::getMappedValue(const K key, const R defval, const std::map<K, R>
template<typename R>
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)
return getMappedValue<R, std::string>(node.String(), defval, map, required);
return defval;
}
void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building)
{
{
std::shared_ptr<Bonus> b;
static TPropagatorPtr playerPropagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::ENodeTypes::PLAYER);
if(building->subId == BuildingSubID::NONE)
{
{
if(building->bid == BuildingID::TAVERN)
b = createBonus(building, Bonus::MORALE, +1);
else if(building->bid == BuildingID::GRAIL
&& building->town->faction != nullptr
&& boost::algorithm::ends_with(building->town->faction->identifier, ":cove"))
{
static TPropagatorPtr allCreaturesPropagator(new CPropagatorNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES));
static auto factionLimiter = std::make_shared<CreatureFactionLimiter>(building->town->faction->index);
b = createBonus(building, Bonus::NO_TERRAIN_PENALTY, 0, allCreaturesPropagator);
b->addLimiter(factionLimiter);
b = createBonus(building, Bonus::MORALE, +1);
}
else if(building->bid == BuildingID::GRAIL
&& building->town->faction != nullptr
&& boost::algorithm::ends_with(building->town->faction->identifier, ":cove"))
{
static TPropagatorPtr allCreaturesPropagator(new CPropagatorNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES));
static auto factionLimiter = std::make_shared<CreatureFactionLimiter>(building->town->faction->index);
b = createBonus(building, Bonus::NO_TERRAIN_PENALTY, 0, allCreaturesPropagator);
b->addLimiter(factionLimiter);
}
}
else

View File

@ -121,7 +121,7 @@ void ScriptImpl::resolveHost()
else if(sourcePathId.getType() == EResType::LUA)
host = owner->lua;
else
throw std::runtime_error("Unknown script language in:"+sourcePath);
throw std::runtime_error("Unknown script language in:" + sourcePath);
}
PoolImpl::PoolImpl(const Environment * ENV)
@ -217,7 +217,8 @@ std::vector<JsonNode> ScriptHandler::loadLegacyData(size_t dataSize)
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);

View File

@ -1407,9 +1407,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
{
auto st = battleGetUnitByPos(tile, true);
if(st && battleMatchOwner(st, attacker)) //only hostile stacks - does it work well with Berserk?
{
at.hostileCreaturePositions.insert(tile);
}
}
}
}
@ -1429,44 +1427,42 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const battl
//friendly stacks can also be damaged by Dragon Breath
auto st = battleGetUnitByPos(tile, true);
if(st && st != attacker)
{
at.friendlyCreaturePositions.insert(tile);
}
at.friendlyCreaturePositions.insert(tile);
}
}
else if(attacker->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH))
{
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
int pseudoVector = destinationTile.hex - hex;
switch(pseudoVector)
{
case 1:
case -1:
BattleHex::checkAndPush(destinationTile.hex + pseudoVector, hexes);
break;
case WN: //17 //left-down or right-down
case -WN: //-17 //left-up or right-up
case WN + 1: //18 //right-down
case -WN + 1: //-16 //right-up
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + (((hex / WN) % 2) ? 1 : -1), hexes);
break;
case WN - 1: //16 //left-down
case -WN - 1: //-18 //left-up
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + (((hex / WN) % 2) ? 1 : 0), hexes);
break;
}
for(BattleHex tile : hexes)
{
//friendly stacks can also be damaged by Dragon Breath
std::vector<BattleHex> hexes; //only one, in fact
int pseudoVector = destinationTile.hex - hex;
switch(pseudoVector)
{
case 1:
case -1:
BattleHex::checkAndPush(destinationTile.hex + pseudoVector, hexes);
break;
case WN: //17 //left-down or right-down
case -WN: //-17 //left-up or right-up
case WN + 1: //18 //right-down
case -WN + 1: //-16 //right-up
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + (((hex / WN) % 2) ? 1 : -1), hexes);
break;
case WN - 1: //16 //left-down
case -WN - 1: //-18 //left-up
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + (((hex / WN) % 2) ? 1 : 0), hexes);
break;
}
for(BattleHex tile : hexes)
{
//friendly stacks can also be damaged by Dragon Breath
auto st = battleGetUnitByPos(tile, true);
if (st != nullptr)
at.friendlyCreaturePositions.insert(tile);
if(st != nullptr)
at.friendlyCreaturePositions.insert(tile);
}
}
}
}
return at;
}

View File

@ -850,18 +850,18 @@ void CGTownInstance::updateBonusingBuildings() //update to version 792
//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
{
switch (this->town->faction->index)
switch(this->town->faction->index)
{
case ETownType::CASTLE:
building->setBuildingSubtype(BuildingSubID::STABLES);
case ETownType::CASTLE:
building->setBuildingSubtype(BuildingSubID::STABLES);
break;
case ETownType::DUNGEON:
case ETownType::DUNGEON:
if(building->getBuildingType() == BuildingID::SPECIAL_2)
building->setBuildingSubtype(BuildingSubID::MANA_VORTEX);
else if(building->getBuildingType() == BuildingID::SPECIAL_4)
building->setBuildingSubtype(BuildingSubID::EXPERIENCE_VISITING_BONUS);
break;
break;
case ETownType::TOWER:
building->setBuildingSubtype(BuildingSubID::KNOWLEDGE_VISITING_BONUS);
@ -875,10 +875,10 @@ void CGTownInstance::updateBonusingBuildings() //update to version 792
building->setBuildingSubtype(BuildingSubID::SPELL_POWER_VISITING_BONUS);
break;
case ETownType::FORTRESS:
case ETownType::FORTRESS:
building->setBuildingSubtype(BuildingSubID::DEFENSE_VISITING_BONUS);
break;
}
break;
}
}
}
//secondly, supplement bonusing buildings list and active bonuses; subtypes for these objects are already set in update792
@ -1264,14 +1264,14 @@ void CGTownInstance::recreateBuildingsBonuses()
continue;
for(auto bonus : building->buildingBonuses)
{
{
if(bonus->propagator != nullptr && bonus->propagator->getPropagatorType() == ALL_CREATURES)
VLC->creh->addBonusForAllCreatures(bonus);
else
addNewBonus(bonus);
}
}
}
}
void CGTownInstance::setVisitingHero(CGHeroInstance *h)
{
@ -1353,11 +1353,11 @@ int CGTownInstance::getTownLevel() const
// count all buildings that are not upgrades
int level = 0;
for (const auto & bid : builtBuildings)
for(const auto & bid : builtBuildings)
{
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
level++;
}
}
return level;
}
@ -1685,7 +1685,7 @@ void COPWBonus::setProperty(ui8 what, ui32 val)
void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
{
ObjectInstanceID heroID = h->id;
if (town->hasBuilt(bID))
if(town->hasBuilt(bID))
{
InfoWindow iw;
iw.player = h->tempOwner;
@ -1693,37 +1693,37 @@ void COPWBonus::onHeroVisit (const CGHeroInstance * h) const
switch (this->bType)
{
case BuildingSubID::STABLES:
if (!h->hasBonusFrom(Bonus::OBJECT, Obj::STABLES)) //does not stack with advMap Stables
{
GiveBonus gb;
gb.bonus = Bonus(Bonus::ONE_WEEK, Bonus::LAND_MOVEMENT, Bonus::OBJECT, 600, 94, VLC->generaltexth->arraytxt[100]);
gb.id = heroID.getNum();
cb->giveHeroBonus(&gb);
if(!h->hasBonusFrom(Bonus::OBJECT, Obj::STABLES)) //does not stack with advMap Stables
{
GiveBonus gb;
gb.bonus = Bonus(Bonus::ONE_WEEK, Bonus::LAND_MOVEMENT, Bonus::OBJECT, 600, 94, VLC->generaltexth->arraytxt[100]);
gb.id = heroID.getNum();
cb->giveHeroBonus(&gb);
SetMovePoints mp;
mp.val = 600;
mp.absolute = false;
mp.hid = heroID;
cb->setMovePoints(&mp);
SetMovePoints mp;
mp.val = 600;
mp.absolute = false;
mp.hid = heroID;
cb->setMovePoints(&mp);
iw.text << VLC->generaltexth->allTexts[580];
cb->showInfoDialog(&iw);
}
break;
iw.text << VLC->generaltexth->allTexts[580];
cb->showInfoDialog(&iw);
}
break;
case BuildingSubID::MANA_VORTEX:
if (visitors.empty())
{
if (h->mana < h->manaLimit() * 2)
if(visitors.empty())
{
if(h->mana < h->manaLimit() * 2)
cb->setManaPoints (heroID, 2 * h->manaLimit());
//TODO: investigate line below
//cb->setObjProperty (town->id, ObjProperty::VISITED, true);
iw.text << getVisitingBonusGreeting();
cb->showInfoDialog(&iw);
//extra visit penalty if hero alredy had double mana points (or even more?!)
town->addHeroToStructureVisitors(h, indexOnTV);
}
break;
//TODO: investigate line below
//cb->setObjProperty (town->id, ObjProperty::VISITED, true);
iw.text << getVisitingBonusGreeting();
cb->showInfoDialog(&iw);
//extra visit penalty if hero alredy had double mana points (or even more?!)
town->addHeroToStructureVisitors(h, indexOnTV);
}
break;
}
}
}
@ -1750,37 +1750,37 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
InfoWindow iw;
PrimarySkill::PrimarySkill what = PrimarySkill::NONE;
switch (bType)
switch(bType)
{
case BuildingSubID::KNOWLEDGE_VISITING_BONUS: //wall of knowledge
what = PrimarySkill::KNOWLEDGE;
val = 1;
iw.components.push_back (Component(Component::PRIM_SKILL, 3, 1, 0));
break;
what = PrimarySkill::KNOWLEDGE;
val = 1;
iw.components.push_back(Component(Component::PRIM_SKILL, 3, 1, 0));
break;
case BuildingSubID::SPELL_POWER_VISITING_BONUS: //order of fire
what = PrimarySkill::SPELL_POWER;
val = 1;
iw.components.push_back (Component(Component::PRIM_SKILL, 2, 1, 0));
break;
what = PrimarySkill::SPELL_POWER;
val = 1;
iw.components.push_back(Component(Component::PRIM_SKILL, 2, 1, 0));
break;
case BuildingSubID::ATTACK_VISITING_BONUS: //hall of Valhalla
what = PrimarySkill::ATTACK;
val = 1;
iw.components.push_back (Component(Component::PRIM_SKILL, 0, 1, 0));
break;
what = PrimarySkill::ATTACK;
val = 1;
iw.components.push_back(Component(Component::PRIM_SKILL, 0, 1, 0));
break;
case BuildingSubID::EXPERIENCE_VISITING_BONUS: //academy of battle scholars
what = PrimarySkill::EXPERIENCE;
what = PrimarySkill::EXPERIENCE;
val = static_cast<int>(h->calculateXp(1000));
iw.components.push_back (Component(Component::EXPERIENCE, 0, val, 0));
break;
iw.components.push_back(Component(Component::EXPERIENCE, 0, val, 0));
break;
case BuildingSubID::DEFENSE_VISITING_BONUS: //cage of warlords
what = PrimarySkill::DEFENSE;
val = 1;
iw.components.push_back (Component(Component::PRIM_SKILL, 1, 1, 0));
break;
what = PrimarySkill::DEFENSE;
val = 1;
iw.components.push_back(Component(Component::PRIM_SKILL, 1, 1, 0));
break;
case BuildingSubID::CUSTOM_VISITING_BONUS:
const auto building = town->town->buildings.at(bID);
@ -1788,19 +1788,20 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
{
const auto & bonuses = building->onVisitBonuses;
applyBonuses(const_cast<CGHeroInstance *>(h), bonuses);
}
break;
}
break;
}
if(what != PrimarySkill::NONE)
{
iw.player = cb->getOwner(heroID);
iw.text << getVisitingBonusGreeting();
cb->showInfoDialog(&iw);
cb->changePrimSkill (cb->getHero(heroID), what, val);
town->addHeroToStructureVisitors(h, indexOnTV);
iw.player = cb->getOwner(heroID);
iw.text << getVisitingBonusGreeting();
cb->showInfoDialog(&iw);
cb->changePrimSkill (cb->getHero(heroID), what, val);
town->addHeroToStructureVisitors(h, indexOnTV);
}
}
}
}
void CTownBonus::applyBonuses(CGHeroInstance * h, const BonusList & bonuses) const
{

View File

@ -207,11 +207,11 @@ void CObjectClassesHandler::loadObjectEntry(const std::string & identifier, cons
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->subIds[convertedId] = id;
}
obj->subObjects[id] = handler;
obj->subIds[convertedId] = id;
}
else
{
logGlobal->warn("Don't override handler %s in object %s(%d)::%s(%d) subTypeName : %s"

View File

@ -203,7 +203,7 @@ bool BattleSpellMechanics::canBeCast(Problem & problem) const
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))
return false;
@ -618,7 +618,7 @@ std::vector<Destination> BattleSpellMechanics::getPossibleDestinations(size_t in
detail::ProblemImpl ingored;
if(canBeCastAt(ingored, tmp))
if(canBeCastAt(tmp, ingored))
ret.emplace_back(dest);
}
}

View File

@ -28,7 +28,7 @@ public:
void applyEffects(ServerCallback * server, const Target & targets, bool indirect, bool ignoreImmunity) 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 castEval(ServerCallback * server, const Target & target) override final;

View File

@ -183,7 +183,7 @@ public:
virtual std::vector<const CStack *> getAffectedStacks(const Target & target) 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;

View File

@ -39,9 +39,9 @@ const std::vector<ServicesProxy::CustomRegType> ServicesProxy::REGISTER_CUSTOM =
{"creatures", LuaMethodWrapper<Services, decltype(&Services::creatures), &Services::creatures>::invoke, false},
{"factions", LuaMethodWrapper<Services, decltype(&Services::factions), &Services::factions>::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},
{"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");

View File

@ -5631,9 +5631,9 @@ void CGameHandler::attackCasting(bool ranged, Bonus::BonusType attackMode, const
auto m = spell->battleMechanics(&parameters);
spells::detail::ProblemImpl ingored;
spells::detail::ProblemImpl ignored;
if(!m->canBeCastAt(ingored, target))
if(!m->canBeCastAt(target, ignored))
continue;
//check if spell should be cast (probability handling)

View File

@ -297,7 +297,7 @@ TEST_F(CGameStateTest, issue2765)
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?)
@ -397,7 +397,7 @@ TEST_F(CGameStateTest, battleResurrection)
EXPECT_TRUE(m->canBeCast(problemMock));
EXPECT_TRUE(m->canBeCastAt(problemMock, target));
EXPECT_TRUE(m->canBeCastAt(target, problemMock));
cast.cast(this, target);
//

View File

@ -25,7 +25,7 @@ public:
MOCK_CONST_METHOD1(getAffectedStacks, std::vector<const CStack *>(const Target &));
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));