mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fixing sieges, part 1
This commit is contained in:
parent
b5d1cb4996
commit
35576834c9
@ -134,9 +134,9 @@ void CAttackAnimation::nextFrame()
|
||||
if(!soundPlayed)
|
||||
{
|
||||
if(shooting)
|
||||
CCS->soundh->playSound(battle_sound(attackingStack->getCreature(), shoot));
|
||||
CCS->soundh->playSound(battle_sound(getCreature(), shoot));
|
||||
else
|
||||
CCS->soundh->playSound(battle_sound(attackingStack->getCreature(), attack));
|
||||
CCS->soundh->playSound(battle_sound(getCreature(), attack));
|
||||
soundPlayed = true;
|
||||
}
|
||||
CBattleAnimation::nextFrame();
|
||||
@ -164,6 +164,14 @@ bool CAttackAnimation::checkInitialConditions()
|
||||
return isEarliest(false);
|
||||
}
|
||||
|
||||
const CCreature * CAttackAnimation::getCreature()
|
||||
{
|
||||
if (attackingStack->getCreature()->idNumber == CreatureID::ARROW_TOWERS)
|
||||
return owner->siegeController->getTurretCreature();
|
||||
else
|
||||
return attackingStack->getCreature();
|
||||
}
|
||||
|
||||
CAttackAnimation::CAttackAnimation(CBattleInterface *_owner, const CStack *attacker, BattleHex _dest, const CStack *defender)
|
||||
: CBattleStackAnimation(_owner, attacker),
|
||||
shooting(false), group(CCreatureAnim::SHOOT_FRONT),
|
||||
@ -767,7 +775,7 @@ void CShootingAnimation::setAnimationGroup()
|
||||
//maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
||||
static const double straightAngle = 0.2;
|
||||
|
||||
double projectileAngle = atan2(shotTarget.y - shooterPos.y, std::abs(shotTarget.x - shooterPos.x));
|
||||
double projectileAngle = -atan2(shotTarget.y - shooterPos.y, std::abs(shotTarget.x - shooterPos.x));
|
||||
|
||||
// Calculate projectile start position. Offsets are read out of the CRANIM.TXT.
|
||||
if (projectileAngle > straightAngle)
|
||||
@ -780,11 +788,7 @@ void CShootingAnimation::setAnimationGroup()
|
||||
|
||||
void CShootingAnimation::initializeProjectile()
|
||||
{
|
||||
const CCreature *shooterInfo = attackingStack->getCreature();
|
||||
|
||||
if(shooterInfo->idNumber == CreatureID::ARROW_TOWERS)
|
||||
shooterInfo = owner->siegeController->getTurretCreature();
|
||||
|
||||
const CCreature *shooterInfo = getCreature();
|
||||
Point shotTarget = owner->stacksController->getStackPositionAtHex(dest, attackedStack) + Point(225, 225);
|
||||
Point shotOrigin = stackAnimation(attackingStack)->pos.topLeft() + Point(222, 265);
|
||||
int multiplier = stackFacingRight(attackingStack) ? 1 : -1;
|
||||
@ -828,12 +832,25 @@ void CShootingAnimation::nextFrame()
|
||||
return;
|
||||
}
|
||||
|
||||
// animation should be paused if there is an active projectile
|
||||
if (projectileEmitted)
|
||||
{
|
||||
if (owner->projectilesController->hasActiveProjectile(attackingStack))
|
||||
{
|
||||
stackAnimation(attackingStack)->pause();
|
||||
return;
|
||||
}
|
||||
else
|
||||
stackAnimation(attackingStack)->play();
|
||||
}
|
||||
|
||||
CAttackAnimation::nextFrame();
|
||||
|
||||
if (!projectileEmitted)
|
||||
{
|
||||
const CCreature *shooterInfo = attackingStack->getCreature();
|
||||
const CCreature *shooterInfo = getCreature();
|
||||
|
||||
if(shooterInfo->idNumber == CreatureID::ARROW_TOWERS)
|
||||
shooterInfo = owner->siegeController->getTurretCreature();
|
||||
assert(stackAnimation(attackingStack)->isShooting());
|
||||
|
||||
// emit projectile once animation playback reached "climax" frame
|
||||
if ( stackAnimation(attackingStack)->getCurrentFrame() >= shooterInfo->animation.attackClimaxFrame )
|
||||
@ -842,17 +859,13 @@ void CShootingAnimation::nextFrame()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// animation should be paused if there is an active projectile
|
||||
if (projectileEmitted && owner->projectilesController->hasActiveProjectile(attackingStack))
|
||||
return;
|
||||
|
||||
|
||||
CAttackAnimation::nextFrame();
|
||||
}
|
||||
|
||||
void CShootingAnimation::endAnim()
|
||||
{
|
||||
assert(!owner->projectilesController->hasActiveProjectile(attackingStack));
|
||||
assert(projectileEmitted);
|
||||
|
||||
// FIXME: is this possible? Animation is over but we're yet to fire projectile?
|
||||
if (!projectileEmitted)
|
||||
{
|
||||
@ -1157,11 +1170,15 @@ void CEffectAnimation::endAnim()
|
||||
{
|
||||
CBattleAnimation::endAnim();
|
||||
|
||||
boost::range::remove_if(owner->effectsController->battleEffects,
|
||||
[&](const BattleEffect & elem)
|
||||
{
|
||||
return elem.effectID == ID;
|
||||
});
|
||||
auto & effects = owner->effectsController->battleEffects;
|
||||
|
||||
for ( auto it = effects.begin(); it != effects.end(); )
|
||||
{
|
||||
if (it->effectID == ID)
|
||||
it = effects.erase(it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ protected:
|
||||
const CStack *attackedStack;
|
||||
const CStack *attackingStack;
|
||||
int attackingStackPosBeforeReturn; //for stacks with return_after_strike feature
|
||||
|
||||
const CCreature * getCreature();
|
||||
public:
|
||||
void nextFrame() override;
|
||||
void endAnim() override;
|
||||
|
@ -106,7 +106,9 @@ void CBattleFieldController::redrawBackgroundWithHexes()
|
||||
|
||||
//prepare background graphic with hexes and shaded hexes
|
||||
backgroundWithHexes->draw(background, Point(0,0));
|
||||
owner->obstacleController->redrawBackgroundWithHexes(backgroundWithHexes);
|
||||
owner->obstacleController->showAbsoluteObstacles(backgroundWithHexes, Point(0,0));
|
||||
if ( owner->siegeController )
|
||||
owner->siegeController->showAbsoluteObstacles(backgroundWithHexes, Point(0,0));
|
||||
|
||||
if (settings["battle"]["stackRange"].Bool())
|
||||
{
|
||||
|
@ -927,9 +927,9 @@ void CBattleInterface::show(SDL_Surface *to)
|
||||
else
|
||||
{
|
||||
fieldController->showBackgroundImage(canvas);
|
||||
obstacleController->showAbsoluteObstacles(canvas);
|
||||
obstacleController->showAbsoluteObstacles(canvas, pos.topLeft());
|
||||
if ( siegeController )
|
||||
siegeController->showAbsoluteObstacles(canvas);
|
||||
siegeController->showAbsoluteObstacles(canvas, pos.topLeft());
|
||||
}
|
||||
fieldController->showHighlightedHexes(canvas);
|
||||
|
||||
|
@ -109,7 +109,7 @@ void CBattleObstacleController::obstaclePlaced(const CObstacleInstance & oi)
|
||||
//CCS->soundh->playSound(sound);
|
||||
}
|
||||
|
||||
void CBattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas)
|
||||
void CBattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset)
|
||||
{
|
||||
//Blit absolute obstacles
|
||||
for(auto & oi : owner->curInt->cb->battleGetAllObstacles())
|
||||
@ -118,7 +118,7 @@ void CBattleObstacleController::showAbsoluteObstacles(std::shared_ptr<CCanvas> c
|
||||
{
|
||||
auto img = getObstacleImage(*oi);
|
||||
if(img)
|
||||
canvas->draw(img, Point(owner->pos.x + oi->getInfo().width, owner->pos.y + oi->getInfo().height));
|
||||
canvas->draw(img, Point(offset.x + oi->getInfo().width, offset.y + oi->getInfo().height));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,17 +196,3 @@ Point CBattleObstacleController::getObstaclePosition(std::shared_ptr<IImage> ima
|
||||
|
||||
return r.topLeft();
|
||||
}
|
||||
|
||||
void CBattleObstacleController::redrawBackgroundWithHexes(std::shared_ptr<CCanvas> to)
|
||||
{
|
||||
//draw absolute obstacles (cliffs and so on)
|
||||
for(auto & oi : owner->curInt->cb->battleGetAllObstacles())
|
||||
{
|
||||
if(oi->obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
|
||||
{
|
||||
auto img = getObstacleImage(*oi);
|
||||
if(img)
|
||||
to->draw(img, Point(oi->getInfo().width, oi->getInfo().height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,9 +35,7 @@ public:
|
||||
|
||||
void obstaclePlaced(const CObstacleInstance & oi);
|
||||
void showObstacles(SDL_Surface *to, std::vector<std::shared_ptr<const CObstacleInstance>> &obstacles);
|
||||
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas);
|
||||
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
|
||||
|
||||
void showBattlefieldObjects(std::shared_ptr<CCanvas> canvas, const BattleHex & location );
|
||||
|
||||
void redrawBackgroundWithHexes(std::shared_ptr<CCanvas> to);
|
||||
};
|
||||
|
@ -246,7 +246,7 @@ bool CBattleProjectileController::hasActiveProjectile(const CStack * stack)
|
||||
|
||||
void CBattleProjectileController::createProjectile(const CStack * shooter, const CStack * target, Point from, Point dest)
|
||||
{
|
||||
const CCreature *shooterInfo = shooter->getCreature();
|
||||
const CCreature *shooterInfo = getShooter(shooter);
|
||||
|
||||
std::shared_ptr<ProjectileBase> projectile;
|
||||
|
||||
@ -262,8 +262,8 @@ void CBattleProjectileController::createProjectile(const CStack * shooter, const
|
||||
catapultProjectile->step = 0;
|
||||
catapultProjectile->steps = 0;
|
||||
|
||||
double animSpeed = AnimationControls::getProjectileSpeed() / 10;
|
||||
catapultProjectile->steps = std::round(std::abs((dest.x - from.x) / animSpeed));
|
||||
//double animSpeed = AnimationControls::getProjectileSpeed() / 10;
|
||||
//catapultProjectile->steps = std::round(std::abs((dest.x - from.x) / animSpeed));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -312,16 +312,18 @@ void CBattleProjectileController::createProjectile(const CStack * shooter, const
|
||||
}
|
||||
missileProjectile->frameNum = bestID;
|
||||
}
|
||||
|
||||
double animSpeed = AnimationControls::getProjectileSpeed(); // flight speed of projectile
|
||||
double distanceSquared = (dest.x - from.x) * (dest.x - from.x) + (dest.y - from.y) * (dest.y - from.y);
|
||||
double distance = sqrt(distanceSquared);
|
||||
projectile->steps = std::round(distance / animSpeed);
|
||||
if(projectile->steps == 0)
|
||||
projectile->steps = 1;
|
||||
|
||||
}
|
||||
|
||||
double animSpeed = AnimationControls::getProjectileSpeed(); // flight speed of projectile
|
||||
if (!target)
|
||||
animSpeed *= 0.2; // catapult attack needs slower speed
|
||||
|
||||
double distanceSquared = (dest.x - from.x) * (dest.x - from.x) + (dest.y - from.y) * (dest.y - from.y);
|
||||
double distance = sqrt(distanceSquared);
|
||||
projectile->steps = std::round(distance / animSpeed);
|
||||
if(projectile->steps == 0)
|
||||
projectile->steps = 1;
|
||||
|
||||
projectile->from = from;
|
||||
projectile->dest = dest;
|
||||
projectile->shooterID = shooter->ID;
|
||||
|
@ -104,12 +104,13 @@ std::string CBattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisu
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleSiegeController::showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what)
|
||||
void CBattleSiegeController::showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what, const Point & offset)
|
||||
{
|
||||
auto & ci = town->town->clientInfo;
|
||||
auto const & pos = ci.siegePositions[what];
|
||||
|
||||
canvas->draw(wallPieceImages[what], owner->pos.topLeft() + Point(pos.x, pos.y));
|
||||
if ( wallPieceImages[what])
|
||||
canvas->draw(wallPieceImages[what], offset + Point(pos.x, pos.y));
|
||||
}
|
||||
|
||||
std::string CBattleSiegeController::getBattleBackgroundName() const
|
||||
@ -250,13 +251,13 @@ void CBattleSiegeController::gateStateChanged(const EGateState state)
|
||||
CCS->soundh->playSound(soundBase::DRAWBRG);
|
||||
}
|
||||
|
||||
void CBattleSiegeController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas)
|
||||
void CBattleSiegeController::showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset)
|
||||
{
|
||||
if (getWallPieceExistance(EWallVisual::MOAT))
|
||||
showWallPiece(canvas, EWallVisual::MOAT);
|
||||
showWallPiece(canvas, EWallVisual::MOAT, owner->pos.topLeft());
|
||||
|
||||
if (getWallPieceExistance(EWallVisual::BACKGROUND_MOAT))
|
||||
showWallPiece(canvas, EWallVisual::BACKGROUND_MOAT);
|
||||
showWallPiece(canvas, EWallVisual::BACKGROUND_MOAT, owner->pos.topLeft());
|
||||
}
|
||||
|
||||
void CBattleSiegeController::showBattlefieldObjects(std::shared_ptr<CCanvas> canvas, const BattleHex & location )
|
||||
@ -275,7 +276,7 @@ void CBattleSiegeController::showBattlefieldObjects(std::shared_ptr<CCanvas> can
|
||||
wallPiece != EWallVisual::BOTTOM_BATTLEMENT &&
|
||||
wallPiece != EWallVisual::UPPER_BATTLEMENT)
|
||||
{
|
||||
showWallPiece(canvas, wallPiece);
|
||||
showWallPiece(canvas, wallPiece, owner->pos.topLeft());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -308,7 +309,7 @@ void CBattleSiegeController::showBattlefieldObjects(std::shared_ptr<CCanvas> can
|
||||
if (turret)
|
||||
{
|
||||
owner->stacksController->showStack(canvas, turret);
|
||||
showWallPiece(canvas, wallPiece);
|
||||
showWallPiece(canvas, wallPiece, owner->pos.topLeft());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ class CBattleSiegeController
|
||||
/// returns true if chosen wall piece should be present in current battle
|
||||
bool getWallPieceExistance(EWallVisual::EWallVisual what) const;
|
||||
|
||||
void showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what);
|
||||
void showWallPiece(std::shared_ptr<CCanvas> canvas, EWallVisual::EWallVisual what, const Point & offset);
|
||||
|
||||
public:
|
||||
CBattleSiegeController(CBattleInterface * owner, const CGTownInstance *siegeTown);
|
||||
@ -88,7 +88,7 @@ public:
|
||||
void stackIsCatapulting(const CatapultAttack & ca);
|
||||
|
||||
/// call-ins from other battle controllers
|
||||
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas);
|
||||
void showAbsoluteObstacles(std::shared_ptr<CCanvas> canvas, const Point & offset);
|
||||
void showBattlefieldObjects(std::shared_ptr<CCanvas> canvas, const BattleHex & location );
|
||||
|
||||
/// queries from other battle controllers
|
||||
|
@ -222,7 +222,7 @@
|
||||
},
|
||||
"moat" :
|
||||
{
|
||||
"bank" : { "x" : -1, "y" : -1 },
|
||||
"bank" : { "x" : 406, "y" : 77 },
|
||||
"moat" : { "x" : 406, "y" : 77 }
|
||||
},
|
||||
"static" :
|
||||
|
Loading…
Reference in New Issue
Block a user