C#:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using UnityEngine;
using Random = System.Random;
namespace Oxide.Plugins
{
[Info("Barren Plus", "Iv Misticos", "1.0.6")]
[Description("Let JunkPiles and DiveSites be alive on Barren!")]
class BarrenPlus : RustPlugin
{
#region Variables
private int _size;
private readonly string[] _prefabsJunkPile = { "assets/prefabs/misc/junkpile_water/junkpile_water_a.prefab", "assets/prefabs/misc/junkpile_water/junkpile_water_b.prefab", "assets/prefabs/misc/junkpile_water/junkpile_water_c.prefab" };
private readonly string[] _prefabsDiveSite = { "assets/prefabs/misc/divesite/divesite_a.prefab", "assets/prefabs/misc/divesite/divesite_b.prefab", "assets/prefabs/misc/divesite/divesite_c.prefab" };
private static readonly Random Random = new Random();
#endregion
#region Configuration
private static Configuration _config = new Configuration();
private class Configuration
{
[JsonProperty(PropertyName = "Junk Pile Spawn Frequency")]
public float JunkPileTime = 30;
[JsonProperty(PropertyName = "Dive Site Spawn Frequency")]
public float DiveSiteTime = 45;
[JsonProperty(PropertyName = "Minimal Distance Between Junk Piles")]
public int JunkPileRange = 50;
[JsonProperty(PropertyName = "Minimal Distance Between Dive Sites")]
public int DiveSiteRange = 50;
[JsonProperty(PropertyName = "Minimal Distance Between Water And Terrain")]
public int BetweenWaterTerrain = 20;
[JsonProperty(PropertyName = "Maximal Dive Site Angle")]
public int AngleMax = 20;
[JsonProperty(PropertyName = "Dive Sites' Lifetime")]
public int DiveSiteLife = 600;
[JsonProperty(PropertyName = "Junk Piles' Lifetime")]
public int JunkPileLife = 300;
[JsonProperty(PropertyName = "Maximum Number Of Attempts To Find A Location")]
public int LocAttemptsMax = 500;
}
protected override void LoadConfig()
{
base.LoadConfig();
try
{
_config = Config.ReadObject<Configuration>();
if (_config == null) throw new Exception();
}
catch
{
PrintError("Your configuration file contains an error.Using default configuration values.");
LoadDefaultConfig();
}
}
protected override void LoadDefaultConfig() => _config = new Configuration();
protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Hooks
// ReSharper disable once UnusedMember.Local
private void OnServerInitialized()
{
LoadConfig();
_size = ConVar.Server.worldsize;
timer.Every(_config.DiveSiteTime, () =>
{
for (var i = 1; i < _config.LocAttemptsMax; i++)
{
if (SpawnDiveSite())
break;
}
});
timer.Every(_config.JunkPileTime, () =>
{
for (var i = 1; i < _config.LocAttemptsMax; i++)
{
if (SpawnJunkPileWater())
break;
}
});
}
#endregion
#region Helpers
private Vector3? GetPosition(bool onWater)
{
var x = Random.Next(-_size / 2, _size / 2);
var z = Random.Next(-_size / 2, _size / 2);
var v = new Vector3(x, 0, z);
var terrain = (int) TerrainMeta.HeightMap.GetHeight(v);
if (_config.BetweenWaterTerrain > -terrain)
return null;
v.y = onWater ? 0 : terrain;
return v;
}
private Quaternion GetRotation(bool isJunkPile)
{
return Quaternion.Euler(isJunkPile ? 0 : Random.Next(-_config.AngleMax, _config.AngleMax),
Random.Next(0, 360), isJunkPile ? 0 : Random.Next(-_config.AngleMax, _config.AngleMax));
}
private bool SpawnDiveSite()
{
var position = GetPosition(false);
if (position == null)
return false;
var ds = new List<DiveSite>();
Vis.Entities(position.Value, _config.DiveSiteRange, ds);
if (ds.Count > 0)
return false;
var entity =
GameManager.server.CreateEntity(_prefabsDiveSite[Random.Next(0, _prefabsDiveSite.Length - 1)],
position.Value, GetRotation(false)) as DiveSite;
if (entity == null) return true;
entity.gameObject.AddComponent<DiveSiteController>();
entity.Spawn();
return true;
}
private bool SpawnJunkPileWater()
{
var position = GetPosition(true);
if (position == null)
return false;
var jp = new List<JunkPileWater>();
Vis.Entities(position.Value, _config.JunkPileRange, jp);
if (jp.Count > 0)
return false;
var entity = GameManager.server.CreateEntity(_prefabsJunkPile[Random.Next(0, _prefabsJunkPile.Length - 1)],
position.Value, GetRotation(true)) as JunkPileWater;
if (entity == null) return true;
entity.gameObject.AddComponent<JunkPileWaterController>();
entity.Spawn();
return true;
}
#endregion
#region Controllers
public class DiveSiteController : MonoBehaviour
{
private float _lastTime = Time.realtimeSinceStartup;
private DiveSite _ent;
private bool _isDestroyed;
private void Awake()
{
_ent = gameObject.GetComponent<DiveSite>();
}
private void FixedUpdate()
{
if (_isDestroyed)
return;
var rt = Time.realtimeSinceStartup;
if (_lastTime + _config.DiveSiteLife > rt)
return;
_isDestroyed = true;
_ent.SinkAndDestroy();
}
}
public class JunkPileWaterController : MonoBehaviour
{
private float _lastTime = Time.realtimeSinceStartup;
private JunkPileWater _ent;
private bool _isDestroyed;
private void Awake()
{
_ent = gameObject.GetComponent<JunkPileWater>();
}
private void FixedUpdate()
{
if (_isDestroyed)
return;
var rt = Time.realtimeSinceStartup;
if (_lastTime + _config.JunkPileLife > rt)
return;
_isDestroyed = true;
_ent.SinkAndDestroy();
}
}
#endregion
}
}