Skip to content

Commit 9eaff49

Browse files
SwedzTechnici4n
andauthored
Use new NeoForge attribute API for quantum armor, quantum sword and gravichestplate (#985)
Co-authored-by: Technici4n <[email protected]>
1 parent 38104ab commit 9eaff49

File tree

14 files changed

+251
-145
lines changed

14 files changed

+251
-145
lines changed

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ org.gradle.jvmargs=-Xmx2G \
99

1010
# Core NeoForge properties
1111
minecraft_version=1.21.1
12-
neo_version=21.1.37
13-
neo_version_range=[21.1.37, 22-)
12+
neo_version=21.1.60
13+
neo_version_range=[21.1.60, 22-)
1414
# For latest see https://parchmentmc.org/docs/getting-started
1515
neoForge.parchment.minecraftVersion=1.21
1616
neoForge.parchment.mappingsVersion=2024.07.28

src/generated/resources/assets/modern_industrialization/lang/en_us.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,7 +1500,8 @@
15001500
"text.modern_industrialization.AcceptsSteamToo": "Also Accepts Steam (1 mb \u003d 1 EU)",
15011501
"text.modern_industrialization.AcceptsUpgrades": "Add upgrades to increase max processing EU/t.",
15021502
"text.modern_industrialization.Activated": "Activated",
1503-
"text.modern_industrialization.AllowCreativeFlight": "Allow Creative Flight",
1503+
"text.modern_industrialization.AttributeInfiniteDamage": "Infinite Damage",
1504+
"text.modern_industrialization.AttributeQuantumArmor": "Quantum Armor",
15041505
"text.modern_industrialization.BarrelStack": "Can store up to %d stacks",
15051506
"text.modern_industrialization.BarrelStorageComponent": "%s / %s (%s)",
15061507
"text.modern_industrialization.BaseDurationSeconds": "%s sec",

src/main/java/aztech/modern_industrialization/MI.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@
6565
import net.minecraft.server.packs.repository.Pack;
6666
import net.minecraft.server.packs.repository.PackCompatibility;
6767
import net.minecraft.server.packs.repository.PackSource;
68+
import net.minecraft.util.Mth;
6869
import net.minecraft.world.InteractionResult;
70+
import net.minecraft.world.entity.EntityType;
71+
import net.minecraft.world.entity.LivingEntity;
6972
import net.minecraft.world.flag.FeatureFlagSet;
7073
import net.minecraft.world.inventory.AnvilMenu;
7174
import net.minecraft.world.item.ItemStack;
@@ -80,6 +83,8 @@
8083
import net.neoforged.neoforge.event.AddPackFindersEvent;
8184
import net.neoforged.neoforge.event.AnvilUpdateEvent;
8285
import net.neoforged.neoforge.event.RegisterGameTestsEvent;
86+
import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent;
87+
import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent;
8388
import net.neoforged.neoforge.event.entity.player.PlayerEvent;
8489
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
8590
import net.neoforged.neoforge.event.village.VillagerTradesEvent;
@@ -174,6 +179,19 @@ public MI(IEventBus modBus, Dist dist) {
174179
}
175180
});
176181

