public ActionResult Ship(String id, Guid shipID, Guid newID, Guid?parentID, String portName) { try { HoloTableController._lockMap[id] = HoloTableController._lockMap.GetValue(id, new Object()); lock (HoloTableController._lockMap[id]) { var model = new DetailModel(id, shipID); // Parents being equipped var parentItems = model.Player.Items.Where(i => i.ID == parentID).ToArray(); // Ports being equipped var newShipPorts = model.Player.Ships.Where(s => s.ID == shipID).Where(s => s.Ports != null).Where(s => s.Ports.Items != null).SelectMany(s => s.Ports.Items).Where(p => p.PortName == portName).ToArray(); var newItemPorts = model.Player.Items.Where(i => i.ID == parentID).Where(i => i.Ports != null).Where(i => i.Ports.Items != null).SelectMany(i => i.Ports.Items).Where(p => p.PortName == portName).ToArray(); var newPorts = newShipPorts.Concat(newItemPorts).ToArray(); // Item IDs being replaced var oldItemIDs = new HashSet <Guid>(newPorts.Select(p => p.ItemID)); // Items being replaced var oldItems = model.Player.Items.Where(i => oldItemIDs.Contains(i.ID)).ToArray(); var oldIDs = new HashSet <Guid>(oldItems.SelectMany(i => this.FlattenIDs(model, i))); // Inventory being moved var oldHangarInventory = model.Player.Inventory.Items.Where(i => oldIDs.Contains(i.ID)); var oldShipInventory = model.Player.Ships.Where(s => s.Inventory != null).Where(s => s.Inventory.Items != null).SelectMany(s => s.Inventory.Items.Where(i => oldIDs.Contains(i.ID))); var oldInventory = oldShipInventory.Union(oldHangarInventory).ToArray(); // Items being equipped var newItems = model.Player.Items.Where(i => i.ID == newID).ToArray(); var newIDs = new HashSet <Guid>(newItems.SelectMany(i => this.FlattenIDs(model, i))); // Inventory being moved var newHangarInventory = model.Player.Inventory.Items.Where(i => newIDs.Contains(i.ID)); var newShipInventory = model.Player.Ships.Where(s => s.Inventory != null).Where(s => s.Inventory.Items != null).SelectMany(s => s.Inventory.Items.Where(i => newIDs.Contains(i.ID))); var newInventory = newShipInventory.Union(newHangarInventory).ToArray(); // Old ports var oldShipPorts = model.Player.Ships.Where(s => s.Ports != null).Where(s => s.Ports.Items != null).SelectMany(s => s.Ports.Items).Where(p => p.ItemID == newID).Where(p => p.ItemID != Guid.Empty).ToArray(); var oldItemPorts = model.Player.Items.Where(i => i.Ports != null).Where(i => i.Ports.Items != null).SelectMany(i => i.Ports.Items).Where(p => p.ItemID == newID).Where(p => p.ItemID != Guid.Empty).ToArray(); var oldPorts = oldItemPorts.Concat(oldShipPorts).ToArray(); // Configure Ship inventory foreach (var ship in model.Player.Ships.Where(s => s.Inventory != null).Where(s => s.Inventory.Items != null)) { ship.Inventory.Items = ship.Inventory.Items.Where(i => !oldIDs.Contains(i.ID)).Where(i => !newIDs.Contains(i.ID)).ToArray(); if (ship.ID == shipID) { ship.Inventory.Items = ship.Inventory.Items.Union(newInventory).ToArray(); } } // Configure Player inventory var shipItemIDs = new HashSet <Guid>(model.Player.Ships.Where(s => s.Inventory != null).Where(s => s.Inventory.Items != null).SelectMany(s => s.Inventory.Items).Select(i => i.ID)); model.Player.Inventory = new Inventory.Inventory { Items = model.Player.Items.Where(i => !shipItemIDs.Contains(i.ID)).Select(i => new Inventory.InventoryItem { ID = i.ID }).ToArray() }; var oldPort = oldPorts.SingleOrDefault(); if (oldPort != null) { oldPort.ItemID = oldItemIDs.Distinct().SingleOrDefault(); } var newPort = newPorts.SingleOrDefault(); if (newPort != null) { newPort.ItemID = newID; } // TODO: Validate parts // Set current ship (Optional) model.Player.VehicleID = shipID; model.Save(); ViewBag.ID = id; return(View(model)); } } catch (FileNotFoundException) { this.Response.StatusCode = 500; return(new JsonResult { Data = new { Reason = "Hangar Removed" } }); } catch (Exception ex) { Elmah.ErrorLog.GetDefault(System.Web.HttpContext.Current).Log(new Elmah.Error(ex)); this.Response.StatusCode = 500; return(new JsonResult { Data = new { Reason = "System Error" } }); } }
public DetailViewModel(DetailModel _model) { Model = _model.AddTo(DisposeCollection); InputTitle = Model.ShownTask.Select(t => t?.TitleString ?? "").ToReactiveProperty("", ReactivePropertyMode.DistinctUntilChanged).AddTo(DisposeCollection); InputExplain = Model.ShownTask.Select(t => t?.ExplainString ?? "").ToReactiveProperty("", ReactivePropertyMode.DistinctUntilChanged).AddTo(DisposeCollection); InputStatus = Model.ShownTask.Select(t => t?.Status ?? Status.Ready).ToReactiveProperty(Status.Ready, ReactivePropertyMode.DistinctUntilChanged).AddTo(DisposeCollection); InputTitle.Where(s => (Model.ShownTask.Value?.Title ?? null) != Domain.Title.Create(s)).Subscribe(s => Model.Save(Domain.Title.Create(s))).AddTo(DisposeCollection); InputExplain.Where(s => (Model.ShownTask.Value?.Explain ?? null) != Domain.Explain.Create(s)).Subscribe(s => Model.Save(Domain.Explain.Create(s))).AddTo(DisposeCollection); InputStatus.Where(s => (Model.ShownTask.Value?.Status ?? null) != s).Subscribe(s => Model.Save(s)).AddTo(DisposeCollection); }