mirror of
https://github.com/vcmi/vcmi.git
synced 2025-05-13 22:06:58 +02:00
Support for wall penalty & No Wall Penalty ability.
All creature abilities should now be more or less working.
This commit is contained in:
parent
bdb6db2ab7
commit
10fce0025a
@ -28,7 +28,7 @@
|
|||||||
{ "id": "MAGIC_RESISTANCE", "name": "Magic Resistance", "description": "%d% chance to resist enemy spell" },
|
{ "id": "MAGIC_RESISTANCE", "name": "Magic Resistance", "description": "%d% chance to resist enemy spell" },
|
||||||
{ "id": "NO_DISTANCE_PENALTY", "name": "No distance penalty", "description": "Full damage from any distance" },
|
{ "id": "NO_DISTANCE_PENALTY", "name": "No distance penalty", "description": "Full damage from any distance" },
|
||||||
{ "id": "NO_MELEE_PENALTY", "name": "No melee penalty", "description": "Creature has no Melee Penalty" },
|
{ "id": "NO_MELEE_PENALTY", "name": "No melee penalty", "description": "Creature has no Melee Penalty" },
|
||||||
{ "id": "NO_OBSTACLES_PENALTY", "name": "No obstacle penalty", "description": "Creature has no Obstacle Penalty" },
|
{ "id": "NO_WALL_PENALTY", "name": "No wall penalty", "description": "Full damage during siege" },
|
||||||
{ "id": "BLOCKS_RETALIATION", "name": "No retaliation", "description": "Enemy cannot Retaliate" },
|
{ "id": "BLOCKS_RETALIATION", "name": "No retaliation", "description": "Enemy cannot Retaliate" },
|
||||||
{ "id": "NON_LIVING", "name": "Non living", "description": "Immunity to many effects" },
|
{ "id": "NON_LIVING", "name": "Non living", "description": "Immunity to many effects" },
|
||||||
{ "id": "SELF_LUCK", "name": "Positive luck", "description": "Always has Positive Luck" },
|
{ "id": "SELF_LUCK", "name": "Positive luck", "description": "Always has Positive Luck" },
|
||||||
|
@ -361,7 +361,7 @@
|
|||||||
"level": 4,
|
"level": 4,
|
||||||
"name": [ "Mage" ],
|
"name": [ "Mage" ],
|
||||||
"faction": 2,
|
"faction": 2,
|
||||||
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", -2, 0, 0 ] ], //mages reduce spell cost
|
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ] ], //mages reduce spell cost
|
||||||
"upgrade": 35,
|
"upgrade": 35,
|
||||||
"defname": "CMAGE.DEF",
|
"defname": "CMAGE.DEF",
|
||||||
"projectile_defname": "PMAGEX.DEF",
|
"projectile_defname": "PMAGEX.DEF",
|
||||||
@ -374,7 +374,7 @@
|
|||||||
"level": 4,
|
"level": 4,
|
||||||
"name": [ "ArchMage" ],
|
"name": [ "ArchMage" ],
|
||||||
"faction": 2,
|
"faction": 2,
|
||||||
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", -2, 0, 0 ] ], //archmages reduce spell cost //genies hate efreets
|
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]], //archmages reduce spell cost
|
||||||
"defname": "CAMAGE.DEF",
|
"defname": "CAMAGE.DEF",
|
||||||
"projectile_defname": "PMAGEX.DEF",
|
"projectile_defname": "PMAGEX.DEF",
|
||||||
"projectile_spin": false
|
"projectile_spin": false
|
||||||
@ -1416,7 +1416,7 @@
|
|||||||
"level": 6,
|
"level": 6,
|
||||||
"name": [ "Enchanter" ],
|
"name": [ "Enchanter" ],
|
||||||
"faction": -1,
|
"faction": -1,
|
||||||
"ability_add": [ [ "NO_OBSTACLES_PENALTY", 0, 0, 0 ],
|
"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
|
||||||
[ "ENCHANTER", 3, 28, 3], //air shield
|
[ "ENCHANTER", 3, 28, 3], //air shield
|
||||||
[ "ENCHANTER", 3, 41, 3], //bless
|
[ "ENCHANTER", 3, 41, 3], //bless
|
||||||
[ "ENCHANTER", 3, 45, 3], //wealness
|
[ "ENCHANTER", 3, 45, 3], //wealness
|
||||||
@ -1434,7 +1434,7 @@
|
|||||||
"level": 4,
|
"level": 4,
|
||||||
"name": [ "Sharpshooter" ],
|
"name": [ "Sharpshooter" ],
|
||||||
"faction": -1,
|
"faction": -1,
|
||||||
"ability_add": [ [ "NO_OBSTACLES_PENALTY", 0, 0, 0 ],
|
"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
|
||||||
[ "NO_DISTANCE_PENALTY", 0, 0, 0 ] ], //Sharpshooter
|
[ "NO_DISTANCE_PENALTY", 0, 0, 0 ] ], //Sharpshooter
|
||||||
"defname": "CSHARP.DEF",
|
"defname": "CSHARP.DEF",
|
||||||
"projectile_defname": "PELFX.DEF",
|
"projectile_defname": "PELFX.DEF",
|
||||||
|
@ -657,12 +657,18 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
|
|||||||
//wall / distance penalty + advanced air shield
|
//wall / distance penalty + advanced air shield
|
||||||
bool distPenalty = !NBonus::hasOfType(attackerHero, Bonus::NO_DISTANCE_PENALTY) &&
|
bool distPenalty = !NBonus::hasOfType(attackerHero, Bonus::NO_DISTANCE_PENALTY) &&
|
||||||
hasDistancePenalty(attacker, defender->position);
|
hasDistancePenalty(attacker, defender->position);
|
||||||
bool obstaclePenalty = !NBonus::hasOfType(attackerHero, Bonus::NO_OBSTACLES_PENALTY) &&
|
bool obstaclePenalty = hasWallPenalty(attacker, defender->position);
|
||||||
hasWallPenalty(attacker, defender->position);
|
if (shooting)
|
||||||
if (shooting && (distPenalty || obstaclePenalty || HLP::hasAdvancedAirShield(defender) ))
|
{
|
||||||
|
if (distPenalty || HLP::hasAdvancedAirShield(defender))
|
||||||
{
|
{
|
||||||
multBonus *= 0.5;
|
multBonus *= 0.5;
|
||||||
}
|
}
|
||||||
|
if (obstaclePenalty)
|
||||||
|
{
|
||||||
|
multBonus *= 0.5; //cumulative
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!shooting && attacker->hasBonusOfType(Bonus::SHOOTER) && !attacker->hasBonusOfType(Bonus::NO_MELEE_PENALTY))
|
if (!shooting && attacker->hasBonusOfType(Bonus::SHOOTER) && !attacker->hasBonusOfType(Bonus::NO_MELEE_PENALTY))
|
||||||
{
|
{
|
||||||
multBonus *= 0.5;
|
multBonus *= 0.5;
|
||||||
@ -982,7 +988,7 @@ ui32 BattleInfo::getSpellCost(const CSpell * sp, const CGHeroInstance * caster)
|
|||||||
{
|
{
|
||||||
if( stacks[g]->owner == caster->tempOwner && stacks[g]->hasBonusOfType(Bonus::CHANGES_SPELL_COST_FOR_ALLY) )
|
if( stacks[g]->owner == caster->tempOwner && stacks[g]->hasBonusOfType(Bonus::CHANGES_SPELL_COST_FOR_ALLY) )
|
||||||
{
|
{
|
||||||
amin(manaReduction, stacks[g]->valOfBonuses(Bonus::CHANGES_SPELL_COST_FOR_ALLY));
|
amax(manaReduction, stacks[g]->valOfBonuses(Bonus::CHANGES_SPELL_COST_FOR_ALLY));
|
||||||
}
|
}
|
||||||
if( stacks[g]->owner != caster->tempOwner && stacks[g]->hasBonusOfType(Bonus::CHANGES_SPELL_COST_FOR_ENEMY) )
|
if( stacks[g]->owner != caster->tempOwner && stacks[g]->hasBonusOfType(Bonus::CHANGES_SPELL_COST_FOR_ENEMY) )
|
||||||
{
|
{
|
||||||
@ -990,7 +996,7 @@ ui32 BattleInfo::getSpellCost(const CSpell * sp, const CGHeroInstance * caster)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret + manaReduction + manaIncrease;
|
return ret - manaReduction + manaIncrease;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BattleInfo::hexToWallPart(THex hex) const
|
int BattleInfo::hexToWallPart(THex hex) const
|
||||||
@ -1000,7 +1006,8 @@ int BattleInfo::hexToWallPart(THex hex) const
|
|||||||
|
|
||||||
static const std::pair<int, int> attackable[] = //potentially attackable parts of wall
|
static const std::pair<int, int> attackable[] = //potentially attackable parts of wall
|
||||||
{std::make_pair(50, 0), std::make_pair(183, 1), std::make_pair(182, 2), std::make_pair(130, 3),
|
{std::make_pair(50, 0), std::make_pair(183, 1), std::make_pair(182, 2), std::make_pair(130, 3),
|
||||||
std::make_pair(62, 4), std::make_pair(29, 5), std::make_pair(12, 6), std::make_pair(95, 7), std::make_pair(96, 7)};
|
std::make_pair(62, 4), std::make_pair(29, 5), std::make_pair(12, 6), std::make_pair(95, 7), std::make_pair(96, 7),
|
||||||
|
std::make_pair(45, -2), std::make_pair(78, -2), std::make_pair(112, -2), std::make_pair(147, -2)}; // -2 - indestructible walls
|
||||||
|
|
||||||
for(int g = 0; g < ARRAY_COUNT(attackable); ++g)
|
for(int g = 0; g < ARRAY_COUNT(attackable); ++g)
|
||||||
{
|
{
|
||||||
@ -1296,16 +1303,27 @@ si8 BattleInfo::sameSideOfWall(int pos1, int pos2) const
|
|||||||
|
|
||||||
si8 BattleInfo::hasWallPenalty( const CStack* stack, THex destHex ) const
|
si8 BattleInfo::hasWallPenalty( const CStack* stack, THex destHex ) const
|
||||||
{
|
{
|
||||||
if (siege == 0)
|
if (!siege || stack->hasBonusOfType(Bonus::NO_WALL_PENALTY))
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (stack->hasBonusOfType(Bonus::NO_WALL_PENALTY))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return !sameSideOfWall(stack->position, destHex);
|
int wallInStackLine = lineToWallHex(stack->position/BFIELD_WIDTH);
|
||||||
|
int wallInDestLine = lineToWallHex(destHex/BFIELD_WIDTH);
|
||||||
|
|
||||||
|
bool stackLeft = stack->position < wallInStackLine;
|
||||||
|
bool destRight = destHex > wallInDestLine;
|
||||||
|
|
||||||
|
if (stackLeft && destRight) //shooting from outside to inside
|
||||||
|
{
|
||||||
|
int row = (stack->position + destHex) / (2 * BFIELD_WIDTH);
|
||||||
|
if (stack->position > destHex && ((destHex & BFIELD_WIDTH - stack->position % BFIELD_WIDTH) < 2)) //shooting up high
|
||||||
|
row -= 2;
|
||||||
|
int wallPos = lineToWallHex(row);
|
||||||
|
if (hexToWallPart(wallPos) != -1) //wall still exists or is indestructible
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
si8 BattleInfo::canTeleportTo(const CStack * stack, THex destHex, int telportLevel) const
|
si8 BattleInfo::canTeleportTo(const CStack * stack, THex destHex, int telportLevel) const
|
||||||
|
@ -659,6 +659,7 @@ void CArtHandler::addBonuses()
|
|||||||
|
|
||||||
giveArtBonus(90,Bonus::WATER_WALKING, 0, 1);//Boots of Levitation
|
giveArtBonus(90,Bonus::WATER_WALKING, 0, 1);//Boots of Levitation
|
||||||
giveArtBonus(91,Bonus::NO_DISTANCE_PENALTY,0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));//Golden Bow
|
giveArtBonus(91,Bonus::NO_DISTANCE_PENALTY,0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));//Golden Bow
|
||||||
|
giveArtBonus(91,Bonus::NO_WALL_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
||||||
giveArtBonus(92,Bonus::SPELL_IMMUNITY,0,35);//Sphere of Permanence
|
giveArtBonus(92,Bonus::SPELL_IMMUNITY,0,35);//Sphere of Permanence
|
||||||
giveArtBonus(93,Bonus::NEGATE_ALL_NATURAL_IMMUNITIES,0);//Orb of Vulnerability
|
giveArtBonus(93,Bonus::NEGATE_ALL_NATURAL_IMMUNITIES,0);//Orb of Vulnerability
|
||||||
|
|
||||||
@ -742,7 +743,6 @@ void CArtHandler::addBonuses()
|
|||||||
giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4, -1, Bonus::INDEPENDENT_MAX);
|
giveArtBonus(134, Bonus::LEVEL_SPELL_IMMUNITY, 4, -1, Bonus::INDEPENDENT_MAX);
|
||||||
|
|
||||||
//Titan's Thunder
|
//Titan's Thunder
|
||||||
// FIXME: should also add a permanent spell book, somehow.
|
|
||||||
giveArtBonus(135, Bonus::SPELL, 3, 57);
|
giveArtBonus(135, Bonus::SPELL, 3, 57);
|
||||||
|
|
||||||
//Admiral's Hat
|
//Admiral's Hat
|
||||||
@ -750,7 +750,7 @@ void CArtHandler::addBonuses()
|
|||||||
|
|
||||||
//Bow of the Sharpshooter
|
//Bow of the Sharpshooter
|
||||||
giveArtBonus(137, Bonus::NO_DISTANCE_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
giveArtBonus(137, Bonus::NO_DISTANCE_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
||||||
giveArtBonus(137, Bonus::NO_OBSTACLES_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
giveArtBonus(137, Bonus::NO_WALL_PENALTY, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
||||||
giveArtBonus(137, Bonus::FREE_SHOOTING, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
giveArtBonus(137, Bonus::FREE_SHOOTING, 0, 0, 0, new HasAnotherBonusLimiter(Bonus::SHOOTER));
|
||||||
|
|
||||||
//Wizard's Well
|
//Wizard's Well
|
||||||
|
@ -890,7 +890,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
|
|||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
enable = true;
|
enable = true;
|
||||||
b.type = Bonus::NO_OBSTACLES_PENALTY;
|
b.type = Bonus::NO_WALL_PENALTY;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -565,7 +565,7 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
|
|||||||
case Bonus::FREE_SHOOTING:
|
case Bonus::FREE_SHOOTING:
|
||||||
case Bonus::NO_MELEE_PENALTY:
|
case Bonus::NO_MELEE_PENALTY:
|
||||||
case Bonus::NO_DISTANCE_PENALTY:
|
case Bonus::NO_DISTANCE_PENALTY:
|
||||||
case Bonus::NO_OBSTACLES_PENALTY:
|
case Bonus::NO_WALL_PENALTY:
|
||||||
case Bonus::JOUSTING: //TODO: percent bonus?
|
case Bonus::JOUSTING: //TODO: percent bonus?
|
||||||
case Bonus::RETURN_AFTER_STRIKE:
|
case Bonus::RETURN_AFTER_STRIKE:
|
||||||
case Bonus::BLOCKS_RETALIATION:
|
case Bonus::BLOCKS_RETALIATION:
|
||||||
@ -743,7 +743,7 @@ std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
|
|||||||
fileName = "E_MORAL.bmp"; break;
|
fileName = "E_MORAL.bmp"; break;
|
||||||
case Bonus::RECEPTIVE:
|
case Bonus::RECEPTIVE:
|
||||||
fileName = "E_NOFRIM.bmp"; break;
|
fileName = "E_NOFRIM.bmp"; break;
|
||||||
case Bonus::NO_OBSTACLES_PENALTY:
|
case Bonus::NO_WALL_PENALTY:
|
||||||
fileName = "E_OBST.bmp"; break;
|
fileName = "E_OBST.bmp"; break;
|
||||||
case Bonus::ENEMY_DEFENCE_REDUCTION:
|
case Bonus::ENEMY_DEFENCE_REDUCTION:
|
||||||
fileName = "E_RDEF.bmp"; break;
|
fileName = "E_RDEF.bmp"; break;
|
||||||
|
@ -133,7 +133,6 @@ namespace PrimarySkill
|
|||||||
BONUS_NAME(FEAR) \
|
BONUS_NAME(FEAR) \
|
||||||
BONUS_NAME(FEARLESS) \
|
BONUS_NAME(FEARLESS) \
|
||||||
BONUS_NAME(NO_DISTANCE_PENALTY) \
|
BONUS_NAME(NO_DISTANCE_PENALTY) \
|
||||||
BONUS_NAME(NO_OBSTACLES_PENALTY) \
|
|
||||||
BONUS_NAME(SELF_LUCK) /*halfling*/ \
|
BONUS_NAME(SELF_LUCK) /*halfling*/ \
|
||||||
BONUS_NAME(ENCHANTER)/* for Enchanter spells, val - skill level, subtype - spell id, additionalInfo - cooldown */ \
|
BONUS_NAME(ENCHANTER)/* for Enchanter spells, val - skill level, subtype - spell id, additionalInfo - cooldown */ \
|
||||||
BONUS_NAME(HEALER) \
|
BONUS_NAME(HEALER) \
|
||||||
|
@ -3147,7 +3147,7 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(CGHeroInstance::BALLISTICS)];
|
CHeroHandler::SBallisticsLevelInfo sbi = VLC->heroh->ballistics[attackingHero->getSecSkillLevel(CGHeroInstance::BALLISTICS)];
|
||||||
|
|
||||||
int attackedPart = gs->curB->hexToWallPart(ba.destinationTile);
|
int attackedPart = gs->curB->hexToWallPart(ba.destinationTile);
|
||||||
if(attackedPart == -1)
|
if(attackedPart < 0)
|
||||||
{
|
{
|
||||||
complain("catapult tried to attack non-catapultable hex!");
|
complain("catapult tried to attack non-catapultable hex!");
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user