| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- /*
- * SummonBoatMechanics.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
- #include "StdInc.h"
- #include "SummonBoatMechanics.h"
- #include "../CSpellHandler.h"
- #include "../../mapObjects/CGHeroInstance.h"
- #include "../../mapObjects/MiscObjects.h"
- #include "../../mapping/CMap.h"
- #include "../../networkPacks/PacksForClient.h"
- VCMI_LIB_NAMESPACE_BEGIN
- SummonBoatMechanics::SummonBoatMechanics(const CSpell * s)
- : AdventureSpellMechanics(s)
- {
- }
- bool SummonBoatMechanics::canBeCastImpl(spells::Problem & problem, const IGameInfoCallback * cb, const spells::Caster * caster) const
- {
- if(!caster->getHeroCaster())
- return false;
- if(caster->getHeroCaster()->inBoat())
- {
- MetaString message = MetaString::createFromTextID("core.genrltxt.333");
- caster->getCasterName(message);
- problem.add(std::move(message));
- return false;
- }
- int3 summonPos = caster->getHeroCaster()->bestLocation();
- if(summonPos.x < 0)
- {
- MetaString message = MetaString::createFromTextID("core.genrltxt.334");
- caster->getCasterName(message);
- problem.add(std::move(message));
- return false;
- }
- return true;
- }
- ESpellCastResult SummonBoatMechanics::applyAdventureEffects(SpellCastEnvironment * env, const AdventureSpellCastParameters & parameters) const
- {
- const auto schoolLevel = parameters.caster->getSpellSchoolLevel(owner);
- //check if spell works at all
- if(env->getRNG()->nextInt(0, 99) >= owner->getLevelPower(schoolLevel)) //power is % chance of success
- {
- InfoWindow iw;
- iw.player = parameters.caster->getCasterOwner();
- iw.text.appendLocalString(EMetaText::GENERAL_TXT, 336); //%s tried to summon a boat, but failed.
- parameters.caster->getCasterName(iw.text);
- env->apply(iw);
- return ESpellCastResult::OK;
- }
- //try to find unoccupied boat to summon
- const CGBoat * nearest = nullptr;
- double dist = 0;
- for(const auto & b : env->getMap()->getObjects<CGBoat>())
- {
- if(b->getBoardedHero() || b->layer != EPathfindingLayer::SAIL)
- continue; //we're looking for unoccupied boat
- double nDist = b->visitablePos().dist2d(parameters.caster->getHeroCaster()->visitablePos());
- if(!nearest || nDist < dist) //it's first boat or closer than previous
- {
- nearest = b;
- dist = nDist;
- }
- }
- int3 summonPos = parameters.caster->getHeroCaster()->bestLocation();
- if(nullptr != nearest) //we found boat to summon
- {
- ChangeObjPos cop;
- cop.objid = nearest->id;
- cop.nPos = summonPos;
- cop.initiator = parameters.caster->getCasterOwner();
- env->apply(cop);
- }
- else if(schoolLevel < 2) //none or basic level -> cannot create boat :(
- {
- InfoWindow iw;
- iw.player = parameters.caster->getCasterOwner();
- iw.text.appendLocalString(EMetaText::GENERAL_TXT, 335); //There are no boats to summon.
- env->apply(iw);
- return ESpellCastResult::ERROR;
- }
- else //create boat
- {
- env->createBoat(summonPos, BoatId::NECROPOLIS, parameters.caster->getCasterOwner());
- }
- return ESpellCastResult::OK;
- }
- VCMI_LIB_NAMESPACE_END
|