Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reforge hooks updates #257

Merged
merged 5 commits into from
Nov 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions ExampleMod/Items/Weapons/ExampleSword.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,23 @@ public class ExampleSword : ModItem
{
public override void SetStaticDefaults()
{
Tooltip.SetDefault("This is a modded sword."); //The (English) text shown below your weapon's name
Tooltip.SetDefault("This is a modded sword."); //The (English) text shown below your weapon's name
}

public override void SetDefaults()
{
item.damage = 50; //The damage of your weapon
item.melee = true; //Is your weapon a melee weapon?
item.width = 40; //Weapon's texture's width
item.height = 40; //Weapon's texture's height
item.useTime = 20; //The time span of using the weapon. Remember in terraria, 60 frames is a second.
item.useAnimation = 20; //The time span of the using animation of the weapon, suggest set it the same as useTime.
item.useStyle = 1; //The use style of weapon, 1 for swinging, 2 for drinking, 3 act like shortsword, 4 for use like life crystal, 5 for use staffs or guns
item.knockBack = 6; //The force of knockback of the weapon. Maximum is 20
item.value = 10000; //The value of the weapon
item.rare = 2; //The rarity of the weapon, from -1 to 13
item.UseSound = SoundID.Item1; //The sound when the weapon is using
item.autoReuse = true; //Whether the weapon can use automatically by pressing mousebutton
item.damage = 50; //The damage of your weapon
item.melee = true; //Is your weapon a melee weapon?
item.width = 40; //Weapon's texture's width
item.height = 40; //Weapon's texture's height
item.useTime = 20; //The time span of using the weapon. Remember in terraria, 60 frames is a second.
item.useAnimation = 20; //The time span of the using animation of the weapon, suggest set it the same as useTime.
item.useStyle = 1; //The use style of weapon, 1 for swinging, 2 for drinking, 3 act like shortsword, 4 for use like life crystal, 5 for use staffs or guns
item.knockBack = 6; //The force of knockback of the weapon. Maximum is 20
item.value = Item.buyPrice(gold: 1); //The value of the weapon
item.rare = 2; //The rarity of the weapon, from -1 to 13
item.UseSound = SoundID.Item1; //The sound when the weapon is using
item.autoReuse = true; //Whether the weapon can use automatically by pressing mousebutton
}

public override void AddRecipes()
Expand All @@ -50,7 +50,7 @@ public override void OnHitNPC(Player player, NPC target, int damage, float knock
{
// Add Onfire buff to the NPC for 1 second
// 60 frames = 1 second
target.AddBuff(BuffID.OnFire, 60);
target.AddBuff(BuffID.OnFire, 60);
}
}
}
25 changes: 23 additions & 2 deletions patches/tModLoader/Terraria.ModLoader/GlobalItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -479,14 +479,35 @@ public virtual void OpenVanillaBag(string context, Player player, int arg)
}

/// <summary>
/// This hooks gets called immediately before an item gets reforged by the Goblin Tinkerer. Useful for storing custom data, since reforging erases custom data.
/// Returns if the normal reforge pricing is applied.
/// If true or false is returned and the price is altered, the price will equal the altered price.
/// The passed reforge price equals the item.value. Vanilla pricing will apply 20% discount if applicable and then price the reforge at a third of that value.
/// </summary>
public virtual bool ReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount)
{
return true;
}

/// <summary>
/// This hook gets called when the player clicks on the reforge button and can afford the reforge.
/// Returns whether the reforge will take place. If false is returned, the PostReforge hook is never called.
/// Reforging preserves modded data on the item.
/// </summary>
public virtual bool NewPreReforge(Item item)
{
return true;
}

// @todo: PreReforge marked obsolete until v0.11
[method: Obsolete("PreReforge now returns a bool to control whether the reforge takes place. For now, use NewPreReforge")]
public virtual void PreReforge(Item item)
{
NewPreReforge(item);
}

/// <summary>
/// This hook gets called immediately after an item gets reforged by the Goblin Tinkerer. Useful for restoring custom data that you saved in PreReforge.
/// This hook gets called immediately after an item gets reforged by the Goblin Tinkerer.
/// Useful for modifying modded data based on the reforge result.
/// </summary>
public virtual void PostReforge(Item item)
{
Expand Down
25 changes: 21 additions & 4 deletions patches/tModLoader/Terraria.ModLoader/ItemLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1009,15 +1009,32 @@ public static void OpenVanillaBag(string context, Player player, int arg)
g.OpenVanillaBag(context, player, arg);
}

