C#:
using Oxide.Core;
using System.Collections.Generic;
namespace Oxide.Plugins
{
[Info("PlayerEventStates", "Flutes", "1.0.0")]
[Description("Useful for developers who wish to create conditional gameplay mechanics based on specific events or states.")]
public class PlayerEventStates : RustPlugin
{
#region Fields
public static PlayerEventStates Instance { get; private set; }
public static PlayerEventStatesManager Core { get; private set; }
#endregion
#region Core
public class PlayerEventStatesManager
{
public readonly GlobalEventStatesData GlobalEventStates;
private Dictionary<ulong, PlayerController> m_players = new Dictionary<ulong, PlayerController>();
public IReadOnlyDictionary<ulong, PlayerController> Players => m_players;
public PlayerEventStatesManager()
{
GlobalEventStates = GlobalEventStatesData.Load();
}
public void SaveData()
{
foreach(var player in m_players)
{
player.Value.PlayerData.Save();
}
GlobalEventStates.Save();
}
public PlayerController GetOrCreatePlayerController(ulong playerId)
{
PlayerController playerController = null;
if (m_players.TryGetValue(playerId, out playerController) == false)
{
PlayerData playerData = PlayerData.Load(playerId);
playerController = new PlayerController(playerData);
m_players.Add(playerId, playerController);
}
return playerController;
}
public bool GetGlobalEventState(string eventName)
{
EventStateData eventStateData = null;
if (GlobalEventStates.EventStates.TryGetValue(eventName, out eventStateData) == false)
{
eventStateData = new EventStateData();
eventStateData.Name = eventName;
GlobalEventStates.EventStates.Add(eventName, eventStateData);
GlobalEventStates.OnChange();
}
return eventStateData.State;
}
public void SetGlobalEventState(string eventName, bool value)
{
if (GlobalEventStates.EventStates.ContainsKey(eventName) == false)
{
Instance.Puts($"Global EventState with name {eventName} not found");
return;
}
GlobalEventStates.EventStates[eventName].State = value;
GlobalEventStates.OnChange();
}
}
public class PlayerController
{
public readonly PlayerData PlayerData;
public PlayerController(PlayerData playerData)
{
PlayerData = playerData;
}
public bool GetEventState(string eventName)
{
EventStateData eventStateData = null;
if (PlayerData.EventStates.TryGetValue(eventName, out eventStateData) == false)
{
return false;
}
return eventStateData.State;
}
public bool HasRecquiredStates(Dictionary<string, bool> eventStates)
{
foreach(var kvp in eventStates)
{
var eventName = kvp.Key;
var state = kvp.Value;
if (GetEventState(eventName) != state)
{
return false;
}
}
return true;
}
public void SetEventState(string eventName, bool value)
{
EventStateData eventStateData = null;
if (PlayerData.EventStates.ContainsKey(eventName))
{
eventStateData = PlayerData.EventStates[eventName];
}
else
{
eventStateData = new EventStateData();
eventStateData.Name = eventName;
PlayerData.EventStates.Add(eventName, eventStateData);
}
eventStateData.State = value;
PlayerData.OnChange();
}
}
#endregion
#region Startup
private void Init()
{
Instance = this;
LoadConfig();
Core = new PlayerEventStatesManager();
}
private void Unload()
{
Core?.SaveData();
}
private void OnServerSave() => Core?.SaveData();
#endregion
#region API
private bool GetEventStatePlayer_API(ulong playerId, string eventName)
{
var player = Core.GetOrCreatePlayerController(playerId);
return player.GetEventState(eventName);
}
private bool GetEventStateGlobal_API(string eventName)
{
return Core.GetGlobalEventState(eventName);
}
private void SetEventStatePlayer_API(ulong playerId, string eventName, bool value)
{
var player = Core.GetOrCreatePlayerController(playerId);
player.SetEventState(eventName, value);
}
private void SetEventStateGlobal_API(string eventName, bool value)
{
Core.SetGlobalEventState(eventName, value);
}
private bool PlayerHasRecquiredStates_API(ulong playerId, Dictionary<string, bool> states)
{
var player = Core.GetOrCreatePlayerController(playerId);
return player.HasRecquiredStates(states);
}
#endregion
#region Data
public class EventStateData
{
public string Name;
public bool State;
}
public class GlobalEventStatesData
{
public Dictionary<string, EventStateData> EventStates = new Dictionary<string, EventStateData>();
private bool m_stateHasChanged;
public static GlobalEventStatesData Load()
{
GlobalEventStatesData data = null;
var file = Interface.Oxide.DataFileSystem.GetFile($"{Instance.Name}/global_events");
if (file == null)
{
Instance.Puts("GlobalEventStatesData file not found");
return null;
}
else
{
data = file.ReadObject<GlobalEventStatesData>();
}
return data;
}
public bool Save()
{
if (m_stateHasChanged == false)
{
return false;
}
Interface.Oxide.DataFileSystem.WriteObject($"{Instance.Name}/global_events", this);
m_stateHasChanged = false;
return true;
}
public void OnChange()
{
m_stateHasChanged = true;
}
}
public class PlayerData
{
public ulong PlayerId;
public Dictionary<string, EventStateData> EventStates = new Dictionary<string, EventStateData>();
private bool m_stateHasChanged;
public static PlayerData Load(ulong userId)
{
PlayerData playerData = null;
var file = Interface.Oxide.DataFileSystem.GetFile($"{Instance.Name}/user_{userId}");
if (file == null)
{
Instance.Puts("PlayerData file not found for player " + userId.ToString());
return null;
}
else
{
playerData = file.ReadObject<PlayerData>();
}
playerData.PlayerId = userId;
playerData.OnChange();
return playerData;
}
public bool Save()
{
if (m_stateHasChanged == false)
{
return false;
}
Interface.Oxide.DataFileSystem.WriteObject($"{Instance.Name}/user_{PlayerId}", this);
m_stateHasChanged = false;
return true;
}
public void OnChange()
{
m_stateHasChanged = true;
}
}
#endregion
}
}