Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- using Newtonsoft.Json;
- using UnityEngine;
- public class SafeZone
- {
- public string Name;
- public Vector3 Position;
- public float Radius;
- public bool BlockProtection;
- public bool PvpProtection;
- public Messages Messages;
- }
- public class Messages
- {
- public string Enter;
- public string Exit;
- }
- public class TraderOverride
- {
- public string Name;
- public float? Radius;
- public Messages Messages;
- }
- public class TraderSafeZoneConfig
- {
- public float DefaultRadius = 200f;
- public bool BlockProtection = true;
- public bool PvpProtection = true;
- public Messages Messages = new Messages { Enter = "You have entered a safezone.", Exit = "You have left the safezone." };
- public List<TraderOverride> TraderOverrides = new List<TraderOverride>();
- public List<SafeZone> CustomSafeZones = new List<SafeZone>();
- }
- public class TraderSafeZonesMod : IModApi
- {
- private static List<SafeZone> safeZones = new List<SafeZone>();
- private static Dictionary<int, string> playerZones = new Dictionary<int, string>();
- private static TraderSafeZoneConfig config;
- private static string configPath = Path.Combine(GamePrefs.GetString(EnumGamePrefs.SaveGameFolder), "TraderSafeZones", "Config", "trader_safezones.json");
- public void InitMod(Mod mod)
- {
- LoadConfigAndZones();
- ModEvents.PlayerMove.RegisterHandler(OnPlayerMove);
- ModEvents.PlayerDamage.RegisterHandler(OnPlayerDamage);
- ModEvents.PlayerPlaceBlock.RegisterHandler(OnBlockPlace);
- ModEvents.PlayerRemoveBlock.RegisterHandler(OnBlockRemove);
- // Register admin command for reloading config
- ModEvents.ServerCommand.RegisterHandler(OnServerCommand);
- }
- private static void LoadConfigAndZones()
- {
- if (!File.Exists(configPath))
- {
- Directory.CreateDirectory(Path.GetDirectoryName(configPath));
- var defaultJson = JsonConvert.SerializeObject(new TraderSafeZoneConfig(), Formatting.Indented);
- File.WriteAllText(configPath, defaultJson);
- }
- config = JsonConvert.DeserializeObject<TraderSafeZoneConfig>(File.ReadAllText(configPath));
- safeZones.Clear();
- // Load trader POIs automatically
- foreach (var poi in GameManager.Instance.World.GetPOIManager().list)
- {
- if (!poi.name.ToLower().Contains("trader")) continue;
- float radius = config.DefaultRadius;
- Messages messages = config.Messages;
- var overrideData = config.TraderOverrides.Find(o => o.Name.Equals(poi.name, StringComparison.OrdinalIgnoreCase));
- if (overrideData != null)
- {
- if (overrideData.Radius.HasValue) radius = overrideData.Radius.Value;
- if (overrideData.Messages != null) messages = overrideData.Messages;
- }
- safeZones.Add(new SafeZone
- {
- Name = poi.name,
- Position = poi.boundingBoxPosition,
- Radius = radius,
- BlockProtection = config.BlockProtection,
- PvpProtection = config.PvpProtection,
- Messages = messages
- });
- }
- // Load custom safezones from config
- if (config.CustomSafeZones != null)
- {
- safeZones.AddRange(config.CustomSafeZones);
- }
- Log.Out($"[TraderSafeZones] Loaded {safeZones.Count} safezones.");
- }
- private static void OnServerCommand(ClientInfo cInfo, string command, string[] args)
- {
- if (!command.Equals("/reloadsafezones", StringComparison.OrdinalIgnoreCase)) return;
- if (!GameManager.Instance.AdminTools.IsPlayerAdmin(cInfo))
- {
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, "You are not an admin.", "FF0000", true));
- return;
- }
- LoadConfigAndZones();
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, "TraderSafeZones config reloaded.", "00FF00", true));
- }
- private static void OnPlayerMove(ClientInfo cInfo, Vector3 newPos)
- {
- foreach (var zone in safeZones)
- {
- bool inside = Vector3.Distance(newPos, zone.Position) <= zone.Radius;
- bool wasInside = playerZones.ContainsKey(cInfo.entityId) && playerZones[cInfo.entityId] == zone.Name;
- if (inside && !wasInside)
- {
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, zone.Messages.Enter, "00FF00", true));
- playerZones[cInfo.entityId] = zone.Name;
- }
- else if (!inside && wasInside)
- {
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, zone.Messages.Exit, "FF0000", true));
- playerZones.Remove(cInfo.entityId);
- }
- }
- }
- private static bool OnPlayerDamage(EntityAlive attacker, EntityAlive victim, DamageSource source, int dmg, bool critHit, bool bBlockDamage)
- {
- if (attacker == null || victim == null) return true;
- Vector3 posAttacker = attacker.position;
- Vector3 posVictim = victim.position;
- foreach (var zone in safeZones)
- {
- bool attackerInZone = Vector3.Distance(posAttacker, zone.Position) <= zone.Radius;
- bool victimInZone = Vector3.Distance(posVictim, zone.Position) <= zone.Radius;
- if (zone.PvpProtection && (attackerInZone || victimInZone))
- {
- attacker.ChatMessage($"PvP is disabled in safezones!");
- return false;
- }
- }
- return true;
- }
- private static bool OnBlockPlace(ClientInfo cInfo, Block block, Vector3i pos)
- {
- foreach (var zone in safeZones)
- {
- if (zone.BlockProtection && Vector3.Distance(pos.ToVector3(), zone.Position) <= zone.Radius)
- {
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, $"You cannot place blocks in a safezone!", "FF0000", true));
- return false;
- }
- }
- return true;
- }
- private static bool OnBlockRemove(ClientInfo cInfo, Block block, Vector3i pos)
- {
- foreach (var zone in safeZones)
- {
- if (zone.BlockProtection && Vector3.Distance(pos.ToVector3(), zone.Position) <= zone.Radius)
- {
- cInfo.SendPackage(NetPackageManager.GetPackage<NetPackageGameMessage>().Setup(EnumGameMessages.Chat, $"You cannot remove blocks in a safezone!", "FF0000", true));
- return false;
- }
- }
- return true;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment