From bf45b4e33be058a6a9abca27a51e591f65e7121a Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 1 Jan 2010 20:27:22 +1300 Subject: [PATCH 01/13] FIX setup done for Plane/Helicopter --- OpenRa.Game/Traits/Helicopter.cs | 13 +++++++++++-- OpenRa.Game/Traits/Plane.cs | 24 +++++++++++++----------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/OpenRa.Game/Traits/Helicopter.cs b/OpenRa.Game/Traits/Helicopter.cs index 38bd07f0c5..1361571a91 100644 --- a/OpenRa.Game/Traits/Helicopter.cs +++ b/OpenRa.Game/Traits/Helicopter.cs @@ -9,6 +9,14 @@ namespace OpenRa.Game.Traits public IDisposable reservation; public Helicopter(Actor self) {} + // todo: push into data! + static bool HeliCanEnter(Actor a) + { + if (a.Info == Rules.UnitInfo["HPAD"]) return true; + if (a.Info == Rules.UnitInfo["FIX"]) return true; + return false; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left) return null; @@ -16,7 +24,7 @@ namespace OpenRa.Game.Traits if (underCursor == null) return new Order("Move", self, null, xy, null); - if (underCursor.Info == Rules.UnitInfo["HPAD"] + if (HeliCanEnter(underCursor) && underCursor.Owner == self.Owner && !Reservable.IsReserved(underCursor)) return new Order("Enter", self, underCursor, int2.Zero, null); @@ -54,7 +62,8 @@ namespace OpenRa.Game.Traits self.QueueActivity(new HeliFly(order.TargetActor.CenterLocation + offsetVec)); self.QueueActivity(new Turn(self.Info.InitialFacing)); self.QueueActivity(new HeliLand(false)); - self.QueueActivity(new Rearm()); + self.QueueActivity(order.TargetActor.Info == Rules.UnitInfo["HPAD"] + ? (IActivity)new Rearm() : new Repair()); } } diff --git a/OpenRa.Game/Traits/Plane.cs b/OpenRa.Game/Traits/Plane.cs index f00bbe54d5..f01c38e76b 100644 --- a/OpenRa.Game/Traits/Plane.cs +++ b/OpenRa.Game/Traits/Plane.cs @@ -12,13 +12,21 @@ namespace OpenRa.Game.Traits public Plane(Actor self) {} + // todo: push into data! + static bool PlaneCanEnter(Actor a) + { + if (a.Info == Rules.UnitInfo["AFLD"]) return true; + if (a.Info == Rules.UnitInfo["FIX"]) return true; + return false; + } + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) { if (mi.Button == MouseButton.Left) return null; if (underCursor == null) return new Order("Move", self, null, xy, null); - if (underCursor.Info == Rules.UnitInfo["AFLD"] + if (PlaneCanEnter(underCursor) && underCursor.Owner == self.Owner && !Reservable.IsReserved(underCursor)) return new Order("Enter", self, underCursor, int2.Zero, null); @@ -51,18 +59,12 @@ namespace OpenRa.Game.Traits self.CancelActivity(); self.QueueActivity(new ReturnToBase(self, order.TargetActor)); - self.QueueActivity(new Rearm()); /* todo: something else when it's FIX rather than AFLD */ + self.QueueActivity(order.TargetActor.Info == Rules.UnitInfo["AFLD"] + ? (IActivity)new Rearm() : new Repair()); } } - public UnitMovementType GetMovementType() - { - return UnitMovementType.Fly; - } - - public bool CanEnterCell(int2 location) - { - return true; // Planes can go anywhere (?) - } + public UnitMovementType GetMovementType() { return UnitMovementType.Fly; } + public bool CanEnterCell(int2 location) { return true; } } } From 5487edf36976a4fb24a4423ba96bc3886973da06 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 07:50:27 +1300 Subject: [PATCH 02/13] use InflictDamage for Repair, so we do half/full transitions properly --- OpenRa.Game/Traits/Activities/Repair.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/OpenRa.Game/Traits/Activities/Repair.cs b/OpenRa.Game/Traits/Activities/Repair.cs index fa3019f5bc..9d8e1d2002 100644 --- a/OpenRa.Game/Traits/Activities/Repair.cs +++ b/OpenRa.Game/Traits/Activities/Repair.cs @@ -19,12 +19,9 @@ namespace OpenRa.Game.Traits.Activities if (isCanceled) return NextActivity; if (--remainingTicks == 0) { - self.Health += hpPerPoint; - if (self.Health >= self.Info.Strength) - { - self.Health = self.Info.Strength; + self.InflictDamage(self, -hpPerPoint, Rules.WarheadInfo["Super"]); + if (self.Health == self.Info.Strength) return NextActivity; - } var hostBuilding = Game.FindUnits(self.CenterLocation, self.CenterLocation) .FirstOrDefault(a => a.traits.Contains()); From 37bc4f2279a41be4f3778e70ff81f7d436656c83 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 09:05:41 +1300 Subject: [PATCH 03/13] FIX works --- OpenRa.Game/Controller.cs | 1 + OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/PathFinder.cs | 2 +- OpenRa.Game/PathSearch.cs | 10 +++++- OpenRa.Game/Traits/Activities/Move.cs | 19 ++++++++-- OpenRa.Game/Traits/EngineerCapture.cs | 4 +-- OpenRa.Game/Traits/Repairable.cs | 50 +++++++++++++++++++++++++++ doc/progress.txt | 16 ++++----- units.ini | 28 +++++++-------- 9 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 OpenRa.Game/Traits/Repairable.cs diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index 1b7ea5dc03..1ea516427e 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -162,6 +162,7 @@ namespace OpenRa.Game else return Cursor.MoveBlocked; case "Enter": return Cursor.Enter; + case "Infiltrate": return Cursor.Enter; case "Capture": return Cursor.Capture; case "Harvest": return Cursor.Attack; // TODO: special harvest cursor? default: diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 20ad6b77ee..8d34a4ebf1 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -198,6 +198,7 @@ + diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index 210613a1e6..c93b0f1f6c 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -49,7 +49,7 @@ namespace OpenRa.Game } } - Func AvoidUnitsNear(int2 p, int dist) + public Func AvoidUnitsNear(int2 p, int dist) { return q => p != q && diff --git a/OpenRa.Game/PathSearch.cs b/OpenRa.Game/PathSearch.cs index 983634cbdf..931733726a 100755 --- a/OpenRa.Game/PathSearch.cs +++ b/OpenRa.Game/PathSearch.cs @@ -15,6 +15,7 @@ namespace OpenRa.Game Func customBlock; public bool checkForBlocked; public bool ignoreTerrain; + public Actor ignoreBuilding; public PathSearch() { @@ -28,6 +29,12 @@ namespace OpenRa.Game return this; } + public PathSearch WithIgnoredBuilding(Actor b) + { + ignoreBuilding = b; + return this; + } + public int2 Expand( float[][ , ] passableCost ) { var p = queue.Pop(); @@ -49,7 +56,8 @@ namespace OpenRa.Game { if (passableCost[(int)umt][newHere.X, newHere.Y] == float.PositiveInfinity) continue; - if (!Game.BuildingInfluence.CanMoveHere(newHere)) + if (!Game.BuildingInfluence.CanMoveHere(newHere) && + Game.BuildingInfluence.GetBuildingAt(newHere) != ignoreBuilding) continue; if (Rules.Map.IsOverlaySolid(newHere)) continue; diff --git a/OpenRa.Game/Traits/Activities/Move.cs b/OpenRa.Game/Traits/Activities/Move.cs index e92863fea2..ebab176413 100755 --- a/OpenRa.Game/Traits/Activities/Move.cs +++ b/OpenRa.Game/Traits/Activities/Move.cs @@ -14,6 +14,7 @@ namespace OpenRa.Game.Traits.Activities int nearEnough; public List path; Func> getPath; + public Actor ignoreBuilding; MovePart move; @@ -26,6 +27,18 @@ namespace OpenRa.Game.Traits.Activities this.nearEnough = nearEnough; } + public Move(int2 destination, Actor ignoreBuilding) + { + this.getPath = (self, mobile) => + Game.PathFinder.FindPath( + PathSearch.FromPoint( self.Location, destination, mobile.GetMovementType(), false ) + .WithCustomBlocker( Game.PathFinder.AvoidUnitsNear( self.Location, 4 )).WithIgnoredBuilding( ignoreBuilding )); + + this.destination = destination; + this.nearEnough = 0; + this.ignoreBuilding = ignoreBuilding; + } + public Move( Actor target, int range ) { this.getPath = ( self, mobile ) => Game.PathFinder.FindUnitPathToRange( @@ -42,9 +55,11 @@ namespace OpenRa.Game.Traits.Activities this.nearEnough = 0; } - static bool CanEnterCell( int2 c, Actor self ) + bool CanEnterCell( int2 c, Actor self ) { - if (!Game.BuildingInfluence.CanMoveHere(c)) return false; + if (!Game.BuildingInfluence.CanMoveHere(c) + && Game.BuildingInfluence.GetBuildingAt(c) != ignoreBuilding) + return false; // Cannot enter a cell if any unit inside is uncrushable // This will need to be updated for multiple-infantry-in-a-cell diff --git a/OpenRa.Game/Traits/EngineerCapture.cs b/OpenRa.Game/Traits/EngineerCapture.cs index 5703d0c59c..5a31ff027d 100644 --- a/OpenRa.Game/Traits/EngineerCapture.cs +++ b/OpenRa.Game/Traits/EngineerCapture.cs @@ -16,13 +16,13 @@ namespace OpenRa.Game.Traits // todo: other bits - return new Order(underCursor.Health <= EngineerDamage ? "Capture" : "Enter", + return new Order(underCursor.Health <= EngineerDamage ? "Capture" : "Infiltrate", self, underCursor, int2.Zero, null); } public void ResolveOrder(Actor self, Order order) { - if (order.OrderString == "Enter" || order.OrderString == "Capture") + if (order.OrderString == "Infiltrate" || order.OrderString == "Capture") { self.CancelActivity(); self.QueueActivity(new Move(order.TargetActor, 1)); diff --git a/OpenRa.Game/Traits/Repairable.cs b/OpenRa.Game/Traits/Repairable.cs new file mode 100644 index 0000000000..b5cafac857 --- /dev/null +++ b/OpenRa.Game/Traits/Repairable.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.Traits.Activities; + +namespace OpenRa.Game.Traits +{ + class Repairable : IOrder + { + IDisposable reservation; + public Repairable(Actor self) { } + + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + if (mi.Button != MouseButton.Right) return null; + if (underCursor == null) return null; + + if (underCursor.Info == Rules.UnitInfo["FIX"] + && underCursor.Owner == self.Owner + && !Reservable.IsReserved(underCursor)) + return new Order("Enter", self, underCursor, int2.Zero, null); + + return null; + } + + public void ResolveOrder(Actor self, Order order) + { + if (reservation != null) + { + reservation.Dispose(); + reservation = null; + } + + if (order.OrderString == "Enter") + { + if (Reservable.IsReserved(order.TargetActor)) + return; + + var res = order.TargetActor.traits.GetOrDefault(); + if (res != null) reservation = res.Reserve(self); + + self.CancelActivity(); + self.QueueActivity(new Move(((1 / 24f) * order.TargetActor.CenterLocation).ToInt2(), order.TargetActor)); + self.QueueActivity(new Rearm()); + self.QueueActivity(new Repair()); + } + } + } +} diff --git a/doc/progress.txt b/doc/progress.txt index 0013085c6c..bcc268c1fb 100644 --- a/doc/progress.txt +++ b/doc/progress.txt @@ -22,7 +22,7 @@ All tracked vehicles Light vehicles V2RL Works APC Cargo doesn't work -MNLY Can't reload at FIX +MNLY Works MGG No gap MRJ No radar JEEP Works @@ -31,15 +31,15 @@ HARV Works ARTY Works Helicopters - - Repair as FIX doesn't work + - Return to base after attack doesnt work TRAN Cargo doesn't work -HELI Weapon offsets wrong -HIND Weapon offsets wrong +HELI Works +HIND Works -Planes - - Repair at FIX doesn't work [fix doesn't work?] -YAK Ammo/ROF are funky -MIG Ammo/ROF are funky +Planes + - Ammo/ROF are funky +YAK Works +MIG Works Ships diff --git a/units.ini b/units.ini index b6eb87044c..6d8a795165 100644 --- a/units.ini +++ b/units.ini @@ -16,47 +16,47 @@ MNLY.AT [V2RL] Description=V2 Rocket -Traits=Unit, Mobile, AttackBase, RenderUnitReload, AutoTarget +Traits=Unit, Mobile, AttackBase, RenderUnitReload, AutoTarget, Repairable Voice=VehicleVoice LongDesc=Long-range rocket artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft [1TNK] Description=Light Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable Recoil=2 Voice=VehicleVoice LongDesc=Light Tank, good for scouting.\n Strong vs Light Vehicles\n Weak vs Tanks, Aircraft [2TNK] Description=Medium Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable Recoil=3 Voice=VehicleVoice LongDesc=Allied Main Battle Tank.\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft [3TNK] Description=Heavy Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable Recoil=3 Voice=VehicleVoice LongDesc=Soviet Main Battle Tank, with dual cannons\n Strong vs Tanks, Light Vehicles\n Weak vs Infantry, Aircraft [4TNK] Description=Mammoth Tank -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable Voice=VehicleVoice LongDesc=Big and slow tank, with anti-air capability.\n Strong vs Tanks, Aircraft\n Weak vs Infantry [ARTY] Description=Artillery -Traits=Unit, Mobile, AttackBase, RenderUnit, Explodes, AutoTarget +Traits=Unit, Mobile, AttackBase, RenderUnit, Explodes, AutoTarget, Repairable Voice=VehicleVoice LongDesc=Long-range artillery.\n Strong vs Infantry, Buildings\n Weak vs Tanks, Aircraft [JEEP] Description=Ranger -Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget +Traits=Unit, Mobile, Turreted, AttackTurreted, RenderUnitTurreted, AutoTarget, Repairable PrimaryOffset=0,0,0,-2 MuzzleFlash=yes Voice=VehicleVoice LongDesc=Fast scout & anti-infantry vehicle.\n Strong vs Infantry\n Weak vs Tanks, Aircraft [APC] Description=Armored Personnel Carrier -Traits=Unit, Mobile, AttackBase, RenderUnitMuzzleFlash, AutoTarget +Traits=Unit, Mobile, AttackBase, RenderUnitMuzzleFlash, AutoTarget, Repairable PrimaryOffset=0,0,0,-4 MuzzleFlash=yes Voice=VehicleVoice @@ -65,40 +65,40 @@ LongDesc=Tough infantry transport.\n Strong vs Infantry, Light Vehicles\n Weak ;; non-combat vehicles [MRJ] Description=Radar Jammer -Traits=Unit, Mobile, RenderUnitSpinner +Traits=Unit, Mobile, RenderUnitSpinner, Repairable PrimaryOffset=0,4,0,-6 SelectionPriority=3 Voice=VehicleVoice LongDesc=Hides nearby units on the enemy's minimap.\n Unarmed [MGG] Description=Mobile Gap Generator -Traits=Unit, Mobile, RenderUnitSpinner +Traits=Unit, Mobile, RenderUnitSpinner, Repairable PrimaryOffset=0,6,0,-3 SelectionPriority=3 Voice=VehicleVoice LongDesc=Regenerates Fog of War in a small area \naround the unit.\n Unarmed [HARV] Description=Ore Truck -Traits=Harvester, Unit, Mobile, RenderUnit +Traits=Harvester, Unit, Mobile, RenderUnit, Repairable SelectionPriority=7 Voice=VehicleVoice LongDesc=Collects Ore and Gems for processing.\n Unarmed [MCV] Description=Mobile Construction Vehicle -Traits=Unit, Mobile, McvDeploy, RenderUnit +Traits=Unit, Mobile, McvDeploy, RenderUnit, Repairable SelectionPriority=3 Voice=VehicleVoice LongDesc=Deploys into another Construction Yard.\n Unarmed [MNLY.AP] Description=Minelayer (Anti-Personnel) -Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune +Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable Voice=VehicleVoice LongDesc=Lays mines to destroy unwary enemy units.\n Unarmed Primary=MINP ;; temporary hack [MNLY.AT] Description=Minelayer (Anti-Tank) -Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune +Traits=Unit, Mobile, RenderUnit, Minelayer, MineImmune, Repairable Voice=VehicleVoice LongDesc=Lays mines to destroy unwary enemy units.\n Unarmed Primary=MINV ;; temporary hack From 5a7b572cfd9e0fafdb48072cad6769da5ae69b28 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 10:57:21 +1300 Subject: [PATCH 04/13] helis return to base after finishing an attack --- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/Activities/HeliReturn.cs | 50 +++++++++++++++++++++ OpenRa.Game/Traits/AttackHeli.cs | 2 +- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 OpenRa.Game/Traits/Activities/HeliReturn.cs diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 8d34a4ebf1..0f4e25dde5 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -117,6 +117,7 @@ + diff --git a/OpenRa.Game/Traits/Activities/HeliReturn.cs b/OpenRa.Game/Traits/Activities/HeliReturn.cs new file mode 100644 index 0000000000..8da692e3f7 --- /dev/null +++ b/OpenRa.Game/Traits/Activities/HeliReturn.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; + +namespace OpenRa.Game.Traits.Activities +{ + class HeliReturn : IActivity + { + public IActivity NextActivity { get; set; } + bool isCanceled; + + static Actor ChooseHelipad(Actor self) + { + return Game.world.Actors.FirstOrDefault( + a => a.Info == Rules.UnitInfo["HPAD"] && + a.Owner == self.Owner && + !Reservable.IsReserved(a)); + } + + public IActivity Tick(Actor self) + { + if (isCanceled) return NextActivity; + var dest = ChooseHelipad(self); + + if (dest == null) + return Util.SequenceActivities( + new Turn(self.Info.InitialFacing), + new HeliLand(true), + NextActivity); + + var res = dest.traits.GetOrDefault(); + if (res != null) + self.traits.Get().reservation = res.Reserve(self); + + var offset = (dest.Info as BuildingInfo).SpawnOffset; + var offsetVec = new float2(offset[0], offset[1]); + + return Util.SequenceActivities( + new HeliFly(dest.CenterLocation + offsetVec), + new Turn(self.Info.InitialFacing), + new HeliLand(false), + new Rearm(), + NextActivity); + } + + public void Cancel(Actor self) { isCanceled = true; NextActivity = null; } + } +} diff --git a/OpenRa.Game/Traits/AttackHeli.cs b/OpenRa.Game/Traits/AttackHeli.cs index f68bd33532..4749edc089 100644 --- a/OpenRa.Game/Traits/AttackHeli.cs +++ b/OpenRa.Game/Traits/AttackHeli.cs @@ -10,7 +10,7 @@ namespace OpenRa.Game.Traits { target = order.TargetActor; self.QueueActivity(new HeliAttack(order.TargetActor)); - // todo: fly home + self.QueueActivity(new HeliReturn()); } } } From acacd99a7174d93d19bc8a5973a88896c1cb6a98 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:00:37 +1300 Subject: [PATCH 05/13] backend support for selling --- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/Activities/Sell.cs | 41 +++++++++++++++++++++++++++ OpenRa.Game/Traits/RenderBuilding.cs | 6 ++++ 3 files changed, 48 insertions(+) create mode 100644 OpenRa.Game/Traits/Activities/Sell.cs diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 0f4e25dde5..185d03cc18 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -146,6 +146,7 @@ + diff --git a/OpenRa.Game/Traits/Activities/Sell.cs b/OpenRa.Game/Traits/Activities/Sell.cs new file mode 100644 index 0000000000..d0dac1d145 --- /dev/null +++ b/OpenRa.Game/Traits/Activities/Sell.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits.Activities +{ + class Sell : IActivity + { + public IActivity NextActivity { get; set; } + + bool started; + + void DoSell(Actor self) + { + var refund = Rules.General.RefundPercent + * self.Health * self.Info.Cost / self.Info.Strength; + + self.Owner.GiveCash((int)refund); + self.Health = 0; + Game.world.Remove(self); + } + + public IActivity Tick(Actor self) + { + if (!started) + { + var rb = self.traits.Get(); + rb.PlayCustomAnimBackwards(self, "make", + () => Game.world.AddFrameEndTask(w => DoSell(self))); + + Sound.Play("cashturn.aud"); + started = true; + } + + return this; + } + + public void Cancel(Actor self) { /* never gonna give you up.. */ } + } +} diff --git a/OpenRa.Game/Traits/RenderBuilding.cs b/OpenRa.Game/Traits/RenderBuilding.cs index 2dd81f7266..24830e0a67 100644 --- a/OpenRa.Game/Traits/RenderBuilding.cs +++ b/OpenRa.Game/Traits/RenderBuilding.cs @@ -62,6 +62,12 @@ namespace OpenRa.Game.Traits () => anim.PlayRepeating(GetPrefix(self) + "idle")); } + public void PlayCustomAnimBackwards(Actor self, string name, Action a) + { + anim.PlayBackwardsThen(GetPrefix(self) + name, + () => { anim.PlayRepeating(GetPrefix(self) + "idle"); a(); }); + } + public virtual void Damaged(Actor self, AttackInfo e) { if (!e.DamageStateChanged) From a2a00ae5990e496dd91a028abce25ce9de970bbd Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:22:34 +1300 Subject: [PATCH 06/13] shuffling --- OpenRa.Game/Chrome.cs | 10 ++++----- OpenRa.Game/Controller.cs | 5 +++-- OpenRa.Game/Game.cs | 1 + OpenRa.Game/OpenRa.Game.csproj | 22 +++++++++---------- OpenRa.Game/{ => Orders}/IOrderGenerator.cs | 0 OpenRa.Game/{ => Orders}/IOrderSource.cs | 2 +- OpenRa.Game/{ => Orders}/LocalOrderSource.cs | 2 +- .../{ => Orders}/NetworkOrderSource.cs | 2 +- OpenRa.Game/{ => Orders}/Order.cs | 0 OpenRa.Game/{ => Orders}/OrderIO.cs | 2 +- OpenRa.Game/{ => Orders}/OrderManager.cs | 2 +- .../PlaceBuildingOrderGenerator.cs} | 6 ++--- OpenRa.Game/{ => Orders}/ReplayOrderSource.cs | 2 +- .../{ => Orders}/UnitOrderGenerator.cs | 2 +- OpenRa.Game/{ => Orders}/UnitOrders.cs | 8 +++---- OpenRa.Game/Traits/RallyPoint.cs | 1 + OpenRa.Game/Traits/RenderUnitRotor.cs | 3 +-- 17 files changed, 34 insertions(+), 36 deletions(-) rename OpenRa.Game/{ => Orders}/IOrderGenerator.cs (100%) rename OpenRa.Game/{ => Orders}/IOrderSource.cs (84%) rename OpenRa.Game/{ => Orders}/LocalOrderSource.cs (91%) rename OpenRa.Game/{ => Orders}/NetworkOrderSource.cs (94%) rename OpenRa.Game/{ => Orders}/Order.cs (100%) rename OpenRa.Game/{ => Orders}/OrderIO.cs (92%) rename OpenRa.Game/{ => Orders}/OrderManager.cs (94%) mode change 100755 => 100644 rename OpenRa.Game/{PlaceBuilding.cs => Orders/PlaceBuildingOrderGenerator.cs} (87%) rename OpenRa.Game/{ => Orders}/ReplayOrderSource.cs (92%) rename OpenRa.Game/{ => Orders}/UnitOrderGenerator.cs (91%) mode change 100755 => 100644 rename OpenRa.Game/{ => Orders}/UnitOrders.cs (93%) mode change 100755 => 100644 diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index a8dac419e0..47a395e019 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -2,13 +2,11 @@ using System.Collections.Generic; using System.Drawing; using System.Linq; -using System.Windows.Forms; -using IjwFramework.Collections; using IjwFramework.Types; -using OpenRa.Game.Graphics; -using OpenRa.Game.Support; using OpenRa.Game.GameRules; - +using OpenRa.Game.Graphics; +using OpenRa.Game.Orders; +using OpenRa.Game.Support; namespace OpenRa.Game { @@ -363,7 +361,7 @@ namespace OpenRa.Game if (producing.Done) { if (group == "Building" || group == "Defense") - Game.controller.orderGenerator = new PlaceBuilding(player.PlayerActor, item); + Game.controller.orderGenerator = new PlaceBuildingOrderGenerator(player.PlayerActor, item); return; } diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index 1ea516427e..875a0950b7 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -5,6 +5,7 @@ using IjwFramework.Collections; using IjwFramework.Types; using OpenRa.Game.GameRules; using OpenRa.Game.Graphics; +using OpenRa.Game.Orders; using OpenRa.Game.Traits; namespace OpenRa.Game @@ -62,7 +63,7 @@ namespace OpenRa.Game if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Down) { - if (!(orderGenerator is PlaceBuilding)) + if (!(orderGenerator is PlaceBuildingOrderGenerator)) dragStart = dragEnd = xy; ApplyOrders(xy, mi); } @@ -72,7 +73,7 @@ namespace OpenRa.Game if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { - if (!(orderGenerator is PlaceBuilding)) + if (!(orderGenerator is PlaceBuildingOrderGenerator)) { var newSelection = Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy); CombineSelection(newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy); diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 7be0cad8fd..e3a6cb490c 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -6,6 +6,7 @@ using System.Net.Sockets; using OpenRa.FileFormats; using OpenRa.Game.GameRules; using OpenRa.Game.Graphics; +using OpenRa.Game.Orders; using OpenRa.Game.Support; using OpenRa.Game.Traits; diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 185d03cc18..25a2d9b677 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -93,16 +93,16 @@ - - + + - - - + + + - + @@ -149,15 +149,15 @@ - - + + - + @@ -234,14 +234,14 @@ - + - + diff --git a/OpenRa.Game/IOrderGenerator.cs b/OpenRa.Game/Orders/IOrderGenerator.cs similarity index 100% rename from OpenRa.Game/IOrderGenerator.cs rename to OpenRa.Game/Orders/IOrderGenerator.cs diff --git a/OpenRa.Game/IOrderSource.cs b/OpenRa.Game/Orders/IOrderSource.cs similarity index 84% rename from OpenRa.Game/IOrderSource.cs rename to OpenRa.Game/Orders/IOrderSource.cs index 6fe8653969..2abd7fda74 100644 --- a/OpenRa.Game/IOrderSource.cs +++ b/OpenRa.Game/Orders/IOrderSource.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { interface IOrderSource { diff --git a/OpenRa.Game/LocalOrderSource.cs b/OpenRa.Game/Orders/LocalOrderSource.cs similarity index 91% rename from OpenRa.Game/LocalOrderSource.cs rename to OpenRa.Game/Orders/LocalOrderSource.cs index 2bee88f8cc..6dcb2b88e8 100644 --- a/OpenRa.Game/LocalOrderSource.cs +++ b/OpenRa.Game/Orders/LocalOrderSource.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { class LocalOrderSource : IOrderSource { diff --git a/OpenRa.Game/NetworkOrderSource.cs b/OpenRa.Game/Orders/NetworkOrderSource.cs similarity index 94% rename from OpenRa.Game/NetworkOrderSource.cs rename to OpenRa.Game/Orders/NetworkOrderSource.cs index 84fa81fc3a..6f279dfa6d 100644 --- a/OpenRa.Game/NetworkOrderSource.cs +++ b/OpenRa.Game/Orders/NetworkOrderSource.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Net.Sockets; using System.Threading; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { class NetworkOrderSource : IOrderSource { diff --git a/OpenRa.Game/Order.cs b/OpenRa.Game/Orders/Order.cs similarity index 100% rename from OpenRa.Game/Order.cs rename to OpenRa.Game/Orders/Order.cs diff --git a/OpenRa.Game/OrderIO.cs b/OpenRa.Game/Orders/OrderIO.cs similarity index 92% rename from OpenRa.Game/OrderIO.cs rename to OpenRa.Game/Orders/OrderIO.cs index dafc95aa31..c2940ddcf7 100644 --- a/OpenRa.Game/OrderIO.cs +++ b/OpenRa.Game/Orders/OrderIO.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.IO; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { static class OrderIO { diff --git a/OpenRa.Game/OrderManager.cs b/OpenRa.Game/Orders/OrderManager.cs old mode 100755 new mode 100644 similarity index 94% rename from OpenRa.Game/OrderManager.cs rename to OpenRa.Game/Orders/OrderManager.cs index 383fb98071..ee0b14a9c9 --- a/OpenRa.Game/OrderManager.cs +++ b/OpenRa.Game/Orders/OrderManager.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { class OrderManager { diff --git a/OpenRa.Game/PlaceBuilding.cs b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs similarity index 87% rename from OpenRa.Game/PlaceBuilding.cs rename to OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs index 3dbb3940d3..6408529c89 100644 --- a/OpenRa.Game/PlaceBuilding.cs +++ b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs @@ -1,14 +1,14 @@ using System.Collections.Generic; using OpenRa.Game.GameRules; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { - class PlaceBuilding : IOrderGenerator + class PlaceBuildingOrderGenerator : IOrderGenerator { readonly Actor Producer; readonly BuildingInfo Building; - public PlaceBuilding(Actor producer, string name) + public PlaceBuildingOrderGenerator(Actor producer, string name) { Producer = producer; Building = (BuildingInfo)Rules.UnitInfo[ name ]; diff --git a/OpenRa.Game/ReplayOrderSource.cs b/OpenRa.Game/Orders/ReplayOrderSource.cs similarity index 92% rename from OpenRa.Game/ReplayOrderSource.cs rename to OpenRa.Game/Orders/ReplayOrderSource.cs index 02485bbd9f..97d62cf8c6 100644 --- a/OpenRa.Game/ReplayOrderSource.cs +++ b/OpenRa.Game/Orders/ReplayOrderSource.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.IO; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { class ReplayOrderSource : IOrderSource { diff --git a/OpenRa.Game/UnitOrderGenerator.cs b/OpenRa.Game/Orders/UnitOrderGenerator.cs old mode 100755 new mode 100644 similarity index 91% rename from OpenRa.Game/UnitOrderGenerator.cs rename to OpenRa.Game/Orders/UnitOrderGenerator.cs index 8885899db3..91515eec3a --- a/OpenRa.Game/UnitOrderGenerator.cs +++ b/OpenRa.Game/Orders/UnitOrderGenerator.cs @@ -2,7 +2,7 @@ using System.Drawing; using System.Linq; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { class UnitOrderGenerator : IOrderGenerator { diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/Orders/UnitOrders.cs old mode 100755 new mode 100644 similarity index 93% rename from OpenRa.Game/UnitOrders.cs rename to OpenRa.Game/Orders/UnitOrders.cs index ec670e62a9..4a03e43ea0 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/Orders/UnitOrders.cs @@ -1,11 +1,9 @@ -using System; -using System.Drawing; -using System.Linq; +using System.Drawing; using OpenRa.Game.GameRules; -using OpenRa.Game.Traits; using OpenRa.Game.Graphics; +using OpenRa.Game.Traits; -namespace OpenRa.Game +namespace OpenRa.Game.Orders { static class UnitOrders { diff --git a/OpenRa.Game/Traits/RallyPoint.cs b/OpenRa.Game/Traits/RallyPoint.cs index acb2b8b63a..21edb5e0f1 100644 --- a/OpenRa.Game/Traits/RallyPoint.cs +++ b/OpenRa.Game/Traits/RallyPoint.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using OpenRa.Game.Graphics; +using OpenRa.Game.Orders; namespace OpenRa.Game.Traits { diff --git a/OpenRa.Game/Traits/RenderUnitRotor.cs b/OpenRa.Game/Traits/RenderUnitRotor.cs index 322345bc71..b2174a97c4 100755 --- a/OpenRa.Game/Traits/RenderUnitRotor.cs +++ b/OpenRa.Game/Traits/RenderUnitRotor.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using OpenRa.Game.Graphics; +using OpenRa.Game.Graphics; namespace OpenRa.Game.Traits { From 802e60b8472870d25b7f3b491a9417f5b33767ab Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:34:33 +1300 Subject: [PATCH 07/13] unhacking a hack --- OpenRa.Game/Controller.cs | 24 ++++++++++-- OpenRa.Game/MainWindow.cs | 1 + .../Orders/PlaceBuildingOrderGenerator.cs | 39 +++++++++++-------- 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index 875a0950b7..db21e2d006 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -19,6 +19,12 @@ namespace OpenRa.Game public Controller(Func getModifierKeys) { GetModifierKeys = getModifierKeys; + CancelInputMode(); + } + + public void CancelInputMode() + { + orderGenerator = new UnitOrderGenerator(new Actor[] { }); } List recentOrders = new List(); @@ -128,13 +134,22 @@ namespace OpenRa.Game public Cursor ChooseCursor() { var mods = GetModifierKeys(); - var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(), - new MouseInput { Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(), Button = MouseButton.Right, Modifiers = mods }) + + var mi = new MouseInput { + Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(), + Button = MouseButton.Right, + Modifiers = mods, + IsFake = true, + }; + + var c = orderGenerator.Order(dragEnd.ToInt2(), mi) .Where(o => o.Validate()) .Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation)) - .FirstOrDefault(a => a != null) : null; + .FirstOrDefault(a => a != null); - return c ?? (Game.SelectActorsInBox(Game.CellSize * dragEnd, Game.CellSize * dragEnd).Any() ? Cursor.Select : Cursor.Default); + return c ?? + (Game.SelectActorsInBox(Game.CellSize * dragEnd, Game.CellSize * dragEnd).Any() + ? Cursor.Select : Cursor.Default); } Cursor CursorForOrderString( string s, Actor a, int2 location ) @@ -166,6 +181,7 @@ namespace OpenRa.Game case "Infiltrate": return Cursor.Enter; case "Capture": return Cursor.Capture; case "Harvest": return Cursor.Attack; // TODO: special harvest cursor? + case "PlaceBuilding": return Cursor.Default; default: return null; } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index e49f0a60ba..dbd76aacf4 100755 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -173,6 +173,7 @@ namespace OpenRa.Game public int2 Location; public MouseButton Button; public Modifiers Modifiers; + public bool IsFake; } enum MouseInputEvent { Down, Move, Up }; diff --git a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs index 6408529c89..0741eae80a 100644 --- a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs @@ -16,33 +16,38 @@ namespace OpenRa.Game.Orders public IEnumerable Order(int2 xy, MouseInput mi) { - if( mi.Button == MouseButton.Left ) + if (mi.IsFake) { - if (!Game.CanPlaceBuilding(Building, xy, null, true)) - { - Sound.Play("nodeply1.aud"); - yield break; - } + // this order is never actually issued, but it's used for choosing a cursor + yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, null, xy, Building.Name); + yield break; + } - if (!Game.IsCloseEnoughToBase(Producer.Owner, Building, xy)) - { - Sound.Play("nodeply1.aud"); - yield break; - } + if (mi.Button == MouseButton.Left) + { + if (!Game.CanPlaceBuilding(Building, xy, null, true)) + { + Sound.Play("nodeply1.aud"); + yield break; + } + + if (!Game.IsCloseEnoughToBase(Producer.Owner, Building, xy)) + { + Sound.Play("nodeply1.aud"); + yield break; + } yield return new Order("PlaceBuilding", Producer.Owner.PlayerActor, null, xy, Building.Name); } - else // rmb - { - Game.world.AddFrameEndTask( _ => { Game.controller.orderGenerator = null; } ); - } + else + Game.controller.CancelInputMode(); } public void Tick() { var producing = Producer.traits.Get().CurrentItem( Rules.UnitCategory[ Building.Name ] ); - if( producing == null || producing.Item != Building.Name || producing.RemainingTime != 0 ) - Game.world.AddFrameEndTask( _ => { Game.controller.orderGenerator = null; } ); + if (producing == null || producing.Item != Building.Name || producing.RemainingTime != 0) + Game.controller.CancelInputMode(); } public void Render() From 97fdedac4faf969456df45fbde7bd01a564c8cb4 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:37:18 +1300 Subject: [PATCH 08/13] merge duplication in PlaceBuildingOrderGenerator --- OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs index 0741eae80a..43bf7be963 100644 --- a/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs +++ b/OpenRa.Game/Orders/PlaceBuildingOrderGenerator.cs @@ -25,13 +25,8 @@ namespace OpenRa.Game.Orders if (mi.Button == MouseButton.Left) { - if (!Game.CanPlaceBuilding(Building, xy, null, true)) - { - Sound.Play("nodeply1.aud"); - yield break; - } - - if (!Game.IsCloseEnoughToBase(Producer.Owner, Building, xy)) + if (!Game.CanPlaceBuilding(Building, xy, null, true) + || !Game.IsCloseEnoughToBase(Producer.Owner, Building, xy)) { Sound.Play("nodeply1.aud"); yield break; From 27e47cd0668b212a629ad67fc8b50e30a47646df Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:40:09 +1300 Subject: [PATCH 09/13] more wiring for selling --- OpenRa.Game/Controller.cs | 1 + OpenRa.Game/Cursor.cs | 1 + OpenRa.Game/Traits/Building.cs | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index db21e2d006..a7bc9f90d9 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -182,6 +182,7 @@ namespace OpenRa.Game case "Capture": return Cursor.Capture; case "Harvest": return Cursor.Attack; // TODO: special harvest cursor? case "PlaceBuilding": return Cursor.Default; + case "Sell": return Cursor.Sell; default: return null; } diff --git a/OpenRa.Game/Cursor.cs b/OpenRa.Game/Cursor.cs index b59bbf6d3d..7c9dd60770 100644 --- a/OpenRa.Game/Cursor.cs +++ b/OpenRa.Game/Cursor.cs @@ -26,5 +26,6 @@ namespace OpenRa.Game public static Cursor C4 { get { return new Cursor("c4"); } } public static Cursor Capture { get { return new Cursor("capture"); } } public static Cursor Heal { get { return new Cursor("heal"); } } + public static Cursor Sell { get { return new Cursor("sell"); } } } } diff --git a/OpenRa.Game/Traits/Building.cs b/OpenRa.Game/Traits/Building.cs index 63a1eda894..d102eb3c25 100644 --- a/OpenRa.Game/Traits/Building.cs +++ b/OpenRa.Game/Traits/Building.cs @@ -1,8 +1,9 @@ using OpenRa.Game.GameRules; +using OpenRa.Game.Traits.Activities; namespace OpenRa.Game.Traits { - class Building : INotifyDamage + class Building : INotifyDamage, IOrder { public readonly BuildingInfo unitInfo; @@ -18,5 +19,19 @@ namespace OpenRa.Game.Traits if (e.DamageState == DamageState.Dead) Sound.Play("kaboom22.aud"); } + + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + return null; // sell/repair orders are issued through Chrome, not here. + } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "Sell") + { + self.CancelActivity(); + self.QueueActivity(new Sell()); + } + } } } From 0737335663f3aa3d2643189106127d92bca35383 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:45:07 +1300 Subject: [PATCH 10/13] added SellOrderGenerator --- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Orders/SellOrderGenerator.cs | 37 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 OpenRa.Game/Orders/SellOrderGenerator.cs diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 25a2d9b677..ffad0fc90a 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -99,6 +99,7 @@ + diff --git a/OpenRa.Game/Orders/SellOrderGenerator.cs b/OpenRa.Game/Orders/SellOrderGenerator.cs new file mode 100644 index 0000000000..2d6c6274d5 --- /dev/null +++ b/OpenRa.Game/Orders/SellOrderGenerator.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using OpenRa.Game.GameRules; +using OpenRa.Game.Traits; + +namespace OpenRa.Game.Orders +{ + class SellOrderGenerator : IOrderGenerator + { + public IEnumerable Order(int2 xy, MouseInput mi) + { + var loc = mi.Location + Game.viewport.Location; + var underCursor = Game.FindUnits(loc, loc) + .Where( a => a.traits.Contains() ).FirstOrDefault(); + + if (underCursor != null && !underCursor.Info.Selectable) + underCursor = null; + + if (underCursor == null) + yield break; + + var building = underCursor.traits.Get(); + if (building.unitInfo.Unsellable) + yield break; + + if (underCursor.Owner != Game.LocalPlayer) + yield break; + + yield return new Order("Sell", underCursor, null, int2.Zero, null); + } + + public void Tick() {} + public void Render() {} + } +} From 43a8604ce9647c9fe3f739ffa3aeb6c48a70b5cd Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:50:45 +1300 Subject: [PATCH 11/13] hacked in selling to F3 --- OpenRa.Game/MainWindow.cs | 3 +++ OpenRa.Game/Orders/SellOrderGenerator.cs | 10 +++------- OpenRa.Game/Traits/Activities/Sell.cs | 4 ++++ OpenRa.Game/Traits/RenderBuilding.cs | 4 +++- OpenRa.Game/Traits/TraitsInterfaces.cs | 1 + 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index dbd76aacf4..665f3501a2 100755 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices; using System.Windows.Forms; using OpenRa.FileFormats; using OpenRa.Game.Graphics; +using OpenRa.Game.Orders; namespace OpenRa.Game { @@ -132,6 +133,8 @@ namespace OpenRa.Game /* temporary hack: DO NOT LEAVE IN */ if (e.KeyCode == Keys.F2) Game.LocalPlayer = Game.players[(Game.LocalPlayer.Index + 1) % 4]; + if (e.KeyCode == Keys.F3) + Game.controller.orderGenerator = new SellOrderGenerator(); if (!Game.chat.isChatting) if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) diff --git a/OpenRa.Game/Orders/SellOrderGenerator.cs b/OpenRa.Game/Orders/SellOrderGenerator.cs index 2d6c6274d5..2734438ce0 100644 --- a/OpenRa.Game/Orders/SellOrderGenerator.cs +++ b/OpenRa.Game/Orders/SellOrderGenerator.cs @@ -13,10 +13,9 @@ namespace OpenRa.Game.Orders { var loc = mi.Location + Game.viewport.Location; var underCursor = Game.FindUnits(loc, loc) - .Where( a => a.traits.Contains() ).FirstOrDefault(); - - if (underCursor != null && !underCursor.Info.Selectable) - underCursor = null; + .Where(a => a.Owner == Game.LocalPlayer + && a.traits.Contains() + && a.Info.Selectable).FirstOrDefault(); if (underCursor == null) yield break; @@ -25,9 +24,6 @@ namespace OpenRa.Game.Orders if (building.unitInfo.Unsellable) yield break; - if (underCursor.Owner != Game.LocalPlayer) - yield break; - yield return new Order("Sell", underCursor, null, int2.Zero, null); } diff --git a/OpenRa.Game/Traits/Activities/Sell.cs b/OpenRa.Game/Traits/Activities/Sell.cs index d0dac1d145..109d93785a 100644 --- a/OpenRa.Game/Traits/Activities/Sell.cs +++ b/OpenRa.Game/Traits/Activities/Sell.cs @@ -18,7 +18,11 @@ namespace OpenRa.Game.Traits.Activities self.Owner.GiveCash((int)refund); self.Health = 0; + foreach (var ns in self.traits.WithInterface()) + ns.Sold(self); Game.world.Remove(self); + + // todo: give dudes } public IActivity Tick(Actor self) diff --git a/OpenRa.Game/Traits/RenderBuilding.cs b/OpenRa.Game/Traits/RenderBuilding.cs index 24830e0a67..d5291d0b59 100644 --- a/OpenRa.Game/Traits/RenderBuilding.cs +++ b/OpenRa.Game/Traits/RenderBuilding.cs @@ -5,7 +5,7 @@ using OpenRa.Game.Effects; namespace OpenRa.Game.Traits { - class RenderBuilding : RenderSimple, INotifyDamage + class RenderBuilding : RenderSimple, INotifyDamage, INotifySold { const int SmallBibStart = 1; const int LargeBibStart = 5; @@ -88,5 +88,7 @@ namespace OpenRa.Game.Traits break; } } + + public void Sold(Actor self) { DoBib(self, true); } } } diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index 9485b850d2..e66744cb4e 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -13,6 +13,7 @@ namespace OpenRa.Game.Traits interface ITick { void Tick(Actor self); } interface IRender { IEnumerable Render(Actor self); } + interface INotifySold { void Sold(Actor self); } interface INotifyDamage { void Damaged(Actor self, AttackInfo e); } interface INotifyBuildComplete { void BuildingComplete (Actor self); } interface INotifyProduction { void UnitProduced(Actor self, Actor other); } From 5f78d3a3d00074689d265b719fd97cb84181fc55 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 12:57:02 +1300 Subject: [PATCH 12/13] missing pieces of selling --- OpenRa.Game/Controller.cs | 1 + OpenRa.Game/Cursor.cs | 1 + OpenRa.Game/Orders/SellOrderGenerator.cs | 15 +++++++++++---- sequences.xml | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index a7bc9f90d9..bb05c67fd0 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -183,6 +183,7 @@ namespace OpenRa.Game case "Harvest": return Cursor.Attack; // TODO: special harvest cursor? case "PlaceBuilding": return Cursor.Default; case "Sell": return Cursor.Sell; + case "NoSell": return Cursor.SellBlocked; default: return null; } diff --git a/OpenRa.Game/Cursor.cs b/OpenRa.Game/Cursor.cs index 7c9dd60770..9c3d5b0f28 100644 --- a/OpenRa.Game/Cursor.cs +++ b/OpenRa.Game/Cursor.cs @@ -27,5 +27,6 @@ namespace OpenRa.Game public static Cursor Capture { get { return new Cursor("capture"); } } public static Cursor Heal { get { return new Cursor("heal"); } } public static Cursor Sell { get { return new Cursor("sell"); } } + public static Cursor SellBlocked { get { return new Cursor("sell-blocked"); } } } } diff --git a/OpenRa.Game/Orders/SellOrderGenerator.cs b/OpenRa.Game/Orders/SellOrderGenerator.cs index 2734438ce0..aac3baf3b5 100644 --- a/OpenRa.Game/Orders/SellOrderGenerator.cs +++ b/OpenRa.Game/Orders/SellOrderGenerator.cs @@ -11,18 +11,25 @@ namespace OpenRa.Game.Orders { public IEnumerable Order(int2 xy, MouseInput mi) { + if (!mi.IsFake && mi.Button == MouseButton.Right) + { + Game.controller.CancelInputMode(); + yield break; + } + var loc = mi.Location + Game.viewport.Location; var underCursor = Game.FindUnits(loc, loc) .Where(a => a.Owner == Game.LocalPlayer && a.traits.Contains() && a.Info.Selectable).FirstOrDefault(); - if (underCursor == null) - yield break; + var building = underCursor != null ? underCursor.Info as BuildingInfo : null; - var building = underCursor.traits.Get(); - if (building.unitInfo.Unsellable) + if (building == null || building.Unsellable) + { + yield return new Order("NoSell", Game.LocalPlayer.PlayerActor, null, int2.Zero, null); yield break; + } yield return new Order("Sell", underCursor, null, int2.Zero, null); } diff --git a/sequences.xml b/sequences.xml index 9f438213cf..bc58377d4d 100644 --- a/sequences.xml +++ b/sequences.xml @@ -372,14 +372,14 @@ - + - + From d2be5085237ed29a806c8244da65eb6492dffc29 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sat, 2 Jan 2010 13:02:37 +1300 Subject: [PATCH 13/13] suppress selection logic in all custom input modes (sell, repair, place building,... ) --- OpenRa.Game/Controller.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index bb05c67fd0..b8ae8cf7f2 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -79,7 +79,7 @@ namespace OpenRa.Game if (mi.Button == MouseButton.Left && mi.Event == MouseInputEvent.Up) { - if (!(orderGenerator is PlaceBuildingOrderGenerator)) + if (orderGenerator is UnitOrderGenerator) { var newSelection = Game.SelectActorsInBox(Game.CellSize * dragStart, Game.CellSize * xy); CombineSelection(newSelection, mi.Modifiers.HasModifier(Modifiers.Shift), dragStart == xy);