Skip to content

Commit

Permalink
Add BuffDefinition Option (#3827)
Browse files Browse the repository at this point in the history
* Add BuffDefinition Option

* Missing WrapIt code, typos

---------

Co-authored-by: JavidPack <javidpack@gmail.com>
  • Loading branch information
EdoanR and JavidPack committed Sep 24, 2023
1 parent de41888 commit d45a528
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ public class ModConfigShowcaseDataTypes : ModConfig
public SimpleData SomeClassA;
// EntityDefinition classes store the identity of an Entity (Item, NPC, Projectile, etc) added by a mod or vanilla. Only the identity is preserved, not other mod data or stack.
// When using XDefinition classes, you can the .Type property to get the ID of the item. You can use .IsUnloaded to check if the item in question is loaded.
// Note that since configs load before content, modders using XDefinition classes in ModConfig code must use the constuctors with string parameters. Using ModContent.XType<ClassName>() in the constuctor taking an int, for example, will lead to troublesome bugs.
// Note that since configs load before content, modders using XDefinition classes in ModConfig code must use the constructors with string parameters. Using ModContent.XType<ClassName>() in the constructor taking an int, for example, will lead to troublesome bugs.
public ItemDefinition itemDefinitionExample;
public NPCDefinition npcDefinitionExample = new NPCDefinition(NPCID.Bunny);
public ProjectileDefinition projectileDefinitionExample = new ProjectileDefinition("ExampleMod", nameof(Content.Projectiles.ExampleHomingProjectile));
public BuffDefinition buffDefinitionExample = new BuffDefinition("ExampleMod", nameof(Content.Buffs.ExampleDefenseBuff));

// Data Structures of reference types
public Dictionary<PrefixDefinition, float> prefixDefinitionDictionaryExample = new Dictionary<PrefixDefinition, float>() {
Expand Down
6 changes: 3 additions & 3 deletions ExampleMod/Localization/TranslationsNeeded.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
en-US, 526/526, 100%, missing 0
ru-RU, 6/526, 1%, missing 520
zh-Hans, 1/526, 0%, missing 525
en-US, 527/527, 100%, missing 0
ru-RU, 6/527, 1%, missing 521
zh-Hans, 1/527, 0%, missing 526
5 changes: 5 additions & 0 deletions ExampleMod/Localization/en-US_Mods.ExampleMod.Configs.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ ModConfigShowcaseDataTypes: {
Label: PrefixDefinition Dictionary Example
Tooltip: ""
}

buffDefinitionExample: {
Label: BuffDefinition Example
Tooltip: ""
}
}

ModConfigShowcaseDefaultValues: {
Expand Down
5 changes: 5 additions & 0 deletions ExampleMod/Localization/ru-RU_Mods.ExampleMod.Configs.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ ModConfigShowcaseDataTypes: {
// Label: PrefixDefinition Dictionary Example
// Tooltip: ""
}

buffDefinitionExample: {
// Label: BuffDefinition Example
// Tooltip: ""
}
}

ModConfigShowcaseDefaultValues: {
Expand Down
5 changes: 5 additions & 0 deletions ExampleMod/Localization/zh-Hans_Mods.ExampleMod.Configs.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ ModConfigShowcaseDataTypes: {
// Label: PrefixDefinition Dictionary Example
// Tooltip: ""
}

buffDefinitionExample: {
// Label: BuffDefinition Example
// Tooltip: ""
}
}

ModConfigShowcaseDefaultValues: {
Expand Down
32 changes: 30 additions & 2 deletions patches/tModLoader/Terraria/ModLoader/Config/EntityDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public TagCompound SerializeData()
}

/// <summary>
/// ItemDefinition represents an Item identity. A typical use for this class is usage in ModConfig, perhapse to facilitate an Item tweaking mod.
/// ItemDefinition represents an Item identity. A typical use for this class is usage in ModConfig, perhaps to facilitate an Item tweaking mod.
/// </summary>
// JSONItemConverter should allow this to be used as a dictionary key.
[TypeConverter(typeof(ToFromStringConverter<ItemDefinition>))]
Expand Down Expand Up @@ -186,10 +186,38 @@ public static PrefixDefinition Load(TagCompound tag)
}
}

[TypeConverter(typeof(ToFromStringConverter<BuffDefinition>))]
public class BuffDefinition : EntityDefinition
{
public static readonly Func<TagCompound, BuffDefinition> DESERIALIZER = Load;

public override int Type {
get {
if (Mod == "Terraria" && Name == "None")
return 0;
return BuffID.Search.TryGetId(Mod != "Terraria" ? $"{Mod}/{Name}" : Name, out int id) ? id : -1;
}
}

public BuffDefinition() : base() { }
/// <summary><b>Note: </b>As ModConfig loads before other content, make sure to only use <see cref="BuffDefinition(string, string)"/> for modded content in ModConfig classes. </summary>
public BuffDefinition(int type) : base(BuffID.Search.GetName(type)) { }
public BuffDefinition(string key) : base(key) { }
public BuffDefinition(string mod, string name) : base(mod, name) { }

public static BuffDefinition FromString(string s)
=> new(s);

public static BuffDefinition Load(TagCompound tag)
=> new(tag.GetString("mod"), tag.GetString("name"));

public override string DisplayName => IsUnloaded ? Language.GetTextValue("Mods.ModLoader.Unloaded") : Lang.GetBuffName(Type);
}

