190 lines
6.2 KiB
C#
190 lines
6.2 KiB
C#
using Terraria;
|
|
using Terraria.ID;
|
|
using TShockAPI;
|
|
using TShockAPI.Hooks;
|
|
using TerrariaApi.Server;
|
|
using TerrariaHealingPlugin.Mappings;
|
|
|
|
namespace TerrariaHealingPlugin;
|
|
|
|
[ApiVersion(2, 1)]
|
|
public class HealingPlugin : TerrariaPlugin
|
|
{
|
|
public override string Author => "Sneefaria Maintainers";
|
|
public override string Name => "HealingPlugin";
|
|
public override string Description => "A healing plugin, duh";
|
|
public override Version Version => new Version(1, 0, 0);
|
|
|
|
private DateTime _lastHealCheck = DateTime.UtcNow;
|
|
private DateTime _lastBuffCheck = DateTime.UtcNow;
|
|
private List<Player> _players = new List<Player>();
|
|
|
|
private HealingMappings _healingItemMappings = new HealingMappings();
|
|
private EquipMappings _equipMappings = new EquipMappings();
|
|
|
|
public HealingPlugin(Main game) : base(game) { }
|
|
|
|
public override void Initialize()
|
|
{
|
|
TShock.Log.Info($"Initializing {Name} v{Version} by {Author}");
|
|
ServerApi.Hooks.ServerJoin.Register(this, OnServerJoin);
|
|
ServerApi.Hooks.GameUpdate.Register(this, OnUpdate);
|
|
ServerApi.Hooks.NetSendData.Register(this, OnSendNetData);
|
|
ServerApi.Hooks.NetGetData.Register(this, OnGetNetData);
|
|
GetDataHandlers.PlayerSlot.Register(OnPlayerSlot);
|
|
// GetDataHandlers.PlayerHP.Register(OnPlayerHPChange);
|
|
GetDataHandlers.PlayerBuff.Register(OnPlayerBuff);
|
|
PlayerHooks.PlayerPostLogin += OnPlayerPostLogin;
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
ServerApi.Hooks.ServerJoin.Deregister(this, OnServerJoin);
|
|
// ServerApi.Hooks.GameUpdate.Deregister(this, OnUpdate);
|
|
ServerApi.Hooks.NetSendData.Deregister(this, OnSendNetData);
|
|
ServerApi.Hooks.NetGetData.Deregister(this, OnGetNetData);
|
|
PlayerHooks.PlayerPostLogin -= OnPlayerPostLogin;
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
|
|
private void OnPlayerPostLogin(PlayerPostLoginEventArgs e)
|
|
{
|
|
ApplyRegenerationBuff(e.Player);
|
|
}
|
|
|
|
// FIXME: not at all complete, needs some work
|
|
private void OnPlayerBuff(object sender, GetDataHandlers.PlayerBuffEventArgs args)
|
|
{
|
|
// Console.WriteLine($"Player buff arguments: {args}");
|
|
TSPlayer player = args.Player;
|
|
int buffType = args.Type;
|
|
Console.WriteLine($"Buff type: {buffType}");
|
|
bool isEquippableBuff = _equipMappings.mappings.ContainsKey(buffType);
|
|
bool isHealingItemBuff = _healingItemMappings.mappings.ContainsKey(buffType);
|
|
Console.WriteLine($"Player: {player.Name}, Buff Type: {buffType}, Is Equippable Buff: {isEquippableBuff}");
|
|
if (isEquippableBuff)
|
|
{
|
|
var multiplier = _equipMappings.GetHealingMultiplier(buffType);
|
|
player.SendSuccessMessage($"Equippable buff detected! Applying x{multiplier} multiplier to healing effects.");
|
|
args.Handled = true;
|
|
}
|
|
}
|
|
|
|
private void OnGetNetData(GetDataEventArgs args)
|
|
{
|
|
// nothing here, yet ;)
|
|
}
|
|
|
|
private void OnPlayerHPChange(object sender, GetDataHandlers.PlayerHPEventArgs args)
|
|
{
|
|
TSPlayer player = args.Player;
|
|
int previousHP = player.TPlayer.statLife;
|
|
int newHP = args.Current;
|
|
short healingAmount = (short)(newHP - previousHP);
|
|
bool isHealingItem = IsHealingValueValid(healingAmount);
|
|
|
|
if (healingAmount > 0 && isHealingItem)
|
|
{
|
|
args.Handled = true;
|
|
}
|
|
}
|
|
|
|
private void OnPlayerSlot(object sender, GetDataHandlers.PlayerSlotEventArgs args)
|
|
{
|
|
TSPlayer player = args.Player;
|
|
short slot = args.Slot;
|
|
short newStack = args.Stack;
|
|
short itemType = args.Type;
|
|
var isHealingItem = IsHealingItem(itemType);
|
|
var isItemConsumed = IsItemBeingConsumed(player, slot, newStack);
|
|
|
|
if (isHealingItem && isItemConsumed)
|
|
{
|
|
var multiplier = _healingItemMappings.GetHealingMultiplier(itemType);
|
|
var baseHeal = GetBaseHealAmount(itemType);
|
|
var enhancedHeal = (int)(baseHeal * multiplier);
|
|
var totalHealing = enhancedHeal + baseHeal;
|
|
|
|
player.Heal(enhancedHeal);
|
|
player.SendSuccessMessage($"Enhanced healing! Restored {enhancedHeal} HP (x{multiplier} multiplier)");
|
|
|
|
args.Handled = true;
|
|
}
|
|
}
|
|
|
|
private bool IsHealingItem(int itemType)
|
|
{
|
|
return _healingItemMappings.mappings.ContainsKey(itemType);
|
|
}
|
|
|
|
private bool IsHealingValueValid(short healAmount)
|
|
{
|
|
return _healingItemMappings.mappings.ContainsValue(healAmount);
|
|
}
|
|
|
|
private int GetBaseHealAmount(int itemType)
|
|
{
|
|
return _healingItemMappings.mappings.TryGetValue(itemType, out var healAmount) ? healAmount : 0;
|
|
}
|
|
|
|
private bool IsItemBeingConsumed(TSPlayer player, int slot, short newStack)
|
|
{
|
|
var item = player.TPlayer.inventory[slot];
|
|
return item.stack > newStack;
|
|
}
|
|
|
|
private void OnSendNetData(SendDataEventArgs args)
|
|
{
|
|
// empty, on purpose :D
|
|
}
|
|
|
|
private void OnUpdate(EventArgs args)
|
|
{
|
|
if ((DateTime.UtcNow - _lastBuffCheck).TotalSeconds >= 30)
|
|
{
|
|
foreach (TSPlayer player in TShock.Players)
|
|
{
|
|
if (player?.Active == true)
|
|
{
|
|
ApplyRegenerationBuff(player);
|
|
}
|
|
}
|
|
|
|
_lastBuffCheck = DateTime.UtcNow;
|
|
}
|
|
}
|
|
|
|
// TODO: method might be used for later
|
|
// private void ApplyRegenerationToAllPlayers()
|
|
// {
|
|
// foreach (TSPlayer player in TShock.Players)
|
|
// {
|
|
// if (player?.Active == true && player.ConnectionAlive)
|
|
// {
|
|
// ApplyRegenerationBuff(player);
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
private void ApplyRegenerationBuff(TSPlayer player)
|
|
{
|
|
if (player?.Active == true && player.ConnectionAlive)
|
|
{
|
|
player.SetBuff(BuffID.Regeneration, 3600, bypass: true);
|
|
}
|
|
}
|
|
|
|
private void OnServerJoin(JoinEventArgs args)
|
|
{
|
|
var player = TShock.Players[args.Who];
|
|
if (player != null)
|
|
{
|
|
_players.Add(new Player(player));
|
|
TShock.Log.Info($"Player {player.Name} joined with IP: {player.IP}");
|
|
}
|
|
}
|
|
}
|