1717
1818package lol .hyper .toolstats .tools ;
1919
20+ import io .papermc .paper .datacomponent .DataComponentTypes ;
21+ import io .papermc .paper .datacomponent .item .CustomModelData ;
2022import lol .hyper .toolstats .ToolStats ;
23+ import net .kyori .adventure .text .Component ;
2124import org .bukkit .Material ;
2225import org .bukkit .NamespacedKey ;
26+ import org .bukkit .configuration .ConfigurationSection ;
27+ import org .bukkit .inventory .ItemStack ;
2328import org .bukkit .inventory .ShapedRecipe ;
29+ import org .bukkit .inventory .meta .ItemMeta ;
30+ import org .bukkit .inventory .meta .components .CustomModelDataComponent ;
31+ import org .bukkit .persistence .PersistentDataContainer ;
32+ import org .bukkit .persistence .PersistentDataType ;
2433
25- import java .util .ArrayList ;
26- import java .util .HashSet ;
27- import java .util .Set ;
34+ import java .util .*;
2835
29- public class TokenCrafting {
36+ public class TokenData {
3037
3138 private final ToolStats toolStats ;
3239 private final Set <ShapedRecipe > recipes = new HashSet <>();
3340 private final ArrayList <String > tokenTypes = new ArrayList <>();
3441
35- public TokenCrafting (ToolStats toolStats ) {
42+ public TokenData (ToolStats toolStats ) {
3643 this .toolStats = toolStats ;
3744 }
3845
3946 public void setup () {
4047 NamespacedKey playerKillsKey = new NamespacedKey (toolStats , "player-kills-token" );
41- ShapedRecipe playerKillRecipe = new ShapedRecipe (playerKillsKey , toolStats . tokenItems . playerKills ( ));
48+ ShapedRecipe playerKillRecipe = new ShapedRecipe (playerKillsKey , createToken ( "player-kills" ));
4249 playerKillRecipe .shape (" P " , "PSP" , " P " );
4350 playerKillRecipe .setIngredient ('P' , Material .PAPER );
4451 playerKillRecipe .setIngredient ('S' , Material .WOODEN_SWORD );
4552 recipes .add (playerKillRecipe );
4653
4754 NamespacedKey mobKillsKey = new NamespacedKey (toolStats , "mob-kills-token" );
48- ShapedRecipe mobKillsRecipe = new ShapedRecipe (mobKillsKey , toolStats . tokenItems . mobKills ( ));
55+ ShapedRecipe mobKillsRecipe = new ShapedRecipe (mobKillsKey , createToken ( "mob-kills" ));
4956 mobKillsRecipe .shape (" P " , "PRP" , " P " );
5057 mobKillsRecipe .setIngredient ('P' , Material .PAPER );
5158 mobKillsRecipe .setIngredient ('R' , Material .ROTTEN_FLESH );
5259 recipes .add (mobKillsRecipe );
5360
5461 NamespacedKey blocksMinedKey = new NamespacedKey (toolStats , "blocks-mined-token" );
55- ShapedRecipe blocksMinedRecipe = new ShapedRecipe (blocksMinedKey , toolStats . tokenItems . blocksMined ( ));
62+ ShapedRecipe blocksMinedRecipe = new ShapedRecipe (blocksMinedKey , createToken ( "blocks-mined" ));
5663 blocksMinedRecipe .shape (" P " , "PSP" , " P " );
5764 blocksMinedRecipe .setIngredient ('P' , Material .PAPER );
5865 blocksMinedRecipe .setIngredient ('S' , Material .WOODEN_PICKAXE );
5966 recipes .add (blocksMinedRecipe );
6067
6168 NamespacedKey cropsMinedKey = new NamespacedKey (toolStats , "crops-mined-token" );
62- ShapedRecipe cropsMinedRecipe = new ShapedRecipe (cropsMinedKey , toolStats . tokenItems . cropsMined ( ));
69+ ShapedRecipe cropsMinedRecipe = new ShapedRecipe (cropsMinedKey , createToken ( "crops-mined" ));
6370 cropsMinedRecipe .shape (" P " , "PHP" , " P " );
6471 cropsMinedRecipe .setIngredient ('P' , Material .PAPER );
6572 cropsMinedRecipe .setIngredient ('H' , Material .WOODEN_HOE );
6673 recipes .add (cropsMinedRecipe );
6774
6875 NamespacedKey fishCaughtKey = new NamespacedKey (toolStats , "fish-caught-token" );
69- ShapedRecipe fishCaughtRecipe = new ShapedRecipe (fishCaughtKey , toolStats . tokenItems . fishCaught ( ));
76+ ShapedRecipe fishCaughtRecipe = new ShapedRecipe (fishCaughtKey , createToken ( "fish-caught" ));
7077 fishCaughtRecipe .shape (" P " , "PCP" , " P " );
7178 fishCaughtRecipe .setIngredient ('P' , Material .PAPER );
7279 fishCaughtRecipe .setIngredient ('C' , Material .COD );
7380 recipes .add (fishCaughtRecipe );
7481
7582 NamespacedKey sheepShearedKey = new NamespacedKey (toolStats , "sheep-sheared-token" );
76- ShapedRecipe sheepShearedRecipe = new ShapedRecipe (sheepShearedKey , toolStats . tokenItems . sheepSheared ( ));
83+ ShapedRecipe sheepShearedRecipe = new ShapedRecipe (sheepShearedKey , createToken ( "sheep-sheared" ));
7784 sheepShearedRecipe .shape (" P " , "PWP" , " P " );
7885 sheepShearedRecipe .setIngredient ('P' , Material .PAPER );
7986 sheepShearedRecipe .setIngredient ('W' , Material .WHITE_WOOL );
8087 recipes .add (sheepShearedRecipe );
8188
8289 NamespacedKey armorDamageKey = new NamespacedKey (toolStats , "damage-taken-token" );
83- ShapedRecipe armorDamageRecipe = new ShapedRecipe (armorDamageKey , toolStats . tokenItems . damageTaken ( ));
90+ ShapedRecipe armorDamageRecipe = new ShapedRecipe (armorDamageKey , createToken ( "damage-taken" ));
8491 armorDamageRecipe .shape (" P " , "PCP" , " P " );
8592 armorDamageRecipe .setIngredient ('P' , Material .PAPER );
8693 armorDamageRecipe .setIngredient ('C' , Material .LEATHER_CHESTPLATE );
8794 recipes .add (armorDamageRecipe );
8895
8996 NamespacedKey damageDoneKey = new NamespacedKey (toolStats , "damage-done-token" );
90- ShapedRecipe damageDoneRecipe = new ShapedRecipe (damageDoneKey , toolStats . tokenItems . damageDone ( ));
97+ ShapedRecipe damageDoneRecipe = new ShapedRecipe (damageDoneKey , createToken ( "damage-done" ));
9198 damageDoneRecipe .shape (" P " , "PSP" , " P " );
9299 damageDoneRecipe .setIngredient ('P' , Material .PAPER );
93100 damageDoneRecipe .setIngredient ('S' , Material .SHIELD );
94101 recipes .add (damageDoneRecipe );
95102
96103 NamespacedKey arrowsShotKey = new NamespacedKey (toolStats , "arrows-shot-token" );
97- ShapedRecipe arrowsShotRecipe = new ShapedRecipe (arrowsShotKey , toolStats . tokenItems . arrowsShot ( ));
104+ ShapedRecipe arrowsShotRecipe = new ShapedRecipe (arrowsShotKey , createToken ( "arrows-shot" ));
98105 arrowsShotRecipe .shape (" P " , "PAP" , " P " );
99106 arrowsShotRecipe .setIngredient ('P' , Material .PAPER );
100107 arrowsShotRecipe .setIngredient ('A' , Material .ARROW );
101108 recipes .add (arrowsShotRecipe );
102109
103110 NamespacedKey flightTimeKey = new NamespacedKey (toolStats , "flight-time-token" );
104- ShapedRecipe flightTimeRecipe = new ShapedRecipe (flightTimeKey , toolStats . tokenItems . flightTime ( ));
111+ ShapedRecipe flightTimeRecipe = new ShapedRecipe (flightTimeKey , createToken ( "flight-time" ));
105112 flightTimeRecipe .shape (" P " , "PFP" , " P " );
106113 flightTimeRecipe .setIngredient ('P' , Material .PAPER );
107114 flightTimeRecipe .setIngredient ('F' , Material .FEATHER );
108115 recipes .add (flightTimeRecipe );
109116
110117 NamespacedKey resetKey = new NamespacedKey (toolStats , "reset-token" );
111- ShapedRecipe resetRecipe = new ShapedRecipe (resetKey , toolStats . tokenItems . resetToken ( ));
118+ ShapedRecipe resetRecipe = new ShapedRecipe (resetKey , createToken ( "reset" ));
112119 resetRecipe .shape (" P " , "PPP" , " P " );
113120 resetRecipe .setIngredient ('P' , Material .PAPER );
114121 recipes .add (resetRecipe );
115122
116123 NamespacedKey removeKey = new NamespacedKey (toolStats , "remove-token" );
117- ShapedRecipe removeRecipe = new ShapedRecipe (removeKey , toolStats . tokenItems . removeToken ( ));
124+ ShapedRecipe removeRecipe = new ShapedRecipe (removeKey , createToken ( "remove" ));
118125 removeRecipe .shape (" P " , "P P" , " P " );
119126 removeRecipe .setIngredient ('P' , Material .PAPER );
120127 recipes .add (removeRecipe );
@@ -140,4 +147,83 @@ public Set<ShapedRecipe> getRecipes() {
140147 public ArrayList <String > getTokenTypes () {
141148 return tokenTypes ;
142149 }
150+
151+ public ItemStack createToken (String tokenType ) {
152+ // we don't have to check if the token exists
153+ // we do that prior
154+ ConfigurationSection tokenConfig = toolStats .config .getConfigurationSection ("tokens.data." + tokenType );
155+
156+ String materialFromConfig = tokenConfig .getString ("material" );
157+ if (materialFromConfig == null ) {
158+ toolStats .logger .warning ("Could not find material config for token " + tokenType );
159+ return null ;
160+ }
161+ Material material = Material .getMaterial (materialFromConfig );
162+ if (material == null ) {
163+ toolStats .logger .warning ("Material " + materialFromConfig + " is not a valid Minecraft material." );
164+ return null ;
165+ }
166+
167+ ItemStack token = new ItemStack (material );
168+ ItemMeta tokenMeta = token .getItemMeta ();
169+ PersistentDataContainer tokenData = tokenMeta .getPersistentDataContainer ();
170+
171+ // set the title and lore
172+ Component title = toolStats .configTools .format ("tokens.data." + tokenType + ".title" );
173+ List <Component > lore = toolStats .configTools .getTokenLore (tokenType );
174+ tokenMeta .displayName (title );
175+ tokenMeta .lore (lore );
176+
177+ // set the custom model data
178+ if (tokenConfig .getBoolean ("custom-model-data.enabled" )) {
179+ String type = tokenConfig .getString ("custom-model-data.type" );
180+ Object value = tokenConfig .get ("custom-model-data.value" );
181+ if (type == null || value == null ) {
182+ toolStats .logger .info ("Could not find custom model data for token " + tokenType );
183+ toolStats .logger .info ("Type: " + type );
184+ toolStats .logger .info ("Value: " + value );
185+ return null ;
186+ }
187+ CustomModelData data = setData (type , value );
188+ if (data != null ) {
189+ token .setData (DataComponentTypes .CUSTOM_MODEL_DATA , data );
190+ } else {
191+ return null ;
192+ }
193+ }
194+
195+ // set the PDC
196+ tokenData .set (toolStats .tokenType , PersistentDataType .STRING , tokenType );
197+ token .setItemMeta (tokenMeta );
198+ return token ;
199+ }
200+
201+ private CustomModelData setData (String type , Object data ) {
202+ switch (type .toLowerCase (Locale .ROOT )) {
203+ case "float" : {
204+ Float f ;
205+ if (data instanceof Float ) {
206+ f = (Float ) data ;
207+ } else {
208+ toolStats .logger .info (type + " is not a valid float!" );
209+ return null ;
210+ }
211+ return CustomModelData .customModelData ().addFloat (f ).build ();
212+ }
213+ case "string" : {
214+ String s ;
215+ if (data instanceof String ) {
216+ s = (String ) data ;
217+ } else {
218+ toolStats .logger .info (type + " is not a valid string!" );
219+ return null ;
220+ }
221+ return CustomModelData .customModelData ().addString (s ).build ();
222+ }
223+ default : {
224+ toolStats .logger .info (type + " is not a valid data type!" );
225+ return null ;
226+ }
227+ }
228+ }
143229}
0 commit comments