-
Posts
29 -
Joined
-
Last visited
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
EveryBlu's Achievements

Tree Puncher (2/8)
0
Reputation
-
I have been working on a complex block for a mod I'm working on. This block is really unfinished right now, but there is this strange bug that is hindering progress. Basically, this block has a single slot where you put a specific item, then there are three "buttons" on the right like the Enchantment Table. Later on these buttons will have a special purpose so don't worry about them, but right now these buttons just increment a new property on the player as long as they have xp levels. The bug is that whenever you click on one of the three buttons, the items you put in are supposed to decrement, but when you take them out or you reopen the block's gui, the item stack mysteriously "resets", meaning that all the items that were consumed are present again. Here is the Block Entity class (do realize that I am developing this mod in IntelliJ IDEA 2024.1.4 Community Edition): package everyblu.ars_mythos.common.block.tiles; import com.github.alexthe666.iceandfire.item.IafItemRegistry; import everyblu.ars_mythos.client.menus.ArcaneScholarsAnalysisMenu; import everyblu.ars_mythos.common.block.ArcaneScholarsBlock; import everyblu.ars_mythos.common.block.ArsMythosBlockStateProperties; import everyblu.ars_mythos.common.registry.ArsMythosObjectRegistry; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.NonNullList; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.world.*; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import software.bernie.geckolib.animatable.GeoBlockEntity; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; import software.bernie.geckolib.core.animation.AnimationController; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; public class ArcaneScholarsTile extends BlockEntity implements GeoBlockEntity, WorldlyContainer, MenuProvider { public final String variant; private final NonNullList<ItemStack> items = NonNullList.withSize(1, ItemStack.EMPTY); public ArcaneScholarsTile(BlockPos pPos, BlockState pBlockState) { super(ArsMythosObjectRegistry.NEW_ARCANE_SCHOLARS_TILE.get(), pPos, pBlockState); this.variant = switch (pBlockState.getValue(ArsMythosBlockStateProperties.ARCANE_SCHOLARS_VARIANT)) { case 1 -> "fire"; case 2 -> "ice"; default -> "lightning"; }; } @Override public void load(@NotNull CompoundTag tag) { super.load(tag); ContainerHelper.loadAllItems(tag, this.items); System.out.println("loaded"); } @Override protected void saveAdditional(@NotNull CompoundTag tag) { if (this.level == null) return; ContainerHelper.saveAllItems(tag, this.items); super.saveAdditional(tag); } private ArcaneScholarsTile getFootPart() { if (this.level == null) return this; BlockEntity nextEntity = this.level.getBlockEntity( this.getBlockPos().relative(this.getBlockState().getValue(ArcaneScholarsBlock.FACING))); if (nextEntity instanceof ArcaneScholarsTile arcaneScholarsTile) return arcaneScholarsTile; return this; } AnimationController<ArcaneScholarsTile> controller; AnimatableInstanceCache factory = GeckoLibUtil.createInstanceCache(this); @Override public void registerControllers(AnimatableManager.ControllerRegistrar controllerRegistrar) { this.controller = new AnimationController<>(this, "controller", 1, (state) -> PlayState.CONTINUE); controllerRegistrar.add(this.controller); } @Override public AnimatableInstanceCache getAnimatableInstanceCache() { return this.factory; } @Override public @NotNull Component getDisplayName() { return Component.literal("Arcane Scholar's Table"); } @Nullable @Override public AbstractContainerMenu createMenu(int pContainerId, @NotNull Inventory pPlayerInventory, @NotNull Player pPlayer) { BlockEntity entity = this.getFootPart(); return new ArcaneScholarsAnalysisMenu(pContainerId, pPlayerInventory, entity); } @Override public int @NotNull [] getSlotsForFace(@NotNull Direction pSide) { return new int[0]; } @Override public boolean canPlaceItemThroughFace(int pIndex, @NotNull ItemStack pItemStack, @Nullable Direction pDirection) { return pDirection == Direction.UP && pItemStack.is(IafItemRegistry.MANUSCRIPT.get()); } @Override public boolean canTakeItemThroughFace(int pIndex, @NotNull ItemStack pStack, @NotNull Direction pDirection) { return false; } @Override public int getContainerSize() { return 1; } @Override public boolean isEmpty() { return this.items.get(0).isEmpty(); } @Override public @NotNull ItemStack getItem(int pSlot) { return this.items.get(0); } @Override public @NotNull ItemStack removeItem(int pSlot, int pAmount) { ItemStack stack = ContainerHelper.removeItem(this.items, pSlot, pAmount); System.out.println(this.items.get(0).getCount()); return stack; } @Override public @NotNull ItemStack removeItemNoUpdate(int pSlot) { return ContainerHelper.takeItem(this.items, pSlot); } @Override public void setItem(int pSlot, @NotNull ItemStack pStack) { this.items.set(pSlot, pStack); if (pStack.getCount() > this.getMaxStackSize()) { pStack.setCount(this.getMaxStackSize()); } if (!pStack.isEmpty()) this.setChanged(); } @Override public boolean stillValid(@NotNull Player pPlayer) { return Container.stillValidBlockEntity(this, pPlayer); } @Override public void clearContent() { this.items.clear(); } } Here is the AbstractContainerMenu: package everyblu.ars_mythos.client.menus; import everyblu.ars_mythos.client.ArsMythosClientRegistry; import everyblu.ars_mythos.common.block.tiles.ArcaneScholarsTile; import everyblu.ars_mythos.common.capabilities.ArcaneResearchDataProvider; import everyblu.ars_mythos.common.helper.ContainerUtils; import everyblu.ars_mythos.common.registry.ArsMythosObjectRegistry; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.sounds.SoundEvents; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.ContainerLevelAccess; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.entity.BlockEntity; import org.jetbrains.annotations.NotNull; public class ArcaneScholarsAnalysisMenu extends AbstractContainerMenu { private final ArcaneScholarsTile tile; public ArcaneScholarsAnalysisMenu(int index, Inventory playerInventory, FriendlyByteBuf data) { this(index, playerInventory, playerInventory.player.level().getBlockEntity(data.readBlockPos())); } public ArcaneScholarsAnalysisMenu(int index, Inventory playerInventory, BlockEntity entity) { super(ArsMythosClientRegistry.AS_ANALYSIS.get(), index); this.tile = ((ArcaneScholarsTile) entity); ContainerUtils.addPlayerInventoryTo(this, playerInventory); ContainerUtils.addPlayerHotBarTo(this, playerInventory); this.addSlot(new Slot(this.tile, 0, 15, 47)); } @Override public boolean clickMenuButton(@NotNull Player player, int pId) { if (this.tile.isEmpty()) return false; if (player.experienceLevel < 1) return false; player.getCapability(ArcaneResearchDataProvider.RESEARCH_DATA_KEY).ifPresent(research -> research.addOrSubResearch(research.getFireResearch(), 1, 0, 0, true)); player.playSound(SoundEvents.VILLAGER_WORK_CARTOGRAPHER); if (!player.getAbilities().instabuild) { this.tile.removeItem(0, 1); player.experienceLevel--; } return super.clickMenuButton(player, pId); } @Override public @NotNull ItemStack quickMoveStack(@NotNull Player pPlayer, int pIndex) { return ContainerUtils.quickMoveStack(pPlayer, pIndex, this.slots, this, (data) -> this.moveItemStackTo(data.getLeft(), data.getMiddle(), data.getRight(), false), 1); } @Override public boolean stillValid(@NotNull Player pPlayer) { return stillValid( ContainerLevelAccess.create(pPlayer.level(), this.tile.getBlockPos()), pPlayer, ArsMythosObjectRegistry.ARCANE_SCHOLARS_TABLE_FIRE.get()); } public boolean manuscriptsEmpty() { return this.tile.isEmpty(); } } And finally, here is the AbstractContainerScreen (if needed): package everyblu.ars_mythos.client.screens; import com.mojang.blaze3d.systems.RenderSystem; import everyblu.ars_mythos.ArsMythos; import everyblu.ars_mythos.client.menus.ArcaneScholarsAnalysisMenu; import everyblu.ars_mythos.common.capabilities.ArcaneResearchDataProvider; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Inventory; import org.jetbrains.annotations.NotNull; public class ArcaneScholarsAnalysisScreen extends AbstractContainerScreen<ArcaneScholarsAnalysisMenu> { public static final ResourceLocation GUI_TEXTURE = ArsMythos.prefix("textures/gui/arcane_scholars_table_analysis.png"); public ArcaneScholarsAnalysisScreen(ArcaneScholarsAnalysisMenu pMenu, Inventory pPlayerInventory, Component pTitle) { super(pMenu, pPlayerInventory, pTitle); } @Override @SuppressWarnings("all") public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) { int x = (this.width - this.imageWidth) / 2; int y = (this.height - this.imageHeight) / 2; for(int k = 0; k < 3; ++k) { double d0 = pMouseX - (double)(x + 60); double d1 = pMouseY - (double)(y + 14 + 19 * k); if (d0 >= 0.0D && d1 >= 0.0D && d0 < 108.0D && d1 < 19.0D && this.menu.clickMenuButton(this.minecraft.player, k)) { this.minecraft.gameMode.handleInventoryButtonClick((this.menu).containerId, k); return true; } } return super.mouseClicked(pMouseX, pMouseY, pButton); } @Override @SuppressWarnings("all") protected void renderBg(@NotNull GuiGraphics guiGraphics, float pPartialTick, int pMouseX, int pMouseY) { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.setShaderTexture(0, GUI_TEXTURE); int x = (this.width - this.imageWidth) / 2; int y = (this.height - this.imageHeight) / 2; guiGraphics.blit(GUI_TEXTURE, x, y, 0, 0, this.imageWidth, this.imageHeight); this.minecraft.player.getCapability(ArcaneResearchDataProvider.RESEARCH_DATA_KEY).ifPresent(research -> guiGraphics.drawString( this.minecraft.font, research.getFireResearch().getLeft().toString(), x + 160, y + 4, 255)); guiGraphics.drawString(this.minecraft.font, String.valueOf(this.minecraft.player.experienceLevel), x + 61, y + 74, 255); for (int k = 0; k < 3; ++k) { if (this.menu.manuscriptsEmpty() || this.minecraft.player.experienceLevel < 1) { guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 185, 108, 19); continue; } guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 166, 108, 19); double d0 = pMouseX - (double)(x + 60); double d1 = pMouseY - (double)(y + 14 + 19 * k); if (d0 >= 0.0D && d1 >= 0.0D && d0 < 108.0D && d1 < 19.0D) { guiGraphics.blit(GUI_TEXTURE, x + 60, y + 14 + (19 * k), 0, 204, 108, 19); } } } @Override public void render(@NotNull GuiGraphics guiGraphics, int mouseX, int mouseY, float delta) { renderBackground(guiGraphics); super.render(guiGraphics, mouseX, mouseY, delta); renderTooltip(guiGraphics, mouseX, mouseY); } } Any help is appreciated.
-
How would I add a tool without a recipe?
EveryBlu replied to DroidCrafter23's topic in Modder Support
Finish the item itself first, then come back to this. Now since you are trying to make it generate in a custom structure, you will need to make a Loot Table. Here is an example of a simple Loot Table: { "pools": [ { "rolls": 1, "entries": [ { "type": "minecraft:item", "name": "minecraft:diamond_axe", "conditions": [ { "condition": "minecraft:random_chance", "chance": 0.5 } ] } ] } ] } You can just copy this, change it to have your item (and other items you may want), and then add it to your mod's Data Pack as a .json file under "loot_tables/chests". I am using 1.19.2 so some of the following information may not apply to you, but when you build your structures, use a command like this: /setblock ~ ~ ~ chest{LootTable:"your_mod_data_pack:chests/your_loot_table"} replace Something like this should spawn a chest that has your Loot Table at your location. On Windows, hold ctrl and middle click the chest (I am assuming that you are using default controls). This should add the chest to your inventory. When you build your structures, use this special chest in your structures, but do not open them. -
How would I add a tool without a recipe?
EveryBlu replied to DroidCrafter23's topic in Modder Support
What structures are you trying to make your custom item generate in? -
I have been wasting several days of my life trying to get this dumb code to work, but it just won't work the way I want it to no matter how I do it. I am trying to make a system where the player gets certain attribute modifiers based off a data-driven system if they have certain items equipped. Here's the class: (No this has nothing to do with the vanilla statistics system you can view in the pause menu.) package everyblu.greateradv.common.events; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; import everyblu.greateradv.GreaterAdventuresMod; import everyblu.greateradv.common.entities.mobs.NetherPaladin; import everyblu.greateradv.common.init.InitEntityTypes; import everyblu.greateradv.common.systems.statistics.Statistics; import everyblu.greateradv.common.systems.statistics.StatisticsManager; import everyblu.greateradv.common.utils.StatisticsAttributeUtils; 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.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.entity.EntityAttributeCreationEvent; import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod; public class CommonEvents { @Mod.EventBusSubscriber(modid = GreaterAdventuresMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE) public static class ForgeEvents { @SubscribeEvent public static void playerPopulateStatisticsAttributes(PlayerEvent.PlayerRespawnEvent event) { if (event.isEndConquered()) {return;} // Pretty sure the player keeps their stuff after conquering the end, so skip this event if that happens. event.getEntity().getAttribute(Attributes.MAX_HEALTH).addTransientModifier(StatisticsAttributeUtils.getStatisticsModifierForAttribute(Attributes.MAX_HEALTH, 0)); } @SubscribeEvent public static void itemStatisticsEquipmentHandler(TickEvent.PlayerTickEvent event) { Player player = event.player; if (event.phase == TickEvent.Phase.START) { float totalMaxHealthBonus = 0; float totalKnockbackResistanceBonus = 0; float totalArmorBonus = 0; float totalArmorToughnessBonus = 0; float totalAttackDamageBonus = 0; for (ItemStack stack : player.getAllSlots()) { if (stack.isEmpty()) {continue;} Statistics itemStatistics = StatisticsManager.Registry.getItemStatsManagerInstance().getStatisticsForItem(stack.getItem()); if (itemStatistics == null) {continue;} if (itemStatistics.maxHealthStat() != null) {totalMaxHealthBonus += itemStatistics.maxHealthStat().getValue();} if (itemStatistics.knockbackResistanceStat() != null) {totalKnockbackResistanceBonus += itemStatistics.knockbackResistanceStat().getValue();} if (itemStatistics.armorStat() != null) {totalArmorBonus += itemStatistics.armorStat().getValue();} if (itemStatistics.armorToughnessStat() != null) {totalArmorToughnessBonus += itemStatistics.armorToughnessStat().getValue();} if (itemStatistics.attackDamageStat() != null) {totalAttackDamageBonus += itemStatistics.attackDamageStat().getValue();} } Multimap<Attribute,AttributeModifier> oldModifiers = ArrayListMultimap.create(); oldModifiers.put(Attributes.MAX_HEALTH, player.getAttribute(Attributes.MAX_HEALTH).getModifier(StatisticsAttributeUtils.MAX_HEALTH_UUID)); Multimap<Attribute, AttributeModifier> newModifiers = ArrayListMultimap.create(); newModifiers.put(Attributes.MAX_HEALTH, StatisticsAttributeUtils.getStatisticsModifierForAttribute(Attributes.MAX_HEALTH, totalMaxHealthBonus)); player.getAttributes().removeAttributeModifiers(newModifiers); player.getAttributes().addTransientAttributeModifiers(newModifiers); } } } @Mod.EventBusSubscriber(modid = GreaterAdventuresMod.MOD_ID, bus = Mod.EventBusSubscriber.Bus.MOD) public static class ModEvents { @SubscribeEvent public static void initEntityAttributes(EntityAttributeCreationEvent event) { event.put(InitEntityTypes.NETHER_PALADIN.get(), NetherPaladin.createAttributes().build()); } } } StatisticsAttributeUtils: package everyblu.greateradv.common.utils; 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 java.util.HashMap; import java.util.Map; import java.util.UUID; public class StatisticsAttributeUtils { public static final UUID MAX_HEALTH_UUID = UUID.fromString("e67a8b8e-5e17-439b-84fc-89b33aaabfbf"); public static final UUID KNOCKBACK_RESISTANCE_UUID = UUID.fromString("c53f398b-1e6f-47e2-9a37-7b85edc02161"); public static final UUID ARMOR_UUID = UUID.fromString("9ef4377c-48b2-43df-ab1d-276abbc2331a"); public static final UUID ARMOR_TOUGHNESS_UUID = UUID.fromString("96f6e24e-227e-48f2-aafc-8e60554d9d97"); public static final UUID ATTACK_DAMAGE_UUID = UUID.fromString("02075396-74b1-486d-99be-4dfe5d20d6d9"); private static final Map<Attribute, UUID> ATTRIBUTE_TO_UUID = new HashMap<>(); static { ATTRIBUTE_TO_UUID.put(Attributes.MAX_HEALTH, MAX_HEALTH_UUID); ATTRIBUTE_TO_UUID.put(Attributes.KNOCKBACK_RESISTANCE, KNOCKBACK_RESISTANCE_UUID); ATTRIBUTE_TO_UUID.put(Attributes.ARMOR, ARMOR_UUID); ATTRIBUTE_TO_UUID.put(Attributes.ARMOR_TOUGHNESS, ARMOR_TOUGHNESS_UUID); ATTRIBUTE_TO_UUID.put(Attributes.ATTACK_DAMAGE, ATTACK_DAMAGE_UUID); } public static AttributeModifier getStatisticsModifierForAttribute(Attribute attribute, float amount) { UUID uuid = ATTRIBUTE_TO_UUID.get(attribute); return new AttributeModifier(uuid, "itemStatistics " + attribute + "Modifier", amount, AttributeModifier.Operation.ADDITION); } } Let me know if you need to see more code. Any help is highly appreciated.
-
I'm trying to have some code run on the tick that certain keybinds are initially pressed; I'm doing this in a ClientTickEvent event, and here's my code: @SubscribeEvent public static void playerInputSignatureHandler(TickEvent.ClientTickEvent event) { LocalPlayer player = Minecraft.getInstance().player; if (player == null) {return;} if (player.isSpectator()) {return;} ((IAbilityActivatingEntity) player).greater_adventures$setTimeSinceLastInput( ((IAbilityActivatingEntity) player).greater_adventures$getTimeSinceLastInput() - 1 ); if (((IAbilityActivatingEntity) player).greater_adventures$getTimeSinceLastInput() <= 0) { ((IAbilityActivatingEntity) player).greater_adventures$resetInputSignature(); } if (event.phase == TickEvent.Phase.END) { while (Minecraft.getInstance().options.keyLeft.consumeClick()) { if (((IAbilityActivatingEntity) player).greater_adventures$getTimeSinceLastInput() > 0) {return;} if (((IAbilityActivatingEntity) player).greater_adventures$getInputSignature().contains("key.left")) {return;} ((IAbilityActivatingEntity) player).greater_adventures$addToInputSignature("key.left"); // Mixins setPlayerInputTime(player); player.setDeltaMovement(0, 0.2, 0); // This line is for in-game testing purposes. } } } // This method is going to be used several times in the future. private static void setPlayerInputTime(LocalPlayer player) { ((IAbilityActivatingEntity) player).greater_adventures$setTimeSinceLastInput(10); } I was following the forge docs for some of this. I thought consumeClick() is supposed to return true upon the initial key press, but here the code runs as long as the keybind is held down, and I have no idea why. Any help is appreciated
-
I mean how do I get a reference of my listener in another class to call these methods? Vanilla code for example gets the RecipeManager via: someLevelObject.getServer().getRecipeListener() Do I use mixins to add a "getMyListener()" method in ReloadableServerResources"?
-
No like how do I use my new PreperableReloadListener, I know how to set it up now and register it, I just need to know how to use it in other classes.
-
How do I get my PreparableReloadListener to use in code? I know how to register it now, but how do I use it in other code?
-
I want to create a registry for a custom data file in a data-driven system I'm trying to make. I know how to use forge's built-in registries (for items, blocks, etc), but I have no idea how to setup my own, let alone one for a custom type of data pack file. Any help is appreciated.
-
[SOLVED] How do I make my custom crossbow shoot a custom arrow?
EveryBlu replied to EveryBlu's topic in Modder Support
Finally got around to fixing this, just removed the use method, and changed FIERY_ARROW_ONLY = (stack) -> stack.getItem() instanceof InitItems.FIERY_ARROW.get(); to FIERY_ARROW_ONLY = (stack) -> stack.is(InitItems.FIERY_ARROW.get()); which fixes the issue. -
[SOLVED] How do I make my custom crossbow shoot a custom arrow?
EveryBlu replied to EveryBlu's topic in Modder Support
This is what I've got private static final Predicate<ItemStack> FIERY_ARROW = (stack) -> stack.getItem() instanceof FieryArrowItem; private static final Predicate<ItemStack> FIERY_ARROW_OR_FIREWORK = FIERY_ARROW.or((stack -> stack.is(Items.FIREWORK_ROCKET))); public WildCrossbowItem(Properties properties) { super(properties); } @Override public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level level, @NotNull Player player, @NotNull InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); if (player.getInventory().items.contains(InitItems.FIERY_ARROW.get())) { performShooting(level, player, hand, stack, getShootingPower(stack), 1.0f); return InteractionResultHolder.consume(stack); } return InteractionResultHolder.fail(stack); } @Override public @NotNull Predicate<ItemStack> getSupportedHeldProjectiles() { return FIERY_ARROW_OR_FIREWORK; } @Override public @NotNull Predicate<ItemStack> getAllSupportedProjectiles() { return FIERY_ARROW; } private static float getShootingPower(ItemStack stack) { return containsChargedProjectile(stack, Items.FIREWORK_ROCKET) ? 1.6F : 3.15F; } but none of this works. Keep in mind I'm not good at modding 😔, so if there's some obvious solution, then that's why I'm look stupid here. -
[SOLVED] How do I make my custom crossbow shoot a custom arrow?
EveryBlu replied to EveryBlu's topic in Modder Support
Did you mean return stack == ModItems.CUSTOM_ARROW.get().defaultInstance(); because your code throws an error (Bad return type in lambda expression: ItemStack cannot be converted to Boolean) -
[SOLVED] How do I make my custom crossbow shoot a custom arrow?
EveryBlu replied to EveryBlu's topic in Modder Support
I want my custom crossbow to shoot my own arrow entity, and require a custom arrow item to be in your inventory. -
I'm not talking about adding new textures, tags, etc. to my resource/data pack, if you don't know how to do that then you're not a Modder. I'm trying to create an entirely new resource type, that you can add to data packs. I've looked at some vanilla classes, and the Better Combat GitHub repo (since it also adds this sort of thing with it's "weapon_attributes" resource), but I don't even know where to start. Keep in mind that I'm not a professional Modder.