Special Tool Tiers

- Added Blazing, Shadow Steel and Gilded Rose Quartz tools with individual traits
This commit is contained in:
simibubi 2020-03-09 17:46:04 +01:00
parent 15680a6c0b
commit 59e9a76e49
34 changed files with 725 additions and 72 deletions

View file

@ -1,5 +1,11 @@
package com.simibubi.create; package com.simibubi.create;
import static com.simibubi.create.foundation.item.AllToolTypes.AXE;
import static com.simibubi.create.foundation.item.AllToolTypes.HOE;
import static com.simibubi.create.foundation.item.AllToolTypes.PICKAXE;
import static com.simibubi.create.foundation.item.AllToolTypes.SHOVEL;
import static com.simibubi.create.foundation.item.AllToolTypes.SWORD;
import java.util.function.Function; import java.util.function.Function;
import com.simibubi.create.foundation.item.IHaveCustomItemModel; import com.simibubi.create.foundation.item.IHaveCustomItemModel;
@ -15,7 +21,10 @@ import com.simibubi.create.modules.curiosities.RefinedRadianceItem;
import com.simibubi.create.modules.curiosities.ShadowSteelItem; import com.simibubi.create.modules.curiosities.ShadowSteelItem;
import com.simibubi.create.modules.curiosities.deforester.DeforesterItem; import com.simibubi.create.modules.curiosities.deforester.DeforesterItem;
import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem; import com.simibubi.create.modules.curiosities.symmetry.SymmetryWandItem;
import com.simibubi.create.modules.curiosities.tools.BlazingToolItem;
import com.simibubi.create.modules.curiosities.tools.RoseQuartzToolItem;
import com.simibubi.create.modules.curiosities.tools.SandPaperItem; import com.simibubi.create.modules.curiosities.tools.SandPaperItem;
import com.simibubi.create.modules.curiosities.tools.ShadowSteelToolItem;
import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperItem; import com.simibubi.create.modules.curiosities.zapper.blockzapper.BlockzapperItem;
import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainzapperItem; import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainzapperItem;
import com.simibubi.create.modules.gardens.TreeFertilizerItem; import com.simibubi.create.modules.gardens.TreeFertilizerItem;
@ -86,6 +95,7 @@ public enum AllItems {
WHISK, WHISK,
BRASS_HAND, BRASS_HAND,
SLOT_COVER, SLOT_COVER,
ZINC_HANDLE,
WRENCH(WrenchItem::new), WRENCH(WrenchItem::new),
GOGGLES(GogglesItem::new), GOGGLES(GogglesItem::new),
@ -100,6 +110,20 @@ public enum AllItems {
DEFORESTER(DeforesterItem::new), DEFORESTER(DeforesterItem::new),
SYMMETRY_WAND(SymmetryWandItem::new), SYMMETRY_WAND(SymmetryWandItem::new),
BLAZING_PICKAXE(p -> new BlazingToolItem(1, -2.8F, p, PICKAXE)),
BLAZING_SHOVEL(p -> new BlazingToolItem(1.5F, -3.0F, p, SHOVEL)),
BLAZING_AXE(p -> new BlazingToolItem(5.0F, -3.0F, p, AXE)),
BLAZING_SWORD(p -> new BlazingToolItem(3, -2.4F, p, SWORD)),
ROSE_QUARTZ_PICKAXE(p -> new RoseQuartzToolItem(1, -2.8F, p, PICKAXE)),
ROSE_QUARTZ_SHOVEL(p -> new RoseQuartzToolItem(1.5F, -3.0F, p, SHOVEL)),
ROSE_QUARTZ_AXE(p -> new RoseQuartzToolItem(5.0F, -3.0F, p, AXE)),
ROSE_QUARTZ_SWORD(p -> new RoseQuartzToolItem(3, -2.4F, p, SWORD)),
SHADOW_STEEL_PICKAXE(p -> new ShadowSteelToolItem(2.5F, -2.0F, p, PICKAXE)),
SHADOW_STEEL_MATTOCK(p -> new ShadowSteelToolItem(2.5F, -1.5F, p, SHOVEL, AXE, HOE)),
SHADOW_STEEL_SWORD(p -> new ShadowSteelToolItem(3, -2.0F, p, SWORD)),
; ;
private static class CategoryTracker { private static class CategoryTracker {

View file

@ -7,6 +7,7 @@ import java.util.function.Supplier;
import com.simibubi.create.foundation.behaviour.filtering.FilteringCountUpdatePacket; import com.simibubi.create.foundation.behaviour.filtering.FilteringCountUpdatePacket;
import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueUpdatePacket; import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueUpdatePacket;
import com.simibubi.create.foundation.command.ConfigureConfigPacket; import com.simibubi.create.foundation.command.ConfigureConfigPacket;
import com.simibubi.create.foundation.item.AbstractToolItem;
import com.simibubi.create.foundation.packet.NbtPacket; import com.simibubi.create.foundation.packet.NbtPacket;
import com.simibubi.create.foundation.packet.SimplePacketBase; import com.simibubi.create.foundation.packet.SimplePacketBase;
import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.ServerSpeedProvider;
@ -45,6 +46,7 @@ public enum AllPackets {
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new), BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new),
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new), CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new), CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new),
; ;

