tModLoader

tModLoader

Artificer's Accessories
 This topic has been pinned, so it's probably important
BlockCrusader  [developer] 21 Jan, 2024 @ 6:30pm
Cross-Mod & Mod.Call Guide:
Do you want to add Ability Accessories to your own mod? Want to add your own modifications to Ability Cooldown times? This guide will give the basic rundown on how to do so via. Mod.Calls. Do note this guides assumes you have some knowledge of modding with tML (For example, you should be comfortable working with the ModItem and ModPlayer classes)


AddArtificerAbility:
This Call allows you to define your own Abilities for use via. Artificer's Accessories Ability system. Thus, using this Call will allow you to make your very own Ability Accessories for your mod.

Paramenters
Below is a list of the parameters for the Call you'll need to use to define your Ability Accessory to the mod, in the order they should be inputted.
Also remember that the Call should be made in the PostSetupContent hook of a ModSystem class, and that Artificer's Accessories has the internal name "ArtificerMod".

0: Name:
This is a string and should always be "AddArtificerAbility". This tells Artificer's Accessories what Call you're making.

1: AccessoryID:
This is an int and should be set to the item.type of the accessory that the ability is associated with.

2: CooldownTime:
This is an int and should be how long of an Ability Cooldown your ability has. Keep in mind this is measured in ticks, not seconds (60 ticks = 1 second in Terraria).

3: AbilityDescription:
This is a string and should be a description of what your ability does (Ex: "Cures you of the Poisoned and Acid Venom debuffs"). It is possible and recommended to utilize Localization keys and retrieve them as strings via. Language.GetTextValue.

4: PlaceholderTooltipName:
This is a string. Artificer's Accessories requires a placeholder tooltip line that it can replace with its associated Ability information (Ability Description, Cooldown time, etc.); this string should be the name of the (placeholder) TooltipLine you want replaced. Here is an example of how to get the line name you need;
TestAbilityItem: { DisplayName: Test Ability Item Tooltip: ''' Increases damage by 10% // This is "Tooltip0" [placeholder] // This is "Tooltip1" 'Ooo, flavor text' // This is "Tooltip2" ''' }
If there were to be another line after "'Ooo, flavor text'", that would be Tooltip3, and so on. In the example above, you would input "Tooltip1" in the Call. Make sure to add placeholder lines in your tooltips as needed!

5: CanActivate:
This is a delegate function that should accept a Player and return a bool. This should return whether or not your ability is available to activate (Ex: Is its associated accessory equipped?).

6: UseAbility:
This is a delegate function that should accept a Player and return a bool. This will be called when the ability is activated; it should carry out the effects of your ability. Normally, this should always return true, but you can prevent Ability Cooldown from being applied by returning false (Ex: For if the ability somehow fails).

Example Call:
artificerMod.Call( "AddArtificerAbility", ModContent.ItemType<TestAbilityItem>(), 1200, Language.GetTextValue("Mods.MyMod.Items.TestAbilityItem.AbilityDesc"), "Tooltip1", TestAbilityItem.CanUseAbility, TestAbilityItem.ActivateAbility);



Requirements
At minimum, you'll need the following to make an Ability Accessory;

A ModItem Class:
This will be the accessory/item you associate with your ability

A ModSystem Class:
This is where you will make your Call(s), in the PostSetupContent hook

Functions for CanActivate and UseAbility:
See Call parameters for more details. These can be placed anywhere so long as you have access to them when making the Call. I recommend keeping them in your ModItem Class to keep things organized.



Example:
Here is an annotated examples of making an Ability Accessory with the Call;

