Иконка ресурса

FREE LandClaim : 0.1.2 0.1.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
#define DEBUG

namespace Oxide.Plugins
{
    using System.Collections.Generic;
    using UnityEngine;
    //using Oxide.Plugins.LandClaimExtensionMethods;
    using System;
    using System.Linq;

    [Info("Land Claim", "SenZen", "0.1.2")]
    [Description("Allows Land Claim and Management")]
    public partial class LandClaim : RustPlugin
    {
        #region Configuration
        private const uint INITIAL_TEAM_ALLOWANCE = 2;
        private const bool REQUIRE_CONTIGUOUS = true;
        private MapGrid map = new MapGrid();
        #endregion

        #region Data
        private Hash<Vector2, ulong> parcelOwner = new Hash<Vector2, ulong>();
        private Hash<ulong, HashSet<Vector2>> teamParcels = new Hash<ulong, HashSet<Vector2>>();
        private Hash<ulong, uint> teamParcelAllowance = new Hash<ulong, uint>();
        #endregion

        private void Init()
        {
            // Initialize teamParcels
            teamParcels.Add(0, new HashSet<Vector2>());
            // Initialize Parcels
            for (uint x = 0; x < map.Width; x++)
            {
                for (uint z = 0; z < map.Height; z++)
                {
                    Vector2 parcel = new Vector2(x, z);
                    parcelOwner[parcel] = 0;
                    teamParcels[0].Add(parcel);
                }
            }
        }


        #region Command Handlers
        private bool TryClaimParcel(Vector2 parcel, BasePlayer player)
        {
            // Check invalid claims
            if (player.currentTeam == 0)
            {
                player.IPlayer.Reply("Must be in a Team to claim parcels.");
                return false;
            }
            if (teamParcelAllowance[player.currentTeam] < 1)
            {
                player.IPlayer.Reply("Your team has claimed the maximum number of parcels.");
                player.IPlayer.Reply("Use `/claim release` to unclaim a parcel.");
                return false;
            }
            if (parcelOwner[parcel] == player.currentTeam)
            {
                player.IPlayer.Reply("Your team already owns this parcel.");
                return false;
            }
            if (parcelOwner[parcel] > 0 && parcelOwner[parcel] != player.currentTeam)
            {
                player.IPlayer.Reply("Another team already owns this parcel.");
                return false;
            }
            if (REQUIRE_CONTIGUOUS && teamParcels[player.currentTeam].Count > 0)
            {
                bool isContiguous = false;
                foreach (Vector2 parcelToCheckAgainst in teamParcels[player.currentTeam].ToList())
                {
                    float deltaX = Mathf.Abs(parcelToCheckAgainst.x - parcel.x);
                    float deltaY = Mathf.Abs(parcelToCheckAgainst.y - parcel.y);
                    isContiguous = (
                        deltaX < 2 &&
                        deltaY < 2 &&
                        deltaX + deltaY == 1
                    );
                    if (isContiguous)
                    {
                        break;
                    }
                }
                if (!isContiguous)
                {
                    player.IPlayer.Reply("Must be adjacent to another parcel your team owns.");
                    return false;
                }
            }
            // Claim parcel for player's team
            parcelOwner[parcel] = player.currentTeam;
            teamParcels[player.currentTeam].Add(parcel);
            teamParcelAllowance[player.currentTeam] -= 1;
            player.IPlayer.Reply("Parcel successfully claimed!");
            player.IPlayer.Reply($"Your team may claim {teamParcelAllowance[player.currentTeam]} more parcels.");
            return true;
        }

