private TradeRoute ToTradeRoute(Map map, Trade[] trade)
 {
     Trade buy;
     Trade sell;
     if (trade[0].BuySell == Trade.TradeType.Buy)
     {
         buy = trade[0];
         sell = trade[1];
     }
     else
     {
         buy = trade[1];
         sell = trade[0];
     }
     var offset = Map.length / 2;
     var dist = offset / 2;
     var fromX = map.LocationsById[sell.Who].X;
     var fromY = map.LocationsById[sell.Who].Y;
     var toX = map.LocationsById[buy.Who].X;
     var toY = map.LocationsById[buy.Who].Y;
     var signX = Math.Sign(fromX - toX);
     var signY = Math.Sign(fromY - toY);
     var result = new TradeRoute
     {
         From = sell.Who,
         FromX = fromX + offset + dist * signX,
         FromY = fromY + offset + dist * signY,
         To = buy.Who,
         ToX = toX + offset + dist * signX,
         ToY = toY + offset + dist * signY,
         SoldTradeGood = sell,
         BoughtTradeGood = buy
     };
     return result;
 }
 public GatesLayer(Map map)
 {
     Map = map;
     var offset = Map.length / 2;
     Gates =
         new ObservableCollection<Gate>(
         from xelem in XDocument.Load("gates.xml").Descendants("gate")
         let fromLoc = xelem.Element("from").Value
         let toLoc = xelem.Element("to").Value
         let id = xelem.Element("id").Value
         where map.LocationsById.ContainsKey(fromLoc) //TODO: gate detections in cloudlands/faery etc
         where map.LocationsById.ContainsKey(toLoc) //TODO: gate detections in cloudlands/faery etc
         select new Gate
         {
             Id = id,
             From = fromLoc,
             FromX = GetX(map, fromLoc, null) + offset, //no backup values - should be known
             FromY = GetY(map, fromLoc, null) + offset,
             To = toLoc,
             ToX = GetX(map, toLoc, fromLoc) + offset,
             ToY = GetY(map, toLoc, fromLoc) + offset,
             Sealed = Boolean.Parse(xelem.Element("sealed").Value.ToLowerInvariant())
         });
     var gateHits =
         from xelem in XDocument.Load("gate-hits.xml").Descendants("gate-hit")
         let loc = xelem.Element("location").Value
         select new GateHit
         {
             LocationId = loc,
             LocationX = GetX(map, loc, null), //no backup values - should be known
             LocationY = GetY(map, loc, null),
             Origins = xelem.Descendants("origin").Select(e => e.Value)
         };
     var gateDetections  =
         from xelem in XDocument.Load("gate-distances.xml").Descendants("gate-distance")
         let loc = xelem.Element("location").Value
         where map.LocationsById.ContainsKey(loc) //TODO: gate detections in cloudlands/faery etc
         select new GateDetection
         {
             LocationId = loc,
             LocationX = GetX(map, loc, null), //no backup values - should be known
             LocationY = GetY(map, loc, null),
             Distance = Int32.Parse(xelem.Element("distance").Value)
         };
     GateHitsAndDetections =
         new ObservableCollection<object>(gateHits.Cast<object>().Concat(gateDetections));
 }
        public MainWindow()
        {
            InitializeComponent();

            provinia = new Map(Map.Region.Provinia);
            undercity = new Map(Map.Region.Undercity);
            faery = new Map(Map.Region.Faery);
            hades = new Map(Map.Region.Hades);
            cloud = new Map(Map.Region.Cloud);

            nobles = new Nobles(new[] { provinia, undercity, faery, hades, cloud });
            gateLayer = new GatesLayer(provinia);
            tradeRoutesLayer = new TradeRoutesLayer(provinia);
            garrisonLayer = new GarrisonLayer(provinia);

            Provinces.ItemsSource = provinia;
            Tunnels.ItemsSource = undercity;
            Faery.ItemsSource = faery;
            Hades.ItemsSource = hades;
            Cloud.ItemsSource = cloud;

            GatesLayer.ItemsSource = gateLayer.Gates;
            GateHitsLayer.ItemsSource = gateLayer.GateHitsAndDetections;
            TradeRoutesLayer.ItemsSource = tradeRoutesLayer.TradeRoutes;
            GarrisonLayer.ItemsSource = garrisonLayer.Garrisons;
            search.DataContext = provinia;

            Filename = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "olyviewer-temp.txt");

            textEditor.SyntaxHighlighting = LoadHighlightingDefinition("oly.xshd");

            textEditor.TextChanged += new EventHandler(textEditor_TextChanged);
            textEditor.TextArea.TextEntered += new TextCompositionEventHandler(TextArea_TextEntered);
            textEditor.TextArea.TextEntering += new TextCompositionEventHandler(TextArea_TextEntering);
            textEditor.MouseHover += new MouseEventHandler(textEditor_MouseHover);
            textEditor.MouseHoverStopped += new MouseEventHandler(textEditor_MouseHoverStopped);
            textEditor.TextArea.DefaultInputHandler.InputBindings.Add(new InputBinding(new MoveCommand(textEditor,"w"), new KeyGesture(Key.Left, ModifierKeys.Control)));
            textEditor.TextArea.DefaultInputHandler.InputBindings.Add(new InputBinding(new MoveCommand(textEditor,"n"), new KeyGesture(Key.Up, ModifierKeys.Control)));
            textEditor.TextArea.DefaultInputHandler.InputBindings.Add(new InputBinding(new MoveCommand(textEditor,"e"), new KeyGesture(Key.Right, ModifierKeys.Control)));
            textEditor.TextArea.DefaultInputHandler.InputBindings.Add(new InputBinding(new MoveCommand(textEditor,"s"), new KeyGesture(Key.Down, ModifierKeys.Control)));

            foreach (var order in Orders.All)
            {
                var o = new CompletionData(order.Name, order.Help);
                orderCompletionData.Add(o);
            }
        }
 public TradeRoutesLayer(Map map)
 {
     this.map = map;
     var cities = from loc in map.LocationsById.Values
                  where loc is City
                  select loc as City;
     var trades = from city in cities
                  from trade in city.Trades
                  where trade.ItemId.Length > 3 //only keep the actual routes, not the crap like woven baskets etc
                  && trade.Who.Length == 3 //only keep buy/sells from cities
                  select trade;
     var result = (from trade in trades
                  group trade by trade.ItemId into route
                  where route.Count() == 2
                  select route).ToDictionary( r => r.Key, r => ToTradeRoute(map, r.ToArray()));
     TradeRoutes = new ObservableCollection<TradeRoute>(result.Values);
 }
        public GarrisonLayer(Map map)
        {
            Map = map;

            Garrisons = new ObservableCollection<Garrison>(
                from xelem in XDocument.Load("garrisons.xml").Descendants("garrison")
                let id = xelem.Element("id").Value
                where xelem.Element("location-id") != null //some garrisons' location can not be determined
                let locationId = xelem.Element("location-id").Value
                where map.LocationsById.ContainsKey(locationId) //garrisons can be in faery etc
                select new Garrison
                {
                    Id = id,
                    LocationId = locationId,
                    CastleId = xelem.Element("castle-id").Value,
                    GarrisonX = map.LocationsById[locationId].X,
                    GarrisonY = map.LocationsById[locationId].Y + Map.length / 2,
                    Inventory = MakeInventory(xelem)
                });
        }
 private static int GetY(Map map, string loc, string backup)
 {
     Location value;
     if (map.LocationsById.TryGetValue(loc, out value))
         return value.Y;
     else
         return map.LocationsById[backup].Y;
 }