Files
TerrariaHealingPlugin/HealingPlugin.cs

212 lines
7.1 KiB
C#
Raw Permalink Normal View History

using Terraria;
using Terraria.ID;
using TShockAPI;
using TShockAPI.Hooks;
using TerrariaApi.Server;
using TerrariaHealingPlugin.Mappings;
using TerrariaHealingPlugin.Models;
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<ServerPlayer> _players = new List<ServerPlayer>();
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;
bool isHealingItem = IsHealingItem(itemType);
bool 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)
{
Terraria.Item item = player.TPlayer.inventory[slot];
bool isMouse = slot != 58; // is slot 58 the mouse?
bool isNewStackLessThanOld = item.stack > newStack;
bool isUseAction = player.TPlayer.ConsumeItem(item.netID);
Console.WriteLine($"Is the slot the mouse slot?: {!isMouse}");
Console.WriteLine($"Is the new stack of items less than the item stack?: {isNewStackLessThanOld}");
Console.WriteLine($"Is the action consuming an item?: {isUseAction}");
// return isMouse && isNewStackLessThanOld && isUseAction;
if (isNewStackLessThanOld && isUseAction)
{
return true;
}
if (slot < 58 && isNewStackLessThanOld)
{
return true;
}
return false;
}
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 ServerPlayer(player));
TShock.Log.Info($"Player {player.Name} joined with IP: {player.IP}");
player.SendSuccessMessage($"Welcome {player.Name} to Sneefaria! Enjoy the regen buff!", Colors.RarityOrange);
}
}
}