diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 2ce8bec10..ffafc8e38 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -439,11 +439,15 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr): CIntObject * CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero { - if(!specific) + if(nullptr == specific) specific = adventureInt->selection; - - assert(specific); - + + if(nullptr == specific) + { + logGlobal->error("createInfoWin: no object to describe"); + return nullptr; + } + switch(specific->ID) { case Obj::HERO: diff --git a/config/bonuses.json b/config/bonuses.json index 44380dcd6..7ae0bade3 100644 --- a/config/bonuses.json +++ b/config/bonuses.json @@ -525,6 +525,11 @@ "icon": "zvs/Lib1.res/E_RETAIL1" } }, + + "VISIONS": + { + "hidden": true + }, "WATER_IMMUNITY": { "graphics": diff --git a/config/spells/adventure.json b/config/spells/adventure.json index a9932a7eb..3aef7c4cc 100644 --- a/config/spells/adventure.json +++ b/config/spells/adventure.json @@ -17,7 +17,7 @@ }, "scuttleBoat" : { "index" : 1, - "targetType": "LOCATION", + "targetType": "NO_TARGET", "sounds": { "cast": "SCUTBOAT" @@ -40,7 +40,30 @@ }, "levels" : { "base":{ - "range" : "X" + "range" : "0", + "effects" : { + "visionsMonsters" : { + "type" : "VISIONS", + "subtype" : 0, + "duration" : "ONE_DAY", + "val" : 1, + "valueType" : "INDEPENDENT_MAX" + } + } + }, + "advanced":{ + "effects" : { + "visionsMonsters" : { + "val" : 2 + } + } + }, + "expert":{ + "effects" : { + "visionsMonsters" : { + "val" : 3 + } + } } }, "flags" : { @@ -104,7 +127,29 @@ }, "levels" : { "base":{ - "range" : "X" + "range" : "0", + "effects" : { + "fly" : { + "type" : "FLYING_MOVEMENT", + "subtype" : 2, + "duration" : "ONE_DAY", + "val" : 0 //in fact unused + } + } + }, + "advanced":{ + "effects" : { + "fly" : { + "subtype" : 1 + } + } + }, + "expert":{ + "effects" : { + "fly" : { + "subtype" : 1 + } + } } }, "flags" : { @@ -120,7 +165,29 @@ }, "levels" : { "base":{ - "range" : "X" + "range" : "0", + "effects" : { + "waterWalk" : { + "type" : "WATER_WALKING", + "subtype" : 2, + "duration" : "ONE_DAY", + "val" : 0 //in fact unused + } + } + }, + "advanced":{ + "effects" : { + "waterWalk" : { + "subtype" : 1 + } + } + }, + "expert":{ + "effects" : { + "waterWalk" : { + "subtype" : 1 + } + } } }, "flags" : { diff --git a/lib/spells/AdventureSpellMechanics.cpp b/lib/spells/AdventureSpellMechanics.cpp index 86d9ee616..8d0cf48ae 100644 --- a/lib/spells/AdventureSpellMechanics.cpp +++ b/lib/spells/AdventureSpellMechanics.cpp @@ -19,37 +19,6 @@ #include "../CGameState.h" #include "../CGameInfoCallback.h" - -///AdventureBonusingMechanics -bool AdventureBonusingMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const -{ - const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner); - const int subtype = spellLevelToSubtype(schoolLevel); - - GiveBonus gb; - gb.id = parameters.caster->id.getNum(); - gb.bonus = Bonus(Bonus::ONE_DAY, bonusTypeID, Bonus::SPELL_EFFECT, 0, owner->id, subtype); - env->sendAndApply(&gb); - return true; -} - -int FlyMechanics::spellLevelToSubtype(const int schoolLevel) const -{ - return schoolLevel >= 2 ? 1 : 2; //adv or expert -} - -int VisionsMechanics::spellLevelToSubtype(const int schoolLevel) const -{ - //0,1 schoolLevel => 0 subtype - //2 schoolLevel => 1 subtype - //3 schoolLevel => 2 subtype - int result = schoolLevel - 1; - vstd::amin(result, 0); - vstd::amax(result, 2); - return result; //adv or expert -} - - ///SummonBoatMechanics bool SummonBoatMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const { diff --git a/lib/spells/AdventureSpellMechanics.h b/lib/spells/AdventureSpellMechanics.h index 7eda5e955..120dfb4b1 100644 --- a/lib/spells/AdventureSpellMechanics.h +++ b/lib/spells/AdventureSpellMechanics.h @@ -13,37 +13,6 @@ #include "CDefaultSpellMechanics.h" -//todo: make configurable -class AdventureBonusingMechanics: public DefaultSpellMechanics -{ -public: - AdventureBonusingMechanics(CSpell * s, Bonus::BonusType _bonusTypeID): DefaultSpellMechanics(s), bonusTypeID(_bonusTypeID){}; -protected: - bool applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override; - - virtual int spellLevelToSubtype(const int schoolLevel) const = 0; -private: - Bonus::BonusType bonusTypeID; -}; - -//FLY & WATER_WALK -class FlyMechanics: public AdventureBonusingMechanics -{ -public: - FlyMechanics(CSpell * s, Bonus::BonusType _bonusTypeID): AdventureBonusingMechanics(s, _bonusTypeID){}; -protected: - int spellLevelToSubtype(const int schoolLevel) const override; -}; - -//VISIONS & DISGUISE -class VisionsMechanics: public AdventureBonusingMechanics -{ -public: - VisionsMechanics(CSpell * s, Bonus::BonusType _bonusTypeID): AdventureBonusingMechanics(s, _bonusTypeID){}; -protected: - int spellLevelToSubtype(const int schoolLevel) const override; -}; - class SummonBoatMechanics: public DefaultSpellMechanics { public: diff --git a/lib/spells/CDefaultSpellMechanics.cpp b/lib/spells/CDefaultSpellMechanics.cpp index 6cb382b94..006c4dfe1 100644 --- a/lib/spells/CDefaultSpellMechanics.cpp +++ b/lib/spells/CDefaultSpellMechanics.cpp @@ -191,9 +191,30 @@ bool DefaultSpellMechanics::adventureCast(const SpellCastEnvironment * env, Adve bool DefaultSpellMechanics::applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const { - //There is no generic algorithm of adventure cast - env->complain("Unimplemented adventure spell"); - return false; + if(owner->hasEffects()) + { + const int schoolLevel = parameters.caster->getSpellSchoolLevel(owner); + + std::vector bonuses; + + owner->getEffects(bonuses, schoolLevel); + + for(Bonus b : bonuses) + { + GiveBonus gb; + gb.id = parameters.caster->id.getNum(); + gb.bonus = b; + env->sendAndApply(&gb); + } + + return true; + } + else + { + //There is no generic algorithm of adventure cast + env->complain("Unimplemented adventure spell"); + return false; + } } diff --git a/lib/spells/CSpellHandler.cpp b/lib/spells/CSpellHandler.cpp index a0fee28c5..b41702ff5 100644 --- a/lib/spells/CSpellHandler.cpp +++ b/lib/spells/CSpellHandler.cpp @@ -358,8 +358,6 @@ const std::string& CSpell::getCastSound() const return castSound; } - - si32 CSpell::getCost(const int skillLevel) const { return getLevelInfo(skillLevel).cost; diff --git a/lib/spells/ISpellMechanics.cpp b/lib/spells/ISpellMechanics.cpp index 025380c83..7cab9ea7c 100644 --- a/lib/spells/ISpellMechanics.cpp +++ b/lib/spells/ISpellMechanics.cpp @@ -69,19 +69,16 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s) case SpellID::DIMENSION_DOOR: return new DimensionDoorMechanics(s); case SpellID::FLY: - return new FlyMechanics(s, Bonus::FLYING_MOVEMENT); //temporary case SpellID::WATER_WALK: - return new FlyMechanics(s, Bonus::WATER_WALKING); //temporary + case SpellID::VISIONS: + case SpellID::DISGUISE: + return new DefaultSpellMechanics(s); //implemented using bonus system case SpellID::TOWN_PORTAL: return new TownPortalMechanics(s); case SpellID::VIEW_EARTH: return new ViewEarthMechanics(s); case SpellID::VIEW_AIR: return new ViewAirMechanics(s); - case SpellID::VISIONS: - return new VisionsMechanics(s, Bonus::VISIONS); //temporary - case SpellID::DISGUISE: - return new VisionsMechanics(s, Bonus::DISGUISED); //temporary default: if(s->isRisingSpell()) return new SpecialRisingSpellMechanics(s);