View file

@ -8,24 +8,33 @@ import static com.simibubi.create.foundation.item.AllToolTypes.SWORD;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Supplier;
import com.simibubi.create.foundation.packet.SimplePacketBase;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.IItemTier; import net.minecraft.item.IItemTier;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext; import net.minecraft.item.ItemUseContext;
import net.minecraft.item.Items; import net.minecraft.item.Items;
import net.minecraft.item.ToolItem; import net.minecraft.item.ToolItem;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.ToolType; import net.minecraftforge.common.ToolType;
import net.minecraftforge.event.world.BlockEvent.HarvestDropsEvent; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.network.NetworkEvent.Context;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
public abstract class AbstractToolItem extends ToolItem { public abstract class AbstractToolItem extends ToolItem {
protected AllToolTypes[] toolTypes; protected AllToolTypes[] toolTypes;
@ -36,6 +45,37 @@ public abstract class AbstractToolItem extends ToolItem {
toolTypes = types; toolTypes = types;
} }
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
boolean canEnchant = super.canApplyAtEnchantingTable(stack, enchantment);
for (AllToolTypes type : toolTypes) {
switch (type) {
case AXE:
canEnchant |= enchantment.canApply(new ItemStack(Items.DIAMOND_AXE));
break;
case HOE:
canEnchant |= enchantment.canApply(new ItemStack(Items.DIAMOND_HOE));
break;
case PICKAXE:
canEnchant |= enchantment.canApply(new ItemStack(Items.DIAMOND_PICKAXE));
break;
case SHEARS:
canEnchant |= enchantment.canApply(new ItemStack(Items.SHEARS));
break;
case SHOVEL:
canEnchant |= enchantment.canApply(new ItemStack(Items.DIAMOND_SHOVEL));
break;
case SWORD:
canEnchant |= enchantment.canApply(new ItemStack(Items.DIAMOND_SWORD));
break;
default:
break;
}
}
return canEnchant;
}
private static Properties setToolTypes(Properties builder, IItemTier tier, AllToolTypes... types) { private static Properties setToolTypes(Properties builder, IItemTier tier, AllToolTypes... types) {
for (AllToolTypes type : types) { for (AllToolTypes type : types) {
if (type == PICKAXE) if (type == PICKAXE)
@ -66,13 +106,13 @@ public abstract class AbstractToolItem extends ToolItem {
@Override @Override
public boolean canHarvestBlock(ItemStack stack, BlockState state) { public boolean canHarvestBlock(ItemStack stack, BlockState state) {
return super.canHarvestBlock(stack, state) return super.canHarvestBlock(stack, state) || getToolTypes(stack).contains(state.getHarvestTool())
|| hasType(SWORD) && Items.WOODEN_SWORD.canHarvestBlock(stack, state); || hasType(SWORD) && Items.WOODEN_SWORD.canHarvestBlock(stack, state);
} }
@Override @Override
public boolean canPlayerBreakBlockWhileHolding(BlockState state, World worldIn, BlockPos pos, PlayerEntity player) { public boolean canPlayerBreakBlockWhileHolding(BlockState state, World worldIn, BlockPos pos, PlayerEntity player) {
return hasType(SWORD) && !player.isCreative(); return !(hasType(SWORD) && !player.isCreative());
} }
@Override @Override
@ -82,22 +122,60 @@ public abstract class AbstractToolItem extends ToolItem {
return super.getDestroySpeed(stack, state); return super.getDestroySpeed(stack, state);
} }
@SubscribeEvent public boolean modifiesDrops() {
public static void onHarvestDrops(HarvestDropsEvent event) { return false;
PlayerEntity harvester = event.getHarvester();
if (harvester == null)
return;
ItemStack tool = harvester.getHeldItemMainhand();
if (tool.isEmpty() || !(tool.getItem() instanceof AbstractToolItem))
return;
if (event.getDrops() != null)
((AbstractToolItem) tool.getItem()).modifyDrops(event.getDrops(), event.getWorld(), event.getPos(), tool,
event.getState());
} }
public void modifyDrops(final List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) { public void modifyDrops(final List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
} }
public void spawnParticles(IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
}
public static class HarvestPacket extends SimplePacketBase {
private BlockState state;
private ItemStack stack;
private BlockPos pos;
private boolean self;
public HarvestPacket(BlockState state, ItemStack stack, BlockPos pos, boolean self) {
this.state = state;
this.stack = stack;
this.pos = pos;
this.self = self;
}
public HarvestPacket(PacketBuffer buffer) {
state = NBTUtil.readBlockState(buffer.readCompoundTag());
stack = buffer.readItemStack();
pos = buffer.readBlockPos();
self = buffer.readBoolean();
}
@Override
public void write(PacketBuffer buffer) {
buffer.writeCompoundTag(NBTUtil.writeBlockState(state));
buffer.writeItemStack(stack);
buffer.writeBlockPos(pos);
buffer.writeBoolean(self);
}
@Override
public void handle(Supplier<Context> context) {
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> this.spawnParticles(self)));
context.get().setPacketHandled(true);
}
@OnlyIn(Dist.CLIENT)
void spawnParticles(boolean self) {
if (!(stack.getItem() instanceof AbstractToolItem))
return;
ClientWorld world = Minecraft.getInstance().world;
if (!self)
world.playEvent(2001, pos, Block.getStateId(state));
((AbstractToolItem) stack.getItem()).spawnParticles(world, pos, stack, state);
}
}
} }

