diff --git a/config/cr_abils.txt b/config/cr_abils.txt index 833466741..de70eff52 100644 --- a/config/cr_abils.txt +++ b/config/cr_abils.txt @@ -46,11 +46,13 @@ + 40 SPELL_IMMUNITY 0 59 0 //giants are immune to mind spells (berserk) + 40 SPELL_IMMUNITY 0 60 0 //giants are immune to mind spells (hypnotize) + 40 SPELL_IMMUNITY 0 61 0 //giants are immune to mind spells (forgetfulness) ++ 40 SPELL_IMMUNITY 0 62 0 //giants are immune to mind spells (blind) + 41 HATE 0 83 0 //titans hate black dragons + 41 SPELL_IMMUNITY 0 50 0 //titans are immune to mind spells (sorrow) + 41 SPELL_IMMUNITY 0 59 0 //titans are immune to mind spells (berserk) + 41 SPELL_IMMUNITY 0 60 0 //titans are immune to mind spells (hypnotize) + 41 SPELL_IMMUNITY 0 61 0 //titans are immune to mind spells (forgetfulness) ++ 41 SPELL_IMMUNITY 0 62 0 //titans are immune to mind spells (blind) + 43 MANA_CHANNELING 20 0 0 //familiars + 45 SPELL_LIKE_ATTACK 21 0 0 //magogs fire with fireballs + 47 BLOCKS_RETALIATION 0 0 0 //cerberus diff --git a/hch/CArtHandler.cpp b/hch/CArtHandler.cpp index 5bfe43ac9..5815a27e8 100644 --- a/hch/CArtHandler.cpp +++ b/hch/CArtHandler.cpp @@ -222,7 +222,7 @@ void CArtHandler::addBonuses() giveArtBonus(49,HeroBonus::SPELL_IMMUNITY,59);//berserk giveArtBonus(49,HeroBonus::SPELL_IMMUNITY,60);//hypnotize giveArtBonus(49,HeroBonus::SPELL_IMMUNITY,61);//forgetfulness - giveArtBonus(49,HeroBonus::SPELL_IMMUNITY,62);//forgetfulness + giveArtBonus(49,HeroBonus::SPELL_IMMUNITY,62);//blind ART_MORALE(50,+1); //Crest of Valor ART_MORALE(51,+1); //Glyph of Gallantry @@ -332,27 +332,46 @@ void CArtHandler::addBonuses() //Armageddon's Blade giveArtBonus(128, HeroBonus::SPELL, 3, 26); + giveArtBonus(128, HeroBonus::SPELL_IMMUNITY, 26); ART_ATTACK_AND_DEFENSE(128, +3); ART_PRIM_SKILL(128, 2, +3); ART_PRIM_SKILL(128, 3, +6); //Angelic Alliance ART_ALL_PRIM_SKILLS(129, +21); + giveArtBonus(129, HeroBonus::NONEVIL_ALIGNMENT_MIX, 0); + giveArtBonus(129, HeroBonus::OPENING_BATTLE_SPELL, 10, 29); // Prayer //Cloak of the Undead King giveArtBonus(130, HeroBonus::SECONDARY_SKILL_PREMY, +30, 12); + giveArtBonus(130, HeroBonus::SECONDARY_SKILL_PREMY, +30, 12); + giveArtBonus(130, HeroBonus::IMPROVED_NECROMANCY, 0); //Elixir of Life giveArtBonus(131, HeroBonus::STACK_HEALTH, +4); giveArtBonus(131, HeroBonus::STACK_HEALTH_PERCENT, +25); + giveArtBonus(131, HeroBonus::HP_REGENERATION, +50); //Armor of the Damned ART_ATTACK_AND_DEFENSE(132, +3); ART_POWER_AND_KNOWLEDGE(132, +2); + giveArtBonus(132, HeroBonus::OPENING_BATTLE_SPELL, 50, 54); // Slow + giveArtBonus(132, HeroBonus::OPENING_BATTLE_SPELL, 50, 47); // Disrupting Ray + giveArtBonus(132, HeroBonus::OPENING_BATTLE_SPELL, 50, 45); // Weakness + giveArtBonus(132, HeroBonus::OPENING_BATTLE_SPELL, 50, 52); // Misfortune + + // Statue of Legion + giveArtBonus(133, HeroBonus::CREATURE_GROWTH, +5, 1); + giveArtBonus(133, HeroBonus::CREATURE_GROWTH, +4, 2); + giveArtBonus(133, HeroBonus::CREATURE_GROWTH, +3, 3); + giveArtBonus(133, HeroBonus::CREATURE_GROWTH, +2, 4); + giveArtBonus(133, HeroBonus::CREATURE_GROWTH, +1, 5); + giveArtBonus(133, HeroBonus::CREATURE_GROWTH_PERCENT, 50); //Power of the Dragon Father ART_ALL_PRIM_SKILLS(134, +16); giveArtBonus(134, HeroBonus::MORALE_AND_LUCK, +1); + giveArtBonus(134, HeroBonus::LEVEL_SPELL_IMMUNITY, 4); //Titan's Thunder ART_ATTACK_AND_DEFENSE(135, +9); @@ -360,11 +379,11 @@ void CArtHandler::addBonuses() giveArtBonus(135, HeroBonus::SPELL, 3, 57); //Admiral's Hat - giveArtBonus(136, HeroBonus::SEA_MOVEMENT, +1000); + giveArtBonus(136, HeroBonus::SEA_MOVEMENT, +1500); giveArtBonus(136, HeroBonus::WHIRLPOOL_PROTECTION, 0); - giveArtBonus(136, HeroBonus::SEA_MOVEMENT, +500); giveArtBonus(136, HeroBonus::SPELL, 3, 0); giveArtBonus(136, HeroBonus::SPELL, 3, 1); + giveArtBonus(136, HeroBonus::FREE_SHIP_BOARDING, 0); //Bow of the Sharpshooter giveArtBonus(137, HeroBonus::SECONDARY_SKILL_PREMY, +30, 1); diff --git a/hch/CObjectHandler.cpp b/hch/CObjectHandler.cpp index 4787fdd7e..4fb7f7e52 100644 --- a/hch/CObjectHandler.cpp +++ b/hch/CObjectHandler.cpp @@ -858,7 +858,18 @@ std::vector > CGHeroInstance::getCurrentMoraleModifie std::set factions; for(std::map >::const_iterator i=army.slots.begin(); i!=army.slots.end(); i++) { - factions.insert(VLC->creh->creatures[i->second.first].faction); + // Take Angelic Alliance troop-mixing freedom into account. + si8 faction = VLC->creh->creatures[i->second.first].faction; + if (hasBonusOfType(HeroBonus::NONEVIL_ALIGNMENT_MIX) + && (faction <= 2 || faction == 6 || faction == 8)) + { + factions.insert(0); // Insert any non-evil alignment as arbitrary single faction, in this case Castle. + } + else + { + factions.insert(faction); + } + if(i->second.first == 13) archangelInArmy = true; } diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 8d0e6de15..f1d3718b0 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -2244,10 +2244,17 @@ CStack * BattleInfo::generateNewStack(const CGHeroInstance * owner, int creature 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->hasBonusOfType(HeroBonus::STACK_HEALTH_PERCENT) ) // Elixir of Life, add 25% HP + if ( owner->hasBonusOfType(HeroBonus::STACK_HEALTH_PERCENT) ) // e.g. Elixir of Life 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->creature->hitPoints * owner->valOfBonuses(HeroBonus::STACK_HEALTH_PERCENT)) / 100, + StackFeature::BONUS_FROM_HERO)); + if (owner->hasBonusOfType(HeroBonus::HP_REGENERATION)) // e.g. Elixir of Life + ret->features.push_back(makeFeature(StackFeature::HP_REGENERATION, StackFeature::WHOLE_BATTLE, 0, + owner->valOfBonuses(HeroBonus::HP_REGENERATION), StackFeature::BONUS_FROM_HERO)); + + if (owner->hasBonusOfType(HeroBonus::LEVEL_SPELL_IMMUNITY)) // e.g. Power of the Dragon Father + ret->features.push_back(makeFeature(StackFeature::LEVEL_SPELL_IMMUNITY, StackFeature::WHOLE_BATTLE, 0, + owner->valOfBonuses(HeroBonus::LEVEL_SPELL_IMMUNITY), 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 078a39a24..127b2f969 100644 --- a/lib/HeroBonus.h +++ b/lib/HeroBonus.h @@ -28,6 +28,9 @@ struct DLL_EXPORT HeroBonus SIGHT_RADIOUS, MANA_REGENERATION, //points per turn apart from normal (1 + mysticism) FULL_MANA_REGENERATION, //all mana points are replenished every day + NONEVIL_ALIGNMENT_MIX, //good and neutral creatures can be mixed without morale penalty + HP_REGENERATION, //regenerates a certain amount of hp for the top of each stack every turn, val - hp regained + LEVEL_SPELL_IMMUNITY, //val - spell level creatures become immune to and below //not handled yet: MAGIC_RESISTANCE, // % SECONDARY_SKILL_PREMY, //% @@ -45,7 +48,11 @@ 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) + FREE_SHOOTING, //stacks can shoot even if otherwise blocked (sharpshooter's bow effect) + OPENING_BATTLE_SPELL, //casts a spell at expert level at beginning of battle, val - spell power, subtype - spell id + IMPROVED_NECROMANCY, //allows Necropolis units other than skeletons to be raised by necromancy + CREATURE_GROWTH_PERCENT, //increases growth of all units in all towns, val - percentage + FREE_SHIP_BOARDING //movement points preserved with ship boarding and landing }; enum BonusDuration{PERMANENT, ONE_BATTLE, ONE_DAY, ONE_WEEK}; enum BonusSource{ARTIFACT, OBJECT};