|
|
|
@@ -972,7 +972,8 @@ bool CShootingAnim::init()
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//projectile
|
|
|
|
|
// Create the projectile animation
|
|
|
|
|
|
|
|
|
|
float projectileAngle; //in radians; if positive, projectiles goes up
|
|
|
|
|
float straightAngle = 0.2f; //maximal angle in radians between straight horizontal line and shooting line for which shot is considered to be straight (absoulte value)
|
|
|
|
|
int fromHex = shooter->position;
|
|
|
|
@@ -980,17 +981,28 @@ bool CShootingAnim::init()
|
|
|
|
|
if(fromHex < dest)
|
|
|
|
|
projectileAngle = -projectileAngle;
|
|
|
|
|
|
|
|
|
|
// Get further info about the shooter e.g. relative pos of projectile to unit.
|
|
|
|
|
// If the creature id is 149 then it's a arrow tower which has no additional info so get the
|
|
|
|
|
// actual arrow tower shooter instead.
|
|
|
|
|
const CCreature *shooterInfo = shooter->getCreature();
|
|
|
|
|
if (shooterInfo->idNumber == 149)
|
|
|
|
|
{
|
|
|
|
|
int creID = CGI->creh->factionToTurretCreature[owner->siegeH->town->town->typeID];
|
|
|
|
|
shooterInfo = CGI->creh->creatures[creID];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SProjectileInfo spi;
|
|
|
|
|
spi.creID = shooter->getCreature()->idNumber;
|
|
|
|
|
spi.stackID = shooter->ID;
|
|
|
|
|
spi.reverse = !shooter->attackerOwned;
|
|
|
|
|
|
|
|
|
|
spi.step = 0;
|
|
|
|
|
spi.frameNum = 0;
|
|
|
|
|
if(vstd::contains(CGI->creh->idToProjectileSpin, spi.creID))
|
|
|
|
|
spi.spin = CGI->creh->idToProjectileSpin[spi.creID];
|
|
|
|
|
if(vstd::contains(CGI->creh->idToProjectileSpin, shooterInfo->idNumber))
|
|
|
|
|
spi.spin = CGI->creh->idToProjectileSpin[shooterInfo->idNumber];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tlog2 << "Warning - no projectile spin for spi.creID " << spi.creID << std::endl;
|
|
|
|
|
tlog2 << "Warning - no projectile spin for spi.creID " << shooterInfo->idNumber << std::endl;
|
|
|
|
|
spi.spin = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1007,26 +1019,35 @@ bool CShootingAnim::init()
|
|
|
|
|
}
|
|
|
|
|
destcoord.x += 250; destcoord.y += 210; //TODO: find a better place to shoot
|
|
|
|
|
|
|
|
|
|
if(projectileAngle > straightAngle) //upper shot
|
|
|
|
|
// The "master" point where all projectile positions relate to.
|
|
|
|
|
static const Point projectileOrigin(181, 252);
|
|
|
|
|
|
|
|
|
|
// Calculate projectile start position. Offsets are read out of the CRANIM.TXT.
|
|
|
|
|
if (projectileAngle > straightAngle)
|
|
|
|
|
{
|
|
|
|
|
spi.x = xycoord.x + 200 + shooter->getCreature()->upperRightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + 100 - shooter->getCreature()->upperRightMissleOffsetY;
|
|
|
|
|
//upper shot
|
|
|
|
|
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->upperRightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->upperRightMissleOffsetY;
|
|
|
|
|
}
|
|
|
|
|
else if(projectileAngle < -straightAngle) //lower shot
|
|
|
|
|
else if (projectileAngle < -straightAngle)
|
|
|
|
|
{
|
|
|
|
|
spi.x = xycoord.x + 200 + shooter->getCreature()->lowerRightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + 150 - shooter->getCreature()->lowerRightMissleOffsetY;
|
|
|
|
|
//lower shot
|
|
|
|
|
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->lowerRightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->lowerRightMissleOffsetY;
|
|
|
|
|
}
|
|
|
|
|
else //straight shot
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
spi.x = xycoord.x + 200 + shooter->getCreature()->rightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + 125 - shooter->getCreature()->rightMissleOffsetY;
|
|
|
|
|
//straight shot
|
|
|
|
|
spi.x = xycoord.x + projectileOrigin.x + shooterInfo->rightMissleOffsetX;
|
|
|
|
|
spi.y = xycoord.y + projectileOrigin.y + shooterInfo->rightMissleOffsetY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spi.lastStep = sqrt((float)((destcoord.x - spi.x)*(destcoord.x - spi.x) + (destcoord.y - spi.y) * (destcoord.y - spi.y))) / 40;
|
|
|
|
|
if(spi.lastStep == 0)
|
|
|
|
|
spi.lastStep = 1;
|
|
|
|
|
spi.dx = (destcoord.x - spi.x) / spi.lastStep;
|
|
|
|
|
spi.dy = (destcoord.y - spi.y) / spi.lastStep;
|
|
|
|
|
|
|
|
|
|
//set starting frame
|
|
|
|
|
if(spi.spin)
|
|
|
|
|
{
|
|
|
|
@@ -1036,8 +1057,9 @@ bool CShootingAnim::init()
|
|
|
|
|
{
|
|
|
|
|
spi.frameNum = ((M_PI/2.0f - projectileAngle) / (2.0f *M_PI) + 1/((float)(2*(owner->idToProjectile[spi.creID]->ourImages.size()-1)))) * (owner->idToProjectile[spi.creID]->ourImages.size()-1);
|
|
|
|
|
}
|
|
|
|
|
//set delay
|
|
|
|
|
spi.animStartDelay = CGI->creh->creatures[spi.creID]->attackClimaxFrame;
|
|
|
|
|
|
|
|
|
|
// Set projectile animation start delay which is specified in frames
|
|
|
|
|
spi.animStartDelay = shooterInfo->attackClimaxFrame;
|
|
|
|
|
owner->projectiles.push_back(spi);
|
|
|
|
|
|
|
|
|
|
//attack animation
|
|
|
|
@@ -1545,7 +1567,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
|
|
|
|
//print shade
|
|
|
|
|
if(spellToCast) //when casting spell
|
|
|
|
|
{
|
|
|
|
|
//calculating spell schoold level
|
|
|
|
|
//calculating spell school level
|
|
|
|
|
const CSpell & spToCast = *CGI->spellh->spells[spellToCast->additionalInfo];
|
|
|
|
|
ui8 schoolLevel = 0;
|
|
|
|
|
if( activeStack->attackerOwned )
|
|
|
|
@@ -1600,7 +1622,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
|
|
|
|
//double loop because dead stacks should be printed first
|
|
|
|
|
BOOST_FOREACH(const CStack *s, stacks)
|
|
|
|
|
{
|
|
|
|
|
if(creAnims.find(s->ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
|
|
|
|
if(creAnims.find(s->ID) == creAnims.end()) //e.g. for summoned but not yet handled stacks
|
|
|
|
|
continue;
|
|
|
|
|
if(creAnims[s->ID]->getType() != 5 && s->position >= 0) //don't show turrets here
|
|
|
|
|
stackAliveByHex[s->position].push_back(s);
|
|
|
|
@@ -1608,7 +1630,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
|
|
|
|
std::vector<const CStack *> stackDeadByHex[BFIELD_SIZE];
|
|
|
|
|
BOOST_FOREACH(const CStack *s, stacks)
|
|
|
|
|
{
|
|
|
|
|
if(creAnims.find(s->ID) == creAnims.end()) //eg. for summoned but not yet handled stacks
|
|
|
|
|
if(creAnims.find(s->ID) == creAnims.end()) //e.g. for summoned but not yet handled stacks
|
|
|
|
|
continue;
|
|
|
|
|
if(creAnims[s->ID]->getType() == 5)
|
|
|
|
|
stackDeadByHex[s->position].push_back(s);
|
|
|
|
@@ -1752,7 +1774,8 @@ void CBattleInterface::show(SDL_Surface * to)
|
|
|
|
|
|
|
|
|
|
//units shown
|
|
|
|
|
|
|
|
|
|
projectileShowHelper(to);//showing projectiles
|
|
|
|
|
// Show projectiles
|
|
|
|
|
projectileShowHelper(to);
|
|
|
|
|
|
|
|
|
|
//showing spell effects
|
|
|
|
|
if(battleEffects.size())
|
|
|
|
@@ -2381,7 +2404,7 @@ void CBattleInterface::newStack(const CStack * stack)
|
|
|
|
|
const CCreature & turretCreature = *CGI->creh->creatures[ CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] ];
|
|
|
|
|
creAnims[stack->ID] = new CCreatureAnimation(turretCreature.animDefName);
|
|
|
|
|
|
|
|
|
|
// Remarks: Turret positions are read out of the /config/wall_pos.txt
|
|
|
|
|
// Turret positions are read out of the /config/wall_pos.txt
|
|
|
|
|
int posID = 0;
|
|
|
|
|
switch (stack->position)
|
|
|
|
|
{
|
|
|
|
@@ -3523,11 +3546,15 @@ void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
|
|
|
|
std::list< std::list<SProjectileInfo>::iterator > toBeDeleted;
|
|
|
|
|
for(std::list<SProjectileInfo>::iterator it=projectiles.begin(); it!=projectiles.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
// Creature have to be in a shooting anim and the anim start delay must be over.
|
|
|
|
|
// Otherwise abort to start moving the projectile.
|
|
|
|
|
if (it->animStartDelay > 0)
|
|
|
|
|
{
|
|
|
|
|
--(it->animStartDelay);
|
|
|
|
|
if(it->animStartDelay == creAnims[it->stackID]->getAnimationFrame() + 1
|
|
|
|
|
&& creAnims[it->stackID]->getType() >= 14 && creAnims[it->stackID]->getType() <= 16)
|
|
|
|
|
it->animStartDelay = 0;
|
|
|
|
|
else
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_Rect dst;
|
|
|
|
|
dst.h = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->h;
|
|
|
|
|
dst.w = idToProjectile[it->creID]->ourImages[it->frameNum].bitmap->w;
|
|
|
|
@@ -3543,6 +3570,7 @@ void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
|
|
|
|
{
|
|
|
|
|
CSDL_Ext::blit8bppAlphaTo24bpp(idToProjectile[it->creID]->ourImages[it->frameNum].bitmap, NULL, to, &dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//actualizing projectile
|
|
|
|
|
++it->step;
|
|
|
|
|
if(it->step == it->lastStep)
|
|
|
|
@@ -3941,11 +3969,11 @@ Point CBattleHex::getXYUnitAnim(const int & hexNum, const bool & attacker, const
|
|
|
|
|
{
|
|
|
|
|
if(attacker)
|
|
|
|
|
{
|
|
|
|
|
ret.x -= 42;
|
|
|
|
|
ret.x -= 44;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret.x += 42;
|
|
|
|
|
ret.x += 45;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|