/// <summary>
/// This TypeConverter facilitates converting to and from the string Type. This is necessary for Objects that are to be used as Dictionary keys, since the JSON for keys needs to be a string. Classes annotated with this TypeConverter need to implement a static FromString method that returns T.
/// </summary>
/// <typeparam name="T">The Type that implementes the static FromString method that returns Type T.</typeparam>
/// <typeparam name="T">The Type that implements the static FromString method that returns Type T.</typeparam>
public class ToFromStringConverter<T> : TypeConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using Terraria.GameContent;
using Terraria.ID;
using Terraria.Localization;
using Terraria.ModLoader.Default;
using Terraria.ModLoader.UI;
using Terraria.UI;

namespace Terraria.ModLoader.Config.UI;

internal class BuffDefinitionElement : DefinitionElement<BuffDefinition>
{
protected override DefinitionOptionElement<BuffDefinition> CreateDefinitionOptionElement() => new BuffDefinitionOptionElement(Value, 0.5f);

protected override List<DefinitionOptionElement<BuffDefinition>> CreateDefinitionOptionElementList()
{
var options = new List<DefinitionOptionElement<BuffDefinition>>();

for (int i = 0; i < BuffLoader.BuffCount; i++) {
// The first buff from BuffID is null, so it's better to create an empty BuffDefinition.
var buffDefinition = i == 0 ? new BuffDefinition() : new BuffDefinition(i);
var optionElement = new BuffDefinitionOptionElement(buffDefinition, OptionScale);
optionElement.OnLeftClick += (a, b) => {
Value = optionElement.Definition;
UpdateNeeded = true;
SelectionExpanded = false;
};
options.Add(optionElement);
}

return options;
}

protected override List<DefinitionOptionElement<BuffDefinition>> GetPassedOptionElements()
{
var passed = new List<DefinitionOptionElement<BuffDefinition>>();

foreach (var option in Options) {
// Should this be the localized buff name?
if (!Lang.GetBuffName(option.Type).Contains(ChooserFilter.CurrentString, StringComparison.OrdinalIgnoreCase))
continue;

string modname = "Terraria";

if (option.Type >= BuffID.Count) {
modname = BuffLoader.GetBuff(option.Type).Mod.DisplayName; // or internal name?
}

if (modname.IndexOf(ChooserFilterMod.CurrentString, StringComparison.OrdinalIgnoreCase) == -1)
continue;

passed.Add(option);
}
return passed;
}
}

internal class BuffDefinitionOptionElement : DefinitionOptionElement<BuffDefinition>
{
public BuffDefinitionOptionElement(BuffDefinition definition, float scale = 0.5f) : base(definition, scale)
{
}

public override void SetItem(BuffDefinition definition)
{
base.SetItem(definition);
}

protected override void DrawSelf(SpriteBatch spriteBatch)
{
CalculatedStyle dimensions = GetInnerDimensions();

spriteBatch.Draw(BackgroundTexture.Value, dimensions.Position(), null, Color.White, 0f, Vector2.Zero, Scale, SpriteEffects.None, 0f);

if (Definition != null) {
int type = Unloaded ? 0 : Type;

Texture2D buffTexture;

if (type == 0) {
// Use ItemID.None as the empty buff texture.
buffTexture = TextureAssets.Item[ItemID.None].Value;
}
else {
buffTexture = TextureAssets.Buff[type].Value;
}

int frameCounter = Interface.modConfig.UpdateCount / 4;
//int frames = Main.projFrames[type];
int frames = 1;

if (Unloaded) {
buffTexture = TextureAssets.Item[ModContent.ItemType<UnloadedItem>()].Value;
frames = 1;
}

int height = buffTexture.Height / frames;
int width = buffTexture.Width;
int frame = frameCounter % frames;
int y = height * frame;
var rectangle2 = new Rectangle(0, y, width, height);

float drawScale = 1f;
float availableWidth = (float)DefaultBackgroundTexture.Width() * Scale;

if (width > availableWidth || height > availableWidth) {
if (width > height) {
drawScale = availableWidth / width;
}
else {
drawScale = availableWidth / height;
}
}

Vector2 vector = BackgroundTexture.Size() * Scale;
Vector2 position2 = dimensions.Position() + vector / 2f - rectangle2.Size() * drawScale / 2f;
Vector2 origin = rectangle2.Size() * 0/* * (pulseScale / 2f - 0.5f)*/;

spriteBatch.Draw(buffTexture, position2, rectangle2, Color.White, 0f, origin, drawScale, SpriteEffects.None, 0f);
}

if (IsMouseHovering)
UIModConfig.Tooltip = Tooltip;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,9 @@ public override void OnActivate()
else if (type == typeof(PrefixDefinition)) {
e = new PrefixDefinitionElement();
}
else if (type == typeof(BuffDefinition)) {
e = new BuffDefinitionElement();
}
else if (type == typeof(Color)) {
e = new ColorElement();
}
Expand Down

0 comments on commit d45a528

Please sign in to comment.