Example #1
0
        private static void LimitDrops(CharacterDrop __instance, List <KeyValuePair <GameObject, int> > __result)
        {
            try
            {
                if (ConfigurationManager.GeneralConfig is null)
                {
                    return;
                }

                for (int i = 0; i < __result.Count; ++i)
                {
                    var item = __result[i];
                    if (ConfigurationManager.GeneralConfig.DropLimit > 0 && item.Value > ConfigurationManager.GeneralConfig.DropLimit)
                    {
                        Log.LogTrace($"Limiting {item.Key.name}:{item.Value} to {ConfigurationManager.GeneralConfig.DropLimit}");

                        __result[i] = Limit(item, ConfigurationManager.GeneralConfig.DropLimit);
                        continue;
                    }

                    var config = TempDropListCache.GetDrop(__instance, i);

                    if (config is not null && config.Config.SetAmountLimit > 0 && item.Value > config.Config.SetAmountLimit)
                    {
                        Log.LogTrace($"Limiting {item.Key.name}:{item.Value} to {config.Config.SetAmountLimit}");

                        __result[i] = Limit(item, config.Config.SetAmountLimit);
                    }
                }
            }
            catch (Exception e)
            {
                Log.LogError("Error while checking and applying drop amount limits.", e);
            }
        }
        private static void StoreConfigReferences(ZDO zdo, CharacterDrop drop, List <KeyValuePair <GameObject, int> > drops)
        {
            try
            {
#if DEBUG
                Log.LogDebug($"Packing config references for zdo {zdo.m_uid}");
#endif

                var cache = TempDropListCache.GetDrops(drops);
                cache ??= TempDropListCache.GetDrops(drop); // If we somehow failed to keep a consistent list reference (probably mod conflict). Attempt with the original CharacterDrop instead.

                if (cache is null)
                {
#if DEBUG
                    Log.LogDebug($"Found no drops for zdo {zdo.m_uid}");
#endif
                    return;
                }

                List <DropConfig> package = cache.ConfigByIndex
                                            .Select(x =>
                                                    new DropConfig
                {
                    Index     = x.Key,
                    ConfigKey = x.Value.Config.SectionKey,
                    IsList    = x.Value.Config.IsFromNamedList,
                })
                                            .ToList();

                using (MemoryStream memStream = new MemoryStream())
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    binaryFormatter.Serialize(memStream, package);

                    byte[] serialized = memStream.ToArray();

#if DEBUG
                    Log.LogDebug($"Serialized and set drops for zdo {zdo.m_uid}");
#endif

                    zdo.Set(ZDOKey, serialized);
                }
            }
            catch (Exception e)
            {
                Log.LogError("Error while attempting to store configurations for items to be dropped on ragdoll 'puff'.", e);
            }
        }
        private static void CarryExtended(List <KeyValuePair <GameObject, int> > dropItems, CharacterDrop.Drop drop, CharacterDrop characterDrop)
        {
            try
            {
                if (dropItems is null)
                {
#if DEBUG
                    Log.LogWarning("Unable to carry drop due to dropitems being null.");
#endif
                }

                if (drop is null)
                {
#if DEBUG
                    Log.LogWarning($"Unable to carry drop due to being null for {characterDrop}.");
#endif
                    return;
                }

                var extended = DropExtended.GetExtension(drop);

                if (extended is not null && dropItems is not null)
                {
#if DEBUG
                    Log.LogDebug($"Carrying configs for drop {extended.Config.SectionKey}:{characterDrop.GetHashCode()}");
                    Log.LogDebug($"Carrying configs for drop {drop.m_prefab.name}");
#endif
                    TempDropListCache.SetDrop(characterDrop, dropItems.Count - 1, extended);
                }

#if DEBUG
                else if (dropItems is null)
                {
                    Log.LogDebug("Disregard. No items to carry");
                    //Log.LogDebug($"Carrying configs for drop {drop.m_prefab.name}");
                }
                else if (extended is null)
                {
                    Log.LogDebug($"Disregard. No config to carry for item {drop}:{(drop.m_prefab.IsNull() ? "" : drop.m_prefab.name)}");
                }
#endif
            }
        private static void MoveConfigReferenceFromComponentToDrop(CharacterDrop __instance, List <KeyValuePair <GameObject, int> > __result)
        {
            try
            {
                var instanceReferences = TempDropListCache.GetDrops(__instance);

                if (instanceReferences is not null)
                {
                    //Re-associate result with configs.
                    foreach (var reference in instanceReferences.ConfigByIndex)
                    {
                        TempDropListCache.SetDrop(__result, reference.Key, reference.Value);
                    }
                }
            }
            catch (Exception e)
            {
                Log.LogWarning("Error while attempting to keep track of drops.", e);
            }
        }
        private static void OnSpawnedItem(GameObject item, List <KeyValuePair <GameObject, int> > drops, Vector3 centerPos)
        {
#if DEBUG
            //Log.LogDebug($"Attempting to apply modifiers to item {item.name}:{drops.GetHashCode()}");
            //Log.LogDebug($"Possible drops: " + drops.Join(x => $"{x.Key.name}:{x.Value}"));
#endif

            int count = LoopCounter.GetCount(drops);
            int index = GetIndex(drops, count);
            LoopCounter.Increment(drops);

#if DEBUG
            //Log.LogDebug($"[OnSpawnedItem] Count: {count}, Index: {index}");
#endif

            try
            {
                var extendedData = TempDropListCache.GetDrop(drops, index);

                if (extendedData is null)
                {
#if DEBUG
                    //Log.LogDebug($"No config for item {item.name} at index {index}");
#endif
                    return;
                }

#if DEBUG
                //Log.LogDebug($"Found config, applying modifiers to item {item.name}");
#endif

                DropModificationManager.Instance.ApplyModifications(item, extendedData, centerPos);
            }
            catch (Exception e)
            {
                Log.LogError("Error during drop modification.", e);
            }
        }
        private static int AfterSpawnedItem(GameObject item, List <KeyValuePair <GameObject, int> > drops, int index)
        {
            var resultIndex = index;

            try
            {
                var count     = LoopCounter.GetCount(drops) - 1;
                int itemIndex = GetIndex(drops, count);

#if DEBUG
                //Log.LogDebug($"[AfterSpawnedItem] Count: {count}, Index: {itemIndex}");
#endif

                if (itemIndex >= drops.Count)
                {
#if DEBUG
                    // Log.LogWarning($"Ups. Attempting to access drop index {itemIndex} in drop list with count {drops.Count}");
#endif
                    return(resultIndex);
                }

                var drop = drops[itemIndex];

                bool shouldStack = false;

                // Check if we should be stacking the item
                if (drop.Value > 1)
                {
                    if (ConfigurationManager.GeneralConfig.AlwaysAutoStack)
                    {
                        shouldStack = true;
                    }
                    else
                    {
                        var extendedData = TempDropListCache.GetDrop(drops, itemIndex);

                        if (extendedData is not null && extendedData.Config.SetAutoStack)
                        {
                            shouldStack = true;
                        }
                    }
                }

                if (shouldStack)
                {
                    var maxStack  = GetMaxStackSize(drop.Key);
                    var stackSize = Math.Min(maxStack, drop.Value - index);

                    if (stackSize > 1)
                    {
                        // Apply stack to item, and skip loop equivalently.
                        var itemDrop = ComponentCache.GetComponent <ItemDrop>(item);

                        Log.LogTrace($"Stacking item '{drop.Key.name}' {stackSize} times out of maximum {maxStack}.");

                        itemDrop.SetStack(stackSize);

                        // Deduct 1 from result, since loop will increment on its own, and OnSpawnedItem will have incremented loop too.
                        LoopCounter.Increment(drops, stackSize - 1);
                        resultIndex += stackSize - 1;

#if DEBUG
                        //Log.LogTrace($"Setting new loop index: {resultIndex}");
#endif
                    }
                }
            }
            catch (Exception e)
            {
                Log.LogError($"Error while attempting to stack item '{item.name}'. Skipping stacking.", e);
            }

            return(resultIndex);

            int GetMaxStackSize(GameObject item)
            {
                var itemDrop = ComponentCache.GetComponent <ItemDrop>(item);

                if (itemDrop.IsNull() ||
                    itemDrop.m_itemData?.m_shared is null)
                {
                    return(-1);
                }

                return(itemDrop.m_itemData.m_shared.m_maxStackSize);
            }
        }
        private static void LoadConfigReferences(ZDO zdo, List <KeyValuePair <GameObject, int> > dropList)
        {
            try
            {
#if DEBUG
                Log.LogDebug($"Unpacking config references for zdo {zdo.m_uid}");
#endif

                if (dropList is null)
                {
#if DEBUG
                    Log.LogDebug($"Drop list is empty. Skipping unpacking of zdo {zdo.m_uid}");
#endif
                    return;
                }

                var serialized = zdo.GetByteArray(ZDOKey);

                if (serialized is null)
                {
#if DEBUG
                    Log.LogDebug($"Found nothing to unpack for zdo {zdo.m_uid}");
#endif
                    return;
                }

                using (MemoryStream memStream = new MemoryStream(serialized))
                {
                    BinaryFormatter binaryFormatter = new BinaryFormatter();
                    var             responseObject  = binaryFormatter.Deserialize(memStream);

                    if (responseObject is List <DropConfig> configPackage)
                    {
#if DEBUG
                        Log.LogDebug($"Deserialized config package for zdo {zdo.m_uid}");
                        Log.LogDebug($"\t" + configPackage.Join(x => $"{x.Index}:{x.ConfigKey}"));
#endif

                        foreach (var entry in configPackage)
                        {
                            var configSections = entry.ConfigKey.SplitBy('.');

                            if (configSections.Count != 2)
                            {
                                Log.LogWarning($"Incorrect Drop That config section header '{entry.ConfigKey}' for zdo {zdo.m_uid}");
                                return;
                            }

                            if (entry.IsList)
                            {
                                if (ConfigurationManager.CharacterDropLists.TryGet(configSections[0], out CharacterDropListConfiguration listConfig))
                                {
                                    if (listConfig.TryGet(configSections[1], out CharacterDropItemConfiguration itemConfig))
                                    {
                                        TempDropListCache.SetDrop(dropList, entry.Index, new DropExtended
                                        {
                                            Config = itemConfig,
                                        });
                                    }
                                }
                            }
                            else if (ConfigurationManager.CharacterDropConfigs.TryGet(configSections[0], out CharacterDropMobConfiguration mobConfig))
                            {
                                if (mobConfig.TryGet(configSections[1], out CharacterDropItemConfiguration itemConfig))
                                {
                                    TempDropListCache.SetDrop(dropList, entry.Index, new DropExtended
                                    {
                                        Config = itemConfig,
                                    });
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.LogError("Error while attempting to attach and apply configurations to items.", e);
            }
        }