mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Fixed #1130.
Moved isToReverse() function to battleCallback so that creature rotation will be handled by core mechanics and not only GUI.
This commit is contained in:
parent
89196c577e
commit
52242692f1
@ -63,48 +63,6 @@ CBattleStackAnimation::CBattleStackAnimation(CBattleInterface * _owner, const CS
|
||||
: CBattleAnimation(_owner), stack(_stack)
|
||||
{}
|
||||
|
||||
bool CBattleStackAnimation::isToReverseHlp(BattleHex hexFrom, BattleHex hexTo, bool curDir)
|
||||
{
|
||||
int fromMod = hexFrom % GameConstants::BFIELD_WIDTH;
|
||||
int fromDiv = hexFrom / GameConstants::BFIELD_WIDTH;
|
||||
int toMod = hexTo % GameConstants::BFIELD_WIDTH;
|
||||
|
||||
if(curDir && fromMod < toMod)
|
||||
return false;
|
||||
else if(curDir && fromMod > toMod)
|
||||
return true;
|
||||
else if(curDir && fromMod == toMod)
|
||||
{
|
||||
return fromDiv % 2 == 0;
|
||||
}
|
||||
else if(!curDir && fromMod < toMod)
|
||||
return true;
|
||||
else if(!curDir && fromMod > toMod)
|
||||
return false;
|
||||
else if(!curDir && fromMod == toMod)
|
||||
{
|
||||
return fromDiv % 2 == 1;
|
||||
}
|
||||
tlog1 << "Catastrope in CBattleStackAnimation::isToReverse!" << std::endl;
|
||||
return false; //should never happen
|
||||
}
|
||||
|
||||
bool CBattleStackAnimation::isToReverse(BattleHex hexFrom, BattleHex hexTo, bool curDir, bool toDoubleWide, bool toDir)
|
||||
{
|
||||
if(hexTo < 0) //turret
|
||||
return false;
|
||||
|
||||
if(toDoubleWide)
|
||||
{
|
||||
return isToReverseHlp(hexFrom, hexTo, curDir) &&
|
||||
(toDir ? isToReverseHlp(hexFrom, hexTo-1, curDir) : isToReverseHlp(hexFrom, hexTo+1, curDir) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return isToReverseHlp(hexFrom, hexTo, curDir);
|
||||
}
|
||||
}
|
||||
|
||||
CCreatureAnimation* CBattleStackAnimation::myAnim()
|
||||
{
|
||||
return owner->creAnims[stack->ID];
|
||||
@ -197,7 +155,7 @@ bool CDefenceAnimation::init()
|
||||
|
||||
|
||||
//reverse unit if necessary
|
||||
if(attacker && isToReverse(stack->position, attacker->position, owner->creDir[stack->ID], attacker->doubleWide(), owner->creDir[attacker->ID]))
|
||||
if (attacker && owner->curInt->cb->isToReverse(stack->position, attacker->position, owner->creDir[stack->ID], attacker->doubleWide(), owner->creDir[attacker->ID]))
|
||||
{
|
||||
owner->addNewAnim(new CReverseAnimation(owner, stack, stack->position, true));
|
||||
return false;
|
||||
@ -313,9 +271,9 @@ bool CMeleeAttackAnimation::init()
|
||||
return false;
|
||||
}
|
||||
|
||||
bool toReverse = isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]);
|
||||
bool toReverse = owner->curInt->cb->isToReverse(attackingStackPosBeforeReturn, dest, owner->creDir[stack->ID], attackedStack->doubleWide(), owner->creDir[attackedStack->ID]);
|
||||
|
||||
if(toReverse)
|
||||
if (toReverse)
|
||||
{
|
||||
|
||||
owner->addNewAnim(new CReverseAnimation(owner, stack, attackingStackPosBeforeReturn, true));
|
||||
|
@ -44,9 +44,6 @@ public:
|
||||
const CStack * stack; //id of stack whose animation it is
|
||||
|
||||
CBattleStackAnimation(CBattleInterface * _owner, const CStack * _stack);
|
||||
|
||||
static bool isToReverseHlp(BattleHex hexFrom, BattleHex hexTo, bool curDir); //helper for isToReverse
|
||||
static bool isToReverse(BattleHex hexFrom, BattleHex hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir); //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo)
|
||||
|
||||
CCreatureAnimation * myAnim(); //animation for our stack
|
||||
};
|
||||
|
@ -122,7 +122,7 @@ private:
|
||||
CDefHandler *fireWall;
|
||||
CDefHandler *smallForceField[2], *bigForceField[2]; // [side]
|
||||
|
||||
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
|
||||
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation> //TODO: move it to battle callback
|
||||
ui8 animCount;
|
||||
const CStack * activeStack; //number of active stack; NULL - no one
|
||||
const CStack * stackToActivate; //when animation is playing, we should wait till the end to make the next stack active; NULL of none
|
||||
|
@ -1282,14 +1282,26 @@ ReachabilityInfo CBattleInfoCallback::getFlyingReachability(const ReachabilityIn
|
||||
return ret;
|
||||
}
|
||||
|
||||
AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos) const
|
||||
AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes (const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos) const
|
||||
{
|
||||
//TODO: apply rotation to two-hex attackers
|
||||
auto side = playerToSide (attacker->owner);
|
||||
|
||||
AttackableTiles at;
|
||||
RETURN_IF_NOT_BATTLE(at);
|
||||
|
||||
const int WN = GameConstants::BFIELD_WIDTH;
|
||||
ui16 hex = (attackerPos != BattleHex::INVALID) ? attackerPos.hex : attacker->position.hex; //real or hypothetical (cursor) position
|
||||
|
||||
//FIXME: dragons or cerbers can rotate before attack, making their base hex different (#1124)
|
||||
bool reverse = isToReverse (hex, destinationTile, side, attacker->doubleWide(), side);
|
||||
if (reverse && attacker->doubleWide())
|
||||
{
|
||||
if (attacker->owner)
|
||||
--hex; //move left
|
||||
else
|
||||
++hex; //move right
|
||||
}
|
||||
if (attacker->hasBonusOfType(Bonus::ATTACKS_ALL_ADJACENT))
|
||||
{
|
||||
boost::copy(attacker->getSurroundingHexes(attackerPos), vstd::set_inserter(at.hostileCreaturePositions));
|
||||
@ -1301,7 +1313,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const CStack*
|
||||
std::vector<BattleHex> hexes = attacker->getSurroundingHexes(attackerPos);
|
||||
BOOST_FOREACH (BattleHex tile, hexes)
|
||||
{
|
||||
if ((BattleHex::mutualPosition(tile, destinationTile) > -1 && BattleHex::mutualPosition(tile, hex) > -1) //adjacent both to attacker's head and attacked tile
|
||||
if ((BattleHex::mutualPosition(tile, destinationTile) > -1 && BattleHex::mutualPosition (tile, hex) > -1) //adjacent both to attacker's head and attacked tile
|
||||
|| tile == destinationTile) //or simply attacked directly
|
||||
{
|
||||
const CStack * st = battleGetStackByPos(tile, true);
|
||||
@ -1312,7 +1324,7 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const CStack*
|
||||
}
|
||||
}
|
||||
}
|
||||
if (attacker->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH))
|
||||
if (attacker->hasBonusOfType(Bonus::TWO_HEX_ATTACK_BREATH) && BattleHex::mutualPosition (destinationTile.hex, hex) > -1) //only adjacent hexes are subject of dragon breath calculation
|
||||
{
|
||||
std::vector<BattleHex> hexes; //only one, in fact
|
||||
int pseudoVector = destinationTile.hex - hex;
|
||||
@ -1320,24 +1332,24 @@ AttackableTiles CBattleInfoCallback::getPotentiallyAttackableHexes(const CStack*
|
||||
{
|
||||
case 1:
|
||||
case -1:
|
||||
BattleHex::checkAndPush(destinationTile.hex + pseudoVector, hexes);
|
||||
BattleHex::checkAndPush (destinationTile.hex + pseudoVector, hexes);
|
||||
break;
|
||||
case WN: //17
|
||||
case WN + 1: //18
|
||||
case -WN: //-17
|
||||
case -WN + 1: //-16
|
||||
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : -1 ), hexes);
|
||||
case WN: //17 //left-down or right-down
|
||||
case -WN: //-17 //left-up or right-up
|
||||
case WN + 1: //18 //right-down
|
||||
case -WN + 1: //-16 //right-up
|
||||
BattleHex::checkAndPush (destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : -1 ), hexes);
|
||||
break;
|
||||
case WN-1: //16
|
||||
case -WN-1: //-18
|
||||
BattleHex::checkAndPush(destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : 0), hexes);
|
||||
case WN-1: //16 //left-down
|
||||
case -WN-1: //-18 //left-up
|
||||
BattleHex::checkAndPush (destinationTile.hex + pseudoVector + ((hex/WN)%2 ? 1 : 0), hexes);
|
||||
break;
|
||||
}
|
||||
BOOST_FOREACH (BattleHex tile, hexes)
|
||||
{
|
||||
//friendly stacks can also be damaged by Dragon Breath
|
||||
if(battleGetStackByPos(tile, true))
|
||||
at.friendlyCreaturePositions.insert(tile);
|
||||
if (battleGetStackByPos (tile, true))
|
||||
at.friendlyCreaturePositions.insert (tile);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1369,6 +1381,48 @@ std::set<const CStack*> CBattleInfoCallback::getAttackedCreatures(const CStack*
|
||||
return attackedCres;
|
||||
}
|
||||
|
||||
bool CBattleInfoCallback::isToReverseHlp (BattleHex hexFrom, BattleHex hexTo, bool curDir) const //TODO: this should apply also to mechanics and cursor interface
|
||||
{
|
||||
int fromMod = hexFrom % GameConstants::BFIELD_WIDTH;
|
||||
int fromDiv = hexFrom / GameConstants::BFIELD_WIDTH;
|
||||
int toMod = hexTo % GameConstants::BFIELD_WIDTH;
|
||||
|
||||
if(curDir && fromMod < toMod)
|
||||
return false;
|
||||
else if(curDir && fromMod > toMod)
|
||||
return true;
|
||||
else if(curDir && fromMod == toMod)
|
||||
{
|
||||
return fromDiv % 2 == 0;
|
||||
}
|
||||
else if(!curDir && fromMod < toMod)
|
||||
return true;
|
||||
else if(!curDir && fromMod > toMod)
|
||||
return false;
|
||||
else if(!curDir && fromMod == toMod)
|
||||
{
|
||||
return fromDiv % 2 == 1;
|
||||
}
|
||||
tlog1 << "Catastrope in CBattleInfoCallback::isToReverse!" << std::endl;
|
||||
return false; //should never happen
|
||||
}
|
||||
|
||||
bool CBattleInfoCallback::isToReverse (BattleHex hexFrom, BattleHex hexTo, bool curDir, bool toDoubleWide, bool toDir) const //TODO: this should apply also to mechanics and cursor interface
|
||||
{
|
||||
if (hexTo < 0) //turret
|
||||
return false;
|
||||
|
||||
if (toDoubleWide)
|
||||
{
|
||||
return (isToReverseHlp (hexFrom, hexTo, curDir)) &&
|
||||
(toDir ? isToReverseHlp (hexFrom, hexTo-1, curDir) : isToReverseHlp (hexFrom, hexTo+1, curDir));
|
||||
}
|
||||
else
|
||||
{
|
||||
return isToReverseHlp(hexFrom, hexTo, curDir);
|
||||
}
|
||||
}
|
||||
|
||||
ReachabilityInfo::TDistances CBattleInfoCallback::battleGetDistances(const CStack * stack, BattleHex hex /*= BattleHex::INVALID*/, BattleHex * predecessors /*= NULL*/) const
|
||||
{
|
||||
ReachabilityInfo::TDistances ret;
|
||||
@ -1400,18 +1454,20 @@ si8 CBattleInfoCallback::battleHasDistancePenalty(const IBonusBearer *bonusBeare
|
||||
if(bonusBearer->hasBonusOfType(Bonus::NO_DISTANCE_PENALTY))
|
||||
return false;
|
||||
|
||||
if(BattleHex::getDistance(shooterPosition, destHex) <= GameConstants::BATTLE_PENALTY_DISTANCE)
|
||||
return false;
|
||||
|
||||
if(const CStack * dstStack = battleGetStackByPos(destHex, false))
|
||||
{
|
||||
//If on dest hex stands stack that occupies a hex within our distance
|
||||
//If any hex of target creature is within range, there is no penalty
|
||||
BOOST_FOREACH(auto hex, dstStack->getHexes())
|
||||
if(BattleHex::getDistance(shooterPosition, hex) <= GameConstants::BATTLE_PENALTY_DISTANCE)
|
||||
return false;
|
||||
|
||||
//TODO what about two-hex shooters?
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BattleHex::getDistance(shooterPosition, destHex) <= GameConstants::BATTLE_PENALTY_DISTANCE)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -269,8 +269,10 @@ public:
|
||||
bool isInTacticRange( BattleHex dest ) const;
|
||||
si8 battleGetTacticDist() const; //returns tactic distance for calling player or 0 if this player is not in tactic phase (for ALL_KNOWING actual distance for tactic side)
|
||||
|
||||
AttackableTiles getPotentiallyAttackableHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos) const;
|
||||
AttackableTiles getPotentiallyAttackableHexes(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos) const; //TODO: apply rotation to two-hex attacker
|
||||
std::set<const CStack*> getAttackedCreatures(const CStack* attacker, BattleHex destinationTile, BattleHex attackerPos = BattleHex::INVALID) const; //calculates range of multi-hex attacks
|
||||
bool isToReverse(BattleHex hexFrom, BattleHex hexTo, bool curDir /*if true, creature is in attacker's direction*/, bool toDoubleWide, bool toDir) const; //determines if creature should be reversed (it stands on hexFrom and should 'see' hexTo)
|
||||
bool isToReverseHlp(BattleHex hexFrom, BattleHex hexTo, bool curDir) const; //helper for isToReverse
|
||||
|
||||
ReachabilityInfo getReachability(const CStack *stack) const;
|
||||
ReachabilityInfo getReachability(const ReachabilityInfo::Parameters ¶ms) const;
|
||||
|
Loading…
Reference in New Issue
Block a user