Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Forge 1.16.4 - Item mod element #554

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion plugins/generator-1.16.4/forge-1.16.4/generator.yaml
@@ -1,5 +1,5 @@
name: Minecraft Forge for @minecraft (@buildfileversion)
basefeatures: [variables]
basefeatures: [variables, model_json, model_obj]
Goldorion marked this conversation as resolved.
Show resolved Hide resolved
status: dev
buildfileversion: 35.1.0

Expand Down Expand Up @@ -71,3 +71,4 @@ resources_setup_tasks:
- task: copy_models
type: JSON_noinlinetextures
to: "@MODASSETSROOT/models/custom"

24 changes: 24 additions & 0 deletions plugins/generator-1.16.4/forge-1.16.4/item.definition.yaml
@@ -0,0 +1,24 @@
templates:
- template: item.java.ftl
name: "@SRCROOT/@BASEPACKAGEPATH/item/@NAMEItem.java"
- template: json/item.json.ftl
writer: json
condition: ["renderType #= 0", "hasNormalModel()"]
name: "@MODASSETSROOT/models/item/@registryname.json"
- template: json/tool.json.ftl
writer: json
condition: ["renderType #= 0", "hasToolModel()"]
name: "@MODASSETSROOT/models/item/@registryname.json"
- template: json/item_cmodel.json.ftl
writer: json
condition: "renderType #= 1"
name: "@MODASSETSROOT/models/item/@registryname.json"
- template: json/item_cmodel_obj.json.ftl
writer: json
condition: "renderType #= 2"
variables: "type=item"
name: "@MODASSETSROOT/models/item/@registryname.json"

localizationkeys:
- key: item.@modid.@registryname
mapto: name
340 changes: 340 additions & 0 deletions plugins/generator-1.16.4/forge-1.16.4/templates/item.java.ftl
@@ -0,0 +1,340 @@
<#--
# MCreator (https://mcreator.net/)
# Copyright (C) 2020 Pylo and contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Additional permission for code generator templates (*.ftl files)
#
# As a special exception, you may create a larger work that contains part or
# all of the MCreator code generator templates (*.ftl files) and distribute
# that work under terms of your choice, so long as that work isn't itself a
# template for code generation. Alternatively, if you modify or redistribute
# the template itself, you may (at your option) remove this special exception,
# which will cause the template and the resulting code generator output files
# to be licensed under the GNU General Public License without this special
# exception.
-->

<#-- @formatter:off -->
<#include "procedures.java.ftl">
<#include "mcitems.ftl">

package ${package}.item;

@${JavaModName}Elements.ModElement.Tag public class ${name}Item extends ${JavaModName}Elements.ModElement{

@ObjectHolder("${modid}:${registryname}")
public static final Item block = null;

public ${name}Item(${JavaModName}Elements instance) {
super(instance, ${data.getModElement().getSortID()});

<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
MinecraftForge.EVENT_BUS.register(this);
</#if>
}

<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
@SubscribeEvent @OnlyIn(Dist.CLIENT) public void onItemDropped(ItemTossEvent event) {
if(event.getEntityItem().getItem().getItem() == block) {
if (Minecraft.getInstance().currentScreen instanceof ${(data.guiBoundTo)}Gui.GuiWindow) {
Minecraft.getInstance().player.closeScreen();
}
}
}
</#if>

@Override public void initElements() {
elements.items.add(() -> new ItemCustom());
}

public static class ItemCustom extends Item {

public ItemCustom() {
super(new Item.Properties()
.group(${data.creativeTab})
<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
.maxStackSize(1)
<#elseif data.damageCount != 0>
.maxDamage(${data.damageCount})
<#else>
.maxStackSize(${data.stackSize})
</#if>
.rarity(Rarity.${data.rarity})

);
setRegistryName("${registryname}");
}

<#if data.stayInGridWhenCrafting>
@Override public boolean hasContainerItem() {
return true;
}

<#if data.recipeRemainder?? && !data.recipeRemainder.isEmpty()>
@Override public ItemStack getContainerItem(ItemStack itemstack) {
return ${mappedMCItemToItemStackCode(data.recipeRemainder, 1)};
}
<#elseif data.damageOnCrafting && data.damageCount != 0>
@Override public ItemStack getContainerItem(ItemStack itemstack) {
ItemStack retval = new ItemStack(this);
retval.setDamage(itemstack.getDamage() + 1);
if(retval.getDamage() >= retval.getMaxDamage()) {
return ItemStack.EMPTY;
}
return retval;
}
<#else>
@Override public ItemStack getContainerItem(ItemStack itemstack) {
return new ItemStack(this);
}
</#if>
</#if>

@Override public int getItemEnchantability() {
return ${data.enchantability};
}

@Override public int getUseDuration(ItemStack itemstack) {
return ${data.useDuration};
}

@Override public float getDestroySpeed(ItemStack par1ItemStack, BlockState par2Block) {
return ${data.toolType}F;
}

<#if data.enableMeleeDamage>
@Override public Multimap<String, AttributeModifier> getAttributeModifiers(EquipmentSlotType slot) {
Multimap<String, AttributeModifier> multimap = super.getAttributeModifiers(slot);
if (slot == EquipmentSlotType.MAINHAND) {
multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "item_damage", (double) ${data.damageVsEntity - 2}, AttributeModifier.Operation.ADDITION));
multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "item_attack_speed", -2.4, AttributeModifier.Operation.ADDITION));
}
return multimap;
}
</#if>

