C#:
using Facepunch;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
namespace Oxide.Plugins {
[Info("Raidable Bases", "nivex", "1.0.8")]
[Description("Create fully automated raidable bases with npcs.")]
class RaidableBases : RustPlugin {
[PluginReference]
private Plugin DangerousTreasures, Vanish, LustyMap, ZoneManager, Economics, ServerRewards, Map, GUIAnnouncements, CopyPaste, Friends, Clans, Kits, TruePVE, Spawns, NightLantern, Wizardry;
protected static SingletonBackbone Backbone {
get;
set;
}
protected Dictionary<int, List<BaseEntity>> Bases {
get;
}
= new Dictionary<int, List<BaseEntity>>();
protected Dictionary<int, RaidableBase> Raids {
get;
}
= new Dictionary<int, RaidableBase>();
protected List<uint> NetworkList {
get;
set;
}
= new List<uint>();
protected Dictionary<ulong, Timer> PvpDelay {
get;
}
= new Dictionary<ulong, Timer>();
private Dictionary<string, List<ulong>> Skins {
get;
}
= new Dictionary<string, List<ulong>>();
private Dictionary<string, List<ulong>> WorkshopSkins {
get;
}
= new Dictionary<string, List<ulong>>();
private Dictionary<MonumentInfo, float> monuments {
get;
set;
}
= new Dictionary<MonumentInfo, float>();
private Dictionary<Vector3, float> managedZones {
get;
set;
}
= new Dictionary<Vector3, float>();
private Dictionary<int, MapInfo> mapMarkers {
get;
set;
}
= new Dictionary<int, MapInfo>();
private Dictionary<int, string> lustyMarkers {
get;
set;
}
= new Dictionary<int, string>();
protected Dictionary<RaidableType, RaidableSpawns> raidSpawns {
get;
set;
}
= new Dictionary<RaidableType, RaidableSpawns>();
protected Dictionary<string, float> buyCooldowns {
get;
set;
}
= new Dictionary<string, float>();
protected List<int> AvailableDifficulties {
get;
set;
}
= new List<int>();
private DynamicConfigFile dataFile {
get;
set;
}
private DynamicConfigFile uidsFile {
get;
set;
}
private StoredData storedData {
get;
set;
}
= new StoredData();
protected Coroutine despawnCoroutine {
get;
set;
}
protected Coroutine maintainCoroutine {
get;
set;
}
protected Coroutine scheduleCoroutine {
get;
set;
}
protected Coroutine gridCoroutine {
get;
set;
}
private Stopwatch gridStopwatch {
get;
}
= new Stopwatch();
private StringBuilder _sb {
get;
}
= new StringBuilder();
protected float Radius {
get;
}
= 25f;
private bool wiped {
get;
set;
}
private float lastSpawnRequestTime {
get;
set;
}
private float gridTime {
get;
set;
}
private bool IsUnloading {
get;
set;
}
public class ResourcePath {
public List<uint> Blocks {
get;
}
public ItemDefinition BoxDefinition {
get;
}
public string ExplosionMarker {
get;
}
public string CodeLock {
get;
}
public string Fireball {
get;
}
public string HighExternalWoodenWall {
get;
}
public string HighExternalStoneWall {
get;
}
public string Ladder {
get;
}
public string Murderer {
get;
}
public string RadiusMarker {
get;
}
public string Sphere {
get;
}
public string Scientist {
get;
}
public string VendingMarker {
get;
}
public ResourcePath() {
Blocks = new List<uint> {
803699375, 2194854973, 919059809, 3531096400, 310235277, 2326657495, 3234260181, 72949757
}
;
BoxDefinition = ItemManager.FindItemDefinition(StringPool.Get(2735448871));
CodeLock = StringPool.Get(3518824735);
ExplosionMarker = StringPool.Get(4060989661);
Fireball = StringPool.Get(2086405370);
//3550347674
HighExternalWoodenWall = StringPool.Get(1745077396);
HighExternalStoneWall = StringPool.Get(1585379529);
Ladder = StringPool.Get(2150203378);
Murderer = StringPool.Get(3879041546);
RadiusMarker = StringPool.Get(2849728229);
Sphere = StringPool.Get(3211242734);
Scientist = StringPool.Get(4223875851);
VendingMarker = StringPool.Get(3459945130);
}
}
public class SingletonBackbone : SingletonComponent<SingletonBackbone> {
public RaidableBases Plugin {
get;
private set;
}
public Oxide.Core.Libraries.Lang lang => Plugin.lang;
private StringBuilder sb => Plugin._sb;
public ResourcePath Path;
public SingletonBackbone(RaidableBases plugin) {
Plugin = plugin;
Path = new ResourcePath();
}
public void Destroy() {
foreach (var timer in Plugin.PvpDelay.Values) {
if (timer == null || timer.Destroyed) {
continue;
}
timer.Destroy();
}
Path = null;
Plugin = null;
DestroyImmediate(Instance);
}
public void Message(BasePlayer player, string key, string id, params object[] args) {
if (player.IsValid()) {
Plugin.Player.Message(player, GetMessage(key, id, args), _config.Settings.ChatID);
}
}
public string GetMessage(string key, string id = null, params object[] args) {
sb.Length = 0;
if (_config.EventMessages.Prefix && id != "server_console" && id != null) {
sb.Append(lang.GetMessage("Prefix", Plugin, id));
}
sb.Append(id == "server_console" || id == null ? RemoveFormatting(lang.GetMessage(key, Plugin, id)) : lang.GetMessage(key, Plugin, id));
return args.Length > 0 ? string.Format(sb.ToString(), args) : sb.ToString();
}
public string RemoveFormatting(string source) => source.Contains(">") ? Regex.Replace(source, "<.*?>", string.Empty) : source;
public Timer Timer(float seconds, Action action) => Plugin.timer.Once(seconds, action);
}
public class Elevation {
public float Min {
get;
set;
}
public float Max {
get;
set;
}
}
public class RaidableSpawnLocation {
public Elevation Elevation = new Elevation();
public Vector3 Location = Vector3.zero;
}
public class RaidableSpawns {
private readonly List<RaidableSpawnLocation> Spawns = new List<RaidableSpawnLocation>();
private readonly List<RaidableSpawnLocation> Cache = new List<RaidableSpawnLocation>();
public void Add(RaidableSpawnLocation rsl) {
Spawns.Add(rsl);
}
public void AddRange() {
if (Cache.Count > 0) {
Spawns.AddRange(new List<RaidableSpawnLocation>(Cache));
Cache.Clear();
}
}
public IEnumerable<RaidableSpawnLocation> All {
get {
if (Cache.Count > 0) {
return Spawns.Union(Cache);
}
else return Spawns;
}
}
public void Check() {
if (Spawns.Count == 0) {
AddRange();
}
}
public void Clear() {
Spawns.Clear();
Cache.Clear();
}
public int Count {
get {
return Spawns.Count;
}
}
public RaidableSpawnLocation GetRandom() {
var rsl = Spawns.GetRandom();
Remove(rsl);
return rsl;
}
private void Remove(RaidableSpawnLocation a) {
Spawns.Remove(a);
Cache.Add(a);
}
public void RemoveNear(RaidableSpawnLocation a, float radius) {
var list = new List<RaidableSpawnLocation>(Spawns);
foreach (var b in list) {
if (Distance2D(a.Location, b.Location) <= radius) {
Remove(b);
}
}
list.Clear();
}
public RaidableSpawns(List<RaidableSpawnLocation> spawns) {
Spawns = spawns;
}
public RaidableSpawns() {
}
}
private class MapInfo {
public string Url;
public string IconName;
public Vector3 Position;
}
private class PlayerInfo {
public int TotalRaids {
get;
set;
}
public int Raids {
get;
set;
}
public PlayerInfo() {
}
}
private class StoredData {
public Dictionary<string, PlayerInfo> Players {
get;
}
= new Dictionary<string, PlayerInfo>();
public double SecondsUntilRaid {
get;
set;
}
= double.MinValue;
public int TotalEvents {
get;
set;
}
public StoredData() {
}
}
private void OnPluginLoaded(Plugin plugin) {
switch (plugin.Title) {
case "Dangerous Treasures" : {
DangerousTreasures = plugin;
if (DangerousTreasures.Version < new VersionNumber(1, 4, 1)) {
DangerousTreasures = null;
}
break;
}
case "Vanish" : {
Vanish = plugin;
break;
}
case "Wizardry" : {
Wizardry = plugin;
break;
}
case "Night Lantern" : {
NightLantern = plugin;
break;
}
case "Spawns" : {
Spawns = plugin;
break;
}
case "TruePVE" : {
TruePVE = plugin;
break;
}
case "LustyMap" : {
LustyMap = plugin;
break;
}
case "ZoneManager" : {
ZoneManager = plugin;
break;
}
case "Economics" : {
Economics = plugin;
break;
}
case "ServerRewards" : {
ServerRewards = plugin;
break;
}
case "Map" : {
Map = plugin;
break;
}
case "GUIAnnouncements" : {
GUIAnnouncements = plugin;
break;
}
case "CopyPaste" : {
CopyPaste = plugin;
break;
}
case "Clans" : {
Clans = plugin;
break;
}
case "Friends" : {
Friends = plugin;
break;
}
case "Kits" : {
Kits = plugin;
break;
}
}
}
private void OnPluginUnloaded(Plugin plugin) {
switch (plugin.Title) {
case "Dangerous Treasures" : {
DangerousTreasures = null;
break;
}
case "Vanish" : {
Vanish = null;
break;
}
case "Wizardry" : {
Wizardry = null;
break;
}
case "Night Lantern" : {
NightLantern = null;
break;
}
case "Spawns" : {
Spawns = null;
break;
}
case "TruePVE" : {
TruePVE = null;
break;
}
case "LustyMap" : {
LustyMap = null;
break;
}
case "ZoneManager" : {
ZoneManager = null;
break;
}
case "Economics" : {
Economics = null;
break;
}
case "ServerRewards" : {
ServerRewards = null;
break;
}
case "Map" : {
Map = null;
break;
}
case "GUIAnnouncements" : {
GUIAnnouncements = null;
break;
}
case "CopyPaste" : {
CopyPaste = null;
break;
}
case "Clans" : {
Clans = null;
break;
}
case "Friends" : {
Friends = null;
break;
}
case "Kits" : {
Kits = null;
break;
}
}
}
private class PlayWithFire : FacepunchBehaviour {
private FireBall fireball {
get;
set;
}
private BaseEntity target {
get;
set;
}
private bool fireFlung {
get;
set;
}
private Coroutine mcCoroutine {
get;
set;
}
public BaseEntity Target {
get {
return target;
}
set {
target = value;
enabled = true;
}
}
private void Awake() {
fireball = GetComponent<FireBall>();
enabled = false;
}
private void FixedUpdate() {
if (!IsValid(target) || target.IsDestroyed || target.Health() <= 0) {
fireball.Extinguish();
Destroy(this);
return;
}
fireball.transform.RotateAround(target.transform.position, Vector3.up, 5f);
fireball.transform.hasChanged = true;
}
public void FlingFire(BaseEntity attacker) {
if (fireFlung) return;
fireFlung = true;
mcCoroutine = StartCoroutine(MakeContact(attacker));
}
private IEnumerator MakeContact(BaseEntity attacker) {
float distance = Vector3.Distance(fireball.ServerPosition, attacker.transform.position);
while (!Backbone.Plugin.IsUnloading && attacker != null && fireball != null && !fireball.IsDestroyed && Distance2D(fireball.ServerPosition, attacker.transform.position) > 2.5f) {
fireball.ServerPosition = Vector3.MoveTowards(fireball.ServerPosition, attacker.transform.position, distance * 0.1f);
yield return Coroutines.WaitForSeconds(0.3f);
}
}
private void OnDestroy() {
if (mcCoroutine != null) {
StopCoroutine(mcCoroutine);
mcCoroutine = null;
}
Destroy(this);
}
}
public enum RaidableType {
None = 0, Manual = 1, Scheduled = 2, Purchased = 3, Maintained = 4, Grid = 5
}
public class PlayerInputEx : FacepunchBehaviour {
public BasePlayer player {
get;
set;
}
private InputState input {
get;
set;
}
private RaidableBase raid {
get;
set;
}
private void Awake() {
player = GetComponent<BasePlayer>();
input = player.serverInput;
}
public void Setup(RaidableBase raid) {
this.raid = raid;
raid.Inputs.Add(this);
InvokeRepeating(Repeater, 0f, 0.1f);
}
private void Repeater() {
if (!player || !player.IsConnected || player.inventory == null || player.inventory.containerBelt == null || player.IsDead() || raid == null) {
if (raid != null && raid.IsPayLocked && raid.IsOpened) {
raid.TryInvokeResetOwner();
}
Destroy(this);
return;
}
if (player.svActiveItemID == 0) {
return;
}
if (!input.WasJustReleased(BUTTON.FIRE_PRIMARY) && !input.IsDown(BUTTON.FIRE_PRIMARY)) {
return;
}
Item item = player.GetActiveItem();
if (item?.info.shortname != "ladder.wooden.wall") {
return;
}
RaycastHit hit;
if (!Physics.Raycast(player.eyes.HeadRay(), out hit, 4f, Layers.Mask.Construction, QueryTriggerInteraction.Ignore)) {
return;
}
var block = hit.GetEntity();
if (!IsValid(block) || block.OwnerID != 0 || !Backbone.Path.Blocks.Contains(block.prefabID) || !Backbone.Plugin.NetworkList.Contains(block.net.ID)) // walls and foundations
{
return;
}
int amount = item.amount;
var action = new Action(() => {
if (raid == null || item?.amount != amount || IsLadderNear(hit.point)) {
return;
}
//* Quaternion.Euler(0f, planner.transform.eulerAngles.y, 0f) * Quaternion.Euler(???);
var rot = Quaternion.LookRotation(hit.normal, Vector3.up);
var e = GameManager.server.CreateEntity(Backbone.Path.Ladder, hit.point, rot, true);
// as BaseLadder;
if (e == null) {
Destroy(this);
return;
}
e.gameObject.SendMessage("SetDeployedBy", player, SendMessageOptions.DontRequireReceiver);
e.OwnerID = 0;
e.Spawn();
item.UseItem(1);
var planner = item.GetHeldEntity() as Planner;
var deployable = planner.GetDeployable();
if (deployable != null && deployable.setSocketParent && block.SupportsChildDeployables()) {
e.SetParent(block, true, false);
}
Backbone.Plugin.NetworkList.Add(e.net.ID);
}
);
player.Invoke(action, 0.1f);
}
public bool IsLadderNear(Vector3 target) {
int hits = Physics.OverlapSphereNonAlloc(target, 0.3f, Vis.colBuffer, Layers.Mask.Deployed, QueryTriggerInteraction.Ignore);
bool flag = false;
for (int i = 0; i < hits; i++) {
if (Vis.colBuffer[i].name == Backbone.Path.Ladder) {
flag = true;
}
Vis.colBuffer[i] = null;
}
return flag;
}
private void OnDestroy() {
if (raid != null) {
raid.Inputs.Remove(this);
}
CancelInvoke();
Destroy(this);
}
}
private class FinalDestination : FacepunchBehaviour {
public NPCPlayerApex apex;
Vector3 lastPosition;
List<Vector3> list;
void Awake() {
apex = GetComponent<NPCPlayerApex>();
}
void OnDestroy() {
StopAllCoroutines();
Destroy(this);
}
public void Set(List<Vector3> list) {
lastPosition = apex.transform.position;
this.list = list;
StartCoroutine(Go());
}
IEnumerator Go() {
while (true) {
if (apex.AttackTarget == null) {
var position = list.GetRandom();
if (apex.IsStuck) {
apex.Pause();
apex.ServerPosition = position;
apex.GetNavAgent.Warp(position);
apex.stuckDuration = 0f;
apex.IsStuck = false;
apex.Resume();
}
if (apex.GetNavAgent == null || !apex.GetNavAgent.isOnNavMesh) {
apex.finalDestination = position;
}
else apex.GetNavAgent.SetDestination(position);
apex.IsStopped = false;
apex.Destination = position;
lastPosition = position;
}
yield return Coroutines.WaitForSeconds(10f);
}
}
}
public class RaidableBase : FacepunchBehaviour {
public readonly Hash<uint, float> conditions = new Hash<uint, float>();
private Dictionary<string, List<string>> _clans {
get;
set;
}
= new Dictionary<string, List<string>>();
private Dictionary<string, List<string>> _friends {
get;
set;
}
= new Dictionary<string, List<string>>();
public List<StorageContainer> _containers {
get;
set;
}
= new List<StorageContainer>();
public List<BuildingPrivlidge> privs {
get;
set;
}
= new List<BuildingPrivlidge>();
public List<PlayerInputEx> Inputs {
get;
set;
}
= new List<PlayerInputEx>();
public List<NPCPlayerApex> npcs {
get;
set;
}
= new List<NPCPlayerApex>();
public List<BasePlayer> raiders {
get;
set;
}
= new List<BasePlayer>();
private List<BasePlayer> intruders {
get;
set;
}
= new List<BasePlayer>();
private List<FireBall> fireballs {
get;
set;
}
= new List<FireBall>();
private List<ulong> allies {
get;
set;
}
= new List<ulong>();
private List<Vector3> foundations {
get;
set;
}
= new List<Vector3>();
private List<SphereEntity> spheres {
get;
set;
}
= new List<SphereEntity>();
private List<BaseEntity> lights {
get;
set;
}
= new List<BaseEntity>();
private List<BaseOven> ovens {
get;
set;
}
= new List<BaseOven>();
private List<AutoTurret> turrets {
get;
set;
}
= new List<AutoTurret>();
private List<string> treasureItems {
get;
}
= new List<string>();
private List<BaseEntity> weapons {
get;
set;
}
= new List<BaseEntity>();
private Dictionary<string, List<string>> npcKits {
get;
set;
}
private List<ulong> friends {
get;
set;
}
= new List<ulong>();
private MapMarkerExplosion explosionMarker {
get;
set;
}
private MapMarkerGenericRadius genericMarker {
get;
set;
}
private VendingMachineMapMarker vendingMarker {
get;
set;
}
private Coroutine setupRoutine {
get;
set;
}
= null;
private bool IsInvokingCanFinish {
get;
set;
}
public bool selfDestruct {
get;
set;
}
public Vector3 PastedLocation {
get;
set;
}
public Vector3 Location {
get;
set;
}
public string BaseName {
get;
set;
}
public int BaseIndex {
get;
set;
}
= -1;
public uint NetworkID {
get;
set;
}
= uint.MaxValue;
public BasePlayer owner {
get;
set;
}
public float OwnerLastHitTime {
get;
set;
}
public float despawnTime {
get;
set;
}
private ulong skinId {
get;
set;
}
public bool AllowPVP {
get;
set;
}
public BuildingOptions Options {
get;
set;
}
public bool IsAuthed {
get;
set;
}
public bool IsOpened {
get;
set;
}
= true;
public bool IsUnloading {
get;
set;
}
public int uid {
get;
set;
}
public bool IsPayLocked {
get;
set;
}
public int npcSpawnedAmount {
get;
set;
}
public RaidableType Type {
get;
set;
}
public string DifficultyMode {
get;
set;
}
public bool IsLooted => CanUndo(_containers);
public bool IsLoading => setupRoutine != null;
public bool IsOwnerLocked => IsPayLocked || IsOwnerActive;
private float Radius {
get;
}
= 25f;
private bool markerCreated {
get;
set;
}
private bool lightsOn {
get;
set;
}
private bool killed {
get;
set;
}
private ItemComparerer itemComparer {
get;
}
= new ItemComparerer();
public class ItemComparerer : IEqualityComparer<TreasureItem> {
public bool Equals(TreasureItem x, TreasureItem y) {
return x != null && y != null && x.GetHashCode() == y.GetHashCode();
}
public int GetHashCode(TreasureItem obj) {
return obj.GetHashCode();
}
}
private bool IsOwnerActive {
get {
if (IsPayLocked) {
return true;
}
bool inactive = _config.Settings.Management.LockTime <= 0 ? false : Time.realtimeSinceStartup - OwnerLastHitTime > _config.Settings.Management.LockTime;
if (owner == null || !owner.IsConnected || Distance2D(owner.transform.position, Location) > _config.Settings.Management.MaxOwnerDistance || inactive) {
if (owner != null) {
owner = null;
UpdateMarker();
}
}
return owner != null;
}
}
private void OnTriggerEnter(Collider col) {
var m = col?.ToBaseEntity() as BaseMountable;
if (m.IsValid() && RemoveMountable(m)) {
return;
}
var p = col?.ToBaseEntity() as BasePlayer;
if (!p.IsValid() || p.IsNpc) {
return;
}
if (!intruders.Contains(p)) {
intruders.Add(p);
}
Protector();
if (!intruders.Contains(p)) {
return;
}
if (!p.GetComponent<PlayerInputEx>()) {
p.gameObject.AddComponent<PlayerInputEx>().Setup(this);
}
StopUsingWand(p);
if (_config.EventMessages.AnnounceEnterExit) {
Backbone.Message(p, AllowPVP ? "OnPlayerEntered" : "OnPlayerEnteredPVE", p.UserIDString);
}
}
private void OnTriggerExit(Collider col) {
if (_config.Settings.Management.PVPDelay <= 0 || !AllowPVP) {
return;
}
var p = col?.ToBaseEntity() as BasePlayer;
if (!p.IsValid()) {
return;
}
var component = p.GetComponent<PlayerInputEx>();
if (component) {
Destroy(component);
}
if (!intruders.Contains(p)) {
return;
}
intruders.Remove(p);
if (Backbone.Plugin.TruePVE == null) {
return;
}
ulong id = p.userID;
Timer timer;
if (!Backbone.Plugin.PvpDelay.TryGetValue(id, out timer)) {
if (!p.IsNpc && _config.EventMessages.AnnounceEnterExit) {
Backbone.Message(p, "DoomAndGloom", p.UserIDString, "PVP", _config.Settings.Management.PVPDelay);
}
Backbone.Plugin.PvpDelay[id] = timer = Backbone.Timer(_config.Settings.Management.PVPDelay, () => Backbone.Plugin.PvpDelay.Remove(id));
return;
}
timer.Reset();
}
private void Protector() {
if (!CanEject()) {
return;
}
var targets = new List<BasePlayer>(intruders);
if (targets.Count == 0) {
return;
}
foreach (var target in targets) {
if (target == owner || friends.Contains(target.userID) || target.IsAdmin) {
continue;
}
if (!IsAlly(target)) {
intruders.Remove(target);
RemovePlayer(target);
}
else friends.Add(target.userID);
}
targets.Clear();
}
private void OnDestroy() {
Despawn();
Destroy(this);
}
public void Despawn() {
IsOpened = false;
if (killed) return;
killed = true;
CancelInvoke();
DestroyFire();
DestroyInputs();
RemoveSpheres();
EnableBags();
KillNpc();
StopAllCoroutines();
RemoveMapMarkers();
if (!IsUnloading) {
ServerMgr.Instance.StartCoroutine(Backbone.Plugin.UndoRoutine(BaseIndex));
}
Backbone.Plugin.Raids.Remove(uid);
if (Backbone.Plugin.Raids.Count == 0) {
if (IsUnloading) {
UnsetStatics();
}
else Backbone.Plugin.UnsubscribeHooks();
}
Destroy(this);
}
private void FillAmmoTurret(AutoTurret turret) {
var attachedWeapon = turret.GetAttachedWeapon();
if (attachedWeapon != null) {
if (!HasAmmo(turret.inventory, attachedWeapon.primaryMagazine.ammoType)) {
Item item = ItemManager.Create(attachedWeapon.primaryMagazine.ammoType, _config.Weapons.Ammo.AutoTurret);
if (!item.MoveToContainer(turret.inventory)) {
item.Remove();
}
}
attachedWeapon.primaryMagazine.contents = attachedWeapon.primaryMagazine.capacity;
attachedWeapon.SendNetworkUpdateImmediate();
turret.UpdateTotalAmmo();
}
}
private bool HasAmmo(ItemContainer container, ItemDefinition ammoType) {
foreach (Item item in container.itemList) {
if (item.info == ammoType) {
return true;
}
}
return false;
}
private void FillAmmoGunTrap(GunTrap gt) {
if (gt.ammoType != null && gt.inventory.itemList.Count == 0) {
Item item = ItemManager.Create(gt.ammoType, _config.Weapons.Ammo.GunTrap);
if (!item.MoveToContainer(gt.inventory)) {
item.Remove();
}
}
}
private void FillAmmoFogMachine(FogMachine fm) {
if (!fm.HasFuel()) {
var ammoType = ItemManager.FindItemDefinition("lowgradefuel");
if (ammoType != null) {
Item item = ItemManager.Create(ammoType, _config.Weapons.Ammo.FogMachine);
if (!item.MoveToContainer(fm.inventory)) {
item.Remove();
}
}
}
}
private void FillAmmoFlameTurret(FlameTurret ft) {
if (!ft.HasFuel()) {
var ammoType = ItemManager.FindItemDefinition("lowgradefuel");
if (ammoType != null) {
Item item = ItemManager.Create(ammoType, _config.Weapons.Ammo.FlameTurret);
if (!item.MoveToContainer(ft.inventory)) {
item.Remove();
}
}
}
}
private void FillAmmoSamSite(SamSite ss) {
if (!ss.HasAmmo()) {
Item item = ItemManager.Create(ss.ammoType, _config.Weapons.Ammo.SamSite);
if (!item.MoveToContainer(ss.inventory)) {
item.Remove();
}
}
}
private void OnWeaponItemAddedRemoved(Item item, bool bAdded) {
if (bAdded) {
return;
}
weapons.RemoveAll(x => !x.IsValid() || x.IsDestroyed);
foreach (var weapon in weapons) {
if (weapon is AutoTurret) {
weapon.Invoke(() => FillAmmoTurret(weapon as AutoTurret), 0.1f);
}
else if (weapon is GunTrap) {
weapon.Invoke(() => FillAmmoGunTrap(weapon as GunTrap), 0.1f);
}
else if (weapon is SamSite) {
weapon.Invoke(() => FillAmmoSamSite(weapon as SamSite), 0.1f);
}
}
}
private void SetupContainers() {
_containers.RemoveAll(x => !x.IsValid() || x.IsDestroyed);
foreach (var container in _containers) {
if (container.inventory == null) continue;
container.inventory.onItemAddedRemoved += new Action<Item, bool>(OnItemAddedRemoved);
}
}
private void OnItemAddedRemoved(Item item, bool bAdded) {
if (!bAdded) {
Check();
}
}
public void Check() {
if (!IsInvokingCanFinish) {
IsInvokingCanFinish = true;
InvokeRepeating(TryToEnd, 0f, 1f);
}
}
private void TryToEnd() {
if (IsOpened && IsLooted) {
CancelInvoke(TryToEnd);
AwardRaiders();
Undo();
}
}
private void AwardRaiders() {
if (_config.Settings.RemoveAdminRaiders) {
raiders.RemoveAll(x => !x || x.IsAdmin);
}
else raiders.RemoveAll(x => !x);
if (raiders.Count == 0) {
return;
}
if (Options.Levels.Level2) {
SpawnNpcs();
}
HandleAwards();
string thieves = string.Join(", ", raiders.Select(x => x.displayName));
string posStr = FormatGridReference(Location);
Backbone.Plugin.Puts(Backbone.GetMessage("Thief", null, posStr, thieves));
if (_config.EventMessages.AnnounceThief) {
foreach (var target in BasePlayer.activePlayerList) {
Backbone.Message(target, "Thief", target.UserIDString, posStr, thieves);
}
}
raiders.Clear();
Backbone.Plugin.SaveData();
}
private void HandleAwards() {
foreach (var raider in raiders) {
if (_config.RankedLadder.Enabled) {
PlayerInfo playerInfo;
if (!Backbone.Plugin.storedData.Players.TryGetValue(raider.UserIDString, out playerInfo)) {
Backbone.Plugin.storedData.Players[raider.UserIDString] = playerInfo = new PlayerInfo();
}
playerInfo.TotalRaids++;
playerInfo.Raids++;
}
if (Options.Rewards.Money > 0 && Backbone.Plugin.Economics != null && Backbone.Plugin.Economics.IsLoaded) {
Backbone.Plugin.Economics.Call("Deposit", raider.UserIDString, Options.Rewards.Money);
Backbone.Message(raider, "EconomicsDeposit", raider.UserIDString, Options.Rewards.Money);
}
if (Options.Rewards.Points > 0 && Backbone.Plugin.ServerRewards != null && Backbone.Plugin.ServerRewards.IsLoaded) {
Backbone.Plugin.ServerRewards.Call("AddPoints", raider.userID, Options.Rewards.Points);
Backbone.Message(raider, "ServerRewardPoints", raider.UserIDString, Options.Rewards.Points);
}
}
}
public string Mode() {
if (owner.IsValid()) {
return string.Format("{0} {1}", owner.displayName, DifficultyMode.SentenceCase());
}
return DifficultyMode.SentenceCase();
}
public void TrySetPayLock(BasePlayer player) {
if (player.IsValid() && player.IsConnected) {
IsPayLocked = true;
owner = player;
}
}
public void TrySetOwner(BasePlayer attacker, BaseEntity entity, HitInfo hitInfo) {
if (!_config.Settings.Management.UseOwners || IsOwnerLocked) {
return;
}
if (owner.IsValid() && owner.userID != attacker.userID) {
return;
}
if (_config.Settings.Management.BypassUseOwnersForPVP && AllowPVP) {
return;
}
if (_config.Settings.Management.BypassUseOwnersForPVE && !AllowPVP) {
return;
}
if (entity is NPCPlayerApex) {
TrySetOwner(attacker);
return;
}
if (hitInfo == null || hitInfo.damageTypes == null || (!(entity is BuildingBlock) && !(entity is Door))) {
return;
}
if (hitInfo.damageTypes.Has(DamageType.Explosion) || hitInfo.damageTypes.Has(DamageType.Blunt) || hitInfo.damageTypes.Has(DamageType.Stab)) {
TrySetOwner(attacker);
}
}
private void TrySetOwner(BasePlayer player) {
if (owner.IsValid() && player.userID == owner.userID) {
OwnerLastHitTime = Time.realtimeSinceStartup;
}
if (!IsOwnerLocked) {
OwnerLastHitTime = Time.realtimeSinceStartup;
owner = player;
UpdateMarker();
}
}
private float lastCheckTime;
public void CheckDespawn() {
if (_config.Settings.Management.DespawnMinutesInactive <= 0 || selfDestruct) {
return;
}
if (lastCheckTime != 0 && Time.realtimeSinceStartup - lastCheckTime < 60f) {
return;
}
lastCheckTime = Time.realtimeSinceStartup;
if (IsInvoking(Despawn)) {
CancelInvoke(Despawn);
}
float time = _config.Settings.Management.DespawnMinutesInactive * 60f;
despawnTime = Time.realtimeSinceStartup + time;
Invoke(Despawn, time);
UpdateMarker();
}
public bool CanUndo(List<StorageContainer> containers) {
containers.RemoveAll(x => !x.IsValid() || x.IsDestroyed || x.inventory == null);
foreach (var container in containers) {
if (container.inventory.itemList.Count > 0) {
return false;
}
}
return true;
}
private bool CanPlayerBeLooted() {
if (!_config.Settings.Management.PlayersLootableInPVE && !AllowPVP) {
return false;
}
else if (!_config.Settings.Management.PlayersLootableInPVP && AllowPVP) {
return false;
}
return true;
}
private bool CanBeLooted(BasePlayer player, BaseEntity e) {
if (e is NPCPlayerCorpse) {
return true;
}
if (e is LootableCorpse) {
var corpse = e as LootableCorpse;
if (!corpse.playerSteamID.IsSteamId() || corpse.playerSteamID == player.userID || corpse.playerName == player.displayName) {
return true;
}
return CanPlayerBeLooted();
}
else if (e is DroppedItemContainer) {
var container = e as DroppedItemContainer;
if (!container.playerSteamID.IsSteamId() || container.playerSteamID == player.userID || container.playerName == player.displayName) {
return true;
}
return CanPlayerBeLooted();
}
if (e is GunTrap || e is FlameTurret || e is FogMachine || e is SamSite || e is AutoTurret) {
// ... [Code preview truncated due to length. Full source in attached file] ...