C#:
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("SpawnCyclesV2", "UrbanViking", "1.2.0")]
[Description("Allows admin to set PvP spawn points with random or set teleportation options.")]
public class SpawnCyclesV2 : RustPlugin
{
private ConfigData configData;
private Vector3 pvpSpawnCenter = Vector3.zero;
private Dictionary<string, int> playerSpawnCycleIndex = new Dictionary<string, int>();
#region Configuration
private class ConfigData
{
public string GoPvpCommand = "gopvp";
public string SetPvpSpawnCommand = "setpvpspawns";
public string SetPvpLocationCommand = "setpvp";
public float SpawnRadius = 150f;
public string[] ActiveHours = { "0", "23" };
public Dictionary<string, bool> BlacklistedPlayers = new Dictionary<string, bool>();
public bool TeleportEnabled = true;
public bool TpRandom = true;
public List<Vector3> TpSetLocations = new List<Vector3>();
}
protected override void LoadDefaultConfig() => configData = new ConfigData();
protected override void LoadConfig()
{
base.LoadConfig();
configData = Config.ReadObject<ConfigData>();
playerSpawnCycleIndex.Clear(); // Clear any stored indexes when loading config
SaveConfig();
}
protected override void SaveConfig()
{
configData.TpSetLocations = configData.TpSetLocations;
Config.WriteObject(configData);
}
#endregion
#region Commands
[ChatCommand("setpvpspawns")]
private void CmdSetPvpSpawn(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
pvpSpawnCenter = player.transform.position;
player.ChatMessage("PvP spawn center has been set to your current location.");
}
[ChatCommand("setpvp")]
private void CmdAddPvpLocation(BasePlayer player, string command, string[] args)
{
if (!player.IsAdmin) return;
configData.TpSetLocations.Add(player.transform.position);
player.ChatMessage("Added a new PvP spawn location.");
SaveConfig();
}
[ChatCommand("gopvp")]
private void CmdGoPvp(BasePlayer player, string command, string[] args)
{
if (!configData.TeleportEnabled) return;
if (configData.BlacklistedPlayers.ContainsKey(player.UserIDString)) return;
// Check if current time falls within the active hours
var now = DateTime.Now;
if (!IsWithinActiveHours(now))
{
player.ChatMessage("Teleport is not active at this time.");
return;
}
if (configData.TpRandom)
{
if (configData.TpSetLocations.Count > 0)
{
var randomIndex = UnityEngine.Random.Range(0, configData.TpSetLocations.Count);
player.Teleport(configData.TpSetLocations[randomIndex]);
}
else if (pvpSpawnCenter != Vector3.zero)
{
var randomSpot = GetRandomPointNear(pvpSpawnCenter, configData.SpawnRadius);
player.Teleport(randomSpot);
}
else
{
player.ChatMessage("No spawn points have been set.");
return;
}
}
else if (configData.TpSetLocations.Any())
{
// Cycle through set spawns
int index;
if (!playerSpawnCycleIndex.TryGetValue(player.UserIDString, out index))
{
index = 0;
}
index = index % configData.TpSetLocations.Count;
player.Teleport(configData.TpSetLocations[index]);
playerSpawnCycleIndex[player.UserIDString] = index + 1;
}
else
{
player.ChatMessage("No set spawn points available for cycling.");
}
}
#endregion
#region Helper Methods
private bool IsWithinActiveHours(DateTime now)
{
var start = Convert.ToInt32(configData.ActiveHours[0]);
var end = Convert.ToInt32(configData.ActiveHours[1]);
return now.Hour >= start && now.Hour <= end;
}
private Vector3 GetRandomPointNear(Vector3 center, float radius)
{
var randomDirection = UnityEngine.Random.insideUnitSphere * radius;
randomDirection.y = Mathf.Max(randomDirection.y, 0); // Ensure y is not below ground
return center + randomDirection;
}
#endregion
#region Admin Commands
[ConsoleCommand("spawncyclesv2.blacklist")]
private void ccBlacklistPlayer(ConsoleSystem.Arg arg)
{
if (arg.Args == null || arg.Args.Length < 1) return;
if (!arg.IsAdmin) return;
var playerId = arg.Args[0];
configData.BlacklistedPlayers[playerId] = true;
SaveConfig();
}
[ConsoleCommand("spawncyclesv2.unblacklist")]
private void ccUnblacklistPlayer(ConsoleSystem.Arg arg)
{
if (arg.Args == null || arg.Args.Length < 1) return;
if (!arg.IsAdmin) return;
var playerId = arg.Args[0];
configData.BlacklistedPlayers.Remove(playerId);
SaveConfig();
}
#endregion
}
}