diff --git a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs index 1c0554207b..a3d24fc7b4 100755 --- a/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs +++ b/OpenRA.Mods.RA/Buildings/RepairableBuilding.cs @@ -22,11 +22,11 @@ namespace OpenRA.Mods.RA.Buildings public object Create(ActorInitializer init) { return new RepairableBuilding(init.self, this); } } - public class RepairableBuilding : ITick, IResolveOrder, ISync + public class RepairableBuilding : ITick, ISync { [Sync] - bool isRepairing = false; - + public Player Repairer = null; + Health Health; RepairableBuildingInfo Info; public RepairableBuilding(Actor self, RepairableBuildingInfo info) @@ -34,42 +34,56 @@ namespace OpenRA.Mods.RA.Buildings Health = self.Trait(); Info = info; } - - public void ResolveOrder(Actor self, Order order) + + public void RepairBuilding(Actor self, Player p) { - if (order.OrderString == "Repair") + if (self.HasTrait()) { - isRepairing = !isRepairing; - if (isRepairing) - Sound.PlayToPlayer(self.Owner, self.World.WorldActor.Info.Traits.Get().Repairing); + if (self.AppearsFriendlyTo(p.PlayerActor)) + { + if (Repairer == p) + Repairer = null; + + else + { + Repairer = p; + Sound.PlayToPlayer(Repairer, p.World.WorldActor.Info.Traits.Get().Repairing); + + self.World.AddFrameEndTask( + w => w.Add(new RepairIndicator(self, p))); + } + } } } int remainingTicks; public void Tick(Actor self) { - if (!isRepairing) return; + if (Repairer == null) return; if (remainingTicks == 0) { + if (Repairer.WinState != WinState.Undefined) + { + Repairer = null; + return; + } + var buildingValue = self.GetSellValue(); var hpToRepair = Math.Min(Info.RepairStep, Health.MaxHP - Health.HP); var cost = (hpToRepair * Info.RepairPercent * buildingValue) / (Health.MaxHP * 100); - if (!self.Owner.PlayerActor.Trait().TakeCash(cost)) + if (!Repairer.PlayerActor.Trait().TakeCash(cost)) { remainingTicks = 1; return; } - self.World.AddFrameEndTask( - w => w.Add(new RepairIndicator(self, Info.RepairInterval / 2))); - self.InflictDamage(self, -hpToRepair, null); if (Health.DamageState == DamageState.Undamaged) { - isRepairing = false; + Repairer = null; return; } @@ -79,7 +93,7 @@ namespace OpenRA.Mods.RA.Buildings --remainingTicks; } } - public class AllowsBuildingRepairInfo : TraitInfo {} - public class AllowsBuildingRepair {} + public class AllowsBuildingRepairInfo : TraitInfo { } + public class AllowsBuildingRepair { } } diff --git a/OpenRA.Mods.RA/Effects/RepairIndicator.cs b/OpenRA.Mods.RA/Effects/RepairIndicator.cs index 4b177f00f3..fe021a5bf1 100755 --- a/OpenRA.Mods.RA/Effects/RepairIndicator.cs +++ b/OpenRA.Mods.RA/Effects/RepairIndicator.cs @@ -18,27 +18,37 @@ namespace OpenRA.Mods.RA.Effects { class RepairIndicator : IEffect { - int framesLeft; - Actor a; - Animation anim = new Animation("select"); + Actor building; + Player player; + Animation anim = new Animation("allyrepair"); - public RepairIndicator(Actor a, int frames) - { - this.a = a; anim.PlayRepeating("repair"); - framesLeft = frames; + public RepairIndicator(Actor building, Player player) + { + this.building = building; + this.player = player; + anim.PlayRepeating("repair"); } - public void Tick( World world ) + public void Tick(World world) { - if (--framesLeft == 0 || !a.IsInWorld || a.IsDead()) + if (!building.IsInWorld || + building.IsDead() || + building.Trait().Repairer == null || + building.Trait().Repairer != player) world.AddFrameEndTask(w => w.Remove(this)); + + anim.Tick(); } public IEnumerable Render() { - if (!a.Destroyed) - yield return new Renderable(anim.Image, - a.CenterLocation - .5f * anim.Image.size, "chrome", (int)a.CenterLocation.Y); + if (!building.Destroyed) + { + var palette = building.Trait().Palette(player); + + yield return new Renderable(anim.Image, + building.CenterLocation - .5f * anim.Image.size, palette, (int)building.CenterLocation.Y); + } } } } diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 3ba1f5c060..db6d0d8a17 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -72,6 +72,7 @@ + diff --git a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs index 4740d38d0c..c91640398f 100644 --- a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs @@ -31,36 +31,36 @@ namespace OpenRA.Mods.RA.Orders if (mi.Button == MouseButton.Left) { var underCursor = world.FindUnitsAtMouse(mi.Location) - .Where(a => a.Owner == world.LocalPlayer && a.HasTrait()).FirstOrDefault(); + .Where(a => a.AppearsFriendlyTo(world.LocalPlayer.PlayerActor) && a.HasTrait()).FirstOrDefault(); if (underCursor == null) yield break; - + if (underCursor.Info.Traits.Contains() - && underCursor.GetDamageState() > DamageState.Undamaged) - yield return new Order("Repair", underCursor, false); + && underCursor.GetDamageState() > DamageState.Undamaged) + yield return new Order("RepairBuilding", world.LocalPlayer.PlayerActor, false) { TargetActor = underCursor }; } } - public void Tick( World world ) + public void Tick(World world) { - if( !PlayerIsAllowedToRepair( world ) ) + if (!PlayerIsAllowedToRepair(world)) world.CancelInputMode(); } - public static bool PlayerIsAllowedToRepair( World world ) - { + public static bool PlayerIsAllowedToRepair(World world) + { return world.ActorsWithTrait() - .Any(a => a.Actor.Owner == world.LocalPlayer); + .Any(a => a.Actor.AppearsFriendlyTo(world.LocalPlayer.PlayerActor)); } - public void RenderAfterWorld( WorldRenderer wr, World world ) { } - public void RenderBeforeWorld( WorldRenderer wr, World world ) { } + public void RenderAfterWorld(WorldRenderer wr, World world) { } + public void RenderBeforeWorld(WorldRenderer wr, World world) { } public string GetCursor(World world, int2 xy, MouseInput mi) { mi.Button = MouseButton.Left; - return OrderInner(world, xy, mi).Any() + return OrderInner(world, xy, mi).Any() ? "repair" : "repair-blocked"; } } diff --git a/OpenRA.Mods.RA/Player/AllyRepair.cs b/OpenRA.Mods.RA/Player/AllyRepair.cs new file mode 100644 index 0000000000..628c17d054 --- /dev/null +++ b/OpenRA.Mods.RA/Player/AllyRepair.cs @@ -0,0 +1,35 @@ +#region Copyright & License Information +/* + * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using OpenRA.Mods.RA.Buildings; +using OpenRA.Mods.RA.Effects; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + class AllyRepairInfo : TraitInfo { } + + class AllyRepair : IResolveOrder + { + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "RepairBuilding") + { + var building = order.TargetActor; + + if (building.HasTrait()) + if (building.AppearsFriendlyTo(self)) + building.Trait().RepairBuilding(building, self.Owner); + } + } + + } +} diff --git a/mods/cnc/bits/allyrepair.shp b/mods/cnc/bits/allyrepair.shp new file mode 100644 index 0000000000..6dfc1e53f2 Binary files /dev/null and b/mods/cnc/bits/allyrepair.shp differ diff --git a/mods/cnc/rules/system.yaml b/mods/cnc/rules/system.yaml index 5dbecea3b3..011a5733a6 100644 --- a/mods/cnc/rules/system.yaml +++ b/mods/cnc/rules/system.yaml @@ -6,6 +6,7 @@ Player: WinNotification:accom1.aud LoseNotification:fail1.aud PowerManager: + AllyRepair: PlayerResources: InitialCash: 5000 ActorGroupProxy: diff --git a/mods/cnc/sequences/misc.yaml b/mods/cnc/sequences/misc.yaml index 5931490d6e..17fcd78d4e 100644 --- a/mods/cnc/sequences/misc.yaml +++ b/mods/cnc/sequences/misc.yaml @@ -111,6 +111,12 @@ select: repair: Start: 2 +allyrepair: + repair: + Start: 0 + Length: * + Tick: 160 + crate: idle: wcrate Start: 0 diff --git a/mods/ra/bits/allyrepair.shp b/mods/ra/bits/allyrepair.shp new file mode 100644 index 0000000000..309ca0c2b1 Binary files /dev/null and b/mods/ra/bits/allyrepair.shp differ diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index e9edbb8ea3..6157e0b5a5 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -34,6 +34,7 @@ Player: WinNotification:misnwon1.aud LoseNotification:misnlst1.aud PowerManager: + AllyRepair: PlayerResources: InitialCash: 5000 ActorGroupProxy: diff --git a/mods/ra/sequences.yaml b/mods/ra/sequences.yaml index 986f8bbdae..24ce28ce85 100644 --- a/mods/ra/sequences.yaml +++ b/mods/ra/sequences.yaml @@ -1546,6 +1546,12 @@ poweroff: Length: * Tick: 160 +allyrepair: + repair: + Start: 0 + Length: * + Tick: 160 + tabs: left-normal: Start: 0