ModItem Class:
This will define the accessory/item that is associated with your Ability
public class TestAbilityItem : ModItem { /* It is highly recommended you only load your item when Artificer's Accessories is enabled. Your item won't break without it, but there will be artifacts in the mod's tooltip due to how the system works */ public override bool IsLoadingEnabled(Mod mod) { return ModLoader.HasMod("ArtificerMod"); } /* SetDefaults() and any other associated hooks you desire to use for your item */ /* Make sure to associate a bool in a ModPlayer to track when the item is equipped! */ public override void UpdateAccessory(Player player, bool hideVisual) { player.GetModPlayer<MyModPlayer>().testAbility = true; } /* Remember that you can technically put these next two functions anywhere, so long as it is accessible to the ModSystem where you make your Call. I've kept them with the ModItem in this example in order to keep things organized. */ // Used to check if this Ability is available for use public static bool CanUseAbility(Player player) { /* Here we utilize the bool from our ModPlayer to verify the ability's associated item is equipped */ return player.GetModPlayer<MyModPlayer>().testAbility; } // Used to enact the effects of an ability public static bool ActivateAbility(Player player) { // For simplicity's sake let's just heal the player for this ability player.Heal(50); // Remember, if you return false, Ability Cooldown won't be applied return true; } }

ModSystem Class:
This Class is used to make the Call to Artificer's Accessories and pass it the needed data to define your Ability for use by Artificer
public class ArtificerIntegration : ModSystem { public override void PostSetupContent() { // First ensure Artificer's Accessories in enabled before Calling it! if (!ModLoader.TryGetMod("ArtificerMod", out Mod artificerMod)) { return; } // Make the Call. Remember the parameters described above artificerMod.Call( "AddArtificerAbility", ModContent.ItemType<TestAbilityItem>(), 1200, "Heals the player for 50 HP", "Tooltip1", TestAbilityItem.CanUseAbility, TestAbilityItem.ActivateAbility); // Note that each of your Ability Accessories requires its own Call! } } }

AddAbilityCooldownMod:
This Call lets you add your own modifications to Ability Cooldown times, allowing you to make accessories that function similarly to the Energy Cell, Artificer Emblem, etc.

Paramenters
Below is a list of the parameters for the Call you'll need to use to define your Cooldown modifcation to the mod, in the order they should be inputted.
Also remember that the Call should be made in the PostSetupContent hook of a ModSystem class, and that Artificer's Accessories has the internal name "ArtificerMod".

0: Name:
This is a string and should always be "AddAbilityCooldownMod". This tells Artificer's Accessories what Call you're making.

1: CooldownMultiplier:
This is an float and is the multiplier that will be enacted upon the duration of Ability Cooldown. It should always be a value above 0!. Values between 0 and 1 decrease duration, and values above 1 increase duration.

2: ShouldApply:
This is a delegate function that should accept a Player and return a bool. This should return whether or not the multiplier should be in effect (Ex: An associated buff or accessory is active/equipped).

3: StateChanged:
This is a delegate function that should accept a Player and return a bool. This should return true whenever your multiplier has just turned on/off. This is used to dynamically adjust the cooldown whenever the multiplier activates/deactivates. This may sound confusing, so please see the annotated example code below!

Example Call:
artificerMod.Call( "AddAbilityCooldownMod", 0.7f, TestPlayer.TestCooldownActive, TestPlayer.TestCooldownStateChange);


Requirements
At minimum, you'll need the following to make a modification to Ability Cooldown times;

A ModPlayer Class:
It is preferable to use a ModPlayer to keep track of any effects associated with your cooldown

A ModSystem Class:
This is where you will make your Call(s), in the PostSetupContent hook

Functions for ShouldApply and StateChanged:
See Call parameters for more details. These can be placed anywhere so long as you have access to them when making the Call. Ideally these should be placed in your ModPlayer class to keep things organized.


Example:
Here is an annotated examples of making an Ability Accessory with the Call;

ModPlayerClass:
This class will keep track of effects associated with your modification
public class TestPlayer : ModPlayer { public bool testCooldown; // Track when the modification is active public bool testCooldownFlag; // Crucial for the StateChange function! /* Don't forget to have some effect (Ex: A buff or accessory) to set testCooldown to true! */ public override void ResetEffects() { // The flag tracks the state of testCooldown from the previous update! testCooldownFlag = testCooldown; testCooldown = false; } public static bool TestCooldownActive(Player player) { return player.GetModPlayer<TestPlayer >().testCooldown; } public static bool TestCooldownStateChange(Player player) { /* Here, comparing testCooldown to its flag lets us know when its state has recently changed (true -> false, false -> true) */ return player.GetModPlayer<TestPlayer >().testCooldown != player.GetModPlayer<TestPlayer >().testCooldownFlag; } }

ModSystem Class:
This Class is used to make the Call to Artificer's Accessories and pass it the needed data to define your Ability for use by Artificer
public class ArtificerIntegration : ModSystem { public override void PostSetupContent() { // First ensure Artificer's Accessories in enabled before Calling it! if (!ModLoader.TryGetMod("ArtificerMod", out Mod artificerMod)) { return; } // Make the Call. Remember the parameters described above artificerMod.Call( "AddAbilityCooldownMod", 0.7f, TestPlayer.TestCooldownActive, TestPlayer.TestCooldownStateChange); // Note that each of your modifications requires its own Call! } } }

AddCooldownAccessory:
This is a very simple call which only has a single parameter (Other than their name), that being the item.type of the accessory you wish to make count as cooldown-related accessory.
This will prevent said accessory from being equipped with other cooldown-reducing accessories.
Examples of these in Artificer's Accessories itself include the Energy Cell, Artificer Emblem, and Clockwork Stopwatch.
This should be called in a mod system in PostSetupContent like the previous Calls described.

CountAsArtificerSetBonus, GetTotalCooldownMod, IsAbilityAccEquipped, IsCooldownAccEquipped, IsAbilityCooldownActive:
These are some more simple calls that only have a single parameter (Other than their name), that being the player.whoAmI of the Player you want to check against. These can be called just about anytime after completing loading, typically in places like an item's UpdateAccessory hook or similar.

CountAsArtificerSetBonus:
Makes it so that the player associated with the given player.whoAmI won't be penalized for not having an Artificer Set Bonus from an Artificer's Accessories armor set. Ideally called in UpdateArmorSet (Part of ModItem class) for making your own Artificer armor sets (Note that you must implement your own bonus accessory slots).

GetTotalCooldownMod:
Returns the total multiplier on Ability Cooldown times for the player associated with the given player.whoAmI.

IsAbilityAccEquipped:
Returns if the player associated with the given player.whoAmI has an ability accessory equipped.

IsCooldownAccEquipped:
Returns if the player associated with the given player.whoAmI has an accessory which reduces ability cooldowns equipped. This includes any accessories registered as such via. AddCooldownAccessory, as well as the following accessories from Artificer's Accessories equipped;
  • Energy Cell
  • Artificer Emblem
  • Cryo Cooling Cell
  • Clockwork Stopwatch
  • Nova Emblem

IsAbilityCooldownActive:
Returns if the player associated with the given player.whoAmI currently has the Ability Cooldown debuff.

Example:
Here, we call IsAbilityAccEquipped in an item's UpdateAccessory hook and apply a damage boost when IsAbilityAccEquipped returns true;
public override void UpdateAccessory(Player player, bool hideVisual) { // Don't try to call Artificer's Accessories if it isn't loaded! if (!ModLoader.TryGetMod("ArtificerMod", out Mod artificerMod)) { return; } if (artificerMod.Call("IsAbilityAccEquipped", player.whoAmI) is bool abilityAccEquip && abilityAccEquip) { player.GetDamage(DamageClass.Generic) += 0.1f; } }

For further help with using Mod.Call, please check out this guide on tModLoader's GitHub![github.com]
Last edited by BlockCrusader; 6 Feb, 2024 @ 10:06am
< >
Showing 1-2 of 2 comments
Hazard 21 Sep, 2024 @ 11:18am 
Did anyone made one?
No? :(
BlockCrusader  [developer] 21 Sep, 2024 @ 11:20am 
Originally posted by ℌ𝔞𝔷𝔞𝔯𝔡:
Did anyone made one?
No? :(
Make an add-on for Artificer? Not that I know of, aside from my two official add-ons (Linked in mod's workshop description).
< >
Showing 1-2 of 2 comments
Per page: 1530 50