private static HookList HookPreReforge = AddHook<Action<Item>>(g => g.PreReforge);
private delegate bool DelegateReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount);
private static HookList HookReforgePrice = AddHook<DelegateReforgePrice>(g => g.ReforgePrice);
/// <summary>
/// Call all ModItem.ReforgePrice, then GlobalItem.ReforgePrice hooks.
/// </summary>
/// <param name="canApplyDiscount"></param>
/// <returns></returns>
public static bool ReforgePrice(Item item, ref int reforgePrice, ref bool canApplyDiscount)
{
bool b = item.modItem?.ReforgePrice(ref reforgePrice, ref canApplyDiscount) ?? true;
foreach (var g in HookReforgePrice.arr)
b &= g.Instance(item).ReforgePrice(item, ref reforgePrice, ref canApplyDiscount);
return b;
}

// @todo: PreReforge marked obsolete until v0.11
private static HookList HookPreReforge = AddHook<Func<Item, bool>>(g => g.NewPreReforge);
/// <summary>
/// Calls ModItem.PreReforge, then all GlobalItem.PreReforge hooks.
/// </summary>
public static void PreReforge(Item item)
public static bool PreReforge(Item item)
{
item.modItem?.PreReforge();
bool b = item.modItem?.NewPreReforge() ?? true;
foreach (var g in HookPreReforge.arr)
g.Instance(item).PreReforge(item);
b &= g.Instance(item).NewPreReforge(item);
return b;
}

private static HookList HookPostReforge = AddHook<Action<Item>>(g => g.PostReforge);
Expand Down
25 changes: 23 additions & 2 deletions patches/tModLoader/Terraria.ModLoader/ModItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -597,14 +597,35 @@ public virtual void OpenBossBag(Player player)
}

/// <summary>
/// This hooks gets called immediately before an item gets reforged by the Goblin Tinkerer. Useful for storing custom data, since reforging erases custom data. Note that, because the ModItem instance will change, the data must be backed up elsewhere, such as in static fields.
/// Returns if the normal reforge pricing is applied.
/// If true or false is returned and the price is altered, the price will equal the altered price.
/// The passed reforge price equals the item.value. Vanilla pricing will apply 20% discount if applicable and then price the reforge at a third of that value.
/// </summary>
public virtual bool ReforgePrice(ref int reforgePrice, ref bool canApplyDiscount)
{
return true;
}

/// <summary>
/// This hook gets called when the player clicks on the reforge button and can afford the reforge.
/// Returns whether the reforge will take place. If false is returned, the PostReforge hook is never called.
/// Reforging preserves modded data on the item.
/// </summary
public virtual bool NewPreReforge()
{
return true;
}

// @todo: PreReforge marked obsolete until v0.11
[method: Obsolete("PreReforge now returns a bool to control whether the reforge takes place. For now, use NewPreReforge")]
public virtual void PreReforge()
{
item.modItem?.NewPreReforge();
}

