1111import net .minecraft .world .item .enchantment .EnchantmentHelper ;
1212import net .minecraft .world .item .enchantment .EnchantmentInstance ;
1313
14- import java .util .Iterator ;
15- import java .util .List ;
16- import java .util .Optional ;
14+ import java .util .*;
1715import java .util .stream .Stream ;
1816
1917public class IFWEnchantmentHelper {
@@ -27,94 +25,71 @@ public static int getExperienceLevel(final int enchantmentCost) {
2725 }
2826
2927 public static int calculateRequiredExperienceLevel (final RandomSource random , final int slot , int bookshelfCount , final ItemStack stack , final int enchantingMultiplier ) {
30- Item item = stack .getItem ();
31- int i = item .getEnchantmentValue ();
32- if (i <= 0 ) {
33- return 0 ;
34- } else {
35- if (bookshelfCount > 24 ) {
36- bookshelfCount = 24 ;
37- }
28+ final Item item = stack .getItem ();
29+ if (item .getEnchantmentValue () <= 0 ) return 0 ;
3830
39- int enchantment_table_power = (1 + bookshelfCount ) * 2 * enchantingMultiplier ;
40- int enchantment_levels = getEnchantmentLevelsAlteredByItem (enchantment_table_power , item );
41- float fraction = (1.0F + (float )slot ) / 3.0F ;
42- if (slot < 2 ) {
43- fraction += (random .nextFloat () - 0.5F ) * 0.2F ;
44- }
31+ bookshelfCount = Math .min (bookshelfCount , 24 );
32+ final int enchantmentTablePower = (bookshelfCount + 1 ) * 2 * enchantingMultiplier ;
33+ final int enchantmentLevels = enchantmentLevelsByItem (enchantmentTablePower , item );
4534
46- return Math .max (Math .round ((float )enchantment_levels * fraction ), 1 );
47- }
48- }
35+ float fraction = (slot + 1 ) / 3.0F ;
36+ if (slot < 2 ) fraction += (random .nextFloat () - 0.5F ) * 0.2F ;
4937
50- public static int getEnchantmentLevelsAlteredByItem (final int enchantment_table_power , final Item item ) {
51- int enchantability = item .getEnchantmentValue ();
52- if (enchantability < 1 ) {
53- return 0 ;
54- } else if (enchantment_table_power <= enchantability ) {
55- return enchantment_table_power ;
56- } else {
57- float enchantmentLevelsFloat = (float ) enchantability ;
58-
59- for (int i = enchantability + 1 ; i <= enchantment_table_power ; ++i ) {
60- if (i <= enchantability * 2 ) {
61- enchantmentLevelsFloat += 0.5F ;
62- } else {
63- if (i > enchantability * 3 ) {
64- break ;
65- }
66-
67- enchantmentLevelsFloat += 0.25F ;
68- }
69- }
38+ return Math .max (Math .round (enchantmentLevels * fraction ), 1 );
39+ }
7040
71- return Math .round (enchantmentLevelsFloat );
41+ private static int enchantmentLevelsByItem (final int enchantment_table_power , final Item item ) {
42+ int value = item .getEnchantmentValue ();
43+ System .out .println (value );
44+ if (value < 1 ) return 0 ;
45+ else if (enchantment_table_power <= value ) return enchantment_table_power ;
46+ else {
47+ int startA = value + 1 ;
48+ int endA = Math .min (2 * value , enchantment_table_power );
49+ int countA = endA >= startA ? endA - startA + 1 : 0 ;
50+
51+ int startB = 2 * value + 1 ;
52+ int endB = Math .min (3 * value , enchantment_table_power );
53+ int countB = endB >= startB ? endB - startB + 1 : 0 ;
54+
55+ return Math .round (value + 0.5f * countA + 0.25f * countB );
7256 }
7357 }
7458
7559 public static List <EnchantmentInstance > selectEnchantment (final RandomSource random , final ItemStack stack , int cost , final Stream <Holder <Enchantment >> possibleEnchantments ) {
76- List <EnchantmentInstance > enchantmentsToAdd = Lists .newArrayList ();
77- int i = stack .getEnchantmentValue ();
78- if (i > 0 ) {
79- float levelFactor = 1.0F + (random .nextFloat () - 0.5F ) * 0.5F ;
80- cost = getExperienceLevel (cost );
81- List <Holder <Enchantment >> streamList = possibleEnchantments .toList ();
82- List <EnchantmentInstance > possibleInstances = getAvailableEnchantmentResults (cost , stack , streamList .stream ());
83- cost = Mth .clamp (Math .round ((float )cost * levelFactor ), 1 , Integer .MAX_VALUE );
84-
85- while (cost > 0 && enchantmentsToAdd .size () <= 2 && !possibleInstances .isEmpty ()) {
86- possibleInstances = getAvailableEnchantmentResults (cost , stack , streamList .stream ());
87-
88- Iterator <EnchantmentInstance > iterator = enchantmentsToAdd .iterator ();
89- EnchantmentInstance e ;
90- while (iterator .hasNext ()) {
91- e = iterator .next ();
92- EnchantmentHelper .filterCompatibleEnchantments (possibleInstances , e );
93- }
60+ if (stack .getEnchantmentValue () <= 0 ) return Collections .emptyList ();
61+ List <EnchantmentInstance > selectedEnchantments = new ArrayList <>();
9462
95- if ( possibleInstances . isEmpty ()) {
96- break ;
97- }
63+ float levelFactor = 1.0F + ( random . nextFloat () - 0.5F ) * 0.5F ;
64+ cost = getExperienceLevel ( cost ) ;
65+ cost = Mth . clamp ( Math . round (( float ) cost * levelFactor ), 1 , Integer . MAX_VALUE );
9866
99- Optional <EnchantmentInstance > instance = WeightedRandom .getRandomItem (random , possibleInstances );
100- if (instance .isPresent ()) {
101- e = instance .get ();
102- if (enchantmentsToAdd .size () < 2 && possibleInstances .size () > 1 && e .enchantment .value ().ifw_hasLevels () && random .nextInt (2 ) == 0 ) {
103- e .level = random .nextInt (e .level ) + 1 ;
104- }
67+ final List <Holder <Enchantment >> candidateEnchantments = possibleEnchantments .toList ();
10568
69+ while (cost > 0 && selectedEnchantments .size () < 3 ) {
70+ List <EnchantmentInstance > availableEnchantments = getAvailableEnchantmentResults (cost , stack , candidateEnchantments .stream ());
10671
107- enchantmentsToAdd .add (e );
108- cost -= e .enchantment .value ().ifw_hasLevels () ? e .enchantment .value ().getMinCost (e .level ) : e .enchantment .value ().getMinCost (1 ) + 5 ;
109- }
72+ for (EnchantmentInstance selected : selectedEnchantments ) EnchantmentHelper .filterCompatibleEnchantments (availableEnchantments , selected );
11073
111- if (cost < 5 ) {
112- break ;
113- }
74+ if (availableEnchantments .isEmpty ()) break ;
75+
76+ Optional <EnchantmentInstance > optionalEnchantment = WeightedRandom .getRandomItem (random , availableEnchantments );
77+ if (optionalEnchantment .isPresent ()) {
78+ EnchantmentInstance chosen = optionalEnchantment .get ();
79+ Holder <Enchantment > enchantmentHolder = chosen .enchantment ;
80+
81+ if (selectedEnchantments .size () < 2 && availableEnchantments .size () > 1 && enchantmentHolder .value ().ifw_hasLevels () && random .nextInt (2 ) == 0 )
82+ chosen .level = random .nextInt (chosen .level ) + 1 ;
83+
84+ selectedEnchantments .add (chosen );
85+
86+ int costReduction = enchantmentHolder .value ().ifw_hasLevels () ? enchantmentHolder .value ().getMinCost (chosen .level ) : enchantmentHolder .value ().getMinCost (1 ) + 5 ;
87+ cost -= costReduction ;
11488 }
115- }
11689
117- return enchantmentsToAdd ;
90+ if (cost < 5 ) break ;
91+ }
92+ return selectedEnchantments ;
11893 }
11994
12095 public static List <EnchantmentInstance > getAvailableEnchantmentResults (int level , ItemStack stack , Stream <Holder <Enchantment >> possibleEnchantments ) {
@@ -135,10 +110,14 @@ public static List<EnchantmentInstance> getAvailableEnchantmentResults(int level
135110 }
136111
137112 public static float getProtectionFactor (ItemStack itemStack ) {
138- if (itemStack .isDamageableItem () && itemStack .getDamageValue () >= itemStack .getMaxDamage () - 1 ) {
139- return 0.0F ;
140- } else {
141- return Math .min (2.0F - (float ) itemStack .getDamageValue () / itemStack .getMaxDamage () * 2.0F , 1.0F );
142- }
113+ if (!itemStack .isDamageableItem ()) return 1.0F ;
114+
115+ final int maxDamage = itemStack .getMaxDamage ();
116+ final int damage = itemStack .getDamageValue ();
117+
118+ if (damage >= maxDamage - 1 ) return 0.0F ;
119+
120+ float factor = 2.0F * (1.0F - ((float ) damage / maxDamage ));
121+ return Math .min (factor , 1.0F );
143122 }
144123}
0 commit comments