<#if data.hasGlow>
@Override @OnlyIn(Dist.CLIENT) public boolean hasEffect(ItemStack itemstack) {
<#if hasCondition(data.glowCondition)>
PlayerEntity entity = Minecraft.getInstance().player;
World world = entity.world;
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
if (!(<@procedureOBJToConditionCode data.glowCondition/>)) {
return false;
}
</#if>
return true;
}
</#if>

<#if data.destroyAnyBlock>
@Override public boolean canHarvestBlock(BlockState state) {
return true;
}
</#if>

<#if data.specialInfo?has_content>
@Override public void addInformation(ItemStack itemstack, World world, List<ITextComponent> list, ITooltipFlag flag) {
super.addInformation(itemstack, world, list, flag);
<#list data.specialInfo as entry>
list.add(new StringTextComponent("${JavaConventions.escapeStringForJava(entry)}"));
</#list>
}
</#if>

<#if hasProcedure(data.onRightClickedInAir) || (data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>")>
@Override public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity entity, Hand hand) {
ActionResult<ItemStack> ar = super.onItemRightClick(world, entity, hand);
ItemStack itemstack = ar.getResult();
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();

<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
if(entity instanceof ServerPlayerEntity) {
NetworkHooks.openGui((ServerPlayerEntity) entity, new INamedContainerProvider() {

@Override public ITextComponent getDisplayName() {
return new StringTextComponent("${data.name}");
}

@Override public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player) {
PacketBuffer packetBuffer = new PacketBuffer(Unpooled.buffer());
packetBuffer.writeBlockPos(new BlockPos(x, y, z));
packetBuffer.writeByte(hand == Hand.MAIN_HAND ? 0 : 1);
return new ${(data.guiBoundTo)}Gui.GuiContainerMod(id, inventory, packetBuffer);
}

}, buf -> {
buf.writeBlockPos(new BlockPos(x, y, z));
buf.writeByte(hand == Hand.MAIN_HAND ? 0 : 1);
});
}
</#if>

<@procedureOBJToCode data.onRightClickedInAir/>
return ar;
}
</#if>

<#if hasProcedure(data.onRightClickedOnBlock)>
@Override public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) {
ActionResultType retval = super.onItemUseFirst(stack, context);
World world = context.getWorld();
BlockPos pos = context.getPos();
PlayerEntity entity = context.getPlayer();
Direction direction = context.getFace();
int x = pos.getX();
int y = pos.getY();
int z = pos.getZ();
ItemStack itemstack = context.getItem();
<@procedureOBJToCode data.onRightClickedOnBlock/>
return retval;
}
</#if>

<#if hasProcedure(data.onEntityHitWith)>
@Override public boolean hitEntity(ItemStack itemstack, LivingEntity entity, LivingEntity sourceentity) {
boolean retval = super.hitEntity(itemstack, entity, sourceentity);
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
World world = entity.world;
<@procedureOBJToCode data.onEntityHitWith/>
return retval;
}
</#if>

