added consumables and buff healing bonuses

This commit is contained in:
2025-08-27 22:15:33 -04:00
parent 5aea4453b0
commit 7b0c9f22ec
7 changed files with 289 additions and 18 deletions

5
Data/ISerializer.cs Normal file
View File

@@ -0,0 +1,5 @@
public interface ISerializer
{
string Serialize<T>(T obj);
T Deserialize<T>(string data);
}

14
Data/JsonSerializer.cs Normal file
View File

@@ -0,0 +1,14 @@
using Newtonsoft.Json;
public class JsonSealizer : ISerializer
{
public string Serialize<T>(T obj)
{
return JsonConvert.SerializeObject(obj, Formatting.Indented);
}
public T Deserialize<T>(string data)
{
return JsonConvert.DeserializeObject<T>(data);
}
}

View File

@@ -1,6 +1,11 @@
using Terraria;
using Terraria.ID;
using Terraria.Net;
using Terraria.Localization;
using TShockAPI;
using TShockAPI.Hooks;
using TerrariaApi.Server;
using TerrariaHealingPlugin.Mappings;
namespace TerrariaHealingPlugin;
@@ -11,51 +16,201 @@ public class HealingPlugin : TerrariaPlugin
public override string Name => "HealingPlugin";
public override string Description => "A healing plugin, duh";
public override Version Version => new Version(1, 0, 0);
private DateTime _lastCheck = DateTime.UtcNow;
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()
{
ServerApi.Hooks.GamePostInitialize.Register(this, OnGamePostInitialize);
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.GamePostInitialize.Deregister(this, OnGamePostInitialize);
ServerApi.Hooks.ServerJoin.Deregister(this, OnServerJoin);
ServerApi.Hooks.GameUpdate.Deregister(this, OnUpdate);
// 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 OnUpdate(EventArgs args)
private void OnPlayerPostLogin(PlayerPostLoginEventArgs e)
{
if ((DateTime.UtcNow - _lastCheck).TotalSeconds >= 1)
{
_lastCheck = DateTime.UtcNow;
ApplyRegenerationBuff(e.Player);
}
foreach (var player in TShock.Players)
{
if (player != null && player.Active)
{
player.Heal(25); // heal all players 25 HP/second
}
}
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 OnGamePostInitialize(EventArgs args)
private void OnGetNetData(GetDataEventArgs args)
{
TShock.Log.Info($"{Name} v{Version} has been initialized.");
// 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);
Console.WriteLine($"Player: {player.Name}, Previous HP: {previousHP}, New HP: {newHP}, Healing Amount: {healingAmount}");
if (healingAmount > 0 && isHealingItem)
{
args.Handled = true;
}
}
private void OnPlayerSlot(object sender, GetDataHandlers.PlayerSlotEventArgs args)
{
Console.WriteLine("In OnPlayerSlot method");
TSPlayer player = args.Player;
short slot = args.Slot;
short newStack = args.Stack;
short itemType = args.Type;
Console.WriteLine($"Player: {player.Name}, Slot: {slot}, New Stack: {newStack}, Item Type: {itemType}");
var isHealingItem = IsHealingItem(itemType);
var isItemConsumed = IsItemBeingConsumed(player, slot, newStack);
Console.WriteLine($"Is Healing Item: {isHealingItem}, Is Item Being Consumed: {isItemConsumed}");
if (isHealingItem && isItemConsumed)
{
var multiplier = _healingItemMappings.GetHealingMultiplier(itemType);
var baseHeal = GetBaseHealAmount(itemType);
var enhancedHeal = (int)(baseHeal * multiplier);
var totalHealing = enhancedHeal + baseHeal;
Console.WriteLine($"Base Heal: {baseHeal}, Multiplier: {multiplier}, Enhanced Heal: {enhancedHeal}");
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 - _lastHealCheck).TotalSeconds >= 1)
{
foreach (var player in TShock.Players)
{
// Console.WriteLine($"Player {player.Name} has the following HP: {player.TPlayer.statLife}");
// if (player != null && player.Active && player.TPlayer.statLife < player.TPlayer.statLifeMax)
// {
// Console.WriteLine($"Player {player.Name} is not healed all the way, let's increase the regen");
// player.TPlayer.statLife += 10;
// player.SendData(PacketTypes.EffectHeal, "", player.Index, 10f);
// Console.WriteLine("Increased health via regen");
// }
// else if (player != null && player.TPlayer.statLife == player.TPlayer.statLifeMax)
// {
// Console.WriteLine($"Player {player.Name} is fully healed.");
// }
}
_lastHealCheck = DateTime.UtcNow;
}
if ((DateTime.UtcNow - _lastBuffCheck).TotalSeconds >= 30)
{
foreach (TSPlayer player in TShock.Players)
{
if (player?.Active == true)
{
ApplyRegenerationBuff(player);
}
}
_lastBuffCheck = DateTime.UtcNow;
}
}
// 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(2, 3600, bypass: true);
Console.WriteLine($"set buff for player {player.Name}");
}
}
private void OnServerJoin(JoinEventArgs args)
{
TShock.Log.Info($"{args.Who} has joined the server.");
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}");
}
}
}