        private bool TryReleaseParcel(Vector2 parcel, BasePlayer player)
        {
            if (player.currentTeam == 0)
            {
                player.IPlayer.Reply("Must be in a Team to claim parcels.");
                return false;
            }
            if (parcelOwner[parcel] == 0)
            {
                player.IPlayer.Reply("This parcel is unclaimed.");
                if (teamParcelAllowance[player.currentTeam] > 0)
                {
                    player.IPlayer.Reply("Use `/claim here` to claim this parcel.");
                }
                return false;
            }
            if (parcelOwner[parcel] > 0 && parcelOwner[parcel] != player.currentTeam)
            {
                player.IPlayer.Reply("Your team does not own this parcel.");
                return false;
            }
            // Release parcel for player's team
            parcelOwner[parcel] = 0;
            teamParcels[player.currentTeam].Remove(parcel);
            teamParcelAllowance[player.currentTeam] += 1;
            if (teamParcelAllowance[player.currentTeam] > INITIAL_TEAM_ALLOWANCE)
            {
                teamParcelAllowance[player.currentTeam] = INITIAL_TEAM_ALLOWANCE;
            }
            player.IPlayer.Reply("Parcel successfully released!");
            player.IPlayer.Reply($"Your team may claim {teamParcelAllowance[player.currentTeam]} more parcels.");
            return true;
        }

        private void ListTeamParcels(BasePlayer player)
        {
            if (player.currentTeam == 0)
            {
                player.IPlayer.Reply("Must be in a Team to claim parcels.");
                return;
            }
            if (teamParcels[player.currentTeam].Count == 0)
            {
                player.IPlayer.Reply("Your team does not own any parcels.");
                return;
            }
            // Iterate over team's parcels
            player.IPlayer.Reply("Your team owns the following parcels:");
            List<string> parcels = new List<string>();
            foreach (Vector2 parcel in teamParcels[player.currentTeam])
            {
                parcels.Add(map.ParcelID(parcel));
            }
            player.IPlayer.Reply(String.Join(", ", parcels.ToArray()));
        }

        private void DrawParcelCube(BasePlayer player, Vector2 parcel)
        {
            Vector3 origin = map.ParcelToWorldSpace(parcel);
            float time = 10f;
            float height = 100f;

            Vector3 point1 = origin;
            Vector3 point2 = new Vector3(origin.x + MapGrid.GRID_CELL_SIZE, origin.y, origin.z);
            Vector3 point3 = new Vector3(origin.x + MapGrid.GRID_CELL_SIZE, origin.y, origin.z + MapGrid.GRID_CELL_SIZE);
            Vector3 point4 = new Vector3(origin.x, origin.y, origin.z + MapGrid.GRID_CELL_SIZE);

            Vector3 point5 = new Vector3(origin.x, origin.y + height, origin.z);
            Vector3 point6 = new Vector3(origin.x + MapGrid.GRID_CELL_SIZE, origin.y + height, origin.z);
            Vector3 point7 = new Vector3(origin.x + MapGrid.GRID_CELL_SIZE, origin.y + height, origin.z + MapGrid.GRID_CELL_SIZE);
            Vector3 point8 = new Vector3(origin.x, origin.y + height, origin.z + MapGrid.GRID_CELL_SIZE);

            player.SendConsoleCommand("ddraw.line", time, Color.green, point1, point2);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point2, point3);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point3, point4);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point4, point1);

            player.SendConsoleCommand("ddraw.line", time, Color.green, point1, point5);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point2, point6);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point3, point7);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point4, point8);

            player.SendConsoleCommand("ddraw.line", time, Color.green, point5, point6);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point6, point7);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point7, point8);
            player.SendConsoleCommand("ddraw.line", time, Color.green, point8, point5);
        }

        private void DrawTeamParcels(BasePlayer player)
        {
            foreach (Vector2 parcel in teamParcels[player.currentTeam].ToList())
            {
                DrawParcelCube(player, parcel);
            }
        }
        #endregion

        #region Hooks
        object OnPlayerCommand(BasePlayer player, string command, string[] args)
        {
            object returnValue = null;

            if (player == null) return null;
            if (command != "claim") return null;

            Vector2 parcel = map.ParcelForCoordinates(player.transform.position);
            string action = args.Length == 0 ? "here" : args[0];
            switch (action)
            {
                case "here":
                    Puts("Claiming Parcel");
                    TryClaimParcel(parcel, player);
                    returnValue = 1;
                    break;

                case "release":
                    Puts("Releasing Parcel");
                    TryReleaseParcel(parcel, player);
                    returnValue = 1;
                    break;

                case "list":
                    Puts("Listing Team Claims");
                    ListTeamParcels(player);
                    returnValue = 1;
                    break;

                case "show":
                    Puts("Showing Team Claims");
                    DrawTeamParcels(player);
                    returnValue = 1;
                    break;

                default:
                    returnValue = null;
                    break;
            }

            return returnValue;
        }

        object CanBuild(Planner planner, Construction prefab, Construction.Target target)
        {
            BasePlayer player = planner.GetOwnerPlayer();
            Vector2 parcel = map.ParcelForCoordinates(player.transform.position);
            // Check if part of a team
            if (player.currentTeam == 0)
            {
                player.IPlayer.Reply("Must be in a team to claim parcels and build.");
                return false;
            }
            // Check if team owns parcel
            if (parcelOwner[parcel] != player.currentTeam)
            {
                player.IPlayer.Reply("Your team does not own this parcel.");
                return false;
            }
            return null;
        }

        object OnTeamCreated(BasePlayer player)
        {
            teamParcels[player.currentTeam] = new HashSet<Vector2>();
            teamParcelAllowance[player.currentTeam] = INITIAL_TEAM_ALLOWANCE;
            player.IPlayer.Reply($"Your new team may claim up to {teamParcelAllowance[player.currentTeam]} parcels");
            return null;
        }

        void OnTeamDisbanded(RelationshipManager.PlayerTeam team)
        {
            teamParcelAllowance[team.teamID] = 0;
            if (teamParcels[team.teamID] != null)
            {
                teamParcels[team.teamID].Clear();
            }
        }
        #endregion
    }
}


