Files
TerrariaHealingPlugin/HealingPlugin.cs

190 lines
6.2 KiB
C#
Raw Normal View History

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);
}
2025-08-28 08:09:43 -04:00
// 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;
}
}
2025-08-28 08:09:43 -04:00
// 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)
{
2025-08-28 08:09:43 -04:00
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}");
}
}
}