<#if hasProcedure(data.onEntitySwing)>
@Override public boolean onEntitySwing(ItemStack itemstack, LivingEntity entity) {
boolean retval = super.onEntitySwing(itemstack, entity);
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
World world = entity.world;
<@procedureOBJToCode data.onEntitySwing/>
return retval;
}
</#if>

<#if hasProcedure(data.onCrafted)>
@Override public void onCreated(ItemStack itemstack, World world, PlayerEntity entity) {
super.onCreated(itemstack, world, entity);
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
<@procedureOBJToCode data.onCrafted/>
}
</#if>

<#if hasProcedure(data.onStoppedUsing)>
@Override
public void onPlayerStoppedUsing(ItemStack itemstack, World world, LivingEntity entity, int time) {
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
<@procedureOBJToCode data.onStoppedUsing/>
}
</#if>

<#if hasProcedure(data.onItemInUseTick) || hasProcedure(data.onItemInInventoryTick)>
@Override public void inventoryTick(ItemStack itemstack, World world, Entity entity, int slot, boolean selected) {
super.inventoryTick(itemstack, world, entity, slot, selected);
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
<#if hasProcedure(data.onItemInUseTick)>
if (selected)
<@procedureOBJToCode data.onItemInUseTick/>
</#if>
<@procedureOBJToCode data.onItemInInventoryTick/>
}
</#if>

<#if hasProcedure(data.onDroppedByPlayer)>
@Override public boolean onDroppedByPlayer(ItemStack itemstack, PlayerEntity entity) {
double x = entity.getPosX();
double y = entity.getPosY();
double z = entity.getPosZ();
World world = entity.world;
<@procedureOBJToCode data.onDroppedByPlayer/>
return true;
}
</#if>

<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
@Override public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundNBT compound) {
return new InventoryCapability();
}

@Override public CompoundNBT getShareTag(ItemStack stack) {
CompoundNBT nbt = super.getShareTag(stack);
if(nbt != null)
stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).ifPresent(capability -> nbt.put("Inventory", ((ItemStackHandler) capability).serializeNBT()));
return nbt;
}

@Override public void readShareTag(ItemStack stack, @Nullable CompoundNBT nbt) {
super.readShareTag(stack, nbt);
if(nbt != null)
stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, null).ifPresent(capability -> ((ItemStackHandler) capability).deserializeNBT((CompoundNBT) nbt.get("Inventory")));
}
</#if>

}

<#if data.guiBoundTo?has_content && data.guiBoundTo != "<NONE>">
private static class InventoryCapability implements ICapabilitySerializable<CompoundNBT> {

private final LazyOptional<ItemStackHandler> inventory = LazyOptional.of(this::createItemHandler);

@Override public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> capability, @Nullable Direction side) {
return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY ? this.inventory.cast() : LazyOptional.empty();
}

@Override public CompoundNBT serializeNBT() {
return getItemHandler().serializeNBT();
}

@Override public void deserializeNBT(CompoundNBT nbt) {
getItemHandler().deserializeNBT(nbt);
}

private ItemStackHandler createItemHandler() {
return new ItemStackHandler(${data.inventorySize}) {

@Override public int getSlotLimit(int slot) {
return ${data.inventoryStackSize};
}

@Override public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
return stack.getItem() != block;
}

};
}

private ItemStackHandler getItemHandler() {
return inventory.orElseThrow(RuntimeException::new);
}

}
</#if>

}
<#-- @formatter:on -->
16 changes: 16 additions & 0 deletions plugins/generator-1.16.4/forge-1.16.4/templates/json/item.json.ftl
@@ -0,0 +1,16 @@
{
"parent": "item/generated",
"textures": {
<#if var_item?? && var_item=="helmet">
"layer0": "${modid}:items/${data.textureHelmet}"
<#elseif var_item?? && var_item=="body">
"layer0": "${modid}:items/${data.textureBody}"
<#elseif var_item?? && var_item=="leggings">
"layer0": "${modid}:items/${data.textureLeggings}"
<#elseif var_item?? && var_item=="boots">
"layer0": "${modid}:items/${data.textureBoots}"
<#else>
"layer0": "${modid}:items/${data.texture}"
</#if>
}
}