View file

@ -14,6 +14,7 @@ import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.IModule; import com.simibubi.create.modules.IModule;
import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.components.flywheel.engine.EngineBlock; import com.simibubi.create.modules.contraptions.components.flywheel.engine.EngineBlock;
import com.simibubi.create.modules.curiosities.tools.AllToolTiers;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
@ -86,7 +87,8 @@ public class TooltipHelper {
public static boolean hasTooltip(ItemStack stack) { public static boolean hasTooltip(ItemStack stack) {
checkLocale(); checkLocale();
boolean hasGlasses = AllItems.GOGGLES.typeOf(Minecraft.getInstance().player.getItemStackFromSlot(EquipmentSlotType.HEAD)); boolean hasGlasses =
AllItems.GOGGLES.typeOf(Minecraft.getInstance().player.getItemStackFromSlot(EquipmentSlotType.HEAD));
if (hasGlasses != gogglesMode) { if (hasGlasses != gogglesMode) {
gogglesMode = hasGlasses; gogglesMode = hasGlasses;
cachedTooltips.clear(); cachedTooltips.clear();
@ -161,6 +163,15 @@ public class TooltipHelper {
} }
public static String getTooltipTranslationKey(ItemStack stack) { public static String getTooltipTranslationKey(ItemStack stack) {
if (stack.getItem() instanceof AbstractToolItem) {
AbstractToolItem abstractToolItem = (AbstractToolItem) stack.getItem();
if (abstractToolItem.getTier() instanceof AllToolTiers) {
AllToolTiers allToolTiers = (AllToolTiers) abstractToolItem.getTier();
return "tool.create." + Lang.asId(allToolTiers.name()) + ".tooltip";
}
}
return stack.getItem().getTranslationKey(stack) + ".tooltip"; return stack.getItem().getTranslationKey(stack) + ".tooltip";
} }

View file

@ -52,7 +52,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
@Override @Override
protected Vec3d getSouthLocation() { protected Vec3d getSouthLocation() {
return super.getSouthLocation().add(0, 4/16f, 0); return super.getSouthLocation().add(0, 4 / 16f, 0);
} }
}; };
@ -191,7 +191,8 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
return false; return false;
NonNullList<Ingredient> ingredients = recipe.getIngredients(); NonNullList<Ingredient> ingredients = recipe.getIngredients();
if (!ingredients.stream().allMatch(Ingredient::isSimple)) if (!ingredients.stream()
.allMatch(ingredient -> (ingredient.isSimple() || ingredient.getMatchingStacks().length == 1)))
return false; return false;
List<ItemStack> remaining = new ArrayList<>(); List<ItemStack> remaining = new ArrayList<>();

View file

@ -11,7 +11,7 @@ import net.minecraft.util.LazyLoadBase;
public enum AllToolTiers implements IItemTier { public enum AllToolTiers implements IItemTier {
BLAZING(3, 750, 10.0F, 2.5F, 16, () -> { BLAZING(3, 450, 10.0F, 2.5F, 16, () -> {
return Ingredient.fromItems(Items.BLAZE_ROD); return Ingredient.fromItems(Items.BLAZE_ROD);
}), }),
@ -19,7 +19,7 @@ public enum AllToolTiers implements IItemTier {
return Ingredient.fromItems(AllItems.POLISHED_ROSE_QUARTZ.get()); return Ingredient.fromItems(AllItems.POLISHED_ROSE_QUARTZ.get());
}), }),
SHADOW_STEEL(4, 2303, 16.0F, 3.5F, 10, () -> { SHADOW_STEEL(4, 2303, 28.0F, 3.5F, 10, () -> {
return Ingredient.fromItems(AllItems.SHADOW_STEEL.get()); return Ingredient.fromItems(AllItems.SHADOW_STEEL.get());
}), }),
@ -29,22 +29,6 @@ public enum AllToolTiers implements IItemTier {
; ;
/* used to belong to AllItems. Banished here until harvest events exist */
// BLAZING_PICKAXE(new BlazingToolItem(1, -2.8F, standardProperties(), PICKAXE)),
// BLAZING_SHOVEL(new BlazingToolItem(1.5F, -3.0F, standardProperties(), SHOVEL)),
// BLAZING_AXE(new BlazingToolItem(5.0F, -3.0F, standardProperties(), AXE)),
// BLAZING_SWORD(new BlazingToolItem(3, -2.4F, standardProperties(), SWORD)),
//
// ROSE_QUARTZ_PICKAXE(new RoseQuartzToolItem(1, -2.8F, standardProperties(), PICKAXE)),
// ROSE_QUARTZ_SHOVEL(new RoseQuartzToolItem(1.5F, -3.0F, standardProperties(), SHOVEL)),
// ROSE_QUARTZ_AXE(new RoseQuartzToolItem(5.0F, -3.0F, standardProperties(), AXE)),
// ROSE_QUARTZ_SWORD(new RoseQuartzToolItem(3, -2.4F, standardProperties(), SWORD)),
//
// SHADOW_STEEL_PICKAXE(new ShadowSteelToolItem(2.5F, -2.0F, standardProperties(), PICKAXE)),
// SHADOW_STEEL_MATTOCK(new ShadowSteelToolItem(2.5F, -1.5F, standardProperties(), SHOVEL, AXE, HOE)),
// SHADOW_STEEL_SWORD(new ShadowSteelToolItem(3, -2.0F, standardProperties(), SWORD)),
private final int harvestLevel; private final int harvestLevel;
private final int maxUses; private final int maxUses;
private final float efficiency; private final float efficiency;

View file

@ -11,15 +11,16 @@ import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.FurnaceRecipe; import net.minecraft.item.crafting.FurnaceRecipe;
import net.minecraft.item.crafting.IRecipeType; import net.minecraft.item.crafting.IRecipeType;
import net.minecraft.item.crafting.RecipeManager; import net.minecraft.item.crafting.RecipeManager;
import net.minecraft.particles.ParticleTypes; import net.minecraft.particles.ParticleTypes;
import net.minecraft.tileentity.FurnaceTileEntity; import net.minecraft.tileentity.FurnaceTileEntity;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
@ -56,39 +57,52 @@ public class BlazingToolItem extends AbstractToolItem {
return world.getDimension().getType() != DimensionType.THE_NETHER; return world.getDimension().getType() != DimensionType.THE_NETHER;
} }
@Override
public boolean modifiesDrops() {
return true;
}
@Override @Override
public void modifyDrops(List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) { public void modifyDrops(List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
super.modifyDrops(drops, world, pos, tool, state); super.modifyDrops(drops, world, pos, tool, state);
World worldIn = world.getWorld(); World worldIn = world.getWorld();
helperFurnace.setWorld(worldIn); helperFurnace.setWorld(worldIn);
RecipeManager recipeManager = worldIn.getRecipeManager();
RecipeManager recipeManager = worldIn.getRecipeManager();
int enchantmentLevel = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, tool);
List<ItemStack> smeltedStacks = new ArrayList<>(); List<ItemStack> smeltedStacks = new ArrayList<>();
Iterator<ItemStack> dropper = drops.iterator(); Iterator<ItemStack> dropper = drops.iterator();
while (dropper.hasNext()) { while (dropper.hasNext()) {
ItemStack stack = dropper.next(); ItemStack stack = dropper.next();
helperFurnace.setInventorySlotContents(0, stack); helperFurnace.setInventorySlotContents(0, stack);
Optional<FurnaceRecipe> smeltingRecipe = recipeManager.getRecipe(IRecipeType.SMELTING, helperFurnace, Optional<FurnaceRecipe> smeltingRecipe =
worldIn); recipeManager.getRecipe(IRecipeType.SMELTING, helperFurnace, worldIn);
if (!smeltingRecipe.isPresent()) if (!smeltingRecipe.isPresent())
continue; continue;
dropper.remove(); dropper.remove();
ItemStack out = smeltingRecipe.get().getRecipeOutput().copy(); ItemStack out = smeltingRecipe.get().getRecipeOutput().copy();
smeltedStacks.addAll(ItemHelper.multipliedOutput(stack, out));
}
if (world.isRemote() && !smeltedStacks.isEmpty()) { float modifier = 1;
for (int i = 0; i < 10; i++) { if (stack.getItem() instanceof BlockItem && !(out.getItem() instanceof BlockItem))
Vec3d flamePos = VecHelper.offsetRandomly(VecHelper.getCenterOf(pos), world.getRandom(), .45f); modifier += world.getRandom().nextFloat() * enchantmentLevel;
Vec3d smokePos = VecHelper.offsetRandomly(VecHelper.getCenterOf(pos), world.getRandom(), .45f);
world.addParticle(ParticleTypes.FLAME, flamePos.getX(), flamePos.getY(), flamePos.getZ(), 0, .1f, 0); out.setCount((int) (out.getCount() * modifier + .4f));
world.addParticle(ParticleTypes.SMOKE, smokePos.getX(), smokePos.getY(), smokePos.getZ(), 0, .1f, 0); smeltedStacks.addAll(ItemHelper.multipliedOutput(stack, out));
}
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, SoundCategory.BLOCKS, .5f, .1f);
} }
drops.addAll(smeltedStacks); drops.addAll(smeltedStacks);
} }
@Override
public void spawnParticles(IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
if (!canHarvestBlock(tool, state))
return;
for (int i = 0; i < 10; i++) {
Vec3d flamePos = VecHelper.offsetRandomly(VecHelper.getCenterOf(pos), world.getRandom(), .45f);
Vec3d smokePos = VecHelper.offsetRandomly(VecHelper.getCenterOf(pos), world.getRandom(), .45f);
world.addParticle(ParticleTypes.FLAME, flamePos.getX(), flamePos.getY(), flamePos.getZ(), 0, .01f, 0);
world.addParticle(ParticleTypes.SMOKE, smokePos.getX(), smokePos.getY(), smokePos.getZ(), 0, .1f, 0);
}
}
} }

