move more combat bits around
This commit is contained in:
@@ -48,10 +48,10 @@ namespace OpenRA.Mods.RA
|
|||||||
public int[] Offset;
|
public int[] Offset;
|
||||||
public Barrel[] Barrels;
|
public Barrel[] Barrels;
|
||||||
|
|
||||||
public Weapon(WeaponInfo info, int[] offset, int[] localOffset)
|
public Weapon(string weaponName, int[] offset, int[] localOffset)
|
||||||
{
|
{
|
||||||
Info = info;
|
Info = Rules.Weapons[weaponName.ToLowerInvariant()];
|
||||||
Burst = info.Burst;
|
Burst = Info.Burst;
|
||||||
Offset = offset;
|
Offset = offset;
|
||||||
|
|
||||||
var barrels = new List<Barrel>();
|
var barrels = new List<Barrel>();
|
||||||
@@ -76,6 +76,11 @@ namespace OpenRA.Mods.RA
|
|||||||
if (FireDelay > 0) --FireDelay;
|
if (FireDelay > 0) --FireDelay;
|
||||||
Recoil = Math.Max(0f, Recoil - .2f);
|
Recoil = Math.Max(0f, Recoil - .2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsValidAgainst(Target target)
|
||||||
|
{
|
||||||
|
return Combat.WeaponValidForTarget(Info, target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice
|
public class AttackBase : IIssueOrder, IResolveOrder, ITick, IExplodeModifier, IOrderCursor, IOrderVoice
|
||||||
@@ -88,12 +93,12 @@ namespace OpenRA.Mods.RA
|
|||||||
{
|
{
|
||||||
var info = self.Info.Traits.Get<AttackBaseInfo>();
|
var info = self.Info.Traits.Get<AttackBaseInfo>();
|
||||||
|
|
||||||
if (self.GetPrimaryWeapon() != null)
|
if (info.PrimaryWeapon != null)
|
||||||
Weapons.Add(new Weapon(self.GetPrimaryWeapon(),
|
Weapons.Add(new Weapon(info.PrimaryWeapon,
|
||||||
info.PrimaryOffset, info.PrimaryLocalOffset));
|
info.PrimaryOffset, info.PrimaryLocalOffset));
|
||||||
|
|
||||||
if (self.GetSecondaryWeapon() != null)
|
if (self.GetSecondaryWeapon() != null)
|
||||||
Weapons.Add(new Weapon(self.GetSecondaryWeapon(),
|
Weapons.Add(new Weapon(info.SecondaryWeapon,
|
||||||
info.SecondaryOffset ?? info.PrimaryOffset, info.SecondaryLocalOffset));
|
info.SecondaryOffset ?? info.PrimaryOffset, info.SecondaryLocalOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +163,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (w.Info.Range * w.Info.Range * Game.CellSize * Game.CellSize
|
if (w.Info.Range * w.Info.Range * Game.CellSize * Game.CellSize
|
||||||
< (target.CenterLocation - self.CenterLocation).LengthSquared) return false;
|
< (target.CenterLocation - self.CenterLocation).LengthSquared) return false;
|
||||||
|
|
||||||
if (!Combat.WeaponValidForTarget(w.Info, target)) return false;
|
if (!w.IsValidAgainst(target)) return false;
|
||||||
|
|
||||||
var barrel = w.Barrels[w.Burst % w.Barrels.Length];
|
var barrel = w.Barrels[w.Burst % w.Barrels.Length];
|
||||||
|
|
||||||
@@ -226,7 +231,7 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
var target = underCursor == null ? Target.FromCell(xy) : Target.FromActor(underCursor);
|
var target = underCursor == null ? Target.FromCell(xy) : Target.FromActor(underCursor);
|
||||||
|
|
||||||
var isHeal = self.GetPrimaryWeapon().Warheads.First().Damage < 0;
|
var isHeal = Weapons[0].Info.Warheads[0].Damage < 0;
|
||||||
var forceFire = mi.Modifiers.HasModifier(Modifiers.Ctrl);
|
var forceFire = mi.Modifiers.HasModifier(Modifiers.Ctrl);
|
||||||
|
|
||||||
if (isHeal)
|
if (isHeal)
|
||||||
@@ -252,7 +257,7 @@ namespace OpenRA.Mods.RA
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Combat.HasAnyValidWeapons(self, target)) return null;
|
if (!HasAnyValidWeapons(target)) return null;
|
||||||
|
|
||||||
return new Order(isHeal ? "Heal" : "Attack", self, underCursor);
|
return new Order(isHeal ? "Heal" : "Attack", self, underCursor);
|
||||||
}
|
}
|
||||||
@@ -308,5 +313,8 @@ namespace OpenRA.Mods.RA
|
|||||||
/* temp hack */
|
/* temp hack */
|
||||||
public float GetPrimaryRecoil() { return Weapons.Count > 0 ? Weapons[0].Recoil : 0; }
|
public float GetPrimaryRecoil() { return Weapons.Count > 0 ? Weapons[0].Recoil : 0; }
|
||||||
public float GetSecondaryRecoil() { return Weapons.Count > 1 ? Weapons[1].Recoil : 0; }
|
public float GetSecondaryRecoil() { return Weapons.Count > 1 ? Weapons[1].Recoil : 0; }
|
||||||
|
|
||||||
|
public bool HasAnyValidWeapons(Target t) { return Weapons.Any(w => w.IsValidAgainst(t)); }
|
||||||
|
public float GetMaximumRange() { return Weapons.Max(w => w.Info.Range); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ namespace OpenRA.Mods.RA
|
|||||||
bool NeedsNewTarget(Actor self)
|
bool NeedsNewTarget(Actor self)
|
||||||
{
|
{
|
||||||
var attack = self.traits.Get<AttackBase>();
|
var attack = self.traits.Get<AttackBase>();
|
||||||
var range = Combat.GetMaximumRange(self);
|
var range = attack.GetMaximumRange();
|
||||||
|
|
||||||
if (!attack.target.IsValid)
|
if (!attack.target.IsValid)
|
||||||
return true; // he's dead.
|
return true; // he's dead.
|
||||||
@@ -47,7 +47,8 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
{
|
{
|
||||||
var range = Combat.GetMaximumRange(self);
|
var attack = self.traits.Get<AttackBase>();
|
||||||
|
var range = attack.GetMaximumRange();
|
||||||
|
|
||||||
if (NeedsNewTarget(self))
|
if (NeedsNewTarget(self))
|
||||||
AttackTarget(self, ChooseTarget(self, range));
|
AttackTarget(self, ChooseTarget(self, range));
|
||||||
@@ -56,12 +57,13 @@ namespace OpenRA.Mods.RA
|
|||||||
Actor ChooseTarget(Actor self, float range)
|
Actor ChooseTarget(Actor self, float range)
|
||||||
{
|
{
|
||||||
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||||
|
var attack = self.traits.Get<AttackBase>();
|
||||||
|
|
||||||
return inRange
|
return inRange
|
||||||
.Where(a => a != self && self.Owner.Stances[ a.Owner ] == Stance.Ally)
|
.Where(a => a != self && self.Owner.Stances[a.Owner] == Stance.Ally)
|
||||||
.Where(a => !a.IsDead())
|
.Where(a => !a.IsDead())
|
||||||
.Where(a => a.traits.Contains<Health>() && a.GetDamageState() > DamageState.Undamaged)
|
.Where(a => a.traits.Contains<Health>() && a.GetDamageState() > DamageState.Undamaged)
|
||||||
.Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a)))
|
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
||||||
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ namespace OpenRA.Mods.RA
|
|||||||
if (--nextScanTime <= 0)
|
if (--nextScanTime <= 0)
|
||||||
{
|
{
|
||||||
var attack = self.traits.Get<AttackBase>();
|
var attack = self.traits.Get<AttackBase>();
|
||||||
var range = Combat.GetMaximumRange(self);
|
var range = attack.GetMaximumRange();
|
||||||
|
|
||||||
if (!attack.target.IsValid ||
|
if (!attack.target.IsValid ||
|
||||||
(Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
|
(Util.CellContaining(attack.target.CenterLocation) - self.Location).LengthSquared > range * range)
|
||||||
@@ -53,10 +53,11 @@ namespace OpenRA.Mods.RA
|
|||||||
Actor ChooseTarget(Actor self, float range)
|
Actor ChooseTarget(Actor self, float range)
|
||||||
{
|
{
|
||||||
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
var inRange = self.World.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range);
|
||||||
|
var attack = self.traits.Get<AttackBase>();
|
||||||
|
|
||||||
return inRange
|
return inRange
|
||||||
.Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy)
|
.Where(a => a.Owner != null && self.Owner.Stances[ a.Owner ] == Stance.Enemy)
|
||||||
.Where(a => Combat.HasAnyValidWeapons(self, Target.FromActor(a)))
|
.Where(a => attack.HasAnyValidWeapons(Target.FromActor(a)))
|
||||||
.Where(a => !a.traits.Contains<Cloak>() || !a.traits.Get<Cloak>().Cloaked)
|
.Where(a => !a.traits.Contains<Cloak>() || !a.traits.Get<Cloak>().Cloaked)
|
||||||
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
.OrderBy(a => (a.Location - self.Location).LengthSquared)
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
@@ -67,7 +68,8 @@ namespace OpenRA.Mods.RA
|
|||||||
if (!self.IsIdle) return;
|
if (!self.IsIdle) return;
|
||||||
|
|
||||||
// not a lot we can do about things we can't hurt... although maybe we should automatically run away?
|
// not a lot we can do about things we can't hurt... although maybe we should automatically run away?
|
||||||
if (!Combat.HasAnyValidWeapons(self, Target.FromActor(e.Attacker))) return;
|
var attack = self.traits.Get<AttackBase>();
|
||||||
|
if (!attack.HasAnyValidWeapons(Target.FromActor(e.Attacker))) return;
|
||||||
|
|
||||||
// don't retaliate against own units force-firing on us. it's usually not what the player wanted.
|
// don't retaliate against own units force-firing on us. it's usually not what the player wanted.
|
||||||
if (self.Owner.Stances[e.Attacker.Owner] == Stance.Ally) return;
|
if (self.Owner.Stances[e.Attacker.Owner] == Stance.Ally) return;
|
||||||
|
|||||||
@@ -176,23 +176,6 @@ namespace OpenRA.Mods.RA
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool HasAnyValidWeapons(Actor self, Target target)
|
|
||||||
{
|
|
||||||
var info = self.Info.Traits.Get<AttackBaseInfo>();
|
|
||||||
if (info.PrimaryWeapon != null &&
|
|
||||||
WeaponValidForTarget(self.GetPrimaryWeapon(), target)) return true;
|
|
||||||
if (info.SecondaryWeapon != null &&
|
|
||||||
WeaponValidForTarget(self.GetSecondaryWeapon(), target)) return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float GetMaximumRange(Actor self)
|
|
||||||
{
|
|
||||||
return new[] { self.GetPrimaryWeapon(), self.GetSecondaryWeapon() }
|
|
||||||
.Where(w => w != null).Max(w => w.Range);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static WeaponInfo GetPrimaryWeapon(this Actor self)
|
public static WeaponInfo GetPrimaryWeapon(this Actor self)
|
||||||
{
|
{
|
||||||
var info = self.Info.Traits.GetOrDefault<AttackBaseInfo>();
|
var info = self.Info.Traits.GetOrDefault<AttackBaseInfo>();
|
||||||
|
|||||||
Reference in New Issue
Block a user