182+
modBus.addListener(EntityAttributeModificationEvent.class, event -> {
183+
for (EntityType<? extends LivingEntity> entityType : event.getTypes()) {
184+
event.add(entityType, MIRegistries.QUANTUM_ARMOR);
185+
event.add(entityType, MIRegistries.INFINITE_DAMAGE);
186+
}
187+
});
188+
NeoForge.EVENT_BUS.addListener(LivingIncomingDamageEvent.class, event -> {
189+
if (event.getSource().getDirectEntity() instanceof LivingEntity damager
190+
&& damager.getAttributeValue(MIRegistries.INFINITE_DAMAGE) > Mth.EPSILON) {
191+
event.setAmount((float) Integer.MAX_VALUE);
192+
}
193+
});
194+
177195
modBus.addListener(FMLCommonSetupEvent.class, event -> {
178196
MIBlock.BLOCK_DEFINITIONS.values().forEach(BlockDefinition::onRegister);
179197
MIItem.ITEM_DEFINITIONS.values().forEach(ItemDefinition::onRegister);

src/main/java/aztech/modern_industrialization/MIRegistries.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424
package aztech.modern_industrialization;
2525

26+
import aztech.modern_industrialization.attributes.InfiniteDamageAttribute;
27+
import aztech.modern_industrialization.attributes.QuantumArmorAttribute;
2628
import aztech.modern_industrialization.blocks.creativestorageunit.CreativeStorageUnitBlockEntity;
2729
import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerRecipe;
2830
import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerScreenHandler;
@@ -39,6 +41,7 @@
3941
import net.minecraft.core.Holder;
4042
import net.minecraft.core.registries.Registries;
4143
import net.minecraft.sounds.SoundEvents;
44+
import net.minecraft.world.entity.ai.attributes.Attribute;
4245
import net.minecraft.world.entity.ai.village.poi.PoiType;
4346
import net.minecraft.world.entity.npc.VillagerProfession;
4447
import net.minecraft.world.flag.FeatureFlags;
@@ -135,6 +138,13 @@ public class MIRegistries {
135138
SoundEvents.VILLAGER_WORK_TOOLSMITH);
136139
});
137140

141+
// Attributes
142+
public static final DeferredRegister<Attribute> ATTRIBUTES = DeferredRegister.create(Registries.ATTRIBUTE, MI.ID);
143+
144+
public static final Holder<Attribute> QUANTUM_ARMOR = ATTRIBUTES.register("quantum_armor", () -> new QuantumArmorAttribute().setSyncable(true));
145+
public static final Holder<Attribute> INFINITE_DAMAGE = ATTRIBUTES.register("infinite_damage",
146+
() -> new InfiniteDamageAttribute().setSyncable(true));
147+
138148
static void init(IEventBus modBus) {
139149
BLOCK_ENTITIES.register(modBus);
140150
CONDITIONS.register(modBus);
@@ -144,5 +154,6 @@ static void init(IEventBus modBus) {
144154
RECIPE_TYPES.register(modBus);
145155
TABS.register(modBus);
146156
VILLAGER_PROFESSIONS.register(modBus);
157+
ATTRIBUTES.register(modBus);
147158
}
148159
}