View file

@ -1,12 +1,27 @@
package com.simibubi.create.modules.curiosities.tools; package com.simibubi.create.modules.curiosities.tools;
import java.util.UUID;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.simibubi.create.foundation.item.AbstractToolItem; import com.simibubi.create.foundation.item.AbstractToolItem;
import com.simibubi.create.foundation.item.AllToolTypes; import com.simibubi.create.foundation.item.AllToolTypes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.PlayerEntity;
public class RoseQuartzToolItem extends AbstractToolItem { public class RoseQuartzToolItem extends AbstractToolItem {
static Multimap<String, AttributeModifier> rangeModifier;
static final UUID attributeId = UUID.fromString("7f7dbdb2-0d0d-458a-aa40-ac7633691f66");
public RoseQuartzToolItem(float attackDamageIn, float attackSpeedIn, Properties builder, AllToolTypes... types) { public RoseQuartzToolItem(float attackDamageIn, float attackSpeedIn, Properties builder, AllToolTypes... types) {
super(attackDamageIn, attackSpeedIn, AllToolTiers.ROSE_QUARTZ, builder, types); super(attackDamageIn, attackSpeedIn, AllToolTiers.ROSE_QUARTZ, builder, types);
if (rangeModifier == null) {
rangeModifier = HashMultimap.create();
rangeModifier.put(PlayerEntity.REACH_DISTANCE.getName(),
new AttributeModifier(attributeId, "Range modifier", 3, AttributeModifier.Operation.ADDITION));
}
} }
} }

