diff --git a/OpenRA.Mods.Common/Traits/Power/RequiresPower.cs b/OpenRA.Mods.Common/Traits/Power/RequiresPower.cs index 335da3efb7..d3ea5c4da9 100644 --- a/OpenRA.Mods.Common/Traits/Power/RequiresPower.cs +++ b/OpenRA.Mods.Common/Traits/Power/RequiresPower.cs @@ -13,23 +13,24 @@ using OpenRA.Traits; namespace OpenRA.Mods.Common.Traits { [Desc("Needs power to operate.")] - class RequiresPowerInfo : ITraitInfo + class RequiresPowerInfo : UpgradableTraitInfo, ITraitInfo { - public object Create(ActorInitializer init) { return new RequiresPower(init.Self); } + public override object Create(ActorInitializer init) { return new RequiresPower(init.Self, this); } } - class RequiresPower : IDisable, INotifyOwnerChanged + class RequiresPower : UpgradableTrait, IDisable, INotifyOwnerChanged { PowerManager playerPower; - public RequiresPower(Actor self) + public RequiresPower(Actor self, RequiresPowerInfo info) + : base(info) { playerPower = self.Owner.PlayerActor.Trait(); } public bool Disabled { - get { return playerPower.PowerProvided < playerPower.PowerDrained; } + get { return playerPower.PowerProvided < playerPower.PowerDrained && !IsTraitDisabled; } } public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) diff --git a/OpenRA.Mods.Common/Traits/Upgrades/UpgradeManager.cs b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeManager.cs index 81a7765d1e..7a440bce0a 100644 --- a/OpenRA.Mods.Common/Traits/Upgrades/UpgradeManager.cs +++ b/OpenRA.Mods.Common/Traits/Upgrades/UpgradeManager.cs @@ -85,13 +85,13 @@ namespace OpenRA.Mods.Common.Traits }); } - /// Upgrade level increments are limited to one per source, i.e., if a single source - /// attempts granting multiple upgrades, they will not accumulate. They will replace each other - /// instead, leaving only the last granted upgrade active. An upgrade from each new distinct - /// source will increment the upgrade's level until AcceptsUpgrade starts returning false. Then, - /// when no new levels are accepted, the upgrade source with the shortest remaining upgrade - /// duration will be replaced by the new source. - public void GrantTimedUpgrade(Actor self, string upgrade, int duration, object source = null) + /// Upgrade level increments are limited to dupesAllowed per source, i.e., if a single + /// source attempts granting more upgrades than dupesAllowed, they will not accumulate. They will + /// replace each other instead, leaving only the most recently granted upgrade active. Each new + /// upgrade granting request will increment the upgrade's level until AcceptsUpgrade starts + /// returning false. Then, when no new levels are accepted, the upgrade source with the shortest + /// remaining upgrade duration will be replaced by the new source. + public void GrantTimedUpgrade(Actor self, string upgrade, int duration, object source = null, int dupesAllowed = 1) { var timed = timedUpgrades.FirstOrDefault(u => u.Upgrade == upgrade); if (timed == null) @@ -102,17 +102,17 @@ namespace OpenRA.Mods.Common.Traits return; } - var src = timed.Sources.FirstOrDefault(s => s.Source == source); - if (src == null) + var srcs = timed.Sources.Where(s => s.Source == source); + if (srcs.Count() < dupesAllowed) { timed.Sources.Add(new TimedUpgrade.UpgradeSource(duration, source)); if (AcceptsUpgrade(self, upgrade)) GrantUpgrade(self, upgrade, timed); else - timed.Sources.Remove(timed.Sources.OrderByDescending(s => s.Remaining).Last()); + timed.Sources.Remove(timed.Sources.MinBy(s => s.Remaining)); } else - src.Remaining = duration; + srcs.MinBy(s => s.Remaining).Remaining = duration; timed.Remaining = Math.Max(duration, timed.Remaining); } diff --git a/OpenRA.Mods.Common/Warheads/GrantUpgradeWarhead.cs b/OpenRA.Mods.Common/Warheads/GrantUpgradeWarhead.cs index 4ea45972e7..f45e1b4ea1 100644 --- a/OpenRA.Mods.Common/Warheads/GrantUpgradeWarhead.cs +++ b/OpenRA.Mods.Common/Warheads/GrantUpgradeWarhead.cs @@ -48,7 +48,7 @@ namespace OpenRA.Mods.Common.Warheads if (Duration > 0) { if (um.AcknowledgesUpgrade(a, u)) - um.GrantTimedUpgrade(a, u, Duration, firedBy); + um.GrantTimedUpgrade(a, u, Duration, firedBy, Upgrades.Count(upg => upg == u)); } else { diff --git a/mods/ra/bits/litningupg.shp b/mods/ra/bits/litningupg.shp new file mode 100644 index 0000000000..c57e2cc7cf Binary files /dev/null and b/mods/ra/bits/litningupg.shp differ diff --git a/mods/ra/bits/teslacharge.aud b/mods/ra/bits/teslacharge.aud new file mode 100644 index 0000000000..f46ad675b1 Binary files /dev/null and b/mods/ra/bits/teslacharge.aud differ diff --git a/mods/ra/rules/infantry.yaml b/mods/ra/rules/infantry.yaml index 027931bb68..d5c46404d3 100644 --- a/mods/ra/rules/infantry.yaml +++ b/mods/ra/rules/infantry.yaml @@ -475,6 +475,17 @@ SHOK: Armament@GARRISONED: Name: garrisoned Weapon: PortaTesla + Armament@CHARGE: + Weapon: PortaCharge + LocalOffset: 427,0,341 + TargetStances: Ally + ForceTargetStances: None + Cursor: ability + OutsideRangeCursor: ability + AmmoPool: + PipCount: 0 + SelfReloads: true + SelfReloadTicks: 70 AttackFrontal: Voice: Attack AttackMove: diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index c1d50a6128..70fea434a3 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -387,6 +387,9 @@ TSLA: Footprint: _ x Dimensions: 1,2 RequiresPower: + UpgradeTypes: tesla + UpgradeMaxEnabledLevel: 2 + UpgradeMaxAcceptedLevel: 3 Selectable: Bounds: 24,24,0,16 SelectionDecorations: @@ -403,8 +406,17 @@ TSLA: HasMinibib: Yes WithChargeAnimation: Armament: + UpgradeTypes: tesla + UpgradeMaxEnabledLevel: 1 + UpgradeMaxAcceptedLevel: 3 Weapon: TeslaZap LocalOffset: 0,0,427 + Armament@Upgraded: + UpgradeTypes: tesla + UpgradeMinEnabledLevel: 2 + UpgradeMaxAcceptedLevel: 3 + Weapon: TeslaZap.Upgraded + LocalOffset: 0,0,427 AttackCharge: ChargeAudio: tslachg2.aud MaxCharges: 3 @@ -414,6 +426,8 @@ TSLA: DetectCloaked: Range: 8c0 ProvidesPrerequisite@buildingname: + Targetable: + TargetTypes: Ground, C4, DetonateAttack, Structure, TeslaBoost AGUN: Inherits: ^Defense diff --git a/mods/ra/rules/vehicles.yaml b/mods/ra/rules/vehicles.yaml index d1a24af220..d2292a8107 100644 --- a/mods/ra/rules/vehicles.yaml +++ b/mods/ra/rules/vehicles.yaml @@ -563,6 +563,17 @@ TTNK: Armament: Weapon: TTankZap LocalOffset: 0,0,213 + Armament@charge: + Weapon: TTankCharge + LocalOffset: 0,0,213 + TargetStances: Ally + ForceTargetStances: None + Cursor: ability + OutsideRangeCursor: ability + AmmoPool: + PipCount: 0 + SelfReloads: true + SelfReloadTicks: 120 AttackFrontal: WithIdleOverlay@SPINNER: Sequence: spinner diff --git a/mods/ra/sequences/misc.yaml b/mods/ra/sequences/misc.yaml index daeca8dd39..593bff19f1 100644 --- a/mods/ra/sequences/misc.yaml +++ b/mods/ra/sequences/misc.yaml @@ -160,6 +160,13 @@ litning: Start: 4 Length: 4 +litningupg: + bright: + Length: 4 + dim: litning + Start: 4 + Length: 4 + fb1: idle: Length: * diff --git a/mods/ra/weapons/other.yaml b/mods/ra/weapons/other.yaml index 69f05d3dc8..53ef56c678 100644 --- a/mods/ra/weapons/other.yaml +++ b/mods/ra/weapons/other.yaml @@ -151,6 +151,21 @@ TeslaZap: Wood: 60 DamageTypes: Prone50Percent, TriggerProne, ElectricityDeath +TeslaZap.Upgraded: + ReloadDelay: 3 + Charges: true + Range: 9c512 + Report: TESLA1.AUD + Projectile: TeslaZap + Image: litningupg + Warhead@1Dam: SpreadDamage + Spread: 42 + Damage: 120 + Versus: + None: 1000 + Wood: 60 + DamageTypes: Prone50Percent, TriggerProne, ElectricityDeath + PortaTesla: ReloadDelay: 70 Range: 6c0 @@ -164,6 +179,22 @@ PortaTesla: None: 1000 DamageTypes: Prone50Percent, TriggerProne, ElectricityDeath +PortaCharge: + ReloadDelay: 70 + Range: 2c0 + Report: teslacharge.aud + Charges: yes + ValidStances: Ally + ValidTargets: TeslaBoost + Projectile: TeslaZap + Image: litningupg + Warhead@charge: GrantUpgrade + Range: 42 + Duration: 75 + Upgrades: tesla + ValidStances: Ally + ValidTargets: TeslaBoost + TTankZap: ReloadDelay: 120 Range: 7c0 @@ -177,6 +208,22 @@ TTankZap: None: 1000 DamageTypes: Prone50Percent, TriggerProne, ElectricityDeath +TTankCharge: + ReloadDelay: 120 + Range: 2c0 + Report: teslacharge.aud + Charges: yes + ValidStances: Ally + ValidTargets: TeslaBoost + Projectile: TeslaZap + Image: litningupg + Warhead@charge: GrantUpgrade + Range: 42 + Duration: 125 + Upgrades: tesla, tesla, tesla + ValidStances: Ally + ValidTargets: TeslaBoost + DogJaw: ValidTargets: Infantry ReloadDelay: 10