From 03c24da6113a451c671e874635994b2136724053 Mon Sep 17 00:00:00 2001 From: Gustas <37534529+PunkPun@users.noreply.github.com> Date: Sat, 14 Jun 2025 14:09:00 +0300 Subject: [PATCH] Give XP to minelayer --- OpenRA.Mods.Common/Activities/LayMines.cs | 1 + .../Traits/FireWarheadOnDeath.cs | 42 +++++++++++++++---- mods/ra/rules/defaults.yaml | 2 + mods/ra/rules/vehicles.yaml | 1 + 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.Common/Activities/LayMines.cs b/OpenRA.Mods.Common/Activities/LayMines.cs index 422f95c1e6..4c1cb5cf69 100644 --- a/OpenRA.Mods.Common/Activities/LayMines.cs +++ b/OpenRA.Mods.Common/Activities/LayMines.cs @@ -221,6 +221,7 @@ namespace OpenRA.Mods.Common.Activities [ new LocationInit(self.Location), new OwnerInit(self.Owner), + new ParentActorInit(self) ]); foreach (var t in self.TraitsImplementing()) diff --git a/OpenRA.Mods.Common/Traits/FireWarheadOnDeath.cs b/OpenRA.Mods.Common/Traits/FireWarheadOnDeath.cs index c8632badff..068e39fefd 100644 --- a/OpenRA.Mods.Common/Traits/FireWarheadOnDeath.cs +++ b/OpenRA.Mods.Common/Traits/FireWarheadOnDeath.cs @@ -18,7 +18,7 @@ namespace OpenRA.Mods.Common.Traits { public enum ExplosionType { Footprint, CenterPosition } - public enum DamageSource { Self, Killer } + public enum DamageSource { Self, Parent, Killer } [Desc("This actor fires warheads when killed.")] public class FireWarheadsOnDeathInfo : ConditionalTraitInfo, Requires @@ -45,7 +45,7 @@ namespace OpenRA.Mods.Common.Traits public readonly BitSet DeathTypes = default; [Desc("Who is counted as source of damage for explosion.", - "Possible values are Self and Killer.")] + "Possible values are Self, Parent and Killer.")] public readonly DamageSource DamageSource = DamageSource.Self; [Desc("Possible values are CenterPosition (explosion at the actors' center) and ", @@ -58,7 +58,7 @@ namespace OpenRA.Mods.Common.Traits public WeaponInfo WeaponInfo { get; private set; } public WeaponInfo EmptyWeaponInfo { get; private set; } - public override object Create(ActorInitializer init) { return new FireWarheadsOnDeath(this, init.Self); } + public override object Create(ActorInitializer init) { return new FireWarheadsOnDeath(this, init); } public override void RulesetLoaded(Ruleset rules, ActorInfo ai) { if (!string.IsNullOrEmpty(Weapon)) @@ -84,13 +84,21 @@ namespace OpenRA.Mods.Common.Traits public class FireWarheadsOnDeath : ConditionalTrait, INotifyKilled, INotifyDamage { readonly IHealth health; + Actor parent; BuildingInfo buildingInfo; Armament[] armaments; - public FireWarheadsOnDeath(FireWarheadsOnDeathInfo info, Actor self) + public FireWarheadsOnDeath(FireWarheadsOnDeathInfo info, ActorInitializer init) : base(info) { - health = self.Trait(); + health = init.Self.Trait(); + + if (Info.DamageSource == DamageSource.Parent) + { + var pa = init.GetOrDefault()?.Value; + if (pa != null) + init.World.AddFrameEndTask(w => parent = pa.Actor(w).Value); + } } protected override void Created(Actor self) @@ -116,7 +124,7 @@ namespace OpenRA.Mods.Common.Traits if (weapon == null) return; - var source = Info.DamageSource == DamageSource.Self ? self : e.Attacker; + var source = GetDamageSource(self, e); if (weapon.Report != null && weapon.Report.Length > 0) Game.Sound.Play(SoundType.World, weapon.Report, self.World, self.CenterPosition); @@ -132,6 +140,25 @@ namespace OpenRA.Mods.Common.Traits } } + Actor GetDamageSource(Actor self, AttackInfo e) + { + switch (Info.DamageSource) + { + case DamageSource.Killer: + return e.Attacker; + case DamageSource.Self: + return self; + case DamageSource.Parent: + if (parent == null || parent.IsDead) + return self; + else + return parent; + } + + // Fallback for the compiler, should not happen. + return self; + } + WeaponInfo ChooseWeaponForExplosion(Actor self) { if (armaments.Length == 0) @@ -156,9 +183,8 @@ namespace OpenRA.Mods.Common.Traits return; // Cast to long to avoid overflow when multiplying by the health. - var source = Info.DamageSource == DamageSource.Self ? self : e.Attacker; if (health.HP * 100L < Info.DamageThreshold * (long)health.MaxHP) - self.World.AddFrameEndTask(w => self.Kill(source, e.Damage.DamageTypes)); + self.World.AddFrameEndTask(w => self.Kill(GetDamageSource(self, e), e.Damage.DamageTypes)); } } } diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index a5291550af..1687667532 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -1240,6 +1240,8 @@ Health: HP: 5000 NotifyAppliedDamage: false + FireWarheadsOnDeath: + DamageSource: Parent Armor: Type: Light Cloak: diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index 7b481c3350..f2ae603e0c 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -505,6 +505,7 @@ APC: MNLY: Inherits: ^TrackedVehicle + Inherits@GAINSEXPERIENCE: ^GainsExperience Inherits@selection: ^SelectableSupportUnit Buildable: Queue: Vehicle