diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index d123520148..5b82ff672f 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -28,23 +28,12 @@ namespace OpenRA.Mods.RA.Activities if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; - // todo: clean this up - self.World.AddFrameEndTask(w => - { - // momentarily remove from world so the ownership queries don't get confused - var oldOwner = target.Owner; - w.Remove(target); - target.Owner = self.Owner; - w.Add(target); + var sellable = target.TraitOrDefault(); + if (sellable != null && sellable.Selling) return NextActivity; - foreach (var t in target.TraitsImplementing()) - t.OnCapture(target, self, oldOwner, self.Owner); + target.Trait().BeginCapture(target, self); + self.World.AddFrameEndTask(w => self.Destroy()); - foreach (var t in self.World.ActorsWithTrait()) - t.Trait.OnActorCaptured(t.Actor, target, self, oldOwner, self.Owner); - - self.Destroy(); - }); return this; } } diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index 962549d04e..2680f2b98b 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -14,13 +14,60 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - public class CapturableInfo : TraitInfo + public class CapturableInfo : ITraitInfo { public readonly string Type = "building"; public readonly bool AllowAllies = false; public readonly bool AllowNeutral = true; public readonly bool AllowEnemies = true; + public readonly int CaptureCompleteTime = 10; // seconds + + public object Create(ActorInitializer init) { return new Capturable(this); } } - public class Capturable {} + public class Capturable : ITick + { + [Sync] Actor captor = null; + [Sync] public int CaptureProgressTime = 0; + public bool CaptureInProgress { get { return captor != null; } } + public CapturableInfo Info; + + public Capturable(CapturableInfo info) + { + this.Info = info; + } + + public void BeginCapture(Actor self, Actor captor) + { + CaptureProgressTime = 0; + + this.captor = captor; + + if (self.Owner != self.World.WorldActor.Owner) + self.ChangeOwner(self.World.WorldActor.Owner); + } + + public void Tick(Actor self) + { + if (!CaptureInProgress) return; + + if (CaptureProgressTime < Info.CaptureCompleteTime * 25) + CaptureProgressTime++; + else + { + self.World.AddFrameEndTask(w => + { + self.ChangeOwner(captor.Owner); + + foreach (var t in self.TraitsImplementing()) + t.OnCapture(self, captor, self.Owner, captor.Owner); + + foreach (var t in captor.World.ActorsWithTrait()) + t.Trait.OnActorCaptured(t.Actor, self, captor, self.Owner, captor.Owner); + + captor = null; + }); + } + } + } } diff --git a/OpenRA.Mods.RA/CapturableBar.cs b/OpenRA.Mods.RA/CapturableBar.cs new file mode 100644 index 0000000000..e489d294b9 --- /dev/null +++ b/OpenRA.Mods.RA/CapturableBar.cs @@ -0,0 +1,40 @@ +#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.Drawing; +using System.Linq; +using OpenRA.Traits; + +namespace OpenRA.Mods.RA +{ + class CapturableBarInfo : ITraitInfo, Requires + { + public object Create(ActorInitializer init) { return new CapturableBar(init.self); } + } + class CapturableBar : ISelectionBar + { + Capturable cap; + + public CapturableBar(Actor self) + { + this.cap = self.Trait(); + } + + public float GetValue() + { + // only show when building is being captured + if (!cap.CaptureInProgress) + return 0f; + + return (float)cap.CaptureProgressTime / (cap.Info.CaptureCompleteTime * 25); + } + public Color GetColor() { return Color.Orange; } + } +} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 9db4b2dbbd..8cff11f2ac 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -140,6 +140,7 @@ + @@ -386,4 +387,4 @@ copy "$(TargetPath)" "$(SolutionDir)mods/ra/" cd "$(SolutionDir)" - \ No newline at end of file + diff --git a/OpenRA.Mods.RA/Sellable.cs b/OpenRA.Mods.RA/Sellable.cs index c5ea33da78..dc280c48d2 100644 --- a/OpenRA.Mods.RA/Sellable.cs +++ b/OpenRA.Mods.RA/Sellable.cs @@ -21,13 +21,13 @@ namespace OpenRA.Mods.RA public class Sellable : IResolveOrder { - bool selling = false; + [Sync] public bool Selling = false; public void ResolveOrder(Actor self, Order order) { - if (order.OrderString == "Sell" && !selling) + if (order.OrderString == "Sell" && !Selling) { - selling = true; + Selling = true; foreach( var ns in self.TraitsImplementing() ) ns.Selling( self ); diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 604ef76559..3683a6ae2b 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -242,6 +242,7 @@ ShakeOnDeath: Sellable: Capturable: + CapturableBar: ^CivBuilding: Inherits: ^Building @@ -257,6 +258,7 @@ WithBuildingExplosion: -RepairableBuilding: -Capturable: + -CapturableBar: -Sellable: Tooltip: Name: Civilian Building @@ -275,6 +277,7 @@ ^TechBuilding: Inherits: ^CivBuilding Capturable: + CapturableBar: RepairableBuilding: RevealsShroud: Range: 3 diff --git a/mods/cnc/rules/tech.yaml b/mods/cnc/rules/tech.yaml index b6b4cc811e..f9b62d1802 100644 --- a/mods/cnc/rules/tech.yaml +++ b/mods/cnc/rules/tech.yaml @@ -27,7 +27,6 @@ HOSP: Dimensions: 2,2 Tooltip: Name: Hospital - -Capturable: LeavesHusk: HuskActor: HOSP.Husk diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index def909d200..77e7de79b8 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -140,6 +140,7 @@ OILB: RevealsShroud: Range: 3 Capturable: + CapturableBar: -MustBeDestroyed: CashTrickler: Period: 250 diff --git a/mods/ra/rules/defaults.yaml b/mods/ra/rules/defaults.yaml index d104100499..93386afa85 100644 --- a/mods/ra/rules/defaults.yaml +++ b/mods/ra/rules/defaults.yaml @@ -185,6 +185,7 @@ TerrainTypes: Clear,Road GivesBuildableArea: Capturable: + CapturableBar: SoundOnDamageTransition: DamagedSound: kaboom1.aud DestroyedSound: kaboom22.aud @@ -253,6 +254,7 @@ -GivesBuildableArea: -Sellable: -Capturable: + -CapturableBar: ^CivField: Inherits: ^CivBuilding