View file

@ -4,22 +4,37 @@ import java.util.List;
import com.simibubi.create.foundation.item.AbstractToolItem; import com.simibubi.create.foundation.item.AbstractToolItem;
import com.simibubi.create.foundation.item.AllToolTypes; import com.simibubi.create.foundation.item.AllToolTypes;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
public class ShadowSteelToolItem extends AbstractToolItem { public class ShadowSteelToolItem extends AbstractToolItem {
public ShadowSteelToolItem(float attackDamageIn, float attackSpeedIn, Properties builder, public ShadowSteelToolItem(float attackDamageIn, float attackSpeedIn, Properties builder, AllToolTypes... types) {
AllToolTypes... types) {
super(attackDamageIn, attackSpeedIn, AllToolTiers.SHADOW_STEEL, builder, types); super(attackDamageIn, attackSpeedIn, AllToolTiers.SHADOW_STEEL, builder, types);
} }
@Override
public boolean modifiesDrops() {
return true;
}
@Override @Override
public void modifyDrops(List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) { public void modifyDrops(List<ItemStack> drops, IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
drops.clear(); drops.clear();
} }
@Override
public void spawnParticles(IWorld world, BlockPos pos, ItemStack tool, BlockState state) {
if (!canHarvestBlock(tool, state))
return;
Vec3d smokePos = VecHelper.offsetRandomly(VecHelper.getCenterOf(pos), world.getRandom(), .15f);
world.addParticle(ParticleTypes.SMOKE, smokePos.getX(), smokePos.getY(), smokePos.getZ(), 0, .01f, 0);
}
} }

