mirror of https://github.com/bmgjet/PirateNPCs.git
5362 lines
295 KiB
C#
5362 lines
295 KiB
C#
using Facepunch;
|
|
using Network;
|
|
using Oxide.Core;
|
|
using Oxide.Core.Libraries;
|
|
using Oxide.Core.Plugins;
|
|
using ProtoBuf;
|
|
using Rust;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.SceneManagement;
|
|
using Physics = UnityEngine.Physics;
|
|
using Pool = Facepunch.Pool;
|
|
using Time = UnityEngine.Time;
|
|
|
|
namespace Oxide.Plugins
|
|
{
|
|
[Info("PirateNPC", "bmgjet", "0.0.8")]
|
|
[Description("Creates NPC To Patrol Ocean,Skies and Land")]
|
|
class PirateNPC : RustPlugin
|
|
{
|
|
#region Variables
|
|
|
|
[PluginReference]
|
|
private Plugin Kits;
|
|
private int piratePlane = 0;
|
|
private int pirateRHIB = 0;
|
|
private int pirateRowBoat = 0;
|
|
private int pirateSub = 0;
|
|
private int piratesMini = 0;
|
|
private int pirateScrap = 0;
|
|
private int pirateRail = 0;
|
|
private int pirateHorse = 0;
|
|
private int pirateSnowMobile = 0;
|
|
private int pirateBase = 0;
|
|
private List<NetworkableId> PirateUintList = new List<NetworkableId>();
|
|
private List<NetworkableId> BaseParts = new List<NetworkableId>();
|
|
private List<NetworkableId> GroundedNPCs = new List<NetworkableId>();
|
|
private Dictionary<ScientistNPC, BaseEntity> ActiveNPCs = new Dictionary<ScientistNPC, BaseEntity>();
|
|
private List<NetworkableId> NPCsUintList = new List<NetworkableId>();
|
|
private List<BaseEntity> TrainsBaseEntityList = new List<BaseEntity>();
|
|
private List<NetworkableId> VoiceUintList = new List<NetworkableId>();
|
|
private List<NetworkableId> CoolDownUintList = new List<NetworkableId>();
|
|
private List<Vector3> PointsOfIntrest = new List<Vector3>();
|
|
private List<BasePlayer> downed = new List<BasePlayer>();
|
|
private List<MapMarkerGenericRadius> mapmarkersList = new List<MapMarkerGenericRadius>();
|
|
private Timer spawner = null;
|
|
private List<Coroutine> Threads = new List<Coroutine>();
|
|
private List<Vector3> seanodes = new List<Vector3>();
|
|
private List<Vector3> airnodes = new List<Vector3>();
|
|
private List<Vector3> groundnodes = new List<Vector3>();
|
|
private List<Vector3> roadnodes = new List<Vector3>();
|
|
private List<Vector3> railnodes = new List<Vector3>();
|
|
private Dictionary<Vector3, bool> dropnodes = new Dictionary<Vector3, bool>();
|
|
private List<PrefabData> footnodes = new List<PrefabData>();
|
|
private List<PrefabData> Alarmtriggers = new List<PrefabData>();
|
|
private List<NetworkableId> alarmcooldown = new List<NetworkableId>();
|
|
private bool sealoaded = false;
|
|
private bool airloaded = false;
|
|
private bool landloaded = false;
|
|
private bool railloaded = false;
|
|
private bool footloaded = false;
|
|
private readonly List<BasePlayer> _openProfiles = new List<BasePlayer>();
|
|
public static PirateNPC plugin;
|
|
public static ServerSettings _ServerSettings;
|
|
private List<List<Dictionary<string, string>>> loottableDict = new List<List<Dictionary<string, string>>>();
|
|
private const string wallprefab = "assets/prefabs/building core/wall/wall.prefab";
|
|
private const string foundationprefab = "assets/prefabs/building core/foundation/foundation.prefab";
|
|
private const string floorprefab = "assets/prefabs/building core/floor/floor.prefab";
|
|
private const string windowprefab = "assets/prefabs/building/wall.window.reinforcedglass/wall.window.glass.reinforced.prefab";
|
|
private const string wallframeprefab = "assets/prefabs/building core/wall.frame/wall.frame.prefab";
|
|
private const string garagedoorprefab = "assets/prefabs/building/wall.frame.garagedoor/wall.frame.garagedoor.prefab";
|
|
private const string workcartprefab = "assets/content/vehicles/trains/workcart/workcart_aboveground.entity.prefab";
|
|
private const string wagonentsprefab = "assets/content/vehicles/trains/wagons/trainwagon$.entity.prefab";
|
|
private const string codelockprefab = "assets/prefabs/locks/keypad/lock.code.prefab";
|
|
private const string autoturretprefab = "assets/prefabs/npc/autoturret/autoturret_deployed.prefab";
|
|
private const string samsiteprefab = "assets/prefabs/npc/sam_site_turret/sam_site_turret_deployed.prefab";
|
|
private const string rhibentityprefab = "assets/content/vehicles/boats/rhib/rhib.prefab";
|
|
private const string rowboatentityprefab = "assets/content/vehicles/boats/rowboat/rowboat.prefab";
|
|
private const string minientityprefab = "assets/content/vehicles/minicopter/minicopter.entity.prefab";
|
|
private const string scrapentityprefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";
|
|
private const string horseentityprefab = "assets/rust.ai/nextai/testridablehorse.prefab";
|
|
private const string snowmobileentityprefab = "assets/content/vehicles/snowmobiles/snowmobile.prefab";
|
|
private const string subentityprefab = "assets/content/vehicles/submarine/submarineduo.entity.prefab";
|
|
private const string hoboentityprefab = "assets/prefabs/misc/twitch/hobobarrel/hobobarrel.deployed.prefab";
|
|
private const string sphereentityprefab = "assets/prefabs/visualization/sphere.prefab";
|
|
private const string buoyantentityprefab = "assets/prefabs/misc/item drop/item_drop_buoyant.prefab";
|
|
private const string eliteentityprefab = "assets/bundled/prefabs/radtown/crate_elite.prefab";
|
|
private const string basicentityprefab = "assets/bundled/prefabs/radtown/crate_basic.prefab";
|
|
private const string normalentityprefab = "assets/bundled/prefabs/radtown/crate_normal.prefab";
|
|
private const string helicrateentityprefab = "assets/prefabs/npc/patrol helicopter/heli_crate.prefab";
|
|
private const string cargoplaneentityprefab = "assets/prefabs/npc/cargo plane/cargo_plane.prefab";
|
|
private const string lanternentityprefab = "assets/prefabs/deployable/lantern/lantern.deployed.prefab";
|
|
private const string woodboxentityprefab = "assets/prefabs/deployable/large wood storage/box.wooden.large.prefab";
|
|
private const string rhibstorageentityprefab = "assets/content/vehicles/boats/rhib/subents/rhib_storage.prefab";
|
|
private const string playerentityprefab = "assets/prefabs/player/player.prefab";
|
|
private const string mapmarkerentityprefab = "assets/prefabs/tools/map/genericradiusmarker.prefab";
|
|
private const string parachuteentityprefab = "assets/prefabs/misc/parachute/parachute.prefab";
|
|
private const string groundfallentityprefab = "assets/bundled/prefabs/fx/player/groundfall.prefab";
|
|
private const string c4_explosionentityprefab = "assets/prefabs/tools/c4/effects/c4_explosion.prefab";
|
|
private const string damage_effect_debrisprefab = "assets/prefabs/npc/patrol helicopter/damage_effect_debris.prefab";
|
|
private const string searchlightentityprefab = "assets/prefabs/deployable/search light/searchlight.deployed.prefab";
|
|
private const string oilfireballsmallprefab = "assets/bundled/prefabs/oilfireballsmall.prefab";
|
|
|
|
private int TopologyBaseBlock = TerrainTopology.MONUMENT;
|
|
#endregion
|
|
|
|
#region Configuration
|
|
|
|
public class ServerSettings
|
|
{
|
|
public int SpawnEvery;
|
|
public int LeaveAfter;
|
|
public bool ShowMapMarkers;
|
|
public float MapMarkerSize;
|
|
public float MapMarkerAlpha;
|
|
public float StartFireHealth;
|
|
public Color AirMapMarkerColour;
|
|
public Color WaterMapMarkerColour;
|
|
public Color LandMapMarkerColour;
|
|
public Color BaseMapMarkerColour;
|
|
public Color RailMapMarkerColour;
|
|
public float StopDelayFloat;
|
|
public float CrashDelayFloat;
|
|
public bool DisableScrapHeliGibs;
|
|
public bool DisableHeliFireball;
|
|
public bool DisableHelilights;
|
|
public bool DisableBoatlights;
|
|
public bool DisableLandlights;
|
|
public float FireDelay;
|
|
public float ExplodeDelay;
|
|
public int RHIBNPCAmount;
|
|
public int RHIBHealth;
|
|
public int RHIBNPCHealth;
|
|
public int RHIBBoatAmount;
|
|
public int RHIBBoatMaxA;
|
|
public float RHIBBoatMaxSpeed;
|
|
public float RHIBBoatTurnSpeed;
|
|
public float RHIBAIDistance;
|
|
public string RHIBKit;
|
|
public string RHIBLootString;
|
|
public int RowBoatNPCAmount;
|
|
public int RowBoatHealth;
|
|
public int RowBoatNPCHealth;
|
|
public int RowBoatBoatAmount;
|
|
public int RowBoatBoatMaxA;
|
|
public float RowBoatBoatMaxSpeed;
|
|
public float RowBoatBoatTurnSpeed;
|
|
public float RowBoatAIDistance;
|
|
public string RowBoatKit;
|
|
public string RowBoatLootString;
|
|
public int SubmarineHealth;
|
|
public int SubmarineAmount;
|
|
public int SubmarineMaxA;
|
|
public float SubmarineMaxSpeed;
|
|
public float SubmarineTurnSpeed;
|
|
public float SubmarineTargetDepth;
|
|
public float SubmarineDamage;
|
|
public string SubmarineLootString;
|
|
public int MiniHealth;
|
|
public int MiniNPCHealth;
|
|
public int MiniNPCAmount;
|
|
public int MiniAmount;
|
|
public int MiniMaxA;
|
|
public float MiniMaxSpeed;
|
|
public float MiniOrbitDistance;
|
|
public float MiniTurnSpeed;
|
|
public float MiniHoverHeight;
|
|
public float MiniAIDistance;
|
|
public float MiniThreatLevel;
|
|
public string MiniKit;
|
|
public string MiniLootString;
|
|
public int ScrapHealth;
|
|
public int ScrapNPCHealth;
|
|
public int ScrapNPCAmount;
|
|
public int ScrapAmount;
|
|
public int ScrapMaxA;
|
|
public float ScrapMaxSpeed;
|
|
public float ScrapOrbitDistance;
|
|
public float ScrapTurnSpeed;
|
|
public float ScrapHoverHeight;
|
|
public float ScrapAIDistance;
|
|
public float ScrapThreatLevel;
|
|
public string ScrapKit;
|
|
public string ScrapLootString;
|
|
public bool CargoPathBool;
|
|
public bool MonumentPathBool;
|
|
public bool SamSitesBool0;
|
|
public bool SamSitesBoat;
|
|
public bool StaticSamSitesBool;
|
|
public float SamSitesDamageFloat;
|
|
public bool NPCParachuteBool;
|
|
public float NPCTick;
|
|
public float NPCParachuteTrigger;
|
|
public float NPCParachuteDecay;
|
|
public float NPCParachuteDie;
|
|
public float HeliTargetDistance;
|
|
public float BoatTargetDistance;
|
|
public float LandTargetDistance;
|
|
public int SnowMobileAmount;
|
|
public int SnowMobileMax;
|
|
public float SnowMobileNPCHealth;
|
|
public float SnowMobileAimMulti;
|
|
public float SnowMobileHealth;
|
|
public float SnowMobileRomeRange;
|
|
public bool SnowMobileCanRoam;
|
|
public float SnowMobileMoveSpeed;
|
|
public string SnowMobileKit;
|
|
public string SnowMobileLootString;
|
|
public int HorseAmount;
|
|
public int HorseMax;
|
|
public float HorseNPCHealth;
|
|
public float HorseAimMulti;
|
|
public float HorseHealth;
|
|
public float HorseRomeRange;
|
|
public bool HorseCanRoam;
|
|
public float HorseMoveSpeed;
|
|
public string HorseKit;
|
|
public string HorseLootString;
|
|
public string LootProfiles;
|
|
public bool NPCChatter;
|
|
public int NPCMaxVoicesAtOnce;
|
|
public string NPCCustomChatter0;
|
|
public int NPCCustomChatterCD;
|
|
public string NPCCustomDeath0;
|
|
public int NPCCustomDeathCD;
|
|
public string NPCCustomKill0;
|
|
public int NPCCustomKillCD;
|
|
public string NPCCustomWarningString;
|
|
public float NPCCustomWarningDistance;
|
|
public int NPCCustomWarningCD;
|
|
public bool NPCCAttackSupplyDrops;
|
|
public bool NPCAttackCreate;
|
|
public bool NPCCountRaids;
|
|
public bool NPCsCanTargetNPCsBool;
|
|
public float NPCDamageScaler;
|
|
public float NPCAimScaler;
|
|
public string NPCNameTag;
|
|
public float PiratesAirPOIRadius;
|
|
public float PiratesWaterPOIRadius;
|
|
public float PiratesLandPOIRadius;
|
|
public bool NPCPeaceKeeperBool;
|
|
public int POIExpires;
|
|
public float NPCPeaceKeeperToggle;
|
|
public bool RaidableBasesAT;
|
|
public int HorseLootMulti;
|
|
public int SnowMobileLootMulti;
|
|
public int ScrapLootMulti;
|
|
public int MiniLootMulti;
|
|
public int SubmarineLootMulti;
|
|
public int RowBoatLootMulti;
|
|
public int RHIBLootMulti;
|
|
public int PirateBaseAmount;
|
|
public int PirateBaseWallRadius;
|
|
public int PirateBaseNPCAmount;
|
|
public float PirateBaseAimMulti;
|
|
public float PirateBaseNPCHealth;
|
|
public string PirateBaseNPCKit;
|
|
public string PirateBaseLootString;
|
|
public int PirateBaseLootMulti;
|
|
public float PirateBaseDoorHealth;
|
|
public int PirateRailAmount;
|
|
public float PirateRailTrainSpeed;
|
|
public int PirateRailHealth;
|
|
public int PirateRailNPCAmount;
|
|
public float PirateRailAimMulti;
|
|
public float PirateRailNPCHealth;
|
|
public float PirateRailNPCDriverHealth;
|
|
public string PirateRailNPCKit;
|
|
public string PirateRailLootString;
|
|
public int PirateRailLootMulti;
|
|
public int PirateRailWagonAmount;
|
|
public float PirateRailWagonSamRange;
|
|
public float PirateRailWagonSamHealth;
|
|
public float PirateRailWagonTurretHealth;
|
|
public string PirateRailWagonTurretGun;
|
|
public float PirateRailWagonhealth;
|
|
public float PirateRailWagondoorhealth;
|
|
public ulong PirateRailwagondoorskinid;
|
|
public float PirateFootNPCHealth;
|
|
public float PirateFootNPCAimMulti;
|
|
public string PirateFootNPCKit;
|
|
public float PirateFootNPCRoam;
|
|
public bool PirateCargoPlane;
|
|
public float PiratePlaneflyheight;
|
|
public float PiratePlaneflyspeed;
|
|
public int PiratePlaneNPCAmount;
|
|
public int PiratePlaneNPCDrops;
|
|
public bool PirateEventEnabled;
|
|
public bool PirateEventAnnounce;
|
|
public float PirateEventRadius;
|
|
public int PirateEventNPCAmount;
|
|
public string PirateEventNPCKit;
|
|
public float PirateEventNPCHealth;
|
|
public float PirateEventNPCAimMulti;
|
|
public float PirateEventCoolDownDelay;
|
|
public float PirateEventSpawnRadius;
|
|
public float PirateEventStationaryRadius;
|
|
public List<string> PiratePlaneAllowedDrops;
|
|
|
|
public void LoadSettings()
|
|
{
|
|
RaidableBasesAT = bool.Parse(plugin.Config["(RaidableBases) Disable Auto Turrets Attacking Pirates"].ToString());
|
|
SpawnEvery = int.Parse(plugin.Config["Spawn Pirates Every (sec)"].ToString());
|
|
LeaveAfter = int.Parse(plugin.Config["Leave After (sec)"].ToString());
|
|
ShowMapMarkers = bool.Parse(plugin.Config["Map Marker Show"].ToString());
|
|
MapMarkerSize = float.Parse(plugin.Config["Map Marker Size"].ToString());
|
|
MapMarkerAlpha = float.Parse(plugin.Config["Map Marker Alpha"].ToString());
|
|
StartFireHealth = float.Parse(plugin.Config["Start Fire When Health Below"].ToString());
|
|
AirMapMarkerColour = plugin.Hex2Colour(plugin.Config["Map Marker Colour (Air) (Hex)"].ToString());
|
|
WaterMapMarkerColour = plugin.Hex2Colour(plugin.Config["Map Marker Colour (Water) (Hex)"].ToString());
|
|
LandMapMarkerColour = plugin.Hex2Colour(plugin.Config["Map Marker Colour (Land) (Hex)"].ToString());
|
|
BaseMapMarkerColour = plugin.Hex2Colour(plugin.Config["Map Marker Colour (Base) (Hex)"].ToString());
|
|
RailMapMarkerColour = plugin.Hex2Colour(plugin.Config["Map Marker Colour (Rail) (Hex)"].ToString());
|
|
StopDelayFloat = float.Parse(plugin.Config["Stop Delay (sec)"].ToString());
|
|
CrashDelayFloat = float.Parse(plugin.Config["Crash Delay (sec)"].ToString());
|
|
DisableScrapHeliGibs = bool.Parse(plugin.Config["Disable ScrapHeli Gibs"].ToString());
|
|
DisableHeliFireball = bool.Parse(plugin.Config["Disable Heli Fireball"].ToString());
|
|
DisableHelilights = bool.Parse(plugin.Config["Disable Heli Lights"].ToString());
|
|
DisableBoatlights = bool.Parse(plugin.Config["Disable Boat Lights"].ToString());
|
|
DisableLandlights = bool.Parse(plugin.Config["Disable Land Lights"].ToString());
|
|
FireDelay = float.Parse(plugin.Config["Fire After Crash/Sink (sec)"].ToString());
|
|
ExplodeDelay = float.Parse(plugin.Config["Explode After Fire (sec)"].ToString());
|
|
RHIBNPCAmount = int.Parse(plugin.Config["RHIB NPC Amount Per Boat"].ToString());
|
|
RHIBHealth = int.Parse(plugin.Config["RHIB Health"].ToString());
|
|
RHIBNPCHealth = int.Parse(plugin.Config["RHIB NPC Health"].ToString());
|
|
RHIBBoatAmount = int.Parse(plugin.Config["RHIB Boat Amount Per Spawn"].ToString());
|
|
RHIBBoatMaxA = int.Parse(plugin.Config["RHIB Boat Max At Once"].ToString());
|
|
RHIBBoatMaxSpeed = float.Parse(plugin.Config["RHIB Boat Max Speed"].ToString());
|
|
RHIBBoatTurnSpeed = float.Parse(plugin.Config["RHIB Boat Turn Speed"].ToString());
|
|
RHIBAIDistance = float.Parse(plugin.Config["RHIB AI Target Distance"].ToString());
|
|
RHIBKit = plugin.Config["RHIB Kit Bots"].ToString();
|
|
RHIBLootString = plugin.Config["RHIB Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
RHIBLootMulti = int.Parse(plugin.Config["RHIB Loot Spawner Multiplier"].ToString());
|
|
RowBoatNPCAmount = int.Parse(plugin.Config["RowBoat NPC Amount Per Boat"].ToString());
|
|
RowBoatHealth = int.Parse(plugin.Config["RowBoat Health"].ToString());
|
|
RowBoatNPCHealth = int.Parse(plugin.Config["RowBoat NPC Health"].ToString());
|
|
RowBoatBoatAmount = int.Parse(plugin.Config["RowBoat Boat Amount Per Spawn"].ToString());
|
|
RowBoatBoatMaxA = int.Parse(plugin.Config["RowBoat Boat Max At Once"].ToString());
|
|
RowBoatBoatMaxSpeed = float.Parse(plugin.Config["RowBoat Boat Max Speed"].ToString());
|
|
RowBoatBoatTurnSpeed = float.Parse(plugin.Config["RowBoat Boat Turn Speed"].ToString());
|
|
RowBoatAIDistance = float.Parse(plugin.Config["RowBoat AI Target Distance"].ToString());
|
|
RowBoatKit = plugin.Config["RowBoat Kit Bots"].ToString();
|
|
RowBoatLootString = plugin.Config["RowBoat Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
RowBoatLootMulti = int.Parse(plugin.Config["RowBoat Loot Spawner Multiplier"].ToString());
|
|
SubmarineHealth = int.Parse(plugin.Config["Submarine Health"].ToString());
|
|
SubmarineAmount = int.Parse(plugin.Config["Submarine Amount Per Spawn"].ToString());
|
|
SubmarineMaxA = int.Parse(plugin.Config["Submarine Max At Once"].ToString());
|
|
SubmarineMaxSpeed = float.Parse(plugin.Config["Submarine Max Speed"].ToString());
|
|
SubmarineTurnSpeed = float.Parse(plugin.Config["Submarine Turn Speed"].ToString());
|
|
SubmarineTargetDepth = float.Parse(plugin.Config["Submarine Target Depth"].ToString());
|
|
SubmarineDamage = float.Parse(plugin.Config["Submarine Take Damage"].ToString());
|
|
SubmarineLootString = plugin.Config["Submarine Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
SubmarineLootMulti = int.Parse(plugin.Config["Submarine Loot Spawner Multiplier"].ToString());
|
|
MiniHealth = int.Parse(plugin.Config["Minicopter Health"].ToString());
|
|
MiniNPCHealth = int.Parse(plugin.Config["Minicopter NPC Health"].ToString());
|
|
MiniNPCAmount = int.Parse(plugin.Config["Minicopter NPC Amount"].ToString());
|
|
MiniAmount = int.Parse(plugin.Config["Minicopter Amount Per Spawn"].ToString());
|
|
MiniMaxA = int.Parse(plugin.Config["Minicopter Max At Once"].ToString());
|
|
MiniMaxSpeed = float.Parse(plugin.Config["Minicopter Max Speed"].ToString());
|
|
MiniOrbitDistance = float.Parse(plugin.Config["Minicopter Orbit Distance"].ToString());
|
|
MiniTurnSpeed = float.Parse(plugin.Config["Minicopter Turn Speed"].ToString());
|
|
MiniHoverHeight = float.Parse(plugin.Config["Minicopter Hover Height"].ToString());
|
|
MiniAIDistance = float.Parse(plugin.Config["Minicopter AI Target Distance"].ToString());
|
|
MiniThreatLevel = float.Parse(plugin.Config["Minicopter Target Threat Level"].ToString());
|
|
MiniKit = plugin.Config["Minicopter Kit Bots"].ToString();
|
|
MiniLootString = plugin.Config["Minicopter Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
MiniLootMulti = int.Parse(plugin.Config["Minicopter Loot Spawner Multiplier"].ToString());
|
|
ScrapHealth = int.Parse(plugin.Config["Scrapcopter Health"].ToString());
|
|
ScrapNPCHealth = int.Parse(plugin.Config["Scrapcopter NPC Health"].ToString());
|
|
ScrapNPCAmount = int.Parse(plugin.Config["Scrapcopter NPC Amount"].ToString());
|
|
ScrapAmount = int.Parse(plugin.Config["Scrapcopter Amount Per Spawn"].ToString());
|
|
ScrapMaxA = int.Parse(plugin.Config["Scrapcopter Max At Once"].ToString());
|
|
ScrapMaxSpeed = float.Parse(plugin.Config["Scrapcopter Max Speed"].ToString());
|
|
ScrapOrbitDistance = float.Parse(plugin.Config["Scrapcopter Orbit Distance"].ToString());
|
|
ScrapTurnSpeed = float.Parse(plugin.Config["Scrapcopter Turn Speed"].ToString());
|
|
ScrapHoverHeight = float.Parse(plugin.Config["Scrapcopter Hover Height"].ToString());
|
|
ScrapAIDistance = float.Parse(plugin.Config["Scrapcopter AI Target Distance"].ToString());
|
|
ScrapThreatLevel = float.Parse(plugin.Config["Scrapcopter Target Threat Level"].ToString());
|
|
ScrapKit = plugin.Config["Scrapcopter Kit Bots"].ToString();
|
|
ScrapLootString = plugin.Config["Scrapcopter Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
ScrapLootMulti = int.Parse(plugin.Config["Scrapcopter Loot Spawner Multiplier"].ToString());
|
|
CargoPathBool = bool.Parse(plugin.Config["Use Cargoship Path For Ocean"].ToString());
|
|
MonumentPathBool = bool.Parse(plugin.Config["Use Monument Path For Air"].ToString());
|
|
SamSitesBool0 = bool.Parse(plugin.Config["Samsites Attack Pirates"].ToString());
|
|
SamSitesBoat = bool.Parse(plugin.Config["Samsites Attack Pirate Boats"].ToString());
|
|
StaticSamSitesBool = bool.Parse(plugin.Config["Static(Server) Samsites Attack Pirates"].ToString());
|
|
SamSitesDamageFloat = float.Parse(plugin.Config["Samsites Damage Multiplyer (Pirates)"].ToString());
|
|
NPCParachuteBool = bool.Parse(plugin.Config["NPCs Parachute"].ToString());
|
|
NPCTick = float.Parse(plugin.Config["NPCs Tick Rate (sec)"].ToString());
|
|
NPCParachuteTrigger = float.Parse(plugin.Config["NPCs Parachute When Heli Health Below"].ToString());
|
|
NPCParachuteDecay = float.Parse(plugin.Config["NPCs Parachute Decay (sec)"].ToString());
|
|
NPCParachuteDie = float.Parse(plugin.Config["NPCs Parachute Suicide (sec)"].ToString());
|
|
HeliTargetDistance = float.Parse(plugin.Config["(Air) Pirates Target Distance"].ToString());
|
|
BoatTargetDistance = float.Parse(plugin.Config["(Sea) Pirates Target Distance"].ToString());
|
|
LandTargetDistance = float.Parse(plugin.Config["(Land) Pirates Target Distance"].ToString());
|
|
SnowMobileAmount = int.Parse(plugin.Config["SnowMobile Amount Per Spawn"].ToString());
|
|
SnowMobileMax = int.Parse(plugin.Config["SnowMobile Max At Once"].ToString());
|
|
SnowMobileNPCHealth = float.Parse(plugin.Config["SnowMobile NPC Health"].ToString());
|
|
SnowMobileAimMulti = float.Parse(plugin.Config["SnowMobile NPC Aim Distance"].ToString());
|
|
SnowMobileHealth = float.Parse(plugin.Config["SnowMobile Health"].ToString());
|
|
SnowMobileRomeRange = float.Parse(plugin.Config["SnowMobile Roam Range"].ToString());
|
|
SnowMobileCanRoam = bool.Parse(plugin.Config["SnowMobile Roam"].ToString());
|
|
SnowMobileMoveSpeed = float.Parse(plugin.Config["SnowMobile Speed"].ToString());
|
|
SnowMobileKit = plugin.Config["SnowMobile Kit Bots"].ToString();
|
|
SnowMobileLootString = plugin.Config["SnowMobile Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
SnowMobileLootMulti = int.Parse(plugin.Config["SnowMobile Loot Spawner Multiplier"].ToString());
|
|
HorseAmount = int.Parse(plugin.Config["Horse Amount Per Spawn"].ToString());
|
|
HorseMax = int.Parse(plugin.Config["Horse Max At Once"].ToString());
|
|
HorseNPCHealth = float.Parse(plugin.Config["Horse NPC Health"].ToString());
|
|
HorseAimMulti = float.Parse(plugin.Config["Horse NPC Aim Distance"].ToString());
|
|
HorseHealth = float.Parse(plugin.Config["Horse Health"].ToString());
|
|
HorseRomeRange = float.Parse(plugin.Config["Horse Roam Range"].ToString());
|
|
HorseCanRoam = bool.Parse(plugin.Config["Horse Roam"].ToString());
|
|
HorseMoveSpeed = float.Parse(plugin.Config["Horse Speed"].ToString());
|
|
HorseKit = plugin.Config["Horse Kit Bots"].ToString();
|
|
HorseLootString = plugin.Config["Horse Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
HorseLootMulti = int.Parse(plugin.Config["Horse Loot Spawner Multiplier"].ToString());
|
|
LootProfiles = plugin.Config["XLootCustomProfiles"].ToString();
|
|
NPCChatter = bool.Parse(plugin.Config["NPCs Radio Disable"].ToString());
|
|
NPCCustomChatter0 = plugin.Config["NPCs Radio Custom"].ToString();
|
|
NPCCustomChatterCD = int.Parse(plugin.Config["NPCs Radio Custom Cooldown"].ToString());
|
|
NPCCustomDeath0 = plugin.Config["NPCs Custom Death Voice"].ToString();
|
|
NPCCustomDeathCD = int.Parse(plugin.Config["NPCs Custom Death VoiceCooldown"].ToString());
|
|
NPCCustomKill0 = plugin.Config["NPCs Custom Kill Voice"].ToString();
|
|
NPCCustomKillCD = int.Parse(plugin.Config["NPCs Custom Kill Voice Cooldown"].ToString());
|
|
NPCNameTag = plugin.Config["NPCs Name Tag"].ToString();
|
|
NPCCustomWarningString = plugin.Config["NPCs Custom Warning Voice"].ToString();
|
|
NPCCustomWarningDistance = float.Parse(plugin.Config["NPCs Custom Warning Voice Trigger Distance"].ToString());
|
|
NPCCustomWarningCD = int.Parse(plugin.Config["NPCs Custom Warning Voice Cooldown"].ToString());
|
|
NPCCAttackSupplyDrops = bool.Parse(plugin.Config["NPCs Pirates Attack Supply Drops"].ToString());
|
|
NPCAttackCreate = bool.Parse(plugin.Config["NPCs Pirates Attack Creates Being Hacked"].ToString());
|
|
NPCsCanTargetNPCsBool = bool.Parse(plugin.Config["NPCs Can Target Other NPCs"].ToString());
|
|
NPCCountRaids = bool.Parse(plugin.Config["NPCs Pirates Counter Raids"].ToString());
|
|
NPCMaxVoicesAtOnce = int.Parse(plugin.Config["NPCs Max Voices To Play At Once On Server"].ToString());
|
|
NPCDamageScaler = float.Parse(plugin.Config["NPC Damage Scaler"].ToString());
|
|
NPCAimScaler = float.Parse(plugin.Config["NPC Aim Scaler"].ToString());
|
|
PiratesAirPOIRadius = float.Parse(plugin.Config["Pirates Distance From POI Air"].ToString());
|
|
PiratesWaterPOIRadius = float.Parse(plugin.Config["Pirates Distance From POI Water"].ToString());
|
|
PiratesLandPOIRadius = float.Parse(plugin.Config["Pirates Distance From POI Land"].ToString());
|
|
NPCPeaceKeeperBool = bool.Parse(plugin.Config["NPCs Pirates PeaceKeeper Mode"].ToString());
|
|
POIExpires = int.Parse(plugin.Config["Pirates POI Expires After (sec)"].ToString());
|
|
NPCPeaceKeeperToggle = float.Parse(plugin.Config["NPCs Pirates PeaceKeeper Toggle Hostile Distance"].ToString());
|
|
PirateBaseAmount = int.Parse(plugin.Config["Pirate Base Amount To Spawn"].ToString());
|
|
PirateBaseNPCAmount = int.Parse(plugin.Config["Pirate Base Amount Of NPCs"].ToString());
|
|
PirateBaseWallRadius = int.Parse(plugin.Config["Pirate Base Wall Radius"].ToString());
|
|
PirateBaseNPCHealth = float.Parse(plugin.Config["Pirate Base NPC Health"].ToString());
|
|
PirateBaseAimMulti = float.Parse(plugin.Config["Pirate Base NPC Aim Distance"].ToString());
|
|
PirateBaseNPCKit = plugin.Config["Pirate Base NPC Kit"].ToString();
|
|
PirateBaseLootString = plugin.Config["Pirate Base Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
PirateBaseDoorHealth = float.Parse(plugin.Config["Pirate Base Door Health"].ToString());
|
|
PirateBaseLootMulti = int.Parse(plugin.Config["Pirate Base Loot Spawner Multiplyer"].ToString());
|
|
PirateRailAmount = int.Parse(plugin.Config["Pirate Rail Amount To Spawn"].ToString());
|
|
PirateRailHealth = int.Parse(plugin.Config["Pirate Rail Train Health"].ToString());
|
|
PirateRailNPCAmount = int.Parse(plugin.Config["Pirate Rail Amount Of NPCs"].ToString());
|
|
PirateRailNPCHealth = float.Parse(plugin.Config["Pirate Rail NPC Health"].ToString());
|
|
PirateRailNPCDriverHealth = float.Parse(plugin.Config["Pirate Rail NPC Driver Health"].ToString());
|
|
PirateRailAimMulti = float.Parse(plugin.Config["Pirate Rail NPC Aim Distance"].ToString());
|
|
PirateRailNPCKit = plugin.Config["Pirate Rail NPC Kit"].ToString();
|
|
PirateRailLootString = plugin.Config["Pirate Rail Loot Spawner (Leave Blank For Profile Loot)"].ToString();
|
|
PirateRailLootMulti = int.Parse(plugin.Config["Pirate Rail Loot Spawner Multiplyer"].ToString());
|
|
PirateRailWagonSamRange = float.Parse(plugin.Config["Pirate Rail Samsite Range"].ToString());
|
|
PirateRailWagonSamHealth = float.Parse(plugin.Config["Pirate Rail Samsite Health"].ToString());
|
|
PirateRailWagonTurretHealth = float.Parse(plugin.Config["Pirate Rail Turret Health"].ToString());
|
|
PirateRailWagonTurretGun = plugin.Config["Pirate Rail Turret Gun"].ToString();
|
|
PirateRailWagonhealth = float.Parse(plugin.Config["Pirate Rail Wagon Health"].ToString());
|
|
PirateRailWagondoorhealth = float.Parse(plugin.Config["Pirate Rail Wagon Door Health"].ToString());
|
|
PirateRailwagondoorskinid = ulong.Parse(plugin.Config["Pirate Rail Wagon Door SkinID"].ToString());
|
|
PirateRailWagonAmount = int.Parse(plugin.Config["Pirate Rail Wagon Spawn Ammount"].ToString());
|
|
PirateRailTrainSpeed = float.Parse(plugin.Config["Pirate Rail Train Speed"].ToString());
|
|
PirateFootNPCHealth = float.Parse(plugin.Config["Pirate Foot NPC Health"].ToString());
|
|
PirateFootNPCAimMulti = float.Parse(plugin.Config["Pirate Foot Aim Distance"].ToString());
|
|
PirateFootNPCKit = plugin.Config["Pirate Foot NPC Kit"].ToString();
|
|
PirateFootNPCRoam = float.Parse(plugin.Config["Pirate Foot NPC Roam Distance"].ToString());
|
|
PirateCargoPlane = bool.Parse(plugin.Config["Pirate Plane Event Enabled"].ToString());
|
|
PiratePlaneflyheight = float.Parse(plugin.Config["Pirate Plane Fly Height"].ToString());
|
|
PiratePlaneflyspeed = float.Parse(plugin.Config["Pirate Plane Fly Speed"].ToString());
|
|
PiratePlaneNPCAmount = int.Parse(plugin.Config["Pirate Plane NPCs Per Drop"].ToString());
|
|
PiratePlaneNPCDrops = int.Parse(plugin.Config["Pirate Plane Number Of Drops"].ToString());
|
|
PiratePlaneAllowedDrops = plugin.AllowedMonumentList(plugin.Config["Pirate Plane Allowed Monuments"].ToString());
|
|
PirateEventEnabled = bool.Parse(plugin.Config["Pirates Events Enabled"].ToString());
|
|
PirateEventCoolDownDelay = float.Parse(plugin.Config["Pirate Events CoolDown Delay"].ToString());
|
|
PirateEventRadius = float.Parse(plugin.Config["Pirate Events Player Radius"].ToString());
|
|
PirateEventNPCAmount = int.Parse(plugin.Config["Pirate Events NPC Amount"].ToString());
|
|
PirateEventNPCKit = plugin.Config["Pirate Events NPC Kit"].ToString();
|
|
PirateEventNPCHealth = float.Parse(plugin.Config["Pirate Events NPC Health"].ToString());
|
|
PirateEventNPCAimMulti = float.Parse(plugin.Config["Pirate Events NPC AimMulti"].ToString());
|
|
PirateEventAnnounce = bool.Parse(plugin.Config["Pirate Events Annoucements"].ToString());
|
|
PirateEventSpawnRadius = float.Parse(plugin.Config["Pirate Events NPC Spawn Radius"].ToString());
|
|
PirateEventStationaryRadius = float.Parse(plugin.Config["Pirate Events NPC Stationary Radius"].ToString());
|
|
}
|
|
}
|
|
|
|
protected override void LoadDefaultConfig()
|
|
{
|
|
Puts("Creating a new configuration file");
|
|
Config["Spawn Pirates Every (sec)"] = 900;
|
|
Config["Leave After (sec)"] = 1300;
|
|
Config["(Air) Pirates Target Distance"] = 200f;
|
|
Config["(Sea) Pirates Target Distance"] = 30f;
|
|
Config["(Land) Pirates Target Distance"] = 40f;
|
|
Config["(RaidableBases) Disable Auto Turrets Attacking Pirates"] = true;
|
|
Config["Map Marker Show"] = true;
|
|
Config["Map Marker Colour (Air) (Hex)"] = "#ada500";
|
|
Config["Map Marker Colour (Water) (Hex)"] = "#001dad";
|
|
Config["Map Marker Colour (Land) (Hex)"] = "#00ad00";
|
|
Config["Map Marker Colour (Base) (Hex)"] = "#ad0000";
|
|
Config["Map Marker Colour (Rail) (Hex)"] = "#ad00a0";
|
|
Config["Map Marker Alpha"] = 0.2f;
|
|
Config["Map Marker Size"] = 0.3f;
|
|
Config["Start Fire When Health Below"] = 80f;
|
|
Config["Stop Delay (sec)"] = 3;
|
|
Config["Crash Delay (sec)"] = 0.5;
|
|
Config["Disable ScrapHeli Gibs"] = true;
|
|
Config["Disable Heli Fireball"] = true;
|
|
Config["Disable Heli Lights"] = false;
|
|
Config["Disable Boat Lights"] = false;
|
|
Config["Disable Land Lights"] = false;
|
|
Config["Fire After Crash/Sink (sec)"] = 60;
|
|
Config["Explode After Fire (sec)"] = 10;
|
|
Config["RHIB Kit Bots"] = "";
|
|
Config["RHIB Loot Spawner (Leave Blank For Profile Loot)"] = eliteentityprefab;
|
|
Config["RHIB Loot Spawner Multiplier"] = 2;
|
|
Config["RHIB NPC Amount Per Boat"] = 4;
|
|
Config["RHIB Health"] = 500;
|
|
Config["RHIB NPC Health"] = 120;
|
|
Config["RHIB Boat Amount Per Spawn"] = 1;
|
|
Config["RHIB Boat Max Speed"] = 14f;
|
|
Config["RHIB Boat Turn Speed"] = 7.5f;
|
|
Config["RHIB AI Target Distance"] = 5f;
|
|
Config["RHIB Boat Max At Once"] = 1;
|
|
Config["RowBoat Kit Bots"] = "";
|
|
Config["RowBoat Loot Spawner (Leave Blank For Profile Loot)"] = basicentityprefab;
|
|
Config["RowBoat Loot Spawner Multiplier"] = 1;
|
|
Config["RowBoat NPC Amount Per Boat"] = 2;
|
|
Config["RowBoat Health"] = 400;
|
|
Config["RowBoat NPC Health"] = 100;
|
|
Config["RowBoat Boat Amount Per Spawn"] = 2;
|
|
Config["RowBoat Boat Max Speed"] = 11f;
|
|
Config["RowBoat Boat Turn Speed"] = 7.5f;
|
|
Config["RowBoat AI Target Distance"] = 10f;
|
|
Config["RowBoat Boat Max At Once"] = 4;
|
|
Config["Submarine Loot Spawner (Leave Blank For Profile Loot)"] = eliteentityprefab;
|
|
Config["Submarine Loot Spawner Multiplier"] = 1;
|
|
Config["Submarine Health"] = 700;
|
|
Config["Submarine Amount Per Spawn"] = 1;
|
|
Config["Submarine Max Speed"] = 6f;
|
|
Config["Submarine Turn Speed"] = 18f;
|
|
Config["Submarine Target Depth"] = 6f;
|
|
Config["Submarine Max At Once"] = 2;
|
|
Config["Submarine Take Damage"] = 2500;
|
|
Config["Minicopter Kit Bots"] = "";
|
|
Config["Minicopter Loot Spawner (Leave Blank For Profile Loot)"] = normalentityprefab;
|
|
Config["Minicopter Loot Spawner Multiplier"] = 1;
|
|
Config["Minicopter Health"] = 300;
|
|
Config["Minicopter NPC Health"] = 600;
|
|
Config["Minicopter NPC Amount"] = 3;
|
|
Config["Minicopter Amount Per Spawn"] = 2;
|
|
Config["Minicopter Max Speed"] = 25f;
|
|
Config["Minicopter Turn Speed"] = 4.5f;
|
|
Config["Minicopter Hover Height"] = 45f;
|
|
Config["Minicopter AI Target Distance"] = 4.5f;
|
|
Config["Minicopter Max At Once"] = 4;
|
|
Config["Minicopter Orbit Distance"] = 60f;
|
|
Config["Minicopter Target Threat Level"] = 0.9f;
|
|
Config["Scrapcopter Kit Bots"] = "";
|
|
Config["Scrapcopter Loot Spawner (Leave Blank For Profile Loot)"] = helicrateentityprefab;
|
|
Config["Scrapcopter Loot Spawner Multiplier"] = 3;
|
|
Config["Scrapcopter Health"] = 850;
|
|
Config["Scrapcopter NPC Health"] = 100;
|
|
Config["Scrapcopter NPC Amount"] = 11;
|
|
Config["Scrapcopter Amount Per Spawn"] = 1;
|
|
Config["Scrapcopter Max Speed"] = 20f;
|
|
Config["Scrapcopter Turn Speed"] = 2.5f;
|
|
Config["Scrapcopter Hover Height"] = 45f;
|
|
Config["Scrapcopter AI Target Distance"] = 4.5f;
|
|
Config["Scrapcopter Max At Once"] = 2;
|
|
Config["Scrapcopter Orbit Distance"] = 65f;
|
|
Config["Scrapcopter Target Threat Level"] = 1f;
|
|
Config["SnowMobile Amount Per Spawn"] = 3;
|
|
Config["SnowMobile Max At Once"] = 6;
|
|
Config["SnowMobile NPC Health"] = 15f;
|
|
Config["SnowMobile NPC Aim Distance"] = 0.5f;
|
|
Config["SnowMobile Health"] = 200f;
|
|
Config["SnowMobile Roam Range"] = 200f;
|
|
Config["SnowMobile Roam"] = true;
|
|
Config["SnowMobile Speed"] = 10f;
|
|
Config["SnowMobile Kit Bots"] = "";
|
|
Config["SnowMobile Loot Spawner (Leave Blank For Profile Loot)"] = normalentityprefab;
|
|
Config["SnowMobile Loot Spawner Multiplier"] = 1;
|
|
Config["Horse Amount Per Spawn"] = 3;
|
|
Config["Horse Max At Once"] = 6;
|
|
Config["Horse NPC Health"] = 15f;
|
|
Config["Horse Health"] = 350f;
|
|
Config["Horse NPC Aim Distance"] = 0.5f;
|
|
Config["Horse Roam Range"] = 280f;
|
|
Config["Horse Roam"] = true;
|
|
Config["Horse Speed"] = 8f;
|
|
Config["Horse Kit Bots"] = "";
|
|
Config["Horse Loot Spawner (Leave Blank For Profile Loot)"] = normalentityprefab;
|
|
Config["Horse Loot Spawner Multiplier"] = 1;
|
|
Config["Use Cargoship Path For Ocean"] = true;
|
|
Config["Use Monument Path For Air"] = false;
|
|
Config["Samsites Attack Pirates"] = false;
|
|
Config["Static(Server) Samsites Attack Pirates"] = false;
|
|
Config["Samsites Attack Pirate Boats"] = false;
|
|
Config["Samsites Damage Multiplyer (Pirates)"] = 2f;
|
|
Config["NPCs Tick Rate (sec)"] = 1.5f;
|
|
Config["NPCs Parachute"] = true;
|
|
Config["NPCs Parachute When Heli Health Below"] = 30f;
|
|
Config["NPCs Parachute Decay (sec)"] = 30f;
|
|
Config["NPCs Parachute Suicide (sec)"] = 600f;
|
|
Config["NPCs Radio Disable"] = false;
|
|
Config["NPCs Radio Custom"] = "";
|
|
Config["NPCs Custom Kill Voice"] = "";
|
|
Config["NPCs Custom Death Voice"] = "";
|
|
Config["NPCs Custom Warning Voice"] = "";
|
|
Config["NPCs Radio Custom Cooldown"] = 10;
|
|
Config["NPCs Custom Death VoiceCooldown"] = 8;
|
|
Config["NPCs Custom Kill Voice Cooldown"] = 8;
|
|
Config["NPCs Custom Warning Voice Cooldown"] = 15;
|
|
Config["NPCs Custom Warning Voice Trigger Distance"] = 15;
|
|
Config["NPCs Max Voices To Play At Once On Server"] = 20;
|
|
Config["NPCs Pirates Attack Supply Drops"] = true;
|
|
Config["NPCs Pirates Attack Creates Being Hacked"] = true;
|
|
Config["NPCs Pirates Counter Raids"] = true;
|
|
Config["NPCs Pirates PeaceKeeper Mode"] = true;
|
|
Config["NPCs Pirates PeaceKeeper Toggle Hostile Distance"] = 4;
|
|
Config["NPC Damage Scaler"] = 0.8f;
|
|
Config["NPC Aim Scaler"] = 1;
|
|
Config["NPCs Name Tag"] = "[Pirate]";
|
|
Config["NPCs Can Target Other NPCs"] = false;
|
|
Config["Pirates Distance From POI Air"] = 5000f;
|
|
Config["Pirates Distance From POI Water"] = 400f;
|
|
Config["Pirates Distance From POI Land"] = 800f;
|
|
Config["Pirates POI Expires After (sec)"] = 60f;
|
|
Config["Pirate Base Amount To Spawn"] = 3;
|
|
Config["Pirate Base Amount Of NPCs"] = 6;
|
|
Config["Pirate Base NPC Aim Distance"] = 0.6f;
|
|
Config["Pirate Base NPC Health"] = 150f;
|
|
Config["Pirate Base NPC Kit"] = "";
|
|
Config["Pirate Base Wall Radius"] = 12;
|
|
Config["Pirate Base Loot Spawner (Leave Blank For Profile Loot)"] = eliteentityprefab;
|
|
Config["Pirate Base Loot Spawner Multiplyer"] = 3;
|
|
Config["Pirate Base Door Health"] = 600f;
|
|
Config["Pirate Rail Amount To Spawn"] = 1;
|
|
Config["Pirate Rail Train Health"] = 1000;
|
|
Config["Pirate Rail Amount Of NPCs"] = 6;
|
|
Config["Pirate Rail NPC Aim Distance"] = 0.6f;
|
|
Config["Pirate Rail NPC Health"] = 150f;
|
|
Config["Pirate Rail NPC Driver Health"] = 2f;
|
|
Config["Pirate Rail NPC Kit"] = "";
|
|
Config["Pirate Rail Loot Spawner (Leave Blank For Profile Loot)"] = eliteentityprefab;
|
|
Config["Pirate Rail Loot Spawner Multiplyer"] = 4;
|
|
Config["Pirate Rail Samsite Range"] = 20f;
|
|
Config["Pirate Rail Samsite Health"] = 200f;
|
|
Config["Pirate Rail Turret Health"] = 50f;
|
|
Config["Pirate Rail Turret Gun"] = "pistol.eoka";
|
|
Config["Pirate Rail Wagon Health"] = 2500f;
|
|
Config["Pirate Rail Wagon Door Health"] = 55f;
|
|
Config["Pirate Rail Wagon Door SkinID"] = 2488843636;
|
|
Config["Pirate Rail Wagon Spawn Ammount"] = 3;
|
|
Config["Pirate Rail Train Speed"] = 8;
|
|
Config["Pirate Foot NPC Health"] = 120;
|
|
Config["Pirate Foot Aim Distance"] = 0.9f;
|
|
Config["Pirate Foot NPC Kit"] = "";
|
|
Config["Pirate Foot NPC Roam Distance"] = 50f;
|
|
Config["Pirates Events Enabled"] = true;
|
|
Config["Pirate Events CoolDown Delay"] = 600f;
|
|
Config["Pirate Events Annoucements"] = true;
|
|
Config["Pirate Events Player Radius"] = 50;
|
|
Config["Pirate Events NPC Amount"] = 5;
|
|
Config["Pirate Events NPC Kit"] = "";
|
|
Config["Pirate Events NPC Health"] = 120f;
|
|
Config["Pirate Events NPC AimMulti"] = 0.8f;
|
|
Config["Pirate Plane Event Enabled"] = true;
|
|
Config["Pirate Plane Fly Height"] = 120f;
|
|
Config["Pirate Plane Fly Speed"] = 40f;
|
|
Config["Pirate Plane NPCs Per Drop"] = 3f;
|
|
Config["Pirate Plane Number Of Drops"] = 6f;
|
|
Config["Pirate Events NPC Spawn Radius"] = 12f;
|
|
Config["Pirate Events NPC Stationary Radius"] = 4f;
|
|
Config["Pirate Plane Allowed Monuments"] = "assets/bundled/prefabs/autospawn/monument/harbor/harbor_2.prefab|assets/bundled/prefabs/autospawn/monument/harbor/harbor_1.prefab|assets/bundled/prefabs/autospawn/monument/military_bases/desert_military_base_d.prefab|assets/bundled/prefabs/autospawn/monument/arctic_bases/arctic_research_base_a.prefab|assets/bundled/prefabs/autospawn/monument/xlarge/launch_site_1.prefab|assets/bundled/prefabs/autospawn/monument/large/excavator_1.prefab|assets/bundled/prefabs/autospawn/monument/medium/junkyard_1.prefab|assets/bundled/prefabs/autospawn/monument/large/trainyard_1.prefab|assets/bundled/prefabs/autospawn/monument/large/powerplant_1.prefab|assets/bundled/prefabs/autospawn/monument/large/military_tunnel_1.prefab|assets/bundled/prefabs/autospawn/monument/large/airfield_1.prefab|assets/bundled/prefabs/autospawn/monument/large/water_treatment_plant_1.prefab|assets/bundled/prefabs/autospawn/monument/medium/radtown_small_3.prefab|assets/bundled/prefabs/autospawn/monument/small/mining_quarry_a.prefab|assets/bundled/prefabs/autospawn/monument/small/satellite_dish.prefab|assets/bundled/prefabs/autospawn/monument/small/sphere_tank.prefab|assets/bundled/prefabs/autospawn/monument/small/mining_quarry_b.prefab|assets/bundled/prefabs/autospawn/monument/small/mining_quarry_c.prefab|assets/bundled/prefabs/autospawn/monument/tiny/water_well_d.prefab|assets/bundled/prefabs/autospawn/monument/tiny/water_well_e.prefab|assets/bundled/prefabs/autospawn/monument/tiny/water_well_c.prefab|assets/bundled/prefabs/autospawn/tunnel-entrance/entrance_bunker_a.prefab|assets/bundled/prefabs/autospawn/tunnel-entrance/entrance_bunker_c.prefab|assets/bundled/prefabs/autospawn/monument/roadside/warehouse.prefab|assets/bundled/prefabs/autospawn/monument/roadside/gas_station_1.prefab|assets/bundled/prefabs/autospawn/monument/roadside/supermarket_1.prefab|assets/bundled/prefabs/autospawn/power substations/small/power_sub_small_2.prefab|assets/bundled/prefabs/autospawn/power substations/small/power_sub_small_1.prefab|assets/bundled/prefabs/autospawn/power substations/big/power_sub_big_2.prefab|assets/bundled/prefabs/autospawn/power substations/big/power_sub_big_1.prefab";
|
|
Config["XLootCustomProfiles"] = "<Profile>jumpsuit.suit.blue,1,0|maxhealthtea.pure,1,0|ammo.rifle,30,0|riflebody,2,0|gunpowder,150,0|can.beans,1,0";
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Commands
|
|
[ChatCommand("pirates.count")]
|
|
private void ActivePiratesCount(BasePlayer player) { if (player.IsAdmin) { Counterfunction(player); } }
|
|
[ChatCommand("pirates.cargoplane")]
|
|
private void ManualSpawncargoplane(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 9); player.ChatMessage("Calling pirate cargo drop spawn."); } }
|
|
[ChatCommand("pirates.drop")]
|
|
private void ManualSpawnFootNPCDrop(BasePlayer player)
|
|
{
|
|
if (player.IsAdmin)
|
|
{
|
|
FootPirate pf = SpawnPirates(player.transform.position, 11).GetComponent<FootPirate>();
|
|
if (pf != null) { pf.movetopoint = player.transform.position; pf.movetopoint.y = TerrainMeta.HeightMap.GetHeight(player.transform.position) + _ServerSettings.PiratePlaneflyheight; player.ChatMessage("Calling pirate cargo drop on your location."); }
|
|
}
|
|
}
|
|
[ChatCommand("pirates.foot")]
|
|
private void ManualSpawnFootNPCGround(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 10); player.ChatMessage("Spawning foot pirate on your location."); } }
|
|
[ChatCommand("pirates.base")]
|
|
private void ManualSpawnBase(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 7); player.ChatMessage("Spawning pirate base on your location."); } }
|
|
[ChatCommand("pirates.showroad")]
|
|
private void ShowRoadCmd(BasePlayer player) { if (!player.IsAdmin) { return; } foreach (Vector3 v in roadnodes) { player.SendConsoleCommand("ddraw.sphere", 8f, Color.blue, v, 1f); } }
|
|
[ConsoleCommand("pirates.addpoi")]
|
|
private void CmdAddPOI(ConsoleSystem.Arg arg) { BasePlayer player = arg?.Connection?.player as BasePlayer; if ((player != null && player?.net?.connection.authLevel < 2) || arg?.Args?.Length != 2) { return; } Manuallyaddpoifunction(arg.Args, null); }
|
|
[ChatCommand("pirates.poi")]
|
|
private void ManualAddPOI(BasePlayer player, string command, string[] Args) { if (!player.IsAdmin) { return; } Manuallyaddpoifunction(Args, player); }
|
|
[ChatCommand("pirates.clearpoi")]
|
|
private void ManualClearPoi(BasePlayer player, string command, string[] Args) { if (!player.IsAdmin) { return; } PointsOfIntrest.Clear(); }
|
|
[ChatCommand("pirates.rhib")]
|
|
private void ManualSpawnRhib(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position); player.ChatMessage("Spawning pirate rhib on your location."); } }
|
|
[ChatCommand("pirates.rowboat")]
|
|
private void ManualSpawnRowBoat(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 1); player.ChatMessage("Spawning pirate rowboat on your location."); } }
|
|
[ChatCommand("pirates.sub")]
|
|
private void ManualSpawnsub(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 6); player.ChatMessage("Spawning pirate sub on your location."); } }
|
|
[ChatCommand("pirates.mini")]
|
|
private void ManualSpawnMini(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 2); player.ChatMessage("Spawning pirate mini on your location."); } }
|
|
[ChatCommand("pirates.scrap")]
|
|
private void ManualSpawnScrap(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 3); player.ChatMessage("Spawning pirate scrappy on your location."); } }
|
|
[ChatCommand("pirates.horse")]
|
|
private void ManualSpawnHorse(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 4); player.ChatMessage("Spawning pirate horse on your location."); } }
|
|
[ChatCommand("pirates.snowmobile")]
|
|
private void ManualSpawnSnowMobile(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 5); player.ChatMessage("Spawning pirate snowmobile on your location."); } }
|
|
[ChatCommand("pirates.train")]
|
|
private void ManualSpawnTrain(BasePlayer player) { if (player.IsAdmin) { SpawnPirates(player.transform.position, 8); player.ChatMessage("Spawning pirate train on your location."); } }
|
|
[ChatCommand("pirates.reload")]
|
|
private void ManualLoadSettings(BasePlayer player) { if (player.IsAdmin) { _ServerSettings = new ServerSettings(); BuildLootTablefunction(); } }
|
|
[ChatCommand("pirates.showpath")]
|
|
private void DrawPathCMD(BasePlayer player) { if (player.IsAdmin) { foreach (Vector3 vector in seanodes) { player.SendConsoleCommand("ddraw.sphere", 8f, Color.blue, vector, 2f); } foreach (Vector3 vector in airnodes) { player.SendConsoleCommand("ddraw.sphere", 8f, Color.red, vector, 2f); } foreach (Vector3 vector in groundnodes) { player.SendConsoleCommand("ddraw.sphere", 8f, Color.red, vector, 2f); } } }
|
|
[ChatCommand("pirates.cargopath")]
|
|
private void SwitchPathCargocmd(BasePlayer player) { if (player.IsAdmin) { player.ChatMessage("Switching to Cargo Pathing"); seanodes = TerrainMeta.Path.OceanPatrolFar; } }
|
|
[ChatCommand("pirates.customseapath")]
|
|
private void SwitchPathCustom(BasePlayer player) { if (player.IsAdmin) { player.ChatMessage("Switching to Custom Pathing"); SetupOceanPatrolPath(); } }
|
|
[ChatCommand("pirates.monumentpath")]
|
|
private void SwitchMonumentPath(BasePlayer player) { if (player.IsAdmin) { player.ChatMessage("Switching to Monument Pathing"); airnodes = MonumentPathList(); } }
|
|
[ChatCommand("pirates.customairpath")]
|
|
private void SwitchMonumentCustom(BasePlayer player) { if (player.IsAdmin) { player.ChatMessage("Switching to Custom Air Pathing"); SetupAirPatrolPath(); } }
|
|
[ChatCommand("pirates.topologytest")]
|
|
private void topologytestcmd(BasePlayer player)
|
|
{
|
|
if (player.IsAdmin) { player.ChatMessage(TerrainMeta.TopologyMap.GetTopology(player.transform.position, TopologyBaseBlock).ToString()); }
|
|
}
|
|
[ChatCommand("pirates.loot")]
|
|
private void SetupLootcmd(BasePlayer player, string command, string[] args)
|
|
{
|
|
if (player.IsAdmin)
|
|
{
|
|
try
|
|
{
|
|
if (args.Length < 1)
|
|
{
|
|
ShowHelpfunction(player);
|
|
return;
|
|
}
|
|
if (args.Length == 1 && args[0].Contains("add"))
|
|
{
|
|
ItemContainer profile = new ItemContainer();
|
|
profile.isServer = true;
|
|
profile.entityOwner = player;
|
|
profile.allowedContents = ItemContainer.ContentsType.Generic;
|
|
profile.GiveUID();
|
|
profile.capacity = 30;
|
|
if (!_openProfiles.Contains(player)) { _openProfiles.Add(player); }
|
|
timer.Once(0.5f, () => { LootContainerfunction(player, profile); });
|
|
player.ChatMessage("Created New Loot Profile.");
|
|
return;
|
|
}
|
|
if (args.Length == 2 && args[0].Contains("edit"))
|
|
{
|
|
if (args[1].IsNumeric())
|
|
{
|
|
ItemContainer profile = new ItemContainer();
|
|
profile.isServer = true;
|
|
profile.entityOwner = player;
|
|
profile.allowedContents = ItemContainer.ContentsType.Generic;
|
|
profile.GiveUID();
|
|
profile.capacity = 30;
|
|
if (!_openProfiles.Contains(player)) { _openProfiles.Add(player); }
|
|
filllootfunction(profile, int.Parse(args[1]), 0);
|
|
plugin.loottableDict.RemoveAt(int.Parse(args[1]));
|
|
timer.Once(0.5f, () => { LootContainerfunction(player, profile); });
|
|
player.ChatMessage("Editing Loot Profile.");
|
|
}
|
|
else { player.ChatMessage("Must profile profile index number."); }
|
|
return;
|
|
}
|
|
}
|
|
catch { ShowHelpfunction(player); }
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Hooks
|
|
private void Init()
|
|
{
|
|
plugin = this;
|
|
try
|
|
{
|
|
_ServerSettings = new ServerSettings();
|
|
_ServerSettings.LoadSettings();
|
|
}
|
|
catch
|
|
{
|
|
Puts("Failed to load settings, Resetting to default");
|
|
LoadDefaultConfig();
|
|
SaveConfig();
|
|
_ServerSettings = new ServerSettings();
|
|
_ServerSettings.LoadSettings();
|
|
}
|
|
if (!_ServerSettings.NPCCAttackSupplyDrops) { Unsubscribe("OnSupplyDropLanded"); }
|
|
if (!_ServerSettings.NPCAttackCreate) { Unsubscribe("OnCrateHack"); }
|
|
if (!_ServerSettings.SamSitesBool0) { Unsubscribe("OnSamSiteTargetScan"); }
|
|
if (!_ServerSettings.RaidableBasesAT) { Unsubscribe("CanBeTargeted"); }
|
|
}
|
|
|
|
private void OnServerInitialized(bool initial)
|
|
{
|
|
BuildLootTablefunction();
|
|
if (!_ServerSettings.CargoPathBool) { SetupOceanPatrolPath(); } else { seanodes = TerrainMeta.Path.OceanPatrolFar; sealoaded = true; Puts("Loaded " + seanodes.Count.ToString() + " Sea Nodes."); }
|
|
if (!_ServerSettings.MonumentPathBool) { SetupAirPatrolPath(); } else { airnodes = MonumentPathList(); airloaded = true; }
|
|
Threads.Add(ServerMgr.Instance.StartCoroutine(GenerateRoadGrid()));
|
|
timer.Once(2f, () => { SetupPlanePath(); });
|
|
SetupLandPatrolPath();
|
|
SetupRailPatrolPath();
|
|
if (_ServerSettings.ShowMapMarkers) { Threads.Add(ServerMgr.Instance.StartCoroutine(MapRoutine())); };
|
|
PirateSpawner();
|
|
spawner = timer.Every(_ServerSettings.SpawnEvery, () => { PirateSpawner(); });
|
|
if (!initial) { ClearUpVectorZerofunction(Vector3.zero); }
|
|
Threads.Add(ServerMgr.Instance.StartCoroutine(GenerateFootGrid()));
|
|
timer.Once(30f, () => { Threads.Add(ServerMgr.Instance.StartCoroutine(NPCAIFunction())); });
|
|
}
|
|
|
|
private void Unload()
|
|
{
|
|
if (spawner != null) { spawner.Destroy(); spawner = null; }
|
|
KillTrainsfunction();
|
|
ClearLootfunction(PirateUintList);
|
|
KillListfunction(GroundedNPCs);
|
|
KillListfunction(NPCsUintList);
|
|
KillListfunction(BaseParts);
|
|
KillListfunction(PirateUintList);
|
|
if (Threads != null && Threads.Count != 0)
|
|
{
|
|
foreach (Coroutine co in Threads) { if (co != null) ServerMgr.Instance.StopCoroutine(co); }
|
|
Threads = null;
|
|
MarkerDisplayingDelete();
|
|
}
|
|
_ServerSettings = null;
|
|
plugin = null;
|
|
}
|
|
|
|
private object CanLootPlayer(BasePlayer looted, BasePlayer looter) { if (_openProfiles.Contains(looter)) { return true; } return null; }
|
|
|
|
private void OnPlayerLootEnd(PlayerLoot playerLoot)
|
|
{
|
|
var player = (BasePlayer)playerLoot.gameObject.ToBaseEntity();
|
|
if (_openProfiles.Contains(player))
|
|
{
|
|
if (playerLoot.containers[0].itemList == null) { _openProfiles.Clear(); return; }
|
|
if (playerLoot.containers[0].itemList.Count == 0)
|
|
{
|
|
savelootfunction();
|
|
_openProfiles.Clear();
|
|
player.ChatMessage("Profile Deleted.");
|
|
return;
|
|
}
|
|
var newitems = new List<Dictionary<string, string>>();
|
|
foreach (Item pl in playerLoot.containers[0].itemList)
|
|
{
|
|
Dictionary<string, string> items = new Dictionary<string, string>();
|
|
items.Add(pl.info.shortname, pl.amount + "," + pl.skin);
|
|
newitems.Add(items);
|
|
}
|
|
loottableDict.Add(newitems);
|
|
savelootfunction();
|
|
_openProfiles.Clear();
|
|
player.ChatMessage("Saved Loot Profile Changes.");
|
|
}
|
|
}
|
|
|
|
private object OnEntityFlagsNetworkUpdate(BaseEntity be)
|
|
{
|
|
if (be.prefabID == 500822506 && _ServerSettings.PirateEventEnabled)
|
|
{
|
|
if (Rust.Application.isLoading || !sealoaded || !airloaded || !landloaded || alarmcooldown.Contains(be.net.ID)) { return null; }
|
|
foreach (PrefabData alarm in Alarmtriggers)
|
|
{
|
|
if (Vector3.Distance(be.transform.position, alarm.position) < 1f && PlayersNearbyfunction(be.transform.position, _ServerSettings.PirateEventRadius))
|
|
{
|
|
NetworkableId ID = be.net.ID;
|
|
alarmcooldown.Add(ID);
|
|
timer.Once(_ServerSettings.PirateEventCoolDownDelay, () => { alarmcooldown.Remove(ID); });
|
|
if (alarm.category.Contains("callpirateplane")) { EventCallfunction(0, alarm); }
|
|
else if (alarm.category.Contains("callpiratestationary")) { EventCallfunction(1, alarm); }
|
|
else if (alarm.category.Contains("callpiratefoot")) { EventCallfunction(2, alarm); }
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object CanBeTargeted(BaseCombatEntity target, AutoTurret at)
|
|
{
|
|
if (target == null || at == null) { return null; }
|
|
if (at.OwnerID != 0) { return null; }
|
|
if (target.net != null) { if (NPCsUintList.Contains(target.net.ID) || GroundedNPCs.Contains(target.net.ID)) { return false; } }
|
|
return null;
|
|
}
|
|
|
|
private object CanMountEntity(BasePlayer player, BaseMountable mount)
|
|
{
|
|
if (player == null | mount == null) { return null; }
|
|
if (player.IsConnected == false) { return null; }
|
|
BaseVehicle bv = mount.VehicleParent();
|
|
if (bv != null) { if (PirateUintList.Contains(bv.net.ID)) { return false; } }
|
|
return null;
|
|
}
|
|
|
|
private void OnEntitySpawned(BaseEntity spawned)
|
|
{
|
|
HelicopterDebris debris = spawned as HelicopterDebris;
|
|
if (debris != null)
|
|
{
|
|
NextTick(() => { if (debris != null && _ServerSettings.DisableScrapHeliGibs && debris.ShortPrefabName == "servergibs_scraptransport") { debris.Kill(); } });
|
|
}
|
|
}
|
|
|
|
private object CanDismountEntity(BasePlayer player, BaseMountable mount) { if (player == null && mount == null || player.net == null) { return null; } if (NPCsUintList.Contains(player.net.ID)) { return false; } return null; }
|
|
|
|
private object OnNpcRadioChatter(ScientistNPC bot)
|
|
{
|
|
if (_ServerSettings.NPCCustomChatter0 != "")
|
|
{
|
|
NetworkableId ID = bot.net.ID;
|
|
if (VoiceUintList.Count > _ServerSettings.NPCMaxVoicesAtOnce) { return false; }
|
|
bool flag = false;
|
|
foreach (BasePlayer bp in BasePlayer.activePlayerList)
|
|
{
|
|
if (bot.Distance(bp.transform.position) < 90)
|
|
{
|
|
flag = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!CoolDownUintList.Contains(ID) && flag)
|
|
{
|
|
CoolDownUintList.Add(ID);
|
|
WebPlayback(_ServerSettings.NPCCustomChatter0, bot);
|
|
timer.Once(_ServerSettings.NPCCustomChatterCD, () => { CoolDownUintList.Remove(ID); });
|
|
return false;
|
|
}
|
|
}
|
|
if (_ServerSettings.NPCChatter) { return false; }
|
|
return null;
|
|
}
|
|
|
|
private void OnSupplyDropLanded(SupplyDrop supplyDrop) { if (_ServerSettings.NPCCAttackSupplyDrops) { assignPOIfunction(new Vector3(supplyDrop.transform.position.x, supplyDrop.transform.position.y, supplyDrop.transform.position.z)); } }
|
|
|
|
private void OnCrateHack(HackableLockedCrate hackableLockedCrate) { if (_ServerSettings.NPCAttackCreate) { assignPOIfunction(new Vector3(hackableLockedCrate.transform.position.x, hackableLockedCrate.transform.position.y, hackableLockedCrate.transform.position.z)); } }
|
|
|
|
private object OnSamSiteTarget(SamSite samsite, SamSite.ISamSiteTarget target)
|
|
{
|
|
if (!_ServerSettings.StaticSamSitesBool) { foreach (NetworkableId id in PirateUintList) { if (target.ToString().Contains(id.ToString())) { return true; } } }
|
|
return null;
|
|
}
|
|
|
|
private object OnSamSiteTargetScan(SamSite samSite)
|
|
{
|
|
if (samSite == null) { return null; }
|
|
if (!_ServerSettings.SamSitesBool0) { return null; }
|
|
if (samSite.HasAmmo() && PirateUintList.Count != 0)
|
|
{
|
|
foreach (NetworkableId p in PirateUintList)
|
|
{
|
|
if (!BaseNetworkable.serverEntities.entityList.Contains(p)) { continue; }
|
|
BaseEntity be = BaseNetworkable.serverEntities.entityList[p] as BaseEntity;
|
|
if (be == null) { continue; }
|
|
if (samSite.Distance(be) < samSite.vehicleScanRadius)
|
|
{
|
|
if (!_ServerSettings.StaticSamSitesBool && samSite.staticRespawn) { samSite.ClearTarget(); return true; }
|
|
AirPirates AP = be.GetComponent<AirPirates>();
|
|
if (AP != null)
|
|
{
|
|
for (int i = 0; i < 3; i++) { timer.Once(i * 0.5f, () => { if (AP == null) { return; } SamLogicfunction(samSite, be, AP.currentVelocity, AP.moveSpeed); }); }
|
|
return true;
|
|
}
|
|
if (_ServerSettings.SamSitesBoat)
|
|
{
|
|
WaterPirate WP = be.GetComponent<WaterPirate>();
|
|
if (WP != null)
|
|
{
|
|
for (int i = 0; i < 3; i++) { timer.Once(i * 0.5f, () => { if (WP == null) { return; } SamLogicfunction(samSite, be, WP.currentVelocity, 0); }); }
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
object OnPlayerDeath(BasePlayer player, HitInfo info)
|
|
{
|
|
if (player == null || player.net == null) { return null; }
|
|
if (NPCsUintList.Contains(player.net.ID) || GroundedNPCs.Contains(player.net.ID)) { CoolDownUintList.Remove(player.net.ID); foreach (BaseEntity be in player.children.ToArray()) { if (be == null) { continue; } be.SetParent(null, true, true); if (be.ToString().Contains("parachute")) { be.Kill(); } if (be is SearchLight) { be.Kill(); } } }
|
|
return null;
|
|
}
|
|
|
|
private void OnEntityDeath(BaseCombatEntity entity, HitInfo info)
|
|
{
|
|
if (entity != null && info != null)
|
|
{
|
|
bool messaged = false;
|
|
if (_ServerSettings.NPCCustomKill0 != "")
|
|
{
|
|
if (info.InitiatorPlayer != null && info.InitiatorPlayer.net != null)
|
|
{
|
|
NetworkableId ID = info.InitiatorPlayer.net.ID;
|
|
if (NPCsUintList.Contains(ID) || GroundedNPCs.Contains(ID))
|
|
{
|
|
messaged = true;
|
|
if (!CoolDownUintList.Contains(ID) && VoiceUintList.Count < _ServerSettings.NPCMaxVoicesAtOnce)
|
|
{
|
|
CoolDownUintList.Add(ID);
|
|
WebPlayback(_ServerSettings.NPCCustomKill0, info.InitiatorPlayer);
|
|
timer.Once(_ServerSettings.NPCCustomKillCD, () => { CoolDownUintList.Remove(ID); });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (_ServerSettings.NPCCustomDeath0 != "" && !messaged && entity.net != null)
|
|
{
|
|
NetworkableId ID = entity.net.ID;
|
|
if (NPCsUintList.Contains(ID) || GroundedNPCs.Contains(ID))
|
|
{
|
|
if (!CoolDownUintList.Contains(ID) && VoiceUintList.Count < _ServerSettings.NPCMaxVoicesAtOnce)
|
|
{
|
|
CoolDownUintList.Add(ID);
|
|
BasePlayer p = entity.ToPlayer();
|
|
if (p != null)
|
|
{
|
|
WebPlayback(_ServerSettings.NPCCustomDeath0, p);
|
|
timer.Once(_ServerSettings.NPCCustomDeathCD, () => { CoolDownUintList.Remove(ID); });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
FreeLists(entity);
|
|
if (_ServerSettings.NPCCountRaids)
|
|
{
|
|
if (info == null) { return; }
|
|
if (!BaseDamagefunction(entity)) { return; }
|
|
if (info.InitiatorPlayer == null) { return; }
|
|
if (entity.OwnerID >= 10000000 && entity.OwnerID <= 20000000)
|
|
{
|
|
assignPOIfunction(new Vector3(entity.transform.position.x, entity.transform.position.y, entity.transform.position.z));
|
|
return;
|
|
}
|
|
BuildingPrivlidge buildingPrivilege = entity.GetBuildingPrivilege();
|
|
if (buildingPrivilege == null || buildingPrivilege.authorizedPlayers.IsEmpty()) { return; }
|
|
foreach (PlayerNameID attacked in buildingPrivilege.authorizedPlayers)
|
|
{
|
|
if (attacked == null) continue;
|
|
if (attacked.userid == info.InitiatorPlayer.userID) return;
|
|
assignPOIfunction(new Vector3(entity.transform.position.x, entity.transform.position.y, entity.transform.position.z));
|
|
}
|
|
}
|
|
}
|
|
|
|
private object CanEntityBeTargeted(BasePlayer player, BaseEntity turret)
|
|
{
|
|
if (turret == null || player == null) { return null; }
|
|
if (BaseParts.Contains(turret.net.ID) && !player.IsNpc)
|
|
{
|
|
return true;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object CanEntityTakeDamage(BaseCombatEntity entity, HitInfo hitInfo)
|
|
{
|
|
if (entity == null || PirateUintList == null || hitInfo == null || entity.net == null) { return null; }
|
|
NetworkableId ID = entity.net.ID;
|
|
if (PirateUintList.Contains(ID) || GroundedNPCs.Contains(ID) || NPCsUintList.Contains(ID) || BaseParts.Contains(ID)) { return true; }
|
|
if (TrainsBaseEntityList != null || TrainsBaseEntityList.Count != 0) { foreach (BaseEntity be in TrainsBaseEntityList) { if (be != null) { if (be.net.ID == ID) { return true; } } } }
|
|
if (hitInfo.Initiator != null)
|
|
{
|
|
NetworkableId ID2 = hitInfo.Initiator.net.ID;
|
|
if (PirateUintList.Contains(ID2) || GroundedNPCs.Contains(ID2) || NPCsUintList.Contains(ID2) || BaseParts.Contains(ID2)) { return true; }
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object OnEntityTakeDamage(BaseCombatEntity bce, HitInfo info)
|
|
{
|
|
if (bce == null || PirateUintList == null || info == null || bce.net == null) { return null; }
|
|
NetworkableId ID = bce.net.ID;
|
|
if (TrainsBaseEntityList.Contains(bce))
|
|
{
|
|
if (info.damageTypes == null) { return null; }
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) { return true; }
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.Collision) { return true; }
|
|
}
|
|
if (NPCsUintList.Contains(ID) || GroundedNPCs.Contains(ID))
|
|
{
|
|
if (info.InitiatorPlayer != null)
|
|
{
|
|
BasePlayer attackingplayer = info.InitiatorPlayer;
|
|
if (attackingplayer == null) { return null; }
|
|
if (BasePlayer.activePlayerList.Contains(attackingplayer))
|
|
{
|
|
ScientistNPC npc = bce as ScientistNPC;
|
|
if (npc != null && npc.Brain != null)
|
|
{
|
|
npc.Brain.Senses.Memory.Targets.Clear();
|
|
npc.Brain.Senses.Memory.Players.Clear();
|
|
npc.Brain.Senses.Memory.Threats.Clear();
|
|
npc.Brain.Senses.Memory.Targets.Add(attackingplayer);
|
|
npc.Brain.Senses.Memory.Players.Add(attackingplayer);
|
|
npc.Brain.Senses.Memory.Threats.Add(attackingplayer);
|
|
if (npc.Brain.AttackRangeMultiplier != 10)
|
|
{
|
|
float oldTLR = npc.Brain.TargetLostRange;
|
|
float oldARM = npc.Brain.AttackRangeMultiplier;
|
|
float oldAIM = npc.aimConeScale;
|
|
npc.aimConeScale = 0.2f;
|
|
npc.Brain.TargetLostRange = 800;
|
|
npc.Brain.AttackRangeMultiplier = 10;
|
|
npc.Invoke(() =>
|
|
{
|
|
if (npc != null)
|
|
{
|
|
npc.aimConeScale = oldAIM;
|
|
npc.Brain.TargetLostRange = oldTLR;
|
|
npc.Brain.AttackRangeMultiplier = oldARM;
|
|
npc.Brain.Senses.Memory.Targets.Clear();
|
|
npc.Brain.Senses.Memory.Players.Clear();
|
|
npc.Brain.Senses.Memory.Threats.Clear();
|
|
}
|
|
}, 8f);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
if (PirateUintList.Contains(ID))
|
|
{
|
|
if (info.damageTypes == null) { return null; }
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) { return true; }
|
|
if ((bce is Snowmobile) && info.damageTypes.GetMajorityDamageType() == DamageType.Collision) { return true; }
|
|
if (info.Initiator != null)
|
|
{
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.Explosion && (info.Initiator.ShortPrefabName == "scraptransporthelicopter" || info.Initiator.ShortPrefabName == "minicopter.entity")) { return true; }
|
|
if (info.Initiator is SamSite) { return null; }
|
|
if (info.Initiator is AutoTurret) { return null; }
|
|
if (info.Initiator is BaseSubmarine) { return null; }
|
|
}
|
|
if (info.InitiatorPlayer != null)
|
|
{
|
|
BasePlayer attackingplayer = info.InitiatorPlayer;
|
|
if (attackingplayer == null) { return null; }
|
|
if (BasePlayer.activePlayerList.Contains(attackingplayer))
|
|
{
|
|
PirateAttackedfunction(bce, attackingplayer);
|
|
if (bce is BaseSubmarine)
|
|
{
|
|
if (info.damageTypes != null)
|
|
{
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.AntiVehicle) { bce.Hurt(_ServerSettings.SubmarineDamage); return null; }
|
|
if (info.damageTypes.GetMajorityDamageType() == DamageType.Bullet) { bce.Hurt(50); return null; }
|
|
}
|
|
if (info.WeaponPrefab != null && info.WeaponPrefab._name != null) { if (info.WeaponPrefab._name.ToString().Contains("explosive.timed.deployed")) { bce.Hurt(_ServerSettings.SubmarineDamage); } }
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private object OnNpcTarget(HumanNPC bot, BaseEntity baseEntity)
|
|
{
|
|
if (bot == null || bot.net == null || baseEntity == null || baseEntity.net == null) { return null; }
|
|
NetworkableId ID = bot.net.ID;
|
|
if (VoiceUintList.Contains(baseEntity.net.ID)) { return true; }
|
|
if (!NPCsUintList.Contains(ID) && !GroundedNPCs.Contains(ID)) { return null; }
|
|
BasePlayer target = baseEntity.ToPlayer();
|
|
if (!_ServerSettings.NPCsCanTargetNPCsBool) { if (target != null) { if (target.IsNpc) { return true; } } }
|
|
if (_ServerSettings.NPCPeaceKeeperBool)
|
|
{
|
|
if (target != null)
|
|
{
|
|
float distance = bot.Distance(target);
|
|
if (distance < _ServerSettings.NPCPeaceKeeperToggle) { target.MarkHostileFor(10); }
|
|
if (_ServerSettings.NPCCustomWarningString != "")
|
|
{
|
|
if (!CoolDownUintList.Contains(ID) && VoiceUintList.Count < _ServerSettings.NPCMaxVoicesAtOnce)
|
|
{
|
|
if (distance > _ServerSettings.NPCPeaceKeeperToggle && distance < _ServerSettings.NPCCustomWarningDistance)
|
|
{
|
|
CoolDownUintList.Add(ID);
|
|
WebPlayback(_ServerSettings.NPCCustomWarningString, bot);
|
|
timer.Once(_ServerSettings.NPCCustomWarningCD, () => { CoolDownUintList.Remove(ID); });
|
|
}
|
|
}
|
|
}
|
|
if (target.IsHostile()) { return null; }
|
|
}
|
|
return true;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Functions
|
|
|
|
private void ShowHelpfunction(BasePlayer player)
|
|
{
|
|
player.ChatMessage("How to setup loot:");
|
|
player.ChatMessage("Type /pirates.loot add to create a new loot profile.");
|
|
player.ChatMessage("Type /pirates.loot edit int to view loot of that index");
|
|
player.ChatMessage("Type /pirates.loot remove int to remove profile loot of that index");
|
|
}
|
|
|
|
private void EventCallfunction(int eventtype, PrefabData alarm)
|
|
{
|
|
if (_ServerSettings.PirateEventAnnounce)
|
|
{
|
|
foreach (BasePlayer bp in BasePlayer.activePlayerList)
|
|
{
|
|
switch (eventtype)
|
|
{
|
|
case 0:
|
|
bp.ChatMessage("Pirate Event Cargo Plane Inbound!");
|
|
break;
|
|
case 1:
|
|
bp.ChatMessage("Pirate Event NPCs Spawning Stationary!");
|
|
break;
|
|
case 2:
|
|
bp.ChatMessage("Pirate Event NPCs Spawning!");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
timer.Once(5f, () =>
|
|
{
|
|
Vector3 pos = Vector3.zero;
|
|
List<Vector3> addpos = new List<Vector3>();
|
|
List<ScientistNPC> npcs = new List<ScientistNPC>();
|
|
switch (eventtype)
|
|
{
|
|
case 0:
|
|
FootPirate pf = SpawnPirates(seanodes.GetRandom(), 11).GetComponent<FootPirate>();
|
|
if (pf != null) { pf.movetopoint = new Vector3(alarm.position.x, TerrainMeta.HeightMap.GetHeight(alarm.position) + _ServerSettings.PiratePlaneflyheight, alarm.position.z); }
|
|
break;
|
|
case 1:
|
|
pos = new Vector3(alarm.position.x, alarm.position.y, alarm.position.z);
|
|
for (int i = 0; i < _ServerSettings.PirateEventNPCAmount; i++)
|
|
{
|
|
Vector3 vector = UnityEngine.Random.insideUnitCircle * _ServerSettings.PirateEventStationaryRadius;
|
|
addpos.Add(pos + new Vector3(vector.x, 0, vector.y));
|
|
}
|
|
npcs = CreateNPCs(_ServerSettings.PirateEventNPCAmount, 10, _ServerSettings.PirateBaseNPCHealth, _ServerSettings.PirateEventNPCKit, _ServerSettings.PirateEventNPCAimMulti, null, addpos);
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { npc.NavAgent.isStopped = true; } }
|
|
break;
|
|
case 2:
|
|
pos = new Vector3(alarm.position.x, alarm.position.y, alarm.position.z);
|
|
for (int i = 0; i < _ServerSettings.PirateEventNPCAmount; i++) { addpos.Add(pos); }
|
|
npcs = CreateNPCs(_ServerSettings.PirateEventNPCAmount, 10, _ServerSettings.PirateBaseNPCHealth, _ServerSettings.PirateEventNPCKit, _ServerSettings.PirateEventNPCAimMulti, null, addpos);
|
|
timer.Once(2f, () =>
|
|
{
|
|
if (npcs == null) { return; }
|
|
foreach (ScientistNPC npc in npcs) { BailOutfunction(alarm.position, npc, alarm.position, (int)_ServerSettings.PirateEventSpawnRadius, 0, false); }
|
|
});
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
|
|
private List<string> AllowedMonumentList(string settings)
|
|
{
|
|
List<string> list = new List<string>();
|
|
list.AddRange(settings.Split('|'));
|
|
return list;
|
|
}
|
|
|
|
private void Counterfunction(BasePlayer p) { p.ChatMessage("Pirates: RHIB:" + pirateRHIB + " RowBoat:" + pirateRowBoat + " Sub:" + pirateSub + " Mini:" + piratesMini + " Scrap:" + pirateScrap + " Horse:" + pirateHorse + " SnowMobile:" + pirateSnowMobile + " Train:" + pirateRail + " Bases:" + pirateBase + " ActiveNPCs:" + ActiveNPCs.Count); }
|
|
|
|
private void KillWagonsfunction(List<BaseEntity> wagons)
|
|
{
|
|
if (wagons == null || wagons.Count == 0) { return; }
|
|
foreach (BaseEntity w in wagons)
|
|
{
|
|
if (w != null && !w.IsDestroyed)
|
|
{
|
|
if ((w as TrainCar).platformParentTrigger != null && (w as TrainCar).platformParentTrigger.HasAnyEntityContents)
|
|
{
|
|
using (HashSet<BaseEntity>.Enumerator enumerator = (w as TrainCar).platformParentTrigger.entityContents.GetEnumerator())
|
|
{
|
|
while (enumerator.MoveNext())
|
|
{
|
|
if (enumerator.Current.ToPlayer() != null)
|
|
{
|
|
enumerator.Current.ToPlayer().SetParent(null, true, true);
|
|
enumerator.Current.ToPlayer().transform.position = enumerator.Current.ToPlayer().transform.position + new Vector3(0, 1.5f, 0);
|
|
enumerator.Current.ToPlayer().SendNetworkUpdateImmediate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
NextFrame(() =>
|
|
{
|
|
if (w != null && !w.IsDestroyed)
|
|
{
|
|
w.transform.position = new Vector3(0, -501, 0);
|
|
w.Kill();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
private void KillTrainsfunction()
|
|
{
|
|
foreach (BaseEntity be in TrainsBaseEntityList)
|
|
{
|
|
if (be != null && !be.IsDestroyed)
|
|
{
|
|
foreach (BaseEntity child in be.children)
|
|
{
|
|
if (child is BasePlayer && !child.IsNpc)
|
|
{
|
|
child.SetParent(null, true, true);
|
|
}
|
|
}
|
|
RailPirate RP = be.GetComponent<RailPirate>();
|
|
KillWagonsfunction(RP.wagons.ToList());
|
|
NextFrame(() =>
|
|
{
|
|
be.transform.position = new Vector3(0, -501, 0); be.Kill();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
public char GetLetterfunction() { return (char)('a' + (ulong)UnityEngine.Random.Range(0, 4)); }
|
|
|
|
private bool HasSpaceToSpawnfunction(TrainTrackSpline trainTrackSpline, Vector3 position)
|
|
{
|
|
foreach (TrainTrackSpline.ITrainTrackUser trainTrackUser in trainTrackSpline.trackUsers)
|
|
{
|
|
if (Vector3.SqrMagnitude(trainTrackUser.Position - position) < 145f)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private Vector3 GetPositionOnFromfunction(ref TrainTrackSpline trainTrackSpline, Vector3 forward, Vector3 position, float distance, out Vector3 tangent)
|
|
{
|
|
float minSplineDistance;
|
|
trainTrackSpline.GetDistance(position, 1f, out minSplineDistance);
|
|
bool facingForward = trainTrackSpline.IsForward(-forward, minSplineDistance);
|
|
bool isAtEndOfLine;
|
|
float newDistance = GetSplineDistAfterMove(minSplineDistance, distance, trainTrackSpline);
|
|
tangent = trainTrackSpline.GetTangentCubicHermiteWorld(newDistance);
|
|
return trainTrackSpline.GetPosition(newDistance);
|
|
}
|
|
|
|
|
|
public float GetSplineDistAfterMove(float prevSplineDist, float distance, TrainTrackSpline trainTrackSpline)
|
|
{
|
|
TrainTrackSpline.MoveResult moveResult = trainTrackSpline.MoveAlongSpline(prevSplineDist, trainTrackSpline.transform.forward, distance, default(TrainTrackSpline.TrackRequest));
|
|
return moveResult.distAlongSpline;
|
|
}
|
|
|
|
public bool PlayersNearbyfunction(Vector3 _base, float Distance)
|
|
{
|
|
if (_base == null) { return false; }
|
|
List<BasePlayer> obj = Pool.GetList<BasePlayer>();
|
|
Vis.Entities(_base, Distance, obj, 131072);
|
|
bool result = false;
|
|
if (obj == null) { return false; }
|
|
foreach (BasePlayer item in obj)
|
|
{
|
|
if (item == null) { continue; }
|
|
if (!item.IsSleeping() && item.IsAlive() && !item.IsNpc)
|
|
{
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
Pool.FreeList(ref obj);
|
|
return result;
|
|
}
|
|
|
|
private void KillListfunction(List<NetworkableId> EntIds)
|
|
{
|
|
if (EntIds == null) { return; }
|
|
foreach (NetworkableId p in EntIds)
|
|
{
|
|
if (BaseEntity.serverEntities.entityList.Contains(p))
|
|
{
|
|
BaseEntity be = BaseEntity.serverEntities.entityList[p] as BaseEntity;
|
|
if (TrainsBaseEntityList.Contains(be)) { continue; }
|
|
if (be != null && !be.IsDestroyed) { be.transform.position = new Vector3(0, -501, 0); be.Kill(); }
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearLootfunction(List<NetworkableId> EntIds)
|
|
{
|
|
if (EntIds == null) { return; }
|
|
foreach (NetworkableId p in EntIds)
|
|
{
|
|
if (BaseEntity.serverEntities.entityList.Contains(p))
|
|
{
|
|
BaseEntity be = BaseEntity.serverEntities.entityList[p] as BaseEntity;
|
|
if (be != null && !be.IsDestroyed)
|
|
{
|
|
AirPirates ap = be.GetComponent<AirPirates>();
|
|
if (ap != null && ap.itembox != null) { ap.itembox.inventory.Clear(); }
|
|
LandPirate lp = be.GetComponent<LandPirate>();
|
|
if (lp != null && lp.itembox != null) { lp.itembox.Clear(); }
|
|
WaterPirate wp = be.GetComponent<WaterPirate>();
|
|
if (wp != null && wp.itembox != null) { wp.itembox.inventory.Clear(); }
|
|
RailPirate rp = be.GetComponent<RailPirate>();
|
|
if (rp != null && rp.itembox != null) { rp.itembox.inventory.Clear(); }
|
|
BasePirate pb = be.GetComponent<BasePirate>();
|
|
if (pb != null && pb.itembox != null)
|
|
{
|
|
pb.itembox.inventory.Clear(); pb.itembox.Kill();
|
|
foreach (BaseEntity b in pb.entitys) { if (b != null && !b.IsDestroyed) { b.Kill(); } }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClearAreafunction(Vector3 Location, float ProtectionRadius)
|
|
{
|
|
int hits = Physics.OverlapSphereNonAlloc(Location, ProtectionRadius * 1.25f, Vis.colBuffer, -1, QueryTriggerInteraction.Ignore);
|
|
for (int i = 0; i < hits; i++)
|
|
{
|
|
var e = Vis.colBuffer[i].ToBaseEntity();
|
|
if (e is TreeEntity || e is BaseVehicle) { e.Kill(); }
|
|
Vis.colBuffer[i] = null;
|
|
}
|
|
}
|
|
|
|
private StorageContainer CreateStoragefunction(Vector3 offset, BaseEntity parent)
|
|
{
|
|
StorageContainer itembox = GameManager.server.CreateEntity(rhibstorageentityprefab) as StorageContainer;
|
|
plugin.DestroyMeshCollider(itembox);
|
|
plugin.DestroyGroundComp(itembox);
|
|
itembox.Spawn();
|
|
itembox.enableSaving = false;
|
|
itembox.SetParent(parent);
|
|
itembox.transform.localPosition = offset;
|
|
itembox.inventory.capacity = 30;
|
|
itembox.SendNetworkUpdateImmediate();
|
|
return itembox;
|
|
}
|
|
|
|
public bool SpawnCheckfunctioon(Vector3 position, float radius, int layers)
|
|
{
|
|
bool flag = true;
|
|
if (TerrainMeta.TopologyMap.GetTopology(position, TopologyBaseBlock)) { return false; }
|
|
var colliders = Pool.GetList<Collider>();
|
|
Vis.Colliders(position, radius, colliders, layers, QueryTriggerInteraction.Collide);
|
|
foreach (var collider in colliders)
|
|
{
|
|
if (collider.name.Contains("SafeZone", CompareOptions.OrdinalIgnoreCase) || collider.name.Contains("rock_", CompareOptions.OrdinalIgnoreCase) || collider.name.Contains("modding", CompareOptions.OrdinalIgnoreCase) || collider.name.Contains("structures", CompareOptions.OrdinalIgnoreCase) || collider.name.Contains("formation_", CompareOptions.OrdinalIgnoreCase)) { flag = false; break; }
|
|
var e = collider.ToBaseEntity();
|
|
if (e.IsValid())
|
|
{
|
|
if (e is BasePlayer)
|
|
{
|
|
var player = e as BasePlayer;
|
|
if (!player.IsConnected || player.IsFlying) { continue; }
|
|
else { flag = false; break; }
|
|
}
|
|
if (e is JunkPile) { flag = false; break; }
|
|
else if (e is PlayerCorpse)
|
|
{
|
|
var corpse = e as PlayerCorpse;
|
|
if (corpse.playerSteamID == 0 || corpse.playerSteamID.IsSteamId()) { flag = false; break; }
|
|
}
|
|
else if (e is DroppedItemContainer && e.ShortPrefabName != "item_drop")
|
|
{
|
|
var backpack = e as DroppedItemContainer;
|
|
if (backpack.playerSteamID == 0 || backpack.playerSteamID.IsSteamId()) { flag = false; break; }
|
|
}
|
|
else if (e.OwnerID == 0)
|
|
{
|
|
if (e is BuildingBlock) { flag = false; break; }
|
|
else if (e is MiningQuarry) { flag = false; break; }
|
|
}
|
|
}
|
|
}
|
|
Pool.FreeList(ref colliders);
|
|
return flag;
|
|
}
|
|
|
|
private void ClearUpVectorZerofunction(Vector3 pos)
|
|
{
|
|
List<BaseNetworkable> ScanEntitys = new List<BaseNetworkable>();
|
|
Vis.Entities<BaseNetworkable>(pos, 5f, ScanEntitys);
|
|
foreach (BaseNetworkable bn in ScanEntitys) { bn.Kill(); }
|
|
}
|
|
|
|
void AddLockfunction(BaseEntity ent)
|
|
{
|
|
CodeLock alock = GameManager.server.CreateEntity(codelockprefab) as CodeLock;
|
|
alock.Spawn();
|
|
alock.OwnerID = ent.OwnerID;
|
|
alock.code = UnityEngine.Random.Range(1111, 9999).ToString();
|
|
alock.SetParent(ent, ent.GetSlotAnchorName(BaseEntity.Slot.Lock));
|
|
ent.SetSlot(BaseEntity.Slot.Lock, alock);
|
|
alock.SetFlag(BaseEntity.Flags.Locked, true);
|
|
alock.enableSaving = false;
|
|
alock.SendNetworkUpdateImmediate(true);
|
|
}
|
|
|
|
private StabilityEntity CreateWindowfunction(Vector3 pos, Vector3 rot, BaseEntity parent)
|
|
{
|
|
StabilityEntity Glasswindow = GameManager.server.CreateEntity(windowprefab, parent.transform.position, Quaternion.Euler(rot)) as StabilityEntity;
|
|
DestroyMeshCollider(Glasswindow);
|
|
DestroyGroundComp(Glasswindow);
|
|
Glasswindow.Spawn();
|
|
Glasswindow.enableSaving = false;
|
|
Glasswindow.pickup.enabled = false;
|
|
Glasswindow.grounded = true;
|
|
Glasswindow.SetParent(parent);
|
|
Glasswindow.transform.localPosition = pos;
|
|
return Glasswindow;
|
|
}
|
|
|
|
private StabilityEntity CreateGarageDoorfunction(Vector3 pos, Vector3 rot, BaseEntity parent, ulong skinid = 0, ulong ID = 0, float health = 400)
|
|
{
|
|
StabilityEntity gdoor = GameManager.server.CreateEntity(garagedoorprefab, parent.transform.position, Quaternion.Euler(rot)) as StabilityEntity;
|
|
DestroyMeshCollider(gdoor);
|
|
DestroyGroundComp(gdoor);
|
|
gdoor.Spawn();
|
|
gdoor.enableSaving = false;
|
|
gdoor.skinID = skinid;
|
|
gdoor.OwnerID = ID;
|
|
gdoor.InitializeHealth(health, health);
|
|
AddLockfunction(gdoor);
|
|
gdoor.grounded = true;
|
|
gdoor.pickup.enabled = false;
|
|
gdoor.SetParent(parent);
|
|
gdoor.transform.localPosition = pos;
|
|
gdoor.SendNetworkUpdateImmediate(true);
|
|
return gdoor;
|
|
}
|
|
|
|
private StorageContainer CreateLootSpawnerfunction(Vector3 pos, Vector3 rot, BaseEntity parent, string CreatePrefab)
|
|
{
|
|
StorageContainer lootHOLDER = GameManager.server.CreateEntity(CreatePrefab, parent.transform.position, Quaternion.Euler(rot)) as StorageContainer;
|
|
if (lootHOLDER)
|
|
{
|
|
lootHOLDER.enableSaving = false;
|
|
lootHOLDER.SendMessage("SetWasDropped", SendMessageOptions.DontRequireReceiver);
|
|
lootHOLDER.Spawn();
|
|
lootHOLDER.SetParent(parent);
|
|
lootHOLDER.enableSaving = false;
|
|
lootHOLDER.transform.localPosition = pos;
|
|
}
|
|
return lootHOLDER;
|
|
}
|
|
|
|
private AutoTurret CreateTurretfunction(Vector3 pos, Vector3 rot, BaseEntity parent)
|
|
{
|
|
AutoTurret createdturret = GameManager.server.CreateEntity(autoturretprefab, parent.transform.position, Quaternion.Euler(rot)) as AutoTurret;
|
|
createdturret.Spawn();
|
|
createdturret.enableSaving = false;
|
|
createdturret.pickup.enabled = false;
|
|
createdturret.SetParent(parent);
|
|
createdturret.transform.localPosition = pos;
|
|
createdturret.InitializeHealth(_ServerSettings.PirateRailWagonTurretHealth, _ServerSettings.PirateRailWagonTurretHealth);
|
|
BaseParts.Add(createdturret.net.ID);
|
|
createdturret.SetFlag(BaseEntity.Flags.Reserved8, true, false, true);
|
|
NextFrame(() =>
|
|
{
|
|
if (createdturret.AttachedWeapon == null)
|
|
{
|
|
var shortname = _ServerSettings.PirateRailWagonTurretGun;
|
|
var itemToCreate = ItemManager.FindItemDefinition(shortname);
|
|
|
|
if (itemToCreate != null)
|
|
{
|
|
Item item = ItemManager.Create(itemToCreate, 1, (ulong)itemToCreate.skins.GetRandom().id);
|
|
if (!item.MoveToContainer(createdturret.inventory, 0, false)) { item.Remove(); }
|
|
}
|
|
}
|
|
});
|
|
createdturret.Invoke(() => FillAmmoTurret(createdturret), 2.5f);
|
|
createdturret.Invoke(createdturret.InitiateStartup, 3f);
|
|
createdturret.inventory.onPreItemRemove += new Action<Item>(OnWeaponItemPreRemove);
|
|
return createdturret;
|
|
}
|
|
|
|
private SamSite CreateSamsitefunction(Vector3 pos, Vector3 rot, BaseEntity parent)
|
|
{
|
|
SamSite createdturret = GameManager.server.CreateEntity(samsiteprefab, parent.transform.position, Quaternion.Euler(rot)) as SamSite;
|
|
createdturret.Spawn();
|
|
createdturret.enableSaving = false;
|
|
createdturret.pickup.enabled = false;
|
|
createdturret.SetParent(parent);
|
|
createdturret.transform.localPosition = pos;
|
|
createdturret.InitializeHealth(_ServerSettings.PirateRailWagonSamHealth, _ServerSettings.PirateRailWagonSamHealth);
|
|
createdturret.SetFlag(BaseEntity.Flags.Reserved8, true, false, true);
|
|
createdturret.vehicleScanRadius = createdturret.missileScanRadius = _ServerSettings.PirateRailWagonSamRange;
|
|
FillAmmoSamSite(createdturret);
|
|
createdturret.inventory.onPreItemRemove += new Action<Item>(OnWeaponItemPreRemove);
|
|
BaseParts.Add(createdturret.net.ID);
|
|
return createdturret;
|
|
}
|
|
|
|
public Color Hex2Colour(string text)
|
|
{
|
|
Color Colour;
|
|
if (ColorUtility.TryParseHtmlString(text, out Colour)) { return Colour; }
|
|
return Color.black;
|
|
}
|
|
|
|
private void FillAmmoTurret(AutoTurret turret)
|
|
{
|
|
var attachedWeaponvar = turret.GetAttachedWeapon();
|
|
if (attachedWeaponvar == null)
|
|
{
|
|
turret.Invoke(() => FillAmmoTurret(turret), 0.2f);
|
|
return;
|
|
}
|
|
attachedWeaponvar.primaryMagazine.contents = 999;
|
|
attachedWeaponvar.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
|
|
turret.Invoke(turret.UpdateTotalAmmo, 0.25f);
|
|
}
|
|
|
|
private void FillAmmoSamSite(SamSite ss)
|
|
{
|
|
if (ss.ammoItem == null || !ss.HasAmmo())
|
|
{
|
|
Item item = ItemManager.Create(ss.ammoType, 5);
|
|
|
|
if (!item.MoveToContainer(ss.inventory))
|
|
{
|
|
item.Remove();
|
|
}
|
|
else ss.ammoItem = item;
|
|
}
|
|
else if (ss.ammoItem.amount < 5) { ss.ammoItem.amount = 5; }
|
|
}
|
|
|
|
private void OnWeaponItemPreRemove(Item item)
|
|
{
|
|
var weaponvar = item.parent?.entityOwner;
|
|
|
|
if (weaponvar is AutoTurret)
|
|
{
|
|
weaponvar.Invoke(() => FillAmmoTurret(weaponvar as AutoTurret), 0.1f);
|
|
}
|
|
else if (weaponvar is SamSite)
|
|
{
|
|
weaponvar.Invoke(() => FillAmmoSamSite(weaponvar as SamSite), 0.1f);
|
|
}
|
|
}
|
|
|
|
private void Manuallyaddpoifunction(string[] Args, BasePlayer player)
|
|
{
|
|
if (Args.Length != 2)
|
|
{
|
|
Vector3 POI = new Vector3(player.transform.position.x, player.transform.position.y, player.transform.position.z);
|
|
PointsOfIntrest.Add(POI);
|
|
timer.Once(_ServerSettings.POIExpires, () => { PointsOfIntrest.Remove(POI); });
|
|
if (player != null) { player.ChatMessage("Set a point of intrest at your location."); }
|
|
}
|
|
else if (Args.Length == 2)
|
|
{
|
|
string sVector = Args[1];
|
|
if (sVector.StartsWith("(") && sVector.EndsWith(")")) { sVector = sVector.Substring(1, sVector.Length - 2); }
|
|
string[] sArray = sVector.Split(',');
|
|
Vector3 result = new Vector3(float.Parse(sArray[0]), float.Parse(sArray[1]), float.Parse(sArray[2]));
|
|
PointsOfIntrest.Add(result);
|
|
timer.Once(_ServerSettings.POIExpires, () => { PointsOfIntrest.Remove(result); });
|
|
if (player != null) { player.ChatMessage("Set a point of intrest at " + result.ToString()); }
|
|
}
|
|
}
|
|
|
|
private void PirateAttackedfunction(BaseCombatEntity bce, BasePlayer basePlayer)
|
|
{
|
|
if (bce == null || basePlayer == null) { return; }
|
|
AirPirates ap = bce.GetComponent<AirPirates>();
|
|
if (ap != null) { ap._targetList.Add(new targetinfo(basePlayer, basePlayer)); return; }
|
|
LandPirate lp = bce.GetComponent<LandPirate>();
|
|
if (lp != null) { lp.PlayerTarget = basePlayer; return; }
|
|
WaterPirate wp = bce.GetComponent<WaterPirate>();
|
|
if (wp != null) { if (TerrainMeta.HeightMap.GetHeight(basePlayer.transform.position) < -2f) { wp.PlayerTarget = basePlayer; } return; }
|
|
}
|
|
|
|
private bool BaseDamagefunction(BaseCombatEntity entity)
|
|
{
|
|
if (entity is Door) return true;
|
|
if (!(entity is BuildingBlock)) return false;
|
|
return ((BuildingBlock)entity).grade != BuildingGrade.Enum.Twigs;
|
|
}
|
|
|
|
private void SamLogicfunction(SamSite samSite, BaseEntity be, Vector3 currentVelocity, float currentspeed)
|
|
{
|
|
try
|
|
{
|
|
if (!samSite.HasAmmo() || currentVelocity == null || be == null) { return; }
|
|
if (be.HasFlag(BaseEntity.Flags.On) || be.HasFlag(BaseEntity.Flags.Reserved2))
|
|
{
|
|
Vector3 estimatedPoint = PredictedPosfunction(be, samSite, currentVelocity);
|
|
estimatedPoint += be.transform.forward * (currentspeed + 3f);
|
|
samSite.currentAimDir = (estimatedPoint - samSite.eyePoint.transform.position).normalized;
|
|
Vector3 vector = Quaternion.LookRotation(samSite.currentAimDir, samSite.transform.up).eulerAngles;
|
|
vector = BaseMountable.ConvertVector(vector);
|
|
float t = Mathf.InverseLerp(0f, 90f, -vector.x);
|
|
float z = Mathf.Lerp(15f, -75f, t);
|
|
Quaternion localRotationq = Quaternion.Euler(0f, vector.y, 0f);
|
|
samSite.yaw.transform.localRotation = localRotationq;
|
|
Quaternion localRotation2 = Quaternion.Euler(samSite.pitch.transform.localRotation.eulerAngles.x, samSite.pitch.transform.localRotation.eulerAngles.y, z);
|
|
samSite.pitch.transform.localRotation = localRotation2;
|
|
samSite.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
|
|
FireProjectilefunction(samSite, samSite.currentAimDir, 1);
|
|
Effect.server.Run(samSite.muzzleFlashTest.resourcePath, samSite, StringPool.Get("Tube " + (samSite.currentTubeIndex + 1).ToString()), Vector3.zero, Vector3.up, null, false);
|
|
samSite.ammoItem.UseItem(1);
|
|
samSite.currentTubeIndex++;
|
|
if (samSite.currentTubeIndex >= samSite.tubes.Length) { samSite.currentTubeIndex = 0; }
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private void FireProjectilefunction(SamSite origin, Vector3 direction, float speedMultiplier)
|
|
{
|
|
BaseEntity baseEntity = GameManager.server.CreateEntity(origin.projectileTest.resourcePath, origin.tubes[origin.currentTubeIndex].position, Quaternion.LookRotation(direction, Vector3.up));
|
|
if (!(baseEntity == null))
|
|
{
|
|
baseEntity.creatorEntity = origin;
|
|
ServerProjectile component = baseEntity.GetComponent<ServerProjectile>();
|
|
TimedExplosive rocket = baseEntity.GetComponent<TimedExplosive>();
|
|
rocket.SetDamageScale(_ServerSettings.SamSitesDamageFloat);
|
|
if ((bool)component) { component.InitializeVelocity(origin.GetInheritedProjectileVelocity(direction) + direction * component.speed * speedMultiplier); }
|
|
baseEntity.Spawn();
|
|
baseEntity.enableSaving = false;
|
|
}
|
|
}
|
|
|
|
private Vector3 PredictedPosfunction(BaseEntity target, SamSite samSite, Vector3 targetVelocity)
|
|
{
|
|
Vector3 targetposv = target.transform.TransformPoint(target.transform.GetBounds().center);
|
|
Vector3 displacement0 = targetposv - samSite.eyePoint.transform.position;
|
|
float projectileSpeed = samSite.projectileTest.Get().GetComponent<ServerProjectile>().speed;
|
|
float targetMoveAngle = Vector3.Angle(-displacement0, targetVelocity) * Mathf.Deg2Rad;
|
|
if (targetVelocity.magnitude == 0 || targetVelocity.magnitude > projectileSpeed && Mathf.Sin(targetMoveAngle) / projectileSpeed > Mathf.Cos(targetMoveAngle) / targetVelocity.magnitude) { return targetposv; }
|
|
float shootAngle = Mathf.Asin(Mathf.Sin(targetMoveAngle) * targetVelocity.magnitude / projectileSpeed);
|
|
return targetposv + targetVelocity * displacement0.magnitude / Mathf.Sin(Mathf.PI - targetMoveAngle - shootAngle) * Mathf.Sin(shootAngle) / targetVelocity.magnitude;
|
|
}
|
|
|
|
private List<BaseEntity> CreateWallsfunction(Vector3 center, float radius)
|
|
{
|
|
List<BaseEntity> WallsList = new List<BaseEntity>();
|
|
string prefabstring = StringPool.Get(1745077396);
|
|
bool gate = true;
|
|
float maxHeightfloat = -499f;
|
|
float minHeightfloat = 999f;
|
|
int raycasts = Mathf.CeilToInt(360 / radius * 0.1375f);
|
|
foreach (var position in GetCircumferencePositions(center, radius, raycasts, false))
|
|
{
|
|
maxHeightfloat = Mathf.Max(position.y, maxHeightfloat, TerrainMeta.WaterMap.GetHeight(position));
|
|
minHeightfloat = Mathf.Min(position.y, minHeightfloat);
|
|
center.y = minHeightfloat;
|
|
}
|
|
float gap = 0.10f;
|
|
float next = 360 / radius - gap;
|
|
float j = 1 * 6f + 6f;
|
|
float groundHeightFLOAT = 0f;
|
|
BaseEntity e;
|
|
List<Vector3> wallpos = GetCircumferencePositions(center, radius, next, false, center.y);
|
|
int halfway = (int)(wallpos.Count / 2);
|
|
int count = 0;
|
|
foreach (var position in wallpos)
|
|
{
|
|
if (center.y - position.y > 48f) { continue; }
|
|
Quaternion Rotation = Quaternion.Euler(0, 180, 0);
|
|
groundHeightFLOAT = TerrainMeta.HeightMap.GetHeight(new Vector3(position.x, position.y + 6f, position.z));
|
|
if (groundHeightFLOAT > position.y + 9f) { continue; }
|
|
if (position.y - groundHeightFLOAT > j && position.y < TerrainMeta.HeightMap.GetHeight(position)) { continue; }
|
|
if (!gate && count != halfway) { e = GameManager.server.CreateEntity(prefabstring, new Vector3(position.x, TerrainMeta.HeightMap.GetHeight(position) - 0.2f, position.z), default(Quaternion), false); }
|
|
else { e = GameManager.server.CreateEntity(StringPool.Get(95147612), new Vector3(position.x, TerrainMeta.HeightMap.GetHeight(position) - 0.25f, position.z), default(Quaternion), false); gate = false; Rotation = Quaternion.Euler(0, 0, 0); }
|
|
if (e == null) { continue; }
|
|
e.OwnerID = (ulong)UnityEngine.Random.Range(10000000, 20000000);
|
|
e.transform.LookAt(center, Vector3.up);
|
|
e.transform.rotation *= Rotation;
|
|
e.enableSaving = false;
|
|
e.Spawn();
|
|
e.enableSaving = false;
|
|
WallsList.Add(e);
|
|
e.gameObject.SetActive(true);
|
|
count++;
|
|
}
|
|
return WallsList;
|
|
}
|
|
|
|
private List<byte[]> ArrayToByteArrayList(byte[] bytes, int offset = 0)
|
|
{
|
|
List<byte[]> packetbytes = new List<byte[]>();
|
|
List<int> packetchecksum = new List<int>();
|
|
for (int checksum = 0; checksum < bytes.Length - offset;)
|
|
{
|
|
packetchecksum.Add(BitConverter.ToInt32(bytes, offset));
|
|
offset += 4;
|
|
checksum = packetchecksum.Sum();
|
|
if (checksum > bytes.Length - offset)
|
|
{
|
|
Puts("Unpacking Stream Failed!");
|
|
return null;
|
|
}
|
|
}
|
|
foreach (int size in packetchecksum) { packetbytes.Add(bytes.Skip(offset).Take(size).ToArray()); offset += size; }
|
|
return packetbytes;
|
|
}
|
|
|
|
public bool IsBase64String(string s) { s = s.Trim(); return (s.Length % 4 == 0) && Regex.IsMatch(s, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None); }
|
|
|
|
public void WebPlayback(string URL, BasePlayer Target)
|
|
{
|
|
if (URL == "" || Target == null || Target.net == null) { return; }
|
|
NetworkableId ID = Target.net.ID;
|
|
if (!GroundedNPCs.Contains(ID) && !NPCsUintList.Contains(ID)) { return; }
|
|
if (Target.transform.position.y > TerrainMeta.HeightMap.GetHeight(Target.transform.position) + 20f) { return; }
|
|
foreach (Connection c in BaseNetworkable.GetConnectionsWithin(Target.transform.position, 50))
|
|
{
|
|
BasePlayer p = c.player as BasePlayer;
|
|
if (p != null) { if (GamePhysics.LineOfSight(p.eyes.transform.position, Target.transform.position + new Vector3(0, -4, 0), -1)) { return; } }
|
|
}
|
|
Vector3 backuppos = new Vector3(Target.transform.position.x, Target.transform.position.y, Target.transform.position.z);
|
|
webrequest.Enqueue(URL, null, (code, response) =>
|
|
{
|
|
if (code != 200 || response == null) { Puts($"Error: {code}"); return; }
|
|
if (IsBase64String(response))
|
|
{
|
|
List<byte[]> VD = ArrayToByteArrayList(Convert.FromBase64String(response));
|
|
Vector3 GroundPos = backuppos + new Vector3(0, -4, 0);
|
|
BasePlayer newPlayer = GameManager.server.CreateEntity(playerentityprefab, GroundPos).ToPlayer();
|
|
newPlayer.Spawn();
|
|
newPlayer.enableSaving = false;
|
|
Interface.Oxide.CallHook("OnNPCRespawn", newPlayer);
|
|
CreateCloths(newPlayer, "burlap.gloves", 2488609451);
|
|
CreateCloths(newPlayer, "hoodie", 2488607577);
|
|
CreateCloths(newPlayer, "pants", 2488608085);
|
|
CreateCloths(newPlayer, "shoes.boots", 2488606012);
|
|
newPlayer.modelState.ducked = true;
|
|
if (Target != null && newPlayer != null) { newPlayer.SetParent(Target, true, true); }
|
|
newPlayer.transform.localScale = Vector3.zero;
|
|
BaseEntity.Query.Server.RemovePlayer(newPlayer);
|
|
NetworkableId IDnum = newPlayer.net.ID;
|
|
VoiceUintList.Add(IDnum);
|
|
timer.Once((VD.Count / 10) + 4f, () => { VoiceUintList.Remove(IDnum); newPlayer.Kill(); });
|
|
NextFrame(() => { Threads.Add(InvokeHandler.Instance.StartCoroutine(PlayVoicefunction(VD, newPlayer))); });
|
|
}
|
|
else { Puts("WebVoice URL Fault!"); }
|
|
}, this, RequestMethod.GET);
|
|
}
|
|
|
|
private IEnumerator PlayVoicefunction(List<byte[]> VD, BasePlayer bot)
|
|
{
|
|
if (VD == null || bot == null) yield break;
|
|
foreach (byte[] data in VD)
|
|
{
|
|
if (Network.Net.sv.IsConnected())
|
|
{
|
|
NetWrite netWrite = Network.Net.sv.StartWrite();
|
|
netWrite.PacketID(Network.Message.Type.VoiceData);
|
|
netWrite.UInt64(bot.net.ID.Value);
|
|
netWrite.BytesWithSize(data);
|
|
netWrite.Send(new SendInfo(BaseNetworkable.GetConnectionsWithin(bot.transform.position, 100)) { priority = Network.Priority.Immediate });
|
|
}
|
|
yield return new WaitForSeconds(0.1f);
|
|
}
|
|
}
|
|
|
|
private IEnumerator MapRoutine()
|
|
{
|
|
do
|
|
{
|
|
try { DrawMapfunction(); } catch { }
|
|
yield return CoroutineEx.waitForSeconds(30);
|
|
} while (true);
|
|
}
|
|
|
|
private void MarkerDisplayingDelete()
|
|
{
|
|
foreach (var m in mapmarkersList)
|
|
{
|
|
if (m != null && !m.IsDestroyed)
|
|
{
|
|
m.Kill();
|
|
m.SendUpdate();
|
|
}
|
|
}
|
|
mapmarkersList.Clear();
|
|
}
|
|
|
|
private void DrawMapfunction()
|
|
{
|
|
MarkerDisplayingDelete();
|
|
if (PirateUintList.Count == 0) { return; }
|
|
foreach (NetworkableId p in PirateUintList.ToArray())
|
|
{
|
|
try
|
|
{
|
|
if (BaseNetworkable.serverEntities.entityList.Contains(p))
|
|
{
|
|
BaseEntity be = BaseNetworkable.serverEntities.entityList[p] as BaseEntity;
|
|
if (be != null && !be.IsDestroyed)
|
|
{
|
|
MapMarkerGenericRadius MapMarkerCustom;
|
|
MapMarkerCustom = GameManager.server.CreateEntity(mapmarkerentityprefab) as MapMarkerGenericRadius;
|
|
MapMarkerCustom.alpha = _ServerSettings.MapMarkerAlpha;
|
|
MapMarkerCustom.radius = _ServerSettings.MapMarkerSize;
|
|
if (be.HasComponent<AirPirates>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.AirMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.AirMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<WaterPirate>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.WaterMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.WaterMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<LandPirate>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.LandMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.LandMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<LandPirate>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.LandMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.LandMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<BasePirate>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.BaseMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.BaseMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<RailPirate>())
|
|
{
|
|
MapMarkerCustom.color1 = _ServerSettings.RailMapMarkerColour;
|
|
MapMarkerCustom.color2 = _ServerSettings.RailMapMarkerColour;
|
|
}
|
|
else if (be.HasComponent<FootPirate>())
|
|
{
|
|
MapMarkerCustom.color1 = Color.white;
|
|
MapMarkerCustom.color2 = Color.white;
|
|
MapMarkerCustom.alpha = 1;
|
|
MapMarkerCustom.radius *= 0.5f;
|
|
}
|
|
|
|
MapMarkerCustom.SetParent(be, false, true);
|
|
if (MapMarkerCustom.transform.position != new Vector3(0, 0, 0)) { mapmarkersList.Add(MapMarkerCustom); }
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
foreach (var m in mapmarkersList)
|
|
{
|
|
m.Spawn();
|
|
MapMarker.serverMapMarkers.Remove(m);
|
|
m.SendUpdate();
|
|
}
|
|
}
|
|
|
|
private void BuildLootTablefunction()
|
|
{
|
|
_ServerSettings.LootProfiles = plugin.Config["XLootCustomProfiles"].ToString();
|
|
if (_ServerSettings.LootProfiles == "") { Puts("No Loot Table"); return; }
|
|
loottableDict.Clear();
|
|
try
|
|
{
|
|
if (_ServerSettings.LootProfiles.Contains("<Profile>"))
|
|
{
|
|
string[] profiles = _ServerSettings.LootProfiles.Split(new string[] { "<Profile>" }, System.StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (string p in profiles)
|
|
{
|
|
string[] items = p.Split(new string[] { "|" }, System.StringSplitOptions.RemoveEmptyEntries);
|
|
var profiledata = new List<Dictionary<string, string>>();
|
|
foreach (string ent in items)
|
|
{
|
|
Dictionary<string, string> data = new Dictionary<string, string>();
|
|
string[] iteminfo = ent.Split(new string[] { "," }, System.StringSplitOptions.RemoveEmptyEntries);
|
|
if (iteminfo.Length < 2) { continue; }
|
|
data.Add(iteminfo[0], ent.Replace(iteminfo[0] + ",", ""));
|
|
profiledata.Add(data);
|
|
}
|
|
loottableDict.Add(profiledata);
|
|
}
|
|
Puts("Rebuilt Loot Table, " + loottableDict.Count.ToString() + " profiles loaded");
|
|
return;
|
|
}
|
|
}
|
|
catch { }
|
|
Puts("Invalid Loot Table");
|
|
return;
|
|
}
|
|
|
|
private void LootContainerfunction(BasePlayer playerVAR, ItemContainer containerVAR)
|
|
{
|
|
playerVAR.inventory.loot.Clear();
|
|
playerVAR.inventory.loot.PositionChecks = false;
|
|
playerVAR.inventory.loot.entitySource = containerVAR.entityOwner ?? playerVAR;
|
|
playerVAR.inventory.loot.itemSource = null;
|
|
playerVAR.inventory.loot.MarkDirty();
|
|
playerVAR.inventory.loot.AddContainer(containerVAR);
|
|
playerVAR.inventory.loot.SendImmediate();
|
|
playerVAR.ClientRPCPlayer(null, playerVAR, "RPC_OpenLootPanel", "generic_resizable");
|
|
}
|
|
|
|
private void filllootfunction(ItemContainer itemb, int selectINT, int multi, string CreatePrefab = "")
|
|
{
|
|
int selectionINT = selectINT;
|
|
if (itemb == null) { return; }
|
|
if (multi == 0)
|
|
{
|
|
if (loottableDict == null || loottableDict.Count == 0) { return; }
|
|
if (selectionINT > loottableDict.Count) { return; }
|
|
foreach (Dictionary<string, string> i in loottableDict[selectionINT].ToArray())
|
|
{
|
|
foreach (KeyValuePair<string, string> it in i.ToArray())
|
|
{
|
|
try
|
|
{
|
|
string[] iteminfo = it.Value.Split(',');
|
|
Item item = ItemManager.CreateByName(it.Key, int.Parse(iteminfo[0]), ulong.Parse(iteminfo[1]));
|
|
if (item == null) { continue; }
|
|
if (!item.MoveToContainer(itemb, -1, false)) { item.Remove(); }
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|
|
|
|
for (int m = 0; m <= multi; m++)
|
|
{
|
|
if (selectINT == -1) { selectionINT = Core.Random.Range(0, plugin.loottableDict.Count); }
|
|
if (CreatePrefab == "")
|
|
{
|
|
if (loottableDict.Count == 0) { return; }
|
|
foreach (Dictionary<string, string> i in loottableDict[selectionINT].ToArray())
|
|
{
|
|
foreach (KeyValuePair<string, string> it in i.ToArray())
|
|
{
|
|
try
|
|
{
|
|
string[] iteminfo = it.Value.Split(',');
|
|
Item item = ItemManager.CreateByName(it.Key, int.Parse(iteminfo[0]), ulong.Parse(iteminfo[1]));
|
|
if (item == null) { continue; }
|
|
if (!item.MoveToContainer(itemb, -1, false)) { item.Remove(); }
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
StorageContainer baseEntity = GameManager.server.CreateEntity(CreatePrefab) as StorageContainer;
|
|
if (baseEntity != null && itemb != null)
|
|
{
|
|
baseEntity.enableSaving = false;
|
|
baseEntity.SendMessage("SetWasDropped", SendMessageOptions.DontRequireReceiver);
|
|
baseEntity.Spawn();
|
|
baseEntity.enableSaving = false;
|
|
foreach (Item i in baseEntity.inventory.itemList.ToList()) { if (i != null) { i.MoveToContainer(itemb); } }
|
|
NextFrame(() => { if (baseEntity != null && !baseEntity.IsDestroyed) { baseEntity.Kill(); } });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void savelootfunction()
|
|
{
|
|
string newloottable = "";
|
|
if (loottableDict.Count != 0)
|
|
{
|
|
foreach (List<Dictionary<string, string>> profiles in loottableDict)
|
|
{
|
|
newloottable += "<Profile>";
|
|
foreach (Dictionary<string, string> i in profiles) { foreach (KeyValuePair<string, string> it in i) { newloottable += it.Key + "," + it.Value + "|"; } }
|
|
}
|
|
Config["XLootCustomProfiles"] = newloottable;
|
|
NextFrame(() => { Config.Save(); });
|
|
timer.Once(1f, () => { BuildLootTablefunction(); });
|
|
}
|
|
}
|
|
|
|
private bool IsKitbool(string kit)
|
|
{
|
|
var success = Kits?.Call("isKit", kit);
|
|
if (success == null || !(success is bool)) { return false; }
|
|
return (bool)success;
|
|
}
|
|
|
|
private void GiveKitfunction(NPCPlayer npc, string NPCKit)
|
|
{
|
|
if (Kits == null) { return; };
|
|
if (NPCKit == "" || !IsKitbool(NPCKit)) { return; };
|
|
object success = Kits?.Call("GiveKit", npc, NPCKit);
|
|
if (success == null || !(success is bool))
|
|
{
|
|
Puts("Failed to give NPC Kit");
|
|
return;
|
|
}
|
|
Item projectileItem = null;
|
|
foreach (var item in npc.inventory.containerBelt.itemList.ToList())
|
|
{
|
|
if (item.GetHeldEntity() is BaseProjectile)
|
|
{
|
|
projectileItem = item;
|
|
break;
|
|
}
|
|
if (item.GetHeldEntity() is MedicalTool)
|
|
{
|
|
item.MoveToContainer(npc.inventory.containerMain);
|
|
continue;
|
|
}
|
|
}
|
|
if (projectileItem == null)
|
|
{
|
|
foreach (var item in npc.inventory.containerBelt.itemList.ToList())
|
|
{
|
|
if (item.GetHeldEntity() is BaseMelee)
|
|
{
|
|
projectileItem = item;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (projectileItem != null)
|
|
{
|
|
npc.UpdateActiveItem(projectileItem.uid);
|
|
npc.inventory.UpdatedVisibleHolsteredItems();
|
|
timer.Once(1f, () => { npc.AttemptReload(); });
|
|
}
|
|
}
|
|
|
|
private void BailOutfunction(Vector3 pos, ScientistNPC npc, Vector3 home, int radius, float distance = 0, bool die = true)
|
|
{
|
|
if (npc != null)
|
|
{
|
|
NPCsUintList.Remove(npc.net.ID);
|
|
npc.EnsureDismounted();
|
|
npc.SetParent(null, true, true);
|
|
npc.transform.position = pos;
|
|
if (!GroundedNPCs.Contains(npc.net.ID))
|
|
{
|
|
float d = radius;
|
|
Vector2 vector = Vector3.zero;
|
|
Vector3 newPos = Vector3.zero;
|
|
for (int scan = 0; scan < 50; scan++)
|
|
{
|
|
vector = UnityEngine.Random.insideUnitCircle * d;
|
|
newPos = pos + new Vector3(vector.x, 0, vector.y);
|
|
if (Vector3.Distance(newPos, pos) < distance) { continue; }
|
|
if (TerrainMeta.HeightMap.GetHeight(newPos) > -0.4f) { break; }
|
|
}
|
|
npc.modelState.mounted = false;
|
|
if (die) { plugin.timer.Once(_ServerSettings.NPCParachuteDie, () => { if (npc != null && npc.IsAlive() && !npc.IsDestroyed) { GroundedNPCs.Remove(npc.net.ID); npc.Kill(); } }); }
|
|
newPos.y = TerrainMeta.HeightMap.GetHeight(newPos) + 4f;
|
|
npc.transform.position = newPos;
|
|
var rb = npc.gameObject.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.drag = 0f;
|
|
rb.useGravity = false;
|
|
rb.isKinematic = false;
|
|
rb.velocity = new Vector3(npc.transform.forward.x * 0, 0, npc.transform.forward.z * 0) - new Vector3(0, 2, 0);
|
|
}
|
|
npc.SendNetworkUpdateImmediate();
|
|
plugin.NextFrame(() => { if (npc != null) { GroundCheckfunction(npc, home); } });
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AttachParachute(ScientistNPC npc, Vector3 pos)
|
|
{
|
|
if (npc == null || npc.IsDead()) { return; }
|
|
if (TerrainMeta.HeightMap.GetHeight(npc.transform.position) < -0.4f) { NPCsUintList.Remove(npc.net.ID); ActiveNPCs.Remove(npc); npc.Die(); }
|
|
npc.transform.localPosition = Vector3.zero;
|
|
npc.transform.localRotation = Quaternion.Euler(Vector3.zero);
|
|
npc.SetParent(null, true, true);
|
|
npc.transform.position = pos;
|
|
npc.transform.rotation = Quaternion.Euler(0, 0, 0);
|
|
npc.SendNetworkUpdateImmediate();
|
|
var rb = npc.gameObject.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.drag = 0f;
|
|
rb.useGravity = false;
|
|
rb.isKinematic = false;
|
|
rb.velocity = new Vector3(npc.transform.forward.x * 0, 0, npc.transform.forward.z * 0) - new Vector3(0, 5, 0);
|
|
}
|
|
timer.Once(1f, () =>
|
|
{
|
|
if (npc == null) { return; }
|
|
timer.Once(_ServerSettings.NPCParachuteDie, () => { if (npc == null) { return; } if (npc.IsAlive() && !npc.IsDestroyed) { GroundedNPCs.Remove(npc.net.ID); npc.Kill(); } });
|
|
var Chute = GameManager.server.CreateEntity(parachuteentityprefab, npc.transform.position, Quaternion.Euler(0, 0, 0));
|
|
if (Chute != null)
|
|
{
|
|
Chute.SetParent(npc, 0, true, true);
|
|
Vector3 movepos = Vector3.zero;
|
|
movepos += npc.transform.forward * -0.10f;
|
|
movepos += npc.transform.up * 1.5f;
|
|
Chute.transform.localPosition = movepos;
|
|
Chute.transform.rotation = Quaternion.FromToRotation(Chute.transform.up, Vector3.up) * Chute.transform.rotation;
|
|
Chute.SendNetworkUpdateImmediate();
|
|
DestroyMeshCollider(Chute);
|
|
Chute.Spawn();
|
|
Chute.enableSaving = false;
|
|
timer.Once(_ServerSettings.NPCParachuteDecay, () =>
|
|
{
|
|
if (Chute != null)
|
|
{
|
|
Chute.SetParent(null, true, true);
|
|
Effect.server.Run(groundfallentityprefab, Chute.transform.position);
|
|
NextFrame(() => { Chute.Kill(); });
|
|
}
|
|
});
|
|
NextFrame(() => { GroundCheckfunction(npc, Vector3.zero, Chute); });
|
|
}
|
|
});
|
|
}
|
|
|
|
private bool collidersbool(Vector3 position)
|
|
{
|
|
List<BuildingBlock> obj = Pool.GetList<BuildingBlock>();
|
|
Vis.Entities(position, 6, obj, -1);
|
|
if (obj != null && obj.Count != 0)
|
|
{
|
|
foreach (BuildingBlock b in obj)
|
|
{
|
|
if (b.OwnerID.ToString().Length >= 17)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void GroundCheckfunction(ScientistNPC npc, Vector3 home, BaseEntity Chute = null)
|
|
{
|
|
if (npc == null || npc.IsDead() || npc.IsDestroyed) { if (Chute != null) { Chute.SetParent(null, true, true); Chute.Kill(); } return; }
|
|
if (npc.transform.position.y > TerrainMeta.HeightMap.GetHeight(npc.transform.position) + 8f)
|
|
{
|
|
timer.Once(0.1f, () => { if (npc != null) { GroundCheckfunction(npc, home, Chute); } });
|
|
return;
|
|
}
|
|
if (collidersbool(npc.transform.position)) { { npc.Die(); } }
|
|
RaycastHit raycastHit;
|
|
if (Physics.SphereCast(npc.transform.position, 3f, Vector3.down, out raycastHit, 5f, -1) || Physics.SphereCast(npc.transform.position, 3f, Vector3.up, out raycastHit, 5f, -1))
|
|
{
|
|
var rb = npc.gameObject.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
npc.gameObject.layer = 17;
|
|
if (Chute != null)
|
|
{
|
|
Chute.SetParent(null, true, true);
|
|
Effect.server.Run(groundfallentityprefab, Chute.transform.position);
|
|
NextFrame(() => { Chute.Kill(); });
|
|
}
|
|
}
|
|
npc.transform.position = raycastHit.point;
|
|
npc.Brain.Navigator.MaxRoamDistanceFromHome = _ServerSettings.PirateFootNPCRoam;
|
|
npc.Brain.Navigator.BestMovementPointMaxDistance = 30f;
|
|
if (home != Vector3.zero)
|
|
{
|
|
npc.Brain.Events.Memory.Position.Set(home, 4);
|
|
}
|
|
else
|
|
{
|
|
npc.Brain.Events.Memory.Position.Set(npc.transform.position, 4);
|
|
}
|
|
npc.Brain.Navigator.BestRoamPointMaxDistance = 40f;
|
|
npc.Brain.Navigator.DefaultArea = "Walkable";
|
|
npc.Brain.Navigator.Agent.agentTypeID = -1372625422;
|
|
npc.Brain.Navigator.MaxWaterDepth = 1f;
|
|
npc.Brain.Navigator.CanUseNavMesh = true;
|
|
npc.Brain.Navigator.Init(npc, npc.Brain.Navigator.Agent);
|
|
npc.Brain.Navigator.SetCurrentNavigationType(BaseNavigator.NavigationType.None);
|
|
npc.SendNetworkUpdateImmediate();
|
|
NPCsUintList.Remove(npc.net.ID);
|
|
GroundedNPCs.Add(npc.net.ID);
|
|
npc.RecoverFromWounded();
|
|
return;
|
|
}
|
|
if (npc.transform.position.y + 0.5f < TerrainMeta.HeightMap.GetHeight(npc.transform.position))
|
|
{
|
|
Vector2 vector = UnityEngine.Random.insideUnitCircle * 4;
|
|
Vector3 newpos = npc.transform.position + new Vector3(vector.x, 0, vector.y);
|
|
newpos.y = TerrainMeta.HeightMap.GetHeight(newpos);
|
|
npc.transform.position = newpos;
|
|
npc.TransformChanged();
|
|
npc.Brain.Navigator.CanUseNavMesh = false;
|
|
var rb = npc.gameObject.GetComponent<Rigidbody>();
|
|
if (rb != null)
|
|
{
|
|
rb.isKinematic = true;
|
|
rb.useGravity = false;
|
|
rb.velocity = new Vector3(npc.transform.forward.x * 0, 0, npc.transform.forward.z * 0) - new Vector3(0, 0, 0);
|
|
npc.gameObject.layer = 17;
|
|
}
|
|
return;
|
|
}
|
|
if (npc.transform.position.y < TerrainMeta.HeightMap.GetHeight(npc.transform.position) - 2f) { npc.Kill(); return; }
|
|
timer.Once(0.1f, () => { if (npc != null) { GroundCheckfunction(npc, home, Chute); } });
|
|
}
|
|
|
|
private void Explodefunction(BaseEntity be)
|
|
{
|
|
if (be == null) { return; }
|
|
plugin.RunEffect(c4_explosionentityprefab, be, be.transform.position);
|
|
plugin.RunEffect(damage_effect_debrisprefab, be, be.transform.position);
|
|
BasePirate pb = be.GetComponent<BasePirate>();
|
|
if (pb != null) { pb.Die(); }
|
|
AirPirates ap = be.GetComponent<AirPirates>();
|
|
if (ap != null) { DropLootfunction(ap.npcs, ap.itembox); }
|
|
WaterPirate wp = be.GetComponent<WaterPirate>();
|
|
if (wp != null) { DropLootfunction(wp.npcs, wp.itembox); }
|
|
RailPirate rp = be.GetComponent<RailPirate>();
|
|
if (rp != null) { DropLootfunction(rp.npcs, rp.itembox); KillWagonsfunction(rp.wagons.ToList()); }
|
|
foreach (NetworkableId id in NPCsUintList.ToArray()) { if (!BaseEntity.serverEntities.Contains(id)) { NPCsUintList.Remove(id); } }
|
|
NextFrame(() => { if (!be.IsDestroyed) { be.AdminKill(); } });
|
|
}
|
|
|
|
private void DropLootfunction(List<ScientistNPC> npcs, StorageContainer itembox)
|
|
{
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc != null && !npc.IsDestroyed && !npc.IsDead()) npc.Die(); } }
|
|
if (itembox != null) { itembox.dropFloats = true; itembox.DropItems(); }
|
|
}
|
|
|
|
private NightLight CreateLightfunction(BaseEntity be, Vector3 LocationPos, Vector3 Rot)
|
|
{
|
|
SphereEntity sph = (SphereEntity)GameManager.server.CreateEntity(sphereentityprefab, be.transform.position, new Quaternion(0, 0, 0, 0), true);
|
|
plugin.DestroyMeshCollider(sph);
|
|
plugin.DestroyGroundComp(sph);
|
|
sph.Spawn();
|
|
sph.SetParent(be);
|
|
sph.transform.localPosition = new Vector3(0, -150, 0);
|
|
SearchLight searchLightE0 = GameManager.server.CreateEntity(searchlightentityprefab, sph.transform.position) as SearchLight;
|
|
plugin.DestroyMeshCollider(searchLightE0);
|
|
plugin.DestroyGroundComp(searchLightE0);
|
|
searchLightE0.Spawn();
|
|
searchLightE0.SetFlag(BaseEntity.Flags.Reserved5, true, false, true);
|
|
searchLightE0.SetFlag(BaseEntity.Flags.Busy, true);
|
|
searchLightE0.SetParent(sph);
|
|
searchLightE0.transform.localPosition = new Vector3(0, 0, 0);
|
|
searchLightE0.transform.localRotation = Quaternion.Euler(Rot);
|
|
searchLightE0.pickup.enabled = false;
|
|
searchLightE0.SendNetworkUpdate();
|
|
searchLightE0.enableSaving = false;
|
|
sph.transform.localScale += new Vector3(0.9f, 0, 0);
|
|
sph.LerpRadiusTo(0.01f, 10f);
|
|
searchLightE0.Invoke(() => { if (sph != null) { sph.transform.localPosition = LocationPos; sph.SendNetworkUpdateImmediate(); } }, 3f);
|
|
NightLight nl = new NightLight();
|
|
nl._light = searchLightE0;
|
|
nl.resizer = sph;
|
|
return nl;
|
|
}
|
|
|
|
private List<ScientistNPC> CreateNPCs(int NPCAmountint, int Type, float NPCHealth, string Kit, float AIShootMultiplyer, BaseEntity baseEntity, List<Vector3> Seats)
|
|
{
|
|
List<ScientistNPC> npcs = new List<ScientistNPC>();
|
|
foreach (Vector3 position in Seats)
|
|
{
|
|
if (npcs.Count >= NPCAmountint) { return npcs; }
|
|
var prefabName = StringPool.Get(3763080634);
|
|
var prefab = GameManager.server.FindPrefab(prefabName);
|
|
var go = Facepunch.Instantiate.GameObject(prefab);
|
|
go.SetActive(false);
|
|
go.name = prefabName;
|
|
go.transform.position = new Vector3(0, 3, 0);
|
|
ScientistNPC npc = go.GetComponent<ScientistNPC>();
|
|
SceneManager.MoveGameObjectToScene(go, Rust.Server.EntityScene);
|
|
npc.userID = (ulong)UnityEngine.Random.Range(0, 10000000);
|
|
npc.UserIDString = npc.userID.ToString();
|
|
npc.displayName = _ServerSettings.NPCNameTag + RandomUsernames.Get(npc.userID);
|
|
npc.startHealth = NPCHealth;
|
|
ScientistBrain brain = npc.GetComponent<ScientistBrain>();
|
|
if (brain != null) { brain.AttackRangeMultiplier = AIShootMultiplyer; brain.SenseRange = 100; brain.CheckVisionCone = false; brain.CheckLOS = false; }
|
|
go.SetActive(true);
|
|
npc.Spawn();
|
|
if (npc == null) { continue; }
|
|
npcs.Add(npc);
|
|
NPCsUintList.Add(npc.net.ID);
|
|
npc.enableSaving = false;
|
|
npc.isSpawned = false;
|
|
timer.Once(5, () => { if (npc != null) { npc.isSpawned = true; } });
|
|
npc.inventory.Strip();
|
|
npc.InitializeHealth(NPCHealth, NPCHealth);
|
|
npc.aimConeScale *= _ServerSettings.NPCAimScaler;
|
|
npc.damageScale *= _ServerSettings.NPCDamageScaler;
|
|
if (baseEntity != null) { npc.transform.position = baseEntity.transform.position; }
|
|
BaseNavigator baseNavigator = npc.GetComponent<BaseNavigator>();
|
|
if (baseNavigator != null) { baseNavigator.CanUseNavMesh = false; }
|
|
switch (Type)
|
|
{
|
|
case 0:
|
|
if (npcs.Count >= 4 && baseEntity != null) { NPCSit(npc, baseEntity); }
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "jumpsuit.suit.blue", true, false); });
|
|
break;
|
|
case 1:
|
|
if ((npcs.Count == 0 || npcs.Count == 1) && baseEntity != null) { NPCSit(npc, baseEntity); }
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "jumpsuit.suit.blue", true, false); });
|
|
break;
|
|
case 2:
|
|
if (baseEntity != null) { NPCSit(npc, baseEntity); }
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "jumpsuit.suit", true, false); });
|
|
break;
|
|
case 3:
|
|
if ((npcs.Count == 0 || npcs.Count == 1 || npcs.Count >= 8) && baseEntity != null) { NPCSit(npc, baseEntity); }
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "jumpsuit.suit", true, false); });
|
|
break;
|
|
case 4:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "attire.ninja.suit", false, true); });
|
|
break;
|
|
case 5:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "hazmatsuit_scientist_arctic", false, false); });
|
|
break;
|
|
case 7:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "hazmatsuit.nomadsuit", false, false); });
|
|
break;
|
|
case 8:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "attire.banditguard", false, false, true); });
|
|
break;
|
|
case 9:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "attire.banditguard", false, false, true); });
|
|
break;
|
|
case 10:
|
|
plugin.timer.Once(Core.Random.Range(1, 3), () => { DressNPC(npc, Kit, "scientistsuit_heavy", false, false, false); });
|
|
break;
|
|
}
|
|
plugin.NextFrame(() =>
|
|
{
|
|
if (npc == null) { return; }
|
|
if (baseEntity != null)
|
|
{
|
|
npc.SetParent(baseEntity);
|
|
npc.transform.localPosition = position;
|
|
}
|
|
else
|
|
{
|
|
npc.transform.localPosition = new Vector3(0, 0, 0);
|
|
npc.transform.position = position;
|
|
npc.SendNetworkUpdateImmediate();
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter + 30, () => { if (npc != null) { DieInPeace(npc); } });
|
|
}
|
|
ActiveNPCs.Add(npc, null);
|
|
});
|
|
}
|
|
return npcs;
|
|
}
|
|
|
|
private void DieInPeace(ScientistNPC npc)
|
|
{
|
|
if (npc == null) { return; }
|
|
BaseEntity target = ActiveNPCs[npc];
|
|
if (PlayersNearbyfunction(npc.transform.position, 40) || target != null)
|
|
{
|
|
timer.Once(60, () => { if (npc != null) { DieInPeace(npc); } });
|
|
return;
|
|
}
|
|
npc.Kill();
|
|
}
|
|
|
|
private void DressNPC(HumanNPC npc, string Kit, string outfit, bool headset = false, bool assassin = false, bool mask = false)
|
|
{
|
|
if (npc == null) { return; }
|
|
if (Kit != "" && plugin.Kits != null) { plugin.GiveKitfunction(npc, Kit); }
|
|
else
|
|
{
|
|
CreateCloths(npc, outfit);
|
|
if (mask) { CreateCloths(npc, "hat.tigermask"); }
|
|
if (headset) { CreateCloths(npc, "twitch.headset"); }
|
|
if (assassin) { CreateGun(npc, "rifle.lr300", "weapon.mod.silencer"); }
|
|
else { CreateGun(npc, "rifle.semiauto", "weapon.mod.flashlight"); }
|
|
}
|
|
}
|
|
|
|
private void CreateCloths(BasePlayer npc, string ItemName, ulong skin = 0)
|
|
{
|
|
if (npc == null) { return; }
|
|
Item item = ItemManager.CreateByName(ItemName, 1, skin);
|
|
if (item == null) { return; }
|
|
if (!item.MoveToContainer(npc.inventory.containerWear, -1, false)) { item.Remove(); }
|
|
}
|
|
|
|
private void CreateGun(HumanNPC npc, string ItemName, string Attachment)
|
|
{
|
|
Item item = ItemManager.CreateByName(ItemName, 1, 0);
|
|
if (item == null) { return; }
|
|
BaseEntity be = item.GetHeldEntity();
|
|
if (be != null) { be.isSpawned = false; timer.Once(2f, () => { if (be != null) { be.isSpawned = true; } }); }
|
|
BaseEntity we = item.GetWorldEntity();
|
|
if (we != null) { we.isSpawned = false; timer.Once(2f, () => { if (we != null) { we.isSpawned = true; } }); }
|
|
if (!item.MoveToContainer(npc.inventory.containerBelt, -1, false)) { item.Remove(); return; }
|
|
if (be != null && be is BaseProjectile)
|
|
{
|
|
if (Attachment != "")
|
|
{
|
|
Item moditem = ItemManager.CreateByName(Attachment, 1, 0);
|
|
if (moditem != null && item.contents != null)
|
|
{
|
|
BaseEntity bemi = moditem.GetHeldEntity();
|
|
if (bemi != null) { bemi.isSpawned = false; timer.Once(2f, () => { if (bemi != null) { bemi.isSpawned = true; } }); }
|
|
BaseEntity wemi = moditem.GetWorldEntity();
|
|
if (wemi != null) { wemi.isSpawned = false; timer.Once(2f, () => { if (wemi != null) { wemi.isSpawned = true; } }); }
|
|
if (!moditem.MoveToContainer(item.contents)) { item.contents.Insert(moditem); }
|
|
}
|
|
}
|
|
timer.Once(4f, () => { if (npc != null && item != null) { npc.UpdateActiveItem(item.uid); } });
|
|
}
|
|
}
|
|
|
|
private void NPCSit(ScientistNPC npc, BaseEntity baseEntity)
|
|
{
|
|
if (npc == null) { return; }
|
|
npc.modelState.mounted = true;
|
|
npc.transform.rotation = baseEntity.transform.rotation;
|
|
npc.ServerRotation = baseEntity.transform.rotation;
|
|
npc.OverrideViewAngles(baseEntity.transform.rotation.eulerAngles);
|
|
npc.eyes.NetworkUpdate(baseEntity.transform.rotation);
|
|
}
|
|
|
|
private void assignPOIfunction(Vector3 AttackVector)
|
|
{
|
|
if (PointsOfIntrest.Count > 5) { return; }
|
|
if (PointsOfIntrest.Count == 0)
|
|
{
|
|
PointsOfIntrest.Add(AttackVector);
|
|
timer.Once(_ServerSettings.POIExpires, () => { PointsOfIntrest.Remove(AttackVector); });
|
|
}
|
|
else if (!PointsOfIntrest.Contains(AttackVector))
|
|
{
|
|
bool Close = false;
|
|
foreach (Vector3 poi in PointsOfIntrest.ToArray())
|
|
{
|
|
if (Vector3.Distance(poi, AttackVector) < 800)
|
|
{
|
|
Close = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!Close)
|
|
{
|
|
PointsOfIntrest.Add(AttackVector);
|
|
timer.Once(_ServerSettings.POIExpires, () => { PointsOfIntrest.Remove(AttackVector); });
|
|
}
|
|
}
|
|
}
|
|
|
|
private Vector3 getPOIfunction(Vector3 orig, float maxDistance)
|
|
{
|
|
if (PointsOfIntrest.Count != 0) { foreach (Vector3 poi in PointsOfIntrest.ToArray()) { if (Vector3.Distance(poi, orig) < maxDistance) { return (poi); } } }
|
|
return Vector3.zero;
|
|
}
|
|
|
|
private float GetSpawnHeight(Vector3 target)
|
|
{
|
|
float y = TerrainMeta.HeightMap.GetHeight(target);
|
|
float w = TerrainMeta.WaterMap.GetHeight(target);
|
|
float p = TerrainMeta.HighestPoint.y + 250f;
|
|
RaycastHit hit;
|
|
if (Physics.Raycast(new Vector3(target.x, w, target.z), Vector3.up, out hit, p, Layers.Mask.World))
|
|
{
|
|
y = Mathf.Max(y, hit.point.y);
|
|
if (Physics.Raycast(new Vector3(target.x, hit.point.y + 0.5f, target.z), Vector3.up, out hit, p, Layers.Mask.World)) { y = Mathf.Max(y, hit.point.y); }
|
|
}
|
|
return Mathf.Max(y, w);
|
|
}
|
|
|
|
private List<Vector3> GetCircumferencePositions(Vector3 center, float radius, float next, bool spawnHeight, float y = 0f)
|
|
{
|
|
var positions = new List<Vector3>();
|
|
if (next < 1f) { next = 1f; }
|
|
float angle = 0f;
|
|
float angleInRadians = 2 * (float)Math.PI;
|
|
while (angle < 360)
|
|
{
|
|
float radian = (angleInRadians / 360) * angle;
|
|
float x = center.x + radius * (float)Math.Cos(radian);
|
|
float z = center.z + radius * (float)Math.Sin(radian);
|
|
var a = new Vector3(x, 0f, z);
|
|
a.y = y == 0f ? spawnHeight ? GetSpawnHeight(a) : TerrainMeta.HeightMap.GetHeight(a) : y;
|
|
if (a.y < -48f) { a.y = -48f; }
|
|
positions.Add(a);
|
|
angle += next;
|
|
}
|
|
positions.RemoveAt(0);
|
|
return positions;
|
|
}
|
|
|
|
private Elevation GetTerrainElevation(Vector3 center)
|
|
{
|
|
float maxY = -1000;
|
|
float minY = 1000;
|
|
foreach (var position in GetCircumferencePositions(center, 20f, 30f, true))
|
|
{
|
|
if (position.y > maxY) maxY = position.y;
|
|
if (position.y < minY) minY = position.y;
|
|
}
|
|
return new Elevation { Min = minY, Max = maxY };
|
|
}
|
|
|
|
private IEnumerator GenerateAirGrid()
|
|
{
|
|
int minPos = (int)(World.Size / -2f);
|
|
int maxPos = (int)(World.Size / 2f);
|
|
int checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 80 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
for (float x = minPos; x < maxPos; x += 25f)
|
|
{
|
|
for (float z = minPos; z < maxPos; z += 25f)
|
|
{
|
|
var pos = new Vector3(x, 0f, z);
|
|
if (TerrainMeta.HeightMap.GetHeight(pos) < 0.5) { continue; }
|
|
pos.y = GetSpawnHeight(pos) + 50f;
|
|
var elevation = GetTerrainElevation(pos);
|
|
if (IsFlatTerrain(pos, elevation, 3)) { airnodes.Add(pos); }
|
|
if (++checks >= 50)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
}
|
|
}
|
|
airloaded = true;
|
|
Puts("Created " + airnodes.Count.ToString() + " Air Nodes.");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GenerateLandGrid()
|
|
{
|
|
int minPos = (int)(World.Size / -2f);
|
|
int maxPos = (int)(World.Size / 2f);
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 80 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
for (float x = minPos; x < maxPos; x += 50f)
|
|
{
|
|
for (float z = minPos; z < maxPos; z += 50f)
|
|
{
|
|
if (++checks >= 50)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
Vector3 original = new Vector3(x, 0, z);
|
|
original.y = TerrainMeta.HeightMap.GetHeight(original);
|
|
var position = FindPointOnNavmesh(original);
|
|
if (position != null && position is Vector3 && (Vector3)position != Vector3.zero)
|
|
{
|
|
if (TerrainMeta.HeightMap.GetHeight((Vector3)position) > TerrainMeta.WaterMap.GetHeight((Vector3)position)) { groundnodes.Add((Vector3)position); }
|
|
}
|
|
}
|
|
}
|
|
landloaded = true;
|
|
Puts("Created " + groundnodes.Count.ToString() + " Land Nodes.");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GenerateRoadGrid()
|
|
{
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 80 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
foreach (PathList roadnode in TerrainMeta.Path.Roads)
|
|
{
|
|
foreach (Vector3 v in roadnode.Path.Points)
|
|
{
|
|
if (++checks >= 1000)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
var elevation = GetTerrainElevation(v);
|
|
if (IsFlatTerrain(v, elevation, 4))
|
|
{
|
|
bool flag = false;
|
|
foreach (Vector3 n in roadnodes) { if (Vector3.Distance(v, n) < 20) { flag = true; break; } }
|
|
if (!flag && SpawnCheckfunctioon(v, _ServerSettings.PirateBaseWallRadius + 1, -1)) { roadnodes.Add(v); }
|
|
}
|
|
}
|
|
}
|
|
Puts("Created " + roadnodes.Count.ToString() + " Road Nodes.");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GenerateFootGrid()
|
|
{
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 30 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
for (int i = World.Serialization.world.prefabs.Count - 1; i >= 0; i--)
|
|
{
|
|
if (++checks >= 500)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
PrefabData prefabdata0 = World.Serialization.world.prefabs[i];
|
|
if (prefabdata0.id == 1519652535 && prefabdata0.category.Contains("piratenpcspawner")) { footnodes.Add(prefabdata0); }
|
|
if (prefabdata0.id == 500822506 && prefabdata0.category.Contains("callpirate")) { Alarmtriggers.Add(prefabdata0); }
|
|
}
|
|
if (footnodes.Count != 0) { footloaded = true; }
|
|
|
|
Puts("Found " + footnodes.Count.ToString() + " NPC Spawner Nodes. & " + Alarmtriggers.Count.ToString() + " triggers");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator NPCAIFunction()
|
|
{
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 30 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
Puts("Starting AI Thread");
|
|
while (plugin != null)
|
|
{
|
|
for (int i = 0; i < ActiveNPCs.Count; i++)
|
|
{
|
|
if (++checks >= 50)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
try
|
|
{
|
|
if (ActiveNPCs.ElementAt(i).Key == null || ActiveNPCs.ElementAt(i).Key.IsDestroyed)
|
|
{
|
|
ActiveNPCs.Remove(ActiveNPCs.ElementAt(i).Key);
|
|
continue;
|
|
}
|
|
KeyValuePair<ScientistNPC, BaseEntity> npc = ActiveNPCs.ElementAt(i);
|
|
if (npc.Key == null || npc.Key.net == null) { continue; }
|
|
if (GroundedNPCs.Contains(npc.Key.net.ID))
|
|
{
|
|
if (npc.Key == null) continue;
|
|
if (NPCsUintList.Contains(npc.Key.net.ID)) { NPCsUintList.Remove(npc.Key.net.ID); }
|
|
if (npc.Key.IsWounded()) { if (!downed.Contains(npc.Key)) { downed.Add(npc.Key); } }
|
|
if (!npc.Key.IsWounded() && downed.Contains(npc.Key))
|
|
{
|
|
downed.Remove(npc.Key);
|
|
npc.Key.EquipWeapon();
|
|
}
|
|
float groundheightFLOAT = TerrainMeta.HeightMap.GetHeight(npc.Key.transform.position);
|
|
if (groundheightFLOAT < -2f || npc.Key.transform.position.y < groundheightFLOAT - 2f) { GroundedNPCs.Remove(npc.Key.net.ID); npc.Key.Die(); continue; }
|
|
if (npc.Value != null) { if (npc.Value.Distance(npc.Key) > 50f) { ActiveNPCs[npc.Key] = null; } }
|
|
if (npc.Value == null) { ActiveNPCs[npc.Key] = npc.Key.Brain.Senses.GetNearestPlayer(50); }
|
|
if (npc.Value != null && !VoiceUintList.Contains(npc.Value.net.ID)) { npc.Key.Brain.Navigator.SetDestination(ActiveNPCs[npc.Key].transform.position, BaseNavigator.NavigationSpeed.Normal); }
|
|
else
|
|
{
|
|
if (!npc.Key.Brain.Navigator.Moving)
|
|
{
|
|
float d = npc.Key.Brain.Navigator.MaxRoamDistanceFromHome;
|
|
Vector2 vector = Vector3.zero;
|
|
Vector3 newPos = npc.Key.Brain.Events.Memory.Position.Get(4);
|
|
for (int scan = 0; scan < 10; scan++)
|
|
{
|
|
vector = UnityEngine.Random.insideUnitCircle * d;
|
|
newPos += new Vector3(vector.x, 0, vector.y);
|
|
newPos.y = TerrainMeta.HeightMap.GetHeight(newPos);
|
|
if (newPos.y > -0.4f) { break; }
|
|
newPos = npc.Key.transform.position;
|
|
}
|
|
npc.Key.Brain.Navigator.SetDestination(newPos, BaseNavigator.NavigationSpeed.Normal);
|
|
}
|
|
if (Vector3.Distance(npc.Key.transform.position, npc.Key.Brain.Events.Memory.Position.Get(4)) > npc.Key.Brain.Navigator.MaxRoamDistanceFromHome) { npc.Key.Brain.Navigator.SetDestination(npc.Key.Brain.Events.Memory.Position.Get(4), BaseNavigator.NavigationSpeed.Fast); }
|
|
}
|
|
try { if (npc.Key.GetGun().primaryMagazine.contents < 1) { npc.Key.AttemptReload(); } } catch { }
|
|
if (npc.Value != null)
|
|
{
|
|
float Distance = npc.Value.Distance2D(npc.Key);
|
|
if (Distance <= 10f && !npc.Key.IsWounded() && npc.Key.IsAlive())
|
|
{
|
|
AttackEntity attackEntity = npc.Key.GetHeldEntity() as AttackEntity;
|
|
if (attackEntity == null)
|
|
{
|
|
bool givennewgun = true;
|
|
foreach (Item it in npc.Key.inventory.AllItems())
|
|
{
|
|
if (it.name.Contains("eoka"))
|
|
{
|
|
givennewgun = false;
|
|
break;
|
|
}
|
|
}
|
|
if (givennewgun)
|
|
{
|
|
CreateGun(npc.Key, "pistol.eoka", "");
|
|
}
|
|
}
|
|
npc.Key.SetAimDirection(npc.Value.transform.position);
|
|
npc.Key.ShotTest(Distance);
|
|
}
|
|
}
|
|
}
|
|
else if (NPCsUintList.Contains(npc.Key.net.ID))
|
|
{
|
|
if (npc.Key.IsAlive())
|
|
{
|
|
float senserange = 30f;
|
|
float terrainheight = TerrainMeta.HeightMap.GetHeight(npc.Key.transform.position);
|
|
if (npc.Key.transform.position.y < 10 && terrainheight < 0)
|
|
{
|
|
senserange = _ServerSettings.BoatTargetDistance;
|
|
}
|
|
else if (npc.Key.transform.position.y + 20f > terrainheight)
|
|
{
|
|
senserange = _ServerSettings.HeliTargetDistance;
|
|
}
|
|
else
|
|
{
|
|
senserange = _ServerSettings.LandTargetDistance;
|
|
}
|
|
if (npc.Value == null) { ActiveNPCs[npc.Key] = npc.Key.Brain.Senses.GetNearestTarget(senserange); }
|
|
if (npc.Value != null)
|
|
{
|
|
BasePlayer p = npc.Value.ToPlayer();
|
|
if (p != null)
|
|
{
|
|
if (p.IsSleeping() || p.IsDead() || plugin.VoiceUintList.Contains(p.net.ID)) { ActiveNPCs[npc.Key] = null; }
|
|
else if (senserange == _ServerSettings.BoatTargetDistance && p.transform.position.y > 505) { ActiveNPCs[npc.Key] = null; }
|
|
}
|
|
}
|
|
}
|
|
else { NPCsUintList.Remove(npc.Key.net.ID); }
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
yield return CoroutineEx.waitForSeconds(_ServerSettings.NPCTick);
|
|
}
|
|
Puts("Stopped AI Thread");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GenerateSeaGrid()
|
|
{
|
|
float x = TerrainMeta.Size.x;
|
|
int Sections = Mathf.CeilToInt(TerrainMeta.Size.x * 2f * 3.14159274f / 50);
|
|
seanodes = new List<Vector3>();
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 30 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
for (int i = 0; i < Sections; i++)
|
|
{
|
|
float num5 = (float)i / (float)Sections * 360f;
|
|
seanodes.Add(new Vector3(Mathf.Sin(num5 * 0.0174532924f) * x, 0, Mathf.Cos(num5 * 0.0174532924f) * x));
|
|
}
|
|
bool flag = true;
|
|
int num8 = 1;
|
|
Vector3[] array = new Vector3[]
|
|
{
|
|
new Vector3(0f, 0f, 0f),
|
|
new Vector3(30, 0f, 0f),
|
|
new Vector3(-30, 0f, 0f),
|
|
new Vector3(0f, 0f, 30),
|
|
new Vector3(0f, 0f, -30)
|
|
};
|
|
while (flag)
|
|
{
|
|
num8++;
|
|
flag = false;
|
|
for (int j = 0; j < Sections; j++)
|
|
{
|
|
Vector3 vector = seanodes[j];
|
|
int index = (j == 0) ? (Sections - 1) : (j - 1);
|
|
int index2 = (j == Sections - 1) ? 0 : (j + 1);
|
|
Vector3 b = seanodes[index2];
|
|
Vector3 b2 = seanodes[index];
|
|
Vector3 normalized = (Vector3.zero - vector).normalized;
|
|
Vector3 vector3 = vector + normalized * 2;
|
|
if (Vector3.Distance(vector3, b) <= 100 && Vector3.Distance(vector3, b2) <= 100)
|
|
{
|
|
bool flag2 = true;
|
|
for (int k = 0; k < array.Length; k++)
|
|
{
|
|
Vector3 vector4 = vector3 + array[k];
|
|
if (GetWaterDepthfunction(vector4) < 5) { flag2 = false; break; }
|
|
}
|
|
if (flag2) { flag = true; seanodes[j] = vector3; }
|
|
}
|
|
if (++checks >= 1000)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
}
|
|
}
|
|
var list = Facepunch.Pool.GetList<int>();
|
|
LineUtility.Simplify(seanodes, 10f, list);
|
|
List<Vector3> list2 = seanodes;
|
|
seanodes = new List<Vector3>();
|
|
foreach (int index3 in list) { seanodes.Add(list2[index3]); }
|
|
sealoaded = true;
|
|
Puts("Created " + seanodes.Count.ToString() + " Sea Nodes.");
|
|
Facepunch.Pool.FreeList(ref list);
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GeneratRailGrid()
|
|
{
|
|
var checks = 0;
|
|
var _instruction = ConVar.FPS.limit > 30 ? CoroutineEx.waitForSeconds(0.01f) : null;
|
|
foreach (PathList pathList in World.GetPaths("Rail").AsEnumerable<PathList>())
|
|
{
|
|
if (railnodes.Count != 0) { break; }
|
|
foreach (Vector3 v in pathList.Path.Points)
|
|
{
|
|
if (++checks >= 1000)
|
|
{
|
|
checks = 0;
|
|
yield return _instruction;
|
|
}
|
|
railnodes.Add(v);
|
|
}
|
|
}
|
|
railloaded = true;
|
|
Puts("Created " + railnodes.Count.ToString() + " Rail Nodes.");
|
|
yield break;
|
|
}
|
|
|
|
private IEnumerator GeneratPlaneGrid()
|
|
{
|
|
int droppable = 0;
|
|
foreach (MonumentInfo pathList in TerrainMeta.Path.Monuments)
|
|
{
|
|
if (!pathList.IsSafeZone)
|
|
{
|
|
if (dropnodes.ContainsKey(pathList.transform.position)) { continue; }
|
|
if (_ServerSettings.PiratePlaneAllowedDrops.Contains(pathList.name))
|
|
{
|
|
droppable++;
|
|
dropnodes.Add(pathList.transform.position, true);
|
|
}
|
|
else { dropnodes.Add(pathList.transform.position, false); }
|
|
}
|
|
}
|
|
Puts("Loaded " + dropnodes.Count.ToString() + " Monument nodes. " + droppable.ToString() + " are drop points.");
|
|
yield break;
|
|
}
|
|
|
|
private object FindPointOnNavmesh(Vector3 pos)
|
|
{
|
|
NavMeshHit navmeshHit;
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
Vector3 position = i == 0 ? pos : pos + (UnityEngine.Random.onUnitSphere * 30);
|
|
if (NavMesh.SamplePosition(position, out navmeshHit, 30, 1))
|
|
{
|
|
if (navmeshHit.mask != 1)
|
|
continue;
|
|
if (!(Physics.OverlapSphere(navmeshHit.position, 15f, 65536).Length == 0))
|
|
continue;
|
|
return navmeshHit.position;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private List<Vector3> FindNavPoints(Vector3 scanpoint, float radius)
|
|
{
|
|
List<Vector3> mesh = new List<Vector3>();
|
|
mesh.Add(scanpoint);
|
|
for (int i = 0; i < 25; i++)
|
|
{
|
|
float d = radius;
|
|
Vector2 vector = UnityEngine.Random.insideUnitCircle * d;
|
|
Vector3 point = scanpoint + new Vector3(vector.x, 0, vector.y);
|
|
point.y = TerrainMeta.HeightMap.GetHeight(point);
|
|
if (point.y < 0) { continue; }
|
|
RaycastHit raycastHit;
|
|
bool add = true;
|
|
if (Physics.Raycast(point, Vector3.up, out raycastHit, 10, 1218511105)) { add = false; }
|
|
if (add)
|
|
{
|
|
foreach (Vector3 check in mesh)
|
|
{
|
|
if (Vector3.Distance(point, check) < 8)
|
|
{
|
|
add = false;
|
|
break;
|
|
}
|
|
}
|
|
if (Physics.OverlapSphere(point, 5f, 65536).Length != 0) { add = false; }
|
|
}
|
|
if (add) { mesh.Add(point); }
|
|
}
|
|
return mesh;
|
|
}
|
|
|
|
private List<Vector3> MonumentPathList()
|
|
{
|
|
List<Vector3> path = new List<Vector3>();
|
|
if (TerrainMeta.Path != null && TerrainMeta.Path.Monuments != null && TerrainMeta.Path.Monuments.Count > 0)
|
|
{
|
|
foreach (MonumentInfo monumentInfo in TerrainMeta.Path.Monuments)
|
|
{
|
|
Vector3 pos = monumentInfo.transform.position;
|
|
pos.y += 50;
|
|
path.Add(pos);
|
|
}
|
|
}
|
|
else { path.Add(new Vector3(0, 50, 0)); }
|
|
if (path.Count == 0) { path.Add(new Vector3(0, 0, 0)); }
|
|
Puts("Loaded " + path.Count.ToString() + " Air Nodes.");
|
|
return path;
|
|
}
|
|
|
|
private bool IsFlatTerrain(Vector3 center, Elevation elevation, float value) { return elevation.Max - elevation.Min <= value && elevation.Max - center.y <= value; }
|
|
|
|
private void SetupOceanPatrolPath() { Threads.Add(ServerMgr.Instance.StartCoroutine(GenerateSeaGrid())); }
|
|
|
|
private void SetupAirPatrolPath() { Threads.Add(ServerMgr.Instance.StartCoroutine(GenerateAirGrid())); }
|
|
|
|
private void SetupLandPatrolPath() { Threads.Add(ServerMgr.Instance.StartCoroutine(GenerateLandGrid())); }
|
|
|
|
private void SetupRailPatrolPath() { Threads.Add(ServerMgr.Instance.StartCoroutine(GeneratRailGrid())); }
|
|
|
|
private void SetupPlanePath() { Threads.Add(ServerMgr.Instance.StartCoroutine(GeneratPlaneGrid())); }
|
|
|
|
private float GetWaterDepthfunction(Vector3 pos)
|
|
{
|
|
RaycastHit raycastHit;
|
|
if (!Physics.Raycast(pos, Vector3.down, out raycastHit, 100f, 8388608)) { return 100f; }
|
|
return raycastHit.distance;
|
|
}
|
|
|
|
private void RunEffect(string name, BaseEntity entity = null, Vector3 position = new Vector3(), Vector3 offset = new Vector3())
|
|
{
|
|
if (entity != null) { Effect.server.Run(name, entity, 0, offset, position, null, true); return; }
|
|
Effect.server.Run(name, position, Vector3.up, null, true);
|
|
}
|
|
|
|
private void CreateFire(float lifetime, Vector3 FireOffset, float FireDelay, BaseEntity parant)
|
|
{
|
|
timer.Once(FireDelay, () =>
|
|
{
|
|
if (parant == null) { return; }
|
|
FireBall fireBallSPAWN = GameManager.server.CreateEntity(oilfireballsmallprefab, parant.transform.position) as FireBall;
|
|
fireBallSPAWN.Spawn();
|
|
fireBallSPAWN.enableSaving = false;
|
|
fireBallSPAWN.SetParent(parant, true, true);
|
|
fireBallSPAWN.transform.localPosition = FireOffset;
|
|
Rigidbody rb = fireBallSPAWN.GetComponent<Rigidbody>();
|
|
rb.isKinematic = true;
|
|
fireBallSPAWN.CancelInvoke(fireBallSPAWN.Extinguish);
|
|
fireBallSPAWN.Invoke(fireBallSPAWN.Extinguish, lifetime);
|
|
});
|
|
}
|
|
|
|
private void FreeLists(BaseEntity baseEntity)
|
|
{
|
|
if (baseEntity == null || baseEntity.net == null) { return; }
|
|
BaseParts.Remove(baseEntity.net.ID);
|
|
if (PirateUintList.Contains(baseEntity.net.ID))
|
|
{
|
|
foreach (BaseEntity be in baseEntity.children.ToArray()) { if (be == null) { continue; } if (be is SphereEntity || be is MapMarkerGenericRadius || be is SearchLight || be is FireBall || be is HorseCorpse || be.ShortPrefabName.Contains("parachute")) { be.SetParent(null, true, true); be.Kill(); } }
|
|
PirateUintList.Remove(baseEntity.net.ID);
|
|
}
|
|
NPCsUintList.Remove(baseEntity.net.ID);
|
|
GroundedNPCs.Remove(baseEntity.net.ID);
|
|
if (TrainsBaseEntityList.Contains(baseEntity))
|
|
{
|
|
RailPirate RP = baseEntity.GetComponent<RailPirate>();
|
|
if (RP != null) { KillWagonsfunction(RP.wagons.ToList()); }
|
|
TrainsBaseEntityList.Remove(baseEntity);
|
|
}
|
|
}
|
|
|
|
private void PirateSpawner()
|
|
{
|
|
if (Rust.Application.isLoading || !sealoaded || !airloaded || !landloaded)
|
|
{
|
|
timer.Once(10f, () => { PirateSpawner(); });
|
|
return;
|
|
}
|
|
for (int s = 0; s < _ServerSettings.RHIBBoatAmount; s++)
|
|
{
|
|
if (pirateRHIB >= _ServerSettings.RHIBBoatMaxA) { break; }
|
|
SpawnPirates(seanodes.GetRandom());
|
|
}
|
|
for (int s = 0; s < _ServerSettings.RowBoatBoatAmount; s++)
|
|
{
|
|
if (pirateRowBoat >= _ServerSettings.RowBoatBoatMaxA) { break; }
|
|
SpawnPirates(seanodes.GetRandom(), 1);
|
|
}
|
|
for (int s = 0; s < _ServerSettings.MiniAmount; s++)
|
|
{
|
|
if (piratesMini >= _ServerSettings.MiniMaxA) { break; }
|
|
SpawnPirates(seanodes.GetRandom(), 2);
|
|
}
|
|
for (int s = 0; s < _ServerSettings.ScrapAmount; s++)
|
|
{
|
|
if (pirateScrap >= _ServerSettings.ScrapMaxA) { break; }
|
|
SpawnPirates(seanodes.GetRandom(), 3);
|
|
}
|
|
for (int s = 0; s < _ServerSettings.HorseAmount; s++)
|
|
{
|
|
if (pirateHorse >= _ServerSettings.HorseMax) { break; }
|
|
SpawnPirates(groundnodes.GetRandom(), 4);
|
|
}
|
|
for (int s = 0; s < _ServerSettings.SnowMobileAmount; s++)
|
|
{
|
|
if (pirateSnowMobile >= _ServerSettings.SnowMobileMax) { break; }
|
|
SpawnPirates(groundnodes.GetRandom(), 5);
|
|
}
|
|
for (int s = 0; s < _ServerSettings.SubmarineAmount; s++)
|
|
{
|
|
if (pirateSub >= _ServerSettings.SubmarineMaxA) { break; }
|
|
SpawnPirates(seanodes.GetRandom(), 6);
|
|
}
|
|
if (roadnodes.Count > 5)
|
|
{
|
|
List<Vector3> BasePositions = new List<Vector3>();
|
|
for (int s = 0; s < _ServerSettings.PirateBaseAmount; s++)
|
|
{
|
|
if (pirateBase >= _ServerSettings.PirateBaseAmount) { break; }
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
Vector3 SpawnPos = roadnodes.GetRandom();
|
|
bool valid = true;
|
|
foreach (Vector3 b in BasePositions) { if (Vector3.Distance(SpawnPos, b) < 200) { valid = false; break; } }
|
|
foreach (PathList pathList in World.GetPaths("Rail").AsEnumerable<PathList>())
|
|
{
|
|
foreach (Vector3 v in pathList.Path.Points)
|
|
{
|
|
if (Vector3.Distance(SpawnPos, v) < 20)
|
|
{
|
|
valid = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (valid && SpawnCheckfunctioon(SpawnPos, _ServerSettings.PirateBaseWallRadius + 2, -1))
|
|
{
|
|
SpawnPirates(SpawnPos, 7);
|
|
BasePositions.Add(SpawnPos);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (railnodes.Count > 5 || !railloaded)
|
|
{
|
|
List<Vector3> BasePositions = new List<Vector3>();
|
|
for (int s = 0; s < _ServerSettings.PirateRailAmount; s++)
|
|
{
|
|
if (pirateRail >= _ServerSettings.PirateRailAmount) { break; }
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
Vector3 SpawnPos = railnodes.GetRandom();
|
|
bool valid = true;
|
|
foreach (Vector3 b in BasePositions)
|
|
{
|
|
if (Vector3.Distance(SpawnPos, b) < 500) { valid = false; break; }
|
|
}
|
|
if (valid && SpawnCheckfunctioon(SpawnPos, 10, -1))
|
|
{
|
|
SpawnPirates(SpawnPos, 8);
|
|
BasePositions.Add(SpawnPos);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (footloaded)
|
|
{
|
|
foreach (PrefabData pd in footnodes)
|
|
{
|
|
if (pd != null)
|
|
{
|
|
Vector3 pos = new Vector3(pd.position.x, pd.position.y, pd.position.z);
|
|
if (PlayersNearbyfunction(pos, 20)) { continue; }
|
|
bool missingnpc = true;
|
|
foreach (ScientistNPC npc in ActiveNPCs.Keys)
|
|
{
|
|
if (npc.Brain.Events.Memory.Position.Get(4) == pos)
|
|
{
|
|
missingnpc = false;
|
|
break;
|
|
}
|
|
}
|
|
if (missingnpc)
|
|
{
|
|
List<Vector3> addpos = new List<Vector3>();
|
|
addpos.Add(pos);
|
|
var NPZ = CreateNPCs(1, 9, _ServerSettings.PirateFootNPCHealth, _ServerSettings.PirateFootNPCKit, _ServerSettings.PirateFootNPCAimMulti, null, addpos);
|
|
if (NPZ != null && NPZ.Count == 1) { NPZ[0].SetAimDirection(pd.rotation); }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (_ServerSettings.PirateCargoPlane && piratePlane == 0)
|
|
{
|
|
SpawnPirates(seanodes.GetRandom(), 9);
|
|
}
|
|
}
|
|
|
|
private void DestroyGroundComp(BaseEntity ent)
|
|
{
|
|
UnityEngine.Object.DestroyImmediate(ent.GetComponent<DestroyOnGroundMissing>());
|
|
UnityEngine.Object.DestroyImmediate(ent.GetComponent<GroundWatch>());
|
|
}
|
|
|
|
private void DestroyMeshCollider(BaseEntity ent) { foreach (var mesh in ent.GetComponentsInChildren<MeshCollider>()) { UnityEngine.Object.DestroyImmediate(mesh); } }
|
|
|
|
private BaseEntity spawnersetupfunction(BaseEntity baseEntity)
|
|
{
|
|
baseEntity.syncPosition = true;
|
|
baseEntity.globalBroadcast = true;
|
|
baseEntity.Spawn();
|
|
baseEntity.enableSaving = false;
|
|
if (baseEntity is RidableHorse)
|
|
{
|
|
RidableHorse horse = baseEntity as RidableHorse;
|
|
Item item = ItemManager.CreateByName("horse.armor.wood", 1, 0);
|
|
if (item != null)
|
|
{
|
|
if (!item.MoveToContainer(horse.equipmentInventory)) { item.Remove(); }
|
|
ItemModAnimalEquipment storage = horse.equipmentInventory.itemList[0].info.GetComponent<ItemModAnimalEquipment>();
|
|
if (storage) { storage.additionalInventorySlots = 30; }
|
|
horse.SendNetworkUpdateImmediate();
|
|
}
|
|
}
|
|
return baseEntity;
|
|
}
|
|
|
|
private void EdgeDelete(List<ScientistNPC> npcz)
|
|
{
|
|
if (npcz == null) { return; }
|
|
foreach (ScientistNPC npc in npcz) { if (npc != null && !npc.IsDestroyed) { npc.Kill(); } }
|
|
}
|
|
|
|
private void InvalidateCheck(BaseEntity baseentitybe)
|
|
{
|
|
if (baseentitybe == null) { return; }
|
|
if (!ValidBounds.Test(baseentitybe.transform.position + baseentitybe.transform.forward * 200f))
|
|
{
|
|
AirPirates ap = baseentitybe.GetComponent<AirPirates>();
|
|
if (ap != null)
|
|
{
|
|
EdgeDelete(ap.npcs);
|
|
if (ap.itembox != null && !ap.itembox.IsDestroyed) { ap.itembox.Kill(); }
|
|
if (ap._heli != null && !ap._heli.IsDestroyed) { ap._heli.Kill(); }
|
|
}
|
|
WaterPirate wp = baseentitybe.GetComponent<WaterPirate>();
|
|
if (wp != null)
|
|
{
|
|
EdgeDelete(wp.npcs);
|
|
if (wp.itembox != null && !wp.itembox.IsDestroyed) { wp.itembox.Kill(); }
|
|
if (wp._boat != null && !wp._boat.IsDestroyed) { wp._boat.Kill(); }
|
|
}
|
|
LandPirate lp = baseentitybe.GetComponent<LandPirate>();
|
|
if (lp != null)
|
|
{
|
|
if (lp.npc != null && !lp.npc.IsDestroyed) { lp.npc.Kill(); }
|
|
if (lp.itembox != null) { lp.itembox.Kill(); }
|
|
if (wp._boat != null && !wp._boat.IsDestroyed) { wp._boat.Kill(); }
|
|
}
|
|
foreach (NetworkableId id in NPCsUintList.ToArray()) { if (!BaseEntity.serverEntities.entityList.Contains(id)) { NPCsUintList.Remove(id); } }
|
|
FootPirate pf = baseentitybe.GetComponent<FootPirate>();
|
|
if (pf != null) { if (pf.baseentitybe != null && !pf.baseentitybe.IsDestroyed) { pf.baseentitybe.Kill(); } }
|
|
return;
|
|
}
|
|
timer.Once(1f, () => { InvalidateCheck(baseentitybe); });
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Classes
|
|
|
|
private BaseEntity SpawnPirates(Vector3 dropPosition, int Type = 0)
|
|
{
|
|
string prefab = "";
|
|
float baseheightFLOAT;
|
|
float groundheightFLOAT = TerrainMeta.HeightMap.GetHeight(dropPosition);
|
|
float waterheightFLOAT = TerrainMeta.WaterMap.GetHeight(dropPosition);
|
|
if (groundheightFLOAT > waterheightFLOAT) { baseheightFLOAT = groundheightFLOAT; }
|
|
else { baseheightFLOAT = waterheightFLOAT; }
|
|
|
|
switch (Type)
|
|
{
|
|
case 0:
|
|
prefab = rhibentityprefab;
|
|
dropPosition.y = baseheightFLOAT;
|
|
break;
|
|
case 1:
|
|
prefab = rowboatentityprefab;
|
|
dropPosition.y = baseheightFLOAT;
|
|
break;
|
|
case 2:
|
|
prefab = minientityprefab;
|
|
dropPosition.y = baseheightFLOAT + 60;
|
|
break;
|
|
case 3:
|
|
prefab = scrapentityprefab;
|
|
dropPosition.y = baseheightFLOAT + 60;
|
|
break;
|
|
case 4:
|
|
prefab = horseentityprefab;
|
|
dropPosition.y = baseheightFLOAT + 1;
|
|
break;
|
|
case 5:
|
|
prefab = snowmobileentityprefab;
|
|
dropPosition.y = baseheightFLOAT + 1;
|
|
break;
|
|
case 6:
|
|
prefab = subentityprefab;
|
|
dropPosition.y = baseheightFLOAT;
|
|
break;
|
|
case 7:
|
|
prefab = hoboentityprefab;
|
|
dropPosition.y = baseheightFLOAT - 5.5f;
|
|
break;
|
|
case 8:
|
|
prefab = workcartprefab;
|
|
break;
|
|
case 9:
|
|
dropPosition.y = TerrainMeta.HighestPoint.y + 50f;
|
|
prefab = sphereentityprefab;
|
|
break;
|
|
case 10:
|
|
List<Vector3> addpos = new List<Vector3>();
|
|
addpos.Add(dropPosition);
|
|
List<ScientistNPC> npc = CreateNPCs(1, 9, _ServerSettings.PirateFootNPCHealth, _ServerSettings.PirateFootNPCKit, _ServerSettings.PirateFootNPCAimMulti, null, addpos);
|
|
timer.Once(5f, () =>
|
|
{
|
|
if (npc != null && npc.Count == 1)
|
|
{
|
|
if (npc[0] != null)
|
|
{
|
|
BailOutfunction(dropPosition, npc[0], dropPosition, 3, 0, false);
|
|
}
|
|
}
|
|
});
|
|
return null;
|
|
case 11:
|
|
dropPosition = seanodes.GetRandom();
|
|
dropPosition.y = TerrainMeta.HighestPoint.y + 50f;
|
|
prefab = sphereentityprefab;
|
|
break;
|
|
}
|
|
BaseEntity baseentitybe = GameManager.server.CreateEntity(prefab, dropPosition, Quaternion.identity, true);
|
|
switch (Type)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 6:
|
|
WaterPirate _Pirate = baseentitybe.gameObject.AddComponent<WaterPirate>();
|
|
_Pirate.Type = Type;
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
AirPirates _PirateAir = baseentitybe.gameObject.AddComponent<AirPirates>();
|
|
_PirateAir.Type = Type;
|
|
if (_ServerSettings.DisableHeliFireball) { (baseentitybe as PlayerHelicopter).fireBall.guid = null; }
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
LandPirate _PirateLand = baseentitybe.gameObject.AddComponent<LandPirate>();
|
|
_PirateLand.Type = Type;
|
|
break;
|
|
case 7:
|
|
BasePirate _PirateBase = baseentitybe.gameObject.AddComponent<BasePirate>();
|
|
_PirateBase.Type = Type;
|
|
break;
|
|
case 8:
|
|
RailPirate _PirateRail = baseentitybe.gameObject.AddComponent<RailPirate>();
|
|
_PirateRail.Type = Type;
|
|
break;
|
|
case 9:
|
|
FootPirate _PirateFoot = baseentitybe.gameObject.AddComponent<FootPirate>();
|
|
_PirateFoot.Type = Type;
|
|
break;
|
|
case 11:
|
|
FootPirate _PirateFoot2 = baseentitybe.gameObject.AddComponent<FootPirate>();
|
|
_PirateFoot2.Type = 91;
|
|
break;
|
|
}
|
|
return spawnersetupfunction(baseentitybe);
|
|
}
|
|
|
|
private class NightLight { public SearchLight _light; public SphereEntity resizer; }
|
|
|
|
private class Elevation { public float Min { get; set; } public float Max { get; set; } }
|
|
|
|
private class targetinfo
|
|
{
|
|
public targetinfo(BaseEntity initEnt, BasePlayer initPly = null)
|
|
{
|
|
ply = initPly;
|
|
ent = initEnt;
|
|
lastSeenTime = float.PositiveInfinity;
|
|
nextLOSCheck = UnityEngine.Time.realtimeSinceStartup + 1.5f;
|
|
}
|
|
|
|
public BasePlayer ply;
|
|
public BaseEntity ent;
|
|
public float lastSeenTime = float.PositiveInfinity;
|
|
public float visibleFor;
|
|
public float nextLOSCheck;
|
|
}
|
|
|
|
private class WaterPirate : MonoBehaviour
|
|
{
|
|
public int Type = 0;
|
|
public BaseEntity _boat;
|
|
public BaseSubmarine _sub;
|
|
private bool burning;
|
|
private bool isDead;
|
|
public List<ScientistNPC> npcs;
|
|
public StorageContainer itembox;
|
|
private int targetNodeIndex = -1;
|
|
public Vector3 currentVelocity = Vector3.zero;
|
|
private float currentThrottle;
|
|
private float currentTurnSpeed;
|
|
private float turnScale = 10;
|
|
private bool egressing;
|
|
private bool stopping;
|
|
private float BoatTurnSpeedfloat;
|
|
private float BoatMaxSpeedfloat;
|
|
private NightLight searchLight;
|
|
private int NPCAmountint;
|
|
private string RandomLoot = "";
|
|
private int LootMulti = 1;
|
|
private List<Vector3> Position = new List<Vector3>();
|
|
private float NPCHealthfloat;
|
|
private string Kit;
|
|
private float AIShootMultiplyer;
|
|
private Vector3 FireOffset;
|
|
public BaseEntity PlayerTarget;
|
|
private Vector3 TargetDest0;
|
|
private bool halftickrate;
|
|
private bool loading = true;
|
|
|
|
private void Awake()
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
_boat = GetComponent<BaseEntity>();
|
|
plugin.timer.Once(10, () => { loading = false; });
|
|
TargetDest0 = _boat.transform.position;
|
|
switch (Type)
|
|
{
|
|
case 0:
|
|
plugin.pirateRHIB++;
|
|
BoatTurnSpeedfloat = _ServerSettings.RHIBBoatTurnSpeed;
|
|
BoatMaxSpeedfloat = _ServerSettings.RHIBBoatMaxSpeed;
|
|
NPCAmountint = _ServerSettings.RHIBNPCAmount;
|
|
NPCHealthfloat = _ServerSettings.RHIBNPCHealth;
|
|
_boat.gameObject.GetComponent<BaseCombatEntity>().InitializeHealth(_ServerSettings.RHIBHealth, _ServerSettings.RHIBHealth);
|
|
Kit = _ServerSettings.RHIBKit;
|
|
RandomLoot = _ServerSettings.RHIBLootString;
|
|
LootMulti = _ServerSettings.RHIBLootMulti;
|
|
AIShootMultiplyer = _ServerSettings.RHIBAIDistance;
|
|
Position.Add(new Vector3(0f, 1f, 0f));
|
|
Position.Add(new Vector3(0f, 1f, 3f));
|
|
Position.Add(new Vector3(0f, 1f, -1f));
|
|
Position.Add(new Vector3(0f, 1f, -1.9f));
|
|
Position.Add(new Vector3(0f, 1f, -2.8f));
|
|
Position.Add(new Vector3(0.9f, 1f, -2.7f));
|
|
Position.Add(new Vector3(-0.9f, 1f, -2.7f));
|
|
Position.Add(new Vector3(0.9f, 1f, -1f));
|
|
Position.Add(new Vector3(-0.9f, 1f, -1f));
|
|
Position.Add(new Vector3(0.9f, 1f, 0f));
|
|
Position.Add(new Vector3(-0.9f, 1f, 0f));
|
|
Position.Add(new Vector3(0.9f, 1f, 1f));
|
|
Position.Add(new Vector3(-0.9f, 1f, 1f));
|
|
Position.Add(new Vector3(0.9f, 1f, 2f));
|
|
Position.Add(new Vector3(-0.9f, 1f, 2f));
|
|
FireOffset = new Vector3(0, 1.3f, 0);
|
|
if (!_ServerSettings.DisableBoatlights) { searchLight = plugin.CreateLightfunction(_boat, new Vector3(0, 1.8f, 4.9f), new Vector3(-5, 180, 0)); }
|
|
break;
|
|
case 1:
|
|
plugin.pirateRowBoat++;
|
|
BoatTurnSpeedfloat = _ServerSettings.RowBoatBoatTurnSpeed;
|
|
BoatMaxSpeedfloat = _ServerSettings.RowBoatBoatMaxSpeed;
|
|
NPCAmountint = _ServerSettings.RowBoatNPCAmount;
|
|
NPCHealthfloat = _ServerSettings.RowBoatNPCHealth;
|
|
_boat.gameObject.GetComponent<BaseCombatEntity>().InitializeHealth(_ServerSettings.RowBoatHealth, _ServerSettings.RowBoatHealth);
|
|
Kit = _ServerSettings.RowBoatKit;
|
|
RandomLoot = _ServerSettings.RowBoatLootString;
|
|
LootMulti = _ServerSettings.RowBoatLootMulti;
|
|
AIShootMultiplyer = _ServerSettings.RowBoatAIDistance;
|
|
Position.Add(new Vector3(0f, 0f, -1.3f));
|
|
Position.Add(new Vector3(0f, 0f, 0f));
|
|
Position.Add(new Vector3(0f, 0f, 1f));
|
|
FireOffset = new Vector3(0, 0.8f, 0);
|
|
if (!_ServerSettings.DisableBoatlights) { searchLight = plugin.CreateLightfunction(_boat, new Vector3(0, 0.8f, 2.2f), new Vector3(-5, 180, 0)); }
|
|
break;
|
|
case 6:
|
|
plugin.pirateSub++;
|
|
BoatTurnSpeedfloat = _ServerSettings.SubmarineTurnSpeed;
|
|
BoatMaxSpeedfloat = _ServerSettings.SubmarineMaxSpeed;
|
|
NPCAmountint = 2;
|
|
NPCHealthfloat = 100;
|
|
_boat.gameObject.GetComponent<BaseCombatEntity>().InitializeHealth(_ServerSettings.SubmarineHealth, _ServerSettings.SubmarineHealth);
|
|
Kit = "";
|
|
RandomLoot = _ServerSettings.SubmarineLootString;
|
|
LootMulti = _ServerSettings.SubmarineLootMulti;
|
|
AIShootMultiplyer = 1;
|
|
Position.Add(new Vector3(0f, 0f, 0f));
|
|
Position.Add(new Vector3(0f, 0f, 0f));
|
|
_sub = (_boat as BaseSubmarine);
|
|
_sub.idleFuelPerSec = 0;
|
|
_sub.maxFuelPerSec = 0;
|
|
_boat.SetFlag(BaseVehicle.Flags.Locked, true);
|
|
break;
|
|
}
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { leaveing(); });
|
|
try { foreach (StorageContainer container in _boat.children) { if (container != null && container.ToString().Contains("rhib_storage") || container.ToString().Contains("rowboat_storage") || container.ToString().Contains("itemstorage")) { itembox = container; itembox.inventory.capacity = 30; break; } } } catch { }
|
|
if (itembox != null) { plugin.filllootfunction(itembox.inventory, -1, LootMulti, RandomLoot); }
|
|
FindInitialNode();
|
|
npcs = plugin.CreateNPCs(NPCAmountint, Type, NPCHealthfloat, Kit, AIShootMultiplyer, _boat, Position);
|
|
if (npcs == null) { _boat.Kill(); }
|
|
plugin.PirateUintList.Add(_boat.net.ID);
|
|
plugin.timer.Once(Core.Random.Range(2, 10), NPCsAlive);
|
|
if (_sub != null)
|
|
{
|
|
foreach (ScientistNPC n in npcs)
|
|
{
|
|
_sub.AttemptMount(n, false);
|
|
n.inventory.Strip();
|
|
}
|
|
_sub.SetupOwner(npcs[0], Vector3.zero, 1);
|
|
_sub.engineController.TryStartEngine(npcs[0]);
|
|
}
|
|
StorageContainer fuelContainer = (_boat as BaseVehicle).GetFuelSystem().GetFuelContainer();
|
|
if (fuelContainer != null) { fuelContainer.SetFlag(BaseEntity.Flags.Locked, true); }
|
|
});
|
|
}
|
|
|
|
private void leaveing()
|
|
{
|
|
if (_boat == null) { return; }
|
|
if (PlayerTarget != null)
|
|
{
|
|
plugin.timer.Once(10f, leaveing);
|
|
return;
|
|
}
|
|
egressing = true;
|
|
plugin.InvalidateCheck(_boat);
|
|
plugin.timer.Once(60f, Die);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
try
|
|
{
|
|
switch (Type)
|
|
{
|
|
case 0:
|
|
plugin.pirateRHIB--;
|
|
break;
|
|
case 1:
|
|
plugin.pirateRowBoat--;
|
|
break;
|
|
case 6:
|
|
plugin.pirateSub--;
|
|
break;
|
|
}
|
|
enabled = false;
|
|
CancelInvoke();
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { npc.transform.position = new Vector3(0, -501, 0); npc.Kill(); } } }
|
|
if (searchLight != null) { if (searchLight.resizer != null && !searchLight.resizer.IsDestroyed) { searchLight.resizer.Kill(); } if (searchLight._light != null && !searchLight._light.IsDestroyed) { searchLight._light.Kill(); } }
|
|
if (_boat != null && !_boat.IsDestroyed) { _boat.Kill(); }
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public void Die() { if (this != null) { Destroy(this); } }
|
|
|
|
private void Explodevoid() { if (_boat != null) { plugin.Explodefunction(_boat); } }
|
|
|
|
private void SubAttack()
|
|
{
|
|
if (_sub == null || PlayerTarget == null) { return; }
|
|
if (_sub.timeSinceTorpedoFired >= _sub.reloadTime)
|
|
{
|
|
if (PlayerTarget.Distance(_sub) < 50 && PlayerTarget.Distance(_sub) > 5)
|
|
{
|
|
if (!GamePhysics.LineOfSight(_sub.torpedoFiringPoint.position, _sub.torpedoFiringPoint.position + _sub.torpedoFiringPoint.forward * 30f, (int)Layers.Server.Players | 1 << (int)Layers.Server.Buildings | 1 << (int)Layers.Server.Deployed | 1 << (int)Layers.Server.VehiclesSimple))
|
|
{
|
|
float minSpeed = _sub.GetSpeed() + 10f;
|
|
ServerProjectile serverProjectile;
|
|
Item item = ItemManager.CreateByName("submarine.torpedo.straight", 1, 0);
|
|
if (item == null) { return; }
|
|
if (!item.MoveToContainer(_sub.GetTorpedoContainer().inventory, -1, false)) { item.Remove(); }
|
|
BaseMountable mount = npcs[0].GetMounted();
|
|
if (mount.TryFireProjectile(_sub.GetTorpedoContainer(), AmmoTypes.TORPEDO, _sub.torpedoFiringPoint.position + _sub.torpedoFiringPoint.forward * 2, _sub.torpedoFiringPoint.forward, npcs[0], 1f, minSpeed, out serverProjectile))
|
|
{
|
|
_sub.timeSinceTorpedoFired = 0f;
|
|
_sub.ClientRPC(null, "TorpedoFired");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
if (_boat == null || targetNodeIndex == -1 || plugin.seanodes == null || loading) { return; }
|
|
try
|
|
{
|
|
if (_sub == null) { _boat.transform.position = new Vector3(_boat.transform.position.x, TerrainMeta.WaterMap.GetHeight(_boat.transform.position), _boat.transform.position.z); }
|
|
_boat.transform.rotation = Quaternion.FromToRotation(transform.up, Vector3.up) * transform.rotation;
|
|
if (!stopping) { _boat.SetFlag(BaseVehicle.Flags.Reserved1, true); }
|
|
if (!_ServerSettings.DisableBoatlights)
|
|
{
|
|
if (searchLight != null)
|
|
{
|
|
searchLight._light.SetFlag(BaseEntity.Flags.On, TOD_Sky.Instance.IsNight);
|
|
searchLight._light.UpdateHasPower(searchLight._light.IsOn() ? 10 : 0, 1);
|
|
}
|
|
else if (_sub != null) { _sub.SetFlag(BaseSubmarine.Flag_Headlights, TOD_Sky.Instance.IsNight); }
|
|
}
|
|
if (!isDead)
|
|
{
|
|
_boat.SetFlag(BaseVehicle.Flags.Reserved2, true);
|
|
if (!halftickrate) { halftickrate = true; }
|
|
else
|
|
{
|
|
if (_boat.Health() < 10) { Explodevoid(); return; }
|
|
if (_sub != null)
|
|
{
|
|
SubAttack();
|
|
Vector3 IdealHeightvec = new Vector3(_boat.transform.position.x, _ServerSettings.SubmarineTargetDepth * -1, _boat.transform.position.z);
|
|
float GroundHeightFLOAT = TerrainMeta.HeightMap.GetHeight(IdealHeightvec);
|
|
if (IdealHeightvec.y < GroundHeightFLOAT) { IdealHeightvec.y = GroundHeightFLOAT + 0.6f; }
|
|
_boat.transform.position = IdealHeightvec;
|
|
}
|
|
if (!burning)
|
|
{
|
|
if (_boat.Health() < _ServerSettings.StartFireHealth)
|
|
{
|
|
burning = true;
|
|
plugin.CreateFire(60, new Vector3(0, 0.9f, -1.8f), 0.1f, _boat);
|
|
}
|
|
}
|
|
halftickrate = false;
|
|
if (TerrainMeta.HeightMap.GetHeight(_boat.transform.position) > 0.01)
|
|
{
|
|
isDead = true;
|
|
_boat.Invoke(() =>
|
|
{
|
|
BailOutcall();
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay + 2f, FireOffset, 0, _boat);
|
|
Invoke("Explodevoid", _ServerSettings.ExplodeDelay);
|
|
}, _ServerSettings.CrashDelayFloat);
|
|
return;
|
|
}
|
|
}
|
|
TargetDest0 = plugin.seanodes[targetNodeIndex];
|
|
if (plugin.PointsOfIntrest.Count != 0)
|
|
{
|
|
Vector3 PointOfIntrest = plugin.getPOIfunction(_boat.transform.position, _ServerSettings.PiratesWaterPOIRadius);
|
|
if (PointOfIntrest != Vector3.zero && TerrainMeta.HeightMap.GetHeight(PointOfIntrest) < -5) { TargetDest0 = PointOfIntrest; }
|
|
}
|
|
if (PlayerTarget != null) { TargetDest0 = PlayerTarget.transform.position; }
|
|
if (egressing) { TargetDest0 = base.transform.position + (base.transform.position - Vector3.zero).normalized * 10000f; }
|
|
Vector3 normalized = (TargetDest0 - base.transform.position).normalized;
|
|
float value = Vector3.Dot(base.transform.forward, normalized);
|
|
float b = Mathf.InverseLerp(0f, 1f, value);
|
|
float num = Vector3.Dot(base.transform.right, normalized);
|
|
float b2 = Mathf.InverseLerp(0.05f, 0.5f, Mathf.Abs(num));
|
|
turnScale = Mathf.Lerp(turnScale, b2, Time.deltaTime * 0.2f);
|
|
float num3 = (float)((num < 0f) ? -1 : 1);
|
|
currentTurnSpeed = BoatTurnSpeedfloat * turnScale * num3;
|
|
base.transform.Rotate(Vector3.up, Time.deltaTime * currentTurnSpeed, Space.World);
|
|
currentThrottle = Mathf.Lerp(currentThrottle, b, Time.deltaTime * 0.2f);
|
|
currentVelocity = base.transform.forward * (BoatMaxSpeedfloat * currentThrottle);
|
|
base.transform.position += currentVelocity * Time.deltaTime;
|
|
if (Vector3.Distance(base.transform.position, TargetDest0) < 80f) { targetNodeIndex++; if (targetNodeIndex >= plugin.seanodes.Count) { targetNodeIndex = 0; } }
|
|
}
|
|
}
|
|
catch { FindInitialNode(); }
|
|
}
|
|
|
|
private void BailOutcall()
|
|
{
|
|
if (itembox != null) { itembox.dropFloats = true; itembox.DropItems(); }
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
if (_sub != null) { plugin.CreateGun(npc, "rifle.lr300", "weapon.mod.silencer"); }
|
|
npcs.Remove(npc);
|
|
plugin.BailOutfunction(_boat.transform.position, npc, Vector3.zero, 8);
|
|
}
|
|
}
|
|
|
|
private int GetClosestNodeToUs()
|
|
{
|
|
if (plugin.seanodes == null || plugin.seanodes.Count == 0) { plugin.seanodes = TerrainMeta.Path.OceanPatrolFar; }
|
|
int result = 0;
|
|
float num = float.PositiveInfinity;
|
|
for (int i = 0; i < plugin.seanodes.Count; i++)
|
|
{
|
|
Vector3 b = plugin.seanodes[i];
|
|
float num2 = Vector3.Distance(base.transform.position, b);
|
|
if (num2 < num)
|
|
{
|
|
result = i;
|
|
num = num2;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void FindInitialNode() { targetNodeIndex = GetClosestNodeToUs(); }
|
|
|
|
private void NPCsAlive()
|
|
{
|
|
if (npcs == null || _boat == null) { return; }
|
|
int alive = 0;
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
if (npc == null || !npc.IsAlive() || !plugin.ActiveNPCs.ContainsKey(npc)) { continue; }
|
|
if (PlayerTarget == null) { PlayerTarget = plugin.ActiveNPCs[npc]; }
|
|
alive++;
|
|
}
|
|
if (alive == 0)
|
|
{
|
|
plugin.timer.Once(10f, () => { if (_boat != null) { _boat.SetFlag(BaseVehicle.Flags.Reserved1, false); stopping = true; } });
|
|
isDead = true;
|
|
plugin.timer.Once(_ServerSettings.StopDelayFloat, Stop);
|
|
return;
|
|
}
|
|
plugin.timer.Once(_ServerSettings.NPCTick, NPCsAlive);
|
|
}
|
|
|
|
private void Stop()
|
|
{
|
|
if (_boat == null) { return; }
|
|
plugin.timer.Once(_ServerSettings.FireDelay + _ServerSettings.ExplodeDelay, Explodevoid);
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay, FireOffset, _ServerSettings.FireDelay, _boat);
|
|
}
|
|
}
|
|
|
|
private class AirPirates : MonoBehaviour
|
|
{
|
|
private enum aiState
|
|
{
|
|
IDLE,
|
|
MOVE,
|
|
ORBIT,
|
|
STRAFE,
|
|
PATROL,
|
|
}
|
|
|
|
public List<ScientistNPC> npcs;
|
|
private Dictionary<ScientistNPC, Vector3> NPCOffSet = new Dictionary<ScientistNPC, Vector3>();
|
|
public StorageContainer itembox;
|
|
public BaseEntity _heli;
|
|
private float AiAltitudeForce = 20000f;
|
|
private Vector3 _moveTarget = Vector3.zero;
|
|
public Vector3 currentVelocity = Vector3.zero;
|
|
private int lastAltitudeCheckFrame;
|
|
private float altOverride;
|
|
private float currentDesiredAltitude;
|
|
private bool altitudeProtection = true;
|
|
private float hoverHeight;
|
|
private Vector3 interestZoneOrigin;
|
|
private Vector3 destination;
|
|
public float moveSpeed;
|
|
private float maxSpeed;
|
|
private float courseAdjustLerpTime = 4f;
|
|
private Quaternion targetRotation;
|
|
private float targetThrottleSpeed;
|
|
private float throttleSpeed;
|
|
private float maxRotationSpeed;
|
|
private float rotationSpeed;
|
|
private aiState _currentState;
|
|
private Vector3 _lastPos;
|
|
private Vector3 _lastMoveDir;
|
|
private bool isDead;
|
|
private bool isRetiring;
|
|
private bool burning;
|
|
private float destination_min_dist = 2f;
|
|
private float currentOrbitDistance;
|
|
private float currentOrbitTime;
|
|
private bool hasEnteredOrbit;
|
|
private float orbitStartTime;
|
|
private float maxOrbitDuration = 10f;
|
|
private bool breakingOrbit;
|
|
private Vector3 strafe_target_position;
|
|
private bool puttingDistance;
|
|
private float lastStrafeTime = float.NegativeInfinity;
|
|
private float _lastThinkTime;
|
|
public List<targetinfo> _targetList = new List<targetinfo>();
|
|
private bool stuckcheck = false;
|
|
private Vector3 SpotCheck = new Vector3(0, 0, 0);
|
|
private NightLight searchLight;
|
|
public int Type = 0;
|
|
private Rigidbody _rb;
|
|
private float NPCHealth;
|
|
private string Kit;
|
|
private Vector3 FireOffset;
|
|
private float orbitDistance;
|
|
private float ThreatTarget;
|
|
private float TargetDistance;
|
|
private float AIShootMultiplyer;
|
|
private List<Vector3> Position = new List<Vector3>();
|
|
private int NPCAmountint;
|
|
private string RandomLoot = "";
|
|
private int LootMulti = 1;
|
|
private float NextPOITick;
|
|
private bool halftickrate;
|
|
|
|
private void Awake()
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
_heli = GetComponent<BaseEntity>();
|
|
_heli.SendNetworkUpdateImmediate();
|
|
NextPOITick = Time.time;
|
|
switch (Type)
|
|
{
|
|
case 2:
|
|
plugin.piratesMini++;
|
|
maxRotationSpeed = _ServerSettings.MiniTurnSpeed;
|
|
maxSpeed = _ServerSettings.MiniMaxSpeed;
|
|
hoverHeight = _ServerSettings.MiniHoverHeight;
|
|
NPCHealth = _ServerSettings.MiniNPCHealth;
|
|
Kit = _ServerSettings.MiniKit;
|
|
orbitDistance = _ServerSettings.MiniOrbitDistance;
|
|
AIShootMultiplyer = _ServerSettings.MiniAIDistance;
|
|
ThreatTarget = _ServerSettings.MiniThreatLevel;
|
|
TargetDistance = _ServerSettings.HeliTargetDistance;
|
|
NPCAmountint = _ServerSettings.MiniNPCAmount;
|
|
gameObject.GetComponent<BaseCombatEntity>().InitializeHealth(_ServerSettings.MiniHealth, _ServerSettings.MiniHealth);
|
|
FireOffset = new Vector3(0, 0.2f, 0);
|
|
itembox = plugin.CreateStoragefunction(new Vector3(0, 0, 0), _heli);
|
|
RandomLoot = _ServerSettings.MiniLootString;
|
|
LootMulti = _ServerSettings.MiniLootMulti;
|
|
Position.Add(new Vector3(0.0f, 0.0f, 0.5f));
|
|
Position.Add(new Vector3(1f, -0.2f, -0.6f));
|
|
Position.Add(new Vector3(-1f, -0.2f, -0.6f));
|
|
Position.Add(new Vector3(0.0f, 0.0f, 1.3f));
|
|
if (!_ServerSettings.DisableHelilights) { searchLight = plugin.CreateLightfunction(_heli, new Vector3(0, 0.24f, 1.8f), new Vector3(-20, 180, 180)); }
|
|
break;
|
|
case 3:
|
|
plugin.pirateScrap++;
|
|
maxRotationSpeed = _ServerSettings.ScrapTurnSpeed;
|
|
maxSpeed = _ServerSettings.ScrapMaxSpeed;
|
|
hoverHeight = _ServerSettings.ScrapHoverHeight;
|
|
NPCHealth = _ServerSettings.ScrapNPCHealth;
|
|
Kit = _ServerSettings.ScrapKit;
|
|
orbitDistance = _ServerSettings.ScrapOrbitDistance;
|
|
AIShootMultiplyer = _ServerSettings.ScrapAIDistance;
|
|
ThreatTarget = _ServerSettings.ScrapThreatLevel;
|
|
TargetDistance = _ServerSettings.HeliTargetDistance;
|
|
NPCAmountint = _ServerSettings.ScrapNPCAmount;
|
|
gameObject.GetComponent<BaseCombatEntity>().InitializeHealth(_ServerSettings.ScrapHealth, _ServerSettings.ScrapHealth);
|
|
FireOffset = new Vector3(0, 0.2f, 0);
|
|
itembox = plugin.CreateStoragefunction(new Vector3(0, 0.8f, 0), _heli);
|
|
RandomLoot = _ServerSettings.ScrapLootString;
|
|
LootMulti = _ServerSettings.ScrapLootMulti;
|
|
Position.Add(new Vector3(0.8f, 0.8f, 2.6f));
|
|
Position.Add(new Vector3(-0.8f, 0.8f, 2.6f));
|
|
Position.Add(new Vector3(-1f, 0.8f, -1.5f));
|
|
Position.Add(new Vector3(1f, 0.8f, -1.5f));
|
|
Position.Add(new Vector3(-1f, 0.8f, -0.5f));
|
|
Position.Add(new Vector3(1f, 0.8f, -0.5f));
|
|
Position.Add(new Vector3(-1f, 0.8f, 0.5f));
|
|
Position.Add(new Vector3(1f, 0.8f, 0.5f));
|
|
Position.Add(new Vector3(-0.9f, 0.4f, -2.7f));
|
|
Position.Add(new Vector3(0.9f, 0.4f, -2.7f));
|
|
Position.Add(new Vector3(0f, 0.4f, -2.7f));
|
|
break;
|
|
}
|
|
_lastPos = transform.position;
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { Retire(); });
|
|
_rb = GetComponent<Rigidbody>();
|
|
if (itembox != null) { plugin.filllootfunction(itembox.inventory, -1, LootMulti, RandomLoot); ; }
|
|
npcs = plugin.CreateNPCs(NPCAmountint, Type, NPCHealth, Kit, AIShootMultiplyer, _heli, Position);
|
|
if (npcs == null) { _heli.Kill(); }
|
|
foreach (ScientistNPC n in npcs) { NPCOffSet.Add(n, n.transform.localPosition); }
|
|
plugin.PirateUintList.Add(_heli.net.ID);
|
|
StorageContainer fuelContainer = (_heli as PlayerHelicopter).GetFuelSystem().GetFuelContainer();
|
|
fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
|
|
plugin.timer.Once(Core.Random.Range(5, 10), NPCsAlive);
|
|
});
|
|
}
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
if (_heli == null || isDead) { return; }
|
|
MaintainAIAltutide();
|
|
if (!halftickrate) { halftickrate = true; }
|
|
else
|
|
{
|
|
halftickrate = false;
|
|
if (_heli.WaterFactor() > 0.4f) { Explodevoid(); return; }
|
|
if (_heli.transform.position.y < TerrainMeta.HeightMap.GetHeight(_heli.transform.position) + 3f && !isDead)
|
|
{
|
|
isDead = true;
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay, FireOffset, 0, _heli);
|
|
Invoke("Explodevoid", _ServerSettings.CrashDelayFloat);
|
|
}
|
|
|
|
if (_heli.Health() < _ServerSettings.NPCParachuteTrigger)
|
|
{
|
|
if (itembox != null) { itembox.dropFloats = true; itembox.DropItems(); }
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
npcs.Remove(npc);
|
|
if (npc != null && npc.IsAlive() && _heli != null)
|
|
{
|
|
npc.modelState.mounted = false;
|
|
if (_ServerSettings.NPCParachuteBool)
|
|
{
|
|
Vector3 pos = UnityEngine.Random.insideUnitCircle * 8;
|
|
plugin.AttachParachute(npc, _heli.transform.position + new Vector3(pos.x, 0, pos.y));
|
|
}
|
|
else
|
|
{
|
|
if (npc != null && !npc.IsDestroyed) { npc.Die(); }
|
|
}
|
|
}
|
|
}
|
|
Invoke("Explodevoid", 2f);
|
|
}
|
|
if (!burning && Type == 2)
|
|
{
|
|
if (_heli.Health() < _ServerSettings.StartFireHealth)
|
|
{
|
|
burning = true;
|
|
plugin.CreateFire(99, new Vector3(1, 1.9f, 0f), 0.1f, _heli);
|
|
}
|
|
}
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc == null) { continue; } if (npc.GetParentEntity() == null) { npc.SetParent(_heli, true, true); npc.transform.localPosition = NPCOffSet[npc]; } } }
|
|
CalculateDesiredAltitude();
|
|
UpdateTargetList();
|
|
}
|
|
|
|
_heli.SetFlag(BaseEntity.Flags.On, true);
|
|
if (_ServerSettings.DisableHelilights) { _heli.SetFlag(BaseEntity.Flags.Reserved5, false); }
|
|
else { if (searchLight == null) { _heli.SetFlag(BaseEntity.Flags.Reserved5, TOD_Sky.Instance.IsNight); } else { searchLight._light.SetFlag(BaseEntity.Flags.On, TOD_Sky.Instance.IsNight); searchLight._light.UpdateHasPower(searchLight._light.IsOn() ? 10 : 0, 1); } }
|
|
Vector3 vector = Vector3.Lerp(_lastMoveDir, (destination - transform.position).normalized, UnityEngine.Time.deltaTime / courseAdjustLerpTime);
|
|
_lastMoveDir = vector;
|
|
throttleSpeed = Mathf.Lerp(throttleSpeed, targetThrottleSpeed, UnityEngine.Time.deltaTime / 3f);
|
|
float d = throttleSpeed * maxSpeed;
|
|
transform.position += vector * d * UnityEngine.Time.deltaTime;
|
|
moveSpeed = Mathf.Lerp(moveSpeed, Vector3.Distance(_lastPos, transform.position) / UnityEngine.Time.deltaTime, UnityEngine.Time.deltaTime * 2f);
|
|
_lastPos = transform.position;
|
|
AIThink();
|
|
if (plugin.PointsOfIntrest.Count != 0)
|
|
{
|
|
if (NextPOITick < Time.time)
|
|
{
|
|
NextPOITick = Time.time + 10;
|
|
Vector3 POI = plugin.getPOIfunction(_heli.transform.position, _ServerSettings.PiratesAirPOIRadius);
|
|
if (POI != Vector3.zero)
|
|
{
|
|
float groundheightFLOAT = TerrainMeta.HeightMap.GetHeight(_heli.transform.position);
|
|
if (groundheightFLOAT < 20) { groundheightFLOAT = 30; }
|
|
POI.y = groundheightFLOAT;
|
|
SetTargetDestination(POI, 10f, 30f);
|
|
SetIdealRotation(GetYawRotationTo(POI), -1f);
|
|
interestZoneOrigin = POI;
|
|
currentVelocity = _lastMoveDir * (throttleSpeed * maxSpeed);
|
|
}
|
|
}
|
|
}
|
|
rotationSpeed = Mathf.Lerp(rotationSpeed, maxRotationSpeed, UnityEngine.Time.deltaTime / 2f);
|
|
transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotationSpeed * UnityEngine.Time.deltaTime);
|
|
transform.rotation = Quaternion.FromToRotation(transform.up, Vector3.up) * transform.rotation;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
try
|
|
{
|
|
switch (Type)
|
|
{
|
|
case 2:
|
|
plugin.piratesMini--;
|
|
break;
|
|
case 3:
|
|
plugin.pirateScrap--;
|
|
break;
|
|
}
|
|
enabled = false;
|
|
CancelInvoke();
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { npc.transform.position = new Vector3(0, -501, 0); npc.Kill(); } } }
|
|
if (searchLight != null) { if (searchLight.resizer != null && !searchLight.resizer.IsDestroyed) { searchLight.resizer.Kill(); } if (searchLight._light != null && !searchLight._light.IsDestroyed) { searchLight._light.Kill(); } }
|
|
if (_heli != null && !_heli.IsDestroyed) { _heli.Kill(); }
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public void Die() { if (this != null) { Destroy(this); } }
|
|
|
|
private void Explodevoid() { plugin.Explodefunction(_heli); }
|
|
|
|
private void NPCsAlive()
|
|
{
|
|
if (npcs == null) { if (_heli != null) { plugin.Explodefunction(_heli); } return; }
|
|
int alive = 0;
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
if (npc == null || !npc.IsAlive() || !plugin.ActiveNPCs.ContainsKey(npc)) { continue; }
|
|
if (plugin.ActiveNPCs[npc] != null) { _targetList.Add(new targetinfo(plugin.ActiveNPCs[npc], plugin.ActiveNPCs[npc].ToPlayer())); }
|
|
alive++;
|
|
}
|
|
if (alive == 0 && !isDead)
|
|
{
|
|
isDead = true;
|
|
if (itembox != null) { itembox.dropFloats = true; itembox.DropItems(); plugin.NextFrame(() => { if (!itembox.IsDestroyed) { itembox.Kill(); } }); }
|
|
plugin.timer.Once(_ServerSettings.FireDelay + _ServerSettings.ExplodeDelay, Explodevoid);
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay, FireOffset, _ServerSettings.FireDelay, _heli);
|
|
return;
|
|
}
|
|
plugin.timer.Once(_ServerSettings.NPCTick, NPCsAlive);
|
|
}
|
|
|
|
|
|
private float GetThrottleForDistance(float distToTarget)
|
|
{
|
|
float result;
|
|
if (distToTarget >= 75f) { result = 1f; }
|
|
else if (distToTarget >= 50f) { result = 0.75f; }
|
|
else if (distToTarget >= 25f) { result = 0.33f; }
|
|
else if (distToTarget >= 5f) { result = 0.05f; }
|
|
else { result = 0.05f * (1f - distToTarget / 5f); }
|
|
return result;
|
|
}
|
|
|
|
private void CalculateDesiredAltitude()
|
|
{
|
|
CalculateOverrideAltitude();
|
|
if (altOverride > currentDesiredAltitude) { currentDesiredAltitude = altOverride; return; }
|
|
currentDesiredAltitude = Mathf.MoveTowards(currentDesiredAltitude, altOverride, Time.fixedDeltaTime * 5f);
|
|
}
|
|
|
|
private void OnCurrentStateExit()
|
|
{
|
|
switch (_currentState)
|
|
{
|
|
default:
|
|
return;
|
|
case aiState.MOVE:
|
|
return;
|
|
case aiState.ORBIT:
|
|
breakingOrbit = false;
|
|
hasEnteredOrbit = false;
|
|
currentOrbitTime = 0f;
|
|
return;
|
|
case aiState.STRAFE:
|
|
lastStrafeTime = UnityEngine.Time.realtimeSinceStartup;
|
|
return;
|
|
case aiState.PATROL:
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void ExitCurrentState()
|
|
{
|
|
OnCurrentStateExit();
|
|
_currentState = aiState.IDLE;
|
|
}
|
|
|
|
|
|
private void Retire()
|
|
{
|
|
if (_heli == null) { return; }
|
|
if (isRetiring) { return; }
|
|
plugin.InvalidateCheck(_heli);
|
|
isRetiring = true;
|
|
float x = TerrainMeta.Size.x;
|
|
float y = 200f;
|
|
Vector3 vector = Vector3Ex.Range(-1f, 1f);
|
|
vector.y = 0f;
|
|
vector.Normalize();
|
|
vector *= x * 20f;
|
|
vector.y = y;
|
|
ExitCurrentState();
|
|
_currentState = aiState.MOVE;
|
|
destination_min_dist = 5f;
|
|
SetTargetDestination(vector, 5f, 30f);
|
|
float distToTarget = Vector3.Distance(base.transform.position, destination);
|
|
targetThrottleSpeed = GetThrottleForDistance(distToTarget);
|
|
}
|
|
|
|
private void SetIdealRotation(Quaternion newTargetRot, float rotationSpeedOverride = -1f)
|
|
{
|
|
float num = (rotationSpeedOverride == -1f) ? Mathf.Clamp01(moveSpeed / (maxSpeed * 0.5f)) : rotationSpeedOverride;
|
|
rotationSpeed = num * maxRotationSpeed;
|
|
targetRotation = newTargetRot;
|
|
}
|
|
|
|
private Quaternion GetYawRotationTo(Vector3 targetDest)
|
|
{
|
|
Vector3 a = targetDest;
|
|
a.y = 0f;
|
|
Vector3 position = base.transform.position;
|
|
position.y = 0f;
|
|
return Quaternion.LookRotation((a - position).normalized);
|
|
}
|
|
|
|
private void SetTargetDestination(Vector3 targetDest, float minDist = 5f, float minDistForFacingRotation = 30f)
|
|
{
|
|
destination = targetDest;
|
|
destination_min_dist = minDist;
|
|
float num = Vector3.Distance(targetDest, base.transform.position);
|
|
if (num > minDistForFacingRotation) { SetIdealRotation(GetYawRotationTo(destination), -1f); }
|
|
targetThrottleSpeed = GetThrottleForDistance(num);
|
|
}
|
|
|
|
private bool AtDestination() { return Vector3.Distance(base.transform.position, destination) < destination_min_dist; }
|
|
|
|
private float CalculateOverrideAltitude()
|
|
{
|
|
if (Time.frameCount == lastAltitudeCheckFrame) { return altOverride; }
|
|
lastAltitudeCheckFrame = Time.frameCount;
|
|
float y = _moveTarget.y;
|
|
float num = Mathf.Max(TerrainMeta.WaterMap.GetHeight(new Vector3(_moveTarget.x, 0, _moveTarget.z)), TerrainMeta.HeightMap.GetHeight(new Vector3(_moveTarget.x, 0, _moveTarget.z)));
|
|
float num2 = Mathf.Max(y, num + hoverHeight);
|
|
if (altitudeProtection)
|
|
{
|
|
Vector3 rhs = (_rb.velocity.magnitude < 0.1f) ? base.transform.forward : _rb.velocity.normalized;
|
|
Vector3 normalized = (Vector3.Cross(Vector3.Cross(base.transform.up, rhs), Vector3.up) + Vector3.down * 0.3f).normalized;
|
|
RaycastHit raycastHit;
|
|
RaycastHit raycastHit2;
|
|
if (Physics.SphereCast(base.transform.position - normalized * 20f, 50f, normalized, out raycastHit, 200f, 1134625043) && Physics.SphereCast(raycastHit.point + Vector3.up * 200f, 50f, Vector3.down, out raycastHit2, 200f, 1134625043)) { num2 = raycastHit2.point.y + hoverHeight; }
|
|
}
|
|
altOverride = num2;
|
|
return altOverride;
|
|
}
|
|
|
|
private void MaintainAIAltutide()
|
|
{
|
|
float groundheightFLOAT = TerrainMeta.HeightMap.GetHeight(_heli.transform.position);
|
|
if (currentDesiredAltitude < groundheightFLOAT + 10f) { currentDesiredAltitude = groundheightFLOAT + 15f; }
|
|
Vector3 ptr = transform.position + _rb.velocity;
|
|
float value = Mathf.Abs(currentDesiredAltitude - ptr.y);
|
|
bool flag = currentDesiredAltitude > ptr.y;
|
|
float d = Mathf.InverseLerp(0f, 12f, value) * AiAltitudeForce * (flag ? 1f : -1f);
|
|
_rb.AddForce(Vector3.up * d, ForceMode.Force);
|
|
}
|
|
|
|
private bool PlayerVisible(BasePlayer ply)
|
|
{
|
|
Vector3 position = ply.eyes.position;
|
|
if (TOD_Sky.Instance.IsNight && Vector3.Distance(position, interestZoneOrigin) > 40f) { return false; }
|
|
Vector3 vector = base.transform.position - Vector3.up * 6f;
|
|
float num = Vector3.Distance(position, vector);
|
|
Vector3 normalized = (position - vector).normalized;
|
|
RaycastHit raycastHit;
|
|
return GamePhysics.Trace(new Ray(vector + normalized * 5f, normalized), 0f, out raycastHit, num * 1.1f, 1218652417, QueryTriggerInteraction.UseGlobal) && raycastHit.collider.gameObject.ToBaseEntity() == ply;
|
|
}
|
|
|
|
private void UpdateTargetList()
|
|
{
|
|
Vector3 strafePos = Vector3.zero;
|
|
bool attacktarget = false;
|
|
for (int i = _targetList.Count - 1; i >= 0; i--)
|
|
{
|
|
targetinfo targetinfo = _targetList[i];
|
|
if (targetinfo == null || targetinfo.ent == null) { _targetList.Remove(targetinfo); }
|
|
else
|
|
{
|
|
if (UnityEngine.Time.realtimeSinceStartup > targetinfo.nextLOSCheck)
|
|
{
|
|
targetinfo.nextLOSCheck = UnityEngine.Time.realtimeSinceStartup + 1f;
|
|
if (PlayerVisible(targetinfo.ply))
|
|
{
|
|
targetinfo.lastSeenTime = UnityEngine.Time.realtimeSinceStartup;
|
|
targetinfo.visibleFor += 1f;
|
|
}
|
|
else { targetinfo.visibleFor = 0f; }
|
|
}
|
|
bool targetdead = targetinfo.ply ? targetinfo.ply.IsDead() : (targetinfo.ent.Health() <= 0f);
|
|
if (UnityEngine.Time.realtimeSinceStartup - targetinfo.lastSeenTime >= 6f || targetdead)
|
|
{
|
|
if (UnityEngine.Time.realtimeSinceStartup - lastStrafeTime >= 5f && _currentState != aiState.STRAFE && !isDead && !attacktarget && !targetdead && UnityEngine.Random.Range(0f, 1f) >= 0f)
|
|
{
|
|
attacktarget = true;
|
|
strafePos = targetinfo.ply.transform.position;
|
|
}
|
|
_targetList.Remove(targetinfo);
|
|
}
|
|
}
|
|
}
|
|
foreach (BasePlayer basePlayer in BasePlayer.activePlayerList)
|
|
{
|
|
if (!basePlayer.HasPlayerFlag(BasePlayer.PlayerFlags.SafeZone) && Vector3Ex.Distance2D(base.transform.position, basePlayer.transform.position) <= TargetDistance)
|
|
{
|
|
bool Target = false;
|
|
using (List<targetinfo>.Enumerator enumerator2 = _targetList.GetEnumerator())
|
|
{
|
|
while (enumerator2.MoveNext())
|
|
{
|
|
if (enumerator2.Current.ply == basePlayer)
|
|
{
|
|
Target = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!Target && basePlayer.GetThreatLevel() > ThreatTarget && PlayerVisible(basePlayer)) { _targetList.Add(new targetinfo(basePlayer, basePlayer)); }
|
|
}
|
|
}
|
|
if (attacktarget)
|
|
{
|
|
ExitCurrentState();
|
|
lastStrafeTime = UnityEngine.Time.realtimeSinceStartup;
|
|
_currentState = aiState.STRAFE;
|
|
Vector3 vector;
|
|
Vector3 vector2;
|
|
if (TransformUtil.GetGroundInfo(strafePos, out vector, out vector2, 100f, 1134625043, base.transform)) { strafe_target_position = vector; }
|
|
else { strafe_target_position = strafePos; }
|
|
Vector3 randomOffset = GetRandomOffset(strafePos, 100f, 192.5f, 20f, 30f);
|
|
SetTargetDestination(randomOffset, 10f, 30f);
|
|
SetIdealRotation(GetYawRotationTo(randomOffset), -1f);
|
|
puttingDistance = true;
|
|
}
|
|
}
|
|
|
|
private Vector3 GetRandomOffset(Vector3 origin, float minRange, float maxRange = 0f, float minHeight = 20f, float maxHeight = 30f)
|
|
{
|
|
Vector3 onUnitSphere = UnityEngine.Random.onUnitSphere;
|
|
onUnitSphere.y = 0f;
|
|
onUnitSphere.Normalize();
|
|
maxRange = Mathf.Max(minRange, maxRange);
|
|
Vector3 origin2 = origin + onUnitSphere * UnityEngine.Random.Range(minRange, maxRange);
|
|
return GetAppropriatePosition(origin2, minHeight, maxHeight);
|
|
}
|
|
|
|
private Vector3 GetAppropriatePosition(Vector3 origin, float minHeight = 20f, float maxHeight = 30f)
|
|
{
|
|
float num = 100f;
|
|
Ray ray = new Ray(origin + new Vector3(0f, num, 0f), Vector3.down);
|
|
float num2 = 5f;
|
|
RaycastHit raycastHit;
|
|
if (UnityEngine.Physics.SphereCast(ray, num2, out raycastHit, num * 2f - num2, 1134625043)) { origin = raycastHit.point; }
|
|
origin.y += UnityEngine.Random.Range(minHeight, maxHeight);
|
|
return origin;
|
|
}
|
|
|
|
private void stuck()
|
|
{
|
|
Vector3 Checkpos = _heli.transform.position;
|
|
Checkpos.y = 0;
|
|
SpotCheck.y = 0;
|
|
if (Vector3.Distance(Checkpos, SpotCheck) < 5f)
|
|
{
|
|
if (plugin.airnodes.Count <= 1) { SetTargetDestination(plugin.airnodes.GetRandom() + new Vector3(0f, 40f, 0f), 10f, 30f); }
|
|
else { SetTargetDestination(plugin.airnodes[UnityEngine.Random.Range(0, plugin.airnodes.Count)], 10f, 30f); }
|
|
_currentState = aiState.MOVE;
|
|
}
|
|
stuckcheck = false;
|
|
}
|
|
|
|
private void AIThink()
|
|
{
|
|
float time = UnityEngine.Time.realtimeSinceStartup;
|
|
float timePassed = time - _lastThinkTime;
|
|
_lastThinkTime = time;
|
|
if (!stuckcheck)
|
|
{
|
|
SpotCheck = _heli.transform.position;
|
|
stuckcheck = true;
|
|
Invoke("stuck", 10f);
|
|
}
|
|
switch (_currentState)
|
|
{
|
|
default:
|
|
ExitCurrentState();
|
|
_currentState = aiState.PATROL;
|
|
destination = plugin.airnodes.GetRandom();
|
|
SetIdealRotation(GetYawRotationTo(destination), -1f);
|
|
return;
|
|
case aiState.MOVE:
|
|
float distToTarget = Vector3.Distance(base.transform.position, destination);
|
|
targetThrottleSpeed = GetThrottleForDistance(distToTarget);
|
|
if (AtDestination())
|
|
{
|
|
ExitCurrentState();
|
|
_currentState = aiState.IDLE;
|
|
}
|
|
return;
|
|
case aiState.ORBIT:
|
|
State_Orbit_Think(timePassed);
|
|
return;
|
|
case aiState.STRAFE:
|
|
if (puttingDistance)
|
|
{
|
|
if (AtDestination())
|
|
{
|
|
puttingDistance = false;
|
|
SetTargetDestination(strafe_target_position + new Vector3(0f, 40f, 0f), 10f, 30f);
|
|
SetIdealRotation(GetYawRotationTo(strafe_target_position), -1f);
|
|
return;
|
|
}
|
|
}
|
|
else { SetIdealRotation(GetYawRotationTo(strafe_target_position), -1f); }
|
|
return;
|
|
case aiState.PATROL:
|
|
float num = Vector3.Distance(base.transform.position, destination);
|
|
if (num <= 25f) { targetThrottleSpeed = GetThrottleForDistance(num); }
|
|
else { targetThrottleSpeed = 0.5f; }
|
|
if (AtDestination())
|
|
{
|
|
ExitCurrentState();
|
|
State_Orbit_Enter();
|
|
}
|
|
if (_targetList.Count > 0)
|
|
{
|
|
interestZoneOrigin = _targetList[0].ply.transform.position + new Vector3(0f, 20f, 0f);
|
|
ExitCurrentState();
|
|
State_Orbit_Enter();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void State_Orbit_Think(float timePassed)
|
|
{
|
|
if (breakingOrbit)
|
|
{
|
|
if (AtDestination())
|
|
{
|
|
ExitCurrentState();
|
|
_currentState = aiState.IDLE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (Vector3Ex.Distance2D(base.transform.position, destination) > 15f) { return; }
|
|
if (!hasEnteredOrbit)
|
|
{
|
|
hasEnteredOrbit = true;
|
|
orbitStartTime = UnityEngine.Time.realtimeSinceStartup;
|
|
}
|
|
float num = 6.28318548f * currentOrbitDistance;
|
|
float num2 = 0.5f * maxSpeed;
|
|
float num3 = num / num2;
|
|
currentOrbitTime += timePassed / (num3 * 1.01f);
|
|
float rate = currentOrbitTime;
|
|
Vector3 orbitPosition = GetOrbitPosition(rate);
|
|
SetTargetDestination(orbitPosition, 0f, 1f);
|
|
targetThrottleSpeed = 0.5f;
|
|
}
|
|
if (UnityEngine.Time.realtimeSinceStartup - orbitStartTime > maxOrbitDuration && !breakingOrbit)
|
|
{
|
|
breakingOrbit = true;
|
|
Vector3 appropriatePosition = GetAppropriatePosition(base.transform.position + base.transform.forward * 75f, 40f, 50f);
|
|
SetTargetDestination(appropriatePosition, 10f, 0f);
|
|
}
|
|
}
|
|
|
|
private Vector3 GetOrbitPosition(float rate)
|
|
{
|
|
float x = Mathf.Sin(6.28318548f * rate) * currentOrbitDistance;
|
|
float z = Mathf.Cos(6.28318548f * rate) * currentOrbitDistance;
|
|
Vector3 vector = new Vector3(x, 20f, z);
|
|
vector = interestZoneOrigin + vector;
|
|
return vector;
|
|
}
|
|
|
|
private void State_Orbit_Enter()
|
|
{
|
|
_currentState = aiState.ORBIT;
|
|
breakingOrbit = false;
|
|
hasEnteredOrbit = false;
|
|
orbitStartTime = UnityEngine.Time.realtimeSinceStartup;
|
|
Vector3 vector = base.transform.position - interestZoneOrigin;
|
|
currentOrbitTime = Mathf.Atan2(vector.x, vector.z);
|
|
currentOrbitDistance = orbitDistance;
|
|
SetTargetDestination(GetOrbitPosition(currentOrbitTime), 20f, 0f);
|
|
}
|
|
}
|
|
|
|
public class LandPirate : MonoBehaviour
|
|
{
|
|
private BaseVehicle _rideable;
|
|
private Snowmobile sm;
|
|
private NavMeshAgent agent;
|
|
public ScientistNPC npc;
|
|
public ItemContainer itembox;
|
|
public Rigidbody rb;
|
|
private bool isleaving = false;
|
|
private float RomeRange;
|
|
private bool CanRoam;
|
|
private float MoveSpeed;
|
|
private float NextRoamTick;
|
|
private float MoveDelay;
|
|
private float FindingPoint;
|
|
private bool PutDistance;
|
|
private float npchealth;
|
|
private float ridablehealth;
|
|
private string RandomLoot = "";
|
|
private int LootMulti = 1;
|
|
private string Kit = "";
|
|
private float AimMulti;
|
|
private NightLight searchLight;
|
|
private List<Vector3> NavMeshPoints;
|
|
public BaseEntity PlayerTarget;
|
|
public int Type;
|
|
private Rigidbody _rb;
|
|
private InputState input = new InputState();
|
|
private InputMessage im = new InputMessage();
|
|
private bool IsMoving = false;
|
|
private Vector3 lastpos;
|
|
private bool halftickrate;
|
|
|
|
private void Awake()
|
|
{
|
|
plugin.NextTick(() =>
|
|
{
|
|
try { _rideable = GetComponent<BaseVehicle>(); } catch { Die(); }
|
|
try { rb = GetComponent<Rigidbody>(); } catch { }
|
|
agent = _rideable.gameObject.AddComponent<NavMeshAgent>();
|
|
_rideable.enableSaving = false;
|
|
MoveDelay = Time.time;
|
|
NextRoamTick = Time.time + 5;
|
|
switch (Type)
|
|
{
|
|
case 4:
|
|
plugin.pirateHorse++;
|
|
npchealth = _ServerSettings.HorseNPCHealth;
|
|
ridablehealth = _ServerSettings.HorseHealth;
|
|
RomeRange = _ServerSettings.HorseRomeRange;
|
|
CanRoam = _ServerSettings.HorseCanRoam;
|
|
MoveSpeed = _ServerSettings.HorseMoveSpeed;
|
|
Kit = _ServerSettings.HorseKit;
|
|
AimMulti = _ServerSettings.HorseAimMulti;
|
|
RandomLoot = _ServerSettings.HorseLootString;
|
|
LootMulti = _ServerSettings.HorseLootMulti;
|
|
RidableHorse horse = _rideable as RidableHorse;
|
|
itembox = horse.storageInventory;
|
|
AttachLight();
|
|
break;
|
|
case 5:
|
|
plugin.pirateSnowMobile++;
|
|
npchealth = _ServerSettings.SnowMobileNPCHealth;
|
|
ridablehealth = _ServerSettings.SnowMobileHealth;
|
|
RomeRange = _ServerSettings.SnowMobileRomeRange;
|
|
CanRoam = _ServerSettings.SnowMobileCanRoam;
|
|
MoveSpeed = _ServerSettings.SnowMobileMoveSpeed;
|
|
Kit = _ServerSettings.SnowMobileKit;
|
|
AimMulti = _ServerSettings.SnowMobileAimMulti;
|
|
RandomLoot = _ServerSettings.SnowMobileLootString;
|
|
LootMulti = _ServerSettings.SnowMobileLootMulti;
|
|
sm = _rideable as Snowmobile;
|
|
im.buttons = 2;
|
|
input.current = im;
|
|
sm.engineKW = 50;
|
|
sm.collisionEffect.guid = null;
|
|
sm.badTerrainDrag = 0.5f;
|
|
sm.idleFuelPerSec = 0f;
|
|
sm.maxFuelPerSec = 0f;
|
|
StorageContainer fuelContainer = sm.GetFuelSystem()?.GetFuelContainer();
|
|
if (fuelContainer != null)
|
|
{
|
|
fuelContainer.inventory.AddItem(fuelContainer.allowedItem, 1);
|
|
fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
|
|
}
|
|
itembox = sm.GetItemContainer().inventory;
|
|
break;
|
|
}
|
|
_rideable.InitializeHealth(ridablehealth, ridablehealth);
|
|
npc = plugin.CreateNPCs(1, Type, npchealth, Kit, AimMulti, _rideable, new List<Vector3> { new Vector3(0f, 0f, 0f) })[0];
|
|
_rideable.AttemptMount(npc, false);
|
|
NavMeshPoints = plugin.FindNavPoints(_rideable.transform.position, RomeRange);
|
|
plugin.PirateUintList.Add(_rideable.net.ID);
|
|
if (itembox != null) { itembox.capacity = 30; plugin.filllootfunction(itembox, -1, LootMulti, RandomLoot); }
|
|
plugin.timer.Once(Core.Random.Range(2, 10), NPCsAlive);
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { Leave(); });
|
|
agent.autoTraverseOffMeshLink = true;
|
|
agent.autoRepath = true;
|
|
agent.autoBraking = true;
|
|
_rb = GetComponent<Rigidbody>();
|
|
RaycastHit raycastHit;
|
|
if (Physics.SphereCast(agent.transform.position + new Vector3(0, 5, 0), 10f, Vector3.down, out raycastHit, 10f, 1134625043) || Physics.SphereCast(agent.transform.position + new Vector3(0, 5, 0), 10f, Vector3.up, out raycastHit, 10f, 1134625043))
|
|
{
|
|
_rideable.transform.position = raycastHit.point;
|
|
agent.transform.position = raycastHit.point;
|
|
}
|
|
});
|
|
}
|
|
|
|
private void Leave()
|
|
{
|
|
if (_rideable == null) { return; }
|
|
if (PlayerTarget != null)
|
|
{
|
|
plugin.timer.Once(10f, Leave);
|
|
return;
|
|
}
|
|
if (agent != null)
|
|
{
|
|
agent.isStopped = true;
|
|
}
|
|
if (npc != null) { plugin.NPCsUintList.Remove(npc.net.ID); }
|
|
plugin.timer.Once(30f, () =>
|
|
{
|
|
if (_rideable == null) { return; }
|
|
plugin.FreeLists(_rideable);
|
|
if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { npc.Kill(); }
|
|
if (!_rideable.IsDestroyed) { if (itembox != null) { itembox.Clear(); } _rideable.transform.position = Vector3.zero; plugin.NextFrame(() => { if (_rideable != null && !_rideable.IsDestroyed) { _rideable.Kill(); } }); }
|
|
});
|
|
}
|
|
|
|
private void AttachLight() { plugin.timer.Once(8f, () => { if (!_ServerSettings.DisableLandlights && _rideable != null) { searchLight = plugin.CreateLightfunction(_rideable, new Vector3(0, 1.8f, 1.2f), new Vector3(-20, 180, 180)); } }); }
|
|
|
|
private void NPCsAlive()
|
|
{
|
|
if (_rideable == null || isleaving) { return; }
|
|
if (npc != null && npc.IsAlive() && plugin.ActiveNPCs.ContainsKey(npc))
|
|
{
|
|
if (!npc.IsMounted() && _rideable._health > 20) { _rideable.AttemptMount(npc, false); }
|
|
if (PlayerTarget == null) { PlayerTarget = plugin.ActiveNPCs[npc]; }
|
|
plugin.timer.Once(_ServerSettings.NPCTick, NPCsAlive);
|
|
return;
|
|
}
|
|
PlayerTarget = null;
|
|
DropLoot();
|
|
plugin.timer.Once(_ServerSettings.StopDelayFloat, Stop);
|
|
}
|
|
|
|
private void Stop()
|
|
{
|
|
IsMoving = false;
|
|
plugin.timer.Once(_ServerSettings.FireDelay + _ServerSettings.ExplodeDelay, () => { try { Explodevoid(); } catch { } });
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay, new Vector3(0, 0, 0), _ServerSettings.FireDelay, _rideable);
|
|
}
|
|
|
|
private void Explodevoid() { if (_rideable == null) { return; } if (sm != null) { plugin.Explodefunction(sm); } else { if (searchLight != null) { searchLight._light.SetParent(null, true, true); searchLight.resizer.SetParent(null, true, true); if (!searchLight._light.IsDestroyed) { searchLight._light.Kill(); } if (!searchLight.resizer.IsDestroyed) { searchLight.resizer.Kill(); } } plugin.NextFrame(() => { _rideable.Die(); }); } }
|
|
|
|
private void setdestination(Vector3 movePoint, float speed = 8f)
|
|
{
|
|
if (agent.isOnNavMesh)
|
|
{
|
|
if (agent.isStopped) agent.isStopped = false;
|
|
if (agent.speed != speed) agent.speed = speed;
|
|
IsMoving = true;
|
|
if (TerrainMeta.HeightMap.GetHeight(new Vector3(movePoint.x, 0, movePoint.z)) > -0.6f) { agent.SetDestination(movePoint); }
|
|
return;
|
|
}
|
|
RaycastHit raycastHit;
|
|
if (Physics.SphereCast(agent.transform.position + new Vector3(0, 5, 0), 10f, Vector3.down, out raycastHit, 10f, 1134625043) || Physics.SphereCast(agent.transform.position + new Vector3(0, 5, 0), 10f, Vector3.up, out raycastHit, 10f, 1134625043))
|
|
{
|
|
agent.transform.position = raycastHit.point;
|
|
agent.areaMask = 1134625043;
|
|
agent.agentTypeID = -1372625422;
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void DropLoot() { if (sm != null) { if (itembox != null) { itembox.Drop(buoyantentityprefab, _rideable.transform.position + new Vector3(0, 5, 0), _rideable.ServerRotation, 0); itembox = null; } } }
|
|
|
|
void BailOutcall()
|
|
{
|
|
DropLoot();
|
|
plugin.BailOutfunction(_rideable.transform.position, npc, Vector3.zero, 3);
|
|
npc = null;
|
|
}
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
if (_rideable == null || rb == null || isleaving) { return; }
|
|
try
|
|
{
|
|
if (!halftickrate) { halftickrate = true; }
|
|
else
|
|
{
|
|
if (npc == null || npc.IsDestroyed || !_rideable.IsMounted()) { if (_rideable != null) { _rideable.SetFlag(BaseVehicle.Flags.On, false); } return; }
|
|
halftickrate = false;
|
|
float GroundH = TerrainMeta.HeightMap.GetHeight(_rideable.transform.position);
|
|
if (_rideable.transform.position.y + 0.5f < GroundH) { _rideable.transform.position = new Vector3(_rideable.transform.position.x, GroundH + 0.5f, _rideable.transform.position.z); }
|
|
if (_rideable.WaterFactor() > 0.4f) { _rb.velocity *= -1; }
|
|
if (_rideable.WaterFactor() > 0.6f) { Explodevoid(); return; }
|
|
if (_rideable.Health() <= 40) { BailOutcall(); }
|
|
if (_rideable.Health() <= 10) { Explodevoid(); }
|
|
if (sm != null)
|
|
{
|
|
if (agent == null) { return; }
|
|
if (Vector3.Distance(agent.destination, npc.transform.position) > 8 && IsMoving) { im.buttons = 2; }
|
|
else { im.buttons = 0; IsMoving = false; }
|
|
sm.PlayerServerInput(input, npc);
|
|
sm.SetFlag(Snowmobile.Flags.On, true);
|
|
}
|
|
if (PlayerTarget != null)
|
|
{
|
|
float distance = Vector3.Distance(_rideable.transform.position, PlayerTarget.transform.position);
|
|
if (!PutDistance && distance < 10)
|
|
{
|
|
PutDistance = true;
|
|
plugin.timer.Once(8f, () => { PutDistance = false; });
|
|
}
|
|
if (PutDistance)
|
|
{
|
|
if (FindingPoint < Time.time)
|
|
{
|
|
Vector3 point = plugin.FindNavPoints(PlayerTarget.transform.position, 20).GetRandom();
|
|
setdestination(point, 6f);
|
|
FindingPoint = Time.time + 5;
|
|
}
|
|
return;
|
|
}
|
|
if (MoveDelay < Time.time)
|
|
{
|
|
MoveDelay = Time.time + 5;
|
|
if (Vector3.Distance(_rideable.transform.position, PlayerTarget.transform.position) > 20)
|
|
{
|
|
if (npc != null) { npc.SetAimDirection(PlayerTarget.transform.position - npc.transform.position); npc.SendNetworkUpdateImmediate(); }
|
|
setdestination(PlayerTarget.transform.position, 8f);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CanRoam && npc != null && NextRoamTick < Time.time)
|
|
{
|
|
if (Vector3.Distance(lastpos, _rideable.transform.position) < 5f) { IsMoving = true; }
|
|
lastpos = _rideable.transform.position;
|
|
NextRoamTick = Time.time + UnityEngine.Random.Range(10, 30);
|
|
if (plugin.PointsOfIntrest.Count != 0)
|
|
{
|
|
Vector3 PointOfIntrest = plugin.getPOIfunction(lastpos, _ServerSettings.PiratesLandPOIRadius);
|
|
if (PointOfIntrest != Vector3.zero && TerrainMeta.HeightMap.GetHeight(PointOfIntrest) > 5f)
|
|
{
|
|
if (npc != null) { npc.SetAimDirection(PointOfIntrest - npc.transform.position); npc.SendNetworkUpdateImmediate(); }
|
|
setdestination(PointOfIntrest, MoveSpeed);
|
|
return;
|
|
}
|
|
}
|
|
if (NavMeshPoints != null && NavMeshPoints.Count > 0)
|
|
{
|
|
Vector3 point = NavMeshPoints.GetRandom();
|
|
if (npc != null) { npc.SetAimDirection(point - npc.transform.position); npc.SendNetworkUpdateImmediate(); }
|
|
setdestination(point, MoveSpeed);
|
|
}
|
|
else { NavMeshPoints = plugin.FindNavPoints(_rideable.transform.position, RomeRange); }
|
|
}
|
|
}
|
|
}
|
|
if (sm != null) { if (!_ServerSettings.DisableLandlights) { sm.SetFlag(Snowmobile.Flag_Headlights, TOD_Sky.Instance.IsNight); } }
|
|
else { if (!_ServerSettings.DisableLandlights) { if (searchLight != null) { searchLight._light.SetFlag(BaseEntity.Flags.On, TOD_Sky.Instance.IsNight); searchLight._light.UpdateHasPower(searchLight._light.IsOn() ? 10 : 0, 1); } } }
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
try
|
|
{
|
|
switch (Type)
|
|
{
|
|
case 4:
|
|
plugin.pirateHorse--;
|
|
break;
|
|
case 5:
|
|
plugin.pirateSnowMobile--;
|
|
break;
|
|
}
|
|
enabled = false;
|
|
if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { npc.transform.position = new Vector3(0, -501, 0); npc.Kill(); }
|
|
if (searchLight != null) { if (searchLight.resizer != null && !searchLight.resizer.IsDestroyed) { searchLight.resizer.Kill(); } if (searchLight._light != null && !searchLight._light.IsDestroyed) { searchLight._light.Kill(); } }
|
|
if (_rideable != null && !_rideable.IsDestroyed) { _rideable.transform.position = new Vector3(0, -501, 0); _rideable.Kill(); }
|
|
CancelInvoke();
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private void Die() { if (this != null) { Destroy(this); } }
|
|
}
|
|
|
|
private class RailPirate : MonoBehaviour
|
|
{
|
|
public int Type = 8;
|
|
public BaseEntity _trainbe;
|
|
public TrainEngine _trainEngine;
|
|
public TrainCar _trainCar;
|
|
public List<BaseEntity> wagons = new List<BaseEntity>();
|
|
private bool burning;
|
|
private bool isDead;
|
|
private bool stopping;
|
|
private bool loading = true;
|
|
public List<ScientistNPC> npcs;
|
|
public StorageContainer itembox;
|
|
private int NPCAmountint;
|
|
private string RandomLoot = "";
|
|
private int LootMulti = 1;
|
|
private List<Vector3> Position = new List<Vector3>();
|
|
private float NPCHealth;
|
|
private string Kit;
|
|
private float AIShootMultiplyer = 1;
|
|
private Vector3 FireOffset;
|
|
public BaseEntity PlayerTarget;
|
|
private bool halftickrate;
|
|
private float TargetSpeed = -8;
|
|
private float CollisionCheck;
|
|
private bool exploding = false;
|
|
private Vector3 curretpos;
|
|
private ScientistNPC Driver;
|
|
|
|
private void Awake()
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
_trainbe = GetComponent<BaseEntity>();
|
|
if (_trainbe == null) { return; }
|
|
plugin.pirateRail++;
|
|
plugin.TrainsBaseEntityList.Add(_trainbe);
|
|
if (_trainbe.transform == null) { _trainbe.Kill(); return; }
|
|
curretpos = _trainbe.transform.position;
|
|
_trainEngine = _trainbe as TrainEngine;
|
|
_trainCar = _trainbe as TrainCar;
|
|
if (_trainEngine == null || _trainCar == null) { _trainbe.Kill(); return; }
|
|
_trainCar.frontCollisionTrigger.interestLayers = Layers.Mask.Vehicle_World | Layers.Mask.Construction | Layers.Mask.Deployed;
|
|
_trainCar.rearCollisionTrigger.interestLayers = Layers.Mask.Vehicle_World | Layers.Mask.Construction | Layers.Mask.Deployed;
|
|
plugin.NextFrame(() => { _trainEngine.CancelInvoke("DecayTick"); });
|
|
TargetSpeed = _ServerSettings.PirateRailTrainSpeed * -1f;
|
|
_trainCar.completeTrain.trackSpeed = TargetSpeed;
|
|
CollisionCheck = Time.time;
|
|
AIShootMultiplyer = _ServerSettings.PirateRailAimMulti;
|
|
NPCAmountint = _ServerSettings.PirateRailNPCAmount;
|
|
NPCHealth = _ServerSettings.PirateBaseNPCHealth;
|
|
plugin.timer.Once(10, () => { loading = false; });
|
|
(_trainbe as BaseCombatEntity).InitializeHealth(_ServerSettings.PirateRailHealth, _ServerSettings.PirateRailHealth);
|
|
Kit = _ServerSettings.PirateRailNPCKit;
|
|
RandomLoot = _ServerSettings.PirateRailLootString;
|
|
LootMulti = _ServerSettings.PirateRailLootMulti;
|
|
Position.Add(new Vector3(0.9f, 1.5f, 2.5f));
|
|
Position.Add(new Vector3(0f, 1.5f, -1.9f));
|
|
Position.Add(new Vector3(0f, 1.5f, -3.8f));
|
|
Position.Add(new Vector3(0.9f, 1.5f, -3.7f));
|
|
Position.Add(new Vector3(-0.9f, 1.5f, -3.7f));
|
|
Position.Add(new Vector3(0f, 1.5f, -2.8f));
|
|
Position.Add(new Vector3(0.9f, 1.5f, -2.7f));
|
|
Position.Add(new Vector3(-0.9f, 1.5f, -2.7f));
|
|
Position.Add(new Vector3(0.9f, 1.5f, -1f));
|
|
Position.Add(new Vector3(-0.9f, 1.5f, -1f));
|
|
FireOffset = new Vector3(0, 1.3f, 0);
|
|
plugin.CreateWindowfunction(new Vector3(1.393f, 2.321f, 3.374f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(1.531f, 2.334f, 4.584f), new Vector3(90.000f, 270.000f, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(0.961f, 2.339f, 4.584f), new Vector3(90.000f, 270.000f, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(-0.195f, 2.341f, 4.584f), new Vector3(90.0000f, 270.000f, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(1.393f, 2.321f, 2.203f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(1.393f, 2.321f, 1.024f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(-1.415f, 2.321f, 1.024f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(-1.415f, 2.321f, 2.203f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(-1.415f, 2.321f, 3.374f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.CreateWindowfunction(new Vector3(-1.415f, 2.321f, 3.374f), new Vector3(90.000f, 0, 0), _trainbe);
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { leaveing(); });
|
|
itembox = plugin.CreateStoragefunction(new Vector3(0, 1.45f, 0), _trainbe);
|
|
if (itembox != null) { plugin.filllootfunction(itembox.inventory, -1, LootMulti, RandomLoot); }
|
|
npcs = plugin.CreateNPCs(NPCAmountint, Type, NPCHealth, Kit, AIShootMultiplyer, _trainbe, Position);
|
|
if (npcs == null) { _trainbe.Kill(); }
|
|
Driver = npcs[0];
|
|
if (npcs.Count == 0) { plugin.NPCSit(Driver, _trainEngine); }
|
|
plugin.timer.Once(2, () => { Driver.InitializeHealth(_ServerSettings.PirateRailNPCDriverHealth, _ServerSettings.PirateRailNPCDriverHealth); });
|
|
plugin.PirateUintList.Add(_trainbe.net.ID);
|
|
plugin.timer.Once(11f, () =>
|
|
{
|
|
_trainEngine.AttemptMount(Driver, false);
|
|
_trainEngine.engineController.TryStartEngine(Driver);
|
|
});
|
|
plugin.timer.Once(Core.Random.Range(5, 10), NPCsAlive);
|
|
StorageContainer fuelContainer = (_trainbe as BaseVehicle).GetFuelSystem().GetFuelContainer();
|
|
if (fuelContainer != null) { fuelContainer.SetFlag(BaseEntity.Flags.Locked, true); }
|
|
TrainTrackSpline trainTrack;
|
|
float splineDistance;
|
|
if (TrainTrackSpline.TryFindTrackNear(_trainCar.transform.position, 10f, out trainTrack, out splineDistance))
|
|
{
|
|
TrainTrackSpline currentTrack = trainTrack;
|
|
if (currentTrack == null) { return; }
|
|
Vector3 lastCheckPosition = currentTrack.GetPosition(splineDistance);
|
|
Vector3 checkForward = currentTrack.GetTangentCubicHermiteWorld(splineDistance);
|
|
TrainCar lastSpawnedCar = _trainCar;
|
|
TrainCar activeTrain;
|
|
for (int i = 0; i < _ServerSettings.PirateRailWagonAmount; i++)
|
|
{
|
|
try
|
|
{
|
|
lastCheckPosition = plugin.GetPositionOnFromfunction(ref currentTrack, checkForward, lastCheckPosition, 21, out checkForward);
|
|
if (!plugin.HasSpaceToSpawnfunction(currentTrack, lastCheckPosition)) { break; }
|
|
Action<TrainCar> disableCoupling = i == _ServerSettings.PirateRailWagonAmount ? new Action<TrainCar>((TrainCar t) => t.rearCoupling = null) : null;
|
|
char Letter = plugin.GetLetterfunction();
|
|
if (Letter == 'd') { Letter = 'a'; }
|
|
if (SpawnEntity(wagonentsprefab.Replace('$', Letter), lastCheckPosition, Quaternion.LookRotation(_trainCar.transform.forward), out activeTrain, disableCoupling))
|
|
{
|
|
plugin.BaseParts.Add(activeTrain.net.ID);
|
|
wagons.Add(activeTrain);
|
|
float distToMove = Vector3Ex.Distance2D(lastSpawnedCar.rearCoupling.position, activeTrain.frontCoupling.position);
|
|
activeTrain.MoveFrontWheelsAlongTrackSpline(activeTrain.FrontTrackSection, activeTrain.FrontWheelSplineDist, distToMove, null, 0);
|
|
activeTrain.coupling.frontCoupling.TryCouple(lastSpawnedCar.coupling.rearCoupling, true);
|
|
lastSpawnedCar = activeTrain;
|
|
Vector3[] WagonPos;
|
|
switch (Letter)
|
|
{
|
|
case 'a':
|
|
WagonPos = new Vector3[] { new Vector3(0.0f, 1.5f, 2.5f), new Vector3(0.0f, 1.5f, 4.5f) };
|
|
npcs.AddRange(plugin.CreateNPCs(WagonPos.Length, 8, _ServerSettings.PirateRailNPCHealth, _ServerSettings.PirateRailNPCKit, AIShootMultiplyer, activeTrain, WagonPos.ToList()));
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.674f, 0.857f, 3.30f), Vector3.zero, activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(-1.619f, 0.857f, 3.142f), new Vector3(0, 180f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(-1.619f, 0.857f, -3.226f), new Vector3(0, 180f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(0f, 0.857f, -4.781f), new Vector3(0, 90f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(0f, 0.857f, 6.097f), new Vector3(0, 90f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.486f, 3.889f, -3.079f), new Vector3(0, 0, 90f), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.486f, 3.889f, -0.378f), new Vector3(0, 0, 90f), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.486f, 3.889f, 2.318f), new Vector3(0, 0, 90f), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.486f, 3.889f, 5.014f), new Vector3(0, 0, 90f), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateTurretfunction(new Vector3(-0.808f, 1.546f, -5.566f), new Vector3(0, 90f, 0), activeTrain).net.ID);
|
|
plugin.CreateLootSpawnerfunction(new Vector3(-0.927f, 1.546f, -0.117f), new Vector3(0, 270f, 0), activeTrain, eliteentityprefab);
|
|
break;
|
|
case 'b':
|
|
WagonPos = new Vector3[] { new Vector3(0.0f, 1.5f, 2.5f), new Vector3(0.0f, 1.5f, 4.5f) };
|
|
npcs.AddRange(plugin.CreateNPCs(WagonPos.Length, 8, _ServerSettings.PirateRailNPCHealth, _ServerSettings.PirateRailNPCKit, AIShootMultiplyer, activeTrain, WagonPos.ToList()));
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(1.674f, 0.857f, 3.30f), Vector3.zero, activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(-1.619f, 0.857f, 3.142f), new Vector3(0, 180f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(-1.619f, 0.857f, -3.226f), new Vector3(0, 180f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(0f, 0.857f, -4.781f), new Vector3(0, 90f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(new Vector3(0f, 0.857f, 6.097f), new Vector3(0, 90f, 0), activeTrain, _ServerSettings.PirateRailwagondoorskinid, activeTrain.OwnerID, _ServerSettings.PirateRailWagondoorhealth).net.ID);
|
|
plugin.BaseParts.Add(plugin.CreateTurretfunction(new Vector3(-0.808f, 1.546f, -5.566f), new Vector3(0, 90f, 0), activeTrain).net.ID);
|
|
plugin.CreateLootSpawnerfunction(new Vector3(-0.927f, 1.546f, -0.117f), new Vector3(0, 270f, 0), activeTrain, eliteentityprefab);
|
|
break;
|
|
//case 'd':
|
|
//lugin.BaseParts.Add(plugin.CreateTurretfunction(new Vector3(-0f, 4.85f, -0f), new Vector3(0, 180f, 0), activeTrain).net.ID);
|
|
// break;
|
|
case 'c':
|
|
plugin.BaseParts.Add(plugin.CreateSamsitefunction(new Vector3(0f, 1.4f, 0f), new Vector3(0, 0, 0), activeTrain).net.ID);
|
|
WagonPos = new Vector3[] { new Vector3(0.9f, 1.5f, 2.5f), };
|
|
npcs.AddRange(plugin.CreateNPCs(WagonPos.Length, 8, _ServerSettings.PirateRailNPCHealth, _ServerSettings.PirateRailNPCKit, AIShootMultiplyer, activeTrain, WagonPos.ToList()));
|
|
break;
|
|
}
|
|
activeTrain.InitializeHealth(_ServerSettings.PirateRailWagonhealth, _ServerSettings.PirateRailWagonhealth);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private bool SpawnEntity(string prefab, Vector3 position, Quaternion rotation, out TrainCar trainCar, Action<TrainCar> preSpawn)
|
|
{
|
|
trainCar = GameManager.server.CreateEntity(prefab, position, rotation) as TrainCar;
|
|
trainCar.enableSaving = false;
|
|
if (preSpawn != null) { preSpawn(trainCar); }
|
|
trainCar.platformParentTrigger.ParentNPCPlayers = true;
|
|
trainCar.Spawn();
|
|
trainCar.enableSaving = false;
|
|
trainCar.transform.position = position;
|
|
if (trainCar == null || trainCar.IsDestroyed) { return false; }
|
|
return true;
|
|
}
|
|
|
|
private void leaveing()
|
|
{
|
|
if (_trainbe == null) { return; }
|
|
if (PlayerTarget != null || plugin.PlayersNearbyfunction(_trainbe.transform.position, 60))
|
|
{
|
|
plugin.timer.Once(10f, leaveing);
|
|
return;
|
|
}
|
|
plugin.KillWagonsfunction(wagons);
|
|
Die();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
try
|
|
{
|
|
plugin.pirateRail--;
|
|
isDead = true;
|
|
enabled = false;
|
|
CancelInvoke();
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { npc.transform.position = new Vector3(0, -501, 0); npc.Kill(); } } }
|
|
if (_trainbe != null && !_trainbe.IsDestroyed) { _trainbe.transform.position = new Vector3(0, -501, 0); _trainbe.Kill(); }
|
|
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public void Die() { if (this != null) { Destroy(this); } }
|
|
|
|
private void Explodevoid() { if (_trainbe != null) { plugin.Explodefunction(_trainbe); } }
|
|
|
|
public void FixedUpdate()
|
|
{
|
|
try
|
|
{
|
|
if (_trainbe == null || isDead || loading || _trainbe.IsDestroyed || _trainCar.completeTrain == null) { return; }
|
|
if (stopping) { _trainCar.completeTrain.trackSpeed = 0; return; }
|
|
if (CollisionCheck < Time.time)
|
|
{
|
|
if (_trainEngine.HasFlag(BaseEntity.Flags.Reserved6) || Vector3.Distance(_trainbe.transform.position, curretpos) < 5f) { TargetSpeed *= -1f; }
|
|
CollisionCheck = Time.time + 4;
|
|
curretpos = _trainbe.transform.position;
|
|
}
|
|
_trainbe.SetFlag(BaseVehicle.Flags.Reserved1, true);
|
|
_trainbe.SetFlag(BaseEntity.Flags.Reserved5, true);
|
|
_trainbe.SetFlag(TrainEngine.Flags.On, true);
|
|
if (!halftickrate) { halftickrate = true; if (Driver == null || Driver.IsDead()) { stopping = true; } }
|
|
else
|
|
{
|
|
_trainCar.completeTrain.trackSpeed = TargetSpeed;
|
|
if (!burning)
|
|
{
|
|
if (_trainbe.Health() < _ServerSettings.StartFireHealth)
|
|
{
|
|
burning = true;
|
|
plugin.CreateFire(60, new Vector3(0, 0.9f, -1.8f), 0.1f, _trainbe);
|
|
BailOutcall();
|
|
}
|
|
}
|
|
if (_trainbe.Health() < 10 && !exploding) { exploding = true; Explodevoid(); return; }
|
|
halftickrate = false;
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private void BailOutcall()
|
|
{
|
|
if (itembox != null) { itembox.dropFloats = true; itembox.DropItems(); }
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
npcs.Remove(npc);
|
|
plugin.BailOutfunction(_trainbe.transform.position, npc, Vector3.zero, 8);
|
|
}
|
|
}
|
|
|
|
private void NPCsAlive()
|
|
{
|
|
if (npcs == null || _trainbe == null) { return; }
|
|
int alive = 0;
|
|
|
|
foreach (ScientistNPC npc in npcs.ToArray())
|
|
{
|
|
if (npc == null || !npc.IsAlive() || !plugin.ActiveNPCs.ContainsKey(npc)) { continue; }
|
|
if (PlayerTarget == null) { PlayerTarget = plugin.ActiveNPCs[npc]; }
|
|
alive++;
|
|
}
|
|
if (alive == 0)
|
|
{
|
|
plugin.timer.Once(10f, () => { if (_trainbe != null) { _trainbe.SetFlag(BaseVehicle.Flags.Reserved1, false); stopping = true; } });
|
|
isDead = true;
|
|
plugin.timer.Once(_ServerSettings.StopDelayFloat, Stop);
|
|
return;
|
|
}
|
|
plugin.timer.Once(_ServerSettings.NPCTick, NPCsAlive);
|
|
}
|
|
|
|
private void Stop()
|
|
{
|
|
if (_trainbe == null) { return; }
|
|
plugin.timer.Once(_ServerSettings.FireDelay + _ServerSettings.ExplodeDelay, Explodevoid);
|
|
plugin.CreateFire(_ServerSettings.ExplodeDelay, FireOffset, _ServerSettings.FireDelay, _trainbe);
|
|
}
|
|
}
|
|
|
|
public class FootPirate : MonoBehaviour
|
|
{
|
|
public int Type = 9;
|
|
private float terraincheck;
|
|
public float flyheightfloat = 150;
|
|
public float flyspeedfloat = 60f;
|
|
public int NPCAmountint = 5;
|
|
public int NPCDropsint = 3;
|
|
public int NPCDropped = 0;
|
|
public BaseEntity baseentitybe;
|
|
public BaseEntity plane;
|
|
public Vector3 movetopoint = Vector3.zero;
|
|
private bool isRetiring = false;
|
|
public List<ScientistNPC> npcs = new List<ScientistNPC>();
|
|
public Dictionary<Vector3, bool> droppoints = plugin.dropnodes;
|
|
private float NextPOITick;
|
|
List<Vector3> DropPos = new List<Vector3>();
|
|
public bool CanDropNext = false;
|
|
|
|
void Awake()
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
baseentitybe = GetComponent<BaseEntity>();
|
|
if (baseentitybe == null) { OnDestroy(); return; }
|
|
flyheightfloat = _ServerSettings.PiratePlaneflyheight;
|
|
flyspeedfloat = _ServerSettings.PiratePlaneflyspeed;
|
|
NPCAmountint = _ServerSettings.PiratePlaneNPCAmount;
|
|
NPCDropsint = _ServerSettings.PiratePlaneNPCDrops;
|
|
terraincheck = Time.time;
|
|
plane = GameManager.server.CreateEntity(cargoplaneentityprefab, baseentitybe.transform.position, Quaternion.identity, true);
|
|
if (plane != null)
|
|
{
|
|
plane.enabled = false;
|
|
plane.Spawn();
|
|
plane.enableSaving = false;
|
|
plane.SetParent(baseentitybe);
|
|
plane.transform.localPosition += new Vector3(0, -15, 0);
|
|
|
|
}
|
|
for (int i = 0; i <= NPCAmountint; i++) { DropPos.Add(new Vector3(0f, 2.1f, -13.1f)); }
|
|
movetopoint = FindPOIvector();
|
|
NextPOITick = Time.time;
|
|
if (Type == 91) { NextPOITick = Time.time + 9999; }
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { Retire(); });
|
|
plugin.piratePlane++;
|
|
plugin.PirateUintList.Add(baseentitybe.net.ID);
|
|
});
|
|
}
|
|
|
|
private Vector3 Retire()
|
|
{
|
|
if (plane == null) { return Vector3.zero; }
|
|
if (isRetiring) { return Vector3.zero; }
|
|
plugin.InvalidateCheck(plane);
|
|
isRetiring = true;
|
|
float x = TerrainMeta.Size.x;
|
|
float y = plane.transform.position.y;
|
|
Vector3 vector = Vector3Ex.Range(-1f, 1f);
|
|
vector.y = 0f;
|
|
vector.Normalize();
|
|
vector *= (x * 20f);
|
|
vector.y = y;
|
|
movetopoint = vector;
|
|
isRetiring = true;
|
|
return vector;
|
|
}
|
|
|
|
private bool DropHere(Vector3 position)
|
|
{
|
|
if (npcs == null || npcs.Count == 0) { return false; }
|
|
float groundheightFLOAT = TerrainMeta.HeightMap.GetHeight(position);
|
|
if (groundheightFLOAT < 1f) { return false; }
|
|
if (CanDropNext) { return true; }
|
|
return false;
|
|
}
|
|
|
|
Vector3 FindPOIvector()
|
|
{
|
|
if (Type == 91)
|
|
{
|
|
if (npcs.Count == 0)
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
if (baseentitybe != null)
|
|
{
|
|
List<Vector3> addpos = new List<Vector3>();
|
|
for (int i = 0; i < _ServerSettings.PirateEventNPCAmount; i++) { addpos.Add(new Vector3(0, 2.1f, -13.1f)); }
|
|
npcs = plugin.CreateNPCs(_ServerSettings.PirateEventNPCAmount, 10, _ServerSettings.PirateBaseNPCHealth, _ServerSettings.PirateEventNPCKit, _ServerSettings.PirateEventNPCAimMulti, baseentitybe, addpos);
|
|
}
|
|
});
|
|
}
|
|
if (Vector3.Distance(movetopoint, plane.transform.position) < 10)
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
if (npcs != null && npcs.Count != 0 && plane != null)
|
|
{
|
|
foreach (ScientistNPC npc in npcs)
|
|
{
|
|
Vector3 pos = UnityEngine.Random.insideUnitCircle * 12;
|
|
plugin.AttachParachute(npc, baseentitybe.transform.position + new Vector3(pos.x, -10f, pos.y));
|
|
}
|
|
npcs.Clear();
|
|
}
|
|
});
|
|
return Retire();
|
|
}
|
|
return movetopoint;
|
|
}
|
|
if (DropHere(baseentitybe.transform.position) && movetopoint != Vector3.zero)
|
|
{
|
|
foreach (ScientistNPC npc in npcs)
|
|
{
|
|
Vector3 pos = UnityEngine.Random.insideUnitCircle * 12;
|
|
plugin.AttachParachute(npc, plane.transform.position + new Vector3(pos.x, -10f, pos.y));
|
|
}
|
|
npcs.Clear();
|
|
}
|
|
plugin.NextFrame(() =>
|
|
{
|
|
if (NPCDropsint > NPCDropped && npcs.Count == 0)
|
|
{
|
|
NPCDropped++;
|
|
npcs = plugin.CreateNPCs(NPCAmountint, 9, _ServerSettings.PirateFootNPCHealth, _ServerSettings.PirateFootNPCKit, _ServerSettings.PirateFootNPCAimMulti, baseentitybe, DropPos);
|
|
}
|
|
else if (NPCDropsint == NPCDropped) { Retire(); }
|
|
});
|
|
Vector3 droppoint = Vector3.zero;
|
|
if (droppoints == null || droppoints.Count == 0)
|
|
{
|
|
float bounds = (ConVar.Server.worldsize / 2) - 200;
|
|
float minx = bounds;
|
|
float maxx = bounds;
|
|
float minz = bounds;
|
|
float maxz = bounds;
|
|
float ran = UnityEngine.Random.Range(0, 2);
|
|
if (ran == 1) { minx = bounds; maxx = bounds; minz = 0; maxz = UnityEngine.Random.Range(0, bounds); }
|
|
if (ran == 0) { minz = bounds; maxz = bounds; minx = 0; maxx = UnityEngine.Random.Range(0, bounds); }
|
|
droppoint = new Vector3(UnityEngine.Random.Range(minx, maxx), flyheightfloat, UnityEngine.Random.Range(minz, maxz));
|
|
float x = UnityEngine.Random.Range(0, 2);
|
|
float z = UnityEngine.Random.Range(0, 2);
|
|
if (x == 1) { droppoint.x = -droppoint.x; }
|
|
if (z == 1) { droppoint.z = -droppoint.z; }
|
|
}
|
|
else
|
|
{
|
|
|
|
droppoint = droppoints.Keys.ToList().GetRandom();
|
|
if (droppoints[droppoint] == true) { CanDropNext = true; }
|
|
if (droppoints.Count == 1 && !droppoints.ContainsKey(new Vector3(9000, 900, 9000)))
|
|
{
|
|
droppoints.Add(new Vector3(9000, 900, 9000), false);
|
|
}
|
|
droppoints.Remove(droppoint);
|
|
}
|
|
droppoint.y = TerrainMeta.HeightMap.GetHeight(droppoint) + flyheightfloat;
|
|
return droppoint;
|
|
}
|
|
|
|
void FixedUpdate()
|
|
{
|
|
if (baseentitybe == null && plane == null) { OnDestroy(); return; }
|
|
if (baseentitybe.Distance2D(movetopoint) < 10f && !isRetiring) { movetopoint = FindPOIvector(); }
|
|
if (plugin.PointsOfIntrest.Count != 0)
|
|
{
|
|
if (NextPOITick < Time.time)
|
|
{
|
|
NextPOITick = Time.time + 10;
|
|
Vector3 POI = plugin.getPOIfunction(baseentitybe.transform.position, _ServerSettings.PiratesAirPOIRadius);
|
|
if (POI != Vector3.zero)
|
|
{
|
|
POI.y = TerrainMeta.HeightMap.GetHeight(POI) + _ServerSettings.PiratePlaneflyheight;
|
|
movetopoint = POI;
|
|
NextPOITick = Time.time + 120;
|
|
}
|
|
}
|
|
}
|
|
Vector3 targetDir = movetopoint - transform.position;
|
|
Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, 5f * Time.deltaTime, 0.0f);
|
|
Vector3 pos = Vector3.MoveTowards(baseentitybe.transform.position, movetopoint, flyspeedfloat * Time.deltaTime);
|
|
if (terraincheck < Time.time)
|
|
{
|
|
float terrainheight = TerrainMeta.HeightMap.GetHeight(plane.transform.position);
|
|
if (pos.y < terrainheight + flyheightfloat - 5) { pos.y += 2f; }
|
|
else if (pos.y > terrainheight + flyheightfloat + 5) { pos.y -= 2f; }
|
|
terraincheck = Time.time + 0.5f;
|
|
}
|
|
baseentitybe.transform.position = pos;
|
|
baseentitybe.transform.rotation = Quaternion.LookRotation(newDir);
|
|
plane.transform.position = baseentitybe.transform.position;
|
|
plane.transform.rotation = baseentitybe.transform.rotation;
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
if (plugin != null) { plugin.piratePlane--; }
|
|
if (plane != null && !plane.IsDestroyed) { plane.Kill(); }
|
|
if (baseentitybe != null && !baseentitybe.IsDestroyed) { baseentitybe.Kill(); }
|
|
}
|
|
}
|
|
|
|
public class BasePirate : MonoBehaviour
|
|
{
|
|
public int Type;
|
|
public BaseEntity _base;
|
|
public List<ScientistNPC> npcs;
|
|
public List<BaseEntity> entitys = new List<BaseEntity>();
|
|
public StorageContainer itembox;
|
|
|
|
private void Awake()
|
|
{
|
|
plugin.NextFrame(() =>
|
|
{
|
|
_base = GetComponent<BaseEntity>();
|
|
if (_base == null) { Die(); return; }
|
|
plugin.pirateBase++;
|
|
plugin.ClearAreafunction(_base.transform.position, _ServerSettings.PirateBaseWallRadius);
|
|
plugin.timer.Once(_ServerSettings.LeaveAfter, () => { if (_base != null) { CheckEmpty(); } });
|
|
plugin.timer.Once(10, () => { if (_base != null) { CheckLoot(); } });
|
|
plugin.PirateUintList.Add(_base.net.ID);
|
|
entitys.Add(_base);
|
|
entitys.AddRange(plugin.CreateWallsfunction(_base.transform.position, _ServerSettings.PirateBaseWallRadius));
|
|
CreateBase();
|
|
CreateStorage0();
|
|
plugin.NextFrame(() =>
|
|
{
|
|
if (itembox != null) { plugin.filllootfunction(itembox.inventory, -1, _ServerSettings.PirateBaseLootMulti, _ServerSettings.PirateBaseLootString); }
|
|
List<Vector3> pos = new List<Vector3>();
|
|
for (int i = 0; i < _ServerSettings.PirateBaseNPCAmount; i++) { pos.Add(_base.transform.position); }
|
|
npcs = plugin.CreateNPCs(_ServerSettings.PirateBaseNPCAmount, Type, _ServerSettings.PirateBaseNPCHealth, _ServerSettings.PirateBaseNPCKit, _ServerSettings.PirateBaseAimMulti, _base, pos);
|
|
if (npcs == null) { _base.Kill(); }
|
|
plugin.BaseParts.Add(itembox.net.ID);
|
|
plugin.timer.Once(1f, () =>
|
|
{
|
|
foreach (ScientistNPC npc in npcs) { plugin.BailOutfunction(_base.transform.position + new Vector3(0, 4, 0), npc, Vector3.zero, _ServerSettings.PirateBaseWallRadius - 3, 5.5f, false); }
|
|
foreach (BaseEntity be in entitys)
|
|
{
|
|
if (be == null || be.net == null) { continue; }
|
|
plugin.BaseParts.Add(be.net.ID);
|
|
}
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
private void CheckLoot()
|
|
{
|
|
if (_base != null && itembox != null)
|
|
{
|
|
plugin.timer.Once(10f, () => { try { CheckLoot(); } catch { } });
|
|
return;
|
|
}
|
|
CheckEmpty();
|
|
}
|
|
|
|
private void CreateBase()
|
|
{
|
|
var entity = GameManager.server.CreateEntity(floorprefab, _base.transform.position + new Vector3(0, 3.5f, 0), _base.transform.rotation);
|
|
if (entity == null) { return; }
|
|
entitys.Add(entity);
|
|
entity.Spawn();
|
|
entity.enableSaving = false;
|
|
entity.OwnerID = (ulong)UnityEngine.Random.Range(10000000, 20000000);
|
|
entity.SetParent(_base, true, true);
|
|
var buildingBlock = entity as BuildingBlock;
|
|
if (buildingBlock != null)
|
|
{
|
|
buildingBlock.SetGrade((BuildingGrade.Enum)4);
|
|
buildingBlock.grounded = true;
|
|
buildingBlock.AttachToBuilding(BuildingManager.server.NewBuildingID());
|
|
buildingBlock.health = buildingBlock.MaxHealth();
|
|
AttachParts(floorprefab, new Vector3(0f, 6, 0), entity.transform.rotation, buildingBlock);
|
|
AttachParts(foundationprefab, new Vector3(0f, 3, 0), entity.transform.rotation, buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(-1.5f, 0, 0), entity.transform.rotation * Quaternion.Euler(0, 180, 0), buildingBlock);
|
|
BaseEntity doorframe = AttachParts(wallframeprefab, new Vector3(-1.5f, 3, 0), entity.transform.rotation * Quaternion.Euler(0, 180, 0), buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(1.5f, 0, 0), entity.transform.rotation, buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(1.5f, 3, 0), entity.transform.rotation, buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(0f, 0, -1.5f), entity.transform.rotation * Quaternion.Euler(0, 90, 0), buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(0f, 3, -1.5f), entity.transform.rotation * Quaternion.Euler(0, 90, 0), buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(0f, 0, 1.5f), entity.transform.rotation * Quaternion.Euler(0, 270, 0), buildingBlock);
|
|
AttachParts(wallprefab, new Vector3(0f, 3, 1.5f), entity.transform.rotation * Quaternion.Euler(0, 270, 0), buildingBlock);
|
|
plugin.BaseParts.Add(plugin.CreateGarageDoorfunction(Vector3.zero, Vector3.zero, doorframe, 2433668609, entity.OwnerID, _ServerSettings.PirateBaseDoorHealth).net.ID);
|
|
BaseEntity lantern = GameManager.server.CreateEntity(lanternentityprefab, _base.transform.position + new Vector3(0, 9.6f, 0), _base.transform.rotation);
|
|
lantern.Spawn();
|
|
lantern.enableSaving = false;
|
|
lantern.OwnerID = entity.OwnerID;
|
|
lantern.SetFlag(BaseEntity.Flags.On, true);
|
|
entitys.Add(lantern);
|
|
plugin.BaseParts.Add(entity.net.ID);
|
|
}
|
|
}
|
|
|
|
private BaseEntity AttachParts(string prefab, Vector3 position, Quaternion rotation, BuildingBlock basepart)
|
|
{
|
|
var entity = GameManager.server.CreateEntity(prefab);
|
|
if (entity == null) { return null; }
|
|
entity.Spawn();
|
|
entity.enableSaving = false;
|
|
entitys.Add(entity);
|
|
entity.SetParent(basepart, false, true);
|
|
entity.OwnerID = basepart.OwnerID;
|
|
var buildingBlock = entity as BuildingBlock;
|
|
if (buildingBlock != null)
|
|
{
|
|
buildingBlock.SetGrade((BuildingGrade.Enum)3);
|
|
buildingBlock.grounded = true;
|
|
buildingBlock.AttachToBuilding(BuildingManager.server.NewBuildingID());
|
|
buildingBlock.health = buildingBlock.MaxHealth();
|
|
}
|
|
entity.transform.localPosition = position;
|
|
entity.transform.localRotation = rotation;
|
|
return entity;
|
|
}
|
|
|
|
private void CreateStorage0()
|
|
{
|
|
itembox = GameManager.server.CreateEntity(woodboxentityprefab, _base.transform.position + new Vector3(0, 6.5f, 0)) as StorageContainer;
|
|
plugin.DestroyGroundComp(itembox);
|
|
plugin.DestroyMeshCollider(itembox);
|
|
itembox.skinID = 931816387;
|
|
itembox.Spawn();
|
|
itembox.enableSaving = false;
|
|
itembox.inventory.capacity = 30;
|
|
itembox.SendNetworkUpdateImmediate();
|
|
plugin.AddLockfunction(itembox);
|
|
}
|
|
|
|
public void CheckEmpty()
|
|
{
|
|
if (_base == null) { return; }
|
|
if (!plugin.PlayersNearbyfunction(_base.transform.position, 25))
|
|
{
|
|
CancelInvoke("CheckEmpty");
|
|
ExplodeAndDestroy();
|
|
return;
|
|
}
|
|
Invoke("CheckEmpty", 15f);
|
|
}
|
|
|
|
public void ExplodeAndDestroy()
|
|
{
|
|
bool killquite = false;
|
|
if (itembox != null) { killquite = true; }
|
|
foreach (BaseEntity b in entitys)
|
|
{
|
|
if (!killquite) { plugin.Explodefunction(b); }
|
|
Invoke("Die", 5f);
|
|
}
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
try
|
|
{
|
|
enabled = false;
|
|
CancelInvoke();
|
|
if (plugin != null && this != null)
|
|
{
|
|
plugin.pirateBase--;
|
|
if (itembox != null && !itembox.IsDestroyed) { itembox.Kill(); }
|
|
if (entitys != null) { foreach (BaseEntity e in entitys) { if (e != null && !e.IsDestroyed) { e.transform.position = new Vector3(0, -501, 0); e.Kill(); } } }
|
|
if (npcs != null) { foreach (ScientistNPC npc in npcs) { if (npc != null && !npc.IsDestroyed && !npc.IsDead()) { if (npc.net != null) { plugin.NPCsUintList.Remove(npc.net.ID); plugin.GroundedNPCs.Remove(npc.net.ID); } npc.transform.position = new Vector3(0, -501, 0); npc.Kill(); } } }
|
|
}
|
|
}
|
|
catch { }
|
|
try { if (_base != null && !_base.IsDestroyed) { _base.Kill(); } } catch { }
|
|
}
|
|
|
|
public void Die() { if (this != null) { Destroy(this); } }
|
|
|
|
private void Explodevoid() { if (_base != null) { plugin.Explodefunction(_base); } }
|
|
}
|
|
#endregion
|
|
}
|
|
}
|