src/main/java/aztech/modern_industrialization/MIText.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ public enum MIText {
4545
AcceptsSteam("Accepts Steam (1 mb = 1 EU)"),
4646
AcceptsSteamToo("Also Accepts Steam (1 mb = 1 EU)"),
4747
AcceptsUpgrades("Add upgrades to increase max processing EU/t."),
48-
AllowCreativeFlight("Allow Creative Flight"),
4948
Activated("Activated"),
49+
AttributeInfiniteDamage("Infinite Damage"),
50+
AttributeQuantumArmor("Quantum Armor"),
5051
BarrelStack("Can store up to %d stacks"),
5152
BarrelStorageComponent("%s / %s (%s)"),
5253
BaseDurationSeconds("%s sec"),
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Azercoco & Technici4n
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package aztech.modern_industrialization.attributes;
25+
26+
import net.minecraft.ChatFormatting;
27+
import net.minecraft.network.chat.Component;
28+
import net.minecraft.network.chat.MutableComponent;
29+
import net.minecraft.world.entity.ai.attributes.Attribute;
30+
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
31+
import net.minecraft.world.item.TooltipFlag;
32+
33+
public abstract class DisplayNamedAttribute extends Attribute {
34+
protected DisplayNamedAttribute(String descriptionId, double defaultValue) {
35+
super(descriptionId, defaultValue);
36+
}
37+
38+
/**
39+
* Translation key to use in tooltips, thanks to our override of {@link #toComponent(AttributeModifier, TooltipFlag)}.
40+
* {@link #getDescriptionId()} is still used in /attribute commands and other contexts.
41+
*/
42+
public abstract String getTooltipDescriptionId();
43+
44+
/*
45+
* The below methods is copied from IAttributeExtension and uses DisplayAttribute#getDisplayDescriptionId so that Attribute#getDescriptionId
46+
* can return the MIText.AttributeQuantumArmor description id. This is desirable because when using the /attribute command it will display the
47+
* attribute name as "Quantum Armor" instead of just "Armor" like it does when using "attribute.name.generic.armor" as the description id (or
48+
* "Infinite Damage" instead of just "Damage" for the InfiniteDamageAttribute).
49+
*/
50+
51+
@Override
52+
public MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) {
53+
double value = modif.amount();
54+
String key = value > 0 ? "neoforge.modifier.plus" : "neoforge.modifier.take";
55+
ChatFormatting color = this.getStyle(value > 0);
56+
57+
Component attrDesc = Component.translatable(this.getTooltipDescriptionId());
58+
Component valueComp = this.toValueComponent(modif.operation(), value, flag);
59+
MutableComponent comp = Component.translatable(key, valueComp, attrDesc).withStyle(color);
60+
61+
return comp.append(this.getDebugInfo(modif, flag));
62+
}
63+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Azercoco & Technici4n
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package aztech.modern_industrialization.attributes;
25+
26+
import aztech.modern_industrialization.MIText;
27+
import aztech.modern_industrialization.items.tools.QuantumSword;
28+
import net.minecraft.ChatFormatting;
29+
import net.minecraft.network.chat.Component;
30+
import net.minecraft.network.chat.MutableComponent;
31+
import net.minecraft.resources.ResourceLocation;
32+
import net.minecraft.util.Mth;
33+
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
34+
import net.minecraft.world.item.TooltipFlag;
35+
36+
public class InfiniteDamageAttribute extends DisplayNamedAttribute {
37+
private static final String INFINITY = "\u221e";
38+
39+
public InfiniteDamageAttribute() {
40+
super(MIText.AttributeInfiniteDamage.getTranslationKey(), 0);
41+
}
42+
43+
// Allows a modifier with the base id to render green with the effective value.
44+
// Other modifiers still render blue with the additional value.
45+
@Override
46+
public ResourceLocation getBaseId() {
47+
return QuantumSword.BASE_INFINITE_DAMAGE;
48+
}
49+
50+
@Override
51+
public MutableComponent toValueComponent(AttributeModifier.Operation operation, double value, TooltipFlag flag) {
52+
return Component.literal(INFINITY);
53+
}
54+
55+
@Override
56+
public MutableComponent toBaseComponent(double value, double entityBase, boolean merged, TooltipFlag flag) {
57+
String stringValue = value > Mth.EPSILON ? INFINITY : FORMAT.format(0);
58+
MutableComponent comp = Component.translatable("attribute.modifier.equals.0", stringValue,
59+
Component.translatable(this.getTooltipDescriptionId()));
60+
if (flag.isAdvanced() && !merged) {
61+
Component debugInfo = Component.literal(" ")
62+
.append(Component.translatable("neoforge.attribute.debug.base", FORMAT.format(entityBase), FORMAT.format(value - entityBase))
63+
.withStyle(ChatFormatting.GRAY));
64+
comp.append(debugInfo);
65+
}
66+
return comp;
67+
}
68+
69+
@Override
70+
public String getTooltipDescriptionId() {
71+
return "attribute.name.generic.attack_damage";
72+
}
73+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2020 Azercoco & Technici4n
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package aztech.modern_industrialization.attributes;
25+
26+
import aztech.modern_industrialization.MIText;
27+
import net.minecraft.network.chat.Component;
28+
import net.minecraft.network.chat.MutableComponent;
29+
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
30+
import net.minecraft.world.item.TooltipFlag;
31+
32+
public class QuantumArmorAttribute extends DisplayNamedAttribute {
33+
public QuantumArmorAttribute() {
34+
super(MIText.AttributeQuantumArmor.getTranslationKey(), 0);
35+
}
36+
37+
@Override
38+
public MutableComponent toValueComponent(AttributeModifier.Operation operation, double value, TooltipFlag flag) {
39+
return Component.literal("\u00B9\u2044\u2084 |\u221E> + \u00B3\u2044\u2084 |0>");
40+
}
41+
42+
@Override
43+
public String getTooltipDescriptionId() {
44+
return "attribute.name.generic.armor";
45+
}
46+
}

src/main/java/aztech/modern_industrialization/items/armor/GraviChestPlateItem.java

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,17 @@
2525

2626
import aztech.modern_industrialization.MI;
2727
import aztech.modern_industrialization.MIComponents;
28-
import aztech.modern_industrialization.MIText;
2928
import aztech.modern_industrialization.items.ActivatableItem;
3029
import dev.technici4n.grandpower.api.ISimpleEnergyItem;
31-
import java.util.List;
32-
import net.minecraft.ChatFormatting;
3330
import net.minecraft.core.component.DataComponentType;
34-
import net.minecraft.network.chat.Component;
3531
import net.minecraft.world.entity.Entity;
3632
import net.minecraft.world.entity.EquipmentSlot;
3733
import net.minecraft.world.entity.EquipmentSlotGroup;
3834
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
3935
import net.minecraft.world.entity.player.Player;
4036
import net.minecraft.world.item.ArmorItem;
41-
import net.minecraft.world.item.Item;
4237
import net.minecraft.world.item.ItemStack;
4338
import net.minecraft.world.item.Rarity;
44-
import net.minecraft.world.item.TooltipFlag;
4539
import net.minecraft.world.item.component.ItemAttributeModifiers;
4640
import net.minecraft.world.level.Level;
4741
import net.neoforged.neoforge.common.NeoForgeMod;
@@ -60,8 +54,7 @@ public ItemAttributeModifiers getDefaultAttributeModifiers(ItemStack stack) {
6054
NeoForgeMod.CREATIVE_FLIGHT,
6155
new AttributeModifier(MI.id("gravichestplate_flight"), 1, AttributeModifier.Operation.ADD_VALUE),
6256
EquipmentSlotGroup.CHEST)
63-
.build()
64-
.withTooltip(false);
57+
.build();
6558
}
6659
return ItemAttributeModifiers.EMPTY;
6760
}
@@ -117,11 +110,4 @@ public long getEnergyMaxInput(ItemStack stack) {
117110
public long getEnergyMaxOutput(ItemStack stack) {
118111
return 0;
119112
}
120-
121-
@Override
122-
public void appendHoverText(ItemStack stack, Item.TooltipContext context, List<Component> list, TooltipFlag flag) {
123-
list.add(Component.empty());
124-
list.add(Component.translatable("item.modifiers." + getType().getSlot().getName()).withStyle(ChatFormatting.GRAY));
125-
list.add(MIText.AllowCreativeFlight.text().withStyle(ChatFormatting.BLUE));
126-
}
127113
}

src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
package aztech.modern_industrialization.items.armor;
2525

2626
import aztech.modern_industrialization.MIItem;
27+
import aztech.modern_industrialization.MIRegistries;
2728
import java.util.concurrent.ThreadLocalRandom;
2829
import net.minecraft.world.damagesource.DamageTypes;
2930
import net.minecraft.world.entity.EquipmentSlot;
@@ -37,12 +38,7 @@ private MIArmorEffects() {
3738
}
3839

3940
public static boolean quantumArmorPreventsDamage(LivingEntity entity) {
40-
int parts = 0;
41-
for (QuantumArmorItem item : QuantumArmorItem.ITEMS) {
42-
if (entity.getItemBySlot(item.getType().getSlot()).getItem() == item) {
43-
parts++;
44-
}
45-
}
41+
double parts = entity.getAttributeValue(MIRegistries.QUANTUM_ARMOR);
4642
return ThreadLocalRandom.current().nextDouble() < parts / 4d;
4743
}
4844

0 commit comments

Comments
 (0)