Upload from upload_mods.ps1
This commit is contained in:
40
Score/RemoteCrafting/Harmony/DropBoxToContainers.cs
Normal file
40
Score/RemoteCrafting/Harmony/DropBoxToContainers.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using Rebirth.RemoteCrafting;
|
||||
|
||||
namespace Features.RemoteCrafting
|
||||
{
|
||||
public class DropBoxToContainersPatches
|
||||
{
|
||||
[HarmonyPatch(typeof(XUiC_LootContainer))]
|
||||
[HarmonyPatch("OnClose")]
|
||||
public class XUiCLootContainerOnClose
|
||||
{
|
||||
public static bool Prefix(XUiC_LootContainer __instance, BlockValue ___blockValue, TileEntityLootContainer ___localTileEntity)
|
||||
{
|
||||
if (!___blockValue.Block.Properties.Values.ContainsKey("DropBox")) return true;
|
||||
if (___localTileEntity == null) return true;
|
||||
StringParsers.TryParseBool(___blockValue.Block.Properties.Values["DropBox"], out var isDropBox);
|
||||
if (!isDropBox) return true;
|
||||
|
||||
var distance = 150f;
|
||||
|
||||
var primaryPlayer = __instance.xui.playerUI.entityPlayer;
|
||||
var items = ___localTileEntity.GetItems();
|
||||
for (var i = 0; i < items.Length; i++)
|
||||
{
|
||||
if (items[i].IsEmpty()) continue;
|
||||
// If we successfully added, clear the stack.
|
||||
if (RemoteCraftingUtils.AddToNearbyContainer(primaryPlayer, items[i], distance))
|
||||
{
|
||||
Debug.Log($"Removing {items[i].itemValue.ItemClass.GetItemName()}");
|
||||
items[i] = ItemStack.Empty.Clone();
|
||||
}
|
||||
___localTileEntity.UpdateSlot(i, items[i]);
|
||||
|
||||
}
|
||||
|
||||
___localTileEntity.SetModified();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
243
Score/RemoteCrafting/Harmony/IngredientsFromContainers.cs
Normal file
243
Score/RemoteCrafting/Harmony/IngredientsFromContainers.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using Rebirth.RemoteCrafting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Features.RemoteCrafting
|
||||
{
|
||||
/// <summary>
|
||||
/// Patches to support the Crafting From Remote Storage
|
||||
/// </summary>
|
||||
public class EnhancedRecipeLists
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to determine which recipes the player can craft based on the availability of ingredients in local containers.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(XUiC_RecipeList))]
|
||||
[HarmonyPatch("BuildRecipeInfosList")]
|
||||
public class BuildRecipeInfosList
|
||||
{
|
||||
public static bool Prefix(XUiC_RecipeList __instance, ref List<ItemStack> _items)
|
||||
{
|
||||
var player = __instance.xui.playerUI.entityPlayer;
|
||||
_items.AddRange(RemoteCraftingUtils.SearchNearbyContainers(player));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extends what is considered to be in the player's backpack / tool belt to include local containers.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(XUiM_PlayerInventory))]
|
||||
[HarmonyPatch("GetAllItemStacks")]
|
||||
public class GetAllItemStacks
|
||||
{
|
||||
public static void Postfix(ref List<ItemStack> __result, EntityPlayerLocal ___localPlayer)
|
||||
{
|
||||
__result.AddRange(RemoteCraftingUtils.SearchNearbyContainers(___localPlayer));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hijacks the GetBindingValue so we can get an accurate count of all the items we have available, including from local storage.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(XUiC_IngredientEntry))]
|
||||
[HarmonyPatch("GetBindingValue")]
|
||||
public class GetBindingValue
|
||||
{
|
||||
public static bool Prefix(XUiC_IngredientEntry __instance, ref bool __result, ref string value,
|
||||
string bindingName, CachedStringFormatter<int> ___needcountFormatter,
|
||||
CachedStringFormatter<int> ___havecountFormatter, bool ___materialBased, ItemStack ___ingredient,
|
||||
string ___material, XUiC_RecipeCraftCount ___craftCountControl,
|
||||
CachedStringFormatterXuiRgbaColor ___itemicontintcolorFormatter)
|
||||
{
|
||||
var flag = ___ingredient != null;
|
||||
switch (bindingName)
|
||||
{
|
||||
case "haveneedcount":
|
||||
{
|
||||
var text = (flag
|
||||
? ___needcountFormatter.Format(___ingredient.count * ___craftCountControl.Count)
|
||||
: "");
|
||||
var value1 = 0;
|
||||
var childByType = __instance.WindowGroup.Controller.GetChildByType<XUiC_WorkstationMaterialInputGrid>();
|
||||
if (childByType != null)
|
||||
{
|
||||
if (___materialBased)
|
||||
{
|
||||
value = (flag
|
||||
? (___havecountFormatter.Format(childByType.GetWeight(___material)) + "/" + text)
|
||||
: "");
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (flag
|
||||
? (___havecountFormatter.Format(
|
||||
__instance.xui.PlayerInventory.GetItemCount(___ingredient.itemValue)) + "/" +
|
||||
text)
|
||||
: "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var childByType2 = __instance.WindowGroup.Controller
|
||||
.GetChildByType<XUiC_WorkstationInputGrid>();
|
||||
if (childByType2 != null)
|
||||
{
|
||||
value = (flag
|
||||
? (___havecountFormatter.Format(
|
||||
childByType2.GetItemCount(___ingredient.itemValue)) + "/" + text)
|
||||
: "");
|
||||
}
|
||||
else
|
||||
{
|
||||
value = (flag
|
||||
? (___havecountFormatter.Format(
|
||||
__instance.xui.PlayerInventory.GetItemCount(___ingredient.itemValue)) + "/" +
|
||||
text)
|
||||
: "");
|
||||
if (flag)
|
||||
{
|
||||
// add items from lootcontainers
|
||||
value1 = __instance.xui.PlayerInventory.GetItemCount(___ingredient.itemValue);
|
||||
var array = RemoteCraftingUtils.SearchNearbyContainers(__instance.xui.playerUI.entityPlayer,
|
||||
___ingredient.itemValue).ToArray();
|
||||
foreach (var t in array)
|
||||
{
|
||||
if (t != null && t.itemValue.type != 0 &&
|
||||
___ingredient.itemValue.type == t.itemValue.type)
|
||||
{
|
||||
value1 += t.count;
|
||||
}
|
||||
}
|
||||
|
||||
value = ___havecountFormatter.Format(value1) + "/" + text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Expands the HasItems search to include local containers.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(XUiM_PlayerInventory))]
|
||||
[HarmonyPatch("HasItems")]
|
||||
public class HasItems
|
||||
{
|
||||
public static bool Postfix(bool __result, IList<ItemStack> _itemStacks, EntityPlayerLocal ___localPlayer,
|
||||
int _multiplier)
|
||||
{
|
||||
if (__result) return true;
|
||||
|
||||
// We need to make sure we satisfy all of the items.
|
||||
var itemsWeHave = 0;
|
||||
foreach (var itemStack in _itemStacks)
|
||||
{
|
||||
var totalCount = 0;
|
||||
// This is how many we need.
|
||||
var num = itemStack.count * _multiplier;
|
||||
// check player inventory
|
||||
var slots = ___localPlayer.bag.GetSlots();
|
||||
foreach (var entry in slots)
|
||||
{
|
||||
if (entry.IsEmpty()) continue;
|
||||
if (itemStack.itemValue.GetItemOrBlockId() != entry.itemValue.GetItemOrBlockId()) continue;
|
||||
totalCount += entry.count;
|
||||
// We have enough.
|
||||
if (totalCount >= num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// We have enough.
|
||||
if (totalCount >= num)
|
||||
{
|
||||
itemsWeHave++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check the toolbelt now.
|
||||
slots = ___localPlayer.inventory.GetSlots();
|
||||
foreach (var entry in slots)
|
||||
{
|
||||
if (entry.IsEmpty()) continue;
|
||||
if (itemStack.itemValue.GetItemOrBlockId() != entry.itemValue.GetItemOrBlockId()) continue;
|
||||
totalCount += entry.count;
|
||||
// We have enough.
|
||||
if (totalCount >= num)
|
||||
break;
|
||||
}
|
||||
|
||||
// We have enough.
|
||||
if (totalCount >= num)
|
||||
{
|
||||
itemsWeHave++;
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
// check container
|
||||
var containers = RemoteCraftingUtils.SearchNearbyContainers(___localPlayer, itemStack.itemValue);
|
||||
foreach (var stack in containers)
|
||||
{
|
||||
if (stack.IsEmpty()) continue;
|
||||
if (itemStack.itemValue.GetItemOrBlockId() != stack.itemValue.GetItemOrBlockId()) continue;
|
||||
totalCount += stack.count;
|
||||
// We have enough.
|
||||
if (totalCount >= num)
|
||||
break;
|
||||
}
|
||||
|
||||
// We don't have enough for this.
|
||||
if (totalCount < num)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (totalCount >= num)
|
||||
{
|
||||
itemsWeHave++;
|
||||
}
|
||||
}
|
||||
|
||||
return itemsWeHave >= _itemStacks.Count;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes from local storage containers items which we've consumed.
|
||||
/// </summary>
|
||||
[HarmonyPatch(typeof(XUiM_PlayerInventory))]
|
||||
[HarmonyPatch("RemoveItems")]
|
||||
public class RemoveItems
|
||||
{
|
||||
public static bool Prefix(XUiM_PlayerInventory __instance, IList<ItemStack> _itemStacks, EntityPlayerLocal ___localPlayer, int _multiplier, IList<ItemStack> _removedItems
|
||||
, Bag ___backpack, Inventory ___toolbelt)
|
||||
{
|
||||
RemoteCraftingUtils.ConsumeItem(_itemStacks, ___localPlayer, _multiplier, _removedItems, ___backpack, ___toolbelt);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Code from OCB7D2D/OcbPinRecipes
|
||||
// Patch world unload to cleanup and save on exit
|
||||
[HarmonyPatch(typeof(World))]
|
||||
[HarmonyPatch("UnloadWorld")]
|
||||
public class WorldUnloadWorld
|
||||
{
|
||||
static void Postfix()
|
||||
{
|
||||
if (!Broadcastmanager.HasInstance) return;
|
||||
Broadcastmanager.Cleanup();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
322
Score/RemoteCrafting/Harmony/ItemActionRepairPatches.cs
Normal file
322
Score/RemoteCrafting/Harmony/ItemActionRepairPatches.cs
Normal file
@@ -0,0 +1,322 @@
|
||||
using HarmonyLib;
|
||||
using Rebirth.RemoteCrafting;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
// todo - fix as methods have changed
|
||||
namespace Features.RemoteCrafting
|
||||
{
|
||||
/// <summary>
|
||||
/// Patches to support repairing from remote storage
|
||||
/// </summary>
|
||||
public class ItemActionRepairPatches
|
||||
{
|
||||
private struct UpgradeInfo
|
||||
{
|
||||
public string FromBlock;
|
||||
public string ToBlock;
|
||||
public string Item;
|
||||
public int ItemCount;
|
||||
public string Sound;
|
||||
public int Hits;
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ItemActionRepair))]
|
||||
[HarmonyPatch("RemoveRequiredResource")]
|
||||
public class RemoveRequiredResource
|
||||
{
|
||||
private static bool Prefix(ref bool __result, ItemActionRepair __instance, ItemInventoryData data, UpgradeInfo ___currentUpgradeInfo)
|
||||
{
|
||||
if (string.IsNullOrEmpty(___currentUpgradeInfo.Item))
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
var itemValue = ItemClass.GetItem(___currentUpgradeInfo.Item);
|
||||
if (data.holdingEntity.inventory.DecItem(itemValue, ___currentUpgradeInfo.ItemCount) == ___currentUpgradeInfo.ItemCount)
|
||||
{
|
||||
var entityPlayerLocal = data.holdingEntity as EntityPlayerLocal;
|
||||
if (entityPlayerLocal != null && ___currentUpgradeInfo.ItemCount != 0)
|
||||
{
|
||||
entityPlayerLocal.AddUIHarvestingItem(new ItemStack(itemValue, -___currentUpgradeInfo.ItemCount));
|
||||
}
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
if (data.holdingEntity.bag.DecItem(itemValue, ___currentUpgradeInfo.ItemCount) == ___currentUpgradeInfo.ItemCount)
|
||||
{
|
||||
var entityPlayerLocal2 = data.holdingEntity as EntityPlayerLocal;
|
||||
if (entityPlayerLocal2 != null)
|
||||
{
|
||||
entityPlayerLocal2.AddUIHarvestingItem(new ItemStack(itemValue, -___currentUpgradeInfo.ItemCount));
|
||||
}
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
|
||||
var distance = 150f;
|
||||
|
||||
var tileEntities = RemoteCraftingUtils.GetTileEntities(primaryPlayer, distance);
|
||||
|
||||
// counter quantity needed from item
|
||||
var q = ___currentUpgradeInfo.ItemCount;
|
||||
|
||||
var itemStack = new ItemStack(ItemClass.GetItem(___currentUpgradeInfo.Item, false), ___currentUpgradeInfo.ItemCount);
|
||||
|
||||
//check player inventory for materials and reduce counter
|
||||
var slots = primaryPlayer.bag.GetSlots();
|
||||
q = q - slots
|
||||
.Where(x => x.itemValue.ItemClass == itemStack.itemValue.ItemClass)
|
||||
.Sum(y => y.count);
|
||||
|
||||
// check storage boxes
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (q <= 0) break;
|
||||
if (tileEntity is not TileEntityLootContainer lootTileEntity) continue;
|
||||
|
||||
// If there's no items in this container, skip.
|
||||
if (!lootTileEntity.HasItem(itemStack.itemValue)) continue;
|
||||
|
||||
for (var y = 0; y < lootTileEntity.items.Length; y++)
|
||||
{
|
||||
var item = lootTileEntity.items[y];
|
||||
if (item.IsEmpty()) continue;
|
||||
if (item.itemValue.ItemClass != itemStack.itemValue.ItemClass) continue;
|
||||
|
||||
// If we can completely satisfy the result, let's do that.
|
||||
if (item.count >= q)
|
||||
{
|
||||
item.count -= q;
|
||||
q = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, let's just count down until we meet the requirement.
|
||||
while (q >= 0)
|
||||
{
|
||||
item.count--;
|
||||
q--;
|
||||
if (item.count <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Update the slot on the container, and do the Setmodified(), so that the dedis can get updated.
|
||||
if (item.count < 1)
|
||||
lootTileEntity.UpdateSlot(y, ItemStack.Empty.Clone());
|
||||
else
|
||||
lootTileEntity.UpdateSlot(y, item);
|
||||
lootTileEntity.SetModified();
|
||||
}
|
||||
}
|
||||
|
||||
primaryPlayer.AddUIHarvestingItem(new ItemStack(itemValue, -___currentUpgradeInfo.ItemCount), false);
|
||||
|
||||
__result = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ItemActionRepair))]
|
||||
[HarmonyPatch("CanRemoveRequiredResource")]
|
||||
public class CanRemoveRequiredResource
|
||||
{
|
||||
private static bool Prefix(ref bool __result, ItemActionRepair __instance, ItemInventoryData data, BlockValue blockValue, ref UpgradeInfo ___currentUpgradeInfo, string ___allowedUpgradeItems, string ___restrictedUpgradeItems, string ___upgradeActionSound, float ___hitCountOffset)
|
||||
{
|
||||
var block = blockValue.Block;
|
||||
var flag = block.Properties.Values.ContainsKey("UpgradeBlock.Item");
|
||||
var upgradeInfo = default(UpgradeInfo);
|
||||
upgradeInfo.FromBlock = block.GetBlockName();
|
||||
upgradeInfo.ToBlock = block.Properties.Values[Block.PropUpgradeBlockClassToBlock];
|
||||
upgradeInfo.Sound = "";
|
||||
if (flag)
|
||||
{
|
||||
upgradeInfo.Item = block.Properties.Values["UpgradeBlock.Item"];
|
||||
if (___allowedUpgradeItems.Length > 0 && !___allowedUpgradeItems.ContainsCaseInsensitive(upgradeInfo.Item))
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
if (___restrictedUpgradeItems.Length > 0 && ___restrictedUpgradeItems.ContainsCaseInsensitive(upgradeInfo.Item))
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (___upgradeActionSound.Length > 0)
|
||||
{
|
||||
upgradeInfo.Sound = ___upgradeActionSound;
|
||||
}
|
||||
else if (flag)
|
||||
{
|
||||
var item = ItemClass.GetItem(upgradeInfo.Item);
|
||||
if (item != null)
|
||||
{
|
||||
var itemClass = ItemClass.GetForId(item.type);
|
||||
if (itemClass != null)
|
||||
{
|
||||
upgradeInfo.Sound =
|
||||
$"ImpactSurface/{data.holdingEntity.inventory.holdingItem.MadeOfMaterial.SurfaceCategory}hit{itemClass.MadeOfMaterial.SurfaceCategory}";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!int.TryParse(block.Properties.Values["UpgradeBlock.UpgradeHitCount"], out var num))
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
upgradeInfo.Hits = (int)(num + ___hitCountOffset < 1f ? 1f : num + ___hitCountOffset);
|
||||
if (!int.TryParse(block.Properties.Values[Block.PropUpgradeBlockClassItemCount], out upgradeInfo.ItemCount) && flag)
|
||||
{
|
||||
__result = false;
|
||||
return false;
|
||||
}
|
||||
___currentUpgradeInfo = upgradeInfo;
|
||||
if (___currentUpgradeInfo.FromBlock != null && flag)
|
||||
{
|
||||
var item = ItemClass.GetItem(___currentUpgradeInfo.Item, false);
|
||||
if (data.holdingEntity.inventory.GetItemCount(item) >= ___currentUpgradeInfo.ItemCount)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
if (data.holdingEntity.bag.GetItemCount(item) >= ___currentUpgradeInfo.ItemCount)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (!flag)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
|
||||
|
||||
var itemStack = new ItemStack(ItemClass.GetItem(___currentUpgradeInfo.Item), ___currentUpgradeInfo.ItemCount);
|
||||
var distance = 150f;
|
||||
|
||||
var totalCount = RemoteCraftingUtils.SearchNearbyContainers(primaryPlayer, itemStack.itemValue, distance).Sum(y => y.count);
|
||||
|
||||
if (totalCount >= ___currentUpgradeInfo.ItemCount)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
__result = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ItemActionRepair))]
|
||||
[HarmonyPatch("removeRequiredItem")]
|
||||
public class RemoveRequiredItem
|
||||
{
|
||||
private static bool Prefix(ref bool __result, ItemActionRepair __instance, ItemInventoryData _data, ItemStack _itemStack)
|
||||
{
|
||||
__result = false;
|
||||
|
||||
__result = _data.holdingEntity.inventory.DecItem(_itemStack.itemValue, _itemStack.count) == _itemStack.count || _data.holdingEntity.bag.DecItem(_itemStack.itemValue, _itemStack.count, false) == _itemStack.count;
|
||||
|
||||
if (__result)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
|
||||
var distance = 150f;
|
||||
|
||||
var tileEntities = RemoteCraftingUtils.GetTileEntities(primaryPlayer, distance);
|
||||
|
||||
// counter quantity needed from item
|
||||
var q = _itemStack.count;
|
||||
|
||||
//check player inventory for materials and reduce counter
|
||||
var slots = primaryPlayer.bag.GetSlots();
|
||||
q -= slots
|
||||
.Where(x => x.itemValue.ItemClass == _itemStack.itemValue.ItemClass)
|
||||
.Sum(y => y.count);
|
||||
|
||||
// check storage boxes
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (q <= 0) break;
|
||||
if (tileEntity is not TileEntityLootContainer lootTileEntity) continue;
|
||||
|
||||
// If there's no items in this container, skip.
|
||||
if (!lootTileEntity.HasItem(_itemStack.itemValue)) continue;
|
||||
|
||||
for (var y = 0; y < lootTileEntity.items.Length; y++)
|
||||
{
|
||||
var item = lootTileEntity.items[y];
|
||||
if (item.IsEmpty()) continue;
|
||||
if (item.itemValue.ItemClass != _itemStack.itemValue.ItemClass) continue;
|
||||
|
||||
// If we can completely satisfy the result, let's do that.
|
||||
if (item.count >= q)
|
||||
{
|
||||
item.count -= q;
|
||||
q = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, let's just count down until we meet the requirement.
|
||||
while (q >= 0)
|
||||
{
|
||||
item.count--;
|
||||
q--;
|
||||
if (item.count <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Update the slot on the container, and do the Setmodified(), so that the dedis can get updated.
|
||||
if (item.count < 1)
|
||||
lootTileEntity.UpdateSlot(y, ItemStack.Empty.Clone());
|
||||
else
|
||||
lootTileEntity.UpdateSlot(y, item);
|
||||
lootTileEntity.SetModified();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(ItemActionRepair))]
|
||||
[HarmonyPatch("canRemoveRequiredItem")]
|
||||
public class CanRemoveRequiredItem
|
||||
{
|
||||
private static bool Prefix(ref bool __result, ItemActionRepair __instance, ItemInventoryData _data, ItemStack _itemStack)
|
||||
{
|
||||
__result = false;
|
||||
|
||||
if (_data.holdingEntity.inventory.GetItemCount(_itemStack.itemValue) >= _itemStack.count || _data.holdingEntity.bag.GetItemCount(_itemStack.itemValue) >= _itemStack.count)
|
||||
{
|
||||
__result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
|
||||
var distance = 150f;
|
||||
|
||||
var totalCount = RemoteCraftingUtils.SearchNearbyContainers(primaryPlayer, _itemStack.itemValue, distance).Sum(y => y.count);
|
||||
|
||||
if (totalCount <= 0) return false;
|
||||
__result = true;
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
204
Score/RemoteCrafting/Manager/Broadcastmanager.cs
Normal file
204
Score/RemoteCrafting/Manager/Broadcastmanager.cs
Normal file
@@ -0,0 +1,204 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
// Stripped down Firemanager
|
||||
public class Broadcastmanager
|
||||
{
|
||||
private static Broadcastmanager instance = null;
|
||||
private static ConcurrentDictionary<Vector3i, BlockValue> Broadcastmap = new ConcurrentDictionary<Vector3i, BlockValue>();
|
||||
|
||||
private const string saveFile = "Broadcastmanager.dat";
|
||||
private ThreadManager.ThreadInfo dataSaveThreadInfo;
|
||||
|
||||
public static bool HasInstance => instance != null;
|
||||
|
||||
//public bool Enabled { private set; get; }
|
||||
public static Broadcastmanager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
public static void Init()
|
||||
{
|
||||
Broadcastmanager.instance = new Broadcastmanager();
|
||||
Log.Out("Starting Broadcast Manager");
|
||||
|
||||
// Read the Broadcastmanager
|
||||
Broadcastmanager.Instance.Load();
|
||||
}
|
||||
|
||||
// Save the lootcontainer location.
|
||||
public void Write(BinaryWriter _bw)
|
||||
{
|
||||
_bw.Write("V1");
|
||||
foreach (var temp in Broadcastmap)
|
||||
_bw.Write(temp.Key.ToString());
|
||||
}
|
||||
|
||||
// Read lootcontainer location.
|
||||
public void Read(BinaryReader _br)
|
||||
{
|
||||
var version = _br.ReadString();
|
||||
if (version == "V1")
|
||||
{
|
||||
while (_br.BaseStream.Position != _br.BaseStream.Length)
|
||||
{
|
||||
string container = _br.ReadString();
|
||||
add(StringParsers.ParseVector3i(container));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var position in version.Split(';'))
|
||||
while (_br.BaseStream.Position != _br.BaseStream.Length)
|
||||
{
|
||||
if (string.IsNullOrEmpty(position)) continue;
|
||||
var vector = StringParsers.ParseVector3i(position);
|
||||
add(vector);
|
||||
add(StringParsers.ParseVector3i(_br.ReadString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if lootcontainer exists in dictionary
|
||||
public bool Check(Vector3i _blockPos)
|
||||
{
|
||||
return Broadcastmap.TryGetValue(_blockPos, out _);
|
||||
}
|
||||
|
||||
public void Add(Vector3i _blockPos, int entityID = -1)
|
||||
{
|
||||
if (!GameManager.IsDedicatedServer)
|
||||
add(_blockPos);
|
||||
|
||||
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
|
||||
{
|
||||
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageAddBroadcastPosition>().Setup(_blockPos, entityID), false);
|
||||
return;
|
||||
}
|
||||
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageAddBroadcastPosition>().Setup(_blockPos, entityID), false, -1, -1, -1, null, 192);
|
||||
}
|
||||
public void Remove(Vector3i _blockPos, int entityID = -1)
|
||||
{
|
||||
if (!GameManager.IsDedicatedServer)
|
||||
remove(_blockPos);
|
||||
if (!SingletonMonoBehaviour<ConnectionManager>.Instance.IsServer)
|
||||
{
|
||||
SingletonMonoBehaviour<ConnectionManager>.Instance.SendToServer(NetPackageManager.GetPackage<NetPackageRemoveBroadcastPosition>().Setup(_blockPos, entityID), false);
|
||||
return;
|
||||
}
|
||||
SingletonMonoBehaviour<ConnectionManager>.Instance.SendPackage(NetPackageManager.GetPackage<NetPackageRemoveBroadcastPosition>().Setup(_blockPos, entityID), false, -1, -1, -1, null, 192);
|
||||
}
|
||||
|
||||
// Remove lootcontainer from dictionary
|
||||
public void remove(Vector3i _blockPos)
|
||||
{
|
||||
if (!Broadcastmap.ContainsKey(_blockPos)) return;
|
||||
Broadcastmap.TryRemove(_blockPos, out var block);
|
||||
}
|
||||
// Add lootcontainer to dictionary
|
||||
public void add(Vector3i _blockPos)
|
||||
{
|
||||
var block = GameManager.Instance.World.GetBlock(_blockPos);
|
||||
Broadcastmap.TryAdd(_blockPos, block);
|
||||
}
|
||||
|
||||
private int saveDataThreaded(ThreadManager.ThreadInfo _threadInfo)
|
||||
{
|
||||
PooledExpandableMemoryStream pooledExpandableMemoryStream = (PooledExpandableMemoryStream)_threadInfo.parameter;
|
||||
string text = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
|
||||
if (!Directory.Exists(GameIO.GetSaveGameDir()))
|
||||
{
|
||||
Directory.CreateDirectory(GameIO.GetSaveGameDir());
|
||||
}
|
||||
if (File.Exists(text))
|
||||
{
|
||||
File.Copy(text, string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak"), true);
|
||||
}
|
||||
pooledExpandableMemoryStream.Position = 0L;
|
||||
StreamUtils.WriteStreamToFile(pooledExpandableMemoryStream, text);
|
||||
MemoryPools.poolMemoryStream.FreeSync(pooledExpandableMemoryStream);
|
||||
Log.Out($"Broadcast Manager {text} Saving: {Broadcastmap.Count}");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (this.dataSaveThreadInfo == null || !ThreadManager.ActiveThreads.ContainsKey("silent_BroadcastDataSave"))
|
||||
{
|
||||
PooledExpandableMemoryStream pooledExpandableMemoryStream = MemoryPools.poolMemoryStream.AllocSync(true);
|
||||
using (PooledBinaryWriter pooledBinaryWriter = MemoryPools.poolBinaryWriter.AllocSync(false))
|
||||
{
|
||||
pooledBinaryWriter.SetBaseStream(pooledExpandableMemoryStream);
|
||||
this.Write(pooledBinaryWriter);
|
||||
}
|
||||
|
||||
|
||||
this.dataSaveThreadInfo = ThreadManager.StartThread("silent_BroadcastDataSave", null, new ThreadManager.ThreadFunctionLoopDelegate(this.saveDataThreaded), null, System.Threading.ThreadPriority.Normal, pooledExpandableMemoryStream, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
string path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), saveFile);
|
||||
if (Directory.Exists(GameIO.GetSaveGameDir()) && File.Exists(path))
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream fileStream = File.OpenRead(path))
|
||||
{
|
||||
using (PooledBinaryReader pooledBinaryReader = MemoryPools.poolBinaryReader.AllocSync(false))
|
||||
{
|
||||
pooledBinaryReader.SetBaseStream(fileStream);
|
||||
this.Read(pooledBinaryReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
path = string.Format("{0}/{1}", GameIO.GetSaveGameDir(), $"{saveFile}.bak");
|
||||
if (File.Exists(path))
|
||||
{
|
||||
using (FileStream fileStream2 = File.OpenRead(path))
|
||||
{
|
||||
using (PooledBinaryReader pooledBinaryReader2 = MemoryPools.poolBinaryReader.AllocSync(false))
|
||||
{
|
||||
pooledBinaryReader2.SetBaseStream(fileStream2);
|
||||
this.Read(pooledBinaryReader2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.Out($"Broadcast Manager {path} Loaded: {Broadcastmap.Count}");
|
||||
}
|
||||
}
|
||||
|
||||
private void WaitOnSave()
|
||||
{
|
||||
if (this.dataSaveThreadInfo != null)
|
||||
{
|
||||
this.dataSaveThreadInfo.WaitForEnd();
|
||||
this.dataSaveThreadInfo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Cleanup()
|
||||
{
|
||||
if (instance != null)
|
||||
{
|
||||
instance.SaveAndClear();
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveAndClear()
|
||||
{
|
||||
WaitOnSave();
|
||||
Save();
|
||||
WaitOnSave();
|
||||
Broadcastmap.Clear();
|
||||
instance = null;
|
||||
Log.Out("Broadcastmanager stopped");
|
||||
}
|
||||
}
|
||||
54
Score/RemoteCrafting/Scripts/BlockDropBoxContainer.cs
Normal file
54
Score/RemoteCrafting/Scripts/BlockDropBoxContainer.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Rebirth.RemoteCrafting;
|
||||
|
||||
public class BlockDropBoxContainer : BlockSecureLootSigned
|
||||
{
|
||||
private float _distance;
|
||||
private float _updateTime;
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_distance = RebirthVariables.broadcastDistance;
|
||||
|
||||
Properties.ParseFloat("Distance", ref _distance);
|
||||
|
||||
_updateTime = 100UL;
|
||||
Properties.ParseFloat("UpdateTick", ref _updateTime);
|
||||
}
|
||||
|
||||
public override ulong GetTickRate()
|
||||
{
|
||||
return (ulong)_updateTime;
|
||||
}
|
||||
public override void OnBlockAdded(WorldBase world, Chunk _chunk, Vector3i _blockPos, BlockValue _blockValue)
|
||||
{
|
||||
base.OnBlockAdded(world, _chunk, _blockPos, _blockValue);
|
||||
if (!world.IsRemote())
|
||||
{
|
||||
world.GetWBT().AddScheduledBlockUpdate(0, _blockPos, this.blockID, GetTickRate());
|
||||
}
|
||||
}
|
||||
|
||||
public override bool UpdateTick(WorldBase world, int _clrIdx, Vector3i _blockPos, BlockValue _blockValue,
|
||||
bool _bRandomTick, ulong _ticksIfLoaded, GameRandom _rnd)
|
||||
{
|
||||
var tileLootContainer = (TileEntityLootContainer)world.GetTileEntity(_clrIdx, _blockPos);
|
||||
if (tileLootContainer == null) return false;
|
||||
|
||||
if (!tileLootContainer.IsUserAccessing())
|
||||
{
|
||||
var primaryPlayer = GameManager.Instance.World.GetPrimaryPlayer();
|
||||
foreach (var itemStack in tileLootContainer.GetItems())
|
||||
{
|
||||
if (itemStack.IsEmpty()) continue;
|
||||
// If we successfully added, clear the stack.
|
||||
if (RemoteCraftingUtils.AddToNearbyContainer(primaryPlayer, itemStack, _distance))
|
||||
itemStack.Clear();
|
||||
}
|
||||
tileLootContainer.bTouched = true;
|
||||
tileLootContainer.SetModified();
|
||||
}
|
||||
|
||||
world.GetWBT().AddScheduledBlockUpdate(0, _blockPos, this.blockID, GetTickRate());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
//copy of NetPackageAddFirePosition
|
||||
public class NetPackageAddBroadcastPosition : NetPackage
|
||||
{
|
||||
private Vector3i position;
|
||||
private int entityThatCausedIt;
|
||||
|
||||
public NetPackageAddBroadcastPosition Setup(Vector3i _position, int _entityThatCausedIt)
|
||||
{
|
||||
this.position = _position;
|
||||
this.entityThatCausedIt = _entityThatCausedIt;
|
||||
return this;
|
||||
}
|
||||
|
||||
public override void read(PooledBinaryReader _br)
|
||||
{
|
||||
this.position = new Vector3i((float)_br.ReadInt32(), (float)_br.ReadInt32(), (float)_br.ReadInt32());
|
||||
this.entityThatCausedIt = _br.ReadInt32();
|
||||
}
|
||||
|
||||
public override void write(PooledBinaryWriter _bw)
|
||||
{
|
||||
base.write(_bw);
|
||||
_bw.Write((int)this.position.x);
|
||||
_bw.Write((int)this.position.y);
|
||||
_bw.Write((int)this.position.z);
|
||||
_bw.Write(this.entityThatCausedIt);
|
||||
}
|
||||
|
||||
public override int GetLength()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
public override void ProcessPackage(World _world, GameManager _callbacks)
|
||||
{
|
||||
if (_world == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_world.IsRemote())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Broadcastmanager.Instance.add(position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
//copy of NetPackageRemoveFirePosition
|
||||
public class NetPackageRemoveBroadcastPosition : NetPackage
|
||||
{
|
||||
private Vector3i position;
|
||||
private int entityThatCausedIt;
|
||||
|
||||
public NetPackageRemoveBroadcastPosition Setup(Vector3i _position, int _entityThatCausedIt)
|
||||
{
|
||||
this.position = _position;
|
||||
this.entityThatCausedIt = _entityThatCausedIt;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public override void read(PooledBinaryReader _br)
|
||||
{
|
||||
this.position = new Vector3i((float)_br.ReadInt32(), (float)_br.ReadInt32(), (float)_br.ReadInt32());
|
||||
this.entityThatCausedIt = _br.ReadInt32();
|
||||
}
|
||||
|
||||
public override void write(PooledBinaryWriter _bw)
|
||||
{
|
||||
base.write(_bw);
|
||||
_bw.Write((int)this.position.x);
|
||||
_bw.Write((int)this.position.y);
|
||||
_bw.Write((int)this.position.z);
|
||||
_bw.Write(this.entityThatCausedIt);
|
||||
}
|
||||
|
||||
public override int GetLength()
|
||||
{
|
||||
return 20;
|
||||
}
|
||||
|
||||
public override void ProcessPackage(World _world, GameManager _callbacks)
|
||||
{
|
||||
if (_world == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_world.IsRemote())
|
||||
{
|
||||
return;
|
||||
}
|
||||
Broadcastmanager.Instance.remove(position);
|
||||
}
|
||||
}
|
||||
|
||||
281
Score/RemoteCrafting/Scripts/RemoteCraftingUtils.cs
Normal file
281
Score/RemoteCrafting/Scripts/RemoteCraftingUtils.cs
Normal file
@@ -0,0 +1,281 @@
|
||||
using JetBrains.Annotations;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Rebirth.RemoteCrafting
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class RemoteCraftingUtils
|
||||
{
|
||||
public static List<TileEntity> GetTileEntities(EntityAlive player)
|
||||
{
|
||||
var distance = 150f;
|
||||
|
||||
var tileEntities = RebirthUtilities.GetTileEntities(player, distance);
|
||||
return tileEntities;
|
||||
}
|
||||
|
||||
public static bool DisableSender(IEnumerable<string> value, TileEntity tileEntity)
|
||||
{
|
||||
if (tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage))
|
||||
{
|
||||
if (value.All(x => x.Trim() != storage.lootListName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool BindToWorkstation(string value, EntityAlive player, TileEntity tileEntity)
|
||||
{
|
||||
var result = false;
|
||||
if (player is not EntityPlayerLocal playerLocal) return false;
|
||||
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) return false;
|
||||
|
||||
// TODO: we want to refactor this to remove the complex LinQ.
|
||||
|
||||
// what could be easier than linq?
|
||||
|
||||
// bind storage to workstation
|
||||
if (value.Split(';').Where(x =>
|
||||
x.Split(':')[0].Split(',').Any(ws => ws.Trim() == playerLocal.PlayerUI.xui.currentWorkstation))
|
||||
.Any(x => x.Split(':')[1].Split(',').Any(y => y == storage.lootListName))) result = true;
|
||||
// bind storage to other workstations if allowed
|
||||
if (value.Split(';').Any(x =>
|
||||
x.Split(':')[0].Split(',').Any(ws => ws.Trim() == playerLocal.PlayerUI.xui.currentWorkstation)))
|
||||
return result;
|
||||
{
|
||||
if (value.Split(';').Any(x => x.Split(':')[1].Split(',').Any(y => y == storage.lootListName)))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static bool NotToWorkstation(string value, EntityAlive player, TileEntity tileEntity)
|
||||
{
|
||||
var result = false;
|
||||
if (player is not EntityPlayerLocal playerLocal) return false;
|
||||
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) return false;
|
||||
|
||||
foreach (var bind in value.Split(';'))
|
||||
{
|
||||
var workstation = bind.Split(':')[0].Split(',');
|
||||
var disablebinding = bind.Split(':')[1].Split(',');
|
||||
if ((workstation.Any(ws => ws.Trim() == playerLocal.PlayerUI.xui.currentWorkstation)) &&
|
||||
(disablebinding.Any(x => x.Trim() == storage.lootListName))) result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<ItemStack> SearchNearbyContainers(EntityAlive player)
|
||||
{
|
||||
var items = new List<ItemStack>();
|
||||
var tileEntities = GetTileEntities(player);
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) continue;
|
||||
|
||||
if (storage.IsUserAccessing()) continue;
|
||||
|
||||
items.AddRange(storage.items);
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static List<ItemStack> SearchNearbyContainers(EntityAlive player, ItemValue itemValue)
|
||||
{
|
||||
var item = new List<ItemStack>();
|
||||
var items = new List<ItemStack>();
|
||||
var tileEntities = GetTileEntities(player);
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) continue;
|
||||
|
||||
// If the container is open, don't use it.
|
||||
if (storage.IsUserAccessing()) continue;
|
||||
|
||||
item.AddRange(storage.items);
|
||||
}
|
||||
|
||||
foreach (var t in item)
|
||||
{
|
||||
if ((!t.itemValue.HasModSlots || !t.itemValue.HasMods()) &&
|
||||
t.itemValue.type == itemValue.type)
|
||||
{
|
||||
items.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static List<ItemStack> SearchNearbyContainers(EntityAlive player, ItemValue itemValue, float distance)
|
||||
{
|
||||
var item = new List<ItemStack>();
|
||||
var items = new List<ItemStack>();
|
||||
var tileEntities = RebirthUtilities.GetTileEntities(player, distance);
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage))
|
||||
{
|
||||
if (storage.IsUserAccessing()) continue;
|
||||
|
||||
item.AddRange(storage.items);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var t in item)
|
||||
{
|
||||
if ((!t.itemValue.HasModSlots || !t.itemValue.HasMods()) &&
|
||||
t.itemValue.type == itemValue.type)
|
||||
{
|
||||
items.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
public static bool AddToNearbyContainer(EntityAlive player, ItemStack itemStack, float distance)
|
||||
{
|
||||
var tileEntities = RebirthUtilities.GetTileEntities(player, distance);
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) continue;
|
||||
|
||||
// If the container is open, don't include it.
|
||||
if (storage.IsUserAccessing()) continue;
|
||||
|
||||
// Don't try to add to a drop box.
|
||||
if (storage.blockValue.Block.Properties.Values.ContainsKey("DropBox")) continue;
|
||||
|
||||
// Can we quickly find a incomplete stack?
|
||||
//if (lootTileEntity.TryStackItem(0, itemStack)) return true;
|
||||
var result = storage.TryStackItem(0, itemStack);
|
||||
if (result.allMoved) return true;
|
||||
|
||||
var matchingItem = false;
|
||||
// Loop through the items and see if we have any matching items.
|
||||
foreach (var item in storage.items)
|
||||
{
|
||||
// We match with something.
|
||||
if (item.itemValue.type != itemStack.itemValue.type) continue;
|
||||
|
||||
matchingItem = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// If we don't match, don't try to add.
|
||||
if (!matchingItem) continue;
|
||||
|
||||
// We added a full stack! No need to keep processing.
|
||||
if (storage.AddItem(itemStack)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void ConsumeItem(IEnumerable<ItemStack> itemStacks, EntityPlayerLocal localPlayer, int multiplier, IList<ItemStack> _removedItems, Bag bag, Inventory toolbelt)
|
||||
{
|
||||
var tileEntities = GetTileEntities(localPlayer);
|
||||
var enumerable = itemStacks as ItemStack[] ?? itemStacks.ToArray();
|
||||
for (var i = 0; i < enumerable.Count(); i++)
|
||||
{
|
||||
// Grab from the backpack first.
|
||||
var num = enumerable[i].count * multiplier;
|
||||
if (bag != null)
|
||||
{
|
||||
num -= bag.DecItem(enumerable[i].itemValue, num, true, _removedItems);
|
||||
if (num > 0)
|
||||
{
|
||||
// Check tool belt
|
||||
if (toolbelt != null)
|
||||
{
|
||||
num -= toolbelt.DecItem(enumerable[i].itemValue, num, true, _removedItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We've met our goals for this.
|
||||
if (num <= 0) continue;
|
||||
|
||||
// check storage boxes
|
||||
foreach (var tileEntity in tileEntities)
|
||||
{
|
||||
if (num <= 0) break;
|
||||
|
||||
if (!tileEntity.TryGetSelfOrFeature(out ITileEntityLootable storage)) continue;
|
||||
|
||||
// If someone is using the tool account, skip it.
|
||||
if (storage.IsUserAccessing()) continue;
|
||||
|
||||
// If there's no items in this container, skip.
|
||||
if (!storage.HasItem(enumerable[i].itemValue)) continue;
|
||||
|
||||
for (var y = 0; y < storage.items.Length; y++)
|
||||
{
|
||||
var item = storage.items[y];
|
||||
if (item.IsEmpty()) continue;
|
||||
if (item.itemValue.ItemClass != enumerable[i].itemValue.ItemClass) continue;
|
||||
|
||||
// If we can completely satisfy the result, let's do that.
|
||||
if (item.count >= num)
|
||||
{
|
||||
item.count -= num;
|
||||
// Add the item to the removed items list so we can return it.
|
||||
_removedItems.Add(new ItemStack(item.itemValue.Clone(), num));
|
||||
num = 0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, let's just count down until we meet the requirement.
|
||||
while (num >= 0)
|
||||
{
|
||||
item.count--;
|
||||
num--;
|
||||
if (item.count <= 0)
|
||||
{
|
||||
_removedItems.Add(new ItemStack(item.itemValue.Clone(), num));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Update the slot on the container, and do the Setmodified(), so that the dedis can get updated.
|
||||
if (item.count < 1)
|
||||
{
|
||||
// Add it to the removed list.
|
||||
_removedItems.Add(item.Clone());
|
||||
storage.UpdateSlot(y, ItemStack.Empty.Clone());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
storage.UpdateSlot(y, item);
|
||||
}
|
||||
}
|
||||
storage.SetModified();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Score/RemoteCrafting/Scripts/XUiC/XUiC_BroadcastButton.cs
Normal file
89
Score/RemoteCrafting/Scripts/XUiC/XUiC_BroadcastButton.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
// Code from Laydor slightly modified
|
||||
public class XUiC_BroadcastButton : XUiController
|
||||
{
|
||||
private XUiV_Button _button;
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
base.Init();
|
||||
_button = viewComponent as XUiV_Button;
|
||||
OnPress += Grab_OnPress;
|
||||
}
|
||||
|
||||
public override void Update(float dt)
|
||||
{
|
||||
base.Update(dt);
|
||||
if (!IsDirty) return;
|
||||
IsDirty = false;
|
||||
SetupButton();
|
||||
}
|
||||
|
||||
public override void OnOpen()
|
||||
{
|
||||
base.OnOpen();
|
||||
|
||||
IsDirty = true;
|
||||
}
|
||||
|
||||
private void Grab_OnPress(XUiController sender, int mouseButton)
|
||||
{
|
||||
//Check if Broadcastmanager is running
|
||||
if (!Broadcastmanager.HasInstance) return;
|
||||
|
||||
if (Broadcastmanager.Instance.Check(xui.lootContainer.ToWorldPos()))
|
||||
{
|
||||
//Unselect button
|
||||
_button.Selected = true;
|
||||
// Remove from Broadcastmanager dictionary
|
||||
Broadcastmanager.Instance.remove(xui.lootContainer.ToWorldPos());
|
||||
}
|
||||
else
|
||||
{
|
||||
//Select button
|
||||
_button.Selected = false;
|
||||
// Add to Broadcastmanager dictionary
|
||||
Broadcastmanager.Instance.add(xui.lootContainer.ToWorldPos());
|
||||
}
|
||||
}
|
||||
|
||||
private void SetupButton()
|
||||
{
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton START");
|
||||
//Unselect button and disable it
|
||||
_button.Enabled = false;
|
||||
_button.Selected = false;
|
||||
_button.IsVisible = false;
|
||||
|
||||
if (xui.lootContainer != null)
|
||||
{
|
||||
Entity entity = GameManager.Instance.World.GetEntity(xui.lootContainer.EntityId) as Entity;
|
||||
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton entity: " + entity.EntityClass.entityClassName);
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton entity is EntityAliveV2: " + (entity is EntityAliveV2));
|
||||
|
||||
if (entity is EntityAliveV2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (xui.lootContainer == null || !Broadcastmanager.HasInstance ||
|
||||
xui.vehicle != null ||
|
||||
(xui.lootContainer != null && GameManager.Instance.World.GetEntity(xui.lootContainer.EntityId) is EntityDrone))
|
||||
{
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton xui.lootContainer == null: " + (xui.lootContainer == null));
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton !Broadcastmanager.HasInstance: " + (!Broadcastmanager.HasInstance));
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton xui.vehicle != null: " + (xui.vehicle != null));
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton EntityNPCRebirth: " + ((xui.lootContainer != null && GameManager.Instance.World.GetEntity(xui.lootContainer.entityId)) is EntityNPCRebirth));
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton EntityDrone: " + ((xui.lootContainer != null && GameManager.Instance.World.GetEntity(xui.lootContainer.entityId) is EntityDrone)));
|
||||
return;
|
||||
}
|
||||
|
||||
//Enable button and set if button is selected
|
||||
_button.IsVisible = true;
|
||||
_button.Enabled = true;
|
||||
_button.Selected = !Broadcastmanager.Instance.Check(xui.lootContainer.ToWorldPos());
|
||||
|
||||
//Log.Out("XUiC_BroadcastButton-SetupButton END");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user