From c8c4507acfbff88893b9120a48a35183dfc9ca26 Mon Sep 17 00:00:00 2001 From: earthpig Date: Tue, 1 May 2012 14:51:21 -0700 Subject: [PATCH 01/56] Few things with Zhukov AI. --- mods/ra/rules/system.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index e928d34cbf..49c8e92053 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -101,13 +101,13 @@ Player: HackyAI@ZhukovAI: Name:Zhukov AI BuildingFractions: - proc: 30% + proc: 20% powr: 35% tent: 1% barr: 1% weap: 1% - pbox: 7% - gun: 10% + pbox: 12% + gun: 12% ftur: 10% tsla: 5% dome: 10% @@ -117,16 +117,16 @@ Player: atek: 1% stek: 1% UnitsToBuild: - e1: 40% - e3: 10% + e1: 4% + e3: 1% harv: 10% ftrk: 5% v2rl: 40% arty: 40% - 1tnk: 20% - 2tnk: 20% - 3tnk: 20% - SquadSize: 30 + 1tnk: 15% + 2tnk: 15% + 3tnk: 15% + SquadSize: 25 HackyAI@RommelAI: Name:Rommel AI BuildingFractions: From d9992eea6a6f6c4dbc2321a61ecbd4a95f28a094 Mon Sep 17 00:00:00 2001 From: earthpig Date: Thu, 3 May 2012 21:45:00 -0700 Subject: [PATCH 02/56] cnc - Increase rocket launcher cost from 800 to 1200 to reflect changes in range. --- mods/cnc/rules/vehicles.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index fb4fe3cc89..bb0c581b95 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -384,7 +384,7 @@ HTNK: MSAM: Inherits: ^Tank Valued: - Cost: 800 + Cost: 1200 Tooltip: Name: Rocket Launcher Icon: msamicnh From 57283b4a80e8f834d986a5a3843098a28a215254 Mon Sep 17 00:00:00 2001 From: psydev Date: Wed, 2 May 2012 23:43:38 -0700 Subject: [PATCH 03/56] Increase range, cost and a modified damage on the MRLS (up vs. light armor, down vs. wood; 2 more bursts). Inaccuracy doubled from 30 to 60. Also increased MinRange from 2 to 4, and added burst delay while increasing rate of fire slightly (burst delay will add 24 to the rate of fire value, making it 70). Justification for these changes is to help fight against recon bike spam and stealth tank spam. Increase APC gun damage from 6 to 12 (is currently pathetic against helis) misc: Made Artillery shell explosion appear bigger Added contrail to Artillery shell --- mods/cnc/weapons.yaml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 407d61bb45..6dcaab9de3 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -530,18 +530,18 @@ MammothMissiles: Damage: 75 227mm: - ROF: 80 - Range: 10 - MinRange: 2 - Burst: 6 - BurstDelay: 1 + ROF: 45 + Range: 15 + MinRange: 4 + Burst: 8 + BurstDelay: 3 Report: ROCKET1 ValidTargets: Ground Projectile: Bullet Arm: 5 High: yes Shadow: yes - Inaccuracy: 30 + Inaccuracy: 60 Angle: 0.1 Image: DRAGON ROT: 5 @@ -551,8 +551,8 @@ MammothMissiles: Spread: 10 Versus: None: 30% - Wood: 75% - Light: 75% + Wood: 50% + Light: 100% Heavy: 50% InfDeath: 3 Explosion: 4 @@ -602,6 +602,7 @@ ArtilleryShell: High: yes Angle: .09 Inaccuracy: 30 + ContrailLength: 30 Image: 120MM Warhead: Damage: 150 @@ -612,7 +613,7 @@ ArtilleryShell: Light: 60% Heavy: 25% InfDeath: 2 - Explosion: 5 + Explosion: 8 SmudgeType: Crater ImpactSound: XPLOSML2 @@ -815,4 +816,4 @@ APCGun: Versus: Light: 100% Explosion: 5 - Damage: 6 \ No newline at end of file + Damage: 12 \ No newline at end of file From 8badbb3d6056d3b625bba65e643ee92e88238374 Mon Sep 17 00:00:00 2001 From: psydev Date: Wed, 2 May 2012 20:49:01 -0700 Subject: [PATCH 04/56] Re-ordering the build menu a bit. Seems like guard tower should go before gun turret since it's more basic, cheaper and more often used. --- mods/cnc/rules/structures.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 9f241ed85a..3dbc1aac1d 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -620,7 +620,7 @@ GUN: Description: Anti-Armor base defense.\n Strong vs Tanks\n Weak vs Infantry, Aircraft Buildable: Queue: Defense - BuildPaletteOrder: 40 + BuildPaletteOrder: 45 Prerequisites: barracks Owner: gdi,nod Building: @@ -692,7 +692,7 @@ GTWR: Description: Basic defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft Buildable: Queue: Defense - BuildPaletteOrder: 50 + BuildPaletteOrder: 40 Prerequisites: barracks Owner: gdi,nod Building: From c06fc0291576e8786181980980a8aeac7d9352d9 Mon Sep 17 00:00:00 2001 From: psydev Date: Wed, 2 May 2012 19:43:14 -0700 Subject: [PATCH 05/56] Changed production menu hotkeys from YUIOP to QWERT (what they are in C&C3). It's more ergonomic and close to the other command keys like A, S, Z, F. It is hard to use the YUIOP keys, because they're too far, even though they are very efficient. The QWERT setup is a good way to run a menu. I think should reserve them for that and use other keys for unit commands. --- mods/cnc/chrome/ingame.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index aad60f205c..6e25a16d36 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -197,7 +197,7 @@ Container@PLAYER_WIDGETS: ToggleButton@BUILDING: Width:30 Height:30 - Key: y + Key: q TooltipText: Buildings TooltipContainer:TOOLTIP_CONTAINER ClickSound:button.aud @@ -211,7 +211,7 @@ Container@PLAYER_WIDGETS: X:35 Width:30 Height:30 - Key: u + Key: w TooltipText: Defense TooltipContainer:TOOLTIP_CONTAINER ClickSound:button.aud @@ -225,7 +225,7 @@ Container@PLAYER_WIDGETS: X:70 Width:30 Height:30 - Key: i + Key: e TooltipText: Infantry TooltipContainer:TOOLTIP_CONTAINER ClickSound:button.aud @@ -239,7 +239,7 @@ Container@PLAYER_WIDGETS: X:105 Width:30 Height:30 - Key: o + Key: r TooltipText: Vehicles TooltipContainer:TOOLTIP_CONTAINER ClickSound:button.aud @@ -253,7 +253,7 @@ Container@PLAYER_WIDGETS: X:140 Width:30 Height:30 - Key: p + Key: t TooltipText: Aircraft TooltipContainer:TOOLTIP_CONTAINER ClickSound:button.aud From 0e43043a334cc40f3b0fbd6b679e3bff8f3eee92 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 6 May 2012 11:26:53 +1200 Subject: [PATCH 06/56] cnc: fix crash loading yaml for ArtilleryShell.ContrailLength --- mods/cnc/weapons.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mods/cnc/weapons.yaml b/mods/cnc/weapons.yaml index 6dcaab9de3..a7e222c044 100644 --- a/mods/cnc/weapons.yaml +++ b/mods/cnc/weapons.yaml @@ -597,7 +597,6 @@ ArtilleryShell: MinRange: 2 Report: TNKFIRE2 Projectile: Bullet - ContrailLength: 30 Speed: 12 High: yes Angle: .09 @@ -816,4 +815,4 @@ APCGun: Versus: Light: 100% Explosion: 5 - Damage: 12 \ No newline at end of file + Damage: 12 From 79afa07118f7914ffb5044230f4f6a2f45e68d1d Mon Sep 17 00:00:00 2001 From: psydev Date: Fri, 4 May 2012 16:09:44 -0700 Subject: [PATCH 07/56] cnc - made helicopter selection bounds a bit smaller --- mods/cnc/rules/aircraft.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/cnc/rules/aircraft.yaml b/mods/cnc/rules/aircraft.yaml index 0c94089d89..1298bfc45a 100644 --- a/mods/cnc/rules/aircraft.yaml +++ b/mods/cnc/rules/aircraft.yaml @@ -11,6 +11,8 @@ TRAN: Prerequisites: hpad BuiltAt: hpad Owner: gdi,nod + Selectable: + Bounds: 41,41 Helicopter: LandWhenIdle: true ROT: 5 @@ -49,6 +51,8 @@ HELI: Prerequisites: hpad, hq BuiltAt: hpad Owner: nod + Selectable: + Bounds: 30,24 Helicopter: ROT: 4 Speed: 20 @@ -93,6 +97,8 @@ ORCA: Prerequisites: hpad, hq BuiltAt: hpad Owner: gdi + Selectable: + Bounds: 30,24 Helicopter: ROT: 4 Speed: 20 From 6291c8396be4b33d9433442ca7de1ff34e4fb834 Mon Sep 17 00:00:00 2001 From: psydev Date: Fri, 4 May 2012 15:11:59 -0700 Subject: [PATCH 08/56] cnc - add new explosion: chemball --- mods/cnc/sequences/misc.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/cnc/sequences/misc.yaml b/mods/cnc/sequences/misc.yaml index be7448f41c..272df55451 100644 --- a/mods/cnc/sequences/misc.yaml +++ b/mods/cnc/sequences/misc.yaml @@ -94,6 +94,10 @@ explosion: 6w: atomsfx Start: 0 Length: * + chemball: chemball + Start: 0 + Length: * + rank: rank: Start: 0 From 6c96a106e77458c1c5bbee4b9cdf3b4b814f4b17 Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Sat, 5 May 2012 11:27:03 +0200 Subject: [PATCH 09/56] Red Alert CashTicks Three options for cash ticks: Extreme: current behavoir (every cash countdown tick is heard) Normal: RedAlert countdown style (only one cash countdown tick every ~1 or 2 seconds) Disabled: No cash tickdown or tickup is heard. Thanks to Tirili for hints on the settings system. --- OpenRA.Game/GameRules/Settings.cs | 7 ++-- OpenRA.Game/Traits/Player/PlayerResources.cs | 34 ++++++++++++++++--- .../Widgets/Logic/SettingsMenuLogic.cs | 30 ++++++++++++++++ mods/ra/chrome/settings.yaml | 11 ++++++ 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index 4bbc9cdb19..1c1bf93213 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -19,6 +19,9 @@ using OpenRA.Server; namespace OpenRA.GameRules { + public enum MouseScrollType { Disabled, Standard, Inverted } + public enum SoundCashTicks { Disabled, Normal, Extreme } + public class ServerSettings { public string Name = "OpenRA Game"; @@ -77,6 +80,8 @@ namespace OpenRA.GameRules public bool Repeat = false; public bool ShellmapMusic = true; public string Engine = "AL"; + + public SoundCashTicks SoundCashTickType = SoundCashTicks.Extreme; } public class PlayerSettings @@ -86,8 +91,6 @@ namespace OpenRA.GameRules public string LastServer = "localhost:1234"; } - public enum MouseScrollType { Disabled, Standard, Inverted } - public class GameSettings { public string[] Mods = { "ra" }; diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index 4aa24f15ea..ec01cf9531 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -10,6 +10,7 @@ using System; using System.Linq; +using OpenRA.GameRules; namespace OpenRA.Traits { @@ -62,6 +63,8 @@ namespace OpenRA.Traits { readonly Player Owner; int AdviceInterval; + + int tickermod = 0; public PlayerResources(Actor self, PlayerResourcesInfo info) { @@ -134,7 +137,8 @@ namespace OpenRA.Traits public void Tick(Actor self) { var eva = self.World.WorldActor.Info.Traits.Get(); - + tickermod = (tickermod + 1) % 3; + OreCapacity = self.World.ActorsWithTrait() .Where(a => a.Actor.Owner == Owner) .Sum(a => a.Trait.Capacity); @@ -158,12 +162,12 @@ namespace OpenRA.Traits if (DisplayCash < Cash) { DisplayCash += move; - Sound.PlayToPlayer(self.Owner, eva.CashTickUp); + playCashTickUp(self); } else if (DisplayCash > Cash) { DisplayCash -= move; - Sound.PlayToPlayer(self.Owner, eva.CashTickDown); + playCashTickDown(self); } diff = Math.Abs(Ore - DisplayOre); @@ -173,13 +177,35 @@ namespace OpenRA.Traits if (DisplayOre < Ore) { DisplayOre += move; - Sound.PlayToPlayer(self.Owner, eva.CashTickUp); + playCashTickUp(self); } else if (DisplayOre > Ore) { DisplayOre -= move; + playCashTickDown(self); + } + } + + + public void playCashTickUp(Actor self) + { + var eva = self.World.WorldActor.Info.Traits.Get(); + if (Game.Settings.Sound.SoundCashTickType != SoundCashTicks.Disabled) + { + Sound.PlayToPlayer(self.Owner, eva.CashTickUp); + } + } + + public void playCashTickDown(Actor self) + { + var eva = self.World.WorldActor.Info.Traits.Get(); + if ( + Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme || + (Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && tickermod == 0) + ) { Sound.PlayToPlayer(self.Owner, eva.CashTickDown); } + } } } diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs index 89eff81fb6..74cf654580 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs @@ -71,6 +71,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic // Audio var audio = bg.Get("AUDIO_PANE"); + var soundSettings = Game.Settings.Sound; var soundslider = audio.Get("SOUND_VOLUME"); soundslider.OnChange += x => Sound.SoundVolume = x; @@ -80,6 +81,12 @@ namespace OpenRA.Mods.RA.Widgets.Logic musicslider.OnChange += x => Sound.MusicVolume = x; musicslider.Value = Sound.MusicVolume; + var cashticksdropdown = audio.Get("CASH_TICK_TYPE"); + cashticksdropdown.OnMouseDown = _ => ShowSoundTickDropdown(cashticksdropdown, soundSettings); + cashticksdropdown.GetText = () => soundSettings.SoundCashTickType == SoundCashTicks.Extreme ? + "Extreme" : soundSettings.SoundCashTickType == SoundCashTicks.Normal ? "Normal" : "Disabled"; + + // Display var display = bg.Get("DISPLAY_PANE"); var gs = Game.Settings.Graphics; @@ -138,6 +145,29 @@ namespace OpenRA.Mods.RA.Widgets.Logic return true; } + + public static bool ShowSoundTickDropdown(DropDownButtonWidget dropdown, SoundSettings audio) + { + var options = new Dictionary() + { + { "Extreme", SoundCashTicks.Extreme }, + { "Normal", SoundCashTicks.Normal }, + { "Disabled", SoundCashTicks.Disabled }, + }; + + Func setupItem = (o, itemTemplate) => + { + var item = ScrollItemWidget.Setup(itemTemplate, + () => audio.SoundCashTickType == options[o], + () => audio.SoundCashTickType = options[o]); + item.Get("LABEL").GetText = () => o; + return item; + }; + + dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); + return true; + } + public static bool ShowWindowModeDropdown(DropDownButtonWidget dropdown, GraphicSettings s) { var options = new Dictionary() diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index 0b122a18c3..f31aa1ae9a 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -136,6 +136,17 @@ Background@SETTINGS_MENU: Width:250 Height:20 Ticks:5 + Label@SOUND_TICK_TYPE_LABEL: + X:0 + Y:70 + Text: Cash ticks + DropDownButton@CASH_TICK_TYPE: + X:100 + Y:60 + Width:250 + Height:20 + Font:Regular + Text:Extreme Container@DISPLAY_PANE: X:37 Y:100 From 8a08365666f083f06f543aa3693ff162fa62067c Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Sun, 6 May 2012 12:37:16 +0200 Subject: [PATCH 10/56] Fixed bug in cash ticks, normal settings. No sound was heared when repairing buildings or on low power. Fixed. --- OpenRA.Game/Traits/Player/PlayerResources.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenRA.Game/Traits/Player/PlayerResources.cs b/OpenRA.Game/Traits/Player/PlayerResources.cs index ec01cf9531..c5af6d6362 100644 --- a/OpenRA.Game/Traits/Player/PlayerResources.cs +++ b/OpenRA.Game/Traits/Player/PlayerResources.cs @@ -64,7 +64,7 @@ namespace OpenRA.Traits readonly Player Owner; int AdviceInterval; - int tickermod = 0; + int cashtickallowed = 0; public PlayerResources(Actor self, PlayerResourcesInfo info) { @@ -137,7 +137,10 @@ namespace OpenRA.Traits public void Tick(Actor self) { var eva = self.World.WorldActor.Info.Traits.Get(); - tickermod = (tickermod + 1) % 3; + + if(cashtickallowed > 0) { + cashtickallowed = cashtickallowed - 1; + } OreCapacity = self.World.ActorsWithTrait() .Where(a => a.Actor.Owner == Owner) @@ -201,9 +204,10 @@ namespace OpenRA.Traits var eva = self.World.WorldActor.Info.Traits.Get(); if ( Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Extreme || - (Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && tickermod == 0) + (Game.Settings.Sound.SoundCashTickType == SoundCashTicks.Normal && cashtickallowed == 0) ) { Sound.PlayToPlayer(self.Owner, eva.CashTickDown); + cashtickallowed = 3; } } From 3058bfbc17e2c7259af2157ff2375ac0dfe96234 Mon Sep 17 00:00:00 2001 From: psydev Date: Fri, 4 May 2012 14:29:43 -0700 Subject: [PATCH 11/56] cnc - updated several building hitpoints --- mods/cnc/rules/structures.yaml | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/mods/cnc/rules/structures.yaml b/mods/cnc/rules/structures.yaml index 3dbc1aac1d..5029ed6479 100644 --- a/mods/cnc/rules/structures.yaml +++ b/mods/cnc/rules/structures.yaml @@ -12,7 +12,9 @@ FACT: Footprint: xxx xxx Dimensions: 3,2 Health: - HP: 1750 + HP: 2000 + Armor: + Type: Heavy RevealsShroud: Range: 10 Bib: @@ -240,7 +242,7 @@ AFLD: Footprint: xxxx xxxx Dimensions: 4,2 Health: - HP: 1000 + HP: 1750 RevealsShroud: Range: 7 Bib: @@ -282,7 +284,7 @@ WEAP: Footprint: ___ xxx === Dimensions: 3,3 Health: - HP: 1000 + HP: 1750 RevealsShroud: Range: 4 Bib: @@ -362,7 +364,7 @@ NUK2: Footprint: xx xx Dimensions: 2,2 Health: - HP: 600 + HP: 650 RevealsShroud: Range: 4 Bib: @@ -409,7 +411,7 @@ HPAD: Footprint: xx xx Dimensions: 2,2 Health: - HP: 800 + HP: 400 RevealsShroud: Range: 5 Exit@1: @@ -561,7 +563,7 @@ CYCL: Prerequisites: fact Owner: nod Health: - HP: 300 + HP: 100 Armor: Type: Light @@ -581,7 +583,7 @@ SBAG: Prerequisites: fact Owner: gdi Health: - HP: 250 + HP: 100 Armor: Type: Light @@ -601,7 +603,7 @@ BRIK: Prerequisites: vehicleproduction Owner: gdi,nod Health: - HP: 1000 + HP: 250 Armor: Type: Heavy Wall: @@ -678,7 +680,6 @@ SAM: PrimaryWeapon: SAMMissile WithMuzzleFlash: AutoTarget: - -AutoTargetIgnore: -RenderBuilding: RenderRangeCircle: From 881b4ba2776b1e2afd753287ee31f34841f30e0a Mon Sep 17 00:00:00 2001 From: psydev Date: Fri, 4 May 2012 16:31:10 -0700 Subject: [PATCH 12/56] cnc - changed various unit speeds; gave increased sight to MCV and MSAM. --- mods/cnc/rules/vehicles.yaml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index bb0c581b95..fbe53765f9 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -19,7 +19,7 @@ MCV: Armor: Type: Light RevealsShroud: - Range: 4 + Range: 8 Transforms: IntoActor: fact Offset:-1,-1 @@ -84,7 +84,7 @@ APC: Owner: gdi Mobile: ROT: 5 - Speed: 11 + Speed: 10 Health: HP: 200 Armor: @@ -186,7 +186,7 @@ BGGY: Owner: nod Mobile: ROT: 10 - Speed: 12 + Speed: 16 Health: HP: 140 Armor: @@ -218,7 +218,14 @@ BIKE: Owner: nod Mobile: ROT: 10 - Speed: 13 + Speed: 20 + TerrainSpeeds: + Clear: 42 + Rough: 25 + Road: 100 + Tiberium: 25 + BlueTiberium: 25 + Beach: 25 Health: HP: 120 Armor: @@ -248,7 +255,7 @@ JEEP: Owner: gdi Mobile: ROT: 10 - Speed: 10 + Speed: 14 Health: HP: 150 Armor: @@ -314,7 +321,7 @@ MTNK: Prerequisites: hq Owner: gdi Mobile: - Speed: 9 + Speed: 7 Health: HP: 400 Armor: @@ -400,7 +407,7 @@ MSAM: Armor: Type: Light RevealsShroud: - Range: 6 + Range: 10 Turreted: ROT: 255 AttackFrontal: From b99e6647265c852ce5374c417732259a1fd4063e Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Thu, 10 May 2012 19:54:57 +0200 Subject: [PATCH 13/56] A Game-tick can execute viewport.Tick itself, removed this dependency from World. --- OpenRA.Game/Game.cs | 2 ++ OpenRA.Game/World.cs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index deed94a085..4df9808aa5 100755 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -188,6 +188,8 @@ namespace OpenRA else if (orderManager.NetFrameNumber == 0) orderManager.LastTickTime = Environment.TickCount; + + viewport.Tick(); } } } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index e2ec53704c..e4c6dc4b50 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -183,7 +183,7 @@ namespace OpenRA while (frameEndActions.Count != 0) frameEndActions.Dequeue()(this); - Game.viewport.Tick(); + } public IEnumerable Actors { get { return actors; } } From a07697be035330bb1bec9ebaff2d00e4e399e8b4 Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 16 May 2012 17:35:10 +0200 Subject: [PATCH 14/56] Pause the game option. Game is paused when PAUSE on the keyboard has been hit. It can also be unpaused this way. --- OpenRA.Game/Game.cs | 2 +- OpenRA.Game/Network/Order.cs | 11 +++++++++++ OpenRA.Game/Network/OrderManager.cs | 1 + OpenRA.Game/Network/UnitOrders.cs | 6 ++++++ OpenRA.Game/Server/Server.cs | 17 +++++++++++++---- .../Widgets/WorldInteractionControllerWidget.cs | 4 ++++ 6 files changed, 36 insertions(+), 5 deletions(-) diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index 4df9808aa5..41638ce1b4 100755 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -166,7 +166,7 @@ namespace OpenRA { var isNetTick = LocalTick % NetTickScale == 0; - if (!isNetTick || orderManager.IsReadyForNextFrame) + if ((!isNetTick || orderManager.IsReadyForNextFrame) && !orderManager.GamePaused ) { ++orderManager.LocalFrameNumber; diff --git a/OpenRA.Game/Network/Order.cs b/OpenRA.Game/Network/Order.cs index b81a9f2731..7f2bb449b7 100755 --- a/OpenRA.Game/Network/Order.cs +++ b/OpenRA.Game/Network/Order.cs @@ -199,7 +199,18 @@ namespace OpenRA { return new Order("HandshakeResponse", null, false) { IsImmediate = true, TargetString = text }; } + + public static Order PauseRequest() + { + return new Order("PauseRequest", null, false) { IsImmediate = true, TargetString="" }; //TODO: targetbool? + } + + public static Order PauseGame() + { + return new Order("PauseGame", null, false) { IsImmediate = true, TargetString=""}; //TODO: targetbool? + } + public static Order Command(string text) { return new Order("Command", null, false) { IsImmediate = true, TargetString = text }; diff --git a/OpenRA.Game/Network/OrderManager.cs b/OpenRA.Game/Network/OrderManager.cs index 708caf08fd..8d16467ad1 100755 --- a/OpenRA.Game/Network/OrderManager.cs +++ b/OpenRA.Game/Network/OrderManager.cs @@ -36,6 +36,7 @@ namespace OpenRA.Network public int LastTickTime = Environment.TickCount; public bool GameStarted { get { return NetFrameNumber != 0; } } + public bool GamePaused {get; set;} public IConnection Connection { get; private set; } public readonly int SyncHeaderSize = 9; diff --git a/OpenRA.Game/Network/UnitOrders.cs b/OpenRA.Game/Network/UnitOrders.cs index 92f3fb3e93..36c18f1eab 100755 --- a/OpenRA.Game/Network/UnitOrders.cs +++ b/OpenRA.Game/Network/UnitOrders.cs @@ -94,6 +94,12 @@ namespace OpenRA.Network Game.StartGame(orderManager.LobbyInfo.GlobalSettings.Map, false); break; } + + case "PauseGame": + { + orderManager.GamePaused = !orderManager.GamePaused; + break; + } case "HandshakeRequest": { diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index e50101bb5b..c5cd929119 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -332,6 +332,9 @@ namespace OpenRA.Server void InterpretServerOrder(Connection conn, ServerOrder so) { + var fromClient = GetClient(conn); + var fromIndex = fromClient != null ? fromClient.Index : 0; + switch (so.Name) { case "Command": @@ -347,17 +350,23 @@ namespace OpenRA.Server } break; + case "HandshakeResponse": ValidateClient(conn, so.Data); break; + case "Chat": case "TeamChat": - var fromClient = GetClient(conn); - var fromIndex = fromClient != null ? fromClient.Index : 0; - foreach (var c in conns.Except(conn).ToArray()) DispatchOrdersToClient(c, fromIndex, 0, so.Serialize()); - break; + break; + + case "PauseRequest": + foreach (var c in conns.ToArray()) + { var x = Order.PauseGame(); + DispatchOrdersToClient(c, fromIndex, 0, x.Serialize()); + } + break; } } diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index accef80e75..bcdc813434 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -148,6 +148,10 @@ namespace OpenRA.Widgets world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers); return true; } + else if(e.KeyName == "pause") + { + world.IssueOrder(Order.PauseRequest()); + } bool handled = false; From 7e1986ecbcbf9395e645e29b39f3da097f3e62ba Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 16 May 2012 19:04:43 +0200 Subject: [PATCH 15/56] Timer shows text "(paused)" when game is in pause. --- OpenRA.Game/Widgets/TimerWidget.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/OpenRA.Game/Widgets/TimerWidget.cs b/OpenRA.Game/Widgets/TimerWidget.cs index 420352d896..d0b7e419be 100644 --- a/OpenRA.Game/Widgets/TimerWidget.cs +++ b/OpenRA.Game/Widgets/TimerWidget.cs @@ -16,12 +16,18 @@ namespace OpenRA.Widgets { public override void Draw() { - var s = WidgetUtils.FormatTime(Game.LocalTick); var font = Game.Renderer.Fonts["Title"]; var rb = RenderBounds; + + var s = WidgetUtils.FormatTime(Game.LocalTick); var pos = new float2(rb.Left - font.Measure(s).X / 2, rb.Top); + var s_paused = (Game.orderManager.GamePaused ? "\n (paused)" : ""); + var pos_paused = new float2(rb.Left - font.Measure(s_paused).X / 2, rb.Top+1); + font.DrawTextWithContrast(s, pos, Color.White, Color.Black, 1); + font.DrawTextWithContrast(s_paused, pos_paused, Color.White, Color.Black, 1); + } } } From ae94d7ecc7603e8388c761a0836c446ba39a0330 Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 16 May 2012 19:11:46 +0200 Subject: [PATCH 16/56] Chat-text displayed when the game is paused and unpaused. : The game is (un-)paused by --- OpenRA.Game/Network/UnitOrders.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/OpenRA.Game/Network/UnitOrders.cs b/OpenRA.Game/Network/UnitOrders.cs index 36c18f1eab..7c7a844f61 100755 --- a/OpenRA.Game/Network/UnitOrders.cs +++ b/OpenRA.Game/Network/UnitOrders.cs @@ -96,8 +96,21 @@ namespace OpenRA.Network } case "PauseGame": - { - orderManager.GamePaused = !orderManager.GamePaused; + { + if(clientId != null) + { + var client = orderManager.LobbyInfo.ClientWithIndex(clientId); + + orderManager.GamePaused = !orderManager.GamePaused; + if(orderManager.GamePaused) + { + Game.AddChatLine(Color.White, "", "The game is paused by "+client.Name); + } + else + { + Game.AddChatLine(Color.White, "", "The game is un-paused by "+client.Name); + } + } break; } From bc7aa9a491deeedbea027e76680aab786eab9af4 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Thu, 17 May 2012 10:04:06 +1200 Subject: [PATCH 17/56] make Health.MaxHP not readonly; some people want to frob it at runtime --- OpenRA.Game/Traits/Health.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Game/Traits/Health.cs b/OpenRA.Game/Traits/Health.cs index 432157094c..3016aece4b 100755 --- a/OpenRA.Game/Traits/Health.cs +++ b/OpenRA.Game/Traits/Health.cs @@ -41,7 +41,7 @@ namespace OpenRA.Traits } public int HP { get { return hp; } } - public readonly int MaxHP; + public int MaxHP; public bool IsDead { get { return hp <= 0; } } public bool RemoveOnDeath = true; From d1241c438a668232e0b26b6deb9427054035372d Mon Sep 17 00:00:00 2001 From: psydev Date: Wed, 16 May 2012 08:50:37 -0700 Subject: [PATCH 18/56] Helicopters targetable when landed --- mods/cnc/rules/defaults.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/cnc/rules/defaults.yaml b/mods/cnc/rules/defaults.yaml index 34971a1c73..87dc0be720 100644 --- a/mods/cnc/rules/defaults.yaml +++ b/mods/cnc/rules/defaults.yaml @@ -69,8 +69,9 @@ ^Helicopter: AppearsOnRadar: UseLocation: yes - TargetableUnit: + TargetableAircraft: TargetTypes: Air + GroundedTargetTypes: Ground SelectionDecorations: Selectable: Voice: VehicleVoice From 8c218b67ab0f3d5763d7cf3a50d1c1e7cd4224b1 Mon Sep 17 00:00:00 2001 From: earthpig Date: Thu, 3 May 2012 23:09:09 -0700 Subject: [PATCH 19/56] Bring back hbox, with both the new garrison stuff and with stealth until firing. --- mods/ra/rules/structures.yaml | 138 ++++++++++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 16 deletions(-) diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml index 5e2af0a339..8a9ba07358 100644 --- a/mods/ra/rules/structures.yaml +++ b/mods/ra/rules/structures.yaml @@ -497,36 +497,142 @@ PBOX.SHOK: HBOX: Inherits: ^Building -# Buildable: -# Queue: Defense -# BuildPaletteOrder: 30 -# Prerequisites: tent -# Owner: allies -# Hotkey: c - Valued: - Cost: 600 Tooltip: - Name: Camo Pillbox - Description: Hidden defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft + Name: Camo Pillbox (Unarmed) Building: Power: -15 -GivesBuildableArea: + Valued: + Cost: 600 Health: HP: 600 Armor: Type: Wood RevealsShroud: Range: 6 + Cloak: + InitialDelay: 125 + CloakDelay: 60 + CloakSound: appear1.aud + UncloakSound: appear1.aud + IronCurtainable: + -AcceptsSupplies: + Turreted: + ROT: 255 + Cargo: + Types: Infantry + MaxWeight: 1 + PipCount: 1 + -EmitInfantryOnSell: +# EmitCargoOnSell: + TransformOnPassenger@e1: + PassengerTypes: e1 + OnEnter: HBOX.e1 + OnExit: HBOX + SkipMakeAnims: true +# TransformOnPassenger@e2: +# PassengerTypes: e2 +# OnEnter: HBOX.e2 +# OnExit: HBOX +# SkipMakeAnims: true + TransformOnPassenger@e3: + PassengerTypes: e3 + OnEnter: HBOX.e3 + OnExit: HBOX + SkipMakeAnims: true + TransformOnPassenger@e4: + PassengerTypes: e4 + OnEnter: HBOX.e4 + OnExit: HBOX + SkipMakeAnims: true + TransformOnPassenger@e7: + PassengerTypes: e7 + OnEnter: HBOX.e7 + OnExit: HBOX + SkipMakeAnims: true + TransformOnPassenger@SHOK: + PassengerTypes: shok + OnEnter: HBOX.shok + OnExit: HBOX + SkipMakeAnims: true + +HBOX.E1: + Inherits: HBOX + Buildable: + Queue: Defense + BuildPaletteOrder: 20 + Prerequisites: tent + Owner: allies + Hotkey: p + Tooltip: + Name: Camo Pillbox (Guns) + Description: Hidden defensive structure.\n Strong vs Infantry, Light Vehicles\n Weak vs Tanks, Aircraft + Icon: HBOXICON + RenderBuilding: + Image: HBOX + RenderRangeCircle: + AutoTarget: AttackTurreted: PrimaryWeapon: Vulcan PrimaryLocalOffset: 0,-11,0,0,0 - AutoTarget: - IronCurtainable: - RenderRangeCircle: - -AcceptsSupplies: WithMuzzleFlash: - Turreted: - ROT: 255 + Cargo: + InitialUnits: e1 + +#HBOX.E2: +# Inherits: HBOX +# Tooltip: +# Name: Camo Pillbox (Grenades) +# RenderBuilding: +# Image: HBOX + +HBOX.E3: + Inherits: HBOX + Tooltip: + Name: Camo Pillbox (Rockets) + RenderBuilding: + Image: HBOX + RenderRangeCircle: + AutoTarget: + AttackTurreted: + PrimaryWeapon: Dragon + PrimaryLocalOffset: 0,-11,0,0,0 + +HBOX.E4: + Inherits: HBOX + Tooltip: + Name: Camo Pillbox (Flamethrower) + RenderBuilding: + Image: HBOX + RenderRangeCircle: + AutoTarget: + AttackTurreted: + PrimaryWeapon: Flamer + PrimaryLocalOffset: 0,-11,0,0,0 + +HBOX.E7: + Inherits: HBOX + Tooltip: + Name: Camo Pillbox (Tanya) + RenderBuilding: + Image: HBOX + RenderRangeCircle: + AutoTarget: + AttackTurreted: + PrimaryWeapon: Colt45 + PrimaryLocalOffset: 0,-11,0,0,0 + +HBOX.SHOK: + Inherits: HBOX + Tooltip: + Name: Camo Pillbox (Tesla) + RenderBuilding: + Image: HBOX + RenderRangeCircle: + AutoTarget: + AttackTurreted: + PrimaryWeapon: PortaTesla + PrimaryLocalOffset: 0,-11,0,0,0 GUN: Inherits: ^Building From f0001856bc7ab5ee204c7f4c36f3e34f821a6221 Mon Sep 17 00:00:00 2001 From: earthpig Date: Fri, 4 May 2012 23:48:28 -0700 Subject: [PATCH 20/56] To go along with introducing the 'cloaked hbox', ensure that the cloak is disabled if at low power. --- OpenRA.Mods.RA/Cloak.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenRA.Mods.RA/Cloak.cs b/OpenRA.Mods.RA/Cloak.cs index 038d20e55f..8002adee7f 100644 --- a/OpenRA.Mods.RA/Cloak.cs +++ b/OpenRA.Mods.RA/Cloak.cs @@ -81,6 +81,8 @@ namespace OpenRA.Mods.RA if (remainingTime > 0 && canCloak) if (--remainingTime <= 0) Sound.Play(info.CloakSound, self.CenterLocation); + if (self.IsDisabled()) + Uncloak(); } public bool IsVisible(Actor self) From 059347af40cc24a01bcfc4eda49d16f2f195be40 Mon Sep 17 00:00:00 2001 From: earthpig Date: Fri, 4 May 2012 13:33:14 -0700 Subject: [PATCH 21/56] bots (once again) build pillboxes. --- mods/ra/rules/system.yaml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 49c8e92053..4d9c2d18c3 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -47,7 +47,7 @@ Player: barr: 1% tent: 1% weap: 1% - pbox: 7% + pbox.e1: 7% gun: 7% tsla: 5% ftur: 10% @@ -77,7 +77,7 @@ Player: tent: 1% barr: 1% weap: 1% - pbox: 7% + pbox.e1: 7% gun: 7% ftur: 10% tsla: 5% @@ -106,8 +106,9 @@ Player: tent: 1% barr: 1% weap: 1% - pbox: 12% - gun: 12% + pbox.e1: 4% + hbox.e1: 3% + gun: 10% ftur: 10% tsla: 5% dome: 10% @@ -135,7 +136,7 @@ Player: tent: 1% barr: 1% weap: 1% - pbox: 7% + pbox.e1: 7% gun: 7% ftur: 10% tsla: 5% From c0006409281660cf36525aabff557784862da928 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 17:42:19 +1200 Subject: [PATCH 22/56] remove dead function from LobbyLogic --- OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs index 2cb45a5bab..03d8ef28e2 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/LobbyLogic.cs @@ -435,8 +435,6 @@ namespace OpenRA.Mods.RA.Widgets.Logic } } - bool SpawnPointAvailable(int index) { return (index == 0) || orderManager.LobbyInfo.Clients.All(c => c.SpawnPoint != index); } - void CycleReady() { orderManager.IssueOrder(Order.Command("ready")); From 6f8f940f3165e3da2e94cfcbc67fe15c82205650 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 18:05:04 +1200 Subject: [PATCH 23/56] #2130 fixed -- #comments can be used at the end of any lines --- OpenRA.FileFormats/MiniYaml.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenRA.FileFormats/MiniYaml.cs b/OpenRA.FileFormats/MiniYaml.cs index 1807c05f77..1962bcfbce 100755 --- a/OpenRA.FileFormats/MiniYaml.cs +++ b/OpenRA.FileFormats/MiniYaml.cs @@ -105,11 +105,14 @@ namespace OpenRA.FileFormats levels.Add(new List()); var lineNo = 0; - foreach (var line in lines) + foreach (var ll in lines) { + var line = ll; ++lineNo; + if (line.Contains('#')) + line = line.Substring(0, line.IndexOf('#')).TrimEnd(' ', '\t'); var t = line.TrimStart(' ', '\t'); - if (t.Length == 0 || t[0] == '#') + if (t.Length == 0) continue; var level = line.Length - t.Length; var location = new MiniYamlNode.SourceLocation { Filename = filename, Line = lineNo }; From c068be453a9bcb7bc1fdd5874dc1296b6f4810d0 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 18:17:03 +1200 Subject: [PATCH 24/56] #2119 fixed - better error message for multiple definitions of the same yaml field --- OpenRA.FileFormats/FieldLoader.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/OpenRA.FileFormats/FieldLoader.cs b/OpenRA.FileFormats/FieldLoader.cs index a61990b5b3..d06fab6252 100755 --- a/OpenRA.FileFormats/FieldLoader.cs +++ b/OpenRA.FileFormats/FieldLoader.cs @@ -56,6 +56,11 @@ namespace OpenRA.FileFormats ret = GetValue( fieldName, fieldType, n[ 0 ].Value.Value ); return true; } + else if ( n.Count > 1 ) + { + throw new InvalidOperationException("The field {0} has multiple definitions:\n{1}" + .F(fieldName, n.Select(m => "\t- " + m.Location).JoinWith("\n"))); + } throw new InvalidOperationException( "TryGetValueFromYaml: unable to load field {0} (of type {1})".F( fieldName, fieldType ) ); } From 3b704e25fa859dcd383a3057bd39af49280d1d63 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:01:49 +1200 Subject: [PATCH 25/56] #2159 fixed -- missiles lose guidance and run out their remaining fuel if the target dies --- OpenRA.Mods.RA/Effects/Missile.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OpenRA.Mods.RA/Effects/Missile.cs b/OpenRA.Mods.RA/Effects/Missile.cs index 5d69008d73..d7df87b0ce 100755 --- a/OpenRA.Mods.RA/Effects/Missile.cs +++ b/OpenRA.Mods.RA/Effects/Missile.cs @@ -99,13 +99,14 @@ namespace OpenRA.Mods.RA.Effects Altitude += Math.Sign(targetAltitude - Altitude); - Facing = Traits.Util.TickFacing(Facing, - Traits.Util.GetFacing(dist, Facing), - Info.ROT); + if (Args.target.IsValid) + Facing = Traits.Util.TickFacing(Facing, + Traits.Util.GetFacing(dist, Facing), + Info.ROT); anim.Tick(); - if (dist.LengthSquared < MissileCloseEnough * MissileCloseEnough || !Args.target.IsValid ) + if (dist.LengthSquared < MissileCloseEnough * MissileCloseEnough && Args.target.IsValid ) Explode(world); // TODO: Replace this with a lookup table From 2d39b1dfac52a75c0c3c4e58dd5fa8518da36b82 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:13:23 +1200 Subject: [PATCH 26/56] #2089 fixed - Explodes filtering on InfDeath --- OpenRA.Mods.RA/Explodes.cs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.RA/Explodes.cs b/OpenRA.Mods.RA/Explodes.cs index 7d64a67aa2..8d23da8c3f 100644 --- a/OpenRA.Mods.RA/Explodes.cs +++ b/OpenRA.Mods.RA/Explodes.cs @@ -13,7 +13,7 @@ using OpenRA.Traits; namespace OpenRA.Mods.RA { - class ExplodesInfo : TraitInfo + class ExplodesInfo : ITraitInfo { [WeaponReference] public readonly string Weapon = "UnitExplode"; @@ -21,13 +21,23 @@ namespace OpenRA.Mods.RA public readonly string EmptyWeapon = "UnitExplode"; public readonly int Chance = 100; + public readonly int[] InfDeath = null; + + public object Create (ActorInitializer init) { return new Explodes(this); } } class Explodes : INotifyKilled { + readonly ExplodesInfo Info; + + public Explodes( ExplodesInfo info ) { Info = info; } + public void Killed(Actor self, AttackInfo e) { - if (self.World.SharedRandom.Next(100) > self.Info.Traits.Get().Chance) + if (self.World.SharedRandom.Next(100) > Info.Chance) + return; + + if (Info.InfDeath != null && e.Warhead != null && !Info.InfDeath.Contains(e.Warhead.InfDeath)) return; var weapon = ChooseWeaponForExplosion(self); @@ -42,9 +52,7 @@ namespace OpenRA.Mods.RA string ChooseWeaponForExplosion(Actor self) { var shouldExplode = self.TraitsImplementing().All(a => a.ShouldExplode(self)); - - var info = self.Info.Traits.Get(); - return shouldExplode ? info.Weapon : info.EmptyWeapon; + return shouldExplode ? Info.Weapon : Info.EmptyWeapon; } } } From 442138e1f81930debc713a691980bbfefa86080c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:18:28 +1200 Subject: [PATCH 27/56] clean up spurious trait lookup in RenderCargo --- OpenRA.Mods.Cnc/RenderCargo.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.Cnc/RenderCargo.cs b/OpenRA.Mods.Cnc/RenderCargo.cs index ee5b9f926a..8a7a29009a 100644 --- a/OpenRA.Mods.Cnc/RenderCargo.cs +++ b/OpenRA.Mods.Cnc/RenderCargo.cs @@ -36,9 +36,12 @@ namespace OpenRA.Mods.Cnc foreach (var c in cargo.Passengers) { c.Trait().SetPxPosition( c, self.Trait().PxPosition ); - if (facing != null && c.HasTrait()) - c.Trait().Facing = facing.Facing; + + var cargoFacing = c.TraitOrDefault(); + if (facing != null && cargoFacing != null) + cargoFacing.Facing = facing.Facing; } + return r.Concat(cargo.Passengers.SelectMany(a => a.Render())); } } From 3fbb81b4fc223e6223c6e1f3c78771227d6b3be5 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:19:49 +1200 Subject: [PATCH 28/56] remove more spurious trait lookups in RenderCargo --- OpenRA.Mods.Cnc/RenderCargo.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Cnc/RenderCargo.cs b/OpenRA.Mods.Cnc/RenderCargo.cs index 8a7a29009a..874c73edfc 100644 --- a/OpenRA.Mods.Cnc/RenderCargo.cs +++ b/OpenRA.Mods.Cnc/RenderCargo.cs @@ -24,18 +24,20 @@ namespace OpenRA.Mods.Cnc { Cargo cargo; IFacing facing; + IHasLocation location; public RenderCargo(Actor self) { cargo = self.Trait(); facing = self.TraitOrDefault(); + location = self.Trait(); } public IEnumerable ModifyRender(Actor self, IEnumerable r) { foreach (var c in cargo.Passengers) { - c.Trait().SetPxPosition( c, self.Trait().PxPosition ); + c.Trait().SetPxPosition( c, location.PxPosition ); var cargoFacing = c.TraitOrDefault(); if (facing != null && cargoFacing != null) From e9656795a20c3b77ff0cedd804c3db0e749e50c5 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:22:22 +1200 Subject: [PATCH 29/56] RenderCargo depends on IMove on the containing actor --- OpenRA.Mods.Cnc/RenderCargo.cs | 6 +++--- OpenRA.Mods.RA/Crate.cs | 9 +++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/OpenRA.Mods.Cnc/RenderCargo.cs b/OpenRA.Mods.Cnc/RenderCargo.cs index 874c73edfc..d621ab4bc9 100644 --- a/OpenRA.Mods.Cnc/RenderCargo.cs +++ b/OpenRA.Mods.Cnc/RenderCargo.cs @@ -24,20 +24,20 @@ namespace OpenRA.Mods.Cnc { Cargo cargo; IFacing facing; - IHasLocation location; + IMove move; public RenderCargo(Actor self) { cargo = self.Trait(); facing = self.TraitOrDefault(); - location = self.Trait(); + move = self.Trait(); } public IEnumerable ModifyRender(Actor self, IEnumerable r) { foreach (var c in cargo.Passengers) { - c.Trait().SetPxPosition( c, location.PxPosition ); + c.Trait().SetPxPosition( c, move.PxPosition ); var cargoFacing = c.TraitOrDefault(); if (facing != null && cargoFacing != null) diff --git a/OpenRA.Mods.RA/Crate.cs b/OpenRA.Mods.RA/Crate.cs index 53f33a8fdd..5324a12287 100644 --- a/OpenRA.Mods.RA/Crate.cs +++ b/OpenRA.Mods.RA/Crate.cs @@ -38,13 +38,10 @@ namespace OpenRA.Mods.RA class Crate : ITick, IOccupySpace, ITeleportable, ICrushable, ISync { readonly Actor self; - [Sync] - int ticks; - - [Sync] - public int2 Location; - + [Sync] int ticks; + [Sync] public int2 Location; CrateInfo Info; + public Crate(ActorInitializer init, CrateInfo info) { this.self = init.self; From ff32864b47f2f30e18a3d6d3d1e90fb0682fd331 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 22 May 2012 19:42:51 +1200 Subject: [PATCH 30/56] #2160 fixed - RenderCargo support for relative altitude --- OpenRA.Mods.Cnc/RenderCargo.cs | 15 +++++++++++---- OpenRA.Mods.RA/Render/WithShadow.cs | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/OpenRA.Mods.Cnc/RenderCargo.cs b/OpenRA.Mods.Cnc/RenderCargo.cs index d621ab4bc9..fa38c27d09 100644 --- a/OpenRA.Mods.Cnc/RenderCargo.cs +++ b/OpenRA.Mods.Cnc/RenderCargo.cs @@ -15,9 +15,12 @@ using OpenRA.Traits; namespace OpenRA.Mods.Cnc { - class RenderCargoInfo : ITraitInfo, Requires + public class RenderCargoInfo : ITraitInfo, Requires { - public object Create(ActorInitializer init) { return new RenderCargo(init.self); } + /* altitude of the cargo, relative to us. -ve is underneath us */ + public readonly int RelativeAltitude = 0; + + public object Create(ActorInitializer init) { return new RenderCargo(init.self, this); } } public class RenderCargo : IRenderModifier @@ -25,12 +28,14 @@ namespace OpenRA.Mods.Cnc Cargo cargo; IFacing facing; IMove move; + RenderCargoInfo Info; - public RenderCargo(Actor self) + public RenderCargo(Actor self, RenderCargoInfo info) { cargo = self.Trait(); facing = self.TraitOrDefault(); move = self.Trait(); + Info = info; } public IEnumerable ModifyRender(Actor self, IEnumerable r) @@ -44,7 +49,9 @@ namespace OpenRA.Mods.Cnc cargoFacing.Facing = facing.Facing; } - return r.Concat(cargo.Passengers.SelectMany(a => a.Render())); + return r.Concat(cargo.Passengers.SelectMany(a => a.Render()) + .Select(a => a.WithPos(a.Pos - new float2(0, Info.RelativeAltitude)) + .WithZOffset(a.ZOffset + Info.RelativeAltitude))); } } } \ No newline at end of file diff --git a/OpenRA.Mods.RA/Render/WithShadow.cs b/OpenRA.Mods.RA/Render/WithShadow.cs index a69fb29839..c07a047dba 100644 --- a/OpenRA.Mods.RA/Render/WithShadow.cs +++ b/OpenRA.Mods.RA/Render/WithShadow.cs @@ -30,7 +30,7 @@ namespace OpenRA.Mods.RA.Render var shadowSprites = r.Select(a => a.WithPalette("shadow")); var flyingSprites = (move.Altitude <= 0) ? r - : r.Select(a => a.WithPos(a.Pos - new float2(0, move.Altitude + visualOffset)).WithZOffset(move.Altitude)); + : r.Select(a => a.WithPos(a.Pos - new float2(0, move.Altitude + visualOffset)).WithZOffset(move.Altitude + a.ZOffset)); return shadowSprites.Concat(flyingSprites); } From 5dd46b1b1616abfb1d0f2233e238855fa06eae27 Mon Sep 17 00:00:00 2001 From: psydev Date: Tue, 22 May 2012 03:26:01 -0700 Subject: [PATCH 31/56] Give Mammoth 8-sec. cooldown for heal, like in RA. --- mods/cnc/rules/vehicles.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/cnc/rules/vehicles.yaml b/mods/cnc/rules/vehicles.yaml index fbe53765f9..703ff87418 100644 --- a/mods/cnc/rules/vehicles.yaml +++ b/mods/cnc/rules/vehicles.yaml @@ -380,6 +380,8 @@ HTNK: AutoTarget: SelfHealing: Ticks: 10 + HealIfBelow: 50% + DamageCooldown: 200 LeavesHusk: HuskActor: HTNK.Husk Explodes: From e1907364e6b16209c93c9465924cdb526812390a Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Tue, 1 May 2012 21:01:40 -0600 Subject: [PATCH 32/56] Fix #2086 - don't let player capture if that same player (or friendly ally) is already capturing --- OpenRA.Mods.RA/Activities/CaptureActor.cs | 7 ++++- OpenRA.Mods.RA/Capturable.cs | 18 +++++++------ OpenRA.Mods.RA/Captures.cs | 31 ++++++++++++++++++----- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/OpenRA.Mods.RA/Activities/CaptureActor.cs b/OpenRA.Mods.RA/Activities/CaptureActor.cs index 5b82ff672f..dd22a4f412 100644 --- a/OpenRA.Mods.RA/Activities/CaptureActor.cs +++ b/OpenRA.Mods.RA/Activities/CaptureActor.cs @@ -28,8 +28,13 @@ namespace OpenRA.Mods.RA.Activities if( !target.OccupiesSpace.OccupiedCells().Any( x => x.First == self.Location ) ) return NextActivity; + var capturable = target.TraitOrDefault(); + if (capturable != null && capturable.CaptureInProgress && capturable.Captor.Owner.Stances[self.Owner] == Stance.Ally) + return NextActivity; + var sellable = target.TraitOrDefault(); - if (sellable != null && sellable.Selling) return NextActivity; + if (sellable != null && sellable.Selling) + return NextActivity; target.Trait().BeginCapture(target, self); self.World.AddFrameEndTask(w => self.Destroy()); diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index 2680f2b98b..04091911d3 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -27,9 +27,9 @@ namespace OpenRA.Mods.RA public class Capturable : ITick { - [Sync] Actor captor = null; + [Sync] public Actor Captor = null; [Sync] public int CaptureProgressTime = 0; - public bool CaptureInProgress { get { return captor != null; } } + public bool CaptureInProgress { get { return Captor != null; } } public CapturableInfo Info; public Capturable(CapturableInfo info) @@ -41,10 +41,12 @@ namespace OpenRA.Mods.RA { CaptureProgressTime = 0; - this.captor = captor; + this.Captor = captor; if (self.Owner != self.World.WorldActor.Owner) + { self.ChangeOwner(self.World.WorldActor.Owner); + } } public void Tick(Actor self) @@ -57,15 +59,15 @@ namespace OpenRA.Mods.RA { self.World.AddFrameEndTask(w => { - self.ChangeOwner(captor.Owner); + self.ChangeOwner(Captor.Owner); foreach (var t in self.TraitsImplementing()) - t.OnCapture(self, captor, self.Owner, captor.Owner); + 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); + foreach (var t in Captor.World.ActorsWithTrait()) + t.Trait.OnActorCaptured(t.Actor, self, Captor, self.Owner, Captor.Owner); - captor = null; + Captor = null; }); } } diff --git a/OpenRA.Mods.RA/Captures.cs b/OpenRA.Mods.RA/Captures.cs index f7baa8e191..375a840a88 100644 --- a/OpenRA.Mods.RA/Captures.cs +++ b/OpenRA.Mods.RA/Captures.cs @@ -8,6 +8,7 @@ */ #endregion +using System; using System.Collections.Generic; using System.Drawing; using System.Linq; @@ -21,14 +22,17 @@ namespace OpenRA.Mods.RA class CapturesInfo : ITraitInfo { public string[] CaptureTypes = {"building"}; - public object Create(ActorInitializer init) { return new Captures(this); } + public object Create(ActorInitializer init) { return new Captures(init.self, this); } } class Captures : IIssueOrder, IResolveOrder, IOrderVoice { public readonly CapturesInfo Info; - public Captures(CapturesInfo info) + readonly Actor self; + + public Captures(Actor self, CapturesInfo info) { + this.self = self; Info = info; } @@ -36,7 +40,7 @@ namespace OpenRA.Mods.RA { get { - yield return new CaptureOrderTargeter(Info.CaptureTypes); + yield return new CaptureOrderTargeter(Info.CaptureTypes, target => CanEnter(target)); } } @@ -50,13 +54,16 @@ namespace OpenRA.Mods.RA public string VoicePhraseForOrder(Actor self, Order order) { - return (order.OrderString == "CaptureActor") ? "Attack" : null; + return (order.OrderString == "CaptureActor" + && CanEnter(order.TargetActor)) ? "Attack" : null; } public void ResolveOrder(Actor self, Order order) { if (order.OrderString == "CaptureActor") { + if (!CanEnter(order.TargetActor)) return; + self.SetTargetLine(Target.FromOrder(order), Color.Red); self.CancelActivity(); @@ -64,15 +71,24 @@ namespace OpenRA.Mods.RA self.QueueActivity(new CaptureActor(order.TargetActor)); } } + + bool CanEnter(Actor target) + { + var c = target.TraitOrDefault(); + return c != null && ( !c.CaptureInProgress || c.Captor.Owner.Stances[self.Owner] != Stance.Ally ); + } } class CaptureOrderTargeter : UnitTraitOrderTargeter { readonly string[] captureTypes; - public CaptureOrderTargeter(string[] captureTypes) - : base( "CaptureActor", 6, "enter", true, true ) + readonly Func useEnterCursor; + + public CaptureOrderTargeter(string[] captureTypes, Func useEnterCursor) + : base( "CaptureActor", 6, "enter", true, true) { this.captureTypes = captureTypes; + this.useEnterCursor = useEnterCursor; } public override bool CanTargetActor(Actor self, Actor target, bool forceAttack, bool forceQueued, ref string cursor) @@ -87,9 +103,10 @@ namespace OpenRA.Mods.RA if( playerRelationship == Stance.Neutral && !ci.AllowNeutral ) return false; IsQueued = forceQueued; + if (captureTypes.Contains(ci.Type)) { - cursor = "enter"; + cursor = useEnterCursor(target) ? "enter" : "enter-blocked"; return true; } From 37f91542a9e7fe4fbf8bb453213fca08a2e2578c Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Wed, 2 May 2012 11:25:38 -0600 Subject: [PATCH 33/56] Change cargo ownership when capturing actors with cargo --- OpenRA.Mods.RA/Capturable.cs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.RA/Capturable.cs b/OpenRA.Mods.RA/Capturable.cs index 04091911d3..3fa232ae55 100644 --- a/OpenRA.Mods.RA/Capturable.cs +++ b/OpenRA.Mods.RA/Capturable.cs @@ -44,9 +44,7 @@ namespace OpenRA.Mods.RA this.Captor = captor; if (self.Owner != self.World.WorldActor.Owner) - { self.ChangeOwner(self.World.WorldActor.Owner); - } } public void Tick(Actor self) @@ -60,6 +58,7 @@ namespace OpenRA.Mods.RA self.World.AddFrameEndTask(w => { self.ChangeOwner(Captor.Owner); + ChangeCargoOwner(self, Captor.Owner); foreach (var t in self.TraitsImplementing()) t.OnCapture(self, Captor, self.Owner, Captor.Owner); @@ -71,5 +70,15 @@ namespace OpenRA.Mods.RA }); } } + + void ChangeCargoOwner(Actor self, Player captor) + { + var cargo = self.TraitOrDefault(); + if (cargo == null) + return; + + foreach (var c in cargo.Passengers) + c.Owner = captor; + } } } From 4778ef803e50f612a556ca9abd8f8bff6430a6ea Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Wed, 2 May 2012 11:40:10 -0600 Subject: [PATCH 34/56] Spy - don't reset exploration if team has GPS --- OpenRA.Mods.RA/InfiltrateForExploration.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenRA.Mods.RA/InfiltrateForExploration.cs b/OpenRA.Mods.RA/InfiltrateForExploration.cs index bf153f6438..d0ccefbe66 100644 --- a/OpenRA.Mods.RA/InfiltrateForExploration.cs +++ b/OpenRA.Mods.RA/InfiltrateForExploration.cs @@ -25,7 +25,13 @@ namespace OpenRA.Mods.RA * - actually steal their exploration before resetting it */ if (self.World.LocalPlayer != null && self.World.LocalPlayer.Stances[self.Owner] == Stance.Ally) + { + var gpsWatcher = self.Owner.PlayerActor.TraitOrDefault(); + if (gpsWatcher != null && (gpsWatcher.Granted || gpsWatcher.GrantedAllies)) + return; + self.Owner.Shroud.ResetExploration(); + } } } } From 8df09da8166c5ff232da34db3e6741a12a60cc14 Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Wed, 2 May 2012 11:52:10 -0600 Subject: [PATCH 35/56] Spy - add voice when sending infiltrate order --- OpenRA.Mods.RA/Spy.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.RA/Spy.cs b/OpenRA.Mods.RA/Spy.cs index a06a0ab21a..407685eb3f 100644 --- a/OpenRA.Mods.RA/Spy.cs +++ b/OpenRA.Mods.RA/Spy.cs @@ -121,7 +121,8 @@ namespace OpenRA.Mods.RA public string VoicePhraseForOrder(Actor self, Order order) { - return order.OrderString == "Disguise" ? "Attack" : null; + return (order.OrderString == "Disguise" + || order.OrderString == "SpyInfiltrate") ? "Attack" : null; } public Color RadarColorOverride(Actor self) From bd29d382c7a60e9898ffce3d956b9ec7232f1cc1 Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Wed, 2 May 2012 13:01:22 -0600 Subject: [PATCH 36/56] fix #2080 - added option to toggle shellmap in CNC --- .../Widgets/Logic/CncSettingsLogic.cs | 4 +++ mods/cnc/chrome/settings.yaml | 29 ++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs index e71efe4de0..a4f30f8705 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs @@ -86,6 +86,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic Game.viewport.Zoom = graphicsSettings.PixelDouble ? 2 : 1; }; + var showShellmapCheckbox = generalPane.Get("SHOW_SHELLMAP"); + showShellmapCheckbox.IsChecked = () => gameSettings.ShowShellmap; + showShellmapCheckbox.OnClick = () => gameSettings.ShowShellmap ^= true; + generalPane.Get("WINDOW_RESOLUTION").IsVisible = () => graphicsSettings.Mode == WindowMode.Windowed; var windowWidth = generalPane.Get("WINDOW_WIDTH"); windowWidth.Text = graphicsSettings.WindowedSize.X.ToString(); diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index 469b2cdbbc..7ce9ba4fe3 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -14,7 +14,7 @@ Container@SETTINGS_PANEL: Text:Settings Background@GENERAL_CONTROLS: Width:740 - Height:250 + Height:290 Background:panel-black Children: Label@TITLE: @@ -142,49 +142,56 @@ Container@SETTINGS_PANEL: Height:20 Font:Regular Text:Enable Pixel Doubling + Checkbox@SHOW_SHELLMAP: + X:375 + Y:120 + Width:200 + Height:20 + Font:Regular + Text:Show Shellmap Label@AUDIO_TITLE: X:375 - Y:130 + Y:160 Width:340 Font:Bold Text:Sound Align:Center Label@SOUND_LABEL: X:375 - Y:145 + Y:175 Width:95 Height:25 Align:Right Text:Sound Volume: Slider@SOUND_SLIDER: X:475 - Y:150 + Y:180 Width:240 Height:20 Ticks:5 Label@MUSIC_LABEL: X:375 - Y:175 + Y:205 Width:95 Height:25 Align:Right Text:Music Volume: Slider@MUSIC_SLIDER: X:475 - Y:180 + Y:210 Width:240 Height:20 Ticks:5 Checkbox@SHELLMAP_MUSIC: X:375 - Y:210 + Y:240 Width:200 Height:20 Font:Regular Text:Shellmap Music Background@INPUT_CONTROLS: Width:740 - Height:250 + Height:290 Background:panel-black Visible:false Children: @@ -260,20 +267,20 @@ Container@SETTINGS_PANEL: Font:Regular Text:Shift-Enter Toggles Team Chat Button@GENERAL_BUTTON: - Y:249 + Y:289 Width:140 Height:35 Text:General Button@INPUT_BUTTON: X:150 - Y:249 + Y:289 Width:140 Height:35 Text:Input Button@BACK_BUTTON: Key:escape X:600 - Y:249 + Y:289 Width:140 Height:35 Text:Back From 1bb1e00a0d4e48c0663e23598ab193cb790c0d5c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 5 Jun 2012 19:41:30 +1200 Subject: [PATCH 37/56] fix #2195 - barrels should not be capturable or sellable --- mods/ra/rules/civilian.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/mods/ra/rules/civilian.yaml b/mods/ra/rules/civilian.yaml index 77e7de79b8..b660f6b7b2 100644 --- a/mods/ra/rules/civilian.yaml +++ b/mods/ra/rules/civilian.yaml @@ -89,11 +89,9 @@ V18: Inherits: ^CivField BARL: - Inherits: ^Building + Inherits: ^CivBuilding Selectable: Priority: 0 - -RepairableBuilding: - -GivesBuildableArea: Health: HP: 10 Explodes: @@ -101,11 +99,9 @@ BARL: Name: Explosive Barrel BRL3: - Inherits: ^Building + Inherits: ^CivBuilding Selectable: Priority: 0 - -RepairableBuilding: - -GivesBuildableArea: Health: HP: 10 Explodes: From 8f981977e0eafcb3fac64f49c2dc4e00b3df1f38 Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 6 Jun 2012 10:47:13 +0200 Subject: [PATCH 38/56] TimeWidget does not collide anymore with koth layout. Screen resolution should be 1024x786+ --- OpenRA.Game/Widgets/TimerWidget.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/OpenRA.Game/Widgets/TimerWidget.cs b/OpenRA.Game/Widgets/TimerWidget.cs index d0b7e419be..b2f5bfb2ba 100644 --- a/OpenRA.Game/Widgets/TimerWidget.cs +++ b/OpenRA.Game/Widgets/TimerWidget.cs @@ -19,15 +19,9 @@ namespace OpenRA.Widgets var font = Game.Renderer.Fonts["Title"]; var rb = RenderBounds; - var s = WidgetUtils.FormatTime(Game.LocalTick); + var s = WidgetUtils.FormatTime(Game.LocalTick) + (Game.orderManager.GamePaused?" (paused)":""); var pos = new float2(rb.Left - font.Measure(s).X / 2, rb.Top); - - var s_paused = (Game.orderManager.GamePaused ? "\n (paused)" : ""); - var pos_paused = new float2(rb.Left - font.Measure(s_paused).X / 2, rb.Top+1); - font.DrawTextWithContrast(s, pos, Color.White, Color.Black, 1); - font.DrawTextWithContrast(s_paused, pos_paused, Color.White, Color.Black, 1); - } } } From 8ad4e0865164241a179a263093c93a6dce85e420 Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 6 Jun 2012 10:54:21 +0200 Subject: [PATCH 39/56] Unit order client != null check fixed (int != null -> always true!) . Removed if-else branch in favour of sugar construct a?b:c. Note: One should (at least) consider to move var client = ... to the start of the switch construct. 4 branches of this switch are using this. (DRY) --- OpenRA.Game/Network/UnitOrders.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/OpenRA.Game/Network/UnitOrders.cs b/OpenRA.Game/Network/UnitOrders.cs index 7c7a844f61..a7e1d9c730 100755 --- a/OpenRA.Game/Network/UnitOrders.cs +++ b/OpenRA.Game/Network/UnitOrders.cs @@ -97,19 +97,13 @@ namespace OpenRA.Network case "PauseGame": { - if(clientId != null) + var client = orderManager.LobbyInfo.ClientWithIndex(clientId); + + if(client != null) { - var client = orderManager.LobbyInfo.ClientWithIndex(clientId); - orderManager.GamePaused = !orderManager.GamePaused; - if(orderManager.GamePaused) - { - Game.AddChatLine(Color.White, "", "The game is paused by "+client.Name); - } - else - { - Game.AddChatLine(Color.White, "", "The game is un-paused by "+client.Name); - } + var pausetext = "The game is {0} by {1}".F( orderManager.GamePaused ? "paused" : "un-paused", client.Name ); + Game.AddChatLine(Color.White, "", pausetext); } break; } From 84124de79de169cb7890339ce9ae56354a487dca Mon Sep 17 00:00:00 2001 From: Remco van der Zon Date: Wed, 6 Jun 2012 11:22:46 +0200 Subject: [PATCH 40/56] Game can now be paused by pressing f3 as well. --- OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs index bcdc813434..29721ccaa2 100644 --- a/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs +++ b/OpenRA.Game/Widgets/WorldInteractionControllerWidget.cs @@ -148,7 +148,7 @@ namespace OpenRA.Widgets world.Selection.DoControlGroup(world, e.KeyName[0] - '0', e.Modifiers); return true; } - else if(e.KeyName == "pause") + else if(e.KeyName == "pause" || e.KeyName == "f3") { world.IssueOrder(Order.PauseRequest()); } From 3f0fafb3801a92d9ee6d5f3e73dcdeff6db31954 Mon Sep 17 00:00:00 2001 From: Igor Popov Date: Sat, 26 May 2012 16:31:14 +0400 Subject: [PATCH 41/56] Add banlist (Server.Ban settings item) support to game servers --- OpenRA.Game/GameRules/Settings.cs | 2 ++ OpenRA.Game/Network/Session.cs | 1 + OpenRA.Game/Server/Server.cs | 19 +++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index 1c1bf93213..49fa8918f4 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -31,6 +31,7 @@ namespace OpenRA.GameRules public string MasterServer = "http://master.open-ra.org/"; public bool AllowCheats = false; public string Map = null; + public string[] Ban = null; public ServerSettings() { } @@ -43,6 +44,7 @@ namespace OpenRA.GameRules MasterServer = other.MasterServer; AllowCheats = other.AllowCheats; Map = other.Map; + Ban = other.Ban; } } diff --git a/OpenRA.Game/Network/Session.cs b/OpenRA.Game/Network/Session.cs index 38447a5a51..686bed1306 100644 --- a/OpenRA.Game/Network/Session.cs +++ b/OpenRA.Game/Network/Session.cs @@ -70,6 +70,7 @@ namespace OpenRA.Network { public string ServerName; public string Map; + public string[] Ban; public string[] Mods = { "ra" }; // mod names public int OrderLatency = 3; public int RandomSeed = 0; diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index e50101bb5b..cae7be0f56 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -71,6 +71,7 @@ namespace OpenRA.Server lobbyInfo.GlobalSettings.RandomSeed = randomSeed; lobbyInfo.GlobalSettings.Map = settings.Map; lobbyInfo.GlobalSettings.ServerName = settings.Name; + lobbyInfo.GlobalSettings.Ban = settings.Ban; foreach (var t in ServerTraits.WithInterface()) t.ServerStarted(this); @@ -205,6 +206,21 @@ namespace OpenRA.Server return; } + // Check if IP is banned + if (lobbyInfo.GlobalSettings.Ban != null) + { + var remote_addr = ((IPEndPoint)newConn.socket.RemoteEndPoint).Address.ToString(); + if (lobbyInfo.GlobalSettings.Ban.Contains(remote_addr)) + { + Console.WriteLine("Rejected connection from "+client.Name+"("+newConn.socket.RemoteEndPoint+"); Banned."); + Log.Write("server", "Rejected connection from {0}; Banned.", + newConn.socket.RemoteEndPoint); + SendOrderTo(newConn, "ServerError", "You are banned from the server!"); + DropClient(newConn); + return; + } + } + // Promote connection to a valid client preConns.Remove(newConn); conns.Add(newConn); @@ -406,6 +422,9 @@ namespace OpenRA.Server public void StartGame() { GameStarted = true; + listener.Stop(); + Console.WriteLine("Game started"); + foreach( var c in conns ) foreach( var d in conns ) DispatchOrdersToClient( c, d.PlayerIndex, 0x7FFFFFFF, new byte[] { 0xBF } ); From 5414875d00f7ad91b9cdd56944d358768c32436f Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 10 Jun 2012 16:31:54 +1200 Subject: [PATCH 42/56] update .gitignore; remove spurious `mono` file --- .gitignore | 9 ++------- mono | 0 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 mono diff --git a/.gitignore b/.gitignore index eddde75363..ac341d94d4 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,8 @@ mods/*/packages/*.[mM][iI][xX] # backup files by various editors *~ *.orig +\#* +.*.sw? # dependency DLLs (different for every platform!) cg.dll cgGL.dll @@ -32,8 +34,6 @@ cgGL.dll *.pidb *.userprefs -packaging/windows/*.exe - # osx crap .DS_Store @@ -52,8 +52,3 @@ OpenRA.Launcher.Mac/OpenRA.xcodeproj/*.mode1v3 *.config *.resources -# other crap -Logs/ -Replays/ -\#* -.*.sw? diff --git a/mono b/mono deleted file mode 100644 index e69de29bb2..0000000000 From b96158adcb430bbaf08b3af7001504b6f6231df3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Sat, 9 Jun 2012 11:47:24 +0200 Subject: [PATCH 43/56] new AI with optimized build order Eisenhower builds less refineries, more units and techs faster --- mods/ra/rules/system.yaml | 59 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 4d9c2d18c3..30abc3c595 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -98,6 +98,65 @@ Player: 2tnk: 25% 3tnk: 50% SquadSize: 10 + HackyAI@OptiAI: + Name:Optimized AI + BuildingFractions: + proc: 25.1% + powr: 35% + tent: 0.1% + barr: 0.1% + weap: 0.1% + fix: 0.1% + dome: 0.1% + atek: 0.1% + stek: 0.1% + UnitsToBuild: + e1: 50% + e2: 1% + e3: 10% + medi: 0.01% + e7: 0.01% + apc: 10% + jeep: 10% + ftrk: 25% + 1tnk: 25% + 2tnk: 50% + 3tnk: 75% + 4tnk: 100% + arty: 30% + v2rl: 30% + SquadSize: 10 + HackyAI@AirAI: + Name:Air AI + BuildingFractions: + proc: 25.1% + powr: 35% + afld: 30% + hpad: 30% + weap: 0.1% + dome: 0.1% + atek: 0.1% + stek: 0.1% + UnitsToBuild: + yak: 50% + hind: 50% + mig: 50% + heli: 50% + SquadSize: 1 + HackyAI@BaseAI: + Name:Basewalk AI + BuildingFractions: + proc: 25.1% + powr: 40% + tent: 0.1% + barr: 0.1% + pbox: 20% + ftur: 25% + weap: 0.1% + gun: 20% + tsla: 15% + UnitsToBuild: + SquadSize: 1 HackyAI@ZhukovAI: Name:Zhukov AI BuildingFractions: From aa36a56b27f7cde4ba8bbbbd60047483990b34f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Mon, 21 May 2012 17:06:03 +0200 Subject: [PATCH 44/56] UPnP source code fixes as suggested by Chris Forbes --- OpenRA.Game/GameRules/Settings.cs | 2 + OpenRA.Game/OpenRA.Game.csproj | 1 + OpenRA.Game/Server/Server.cs | 23 ++- OpenRA.Game/Server/UPnP.cs | 139 ++++++++++++++++++ .../Widgets/Logic/ServerCreationLogic.cs | 8 +- mods/ra/chrome/create-server.yaml | 6 + 6 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 OpenRA.Game/Server/UPnP.cs diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index 49fa8918f4..f1265e5e40 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -29,6 +29,7 @@ namespace OpenRA.GameRules public int ExternalPort = 1234; public bool AdvertiseOnline = true; public string MasterServer = "http://master.open-ra.org/"; + public bool AllowUPnP = true; public bool AllowCheats = false; public string Map = null; public string[] Ban = null; @@ -42,6 +43,7 @@ namespace OpenRA.GameRules ExternalPort = other.ExternalPort; AdvertiseOnline = other.AdvertiseOnline; MasterServer = other.MasterServer; + AllowUPnP = other.AllowUPnP; AllowCheats = other.AllowCheats; Map = other.Map; Ban = other.Ban; diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index ea15d2ac38..17ab5219b7 100755 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -142,6 +142,7 @@ + diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 6af0357e56..c443b8c94a 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 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, @@ -13,9 +13,13 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; using System.Net; using System.Net.Sockets; +using System.Net.NetworkInformation; +using UPnP; using System.Threading; +using System.Xml; using OpenRA.FileFormats; using OpenRA.GameRules; using OpenRA.Network; @@ -64,6 +68,9 @@ namespace OpenRA.Server randomSeed = (int)DateTime.Now.ToBinary(); + if (settings.AllowUPnP) + PortForward(); + foreach (var trait in modData.Manifest.ServerTraits) ServerTraits.Add( modData.ObjectCreator.CreateObject(trait) ); @@ -123,6 +130,20 @@ namespace OpenRA.Server } ) { IsBackground = true }.Start(); } + void PortForward() + { + if (UPnP.NAT.Discover()) + { + Log.Write("server", "UPnP-enabled router discovered."); + UPnP.NAT.ForwardPort(Port, ProtocolType.Tcp, "OpenRA"); //might timeout after second try + Log.Write("server", "Port {0} (TCP) has been forwarded.", Port); + Log.Write("server", "Your IP is: {0}", UPnP.NAT.GetExternalIP() ); + } + else + Log.Write("server", "No UPnP-enabled router detected."); + return; + } + /* lobby rework todo: * - "teams together" option for team games -- will eliminate most need * for manual spawnpoint choosing. diff --git a/OpenRA.Game/Server/UPnP.cs b/OpenRA.Game/Server/UPnP.cs new file mode 100644 index 0000000000..a64b26126e --- /dev/null +++ b/OpenRA.Game/Server/UPnP.cs @@ -0,0 +1,139 @@ +#region Copyright & License Information +/* + * Copyright 2008-2009 http://www.codeproject.com/Members/Harold-Aptroot + * Source: http://www.codeproject.com/Articles/27992/NAT-Traversal-with-UPnP-in-C + * This file is licensed under A Public Domain dedication. + * For more information, see http://creativecommons.org/licenses/publicdomain/ + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Text; +using System.Net.Sockets; +using System.Net; +using System.Xml; +using System.IO; + +namespace UPnP +{ + public class NAT + { + public static TimeSpan _timeout = new TimeSpan(0, 0, 0, 3); + static string _serviceUrl; + + public static bool Discover() + { + Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1); + string req = "M-SEARCH * HTTP/1.1\r\n" + + "HOST: 239.255.255.250:1900\r\n" + + "ST:upnp:rootdevice\r\n" + + "MAN:\"ssdp:discover\"\r\n" + + "MX:3\r\n\r\n"; + byte[] data = Encoding.ASCII.GetBytes(req); + IPEndPoint ipe = new IPEndPoint(IPAddress.Broadcast, 1900); + byte[] buffer = new byte[0x1000]; + + DateTime start = DateTime.Now; + + do + { + s.SendTo(data, ipe); + s.SendTo(data, ipe); + s.SendTo(data, ipe); + + int length = 0; + do + { + length = s.Receive(buffer); + + string resp = Encoding.ASCII.GetString(buffer, 0, length).ToLower(); + if (resp.Contains("upnp:rootdevice")) + { + resp = resp.Substring(resp.ToLower().IndexOf("location:") + 9); + resp = resp.Substring(0, resp.IndexOf("\r")).Trim(); + if (!string.IsNullOrEmpty(_serviceUrl = GetServiceUrl(resp))) + return true; + } + } while (length > 0); + } while ((start - DateTime.Now) < _timeout); + return false; + } + + private static String GetServiceUrl(string resp) + { + XmlDocument desc = new XmlDocument(); + desc.Load(WebRequest.Create(resp).GetResponse().GetResponseStream()); + XmlNamespaceManager nsMgr = new XmlNamespaceManager(desc.NameTable); + nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); + XmlNode typen = desc.SelectSingleNode("//tns:device/tns:deviceType/text()", nsMgr); + if (!typen.Value.Contains("InternetGatewayDevice")) + return null; + XmlNode node = desc.SelectSingleNode("//tns:service[tns:serviceType=\"urn:schemas-upnp-org:service:WANIPConnection:1\"]/tns:controlURL/text()", nsMgr); + if (node == null) + return null; + Uri respUri = new Uri(resp); + Uri combinedUri = new Uri(respUri, node.Value); + return combinedUri.AbsoluteUri; + } + + public static void ForwardPort(int port, ProtocolType protocol, string description) + { + if (string.IsNullOrEmpty(_serviceUrl)) + throw new Exception("No UPnP service available or Discover() has not been called"); + string body = String.Format(""+ + "{0}"+ + "{1}{0}" + + "{2}1" + + "{3}"+ + "0", + port, protocol.ToString().ToUpper(),Dns.GetHostAddresses(Dns.GetHostName())[0], description); + SOAPRequest(_serviceUrl, body, "AddPortMapping"); + } + + public static void DeleteForwardingRule(int port, ProtocolType protocol) + { + if (string.IsNullOrEmpty(_serviceUrl)) + throw new Exception("No UPnP service available or Discover() has not been called"); + string body = String.Format("" + + "{0}"+ + "{1}", port, protocol.ToString().ToUpper() ); + SOAPRequest(_serviceUrl, body, "DeletePortMapping"); + } + + public static IPAddress GetExternalIP() + { + if (string.IsNullOrEmpty(_serviceUrl)) + throw new Exception("No UPnP service available or Discover() has not been called"); + XmlDocument xdoc = SOAPRequest(_serviceUrl, "" + + "", "GetExternalIPAddress"); + XmlNamespaceManager nsMgr = new XmlNamespaceManager(xdoc.NameTable); + nsMgr.AddNamespace("tns", "urn:schemas-upnp-org:device-1-0"); + string IP = xdoc.SelectSingleNode("//NewExternalIPAddress/text()", nsMgr).Value; + return IPAddress.Parse(IP); + } + + private static XmlDocument SOAPRequest(string url, string soap, string function) + { + string req = "" + + "" + + "" + + soap + + "" + + ""; + WebRequest r = HttpWebRequest.Create(url); + r.Method = "POST"; + byte[] b = Encoding.UTF8.GetBytes(req); + r.Headers.Add("SOAPACTION", "\"urn:schemas-upnp-org:service:WANIPConnection:1#" + function + "\""); + r.ContentType = "text/xml; charset=\"utf-8\""; + r.ContentLength = b.Length; + r.GetRequestStream().Write(b, 0, b.Length); + XmlDocument resp = new XmlDocument(); + WebResponse wres = r.GetResponse(); + Stream ress = wres.GetResponseStream(); + resp.Load(ress); + return resp; + } + } +} diff --git a/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs index abe2a490e7..e93d00a2f4 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ServerCreationLogic.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 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, @@ -22,6 +22,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic Action onExit; Map map; bool advertiseOnline; + bool allowUPnP; [ObjectCreator.UseCtor] public ServerCreationLogic(Widget widget, Action onExit, Action openLobby) @@ -64,6 +65,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic var advertiseCheckbox = panel.Get("ADVERTISE_CHECKBOX"); advertiseCheckbox.IsChecked = () => advertiseOnline; advertiseCheckbox.OnClick = () => advertiseOnline ^= true; + + var UPnPCheckbox = panel.Get("UPNP_CHECKBOX"); + UPnPCheckbox.IsChecked = () => allowUPnP; + UPnPCheckbox.OnClick = () => allowUPnP ^= true; } void CreateAndJoin() @@ -81,6 +86,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic Game.Settings.Server.ListenPort = listenPort; Game.Settings.Server.ExternalPort = externalPort; Game.Settings.Server.AdvertiseOnline = advertiseOnline; + Game.Settings.Server.AllowUPnP = allowUPnP; Game.Settings.Server.Map = map.Uid; Game.Settings.Save(); diff --git a/mods/ra/chrome/create-server.yaml b/mods/ra/chrome/create-server.yaml index 2fd4466391..3a81044bd2 100644 --- a/mods/ra/chrome/create-server.yaml +++ b/mods/ra/chrome/create-server.yaml @@ -60,6 +60,12 @@ Background@CREATESERVER_BG: Width:300 Height:20 Text:Advertise game Online + Checkbox@UPNP_CHECKBOX: + X:165 + Y:165 + Width:300 + Height:20 + Text:Allow UPnP port forwarding Button@CREATE_BUTTON: X:130 Y:PARENT_BOTTOM - 45 From dc6b286d25af86a3bcf908929ec26e7305cbfddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Wed, 23 May 2012 08:22:31 +0200 Subject: [PATCH 45/56] remove unneccessary dependencies, make SendTo less spammy --- OpenRA.Game/Server/Server.cs | 2 -- OpenRA.Game/Server/UPnP.cs | 2 -- 2 files changed, 4 deletions(-) diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index c443b8c94a..c704efbbb7 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -13,13 +13,11 @@ using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Net; using System.Net.Sockets; using System.Net.NetworkInformation; using UPnP; using System.Threading; -using System.Xml; using OpenRA.FileFormats; using OpenRA.GameRules; using OpenRA.Network; diff --git a/OpenRA.Game/Server/UPnP.cs b/OpenRA.Game/Server/UPnP.cs index a64b26126e..6b3e2ecdc4 100644 --- a/OpenRA.Game/Server/UPnP.cs +++ b/OpenRA.Game/Server/UPnP.cs @@ -40,8 +40,6 @@ namespace UPnP do { s.SendTo(data, ipe); - s.SendTo(data, ipe); - s.SendTo(data, ipe); int length = 0; do From 4a7417347ada985fe41d8ace2472b2fdc31a6d33 Mon Sep 17 00:00:00 2001 From: Igor Popov Date: Thu, 7 Jun 2012 21:10:26 +0400 Subject: [PATCH 46/56] fix #2199; Game Timer (min 10 seconds) --- OpenRA.Game/GameRules/Settings.cs | 2 ++ OpenRA.Game/Server/Server.cs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index f1265e5e40..2c748f7a22 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -33,6 +33,7 @@ namespace OpenRA.GameRules public bool AllowCheats = false; public string Map = null; public string[] Ban = null; + public int TimeOut = 0; public ServerSettings() { } @@ -47,6 +48,7 @@ namespace OpenRA.GameRules AllowCheats = other.AllowCheats; Map = other.Map; Ban = other.Ban; + TimeOut = other.TimeOut; } } diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index c704efbbb7..99201d2cc9 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -18,6 +18,7 @@ using System.Net.Sockets; using System.Net.NetworkInformation; using UPnP; using System.Threading; +using System.Timers; using OpenRA.FileFormats; using OpenRA.GameRules; using OpenRA.Network; @@ -466,6 +467,22 @@ namespace OpenRA.Server foreach (var t in ServerTraits.WithInterface()) t.GameStarted(this); + + // Check TimeOut + if ( Game.Settings.Server.TimeOut > 10000 ) + { + aTimer = new System.Timers.Timer(Game.Settings.Server.TimeOut); + aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); + aTimer.Enabled = true; + } + } + + private static System.Timers.Timer aTimer; + + private static void OnTimedEvent(object source, ElapsedEventArgs e) + { + Console.WriteLine("Started game has Timed Out at {0} !!!", e.SignalTime); + System.Environment.Exit(0); } } } From 3827a5436a9407551de9abd562a8b44e4e73ac3c Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 10 Jun 2012 17:17:38 +1200 Subject: [PATCH 47/56] #2191 fixed -- custom OGs canceled on win/lose --- OpenRA.Mods.RA/Orders/PowerDownOrderGenerator.cs | 8 +++++++- OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/OpenRA.Mods.RA/Orders/PowerDownOrderGenerator.cs b/OpenRA.Mods.RA/Orders/PowerDownOrderGenerator.cs index c344a6706a..3dcf38a460 100755 --- a/OpenRA.Mods.RA/Orders/PowerDownOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/PowerDownOrderGenerator.cs @@ -48,7 +48,13 @@ namespace OpenRA.Mods.RA.Orders } } - public void Tick(World world) { } + public void Tick(World world) + { + if (world.LocalPlayer != null && + world.LocalPlayer.WinState != WinState.Undefined) + world.CancelInputMode(); + } + public void RenderAfterWorld(WorldRenderer wr, World world) { } public void RenderBeforeWorld(WorldRenderer wr, World world) { } diff --git a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs index c1ede6fc60..cbbf16e54c 100644 --- a/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs +++ b/OpenRA.Mods.RA/Orders/RepairOrderGenerator.cs @@ -42,7 +42,13 @@ namespace OpenRA.Mods.RA.Orders } } - public void Tick(World world) { } + public void Tick(World world) + { + if (world.LocalPlayer != null && + world.LocalPlayer.WinState != WinState.Undefined) + world.CancelInputMode(); + } + public void RenderAfterWorld(WorldRenderer wr, World world) { } public void RenderBeforeWorld(WorldRenderer wr, World world) { } From f3d68f4944808a23b86b817efb42bdc239a36d2a Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Sun, 10 Jun 2012 19:52:25 +1200 Subject: [PATCH 48/56] remove some junk ai profiles --- mods/ra/rules/system.yaml | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/mods/ra/rules/system.yaml b/mods/ra/rules/system.yaml index 30abc3c595..a25b700feb 100644 --- a/mods/ra/rules/system.yaml +++ b/mods/ra/rules/system.yaml @@ -99,7 +99,7 @@ Player: 3tnk: 50% SquadSize: 10 HackyAI@OptiAI: - Name:Optimized AI + Name:Eisenhower AI BuildingFractions: proc: 25.1% powr: 35% @@ -126,37 +126,6 @@ Player: arty: 30% v2rl: 30% SquadSize: 10 - HackyAI@AirAI: - Name:Air AI - BuildingFractions: - proc: 25.1% - powr: 35% - afld: 30% - hpad: 30% - weap: 0.1% - dome: 0.1% - atek: 0.1% - stek: 0.1% - UnitsToBuild: - yak: 50% - hind: 50% - mig: 50% - heli: 50% - SquadSize: 1 - HackyAI@BaseAI: - Name:Basewalk AI - BuildingFractions: - proc: 25.1% - powr: 40% - tent: 0.1% - barr: 0.1% - pbox: 20% - ftur: 25% - weap: 0.1% - gun: 20% - tsla: 15% - UnitsToBuild: - SquadSize: 1 HackyAI@ZhukovAI: Name:Zhukov AI BuildingFractions: From 4e881666735606b16aeaf81d178d0757c7562ebe Mon Sep 17 00:00:00 2001 From: Curtis Shmyr Date: Sun, 10 Jun 2012 12:56:24 -0600 Subject: [PATCH 49/56] Added two new RA maps by Tirili: Ice Woods & Nishnekolymsk --- mods/ra/maps/ice-woods.oramap | Bin 0 -> 16215 bytes mods/ra/maps/nishnekolymsk.oramap | Bin 0 -> 42165 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ra/maps/ice-woods.oramap create mode 100644 mods/ra/maps/nishnekolymsk.oramap diff --git a/mods/ra/maps/ice-woods.oramap b/mods/ra/maps/ice-woods.oramap new file mode 100644 index 0000000000000000000000000000000000000000..4f6919a4bbf28263a138c86fca7186e94d31461b GIT binary patch literal 16215 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 literal 0 HcmV?d00001 diff --git a/mods/ra/maps/nishnekolymsk.oramap b/mods/ra/maps/nishnekolymsk.oramap new file mode 100644 index 0000000000000000000000000000000000000000..9e5839b855378d50da002a274b1bf5492d7722a4 GIT binary patch literal 42165 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 OzwGd@<}Lb9@4o=ZmjxC8 literal 0 HcmV?d00001 From 9862b8ccee19d7096792d865742976be57d50cfa Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Tue, 12 Jun 2012 09:33:40 +1200 Subject: [PATCH 50/56] remove sequence save junk --- OpenRA.Game/Graphics/Sequence.cs | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/OpenRA.Game/Graphics/Sequence.cs b/OpenRA.Game/Graphics/Sequence.cs index 5b114e9d07..d8a0bfeceb 100644 --- a/OpenRA.Game/Graphics/Sequence.cs +++ b/OpenRA.Game/Graphics/Sequence.cs @@ -27,10 +27,9 @@ namespace OpenRA.Graphics public int Facings { get { return facings; } } public int Tick { get { return tick; } } - string srcOverride; public Sequence(string unit, string name, MiniYaml info) { - srcOverride = info.Value; + var srcOverride = info.Value; Name = name; var d = info.NodesDict; @@ -62,26 +61,6 @@ namespace OpenRA.Graphics info.Nodes[0].Location)); } - public MiniYaml Save() - { - var root = new List(); - - root.Add(new MiniYamlNode("Start", start.ToString())); - - if (length > 1 && (start != 0 || length != sprites.Length - start)) - root.Add(new MiniYamlNode("Length", length.ToString())); - else if (length > 1 && length == sprites.Length - start) - root.Add(new MiniYamlNode("Length", "*")); - - if (facings > 1) - root.Add(new MiniYamlNode("Facings", facings.ToString())); - - if (tick != 40) - root.Add(new MiniYamlNode("Tick", tick.ToString())); - - return new MiniYaml(srcOverride, root); - } - public Sprite GetSprite( int frame ) { return GetSprite( frame, 0 ); From 94f7f1c473449373d597fdeab82b44f642ebb418 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Fri, 15 Jun 2012 15:14:56 +1200 Subject: [PATCH 51/56] clean up game timeout --- OpenRA.Game/Server/Server.cs | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/OpenRA.Game/Server/Server.cs b/OpenRA.Game/Server/Server.cs index 99201d2cc9..3879fd76ae 100644 --- a/OpenRA.Game/Server/Server.cs +++ b/OpenRA.Game/Server/Server.cs @@ -18,11 +18,12 @@ using System.Net.Sockets; using System.Net.NetworkInformation; using UPnP; using System.Threading; -using System.Timers; using OpenRA.FileFormats; using OpenRA.GameRules; using OpenRA.Network; +using XTimer = System.Timers.Timer; + namespace OpenRA.Server { public class Server @@ -48,6 +49,7 @@ namespace OpenRA.Server public ServerSettings Settings; public ModData ModData; public Map Map; + XTimer gameTimeout; volatile bool shutdown = false; public void Shutdown() { shutdown = true; } @@ -469,20 +471,16 @@ namespace OpenRA.Server t.GameStarted(this); // Check TimeOut - if ( Game.Settings.Server.TimeOut > 10000 ) + if ( Settings.TimeOut > 10000 ) { - aTimer = new System.Timers.Timer(Game.Settings.Server.TimeOut); - aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent); - aTimer.Enabled = true; + gameTimeout = new XTimer(Settings.TimeOut); + gameTimeout.Elapsed += (_,e) => + { + Console.WriteLine("Timeout at {0}!!!", e.SignalTime); + Environment.Exit(0); + }; + gameTimeout.Enabled = true; } } - - private static System.Timers.Timer aTimer; - - private static void OnTimedEvent(object source, ElapsedEventArgs e) - { - Console.WriteLine("Started game has Timed Out at {0} !!!", e.SignalTime); - System.Environment.Exit(0); - } } } From 4d94cb5593e3975af95575796c6880bb38a0186d Mon Sep 17 00:00:00 2001 From: Igor Popov Date: Fri, 15 Jun 2012 13:32:18 +0400 Subject: [PATCH 52/56] 2 maps: Bomber John(minigame->new); Free Coasts(conquest->replace) --- mods/ra/maps/bomber-john.oramap | Bin 0 -> 6883 bytes mods/ra/maps/free-coasts.oramap | Bin 9926 -> 10996 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 mods/ra/maps/bomber-john.oramap diff --git a/mods/ra/maps/bomber-john.oramap b/mods/ra/maps/bomber-john.oramap new file mode 100644 index 0000000000000000000000000000000000000000..1305507ac36a94eeaefc11d59b1281c381486278 GIT binary patch literal 6883 zcmZ{J1z1!;*Z(fPfJ#V%bi>jhxhpK)h_p1w5`x4k-34*>uG9^k}25L!>7feD#6smJB3_uy*%e@c%}c~F_|Qc*`d0ALHvhZX>P zC-}>MFzUf0u3-=Tm0Md|sM9NFxa=$Zjf>S?^0XzM&N$V>m(E}}tD(5LvrEs$HP$QA z>y$T@W{lg2`Y_30OHPL!no`gQy5no9KpRQD9XoameJZ|o-|mf7qnj0C)!{% zqSqR!{eBg{r|WIn=c2g@2s@e=X8EW;K4+MN!lU9;|2$CrZ7^7& z0iNrKA`VLPE%z`|rK=@+MZSrPzit8MF-9!LRutM0=oR5uG4a4zCxR5|Sg8CO9fiw@ zrTqC6^c4AcMU4?)!jonW-6j%F+3n}gS856zwQ@Mrd^v^RG}+|2g4tAyL400_Ct@Q! zgw=DCeD=h?7e165Q^C*WyB0@O>_oPXTEUn__}?k6f(5y#zO4jp2+oBr_Sy^Y0Dy zET*&HxGnLf>s5+5uK2A5;BPrLnrRmqG$kTAe6a4Z^Ig5=lGOznPMl+ct+IOtwAqSfQ7ngY?S@7(NIIS06|!M-djTdtQs6AEUnilZTpV!uRm>2;4B4dp~oz5vgsy9{SV^c9(d(cFzkl-~?N}>}=?EuVtAve0ppcxXCvsLhOFT;s( z%l)p7=nGP%Ge`yV(xkmdgu0s1?7M54*CdVL?zf@1BUEuuxkBpu=;MaB389nukX^eC zg2hvH*AYGnoWXca=^g5@q~dPd*JU5kMB{dm7hcljQ`Tm z3{P8`cEe;%y3jRCrS5zinN#c?s1^2|UzbC~=gqi?+GFbF-KW%AhXz2yS0~*4rO*m9 zYPIm{+|i&d7_!6V%RL!-oLgCFN%4&DlT@lb9G_Jxp2M3-QC(f?j+u^C+2&~)GVpuw z-jR=KyX7_eOWjL}JRbbu-s=u}!Yhlw15~==yM??b?|Nc09P$be8q+1L&&LZ-wDVc| zwq$SY8N+a%7l%t3yl`;j?fbFfh2xy>jg0Cigy5|n29QN1&(t(jVSB;7;)lY$Z<2m7 zdlc51Dk+8idccl|5b_GHw;