View file

@ -0,0 +1,136 @@
package com.simibubi.create.modules.curiosities.tools;
import java.util.List;
import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.item.AbstractToolItem;
import com.simibubi.create.foundation.item.AbstractToolItem.HarvestPacket;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.loot.LootContext.Builder;
import net.minecraft.world.storage.loot.LootParameters;
import net.minecraftforge.event.entity.living.LivingDropsEvent;
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
import net.minecraftforge.event.entity.living.LivingExperienceDropEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.eventbus.api.Event.Result;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import net.minecraftforge.fml.network.PacketDistributor;
@EventBusSubscriber
public class ToolEvents {
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void toolsCanModifyBlockDrops(BlockEvent.BreakEvent event) {
if (event.isCanceled())
return;
PlayerEntity player = event.getPlayer();
ItemStack held = player.getHeldItemMainhand();
if (player.isCreative())
return;
if (!(held.getItem() instanceof AbstractToolItem))
return;
AbstractToolItem tool = (AbstractToolItem) held.getItem();
if (!tool.modifiesDrops())
return;
BlockState state = event.getState();
if (!tool.canHarvestBlock(held, state))
return;
IWorld world = event.getWorld();
BlockPos pos = event.getPos();
boolean onServer = !world.isRemote();
if (!onServer) {
tool.spawnParticles(world, pos, held, state);
return;
}
World actualWorld = world.getWorld();
if (!(actualWorld instanceof ServerWorld))
return;
List<ItemStack> drops = state.getDrops(new Builder((ServerWorld) actualWorld)
.withRandom(actualWorld.getRandom()).withParameter(LootParameters.POSITION, pos)
.withParameter(LootParameters.TOOL, held).withParameter(LootParameters.THIS_ENTITY, player)
.withNullableParameter(LootParameters.BLOCK_ENTITY, world.getTileEntity(pos)));
tool.modifyDrops(drops, world, pos, held, state);
tool.onBlockDestroyed(held, actualWorld, state, pos, player);
world.setBlockState(pos, Blocks.AIR.getDefaultState(), 3);
for (ItemStack dropped : drops)
Block.spawnAsEntity(actualWorld, pos, dropped);
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> player),
new HarvestPacket(state, held, pos, false));
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) player),
new HarvestPacket(state, held, pos, true));
event.setResult(Result.DENY);
}
@SubscribeEvent
public static void holdingRoseQuartzToolIncreasesRange(LivingUpdateEvent event) {
if (!(event.getEntity() instanceof PlayerEntity))
return;
if (event.isCanceled())
return;
PlayerEntity player = (PlayerEntity) event.getEntityLiving();
ItemStack heldItemMainhand = player.getHeldItemMainhand();
String marker = "create_roseQuartzRange";
CompoundNBT persistentData = player.getPersistentData();
if (!(heldItemMainhand.getItem() instanceof RoseQuartzToolItem)) {
if (persistentData.contains(marker)) {
player.getAttributes().removeAttributeModifiers(RoseQuartzToolItem.rangeModifier);
persistentData.remove(marker);
}
return;
}
if (!persistentData.contains(marker)) {
player.getAttributes().applyAttributeModifiers(RoseQuartzToolItem.rangeModifier);
persistentData.putBoolean(marker, true);
}
}
@SubscribeEvent
public static void shadowSteelToolsDoNotDropEntityLoot(LivingDropsEvent event) {
if (!(event.getSource() instanceof EntityDamageSource))
return;
EntityDamageSource source = (EntityDamageSource) event.getSource();
Entity trueSource = source.getTrueSource();
if (trueSource != null && trueSource instanceof PlayerEntity) {
PlayerEntity player = (PlayerEntity) trueSource;
if (player.getHeldItemMainhand().getItem() instanceof ShadowSteelToolItem)
event.setCanceled(true);
}
}
@SubscribeEvent
public static void shadowSteelToolsDropMoreXPonKill(LivingExperienceDropEvent event) {
ItemStack heldItemMainhand = event.getAttackingPlayer().getHeldItemMainhand();
if (heldItemMainhand.getItem() instanceof ShadowSteelToolItem) {
int level = EnchantmentHelper.getEnchantmentLevel(Enchantments.LOOTING, heldItemMainhand);
float modifier = 1 + event.getEntity().world.getRandom().nextFloat() * level;
event.setDroppedExperience((int) (event.getDroppedExperience() * modifier + .4f));
}
}
}

View file

