using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Bloodstone.API;
using Bloody.Core;
using Bloody.Core.API.v1;
using Bloody.Core.GameData.v1;
using Bloody.Core.Helper.v1;
using Bloody.Core.Methods;
using Bloody.Core.Models.v1;
using Bloody.Core.Models.v1.Base;
using Bloody.Core.Patch.Server;
using BloodyEncounters.Data;
using BloodyEncounters.Data.Models;
using BloodyEncounters.EventsHandler;
using BloodyEncounters.Exceptions;
using HarmonyLib;
using ProjectM;
using ProjectM.Shared;
using Stunlock.Core;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using VampireCommandFramework;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("BloodyEncounters")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A server side mod for V Rising which spawns a random NPC near a random online player at random intervals, and the player wins a random item reward if the NPC is killed within the given time limit.")]
[assembly: AssemblyFileVersion("3.0.1.0")]
[assembly: AssemblyInformationalVersion("3.0.1+1.Branch.master.Sha.aae5bc66d36eaa365dfdb46f68203648d9aa1445")]
[assembly: AssemblyProduct("BloodyEncounters")]
[assembly: AssemblyTitle("BloodyEncounters")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.1.0")]
[module: UnverifiableCode]
namespace BloodyEncounters
{
internal class EncounterSystem
{
public static bool EncounterStarted = false;
private static readonly ConcurrentDictionary<ulong, ConcurrentDictionary<int, ItemEncounterModel>> RewardsMap = new ConcurrentDictionary<ulong, ConcurrentDictionary<int, ItemEncounterModel>>();
private static readonly ConcurrentDictionary<int, UserModel> NpcPlayerMap = new ConcurrentDictionary<int, UserModel>();
private static PrefabCollectionSystem _prefabCollectionSystem = Plugin.SystemsCore.PrefabCollectionSystem;
internal static Dictionary<long, (float actualDuration, Action<Entity> Actions)> PostActions = new Dictionary<long, (float, Action<Entity>)>();
public static Random Random = new Random();
public static Action encounterAction;
internal static void Initialize()
{
if (Config.Enabled.Value)
{
GenerateStats();
StartEncounterTimer();
}
}
internal static void GenerateStats()
{
foreach (NpcEncounterModel item in Database.NPCS.Where((NpcEncounterModel x) => x.unitStats == null).ToList())
{
item.GenerateStats();
}
Database.saveDatabase();
}
public static void StartEncounterTimer()
{
Plugin.Logger.LogInfo("Start Timner for encounters");
encounterAction = delegate
{
if (Config.Enabled.Value)
{
ActionScheduler.RunActionOnMainThread((Action)delegate
{
StartEncounter();
});
}
};
CoroutineHandler.StartRandomIntervalCoroutine(encounterAction, (float)Config.EncounterTimerMin.Value, (float)Config.EncounterTimerMax.Value);
}
internal static void StartEncounter(UserModel user = null)
{
//IL_0223: Unknown result type (might be due to invalid IL or missing references)
//IL_022e: Unknown result type (might be due to invalid IL or missing references)
//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
if (EncounterStarted)
{
return;
}
_ = Core.World;
if (user == null)
{
IEnumerable<UserModel> source = GameData.Users.Online.Where((UserModel u) => GameData.Users.FromEntity(((EntityModel)u).Entity).Character.Equipment.Level >= (float)Config.EncounterMinLevel.Value);
if (Config.SkipPlayersInCastle.Value)
{
source = source.Where((UserModel u) => !UserModelMethods.IsInCastle(u));
}
if (Config.SkipPlayersInCombat.Value)
{
source = source.Where((UserModel u) => !UserModelMethods.IsInCombat(u));
}
user = source.OrderBy((UserModel _) => Random.Next()).FirstOrDefault();
}
if (user == null)
{
Plugin.Logger.LogMessage("Could not find any eligible players for a random encounter...");
return;
}
NpcEncounterModel npc = DataFactory.GetRandomNpc();
if (npc == null)
{
Plugin.Logger.LogWarning("Could not find any NPCs");
return;
}
Plugin.Logger.LogMessage("Attempting to start a new encounter for " + user.CharacterName);
try
{
string empty = string.Empty;
NpcPlayerMap[npc.PrefabGUID] = user;
if (npc.Group != "")
{
foreach (NpcEncounterModel item in Database.NPCS.Where((NpcEncounterModel x) => x.Group == npc.Group).ToList())
{
item.Spawn(((EntityModel)user).Entity, user.Position, npc.Lifetime);
}
empty = string.Format(Config.EncounterMessageGroupTemplate.Value, npc.Group, npc.Lifetime);
}
else
{
npc.Spawn(((EntityModel)user).Entity, user.Position);
empty = string.Format(Config.EncounterMessageTemplate.Value, npc.name, npc.Lifetime);
}
UserModelMethods.SendSystemMessage(user, empty);
EncounterStarted = true;
CoroutineHandler.StartRepeatingCoroutine((Action)delegate
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
if (EncounterStarted)
{
if (npc.Group != "")
{
foreach (NpcEncounterModel item2 in Database.NPCS.Where((NpcEncounterModel x) => x.Group == npc.Group).ToList())
{
item2.KillNpc(((EntityModel)user).Entity);
}
EncounterStarted = false;
}
else
{
npc.KillNpc(((EntityModel)user).Entity);
EncounterStarted = false;
}
}
}, npc.Lifetime, 1);
}
catch (Exception ex)
{
Plugin.Logger.LogError(ex);
EncounterStarted = false;
}
}
}
[BepInPlugin("BloodyEncounters", "BloodyEncounters", "3.0.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[Reloadable]
public class Plugin : BasePlugin, IRunOnInitialized
{
private Harmony _harmony;
public static Logger Logger;
public static SystemsCore SystemsCore;
public override void Load()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Expected O, but got Unknown
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Expected O, but got Unknown
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Expected O, but got Unknown
ManualLogSource log = ((BasePlugin)this).Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("BloodyEncounters");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("3.0.1");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
}
log.LogInfo(val);
Logger = new Logger(((BasePlugin)this).Log);
_harmony = new Harmony("BloodyEncounters");
_harmony.PatchAll(Assembly.GetExecutingAssembly());
EventsHandlerSystem.OnInitialize += new OnGameDataInitializedEventHandler(GameDataOnInitialize);
EventsHandlerSystem.OnDestroy += new OnGameDataDestroyedEventHandler(GameDataOnDestroy);
CommandRegistry.RegisterAll();
}
public override bool Unload()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Expected O, but got Unknown
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Expected O, but got Unknown
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
EventsHandlerSystem.OnInitialize -= new OnGameDataInitializedEventHandler(GameDataOnInitialize);
EventsHandlerSystem.OnDestroy -= new OnGameDataDestroyedEventHandler(GameDataOnDestroy);
EventsHandlerSystem.OnDeath -= new DeathEventHandler(OnDeath.OnDeathEvent);
CommandRegistry.UnregisterAssembly();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
return true;
}
public void OnGameInitialized()
{
}
private static void GameDataOnInitialize(World world)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Expected O, but got Unknown
SystemsCore = Core.SystemsCore;
Logger.LogInfo("Loading main data");
Database.Initialize();
Logger.LogInfo("Binding configuration");
Config.Initialize();
EventsHandlerSystem.OnDeath += new DeathEventHandler(OnDeath.OnDeathEvent);
EncounterSystem.Initialize();
}
private static void GameDataOnDestroy()
{
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "BloodyEncounters";
public const string PLUGIN_NAME = "BloodyEncounters";
public const string PLUGIN_VERSION = "3.0.1";
}
}
namespace BloodyEncounters.Exceptions
{
internal class NPCDontExistException : Exception
{
public NPCDontExistException()
{
}
public NPCDontExistException(string message)
: base(message)
{
}
public NPCDontExistException(string message, Exception innerException)
: base(message, innerException)
{
}
protected NPCDontExistException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
internal class NPCExistException : Exception
{
public NPCExistException()
{
}
public NPCExistException(string message)
: base(message)
{
}
public NPCExistException(string message, Exception innerException)
: base(message, innerException)
{
}
protected NPCExistException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
internal class ProductDontExistException : Exception
{
public ProductDontExistException()
{
}
public ProductDontExistException(string message)
: base(message)
{
}
public ProductDontExistException(string message, Exception innerException)
: base(message, innerException)
{
}
protected ProductDontExistException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
internal class ProductExistException : Exception
{
public ProductExistException()
{
}
public ProductExistException(string message)
: base(message)
{
}
public ProductExistException(string message, Exception innerException)
: base(message, innerException)
{
}
protected ProductExistException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}
}
namespace BloodyEncounters.EventsHandler
{
internal class OnDeath
{
public static void OnDeathEvent(DeathEventListenerSystem sender, NativeArray<DeathEvent> deathEvents)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
PrefabCollectionSystem prefabCollectionSystem = Plugin.SystemsCore.PrefabCollectionSystem;
Enumerator<DeathEvent> enumerator = deathEvents.GetEnumerator();
PrefabGUID val2 = default(PrefabGUID);
Entity val3 = default(Entity);
while (enumerator.MoveNext())
{
DeathEvent current = enumerator.Current;
if (!ECSExtensions.Has<PlayerCharacter>(current.Killer) || !ECSExtensions.Has<NameableInteractable>(current.Died))
{
continue;
}
EntityManager entityManager = ((ComponentSystemBase)sender).EntityManager;
PlayerCharacter componentData = ((EntityManager)(ref entityManager)).GetComponentData<PlayerCharacter>(current.Killer);
UserModel userModel = GameData.Users.FromEntity(componentData.UserEntity);
PrefabGUID val = ECSExtensions.Read<PrefabGUID>(current.Died);
FixedString128Bytes npc = prefabCollectionSystem._PrefabDataLookup[val].AssetName;
NpcEncounterModel npcEncounterModel = Database.NPCS.Where((NpcEncounterModel x) => x.AssetName == ((object)(FixedString128Bytes)(ref npc)).ToString()).FirstOrDefault();
if (npcEncounterModel == null)
{
EncounterSystem.EncounterStarted = false;
}
else
{
if (!npcEncounterModel.GetNPCEntity())
{
continue;
}
ItemEncounterModel randomItem = DataFactory.GetRandomItem(npcEncounterModel);
((PrefabGUID)(ref val2))..ctor(randomItem.ItemID);
int stack = randomItem.Stack;
if (!UserModelMethods.TryGiveItem(userModel, val2, stack, ref val3))
{
Plugin.Logger.LogError(userModel.CharacterName + " Error Drop " + randomItem.name);
}
string text = string.Format(Config.RewardMessageTemplate.Value, randomItem.Color, randomItem.name);
UserModelMethods.SendSystemMessage(userModel, text);
Plugin.Logger.LogDebug(userModel.CharacterName + " earned reward: " + randomItem.name);
string text2 = string.Format(Config.RewardAnnouncementMessageTemplate.Value, userModel.CharacterName, randomItem.Color, randomItem.name);
if (Config.NotifyAllPlayersAboutRewards.Value)
{
foreach (UserModel item in GameData.Users.Online.Where((UserModel u) => u.PlatformId != userModel.PlatformId))
{
UserModelMethods.SendSystemMessage(item, text2);
}
}
else if (Config.NotifyAdminsAboutEncountersAndRewards.Value)
{
foreach (UserModel item2 in GameData.Users.Online.Where((UserModel x) => x.IsAdmin))
{
UserModelMethods.SendSystemMessage(item2, $"{userModel.CharacterName} earned an encounter reward: <color={randomItem.Color}>{randomItem.name}</color>");
}
}
EncounterSystem.EncounterStarted = false;
}
}
}
}
}
namespace BloodyEncounters.Data
{
internal class Config
{
private static ConfigFile _mainConfig;
public static ConfigEntry<bool> Enabled { get; private set; }
public static ConfigEntry<bool> SkipPlayersInCastle { get; private set; }
public static ConfigEntry<int> EncounterTimerMin { get; private set; }
public static ConfigEntry<int> EncounterTimerMax { get; private set; }
public static ConfigEntry<int> EncounterMinLevel { get; private set; }
public static ConfigEntry<string> EncounterMessageTemplate { get; private set; }
public static ConfigEntry<string> EncounterMessageGroupTemplate { get; private set; }
public static ConfigEntry<string> RewardMessageTemplate { get; private set; }
public static ConfigEntry<string> RewardAnnouncementMessageTemplate { get; private set; }
public static ConfigEntry<bool> NotifyAdminsAboutEncountersAndRewards { get; private set; }
public static ConfigEntry<bool> NotifyAllPlayersAboutRewards { get; private set; }
public static ConfigEntry<bool> SkipPlayersInCombat { get; private set; }
public static void Initialize()
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath ?? Path.Combine("BepInEx", "config"), "BloodyEncounters");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
string text2 = Path.Combine(text, "BloodyEncounters.cfg");
_mainConfig = (File.Exists(text2) ? new ConfigFile(text2, false) : new ConfigFile(text2, true));
Enabled = _mainConfig.Bind<bool>("Main", "Enabled", true, "Determines whether the random encounter timer is enabled or not.");
SkipPlayersInCastle = _mainConfig.Bind<bool>("Main", "SkipPlayersInCastle", true, "When enabled, players who are in a castle are excluded from encounters");
SkipPlayersInCombat = _mainConfig.Bind<bool>("Main", "SkipPlayersInCombat", false, "When enabled, players who are in combat are excluded from the random encounters.");
EncounterTimerMin = _mainConfig.Bind<int>("Main", "EncounterTimerMin", 1200, "Minimum seconds before a new encounter is initiated. This value is divided by the online users count.");
EncounterTimerMax = _mainConfig.Bind<int>("Main", "EncounterTimerMax", 2400, "Maximum seconds before a new encounter is initiated. This value is divided by the online users count.");
EncounterMinLevel = _mainConfig.Bind<int>("Main", "EncounterMinLevel", 10, "The lower value for the Player level for encounter.");
EncounterMessageTemplate = _mainConfig.Bind<string>("Main", "EncounterMessageTemplate", "You have encountered a <color=#daa520>{0}</color>. You have <color=#daa520>{1}</color> seconds to kill it for a chance of a random reward.", "System message template for the encounter.");
EncounterMessageGroupTemplate = _mainConfig.Bind<string>("Main", "EncounterMessageGroupTemplate", "You have encountered with a group called <color=#daa520>{0}</color>. You have <color=#daa520>{1}</color> seconds to kill it for a chance of a random reward.", "System message template for the group encounter.");
RewardMessageTemplate = _mainConfig.Bind<string>("Main", "RewardMessageTemplate", "Congratulations. Your reward: <color={0}>{1}</color>.", "System message template for the reward.");
RewardAnnouncementMessageTemplate = _mainConfig.Bind<string>("Main", "RewardAnnouncementMessageTemplate", "{0} earned an encounter reward: <color={1}>{2}</color>.", "System message template for the reward announcement.");
NotifyAdminsAboutEncountersAndRewards = _mainConfig.Bind<bool>("Main", "NotifyAdminsAboutEncountersAndRewards", true, "If enabled, all online admins are notified about encounters and rewards.");
NotifyAllPlayersAboutRewards = _mainConfig.Bind<bool>("Main", "NotifyAllPlayersAboutRewards", false, "When enabled, all online players are notified about any player's rewards.");
}
public static void Destroy()
{
_mainConfig.Clear();
}
private static string CleanupName(string name)
{
return new Regex("[^a-zA-Z0-9 -]").Replace(name, "");
}
}
internal class Database
{
private static readonly Random Random = new Random();
public static readonly string ConfigPath = Path.Combine(Paths.ConfigPath, "BloodyEncounters");
public static string NPCSListFile = Path.Combine(ConfigPath, "NPCS.json");
public static List<NpcEncounterModel> NPCS { get; set; } = new List<NpcEncounterModel>();
public static void Initialize()
{
createDatabaseFiles();
loadDatabase();
}
public static bool createDatabaseFiles()
{
if (!Directory.Exists(ConfigPath))
{
Directory.CreateDirectory(ConfigPath);
}
if (!File.Exists(NPCSListFile))
{
File.WriteAllText(NPCSListFile, "[]");
}
Plugin.Logger.LogDebug("Create Database: OK");
return true;
}
public static bool saveDatabase()
{
try
{
string contents = JsonSerializer.Serialize(NPCS, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText(NPCSListFile, contents);
Plugin.Logger.LogDebug("Save Database: OK");
return true;
}
catch (Exception ex)
{
Plugin.Logger.LogError("Error SaveDatabase: " + ex.Message);
return false;
}
}
public static bool loadDatabase()
{
try
{
List<NpcEncounterModel> list = JsonSerializer.Deserialize<List<NpcEncounterModel>>(File.ReadAllText(NPCSListFile));
foreach (NpcEncounterModel item in list)
{
item.nameHash = item.name.GetHashCode().ToString();
}
NPCS = list;
Plugin.Logger.LogDebug("Load Database: OK");
return true;
}
catch (Exception ex)
{
Plugin.Logger.LogError("Error LoadDatabase: " + ex.Message);
return false;
}
}
public static bool GetNPC(string NPCName, out NpcEncounterModel npc)
{
npc = NPCS.Where((NpcEncounterModel x) => x.name == NPCName).FirstOrDefault();
if (npc == null)
{
return false;
}
return true;
}
public static bool GetNPCFromEntity(Entity npcEntity, out NpcEncounterModel npc)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
npc = NPCS.Where((NpcEncounterModel x) => ((Entity)(ref x.npcEntity)).Equals(npcEntity)).FirstOrDefault();
if (npc == null)
{
return false;
}
return true;
}
public static bool AddNPC(string NPCName, int prefabGUIDOfNPC, int levelAbove, int lifetime, string group)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
if (GetNPC(NPCName, out var npc))
{
throw new NPCExistException();
}
ConvertedAssetData val = Plugin.SystemsCore.PrefabCollectionSystem._PrefabDataLookup[new PrefabGUID(prefabGUIDOfNPC)];
string assetName = ((object)(FixedString128Bytes)(ref val.AssetName)).ToString();
Entity val2 = Plugin.SystemsCore.PrefabCollectionSystem._PrefabGuidToEntityMap[new PrefabGUID(prefabGUIDOfNPC)];
npc = new NpcEncounterModel();
npc.AssetName = assetName;
npc.name = NPCName;
npc.nameHash = NPCName.GetHashCode().ToString();
npc.PrefabGUID = prefabGUIDOfNPC;
npc.levelAbove = levelAbove;
npc.Lifetime = lifetime;
npc.Group = group;
UnitStats stats = ECSExtensions.Read<UnitStats>(val2);
npc.unitStats = new UnitStatsModel();
npc.unitStats.SetStats(stats);
NPCS.Add(npc);
saveDatabase();
return true;
}
public static bool RemoveNPC(string NPCName)
{
if (GetNPC(NPCName, out var npc))
{
NPCS.Remove(npc);
saveDatabase();
return true;
}
throw new NPCDontExistException();
}
}
internal static class DataFactory
{
private static readonly Random Random = new Random();
private static List<NpcEncounterModel> _npcs;
private static List<ItemEncounterModel> _items;
internal static NpcEncounterModel GetRandomNpc()
{
_npcs = Database.NPCS;
return _npcs.GetRandomItem();
}
internal static ItemEncounterModel GetRandomItem(NpcEncounterModel npc)
{
_items = npc.items;
return _items.GetRandomItem();
}
private static T GetRandomItem<T>(this List<T> items)
{
if (items == null || items.Count == 0)
{
return default(T);
}
return items[Random.Next(items.Count)];
}
}
}
namespace BloodyEncounters.Data.Models
{
internal class ItemEncounterModel
{
public string name { get; set; }
public int ItemID { get; set; }
public int Stack { get; set; }
public int Chance { get; set; } = 1;
public string Color { get; set; } = "#daa520";
}
internal class NpcEncounterModel
{
internal string nameHash;
public NpcModel npcModel;
public Entity npcEntity;
public string name { get; set; } = string.Empty;
public int PrefabGUID { get; set; }
public string AssetName { get; set; } = string.Empty;
public int levelAbove { get; set; }
public List<ItemEncounterModel> items { get; set; } = new List<ItemEncounterModel>();
public float Lifetime { get; set; }
public string Group { get; set; } = string.Empty;
public UnitStatsModel unitStats { get; set; }
public List<ItemEncounterModel> GetItems()
{
return items;
}
public bool GetItem(int itemPrefabID, out ItemEncounterModel item)
{
item = items.Where((ItemEncounterModel x) => x.ItemID == itemPrefabID).FirstOrDefault();
if (item == null)
{
return false;
}
return true;
}
public bool GetItemFromName(string ItemName, out ItemEncounterModel item)
{
item = items.Where((ItemEncounterModel x) => x.name == ItemName).FirstOrDefault();
if (item == null)
{
return false;
}
return true;
}
public bool AddItem(string ItemName, int ItemPrefabID, int Stack)
{
if (!GetItem(ItemPrefabID, out var item))
{
item = new ItemEncounterModel();
item.name = ItemName;
item.ItemID = ItemPrefabID;
item.Stack = Stack;
items.Add(item);
Database.saveDatabase();
return true;
}
throw new ProductExistException();
}
public bool RemoveItem(string ItemName)
{
if (GetItemFromName(ItemName, out var item))
{
items.Remove(item);
Database.saveDatabase();
return true;
}
throw new ProductDontExistException();
}
public bool Spawn(Entity sender, float3 pos)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
SpawnSystem.SpawnUnitWithCallback(sender, new PrefabGUID(PrefabGUID), new float2(pos.x, pos.z), Lifetime, (Action<Entity>)delegate(Entity e)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
npcEntity = e;
if (ECSExtensions.Has<VBloodUnit>(npcEntity))
{
CoroutineHandler.StartFrameCoroutine((Action)delegate
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
VBloodUnit val = ECSExtensions.Read<VBloodUnit>(npcEntity);
val.CanBeTracked = false;
val.UnlocksTrophyOnFeed = (Trophy)(-1);
val.UnlocksTrophyOnFeedBrutal = (Trophy)(-1);
ECSExtensions.Write<VBloodUnit>(npcEntity, val);
}, 3, 1);
}
ECSExtensions.ReadBuffer<DropTableBuffer>(npcEntity).Clear();
npcModel = GameData.Npcs.FromEntity(npcEntity);
ModifyNPC(sender, e);
});
return true;
}
public bool Spawn(Entity sender, float3 pos, float lifetime)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
SpawnSystem.SpawnUnitWithCallback(sender, new PrefabGUID(PrefabGUID), new float2(pos.x, pos.z), lifetime, (Action<Entity>)delegate(Entity e)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
npcEntity = e;
if (ECSExtensions.Has<VBloodUnit>(npcEntity))
{
CoroutineHandler.StartFrameCoroutine((Action)delegate
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
VBloodUnit val = ECSExtensions.Read<VBloodUnit>(npcEntity);
val.CanBeTracked = false;
val.UnlocksTrophyOnFeed = (Trophy)(-1);
val.UnlocksTrophyOnFeedBrutal = (Trophy)(-1);
ECSExtensions.Write<VBloodUnit>(npcEntity, val);
}, 3, 1);
}
ECSExtensions.ReadBuffer<DropTableBuffer>(npcEntity).Clear();
npcModel = GameData.Npcs.FromEntity(npcEntity);
ModifyNPC(sender, e);
});
return true;
}
public void ModifyNPC(Entity user, Entity npc)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
float level = GameData.Users.FromEntity(user).Character.Equipment.Level;
EntityManager entityManager = Core.World.EntityManager;
UnitLevel componentData = ((EntityManager)(ref entityManager)).GetComponentData<UnitLevel>(npc);
int num = (int)(level + (float)levelAbove);
componentData.Level = new ModifiableInt(num);
UnitStats stats = ECSExtensions.Read<UnitStats>(npc);
if (unitStats == null)
{
GenerateStats();
}
ECSExtensions.Write<UnitStats>(npc, unitStats.FillStats(stats));
entityManager = Core.World.EntityManager;
((EntityManager)(ref entityManager)).SetComponentData<UnitLevel>(npc, componentData);
RenameNPC(npc);
}
public void GenerateStats()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
UnitStats stats = ECSExtensions.Read<UnitStats>(Plugin.SystemsCore.PrefabCollectionSystem._PrefabGuidToEntityMap[new PrefabGUID(PrefabGUID)]);
unitStats = new UnitStatsModel();
unitStats.SetStats(stats);
}
private void RenameNPC(Entity boss)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
ECSExtensions.Add<NameableInteractable>(boss);
NameableInteractable val = ECSExtensions.Read<NameableInteractable>(boss);
val.Name = new FixedString64Bytes(nameHash + "be");
ECSExtensions.Write<NameableInteractable>(boss, val);
}
public bool GetNPCEntity()
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
NativeArray<Entity> entitiesByComponentTypes = QueryComponents.GetEntitiesByComponentTypes<NameableInteractable, LifeTime>((EntityQueryOptions)2, false);
Enumerator<Entity> enumerator = entitiesByComponentTypes.GetEnumerator();
while (enumerator.MoveNext())
{
Entity current = enumerator.Current;
NameableInteractable val = ECSExtensions.Read<NameableInteractable>(current);
if (((FixedString64Bytes)(ref val.Name)).Value == nameHash + "be")
{
npcEntity = current;
entitiesByComponentTypes.Dispose();
return true;
}
}
entitiesByComponentTypes.Dispose();
return false;
}
internal void KillNpc(Entity user)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
if (GetNPCEntity())
{
StatChangeUtility.KillOrDestroyEntity(Plugin.SystemsCore.EntityManager, npcEntity, user, user, 0.0, (StatChangeReason)0, true);
}
}
}
internal class UnitStatsModel
{
public float PhysicalCriticalStrikeChance { get; set; }
public float PhysicalCriticalStrikeDamage { get; set; }
public float SpellCriticalStrikeChance { get; set; }
public float SpellCriticalStrikeDamage { get; set; }
public float PhysicalPower { get; set; }
public float SpellPower { get; set; }
public float ResourcePower { get; set; }
public float SiegePower { get; set; }
public float ResourceYieldModifier { get; set; }
public float ReducedResourceDurabilityLoss { get; set; }
public float PhysicalResistance { get; set; }
public float SpellResistance { get; set; }
public int SunResistance { get; set; }
public int FireResistance { get; set; }
public int HolyResistance { get; set; }
public int SilverResistance { get; set; }
public int SilverCoinResistance { get; set; }
public int GarlicResistance { get; set; }
public float PassiveHealthRegen { get; set; }
public int CCReduction { get; set; }
public float HealthRecovery { get; set; }
public float DamageReduction { get; set; }
public float HealingReceived { get; set; }
public float ShieldAbsorbModifier { get; set; }
public float BloodEfficiency { get; set; }
public void SetStats(UnitStats stats)
{
PhysicalCriticalStrikeChance = ((ModifiableFloat)(ref stats.PhysicalCriticalStrikeChance)).Value;
PhysicalCriticalStrikeDamage = ((ModifiableFloat)(ref stats.PhysicalCriticalStrikeDamage)).Value;
SpellCriticalStrikeChance = ((ModifiableFloat)(ref stats.SpellCriticalStrikeChance)).Value;
SpellCriticalStrikeDamage = ((ModifiableFloat)(ref stats.SpellCriticalStrikeDamage)).Value;
PhysicalPower = ((ModifiableFloat)(ref stats.PhysicalPower)).Value;
SpellPower = ((ModifiableFloat)(ref stats.SpellPower)).Value;
ResourcePower = ((ModifiableFloat)(ref stats.ResourcePower)).Value;
SiegePower = ((ModifiableFloat)(ref stats.SiegePower)).Value;
ResourceYieldModifier = ((ModifiableFloat)(ref stats.ResourceYieldModifier)).Value;
ReducedResourceDurabilityLoss = ((ModifiableFloat)(ref stats.ReducedResourceDurabilityLoss)).Value;
PhysicalResistance = ((ModifiableFloat)(ref stats.PhysicalResistance)).Value;
SpellResistance = ((ModifiableFloat)(ref stats.SpellResistance)).Value;
SunResistance = ((ModifiableInt)(ref stats.SunResistance)).Value;
FireResistance = ((ModifiableInt)(ref stats.FireResistance)).Value;
HolyResistance = ((ModifiableInt)(ref stats.HolyResistance)).Value;
SilverResistance = ((ModifiableInt)(ref stats.SilverResistance)).Value;
SilverCoinResistance = ((ModifiableInt)(ref stats.SilverCoinResistance)).Value;
GarlicResistance = ((ModifiableInt)(ref stats.GarlicResistance)).Value;
PassiveHealthRegen = ((ModifiableFloat)(ref stats.PassiveHealthRegen)).Value;
CCReduction = ((ModifiableInt)(ref stats.CCReduction)).Value;
HealthRecovery = ((ModifiableFloat)(ref stats.HealthRecovery)).Value;
DamageReduction = ((ModifiableFloat)(ref stats.DamageReduction)).Value;
HealingReceived = ((ModifiableFloat)(ref stats.HealingReceived)).Value;
ShieldAbsorbModifier = ((ModifiableFloat)(ref stats.ShieldAbsorbModifier)).Value;
BloodEfficiency = ((ModifiableFloat)(ref stats.BloodEfficiency)).Value;
}
public UnitStats FillStats(UnitStats stats)
{
//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
stats.PhysicalCriticalStrikeChance._Value = PhysicalCriticalStrikeChance;
stats.PhysicalCriticalStrikeDamage._Value = PhysicalCriticalStrikeDamage;
stats.SpellCriticalStrikeChance._Value = SpellCriticalStrikeChance;
stats.SpellCriticalStrikeDamage._Value = SpellCriticalStrikeDamage;
stats.PhysicalPower._Value = PhysicalPower;
stats.SpellPower._Value = SpellPower;
stats.ResourcePower._Value = ResourcePower;
stats.SiegePower._Value = SiegePower;
stats.ResourceYieldModifier._Value = ResourceYieldModifier;
stats.ReducedResourceDurabilityLoss._Value = ReducedResourceDurabilityLoss;
stats.PhysicalResistance._Value = PhysicalResistance;
stats.SpellResistance._Value = SpellResistance;
stats.SunResistance._Value = SunResistance;
stats.FireResistance._Value = FireResistance;
stats.HolyResistance._Value = HolyResistance;
stats.SilverResistance._Value = SilverResistance;
stats.SilverCoinResistance._Value = SilverCoinResistance;
stats.GarlicResistance._Value = GarlicResistance;
stats.PassiveHealthRegen._Value = PassiveHealthRegen;
stats.CCReduction._Value = CCReduction;
stats.HealthRecovery._Value = HealthRecovery;
stats.DamageReduction._Value = DamageReduction;
stats.HealingReceived._Value = HealingReceived;
stats.ShieldAbsorbModifier._Value = ShieldAbsorbModifier;
stats.BloodEfficiency._Value = BloodEfficiency;
return stats;
}
}
}
namespace BloodyEncounters.Commands
{
[CommandGroup("be", null)]
internal class EncountersCommand
{
[Command("reload", null, "", "Reload Database Boss", null, true)]
public static void ReloadDatabase(ChatCommandContext ctx)
{
try
{
Database.loadDatabase();
ctx.Reply("Boss database reload successfully");
}
catch (Exception ex)
{
throw ctx.Error("Error: " + ex.Message);
}
}
[Command("start", null, "", "Starts an encounter for a random online user.", null, true)]
public static void StartCommand(ChatCommandContext ctx)
{
EncounterSystem.StartEncounter();
ctx.Reply("The hunt has begun...");
}
[Command("me", null, "", "Starts an encounter for the admin who sends the command.", null, true)]
public static void MeCommand(ChatCommandContext ctx)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
EncounterSystem.StartEncounter(GameData.Users.FromEntity(ctx.Event.SenderUserEntity));
ctx.Reply("Prepare for the fight...");
}
[Command("player", null, "<PlayerName>", "Starts an encounter for the given player, for example.", null, true)]
public static void PlayerCommand(ChatCommandContext ctx, string PlayerName)
{
UserModel obj = GameData.Users.GetUserByCharacterName(PlayerName) ?? throw ctx.Error("Player not found");
if (!obj.IsConnected)
{
throw ctx.Error("Could not find an online player with name " + PlayerName);
}
EncounterSystem.StartEncounter(obj);
ctx.Reply("Sending an ambush to " + PlayerName + ".");
}
[Command("enable", null, "", "Enables the random encounter timer.", null, true)]
public static void EnableCommand(ChatCommandContext ctx)
{
if (Config.Enabled.Value)
{
throw ctx.Error("Already enabled.");
}
Config.Enabled.Value = true;
ctx.Reply("Enabled");
}
[Command("disable", null, "", "Disables the random encounter timer.", null, true)]
public static void DisableCommand(ChatCommandContext ctx)
{
if (!Config.Enabled.Value)
{
throw ctx.Error("Already disabled.");
}
Config.Enabled.Value = false;
ctx.Reply("Disabled.");
}
}
[CommandGroup("be items", null)]
internal class ItemsCommand
{
[Command("list", null, "", "List items of NPC drop", null, true)]
public void ListNPCItems(ChatCommandContext ctx, string NPCName)
{
try
{
if (Database.GetNPC(NPCName, out var npc))
{
ctx.Reply(npc.name + " Items List");
ctx.Reply("----------------------------");
ctx.Reply("--");
foreach (ItemEncounterModel item in npc.GetItems())
{
ctx.Reply($"Item {item.ItemID}");
ctx.Reply($"Stack {item.Stack}");
ctx.Reply("--");
}
ctx.Reply("----------------------------");
return;
}
throw new NPCDontExistException();
}
catch (NPCDontExistException)
{
throw ctx.Error("NPC with name '" + NPCName + "' does not exist.");
}
catch (ProductExistException)
{
throw ctx.Error("This item configuration already exists at merchant '" + NPCName + "'");
}
catch (Exception ex3)
{
throw ctx.Error("Error: " + ex3.Message);
}
}
[Command("add", null, "<NameOfNPC> <ItemName> <ItemPrefabID> <Stack>", "Add a item to a NPC drop", null, true)]
public void CreateItem(ChatCommandContext ctx, string NPCName, string ItemName, int ItemPrefabID, int Stack)
{
try
{
if (Database.GetNPC(NPCName, out var npc))
{
npc.AddItem(ItemName, ItemPrefabID, Stack);
ctx.Reply("Item successfully added to NPC '" + NPCName + "'");
return;
}
throw new NPCDontExistException();
}
catch (NPCDontExistException)
{
throw ctx.Error("NPC with name '" + NPCName + "' does not exist.");
}
catch (ProductExistException)
{
throw ctx.Error("This item configuration already exists at merchant '" + NPCName + "'");
}
catch (Exception ex3)
{
throw ctx.Error("Error: " + ex3.Message);
}
}
[Command("remove", null, "<NameOfNPC> <ItemName>", "Remove a item to a NPC", null, true)]
public void RemoveProduct(ChatCommandContext ctx, string NPCName, string ItemName)
{
try
{
if (Database.GetNPC(NPCName, out var npc))
{
npc.RemoveItem(ItemName);
ctx.Reply("NPC '" + NPCName + "''s item has been successfully removed");
return;
}
throw new NPCDontExistException();
}
catch (NPCDontExistException)
{
throw ctx.Error("NPC with name '" + NPCName + "' does not exist.");
}
catch (ProductDontExistException)
{
throw ctx.Error("This item does not exist at NPC '" + NPCName + "'");
}
catch (Exception ex3)
{
throw ctx.Error("Error: " + ex3.Message);
}
}
}
[CommandGroup("be npc", null)]
internal class NpcCommand
{
[Command("list", null, "", "List of npc", null, true)]
public void ListMerchant(ChatCommandContext ctx)
{
List<NpcEncounterModel> nPCS = Database.NPCS;
if (nPCS.Count == 0)
{
throw ctx.Error("There are no npcs created");
}
ctx.Reply("NPCS List");
ctx.Reply("----------------------------");
ctx.Reply("--");
foreach (NpcEncounterModel item in nPCS)
{
ctx.Reply("NPC " + item.name);
ctx.Reply("Group " + item.Group);
ctx.Reply("--");
}
ctx.Reply("----------------------------");
}
[Command("create", null, "<NameOfNPC> <PrefabGUIDOfNPC> <LevelsAbovePlayer> <LifeTime> <Group>", "Create a NPC", null, true)]
public void CreateNPC(ChatCommandContext ctx, string npcName, int prefabGUID, int levelAbove, int lifeTime, string group = "")
{
try
{
if (Database.AddNPC(npcName, prefabGUID, levelAbove, lifeTime, group))
{
ctx.Reply("NPC '" + npcName + "' created successfully");
}
}
catch (NPCExistException)
{
throw ctx.Error("NPC with name '" + npcName + "' exist.");
}
catch (Exception ex2)
{
throw ctx.Error("Error: " + ex2.Message);
}
}
[Command("remove", null, "<NameOfNPC>", "Remove a NPC", null, true)]
public void RemoveMerchant(ChatCommandContext ctx, string npcName)
{
try
{
if (Database.RemoveNPC(npcName))
{
ctx.Reply("NPC '" + npcName + "' remove successfully");
}
}
catch (NPCDontExistException)
{
throw ctx.Error("NPC with name '" + npcName + "' does not exist.");
}
catch (Exception ex2)
{
throw ctx.Error("Error: " + ex2.Message);
}
}
}
}