Skip to content

Commit

Permalink
add the Nano Saber (#1350)
Browse files Browse the repository at this point in the history
* add the Nano Saber

* reviews

* spotless
  • Loading branch information
screret committed Jun 4, 2024
1 parent f17116a commit cc8d624
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 13 deletions.
1 change: 1 addition & 0 deletions src/generated/resources/assets/gtceu/lang/en_ud.json
Original file line number Diff line number Diff line change
Expand Up @@ -4122,6 +4122,7 @@
"item.gtceu.nano_processor_mainframe": "ǝɯɐɹɟuıɐW ɹossǝɔoɹdouɐN",
"item.gtceu.nano_processor_mainframe.tooltip.0": "ɹǝʌǝ uɐɥʇ ɹǝןןɐɯSㄥ§",
"item.gtceu.nano_processor_mainframe.tooltip.1": "ʇınɔɹıƆ ɹǝı⟘-ΛnꞀq§",
"item.gtceu.nano_saber": "ɹǝqɐS ouɐN",
"item.gtceu.nano_saber.tooltip": "¡ǝɐɹnʞ oʍ uǝʞ ou uıظnʎᴚㄥ§",
"item.gtceu.nanomuscle_boots": "sʇooᗺ ǝʇınS ™ǝןɔsnWouɐN",
"item.gtceu.nanomuscle_chestplate": "ǝʇɐןdʇsǝɥƆ ǝʇınS ™ǝןɔsnWouɐN",
Expand Down
1 change: 1 addition & 0 deletions src/generated/resources/assets/gtceu/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -4172,6 +4172,7 @@
"item.gtceu.nano_processor_mainframe": "Nanoprocessor Mainframe",
"item.gtceu.nano_processor_mainframe.tooltip.0": "§7Smaller than ever",
"item.gtceu.nano_processor_mainframe.tooltip.1": "§bLuV-Tier Circuit",
"item.gtceu.nano_saber": "Nano Saber",
"item.gtceu.nano_saber.tooltip": "§7Ryujin no ken wo kurae!",
"item.gtceu.nanomuscle_boots": "NanoMuscle™ Suite Boots",
"item.gtceu.nanomuscle_chestplate": "NanoMuscle™ Suite Chestplate",
Expand Down
14 changes: 14 additions & 0 deletions src/generated/resources/assets/gtceu/models/item/nano_saber.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"parent": "minecraft:item/generated",
"overrides": [
{
"model": "gtceu:item/nano_saber/active",
"predicate": {
"gtceu:nano_saber_active": 1.0
}
}
],
"textures": {
"layer0": "gtceu:item/nano_saber/normal"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "gtceu:item/nano_saber/active"
}
}
59 changes: 59 additions & 0 deletions src/main/java/com/gregtechceu/gtceu/api/item/ComponentItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper;
import com.gregtechceu.gtceu.api.capability.IElectricItem;
import com.gregtechceu.gtceu.api.item.capability.ElectricItem;
import com.gregtechceu.gtceu.api.item.component.*;

import com.lowdragmc.lowdraglib.client.renderer.IItemRendererProvider;
Expand All @@ -16,16 +17,21 @@
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.level.Level;

import com.google.common.collect.Multimap;
import lombok.Getter;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -136,6 +142,49 @@ public InteractionResult useOn(UseOnContext context) {
return super.useOn(context);
}

@Override
public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot, ItemStack stack) {
for (IItemComponent component : components) {
if (component instanceof IItemAttributes itemAttributes) {
var result = itemAttributes.getAttributeModifiers(slot, stack);
if (result != null && !result.isEmpty()) {
return result;
}
}
}
return super.getAttributeModifiers(slot, stack);
}

@Override
public boolean isEnchantable(ItemStack stack) {
for (IItemComponent component : components) {
if (component instanceof IEnchantableItem enchantableItem) {
return enchantableItem.isEnchantable(stack);
}
}
return super.isEnchantable(stack);
}