namespace Oxide.Plugins
{
    using System;
    using System.Text.RegularExpressions;
    using UnityEngine;

    public class MapGrid
    {
        // Rust doesn't consistently calculate width/height for maps so
        // we have to manually specify the number of rows...private const uint GRID_ROWS = 30;
        public static readonly float GRID_CELL_SIZE = 146.3f;
        public float Size { get; private set; }
        public float Width { get; private set; }
        public float Height { get; private set; }
        public float Origin { get; private set; }
        public float Offset { get; private set; }


        public MapGrid()
        {
            Size = TerrainMeta.Size.x;
            Offset = TerrainMeta.Size.x / 2;
            Width = Mathf.Ceil(TerrainMeta.Size.x / GRID_CELL_SIZE);
            Height = Mathf.Ceil(TerrainMeta.Size.z / GRID_CELL_SIZE);
        }

        public Vector2 ParcelForCoordinates(Vector3 coordinates)
        {
            Vector3 normalizationOffset = new Vector3(Offset, 0, Offset);
            Vector3 normalizedCoordinates = coordinates + normalizationOffset;
            Vector2 cell = new Vector2(
                Mathf.Floor(normalizedCoordinates.x / GRID_CELL_SIZE),
                Mathf.Floor(normalizedCoordinates.z / GRID_CELL_SIZE)
            );
            return cell;
        }

        public Vector3 ParcelToWorldSpace(Vector2 parcel)
        {
            Vector3 worldSpace = new Vector3(
                (parcel.x * GRID_CELL_SIZE) - Offset,
                0,
                (parcel.y * GRID_CELL_SIZE) - Offset
            );
            Console.WriteLine($"Parcel: {parcel}\nWorldSpace: {worldSpace}");
            return worldSpace;
        }

        public string ParcelID(Vector2 parcel)
        {
            // Calculate Alpha
            const string ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string parcelAlpha = "";
            int x = (int)parcel.x;

             while (x >= 0)
            {
                int index = x % 26;
                char character = ALPHABET[index];
                parcelAlpha = character + parcelAlpha;
                if (x < 26) break;
                x = (x - index) / 26 - 1;
            }

            uint parcelNum = GRID_ROWS - (uint)parcel.y - 1;
            string parcelAlphaNum = $"{parcelAlpha}{parcelNum}";
            return parcelAlphaNum;
        }
    }
}


//namespace Oxide.Plugins.LandClaimExtensionMethods
//{
//    public static class ExtensionMethods
//    {
//    }
//}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху