Units can now (optionally) have a RangedAttack animation specified
This commit is contained in:
parent
79d93b7500
commit
bf841969a7
8 changed files with 53 additions and 6 deletions
doc/scripts
src
action
animation
include
missile
sound
unit
|
@ -74,6 +74,7 @@ animation.</dd>
|
|||
<li>Still</li>
|
||||
<li>Move</li>
|
||||
<li>Attack</li>
|
||||
<li>RangedAttack</li>
|
||||
<li>Repair</li>
|
||||
<li>Train</li>
|
||||
<li>Research</li>
|
||||
|
|
|
@ -83,11 +83,15 @@ void AnimateActionAttack(CUnit &unit, COrder &order)
|
|||
// No animation.
|
||||
// So direct fire missile.
|
||||
// FIXME : wait a little.
|
||||
if (!unit.Type->Animations || !unit.Type->Animations->Attack) {
|
||||
order.OnAnimationAttack(unit);
|
||||
return;
|
||||
if (unit.Type->Animations && unit.Type->Animations->RangedAttack && unit.IsAttackRanged(order.GetGoal(), order.GetGoalPos())) {
|
||||
UnitShowAnimation(unit, unit.Type->Animations->RangedAttack);
|
||||
} else {
|
||||
if (!unit.Type->Animations || !unit.Type->Animations->Attack) {
|
||||
order.OnAnimationAttack(unit);
|
||||
return;
|
||||
}
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Attack);
|
||||
}
|
||||
UnitShowAnimation(unit, unit.Type->Animations->Attack);
|
||||
}
|
||||
|
||||
/* static */ COrder *COrder::NewActionAttack(const CUnit &attacker, CUnit &target)
|
||||
|
|
|
@ -703,6 +703,8 @@ static int CclDefineAnimations(lua_State *l)
|
|||
}
|
||||
} else if (!strcmp(value, "Attack")) {
|
||||
anims->Attack = ParseAnimation(l, -1);
|
||||
} else if (!strcmp(value, "RangedAttack")) {
|
||||
anims->RangedAttack = ParseAnimation(l, -1);
|
||||
} else if (!strcmp(value, "SpellCast")) {
|
||||
anims->SpellCast = ParseAnimation(l, -1);
|
||||
} else if (!strcmp(value, "Move")) {
|
||||
|
@ -732,6 +734,7 @@ static int CclDefineAnimations(lua_State *l)
|
|||
AddAnimationToArray(anims->Death[i]);
|
||||
}
|
||||
AddAnimationToArray(anims->Attack);
|
||||
AddAnimationToArray(anims->RangedAttack);
|
||||
AddAnimationToArray(anims->SpellCast);
|
||||
AddAnimationToArray(anims->Move);
|
||||
AddAnimationToArray(anims->Repair);
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
class CAnimations
|
||||
{
|
||||
public:
|
||||
CAnimations() : Attack(NULL), Build(NULL), Move(NULL), Repair(NULL),
|
||||
CAnimations() : Attack(NULL), RangedAttack(NULL), Build(NULL), Move(NULL), Repair(NULL),
|
||||
Research(NULL), SpellCast(NULL), Start(NULL), Still(NULL),
|
||||
Train(NULL), Upgrade(NULL)
|
||||
{
|
||||
|
@ -118,6 +118,7 @@ public:
|
|||
~CAnimations()
|
||||
{
|
||||
delete Attack;
|
||||
delete RangedAttack;
|
||||
delete Build;
|
||||
for (int i = 0; i < ANIMATIONS_DEATHTYPES + 1; ++i) {
|
||||
delete Death[i];
|
||||
|
@ -141,6 +142,7 @@ public:
|
|||
|
||||
public:
|
||||
CAnimation *Attack;
|
||||
CAnimation *RangedAttack;
|
||||
CAnimation *Build;
|
||||
CAnimation *Death[ANIMATIONS_DEATHTYPES + 1];
|
||||
CAnimation *Harvest[MaxCosts];
|
||||
|
|
|
@ -286,6 +286,8 @@ public:
|
|||
|
||||
int GetDrawLevel() const;
|
||||
|
||||
bool IsAttackRanged(CUnit *goal, const Vec2i &goalPos);
|
||||
|
||||
PixelPos GetMapPixelPosTopLeft() const;
|
||||
PixelPos GetMapPixelPosCenter() const;
|
||||
|
||||
|
|
|
@ -367,7 +367,10 @@ void FireMissile(CUnit &unit, CUnit *goal, const Vec2i &goalPos)
|
|||
}
|
||||
|
||||
// No missile hits immediately!
|
||||
if (unit.Type->Missile.Missile->Class == MissileClassNone) {
|
||||
if (
|
||||
unit.Type->Missile.Missile->Class == MissileClassNone
|
||||
|| (unit.Type->Animations && unit.Type->Animations->Attack && unit.Type->Animations->RangedAttack && !unit.IsAttackRanged(goal, goalPos)) // treat melee attacks from units that have both attack and ranged attack animations as having missile class none
|
||||
) {
|
||||
// No goal, take target coordinates
|
||||
if (!goal) {
|
||||
if (Map.WallOnMap(goalPos)) {
|
||||
|
|
|
@ -120,6 +120,7 @@ static void MapAnimSounds(CUnitType &type)
|
|||
MapAnimSounds2(type.Animations->Still);
|
||||
MapAnimSounds2(type.Animations->Move);
|
||||
MapAnimSounds2(type.Animations->Attack);
|
||||
MapAnimSounds2(type.Animations->RangedAttack);
|
||||
MapAnimSounds2(type.Animations->SpellCast);
|
||||
for (int i = 0; i <= ANIMATIONS_DEATHTYPES; ++i) {
|
||||
MapAnimSounds2(type.Animations->Death[i]);
|
||||
|
|
|
@ -3121,6 +3121,37 @@ bool CUnit::IsUnusable(bool ignore_built_state) const
|
|||
return (!IsAliveOnMap() || (!ignore_built_state && CurrentAction() == UnitActionBuilt));
|
||||
}
|
||||
|
||||
/**
|
||||
** Check if the unit attacking its goal will result in a ranged attack
|
||||
*/
|
||||
bool CUnit::IsAttackRanged(CUnit *goal, const Vec2i &goalPos)
|
||||
{
|
||||
if (this->Variable[ATTACKRANGE_INDEX].Value <= 1) { //always return false if the units attack range is 1 or lower
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->Container) { //if the unit is inside a container, the attack will always be ranged
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
goal
|
||||
&& goal->IsAliveOnMap()
|
||||
&& (
|
||||
this->MapDistanceTo(*goal) > 1
|
||||
|| (this->Type->UnitType != UnitTypeFly && goal->Type->UnitType == UnitTypeFly)
|
||||
|| (this->Type->UnitType == UnitTypeFly && goal->Type->UnitType != UnitTypeFly)
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!goal && Map.Info.IsPointOnMap(goalPos) && this->MapDistanceTo(goalPos) > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Initialize/Cleanup
|
||||
|
|
Loading…
Add table
Reference in a new issue