258 lines
6.6 KiB
C#
258 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using Comfort.Common;
|
|
using EFT;
|
|
using EFT.InventoryLogic;
|
|
using UnityEngine;
|
|
|
|
public class ItemFactory
|
|
{
|
|
public class ContainerCollection
|
|
{
|
|
private static Type _containerCollectionType;
|
|
|
|
private static PropertyInfo _containersProperty;
|
|
|
|
private static MethodInfo _getContainerMethod;
|
|
|
|
private static MethodInfo _tryFindItemMethod;
|
|
|
|
public IEnumerable<IContainer> Containers
|
|
{
|
|
get
|
|
{
|
|
if (_containersProperty != null)
|
|
{
|
|
return (IEnumerable<IContainer>)_containersProperty.GetValue(this);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
static ContainerCollection()
|
|
{
|
|
LoadContainerCollectionType();
|
|
}
|
|
|
|
private static void LoadContainerCollectionType()
|
|
{
|
|
Assembly assembly = Assembly.Load("Assembly-CSharp");
|
|
if (assembly == null)
|
|
{
|
|
Log("Log: Failed to load Assembly-CSharp.");
|
|
return;
|
|
}
|
|
Type[] types = assembly.GetTypes();
|
|
foreach (Type type in types)
|
|
{
|
|
if (type.Name == "\uecea")
|
|
{
|
|
_containerCollectionType = type;
|
|
break;
|
|
}
|
|
}
|
|
if (!(_containerCollectionType == null))
|
|
{
|
|
_containersProperty = _containerCollectionType.GetProperty("Containers", BindingFlags.Instance | BindingFlags.Public);
|
|
_getContainerMethod = _containerCollectionType.GetMethod("GetContainer", BindingFlags.Instance | BindingFlags.Public);
|
|
_tryFindItemMethod = _containerCollectionType.GetMethod("TryFindItem", BindingFlags.Instance | BindingFlags.Public);
|
|
}
|
|
}
|
|
|
|
public IContainer GetContainer(string containerId)
|
|
{
|
|
if (_getContainerMethod != null)
|
|
{
|
|
return (IContainer)_getContainerMethod.Invoke(this, new object[1] { containerId });
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public bool TryFindItem(string itemId, out Item item)
|
|
{
|
|
item = null;
|
|
if (_tryFindItemMethod != null)
|
|
{
|
|
object[] array = new object[2] { itemId, null };
|
|
bool result = (bool)_tryFindItemMethod.Invoke(this, array);
|
|
item = (Item)array[1];
|
|
return result;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static void Log(string message)
|
|
{
|
|
using StreamWriter streamWriter = new StreamWriter(Path.Combine(Application.persistentDataPath, "log.txt"), append: true);
|
|
streamWriter.WriteLine($"{DateTime.Now}: {message}");
|
|
}
|
|
}
|
|
|
|
public class GridHelper
|
|
{
|
|
public LocationInGrid FindFreeSpace(Item item, dynamic grid)
|
|
{
|
|
_E374 obj = item.CalculateCellSize();
|
|
int x = obj.X;
|
|
int y = obj.Y;
|
|
int num = grid.GridWidth;
|
|
int num2 = grid.GridHeight;
|
|
dynamic val = grid.ItemCollection;
|
|
dynamic occupiedSpaces = GetOccupiedSpaces(val);
|
|
LocationInGrid locationInGrid = TryFindLocation(x, y, num, num2, occupiedSpaces);
|
|
if (locationInGrid == null && x != y)
|
|
{
|
|
locationInGrid = TryFindLocation(y, x, num, num2, occupiedSpaces);
|
|
}
|
|
if (locationInGrid == null)
|
|
{
|
|
locationInGrid = HandleStretching(x, y, grid, num, num2);
|
|
}
|
|
return locationInGrid;
|
|
}
|
|
|
|
private Dictionary<(int, int), bool> GetOccupiedSpaces(dynamic itemCollection)
|
|
{
|
|
Dictionary<(int, int), bool> dictionary = new Dictionary<(int, int), bool>();
|
|
foreach (dynamic item in itemCollection.Values)
|
|
{
|
|
dynamic val = item.Position;
|
|
dynamic val2 = item.CalculateCellSize();
|
|
int num = val2.X;
|
|
int num2 = val2.Y;
|
|
for (int i = val.X; i < val.X + num; i++)
|
|
{
|
|
for (int j = val.Y; j < val.Y + num2; j++)
|
|
{
|
|
dictionary[(i, j)] = true;
|
|
}
|
|
}
|
|
}
|
|
return dictionary;
|
|
}
|
|
|
|
private LocationInGrid TryFindLocation(int itemWidth, int itemHeight, int gridWidth, int gridHeight, Dictionary<(int, int), bool> occupiedSpaces)
|
|
{
|
|
for (int i = 0; i <= gridWidth - itemWidth; i++)
|
|
{
|
|
for (int j = 0; j <= gridHeight - itemHeight; j++)
|
|
{
|
|
if (IsSpaceAvailable(i, j, itemWidth, itemHeight, occupiedSpaces))
|
|
{
|
|
return new LocationInGrid(i, j, ItemRotation.Horizontal);
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private bool IsSpaceAvailable(int startX, int startY, int itemWidth, int itemHeight, Dictionary<(int, int), bool> occupiedSpaces)
|
|
{
|
|
for (int i = startX; i < startX + itemWidth; i++)
|
|
{
|
|
for (int j = startY; j < startY + itemHeight; j++)
|
|
{
|
|
if (occupiedSpaces.ContainsKey((i, j)))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private LocationInGrid HandleStretching(int itemWidth, int itemHeight, dynamic grid, int gridWidth, int gridHeight)
|
|
{
|
|
if (grid.CanStretchHorizontally && gridHeight >= gridWidth + itemWidth)
|
|
{
|
|
return new LocationInGrid(gridWidth, 0, ItemRotation.Horizontal);
|
|
}
|
|
if (grid.CanStretchVertically && (itemWidth <= gridWidth || grid.CanStretchHorizontally))
|
|
{
|
|
return new LocationInGrid(0, gridHeight, ItemRotation.Vertical);
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static string _logFilePath;
|
|
|
|
private static Type _itemFactoryType;
|
|
|
|
private static MethodInfo _createItemMethod;
|
|
|
|
private static object _singletonInstance;
|
|
|
|
static ItemFactory()
|
|
{
|
|
LoadItemFactoryType();
|
|
}
|
|
|
|
private static void LoadItemFactoryType()
|
|
{
|
|
Assembly assembly = Assembly.Load("Assembly-CSharp");
|
|
if (assembly == null)
|
|
{
|
|
return;
|
|
}
|
|
Type[] types = assembly.GetTypes();
|
|
foreach (Type type in types)
|
|
{
|
|
_createItemMethod = type.GetMethod("CreateItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
|
if (_createItemMethod != null)
|
|
{
|
|
_itemFactoryType = type;
|
|
break;
|
|
}
|
|
}
|
|
if (!(_itemFactoryType == null))
|
|
{
|
|
PropertyInfo property = typeof(Singleton<>).MakeGenericType(_itemFactoryType).GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
|
|
if (property != null)
|
|
{
|
|
_singletonInstance = property.GetValue(null);
|
|
}
|
|
}
|
|
}
|
|
|
|
public Item CreateItem(string id)
|
|
{
|
|
if (_createItemMethod == null || _singletonInstance == null)
|
|
{
|
|
return null;
|
|
}
|
|
string text = MongoID.Generate();
|
|
object[] parameters = new object[3] { text, id, null };
|
|
object obj = _createItemMethod.Invoke(_singletonInstance, parameters);
|
|
if (obj != null)
|
|
{
|
|
return (Item)obj;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public Item CreateItemWithParent(string itemId, string parentId)
|
|
{
|
|
if (_createItemMethod == null || _singletonInstance == null)
|
|
{
|
|
return null;
|
|
}
|
|
string text = ((!string.IsNullOrEmpty(parentId)) ? parentId : ((string)MongoID.Generate()));
|
|
object[] parameters = new object[3] { text, itemId, null };
|
|
object obj = _createItemMethod.Invoke(_singletonInstance, parameters);
|
|
if (obj != null)
|
|
{
|
|
return (Item)obj;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static void Log(string message)
|
|
{
|
|
_logFilePath = Path.Combine(Application.persistentDataPath, "log.txt");
|
|
using StreamWriter streamWriter = new StreamWriter(_logFilePath, append: true);
|
|
streamWriter.WriteLine($"{DateTime.Now}: {message}");
|
|
}
|
|
}
|