D@^@QfeFmn?{Q<-(QxVfCdK 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 literal 9926 zcma)i1xy^k(=S>aibK)j?!~>hyA+DMyTjq`?smo9U9Y%9ad(QlbNBks_mU@hU-EV* zS((i4WOrvK+4-r+!@}V}K|vux0ZTbVf>sPcGhd;g;6SUX(&lue+L zYy?jVEluiF5>X_rSw76mm*kbV)Tc=u{kk~5tV{-uWh zXV-akq{(5$Qk9@TFkIWzXimaR9ekjRHgv+ZSD0KzND`R-rG zd`U19!#C_Iow@Lsmal1CigwRopS}4pPZ1MM+(XMgMdQpF4{WgiN;FnzhsRM;gE$M4 z6^P{!uZJv%mjDYAl)7U%`w%vA2yjoOW$>&(lp#*LsofDcpfhZ-sEx?>pJWFz zq^DV#*RIYaFYb1=Fxtj-#X6y2E?Oa(DHYxYH72-?1EG&A_(lq>!BjRKAGKz+$Wf)J z`Gz9yC@svI$Up1Do}@s2Dc4va(L;5vde8A)p#kD3%phDLggyd0Kn$(kO3G?nJj;tx0Om?1Aaz$OZCg zE&s|7ow-A=rIe7P-{AtlgOTqTt}7{f@sIMyre2;~EZsS;0YVCO#8&w?9)CcW&v}&? z%KtQ8{Irbln!}f3V^)d112+_vlXIc^bmB|=UVuXz;2-@cEH1^{tyb5CcwHMv);c1K zEEmE_3m~<2n%^m1NHai7-X zpLnn|ZM#P>5$H!N$c_jv6MjMsG8Mag1~AjbxAfzZ%8sP#Lg|b-zdVU;aqT6SJ8$_* z-n~2QfZ~!)N?A{K)RbfVz;b;#I?r4c60KQdY_C_D#B2hg2u+g8(U2nS2tjUl2|lB3 z9~*2!%TQ;ldZS*RJm%`|FupiahJJq5VI995+>i{w$At&yj*2Mk(q|G=GQBfjxlA|4 z3qJed-`BqN^7M9pP$L?H)ERUW$Eh&n0QRPzE?f8j!K!qlY{zCyF>*_uo6`N#Yy~g{ zw`a8dv}|OsWCE{VY0Edmi~0KBR6t9nY=}i7+|fh7wvbGA`v}3+v^z^E*nN~&gWYFG z-6W6Zpxl&(m5utFvoL^XZzzQG_Cg`QAoUsih7A8=iq36mW8etEJfU1s7W>Z@g~~=E zpZsHEJ)x_idrGnv3)gzmi-h8TE81Xd7x^BOZCvZCHW56T{4%Gh=pp|i+-ZWe|6n&k zL3iAzlFNDkNyxpnn9eE{dJGQ!5-vozADw^k6hA;pFMKZIAx-|&b%-$X*w{vO@t83o6z=^`UdizI-i)Fui5YE2B(nm*@d@wS zI1Z0iR7sA7br1k zL(_|hkFkDOazpfm*I%yJMkihFxdkI)(;C}6T#urIYj)BV)52AW@pb^O4Fi)R4cmm- zoccl_q&sdM@aO%u=(zFlnbGtYx%R5vi$M2x!yk4i2mutUST9+!(tzUnLEFM*DRw$^ zI<@2JnC#%9A7gZD^;zBKOd9OmyzTD^k%Ei>I;gL1;g6^Zxx1;<3e&d;<6&L9C5ucy z86Q7<)4hE6g!&3Z!XCu676gfOaA+lWa>pr|nsj{lD*_XKIz`+Rivv>&6wh$Qpx2#hN;k9I~;>Da$@f33rB}c z5m-Qe^(`}5P_FW}79WIqhuVR$exg~oA5x*1>7T8Q1j#!Xo37^r%@Nk-@x3o_w#XkY zRuJ+X_;uOAHnZ$y)g-Z}2_qkwo<{^KWN9(xmk83$j z;d28_9Fo}q4?4Q|L5W_g;(p{9b;6GWTp25{?SVZ2`HRQ5n3VC`UL0ic1C(n>6R>HS zP9R3SiE*c4#F&h%#2mC!WFf1@khR(rVF}Favv{`W?QAff3CvMII8Ah?6Ue|7mBmqr z__A=Vk{V-$BQyFOxX1?w5>h)CM+6=qetu+FIOlYd;SXOUqjn58QaMxUpKk*asJAlE;iPo8K1 zm%`|dO{&8@bB<#Y8*z;TBA}{2m^v!&$wnVLSXR+NGnO|?9<;KD-KGaJ>Q}s#pUtS> z=H1I-9bWY??4nGZU||vkAX6rYkXxs{e=V)oyu6ny;S6%Gh0|<{rQ=A4ggeirGty6mYy7 zTstaoiVL0bdBvNJl@h-*j1iQa^C|YcSdaJQFvE};NPO^hWp4wu^TIDX+K zSQ>b!%cYs1xfKv(C96`8T4XI+WEptf0@Y5Ga~UcqC4^vW;vw|4;n})%C zfYD(kBQOJIZ(V}^%x;(2)))u_O#d#9j{g$c;27j6{kjezJ?@BokMg4j^7$RDY;A}; z+cxL$y9Y4haden~a~1QG_wmuHTG0w_lEdoDhqSD>n$28tlj~}{;O~(eGelXxzM)*> zr}3F4y9}}^ms$WU1`xbKM=wjXvHmEp9*uMt95<}d3w+h7J|rOy16yA}--#@=qdvdz zx(`e`5@>&};v^b|W?Y&;BTJbhSIb_e(u@NN-n8J>{R^yy!QMzOhN1wZTZp0tZMn+l zhGzOz2>JP@e9MGqzvlvdJ<79)qF=Po$A}uMp`LRl1G%yW`eKMKg&ag5_`I8&3w__UP2<kuD6rt z2fYi-dJfQA;Vtxa9x2K7w6_)?S5vX4{;t}wdS-2dPbVx@A?y%}(9#2MihGywFhR%8 zcgr||=>UFqH_Wqoqg!x2QRi3A4ViHi-^PvqS*8)+-!`Lhyd#FUD5_Ybxte<~5YC+@>RSNe?iHQfvy<*QS!h8)ocH`k zt`h+mpzP6t_+en-jA#LK7(|GbKBq@@)km*Xgn$5>=yt1?RRm6$7+Pwqd$U0K%}VE4 z<`AXf+~%K>JsB(Y3_=3eFQJ)e)<3ZX6p+&kl8b2n7Md`(R=0Mmu6p6zXRQbOjlItd z7-8o0m|3>-O35AJnH&n7ZeWO!#fPWuMhE5_dk_v2QyYkUGW^2hviJ!uDkU!YlQXyM zJmPCI{mMc`eMYV!5ShybH;_EsUJuONRQOJq(A~IN!!bYfZ1aL6^O5awy;PaVpxu>T z5v&g)R0&wr4Jmfca$MBcl&1phRR`AV&6UUCo?E{F^~}Zbh|@-OjT|yHsb2aF`d>cZ zitx4>YCoqlP*-S|eN*2u9ixDS^_3M%a#9IqZl-LRizJzs56H*u2TEJAFT(wmus$+?poDpz{MC~%MVmK z3En)$v253)g`wG=(OI*Gvq8M0W2ozCwVCGVRa9MqTFrU$n)E3w@~PuR!==B!;TKJ@ zSg&_raimqMd|p{#3+1l%<~g@_z_|(nn$k>?)PT5g8k!S+SW`2%o(r!4$6=}WYmL4Z zRGezZEm0BlKz$@2q@xVVGK{I)(D4sJlKFG!w=D*oQm4zdnZ282N@BIn-T!K=>5-P^ zWqw|l&@J?+jVf2o64Ap|sL*8YhWic=k-w2In+6_sFwa7E*ZN(sy|iSt_852=3hLEg zn)y*0RK`-^<%uRPPl7Sv!~Tw_>+5vv6ia1T)Iy462icF?<&VNI;m|G}E{xPBG5=u?x`qF&#bS0gt~O7_R_6M=sFaY%r}aBD#KC$;ID*f`8u z{cC)%A@|?t#7|_DlYKxzq44vDv3**;f^VEn=4>=Sye76Q2wd6(kEbXe@VONjKxjPY zajI3(ZHmY-f(zMKV%y3JTjk>e`4LFA3NB#FBK-kyc4OA-=aiP8wcLne4GnuTm0!iV}u(GHo9mbfqOTY()x@56sYWxM&)yxcFlnCUJ}eaWO5j;PH&Td?Z)m~7IlQGaH9 zMLL!(n4!Z9@3=g}KHhNCOWe-gsLA87Xk!v|#d|A`cg4lEf6md<+L*W}%b#}1?2}_+ zx64#BxdL`490}LfCsL)skZ5M$pz=u=Cc-rE?{0*%AR<@wSg}wJ*{JxON=?^>r$6yq zhHl*HwvGeVn{u>aQj-a0nIs{F{S4<$6eR{FgYOsq8c!o$T0@CyD*6M*LfXlFrkY)< zTitereM-D#Y{$$tR>TjfQU`Uy?m%7=@2zV)^QR#wN6neUT-{aLsoISN~23EQ+k8*I{imDOTj;d#NR38X-^UA)+S$TuG z#e$Nq(Trv7!w$`{ZN9+9%|Z?rd98)y!sM!Wg^8URsGoGKDgmUwmxLHDNue+jg))Q7 z)ZjPhM}7{EbZbN@XN_aJZ=)`3(OKUTZc-YhSUJu{Ug0d#uc_+`4Y@y-AthI9Zn%Q5 zZ8ayVtJ{qUI77|#Xae5SwsYD0Xq zWHW!PqI~oHGsLDZ3eNexy+<;)xvCfFZ4esuzdtPJYc}W@Lj&pz~QzZ6N5n9}f0H1L5xN=U>neomC$XFBFm<<1m;A+j+5o^7N=qx!%+BH<`2 zpu^FhuQl3Puh=hEj!#K_6Q2|HX#o4q6$XKitZ|f0T@l<6hDhwLctfg^=O0v1BA2T) z;H6s_;3m>yZ6Xe^YrKJW*j;5{u4ute8Tf*`Qjc)sv@}mfBP+e=>P{&6!^36#P9prW zdM)w~0MS8rF{^!RX%AO~LlQ1er$hAGO~RMeIW22w*%Z!6k&^jtLOtXZMm=kT?6Y7} zXK=6J%h=}tn4_o)!eE@zze+eQWvy2ce+~UBLC5N9+v&{X=GOq9tYu-IWe5D)tpRs` z;#9mu(O;?8^6Ju6I5#JWI8(ms=8YF!B=jW4Ug$sNBkM=v5_Kx)hjA|6y58w_drRyjf7f-D5U|taV8J#<7qlf`63Kxl915 z7nUUo9ePOMNL2lp;O2L}l$}j+K(UF|tVE;i`zvJ2Z5_)wZ%CahQ>J4%aP3_14cyT1N=9kv71Dz_fDCXvcK3(GsA)$K zO&xT4G5d~Sv#e+Qu$Oh3j!+X5jT*$_4W#|i%UbF4b=W_@co+FDXk*Rf zwA_1(>)G^ab9EMH3st?tlWCzA{X_@vg>tx)z4Td3gTvxe?iB#+GiL?cIfrb3xkq4x!V!xgGFTr$D|~yN*dHa<&CP3juU$gDqDOVl|ZeaKI*IO zW>tX`zHNbIDl=@YS-9}iOI}pOg-K1M68xitcKBY>b&SO{SDf*TX5{svcAqm` z>EHal%z+TXbw`e6R!JD%Fpw)aeh$v4CgFEK&bY_0#&7OZ@WI$2)wEskwRqCU3;gA7 z=_X2Ny@`iHsO)X%@yc;xuKg~6TTmIO4SZ#f7D2AuR4E-a2-6{vsOpodRPzER=2Nmaa8GS*zWlw_5)vu_ldi?0gNdR`U3Op!O#V8-c7!WPa*Q@Rx z$-xiG;o>;pex`6&oUy=scLX$dW`%bh)0O7P4pPq@N;Dh#eVt_Hq2Ie*?CtZsyGgy$ zOieL>GYIv@)Wy1{2p8SDtnVEodU6f%8a(#7lm&&x!d4tzzeFUQ=Iqa(T9k@h*nVy( z<6KdI;hO?6r=-@tO}K5CvpABIl~PTLaB~CZ><6r*L!nvO*1O8@A?@gnwPQJ#mB;i2 zj~j0m%{VTLi2gxu%fsboy{8u0V*V>BbmqzLp>)2pDyUxbzP{49cl_6{Zdvlq!tQCF zTe0|o_^Gcde4OxaS&ZnVypzDLQ}1!t8KJf^aM^ZXZ_vl~97+cBj^Eu&TL6-8Wsc&h zSCqp3G3e3r%gVz0&miuoASEPd%L%&eyY`qC*~*-;$##F3Qh(uVTr02rfI|b~y=DBLs%kdu(5e7ZLsuqa zP4o+|WuiNPN_CA-@1lMPJ)2r1S&;@?g?s={?mId4dye@j09!bAQU|-VKs9)N6aUGg zp4#fjL6-_1$9iSLGr3?Im=VpO-(?JLdvkku(&U4T94)G2VE?OmXsyiPohRj{v4ucVmLRw^`B z@_0eN)D^Q_T1Q(M^4kAp5LNLOdf%25+jZpTC4(=a#}-w^Fd+4An=}EW*)ijionxiK z{EM_xl~R`WE0434u}mGGB#Fh6Y3Z4P_%VI!2c;OZyR$Oa7XG&~H8HR?6!HFC_k0DNnV(iO~RHv_23c03u0}t)i zGv|j)Mfx1B_ZX%QDmXcnua;<{x+@_a*EBeY|nL?FYs5A zJdZ*~^UMx!R7C&3%{Kp64jLa&J@fkiL;Cj-q7oiYHms|iQL%nZEN_LCdnP?zdh-;Tz-H&AQdkXuif$@$ZryF3%Hg?B?rUpEfxu zvjQ4E%3^%RBZNFR0R8GRV3E#990HGFTQXnKFTNcnEL4yXzMVjhBN+L>C=B#=uxhV? znvkPzo5B3ULOoc%^L4CO_oDkjx8R|}>g0Id#vCH@bFGI=OF1L!jlRXtvS!(^#8HU} z@Tz(>RQI_jKA-f9J?C8r$2_N${eu7F!(?IW z%HEqG!tNeCpCCH`Yi0P@KEBFvv@07DLGB-`Vss#4N}A85qyI`!I&gR&HJJ;ZKp9?o zs5>*HhcYF*EF%)sH-4`d*^Cv~p-hh$fIF}s*Zu9Rs<9gxi(%<`)j&4||Fs`X@*4IC z*na(c&Gd&TfTh<_eHi|2a_VW>Mo1C`mpY-S@VG*x{+JJ=I;|!OzDKr zcP0d}ff$UO!zbB7xhr47U;A_3?$m*^{_j5z8^<+*stjm0sTt3pihV_}d ziqP73CMFlnMWQnAzLd$!gpy?NTN(B9@1&ohqIh%Rfi{c$<>pn@>7c2;6~<5e3DSX{ zxlCHS_TS8hN|82*6s?g#6CobdY^#j22mM;Cs9Y zrnxzsuc8xv*lpbw3hNYpagF`G>>uj_`5+$aYJK4j51@-qXn~M+2B>f7$G7gvpNP96 z0{js7XJ7aOTg9*5fb1yMLW@DNG!&J+u7}Wn=R(-ORzT9wgA1E3M+r) zy-oUFGC+{_yF5nk`%{cRZQvo4WUMIEcIwRJBvfxPxl5o9v>AFNp9~xwR6j8n6fX=a z6afsAOg2S-ka-vskT19f6ZJD2N_cb}l7_v4jA*|J8$6at(@m+<~7|s8nuJpjvCXY}pXZ z7Yr%^qOro0@2DhUeSZEb3Js&Bc1pdwksUe)%X?LUaR?JAU*!d3@hP1# zUYluw!VP{_kTWpWz*ax4Gy3O@B&8OSHuHi^ixV$K29i8AW_L{cMt5n0H(~w{ztu~c zZ!E+ma%Kz^OBSC)))Da*w{x0yvP&~xC%kHV&nEr$%FMq}&EupJCv?KE*Eu&S4h016XZ3@#O zY<6Kb83oG1SfiB!W*UK#c4UT%7;~0J%8b-Hl?KKmZI@5HTC#*TcnX;O%#$*V>H;Jm&;m1+hw<1k zHBMOkuujEJ3N&?r&^gdls`YIb_vgdMlq55B(oIm8b{TKXm;isHh^~zzRv^Slg+h5J z%!Q*5p3X|Q%q4+}-Sq?`WBtP}_mGz%Wno9cY}lwlAa10tXd7q9qq^+r=QDRHWTs?) zWM{@cB_8Zh^>-daMIIW46Y9T*k^S>3|6BQ=ptAp4=>PUZ|4ZWjA0q8PLjUnfD)R83 R{= Date: Sun, 17 Jun 2012 21:57:54 +0300 Subject: [PATCH 53/56] added Renderer Dropdown in RA Settings --- .../Widgets/Logic/SettingsMenuLogic.cs | 28 ++++++++++++++++++- mods/ra/chrome/settings.yaml | 27 +++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs index 74cf654580..a81e9ec86a 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs @@ -1,6 +1,6 @@ #region Copyright & License Information /* - * Copyright 2007-2011 The OpenRA Developers (see AUTHORS) + * Copyright 2007-2012 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, @@ -91,6 +91,11 @@ namespace OpenRA.Mods.RA.Widgets.Logic var display = bg.Get("DISPLAY_PANE"); var gs = Game.Settings.Graphics; + var GraphicsRendererDropdown = display.Get("GRAPHICS_RENDERER"); + GraphicsRendererDropdown.OnMouseDown = _ => ShowRendererDropdown(GraphicsRendererDropdown, gs); + GraphicsRendererDropdown.GetText = () => gs.Renderer == "Gl" ? + "OpenGL" : gs.Renderer == "Cg" ? "Cg Toolkit" : "OpenGL"; + var windowModeDropdown = display.Get("MODE_DROPDOWN"); windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(windowModeDropdown, gs); windowModeDropdown.GetText = () => gs.Mode == WindowMode.Windowed ? @@ -189,5 +194,26 @@ namespace OpenRA.Mods.RA.Widgets.Logic dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); return true; } + + public static bool ShowRendererDropdown(DropDownButtonWidget dropdown, GraphicSettings s) + { + var options = new Dictionary() + { + { "OpenGL", "Gl" }, + { "Cg Toolkit", "Cg" }, + }; + + Func setupItem = (o, itemTemplate) => + { + var item = ScrollItemWidget.Setup(itemTemplate, + () => s.Renderer == options[o], + () => s.Renderer = options[o]); + item.Get("LABEL").GetText = () => o; + return item; + }; + + dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem); + return true; + } } } diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index f31aa1ae9a..e69d5b72a5 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -154,22 +154,35 @@ Background@SETTINGS_MENU: Height:PARENT_BOTTOM - 100 Visible: false Children: - Label@MODE_LABEL: + Label@RENDERER_LABEL: X:0 Y:0 + Width:75 + Height:25 + Text:Renderer: + DropDownButton@GRAPHICS_RENDERER: + X:80 + Y:1 + Width:120 + Height:25 + Font:Regular + Text:OpenGL + Label@MODE_LABEL: + X:0 + Y:30 Width:45 Height:25 Text:Mode: DropDownButton@MODE_DROPDOWN: X:50 - Y:1 + Y:30 Width:170 Height:25 Font:Regular Text:Windowed Container@WINDOW_RESOLUTION: - X:220 - Y:0 + X:225 + Y:30 Children: Label@At: Text:@ @@ -197,14 +210,14 @@ Background@SETTINGS_MENU: Height:25 MaxLength:5 Label@VIDEO_DESC: - Y:25 + Y:60 Width:PARENT_RIGHT Height:25 Font:Tiny Align:Center - Text:Mode/Resolution changes will be applied after the game is restarted + Text:Renderer/Mode/Resolution changes will be applied after the game is restarted. Checkbox@PIXELDOUBLE_CHECKBOX: - Y:50 + Y:90 Width:200 Height:20 Font:Regular From 4f1a7ff5fbea18cdb30c029fad487e9d61284c9f Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 18 Jun 2012 11:22:24 +1200 Subject: [PATCH 54/56] add --transpose option to utility --- OpenRA.Utility/Command.cs | 19 +++++++++++++++++++ OpenRA.Utility/Program.cs | 2 ++ 2 files changed, 21 insertions(+) diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index 0f89cf2ea3..345c4ce74b 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -398,5 +398,24 @@ namespace OpenRA.Utility ShpWriter.Write(destStream, srcImage.Width, srcImage.Height, srcImage.Frames.Select( im => im.Image.Select(px => (byte)remap[px]).ToArray() )); } + + public static void TransposeShp(string[] args) + { + var srcImage = ShpReader.Load(args[1]); + var start = int.Parse(args[3]); + var m = int.Parse(args[4]); + var n = int.Parse(args[5]); + + var srcFrames = srcImage.Frames.ToArray(); + var destFrames = srcImage.Frames.ToArray(); + + for( var i = 0; i < m; i++ ) + for( var j = 0; j < n; j++ ) + destFrames[ start + i*n + j ] = srcFrames[ start + j*m + i ]; + + using( var destStream = File.Create(args[2]) ) + ShpWriter.Write(destStream, srcImage.Width, srcImage.Height, + destFrames.Select(f => f.Image)); + } } } diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index 06e256fddb..47a386e92f 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -28,6 +28,7 @@ namespace OpenRA.Utility { "--tmp-png", Command.ConvertTmpToPng }, { "--remap", Command.RemapShp }, { "--r8", Command.ConvertR8ToPng }, + { "--transpose", Command.TransposeShp }, }; if (args.Length == 0) { PrintUsage(); return; } @@ -61,6 +62,7 @@ namespace OpenRA.Utility Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG"); Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette"); Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--transparent] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally setting up transparency."); + Console.WriteLine(" --transpose SRCSHP DESTSHP START N M Transpose the N*M block of frames starting at START."); } static string GetNamedArg(string[] args, string arg) From 7af0e64708057781b4f50a5de983816909fd34e8 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 18 Jun 2012 20:38:37 +1200 Subject: [PATCH 55/56] allow --transpose to do multiple operations in one pass --- OpenRA.Utility/Command.cs | 16 ++++++++++------ OpenRA.Utility/Program.cs | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/OpenRA.Utility/Command.cs b/OpenRA.Utility/Command.cs index 345c4ce74b..6fc2d02acc 100644 --- a/OpenRA.Utility/Command.cs +++ b/OpenRA.Utility/Command.cs @@ -402,16 +402,20 @@ namespace OpenRA.Utility public static void TransposeShp(string[] args) { var srcImage = ShpReader.Load(args[1]); - var start = int.Parse(args[3]); - var m = int.Parse(args[4]); - var n = int.Parse(args[5]); var srcFrames = srcImage.Frames.ToArray(); var destFrames = srcImage.Frames.ToArray(); - for( var i = 0; i < m; i++ ) - for( var j = 0; j < n; j++ ) - destFrames[ start + i*n + j ] = srcFrames[ start + j*m + i ]; + for( var z = 3; z < args.Length - 2; z += 3 ) + { + var start = int.Parse(args[z]); + var m = int.Parse(args[z+1]); + var n = int.Parse(args[z+2]); + + for( var i = 0; i < m; i++ ) + for( var j = 0; j < n; j++ ) + destFrames[ start + i*n + j ] = srcFrames[ start + j*m + i ]; + } using( var destStream = File.Create(args[2]) ) ShpWriter.Write(destStream, srcImage.Width, srcImage.Height, diff --git a/OpenRA.Utility/Program.cs b/OpenRA.Utility/Program.cs index 47a386e92f..d46783c004 100644 --- a/OpenRA.Utility/Program.cs +++ b/OpenRA.Utility/Program.cs @@ -62,7 +62,7 @@ namespace OpenRA.Utility Console.WriteLine(" --tmp-png MOD[,MOD]* THEATER FILES Extract terrain tiles to PNG"); Console.WriteLine(" --remap SRCMOD:PAL DESTMOD:PAL SRCSHP DESTSHP Remap SHPs to another palette"); Console.WriteLine(" --r8 R8FILE PALETTE START END FILENAME [--transparent] [--infrantry] [--vehicle] [--projectile] [--building] [--wall] [--tileset] Convert Dune 2000 DATA.R8 to PNGs choosing start- and endframe as well as type for correct offset to append multiple frames to one PNG named by filename optionally setting up transparency."); - Console.WriteLine(" --transpose SRCSHP DESTSHP START N M Transpose the N*M block of frames starting at START."); + Console.WriteLine(" --transpose SRCSHP DESTSHP START N M [START N M ...] Transpose the N*M block of frames starting at START."); } static string GetNamedArg(string[] args, string arg) From 21ab0b461cab34c3b879429e62e862a56b9f7c70 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 17 Jun 2012 17:51:25 -0500 Subject: [PATCH 56/56] Added straightforward hover behavior for all units. Give a unit a nonzero Altitude: in its Mobile: block and the WithShadow: trait to make it hover. --- OpenRA.Mods.RA/Move/Mobile.cs | 9 +++------ OpenRA.Mods.RA/Move/Move.cs | 8 ++++++++ OpenRA.Mods.RA/Render/WithShadow.cs | 3 ++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/OpenRA.Mods.RA/Move/Mobile.cs b/OpenRA.Mods.RA/Move/Mobile.cs index 0dddfdd7f0..c674139016 100755 --- a/OpenRA.Mods.RA/Move/Mobile.cs +++ b/OpenRA.Mods.RA/Move/Mobile.cs @@ -30,6 +30,7 @@ namespace OpenRA.Mods.RA.Move public readonly int Speed = 1; public readonly bool OnRails = false; public readonly bool SharesCell = false; + public readonly int Altitude; public virtual object Create(ActorInitializer init) { return new Mobile(init, this); } @@ -110,7 +111,7 @@ namespace OpenRA.Mods.RA.Move int2 __fromCell, __toCell; public SubCell fromSubCell, toSubCell; - int __altitude; + //int __altitude; [Sync] public int Facing @@ -120,11 +121,7 @@ namespace OpenRA.Mods.RA.Move } [Sync] - public int Altitude - { - get { return __altitude; } - set { __altitude = value; } - } + public int Altitude { get; set; } public int ROT { get { return Info.ROT; } } public int InitialFacing { get { return Info.InitialFacing; } } diff --git a/OpenRA.Mods.RA/Move/Move.cs b/OpenRA.Mods.RA/Move/Move.cs index fb4ecbcd5d..15d090d3c4 100755 --- a/OpenRA.Mods.RA/Move/Move.cs +++ b/OpenRA.Mods.RA/Move/Move.cs @@ -95,6 +95,14 @@ namespace OpenRA.Mods.RA.Move public override Activity Tick( Actor self ) { var mobile = self.Trait(); + var info = self.Info.Traits.Get(); + + if (mobile.Altitude != info.Altitude) + { + if (mobile.Altitude < info.Altitude) + ++mobile.Altitude; + return this; + } if (destination == mobile.toCell) return NextActivity; diff --git a/OpenRA.Mods.RA/Render/WithShadow.cs b/OpenRA.Mods.RA/Render/WithShadow.cs index c07a047dba..1419dd0d8a 100644 --- a/OpenRA.Mods.RA/Render/WithShadow.cs +++ b/OpenRA.Mods.RA/Render/WithShadow.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Traits; using OpenRA.Mods.RA.Air; +using OpenRA.Mods.RA.Move; namespace OpenRA.Mods.RA.Render { @@ -25,7 +26,7 @@ namespace OpenRA.Mods.RA.Render var move = self.Trait(); /* rude hack */ - var visualOffset = (move is Helicopter && move.Altitude > 0) + var visualOffset = ((move is Helicopter || move is Mobile) && move.Altitude > 0) ? Math.Abs((self.ActorID + Game.LocalTick) / 5 % 4 - 1) - 1 : 0; var shadowSprites = r.Select(a => a.WithPalette("shadow"));