1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00
Moved isToReverse() function to battleCallback so that creature rotation will be handled by core mechanics and not only GUI.
This commit is contained in:
DjWarmonger 2012-11-29 15:02:55 +00:00
parent 89196c577e
commit 52242692f1
5 changed files with 81 additions and 68 deletions

View File

@ -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));

View File

@ -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
};

View File

@ -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

View File

@ -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;
}

View File

@ -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 &params) const;