C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using System;
using Oxide.Core;
using System.Collections;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
namespace Oxide.Plugins {
[Info("Personal Builder", "walkinrey & Max39ru", "1.0.8")]
public class PersonalBuilder : RustPlugin {
[PluginReference]
private Plugin ZoneManager;
private Dictionary<ulong, PlayerBuilderController> _controllersByOwner = new Dictionary<ulong, PlayerBuilderController>();
private Dictionary<ulong, PlayerBuilderController> _controllersByBot = new Dictionary<ulong, PlayerBuilderController>();
//nullHit.HitPositionWorld, 1f, 97185f);
private Dictionary<ulong, DateTime> _cooldownInfo = new Dictionary<ulong, DateTime>();
private Configuration _config;
private List<string> _permissionKeys = new List<string>();
public PlayerBuilderController GetControllerByBot(ulong id) {
if(_controllersByBot.ContainsKey(id)) {
var controller = _controllersByBot[id];
if(controller == null) _controllersByBot.Remove(id);
else return controller;
}
return null;
}
public PlayerBuilderController GetControllerByOwner(ulong id) {
if(_controllersByOwner.ContainsKey(id)) {
var controller = _controllersByOwner[id];
if(controller == null) _controllersByOwner.Remove(id);
else return controller;
}
return null;
}
public readonly BuildCostInfo buildCostInfo = new BuildCostInfo();
public const int WoodItemID = -151838493, StoneItemID = -2099697608, MetalItemID = 69511070, HQMItemID = 317398316, GearsItemID = 479143914;
public class BuildCostInfo : Dictionary<string, ResourcesFromBuild> {
public BuildCostInfo() {
Add("assets/prefabs/building core/foundation.triangle/foundation.triangle.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/foundation/foundation.prefab", new ResourcesFromBuild(50, 0, 0, 0, 0, 200, 300, 200, 25));
Add("assets/prefabs/building core/foundation.steps/foundation.steps.prefab", new ResourcesFromBuild(50, 0, 0, 0, 0, 200, 300, 200, 25));
Add("assets/prefabs/building core/floor.triangle/floor.triangle.prefab", new ResourcesFromBuild(13, 0, 0, 0, 0, 50, 75, 50, 7));
Add("assets/prefabs/building core/floor/floor.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/roof/roof.prefab", new ResourcesFromBuild(50, 0, 0, 0, 0, 200, 300, 200, 25));
Add("assets/prefabs/building core/ramp/ramp.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/wall/wall.prefab", new ResourcesFromBuild(50, 0, 0, 0, 0, 200, 300, 200, 25));
Add("assets/prefabs/building core/wall.half/wall.half.prefab", new ResourcesFromBuild(50, 0, 0, 0, 0, 200, 300, 200, 25));
Add("assets/prefabs/building core/wall.low/wall.low.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/wall.frame/wall.frame.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/wall.window/wall.window.prefab", new ResourcesFromBuild(35, 0, 0, 0, 0, 140, 210, 140, 18));
Add("assets/prefabs/building core/wall.doorway/wall.doorway.prefab", new ResourcesFromBuild(35, 0, 0, 0, 0, 140, 210, 140, 18));
Add("assets/prefabs/building core/stairs.spiral.triangle/block.stair.spiral.triangle.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/stairs.spiral/block.stair.spiral.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/stairs.l/block.stair.lshape.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building core/stairs.u/block.stair.ushape.prefab", new ResourcesFromBuild(25, 0, 0, 0, 0, 100, 150, 100, 13));
Add("assets/prefabs/building/door.hinged/door.hinged.wood.prefab", new ResourcesFromBuild(300, 0, 0, 0, 0));
Add("assets/prefabs/building/door.double.hinged/door.double.hinged.wood.prefab", new ResourcesFromBuild(350, 0, 0, 0, 0));
Add("assets/prefabs/building/door.hinged/door.hinged.metal.prefab", new ResourcesFromBuild(0, 0, 150, 0, 0));
Add("assets/prefabs/building/door.double.hinged/door.double.hinged.metal.prefab", new ResourcesFromBuild(0, 0, 200, 0, 0));
Add("assets/prefabs/building/door.hinged/door.hinged.toptier.prefab", new ResourcesFromBuild(0, 0, 0, 20, 5));
Add("assets/prefabs/building/door.double.hinged/door.double.hinged.toptier.prefab", new ResourcesFromBuild(0, 0, 0, 25, 5));
Add("assets/prefabs/deployable/tool cupboard/cupboard.tool.deployed.prefab", new ResourcesFromBuild(1000, 0, 0, 0, 0));
Add("assets/prefabs/deployable/tool cupboard/retro/cupboard.tool.retro.deployed.prefab", new ResourcesFromBuild(1000, 0, 0, 0, 0));
}
public ResourcesFromBuild GetResources(string prefab) {
TryGetValue(prefab, out var resources);
return resources;
}
}
public class ResourcesFromBuild {
public int Wood, Stone, Metal, HQM, Gears;
private Dictionary<BuildingGrade.Enum, int> gradeResources;
private ResourcesFromBuild(int wood, int stone, int metal, int hQM, int gears) {
Wood = wood;
Stone = stone;
Metal = metal;
HQM = hQM;
Gears = gears;
gradeResources = new Dictionary<BuildingGrade.Enum, int>();
}
public ResourcesFromBuild(int wood, int stone, int metal, int hQM, int gears, int grade_wood = 0, int grade_stone = 0, int grade_metal= 0, int grade_top = 0) : this(wood, stone, metal, hQM, gears) {
if(grade_wood == 0 && grade_stone == 0 && grade_metal == 0 && grade_top == 0) return;
gradeResources.Add(BuildingGrade.Enum.Wood, grade_wood);
gradeResources.Add(BuildingGrade.Enum.Stone, grade_stone);
gradeResources.Add(BuildingGrade.Enum.Metal, grade_metal);
gradeResources.Add(BuildingGrade.Enum.TopTier, grade_top);
}
public ResourcesFromBuild() {
gradeResources = new Dictionary<BuildingGrade.Enum, int>();
}
public void Add(ResourcesFromBuild resources, BuildingGrade.Enum? grade) {
if(resources == null) return;
Wood += resources.Wood;
Stone += resources.Stone;
Metal += resources.Metal;
HQM += resources.HQM;
Gears += resources.Gears;
int value = 0;
if(grade != null && resources.gradeResources != null && resources.gradeResources.TryGetValue((BuildingGrade.Enum)grade, out value)) {
switch((BuildingGrade.Enum)grade) {
case BuildingGrade.Enum.Wood : Wood += value;
break;
case BuildingGrade.Enum.Stone : Stone += value;
break;
case BuildingGrade.Enum.Metal : Metal += value;
break;
case BuildingGrade.Enum.TopTier : HQM += value;
break;
default : break;
}
}
}
public void AddNew(ResourcesFromBuild resources, BuildingGrade.Enum? grade) {
Clear();
Add(resources, grade);
}
public void Clear() {
Wood = 0;
Stone = 0;
Metal = 0;
HQM = 0;
Gears = 0;
gradeResources.Clear();
}
public void AddNew(int wood, int stone, int metal, int hQM, int gears) {
Clear();
Wood = wood;
Stone = stone;
Metal = metal;
HQM = hQM;
Gears = gears;
}
internal void SubtractionResourcesFromPlayer(PlayerInventory inventory, ResourcesFromBuild currentSubtractionResources) {
currentSubtractionResources.Clear();
if(inventory == null) return;
int wood = 0, stone = 0, metal = 0, hQM = 0, gears = 0;
if(Wood > 0) {
wood = inventory.Take(null, WoodItemID, Wood);
Wood -= wood;
}
if(Stone > 0) {
stone = inventory.Take(null, StoneItemID, Stone);
Stone -= stone;
}
if(Metal > 0) {
metal = inventory.Take(null, MetalItemID, Metal);
Metal -= metal;
}
if(HQM > 0) {
hQM = inventory.Take(null, HQMItemID, HQM);
HQM -= hQM;
}
if(Gears > 0) {
gears = inventory.Take(null, GearsItemID, Gears);
Gears -= gears;
}
currentSubtractionResources.AddNew(wood, stone, metal, hQM, gears);
}
public void GetResources(PlayerInventory inventoryOwner, ItemContainer containerBot) {
int value;
if(Wood > 0) value = inventoryOwner.Take(null, WoodItemID, Wood);
else value = 0;
if(value > 0) SetItem(WoodItemID, value, containerBot);
if(Stone > 0) value = inventoryOwner.Take(null, StoneItemID, Stone);
else value = 0;
if(value > 0) SetItem(StoneItemID, value, containerBot);
if(Metal > 0) value = inventoryOwner.Take(null, MetalItemID, Metal);
else value = 0;
if(value > 0) SetItem(MetalItemID, value, containerBot);
if(HQM > 0) value = inventoryOwner.Take(null, HQMItemID, HQM);
else value = 0;
if(value > 0) SetItem(HQMItemID, value, containerBot);
if(Gears > 0) value = inventoryOwner.Take(null, GearsItemID, Gears);
else value = 0;
if(value > 0) SetItem(GearsItemID, value, containerBot);
}
private void SetItem(int idItem, int amount, ItemContainer container) {
ItemManager.CreateByItemID(idItem, amount)?.MoveToContainer(container);
}
internal void Subtraction(ResourcesFromBuild currentSubtractionResources) {
Wood -= currentSubtractionResources.Wood;
Stone -= currentSubtractionResources.Stone;
Metal -= currentSubtractionResources.Metal;
HQM -= currentSubtractionResources.HQM;
Gears -= currentSubtractionResources.Gears;
}
public string ToString(PlayerInventory inventory, PersonalBuilder plugin, string userID) {
if(inventory == null) return "";
string text = "";
string color = "";
int num;
if(Wood > 0) {
num = inventory.GetAmount(WoodItemID);
color = num >= Wood ? "green" : "red";
text += $"\n{plugin.GetMsg("Resource_Wood", userID)}: {Wood}/<color={color}>{num}</color>";
}
if(Stone > 0) {
num = inventory.GetAmount(StoneItemID);
color = num >= Stone ? "green" : "red";
text += $"\n{plugin.GetMsg("Resource_Stone", userID)}: {Stone}/<color={color}>{num}</color>";
}
if(Metal > 0) {
num = inventory.GetAmount(MetalItemID);
color = num >= Metal ? "green" : "red";
text += $"\n{plugin.GetMsg("Resource_MetalFragment", userID)}: {Metal}/<color={color}>{num}</color>";
}
if(HQM > 0) {
num = inventory.GetAmount(HQMItemID);
color = num >= HQM ? "green" : "red";
text += $"\n{plugin.GetMsg("Resource_HQM", userID)}: {HQM}/<color={color}>{num}</color>";
}
if(Gears > 0) {
num = inventory.GetAmount(GearsItemID);
color = num >= Gears ? "green" : "red";
text += $"\n{plugin.GetMsg("Resource_Gears", userID)}: {Gears}/<color={color}>{num}</color>";
}
return text;
}
public bool CanBuild() => Wood == 0 && Stone == 0 && Metal == 0 && HQM == 0 && Gears == 0;
}
#region Config
public class Configuration {
[JsonProperty("Controls")]
public ControlsSetup Controls = new ControlsSetup();
[JsonProperty("Build Limitations")]
public GlobalLimitationsSetup Limitations = new GlobalLimitationsSetup();
[JsonProperty("Permissions")]
public Dictionary<string, List<BotSetup>> permissionBot = new Dictionary<string, List<BotSetup>>();
[JsonProperty("Builder install by item")]
public List<ItemInfo> installItem = new List<ItemInfo>();
public struct ItemInfo {
[JsonProperty("Item name")]
public string name;
[JsonProperty("Item shortname")]
public string shortname;
[JsonProperty("Item skin")]
public ulong skin;
[JsonProperty("Return item on bot despawn?")]
public bool returnItem;
[JsonProperty("Bot info")]
public BotSetup bot;
}
public class ControlsSetup {
[JsonIgnore]
public BUTTON controlButton = BUTTON.FIRE_THIRD;
[JsonProperty("Button to assign build position (MIDDLE_MOUSE, SECOND_MOUSE, E, RELOAD, SPRINT)")]
public string mainControlButton = "MIDDLE_MOUSE";
[JsonProperty("Range of the task assignment button")]
public float rayLength = 25f;
[JsonProperty("Display 3D arrows over a build position?")]
public bool enableArrowView = true;
[JsonProperty("Arrow display duration")]
public int arrowViewDuration = 2;
[JsonProperty("Block bot spawn in safezones")]
public bool blockBotSpawnSafezone = false;
[JsonProperty("Block bot spawn in ZoneManager zones (enter zone id belove)")]
public List<string> blockBotZoneManager = new List<string>();
}
public class GlobalLimitationsSetup {
[JsonProperty("Clear limitations data on server wipe?")]
public bool clearLimitsOnWipe = true;
[JsonProperty("Clear limitations data on permission revoke?")]
public bool clearLimitsOnRevoke = true;
}
public class BotSetup {
[JsonProperty("The name of the bot to be selected through the command when spawning")]
public string spawnName = "bot1";
[JsonProperty("Bot spawn delay")]
public float cooldown = 300f;
[JsonProperty("CopyPaste file name")]
public string filename = "";
[JsonProperty("Player (bot)")]
public PlayerSetup player = new PlayerSetup();
[JsonProperty("Resources")]
public ResourcesSetup resources = new ResourcesSetup();
[JsonProperty("Speed")]
public SpeedSetup speed = new SpeedSetup();
[JsonProperty("Build")]
public BuildSetup build = new BuildSetup();
[JsonProperty("Effects")]
public EffectsSetup effects = new EffectsSetup();
[JsonProperty("Limitations")]
public LimitationsSetup limitations = new LimitationsSetup();
[JsonProperty("Clothes")]
public List<ItemSetup> startKit = new List<ItemSetup>();
public class LimitationsSetup {
[JsonProperty("Enable limit on number of buildings that can be built? (linked to player, doesn't apply to everyone)")]
public bool enableLimits = false;
[JsonProperty("How many bases can this bot build?")]
public int times = 5;
}
public class PlayerSetup {
[JsonProperty("Bot display name")]
public string displayName = "";
[JsonProperty("Bot health")]
public float health = 1000f;
[JsonProperty("Make bot immortal?")]
public bool isImmortal = false;
[JsonProperty("Lock wear (attire) container?")]
public bool lockWearContainer = true;
[JsonProperty("Lock belt container?")]
public bool lockBeltContainer = true;
}
public class EffectsSetup {
[JsonProperty("Enable effects on appear & disappear?")]
public bool enableSpawnEffects = true;
[JsonProperty("Enable building block upgrade effects?")]
public bool enableUpgradeEffects = true;
}
public class ResourcesSetup {
[JsonProperty("Require resources?")]
public bool requireResources = true;
[JsonProperty("Drop bot's resources on death?")]
public bool dropResources = true;
}
public class BuildSetup {
[JsonProperty("Max allowable height of foundation")]
public float maxHeightBlockFoundation = 3.1f;
[JsonProperty("Start height to ground")]
public float startHeightToGround = 0.5f;
[JsonProperty("Max depth when building in water")]
public float maxDepthInWater = 2.5f;
[JsonProperty("Checks")]
public ChecksSetup Checks = new ChecksSetup();
[JsonProperty("Doors")]
public DoorsSetup Doors = new DoorsSetup();
// [JsonProperty("BuildingPrivileges")]
[JsonIgnore]
public CupSetup Cup = new CupSetup();
public class DoorsSetup {
[JsonProperty("Deploy doors?")]
public bool deployDoors = false;
[JsonProperty("Require resources for doors?")]
public bool requireResources = false;
}
public class CupSetup {
[JsonProperty("Deploy Building Privileges?")]
public bool deployCup = false;
[JsonProperty("Require resources for doors?")]
public bool requireResources = false;
[JsonProperty("Authorize the owner?")]
public bool canAuth = false;
}
public class ChecksSetup {
[JsonProperty("Check is close to road?")]
public bool checkIsCloseToRoad = true;
[JsonProperty("Check is building blocked?")]
public bool checkIsBuildingBlocked = true;
[JsonProperty("Check for Prevent Building triggers")]
public bool checkForPreventBuilding = true;
[JsonProperty("Prevent Building check radius")]
public float preventBuildingRadius = 10f;
}
}
public class SpeedSetup {
[JsonProperty("Bot speed multiplier")]
public float lerpSpeedMultiplier = 1f;
[JsonProperty("Build speed multiplier")]
public float buildSpeedMultiplier = 1f;
[JsonProperty("Time to check 1 foundation")]
public float timeCheckFoundation = 0.15f;
[JsonProperty("Time to check 1 building block")]
public float timeCheckBuildingBlock = 0.15f;
}
public class ItemSetup {
[JsonProperty("Item name")]
public string name = "";
[JsonProperty("Item shortname")]
public string shortname = "";
[JsonProperty("Item skin")]
public ulong skin = 0;
[JsonProperty("Item amount")]
public int amount = 1;
}
}
}
public class OldConfiguration {
[JsonProperty("Controls")]
public Configuration.ControlsSetup Controls = new Configuration.ControlsSetup();
[JsonProperty("Build Limitations")]
public Configuration.GlobalLimitationsSetup Limitations = new Configuration.GlobalLimitationsSetup();
[JsonProperty("Permissions")]
public Dictionary<string, Configuration.BotSetup> permissionBot = new Dictionary<string, Configuration.BotSetup>();
[JsonProperty("Builder install by item")]
public List<Configuration.ItemInfo> installItem = new List<Configuration.ItemInfo>();
}
protected override void LoadDefaultConfig() {
_config = new Configuration {
permissionBot = new Dictionary<string, List<Configuration.BotSetup>> {
["personalbuilder.bot1"]
= new List<Configuration.BotSetup> {
new Configuration.BotSetup {
player = new Configuration.BotSetup.PlayerSetup {
displayName = "Personal Builder"
}
, filename = "pbuilder_test", startKit = new List<Configuration.BotSetup.ItemSetup> {
new Configuration.BotSetup.ItemSetup {
shortname = "shoes.boots",
}
, new Configuration.BotSetup.ItemSetup {
shortname = "pants",
}
, new Configuration.BotSetup.ItemSetup {
shortname = "hoodie",
}
, new Configuration.BotSetup.ItemSetup {
shortname = "mask.bandana",
}
, new Configuration.BotSetup.ItemSetup {
shortname = "hat.boonie",
}
, new Configuration.BotSetup.ItemSetup {
shortname = "sunglasses",
}
}
}
}
}
}
;
}
protected override void LoadConfig() {
base.LoadConfig();
try {
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
SaveConfig();
}
catch (Exception ex) {
var oldConfig = Config.ReadObject<OldConfiguration>();
if(oldConfig == null) {
PrintError("{0}", ex);
LoadDefaultConfig();
}
else {
_config = new Configuration();
_config.Controls = oldConfig.Controls;
_config.Limitations = oldConfig.Limitations;
_config.installItem = oldConfig.installItem;
foreach(var pair in oldConfig.permissionBot) {
_config.permissionBot.Add(pair.Key, new List<Configuration.BotSetup> {
pair.Value
}
);
}
SaveConfig();
}
}
switch(_config.Controls.mainControlButton) {
case "E" : _config.Controls.controlButton = BUTTON.USE;
break;
case "MIDDLE_MOUSE" : _config.Controls.controlButton = BUTTON.FIRE_THIRD;
break;
case "RELOAD" : _config.Controls.controlButton = BUTTON.RELOAD;
break;
case "SPRINT" : _config.Controls.controlButton = BUTTON.SPRINT;
break;
case "SECOND_MOUSE" : _config.Controls.controlButton = BUTTON.FIRE_SECONDARY;
break;
}
}
protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Data
private DataFile _data;
public class DataFile {
public Dictionary<ulong, LimitInfo> LimitsInfo = new Dictionary<ulong, LimitInfo>();
public class LimitInfo {
public Dictionary<string, int> LimitsByPermission = new Dictionary<string, int>();
}
}
private void LoadData() {
_data = Interface.Oxide.DataFileSystem.ReadObject<DataFile>("PersonalBuilder_LimitsData");
}
private void SaveData() {
Interface.Oxide.DataFileSystem.WriteObject("PersonalBuilder_LimitsData", _data);
}
private void ClearAllData() {
_data = new DataFile();
SaveData();
}
#endregion
#region Loc
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["ChatCommand_Error_NoPermission"]
= "You don't have a permission to spawn a personal builder", ["ChatCommand_Error_NotFound"] = "Bot not found", ["ChatCommand_Error_NoResources"] = "The bot doesn't have enough resources!\nFor construction, it is necessary:\n", ["ChatCommand_Error_Abort"] = "Construction stopped, bot is killed!", ["ChatCommand_Error_Limit"] = "Your limit for this building has been reached!", ["ChatCommand_Error_NoSpawnHere"] = "You can't spawn personal builder here!", ["ChatCommand_Success_Despawn"] = "Your personal builder was sucessfully despawned", ["ChatCommand_Success_Built"] = "Your building is ready!", ["ChatCommand_Success_Start"] = "Construction has started!", ["ChatCommand_Notice_Cooldown"] = "You need to wait {0} seconds to spawn a bot again", ["ChatCommand_Notice_AvailableBots"] = "<size=16>Available bots:</size>\n{BOTS}\n\nEnter /pbuilder [short bot name] to spawn!", ["ChatCommand_Notice_Check"] = "Checking the place to build...", ["open_loot_builder"] = "Open Inventory(USE)", ["Calculation_of_the_drawing"] = "Calculation of the building drawing...", ["Calculation_resources"] = "List of resources for construction:\n", ["CopyPaste_Error_NoFile"] = "Contact server admin, building file doesn't exist", ["CopyPaste_Error_FileCorrupt"] = "Contact server admin, build file is broken/corrupted.", ["CopyPaste_Error_BuildBlocked"] = "Building is blocked here!", ["CopyPaste_Error_CloseToRoad"] = "Close to road, can't build here!", ["CopyPaste_Error_NotSuitablePlace"] = "Not suitable landscape for construction!", ["CopyPaste_Error_WallBlocked"] = "Obstacle to wall construction detected!", ["CopyPaste_Error_RoofBlocked"] = "Obstacle to roof construction detected!", ["Resource_Wood"] = "Wood", ["Resource_Stone"] = "Stones", ["Resource_MetalFragment"] = "Metal Fragments", ["Resource_HQM"] = "High Quality Metal", ["Resource_Gears"] = "Gears", ["CommandPaused"] = "Construction is paused!", ["BotCalculated"] = "Checking the place to build...", ["BotCheckedTerritory"] = "Checking the place to build...", ["BotBuilding"] = "Construction resumed!",
}
, this, "en");
lang.RegisterMessages(new Dictionary<string, string> {
["ChatCommand_Error_NoPermission"]
= "У вас нет разрешения на спавн персонального строителя", ["ChatCommand_Error_NotFound"] = "Бот не найден", ["ChatCommand_Error_NoResources"] = "У Бота недостаточно ресурсов!\nДля строительства необходимо:\n", ["ChatCommand_Error_Abort"] = "Строительство прекращено, бот мертв!", ["ChatCommand_Error_Limit"] = "Ваш лимит на данную постройку был исчерпан!", ["ChatCommand_Error_NoSpawnHere"] = "Вы не можете заспавнить персонального строителя здесь!", ["ChatCommand_Success_Despawn"] = "Вас персональный строитель был успешно задеспавнен", ["ChatCommand_Success_Built"] = "Ваше здание готово!", ["ChatCommand_Success_Start"] = "Строительство начато!", ["ChatCommand_Notice_Cooldown"] = "Вам нужно подождать {0} секунд, прежде чем повторно заспавнить бота", ["ChatCommand_Notice_AvailableBots"] = "<size=16>Доступные боты:</size>\n{BOTS}\n\nВведите /pbuilder [короткое название бота], чтобы заспавнить!", ["ChatCommand_Notice_Check"] = "Проверка территории под строительство...", ["open_loot_builder"] = "Открыть Инвентарь(USE)", ["Calculation_of_the_drawing"] = "Расчет чертежа здания...", ["Calculation_resources"] = "Список ресурсов для строительства:\n", ["CopyPaste_Error_NoFile"] = "Свяжитесь с администратором сервера, файл постройки отсутствует", ["CopyPaste_Error_FileCorrupt"] = "Свяжитесь с администратором сервера, файл постройки поврежден", ["CopyPaste_Error_BuildBlocked"] = "Строительство недоступно здесь!", ["CopyPaste_Error_CloseToRoad"] = "Близко к дороге, строительство недоступно!", ["CopyPaste_Error_NotSuitablePlace"] = "Не подходящий ландшафт для строительства!", ["CopyPaste_Error_WallBlocked"] = "Обнаружено препятствие для строительства стены!", ["CopyPaste_Error_RoofBlocked"] = "Обнаружено препятствие для строительства крыши!", ["Resource_Wood"] = "Дерево", ["Resource_Stone"] = "Камни", ["Resource_MetalFragment"] = "Метал.фрагменты", ["Resource_HQM"] = "МВК", ["Resource_Gears"] = "Шестерни", ["CommandPaused"] = "Строительство приостановлено!", ["BotCalculated"] = "Бот рассчитывает чертеж здания...", ["BotCheckedTerritory"] = "Бот проверяет территорию под строительство...", ["BotBuilding"] = "Строительство возобновлено!",
}
, this, "ru");
}
#endregion
#region Methods
public void DropLoot(BasePlayer player, PlayerBuilderController controller, HitInfo info) {
if(!controller.BotSetup.resources.dropResources || player.inventory.containerMain.itemList.Count == 0) return;
List<ItemContainer> containers = new List<ItemContainer>();
if(!player.inventory.containerMain.IsLocked()) containers.Add(player.inventory.containerMain);
DroppedItemContainer droppedContainer = GameManager.server.CreateEntity("assets/prefabs/misc/item drop/item_drop_backpack.prefab", player.transform.position, Quaternion.identity) as DroppedItemContainer;
droppedContainer.TakeFrom(containers.ToArray());
droppedContainer.playerName = player.displayName;
droppedContainer.playerSteamID = player.userID;
droppedContainer.Spawn();
}
public List<Configuration.BotSetup> GetBotSetup(BasePlayer player) {
List<Configuration.BotSetup> setups = new List<Configuration.BotSetup>();
foreach(var key in _permissionKeys) {
if(permission.UserHasPermission(player.UserIDString, key)) {
setups.AddRange(_config.permissionBot[key]);
}
}
return setups;
}
public string GetMsg(string key, string id) => lang.GetMessage(key, this, id);
public void SendMsg(BasePlayer player, string key, string[] args = null) {
if(args != null) player.ChatMessage(string.Format(lang.GetMessage(key, this, player.UserIDString), args));
else {
player.ChatMessage(lang.GetMessage(key, this, player.UserIDString));
}
}
[ChatCommand("pbuilder")]
private void chatMsg(BasePlayer player, string command, string[] args) {
var controller = GetControllerByOwner(player.userID);
if(args == null || args?.Length == 0) {
if(controller != null) {
if(controller.ItemInfo != null) {
if(controller.ItemInfo.HasValue) {
if(controller.ItemInfo.Value.returnItem) {
var item = ItemManager.CreateByName(controller.ItemInfo.Value.shortname, 1, controller.ItemInfo.Value.skin);
if(!string.IsNullOrEmpty(controller.ItemInfo.Value.name)) item.name = controller.ItemInfo.Value.name;
player.GiveItem(item);
}
}
}
UnityEngine.Object.Destroy(controller);
SendMsg(player, "ChatCommand_Success_Despawn");
}
else {
var botSetup = GetBotSetup(player);
if(botSetup != null) {
if(botSetup.Count == 0) SendMsg(player, "ChatCommand_Error_NoPermission");
else {
if(botSetup.Count == 1) {
chatMsg(player, command, new string[] {
botSetup[0].spawnName
}
);
return;
}
string msg = lang.GetMessage("ChatCommand_Notice_AvailableBots", this, player.UserIDString);
string availableBots = "";
foreach(var bot in botSetup) availableBots = availableBots + $"\n{botSetup.IndexOf(bot) + 1}.{bot.spawnName}";
msg = msg.Replace("{BOTS}", availableBots);
player.ChatMessage(msg);
}
}
}
return;
}
if(controller != null && args != null && args.Length == 1 && args[0] == "pause") {
if(controller.Status == PlayerBuilderController.StatusBot.Building && !controller.Command_paused) {
controller.Command_paused = true;
}
controller.PrintStatus();
return;
}
if(controller != null && args != null && args.Length == 1 && args[0] == "resume") {
if(controller.Status == PlayerBuilderController.StatusBot.Building && controller.Command_paused) {
controller.Command_paused = false;
}
controller.PrintStatus();
return;
}
var bots = GetBotSetup(player);
if(bots.Count > 0) {
List<Configuration.BotSetup> botsFinded = new List<Configuration.BotSetup>();
foreach(var botSetup in bots) if(botSetup.spawnName == args[0]) botsFinded.Add(botSetup);
Configuration.BotSetup bot = null;
if(botsFinded.Count != 0) bot = botsFinded[0];
else {
SendMsg(player, "ChatCommand_Error_NotFound");
return;
}
if(bot != null) {
string perm = string.Empty;
foreach(var pair in _config.permissionBot) {
if(pair.Value.Contains(bot)) {
perm = pair.Key;
break;
}
}
if(permission.UserHasPermission(player.UserIDString, perm)) {
if(controller != null) {
if(controller.ItemInfo != null) {
if(controller.ItemInfo.HasValue) {
if(controller.ItemInfo.Value.returnItem) {
var item = ItemManager.CreateByName(controller.ItemInfo.Value.shortname, 1, controller.ItemInfo.Value.skin);
if(!string.IsNullOrEmpty(controller.ItemInfo.Value.name)) item.name = controller.ItemInfo.Value.name;
player.GiveItem(item);
}
}
}
UnityEngine.Object.Destroy(controller);
SendMsg(player, "ChatCommand_Success_Despawn");
return;
}
if(bot.limitations.enableLimits) {
if(_data.LimitsInfo.ContainsKey(player.userID)) {
var playerInfo = _data.LimitsInfo[player.userID];
if(playerInfo != null) {
if(playerInfo.LimitsByPermission.ContainsKey(perm)) {
int currentBuilt = playerInfo.LimitsByPermission[perm];
if(currentBuilt >= bot.limitations.times) {
SendMsg(player, "ChatCommand_Error_Limit");
return;
}
}
}
}
}
if(_cooldownInfo.ContainsKey(player.userID)) {
var lastTimeSpawn = _cooldownInfo[player.userID];
if(DateTime.Now > lastTimeSpawn.AddSeconds(bot.cooldown)) {
_cooldownInfo.Remove(player.userID);
_cooldownInfo.Add(player.userID, DateTime.Now);
}
else {
SendMsg(player, "ChatCommand_Notice_Cooldown", new string[] {
Mathf.RoundToInt((float)(lastTimeSpawn.AddSeconds(bot.cooldown) - DateTime.Now).TotalSeconds).ToString()
}
);
return;
}
}
else _cooldownInfo.Add(player.userID, DateTime.Now);
controller = PlayerBuilderController.CreateBot(player, bot, null, buildCostInfo, this);
_controllersByOwner.Add(player.userID, controller);
_controllersByBot.Add(controller.BotPlayer.userID, controller);
}
else SendMsg(player, "ChatCommand_Error_NoPermission");
}
else SendMsg(player, "ChatCommand_Error_NotFound");
}
else SendMsg(player, "ChatCommand_Error_NoPermission");
}
[ConsoleCommand("pbuilder.item")]
private void cnslCommandItem(ConsoleSystem.Arg arg) {
if(arg.Player() != null) return;
if(!arg.HasArgs(2)) {
PrintError("Please enter Steam ID and item skin!");
return;
}
ulong id, skin;
if(!ulong.TryParse(arg.Args[0], out id)) {
PrintError("Steam ID is incorrect");
return;
}
if(!ulong.TryParse(arg.Args[1], out skin)) {
PrintError("Skin is incorrect");
return;
}
BasePlayer reciver = BasePlayer.FindByID(id);
if(reciver == null) {
PrintError("Player not found");
return;
}
Configuration.ItemInfo info = new Configuration.ItemInfo();
foreach(var loopInfo in _config.installItem) {
if(loopInfo.skin == skin) {
info = loopInfo;
break;
}
}
if(info.bot == null) {
PrintError("Item is not found");
return;
}
Item pnpc = ItemManager.CreateByName(info.shortname, 1, info.skin);
if(!string.IsNullOrEmpty(info.name)) pnpc.name = info.name;
reciver.GiveItem(pnpc);
Puts($"Item was successfully given to player {reciver.displayName}");
}
#endregion
#region Hooks
private void OnEntityBuilt(Planner plan, GameObject go) {
if(_config.installItem.Count == 0) return;
var player = plan.GetOwnerPlayer();
if(player == null) return;
var item = player.GetActiveItem();
if(item == null) return;
if(_config.Controls.blockBotZoneManager.Count != 0 && ZoneManager != null) {
foreach(var zone in _config.Controls.blockBotZoneManager) {
if(ZoneManager.Call<bool>("IsPlayerInZone", zone, player)) {
SendMsg(player, "ChatCommand_Error_NoSpawnHere");
int itemAmount = item.amount;
this.NextTick(() => {
var ent = go.ToBaseEntity();
if(ent != null) ent.Kill();
var newItem = ItemManager.CreateByName(item.info.shortname, itemAmount, item.skin);
player.GiveItem(newItem);
}
);
return;
}
}
}
foreach(var loopInfo in _config.installItem) {
if(loopInfo.skin == item.skin) {
var controller = GetControllerByOwner(player.userID);
var bot = loopInfo.bot;
if(controller != null) {
if(controller.ItemInfo != null) {
if(controller.ItemInfo.HasValue) {
if(controller.ItemInfo.Value.returnItem) {
var item2 = ItemManager.CreateByName(controller.ItemInfo.Value.shortname, 1, controller.ItemInfo.Value.skin);
if(!string.IsNullOrEmpty(controller.ItemInfo.Value.name)) item2.name = controller.ItemInfo.Value.name;
player.GiveItem(item2);
}
}
}
UnityEngine.Object.Destroy(controller);
}
controller = PlayerBuilderController.CreateBot(player, bot, loopInfo, buildCostInfo, this, go.transform.position);
_controllersByOwner.Remove(player.userID);
_controllersByBot.Remove(controller.BotPlayer.userID);
_controllersByOwner.Add(player.userID, controller);
_controllersByBot.Add(controller.BotPlayer.userID, controller);
this.NextTick(() => {
var ent = go.ToBaseEntity();
if(ent != null) ent.Kill();
}
);
break;
}
}
}
private void Unload() {
foreach(var controller in _controllersByOwner.Values) {
if(controller == null) continue;
UnityEngine.Object.Destroy(controller);
}
}
private void Init() {
LoadData();
}
private void OnNewSave(string filename) {
if(_config.Limitations.clearLimitsOnWipe) ClearAllData();
}
private void OnUserPermissionRevoked(string id, string permName) {
if(_config.Limitations.clearLimitsOnRevoke) {
ulong result;
if(ulong.TryParse(id, out result)) {
if(_data.LimitsInfo.ContainsKey(result)) {
var info = _data.LimitsInfo[result];
if(info.LimitsByPermission.ContainsKey(permName)) {
info.LimitsByPermission.Remove(permName);
_data.LimitsInfo[result] = info;
SaveData();
}
}
}
}
}
private object OnPlayerDeath(BasePlayer player, HitInfo info) {
if(player == null || player?.net == null) return null;
if(player.IsNpc) {
var controller = GetControllerByBot(player.userID);
if(controller != null) {
DropLoot(player, controller, info);
player.Teleport(new Vector3(0, -1000, 0));
NextTick(() => {
if(player != null && !player.IsDestroyed) player.Kill();
}
);
return false;
}
}
return null;
}
private void OnServerInitialized() {
_permissionKeys = new List<string>(_config.permissionBot.Keys);
_permissionKeys.ForEach(x => permission.RegisterPermission(x, this));
}
private void OnPlayerInput(BasePlayer player, InputState input) {
if(player == null || input == null) return;
if(!input.WasJustPressed(_config.Controls.controlButton)) return;
var controller = GetControllerByOwner(player.userID);
if(controller == null) return;
controller.OnInput(input);
}
private object OnEntityTakeDamage(BaseCombatEntity ent, HitInfo info) {
if(ent == null || info == null) return null;
if(ent is BasePlayer) {
var player = ent.ToPlayer();
if(player != null) {
if(_controllersByBot.ContainsKey(player.userID)) {
var controller = _controllersByBot[player.userID];
if(controller != null) {
i
// ... [Code preview truncated due to length. Full source in attached file] ...