1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

Added abstract method to caster interface

This commit is contained in:
nordsoft
2023-04-10 01:31:41 +04:00
parent 72b2a09f0b
commit 0093a44889
8 changed files with 44 additions and 23 deletions

View File

@ -15,6 +15,7 @@ VCMI_LIB_NAMESPACE_BEGIN
class PlayerColor; class PlayerColor;
struct MetaString; struct MetaString;
class ServerCallback; class ServerCallback;
class CGHeroInstance;
namespace battle namespace battle
{ {
@ -65,6 +66,9 @@ public:
virtual void getCastDescription(const Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const = 0; virtual void getCastDescription(const Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const = 0;
virtual void spendMana(ServerCallback * server, const int32_t spellCost) const = 0; virtual void spendMana(ServerCallback * server, const int32_t spellCost) const = 0;
///used to identify actual hero caster
virtual const CGHeroInstance * getHeroCaster() const = 0;
}; };
} }

View File

@ -418,6 +418,11 @@ int32_t CUnitState::getCasterUnitId() const
return static_cast<int32_t>(unitId()); return static_cast<int32_t>(unitId());
} }
const CGHeroInstance * CUnitState::getHeroCaster() const
{
return nullptr;
}
int32_t CUnitState::getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool) const int32_t CUnitState::getSpellSchoolLevel(const spells::Spell * spell, int32_t * outSelectedSchool) const
{ {
int32_t skill = valOfBonuses(Selector::typeSubtype(Bonus::SPELLCASTER, spell->getIndex())); int32_t skill = valOfBonuses(Selector::typeSubtype(Bonus::SPELLCASTER, spell->getIndex()));

View File

@ -192,6 +192,7 @@ public:
int64_t getEffectValue(const spells::Spell * spell) const override; int64_t getEffectValue(const spells::Spell * spell) const override;
PlayerColor getCasterOwner() const override; PlayerColor getCasterOwner() const override;
const CGHeroInstance * getHeroCaster() const override;
void getCasterName(MetaString & text) const override; void getCasterName(MetaString & text) const override;
void getCastDescription(const spells::Spell * spell, const std::vector<const Unit *> & attacked, MetaString & text) const override; void getCastDescription(const spells::Spell * spell, const std::vector<const Unit *> & attacked, MetaString & text) const override;

View File

@ -669,6 +669,11 @@ void CGHeroInstance::getCastDescription(const spells::Spell * spell, const std::
attacked.at(0)->addNameReplacement(text, true); attacked.at(0)->addNameReplacement(text, true);
} }
const CGHeroInstance * CGHeroInstance::getHeroCaster() const
{
return this;
}
void CGHeroInstance::spendMana(ServerCallback * server, const int spellCost) const void CGHeroInstance::spendMana(ServerCallback * server, const int spellCost) const
{ {
if(spellCost != 0) if(spellCost != 0)

View File

@ -275,6 +275,7 @@ public:
int64_t getEffectValue(const spells::Spell * spell) const override; int64_t getEffectValue(const spells::Spell * spell) const override;
PlayerColor getCasterOwner() const override; PlayerColor getCasterOwner() const override;
const CGHeroInstance * getHeroCaster() const override;
void getCasterName(MetaString & text) const override; void getCasterName(MetaString & text) const override;
void getCastDescription(const spells::Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override; void getCastDescription(const spells::Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override;

View File

@ -143,12 +143,13 @@ SummonBoatMechanics::SummonBoatMechanics(const CSpell * s):
ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
{ {
//casts to minimal abstraction level if(!parameters.caster->getHeroCaster())
const auto * objectCaster = dynamic_cast<const CGObjectInstance *>(parameters.caster); {
const auto * heroCaster = dynamic_cast<const CGHeroInstance *>(parameters.caster); logGlobal->error("Summoning boat without hero as actor");
const auto * boatGeneratorCaster = dynamic_cast<const IBoatGenerator *>(parameters.caster); return ESpellCastResult::ERROR;
}
if(heroCaster && heroCaster->boat) if(parameters.caster->getHeroCaster()->boat)
{ {
InfoWindow iw; InfoWindow iw;
iw.player = parameters.caster->getCasterOwner(); iw.player = parameters.caster->getCasterOwner();
@ -158,9 +159,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
return ESpellCastResult::CANCEL; return ESpellCastResult::CANCEL;
} }
int3 summonPos(-1, -1, -1); int3 summonPos = parameters.caster->getHeroCaster()->bestLocation();
if(boatGeneratorCaster)
summonPos = (boatGeneratorCaster)->bestLocation();
if(summonPos.x < 0) if(summonPos.x < 0)
{ {
@ -187,8 +186,6 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
//try to find unoccupied boat to summon //try to find unoccupied boat to summon
const CGBoat * nearest = nullptr; const CGBoat * nearest = nullptr;
double dist = 0; double dist = 0;
if(objectCaster)
{
for(const CGObjectInstance * obj : env->getMap()->objects) for(const CGObjectInstance * obj : env->getMap()->objects)
{ {
if(obj && obj->ID == Obj::BOAT) if(obj && obj->ID == Obj::BOAT)
@ -197,7 +194,7 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
if(b->hero) if(b->hero)
continue; //we're looking for unoccupied boat continue; //we're looking for unoccupied boat
double nDist = b->pos.dist2d(objectCaster->visitablePos()); double nDist = b->pos.dist2d(parameters.caster->getHeroCaster()->visitablePos());
if(!nearest || nDist < dist) //it's first boat or closer than previous if(!nearest || nDist < dist) //it's first boat or closer than previous
{ {
nearest = b; nearest = b;
@ -205,7 +202,6 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
} }
} }
} }
}
if(nullptr != nearest) //we found boat to summon if(nullptr != nearest) //we found boat to summon
{ {
@ -221,11 +217,11 @@ ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment
iw.text.addTxt(MetaString::GENERAL_TXT, 335); //There are no boats to summon. iw.text.addTxt(MetaString::GENERAL_TXT, 335); //There are no boats to summon.
env->apply(&iw); env->apply(&iw);
} }
else if(boatGeneratorCaster) //create boat else //create boat
{ {
NewObject no; NewObject no;
no.ID = Obj::BOAT; no.ID = Obj::BOAT;
no.subID = boatGeneratorCaster->getBoatType(); no.subID = parameters.caster->getHeroCaster()->getBoatType();
no.pos = summonPos + int3(1,0,0); no.pos = summonPos + int3(1,0,0);
env->apply(&no); env->apply(&no);
} }

View File

@ -118,6 +118,14 @@ void ProxyCaster::spendMana(ServerCallback * server, const int32_t spellCost) co
actualCaster->spendMana(server, spellCost); actualCaster->spendMana(server, spellCost);
} }
const CGHeroInstance * ProxyCaster::getHeroCaster() const
{
if(actualCaster)
return actualCaster->getHeroCaster();
return nullptr;
}
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -35,6 +35,7 @@ public:
void getCasterName(MetaString & text) const override; void getCasterName(MetaString & text) const override;
void getCastDescription(const Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override; void getCastDescription(const Spell * spell, const std::vector<const battle::Unit *> & attacked, MetaString & text) const override;
void spendMana(ServerCallback * server, const int32_t spellCost) const override; void spendMana(ServerCallback * server, const int32_t spellCost) const override;
const CGHeroInstance * getHeroCaster() const override;
protected: protected:
const Caster * actualCaster; const Caster * actualCaster;