@ -28,6 +28,7 @@
"item.create.whisk": "Whisk", "item.create.whisk": "Whisk",
"item.create.brass_hand": "Hand", "item.create.brass_hand": "Hand",
"item.create.slot_cover": "Crafter Slot Cover", "item.create.slot_cover": "Crafter Slot Cover",
"item.create.zinc_handle": "Quality Tool Handle",
"item.create.flour": "Wheat Flour", "item.create.flour": "Wheat Flour",
"item.create.dough": "Dough", "item.create.dough": "Dough",
"item.create.wrench": "Wrench", "item.create.wrench": "Wrench",
@ -62,7 +63,7 @@
"item.create.blazing_pickaxe": "Blazing Pickaxe", "item.create.blazing_pickaxe": "Blazing Pickaxe",
"item.create.blazing_shovel": "Blazing Shovel", "item.create.blazing_shovel": "Blazing Shovel",
"item.create.blazing_axe": "Blazing Axe", "item.create.blazing_axe": "Blazing Axe",
"item.create.blazing_sword": "Blazing Longsword", "item.create.blazing_sword": "Blazing Cleaver",
"item.create.shadow_steel_pickaxe": "Shadow Steel Pickaxe", "item.create.shadow_steel_pickaxe": "Shadow Steel Pickaxe",
"item.create.shadow_steel_mattock": "Shadow Steel Garden Mattock", "item.create.shadow_steel_mattock": "Shadow Steel Garden Mattock",
@ -1113,6 +1114,15 @@
"item.create.slot_cover.tooltip": "SLOT COVER", "item.create.slot_cover.tooltip": "SLOT COVER",
"item.create.slot_cover.tooltip.summary": "Used to mark a _Mechanical_ _Crafter_ as an empty slot in a recipe. Crafters do not necessarily have to form a full square grid, this cover find its use when there are recipes where _ingredients_ _are_ _diagonal_ to each other.", "item.create.slot_cover.tooltip.summary": "Used to mark a _Mechanical_ _Crafter_ as an empty slot in a recipe. Crafters do not necessarily have to form a full square grid, this cover find its use when there are recipes where _ingredients_ _are_ _diagonal_ to each other.",
"tool.create.shadow_steel.tooltip": "SHADOW STEEL TOOLS",
"tool.create.shadow_steel.tooltip.summary": "This tool breaks blocks _extremely_ _quick,_ but _shatters_ all of their _drops_ with them. Killed mobs can drop _more_ _experience_ based on the _Looting_ modifier of this tool.",
"tool.create.blazing.tooltip": "BLAZING TOOLS",
"tool.create.blazing.tooltip.summary": "This tool will _melt_ _broken_ _blocks_ and _ignite_ _attacked_ _mobs._ It will not lose Durability while being used in the _Nether._",
"tool.create.rose_quartz.tooltip": "ROSE QUARTZ TOOLS",
"tool.create.rose_quartz.tooltip.summary": "This tool grants you a _greater_ _reach_ for _breaking_ _blocks_ or _placing_ _blocks_ from the off-hand.",
"item.create.logistical_controller_calculation.tooltip": "WIP", "item.create.logistical_controller_calculation.tooltip": "WIP",
"item.create.logistical_controller_request.tooltip": "WIP", "item.create.logistical_controller_request.tooltip": "WIP",
"item.create.logistical_controller_storage.tooltip": "WIP", "item.create.logistical_controller_storage.tooltip": "WIP",

View file

