craztheking

Untitled

Aug 23rd, 2025
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.91 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using Newtonsoft.Json;
  5. using UnityEngine;
  6.  
  7. public class SafeZone
  8. {
  9. public string Name;
  10. public Vector3 Position;
  11. public float Radius;
  12. public bool BlockProtection;
  13. public bool PvpProtection;
  14. public Messages Messages;
  15. }
  16.  
  17. public class Messages
  18. {
  19. public string Enter;
  20. public string Exit;
  21. }
  22.  
  23. public class TraderOverride
  24. {
  25. public string Name;
  26. public float? Radius;
  27. public Messages Messages;
  28. }
  29.  
  30. public class TraderSafeZoneConfig
  31. {
  32. public float DefaultRadius = 200f;
  33. public bool BlockProtection = true;
  34. public bool PvpProtection = true;
  35. public Messages Messages = new Messages { Enter = "You have entered a safezone.", Exit = "You have left the safezone." };
  36. public List<TraderOverride> TraderOverrides = new List<TraderOverride>();
  37. public List<SafeZone> CustomSafeZones = new List<SafeZone>();
  38. }
  39.  
  40. public class TraderSafeZonesMod : IModApi
  41. {
  42. private static List<SafeZone> safeZones = new List<SafeZone>();
  43. private static Dictionary<int, string> playerZones = new Dictionary<int, string>();
  44. private static TraderSafeZoneConfig config;
  45. private static string configPath = Path.Combine(GamePrefs.GetString(EnumGamePrefs.SaveGameFolder), "TraderSafeZones", "Config", "trader_safezones.json");
  46.  
  47. public void InitMod(Mod mod)
  48. {
  49. LoadConfigAndZones();
  50.  
  51. ModEvents.PlayerMove.RegisterHandler(OnPlayerMove);
  52. ModEvents.PlayerDamage.RegisterHandler(OnPlayerDamage);
  53. ModEvents.PlayerPlaceBlock.RegisterHandler(OnBlockPlace);
  54. ModEvents.PlayerRemoveBlock.RegisterHandler(OnBlockRemove);
  55.  
  56. // Register admin command for reloading config
  57. ModEvents.ServerCommand.RegisterHandler(OnServerCommand);
  58. }
  59.  
  60. private static void LoadConfigAndZones()
  61. {
  62. if (!File.Exists(configPath))
  63. {
  64. Directory.CreateDirectory(Path.GetDirectoryName(configPath));
  65. var defaultJson = JsonConvert.SerializeObject(new TraderSafeZoneConfig(), Formatting.Indented);
  66. File.WriteAllText(configPath, defaultJson);
  67. }
  68.  
  69. config = JsonConvert.DeserializeObject<TraderSafeZoneConfig>(File.ReadAllText(configPath));
  70. safeZones.Clear();
  71.  
  72. // Load trader POIs automatically
  73. foreach (var poi in GameManager.Instance.World.GetPOIManager().list)
  74. {
  75. if (!poi.name.ToLower().Contains("trader")) continue;
  76.  
  77. float radius = config.DefaultRadius;
  78. Messages messages = config.Messages;
  79.  
  80. var overrideData = config.TraderOverrides.Find(o => o.Name.Equals(poi.name, StringComparison.OrdinalIgnoreCase));
  81. if (overrideData != null)
  82. {
  83. if (overrideData.Radius.HasValue) radius = overrideData.Radius.Value;
  84. if (overrideData.Messages != null) messages = overrideData.Messages;
  85. }
  86.  
  87. safeZones.Add(new SafeZone
  88. {
  89. Name = poi.name,
  90. Position = poi.boundingBoxPosition,
  91. Radius = radius,
  92. BlockProtection = config.BlockProtection,
  93. PvpProtection = config.PvpProtection,
  94. Messages = messages
  95. });
  96. }
  97.  
  98. // Load custom safezones from config
  99. if (config.CustomSafeZones != null)
  100. {
  101. safeZones.AddRange(config.CustomSafeZones);
  102. }
  103.  
  104. Log.Out($"[TraderSafeZones] Loaded {safeZones.Count} safezones.");
  105. }
  106.  
  107. private static void OnServerCommand(ClientInfo cInfo, string command, string[] args)
  108. {
  109. if (!command.Equals("/reloadsafezones", StringComparison.OrdinalIgnoreCase)) return;
  110.  
  111. if (!GameManager.Instance.AdminTools.IsPlayerAdmin(cInfo))
  112. {
  113. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, "You are not an admin.", "FF0000", true));
  114. return;
  115. }
  116.  
  117. LoadConfigAndZones();
  118. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, "TraderSafeZones config reloaded.", "00FF00", true));
  119. }
  120.  
  121. private static void OnPlayerMove(ClientInfo cInfo, Vector3 newPos)
  122. {
  123. foreach (var zone in safeZones)
  124. {
  125. bool inside = Vector3.Distance(newPos, zone.Position) <= zone.Radius;
  126. bool wasInside = playerZones.ContainsKey(cInfo.entityId) && playerZones[cInfo.entityId] == zone.Name;
  127.  
  128. if (inside && !wasInside)
  129. {
  130. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, zone.Messages.Enter, "00FF00", true));
  131. playerZones[cInfo.entityId] = zone.Name;
  132. }
  133. else if (!inside && wasInside)
  134. {
  135. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, zone.Messages.Exit, "FF0000", true));
  136. playerZones.Remove(cInfo.entityId);
  137. }
  138. }
  139. }
  140.  
  141. private static bool OnPlayerDamage(EntityAlive attacker, EntityAlive victim, DamageSource source, int dmg, bool critHit, bool bBlockDamage)
  142. {
  143. if (attacker == null || victim == null) return true;
  144.  
  145. Vector3 posAttacker = attacker.position;
  146. Vector3 posVictim = victim.position;
  147.  
  148. foreach (var zone in safeZones)
  149. {
  150. bool attackerInZone = Vector3.Distance(posAttacker, zone.Position) <= zone.Radius;
  151. bool victimInZone = Vector3.Distance(posVictim, zone.Position) <= zone.Radius;
  152.  
  153. if (zone.PvpProtection && (attackerInZone || victimInZone))
  154. {
  155. attacker.ChatMessage($"PvP is disabled in safezones!");
  156. return false;
  157. }
  158. }
  159.  
  160. return true;
  161. }
  162.  
  163. private static bool OnBlockPlace(ClientInfo cInfo, Block block, Vector3i pos)
  164. {
  165. foreach (var zone in safeZones)
  166. {
  167. if (zone.BlockProtection && Vector3.Distance(pos.ToVector3(), zone.Position) <= zone.Radius)
  168. {
  169. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, $"You cannot place blocks in a safezone!", "FF0000", true));
  170. return false;
  171. }
  172. }
  173. return true;
  174. }
  175.  
  176. private static bool OnBlockRemove(ClientInfo cInfo, Block block, Vector3i pos)
  177. {
  178. foreach (var zone in safeZones)
  179. {
  180. if (zone.BlockProtection && Vector3.Distance(pos.ToVector3(), zone.Position) <= zone.Radius)
  181. {
  182. cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, $"You cannot remove blocks in a safezone!", "FF0000", true));
  183. return false;
  184. }
  185. }
  186. return true;
  187. }
  188. }
Advertisement
Add Comment
Please, Sign In to add comment