LootChests

Moved

Total Downloads: 3,131 - First Release: Jan 29, 2016 - Last Update: Jul 17, 2017

5/5, 16 likes
  1. I'm trying to remember is a server restart required for a full re install of the plugin? I deleted all files, uploaded the CS into the oxide plugins folder... reloaded via chat command. But now when I try to add items to the chests it says unknown command:lootchests
     
  2. It's /lootchest
    There's no s on the command
     
  3. :mad: Noviets U fail its "/lootchests" ^^

    have porbleme me my spawn chest = chest have spawned 2 secondes after chest despawned changed time to 1800 secondes for spawn and 3600 to despanw and dont works
     
  4. Forgot that I changed that lol, I've just updated the overview to say lootchests instead of lootchest.

    As for your issue. Make sure that your Despawn time is less than your respawn time, or you will be spawning more before they despawn.

    The Despawn timer starts AFTER they spawn, so if your have spawn time of 20 and despawn of 10. they will spawn after 20s, despawn 10 secs later. Then 10s after they despawn, they will respawn again.
     
  5. {
    "ChestSpawnCount": 20,
    "DestroyOnEmpty": true,
    "ItemsPerChest": 3,
    "MaximumRange": 3000.0,
    "MininumRange": 0.0,
    "SecondsForSpawn": 600,
    "SecondsTillDestroy": 1800,
    "ShowDespawnMessage": true,
    "ShowSpawnMessage": true,
    "StartPoints": [
    "-3000, 450, -3000"
    ]
    }

    i have this and bug again ^^'
     
  6. Noviets i just cannot check it.

    If I reload your plugin does the start time restart?
    For example:
    The server is turned on at 08:00
    At 09:00 i do a reload of the plugin every 2 hours the chest spawn. Does that mean at 11:00 the chest spawn or at 10:00?
    If so I might found a way to respawn them at my given times.
     
  7. need update for "DestroyOnEmpty": true, will destroy instantly chest lol ( no loot just chest )
     
  8. i get this spam error wen i use lootchests,

    Code:
    (Filename: Line: -1)Exception in SlowUpdate: Array index is out of range.
    at BiomeManager.FillGenerateBiomeData (Vector2 position, .BiomeCellData data) [0x00000] in <filename unknown>:0at BiomeManager.UpdateEffectsOnEntity (IBiomeAffectedObject biomeObject) [0x00000] in <filename unknown>:0at BiomeObject.SlowUpdate (Single delta) [0x00000] in <filename unknown>:0at LoadBalancer.RunFrame () [0x00000] in <filename unknown>:0 
     
  9. I have my "destroy on loot" set to true but they still load as chests
     
  10. What did I do wrong here?


    {
    "ChestSpawnCount": 10,
    "DestroyOnEmpty": false,
    "ItemsPerChest": 1,
    "MaximumRange": 1700.0,
    "MininumRange": 20.0,
    "SecondsForSpawn": 3600,
    "SecondsTillDestroy": 1200,
    "ShowDespawnMessage": true,
    "ShowSpawnMessage": true,
    "StartPoints": [
    "-2816, 198, -1409",
    "-2136, 181, 1261",
    "-755, 227, -2637",
    "1556, 192, -1686"
    ]
    }

    It says in the console that the spawn stops because of too many invalid spawn locations. I used the location plugin to choose the start points.
     
  11. Correct me if i am wrong but i think you need to change the hight. The middle. Change it like the example 450.
     
    Last edited by a moderator: Mar 1, 2016
  12. Thanks! That fixed it!

    Now the number of spawn is that total of all spawn points or per spawn point?
     
    Last edited by a moderator: Mar 7, 2016
  13. Any answers on my above question?
     
  14. Total so 20 is 20 over the while map
     
  15. I got this working partly, it spawned boxes in 7 specific locations, but it spawned a fuckton of them. So i changed the number of spawn and reloaded and now anytime I change the config and reload it wipes its own config file :(
     
  16. Same problem for me.
     
  17. Hi i am having trouble with Lootchests spawning in game. I have tried repeatedly to make them work. The first time they worked but only spawned 1 or two chests in the entire map so i tried to increase them and updated it all. Next, i reloaded the number for the items into the game again and it said it all was added. And they spawned, but when we all tried to access them they were empty? So i got so frustrated that i deleted the whole thing and started fresh. downloaded a new install and reinstalled a whole new item count into the game manually and it said again that it worked. Now there is nothing spawning at all and im about at my wits end. Everyone is asking me when its going to be fixed and i am not sure what to do. If Someone could tell me how the configurations should be set, at least that would be a huge help...

    Thanks
     
  18. Could you post your config? and do you use the default map (Diemensland) or an other map?
     
  19. Here it is
    //#define DEBUG

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Text;

    using Newtonsoft.Json;
    using Newtonsoft.Json.Converters;

    namespace Oxide.Plugins
    {
    [Info("LootConfig", "Nogrod", "1.0.2", ResourceId = 1550)]
    internal class LootConfig : HurtworldPlugin
    {
    private const int VersionConfig = 3;
    private ConfigData _config;

    private readonly FieldInfo lootConfigsField = typeof(LootCalculator).GetField("_lootConfigs", BindingFlags.NonPublic | BindingFlags.Instance);
    private readonly FieldInfo childrenField = typeof(LootTreeNode).GetField("_children", BindingFlags.NonPublic | BindingFlags.Instance);

    private new void LoadDefaultConfig()
    {
    }

    private new bool LoadConfig()
    {
    try
    {
    Config.Settings = new JsonSerializerSettings();
    if (!Config.Exists())
    return CreateDefaultConfig();
    _config = Config.ReadObject<ConfigData>();
    }
    catch (Exception e)
    {
    Puts("Config load failed: {0}{1}{2}", e.Message, Environment.NewLine, e.StackTrace);
    return false;
    }
    return true;
    }

    private void OnServerInitialized()
    {
    if (!LoadConfig())
    return;
    CheckConfig();
    NextTick(UpdateLoot);
    }

    [ConsoleCommand("loot.stats")]
    private void cmdLootStats(string commandString)
    {
    var lootConfigs = (Dictionary<ELootConfig, LootTreeNode>)lootConfigsField.GetValue(LootCalculator.Instance);
    var sb = new StringBuilder();
    sb.AppendLine();
    foreach (var loot in lootConfigs)
    {
    sb.AppendLine(loot.Key.ToString());
    PrintLootNode(loot.Value, 1, sb, 1);
    }
    Puts(sb.ToString());
    }

    [ConsoleCommand("loot.reload")]
    private void cmdConsoleReload(string commandString)
    {
    if (!LoadConfig())
    return;
    CheckConfig();
    UpdateLoot();
    Puts("Loot config reloaded.");
    }

    [ConsoleCommand("loot.reset")]
    private void cmdConsoleReset(string commandString)
    {
    lootConfigsField.SetValue(LootCalculator.Instance, new Dictionary<ELootConfig, LootTreeNode>());
    LootCalculator.Instance.Start();
    if (!CreateDefaultConfig())
    return;
    CheckConfig();
    UpdateLoot();
    Puts("Loot config reset.");
    }

    private void PrintLootNode(LootTreeNode lootNode, double parentChance, StringBuilder sb, int depth = 0)
    {
    var children = (List<KeyValuePair<double, LootTreeNode>>)childrenField.GetValue(lootNode);
    if (children != null && children.Count > 0)
    {
    sb.Append('\t', depth);
    sb.AppendLine($"{parentChance:p1}");
    depth++;
    var sum = children.Sum(l => l.Key);
    var cur = 0d;
    foreach (var entry in children)
    {
    cur += entry.Key;
    PrintLootNode(entry.Value, parentChance * (cur / sum), sb, depth);
    }
    return;
    }
    var itemGeneratorStatic = lootNode.LootResult as ItemGeneratorStatic;
    if (itemGeneratorStatic != null)
    {
    sb.Append('\t', depth);
    sb.AppendLine($"{parentChance:p1} {itemGeneratorStatic.StackSize}x {itemGeneratorStatic.ItemId} ({itemGeneratorStatic.RandomVariance})");
    }
    }

    private bool CreateDefaultConfig()
    {
    Config.Clear();

    var lootConfigs = (Dictionary<ELootConfig, LootTreeNode>)lootConfigsField.GetValue(LootCalculator.Instance);

    try
    {
    Config.Settings = new JsonSerializerSettings
    {
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    Converters = new List<JsonConverter>
    {
    new StringEnumConverter(),
    new LootTreeNodeConverter(),
    new ItemGeneratorStaticConverter()
    }
    };
    Config.WriteObject(new ExportData
    {
    Version = GameManager.Instance.GetProtocolVersion(),
    VersionConfig = VersionConfig,
    LootConfigs = lootConfigs
    });
    }
    catch (Exception e)
    {
    Puts("Config save failed: {0}{1}{2}", e.Message, Environment.NewLine, e.StackTrace);
    return false;
    }
    Puts("Created new config");
    return LoadConfig();
    }

    private void CheckConfig()
    {
    if (_config.Version == GameManager.Instance.GetProtocolVersion() && _config.VersionConfig == VersionConfig) return;
    Puts("Incorrect config version({0}/{1})", _config.Version, _config.VersionConfig);
    if (_config.Version > 0) Config.WriteObject(_config, false, $"{Config.Filename}.old");
    CreateDefaultConfig();
    }

    private void UpdateLoot()
    {
    var lootConfigs = new Dictionary<ELootConfig, LootTreeNode>();
    foreach (var nodeData in _config.LootConfigs)
    lootConfigs.Add(nodeData.Key, GetLootTreeNode(nodeData.Value));
    lootConfigsField.SetValue(LootCalculator.Instance, lootConfigs);
    }

    private LootTreeNode GetLootTreeNode(LootTreeNodeData lootTreeNodeData)
    {
    var lootTreeNode = new LootTreeNode
    {
    RollCount = lootTreeNodeData.RollCount,
    RollWithoutReplacement = lootTreeNodeData.RollWithoutReplacement
    };
    if (lootTreeNodeData.LootResult != null)
    {
    var itemGenerator = new ItemGeneratorStatic
    {
    ItemId = lootTreeNodeData.LootResult.ItemId,
    RandomVariance = lootTreeNodeData.LootResult.RandomVariance,
    StackSize = (int) Math.Ceiling(lootTreeNodeData.LootResult.StackSize * _config.GlobalStackSizeMultiplier)
    };
    lootTreeNode.LootResult = itemGenerator;
    }
    foreach (var child in lootTreeNodeData.Children)
    lootTreeNode.AddChild(child.Key, GetLootTreeNode(child.Value));
    return lootTreeNode;
    }

    #region Nested type: ConfigData

    public class ConfigData
    {
    public float GlobalStackSizeMultiplier { get; set; } = 5;
    public int Version { get; set; }
    public int VersionConfig { get; set; }
    public Dictionary<ELootConfig, LootTreeNodeData> LootConfigs { get; set; } = new Dictionary<ELootConfig, LootTreeNodeData>();
    }

    #endregion

    #region Nested type: ExportData

    public class ExportData
    {
    public float GlobalStackSizeMultiplier { get; set; } = 5;
    public int Version { get; set; }
    public int VersionConfig { get; set; }
    public Dictionary<ELootConfig, LootTreeNode> LootConfigs { get; set; } = new Dictionary<ELootConfig, LootTreeNode>();
    }

    #endregion

    #region Nested type: LootTreeNodeConverter

    private class LootTreeNodeConverter : JsonConverter
    {
    private readonly FieldInfo childrenField = typeof(LootTreeNode).GetField("_children", BindingFlags.NonPublic | BindingFlags.Instance);

    public override bool CanRead => false;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    var node = (LootTreeNode) value;
    writer.WriteStartObject();
    writer.WritePropertyName(nameof(node.RollCount));
    writer.WriteValue(node.RollCount);
    writer.WritePropertyName(nameof(node.RollWithoutReplacement));
    writer.WriteValue(node.RollWithoutReplacement);
    writer.WritePropertyName(nameof(node.LootResult));
    serializer.Serialize(writer, node.LootResult);
    writer.WritePropertyName("Children");
    serializer.Serialize(writer, childrenField.GetValue(node));
    writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
    return null;
    }

    public override bool CanConvert(Type objectType)
    {
    return typeof (LootTreeNode).IsAssignableFrom(objectType);
    }
    }

    #endregion

    #region Nested type: LootTreeNodeData

    public class LootTreeNodeData
    {
    public int RollCount { get; set; } = 1;
    public bool RollWithoutReplacement { get; set; } = true;
    public ItemGeneratorData LootResult { get; set; }
    public List<KeyValuePair<double, LootTreeNodeData>> Children { get; set; } = new List<KeyValuePair<double, LootTreeNodeData>>();
    }

    #endregion

    #region Nested type: ItemGeneratorStaticConverter

    private class ItemGeneratorStaticConverter : JsonConverter
    {
    public override bool CanRead => false;

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    var itemGeneratorStatic = (ItemGeneratorStatic)value;
    writer.WriteStartObject();
    writer.WritePropertyName(nameof(itemGeneratorStatic.ItemId));
    writer.WriteValue(itemGeneratorStatic.ItemId.ToString());
    writer.WritePropertyName(nameof(itemGeneratorStatic.StackSize));
    writer.WriteValue(itemGeneratorStatic.StackSize);
    writer.WritePropertyName(nameof(itemGeneratorStatic.RandomVariance));
    writer.WriteValue(itemGeneratorStatic.RandomVariance);
    writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
    return null;
    }

    public override bool CanConvert(Type objectType)
    {
    return typeof(ItemGeneratorStatic).IsAssignableFrom(objectType);
    }
    }

    #endregion

    #region Nested type: ItemGeneratorData

    public class ItemGeneratorData
    {
    public EItemCode ItemId { get; set; }
    public int StackSize { get; set; } = 1;
    public int RandomVariance { get; set; }
    }

    #endregion
    }
    }
     
  20. Thats the script itself. Did you change this there?
    The config is in oxide/config and maybe also post the data. Please use attachment for easy reading