C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Newtonsoft.Json;
using Oxide.Core.Libraries.Covalence;
using Oxide.Core.Plugins;
using Oxide.Core;
using System.Collections.Generic;
using System;
namespace Oxide.Plugins
{
[Info("Life Support", "OG61", "1.5.0")]
[Description("Use reward points to prevent player from dying")]
//Change log
//1.4.0 Moved code from OnPlayerDeath to SaveLife and call from OnPlayerDeath and OnPlayerWound (when health below 1)
//1.5.0 Added ability to suspend LifeSupport in DangerousTreasures zones and added support for zone manager.public class LifeSupport : CovalencePlugin
{
#region Plugin References
[PluginReference]
private Plugin RaidableBases, ServerRewards, DangerousTreasures, ZoneManager;
#endregion
#region Config
private const string PERMISSION_BLOCKED = "lifesupport.blocked";
private class Perms
{
public string Permission { get; set; }
public int Cost { get; set; }
}
private class PluginConfig
{
[JsonProperty(PropertyName = "Use Zone Manager (true/false)")]
public bool UseZoneManager = false;
[JsonProperty(PropertyName = "Use Server Rewards (true/false)")]
public bool UseServerRewards = false;
[JsonProperty(PropertyName = "Disable LifeSupport in RaidableBases Zones (true/false)")]
public bool UseRaidableBases = false;
[JsonProperty(PropertyName = "Disable LifeSupport in DangerousTreasures Zones (true/false)")]
public bool UseDangerousTreasures = false;
[JsonProperty(PropertyName = "Enable Log file (true/false)")]
public bool LogToFile = true;
[JsonProperty(PropertyName = "Log output to console (true/false)")]
public bool LogToConsole = true;
[JsonProperty(PropertyName = "Permissions and cost", ObjectCreationHandling = ObjectCreationHandling.Replace)]
public List<Perms> perms = new List<Perms>()
{
new Perms() {Permission = "lifesupport.default", Cost = 400 },
new Perms() {Permission = "lifesupport.vip", Cost = 200},
new Perms() {Permission = "lifesupport.admin", Cost = 0}
};
}
private PluginConfig config;
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null)
{
LoadDefaultConfig();
}
}
catch
{
LoadDefaultConfig();
Logger("ConfigError");
}
SaveConfig();
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void SaveConfig() => Config.WriteObject(config);
private void OnPluginLoaded(Plugin plugin)
{
switch (plugin.Title)
{
case "RaidableBases":
{
RaidableBases = plugin;
break;
}
case "DangerousTreasures":
{
DangerousTreasures = plugin;
break;
}
case "ServerRewards":
{
ServerRewards = plugin;
break;
}
case "ZoneManager":
{
ZoneManager = plugin;
break;
}
}
}
private void OnPluginUnloaded(Plugin plugin)
{
switch (plugin.Title)
{
case "RaidableBases":
{
RaidableBases = null;
break;
}
case "DangerousTreasures":
{
DangerousTreasures = null;
break;
}
case "ServerRewards":
{
ServerRewards = null;
break;
}
case "ZoneManager":
{
ZoneManager = null;
break;
}
}
}
#endregion //Config
#region Data
private Data data;
private class Data
{
public List<string> activatedIDs = new List<string>();
public List<string> excludedZones = new List<string>();
}
private void SaveData() => Interface.Oxide.DataFileSystem.WriteObject(Name, data);
#endregion //Data
#region Oxide Hooks
private void Loaded()
{
data = Interface.Oxide.DataFileSystem.ReadObject<Data>(Name);
config.perms.ForEach(p =>
{
permission.RegisterPermission(p.Permission, this);
});
permission.RegisterPermission(PERMISSION_BLOCKED, this);
}
//Prevent player from entering wounded state
private object OnPlayerWound(BasePlayer player)
{
if (player == null) return null;
if (permission.UserHasPermission(player.UserIDString, PERMISSION_BLOCKED)) return null;
if (config.UseRaidableBases)
{
if (RaidableBases != null && RaidableBases.IsLoaded)
{
if (RaidableBases.Call<bool>("EventTerritory", player.transform.position))
{
Message("ExcludedZone", player.IPlayer);
Logger("RBZone", player.IPlayer);
return null;
}
}
}
if (config.UseDangerousTreasures)
{
if (DangerousTreasures != null && DangerousTreasures.IsLoaded)
{
if (DangerousTreasures.Call<bool>("EventTerritory", player.transform.position))
{
Message("ExcludedZone", player.IPlayer);
Logger("DTZone",player.IPlayer);
return null;
}
}
}
if (config.UseZoneManager)
{
if (ZoneManager != null && ZoneManager.IsLoaded)
{
foreach (string s in data.excludedZones)
if (ZoneManager.Call<bool>("IsPlayerInZone", s, player))
{
Message("ExcludedZone", player.IPlayer);
Logger("ZMZone",player.IPlayer);
return null;
}
}
}
bool preventWounded = false;
config.perms.ForEach(p =>
{
if (permission.UserHasPermission(player.UserIDString, p.Permission)&&
data.activatedIDs.Contains(player.UserIDString))
{
preventWounded = true;
}
});
if (preventWounded)
{
if (player.health < 1) return SaveLife(player); else return true;
}
else return null;
}
private object OnPlayerDeath(BasePlayer player, HitInfo hitInfo)
{
return (SaveLife(player));
}
bool CanDropActiveItem(BasePlayer player)
{
try
{
if (player == null || player.IsNpc) return true;
if (config.UseRaidableBases)
{
if (RaidableBases != null && RaidableBases.IsLoaded)
{
if (RaidableBases.Call<bool>("EventTerritory", player.transform.position)) return true;
}
}
if (config.UseDangerousTreasures)
{
if (DangerousTreasures != null && DangerousTreasures.IsLoaded)
{
if (DangerousTreasures.Call<bool>("EventTerritory", player.transform.position)) return true;
}
}
if (config.UseZoneManager)
{
if (ZoneManager != null && ZoneManager.IsLoaded)
{
foreach (string s in data.excludedZones)
if (ZoneManager.Call<bool>("IsPlayerInZone", s, player)) return true;
}
}
return data.activatedIDs.Contains(player.UserIDString) ? false : true;
}
catch (System.Exception ex)
{
Puts("CanDropActiveItem trew Exception: " + ex) ;
throw;
}
}
#endregion //Oxide Hooks
#region Helpers
private object SaveLife(BasePlayer player)
{
if (player == null || player.IsNpc || player.IsSleeping()) return null;
if (permission.UserHasPermission(player.UserIDString, PERMISSION_BLOCKED)) return null;
if (Interface.CallHook("OnLifeSupportSavingLife", player) != null)
{
Logger("CanceledByPlugin", player.IPlayer);
return null;
}
bool preventDeath = false;
int costOfLife = int.MaxValue;
if (config.UseRaidableBases)
{
if (RaidableBases != null && RaidableBases.IsLoaded)
{
if (RaidableBases.Call<bool>("EventTerritory", player.transform.position)) return null;
}
}
if (config.UseDangerousTreasures)
{
if (DangerousTreasures != null && DangerousTreasures.IsLoaded)
{
if (DangerousTreasures.Call<bool>("EventTerritory", player.transform.position)) return null;
}
}
if (config.UseZoneManager)
{
if (ZoneManager != null && ZoneManager.IsLoaded)
{
foreach(string s in data.excludedZones)
if (ZoneManager.Call<bool>("IsPlayerInZone", s, player)) return null;
}
}
if (data.activatedIDs.Contains(player.UserIDString))
{
config.perms.ForEach(p =>
{
if (permission.UserHasPermission(player.UserIDString, p.Permission))
{
preventDeath = true;
if (p.Cost < costOfLife) costOfLife = p.Cost;
}
});
if (!preventDeath) return null; //Player does not have permission so exit
if (config.UseServerRewards)
{
if (ServerRewards == null || !ServerRewards.IsLoaded)
{//Server Rewards enabled but not present.Log error and return
Message("ServerRewardsNull", player.IPlayer);
Logger("ServerRewardsNull");
return null;
}
if (costOfLife > 0)
{//object object CheckPoints(ulong ID) // Returns int, or null if no data is saved
var rp = ServerRewards.Call("CheckPoints", player.userID);
if ((rp is int ? (int)rp : 0) >= costOfLife)
{
ServerRewards.Call("TakePoints", player.UserIDString, costOfLife);
}
else
{
Message("CantAfford", player.IPlayer);
Logger("DiedCouldntAfford", player.IPlayer);
return null; //Player can't afford so exit
}
}
Message("SavedYourLifeCost", player.IPlayer, costOfLife);
Logger("SavedLife", player.IPlayer, costOfLife);
}
else //Not using ServerRewards
{
Message("SavedYourLife", player.IPlayer);
Logger("ServerRewardsInactiveSavedLife", player.IPlayer);
}
player.health = 100f;
if (player.IsWounded()) player.StopWounded();
return true;
}
Logger("DiedNotActive", player.IPlayer);
return null; //Life Support not activated for this player so exit
}
private string GetLang(string key, string id = "", params object[] args)
{
return string.Format(lang.GetMessage(key, this, id), args);
}
private void Logger(string key, IPlayer player = null, params object[] args)
{
string s = GetLang(key, player != null ? player.Id : "", args);
string ps = "";
if (player != null) ps = $"{player.Name} ({player.Id}) ";
s = $"[{DateTime.Now}] {ps} {s}";
if (config.LogToFile) LogToFile("LifeSupport", s, this);
if (config.LogToConsole) Puts(s);
}
private void Message(string key, IPlayer player, params object[] args)
{
if (player != null)
{
player.Reply(GetLang(key, player.Id, args));
}
}
#endregion //Helpers
#region Commands
[Command("lifesupport")]
private void LifeSupportToggle(IPlayer player, string msg, string[] args)
{
if (permission.UserHasPermission(player.Id, PERMISSION_BLOCKED))
{
Message("NoPermission", player);
return;
}
int costOfLife = int.MaxValue;
bool hasPermission = false;
if (args.Length > 0)
{
if (args.Length == 1 && args[0].ToLower() == "help")
{
Message("Help", player);
return;
}
Message("DontUnderstand", player);
return;
}
config.perms.ForEach(p =>
{
if (permission.UserHasPermission(player.Id, p.Permission))
{
hasPermission = true;
if (p.Cost < costOfLife) costOfLife = p.Cost; //Get the lowest cost if player has multiple permissions
}
});
if (data.activatedIDs.Contains(player.Id))
{
data.activatedIDs.Remove(player.Id);
Message("Deactivated", player);
Logger("Deactivated" , player);
SaveData();
}
else if(hasPermission)
{
data.activatedIDs.Add(player.Id);
Message("Activated", player, config.UseServerRewards ? costOfLife: 0);
Logger("Activated", player, costOfLife);
SaveData();
}
else Message("NoPermission", player);
}
[Command("lsZones")]
private void LsZones(IPlayer player, string msg, string[] args)
{
//ToDo Limit to admins
if (permission.UserHasPermission(player.Id, "lifesupport.admin"))
{
if (args.Length > 0)
{
switch (args[0].ToLower())
{
case "add":
for (int i = 1; i < args.Length; i++)
{
data.excludedZones.Add(args[i]);
}
SaveData();
Message("ZoneAdded", player);
for (int i = 1; i < args.Length; i++)
{
Message(args[i], player);
}
break;
case "remove":
for (int i = 1; i < args.Length; i++)
{
data.excludedZones.Remove(args[i]);
}
SaveData();
Message("ZonesRemoved", player);
for (int i = 1; i < args.Length; i++)
{
Message(args[i], player);
}
break;
case "clear":
data.excludedZones.Clear();
SaveData();
Message("ZonesCleared", player);
break;
case "list":
Message("ListZones", player);
foreach (string s in data.excludedZones)
{
Message(s, player);
}
break;
default:
Message("DontUnderstand", player);
break;
}
return;
}
}else
{
Message("NoPermission", player);
Logger("NoPermission", player);
return;
}
}
#endregion
#region Localization
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["ZoneAdded"] = "Added the following zone(s) to LifeSupport exclusionary list",
["ZoneRemoved"] = "Removed the following zone(s) from LifeSupport exclusionary list",
["ZonesCleared"] = "Cleared all zones from LifeSupport exclusionary list",
["ListZones"] = "LifeSupport is disabled in the following zones",
["ExcludedZone"] = "LifeSupport is disabled in this zone",
["RBZone"] = "LifeSupport is disabled in Raidable Bases zone",
["DTZone"] = "LifeSupport disabled in Dangerous Treasures zone",
["ZMZone"] = "LifeSupport disabled in Zone Manager zone",
["CanceledByPlugin"] = "LifeSupport canceled by another plugin",
["ServerRewardsNull"] = "LifeSupport could not save your life.\n"+
"ServerRewards is enabled but the ServerRewards plugin is not available.",
["DontUnderstand"] = "Don't Understand.",
["DiedNotActive"] = "Player died.LifeSupport not active.",
["ConfigError"] = "Error reading config file.Defaut configuration used.",
["NoPermission"] = "You do not have permission to use this command.",
["CantAfford"] = "Sorry, insufficent reward points to use LifeSupport.",
["DiedCouldntAfford"] = "Player died.Could not afford LifeSupport.",
["Deactivated"] = "Life Support de-activated.",
["Activated"] = "Life Support activated.Cost per life {0} RP",
["SavedYourLifeCost"] = "Life Support saved your life.Cost: {0} RP",
["SavedYourLife"] = "Life Support saved your life.",
["SavedLife"] = "Prevented death.Cost: {0} RP",
["ServerRewardsInactiveSavedLife"] = "Prevented death.Server Rewards inactive",
["Help"] = "When active LifeSupport will prevent a player's death if\n" +
"they have permission and a sufficent amount of reward points \n" +
"or if Server Rewards is turned off.\n" +
"It also prevents dropping their active item.\n" +
"Type /LifeSupport in chat to toggle on and off."
}, this);
}
#endregion
}
}