2021-06-18 07:23:41 -07:00
using Newtonsoft.Json ;
2021-07-03 18:12:19 -07:00
using System.Collections ;
2021-06-18 07:23:41 -07:00
using System.Collections.Generic ;
2021-07-03 18:12:19 -07:00
using System.Linq ;
2021-06-18 07:23:41 -07:00
using UnityEngine ;
namespace Oxide.Plugins
{
2021-07-31 19:43:48 -07:00
[Info("BCargo", "bmgjet", "1.0.4")]
2021-06-18 07:23:41 -07:00
[Description("Allows inland cargoship by blocking egress while building blocked, Sets Cargo Spawn point to stop it running though islands coming in, Cargo auto heights for tides support")]
class BCargo : RustPlugin
{
public Timer CargoCheck ;
private PluginConfig config ;
2021-07-03 18:12:19 -07:00
private Vector3 randompoint ;
private Dictionary < int , Vector3 > CargoBlockPoint ;
private Coroutine _routine ;
private Dictionary < BasePlayer , Dictionary < bool , ulong > > Viewers = new Dictionary < BasePlayer , Dictionary < bool , ulong > > ( ) ;
2021-06-18 07:23:41 -07:00
private const string permAdmin = "BCargo.admin" ;
#region Load
private void Init ( )
{
permission . RegisterPermission ( permAdmin , this ) ;
config = Config . ReadObject < PluginConfig > ( ) ;
if ( config = = null )
{
LoadDefaultConfig ( ) ;
}
2021-07-03 18:12:19 -07:00
CargoBlockPoint = config . CargoBlockPoint ;
2021-06-18 07:23:41 -07:00
}
private void Unload ( )
{
2021-06-18 19:47:47 -07:00
if ( CargoCheck ! = null )
{
CargoCheck . Destroy ( ) ;
CargoCheck = null ;
2021-06-18 07:23:41 -07:00
}
2021-07-03 18:12:19 -07:00
if ( _routine ! = null )
{
try
{
ServerMgr . Instance . StopCoroutine ( _routine ) ;
foreach ( KeyValuePair < BasePlayer , Dictionary < bool , ulong > > viewer in Viewers )
{
message ( viewer . Key , "View" , "Stopped" ) ;
}
}
catch { }
_routine = null ;
}
2021-06-18 07:23:41 -07:00
}
#endregion
#region Configuration
private class PluginConfig
{
[JsonProperty(PropertyName = "Override random cargo spawn point : ")] public bool SpawnAtDefined { get ; set ; }
[JsonProperty(PropertyName = "Defined Spawn Point for Cargo : ")] public Vector3 CargoSpawnLocation { get ; set ; }
2021-07-03 18:12:19 -07:00
[JsonProperty(PropertyName = "Defined Block Points for Cargo : ")] public Dictionary < int , Vector3 > CargoBlockPoint { get ; set ; }
[JsonProperty(PropertyName = "Distance from block point before allowing leave : ")] public float LeaveBlockDistance { get ; set ; }
2021-06-18 07:23:41 -07:00
[JsonProperty(PropertyName = "Seconds between recheck if can leave : ")] public float ReCheckDelay { get ; set ; }
[JsonProperty(PropertyName = "Enable auto leveling for tides plugin : ")] public bool Tides { get ; set ; }
[JsonProperty(PropertyName = "Show debug in console : ")] public bool Debug { get ; set ; }
}
private PluginConfig GetDefaultConfig ( )
{
return new PluginConfig
{
SpawnAtDefined = false ,
2021-07-03 18:12:19 -07:00
CargoSpawnLocation = randompoint ,
CargoBlockPoint = new Dictionary < int , Vector3 > { { 0 , randompoint } } ,
LeaveBlockDistance = 120 ,
2021-06-18 19:47:47 -07:00
ReCheckDelay = 10 ,
2021-06-18 07:23:41 -07:00
Tides = false ,
Debug = false
} ;
}
protected override void LoadDefaultConfig ( )
{
Config . Clear ( ) ;
2021-07-03 18:12:19 -07:00
randompoint = DefaultRandomPos ( ) ;
2021-06-18 07:23:41 -07:00
Config . WriteObject ( GetDefaultConfig ( ) , true ) ;
2021-06-18 19:47:47 -07:00
config = Config . ReadObject < PluginConfig > ( ) ;
2021-06-18 07:23:41 -07:00
}
protected override void SaveConfig ( )
{
Config . WriteObject ( config , true ) ;
}
#endregion
#region Localization
protected override void LoadDefaultMessages ( )
{
lang . RegisterMessages ( new Dictionary < string , string >
{
["notallowed"] = "You are not authorized to do that." ,
["reloaded"] = "Settings reloaded!" ,
2021-07-31 19:43:48 -07:00
["reset"] = "Settings file reset to default!" ,
2021-07-03 18:12:19 -07:00
["saved"] = "Settings saved!" ,
["View"] = "{0} BCargo view!" ,
["added"] = "Node {0} added!" ,
["removed"] = "Node {0} removed!" ,
["spawnstatus"] = "{0} BCargo Manaul Spawn Overide" ,
["spawnlocation"] = "Set Cargoships spawn location to {0}" ,
["help"] = "<color=orange>Help:</color>\n\n/bcargo spawn = Sets spawn location of cargo.\n/bcargo spawn on = Enables manual spawn point.\n/bcargo spawn off = Disables manual spawn point.\n\n/bcargo add = Adds a block zone.\n/bcargo remove 0 = Removes last placed block zone\n/bcargo remove x = Removes node numbered X\n/bcargo view = Shows current block points in red and default cargo path in blue.\n\n/bcargo save = Saves changes\n/bcargo reload = Reloads config file\n/bcargo debug on = Shows console debug info\n/bcargo blocked = Prints back if cargo would be blocked here" ,
["args"] = "You havnt provided the correct args type /bcargo help!"
2021-06-18 07:23:41 -07:00
} , this ) ;
}
2021-07-03 18:12:19 -07:00
private void message ( BasePlayer chatplayer , string key , params object [ ] args )
{
if ( chatplayer = = null & & ! chatplayer . IsConnected ) { return ; }
var message = string . Format ( lang . GetMessage ( key , this , chatplayer . UserIDString ) , args ) ;
chatplayer . ChatMessage ( message ) ;
}
2021-06-18 07:23:41 -07:00
#endregion
#region Hooks
private object OnCargoShipEgress ( CargoShip cs )
{
2021-06-18 19:47:47 -07:00
if ( cs ! = null )
2021-06-18 07:23:41 -07:00
{
2021-06-18 19:47:47 -07:00
bool BlockEgress = false ;
2021-07-31 19:43:48 -07:00
BlockEgress = BlockE ( cs . transform . position ) ;
//Old Method
//BlockEgress = GamePhysics.CheckSphere(cs.transform.position, config.LeaveBlockDistance, LayerMask.GetMask("Prevent Building"), QueryTriggerInteraction.Collide); //Check if in building block.
2021-06-18 19:47:47 -07:00
if ( BlockEgress )
{
Timer CheckEgress = timer . Once ( config . ReCheckDelay , ( ) = > { cs . StartEgress ( ) ; } ) ;
2021-07-03 18:12:19 -07:00
if ( config . Debug ) Puts ( "Cargo Blocked!" ) ;
2021-06-18 19:47:47 -07:00
return true ;
}
2021-07-03 18:12:19 -07:00
if ( config . Debug ) Puts ( "Cargo Allowed" ) ;
2021-07-31 19:43:48 -07:00
if ( CargoCheck ! = null )
{
CargoCheck . Destroy ( ) ;
2021-07-03 18:12:19 -07:00
}
2021-06-18 07:23:41 -07:00
}
return null ;
}
void OnEntitySpawned ( CargoShip cs )
{
if ( cs ! = null )
{
2021-06-18 19:47:47 -07:00
if ( config . SpawnAtDefined ) { cs . transform . position = DefaultRandomPos ( true ) ; }
2021-06-18 07:23:41 -07:00
if ( config . Tides ) //Changes cargoship height to match tide level.
{
2021-06-18 19:47:47 -07:00
CargoCheck = timer . Every ( config . ReCheckDelay , ( ) = >
{
if ( cs ! = null & & config . Tides )
2021-06-18 07:23:41 -07:00
{
2021-06-18 19:47:47 -07:00
Vector3 CurrentPos = cs . transform . position ;
if ( CurrentPos . y ! = WaterLevel ( config . CargoSpawnLocation ) )
2021-06-18 07:23:41 -07:00
{
2021-06-18 19:47:47 -07:00
CurrentPos . y = WaterLevel ( config . CargoSpawnLocation ) ;
cs . transform . position = CurrentPos ;
if ( config . Debug ) Puts ( "Adjusting Cargo Height To Match Water Level!" ) ;
2021-06-18 07:23:41 -07:00
}
2021-06-18 19:47:47 -07:00
}
else
{
if ( CargoCheck ! = null )
2021-06-18 07:23:41 -07:00
{
2021-06-18 19:47:47 -07:00
CargoCheck . Destroy ( ) ;
CargoCheck = null ;
2021-06-18 07:23:41 -07:00
}
2021-06-18 19:47:47 -07:00
}
} ) ;
2021-06-18 07:23:41 -07:00
}
}
}
#endregion
2021-07-03 18:12:19 -07:00
#region Bcargo
public Vector3 DefaultRandomPos ( bool NotRandom = false )
2021-06-18 07:23:41 -07:00
{
2021-07-03 18:12:19 -07:00
Vector3 vector = TerrainMeta . RandomPointOffshore ( ) ;
if ( NotRandom ) vector = config . CargoSpawnLocation ;
vector . y = WaterLevel ( vector ) ;
return vector ;
}
2021-07-31 19:43:48 -07:00
private void showonscreen ( BasePlayer player , string key , Vector3 value , Color c , bool nameonly = false )
2021-07-03 18:12:19 -07:00
{
if ( ! nameonly )
2021-07-31 19:43:48 -07:00
player . SendConsoleCommand ( "ddraw.sphere" , 8f , c , value , config . LeaveBlockDistance ) ;
2021-07-03 18:12:19 -07:00
player . SendConsoleCommand ( "ddraw.text" , 8f , c , value , "<size=22> Node:" + key + " </size>" ) ;
}
private void viewcsnodes ( BasePlayer player )
{
//Shows map placed cargo nodes
for ( int i = 0 ; i < global :: TerrainMeta . Path . OceanPatrolFar . Count ; i + + )
2021-06-18 07:23:41 -07:00
{
2021-07-31 19:43:48 -07:00
showonscreen ( player , i . ToString ( ) , TerrainMeta . Path . OceanPatrolFar [ i ] , Color . blue , true ) ;
2021-06-18 07:23:41 -07:00
}
}
2021-07-03 18:12:19 -07:00
private void view ( BasePlayer player )
2021-06-18 07:23:41 -07:00
{
2021-07-31 19:43:48 -07:00
if ( CargoBlockPoint = = null )
return ;
2021-07-03 18:12:19 -07:00
foreach ( KeyValuePair < int , Vector3 > point in CargoBlockPoint )
2021-06-18 07:23:41 -07:00
{
2021-07-03 18:12:19 -07:00
try
{
2021-07-31 19:43:48 -07:00
showonscreen ( player , point . Key . ToString ( ) , point . Value , Color . red ) ;
2021-07-03 18:12:19 -07:00
}
catch { }
}
}
2021-07-31 19:43:48 -07:00
2021-07-03 18:12:19 -07:00
private void CheckIfViewed ( )
{
if ( Viewers . Count = = 0 ) //If no viewers left remove routine
{
ServerMgr . Instance . StopCoroutine ( _routine ) ;
_routine = null ;
Puts ( "BCargo View Thread Stopped!" ) ;
}
}
2021-07-31 19:43:48 -07:00
2021-07-03 18:12:19 -07:00
IEnumerator BCargoView ( )
{
do //start loop
{
foreach ( KeyValuePair < BasePlayer , Dictionary < bool , ulong > > viewer in Viewers . ToList ( ) )
{
foreach ( KeyValuePair < bool , ulong > viewerinfo in viewer . Value . ToList ( ) )
{
//toggle admin flag so you can show a normal user with out it auto banning them for cheating
if ( ! viewerinfo . Key )
{
viewer . Key . SetPlayerFlag ( BasePlayer . PlayerFlags . IsAdmin , true ) ;
viewer . Key . SendNetworkUpdateImmediate ( ) ;
}
view ( viewer . Key ) ;
viewcsnodes ( viewer . Key ) ;
if ( ! viewerinfo . Key & & viewer . Key . HasPlayerFlag ( BasePlayer . PlayerFlags . IsAdmin ) )
{
viewer . Key . SetPlayerFlag ( BasePlayer . PlayerFlags . IsAdmin , false ) ;
viewer . Key . SendNetworkUpdateImmediate ( ) ;
}
}
2021-07-31 19:43:48 -07:00
2021-07-03 18:12:19 -07:00
if ( ! viewer . Key . IsConnected | | viewer . Key . IsSleeping ( ) )
{
//Remove from viewers list
Viewers . Remove ( viewer . Key ) ;
message ( viewer . Key , "View" , "Stopped" ) ;
}
}
yield return CoroutineEx . waitForSeconds ( 8f ) ;
} while ( Viewers . Count ! = 0 ) ;
_routine = null ;
Puts ( "BCargo View Thread Stopped!" ) ;
}
public void CargoView ( BasePlayer player )
{
if ( _routine ! = null ) //Check if already running
{
if ( Viewers . ContainsKey ( player ) )
{
Viewers . Remove ( player ) ; //Remove player from list
message ( player , "View" , "Stopped" ) ;
CheckIfViewed ( ) ;
return ;
}
}
2021-07-31 19:43:48 -07:00
if ( ! Viewers . ContainsKey ( player ) )
{
Viewers . Add ( player , new Dictionary < bool , ulong > { { player . IsAdmin , 0 } } ) ;
}
2021-07-03 18:12:19 -07:00
if ( _routine = = null ) //Start routine
{
Puts ( "BCargo View Thread Started" ) ;
_routine = ServerMgr . Instance . StartCoroutine ( BCargoView ( ) ) ;
}
}
public void CargoPoints ( BasePlayer player , Vector3 location )
{
2021-07-31 22:35:29 -07:00
int node = 0 ;
try { node = CargoBlockPoint . Keys . Last ( ) + 1 ; }
catch { }
2021-07-03 18:12:19 -07:00
CargoBlockPoint . Add ( node , location ) ;
message ( player , "added" , node ) ;
}
public bool BlockE ( Vector3 currentlocation )
{
//checks each point to see if cargo is within area.
2021-07-31 22:35:29 -07:00
if ( CargoBlockPoint = = null )
{
return false ;
}
2021-07-03 18:12:19 -07:00
foreach ( KeyValuePair < int , Vector3 > blockpoints in CargoBlockPoint )
{
if ( Vector3 . Distance ( currentlocation , blockpoints . Value ) < config . LeaveBlockDistance )
return true ;
}
return false ;
}
2021-07-31 19:43:48 -07:00
public float WaterLevel ( Vector3 Pos )
{
return TerrainMeta . WaterMap . GetHeight ( Pos ) ;
}
2021-07-03 18:12:19 -07:00
#endregion
#region ChatCommands
[ChatCommand("bcargo")]
private void CmdPositionCheck ( BasePlayer player , string command , string [ ] args )
{
if ( ! player . IPlayer . HasPermission ( permAdmin ) )
{
message ( player , "notallowed" ) ;
return ;
}
if ( args . Length < 1 )
{
message ( player , "args" ) ;
return ;
}
Vector3 NewCargoPos = player . transform . position ;
NewCargoPos . y = WaterLevel ( NewCargoPos ) ;
switch ( args [ 0 ] )
{
case "spawn" : //Sets manual spawn point or enable/disable manual spawn point
if ( args . Length = = 2 )
{
if ( args [ 1 ] . ToLower ( ) . Contains ( "on" ) )
{
message ( player , "spawnstatus" , "Enabled" ) ;
config . SpawnAtDefined = true ;
}
else if ( args [ 1 ] . ToLower ( ) . Contains ( "off" ) )
{
message ( player , "spawnstatus" , "Disabled" ) ;
config . SpawnAtDefined = false ;
}
return ;
}
//Updates node 0 to spawn point
if ( CargoBlockPoint . ContainsKey ( 0 ) )
{
CargoBlockPoint [ 0 ] = NewCargoPos ;
}
else
{
CargoBlockPoint . Add ( 0 , NewCargoPos ) ;
}
config . CargoSpawnLocation = NewCargoPos ;
SaveConfig ( ) ;
message ( player , "spawnlocation" , config . CargoSpawnLocation . ToString ( ) ) ;
return ;
case "add" : //Adds a cargo leave block point
2021-07-31 19:43:48 -07:00
CargoPoints ( player , NewCargoPos ) ;
2021-07-03 18:12:19 -07:00
break ;
2021-07-31 19:43:48 -07:00
2021-07-03 18:12:19 -07:00
case "remove" : //Removes a cargo leave block point
if ( args . Length ! = 2 )
{
message ( player , "args" ) ;
return ;
}
int node = 0 ;
try
{
node = int . Parse ( args [ 1 ] ) ; //try catch incase users try to use letters.
}
catch { }
if ( CargoBlockPoint . ContainsKey ( node ) & & node ! = 0 ) //If valid node point selected remove
{
CargoBlockPoint . Remove ( node ) ;
message ( player , "removed" , node ) ;
break ;
}
node = CargoBlockPoint . Keys . Last ( ) ; //Other wise remove last node added.
CargoBlockPoint . Remove ( node ) ;
message ( player , "removed" , node ) ;
break ;
case "debug" : //Shows console debug
if ( args . Length = = 2 )
{
if ( args [ 1 ] . ToLower ( ) . Contains ( "on" ) )
{
config . Debug = true ;
Puts ( "Debug mode on!" ) ;
}
else
{
config . Debug = false ;
Puts ( "Debug mode off!" ) ;
}
}
return ;
case "reload" :
config = Config . ReadObject < PluginConfig > ( ) ;
CargoBlockPoint = config . CargoBlockPoint ;
message ( player , "reloaded" ) ;
return ;
2021-07-31 19:43:48 -07:00
case "reset" :
LoadDefaultConfig ( ) ;
message ( player , "reloaded" ) ;
return ;
2021-07-03 18:12:19 -07:00
case "save" :
config . CargoBlockPoint = CargoBlockPoint ;
SaveConfig ( ) ;
message ( player , "saved" ) ;
return ;
case "view" :
CargoView ( player ) ;
break ;
case "blocked" :
player . ChatMessage ( BlockE ( player . transform . position ) . ToString ( ) ) ;
return ;
default :
message ( player , "help" ) ;
return ;
2021-06-18 07:23:41 -07:00
}
2021-07-03 18:12:19 -07:00
view ( player ) ; //Tempory show node changes.
2021-06-18 07:23:41 -07:00
}
#endregion
}
}