C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
// Requires: GameModeManager
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Recoil Training Ground", "Amino", "0.4.2")]
[Description("Practice and improve your aim on stationary and moving targets provided with a recoil pattern display of your spray.")]
public class RecoilTrainingGround : RustPlugin, GameModeManager.IAdvancedLobby
{
private static GameModeManager _arena;
public static RecoilTrainingGround _instance;
private const string onShotRecordHook = "OnRecoilRecorded";
private bool _isInitialized;
private Configuration _config;
private DynamicConfigFile _dataManager;
private PluginData _pluginData;
private AdvancedTrainingArenaData _arenaToEdit;
private Dictionary<ulong, AdvancedTrainingPlayer> _players = new Dictionary<ulong, AdvancedTrainingPlayer>();
private Dictionary<int, AdvancedTrainingArena> _arenas { get; set; } = new Dictionary<int, AdvancedTrainingArena>();
public string _patternUiContainer = "recoiltrainingground.container";
public const string _patternUi = "recoiltrainingground.pattern";
private const float _ShotingCooldown = 1f;
public static string _mainPanelJson;
public const int _patternStartY = -20;
public const int _patternYOffset = -6;
public const int _patternPanelSizeY = 220;
public const int _patternPanelSizeX = 150;
private const int _border = 135;
float _velocity;
bool _clearedShots = false;
//List<Vector3> angleVectors = new List<Vector3>();
int shotIndex = 0;
#region Classes
public class AdvancedTrainingPlayerStats : GameModeManager.PlayerStatistics
{
public AdvancedTrainingPlayerStats(BasePlayer player) : base(player)
{
}
public int Shots { get; set; }
public int Hits { get; set; }
public int Headshots { get; set; }
public int BulletsFired { get; set; }
public override void Reset()
{
base.Reset();
Hits = 0;
Headshots = 0;
BulletsFired = 0;
Shots = 0;
}
}
#region Config
public class Configuration
{
[JsonProperty("Symbol - Original Weapon Pattern")]
public string PatternSymbol { get; set; } = "⦿";
[JsonProperty("Symbol - Hit")]
public string HitSymbol { get; set; } = "⦿";
[JsonProperty("Symbol - Miss")]
public string MissSymbol { get; set; } = "⦿";
[JsonProperty("Color - Original Weapon Pattern")]
public string PatternColor { get; set; } = "#ffffff";
[JsonProperty("Color - Hit")]
public string HitColor { get; set; } = "#00ff00";
[JsonProperty("Color - Miss")]
public string MissColor { get; set; } = "#ff0000";
[JsonProperty("Font - Original Weapon Pattern")]
public int PatternFont { get; set; } = 10;
[JsonProperty("Font - Hit")]
public int HitFont { get; set; } = 10;
[JsonProperty("Font - Miss")]
public int MissFont { get; set; } = 10;
[JsonProperty("Hit - Max Tolerance")]
public int HitMaxTolerance { get; set; } = 10;
[JsonProperty(PropertyName = "Bots List")]
public List<Bot> Bots { get; set; } = new List<Bot>();
}
public class Bot
{
[JsonProperty(PropertyName = "Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Loadout")]
public string Loadout { get; set; }
[JsonProperty(PropertyName = "Minimum Movement Speed")]
public float MinimumMovementSpeed { get; set; }
[JsonProperty(PropertyName = "Maximum Movement Speed")]
public float MaximumMovementSpeed { get; set; }
[JsonProperty(PropertyName = "Restrict To Named Spawn Point")]
public bool RestrictToNamedSpawnPoint { get; set; }
[JsonProperty(PropertyName = "Infinitive Health")]
public bool InfinitiveHealth { get; set; }
}
#endregion Config
#region Data
public class AdvancedTrainingArenaData : GameModeManager.ArenaData
{
[JsonProperty(PropertyName = "Entrance Point - Display Text", Order = 16)]
public string EntranceDisplayText { get; set; } = "$.Name";
[JsonProperty(PropertyName = "Player Loadout", Order = 19)]
public string PlayerLoadout { get; set; } = "";
[JsonProperty(PropertyName = "Player Spawn Location", Order = 20)]
public Vector3 PlayerSpawnLocation { get; set; } = Vector3.zero;
[JsonProperty(PropertyName = "Performance Mode - Enabled", Order = 21)]
public bool PerformanceMode { get; set; }//TODO: Set by commands
[JsonProperty(PropertyName = "Bots", Order = 22)]
public List<BotData> Bots { get; set; } = new List<BotData>();
[JsonProperty(PropertyName = "Spawn Points", Order = 23)]
public HashSet<ArenaSpawnData> SpawnLocations { get; set; } = new HashSet<ArenaSpawnData>();
}
public class BotData
{
[JsonProperty(PropertyName = "Bot Name")]
public string Name { get; set; }
[JsonProperty(PropertyName = "Bot Count")]
public int Count { get; set; }
}
public class ArenaSpawnData : GameModeManager.BaseSpawnData
{
[JsonProperty(PropertyName = "Spawn - Bot Name", Order = 1)]
public string BotName { get; set; }
public override bool Equals(object obj)
{
var spawnData = obj as ArenaSpawnData;
if (spawnData == null)
{
return false;
}
return spawnData.Name.Equals(Name, StringComparison.OrdinalIgnoreCase);
}
public override int GetHashCode()
{
return Name.ToLower().GetHashCode();
}
}
public class AttachmentData
{
[JsonProperty(PropertyName = "Item Short Name")]
public string ItemShortName { get; set; } = "";
}
public class RecoilData
{
[JsonProperty(PropertyName = "Weapon Short Name")]
public string WeaponName { get; set; } = "";
[JsonProperty(PropertyName = "Attachments")]
public List<AttachmentData> Attachments { get; set; } = new List<AttachmentData>();
[JsonProperty(PropertyName = "Recoil Points")]
public List<int> RecoilPoints { get; set; } = new List<int>();
public override bool Equals(object obj)
{
var targetData = obj as RecoilData;
if (targetData == null || string.IsNullOrEmpty(targetData.WeaponName))
return false;
//if (Attachements.Any() && targetData.Attachements.Any())
//{
var currentAttachments = Attachments.Any() ? Attachments.Select(a => a.ItemShortName).Aggregate((a1, a2) => $"{a1}-{a2}") : "";
currentAttachments = $"{currentAttachments}-{WeaponName}";
var targetAttachments = targetData.Attachments.Any() ? targetData.Attachments.Select(a => a.ItemShortName).Aggregate((a1, a2) => $"{a1}-{a2}") : "";
targetAttachments = $"{targetAttachments}-{targetData.WeaponName}";
return currentAttachments.ToLower() == targetAttachments.ToLower();
//}
//if (!string.IsNullOrEmpty(WeaponName) && !string.IsNullOrEmpty(targetData.WeaponName))
// return WeaponName.ToLower() == targetData.WeaponName.ToLower();
//return false;
}
public override int GetHashCode()
{
if (!Attachments.Any())
return WeaponName.GetHashCode();
var currentAttachments = Attachments.Select(a => a.ItemShortName).Aggregate((a1, a2) => $"{a1}-{a2}");
currentAttachments = $"{currentAttachments}-{WeaponName}";
return currentAttachments.GetHashCode();
}
}
public class PluginData
{
[JsonProperty(PropertyName = "Recoils")]
public List<RecoilData> Recoils { get; set; } = new List<RecoilData>();
[JsonProperty(PropertyName = "Arenas")]
public List<AdvancedTrainingArenaData> Arenas { get; set; } = new List<AdvancedTrainingArenaData>();
}
#endregion Data
#region Behaviours
private class ShotRecorderBehaviour : MonoBehaviour
{
private List<int> _shots = new List<int>();
private BaseProjectile _lastWeapon;
private BasePlayer _player;
private AdvancedTrainingPlayer matchPlayer;
private float _firstShot = 0;
private float _lastShotTime;
public RecoilData RecoilPattern = new RecoilData();
private int[] Shots => _shots.ToArray();
private void Awake()
{
_player = GetComponent<BasePlayer>();
_instance._players.TryGetValue(_player.userID, out matchPlayer);
}
private void Start()
{
InvokeRepeating(nameof(CheckPlayer), 60, 60);
Enable();
}
public void Enable()
{
CuiHelper.DestroyUi(_player, _instance._patternUiContainer);
CuiHelper.AddUi(_player, _mainPanelJson);
Awake();
}
public void Disable()
{
CuiHelper.DestroyUi(_player, _instance._patternUiContainer);
}
private void OnDestroy()
{
Disable();
}
public void OnFired(BaseProjectile weapon)
{
CheckWeapon(weapon);
RecordShot();
_instance._clearedShots = false;
var didHit = false;
var index = _shots.Count - 1;
var shotX = _shots[index];
if (RecoilPattern == null || RecoilPattern.RecoilPoints.Count < _shots.Count)
{
return;
}
var patternX = -RecoilPattern.RecoilPoints[index];
if (Math.Abs(shotX) < _instance._config.HitMaxTolerance)
{
shotX = patternX;
didHit = true;
}
_lastShotTime = Time.realtimeSinceStartup;
ShowShot(_player, shotX, index, didHit);
ShowScores(matchPlayer);
}
public void OnReloaded()
{
Interface.Call(onShotRecordHook, _player, Shots, RecoilPattern);
_shots.Clear();
ShowPattern(_player, RecoilPattern);
}
private void RecordShot()
{
var current = _player.eyes.rotation.eulerAngles.y;
var value = 0f;
if (_shots.Count == 0)
{
_firstShot = current;
_shots.Add(0);
return;
}
if (_firstShot > _border)
{
if (current < _border)
{
value = 360 - _firstShot + current;
}
else
{
value = current - _firstShot;
}
}
else
{
if (current > _border)
{
value = -(360 - current);
}
else
{
value = current - _firstShot;
}
}
value *= 10;
_shots.Add(Convert.ToInt32(value));
}
private void CheckWeapon(BaseProjectile weapon)
{
if (_lastWeapon != weapon)
{
_lastWeapon = weapon;
RecoilPattern = _instance._pluginData.Recoils.FirstOrDefault(r => r.Equals(_instance.GetPlayerRecoilData(weapon.GetOwnerPlayer())));
if (RecoilPattern == null)
{
RecoilPattern = new RecoilData();
}
ClearShots();
return;
}
if (weapon != null && _shots.Count >= weapon.primaryMagazine.capacity)
{
ClearShots();
return;
}
}
void Update()
{
if (Time.realtimeSinceStartup > _lastShotTime + _ShotingCooldown && !_instance._clearedShots)
{
_instance._clearedShots = true;
ClearShots();
}
}
private void ClearShots()
{
_shots.Clear();
ShowPattern(_player, RecoilPattern);
}
private void CheckPlayer()
{
if (_player.IsConnected == false)
{
Destroy(this);
}
}
}
public class BotPlayer : MonoBehaviour
{
private Vector3 _moveTo;
private Vector3 _moveFrom;
private float _timeToTravel;
private float _deltaTime;
private float _movementSpeed;
public BasePlayer Player { get; set; }
//public AdvancedTrainingMatch AdvancedTrainingMatch => Match;
public Bot Config { get; set; }
public AdvancedTrainingMatch Match { get; set; }
public AdvancedTrainingArena Arena { get; set; }
public bool IsMoving { get; set; }
public void SetRandomSpeed()
{
_movementSpeed = Core.Random.Range(Config.MinimumMovementSpeed, Config.MaximumMovementSpeed);
}
public static BotPlayer CreateInstance(AdvancedTrainingArena arena, AdvancedTrainingMatch match, BaseEntity botEntity)
{
// var gameObject = new GameObject();
var botPlayer = botEntity.gameObject.AddComponent<BotPlayer>();
var player = botEntity.gameObject.GetComponent<BasePlayer>();
botPlayer.Player = player;
botPlayer.Arena = arena;
botPlayer.Match = match;
return botPlayer;
}
public void Initial(Bot config)
{
Player = GetComponent<BasePlayer>();
Config = config;
_movementSpeed = Core.Random.Range(Config.MinimumMovementSpeed, Config.MaximumMovementSpeed);
Player._lastSetName = string.Empty;
Player.displayName = Config.Name;
if (!string.IsNullOrWhiteSpace(Config.Loadout))
{
_arena.GiveLoadout(Player, Config.Loadout);
}
Go();
}
public void Go()
{
//if (!Match.Arena.SpawnZones.Any())
//{
// IsMoving = false;
// return;
//}
if (Player.IsSleeping())
{
Player.EndSleeping();
}
var spawnZone = Arena.GetRandomSpawnLocationForBot(Config.Name, false);
if (!spawnZone.HasValue)
{
return;
}
_moveTo = spawnZone.Value;
_moveFrom = Player.transform.position;
if (_moveTo != transform.position)
{
SetBotDirection(Quaternion.LookRotation(_moveTo - _moveFrom));
}
var distanceToTravel = Vector3.Distance(_moveFrom, _moveTo);
_timeToTravel = distanceToTravel / _movementSpeed;
_deltaTime = 0f;
IsMoving = true;
Arena.IsAnyBotMoving = true;
}
private void SetBotDirection(Quaternion angel)
{
if (angel.eulerAngles == default(Vector3))
{
return;
}
Player.OverrideViewAngles(angel.eulerAngles);
Player.SendNetworkUpdateImmediate();
}
private float GetLocationRealYInMap(Vector3 currentLocation)
{
RaycastHit raycastHit;
var layerMask = LayerMask.GetMask("Construction", "Clutter", "World");
var isRaycastHit = Physics.Raycast(currentLocation + Vector3.up, Vector3.down, out raycastHit, 30f, layerMask);
var heightInMap = TerrainMeta.HeightMap.GetHeight(currentLocation);
if (isRaycastHit)
{
float locationY = Math.Max(raycastHit.point.y, heightInMap);
return locationY;
}
var location = new Vector3(currentLocation.x, heightInMap, currentLocation.z);
return location.y;
}
private void FixedUpdate()
{
_deltaTime += Time.deltaTime;
if (IsMoving && !Player.IsWounded() && _deltaTime >= 0.2f)
{
if (_movementSpeed <= 0.5f)
return;
var movementPercentage = _deltaTime / _timeToTravel;
if (movementPercentage >= 1.0f)
{
IsMoving = false;
return;
}
var newLocation = Vector3.Lerp(_moveFrom, _moveTo, movementPercentage);
newLocation.y = GetLocationRealYInMap(newLocation);
Player.MovePosition(newLocation);
//Player.EnablePlayerCollider();
}
else if (!IsMoving)
{
Go();
}
}
public override bool Equals(object obj)
{
var botPlayer = obj as BotPlayer;
if (botPlayer == null || botPlayer.Player == null || Player == null)
{
return false;
}
return botPlayer.Player.userID == Player.userID;
}
public override int GetHashCode()
{
if (Player == null)
{
return 0;
}
return Player.userID.GetHashCode();
}
public void DoDestroy()
{
if (!Player.IsDestroyed)
Player.Kill();
if (Arena.Data.PerformanceMode)
Arena.Bots.Remove(this);
else
Match.Bots.Remove(this);
Destroy(this);
}
}
#endregion Behaviours
public static class ConsoleCommands
{
public const string ArenaHelp = "rtg.help";
public const string ArenaEdit = "rtg.edit";
public const string ArenaDone = "rtg.done";
public const string ArenaDelete = "rtg.delete";
public const string ArenaCreate = "rtg.create";
public const string ArenaSet = "rtg.set";
public const string ArenaSetHelp = "rtg.set.help";
public const string ArenaSetSpawn = "rtg.set.spawn";
public const string ArenaDeleteSpawn = "rtg.delete.spawn";
public const string ArenaAllow = "rtg.allow";
public const string ArenaBan = "rtg.ban";
public const string ArenaBotAdd = "rtg.bot.add";
public const string ArenaBotRemove = "rtg.bot.remove";
public const string ArenaJoin = "rtg.join";
public const string ArenaLeave = "rtg.leave";
public const string ResetMatchStats = "rtg.match.reset.stats";
public const string ResetMatch = "rtg.match.reset";
public const string ResetLoadout = "rtg.match.reset.loadout";
public const string UnlimitedAmmoToggle = "rtg.ammo.limit.toggle";
}
private static class Messages
{
public const string NoPermission = "No Permission";
public const string WrongCommand = "Wrong Command";
public const string ArenaCommandsList = "Arena Commands List";
public const string AdvancedTrainingCommandsList = "Advanced Training Commands Help";
public const string InvalidPlayerId = "Invalid Player Id";
public const string PlayerNotFound = "Player Not Found";
public const string LobbyNotFound = "Lobby Not Found";
public const string ArenaNotFound = "Arena Not Found";
public const string ChangesSaved = "Changes Saved";
public const string NoEditingLobby = "No Editing Lobby";
public const string NoEditingArena = "No Editing Arena";
public const string ArenaParameterChanged = "Arena Parameter Changed";
public const string ArenaSpawnPointAdded = "Arena Spawn Point Added";
public const string ArenaInvalidPosition = "Arena Invalid Position";
public const string ArenaInvalidEntrancePosition = "Arena Invalid Entrance Position";
public const string ArenaDeleted = "Arena Deleted";
public const string ArenaEditingStarted = "Arena Editing Started";
public const string ArenaEditingDone = "Arena Editing Done";
public const string ArenaNoAccess = "Arena No Access";
public const string ArenaZoneNotFound = "Arena Zone Not Found";
public const string LobbyZoneNotFound = "Lobby Zone Not Found";
public const string ArenaCreated = "Arena Created";
public const string SpawnPointNotFound = "Spawn Point Not Found";
public const string ArenaSetValueHelp = "Arena Set Value Help";
public const string UnlimitedAmmoEnabled = "Unlimited Ammo Enabled";
public const string UnlimitedAmmoDisabled = "Unlimited Ammo Disabled";
}
public class AdvancedTrainingArena : GameModeManager.Arena
{
public AdvancedTrainingArena(GameModeManager.Lobby lobby, AdvancedTrainingArenaData arenaData) : base(lobby, arenaData)
{
Data = arenaData;
Match = new Dictionary<Guid, AdvancedTrainingMatch>();
if (arenaData.PerformanceMode)
BotManagementTimer = _instance.timer.Every(2, CheckBotAmounts);
}
public Timer BotManagementTimer { get; set; }
public bool IsAnyBotMoving { get; set; }
public List<BotPlayer> Bots { get; set; } = new List<BotPlayer>();
public new Dictionary<Guid, AdvancedTrainingMatch> Match { get; set; }
public new AdvancedTrainingArenaData Data { get; set; }
public override string GetEntranceText()
{
var formattedText = Data.EntranceDisplayText?.Replace("$.Name", Data.Name).Replace("$.ZoneName", Zone?.Name).Replace("$.TotalCount", Match.Count.ToString()).Replace("$.MatchType", Data.MatchType.ToString());
return formattedText ?? "";
}
public Vector3? GetRandomSpawnLocationForBot(string botName, bool restrictToName)
{
Vector2? randomPos = null;
ArenaSpawnData spawnZone;
var tryCount = 0;
var randomChance = UnityEngine.Random.Range(0.1f, 100);
List<ArenaSpawnData> validSpawnZones;
if (restrictToName)
{
validSpawnZones = Data.SpawnLocations.Where(x => x.IsEnabled && x.BotName.Equals(botName, StringComparison.OrdinalIgnoreCase)).ToList();
}
else
{
validSpawnZones = Data.SpawnLocations.Where(x => x.IsEnabled && (string.IsNullOrWhiteSpace(x.BotName) ||
x.BotName.Equals(botName, StringComparison.OrdinalIgnoreCase))).ToList();
}
if (!validSpawnZones.Any())
{
if (restrictToName)
{
return null;
}
spawnZone = new ArenaSpawnData { Radius = Zone.Radius, SpawnPoint = Zone.Location };
}
else
{
spawnZone = validSpawnZones.Where(x => x.SpawnChance >= randomChance).ToList().GetRandom();
}
if (spawnZone.Radius > 0)
{
while (tryCount < 20)
{
randomPos = UnityEngine.Random.insideUnitCircle * spawnZone.Radius;
var entities = Facepunch.Pool.GetList<BaseEntity>();
Vis.Entities(randomPos.Value, 10, entities, LayerMask.GetMask("Construction", "Deployable"));
var count = entities.Count;
Facepunch.Pool.FreeList(ref entities);
if (count == 0)
{
break;
}
randomPos = null;
tryCount++;
}
}
else
{
randomPos = Vector2.zero;
}
return randomPos.HasValue
? new Vector3(spawnZone.SpawnPoint.x + randomPos.Value.x, spawnZone.SpawnPoint.y, spawnZone.SpawnPoint.z + randomPos.Value.y)
: Vector3.zero;
}
public void CheckBotAmounts()
{
_instance.CheckBotAmount(this);
}
}
public class AdvancedTrainingMatch : GameModeManager.Match
{
public AdvancedTrainingMatch(AdvancedTrainingArena arena) : base(arena)
{
arena.Match.Add(Id, this);
Arena = arena;
}
public new AdvancedTrainingArena Arena { get; set; }
public new HashSet<AdvancedTrainingPlayer> Players { get; set; } = new HashSet<AdvancedTrainingPlayer>();
public List<BotPlayer> Bots { get; set; } = new List<BotPlayer>();
public void SetMatchInitialData()
{
IsStarted = false;
ResetStats();
}
public void ResetStats()
{
foreach (var matchPlayer in Players)
{
matchPlayer.ResetStats();
}
}
public void ResetLoadout()
{
foreach (var matchPlayer in Players)
{
ResetLoadout(matchPlayer);
}
}
public void ResetLoadout(AdvancedTrainingPlayer matchPlayer)
{
matchPlayer.ResetLoadout(Arena.Data.PlayerLoadout);
}
}
public class AdvancedTrainingPlayer : GameModeManager.MatchPlayer
{
public AdvancedTrainingPlayer(BasePlayer player, AdvancedTrainingMatch match) : base(player, match)
{
Match = match;
Statistics = new AdvancedTrainingPlayerStats(player);
GiveLoadout(Match.Arena.Data.PlayerLoadout);
if (!Match.Arena.Data.PerformanceMode)
BotManagementTimer = _instance.timer.Every(2, CheckBotAmounts);
}
//public AdvancedTrainingMatch AdvancedTrainingMatch => Match;
public Timer BotManagementTimer { get; set; }
public new AdvancedTrainingMatch Match { get; set; }
public new AdvancedTrainingPlayerStats Statistics { get; set; }
public bool UnlimitedAmmo { get; set; }
public string WeaponName { get; set; }
public void CheckBotAmounts()
{
_instance.CheckBotAmount(Match, PlayerId);
}
public void ResetLoadout(string loadoutName)
{
ClearInventory();
GiveLoadout(loadoutName);
}
public void GiveLoadout(string loadoutName)
{
if (!string.IsNullOrWhiteSpace(loadoutName))
{
_arena.GiveLoadout(Player, loadoutName);
}
}
public override bool Equals(object obj)
{
var matchPlayer = obj as AdvancedTrainingPlayer;
if (matchPlayer == null)
{
return false;
}
return matchPlayer.PlayerId == PlayerId;
}
public override int GetHashCode()
{
return PlayerId.GetHashCode();
}
}
#endregion Classes
#region Commands
#region ArenaDataCommands
//rtg.help
[ConsoleCommand(ConsoleCommands.ArenaHelp)]
void ArenaHelp(ConsoleSystem.Arg conArgs)
{
var player = conArgs?.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
_arena.ShowMessage(player, Messages.ArenaCommandsList, this, GetArenaCommands());
}
//rtg.edit <id>
[ConsoleCommand(ConsoleCommands.ArenaEdit)]
void EditArena(ConsoleSystem.Arg conArgs)
{
if (conArgs == null)
{
_arena.ShowMessage(null, Messages.WrongCommand, this, GetArenaCommands());
return;
}
var player = conArgs.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
//if (_lobbyToEdit == null)
//{
// _arena.ShowMessage(player, Messages.NoEditingLobby, this, ConsoleCommands.LobbyEdit);
// return;
//}
var id = conArgs.GetInt(0, -1);
if (id >= 0)
{
_arenaToEdit = _pluginData.Arenas.FirstOrDefault(x => x.Id == id);
if (_arenaToEdit == null)
{
_arena.ShowMessage(player, Messages.ArenaNotFound, this, GetArenaCommands());
return;
}
_arena.UnLockEntities(_arenaToEdit.ZoneId, player.userID);
_arena.ShowMessage(player, Messages.ArenaEditingStarted, this, _arenaToEdit.Name, _arenaToEdit.Id);
}
else
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
}
}
//rtg.done
[ConsoleCommand(ConsoleCommands.ArenaDone)]
void DoneArena(ConsoleSystem.Arg conArgs)
{
if (conArgs == null)
{
_arena.ShowMessage(null, Messages.WrongCommand, this, GetArenaCommands());
return;
}
var player = conArgs.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
if (_arenaToEdit != null)
{
_arena.LockEntities(_arenaToEdit.ZoneId);
var name = _arenaToEdit.Name;
var id = _arenaToEdit.Id;
_arenaToEdit = null;
_arena.ShowMessage(player, Messages.ArenaEditingDone, this, name, id);
}
}
//rtg.delete <id>
[ConsoleCommand(ConsoleCommands.ArenaDelete)]
void DeleteArena(ConsoleSystem.Arg conArgs)
{
if (conArgs == null)
{
_arena.ShowMessage(null, Messages.WrongCommand, this, GetArenaCommands());
return;
}
var player = conArgs.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
//if (_lobbyToEdit == null)
//{
// _arena.ShowMessage(player, Messages.NoEditingLobby, this, ConsoleCommands.LobbyEdit);
// return;
//}
var id = conArgs.GetInt(0, -1);
if (id >= 0)
{
var arenaToRemove = _pluginData.Arenas.FirstOrDefault(x => x.Id == id);
if (arenaToRemove != null)
{
_pluginData.Arenas.Remove(arenaToRemove);
SaveData();
AdvancedTrainingArena teamDeathMatchArena;
_arenas.TryGetValue(arenaToRemove.Id, out teamDeathMatchArena);
RemoveArena(teamDeathMatchArena);
_arena.ShowMessage(player, Messages.ArenaDeleted, this);
}
else
{
_arena.ShowMessage(player, Messages.ArenaNotFound, this);
}
}
else
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
}
}
//rtg.create <Name> <ZoneId> [<EntranceTriggerRadius>]
[ConsoleCommand(ConsoleCommands.ArenaCreate)]
void CreateArena(ConsoleSystem.Arg conArgs)
{
if (conArgs == null)
{
_arena.ShowMessage(null, Messages.WrongCommand, this, GetArenaCommands());
return;
}
var player = conArgs.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
if (conArgs.Args.Length < 2)
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
return;
}
if (_arena.LobbyToEdit == null)
{
_arena.ShowMessage(player, Messages.NoEditingLobby, this, GameModeManager.ConsoleCommands.LobbyEdit);
return;
}
GameModeManager.Lobby lobby;
if (!_arena.Lobbies.TryGetValue(_arena.LobbyToEdit.Id, out lobby) || lobby == null)
{
_arena.ShowMessage(player, Messages.LobbyNotFound, this);
return;
}
var name = conArgs.GetString(0);
var zoneId = conArgs.GetString(1);
var radius = conArgs.GetFloat(2, 2);
var entrancePosition = Vector3.zero;
if (player != null)
{
entrancePosition = player.ServerPosition;
}
var zone = _arena.GetZone(zoneId);
if (zone == null)
{
_arena.ShowMessage(player, Messages.ArenaZoneNotFound, this);
return;
}
var lobbyZone = _arena.GetZone(_arena.LobbyToEdit.ZoneId);
if (lobbyZone == null)
{
_arena.ShowMessage(player, Messages.LobbyZoneNotFound, this);
return;
}
if (Vector3.Distance(entrancePosition, lobbyZone.Location) >= lobbyZone.Radius)
{
entrancePosition = Vector3.zero;
}
var id = (_arena.LobbyToEdit.Id * 100) + 1;
var arenaIds = _arena.GetArenaIdsInLobby(_arena.LobbyToEdit.Id);
if (arenaIds.Any())
{
id = arenaIds.Max() + 1;
}
var newArena = new AdvancedTrainingArenaData
{
Id = id,
LobbyId = lobby.Data.Id,
Name = name,
ZoneId = zoneId,
Capacity = 1,
IsEnabled = true,
MatchType = GameModeManager.MatchType.TrainingGround,
EntranceLocation = entrancePosition,
IsEntranceTriggerActive = entrancePosition != Vector3.zero,
EntranceTriggerRadius = radius,
AccessThroughLobbyOnly = false,
RestrictAccess = false,
SpawnLocations = new HashSet<ArenaSpawnData>()
};
_pluginData.Arenas.Add(newArena);
_arenaToEdit = newArena;
SaveData();
var arena = new AdvancedTrainingArena(lobby, _arenaToEdit);
if (arena.Match == null)
{
player.ChatMessage("Arena data is created but Match type is missing and arena is not activated!");//TODO: Lang
return;
}
arena.Zone = zone;
arena.Behaviour = GameModeManager.ArenaBehaviour.CreateEntrance($"Arena_EP_{newArena.Id}", _arenaToEdit.EntranceLocation,
_arenaToEdit.EntranceTriggerRadius,
_arenaToEdit.IsEntranceTriggerActive);
arena.Behaviour.Initialize(arena);
_arenas.Add(_arenaToEdit.Id, arena);
_arena.ShowMessage(player, Messages.ArenaCreated, this);
}
//rtg.set <key> <value> [<key> <value>] [<key> <value>]...[ConsoleCommand(ConsoleCommands.ArenaSet)]
void SetArenaValue(ConsoleSystem.Arg conArgs)
{
if (conArgs == null)
{
_arena.ShowMessage(null, Messages.WrongCommand, this, GetArenaCommands());
return;
}
var player = conArgs.Player();
if (player != null && !permission.UserHasPermission(player.UserIDString, GameModeManager.PermissionAdmin))
{
_arena.ShowMessage(player, Messages.NoPermission, this);
return;
}
if (conArgs.Args.Length <= 1)
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
return;
}
if (_arenaToEdit == null)
{
_arena.ShowMessage(player, Messages.NoEditingArena, this, ConsoleCommands.ArenaEdit);
return;
}
GameModeManager.Zone zone = null;
var updateEntrance = false;
var length = conArgs.Args.Length / 2;
var index = 0;
for (var i = 0; i < length; i++)
{
var key = conArgs.GetString(index).ToLower();
index++;
switch (key)
{
case "name":
{
_arenaToEdit.Name = conArgs.GetString(index);
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.Name));
break;
}
case "zone":
case "zoneid":
{
var zoneId = conArgs.GetString(index);
zone = _arena.GetZone(zoneId);
if (zone == null)
{
_arena.ShowMessage(player, Messages.ArenaZoneNotFound, this);
}
else
{
_arenaToEdit.ZoneId = zoneId;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.ZoneId));
}
break;
}
case "lobby":
case "lobbyid":
{
var lobbyId = conArgs.GetInt(index);
if (_arena.Lobbies.ContainsKey(lobbyId))
{
_arena.ShowMessage(player, Messages.LobbyNotFound, this);
}
else
{
_arenaToEdit.LobbyId = lobbyId;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.LobbyId));
}
break;
}
case "enabled":
case "isenabled":
{
_arenaToEdit.IsEnabled = conArgs.GetBool(index);
updateEntrance = true;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.IsEnabled));
break;
}
case "restrict":
case "restrictaccess":
{
_arenaToEdit.RestrictAccess = conArgs.GetBool(index);
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.RestrictAccess));
break;
}
case "entrance.active":
{
_arenaToEdit.IsEntranceTriggerActive = conArgs.GetBool(index);
updateEntrance = true;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.IsEntranceTriggerActive));
break;
}
case "entrance.vr":
case "entrance.visibilityrange":
case "entrance.textvisibilityrange":
{
_arenaToEdit.EntrancePointTextVisibilityRange = conArgs.GetFloat(index);
updateEntrance = true;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.EntrancePointTextVisibilityRange));
break;
}
case "entrance.pos":
{
var pos = conArgs.GetVector3(index, Vector3.zero);
if (pos.Equals(Vector3.zero))
{
if (conArgs.GetString(index).ToLower().Equals("here") && player != null)
{
pos = player.ServerPosition;
}
else
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
break;
}
}
GameModeManager.Lobby lobby;
if (!_arena.Lobbies.TryGetValue(_arenaToEdit.LobbyId, out lobby) || lobby == null)
{
_arena.ShowMessage(player, Messages.LobbyNotFound, this);
break;
}
if (Vector3.Distance(player.ServerPosition, lobby.Zone.Location) >= lobby.Zone.Radius)
{
_arena.ShowMessage(player, Messages.ArenaInvalidPosition, this, pos);
break;
}
_arenaToEdit.EntranceLocation = pos;
updateEntrance = true;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.EntranceLocation));
break;
}
case "entrance.r":
case "entrance.radius":
{
_arenaToEdit.EntranceTriggerRadius = conArgs.GetFloat(index);
updateEntrance = true;
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.EntranceTriggerRadius));
break;
}
case "access.lobbyonly":
{
_arenaToEdit.AccessThroughLobbyOnly = conArgs.GetBool(index);
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.AccessThroughLobbyOnly));
break;
}
case "kit.p":
case "kit.player":
case "loadout.p":
case "loadout.player":
{
_arenaToEdit.PlayerLoadout = conArgs.GetString(index);
_arena.ShowMessage(player, Messages.ArenaParameterChanged, this, nameof(AdvancedTrainingArenaData.PlayerLoadout));
break;
}
case "player.pos":
case "player.sp":
case "player.spawnposition":
{
var pos = conArgs.GetVector3(index, Vector3.zero);
if (pos.Equals(Vector3.zero))
{
if (conArgs.GetString(index).ToLower().Equals("here") && player != null)
{
pos = player.ServerPosition;
}
else
{
_arena.ShowMessage(player, Messages.WrongCommand, this, GetArenaCommands());
break;
}
}
var arenaZone = _arena.GetZone(_arenaToEdit.ZoneId);
// ... [Code preview truncated due to length. Full source in attached file] ...