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;
}
foreach (var item in newItems)
{
if (item.Ports.Items == null) continue;
var gameItem = model.GameData_ItemMap[newID];
if (gameItem.Ports.Items == null) continue;
var itemPorts = item.Ports.Items.ToList();
var missingPorts = gameItem.Ports.Items.Where(p => !item.Ports.Items.Select(i => i.PortName).Distinct().Contains(p.Name));
foreach (var port in missingPorts)
{
itemPorts.Add(new Port
{
ItemID = Guid.Empty,
PortName = port.Name,
});
}
item.Ports.Items = itemPorts.ToArray();
}
// TODO: Validate parts - can't because CIG breaks the rules
// Set current ship (Optional)
model.Player.VehicleID = shipID;
model.Save();
ViewBag.ID = id;
return View(model);
}
}
catch (FileNotFoundException)
{
this.Response.StatusCode = 500;
this.Response.TrySkipIisCustomErrors = true;
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;
this.Response.TrySkipIisCustomErrors = true;
return new JsonResult
{
Data = new
{
Reason = "System Error"
}
};
}
}