@Override
public int getEnchantmentValue(ItemStack stack) {
for (IItemComponent component : components) {
if (component instanceof IEnchantableItem enchantableItem) {
return enchantableItem.getEnchantmentValue(stack);
}
}
return super.getEnchantmentValue(stack);
}

@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
for (IItemComponent component : components) {
if (component instanceof IEnchantableItem enchantableItem) {
return enchantableItem.canApplyAtEnchantingTable(stack, enchantment);
}
}
return super.canApplyAtEnchantingTable(stack, enchantment);
}

@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand usedHand) {
for (IItemComponent component : components) {
Expand Down Expand Up @@ -288,4 +337,14 @@ public ItemStack getChargedStack(long chargeAmount) {
electricItem.charge(chargeAmount, Integer.MAX_VALUE, true, false);
return itemStack;
}

public ItemStack getInfiniteChargedStack() {
ItemStack itemStack = getDefaultInstance();
IElectricItem iElectricItem = GTCapabilityHelper.getElectricItem(itemStack);
if (!(iElectricItem instanceof ElectricItem electricItem)) {
throw new IllegalStateException("Not a supported electric item.");
}
electricItem.setInfiniteCharge(true);
return itemStack;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gregtechceu.gtceu.api.item.component;

import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.Enchantment;

public interface IEnchantableItem {

boolean isEnchantable(ItemStack stack);

int getEnchantmentValue(ItemStack stack);

boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gregtechceu.gtceu.api.item.component;

import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.item.ItemStack;

import com.google.common.collect.Multimap;

public interface IItemAttributes {

Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot, ItemStack stack);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1173,9 +1173,9 @@ public Builder radioactiveHazard(float multiplier) {
properties.setProperty(HAZARD, new HazardProperty(
HazardProperty.HazardType.RADIOACTIVE,
List.of(
HazardProperty.slownessEffect(-1, (int) (2000 / multiplier), effectAmplifier),
HazardProperty.weaknessEffect(-1, (int) (2000 / multiplier), effectAmplifier),
HazardProperty.miningFautigueEffect(-1, (int) (3000 / multiplier), effectAmplifier),
HazardProperty.slownessEffect(4000, (int) (2000 / multiplier), effectAmplifier),
HazardProperty.weaknessEffect(4000, (int) (2000 / multiplier), effectAmplifier),
HazardProperty.miningFautigueEffect(4000, (int) (3000 / multiplier), effectAmplifier),
HazardProperty.maxAirLoweringEffect(1000, (int) (4000 / multiplier),
(int) (100 / multiplier)),
HazardProperty.maxHealthLoweringEffect(4000, (int) (6000 / multiplier), 10),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.gregtechceu.gtceu.common.item;

import com.gregtechceu.gtceu.GTCEu;
import com.gregtechceu.gtceu.api.item.component.IEnchantableItem;
import com.gregtechceu.gtceu.api.item.component.IItemAttributes;
import com.gregtechceu.gtceu.config.ConfigHolder;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.Enchantments;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

public class NanoSaberBehavior extends ToggleEnergyConsumerBehavior implements IItemAttributes, IEnchantableItem {

public static final ResourceLocation OVERRIDE_KEY_LOCATION = GTCEu.id("nano_saber_active");

private final double baseAttackDamage;
private final double additionalAttackDamage;

public NanoSaberBehavior() {
super(ConfigHolder.INSTANCE.tools.nanoSaber.energyConsumption);
this.baseAttackDamage = ConfigHolder.INSTANCE.tools.nanoSaber.nanoSaberBaseDamage;
this.additionalAttackDamage = ConfigHolder.INSTANCE.tools.nanoSaber.nanoSaberDamageBoost;
}

@Override
public Multimap<Attribute, AttributeModifier> getAttributeModifiers(EquipmentSlot slot, ItemStack stack) {
HashMultimap<Attribute, AttributeModifier> modifiers = HashMultimap.create();
if (slot == EquipmentSlot.MAINHAND) {
double attackDamage = baseAttackDamage + (isItemActive(stack) ? additionalAttackDamage : 0.0D);
modifiers.put(Attributes.ATTACK_SPEED,
new AttributeModifier(Item.BASE_ATTACK_SPEED_UUID, "Weapon modifier", -2.0,
AttributeModifier.Operation.ADDITION));
modifiers.put(Attributes.ATTACK_DAMAGE,
new AttributeModifier(Item.BASE_ATTACK_DAMAGE_UUID, "Weapon Modifier", attackDamage,
AttributeModifier.Operation.ADDITION));
}
return modifiers;
}

@Override
public boolean isEnchantable(ItemStack stack) {
return true;
}

@Override
public int getEnchantmentValue(ItemStack stack) {
return 33;
}

@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment.category == null) {
return false;
}
return enchantment != Enchantments.UNBREAKING &&
enchantment != Enchantments.MENDING &&
enchantment.category.canEnchant(Items.IRON_SWORD);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.gregtechceu.gtceu.common.item;

import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper;
import com.gregtechceu.gtceu.api.capability.IElectricItem;
import com.gregtechceu.gtceu.api.item.component.IAddInformation;
import com.gregtechceu.gtceu.api.item.component.IInteractionItem;
import com.gregtechceu.gtceu.api.item.component.IItemLifeCycle;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;

import org.jetbrains.annotations.Nullable;

import java.util.List;

public class ToggleEnergyConsumerBehavior implements IInteractionItem, IItemLifeCycle, IAddInformation {

private final int energyUsagePerTick;

public ToggleEnergyConsumerBehavior(int energyUsagePerTick) {
this.energyUsagePerTick = energyUsagePerTick;
}

@Override
public InteractionResultHolder<ItemStack> use(Item item, Level world, Player player, InteractionHand hand) {
ItemStack itemStack = player.getItemInHand(hand);
if (player.isShiftKeyDown()) {
IElectricItem electricItem = GTCapabilityHelper.getElectricItem(itemStack);
boolean isItemActive = isItemActive(itemStack);
if (isItemActive) {
setItemActive(itemStack, false);
} else if (electricItem != null && drainActivationEnergy(electricItem, true)) {
setItemActive(itemStack, true);
}
}
return InteractionResultHolder.pass(itemStack);
}

private boolean drainActivationEnergy(IElectricItem electricItem, boolean simulate) {
return electricItem.discharge(energyUsagePerTick, electricItem.getTier(), true, false, simulate) >=
energyUsagePerTick;
}

@Override
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slotId, boolean isSelected) {
IElectricItem electricItem = GTCapabilityHelper.getElectricItem(stack);
if (isItemActive(stack) && electricItem != null) {
boolean shouldRemainActive = drainActivationEnergy(electricItem, false);
if (!shouldRemainActive) {
setItemActive(stack, false);
}
}
}

@Override
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltipComponents,
TooltipFlag isAdvanced) {
tooltipComponents.add(Component.translatable("behavior.toggle_energy_consumer.tooltip"));
}

public static boolean isItemActive(ItemStack itemStack) {
CompoundTag tagCompound = itemStack.getTag();
return tagCompound != null && tagCompound.getBoolean("Active");
}

public static void setItemActive(ItemStack itemStack, boolean isActive) {
CompoundTag tagCompound = itemStack.getOrCreateTag();
tagCompound.putBoolean("Active", isActive);
}
}
33 changes: 30 additions & 3 deletions src/main/java/com/gregtechceu/gtceu/data/item/GTItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.renderer.item.ItemProperties;
import net.minecraft.client.renderer.item.ItemPropertyFunction;
import net.minecraft.core.cauldron.CauldronInteraction;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
Expand Down Expand Up @@ -2258,11 +2259,27 @@ public Component getItemName(ItemStack stack) {
public static ItemEntry<ComponentItem> RAD_AWAY_PILL = REGISTRATE.item("rad_away_pill", ComponentItem::create)
.lang("RadAway™ Pill")
.properties(p -> p.food(GTFoods.ANTIDOTE))
.onRegister(attach(new AntidoteBehavior(75, HazardProperty.HazardType.RADIOACTIVE)))
.onRegister(attach(new AntidoteBehavior(50, HazardProperty.HazardType.RADIOACTIVE)))
.register();

public static ItemEntry<Item> NANO_SABER;
public static ItemEntry<ComponentItem> PROSPECTOR_LV = REGISTRATE.item("lv_prospector", ComponentItem::new)
public static ItemEntry<ComponentItem> NANO_SABER = REGISTRATE.item("nano_saber", ComponentItem::create)
.lang("Nano Saber")
.properties(p -> p.stacksTo(1))
.onRegister(attach(new NanoSaberBehavior(), ElectricStats.createElectricItem(4_000_000L, GTValues.HV)))
.model((ctx, prov) -> {
var rootModel = prov.generated(ctx::getEntry, prov.modLoc("item/nano_saber/normal"));
prov.getBuilder("item/nano_saber/active")
.parent(new ModelFile.UncheckedModelFile("item/generated"))
.texture("layer0", prov.modLoc("item/nano_saber/active"));

rootModel.override().predicate(NanoSaberBehavior.OVERRIDE_KEY_LOCATION, 1.0f)
.model(new ModelFile.UncheckedModelFile(prov.modLoc("item/nano_saber/active")))
.end();
})
.onRegister(modelPredicate(NanoSaberBehavior.OVERRIDE_KEY_LOCATION,
(stack, level, entity, layer) -> NanoSaberBehavior.isItemActive(stack) ? 1.0f : 0.0f))
.register();
public static ItemEntry<ComponentItem> PROSPECTOR_LV = REGISTRATE.item("lv_prospector", ComponentItem::create)
.lang("Ore Prospector (LV)")
.properties(p -> p.stacksTo(1))
.onRegister(compassNodeExist(GTCompassSections.ITEMS, "prospector"))
Expand Down Expand Up @@ -2705,6 +2722,16 @@ public static <T extends Item> NonNullConsumer<T> modelPredicate(ResourceLocatio
};
}

@SuppressWarnings("deprecation")
public static <T extends Item> NonNullConsumer<T> modelPredicate(ResourceLocation predicate,
ItemPropertyFunction property) {
return item -> {
if (LDLib.isClient()) {
ItemProperties.register(item, predicate, property);
}
};
}

@NotNull
private static <
T extends Item> NonNullBiConsumer<DataGenContext<Item, T>, RegistrateLangProvider> reverseLangValue() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,9 @@ public static void init(RecipeOutput provider) {
VanillaRecipeHelper.addShapedRecipe(provider, "minecart_wheels_steel", STEEL_MINECART_WHEELS.asStack(), " h ",
"RSR", " w ", 'R', new UnificationEntry(ring, Steel), 'S', new UnificationEntry(rod, Steel));

// todo nanosaber
// VanillaRecipeHelper.addShapedRecipe(provider, "nano_saber", NANO_SABER.asStack(), "PIC", "PIC", "XEX", 'P',
// new UnificationEntry(plate, Platinum), 'I', new UnificationEntry(plate, Ruridit), 'C',
// CARBON_FIBER_PLATE.asStack(), 'X', new UnificationEntry(circuit, Tier.EV), 'E', ENERGIUM_CRYSTAL.asStack());
VanillaRecipeHelper.addShapedRecipe(provider, "nano_saber", NANO_SABER.asStack(), "PIC", "PIC",
"XEX", 'P', new UnificationEntry(plate, Platinum), 'I', new UnificationEntry(plate, Ruridit), 'C',
CARBON_FIBER_PLATE.asStack(), 'X', CustomTags.EV_CIRCUITS, 'E', ENERGIUM_CRYSTAL.asStack());

VanillaRecipeHelper.addShapedRecipe(provider, "solar_panel_basic", COVER_SOLAR_PANEL.asStack(), "WGW", "CPC",
'W', SILICON_WAFER.asStack(), 'G', new ItemStack(Blocks.GLASS_PANE), 'C', CustomTags.LV_CIRCUITS, 'P',
Expand Down
Loading

0 comments on commit cc8d624

Please sign in to comment.