31
Mappings/EquipMappings.cs Normal file
View File

@@ -0,0 +1,31 @@
using Terraria.ID;
namespace TerrariaHealingPlugin.Mappings
{
public class EquipMappings : IMappings
{
public Dictionary<int, short> mappings => new()
{
// FIXME: NOT AT ALL COMPLETED
// choosen designated equipment pieces go here that get a healing boost as an incentive
// ItemID | Healing Amount
{ ItemID.FleshKnuckles, 20 },
{ ItemID.PaladinsShield, 20 },
{ ItemID.MedicatedBandage, 20 },
{ ItemID.LifeforcePotion, 80 },
{ ItemID.WormScarf, 10 },
{ ItemID.CelestialShell, 10 },
{ ItemID.CelestialCuffs, 10 },
};
public double GetHealingMultiplier(int itemType)
{
return itemType switch
{
// nothing here, yet ;)
_ => 1,
};
}
}
}

View File

@@ -0,0 +1,44 @@
using Terraria.ID;
namespace TerrariaHealingPlugin.Mappings
{
public class HealingMappings : IMappings
{
public Dictionary<int, short> mappings => new()
{
// choosen designated items go here that get a healing boost as an incentive
// ItemID | Healing Amount
{ ItemID.Mushroom, 15 },
{ ItemID.Heart, 20},
{ ItemID.BottledWater, 25 },
{ ItemID.LesserHealingPotion, 50 },
{ ItemID.BottledHoney, 80 },
{ ItemID.LesserRestorationPotion, 80 },
{ ItemID.Eggnog, 80 },
{ ItemID.StrangeBrew, 80 },
{ ItemID.RestorationPotion, 90 },
{ ItemID.HealingPotion, 100 },
{ ItemID.Honeyfin, 120 },
{ ItemID.GreaterHealingPotion, 150 },
{ ItemID.SuperHealingPotion, 200 },
};
public double GetHealingMultiplier(int itemType)
{
return itemType switch
{
ItemID.Mushroom => ((0.1 + 1)),
ItemID.Heart => ((0.1 + 1)),
ItemID.BottledWater => ((0.1 + 1)),
ItemID.LesserHealingPotion => ((0.2 + 1)),
ItemID.LesserRestorationPotion => ((0.2 + 1)),
ItemID.BottledHoney => ((0.2 + 1)),
ItemID.HealingPotion => ((0.5 + 1)),
ItemID.Honeyfin => ((0.5 + 1)),
ItemID.GreaterHealingPotion => ((0.5 + 1)),
ItemID.SuperHealingPotion => ((0.5 + 1)),
_ => 1,
};
}
}
}

5
Mappings/IMappings.cs Normal file
View File

@@ -0,0 +1,5 @@
public interface IMappings
{
public Dictionary<int, short> mappings { get; }
public double GetHealingMultiplier(int itemType);
}

17
Player.cs Normal file
View File

@@ -0,0 +1,17 @@
using Terraria.ID;
using TShockAPI;
namespace TerrariaHealingPlugin
{
public class Player
{
public TSPlayer player { get; set; }
public int healAmount { get; set; } = 0;
public int healItem { get; set; } = ItemID.None;
public Player(TSPlayer player)
{
this.player = player;
}
}
}