diff --git a/CCallback.cpp b/CCallback.cpp index 14e09d081..d1795e36f 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -546,7 +546,10 @@ bool CCallback::battleCanShoot(int ID, int dest) { boost::shared_lock lock(*gs->mx); const CStack *our = battleGetStackByID(ID), *dst = battleGetStackByPos(dest); - if(!our || !dst || !gs->curB) return false; + + if(!our || !dst || !gs->curB) return false; + + int ourHero = our->attackerOwned ? gs->curB->hero1 : gs->curB->hero2; //for(size_t g=0; geffects.size(); ++g) //{ @@ -557,16 +560,10 @@ bool CCallback::battleCanShoot(int ID, int dest) return false; - // See if the stack can benefit from the Bow of the Sharpshooter. - int ourHero = our->attackerOwned ? gs->curB->hero1 : gs->curB->hero2; - bool hasSharpshooterBow = false; - if (ourHero != -1) - hasSharpshooterBow = gs->getHero(ourHero)->getArtPos(137) != -1; - if(our->hasFeatureOfType(StackFeature::SHOOTER)//it's shooter && our->owner != dst->owner && dst->alive() - && (!gs->curB->isStackBlocked(ID) || hasSharpshooterBow) + && (!gs->curB->isStackBlocked(ID) || gs->getHero(ourHero)->hasBonusOfType(HeroBonus::FREE_SHOOTING)) && our->shots ) return true; diff --git a/hch/CArtHandler.cpp b/hch/CArtHandler.cpp index 0dbf606de..5bfe43ac9 100644 --- a/hch/CArtHandler.cpp +++ b/hch/CArtHandler.cpp @@ -344,6 +344,7 @@ void CArtHandler::addBonuses() //Elixir of Life giveArtBonus(131, HeroBonus::STACK_HEALTH, +4); + giveArtBonus(131, HeroBonus::STACK_HEALTH_PERCENT, +25); //Armor of the Damned ART_ATTACK_AND_DEFENSE(132, +3); @@ -368,6 +369,10 @@ void CArtHandler::addBonuses() //Bow of the Sharpshooter giveArtBonus(137, HeroBonus::SECONDARY_SKILL_PREMY, +30, 1); giveArtBonus(137, HeroBonus::NO_SHOTING_PENALTY, 0); + giveArtBonus(137, HeroBonus::FREE_SHOOTING, 0); + + //Wizard's Well + giveArtBonus(138, HeroBonus::FULL_MANA_REGENERATION, 0); //Ring of the Magi giveArtBonus(139, HeroBonus::SPELL_DURATION, +56); diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index e07721244..f15f5513d 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -1014,8 +1014,9 @@ int CGHeroInstance::getSightRadious() const si32 CGHeroInstance::manaRegain() const { - if (getArtPos(138) != -1) // Hero has Wizard's Well equipped. + if (hasBonusOfType(HeroBonus::FULL_MANA_REGENERATION)) return manaLimit(); + return 1 + getSecSkillLevel(8) + valOfBonuses(HeroBonus::MANA_REGENERATION); //1 + Mysticism level } diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 9a748b195..2409771b9 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -267,6 +267,14 @@ CStack * BattleInfo::getStackT(int tileID, bool onlyAlive) void BattleInfo::getAccessibilityMap(bool *accessibility, bool twoHex, bool attackerOwned, bool addOccupiable, std::set & occupyable, bool flying, int stackToOmmit) { memset(accessibility, 1, BFIELD_SIZE); //initialize array with trues + + //removing accessibility for side columns of hexes + for(int v = 0; v < BFIELD_SIZE; ++v) + { + if( v % BFIELD_WIDTH == 0 || v % BFIELD_WIDTH == (BFIELD_WIDTH - 1) ) + accessibility[v] = false; + } + for(unsigned int g=0; galive() || stacks[g]->ID==stackToOmmit) //we don't want to lock position of this stack @@ -411,20 +419,6 @@ std::vector BattleInfo::getAccessibility(int stackID, bool addOccupiable) } } - // 2-hex creatures should not be able to move to a hex with an inaccesible hex to the left or right - // at the horizontal edges of the battlefield. - if (s->hasFeatureOfType(StackFeature::DOUBLE_WIDE)) { - int i = 0; - while (i < ret.size()) { - if (ret[i]%BFIELD_WIDTH == 1 && ret[i] + 1 != ret[i + 1]) - ret.erase(ret.begin() + i); - else if (ret[i]%BFIELD_WIDTH == BFIELD_WIDTH - 1 && (i == 0 || ret[i] - 1 != ret[i - 1])) - ret.erase(ret.begin() + i); - else - i++; - } - } - return ret; } bool BattleInfo::isStackBlocked(int ID) @@ -2238,8 +2232,12 @@ CStack * BattleInfo::generateNewStack(const CGHeroInstance * owner, int creature //other bonuses ret->features.push_back(makeFeature(StackFeature::ATTACK_BONUS, StackFeature::WHOLE_BATTLE, 0, owner->getPrimSkillLevel(0), StackFeature::BONUS_FROM_HERO)); ret->features.push_back(makeFeature(StackFeature::DEFENCE_BONUS, StackFeature::WHOLE_BATTLE, 0, owner->getPrimSkillLevel(1), StackFeature::BONUS_FROM_HERO)); - if (owner->getArtPos(131) != -1) // Elixir of Life, add 25% HP - ret->features.push_back(makeFeature(StackFeature::HP_BONUS, StackFeature::WHOLE_BATTLE, 0, ret->creature->hitPoints*0.25, StackFeature::BONUS_FROM_HERO)); + + if ( owner->hasBonusOfType(HeroBonus::STACK_HEALTH_PERCENT) ) // Elixir of Life, add 25% HP + ret->features.push_back(makeFeature(StackFeature::HP_BONUS, StackFeature::WHOLE_BATTLE, 0, + (ret->creature->hitPoints * owner->valOfBonuses(HeroBonus::STACK_HEALTH_PERCENT)) / 100, + StackFeature::BONUS_FROM_HERO)); + ret->features.push_back(makeFeature(StackFeature::HP_BONUS, StackFeature::WHOLE_BATTLE, 0, owner->valOfBonuses(HeroBonus::STACK_HEALTH), StackFeature::BONUS_FROM_HERO)); ret->firstHPleft = ret->MaxHealth(); } diff --git a/lib/HeroBonus.h b/lib/HeroBonus.h index 81df81b5a..078a39a24 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -27,6 +27,7 @@ struct DLL_EXPORT HeroBonus PRIMARY_SKILL, //uses subtype to pick skill SIGHT_RADIOUS, MANA_REGENERATION, //points per turn apart from normal (1 + mysticism) + FULL_MANA_REGENERATION, //all mana points are replenished every day //not handled yet: MAGIC_RESISTANCE, // % SECONDARY_SKILL_PREMY, //% @@ -34,7 +35,8 @@ struct DLL_EXPORT HeroBonus STACKS_SPEED, FLYING_MOVEMENT, SPELL_DURATION, AIR_SPELL_DMG_PREMY, EARTH_SPELL_DMG_PREMY, FIRE_SPELL_DMG_PREMY, WATER_SPELL_DMG_PREMY, BLOCK_SPELLS_ABOVE_LEVEL, WATER_WALKING, NO_SHOTING_PENALTY, DISPEL_IMMUNITY, - NEGATE_ALL_NATURAL_IMMUNITIES, STACK_HEALTH, SPELL_IMMUNITY, BLOCK_MORALE, BLOCK_LUCK, FIRE_SPELLS, + NEGATE_ALL_NATURAL_IMMUNITIES, STACK_HEALTH, STACK_HEALTH_PERCENT, //the second one of stack health - value in % of base HP to be added to overall stack HP + SPELL_IMMUNITY, BLOCK_MORALE, BLOCK_LUCK, FIRE_SPELLS, AIR_SPELLS, WATER_SPELLS, EARTH_SPELLS, GENERATE_RESOURCE, //daily value, uses subtype (resource type) CREATURE_GROWTH, //for legion artifacts: value - week growth bonus, subtype - monster level @@ -43,6 +45,7 @@ struct DLL_EXPORT HeroBonus SPELLS_OF_LEVEL, //hero knows all spells of given level, val - skill level; subtype - level ENEMY_CANT_ESCAPE, //for shackles of war MAGIC_SCHOOL_SKILL, //eg. for magic plains terrain, subtype: school of magic (0 - all, 1 - fire, 2 - air, 4 - water, 8 - earth), value - level + FREE_SHOOTING //stacks can shoot even if otherwise blocked (sharpshooter's bow effect) }; enum BonusDuration{PERMANENT, ONE_BATTLE, ONE_DAY, ONE_WEEK}; enum BonusSource{ARTIFACT, OBJECT};