Skip to content

Commit

Permalink
added API for modifying the player's max health/mana stats
Browse files Browse the repository at this point in the history
- also modified all vanilla uses of checking if statLifeMax or statManaMax were above/below a certain number with checks for consumed item counts in order to properly account for the new API
- updated ExampleLifeFruitPlayer to account for the new API
  • Loading branch information
absoluteAquarian committed Sep 4, 2022
1 parent 0354079 commit 7ca3be4
Show file tree
Hide file tree
Showing 9 changed files with 339 additions and 12 deletions.
8 changes: 4 additions & 4 deletions ExampleMod/Content/Items/Consumables/ExampleLifeFruit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ public class ExampleLifeFruitPlayer : ModPlayer
{
public int exampleLifeFruits;

public override void ResetEffects() {
// Increasing health in the ResetEffects hook in particular is important so it shows up properly in the player select menu
// and so that life regeneration properly scales with the bonus health
Player.statLifeMax2 += exampleLifeFruits * ExampleLifeFruit.LifePerFruit;
public override void ModifyMaxStats(ref int lifeMax, ref int manaMax) {
// "lifeMax" is added as a shortcut for "player.statLifeMax"
// Modifying "lifeMax" here allows the changes to appear in the player select menu as well
lifeMax += exampleLifeFruits * ExampleLifeFruit.LifePerFruit;
}

public override void SyncPlayer(int toWho, int fromWho, bool newPlayer) {
Expand Down
15 changes: 15 additions & 0 deletions patches/tModLoader/Terraria/Chest.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,21 @@
}

public void SetupShop(int type) {
@@ -2015,12 +_,12 @@
num++;
array[num].SetDefaults(1979);
num++;
- if (Main.player[Main.myPlayer].statLifeMax >= 400) {
+ if (Main.player[Main.myPlayer].ConsumedLifeCrystals == Player.LifeCrystalMax) {
array[num].SetDefaults(1977);
num++;
}

- if (Main.player[Main.myPlayer].statManaMax >= 200) {
+ if (Main.player[Main.myPlayer].ConsumedManaCrystals == Player.ManaCrystalMax) {
array[num].SetDefaults(1978);
num++;
}
@@ -2611,6 +_,7 @@
array[num++].SetDefaults(4921);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@
namespace Terraria.GameContent.Achievements
{
public class AchievementsHelper
@@ -99,7 +_,7 @@
if (player.statManaMax > 20)
@@ -96,10 +_,10 @@
}
}

- if (player.statManaMax > 20)
+ if (player.ConsumedManaCrystals > 0)
Main.Achievements.GetCondition("STAR_POWER", "Use").Complete();

- if (player.statLifeMax == 500 && player.statManaMax == 200)
+ if (player.statLifeMax >= 500 && player.statManaMax >= 200)
+ if (player.ConsumedLifeCrystals == Player.LifeCrystalMax && player.ConsumedLifeFruit == Player.LifeFruitMax && player.ConsumedManaCrystals == Player.ManaCrystalMax)
Main.Achievements.GetCondition("TOPPED_OFF", "Use").Complete();

if (player.miscEquips[4].type > 0)
Expand All @@ -29,13 +33,13 @@
case 1:
Main.Achievements.GetCondition("STAR_POWER", "Use").Complete();
- if (player.statLifeMax == 500 && player.statManaMax == 200)
+ if (player.statLifeMax >= 500 && player.statManaMax >= 200)
+ if (player.ConsumedLifeCrystals == Player.LifeCrystalMax && player.ConsumedLifeFruit == Player.LifeFruitMax && player.ConsumedManaCrystals == Player.ManaCrystalMax)
Main.Achievements.GetCondition("TOPPED_OFF", "Use").Complete();
break;
case 2:
Main.Achievements.GetCondition("GET_A_LIFE", "Use").Complete();
- if (player.statLifeMax == 500 && player.statManaMax == 200)
+ if (player.statLifeMax >= 500 && player.statManaMax >= 200)
+ if (player.ConsumedLifeCrystals == Player.LifeCrystalMax && player.ConsumedLifeFruit == Player.LifeFruitMax && player.ConsumedManaCrystals == Player.ManaCrystalMax)
Main.Achievements.GetCondition("TOPPED_OFF", "Use").Complete();
break;
case 3:
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,22 @@
using Terraria.UI;
using Terraria.UI.Gamepad;

@@ -1019,8 +_,15 @@
private void SetupPlayerStatsAndInventoryBasedOnDifficulty() {
int num = 0;
if (_player.difficulty == 3) {
+ _player.statLifeMax = 100;
+ _player.statManaMax = 20;
+ PlayerLoader.ModifyBaseMaxStats(_player);
+ _player.statLife = _player.statLifeMax;
+ _player.statMana = _player.statManaMax;
+ /*
_player.statLife = (_player.statLifeMax = 100);
_player.statMana = (_player.statManaMax = 20);
+ */
_player.inventory[num].SetDefaults(6);
_player.inventory[num++].Prefix(-1);
_player.inventory[num].SetDefaults(1);
@@ -1055,6 +_,8 @@

_player.savedPerPlayerFieldsThatArentInThePlayerClass = new Player.SavedPlayerDataWithAnnoyingRules();
Expand Down
179 changes: 179 additions & 0 deletions patches/tModLoader/Terraria/Main.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -2941,6 +2941,140 @@
spriteBatch.Draw(TextureAssets.Dust.Value, dust.position - screenPosition, dust.frame, newColor, dust.GetVisualRotation(), new Vector2(4f, 4f), scale, SpriteEffects.None, 0f);
if (dust.color.PackedValue != 0) {
Microsoft.Xna.Framework.Color color6 = dust.GetColor(newColor);
@@ -28506,11 +_,11 @@

private static void HelpText() {
bool flag = false;
- if (player[myPlayer].statLifeMax > 100)
+ if (player[myPlayer].ConsumedLifeCrystals > 0)
flag = true;

bool flag2 = false;
- if (player[myPlayer].statManaMax > 20)
+ if (player[myPlayer].ConsumedManaCrystals > 0)
flag2 = true;

bool flag3 = true;
@@ -28932,7 +_,7 @@
return;
}

- if (helpText == 202 && !hardMode && player[myPlayer].statLifeMax >= 140) {
+ if (helpText == 202 && !hardMode && player[myPlayer].ConsumedLifeCrystals >= 2) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1120");
return;
}
@@ -28942,12 +_,12 @@
return;
}

- if (helpText == 204 && !NPC.downedGoblins && player[myPlayer].statLifeMax >= 200 && WorldGen.shadowOrbSmashed) {
+ if (helpText == 204 && !NPC.downedGoblins && player[myPlayer].ConsumedLifeCrystals >= 5 && WorldGen.shadowOrbSmashed) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1122");
return;
}

- if (helpText == 205 && hardMode && !NPC.downedPirates && player[myPlayer].statLifeMax >= 200) {
+ if (helpText == 205 && hardMode && !NPC.downedPirates && player[myPlayer].ConsumedLifeCrystals >= 5) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1123");
return;
}
@@ -29026,7 +_,7 @@
return;
}

- if (helpText == 1050 && !NPC.downedBoss1 && player[myPlayer].statLifeMax < 200) {
+ if (helpText == 1050 && !NPC.downedBoss1 && player[myPlayer].ConsumedLifeCrystals < 5) {
npcChatText = Lang.dialog(211);
return;
}
@@ -29036,22 +_,22 @@
return;
}

- if (helpText == 1052 && !NPC.downedBoss1 && player[myPlayer].statLifeMax >= 200 && player[myPlayer].statDefense > 10) {
+ if (helpText == 1052 && !NPC.downedBoss1 && player[myPlayer].ConsumedLifeCrystals >= 5 && player[myPlayer].statDefense > 10) {
npcChatText = Lang.dialog(WorldGen.crimson ? 404 : 213);
return;
}

- if (helpText == 1053 && NPC.downedBoss1 && !NPC.downedBoss2 && player[myPlayer].statLifeMax < 300) {
+ if (helpText == 1053 && NPC.downedBoss1 && !NPC.downedBoss2 && player[myPlayer].ConsumedLifeCrystals < 10) {
npcChatText = Lang.dialog(214);
return;
}

- if (helpText == 1054 && NPC.downedBoss1 && !NPC.downedBoss2 && !WorldGen.crimson && player[myPlayer].statLifeMax >= 300) {
+ if (helpText == 1054 && NPC.downedBoss1 && !NPC.downedBoss2 && !WorldGen.crimson && player[myPlayer].ConsumedLifeCrystals >= 10) {
npcChatText = Lang.dialog(215);
return;
}

- if (helpText == 1055 && NPC.downedBoss1 && !NPC.downedBoss2 && !WorldGen.crimson && player[myPlayer].statLifeMax >= 300) {
+ if (helpText == 1055 && NPC.downedBoss1 && !NPC.downedBoss2 && !WorldGen.crimson && player[myPlayer].ConsumedLifeCrystals >= 10) {
npcChatText = Lang.dialog(216);
return;
}
@@ -29061,22 +_,22 @@
return;
}

- if (helpText == 1057 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].statLifeMax < 400) {
+ if (helpText == 1057 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].ConsumedLifeCrystals < Player.LifeCrystalMax) {
npcChatText = Lang.dialog(218);
return;
}

- if (helpText == 1058 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].statLifeMax >= 400) {
+ if (helpText == 1058 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].ConsumedLifeCrystals == Player.LifeCrystalMax) {
npcChatText = Lang.dialog(219);
return;
}

- if (helpText == 1059 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].statLifeMax >= 400) {
+ if (helpText == 1059 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].ConsumedLifeCrystals == Player.LifeCrystalMax) {
npcChatText = Lang.dialog(220);
return;
}

- if (helpText == 1060 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].statLifeMax >= 400) {
+ if (helpText == 1060 && NPC.downedBoss1 && NPC.downedBoss2 && NPC.downedBoss3 && !hardMode && player[myPlayer].ConsumedLifeCrystals == Player.LifeCrystalMax) {
npcChatText = Lang.dialog(221);
return;
}
@@ -29091,12 +_,12 @@
return;
}

- if (helpText == 1140 && NPC.downedBoss1 && !NPC.downedBoss2 && WorldGen.crimson && player[myPlayer].statLifeMax >= 300) {
+ if (helpText == 1140 && NPC.downedBoss1 && !NPC.downedBoss2 && WorldGen.crimson && player[myPlayer].ConsumedLifeCrystals >= 10) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1140");
return;
}

- if (helpText == 1141 && NPC.downedBoss1 && !NPC.downedBoss2 && WorldGen.crimson && player[myPlayer].statLifeMax >= 300) {
+ if (helpText == 1141 && NPC.downedBoss1 && !NPC.downedBoss2 && WorldGen.crimson && player[myPlayer].ConsumedLifeCrystals >= 10) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1141");
return;
}
@@ -29106,7 +_,7 @@
return;
}

- if (helpText == 1143 && NPC.downedBoss2 && !NPC.downedQueenBee && player[myPlayer].statLifeMax >= 300) {
+ if (helpText == 1143 && NPC.downedBoss2 && !NPC.downedQueenBee && player[myPlayer].ConsumedLifeCrystals >= 10) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1143");
return;
}
@@ -29136,7 +_,7 @@
return;
}

- if (helpText == 1149 && hardMode && NPC.downedMechBossAny && player[myPlayer].statLifeMax < 500) {
+ if (helpText == 1149 && hardMode && NPC.downedMechBossAny && player[myPlayer].ConsumedLifeCrystals == Player.LifeCrystalMax && player[myPlayer].ConsumedLifeFruit < Player.LifeFruitMax) {
npcChatText = Language.GetTextValue("GuideHelpTextSpecific.Help_1149");
return;
}
@@ -29206,8 +_,8 @@
int num = (mouseTextColor * 2 + 255) / 3;
Microsoft.Xna.Framework.Color textColor = new Microsoft.Xna.Framework.Color(num, num, num, num);
Expand Down Expand Up @@ -4990,6 +5124,24 @@

if (invasionX > (double)spawnTileX) {
invasionX -= num;
@@ -49722,7 +_,7 @@

int num = 0;
for (int i = 0; i < 255; i++) {
- if (player[i].active && player[i].statLifeMax >= 200)
+ if (player[i].active && player[i].ConsumedLifeCrystals >= 5)
num++;
}

@@ -49738,7 +_,7 @@

int num = 0;
for (int i = 0; i < 255; i++) {
- if (player[i].active && player[i].statLifeMax >= 200)
+ if (player[i].active && player[i].ConsumedLifeCrystals >= 5)
num++;
}

@@ -49871,7 +_,7 @@
Netplay.Clients[k].TimeOutTimer += 3;

Expand Down Expand Up @@ -5097,6 +5249,15 @@
if (!NPC.downedSlimeKing)
num3 /= 2;

@@ -50069,7 +_,7 @@

bool flag = false;
for (int i = 0; i < 255; i++) {
- if (Main.player[i].active && Main.player[i].statLifeMax > 140 && Main.player[i].statDefense > 8)
+ if (Main.player[i].active && Main.player[i].ConsumedLifeCrystals > 2 && Main.player[i].statDefense > 8)
flag = true;
}

@@ -50141,6 +_,7 @@
WorldGen.UnspawnTravelNPC();
}
Expand All @@ -5115,6 +5276,24 @@
int num8 = 0;
for (int j = 0; j < 200; j++) {
if (npc[j].active && npc[j].townNPC && npc[j].type != 37 && npc[j].type != 453)
@@ -50288,7 +_,7 @@
if (!NPC.downedBoss1 && netMode != 1) {
bool flag = false;
for (int i = 0; i < 255; i++) {
- if (player[i].active && player[i].statLifeMax >= 200 && player[i].statDefense > 10) {
+ if (player[i].active && player[i].ConsumedLifeCrystals >= 5 && player[i].statDefense > 10) {
flag = true;
break;
}
@@ -50360,7 +_,7 @@

if (!WorldGen.spawnEye && moonPhase != 4 && rand.Next(maxValue) == 0 && netMode != 1) {
for (int m = 0; m < 255; m++) {
- if (player[m].active && player[m].statLifeMax > 120) {
+ if (player[m].active && player[m].ConsumedLifeCrystals > 1) {
bloodMoon = true;
break;
}
@@ -50505,6 +_,11 @@
}

Expand Down
29 changes: 29 additions & 0 deletions patches/tModLoader/Terraria/ModLoader/ModPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,35 @@ public virtual void Initialize() {
public virtual void ResetEffects() {
}

/// <summary>
/// Allows you to modify the player's base max stats before increases from the Life Crystal, Life Fruit and Mana Crystal are applied
/// </summary>
/// <param name="player"></param>
/// <param name="lifeMax">The base maximum health. Defaults to 100</param>
/// <param name="manaMax">The base maximum mana. Defaults to 20</param>
public virtual void ModifyBaseMaxStats(ref int lifeMax, ref int manaMax) {
}

/// <summary>
/// This is called before <see cref="ModifyMaxStats(ref int, ref int)"/>, but after the intial increases from the Life Crystal, Life Fruit, Mana Crystal and <see cref="ModifyBaseMaxStats(ref int, ref int)"/> are applied
/// </summary>
public virtual void PreModifyMaxStats(int lifeMax, int manaMax) {
}

/// <summary>
/// Allows you to modify the player's max stats. This hook runs after vanilla increases from the Life Crystal, Life Fruit and Mana Crystal are applied
/// </summary>
/// <param name="lifeMax">The base maximum health. Defaults to 100</param>
/// <param name="manaMax">The base maximum mana. Defaults to 20</param>
public virtual void ModifyMaxStats(ref int lifeMax, ref int manaMax) {
}

/// <summary>
/// This is called after <see cref="ModifyMaxStats(ref int, ref int)"/>
/// </summary>
public virtual void PostModifyMaxStats(int lifeMax, int manaMax) {
}

/// <summary>
/// Similar to UpdateDead, except this is only called when the player is dead. If this is called, then ResetEffects will not be called.
/// </summary>
Expand Down
53 changes: 53 additions & 0 deletions patches/tModLoader/Terraria/ModLoader/PlayerLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,59 @@ public static void ResetEffects(Player player) {
}
}

private delegate void DelegateModifyBaseMaxStats(Player player, ref int healthMax, ref int manaMax);
private static HookList HookModifyBaseMaxStats = AddHook<DelegateModifyBaseMaxStats>(p => p.ModifyBaseMaxStats);

public static void ModifyBaseMaxStats(Player player) {
foreach (var modPlayer in HookModifyBaseMaxStats.Enumerate(player.modPlayers)) {
modPlayer.ModifyBaseMaxStats(ref player.statLifeMax, ref player.statManaMax);
}
}

private delegate void DelegatePreModifyMaxStats(int healthMax, int manaMax);
private static HookList HookPreModifyMaxStats = AddHook<DelegatePreModifyMaxStats>(p => p.PreModifyMaxStats);

public static void PreModifyMaxStats(Player player) {
foreach (var modPlayer in HookPreModifyMaxStats.Enumerate(player.modPlayers)) {
modPlayer.PreModifyMaxStats(player.statLifeMax, player.statManaMax);
}
}

private delegate void DelegateModifyMaxStats(ref int healthMax, ref int manaMax);
private static HookList HookModifyMaxStats = AddHook<DelegateModifyMaxStats>(p => p.ModifyMaxStats);

public static void ModifyMaxStats(Player player) {
foreach (var modPlayer in HookModifyMaxStats.Enumerate(player.modPlayers)) {
modPlayer.ModifyMaxStats(ref player.statLifeMax, ref player.statManaMax);
}
}

private delegate void DelegatePostModifyMaxStats(int healthMax, int manaMax);
private static HookList HookPostModifyMaxStats = AddHook<DelegatePostModifyMaxStats>(p => p.PostModifyMaxStats);

public static void PostModifyMaxStats(Player player) {
foreach (var modPlayer in HookPostModifyMaxStats.Enumerate(player.modPlayers)) {
modPlayer.PostModifyMaxStats(player.statLifeMax, player.statManaMax);
}
}

public static void UpdateMaxStats(Player player) {
player.statLifeMax = 100;
player.statManaMax = 20;

ModifyBaseMaxStats(player);

player.statLifeMax += player.ConsumedLifeCrystals * 20 + player.ConsumedLifeFruit * 5;
player.statManaMax += player.ConsumedManaCrystals * 20;

PreModifyMaxStats(player);
ModifyMaxStats(player);
PostModifyMaxStats(player);

player.statLifeMax2 = player.statLifeMax;
player.statManaMax2 = player.statManaMax;
}

private static HookList HookUpdateDead = AddHook<Action>(p => p.UpdateDead);

public static void UpdateDead(Player player) {
Expand Down
Loading

0 comments on commit 7ca3be4

Please sign in to comment.