Make Explodes conditional

This commit is contained in:
reaperrr
2017-05-24 17:59:09 +02:00
committed by atlimit8
parent 6dca6b3740
commit a6b9bab033

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Traits
public enum ExplosionType { Footprint, CenterPosition } public enum ExplosionType { Footprint, CenterPosition }
[Desc("This actor explodes when killed.")] [Desc("This actor explodes when killed.")]
public class ExplodesInfo : ITraitInfo, IRulesetLoaded, Requires<HealthInfo> public class ExplodesInfo : ConditionalTraitInfo, Requires<HealthInfo>
{ {
[WeaponReference, FieldLoader.Require, Desc("Default weapon to use for explosion if ammo/payload is loaded.")] [WeaponReference, FieldLoader.Require, Desc("Default weapon to use for explosion if ammo/payload is loaded.")]
public readonly string Weapon = "UnitExplode"; public readonly string Weapon = "UnitExplode";
@@ -47,23 +47,24 @@ namespace OpenRA.Mods.Common.Traits
public WeaponInfo WeaponInfo { get; private set; } public WeaponInfo WeaponInfo { get; private set; }
public WeaponInfo EmptyWeaponInfo { get; private set; } public WeaponInfo EmptyWeaponInfo { get; private set; }
public object Create(ActorInitializer init) { return new Explodes(this, init.Self); } public override object Create(ActorInitializer init) { return new Explodes(this, init.Self); }
public void RulesetLoaded(Ruleset rules, ActorInfo ai) public override void RulesetLoaded(Ruleset rules, ActorInfo ai)
{ {
WeaponInfo = string.IsNullOrEmpty(Weapon) ? null : rules.Weapons[Weapon.ToLowerInvariant()]; WeaponInfo = string.IsNullOrEmpty(Weapon) ? null : rules.Weapons[Weapon.ToLowerInvariant()];
EmptyWeaponInfo = string.IsNullOrEmpty(EmptyWeapon) ? null : rules.Weapons[EmptyWeapon.ToLowerInvariant()]; EmptyWeaponInfo = string.IsNullOrEmpty(EmptyWeapon) ? null : rules.Weapons[EmptyWeapon.ToLowerInvariant()];
base.RulesetLoaded(rules, ai);
} }
} }
public class Explodes : INotifyKilled, INotifyDamage, INotifyCreated public class Explodes : ConditionalTrait<ExplodesInfo>, INotifyKilled, INotifyDamage, INotifyCreated
{ {
readonly ExplodesInfo info;
readonly Health health; readonly Health health;
BuildingInfo buildingInfo; BuildingInfo buildingInfo;
public Explodes(ExplodesInfo info, Actor self) public Explodes(ExplodesInfo info, Actor self)
: base(info)
{ {
this.info = info;
health = self.Trait<Health>(); health = self.Trait<Health>();
} }
@@ -74,13 +75,13 @@ namespace OpenRA.Mods.Common.Traits
void INotifyKilled.Killed(Actor self, AttackInfo e) void INotifyKilled.Killed(Actor self, AttackInfo e)
{ {
if (!self.IsInWorld) if (IsTraitDisabled || !self.IsInWorld)
return; return;
if (self.World.SharedRandom.Next(100) > info.Chance) if (self.World.SharedRandom.Next(100) > Info.Chance)
return; return;
if (info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(info.DeathTypes)) if (Info.DeathTypes.Count > 0 && !e.Damage.DamageTypes.Overlaps(Info.DeathTypes))
return; return;
var weapon = ChooseWeaponForExplosion(self); var weapon = ChooseWeaponForExplosion(self);
@@ -90,7 +91,7 @@ namespace OpenRA.Mods.Common.Traits
if (weapon.Report != null && weapon.Report.Any()) if (weapon.Report != null && weapon.Report.Any())
Game.Sound.Play(SoundType.World, weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition); Game.Sound.Play(SoundType.World, weapon.Report.Random(e.Attacker.World.SharedRandom), self.CenterPosition);
if (info.Type == ExplosionType.Footprint && buildingInfo != null) if (Info.Type == ExplosionType.Footprint && buildingInfo != null)
{ {
var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location); var cells = FootprintUtils.UnpathableTiles(self.Info.Name, buildingInfo, self.Location);
foreach (var c in cells) foreach (var c in cells)
@@ -106,16 +107,19 @@ namespace OpenRA.Mods.Common.Traits
WeaponInfo ChooseWeaponForExplosion(Actor self) WeaponInfo ChooseWeaponForExplosion(Actor self)
{ {
var shouldExplode = self.TraitsImplementing<IExplodeModifier>().All(a => a.ShouldExplode(self)); var shouldExplode = self.TraitsImplementing<IExplodeModifier>().All(a => a.ShouldExplode(self));
var useFullExplosion = self.World.SharedRandom.Next(100) <= info.LoadedChance; var useFullExplosion = self.World.SharedRandom.Next(100) <= Info.LoadedChance;
return (shouldExplode && useFullExplosion) ? info.WeaponInfo : info.EmptyWeaponInfo; return (shouldExplode && useFullExplosion) ? Info.WeaponInfo : Info.EmptyWeaponInfo;
} }
void INotifyDamage.Damaged(Actor self, AttackInfo e) void INotifyDamage.Damaged(Actor self, AttackInfo e)
{ {
if (info.DamageThreshold == 0) if (IsTraitDisabled || !self.IsInWorld)
return; return;
if (health.HP * 100 < info.DamageThreshold * health.MaxHP) if (Info.DamageThreshold == 0)
return;
if (health.HP * 100 < Info.DamageThreshold * health.MaxHP)
self.World.AddFrameEndTask(w => self.Kill(e.Attacker)); self.World.AddFrameEndTask(w => self.Kill(e.Attacker));
} }
} }