From c6e97f7278b95767c5c606e7bd09a64ea17f65e3 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 11:30:12 +1300 Subject: [PATCH 1/9] logs of negative numbers -> fail --- OpenRa.Game/Combat.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRa.Game/Combat.cs b/OpenRa.Game/Combat.cs index 9d42af2457..87e30467e2 100644 --- a/OpenRa.Game/Combat.cs +++ b/OpenRa.Game/Combat.cs @@ -39,7 +39,7 @@ namespace OpenRa.Game static float GetMaximumSpread(WeaponInfo weapon, WarheadInfo warhead) { - return (int)(warhead.Spread * Math.Log(weapon.Damage, 2)); + return (int)(warhead.Spread * Math.Log(Math.Abs(weapon.Damage), 2)); } static float GetDamageToInflict(Actor target, int2 loc, WeaponInfo weapon, WarheadInfo warhead) From d7251e4703e6c9fd5a19caf0eb0630528bef4dd5 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 11:34:56 +1300 Subject: [PATCH 2/9] wtf. --- OpenRa.Game/Actor.cs | 1 - rules.ini | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 6e5f8987bc..daef776db9 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -50,7 +50,6 @@ namespace OpenRa.Game public void Tick() { - while (currentActivity != null) { var a = currentActivity; diff --git a/rules.ini b/rules.ini index ce3e93ff4e..80f49d6f47 100644 --- a/rules.ini +++ b/rules.ini @@ -2411,7 +2411,7 @@ InfDeath=5 ; special case to only affect infantry (do not use for regular weapons) [Organic] -Spread=0 +Spread=5 Verses=100%,0%,0%,0%,0% InfDeath=0 From 73864861e53f8814f57ddaf94dfcfb4d4c74cd1e Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 11:36:51 +1300 Subject: [PATCH 3/9] medic can't overheal anymore --- OpenRa.Game/Actor.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index daef776db9..781b65b96f 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -149,6 +149,8 @@ namespace OpenRa.Game Game.world.AddFrameEndTask(w => w.Remove(this)); } + if (Health > Info.Strength) + Health = Info.Strength; var newState = GetDamageState(); From d3767f2d99448db881dcb4328f2c28822a1d0203 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:08:56 +1300 Subject: [PATCH 4/9] non-turreted AutoTarget is sensible now --- OpenRa.Game/Actor.cs | 17 ++++++++--------- OpenRa.Game/Game.cs | 12 +++++++++--- OpenRa.Game/Graphics/WorldRenderer.cs | 2 +- OpenRa.Game/Traits/AutoTarget.cs | 11 +++++++++-- OpenRa.Game/Traits/RenderBuildingWarFactory.cs | 2 +- doc/progress.txt | 2 +- session.ini | 3 ++- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 781b65b96f..1091e3a71a 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -106,19 +106,18 @@ namespace OpenRa.Game .FirstOrDefault( x => x != null ); } - public RectangleF Bounds + public RectangleF GetBounds(bool useAltitude) { - get + var size = SelectedSize; + var loc = CenterLocation - 0.5f * size; + + if (useAltitude) { - var size = SelectedSize; - var loc = CenterLocation - 0.5f * size; var unit = traits.GetOrDefault(); - - if (unit != null) - loc -= new float2(0, unit.Altitude); - - return new RectangleF(loc.X, loc.Y, size.X, size.Y); + if (unit != null) loc -= new float2(0, unit.Altitude); } + + return new RectangleF(loc.X, loc.Y, size.X, size.Y); } public bool IsDead { get { return Health <= 0; } } diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index fc88c0922a..7be0cad8fd 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -269,13 +269,19 @@ namespace OpenRa.Game var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); return world.Actors - .Where(x => x.Bounds.IntersectsWith(rect)); + .Where(x => x.GetBounds(true).IntersectsWith(rect)); } public static IEnumerable FindUnitsInCircle(float2 a, float r) { - return FindUnits(a - new float2(r, r), a + new float2(r, r)) - .Where(x => (x.CenterLocation - a).LengthSquared < r * r); + var min = a - new float2(r, r); + var max = a + new float2(r, r); + + var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); + + var inBox = world.Actors.Where(x => x.GetBounds(false).IntersectsWith(rect)); + + return inBox.Where(x => (x.CenterLocation - a).LengthSquared < r * r); } public static IEnumerable FindTilesInCircle(int2 a, int r) diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index e155bbf7c4..65032fcacb 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -111,7 +111,7 @@ namespace OpenRa.Game.Graphics public void DrawSelectionBox(Actor selectedUnit, Color c, bool drawHealthBar) { - var bounds = selectedUnit.Bounds; + var bounds = selectedUnit.GetBounds(true); var xy = new float2(bounds.Left, bounds.Top); var Xy = new float2(bounds.Right, bounds.Top); diff --git a/OpenRa.Game/Traits/AutoTarget.cs b/OpenRa.Game/Traits/AutoTarget.cs index 77ad306377..2f84497eb5 100644 --- a/OpenRa.Game/Traits/AutoTarget.cs +++ b/OpenRa.Game/Traits/AutoTarget.cs @@ -16,16 +16,23 @@ namespace OpenRa.Game.Traits attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null)); } + float GetMaximumRange(Actor self) + { + return new[] { self.Info.Primary, self.Info.Secondary } + .Where(w => w != null) + .Max(w => Rules.WeaponInfo[w].Range); + } + public void Tick(Actor self) { if (!self.IsIdle) return; var attack = self.traits.WithInterface().First(); - var range = Rules.WeaponInfo[self.Info.Primary].Range; + var range = GetMaximumRange(self); if (attack.target == null || (attack.target.Location - self.Location).LengthSquared > range * range + 2) - attack.target = ChooseTarget(self, range); + AttackTarget(self, ChooseTarget(self, range)); } Actor ChooseTarget(Actor self, float range) diff --git a/OpenRa.Game/Traits/RenderBuildingWarFactory.cs b/OpenRa.Game/Traits/RenderBuildingWarFactory.cs index 40ccaf25e9..3b34f837d7 100644 --- a/OpenRa.Game/Traits/RenderBuildingWarFactory.cs +++ b/OpenRa.Game/Traits/RenderBuildingWarFactory.cs @@ -35,7 +35,7 @@ namespace OpenRa.Game.Traits { if (doneBuilding) roof.Tick(); - var b = self.Bounds; + var b = self.GetBounds(false); if (isOpen && !Game.UnitInfluence.GetUnitsAt(((1/24f) * self.CenterLocation).ToInt2()).Any()) { isOpen = false; diff --git a/doc/progress.txt b/doc/progress.txt index be4e61b168..6397443e03 100644 --- a/doc/progress.txt +++ b/doc/progress.txt @@ -8,7 +8,7 @@ E3 AA weapon doesn't work. E4 Flamer origin is wrong E6 Capture action missing, repair action missing E7 C4 action missing -MEDI Heal doesn't work +MEDI Heal targeting is wrong SPY Infiltrate action missing THF Steal action missing C1,C2,Einstein,Kosygin Not implemented diff --git a/session.ini b/session.ini index ac2d39b77d..520eedf061 100644 --- a/session.ini +++ b/session.ini @@ -6,5 +6,6 @@ [UNITS] s0=Multi0,mcv,600,2841,0,Guard,None s1=Multi2,mcv,600,12445,0,Guard,None -s2=Multi1,mcv,600,12505,0,Guard,None +;s2=Multi1,mcv,600,12505,0,Guard,None +s2=Multi1,e3,600,12505,0,Guard,None s3=Multi3,mcv,600,2910,0,Guard,None \ No newline at end of file From dad222ff1f58f3e73e970352b911d22f12e60b78 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:14:09 +1300 Subject: [PATCH 5/9] FTUR fixed --- doc/progress.txt | 3 +-- units.ini | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/progress.txt b/doc/progress.txt index 6397443e03..2159ddbf1d 100644 --- a/doc/progress.txt +++ b/doc/progress.txt @@ -4,7 +4,7 @@ Ground Units: All Infantry No idle animations E1 Range is wrong. E2 Grenades are too accurate. -E3 AA weapon doesn't work. +E3 Works E4 Flamer origin is wrong E6 Capture action missing, repair action missing E7 C4 action missing @@ -33,7 +33,6 @@ ARTY Works Helicopters - Weapons don't work, - hover while attacking doesn't work, - - render is broken (altitude) -- less broken, but there are Z-order issues. - Repair/rearm doesn't work TRAN Cargo doesn't work diff --git a/units.ini b/units.ini index 97d8bb6d1c..2644c3a949 100755 --- a/units.ini +++ b/units.ini @@ -248,7 +248,7 @@ InitialFacing=224 LongDesc=Anti-Air base defense.\n Strong vs Aircraft\n Weak vs Infantry, Tanks [FTUR] Description=Flame Turret -Traits=Building, RenderBuilding, AttackTurreted, AutoTarget +Traits=Turreted, Building, RenderBuilding, AttackTurreted, AutoTarget Dimensions=1,1 Footprint=x SelectionPriority=3 From 2d7abefc4976aa96e90c98b99a885f17989848e3 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:27:47 +1300 Subject: [PATCH 6/9] Multi1 needs his MCV back. --- session.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/session.ini b/session.ini index 520eedf061..e78029b52a 100644 --- a/session.ini +++ b/session.ini @@ -6,6 +6,6 @@ [UNITS] s0=Multi0,mcv,600,2841,0,Guard,None s1=Multi2,mcv,600,12445,0,Guard,None -;s2=Multi1,mcv,600,12505,0,Guard,None -s2=Multi1,e3,600,12505,0,Guard,None +s2=Multi1,mcv,600,12505,0,Guard,None +;s2=Multi1,e3,600,12505,0,Guard,None s3=Multi3,mcv,600,2910,0,Guard,None \ No newline at end of file From 77bb9494112c87d5bf97b42ab96b8e23e243af92 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:40:00 +1300 Subject: [PATCH 7/9] autoheal split from autotarget; it's fairly different. --- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Traits/AutoHeal.cs | 64 ++++++++++++++++++++++++++++++++++ units.ini | 2 +- 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 OpenRa.Game/Traits/AutoHeal.cs diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 3ea793d682..9540200910 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -172,6 +172,7 @@ + diff --git a/OpenRa.Game/Traits/AutoHeal.cs b/OpenRa.Game/Traits/AutoHeal.cs new file mode 100644 index 0000000000..2015140ccd --- /dev/null +++ b/OpenRa.Game/Traits/AutoHeal.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace OpenRa.Game.Traits +{ + class AutoHeal : ITick + { + public AutoHeal(Actor self) { } + + void AttackTarget(Actor self, Actor target) + { + var attack = self.traits.WithInterface().First(); + if (target != null) + attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null)); + } + + float GetMaximumRange(Actor self) + { + return new[] { self.Info.Primary, self.Info.Secondary } + .Where(w => w != null) + .Max(w => Rules.WeaponInfo[w].Range); + } + + bool NeedsNewTarget(Actor self) + { + var attack = self.traits.WithInterface().First(); + var range = GetMaximumRange(self); + + if (attack.target == null) + return true; // he's dead. + if ((attack.target.Location - self.Location).LengthSquared > range * range + 2) + return true; // wandered off faster than we could follow + if (attack.target.Health == attack.target.Info.Strength) + return true; // fully healed + + return false; + } + + public void Tick(Actor self) + { + if (!self.IsIdle) return; + + var attack = self.traits.WithInterface().First(); + var range = GetMaximumRange(self); + + if (NeedsNewTarget(self)) + AttackTarget(self, ChooseTarget(self, range)); + } + + Actor ChooseTarget(Actor self, float range) + { + var inRange = Game.FindUnitsInCircle(self.CenterLocation, Game.CellSize * range); + + return inRange + .Where(a => a.Owner == self.Owner) /* todo: one day deal with friendly players */ + .Where(a => Combat.HasAnyValidWeapons(self, a)) + .Where(a => a.Health < a.Info.Strength) + .OrderBy(a => (a.Location - self.Location).LengthSquared) + .FirstOrDefault(); + } + } +} diff --git a/units.ini b/units.ini index 2644c3a949..633e89a442 100755 --- a/units.ini +++ b/units.ini @@ -569,7 +569,7 @@ LongDesc=Elite commando infantry, armed with \ndual pistols and C4.\n Strong vs [MEDI] Description=Medic Voice=MedicVoice -Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry, AutoTarget +Traits=Unit, Mobile, RenderInfantry, AttackBase, TakeCover, Infantry, AutoHeal LongDesc=Heals nearby infantry.\n Strong vs Nothing\n Weak vs Everything From daaf9686b700d32036d7bcba86b4229bb5843497 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:43:23 +1300 Subject: [PATCH 8/9] oops --- OpenRa.Game/Traits/AutoHeal.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenRa.Game/Traits/AutoHeal.cs b/OpenRa.Game/Traits/AutoHeal.cs index 2015140ccd..5eb31d11ea 100644 --- a/OpenRa.Game/Traits/AutoHeal.cs +++ b/OpenRa.Game/Traits/AutoHeal.cs @@ -14,6 +14,8 @@ namespace OpenRa.Game.Traits var attack = self.traits.WithInterface().First(); if (target != null) attack.ResolveOrder(self, new Order("Attack", self, target, int2.Zero, null)); + else + self.CancelActivity(); } float GetMaximumRange(Actor self) @@ -40,8 +42,6 @@ namespace OpenRa.Game.Traits public void Tick(Actor self) { - if (!self.IsIdle) return; - var attack = self.traits.WithInterface().First(); var range = GetMaximumRange(self); From bf6c30e9ef1bd01badacdd8809f2b69a599e1c96 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 28 Dec 2009 12:54:43 +1300 Subject: [PATCH 9/9] air units are targetable --- OpenRa.Game/Actor.cs | 7 ++----- OpenRa.Game/Controller.cs | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 1091e3a71a..bf32437eaf 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -92,11 +92,8 @@ namespace OpenRa.Game if (!Rules.Map.IsInMap(xy.X, xy.Y)) return null; - // HACK: Get the first unit in the cell - // This will need to be updated for multiple-infantry-in-a-cell - // HACK: this doesn't work for targeting air units either - var underCursor = Game.UnitInfluence.GetUnitsAt( xy ).FirstOrDefault() - ?? Game.BuildingInfluence.GetBuildingAt( xy ); + var loc = mi.Location + Game.viewport.Location; + var underCursor = Game.FindUnits(loc, loc).FirstOrDefault(); if (underCursor != null && !underCursor.Info.Selectable) underCursor = null; diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index a1c0dc38a8..c51f7f6499 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -124,7 +124,7 @@ namespace OpenRa.Game { var mods = GetModifierKeys(); var c = (orderGenerator is UnitOrderGenerator) ? orderGenerator.Order(dragEnd.ToInt2(), - new MouseInput { Button = MouseButton.Right, Modifiers = mods }) + new MouseInput { Location = (Game.CellSize * dragEnd - Game.viewport.Location).ToInt2(), Button = MouseButton.Right, Modifiers = mods }) .Where(o => o.Validate()) .Select(o => CursorForOrderString(o.OrderString, o.Subject, o.TargetLocation)) .FirstOrDefault(a => a != null) : null;