C#:
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.AI;
///Скачано с дискорд сервера Rust Edit [PRO+]
///discord.gg/9vyTXsJyKR
namespace Oxide.Plugins {
[Info("Store Robbery", "discord.gg/9vyTXsJyKR", "1.1.5")]
public class StoreRobbery : CovalencePlugin {
#region Localization
protected override void LoadDefaultMessages() {
lang.RegisterMessages(new Dictionary<string, string> {
["NoItemBox"]
= "Clerk does not have an item box, please contact a admin/developer.", ["PlayerCooldown"] = "You are currently on a cooldown for store robberys, please come back later.", ["ClerkCooldown"] = "This clerk has recently been robbed, please come back later.", ["TooFarAway"] = "You must be within {0}m of the clerk to rob him!", ["BeingRobbed"] = "The station is currently being robbed by someone else!", ["NoWeapon"] = "The clerk is only intimidated by a gun, you dont have anything!", ["NotIntimidated"] = "The clerk is not intimidated, that weapon dosen't scare him!", ["RobbingText"] = "Robbing store, please stay within {0}m ({1}%)", ["FailedConditions"] = "Conditions were not met, robbery ended.", ["CompletedEconomics"] = "You have completed the robbery, you have earned {0} credits.", ["CompletedServerRewards"] = "You have completed the robbery, you have earned {0}RP.", ["CompletedInventory"] = "You have completed the robbery, press USE key on NPC to get items.", ["NoPermission"] = "You do not have permission to use this command.", ["NoNPC"] = "Could not find an NPC infront of you.", ["RemovedNPC"] = "NPC was removed, use /createclerk to make a new one.", ["NPCID"] = "NPC ID: {0}", ["ClerkBeingRobbed"] = "<b><color=green>A clerk is being robbed in grid {0}!</color></b>"
}
, this);
}
private void SendMessage(BasePlayer player, string langKey, params object[] args) {
if (player.IsConnected) player.ChatMessage(string.Format(lang.GetMessage(langKey, this, player.UserIDString), args));
}
#endregion
#region Config
public class ItemDetails {
public string shortname = string.Empty;
public string customname = string.Empty;
public ulong skin = 0;
public int minamount = 0;
public int maxamount = 1;
public int probability = 0;
}
public class NPCClothing {
public List<string> Clothing = new List<string>();
public List<uint> Skins = new List<uint>();
}
public class Rewards {
[JsonProperty(PropertyName = "Use Economics Plugin")]
public bool useEconomics;
[JsonProperty(PropertyName = "Minimum Amount Of Credits")]
public int minCredits;
[JsonProperty(PropertyName = "Maximum Amount Of Credits")]
public int maxCredits;
[JsonProperty(PropertyName = "Use Server Rewards Plugin")]
public bool useServerRewards;
[JsonProperty(PropertyName = "Minimum Amount Of RP")]
public int minPoints;
[JsonProperty(PropertyName = "Maximum Amount Of RP")]
public int maxPoints;
[JsonProperty(PropertyName = "Use Item Box Rewards")]
public bool useItemBox;
[JsonProperty(PropertyName = "Minimum Amount Of Items From List")]
public int minItems;
[JsonProperty(PropertyName = "Maximum Amount Of Items From List")]
public int maxItems;
[JsonProperty(PropertyName = "Possible Item List")]
public List<ItemDetails> itemsToRecieve;
}
public class Guards {
[JsonProperty(PropertyName = "Play Alarm Sound")]
public bool playAlarmSound;
[JsonProperty(PropertyName = "Alarm Sound Prefab")]
public string alarmSoundFX;
[JsonProperty(PropertyName = "Spawn Guards at Robbery Start")]
public bool spawnRobberyStart;
[JsonProperty(PropertyName = "Spawn Guards at Robbery End")]
public bool spawnRobberyEnd;
[JsonProperty(PropertyName = "Chance of Guard Spawn (0-100%)")]
public int spawnChance;
[JsonProperty(PropertyName = "Amount of Guard at Robbery Start")]
public int amountOfGuardsAtStart;
[JsonProperty(PropertyName = "Amount of Guard at Robbery End")]
public int amountOfGuardsAtEnd;
[JsonProperty(PropertyName = "Store Guard")]
public string guardName;
[JsonProperty(PropertyName = "Gaurds HP")]
public float guardHP;
[JsonProperty(PropertyName = "Gaurds Damage Scale")]
public float guardDamageScale;
[JsonProperty(PropertyName = "Gaurds Despawn Time (Secs) - 0 = Disabled")]
public int guardDespawnTime;
}
static Configuration config;
public class Configuration {
[JsonProperty(PropertyName = "Announce Robberies In Chat")]
public bool announceRobberies;
[JsonProperty(PropertyName = "Require Permission for Announcement")]
public bool requirePermission;
[JsonProperty(PropertyName = "Announcement Permission")]
public string announcementPerm;
[JsonProperty(PropertyName = "Use Clerk Marker")]
public bool useClerkMarker;
[JsonProperty(PropertyName = "Use Robbery Area Marker")]
public bool useRobberyAreaMarker;
[JsonProperty(PropertyName = "Allow Shoot To Rob")]
public bool allowShootToRob;
[JsonProperty(PropertyName = "Robbery Distance (m)")]
public float robberyDistance;
[JsonProperty(PropertyName = "Robbery Time (Secs)")]
public int robberyTime;
[JsonProperty(PropertyName = "NPC Cooldown/Reset Time (Secs)")]
public int npcCooldownTime;
[JsonProperty(PropertyName = "Use Player Cooldown?")]
public bool usePlayerCooldown;
[JsonProperty(PropertyName = "Player Robbery Cooldown Time (Secs)")]
public int playerCooldownTime;
[JsonProperty(PropertyName = "Whitelisted Robbery Weapons")]
public List<string> whitelistedWeapoons;
[JsonProperty(PropertyName = "Clear NPCs On New Save")]
public bool clearNPCsOnNewSave;
[JsonProperty(PropertyName = "Clerk Name")]
public string clerkName;
[JsonProperty(PropertyName = "Fill Clerks at Supermarkets")]
public bool fillClerksAtSupermarkets;
[JsonProperty(PropertyName = "Supermarket Clerk Position")]
public Vector3 SupermarketClerkPosition;
[JsonProperty(PropertyName = "Supermarket Clerk Rotation")]
public Vector3 SupermarketClerkRotation;
[JsonProperty(PropertyName = "Fill Clerks at Gas Stations")]
public bool fillClerksAtGas;
[JsonProperty(PropertyName = "Gas Station Clerk Position")]
public Vector3 GasStationClerkPosition;
[JsonProperty(PropertyName = "Gas Station Clerk Rotation")]
public Vector3 GasStationClerkRotation;
[JsonProperty(PropertyName = "Guard Settings")]
public Guards Guards;
[JsonProperty(PropertyName = "NPC Clothing")]
public NPCClothing NPCClothing;
[JsonProperty(PropertyName = "Robbery Rewards")]
public Rewards rewards;
public static Configuration DefaultConfig() {
return new Configuration {
announceRobberies = true, requirePermission = false, announcementPerm = "storerobbery.receiveannouncement", useClerkMarker = true, useRobberyAreaMarker = true, allowShootToRob = false, robberyDistance = 10, robberyTime = 300, npcCooldownTime = 120, usePlayerCooldown = true, playerCooldownTime = 120, whitelistedWeapoons = new List<string>() {
"rifle.ak", "rifle.bolt", "smg.2", "rifle.l96", "lmg.m249", "rifle.lr300", "rifle.m39", "pistol.m92", "smg.mp5", "pistol.python", "pistol.revolver", "rocket.launcher", "rifle.semiauto", "pistol.semiauto", "shotgun.spas12", "smg.thompson"
}
, clearNPCsOnNewSave = true, fillClerksAtSupermarkets = true, clerkName = "Store Clerk", SupermarketClerkPosition = new Vector3(8.8f, 0, 3.5f), SupermarketClerkRotation = new Vector3(8.8f, 0, 2.0f), fillClerksAtGas = true, GasStationClerkPosition = new Vector3(-8.7f, 0, 21.5f), GasStationClerkRotation = new Vector3(-8.2f, 0, 21.5f), Guards = new Guards {
playAlarmSound = true, alarmSoundFX = "assets/bundled/prefabs/fx/invite_notice.prefab", spawnRobberyStart = false, spawnRobberyEnd = true, spawnChance = 75, amountOfGuardsAtStart = 0, amountOfGuardsAtEnd = 5, guardName = "Store Guard", guardHP = 400, guardDespawnTime = 300
}
, NPCClothing = new NPCClothing() {
Clothing = new List<string>() {
"hat.cap", "shirt.collared", "pants.shorts", "shoes.boots"
}
, Skins = new List<uint>() {
1125552993, 1145623671, 883719992, 2592902166
}
}
, rewards = new Rewards {
useEconomics = false, minCredits = 3000, maxCredits = 6000, useServerRewards = false, minPoints = 300, maxPoints = 600, useItemBox = true, minItems = 3, maxItems = 6, itemsToRecieve = new List<ItemDetails>() {
new ItemDetails {
shortname = "rifle.ak", customname = "Red Zircon AK47", skin = 2589524856, minamount = 1, maxamount = 1, probability = 5
}
, new ItemDetails {
shortname = "rifle.bolt", customname = string.Empty, skin = 0, minamount = 1, maxamount = 1, probability = 5
}
, new ItemDetails {
shortname = "ammo.pistol", customname = string.Empty, skin = 0, minamount = 10, maxamount = 50, probability = 70
}
, new ItemDetails {
shortname = "ammo.shotgun", customname = string.Empty, skin = 0, minamount = 10, maxamount = 30, probability = 70
}
, new ItemDetails {
shortname = "syringe.medical", customname = string.Empty, skin = 0, minamount = 1, maxamount = 3, probability = 40
}
, new ItemDetails {
shortname = "keycard_blue", customname = string.Empty, skin = 0, minamount = 1, maxamount = 1, probability = 35
}
, new ItemDetails {
shortname = "cctv.camera", customname = string.Empty, skin = 0, minamount = 1, maxamount = 2, probability = 50
}
, new ItemDetails {
shortname = "shotgun.double", customname = string.Empty, skin = 0, minamount = 1, maxamount = 1, probability = 70
}
, new ItemDetails {
shortname = "bow.hunting", customname = string.Empty, skin = 0, minamount = 1, maxamount = 1, probability = 90
}
, new ItemDetails {
shortname = "pistol.revolver", customname = string.Empty, skin = 0, minamount = 1, maxamount = 1, probability = 80
}
, new ItemDetails {
shortname = "arrow.wooden", customname = string.Empty, skin = 0, minamount = 10, maxamount = 40, probability = 85
}
, new ItemDetails {
shortname = "arrow.fire", customname = string.Empty, skin = 0, minamount = 5, maxamount = 20, probability = 70
}
, new ItemDetails {
shortname = "rope", customname = string.Empty, skin = 0, minamount = 3, maxamount = 6, probability = 75
}
, new ItemDetails {
shortname = "propanetank", customname = string.Empty, skin = 0, minamount = 3, maxamount = 6, probability = 75
}
, new ItemDetails {
shortname = "metalpipe", customname = string.Empty, skin = 0, minamount = 2, maxamount = 4, probability = 75
}
}
,
}
}
;
}
}
protected override void LoadConfig() {
base.LoadConfig();
try {
config = Config.ReadObject<Configuration>();
if (config == null) LoadDefaultConfig();
SaveConfig();
}
catch {
PrintWarning($"Creating new config file.");
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig() => config = Configuration.DefaultConfig();
protected override void SaveConfig() => Config.WriteObject(config);
#endregion
#region Data
public class Store {
public int dataId = -1;
public bool isBeingRobbed = false;
public float robberyTime = 0;
public BasePlayer robber = null;
public VendingMachineMapMarker mapMarker = null;
public MapMarkerGenericRadius robberyMarker = null;
public BoxStorage itemsBox = null;
}
;
public class NPCData {
public Vector3 position = default(Vector3);
public Vector3 rotation = default(Vector3);
}
public class Save {
public bool FilledClerks = false;
public Dictionary<int, NPCData> NPCData = new Dictionary<int, NPCData>();
}
private Save _save;
private void SaveData() => Interface.GetMod().DataFileSystem.WriteObject("StoreRobbery", _save);
#endregion
#region Defines
[PluginReference]
Plugin ServerRewards, Economics;
public Dictionary<string, Timer> playerTimers = new Dictionary<string, Timer>();
public Dictionary<string, float> playerCooldowns = new Dictionary<string, float>();
public Dictionary<BasePlayer, Store> shopNpcs = new Dictionary<BasePlayer, Store>();
private const string manageperm = "storerobbery.manage";
#endregion
#region Hooks
private void OnServerInitialized() {
foreach (KeyValuePair<int, NPCData> npcs in _save.NPCData) CreateNPC(npcs.Key, npcs.Value.position, npcs.Value.rotation);
FillClerks();
}
private void Loaded() {
permission.RegisterPermission(manageperm, this);
if (config != null && config.requirePermission && !string.IsNullOrEmpty(config.announcementPerm)) permission.RegisterPermission(config.announcementPerm, this);
_save = Interface.GetMod().DataFileSystem.ReadObject<Save>("StoreRobbery");
foreach (BasePlayer player in BasePlayer.activePlayerList) {
OnPlayerConnected(player);
}
}
private void Unload() {
config = null;
SaveData();
if (_save.NPCData.Count == 0) return;
foreach (BasePlayer npc in shopNpcs.Keys.ToList()) RemoveNPC(npc);
foreach (BasePlayer player in BasePlayer.activePlayerList) {
CuiHelper.DestroyUi(player, "ProgressTopPanel");
CuiHelper.DestroyUi(player, "ProgressBackground");
CuiHelper.DestroyUi(player, "ProgressBarPanel");
CuiHelper.DestroyUi(player, "ProgressBar");
}
shopNpcs.Clear();
}
void OnServerSave() => SaveData();
void OnNewSave(string filename) {
if (config.clearNPCsOnNewSave) {
_save.FilledClerks = false;
_save.NPCData.Clear();
SaveData();
}
}
void OnPlayerConnected(BasePlayer player) {
if (!playerTimers.ContainsKey(player.UserIDString)) playerTimers.Add(player.UserIDString, null);
}
void OnPlayerDisconnected(BasePlayer player) {
if (playerTimers.ContainsKey(player.UserIDString)) playerTimers.Remove(player.UserIDString);
}
object OnEntityTakeDamage(BasePlayer player, HitInfo info) {
if (shopNpcs.ContainsKey(player)) {
info.damageTypes.ScaleAll(0);
if (config.allowShootToRob) {
BasePlayer attacker = info.InitiatorPlayer;
if (attacker == null) return null;
RobGasStation(attacker, player);
}
}
return null;
}
void OnPlayerInput(BasePlayer player, InputState input) {
if (!input.WasJustPressed(BUTTON.USE)) return;
RaycastHit hit;
if (Physics.Raycast(player.eyes.HeadRay(), out hit, 10f)) {
if (hit.GetEntity() == null) return;
BasePlayer npc = hit.GetEntity().ToPlayer();
if (npc == null || !shopNpcs.ContainsKey(npc)) return;
if (shopNpcs[npc].itemsBox == null) {
SendMessage(player, "NoItemBox");
return;
}
if (shopNpcs[npc].itemsBox.inventory.itemList.Count == 0) RobGasStation(player, npc);
else OpenLoot(player, npc);
}
}
object OnNpcTarget(BaseEntity npc, BasePlayer target) {
if (shopNpcs.ContainsKey(target)) return true;
return null;
}
#endregion
#region Functions
private ItemDetails GetRandom() {
List<ItemDetails> items = config.rewards.itemsToRecieve;
int sum_of_weight = 0;
for (int i = 0; i < items.Count; i++) sum_of_weight += items[i].probability;
int rnd = UnityEngine.Random.Range(1, sum_of_weight);
for (int i = 0; i < config.rewards.itemsToRecieve.Count; i++) {
if (rnd < items[i].probability) return items[i];
rnd -= items[i].probability;
}
return null;
}
private void OpenLoot(BasePlayer player, BasePlayer NPC) {
if (NPC == null || player == null) return;
if (shopNpcs[NPC] == null || shopNpcs[NPC].itemsBox == null) return;
player.inventory.loot.Clear();
player.inventory.loot.PositionChecks = false;
player.inventory.loot.entitySource = shopNpcs[NPC].itemsBox.inventory.entityOwner ?? player;
player.inventory.loot.itemSource = null;
player.inventory.loot.MarkDirty();
player.inventory.loot.AddContainer(shopNpcs[NPC].itemsBox.inventory);
player.inventory.loot.SendImmediate();
player.ClientRPCPlayer(null, player, "RPC_OpenLootPanel", "generic_resizable");
}
private void LookAt(BasePlayer clerk, Vector3 position) {
SetViewAngle(clerk, Quaternion.LookRotation(position - clerk.eyes.transform.position));
clerk.eyes.position.Set(position.x, position.y, position.z);
}
private void SetViewAngle(BasePlayer clerk, Quaternion view) {
if (view.eulerAngles == default(Vector3)) return;
clerk.viewAngles = view.eulerAngles;
}
private void CreateNPC(int id, Vector3 position, Vector3 rotation) {
BasePlayer shopNPC = GameManager.server.CreateEntity("assets/prefabs/player/player.prefab", position, new Quaternion(0, 0, 0, 1)).ToPlayer();
shopNPC.displayName = config.clerkName;
ulong playerid = (ulong)UnityEngine.Random.Range(1111, 9999);
shopNPC.userID = playerid;
shopNPC.UserIDString = playerid.ToString();
shopNPC.enableSaving = false;
shopNPC.Spawn();
LookAt(shopNPC, rotation);
shopNPC.SendNetworkUpdateImmediate();
if (!shopNpcs.ContainsKey(shopNPC)) shopNpcs.Add(shopNPC, new Store());
for (int i = 0; i < config.NPCClothing.Clothing.Count; i++) {
if (config.NPCClothing.Clothing[i] == null) return;
ItemDefinition def = ItemManager.FindItemDefinition(config.NPCClothing.Clothing[i]);
if (def == null) continue;
uint skin = 0;
if (i <= config.NPCClothing.Skins.Count - 1) skin = config.NPCClothing.Skins[i];
Item item = ItemManager.Create(def, skin : skin);
if (item == null) continue;
if (!item.MoveToContainer(shopNPC.inventory.containerWear)) item.Remove();
}
if (shopNpcs[shopNPC] != null) {
shopNpcs[shopNPC].dataId = id;
if (config.useClerkMarker) {
VendingMachineMapMarker ShopMapMarker = GameManager.server.CreateEntity("assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab", position) as VendingMachineMapMarker;
ShopMapMarker.markerShopName = config.clerkName;
ShopMapMarker.Spawn();
shopNpcs[shopNPC].mapMarker = ShopMapMarker;
}
BoxStorage storageBox = GameManager.server.CreateEntity("assets/prefabs/deployable/large wood storage/box.wooden.large.prefab", new Vector3(position.x, position.y - 3, position.z), new Quaternion(0, 0, 0, 1)) as BoxStorage;
storageBox.Spawn();
if (storageBox == null) return;
storageBox.inventory.SetFlag(ItemContainer.Flag.NoItemInput, true);
storageBox.decay = null;
UnityEngine.Object.DestroyImmediate(storageBox.GetComponent<GroundWatch>());
UnityEngine.Object.DestroyImmediate(storageBox.GetComponent<DestroyOnGroundMissing>());
storageBox.syncPosition = false;
storageBox.limitNetworking = true;
shopNpcs[shopNPC].itemsBox = storageBox;
}
}
private void RemoveNPC(BasePlayer npc) {
if (shopNpcs[npc] != null) {
if (shopNpcs[npc].mapMarker != null) shopNpcs[npc].mapMarker.KillMessage();
if (shopNpcs[npc].itemsBox != null) shopNpcs[npc].itemsBox.Kill();
if (shopNpcs[npc].robberyMarker != null) shopNpcs[npc].robberyMarker.KillMessage();
}
shopNpcs.Remove(npc);
npc.KillMessage();
}
private void RobGasStation(BasePlayer player, BasePlayer NPC) {
if (config.usePlayerCooldown && playerCooldowns.ContainsKey(player.UserIDString) && (Time.time - playerCooldowns[player.UserIDString]) < config.playerCooldownTime) {
SendMessage(player, "PlayerCooldown");
return;
}
;
if ((Time.time - shopNpcs[NPC].robberyTime) < config.npcCooldownTime) {
SendMessage(player, "ClerkCooldown");
return;
}
;
if (player.Distance(NPC) > config.robberyDistance) {
SendMessage(player, "TooFarAway", config.robberyDistance);
return;
}
;
if (shopNpcs[NPC].isBeingRobbed) {
SendMessage(player, "BeingRobbed");
return;
}
;
var weapon = player?.GetHeldEntity()?.GetItem();
if (weapon == null) {
SendMessage(player, "NoWeapon");
return;
}
if (!config.whitelistedWeapoons.Contains(weapon.info.shortname)) {
SendMessage(player, "NotIntimidated");
return;
}
;
shopNpcs[NPC].isBeingRobbed = true;
shopNpcs[NPC].robber = player;
StartRobbery(player, NPC);
}
private void StartRobbery(BasePlayer player = null, BasePlayer npc = null) {
if (player == null || npc == null) return;
if (config.useRobberyAreaMarker && shopNpcs[npc] != null) {
if (shopNpcs[npc].robberyMarker != null) shopNpcs[npc].robberyMarker.KillMessage();
MapMarkerGenericRadius marker = GameManager.server.CreateEntity("assets/prefabs/tools/map/genericradiusmarker.prefab", npc.ServerPosition) as MapMarkerGenericRadius;
marker.alpha = 0.6f;
marker.color1 = Color.red;
marker.color2 = Color.clear;
marker.radius = 0.4f;
marker.Spawn();
marker.SendUpdate();
shopNpcs[npc].robberyMarker = marker;
}
float percent = 0;
float percentValue = 100f / (float)config.robberyTime;
int offset = 0;
CuiHelper.DestroyUi(player, "LazarusProgressBar");
var container = new CuiElementContainer();
container.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "1 1 1 0"
}
, RectTransform = {
AnchorMin = "0.5 1", AnchorMax = "0.5 1", OffsetMin = "-272.538 -76.721", OffsetMax = "291.3 -45.23"
}
}
, "Hud", "LazarusProgressBar");
container.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "0.1764706 0.1764706 0.1764706 1"
}
, RectTransform = {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-281.241 -15.745", OffsetMax = "281.919 15.745"
}
}
, "LazarusProgressBar", "ProgressTopPanel");
container.Add(new CuiElement {
Name = "ProgressBarText", Parent = "LazarusProgressBar", Components = {
new CuiTextComponent {
Text = string.Format(lang.GetMessage("RobbingText", this, player.UserIDString), config.robberyDistance, Convert.ToInt32(percent)), Font = "robotocondensed-bold.ttf", FontSize = 13, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 0.3686275", Distance = "1 -1"
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-268.975 -12.815", OffsetMax = "-37.347 13.436"
}
}
}
);
CuiHelper.AddUi(player, container);
playerTimers[player.UserIDString] = timer.Every(1f, () => {
CuiHelper.DestroyUi(player, "ProgressBarContainer");
CuiHelper.DestroyUi(player, "ProgressBar");
CuiHelper.DestroyUi(player, "ProgressOverlay");
CuiHelper.DestroyUi(player, "ProgressBarText");
if (player.Distance(npc) > config.robberyDistance || shopNpcs[npc].robber != player || player.GetHeldEntity()?.GetItem() == null || !config.whitelistedWeapoons.Contains(player.GetHeldEntity().GetItem().info.shortname) || player.IsDead() || player.IsIncapacitated() || player.IsCrawling()) {
CuiHelper.DestroyUi(player, "LazarusProgressBar");
CuiHelper.DestroyUi(player, "ProgressBarContainer");
CuiHelper.DestroyUi(player, "ProgressBar");
CuiHelper.DestroyUi(player, "ProgressOverlay");
CuiHelper.DestroyUi(player, "ProgressBarText");
ResetNPC(player, npc, true);
SendMessage(player, "FailedConditions");
return;
}
percent += percentValue;
offset = ((int)percent * 558) / 100;
var progcontainer = new CuiElementContainer();
progcontainer.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "1 1 1 0"
}
, RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "370.325 285.001", OffsetMax = "928.341 313.339"
}
}
, "Hud", "ProgressBarContainer");
progcontainer.Add(new CuiPanel {
CursorEnabled = false, Image = {
Color = "0.5607843 0.9411765 0.2235294 1"
}
, RectTransform = {
AnchorMin = "0 0.5", AnchorMax = "0 0.5", OffsetMin = "-0.075 -12.961", OffsetMax = $"{offset} 13.29"
}
}
, "ProgressBarContainer", "ProgressBar");
if (percent >= 30) progcontainer.Add(new CuiElement {
Name = "ProgressOverlay", Parent = "ProgressBar", Components = {
new CuiRawImageComponent {
Color = "1 1 1 1", Url = "https://i.imgur.com/SxZU7Nb.png"
}
, new CuiRectTransformComponent {
AnchorMin = "1 0.5", AnchorMax = "1 0.5", OffsetMin = "-222.542 -12.961", OffsetMax = "0 13.29"
}
}
}
);
progcontainer.Add(new CuiElement {
Name = "ProgressBarText", Parent = "ProgressBarContainer", Components = {
new CuiTextComponent {
Text = string.Format(lang.GetMessage("RobbingText", this, player.UserIDString), config.robberyDistance, Convert.ToInt32(percent)), Font = "robotocondensed-bold.ttf", FontSize = 13, Align = TextAnchor.MiddleLeft, Color = "1 1 1 1"
}
, new CuiOutlineComponent {
Color = "0 0 0 0.3686275", Distance = "1 -1"
}
, new CuiRectTransformComponent {
AnchorMin = "0.5 0.5", AnchorMax = "0.5 0.5", OffsetMin = "-268.928 -12.961", OffsetMax = "-37.3 13.29"
}
}
}
);
CuiHelper.AddUi(player, progcontainer);
if (offset >= 558) {
CuiHelper.DestroyUi(player, "LazarusProgressBar");
CuiHelper.DestroyUi(player, "ProgressBarContainer");
CuiHelper.DestroyUi(player, "ProgressBar");
CuiHelper.DestroyUi(player, "ProgressOverlay");
CuiHelper.DestroyUi(player, "ProgressBarText");
RobberyCompleted(player, npc);
return;
}
}
);
if (config.announceRobberies) {
foreach (BasePlayer altplayer in BasePlayer.activePlayerList) {
if (altplayer == null) continue;
if (config.requirePermission && !permission.UserHasPermission(altplayer.UserIDString, config.announcementPerm)) continue;
SendMessage(altplayer, "ClerkBeingRobbed", GetGrid(npc.transform.position));
}
}
SpawnGaurds(player, npc, true);
}
private static string GetGrid(Vector3 pos) {
const float scale = 150f;
float x = pos.x + World.Size / 2f;
float z = pos.z + World.Size / 2f;
int lat = (int)(x / scale);
char latChar = (char)('A' + lat);
int lon = (int)(World.Size / scale - z / scale);
return latChar + lon.ToString();
}
private void ResetNPC(BasePlayer player, BasePlayer NPC, bool onlyPReset = false) {
if (NPC != null && shopNpcs[NPC] != null) {
shopNpcs[NPC].isBeingRobbed = false;
shopNpcs[NPC].robber = null;
if (!onlyPReset) shopNpcs[NPC].robberyTime = Time.time;
if (shopNpcs[NPC].robberyMarker != null) shopNpcs[NPC].robberyMarker.KillMessage();
}
if (player != null) {
if (playerTimers.ContainsKey(player.UserIDString) && playerTimers[player.UserIDString] != null && !playerTimers[player.UserIDString].Destroyed) playerTimers[player.UserIDString].Destroy();
if (config.usePlayerCooldown) {
if (!playerCooldowns.ContainsKey(player.UserIDString)) {
playerCooldowns.Add(player.UserIDString, Time.time);
return;
}
playerCooldowns[player.UserIDString] = Time.time;
}
}
}
private void RobberyCompleted(BasePlayer player, BasePlayer NPC) {
if (player == null || NPC == null || shopNpcs[NPC] == null) return;
ResetNPC(player, NPC);
SpawnGaurds(player, NPC, false);
if (ServerRewards && config.rewards.useServerRewards) {
int points = UnityEngine.Random.Range(config.rewards.minPoints, config.rewards.maxPoints + 1);
ServerRewards?.Call("AddPoints", player.UserIDString, points);
SendMessage(player, "CompletedServerRewards", points);
}
if (Economics && config.rewards.useEconomics) {
int credits = UnityEngine.Random.Range(config.rewards.minCredits, config.rewards.maxCredits + 1);
Economics?.Call("Deposit", player.UserIDString, (double)credits);
SendMessage(player, "CompletedEconomics", credits);
}
if (config.rewards.useItemBox) {
SendMessage(player, "CompletedInventory");
int amountOfItems = UnityEngine.Random.Range(config.rewards.minItems, config.rewards.maxItems + 1);
BoxStorage box = shopNpcs[NPC].itemsBox;
if (box == null) return;
box.inventory.capacity = amountOfItems;
for (int i = 0; i < amountOfItems; i++) {
ItemDetails itemDetails = GetRandom();
if (itemDetails == null) continue;
ItemDefinition def = ItemManager.FindItemDefinition(itemDetails.shortname);
if (def == null) continue;
Item item = ItemManager.Create(def, UnityEngine.Random.Range(itemDetails.minamount, itemDetails.maxamount + 1), itemDetails.skin);
if (item == null) continue;
item.name = itemDetails.customname;
if (!item.MoveToContainer(box.inventory)) {
item.Remove();
continue;
}
}
}
}
private void FillClerks() {
if (_save.FilledClerks) return;
TerrainMeta.Path.Monuments.ForEach(monument => {
if (monument == null) return;
var transform = monument.transform;
var rot = transform.rotation;
var pos = transform.position;
var pos2 = transform.position;
if (config.fillClerksAtSupermarkets && monument.name.Contains("supermarket_1")) {
pos = pos + rot * config.SupermarketClerkPosition;
pos2 = pos2 + rot * config.SupermarketClerkRotation;
pos.y = TerrainMeta.HeightMap.GetHeight(pos);
pos2.y = TerrainMeta.HeightMap.GetHeight(pos);
_save.NPCData.Add(_save.NPCData.Count, new NPCData() {
position = pos, rotation = pos2
}
);
CreateNPC(_save.NPCData.Count - 1, pos, pos2);
}
if (config.fillClerksAtGas && monument.name.Contains("gas_station_1")) {
pos = pos + rot * config.GasStationClerkPosition;
pos2 = pos2 + rot * config.GasStationClerkRotation;
pos.y = TerrainMeta.HeightMap.GetHeight(pos);
pos2.y = TerrainMeta.HeightMap.GetHeight(pos);
_save.NPCData.Add(_save.NPCData.Count, new NPCData() {
position = pos, rotation = pos2
}
);
CreateNPC(_save.NPCData.Count - 1, pos, pos2);
}
}
);
_save.FilledClerks = true;
SaveData();
}
private void SpawnGaurds(BasePlayer player, BasePlayer NPC, bool start = false) {
if (config.Guards.spawnChance == 0) return;
bool spawn = start ? config.Guards.spawnRobberyStart : config.Guards.spawnRobberyEnd;
if (!spawn) return;
int spawnChance = UnityEngine.Random.Range(0, 100);
if (spawnChance > config.Guards.spawnChance) return;
int amountOfGuards = start ? config.Guards.amountOfGuardsAtStart : config.Guards.amountOfGuardsAtEnd;
if (amountOfGuards <= 0) return;
if (config.Guards.playAlarmSound) {
timer.Repeat(1.5f, 10, () => {
Effect.server.Run(config.Guards.alarmSoundFX, NPC.transform.position);
}
);
}
for (int i = 0; i < amountOfGuards; i++) {
float angle = UnityEngine.Random.Range(0, 2f * Mathf.PI);
Vector3 pos = NPC.ServerPosition + new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * 10;
ScientistNPC npc = GameManager.server.CreateEntity("assets/rust.ai/agents/npcplayer/humannpc/scientist/scientistnpc_full_any.prefab", pos, Quaternion.identity) as ScientistNPC;
if (npc == null) return;
npc.Spawn();
npc.startHealth = config.Guards.guardHP;
npc.displayName = config.Guards.guardName;
npc.damageScale = config.Guards.guardDamageScale;
npc.InitializeHealth(config.Guards.guardHP, config.Guards.guardHP);
NextFrame(() => {
if (npc == null || npc.IsDestroyed) return;
npc.Brain.Navigator.Agent.agentTypeID = -1372625422;
npc.Brain.Navigator.DefaultArea = "Walkable";
npc.Brain.Navigator.Destination = player.transform.position;
npc.Brain.Navigator.Init(npc, npc.Brain.Navigator.Agent);
npc.Brain.ForceSetAge(0);
npc.Brain.states.Remove(AIState.TakeCover);
npc.Brain.states.Remove(AIState.Roam);
npc.Brain.states.Remove(AIState.Chase);
npc.Brain.states.Remove(AIState.Idle);
npc.Brain.states.Remove(AIState.Flee);
npc.Brain.AddState(new TakeCoverState {
brain = npc.Brain, Position = player.transform.position
}
);
npc.Brain.AddState(new RoamState(npc) {
brain = npc.Brain, Position = player.transform.position
}
);
npc.Brain.AddState(new IdleState(npc) {
brain = npc.Brain
}
);
npc.Brain.AddState(new ChaseState(npc) {
brain = npc.Brain
}
);
npc.Brain.Navigator.BestCoverPointMaxDistance = 40;
npc.Brain.Navigator.BestRoamPointMaxDistance = 80;
npc.Brain.Navigator.MaxRoamDistanceFromHome = 80;
npc.Brain.Senses.Init(npc, npc.Brain, 5f, 200f, 205f, -1f, true, true, true, 200f, false, false, true, EntityType.Player, false);
}
);
if (config.Guards.guardDespawnTime == 0) return;
timer.Once(config.Guards.guardDespawnTime, () => {
if (npc == null) return;
npc.Kill();
}
);
}
}
#endregion
#region Overrides (Bradley Guards)
public class RoamState : ScientistBrain.BasicAIState {
private readonly float _maxRoamRadius = 10f;
private readonly ScientistNPC _npc;
private StateStatus status = StateStatus.Error;
public Vector3 Position;
public RoamState(ScientistNPC npc) : base(AIState.Roam) {
_npc = npc;
}
public override float GetWeight() => 0.0f;
public override void StateEnter(BaseAIBrain brain, BaseEntity entity) {
base.StateEnter(brain, entity);
status = StateStatus.Error;
if (brain.Navigator.SetDestination(Position, BaseNavigator.NavigationSpeed.Slow)) status = StateStatus.Running;
_npc.SetPlayerFlag(BasePlayer.PlayerFlags.Relaxed, true);
}
public override void StateLeave(BaseAIBrain brain, BaseEntity entity) {
base.StateLeave(brain, entity);
Stop();
_npc.SetPlayerFlag(BasePlayer.PlayerFlags.Relaxed, false);
}
public override StateStatus StateThink(float delta, BaseAIBrain brain, BaseEntity entity) {
base.StateThink(delta, brain, entity);
if (Vector3.Distance(entity.transform.position, Position) >= _maxRoamRadius) brain.Navigator.SetDestination(Position, BaseNavigator.NavigationSpeed.Fast);
else if (!brain.Navigator.Moving) brain.Navigator.SetDestination(GetRoamPosition(entity), BaseNavigator.NavigationSpeed.Slowest);
return StateStatus.Running;
}
private void Stop() => brain.Navigator.Stop();
private Vector3 GetRoamPosition(BaseEntity entity) {
Vector3 positionAround = brain.PathFinder.GetRandomPositionAround(Position, 0f, _maxRoamRadius - 2f < 0f ? 0f : _maxRoamRadius - 2f);
NavMeshHit meshHit;
if (NavMesh.SamplePosition(positionAround, out meshHit, 2f, _npc.NavAgent.areaMask)) {
NavMeshPath path = new NavMeshPath();
if (NavMesh.CalculatePath(entity.transform.position, meshHit.position, _npc.NavAgent.areaMask, path)) positionAround = path.status == NavMeshPathStatus.PathComplete ? meshHit.position : path.corners.Last();
else positionAround = Position;
}
else positionAround = Position;
return positionAround;
}
}
public class IdleState : ScientistBrain.BasicAIState {
private readonly ScientistNPC _npc;
public IdleState(ScientistNPC npc) : base(AIState.Idle) {
_npc = npc;
}
public override float GetWeight() => 50f;
public override void StateEnter(BaseAIBrain brain, BaseEntity entity) {
base.StateEnter(brain, entity);
_npc.SetPlayerFlag(BasePlayer.PlayerFlags.Relaxed, true);
}
public override void StateLeave(BaseAIBrain brain, BaseEntity entity) {
base.StateLeave(brain, entity);
_npc.SetPlayerFlag(BasePlayer.PlayerFlags.Relaxed, false);
}
}
public class ChaseState : ScientistBrain.BasicAIState {
private StateStatus status = StateStatus.Error;
private float nextPositionUpdateTime;
public ChaseState(ScientistNPC npc) : base(AIState.Chase) {
AgrresiveState = true;
}
public override void StateEnter(BaseAIBrain brain, BaseEntity entity) {
base.StateEnter(brain, entity);
status = StateStatus.Error;
if (brain.PathFinder == null) return;
status = StateStatus.Running;
nextPositionUpdateTime = 0.0f;
}
public override void StateLeave(BaseAIBrain brain, BaseEntity entity) {
base.StateLeave(brain, entity);
Stop();
}
public override StateStatus StateThink(float delta, BaseAIBrain brain, BaseEntity entity) {
if (status == StateStatus.Error) return status;
BaseEntity baseEntity = brain.Events.Memory.Entity.Get(brain.Events.CurrentInputMemorySlot);
if (baseEntity == null) return StateStatus.Error;
float distance = Vector3.Distance(entity.transform.position, baseEntity.transform.position);
if (brain.Senses.Memory.IsLOS(baseEntity) || (double)distance <= brain.Navigator.MaxRoamDistanceFromHome) brain.Navigator.SetFacingDirectionEntity(baseEntity);
else brain.Navigator.ClearFacingDirectionOverride();
brain.Navigator.SetCurrentSpeed(distance <= brain.Navigator.MaxRoamDistanceFromHome ? BaseNavigator.NavigationSpeed.Normal : BaseNavigator.NavigationSpeed.Fast);
if (Time.time > nextPositionUpdateTime) {
nextPositionUpdateTime = Time.time + UnityEngine.Random.Range(0.5f, 1f);
brain.Navigator.SetDestination(baseEntity.transform.position, BaseNavigator.NavigationSpeed.Normal);
}
return brain.Navigator.Moving ? StateStatus.Running : StateStatus.Finished;
}
private void Stop() {
brain.Navigator.Stop();
brain.Navigator.ClearFacingDirectionOverride();
}
}
public class TakeCoverState : ScientistBrain.BasicAIState {
private StateStatus status = StateStatus.Error;
private BaseEntity coverFromEntity;
public Vector3 Position;
public TakeCoverState() : base(AIState.TakeCover) {
}
public override void StateEnter(BaseAIBrain brain, BaseEntity entity) {
base.StateEnter(brain, entity);
status = StateStatus.Running;
if (StartMovingToCover()) return;
status = StateStatus.Error;
}
publ
// ... [Code preview truncated due to length. Full source in attached file] ...