diff --git a/Commands/AddMaterials.cs b/Commands/AddMaterials.cs new file mode 100644 index 0000000..36a6dac --- /dev/null +++ b/Commands/AddMaterials.cs @@ -0,0 +1,34 @@ +using CommunityCommands.Utils; +using Unity.Entities; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + public class AddMaterials + { + [Command("ct5", description: "Add some materials to a player's inventory to directly builde a level 5 castle.", adminOnly: false)] + public static void AddMaterialsCommand(ChatCommandContext ctx, string playerName = "") + { + if (string.IsNullOrEmpty(playerName)) + { + playerName = ctx.Event.User.CharacterName.ToString(); + } + + var playerEntity = CharacterUtil.GetPlayerEntityByName(playerName); + + if (playerEntity != Entity.Null) + { + foreach (var keyValuePair in DatabaseUtils.GetMaterialDictionary) + { + Helper.AddItemToInventory(playerEntity, keyValuePair.Value.Item1, keyValuePair.Value.Item2); + } + + ctx.Reply($"Materials added to {playerName}'s inventory."); + } + else + { + ctx.Reply($"Player '{playerName}' not found."); + } + } + } +} \ No newline at end of file diff --git a/Commands/Blood.cs b/Commands/Blood.cs new file mode 100644 index 0000000..8c0486e --- /dev/null +++ b/Commands/Blood.cs @@ -0,0 +1,33 @@ +using ProjectM; +using Unity.Entities; +using UnityEngine; +using VampireCommandFramework; +using CommunityCommands.Utils; + +namespace CommunityCommands.Commands; + +internal static class Blood +{ + [Command("bloodpotion", "bp", description: "Creates a Potion with specified Blood Type, Quality and Value", + adminOnly: false)] + public static void GiveBloodPotionCommand(ChatCommandContext ctx, string bloodName = "Frailed", + float quality = 100f) + { + quality = Mathf.Clamp(quality, 0, 100); + var em = Helper.Server.EntityManager; + + Entity entity = + Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, BloodUtils.GetBloodPotionRecipe(), 1); + + var blood = new StoredBlood() + { + BloodQuality = quality, + BloodType = BloodUtils.GetBloodPrefabGuid(bloodName) + }; + + em.SetComponentData(entity, blood); + + ctx.Reply( + $"Got Blood Potion Type {BloodUtils.GetBloodName(bloodName)} with {(int)quality}% quality"); + } +} \ No newline at end of file diff --git a/Commands/BloodCommands.cs b/Commands/BloodCommands.cs index a92b849..5d8dc9d 100644 --- a/Commands/BloodCommands.cs +++ b/Commands/BloodCommands.cs @@ -21,10 +21,11 @@ public enum BloodType [Command("bloodpotion", "bp", description: "Creates a Potion with specified Blood Type, Quality and Value", adminOnly: true)] public static void GiveBloodPotionCommand(ChatCommandContext ctx, BloodType type = BloodType.Frailed, float quality = 100f) { + var bloodPotionRecipeId = 1223264867; quality = Mathf.Clamp(quality, 0, 100); var em = Helper.Server.EntityManager; - Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, new PrefabGUID(828432508), 1); + Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, new PrefabGUID(bloodPotionRecipeId), 1); var blood = new StoredBlood() { diff --git a/Commands/ChangeSpeed.cs b/Commands/ChangeSpeed.cs new file mode 100644 index 0000000..3c81e3c --- /dev/null +++ b/Commands/ChangeSpeed.cs @@ -0,0 +1,13 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class ChangeSpeed +{ + [Command("changespeed", "cs", description: "Change the speed of your character.", adminOnly: false)] + public static void ChangeSpeedCommand(ChatCommandContext ctx, float speed = 4.4f) + { + CharacterUtil.ChangeSpeed(ctx, speed); + } +} \ No newline at end of file diff --git a/Commands/ClearInventory.cs b/Commands/ClearInventory.cs new file mode 100644 index 0000000..58f981f --- /dev/null +++ b/Commands/ClearInventory.cs @@ -0,0 +1,13 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class ClearInventory +{ + [Command("clearinventory", "ci", description: "Clears your inventory", adminOnly: false)] + public static void ClearInventoryCommand(ChatCommandContext ctx) + { + CharacterUtil.ClearInventory(ctx); + } +} \ No newline at end of file diff --git a/Commands/DoorsWindow.cs b/Commands/DoorsWindow.cs new file mode 100644 index 0000000..15d0149 --- /dev/null +++ b/Commands/DoorsWindow.cs @@ -0,0 +1,108 @@ +using System.Collections.Generic; +using CommunityCommands.Utils; +using ProjectM; +using ProjectM.CastleBuilding; +using ProjectM.Scripting; +using Unity.Collections; +using Unity.Entities; +using Unity.Transforms; +using UnityEngine; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + public class DoorsWindow + { + [Command("close-all", "ca", description: "Close all doors.", adminOnly: false)] + public static void CloseAll(ChatCommandContext ctx, DoorWindow? target = null) => ChangeDoorWindows(ctx, false, target); + + [Command("open-all", "oa", description: "Open all doors.", adminOnly: false)] + public static void OpenAll(ChatCommandContext ctx, DoorWindow? target = null) => ChangeDoorWindows(ctx, true, target); + + public enum DoorWindow { Doors, Windows } + private static readonly HashSet WINDOW_PREFABS = new HashSet { -1771014048 }; + private const float MaxCastleDistance = 60f; + + public struct DoorState + { + public Entity Entity; + public bool OpenState; + } + + public static void ChangeDoorWindows(ChatCommandContext ctx, bool open, DoorWindow? target) + { + var character = ctx.Event.SenderCharacterEntity; + var castleHearts = Helper.Server.EntityManager.CreateEntityQuery(ComponentType.ReadOnly(), ComponentType.ReadOnly()) + .ToEntityArray(Allocator.Temp); + var gameManager = Helper.Server.GetExistingSystem()?._ServerGameManager; + var playerPos = Helper.Server.EntityManager.GetComponentData(character).Position; + + var closestCastle = Entity.Null; + float closest = float.MaxValue; + + foreach (var castle in castleHearts) + { + var isPlayerOwned = gameManager.Value.IsAllies(character, castle); + if (!isPlayerOwned) continue; + + var castlePos = Helper.Server.EntityManager.GetComponentData(castle).Position; + var distance = Vector3.Distance(castlePos, playerPos); + if (distance < closest && distance < MaxCastleDistance) + { + closest = distance; + closestCastle = castle; + } + } + + if (closestCastle == Entity.Null) + { + ctx.Reply("Could not find nearby castle you own"); + return; + } + + var doors = Helper.Server.EntityManager.CreateEntityQuery(new EntityQueryDesc() + { + All = new[] { ComponentType.ReadWrite(), ComponentType.ReadOnly(), ComponentType.ReadOnly(), ComponentType.ReadOnly() }, + Options = EntityQueryOptions.IncludeDisabled + }).ToEntityArray(Allocator.Temp); + + var doorStates = new List(); + + int count = 0; + for (int i = 0; i < doors.Length; i++) + { + var connection = Helper.Server.EntityManager.GetComponentData(doors[i]); + if (connection.CastleHeartEntity._Entity != closestCastle) continue; + + if (target != null) + { + var prefab = Helper.Server.EntityManager.GetComponentData(doors[i]); + + if (target == DoorWindow.Doors && WINDOW_PREFABS.Contains(prefab.GuidHash)) continue; + if (target == DoorWindow.Windows && !WINDOW_PREFABS.Contains(prefab.GuidHash)) continue; + } + + var doorState = new DoorState + { + Entity = doors[i], + OpenState = open, + + }; + doorStates.Add(doorState); + count++; + } + + var doorComponents = Helper.Server.EntityManager.GetComponentDataFromEntity(true); + + foreach (var doorState in doorStates) + { + var door = doorComponents[doorState.Entity]; + door.OpenState = doorState.OpenState; + doorComponents[doorState.Entity] = door; + } + doorStates.Clear(); + + ctx.Reply($"Changed {count} {(target?.ToString() ?? "Windows and Doors")}"); + } + } +} diff --git a/Commands/GetPosition.cs b/Commands/GetPosition.cs new file mode 100644 index 0000000..d16d216 --- /dev/null +++ b/Commands/GetPosition.cs @@ -0,0 +1,25 @@ +using ProjectM; +using Unity.Entities; +using Unity.Mathematics; +using UnityEngine; +using VampireCommandFramework; +using System; +using Il2CppSystem.Collections.Generic; +using Unity.Transforms; + +namespace CommunityCommands.Commands +{ + internal static class GetPosition + { + [Command("getposition", "gp", description: "Get the current position of the player", adminOnly: false)] + public static void GetPositionCommand(ChatCommandContext ctx) + { + var em = Helper.Server.EntityManager; + var playerEntity = ctx.Event.SenderCharacterEntity; + var translation = em.GetComponentData(playerEntity); + var currentPosition = translation.Value; + + ctx.Reply($"Current position: {currentPosition}"); + } + } +} \ No newline at end of file diff --git a/Commands/GiveItem.cs b/Commands/GiveItem.cs new file mode 100644 index 0000000..336bde0 --- /dev/null +++ b/Commands/GiveItem.cs @@ -0,0 +1,25 @@ +using CommunityCommands.Commons; +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class GiveItem +{ + [Command("give", "g", description: "Give a specific item or set of items to yourself", adminOnly: false)] + public static void GiveItemCommand(ChatCommandContext ctx, GiveType type, string name) + { + switch (type) + { + case GiveType.Item: + DatabaseUtils.GiveSingleItem(ctx, name); + return; + case GiveType.Set: + DatabaseUtils.GiveEquipmentSet(ctx, name); + break; + default: + throw ctx.Error( + "Invalid give type. Please specify either 'item' or 'set'."); + } + } +} \ No newline at end of file diff --git a/Commands/Horse.cs b/Commands/Horse.cs new file mode 100644 index 0000000..d8f2dfc --- /dev/null +++ b/Commands/Horse.cs @@ -0,0 +1,85 @@ +using ProjectM; +using Unity.Entities; +using Unity.Mathematics; +using UnityEngine; +using VampireCommandFramework; +using System; +using CommunityCommands.Utils; +using Il2CppSystem.Collections.Generic; +using Unity.DebugDisplay; +using Unity.Transforms; + +namespace CommunityCommands.Commands +{ + internal static class Horse + { + [Command("horse", "h", description: "Manage horses (spawn or set max attributes)", adminOnly: false)] + public static void HorseCommand(ChatCommandContext ctx, string subCommand, int quantity = 1, float speed = 11f, + float acceleration = 7.0f, float rotation = 14.0f) + { + var em = Helper.Server.EntityManager; + var playerEntity = ctx.Event.SenderCharacterEntity; + if (!em.Exists(playerEntity)) + { + ctx.Reply("Player entity not found."); + return; + } + + subCommand = subCommand.ToLower(); + + if (subCommand == "spawn") + { + SpawnHorse(ctx, playerEntity, quantity, speed, acceleration, rotation); + } + else if (subCommand == "max") + { + SetMaxAttributes(ctx, playerEntity, speed, acceleration, rotation); + } + else + { + ctx.Reply("Invalid subcommand. Available subcommands: spawn, max."); + } + } + + private static void SpawnHorse(ChatCommandContext ctx, Entity playerEntity, int quantity, float speed, + float acceleration, float rotation) + { + try + { + var em = Helper.Server.EntityManager; + var playerPosition = em.GetComponentData(playerEntity).Value; + + for (int i = 0; i < quantity; i++) + { + HorseUtil.SpawnHorse(1, playerPosition); + } + + ctx.Reply($"Spawned {quantity} horse(s) next to the player."); + } + catch (Exception e) + { + throw ctx.Error($"An error occurred: {e.Message}"); + } + } + + private static void SetMaxAttributes(ChatCommandContext ctx, Entity playerEntity, float speed, + float acceleration, float rotation) + { + + var closestHorse = HorseUtil.GetClosetHorse(playerEntity); + + if (closestHorse != null) + { + HorseUtil.ModifyHorseAttributes(ctx, closestHorse.Value, speed, acceleration, rotation); + + ctx.Reply( + $"Changed attributes for the closest horse: Speed: {speed}, Acceleration: {acceleration}, Rotation: {rotation}"); + } + else + { + ctx.Reply("No horse found nearby."); + } + + } + } +} \ No newline at end of file diff --git a/Commands/Jewels.cs b/Commands/Jewels.cs new file mode 100644 index 0000000..d734194 --- /dev/null +++ b/Commands/Jewels.cs @@ -0,0 +1,27 @@ +using CommunityCommands.Commons; +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + public class Jewels + { + [Command("jewel", "jw", description: "Add a jewel in your inventory.", adminOnly: false)] + public static void FindJewelPrefabCommand(ChatCommandContext ctx, GiveType type, string name, + string jewelTier = "t02") + { + if (type == GiveType.Item) + { + DatabaseUtils.GiveSingleJewel(ctx, name, jewelTier); + } + else if (type == GiveType.Set) + { + DatabaseUtils.GiveJewelSet(ctx, name); + } + else + { + ctx.Reply($"No jewel or jewel set matching the name '{name}' and tier '{jewelTier}' was found."); + } + } + } +} \ No newline at end of file diff --git a/Commands/ModifyVBloodCharacteristics.cs b/Commands/ModifyVBloodCharacteristics.cs new file mode 100644 index 0000000..4eb4df8 --- /dev/null +++ b/Commands/ModifyVBloodCharacteristics.cs @@ -0,0 +1,41 @@ +using System.IO; +using CommunityCommands.Utils; +using ProjectM; +using Unity.Entities; +using Unity.Mathematics; +using Unity.Transforms; +using UnityEngine; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + internal static class ModifyVBloodCharacteristics + { + [Command("modifyvblood", "mvb", description: "Modify the characteristics of the nearest VBlood.", adminOnly: false)] + public static void ModifyVBloodCommand(ChatCommandContext ctx, int level) + { + var entityManager = Helper.Server.EntityManager; + var playerEntity = ctx.Event.SenderCharacterEntity; + + // Get the closest VBlood entity with the specified PrefabGUID + var closestVBlood = VBloodUtils.GetClosestVBlood(playerEntity); + + if (closestVBlood != null) + { + // Modify the UnitLevel component of the closest VBlood entity + var unitLevel = entityManager.GetComponentData(closestVBlood.Value); + unitLevel.Level = level; + entityManager.SetComponentData(closestVBlood.Value, unitLevel); + var unitStats = entityManager.GetComponentData(closestVBlood.Value); + unitStats.PhysicalPower.Value = 150; + + ctx.Reply($"Modified the characteristics of the nearest VBlood to level: {level}"); + } + else + { + ctx.Reply("No VBlood found nearby."); + } + } + + } +} diff --git a/Commands/RestoreSkillsAndHealt.cs b/Commands/RestoreSkillsAndHealt.cs new file mode 100644 index 0000000..1f45f6d --- /dev/null +++ b/Commands/RestoreSkillsAndHealt.cs @@ -0,0 +1,15 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class RestoreSkillsAndHealt +{ + [Command("reset", "rs", description: "Restore healt ( 100% ) and reset skills cooldown.", adminOnly: false)] + public static void RestoreSkillsAndHealtCommand(ChatCommandContext ctx) + { + CharacterUtil.RecoverHealt(ctx); + CharacterUtil.ResetSkillsCooldown(ctx.Event.SenderCharacterEntity); + ctx.Reply("Health and skills cooldown restored."); + } +} \ No newline at end of file diff --git a/Commands/SpawnBoss.cs b/Commands/SpawnBoss.cs new file mode 100644 index 0000000..86f43ae --- /dev/null +++ b/Commands/SpawnBoss.cs @@ -0,0 +1,28 @@ +using ProjectM; +using Unity.Entities; +using VampireCommandFramework; +using System; +using CommunityCommands.Commons; +using Unity.Mathematics; +using Unity.Transforms; +using CommunityCommands.Utils; + + +namespace CommunityCommands.Commands +{ + internal static class SpawnBoss + { + [Command("spawn", "s", description: "Spawn a vblood or npc next to the player", adminOnly: false)] + public static void SpawnBossCommand(ChatCommandContext ctx, SpawnType type, string vBloodName = "wolf", int quantity = 1) + { + if (type == SpawnType.All) + { + VBloodUtils.SpawnAllBoss(ctx, ctx.Event.SenderCharacterEntity, quantity); + } + else if (type == SpawnType.Vblood) + { + VBloodUtils.SpawnSingleBoss(ctx, ctx.Event.SenderCharacterEntity, vBloodName, quantity); + } + } + } +} \ No newline at end of file diff --git a/Commands/Teleport.cs b/Commands/Teleport.cs new file mode 100644 index 0000000..f2f34fe --- /dev/null +++ b/Commands/Teleport.cs @@ -0,0 +1,32 @@ +using Unity.Mathematics; +using VampireCommandFramework; +using CommunityCommands.Utils; +using System; + +namespace CommunityCommands.Commands +{ + internal static class Teleport + { + [Command("teleport", "tp", description: "Teleport to a specific boss", adminOnly: false)] + public static void TeleportToTarget(ChatCommandContext ctx, string targetName) + { + float3 targetPosition; + try + { + targetPosition = DatabaseUtils.GetBossPosition(targetName); + } + catch (Exception e) + { + throw ctx.Error($"Error: {e.Message}"); + } + + if (targetPosition.Equals(float3.zero)) + { + ctx.Reply($"{DatabaseUtils.GetBossPositionText(targetName)}"); + return; + } + + CharacterUtil.TeleportToPos(ctx, targetName, targetPosition); + } + } +} \ No newline at end of file diff --git a/Commands/UnlockAllAbilities.cs b/Commands/UnlockAllAbilities.cs new file mode 100644 index 0000000..c112006 --- /dev/null +++ b/Commands/UnlockAllAbilities.cs @@ -0,0 +1,13 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class UnlockAllAbilities +{ + [Command("unlockallabilities", "uaa", description: "Unlock all abilities for the player.", adminOnly: false)] + public static void UnlockAllAbilitiesCommand(ChatCommandContext ctx) + { + CharacterUtil.UnlockAllAbilities(ctx); + } +} \ No newline at end of file diff --git a/Commands/UnlockAllResearch.cs b/Commands/UnlockAllResearch.cs new file mode 100644 index 0000000..b1d42e6 --- /dev/null +++ b/Commands/UnlockAllResearch.cs @@ -0,0 +1,13 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands; + +public class UnlockAllResearch +{ + [Command("unlockallresearch", "uar", description: "Unlock all research for the player.", adminOnly: false)] + public static void UnlockAllResearchCommand(ChatCommandContext ctx) + { + CharacterUtil.UnlockAllResearch(ctx); + } +} \ No newline at end of file diff --git a/Commons/Blood.cs b/Commons/Blood.cs new file mode 100644 index 0000000..a34f943 --- /dev/null +++ b/Commons/Blood.cs @@ -0,0 +1,9 @@ +using ProjectM; + +namespace CommunityCommands.Commons; + +public class Blood +{ + public string name { get; set; } + public PrefabGUID prefab { get; set; } +} \ No newline at end of file diff --git a/Commons/Database.cs b/Commons/Database.cs new file mode 100644 index 0000000..5936245 --- /dev/null +++ b/Commons/Database.cs @@ -0,0 +1,854 @@ +using ProjectM; +using System.Collections.Generic; +using Unity.Mathematics; + +namespace CommunityCommands.Commons +{ + public class Database + { + public static List BloodTypes { get; } = new List + { + new Blood { name = "Frailed", prefab = new PrefabGUID(-899826404) }, + new Blood { name = "Creature", prefab = new PrefabGUID(-77658840) }, + new Blood { name = "Warrior", prefab = new PrefabGUID(-1094467405) }, + new Blood { name = "Rogue", prefab = new PrefabGUID(793735874) }, + new Blood { name = "Brute", prefab = new PrefabGUID(581377887) }, + new Blood { name = "Scholar", prefab = new PrefabGUID(-586506765) }, + new Blood { name = "Mutant", prefab = new PrefabGUID(-2017994753) }, + new Blood { name = "Worker", prefab = new PrefabGUID(-540707191) } + }; + + + public static Dictionary BossDatabase { get; } = new Dictionary() + { + { + "wolf", new VBlood + { + DisplayName = "Alpha Wolf", + Prefab = new PrefabGUID(-1905691330), + Position = new Position + { + position = float3.zero, + text = + "I cannot teleport you to the Alpha Wolf as VBlood moves around Farbane Woods, so you will have to track him yourself." + } + } + }, + { + "errol", new VBlood + { + DisplayName = "Errol the Stonebreaker", + Prefab = new PrefabGUID(-2025101517), + Position = new Position { position = new float3(-1554f, 10f, 1478f), text = "None" } + } + }, + { + "keely", new VBlood + { + DisplayName = "Keely the Frost Archer", + Prefab = new PrefabGUID(1124739990), + Position = new Position { position = new float3(-1029f, 0f, -1358f), text = "None" } + } + }, + { + "rufus", new VBlood + { + DisplayName = "Rufus the Foreman", + Prefab = new PrefabGUID(2122229952), + Position = new Position { position = new float3(-1218f, 0f, -1549f), text = "None" } + } + }, + { + "goreswine", new VBlood + { + DisplayName = "Goreswine the Ravager", + Prefab = new PrefabGUID(577478542), + Position = new Position + { + position = float3.zero, + text = + "I cannot teleport you to Goreswine the Ravager as VBlood moves from The Desecrated Graveyard to The Infested Graveyard." + } + } + }, + { + "grayson", new VBlood + { + DisplayName = "Grayson the Armourer", + Prefab = new PrefabGUID(1106149033), + Position = new Position { position = new float3(-1692f, 5f, 1400f), text = "None" } + } + }, + { + "rat", new VBlood + { + DisplayName = "Putrid Rat", + Prefab = new PrefabGUID(-2039908510), + Position = new Position { position = float3.zero, text = "Summon" } + } + }, + { + "lidia", new VBlood + { + DisplayName = "Lidia the Chaos Archer", + Prefab = new PrefabGUID(763273073), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you to Lidia the Chaos Archer as VBlood moves around Farbane Woods." + } + } + }, + { + "clive", new VBlood + { + DisplayName = "Clive the Firestarter", + Prefab = new PrefabGUID(1896428751), + Position = new Position { position = new float3(-2133f, 5f, -1528f), text = "None" } + } + }, + { + "bear", new VBlood + { + DisplayName = "Ferocious Bear", + Prefab = new PrefabGUID(-1391546313), + Position = new Position { position = new float3(-702f, 0f, -1521f), text = "None" } + } + }, + { + "polora", new VBlood + { + DisplayName = "Polora the Feywalker", + Prefab = new PrefabGUID(-484556888), + Position = new Position { position = new float3(-2018f, 0f, -1218f), text = "None" } + } + }, + { + "nicholaus", new VBlood + { + DisplayName = "Nicholaus the Fallen", + Prefab = new PrefabGUID(153390636), + Position = new Position { position = new float3(-1357f, 15f, 1332f), text = "None" } + } + }, + { + "quincey", new VBlood + { + DisplayName = "Quincey the Bandit King", + Prefab = new PrefabGUID(-1659822956), + Position = new Position { position = new float3(-1392f, 20f, -1211f), text = "None" } + } + }, + { + "beatrice", new VBlood + { + DisplayName = "Beatrice the Tailor", + Prefab = new PrefabGUID(-1942352521), + Position = new Position + { + position = new float3(-1045f, 0f, -880f), + text = + " Beatrice the Tailor remains within Dawnbreak Village and does not roam beyond its boundaries" + } + } + }, + { + "tristan", new VBlood + { + DisplayName = "Tristan the Vampire Hunter", + Prefab = new PrefabGUID(-1449631170), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you directly to Tristan the Vampire Hunter. He is known to patrol both Farbane Woods and Dunley Farmlands." + } + } + }, + { + "kriig", new VBlood + { + DisplayName = "Kriig the Undead General", + Prefab = new PrefabGUID(-1365931036), + Position = new Position + { + position = new float3(-1368f, 0f, -1048f), + text = + " Kriig the Undead General can be found roaming inside The Haunted Iron Mine." + } + } + }, + { + "christina", new VBlood + { + DisplayName = "Christina the Sun Priestess", + Prefab = new PrefabGUID(-99012450), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you directly to Christina the Sun Priestess. She is known to roam between Mossick Village and Dawnbreak Village." + } + } + }, + { + "vincent", new VBlood + { + DisplayName = "Vincent the Frostbringer", + Prefab = new PrefabGUID(-29797003), + Position = new Position + { + position = new float3(-1339f, 0f, -824f), + text = + " Vincent the Frostbringer can often be found patrolling the streets of Dunley Farmlands." + } + } + }, + { + "bane", new VBlood + { + DisplayName = "Bane the Shadowblade", + Prefab = new PrefabGUID(613251918), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you directly to Bane the Shadowblade. This VBlood has a tendency to wander throughout Dunley Farmlands." + } + } + }, + { + "grethel", new VBlood + { + DisplayName = "Grethel the Glassblower", + Prefab = new PrefabGUID(910988233), + Position = new Position { position = new float3(-1727f, 1f, -370f), text = "None" } + } + }, + { + "leandra", new VBlood + { + DisplayName = "Leandra the Shadow Priestess", + Prefab = new PrefabGUID(939467639), + Position = new Position { position = new float3(-1182f, 15f, -376f), text = "None" } + } + }, + { + "maja", new VBlood + { + DisplayName = "Maja the Dark Savant", + Prefab = new PrefabGUID(1945956671), + Position = new Position { position = new float3(-867f, 15f, 510f), text = "None" } + } + }, + { + "terah", new VBlood + { + DisplayName = "Terah the Geomancer", + Prefab = new PrefabGUID(-1065970933), + Position = new Position { position = new float3(-1660f, 8f, -543f), text = "None" } + } + }, + { + "meredith", new VBlood + { + DisplayName = "Meredith the Bright Archer", + Prefab = new PrefabGUID(850622034), + Position = new Position + { + position = new float3(-1395f, 0f, -904f), + text = + " Meredith the Bright Archer can be found roaming inside The Haunted Iron Mine." + } + } + }, + { + "jade", new VBlood + { + DisplayName = "Jade the Vampire Hunter", + Prefab = new PrefabGUID(-1968372384), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you directly to Jade the Vampire Hunter. This VBlood is known to roam around Dunley Farmlands." + } + } + }, + { + "raziel", new VBlood + { + DisplayName = "Raziel the Shepherd", + Prefab = new PrefabGUID(-680831417), + Position = new Position { position = new float3(-166f, 5f, -697f), text = "None" } + } + }, + { + "frostmaw", new VBlood + { + DisplayName = "Frostmaw the Mountain Terror", + Prefab = new PrefabGUID(24378719), + Position = new Position + { + position = float3.zero, + text = + "I'm afraid I can't teleport you directly to Frostmaw the Mountain Terror. This VBlood creature roams the treacherous terrain of The Hallowed Mountains." + } + } + }, + { + "octavian", new VBlood + { + DisplayName = "Octavian the Militia Captain", + Prefab = new PrefabGUID(1688478381), + Position = new Position { position = new float3(-1215f, 5f, -523f), text = "None" } + } + }, + { + "domina", new VBlood + { + DisplayName = "Domina the Blade Dancer", + Prefab = new PrefabGUID(-1101874342), + Position = new Position { position = new float3(-1706f, 0f, -153f), text = "None" } + } + }, + { + "angram", new VBlood + { + DisplayName = "Angram the Purifier", + Prefab = new PrefabGUID(106480588), + Position = new Position + { + position = new float3(-1707f, 0f, -70f), + text = + " Angram the Purifier freely roams inside The Pools of Rebirth." + } + } + }, + { + "ziva", new VBlood + { + DisplayName = "Ziva the Engineer", + Prefab = new PrefabGUID(172235178), + Position = new Position { position = new float3(-1344f, 9f, 108f), text = "None" } + } + }, + { + "ungora", new VBlood + { + DisplayName = "Ungora the Spider Queen", + Prefab = new PrefabGUID(-548489519), + Position = new Position { position = new float3(-1074f, 5f, 52f), text = "None" } + } + }, + { + "wanderer", new VBlood + { + DisplayName = "The Old Wanderer", + Prefab = new PrefabGUID(109969450), + Position = new Position { position = new float3(-1250f, 0f, -105f), text = "None" } + } + }, + { + "foulrot", new VBlood + { + DisplayName = "Foulrot the Soultaker", + Prefab = new PrefabGUID(-1208888966), + Position = new Position { position = new float3(-604f, 0f, -67f), text = "None" } + } + }, + { + "willfred", new VBlood + { + DisplayName = "Willfred the Werewolf Chief", + Prefab = new PrefabGUID(-1007062401), + Position = new Position { position = new float3(-1041f, 10f, -254f), text = "None" } + } + }, + { + "balaton", new VBlood + { + DisplayName = "The Duke of Balaton", + Prefab = new PrefabGUID(-203043163), + Position = new Position { position = new float3(-925f, 0f, 246f), text = "None" } + } + }, + { + "cyril", new VBlood + { + DisplayName = "Cyril the Cursed Smith", + Prefab = new PrefabGUID(326378955), + Position = new Position { position = new float3(-753f, 0f, 96f), text = "None" } + } + }, + { + "magnus", new VBlood + { + DisplayName = "Sir Magnus the Overseer", + Prefab = new PrefabGUID(-26105228), + Position = new Position { position = new float3(-2326f, 10f, -582f), text = "None" } + } + }, + { + "mairwyn", new VBlood + { + DisplayName = "Mairwyn the Elementalist", + Prefab = new PrefabGUID(-2013903325), + Position = new Position { position = new float3(-2007f, 15f, -897f), text = "None" } + } + }, + { + "baron", new VBlood + { + DisplayName = "Baron du Bouchon the Sommelier", + Prefab = new PrefabGUID(192051202), + Position = new Position { position = new float3(-2208f, -4f, -774f), text = "None" } + } + }, + { + "morian", new VBlood + { + DisplayName = "Morian the Stormwing Matriarch", + Prefab = new PrefabGUID(685266977), + Position = new Position { position = new float3(-2174f, 15f, -911f), text = "None" } + } + }, + { + "terrorclaw", new VBlood + { + DisplayName = "Terrorclaw the Ogre", + Prefab = new PrefabGUID(-1347412392), + Position = new Position { position = new float3(-563f, 15f, 1212f), text = "None" } + } + }, + { + "azariel", new VBlood + { + DisplayName = "Azariel the Sunbringer", + Prefab = new PrefabGUID(114912615), + Position = new Position { position = new float3(-2490f, 10f, -710f), text = "None" } + } + }, + { + "henry", new VBlood + { + DisplayName = "Henry Blackbrew the Doctor", + Prefab = new PrefabGUID(814083983), + Position = new Position { position = new float3(-1795f, 18f, 40f), text = "None" } + } + }, + { + "matka", new VBlood + { + DisplayName = "Matka the Curse Weaver", + Prefab = new PrefabGUID(-910296704), + Position = new Position { position = new float3(-685f, 0f, 86f), text = "None" } + } + }, + { + "voltatia", new VBlood + { + DisplayName = "Voltatia the Power Master", + Prefab = new PrefabGUID(2054432370), + Position = new Position { position = new float3(-1502f, 20f, 264f), text = "None" } + } + }, + { + "styx", new VBlood + { + DisplayName = "Nightmarshal Styx the Sunderer", + Prefab = new PrefabGUID(1112948824), + Position = new Position + { + position = float3.zero, + text = + "I'm sorry, but I cannot teleport you directly to Nightmarshal Styx the Sunderer. This VBlood entity roams within the depths of The Cursed Forest." + } + } + }, + { + "solarus", new VBlood + { + DisplayName = "Solarus the Immaculate", + Prefab = new PrefabGUID(-740796338), + Position = new Position { position = new float3(-1980f, 25f, -717f), text = "None" } + } + }, + { + "behemot", new VBlood + { + DisplayName = "Gorecrusher the Behemoth", + Prefab = new PrefabGUID(-1936575244), + Position = new Position { position = new float3(692f, 10f, -87f), text = "None" } + } + }, + { + "horror", new VBlood + { + DisplayName = "The Winged Horror", + Prefab = new PrefabGUID(-393555055), + Position = new Position { position = new float3(-690f, 20f, -1330f), text = "None" } + } + }, + { + "adam", new VBlood + { + DisplayName = "Adam The Firstborn", + Prefab = new PrefabGUID(1233988687), + Position = new Position { position = new float3(-1854f, 20f, -346f), text = "None" } + } + }, + }; + + public static Dictionary> ItemSets { get; } = new Dictionary>() + { + { + "tx", new List + { + //Weapons + new Item { Name = "ShadowMatter_NecromancyDagger", Prefab = -526440176 }, + new Item { Name = "ShadowMatter_Longbow", Prefab = 1283345494 }, + } + }, + { + "leg", new List + { + //Weapons + new Item { Name = "Legendary_GreatSword", Prefab = -1173681254 }, + new Item { Name = "Legendary_Mace", Prefab = 1994084762 }, + new Item { Name = "Legendary_Pistols", Prefab = -944318126 }, + new Item { Name = "Legendary_Reaper", Prefab = -105026635 }, + new Item { Name = "Legendary_Slashers", Prefab = 821410795 }, + new Item { Name = "Legendary_Spear", Prefab = -1931117134 }, + new Item { Name = "Legendary_Sword", Prefab = 195858450 }, + new Item { Name = "Legendary_Crossbow", Prefab = 935392085 }, + new Item { Name = "Legendary_Axes", Prefab = -102830349 }, + } + }, + { + "t9", new List + { + //Weapons + new Item { Name = "ShadowMatter_Axes", Prefab = 2100090213 }, + new Item { Name = "ShadowMatter_Crossbow", Prefab = 1957540013 }, + new Item { Name = "ShadowMatter_Mace", Prefab = 160471982 }, + new Item { Name = "ShadowMatter_Reaper", Prefab = -465491217 }, + new Item { Name = "ShadowMatter_Slashers", Prefab = 506082542 }, + new Item { Name = "ShadowMatter_Spear", Prefab = 1307774440 }, + new Item { Name = "ShadowMatter_Sword", Prefab = -1215982687 }, + new Item { Name = "ShadowMatter_Pistols", Prefab = -1265586439 }, + new Item { Name = "ShadowMatter_GreatSword", Prefab = 1322254792 }, + new Item { Name = "ShadowMatter_Longbow", Prefab = 1283345494 }, + new Item { Name = "ShadowMatter_Necromancy_Dagger", Prefab = -526440176 }, + + //Stuff + new Item { Name = "DarkMatter_Boots", Prefab = 1400688919 }, + new Item { Name = "DarkMatter_Chest", Prefab = 1055898174 }, + new Item { Name = "DarkMatter_Gloves", Prefab = -204401621 }, + new Item { Name = "DarkMatter_Leggings", Prefab = 125611165 }, + } + }, + { + "t8", new List + { + //Weapons + new Item { Name = "Sanguine_Axes", Prefab = -2044057823 }, + new Item { Name = "Sanguine_Crossbow", Prefab = 1389040540 }, + new Item { Name = "Sanguine_Mace", Prefab = -126076280 }, + new Item { Name = "Sanguine_Reaper", Prefab = -2053917766 }, + new Item { Name = "Sanguine_Slashers", Prefab = 1322545846 }, + new Item { Name = "Sanguine_Spear", Prefab = -850142339 }, + new Item { Name = "Sanguine_Sword", Prefab = -774462329 }, + new Item { Name = "Sanguine_GreatSword", Prefab = 147836723 }, + + //Stuff + new Item { Name = "Bloodmoon_Boots", Prefab = -556769032 }, + new Item { Name = "Bloodmoon_Chestguard", Prefab = 488592933 }, + new Item { Name = "Bloodmoon_Leggings", Prefab = 1292986377 }, + new Item { Name = "Bloodmoon_Gloves", Prefab = 1634690081 }, + + //Jewels + new Item { Name = "Amulet_Of_The_Arch-Warlock", Prefab = 1380368392 }, + new Item { Name = "Amulet_Of_The_Crimson_Commander", Prefab = -104934480 }, + new Item { Name = "Amulet_Of_The_Unyielding_Charger", Prefab = -1004351840 }, + new Item { Name = "Amulet_Of_The_Blademaster", Prefab = -296161379 }, + new Item { Name = "Amulet_Of_The_Master_Spellweaver", Prefab = -1306155896 }, + new Item { Name = "Amulet_Of_The_Wicked_Prophet", Prefab = -175650376 }, + } + }, + { + "t7", new List + { + //Weapons + new Item { Name = "Dark_Silver_Axes", Prefab = -1130238142 }, + new Item { Name = "Dark_Silver_Crossbow", Prefab = -814739263 }, + new Item { Name = "Dark_Silver_Mace", Prefab = -184713893 }, + new Item { Name = "Dark_Silver_Reaper", Prefab = 6711686 }, + new Item { Name = "Dark_Silver_Slashers", Prefab = 633666898 }, + new Item { Name = "Dark_Silver_Spear", Prefab = -352704566 }, + new Item { Name = "Dark_Silver_Sword", Prefab = -1455388114 }, + new Item { Name = "Dark_Silver_GreatSword", Prefab = 674704033 }, + + //Stuff + new Item { Name = "Dawnthorn_Boots", Prefab = 560446510 }, + new Item { Name = "Dawnthorn_Gloves", Prefab = 2055058719 }, + new Item { Name = "Dawnthorn_Chestguard", Prefab = -930514044 }, + new Item { Name = "Dawnthorn_Leggings", Prefab = -1555051415 }, + + //Jewels + new Item { Name = "Bloody_Merlot_Amulet", Prefab = 991396285 }, + } + }, + + { + "t6", new List + { + //Weapons + new Item { Name = "Merciless_Iron_Axes", Prefab = 198951695 }, + new Item { Name = "Merciless_Iron_Crossbow", Prefab = 1221976097 }, + new Item { Name = "Merciless_Iron_Mace", Prefab = -276593802 }, + new Item { Name = "Merciless_Iron_Reaper", Prefab = 1778128946 }, + new Item { Name = "Merciless_Iron_Slashers", Prefab = 866934844 }, + new Item { Name = "Merciless_Iron_Spear", Prefab = 1065194820 }, + new Item { Name = "Merciless_Iron_Sword", Prefab = -435501075 }, + new Item { Name = "Merciless_GreatSword", Prefab = 82781195 }, + + //Stuff + new Item { Name = "Merciless_Hollowfang_Boots", Prefab = -674860200 }, + new Item { Name = "Merciless_Hollowfang_Gloves", Prefab = 82446940 }, + new Item { Name = "Merciless_Hollowfang_Leggings", Prefab = -916555565 }, + new Item { Name = "Merciless_Hollowfang_Chestguard", Prefab = 1388572480 }, + + //Jewels + new Item { Name = "Pendant_Of_The_Dawnrunner", Prefab = -1046748791 }, + new Item { Name = "Pendant_Of_The_Duskwatcher", Prefab = 610958202 }, + new Item { Name = "Pendant_Of_The_knigth", Prefab = -425306671 }, + new Item { Name = "Pendant_Of_The_Sorcerer", Prefab = 199425997 }, + new Item { Name = "Pendant_Of_The_Spellweaver", Prefab = 1012837641 }, + new Item { Name = "Pendant_Of_The_Warlock", Prefab = -651554566 }, + } + }, + + + { + "t5", new List + { + //Weapons + new Item { Name = "Iron_Axes", Prefab = -1579575933 }, + new Item { Name = "Iron_Crossbow", Prefab = 836066667 }, + new Item { Name = "Iron_Mace", Prefab = -1714012261 }, + new Item { Name = "Iron_Reaper", Prefab = -2081286944 }, + new Item { Name = "Iron_Slashers", Prefab = -314614708 }, + new Item { Name = "Iron_Spear", Prefab = 1853029976 }, + new Item { Name = "Iron_Sword", Prefab = -903587404 }, + new Item { Name = "Iron_GreatSword", Prefab = -768054337 }, + + //Stuff + new Item { Name = "Hollowfang_Boots", Prefab = -1837769884 }, + new Item { Name = "Hollowfang_Gloves", Prefab = -406808302 }, + new Item { Name = "Hollowfang_Leggings", Prefab = 12127911 }, + new Item { Name = "Hollowfang_Chestguard", Prefab = -604941435 }, + + //Jewels + new Item { Name = "Scourgestone_Pendant", Prefab = -650855520 }, + } + }, + + + { + "t4", new List + { + //Weapons + new Item { Name = "Merciless_Copper_Axes", Prefab = -491969324 }, + new Item { Name = "Merciless_Copper_Crossbow", Prefab = -1636801169 }, + new Item { Name = "Merciless_Copper_Mace", Prefab = 343324920 }, + new Item { Name = "Merciless_Copper_Slashers", Prefab = -1042299347 }, + new Item { Name = "Merciless_Copper_Spear", Prefab = 790210443 }, + new Item { Name = "Merciless_Copper_Sword", Prefab = -1219959051 }, + + //Stuff + new Item { Name = "Merciless_Nightstalker_Boots", Prefab = -1675225643 }, + new Item { Name = "Merciless_Nightstalker_Gloves", Prefab = -1739590652 }, + new Item { Name = "Merciless_Nightstalker_Leggings", Prefab = -1771720396 }, + new Item { Name = "Merciless_Nightstalker_Chestguard", Prefab = 1721366777 }, + + //Jewels + new Item { Name = "Ring_Of_The_Dawnrunner", Prefab = -154264228 }, + new Item { Name = "Ring_Of_The_Duskwatcher", Prefab = -809059551 }, + new Item { Name = "Ring_Of_The_Spellweaver", Prefab = -886916793 }, + new Item { Name = "Ring_Of_The_Warlock", Prefab = 336922685 }, + } + }, + + { + "t3", new List + { + //Weapons + new Item { Name = "Copper_Axes", Prefab = 518802008 }, + new Item { Name = "Copper_Crossbow", Prefab = -1277074895 }, + new Item { Name = "Copper_Mace", Prefab = -331345186 }, + new Item { Name = "Copper_Spear", Prefab = 1370755976 }, + new Item { Name = "Copper_Sword", Prefab = -2037272000 }, + + //Stuff + new Item { Name = "Nightstalker_Boots", Prefab = -1354920908 }, + new Item { Name = "Nightstalker_Gloves", Prefab = -1183157751 }, + new Item { Name = "Nightstalker_Leggings", Prefab = 1925394440 }, + new Item { Name = "Nightstalker_Chestguard", Prefab = -957963240 }, + + //Jewels + new Item { Name = "Gravedigger_Ring", Prefab = -1588051702 }, + } + }, + }; + + public static Dictionary> JewelDictionary { get; } = new Dictionary> + { + { + "blood", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(-113436752) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(-996555621) }, + new Jewel { Name = "Blood_Fountain", Tier = "T02", PrefabGuid = new PrefabGUID(-1624411159) }, + new Jewel { Name = "Blood_Rage", Tier = "T02", PrefabGuid = new PrefabGUID(343217159) }, + new Jewel { Name = "Blood_Rite", Tier = "T02", PrefabGuid = new PrefabGUID(-2059886133) }, + new Jewel { Name = "Sanguine_Coil", Tier = "T02", PrefabGuid = new PrefabGUID(75934448) }, + new Jewel { Name = "Shadowbolt", Tier = "T02", PrefabGuid = new PrefabGUID(918613164) }, + new Jewel { Name = "Veil_Of_Blood", Tier = "T02", PrefabGuid = new PrefabGUID(-431964258) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(-41686151) }, + new Jewel { Name = "Blood_Fountain", Tier = "T03", PrefabGuid = new PrefabGUID(-312598876) }, + new Jewel { Name = "Blood_Rage", Tier = "T03", PrefabGuid = new PrefabGUID(-1952560879) }, + new Jewel { Name = "Blood_Rite", Tier = "T03", PrefabGuid = new PrefabGUID(1881059081) }, + new Jewel { Name = "Sanguine_Coil", Tier = "T03", PrefabGuid = new PrefabGUID(1785926321) }, + new Jewel { Name = "Shadowbolt", Tier = "T03", PrefabGuid = new PrefabGUID(738473666) }, + new Jewel { Name = "Veil_Of_Blood", Tier = "T03", PrefabGuid = new PrefabGUID(-1302801575) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(271061481) } + } + }, + { + "chaos", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(2130810069) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(1083105737) }, + new Jewel { Name = "Aftershock", Tier = "T02", PrefabGuid = new PrefabGUID(1035334240) }, + new Jewel { Name = "Chaos_Barrier", Tier = "T02", PrefabGuid = new PrefabGUID(1112619884) }, + new Jewel { Name = "Chaos_Volley", Tier = "T02", PrefabGuid = new PrefabGUID(1243967840) }, + new Jewel { Name = "Power_Surge", Tier = "T02", PrefabGuid = new PrefabGUID(1168555540) }, + new Jewel { Name = "Veil_Of_Chaos", Tier = "T02", PrefabGuid = new PrefabGUID(-2133879652) }, + new Jewel { Name = "Void", Tier = "T02", PrefabGuid = new PrefabGUID(157004582) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(-1601295908) }, + new Jewel { Name = "Aftershock", Tier = "T03", PrefabGuid = new PrefabGUID(685024499) }, + new Jewel { Name = "Chaos_Barrier", Tier = "T03", PrefabGuid = new PrefabGUID(-209873380) }, + new Jewel { Name = "Chaos_Volley", Tier = "T03", PrefabGuid = new PrefabGUID(-1111771702) }, + new Jewel { Name = "Power_Surge", Tier = "T03", PrefabGuid = new PrefabGUID(-1090887222) }, + new Jewel { Name = "Veil_Of_Chaos", Tier = "T03", PrefabGuid = new PrefabGUID(1613948207) }, + new Jewel { Name = "Void", Tier = "T03", PrefabGuid = new PrefabGUID(-2054797612) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(-1796954295) } + } + }, + { + "frost", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(1908312304) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(1030854657) }, + new Jewel { Name = "Crystal_Lance", Tier = "T02", PrefabGuid = new PrefabGUID(-390381611) }, + new Jewel { Name = "Frost_Barrier", Tier = "T02", PrefabGuid = new PrefabGUID(2134082866) }, + new Jewel { Name = "Frost_Bat", Tier = "T02", PrefabGuid = new PrefabGUID(-309124704) }, + new Jewel { Name = "Ice_Block", Tier = "T02", PrefabGuid = new PrefabGUID(724975767) }, + new Jewel { Name = "Ice_Nova", Tier = "T02", PrefabGuid = new PrefabGUID(-535477182) }, + new Jewel { Name = "Veil_Of_Frost", Tier = "T02", PrefabGuid = new PrefabGUID(-710738056) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(223899244) }, + new Jewel { Name = "Crystal_Lance", Tier = "T03", PrefabGuid = new PrefabGUID(594180030) }, + new Jewel { Name = "Frost_Barrier", Tier = "T03", PrefabGuid = new PrefabGUID(1381699867) }, + new Jewel { Name = "Frost_Bat", Tier = "T03", PrefabGuid = new PrefabGUID(-1530254765) }, + new Jewel { Name = "Ice_Block", Tier = "T03", PrefabGuid = new PrefabGUID(-889584357) }, + new Jewel { Name = "Ice_Nova", Tier = "T03", PrefabGuid = new PrefabGUID(1123463900) }, + new Jewel { Name = "Veil_Of_Frost", Tier = "T03", PrefabGuid = new PrefabGUID(-1190496962) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(-147757377) } + } + }, + { + "illusion", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(1387124262) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(437696083) }, + new Jewel { Name = "Mist_Trance", Tier = "T02", PrefabGuid = new PrefabGUID(101601247) }, + new Jewel { Name = "Mosquito", Tier = "T02", PrefabGuid = new PrefabGUID(-928330249) }, + new Jewel { Name = "Phantom_Aegis", Tier = "T02", PrefabGuid = new PrefabGUID(1123282909) }, + new Jewel { Name = "Spectral_Wolf", Tier = "T02", PrefabGuid = new PrefabGUID(1520619383) }, + new Jewel { Name = "Veil_Of_Illusion", Tier = "T02", PrefabGuid = new PrefabGUID(606339127) }, + new Jewel { Name = "Wraith_Spear", Tier = "T02", PrefabGuid = new PrefabGUID(665418354) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(1540217782) }, + new Jewel { Name = "Mist_Trance", Tier = "T03", PrefabGuid = new PrefabGUID(-1513121786) }, + new Jewel { Name = "Mosquito", Tier = "T03", PrefabGuid = new PrefabGUID(-826325611) }, + new Jewel { Name = "Phantom_Aegis", Tier = "T03", PrefabGuid = new PrefabGUID(870884715) }, + new Jewel { Name = "Spectral_Wolf", Tier = "T03", PrefabGuid = new PrefabGUID(455494178) }, + new Jewel { Name = "Veil_Of_Illusion", Tier = "T03", PrefabGuid = new PrefabGUID(-1206629745) }, + new Jewel { Name = "Wraith_Spear", Tier = "T03", PrefabGuid = new PrefabGUID(998259069) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(97169184) } + } + }, + { + "storm", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(-560146452) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(876293388) }, + new Jewel { Name = "Ball_Lightning", Tier = "T02", PrefabGuid = new PrefabGUID(-1703746731) }, + new Jewel { Name = "Cyclone", Tier = "T02", PrefabGuid = new PrefabGUID(994654794) }, + new Jewel { Name = "Discharge", Tier = "T02", PrefabGuid = new PrefabGUID(-313733383) }, + new Jewel { Name = "Lightning_Wall", Tier = "T02", PrefabGuid = new PrefabGUID(394140527) }, + new Jewel { Name = "Polarity_Shift", Tier = "T02", PrefabGuid = new PrefabGUID(-944716649) }, + new Jewel { Name = "Veil_Of_Storm", Tier = "T02", PrefabGuid = new PrefabGUID(-1416449755) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(189228039) }, + new Jewel { Name = "Ball_Lightning", Tier = "T03", PrefabGuid = new PrefabGUID(973763812) }, + new Jewel { Name = "Cyclone", Tier = "T03", PrefabGuid = new PrefabGUID(-341717525) }, + new Jewel { Name = "Discharge", Tier = "T03", PrefabGuid = new PrefabGUID(1533847605) }, + new Jewel { Name = "Lightning_Wall", Tier = "T03", PrefabGuid = new PrefabGUID(-2134499162) }, + new Jewel { Name = "Polarity_Shift", Tier = "T03", PrefabGuid = new PrefabGUID(-844537086) }, + new Jewel { Name = "Veil_Of_Storm", Tier = "T03", PrefabGuid = new PrefabGUID(182214837) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(2023809276) } + } + }, + { + "unholy", new List + { + new Jewel { Name = "T01", Tier = "T01", PrefabGuid = new PrefabGUID(803445709) }, + new Jewel { Name = "T02", Tier = "T02", PrefabGuid = new PrefabGUID(-860388090) }, + new Jewel { Name = "Corpse_Explosion", Tier = "T02", PrefabGuid = new PrefabGUID(977816262) }, + new Jewel { Name = "Corrupted_Skull", Tier = "T02", PrefabGuid = new PrefabGUID(-1183600395) }, + new Jewel { Name = "Death_Knight", Tier = "T02", PrefabGuid = new PrefabGUID(-173571027) }, + new Jewel { Name = "Soulburn", Tier = "T02", PrefabGuid = new PrefabGUID(1277476884) }, + new Jewel { Name = "Veil_Of_Bones", Tier = "T02", PrefabGuid = new PrefabGUID(-1347054873) }, + new Jewel { Name = "Ward_Of_The_Damned", Tier = "T02", PrefabGuid = new PrefabGUID(-593608743) }, + new Jewel { Name = "T03", Tier = "T03", PrefabGuid = new PrefabGUID(-647547545) }, + new Jewel { Name = "Corpse_Explosion", Tier = "T03", PrefabGuid = new PrefabGUID(-1123608041) }, + new Jewel { Name = "Corrupted_Skull", Tier = "T03", PrefabGuid = new PrefabGUID(-1508992859) }, + new Jewel { Name = "Death_Knight", Tier = "T03", PrefabGuid = new PrefabGUID(-318118264) }, + new Jewel { Name = "Soulburn", Tier = "T03", PrefabGuid = new PrefabGUID(282707515) }, + new Jewel { Name = "Veil_Of_Bones", Tier = "T03", PrefabGuid = new PrefabGUID(-1913987811) }, + new Jewel { Name = "Ward_Of_The_Damned", Tier = "T03", PrefabGuid = new PrefabGUID(665184248) }, + new Jewel { Name = "T04", Tier = "T04", PrefabGuid = new PrefabGUID(1412786604) } + } + } + }; + + internal static readonly Dictionary MaterialDictionary = + new Dictionary() + { + { "planche", (new PrefabGUID(-1017402979), 400) }, // + { "planche-renforcé", (new PrefabGUID(-1397591435), 8) }, // + { "brique de pierre", (new PrefabGUID(1788016417), 400) }, // + { "pierre", (new PrefabGUID(-1531666018), 240) }, // + { "cuir", (new PrefabGUID(-1907572080), 12) }, // + { "dark silver ingot", (new PrefabGUID(-762000259), 12) }, // + { "lingots de cuivre", (new PrefabGUID(-1237019921), 12) }, // + { "verre", (new PrefabGUID(-1233716303), 24) }, // + { "power core", (new PrefabGUID(-1190647720), 4) }, // + { "radium alloy", (new PrefabGUID(2116142390), 12) }, // + { "essence", (new PrefabGUID(862477668), 250) }, // + { "grande essence", (new PrefabGUID(271594022), 1) }, // + { "essence originel", (new PrefabGUID(1566989408), 2) } // + }; + } +} \ No newline at end of file diff --git a/Commons/GiveType.cs b/Commons/GiveType.cs new file mode 100644 index 0000000..a8bc092 --- /dev/null +++ b/Commons/GiveType.cs @@ -0,0 +1,7 @@ +namespace CommunityCommands.Commons; + +public enum GiveType +{ + Set, + Item +} \ No newline at end of file diff --git a/Commons/Item.cs b/Commons/Item.cs new file mode 100644 index 0000000..141a910 --- /dev/null +++ b/Commons/Item.cs @@ -0,0 +1,12 @@ +namespace CommunityCommands.Commons; + +public class Item +{ + public string Name { get; set; } + public int Prefab { get; set; } + + public override string ToString() + { + return $"{{name: \"{Name}\", prefab: {Prefab}}}"; + } +} \ No newline at end of file diff --git a/Commons/Jewel.cs b/Commons/Jewel.cs new file mode 100644 index 0000000..2a2a4c4 --- /dev/null +++ b/Commons/Jewel.cs @@ -0,0 +1,10 @@ +using ProjectM; + +namespace CommunityCommands.Commons; + +public class Jewel +{ + public string Name { get; set; } + public string Tier { get; set; } + public PrefabGUID PrefabGuid { get; set; } +} \ No newline at end of file diff --git a/Commons/Position.cs b/Commons/Position.cs new file mode 100644 index 0000000..ce75351 --- /dev/null +++ b/Commons/Position.cs @@ -0,0 +1,9 @@ +using Unity.Mathematics; + +namespace CommunityCommands.Commons; + +public class Position +{ + public float3 position { get; set; } + public string text { get; set; } +} \ No newline at end of file diff --git a/Commons/SpawnType.cs b/Commons/SpawnType.cs new file mode 100644 index 0000000..42da34f --- /dev/null +++ b/Commons/SpawnType.cs @@ -0,0 +1,7 @@ +namespace CommunityCommands.Commons; +public enum SpawnType +{ + Vblood, + All, + Npc +} \ No newline at end of file diff --git a/Commons/VBlood.cs b/Commons/VBlood.cs new file mode 100644 index 0000000..3dae0a8 --- /dev/null +++ b/Commons/VBlood.cs @@ -0,0 +1,10 @@ +using ProjectM; + +namespace CommunityCommands.Commons; + +public class VBlood +{ + public string DisplayName { get; set; } + public PrefabGUID Prefab { get; set; } + public Position Position { get; set; } +} \ No newline at end of file diff --git a/CommunityCommands.csproj b/CommunityCommands.csproj index 7d164c2..75af0d4 100644 --- a/CommunityCommands.csproj +++ b/CommunityCommands.csproj @@ -15,9 +15,9 @@ - + - + \ No newline at end of file diff --git a/README.md b/README.md index 334be7e..e7654d9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,110 @@ ![](logo.png) + # CommunityCommands for V Rising -CommunityCommands is a server modification for V Rising that adds chat commands that are compatbible with [VampireCommandFramework](https://github.com/decaprime/VampireCommandFramework). This is a spirtual successor in the line of ChatCommands by Nopey and RPGMods by Kaltharos. This mod is not a direct fork from that line and will not contain the RPG functionalities. It's purpose is to provide a generic collection of commands for a variety of community server needs. -## Commands -- `.bloodpotion` \ No newline at end of file +CommunityCommands is a server modification for V Rising that adds chat commands compatible with the [VampireCommandFramework](https://github.com/decaprime/VampireCommandFramework). It is designed to provide a generic collection of commands to meet various community server needs. This is a spirtual successor in the line of ChatCommands by Nopey and RPGMods by Kaltharos. This mod is not a direct fork from that line and will not contain the RPG functionalities. It's purpose is to provide a generic collection of commands for a variety of community server needs. + +## Usage + +CommunityCommands introduces the following commands: +### .ct5 +Add some materials to a player's inventory to directly build a level 5 castle. + +Example usage: +- `.ct5` + +### .bloodpotion (or .bp) +Creates a potion with a specified blood type, quality, and value. + +Example usage: +- `.bloodpotion Warrior 80` *give you a 80% warrior blood merlot potion* +- `.bp rogue` *give you a 100% rogue blood merlot potion* + +### .changespeed (or .cs) +Change the speed of your character. + +Example usage: +- `.cs 25` +- `changespeed 160` + +### .clearinventory (or .ci) +Clears your inventory. + +Example usage: +- `.ci` +- `clearinventory` + +### .windows and doors +Close/Open all doors. + +Example usage: +- `.close-all` or `.ca` +- `open-all` or `.oa` + +### .ct5 +Add some materials to a player's inventory to directly build a level 5 castle. + +Example usage: +- `.ct5` + +### .give (or .g) +Give a specific item or set of items to yourself. + +Example usage: +- `.give item Amulet_Of_The_Unyielding_Charger` *give you the "Amulet Of The Unyielding Charger"* +- `.give set t8` *give you a full `T8` set* + +### .windows and doors +Close/Open all doors. + +Example usage: +- `.close-all` or `.ca` +- `open-all` or `.oa` + +### .horse (or .h) +Manage horses (spawn or change attributes) + +Example usage: +- `.h spawn` or `.horse spawn` +- `h max` or `.h max 1 11 7 14` change speed = 11, acceleration = 7 and rotation = 14. + +### .jewel (or .jw) +Add a jewel or a set of jewels in your inventory. + +Example usage: +- `.jewel item chaos_volley t03` +- `.jw set frost` or `.jw set blood` + +### .reset (or .rs) +Restore healt ( 100% ) and reset skills cooldown. + +Example usage: +- `.reset` or `.rs` + +### .teleport (or .tp) +Teleport to a specific vblood. + +Example usage: +- `.teleport wolf` or `.tp solarus` +- `.tp bEAtrice` or `.tp adam` + +### .unlockallabilities (or .uaa) +Unlock all abilities for the player. + +Example usage: +- `.uaa` or `.unlockallabilities` + +### .unlockallresearch (or .uar) +Unlock all research for the player. + +Example usage: +- `.unlockallresearch` or `.uar` + +### .spawn (or .s) +Spawn a vblood or npc next to the player. + +Example usage: +- `.spawn vblood rufus 3` *spawn 3 rufus boss near the player.* +- `.spawn all 2` *spawn all the bosses 2 times.* + +Happy gaming! diff --git a/Utils/BloodUtils.cs b/Utils/BloodUtils.cs new file mode 100644 index 0000000..28183b4 --- /dev/null +++ b/Utils/BloodUtils.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using CommunityCommands.Commons; +using ProjectM; +using Blood = CommunityCommands.Commons.Blood; + +namespace CommunityCommands.Utils; + +public class BloodUtils +{ + public static PrefabGUID GetBloodPotionRecipe() + { + return new PrefabGUID(1223264867); + } + + public static PrefabGUID GetBloodPrefabGuid(string bloodName) + { + var bloodTypes = Database.BloodTypes; + foreach (var blood in bloodTypes) + { + if (blood.name.ToLower().Equals(bloodName.ToLower())) + { + return blood.prefab; + } + } + + return default(PrefabGUID); + } + + public static string GetBloodName(PrefabGUID prefab) + { + var bloodTypes = Database.BloodTypes; + foreach (var blood in bloodTypes) + { + if (blood.prefab == prefab) + { + return blood.name; + } + } + + return "Frailed"; + } + + public static string GetBloodName(string blooName) + { + var bloodTypes = Database.BloodTypes; + foreach (var blood in bloodTypes) + { + if (blood.name.ToLower().Equals(blooName.ToLower())) + { + return blood.name; + } + } + + return "Frailed"; + } +} \ No newline at end of file diff --git a/Utils/CharacterUtil.cs b/Utils/CharacterUtil.cs new file mode 100644 index 0000000..285159c --- /dev/null +++ b/Utils/CharacterUtil.cs @@ -0,0 +1,241 @@ +using System; +using CommunityCommands.Utils; +using ProjectM; +using ProjectM.Network; +using Unity.Collections; +using Unity.Entities; +using Unity.Mathematics; +using Unity.Transforms; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + public static class CharacterUtil + { + private static EntityManager EntityManager = Helper.Server.EntityManager; + + public static void TeleportToPos(ChatCommandContext ctx, string targetName, float3 pos) + { + var entity = EntityManager.CreateEntity( + ComponentType.ReadWrite(), + ComponentType.ReadWrite()); + + EntityManager.SetComponentData(entity, new() + { + User = ctx.Event.SenderUserEntity, + Character = ctx.Event.SenderCharacterEntity + }); + + EntityManager.SetComponentData(entity, new() + { + Position = new float3(pos.x, pos.y, pos.z), + Target = PlayerTeleportDebugEvent.TeleportTarget.Self + }); + + var messageReply = DatabaseUtils.GetBossPositionText(targetName.ToLower()) == "None" + ? "" + : DatabaseUtils.GetBossPositionText(targetName.ToLower()); + ctx.Reply($"Teleported to {DatabaseUtils.GetUnitDisplayName(targetName)}.{messageReply}"); + } + + public static void ClearInventory(ChatCommandContext ctx ) + { + Entity characterEntity = ctx.Event.SenderCharacterEntity; + if (!InventoryUtilities.TryGetInventoryEntity(EntityManager, characterEntity, out Entity playerInventory) || + playerInventory == Entity.Null) + return; + + var inventoryBuffer = EntityManager.GetBuffer(playerInventory); + + foreach (var inventoryItem in inventoryBuffer) + { + InventoryUtilitiesServer.TryRemoveItem(EntityManager, playerInventory, inventoryItem.ItemType, + inventoryItem.Amount); + } + ctx.Reply("Inventory cleared."); + } + + public static void ResetSkillsCooldown(Entity characterEntity) + { + var AbilityBuffer = EntityManager.GetBuffer(characterEntity); + foreach (var ability in AbilityBuffer) + { + var AbilitySlot = ability.GroupSlotEntity._Entity; + var ActiveAbility = EntityManager.GetComponentData(AbilitySlot); + var ActiveAbility_Entity = ActiveAbility.StateEntity._Entity; + + var b = GetPrefabGUID(ActiveAbility_Entity); + if (b.GuidHash == 0) continue; + + var AbilityStateBuffer = EntityManager.GetBuffer(ActiveAbility_Entity); + foreach (var state in AbilityStateBuffer) + { + var abilityState = state.StateEntity._Entity; + var abilityCooldownState = EntityManager.GetComponentData(abilityState); + abilityCooldownState.CooldownEndTime = 0; + EntityManager.SetComponentData(abilityState, abilityCooldownState); + } + } + } + + public static void RecoverHealt(ChatCommandContext ctx) + { + var userIndex = ctx.Event.User.Index; + var entityManager = Helper.Server.EntityManager; + var component = entityManager.GetComponentData(ctx.Event.SenderCharacterEntity); + + var restoreHp = ((component.MaxHealth / 100) * 100) - component.Value; + + var healthEvent = new ChangeHealthDebugEvent() + { + Amount = (int)restoreHp + }; + + Helper.Server.GetExistingSystem().ChangeHealthEvent(userIndex, ref healthEvent); + + if (BuffUtility.TryGetBuff(entityManager, ctx.Event.SenderCharacterEntity, new PrefabGUID(697095869), + out var inCombatBuff)) + { + entityManager.AddComponent(inCombatBuff); + } + } + + public static void UnlockAllAbilities(ChatCommandContext ctx) + { + try + { + var fromCharacter = new FromCharacter(); + fromCharacter.Character = ctx.Event.SenderCharacterEntity; + fromCharacter.User = ctx.Event.SenderUserEntity; + + Helper.Server.GetExistingSystem().UnlockAllVBloods(fromCharacter); + ctx.Reply("Unlocked all abilities for the player."); + } + catch (Exception e) + { + Console.WriteLine(e); + throw ctx.Error(e.Message); + } + } + + public static void UnlockAllResearch(ChatCommandContext ctx) + { + try + { + var fromCharacter = new FromCharacter(); + fromCharacter.Character = ctx.Event.SenderCharacterEntity; + fromCharacter.User = ctx.Event.SenderUserEntity; + + Helper.Server.GetExistingSystem().UnlockAllResearch(fromCharacter); + ctx.Reply("Unlocked all research for the player."); + } + catch (Exception e) + { + Console.WriteLine(e); + throw ctx.Error(e.Message); + } + } + + public static void UnlockAllQuest(ChatCommandContext ctx) + { + try + { + var debugEventsSystem = Helper.Server.GetExistingSystem(); + + var fromCharacter = new FromCharacter + { + Character = ctx.Event.SenderCharacterEntity, + User = ctx.Event.SenderUserEntity + }; + + var commandBuffer = new EntityCommandBuffer(Allocator.Temp); + + debugEventsSystem.CompleteJournal(commandBuffer, fromCharacter); + + commandBuffer.Playback(Helper.Server.EntityManager); + commandBuffer.Dispose(); + + ctx.Reply("Unlocked all quests for the player."); + } + catch (Exception e) + { + Console.WriteLine(e); + throw ctx.Error(e.Message); + } + } + + public static void ChangeSpeed(ChatCommandContext ctx, float speed) + { + Entity characterEntity = ctx.Event.SenderCharacterEntity; + var component = EntityManager.GetComponentData(characterEntity); + component.Speed = ModifiableFloat.Create(characterEntity, EntityManager, speed); + EntityManager.SetComponentData(characterEntity, component); + ctx.Reply($"Speed of character changed to {speed}"); + } + + public static void GetPlayerPosition(ChatCommandContext ctx) + { + var em = Helper.Server.EntityManager; + var playerEntity = ctx.Event.SenderCharacterEntity; + var translation = em.GetComponentData(playerEntity); + var currentPosition = translation.Value; + + ctx.Reply($"Current position: {currentPosition}"); + } + + private static PrefabGUID GetPrefabGUID(Entity entity) + { + PrefabGUID guid; + try + { + guid = EntityManager.GetComponentData(entity); + } + catch + { + guid.GuidHash = 0; + } + + return guid; + } + + public static Entity GetPlayerEntityByName(string playerName) + { + playerName = playerName.ToLower(); + var entityManager = Helper.Server.EntityManager; + var characterDataEntities = GetAllPlayers(); + + foreach (var characterDataEntity in characterDataEntities) + { + var characterData = entityManager.GetComponentData(characterDataEntity); + if (characterData.Name.ToString().ToLower().Equals(playerName)) + { + characterDataEntities.Dispose(); + return characterDataEntity; + } + } + characterDataEntities.Dispose(); + return Entity.Null; + } + + + public static NativeArray GetAllPlayers() + { + var query = Helper.Server.EntityManager.CreateEntityQuery( + ComponentType.ReadOnly() + ); + return query.ToEntityArray(Allocator.Temp); + } + + + + + + private static FromCharacter GetFromCharacter(ChatCommandContext ctx) + { + var fromCharacter = new FromCharacter(); + fromCharacter.Character = ctx.Event.SenderCharacterEntity; + fromCharacter.User = ctx.Event.SenderUserEntity; + return fromCharacter; + } + } +} \ No newline at end of file diff --git a/Utils/Database.cs b/Utils/Database.cs new file mode 100644 index 0000000..eb267ac --- /dev/null +++ b/Utils/Database.cs @@ -0,0 +1,262 @@ +using ProjectM; +using System.Collections.Generic; +using CommunityCommands.Commands; + +namespace CommunityCommands +{ + public class Database + { + private static Dictionary GetUnitDatabase() + { + Dictionary database_units = + new Dictionary + { + { "wolf", ("Alpha Wolf", new PrefabGUID(-1905691330)) }, + { "errol", ("Errol the Stonebreaker", new PrefabGUID(-2025101517)) }, + { "keely", ("Keely the Frost Archer", new PrefabGUID(1124739990)) }, + { "rufus", ("Rufus the Foreman", new PrefabGUID(2122229952)) }, + { "goreswine", ("Goreswine the Ravager", new PrefabGUID(577478542)) }, + { "grayson", ("Grayson the Armourer", new PrefabGUID(1106149033)) }, + { "rat", ("Putrid Rat", new PrefabGUID(-2039908510)) }, + { "lidia", ("Lidia the Chaos Archer", new PrefabGUID(763273073)) }, + { "clive", ("Clive the Firestarter", new PrefabGUID(1896428751)) }, + { "bear", ("Ferocious Bear", new PrefabGUID(-1391546313)) }, + { "polora", ("Polora the Feywalker", new PrefabGUID(-484556888)) }, + { "nicholaus", ("Nicholaus the Fallen", new PrefabGUID(153390636)) }, + { "quincey", ("Quincey the Bandit King", new PrefabGUID(-1659822956)) }, + { "beatrice", ("Beatrice the Tailor", new PrefabGUID(-1942352521)) }, + { "tristan", ("Tristan the Vampire Hunter", new PrefabGUID(-1449631170)) }, + { "kriig", ("Kriig the Undead General", new PrefabGUID(-1365931036)) }, + { "christina", ("Christina the Sun Priestess", new PrefabGUID(-99012450)) }, + { "vincent", ("Vincent the Frostbringer", new PrefabGUID(-29797003)) }, + { "bane", ("Bane the Shadowblade", new PrefabGUID(613251918)) }, + { "grethel", ("Grethel the Glassblower", new PrefabGUID(910988233)) }, + { "leandra", ("Leandra the Shadow Priestess", new PrefabGUID(939467639)) }, + { "maja", ("Maja the Dark Savant", new PrefabGUID(1945956671)) }, + { "terah", ("Terah the Geomancer", new PrefabGUID(-1065970933)) }, + { "meredith", ("Meredith the Bright Archer", new PrefabGUID(850622034)) }, + { "jade", ("Jade the Vampire Hunter", new PrefabGUID(-1968372384)) }, + { "raziel", ("Raziel the Shepherd", new PrefabGUID(-680831417)) }, + { "frostmaw", ("Frostmaw the Mountain Terror", new PrefabGUID(24378719)) }, + { "octavian", ("Octavian the Militia Captain", new PrefabGUID(1688478381)) }, + { "domina", ("Domina the Blade Dancer", new PrefabGUID(-1101874342)) }, + { "angram", ("Angram the Purifier", new PrefabGUID(106480588)) }, + { "ziva", ("Ziva the Engineer", new PrefabGUID(172235178)) }, + { "ungora", ("Ungora the Spider Queen", new PrefabGUID(-548489519)) }, + { "wanderer", ("The Old Wanderer", new PrefabGUID(109969450)) }, + { "foulrot", ("Foulrot the Soultaker", new PrefabGUID(-1208888966)) }, + { "willfred", ("Willfred the Werewolf Chief", new PrefabGUID(-1007062401)) }, + { "balaton", ("The Duke of Balaton", new PrefabGUID(-203043163)) }, + { "cyril", ("Cyril the Cursed Smith", new PrefabGUID(326378955)) }, + { "magnus", ("Sir Magnus the Overseer", new PrefabGUID(-26105228)) }, + { "mairwyn", ("Mairwyn the Elementalist", new PrefabGUID(-2013903325)) }, + { "baron", ("Baron du Bouchon the Sommelier", new PrefabGUID(192051202)) }, + { "morian", ("Morian the Stormwing Matriarch", new PrefabGUID(685266977)) }, + { "terrorclaw", ("Terrorclaw the Ogre", new PrefabGUID(-1347412392)) }, + { "azariel", ("Azariel the Sunbringer", new PrefabGUID(114912615)) }, + { "henry", ("Henry Blackbrew the Doctor", new PrefabGUID(814083983)) }, + { "matka", ("Matka the Curse Weaver", new PrefabGUID(-910296704)) }, + { "voltatia", ("Voltatia the Power Master", new PrefabGUID(2054432370)) }, + { "styx", ("Nightmarshal Styx the Sunderer", new PrefabGUID(1112948824)) }, + { "solarus", ("Solarus the Immaculate", new PrefabGUID(-740796338)) } + }; + + return database_units; + } + + + public static Dictionary GetBossPrefabs() + { + Dictionary bossPrefabs = new Dictionary(); + + Dictionary unitDatabase = GetUnitDatabase(); + foreach (var unitData in unitDatabase) + { + bossPrefabs.Add(unitData.Value.name, unitData.Value.Item2); + } + + return bossPrefabs; + } + + + public static string GetUnitName(string unitId) + { + Dictionary unitDatabase = GetUnitDatabase(); + + foreach (var unitData in unitDatabase) + { + if (unitData.Value.Item2.ToString() == unitId) + { + return unitData.Value.name; + } + } + + return null; + } + + + public static PrefabGUID GetUnitPrefabGUID(string unitId) + { + Dictionary unitDatabase = GetUnitDatabase(); + if (unitDatabase.ContainsKey(unitId)) + { + return unitDatabase[unitId].Item2; + } + else + { + return default(PrefabGUID); + } + } + + public static Dictionary> GetSetDatabase() + { + Dictionary> item_sets = new Dictionary>(); + + List t8 = new List + { + //Weapons + new Item { Name = "Sanguine_Axes", Prefab = -2044057823}, + new Item { Name = "Sanguine_Crossbow", Prefab = 1389040540}, + new Item { Name = "Sanguine_Mace", Prefab = -126076280 }, + new Item { Name = "Sanguine_Reaper", Prefab = -2053917766}, + new Item { Name = "Sanguine_Slashers", Prefab = 1322545846 }, + new Item { Name = "Sanguine_Spear", Prefab = -850142339 }, + new Item { Name = "Sanguine_Sword", Prefab = -774462329 }, + + //Stuff + new Item { Name = "Bloodmoon_Boots", Prefab = -556769032 }, + new Item { Name = "Bloodmoon_Chestguard", Prefab = 488592933 }, + new Item { Name = "Bloodmoon_Leggings", Prefab = 1292986377 }, + new Item { Name = "Bloodmoon_Gloves", Prefab = 1634690081}, + + //Jewels + new Item { Name = "Amulet_Of_The_Arch-Warlock", Prefab = 1380368392 }, + new Item { Name = "Amulet_Of_The_Crimson_Commander", Prefab = -104934480 }, + new Item { Name = "Amulet_Of_The_Unyielding_Charger", Prefab = -1004351840 }, + new Item { Name = "Amulet_Of_The_Blademaster", Prefab = -296161379 }, + new Item { Name = "Amulet_Of_The_Master_Spellweaver", Prefab = -1306155896 }, + new Item { Name = "Amulet_Of_The_Wicked_Prophet", Prefab = -175650376 }, + }; + + List t7 = new List + { + //Weapons + new Item { Name = "Dark_Silver_Axes", Prefab = -1130238142 }, + new Item { Name = "Dark_Silver_Crossbow", Prefab = -814739263 }, + new Item { Name = "Dark_Silver_Mace", Prefab = -184713893 }, + new Item { Name = "Dark_Silver_Reaper", Prefab = 6711686}, + new Item { Name = "Dark_Silver_Slashers", Prefab = 633666898 }, + new Item { Name = "Dark_Silver_Spear", Prefab = -352704566 }, + new Item { Name = "Dark_Silver_Sword", Prefab = -1455388114 }, + + //Stuff + new Item { Name = "Dawnthorn_Boots", Prefab = 560446510 }, + new Item { Name = "Dawnthorn_Gloves", Prefab = 2055058719 }, + new Item { Name = "Dawnthorn_Chestguard", Prefab = -930514044}, + new Item { Name = "Dawnthorn_Leggings", Prefab = -1555051415 }, + + //Jewels + new Item { Name = "Bloody_Merlot_Amulet", Prefab = 991396285 }, + }; + + List t6 = new List + { + //Weapons + new Item { Name = "Merciless_Iron_Axes", Prefab = 198951695 }, + new Item { Name = "Merciless_Iron_Crossbow", Prefab = 1221976097 }, + new Item { Name = "Merciless_Iron_Mace", Prefab = -276593802 }, + new Item { Name = "Merciless_Iron_Reaper", Prefab = 1778128946}, + new Item { Name = "Merciless_Iron_Slashers", Prefab = 866934844 }, + new Item { Name = "Merciless_Iron_Spear", Prefab = 1065194820 }, + new Item { Name = "Merciless_Iron_Sword", Prefab = -435501075 }, + + //Stuff + new Item { Name = "Merciless_Hollowfang_Boots", Prefab = -674860200 }, + new Item { Name = "Merciless_Hollowfang_Gloves", Prefab = 82446940 }, + new Item { Name = "Merciless_Hollowfang_Leggings", Prefab = -916555565 }, + new Item { Name = "Merciless_Hollowfang_Chestguard", Prefab = 1388572480 }, + + //Jewels + new Item { Name = "Pendant_Of_The_Dawnrunner", Prefab = -1046748791 }, + new Item { Name = "Pendant_Of_The_Duskwatcher", Prefab = 610958202 }, + new Item { Name = "Pendant_Of_The_knigth", Prefab = -425306671 }, + new Item { Name = "Pendant_Of_The_Sorcerer", Prefab = 199425997 }, + new Item { Name = "Pendant_Of_The_Spellweaver", Prefab = 1012837641 }, + new Item { Name = "Pendant_Of_The_Warlock", Prefab = -651554566 }, + }; + + List t5 = new List + { + //Weapons + new Item { Name = "Iron_Axes", Prefab = -1579575933 }, + new Item { Name = "Iron_Crossbow", Prefab = 836066667 }, + new Item { Name = "Iron_Mace", Prefab = -1714012261 }, + new Item { Name = "Iron_Reaper", Prefab = -2081286944}, + new Item { Name = "Iron_Slashers", Prefab = -314614708 }, + new Item { Name = "Iron_Spear", Prefab = 1853029976 }, + new Item { Name = "Iron_Sword", Prefab = -903587404 }, + + //Stuff + new Item { Name = "Hollowfang_Boots", Prefab = -1837769884 }, + new Item { Name = "Hollowfang_Gloves", Prefab = -406808302 }, + new Item { Name = "Hollowfang_Leggings", Prefab = 12127911 }, + new Item { Name = "Hollowfang_Chestguard", Prefab = -604941435 }, + + //Jewels + new Item { Name = "Scourgestone_Pendant", Prefab = -650855520 }, + }; + + List t4 = new List + { + //Weapons + new Item { Name = "Merciless_Copper_Axes", Prefab = -491969324 }, + new Item { Name = "Merciless_Copper_Crossbow", Prefab = -1636801169 }, + new Item { Name = "Merciless_Copper_Mace", Prefab = 343324920 }, + new Item { Name = "Merciless_Copper_Slashers", Prefab = -1042299347 }, + new Item { Name = "Merciless_Copper_Spear", Prefab = 790210443 }, + new Item { Name = "Merciless_Copper_Sword", Prefab = -1219959051 }, + + //Stuff + new Item { Name = "Merciless_Nightstalker_Boots", Prefab = -1675225643 }, + new Item { Name = "Merciless_Nightstalker_Gloves", Prefab = -1739590652 }, + new Item { Name = "Merciless_Nightstalker_Leggings", Prefab = -1771720396 }, + new Item { Name = "Merciless_Nightstalker_Chestguard", Prefab = 1721366777 }, + + //Jewels + new Item { Name = "Ring_Of_The_Dawnrunner", Prefab = -154264228 }, + new Item { Name = "Ring_Of_The_Duskwatcher", Prefab = -809059551 }, + new Item { Name = "Ring_Of_The_Spellweaver", Prefab = -886916793 }, + new Item { Name = "Ring_Of_The_Warlock", Prefab = 336922685 }, + }; + + List t3 = new List + { + //Weapons + new Item { Name = "Copper_Axes", Prefab = 518802008 }, + new Item { Name = "Copper_Crossbow", Prefab = -1277074895 }, + new Item { Name = "Copper_Mace", Prefab = -331345186 }, + new Item { Name = "Copper_Spear", Prefab = 1370755976 }, + new Item { Name = "Copper_Sword", Prefab = -2037272000 }, + + //Stuff + new Item { Name = "Nightstalker_Boots", Prefab = -1354920908 }, + new Item { Name = "Nightstalker_Gloves", Prefab = -1183157751 }, + new Item { Name = "Nightstalker_Leggings", Prefab = 1925394440 }, + new Item { Name = "Nightstalker_Chestguard", Prefab = -957963240 }, + + //Jewels + new Item { Name = "Gravedigger_Ring", Prefab = -1588051702 }, + }; + + item_sets.Add("t8", t8); + item_sets.Add("t7", t7); + item_sets.Add("t6", t6); + item_sets.Add("t5", t5); + item_sets.Add("t4", t4); + item_sets.Add("t3", t3); + + return item_sets; + } + + } +} \ No newline at end of file diff --git a/Utils/DatabaseUtils.cs b/Utils/DatabaseUtils.cs new file mode 100644 index 0000000..48b6c94 --- /dev/null +++ b/Utils/DatabaseUtils.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using ProjectM; +using Unity.Entities; +using Unity.Mathematics; +using VampireCommandFramework; +using CommunityCommands.Commons; + +namespace CommunityCommands.Utils +{ + public class DatabaseUtils + { + private static readonly Dictionary VBloodDatabase = Database.BossDatabase; + private static readonly Dictionary> ItemSetsDatabase = Database.ItemSets; + + public static string GetUnitDisplayName(string bossName) + { + if (VBloodDatabase.TryGetValue(bossName.ToLower(), out var boss)) + { + return boss.DisplayName; + } + + return null; + } + + public static string GetUnitDisplayName(PrefabGUID bossPrefab) + { + foreach (var boss in VBloodDatabase.Values) + { + if (boss.Prefab == bossPrefab) + { + return boss.DisplayName; + } + } + + return null; + } + + public static PrefabGUID GetUnitPrefabGUID(string bossName) + { + if (VBloodDatabase.TryGetValue(bossName.ToLower(), out var boss)) + { + return boss.Prefab; + } + + return default(PrefabGUID); + } + + public static float3 GetBossPosition(string targetName) + { + if (VBloodDatabase.TryGetValue(targetName.ToLower(), out var boss)) + { + return boss.Position.position; + } + + throw new Exception($"Invalid target name '{targetName}'."); + } + + public static string GetBossPositionText(string targetName) + { + if (VBloodDatabase.TryGetValue(targetName.ToLower(), out var boss)) + { + return boss.Position.text; + } + + throw new Exception($"Invalid target name '{targetName}'."); + } + + internal static void GiveEquipmentSet(ChatCommandContext ctx, string setName) + { + if (ItemSetsDatabase.TryGetValue(setName, out var equipmentList)) + { + var cpt = 0; + foreach (var item in equipmentList) + { + PrefabGUID prefab = new PrefabGUID(item.Prefab); + + Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, prefab, 1); + if (entity == Entity.Null) + { + ctx.Reply( + $"Failed to add item {item.Name.Replace("_", " ")} to inventory, your inventory is full."); + } + else + { + cpt++; + } + } + + ctx.Reply( + $"Given {cpt} out of {equipmentList.Count} items from the {setName} item set to the player."); + } + else + { + ctx.Reply($"Equipment set {setName} not found."); + } + } + + internal static void GiveSingleItem(ChatCommandContext ctx, string itemName) + { + var item = GetItem(ctx, itemName); + if (item == null) + { + return; + } + + PrefabGUID prefab = new PrefabGUID(item.Prefab); + + Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, prefab, 1); + var replyMessage = entity != Entity.Null + ? $"Given item {item.Name.Replace("_", " ")} to the player." + : $"Failed to add item {item.Name.Replace("_", " ")} to inventory, your inventory is full."; + + ctx.Reply(replyMessage); + } + + public static Item GetItem(ChatCommandContext ctx, string itemName) + { + var lowercaseItemName = itemName.ToLower(); + Item foundItem = null; + var matchingItems = new List(); + + foreach (var itemSet in ItemSetsDatabase.Values) + { + foreach (var item in itemSet) + { + if (item.Name.ToLower().Contains(lowercaseItemName)) + { + foundItem = item; + matchingItems.Add(item); + } + } + } + + switch (matchingItems.Count) + { + case 0: + return null; + case 1: + return foundItem; + default: + var matchedItemNames = + string.Join(", ", matchingItems.Select(i => $"{i.Name}")); + ctx.Reply($"Multiple matches found: {matchedItemNames}"); + return null; + } + } + + internal static void GiveJewelSet(ChatCommandContext ctx, string jewelSet) + { + if (Database.JewelDictionary.TryGetValue(jewelSet.ToLower(), out var jewelList)) + { + var count = 0; + foreach (var jewel in jewelList) + { + PrefabGUID prefab = jewel.PrefabGuid; + + Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, prefab, 1); + if (entity == Entity.Null) + { + ctx.Reply( + $"Failed to add jewel {jewel.Name.Replace("_", " ")} to inventory, your inventory is full."); + } + else + { + count++; + } + } + + ctx.Reply( + $"Given {count} out of {jewelList.Count} jewels from the {jewelSet} set to the player."); + } + else + { + ctx.Reply($"Jewel set {jewelSet} not found."); + } + } + + internal static void GiveSingleJewel(ChatCommandContext ctx, string jewelName, string jewelTier) + { + var jewel = GetJewel(ctx, jewelName, jewelTier); + if (jewel == null) + { + return; + } + + PrefabGUID prefab = jewel.PrefabGuid; + + Entity entity = Helper.AddItemToInventory(ctx.Event.SenderCharacterEntity, prefab, 1); + var replyMessage = entity != Entity.Null + ? $"Given jewel {jewel.Name.Replace("_", " ")} {jewel.Tier} to the player." + : $"Failed to add jewel {jewel.Name.Replace("_", " ")} to inventory, your inventory is full."; + + ctx.Reply(replyMessage); + } + + public static Jewel GetJewel(ChatCommandContext ctx, string jewelName, string jewelTier) + { + var lowercaseJewelName = jewelName.ToLower(); + var lowercaseJewelTier = jewelTier.ToLower(); + Jewel foundJewel = null; + var matchingJewels = new List(); + + foreach (var jewelSet in Database.JewelDictionary.Values) + { + foreach (var jewel in jewelSet) + { + if (jewel.Name.ToLower().Contains(lowercaseJewelName) && jewel.Tier.ToLower() == lowercaseJewelTier) + { + foundJewel = jewel; + matchingJewels.Add(jewel); + } + } + } + + switch (matchingJewels.Count) + { + case 0: + return null; + case 1: + return foundJewel; + default: + var matchedJewelNames = + string.Join(", ", matchingJewels.Select(j => $"{j.Name}")); + ctx.Reply($"Multiple matches found: {matchedJewelNames}"); + return null; + } + } + + public static Dictionary GetMaterialDictionary { get; } = Database.MaterialDictionary; + } +} \ No newline at end of file diff --git a/Utils/HorseUtil.cs b/Utils/HorseUtil.cs new file mode 100644 index 0000000..4868e9c --- /dev/null +++ b/Utils/HorseUtil.cs @@ -0,0 +1,100 @@ +using CommunityCommands.Utils; +using VampireCommandFramework; + +namespace CommunityCommands.Commands +{ + using ProjectM; + using Unity.Entities; + using Unity.Transforms; + using Unity.Collections; + using Unity.Mathematics; + using System.Collections.Generic; + + internal static class HorseUtil + { + private static Entity empty_entity = new Entity(); + + internal static void SpawnHorse(int countlocal, float3 localPos) + { + Helper.Server.GetExistingSystem().SpawnUnit(empty_entity, + new PrefabGUID(1149585723), new float3(localPos.x, 0, localPos.z), countlocal, 1, 2, -1); + } + + internal static NativeArray GetHorses() + { + var horseQuery = Helper.Server.EntityManager.CreateEntityQuery(new EntityQueryDesc() + { + All = new[] + { + ComponentType.ReadWrite(), + ComponentType.ReadWrite(), + ComponentType.ReadWrite(), + ComponentType.ReadOnly(), + ComponentType.ReadOnly() + }, + None = new[] { ComponentType.ReadOnly(), ComponentType.ReadOnly() } + }); + + return horseQuery.ToEntityArray(Unity.Collections.Allocator.Temp); + } + + internal static Entity? GetClosetHorse(Entity e) + { + var horseEntityQuery = GetHorses(); + + + var origin = Helper.Server.EntityManager.GetComponentData(e).Position; + var closest = float.MaxValue; + + Entity? closestHorse = null; + foreach (var horse in horseEntityQuery) + { + var position = Helper.Server.EntityManager.GetComponentData(horse).Position; + var distance = UnityEngine.Vector3.Distance(origin, position); + if (distance < closest) + { + closest = distance; + closestHorse = horse; + } + } + + return closestHorse; + } + + internal static List ClosestHorses(Entity e, float radius = 5f) + { + var horses = GetHorses(); + var results = new List(); + var origin = Helper.Server.EntityManager.GetComponentData(e).Position; + + foreach (var horse in horses) + { + var position = Helper.Server.EntityManager.GetComponentData(horse).Position; + var distance = UnityEngine.Vector3.Distance(origin, position); // wait really? + if (distance < radius) + + { + results.Add(horse); + } + } + + return results; + } + + internal static void ModifyHorseAttributes(ChatCommandContext ctx, Entity horseEntity, float maxSpeed, float acceleration, float rotation) + { + var em = Helper.Server.EntityManager; + var mountableComponents = em.GetComponentDataFromEntity(true); + + if (mountableComponents.HasComponent(horseEntity)) + { + var mountable = mountableComponents[horseEntity]; + mountable.MaxSpeed = maxSpeed; + mountable.Acceleration = acceleration; + mountable.RotationSpeed = rotation * 10; + mountableComponents[horseEntity] = mountable; + } + } + + } +} \ No newline at end of file diff --git a/Utils/Item.cs b/Utils/Item.cs new file mode 100644 index 0000000..8b4872b --- /dev/null +++ b/Utils/Item.cs @@ -0,0 +1,12 @@ +namespace CommunityCommands.Commands; + +public class Item +{ + public string Name { get; set; } + public int Prefab { get; set; } + + public override string ToString() + { + return $"{{name: \"{Name}\", prefab: {Prefab}}}"; + } +} \ No newline at end of file diff --git a/Utils/VBloodUtils.cs b/Utils/VBloodUtils.cs new file mode 100644 index 0000000..bf61881 --- /dev/null +++ b/Utils/VBloodUtils.cs @@ -0,0 +1,147 @@ +using System; +using CommunityCommands.Commons; +using ProjectM; +using ProjectM.Network; +using ProjectM.UI; +using Unity.Entities; +using Unity.Mathematics; +using Unity.Transforms; +using VampireCommandFramework; + +namespace CommunityCommands.Utils; + +public class VBloodUtils +{ + private static readonly UnitSpawnerUpdateSystem UnitSpawnerSystem = Helper.Server.GetExistingSystem(); + public static void SpawnAllBoss(ChatCommandContext ctx, Entity playerEntity, int quantity) + { + if (Database.BossDatabase.Count == 0) + { + ctx.Reply("There is no boss in the database."); + return; + } + + var bossSpawnCount = 0; + + foreach (var boss in Database.BossDatabase) + { + SpawnBosses(ctx, playerEntity, boss.Value.Prefab, quantity); + bossSpawnCount++; + } + + ctx.Reply($"Spawned {bossSpawnCount} bosses next to {ctx.User.CharacterName}."); + } + + public static void SpawnSingleBoss(ChatCommandContext ctx, Entity playerEntity, string vBloodName, int quantity) + { + var bossPrefab = DatabaseUtils.GetUnitPrefabGUID(vBloodName); + if (bossPrefab.Equals(default(PrefabGUID))) + { + ctx.Reply($"VBlood with name {vBloodName} not found."); + return; + } + SpawnBosses(ctx, playerEntity, bossPrefab, quantity); + var spawnMessage = quantity == 1 + ? $"Spawned {DatabaseUtils.GetUnitDisplayName(bossPrefab)} next to {ctx.Event.User.CharacterName}." + : $"Spawned {quantity} {DatabaseUtils.GetUnitDisplayName(bossPrefab)} next {ctx.Event.User.CharacterName}."; + + ctx.Reply(spawnMessage); + } + + private static void SpawnBosses(ChatCommandContext ctx, Entity playerEntity, PrefabGUID bossPrefab, + int quantity) + { + var em = Helper.Server.EntityManager; + try + { + var playerPosition = em.GetComponentData(playerEntity).Position; + + if (UnitSpawnerSystem == null) + { + throw ctx.Error("Unit spawner system not found."); + } + + for (var i = 0; i < quantity; i++) + { + float3 spawnPosition = GetRandomSpawnPosition(playerPosition); + UnitSpawnerSystem.SpawnUnit(Entity.Null, bossPrefab, spawnPosition, 1, 1, 0f, 0f); + } + } + catch (Exception e) + { + throw ctx.Error($"An error occurred: {e.Message}"); + } + } + + private static float3 GetRandomSpawnPosition(float3 playerPosition) + { + var spawnRadius = 5f; + float2 randomOffset = UnityEngine.Random.insideUnitCircle * spawnRadius; + var spawnPosition = playerPosition + new float3(randomOffset.x, 0f, randomOffset.y); + return spawnPosition; + } + + public static Entity? GetClosestVBlood(Entity playerEntity) + { + var entityManager = Helper.Server.EntityManager; + + var origin = entityManager.GetComponentData(playerEntity).Value; + var closestDistance = float.MaxValue; + Entity? closestVBlood = null; + + var vBloodEntities = entityManager.GetAllEntities(); + foreach (var entity in vBloodEntities) + { + if (entity == playerEntity || !entityManager.HasComponent(entity)) + continue; + + // Vérifier si l'entité est un VBlood + if (entityManager.HasComponent(entity)) + { + var position = entityManager.GetComponentData(entity).Value; + var distance = math.distance(origin, position); + + if (distance < closestDistance) + { + closestDistance = distance; + closestVBlood = entity; + } + } + } + + return closestVBlood; + } + + public static Entity? GetVBloodByPrefabGUID(EntityManager entityManager, PrefabGUID prefabGUID) + { + var vBloodEntities = entityManager.GetAllEntities(); + + foreach (var entity in vBloodEntities) + { + // Vérifier si l'entité est un VBlood et correspond au PrefabGUID spécifié + if (entityManager.HasComponent(entity) && entityManager.HasComponent(entity)) + { + var entityPrefabGUID = entityManager.GetComponentData(entity); + + if (entityPrefabGUID.Equals(prefabGUID)) + { + return entity; + } + } + } + + return null; + } + + public static UnitStats GetUnitStats(EntityManager entityManager, Entity vBloodEntity) + { + if (entityManager.HasComponent(vBloodEntity)) + { + return entityManager.GetComponentData(vBloodEntity); + } + else + { + throw new InvalidOperationException("VBlood entity is missing UnitStats component."); + } + } +} \ No newline at end of file