@ -1,5 +1,5 @@
{ {
"parent": "item/handheld", "parent": "create:item/rose_quartz_tool",
"textures": { "textures": {
"layer0": "create:item/rose_quartz_axe" "layer0": "create:item/rose_quartz_axe"
} }

View file

@ -1,5 +1,5 @@
{ {
"parent": "item/handheld", "parent": "create:item/rose_quartz_tool",
"textures": { "textures": {
"layer0": "create:item/rose_quartz_pickaxe" "layer0": "create:item/rose_quartz_pickaxe"
} }

View file

@ -1,5 +1,5 @@
{ {
"parent": "item/handheld", "parent": "create:item/rose_quartz_tool",
"textures": { "textures": {
"layer0": "create:item/rose_quartz_shovel" "layer0": "create:item/rose_quartz_shovel"
} }

View file

@ -1,5 +1,5 @@
{ {
"parent": "item/handheld", "parent": "create:item/rose_quartz_tool",
"textures": { "textures": {
"layer0": "create:item/rose_quartz_sword" "layer0": "create:item/rose_quartz_sword"
} }

View file

@ -0,0 +1,15 @@
{
"parent": "item/handheld",
"display": {
"firstperson_righthand": {
"rotation": [ 0, -90, 25 ],
"translation": [ 1.13, 4.2, 1.13 ],
"scale": [ 0.68, 0.68, 0.68 ]
},
"firstperson_lefthand": {
"rotation": [ 0, 90, -25 ],
"translation": [ 1.13, 4.2, 1.13 ],
"scale": [ 0.68, 0.68, 0.68 ]
}
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/tool_handle"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 479 B

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 508 B

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

View file

@ -0,0 +1,26 @@
{
"type": "crafting_shaped",
"pattern": [
"PPP",
"PS ",
" S "
],
"key": {
"S": {
"item": "create:zinc_handle"
},
"P": {
"item": "create:shadow_steel"
}
},
"result": {
"item": "create:shadow_steel_mattock",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "curiosities"
}
]
}

View file

@ -0,0 +1,26 @@
{
"type": "crafting_shaped",
"pattern": [
"PPP",
" S ",
" S "
],
"key": {
"S": {
"item": "create:zinc_handle"
},
"P": {
"item": "create:shadow_steel"
}
},
"result": {
"item": "create:shadow_steel_pickaxe",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "curiosities"
}
]
}

View file

@ -0,0 +1,26 @@
{
"type": "crafting_shaped",
"pattern": [
"P",
"P",
"S"
],
"key": {
"S": {
"item": "create:zinc_handle"
},
"P": {
"item": "create:shadow_steel"
}
},
"result": {
"item": "create:shadow_steel_sword",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "curiosities"
}
]
}

View file

@ -0,0 +1,16 @@
{
"type": "crafting_shaped",
"pattern": [
"Z",
"Z"
],
"key": {
"Z": {
"tag": "forge:ingots/zinc"
}
},
"result": {
"item": "create:zinc_handle",
"count": 1
}
}

View file

@ -0,0 +1,33 @@
{
"type": "create:mechanical_crafting",
"pattern": [
" C ",
"RGR",
"RZ ",
" Z "
],
"key": {
"Z": {
"item": "create:zinc_handle"
},
"R": {
"item": "create:polished_rose_quartz"
},
"C": {
"tag": "forge:plates/iron"
},
"G": {
"tag": "forge:ingots/gold"
}
},
"result": {
"item": "create:rose_quartz_axe",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -0,0 +1,33 @@
{
"type": "create:mechanical_crafting",
"pattern": [
" C ",
"RGR",
"RZR",
" Z "
],
"key": {
"Z": {
"item": "create:zinc_handle"
},
"R": {
"item": "create:polished_rose_quartz"
},
"C": {
"tag": "forge:plates/iron"
},
"G": {
"tag": "forge:ingots/gold"
}
},
"result": {
"item": "create:rose_quartz_pickaxe",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -0,0 +1,33 @@
{
"type": "create:mechanical_crafting",
"pattern": [
" R ",
"CGC",
" Z ",
" Z "
],
"key": {
"Z": {
"item": "create:zinc_handle"
},
"R": {
"item": "create:polished_rose_quartz"
},
"C": {
"tag": "forge:plates/iron"
},
"G": {
"tag": "forge:ingots/gold"
}
},
"result": {
"item": "create:rose_quartz_shovel",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -0,0 +1,33 @@
{
"type": "create:mechanical_crafting",
"pattern": [
" R ",
" R ",
"CGC",
" Z "
],
"key": {
"Z": {
"item": "create:zinc_handle"
},
"R": {
"item": "create:polished_rose_quartz"
},
"C": {
"tag": "forge:plates/iron"
},
"G": {
"tag": "forge:ingots/gold"
}
},
"result": {
"item": "create:rose_quartz_sword",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}

View file

@ -0,0 +1,29 @@
{
"type": "create:mixing",
"ingredients": [
{
"item": "minecraft:golden_axe"
},
{
"item": "create:obsidian_dust"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
}
],
"results": [
{
"item": "create:blazing_axe",
"count": 1
}
]
}

View file

@ -0,0 +1,29 @@
{
"type": "create:mixing",
"ingredients": [
{
"item": "minecraft:golden_pickaxe"
},
{
"item": "create:obsidian_dust"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
}
],
"results": [
{
"item": "create:blazing_pickaxe",
"count": 1
}
]
}

View file

@ -0,0 +1,29 @@
{
"type": "create:mixing",
"ingredients": [
{
"item": "minecraft:golden_shovel"
},
{
"item": "create:obsidian_dust"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
}
],
"results": [
{
"item": "create:blazing_shovel",
"count": 1
}
]
}

View file

@ -0,0 +1,29 @@
{
"type": "create:mixing",
"ingredients": [
{
"item": "minecraft:golden_sword"
},
{
"item": "create:obsidian_dust"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
},
{
"item": "minecraft:blaze_powder"
}
],
"results": [
{
"item": "create:blazing_sword",
"count": 1
}
]
}