diff --git a/OpenRa.DataStructures/float2.cs b/OpenRa.DataStructures/float2.cs
index 6b57223279..8c6f3ef20d 100644
--- a/OpenRa.DataStructures/float2.cs
+++ b/OpenRa.DataStructures/float2.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Runtime.InteropServices;
using System.Drawing;
+using System.Runtime.InteropServices;
namespace OpenRa
{
@@ -18,6 +16,7 @@ namespace OpenRa
public float2(SizeF p) { X = p.Width; Y = p.Height; }
public PointF ToPointF() { return new PointF(X, Y); }
+ public SizeF ToSizeF() { return new SizeF(X, Y); }
public static implicit operator float2(int2 src) { return new float2(src.X, src.Y); }
diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs
new file mode 100644
index 0000000000..7a3a8b31f4
--- /dev/null
+++ b/OpenRa.Game/Controller.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace OpenRa.Game
+{
+ class Controller
+ {
+ Game game;
+
+ public IOrderGenerator orderGenerator;
+
+ public Controller(Game game)
+ {
+ this.game = game;
+ }
+
+ public void WorldClicked(object sender, MouseEventArgs e)
+ {
+ var xy = (1 / 24.0f) * (new float2(e.Location) + game.viewport.Location);
+ if (orderGenerator != null)
+ orderGenerator.Order(game, new int2((int)xy.X, (int)xy.Y)).Apply(game);
+ // todo: route all orders through netcode
+ }
+ }
+}
diff --git a/OpenRa.Game/Game Code.cd b/OpenRa.Game/Game Code.cd
new file mode 100644
index 0000000000..cef986620c
--- /dev/null
+++ b/OpenRa.Game/Game Code.cd
@@ -0,0 +1,234 @@
+
+
+
+
+
+ AAAAgAAAAAAAgAAAAAAAAAAAAAAAAAAIAAAAAIAAQAA=
+ Actor.cs
+
+
+
+
+
+ AAaAACBBAAAAAiAAAIACBgAAAAAAAAAIAAAAAAgAAAA=
+ World.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA=
+ Building.cs
+
+
+
+
+
+ AAEAEAAAAIAAAgAABAAAIAAQAAAAAQAAJAAAAABAQAA=
+ Game.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAABAAAAAKIEAACAAAgAI=
+ MainWindow.cs
+
+
+
+
+
+ AAAAAAAAABAAAAAAIAAAAAAAAAAAAAAEAAAAAAAAAAA=
+ MoveOrder.cs
+
+
+
+
+
+ AAAAAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ MoveOrder.cs
+
+
+
+
+
+ AAAAAAAAABAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ MoveOrder.cs
+
+
+
+
+
+ AAAAEAAAAAAAABAAAAAAAAAAAAAEEAAAMAAAAAAAAAA=
+ PathFinder.cs
+
+
+
+
+
+ AAEAAAAAAAAAAAAAAAAAACAAAgAAAAAAAAAAAAAAAAA=
+ Player.cs
+
+
+
+
+
+ AAAAgAAAAAAAIAAAAAAAAIACAAAAAAAAAgAAAIAAAAA=
+ PlayerOwned.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Refinery.cs
+
+
+
+
+
+ AAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Rules.cs
+
+
+
+
+
+ AACAAAQAgECAAGAAEAgCAEAACABAiIAIAAAAIAC8AAA=
+ Sidebar.cs
+
+
+
+
+
+ AAEAAACAAAAAAAAAAAAAAAQAAAAAAAAAAAAAQAAAAAA=
+ Sidebar.cs
+
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAACEBAAACAAAAAAAAAIAAA=
+ SidebarItem.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAIAAAAAABAAAAAAAAAAAAAAAAAAAAA=
+ TerrainCosts.cs
+
+
+
+
+
+ gAAAgAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAIAAAAA=
+ Tree.cs
+
+
+
+
+
+ AAAAAAAAAIAAAiQAQAAQIABAQAAgAAAYAAAAAAQAAAA=
+ UiOverlay.cs
+
+
+
+
+
+ AAEAgDgAAAAAAAAAAAAAAAEAAAEGAAgAAAAERAAAQAA=
+ Unit.cs
+
+
+
+
+
+
+ AIAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAA=
+ UnitInfo.cs
+
+
+
+
+
+
+
+
+ AAAAAAAAAYAAAAAAAAACAAABAAAAAAAAABAAAAAAAAA=
+ UnitMissions.cs
+
+
+
+
+
+ AAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ MoveOrder.cs
+
+
+
+
+
+ EAAAAAAAABAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Sidebar.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAIAAAEAAAAAAAAAAAQAAAAAAAAAAAA=
+ PathFinder.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAQAAAIAQAAAAAAAAAAAAAAAAAAAAAA=
+ PathFinder.cs
+
+
+
+
+
+
+ AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA=
+ IOrderGenerator.cs
+
+
+
+
+
+ AAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAQAAAAAAAiAAA=
+ TerrainCosts.cs
+
+
+
+
+
+ AAAAAAABAAAAAAAAIEAAAAAAAABgAAQgAAAAAABQAAA=
+ TerrainCosts.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAIBAAAAAAAAA=
+ UnitMissions.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAEAAAA=
+ Race.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAA=
+ UnitMissions.cs
+
+
+
+
\ No newline at end of file
diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs
index e23b35d36f..fb91c4947c 100644
--- a/OpenRa.Game/Game.cs
+++ b/OpenRa.Game/Game.cs
@@ -15,14 +15,18 @@ namespace OpenRa.Game
public readonly Viewport viewport;
public readonly PathFinder pathFinder;
public readonly Network network;
+ public readonly WorldRenderer worldRenderer;
+ public readonly Controller controller;
- public int localPlayerIndex = 1;
+ int localPlayerIndex = 1;
public readonly Dictionary players = new Dictionary();
// temporary, until we remove all the subclasses of Building
public Dictionary> buildingCreation = new Dictionary>();
+ public Player LocalPlayer { get { return players[localPlayerIndex]; } }
+
public Game(string mapName, Renderer renderer, int2 clientSize)
{
for (int i = 0; i < 8; i++)
@@ -34,7 +38,7 @@ namespace OpenRa.Game
viewport = new Viewport(clientSize, map.Size, renderer);
terrain = new TerrainRenderer(renderer, map, viewport);
- world = new World(renderer, this);
+ world = new World(this);
treeCache = new TreeCache(map);
foreach (TreeReference treeReference in map.Trees)
@@ -48,20 +52,18 @@ namespace OpenRa.Game
string[] buildings = { "fact", "powr", "apwr", "weap", "barr", "atek", "stek", "dome" };
foreach (string s in buildings)
- AddBuilding(s);
- }
+ buildingCreation.Add(s, (location, owner) => new Building(s, location, owner, this));
- void AddBuilding(string name)
- {
- buildingCreation.Add(name, (location, owner) => new Building(name, location, owner, this));
+ controller = new Controller(this); // CAREFUL THERES AN UGLY HIDDEN DEPENDENCY HERE STILL
+ worldRenderer = new WorldRenderer(renderer, world);
}
public void Tick()
{
- viewport.DrawRegions(this);
- Queue stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
- }
+ var stuffFromOtherPlayers = network.Tick(); // todo: actually use the orders!
+ world.Update();
- public void Issue(IOrder order) { order.Apply(this); }
+ viewport.DrawRegions(this);
+ }
}
}
diff --git a/OpenRa.Game/Graphics/Viewport.cs b/OpenRa.Game/Graphics/Viewport.cs
index 9ba0db84db..1bc83e6b78 100644
--- a/OpenRa.Game/Graphics/Viewport.cs
+++ b/OpenRa.Game/Graphics/Viewport.cs
@@ -28,10 +28,8 @@ namespace OpenRa.Game.Graphics
}
List regions = new List();
- public void AddRegion(Region r)
- {
- regions.Add(r);
- }
+
+ public void AddRegion(Region r) { regions.Add(r); }
public void DrawRegions(Game game)
{
@@ -46,9 +44,6 @@ namespace OpenRa.Game.Graphics
renderer.EndFrame();
}
- public IEnumerable Regions
- {
- get { return regions; }
- }
+ public IEnumerable Regions { get { return regions; } }
}
}
diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs
new file mode 100644
index 0000000000..d060b4bbae
--- /dev/null
+++ b/OpenRa.Game/Graphics/WorldRenderer.cs
@@ -0,0 +1,48 @@
+using System.Drawing;
+using System.Windows.Forms;
+
+namespace OpenRa.Game.Graphics
+{
+ class WorldRenderer
+ {
+ public readonly SpriteRenderer spriteRenderer;
+ public readonly World world;
+ public readonly Region region;
+ public readonly UiOverlay uiOverlay;
+
+ public WorldRenderer(Renderer renderer, World world)
+ {
+ // TODO: this is layout policy. it belongs at a higher level than this.
+
+ region = Region.Create(world.game.viewport, DockStyle.Left,
+ world.game.viewport.Width - 128, Draw, world.game.controller.WorldClicked); // TODO: world.WorldClicked is part of the CONTROLLER
+ world.game.viewport.AddRegion(region);
+
+ spriteRenderer = new SpriteRenderer(renderer, true);
+ uiOverlay = new UiOverlay(spriteRenderer, world.game);
+ this.world = world;
+ }
+
+ public void Draw()
+ {
+ var rect = new RectangleF(region.Location.ToPointF(), region.Size.ToSizeF());
+
+ foreach (Actor a in world.Actors)
+ {
+ Sprite[] images = a.CurrentImages;
+ float2 loc = a.RenderLocation;
+
+ if (loc.X > rect.Right || loc.X < rect.Left - images[0].bounds.Width)
+ continue;
+
+ if (loc.Y > rect.Bottom || loc.Y < rect.Top - images[0].bounds.Height)
+ continue;
+
+ foreach (Sprite image in images)
+ spriteRenderer.DrawSprite(image, loc, (a.owner != null) ? a.owner.Palette : 0);
+ }
+
+ spriteRenderer.Flush();
+ }
+ }
+}
diff --git a/OpenRa.Game/IOrderGenerator.cs b/OpenRa.Game/IOrderGenerator.cs
index 74ec7ca9c6..cf605dc73a 100644
--- a/OpenRa.Game/IOrderGenerator.cs
+++ b/OpenRa.Game/IOrderGenerator.cs
@@ -6,7 +6,7 @@ namespace OpenRa.Game
{
interface IOrderGenerator
{
- IOrder Order( Game game, int2 xy );
+ Order Order( Game game, int2 xy );
void PrepareOverlay( Game game, int2 xy );
}
}
diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs
index d541db0fae..10f1c22715 100644
--- a/OpenRa.Game/MainWindow.cs
+++ b/OpenRa.Game/MainWindow.cs
@@ -47,7 +47,7 @@ namespace OpenRa.Game
game.world.Add( new Unit( "mcv", new int2( 5, 5 ), game.players[ 3 ], game ) );
game.world.Add( new Unit( "mcv", new int2( 7, 5 ), game.players[ 2 ], game ) );
Unit mcv = new Unit( "mcv", new int2( 9, 5 ), game.players[ 1 ], game );
- game.world.orderGenerator = mcv;
+ game.controller.orderGenerator = mcv;
game.world.Add( mcv );
sidebar = new Sidebar(Race.Soviet, renderer, game);
@@ -72,7 +72,7 @@ namespace OpenRa.Game
lastPos = new int2(e.Location);
if (e.Button == MouseButtons.Left)
- foreach (GRegion region in game.viewport.Regions)
+ foreach (var region in game.viewport.Regions)
if (region.Contains(lastPos))
region.Clicked(e);
}
@@ -88,8 +88,8 @@ namespace OpenRa.Game
lastPos = p;
}
- if (game.world.orderGenerator != null)
- game.world.orderGenerator.PrepareOverlay(game,
+ if (game.controller.orderGenerator != null)
+ game.controller.orderGenerator.PrepareOverlay(game,
new int2(e.Location.X / 24, e.Location.Y / 24));
}
}
diff --git a/OpenRa.Game/MoveOrder.cs b/OpenRa.Game/MoveOrder.cs
index 87aeebb36f..80cbf96671 100644
--- a/OpenRa.Game/MoveOrder.cs
+++ b/OpenRa.Game/MoveOrder.cs
@@ -4,12 +4,12 @@ using System.Text;
namespace OpenRa.Game
{
- interface IOrder
+ abstract class Order
{
- void Apply( Game game );
+ public abstract void Apply( Game game );
}
- class MoveOrder : IOrder
+ class MoveOrder : Order
{
public readonly Unit Unit;
public readonly int2 Destination;
@@ -20,13 +20,13 @@ namespace OpenRa.Game
this.Destination = destination;
}
- public void Apply( Game game )
+ public override void Apply( Game game )
{
Unit.nextOrder = UnitMissions.Move( Unit, Destination );
}
}
- class DeployMcvOrder : IOrder
+ class DeployMcvOrder : Order
{
Unit unit;
@@ -35,13 +35,13 @@ namespace OpenRa.Game
this.unit = unit;
}
- public void Apply( Game game )
+ public override void Apply( Game game )
{
unit.nextOrder = UnitMissions.Deploy( unit );
}
}
- class HarvestOrder : IOrder
+ class HarvestOrder : Order
{
Unit unit;
@@ -50,7 +50,7 @@ namespace OpenRa.Game
this.unit = unit;
}
- public void Apply( Game game )
+ public override void Apply( Game game )
{
unit.nextOrder = UnitMissions.Harvest( unit );
}
diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj
index 4fb47ae327..af776e909b 100644
--- a/OpenRa.Game/OpenRa.Game.csproj
+++ b/OpenRa.Game/OpenRa.Game.csproj
@@ -71,9 +71,11 @@
+
+
@@ -81,7 +83,7 @@
-
+
@@ -148,6 +150,7 @@
+
diff --git a/OpenRa.Game/Refinery.cs b/OpenRa.Game/Refinery.cs
index 5f03dd087f..38721123a9 100644
--- a/OpenRa.Game/Refinery.cs
+++ b/OpenRa.Game/Refinery.cs
@@ -15,7 +15,7 @@ namespace OpenRa.Game
Unit harvester = new Unit( "harv", location + new int2( 1, 2 ), owner, game );
harvester.facing = 8;
game.world.Add(harvester);
- game.world.orderGenerator = harvester;
+ game.controller.orderGenerator = harvester;
});
});
}
diff --git a/OpenRa.Game/Sidebar.cs b/OpenRa.Game/Sidebar.cs
index 888ac68a60..465776a8e2 100644
--- a/OpenRa.Game/Sidebar.cs
+++ b/OpenRa.Game/Sidebar.cs
@@ -31,7 +31,7 @@ namespace OpenRa.Game
public Sidebar( Race race, Renderer renderer, Game game )
{
- this.techTree = game.players[ game.localPlayerIndex ].TechTree;
+ this.techTree = game.LocalPlayer.TechTree;
this.game = game;
region = GRegion.Create(game.viewport, DockStyle.Right, 128, Paint, MouseHandler);
game.viewport.AddRegion( region );
@@ -49,7 +49,7 @@ namespace OpenRa.Game
public void Build(SidebarItem item)
{
if (item != null)
- game.world.orderGenerator = new PlaceBuilding(game.players[1], item.techTreeItem.tag.ToLowerInvariant());
+ game.controller.orderGenerator = new PlaceBuilding(game.players[1], item.techTreeItem.tag.ToLowerInvariant());
}
void LoadSprites(string filename)
@@ -132,16 +132,16 @@ namespace OpenRa.Game
class PlaceBuilding : IOrderGenerator
{
- Player owner;
- string buildingName;
+ public readonly Player Owner;
+ public readonly string Name;
- public PlaceBuilding( Player owner, string buildingName )
+ public PlaceBuilding( Player owner, string name )
{
- this.owner = owner;
- this.buildingName = buildingName;
+ Owner = owner;
+ Name = name;
}
- public IOrder Order( Game game, int2 xy )
+ public Order Order( Game game, int2 xy )
{
// todo: check that space is free
return new PlaceBuildingOrder( this, xy );
@@ -149,34 +149,34 @@ namespace OpenRa.Game
public void PrepareOverlay(Game game, int2 xy)
{
- game.world.uiOverlay.SetCurrentOverlay(false, xy, 2, 3);
+ game.worldRenderer.uiOverlay.SetCurrentOverlay(false, xy, 2, 3);
+ }
+ }
+
+ class PlaceBuildingOrder : Order
+ {
+ PlaceBuilding building;
+ int2 xy;
+
+ public PlaceBuildingOrder(PlaceBuilding building, int2 xy)
+ {
+ this.building = building;
+ this.xy = xy;
}
- class PlaceBuildingOrder : IOrder
+ public override void Apply(Game game)
{
- PlaceBuilding building;
- int2 xy;
-
- public PlaceBuildingOrder( PlaceBuilding building, int2 xy )
+ game.world.AddFrameEndTask(_ =>
{
- this.building = building;
- this.xy = xy;
- }
-
- public void Apply( Game game )
- {
- game.world.AddFrameEndTask( _ =>
+ Func newBuilding;
+ if (game.buildingCreation.TryGetValue(building.Name, out newBuilding))
{
- Func newBuilding;
- if( game.buildingCreation.TryGetValue( building.buildingName, out newBuilding ) )
- {
- Log.Write( "Player \"{0}\" builds {1}", building.owner.PlayerName, building.buildingName );
- game.world.Add( newBuilding( xy, building.owner ) );
- }
- game.world.orderGenerator = null;
- game.world.uiOverlay.KillOverlay();
- } );
- }
+ Log.Write("Player \"{0}\" builds {1}", building.Owner.PlayerName, building.Name);
+ game.world.Add(newBuilding(xy, building.Owner));
+ }
+ game.controller.orderGenerator = null;
+ game.worldRenderer.uiOverlay.KillOverlay();
+ });
}
}
}
diff --git a/OpenRa.Game/Support/SharedResources.cs b/OpenRa.Game/Support/SharedResources.cs
new file mode 100644
index 0000000000..efc22425dd
--- /dev/null
+++ b/OpenRa.Game/Support/SharedResources.cs
@@ -0,0 +1,13 @@
+using IjwFramework.Types;
+using OpenRa.FileFormats;
+
+namespace OpenRa.Game
+{
+ class SharedResources
+ {
+ static Lazy rules = new Lazy(
+ () => new IniFile( FileSystem.Open( "rules.ini" )));
+
+ public static IniFile Rules { get { return rules.Value; } }
+ }
+}
diff --git a/OpenRa.Game/UiOverlay.cs b/OpenRa.Game/UiOverlay.cs
index 037b18ccb1..3e8d370293 100644
--- a/OpenRa.Game/UiOverlay.cs
+++ b/OpenRa.Game/UiOverlay.cs
@@ -39,6 +39,8 @@ namespace OpenRa.Game
for (int j = 0; j < height; j++)
spriteRenderer.DrawSprite(blocked ? buildBlocked : buildOk,
24 * (position + new int2(i, j)) + game.viewport.Location, 0);
+
+ spriteRenderer.Flush();
}
bool blocked, hasOverlay;
diff --git a/OpenRa.Game/Unit.cs b/OpenRa.Game/Unit.cs
index 34651138d7..4b9bd67528 100644
--- a/OpenRa.Game/Unit.cs
+++ b/OpenRa.Game/Unit.cs
@@ -83,7 +83,7 @@ namespace OpenRa.Game
return mission == ( unitInfo.supportedMissions & mission );
}
- public IOrder Order( Game game, int2 xy )
+ public Order Order( Game game, int2 xy )
{
if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy )
{
diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs
index d07f81c5e8..3a14768b2b 100644
--- a/OpenRa.Game/World.cs
+++ b/OpenRa.Game/World.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
-using Ijw.DirectX;
-using OpenRa.Game.Graphics;
namespace OpenRa.Game
{
@@ -10,22 +8,10 @@ namespace OpenRa.Game
{
List actors = new List();
List> frameEndActions = new List>();
- SpriteRenderer spriteRenderer;
- Game game;
- Region region;
- public IOrderGenerator orderGenerator;
- public UiOverlay uiOverlay;
- public World(Renderer renderer, Game game)
- {
- region = Region.Create(game.viewport, DockStyle.Left, game.viewport.Width - 128, Draw, WorldClicked);
- this.game = game;
- game.viewport.AddRegion(region);
-
- spriteRenderer = new SpriteRenderer(renderer, true);
+ public readonly Game game;
- uiOverlay = new UiOverlay(spriteRenderer, game);
- }
+ public World(Game game) { this.game = game; }
public void Add(Actor a) { actors.Add(a); }
public void Remove( Actor a ) { actors.Remove( a ); }
@@ -33,46 +19,21 @@ namespace OpenRa.Game
int lastTime = Environment.TickCount;
- void WorldClicked(object sender, MouseEventArgs e)
- {
- float2 xy = (1 / 24.0f) * (new float2(e.Location) + game.viewport.Location);
- if (orderGenerator != null)
- {
- IOrder order = orderGenerator.Order(game, new int2((int)xy.X, (int)xy.Y));
- game.Issue(order);
- }
- }
- void Draw()
+
+ public void Update()
{
int t = Environment.TickCount;
int dt = t - lastTime;
lastTime = t;
- var range = new Range(region.Location, region.Location + region.Size);
-
foreach (Actor a in actors)
- {
- a.Tick( game, dt );
-
- Sprite[] images = a.CurrentImages;
- float2 loc = a.RenderLocation;
-
- if( loc.X > range.End.X || loc.X < range.Start.X - images[ 0 ].bounds.Width )
- continue;
-
- if( loc.Y > range.End.Y || loc.Y < range.Start.Y - images[ 0 ].bounds.Height )
- continue;
-
- foreach( Sprite image in images )
- spriteRenderer.DrawSprite(image, loc, (a.owner != null) ? a.owner.Palette : 0);
- }
+ a.Tick(game, dt);
foreach (Action a in frameEndActions) a(this);
frameEndActions.Clear();
-
- uiOverlay.Draw();
- spriteRenderer.Flush();
}
+
+ public IEnumerable Actors { get { return actors; } }
}
}