/// <summary>
/// This hook gets called immediately after an item gets reforged by the Goblin Tinkerer. Useful for restoring custom data that you saved in PreReforge.
/// This hook gets called immediately after an item gets reforged by the Goblin Tinkerer.
/// Useful for modifying modded data based on the reforge result.
/// </summary>
public virtual void PostReforge()
{
Expand Down
10 changes: 9 additions & 1 deletion patches/tModLoader/Terraria/Item.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,22 @@
if (num3 < (float)NPC.sWidth && num3 < num2)
{
num2 = num3;
@@ -43998,7 +_,10 @@
@@ -43998,7 +_,18 @@

public Item Clone()
{
- return (Item)base.MemberwiseClone();
+ Item newItem = (Item)base.MemberwiseClone();
+ newItem.modItem = modItem?.Clone(newItem);
+ newItem.globalItems = globalItems.Select(g => g.Clone(this, newItem)).ToArray();
+ return newItem;
+ }
+
+ public Item CloneWithModdedData(Item dataSource)
+ {
+ Item newItem = (Item)base.MemberwiseClone();
+ newItem.modItem = modItem?.Clone(newItem);
+ newItem.globalItems = dataSource.globalItems.Select(g => g.Clone(dataSource, newItem)).ToArray();
+ return newItem;
}

Expand Down
45 changes: 39 additions & 6 deletions patches/tModLoader/Terraria/Main.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -3239,13 +3239,46 @@
}
}
}
@@ -36640,11 +_,13 @@
if (Main.mouseLeftRelease && Main.mouseLeft && Main.player[Main.myPlayer].BuyItem(num62, -1))
{
@@ -36521,12 +_,18 @@
string text2 = Lang.inter[46].Value + ": ";
if (Main.reforgeItem.type > 0)
{
+ bool canApplyDiscount = true;
int num62 = Main.reforgeItem.value;
- if (Main.player[Main.myPlayer].discount)
- {
- num62 = (int)((double)num62 * 0.8);
- }
- num62 /= 3;
+
+ if (ItemLoader.ReforgePrice(Main.reforgeItem, ref num62, ref canApplyDiscount))
+ {
+ if (canApplyDiscount && Main.player[Main.myPlayer].discount)
+ {
+ num62 = (int)((double)num62 * 0.8);
+ }
+ num62 /= 3;
+ }
+
string text3 = "";
int num63 = 0;
int num64 = 0;
@@ -36637,14 +_,18 @@
}
Main.mouseReforge = true;
Main.player[Main.myPlayer].mouseInterface = true;
- if (Main.mouseLeftRelease && Main.mouseLeft && Main.player[Main.myPlayer].BuyItem(num62, -1))
- {
+ if (Main.mouseLeftRelease && Main.mouseLeft && Main.player[Main.myPlayer].CanBuyItem(num62, -1) && ItemLoader.PreReforge(Main.reforgeItem))
+ {
+ Main.player[Main.myPlayer].BuyItem(num62, -1);
bool favorited = Main.reforgeItem.favorited;
+ ItemLoader.PreReforge(Main.reforgeItem);
Main.reforgeItem.netDefaults(Main.reforgeItem.netID);
Main.reforgeItem.Prefix(-2);
- Main.reforgeItem.netDefaults(Main.reforgeItem.netID);
- Main.reforgeItem.Prefix(-2);
+ Item reforgeItem = new Item();
+ reforgeItem.netDefaults(Main.reforgeItem.netID);
+ reforgeItem.Prefix(-2);
+ Main.reforgeItem = reforgeItem.CloneWithModdedData(Main.reforgeItem);
Main.reforgeItem.position.X = Main.player[Main.myPlayer].position.X + (float)(Main.player[Main.myPlayer].width / 2) - (float)(Main.reforgeItem.width / 2);
Main.reforgeItem.position.Y = Main.player[Main.myPlayer].position.Y + (float)(Main.player[Main.myPlayer].height / 2) - (float)(Main.reforgeItem.height / 2);
Main.reforgeItem.favorited = favorited;
Expand Down
39 changes: 39 additions & 0 deletions patches/tModLoader/Terraria/Player.cs.patch
Original file line number Diff line number Diff line change
Expand Up @@ -3371,6 +3371,45 @@
{
float num3 = 12f;
Vector2 vector = new Vector2(Main.item[j].position.X + (float)(Main.item[j].width / 2), Main.item[j].position.Y + (float)(Main.item[j].height / 2));
@@ -26430,6 +_,38 @@
{
this.inventory[num5] = array[num5].Clone();
}
+ return false;
+ }
+ return true;
+ }
+
+ public bool CanBuyItem(int price, int customCurrency = -1)
+ {
+ if (customCurrency != -1)
+ {
+ return CustomCurrencyManager.BuyItem(this, price, customCurrency);
+ }
+ bool flag;
+ long num = Utils.CoinsCount(out flag, this.inventory, new int[]
+ {
+ 58,
+ 57,
+ 56,
+ 55,
+ 54
+ });
+ long num2 = Utils.CoinsCount(out flag, this.bank.item, new int[0]);
+ long num3 = Utils.CoinsCount(out flag, this.bank2.item, new int[0]);
+ long num4 = Utils.CoinsCount(out flag, this.bank3.item, new int[0]);
+ long num5 = Utils.CoinsCombineStacks(out flag, new long[]
+ {
+ num,
+ num2,
+ num3,
+ num4
+ });
+ if (num5 < (long)price)
+ {
return false;
}
return true;
@@ -26899,7 +_,7 @@
{
int num = 4;
Expand Down