More work on potato cannon projectile types

This commit is contained in:
PepperCode1 2025-02-24 16:41:34 -08:00
parent 8dd17cf7c2
commit ac20501426
22 changed files with 439 additions and 415 deletions

View file

@ -268,7 +268,6 @@ import com.simibubi.create.foundation.data.ModelGen;
import com.simibubi.create.foundation.data.SharedProperties;
import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.UncontainableBlockItem;
import com.simibubi.create.foundation.utility.ColorHandlers;
import com.simibubi.create.foundation.utility.DyeHelper;
import com.simibubi.create.infrastructure.config.CStress;
import com.tterrag.registrate.providers.RegistrateRecipeProvider;
@ -296,6 +295,7 @@ import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.IronBarsBlock;
import net.minecraft.world.level.block.RedStoneWireBlock;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -1259,7 +1259,8 @@ public class AllBlocks {
.transform(pickaxeOnly())
.blockstate(new ControllerRailGenerator()::generate)
.addLayer(() -> RenderType::cutoutMipped)
.color(() -> ColorHandlers::getRedstonePower)
.color(() -> () -> (state, world, pos, layer) -> RedStoneWireBlock
.getColorForPower(pos != null && world != null ? state.getValue(BlockStateProperties.POWER) : 0))
.tag(BlockTags.RAILS)
.item()
.model((c, p) -> p.generated(c, Create.asResource("block/" + c.getName())))

View file

@ -26,6 +26,7 @@ import com.simibubi.create.content.schematics.ServerSchematicLoader;
import com.simibubi.create.content.trains.GlobalRailwayManager;
import com.simibubi.create.content.trains.bogey.BogeySizes;
import com.simibubi.create.content.trains.track.AllPortalTracks;
import com.simibubi.create.foundation.CreateNBTProcessors;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.block.CopperRegistries;
@ -33,7 +34,6 @@ import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.item.KineticStats;
import com.simibubi.create.foundation.item.TooltipModifier;
import com.simibubi.create.foundation.utility.CreateNBTProcessors;
import com.simibubi.create.infrastructure.command.ServerLagger;
import com.simibubi.create.infrastructure.config.AllConfigs;
import com.simibubi.create.infrastructure.data.CreateDatagen;

View file

@ -20,9 +20,9 @@ import com.simibubi.create.content.schematics.client.SchematicHandler;
import com.simibubi.create.content.trains.GlobalRailwayManager;
import com.simibubi.create.foundation.ClientResourceReloadListener;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsClient;
import com.simibubi.create.foundation.model.ModelSwapper;
import com.simibubi.create.foundation.ponder.CreatePonderPlugin;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import com.simibubi.create.foundation.utility.ModelSwapper;
import com.simibubi.create.infrastructure.config.AllConfigs;
import com.simibubi.create.infrastructure.gui.CreateMainMenuScreen;
@ -40,6 +40,7 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;

View file

@ -4,8 +4,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import com.simibubi.create.api.equipment.potatoCannon.PotatoProjectileEntityHitAction.Type;
@ -17,15 +15,12 @@ import com.simibubi.create.content.equipment.potatoCannon.AllPotatoProjectileRen
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
import net.minecraft.core.HolderSet;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.RegistryCodecs;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
@ -55,26 +50,12 @@ public record PotatoCannonProjectileType(HolderSet<Item> items, int reloadTicks,
PotatoProjectileBlockHitAction.CODEC.optionalFieldOf("on_entity_hit").forGetter(p -> p.onBlockHit)
).apply(i, PotatoCannonProjectileType::new));
@Nullable
public static PotatoCannonProjectileType getTypeForItem(Level level, Item item) {
public static Optional<Reference<PotatoCannonProjectileType>> getTypeForItem(RegistryAccess registryAccess, Item item) {
// Cache this if it causes performance issues, but it probably won't
List<PotatoCannonProjectileType> types = level.registryAccess()
.lookupOrThrow(CreateRegistries.POTATO_PROJECTILE_TYPE)
return registryAccess.lookupOrThrow(CreateRegistries.POTATO_PROJECTILE_TYPE)
.listElements()
.map(Reference::value)
.toList();
for (PotatoCannonProjectileType type : types)
if (type.items.contains(item.builtInRegistryHolder()))
return type;
return null;
}
public static Optional<PotatoCannonProjectileType> getTypeForStack(Level level, ItemStack item) {
if (item.isEmpty())
return Optional.empty();
return Optional.ofNullable(getTypeForItem(level, item.getItem()));
.filter(ref -> ref.value().items.contains(item.builtInRegistryHolder()))
.findFirst();
}
public boolean preEntityHit(ItemStack stack, EntityHitResult ray) {
@ -96,8 +77,6 @@ public record PotatoCannonProjectileType(HolderSet<Item> items, int reloadTicks,
}
public static class Builder {
private ResourceLocation id;
private final List<Holder<Item>> items = new ArrayList<>();
private int reloadTicks = 10;
private int damage = 1;
@ -114,10 +93,6 @@ public record PotatoCannonProjectileType(HolderSet<Item> items, int reloadTicks,
private PotatoProjectileEntityHitAction onEntityHit = null;
private PotatoProjectileBlockHitAction onBlockHit = null;
public Builder(ResourceLocation id) {
this.id = id;
}
public Builder reloadTicks(int reload) {
this.reloadTicks = reload;
return this;
@ -209,8 +184,8 @@ public record PotatoCannonProjectileType(HolderSet<Item> items, int reloadTicks,
return this;
}
public void register(BootstapContext<PotatoCannonProjectileType> ctx) {
PotatoCannonProjectileType type = new PotatoCannonProjectileType(
public PotatoCannonProjectileType build() {
return new PotatoCannonProjectileType(
HolderSet.direct(items),
reloadTicks,
damage,
@ -227,12 +202,6 @@ public record PotatoCannonProjectileType(HolderSet<Item> items, int reloadTicks,
Optional.ofNullable(onEntityHit),
Optional.ofNullable(onBlockHit)
);
ctx.register(ResourceKey.create(CreateRegistries.POTATO_PROJECTILE_TYPE, id), type);
}
public void registerAndAssign(BootstapContext<PotatoCannonProjectileType> ctx, ItemLike... items) {
addItems(items);
register(ctx);
}
}
}

View file

@ -73,7 +73,6 @@ import com.simibubi.create.content.trains.bogey.AbstractBogeyBlock;
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.ICoordinate;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.data.Iterate;
@ -86,6 +85,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.HolderGetter;
import net.minecraft.core.Vec3i;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
@ -1389,7 +1389,7 @@ public abstract class Contraption {
public void expandBoundsAroundAxis(Axis axis) {
Set<BlockPos> blocks = getBlocks().keySet();
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
int radius = (int) (Math.ceil(getRadius(blocks, axis)));
int maxX = radius + 2;
int maxY = radius + 2;
@ -1398,13 +1398,13 @@ public abstract class Contraption {
int minY = -radius - 1;
int minZ = -radius - 1;
if (axis == Direction.Axis.X) {
if (axis == Axis.X) {
maxX = (int) bounds.maxX;
minX = (int) bounds.minX;
} else if (axis == Direction.Axis.Y) {
} else if (axis == Axis.Y) {
maxY = (int) bounds.maxY;
minY = (int) bounds.minY;
} else if (axis == Direction.Axis.Z) {
} else if (axis == Axis.Z) {
maxZ = (int) bounds.maxZ;
minZ = (int) bounds.minZ;
}
@ -1489,32 +1489,38 @@ public abstract class Contraption {
});
}
public static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
public static double getRadius(Iterable<? extends Vec3i> blocks, Axis axis) {
Axis axisA;
Axis axisB;
switch (axis) {
case X:
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
case Y:
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
case Z:
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
case X -> {
axisA = Axis.Y;
axisB = Axis.Z;
}
case Y -> {
axisA = Axis.X;
axisB = Axis.Z;
}
case Z -> {
axisA = Axis.X;
axisB = Axis.Y;
}
default -> throw new IllegalStateException("Unexpected value: " + axis);
}
throw new IllegalStateException("Impossible axis");
}
int maxDistSq = 0;
for (Vec3i vec : blocks) {
int a = vec.get(axisA);
int b = vec.get(axisB);
public static float getMaxDistSqr(Set<BlockPos> blocks, ICoordinate one, ICoordinate other) {
float maxDistSq = -1;
for (BlockPos pos : blocks) {
float a = one.get(pos);
float b = other.get(pos);
float distSq = a * a + b * b;
int distSq = a * a + b * b;
if (distSq > maxDistSq)
maxDistSq = distSq;
}
return maxDistSq;
return Math.sqrt(maxDistSq);
}
public MountedStorageManager getStorage() {

View file

@ -1,9 +1,10 @@
package com.simibubi.create.content.equipment.clipboard;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import javax.annotation.Nullable;
import com.simibubi.create.foundation.utility.CreateNBTProcessors;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.CreateNBTProcessors;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
@ -11,9 +12,8 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent.Context;
import javax.annotation.Nullable;
import net.minecraftforge.network.NetworkEvent.Context;
public class ClipboardEditPacket extends SimplePacketBase {

View file

@ -21,32 +21,34 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
public class AllPotatoProjectileTypes {
public static ResourceKey<PotatoCannonProjectileType> FALLBACK = ResourceKey.create(CreateRegistries.POTATO_PROJECTILE_TYPE, Create.asResource("fallback"));
public static final ResourceKey<PotatoCannonProjectileType> FALLBACK = ResourceKey.create(CreateRegistries.POTATO_PROJECTILE_TYPE, Create.asResource("fallback"));
public static void bootstrap(BootstapContext<PotatoCannonProjectileType> ctx) {
create("fallback")
register(ctx, "fallback", new PotatoCannonProjectileType.Builder()
.damage(0)
.register(ctx);
.build());
create("potato")
register(ctx, "potato", new PotatoCannonProjectileType.Builder()
.damage(5)
.reloadTicks(15)
.velocity(1.25f)
.knockback(1.5f)
.renderTumbling()
.onBlockHit(new PlantCrop(Blocks.POTATOES))
.registerAndAssign(ctx, Items.POTATO);
.addItems(Items.POTATO)
.build());
create("baked_potato")
register(ctx, "baked_potato", new PotatoCannonProjectileType.Builder()
.damage(5)
.reloadTicks(15)
.velocity(1.25f)
.knockback(0.5f)
.renderTumbling()
.preEntityHit(SetOnFire.seconds(3))
.registerAndAssign(ctx, Items.BAKED_POTATO);
.addItems(Items.BAKED_POTATO)
.build());
create("carrot")
register(ctx, "carrot", new PotatoCannonProjectileType.Builder()
.damage(4)
.reloadTicks(12)
.velocity(1.45f)
@ -54,18 +56,20 @@ public class AllPotatoProjectileTypes {
.renderTowardMotion(140, 1)
.soundPitch(1.5f)
.onBlockHit(new PlantCrop(Blocks.CARROTS))
.registerAndAssign(ctx, Items.CARROT);
.addItems(Items.CARROT)
.build());
create("golden_carrot")
register(ctx, "golden_carrot", new PotatoCannonProjectileType.Builder()
.damage(12)
.reloadTicks(15)
.velocity(1.45f)
.knockback(0.5f)
.renderTowardMotion(140, 2)
.soundPitch(1.5f)
.registerAndAssign(ctx, Items.GOLDEN_CARROT);
.addItems(Items.GOLDEN_CARROT)
.build());
create("sweet_berry")
register(ctx, "sweet_berry", new PotatoCannonProjectileType.Builder()
.damage(3)
.reloadTicks(10)
.knockback(0.1f)
@ -73,9 +77,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.splitInto(3)
.soundPitch(1.25f)
.registerAndAssign(ctx, Items.SWEET_BERRIES);
.addItems(Items.SWEET_BERRIES)
.build());
create("glow_berry")
register(ctx, "glow_berry", new PotatoCannonProjectileType.Builder()
.damage(2)
.reloadTicks(10)
.knockback(0.05f)
@ -84,9 +89,10 @@ public class AllPotatoProjectileTypes {
.splitInto(2)
.soundPitch(1.2f)
.onEntityHit(new PotionEffect(MobEffects.GLOWING, 1, 200, false))
.registerAndAssign(ctx, Items.GLOW_BERRIES);
.addItems(Items.GLOW_BERRIES)
.build());
create("chocolate_berry")
register(ctx, "chocolate_berry", new PotatoCannonProjectileType.Builder()
.damage(4)
.reloadTicks(10)
.knockback(0.2f)
@ -94,36 +100,40 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.splitInto(3)
.soundPitch(1.25f)
.registerAndAssign(ctx, AllItems.CHOCOLATE_BERRIES.get());
.addItems(AllItems.CHOCOLATE_BERRIES.get())
.build());
create("poison_potato")
register(ctx, "poison_potato", new PotatoCannonProjectileType.Builder()
.damage(5)
.reloadTicks(15)
.knockback(0.05f)
.velocity(1.25f)
.renderTumbling()
.onEntityHit(new PotionEffect(MobEffects.POISON, 1, 160, true))
.registerAndAssign(ctx, Items.POISONOUS_POTATO);
.addItems(Items.POISONOUS_POTATO)
.build());
create("chorus_fruit")
register(ctx, "chorus_fruit", new PotatoCannonProjectileType.Builder()
.damage(3)
.reloadTicks(15)
.velocity(1.20f)
.knockback(0.05f)
.renderTumbling()
.onEntityHit(new ChorusTeleport(20))
.registerAndAssign(ctx, Items.CHORUS_FRUIT);
.addItems(Items.CHORUS_FRUIT)
.build());
create("apple")
register(ctx, "apple", new PotatoCannonProjectileType.Builder()
.damage(5)
.reloadTicks(10)
.velocity(1.45f)
.knockback(0.5f)
.renderTumbling()
.soundPitch(1.1f)
.registerAndAssign(ctx, Items.APPLE);
.addItems(Items.APPLE)
.build());
create("honeyed_apple")
register(ctx, "honeyed_apple", new PotatoCannonProjectileType.Builder()
.damage(6)
.reloadTicks(15)
.velocity(1.35f)
@ -131,9 +141,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(1.1f)
.onEntityHit(new PotionEffect(MobEffects.MOVEMENT_SLOWDOWN, 2, 160, true))
.registerAndAssign(ctx, AllItems.HONEYED_APPLE.get());
.addItems(AllItems.HONEYED_APPLE.get())
.build());
create("golden_apple")
register(ctx, "golden_apple", new PotatoCannonProjectileType.Builder()
.damage(1)
.reloadTicks(100)
.velocity(1.45f)
@ -141,9 +152,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(1.1f)
.onEntityHit(CureZombieVillager.INSTANCE)
.registerAndAssign(ctx, Items.GOLDEN_APPLE);
.addItems(Items.GOLDEN_APPLE)
.build());
create("enchanted_golden_apple")
register(ctx, "enchanted_golden_apple", new PotatoCannonProjectileType.Builder()
.damage(1)
.reloadTicks(100)
.velocity(1.45f)
@ -151,27 +163,30 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(1.1f)
.onEntityHit(new FoodEffects(Foods.ENCHANTED_GOLDEN_APPLE, false))
.registerAndAssign(ctx, Items.ENCHANTED_GOLDEN_APPLE);
.addItems(Items.ENCHANTED_GOLDEN_APPLE)
.build());
create("beetroot")
register(ctx, "beetroot", new PotatoCannonProjectileType.Builder()
.damage(2)
.reloadTicks(5)
.velocity(1.6f)
.knockback(0.1f)
.renderTowardMotion(140, 2)
.soundPitch(1.6f)
.registerAndAssign(ctx, Items.BEETROOT);
.addItems(Items.BEETROOT)
.build());
create("melon_slice")
register(ctx, "melon_slice", new PotatoCannonProjectileType.Builder()
.damage(3)
.reloadTicks(8)
.knockback(0.1f)
.velocity(1.45f)
.renderTumbling()
.soundPitch(1.5f)
.registerAndAssign(ctx, Items.MELON_SLICE);
.addItems(Items.MELON_SLICE)
.build());
create("glistering_melon")
register(ctx, "glistering_melon", new PotatoCannonProjectileType.Builder()
.damage(5)
.reloadTicks(8)
.knockback(0.1f)
@ -179,9 +194,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(1.5f)
.onEntityHit(new PotionEffect(MobEffects.GLOWING, 1, 100, true))
.registerAndAssign(ctx, Items.GLISTERING_MELON_SLICE);
.addItems(Items.GLISTERING_MELON_SLICE)
.build());
create("melon_block")
register(ctx, "melon_block", new PotatoCannonProjectileType.Builder()
.damage(8)
.reloadTicks(20)
.knockback(2.0f)
@ -189,9 +205,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(0.9f)
.onBlockHit(new PlaceBlockOnGround(Blocks.MELON))
.registerAndAssign(ctx, Blocks.MELON);
.addItems(Blocks.MELON)
.build());
create("pumpkin_block")
register(ctx, "pumpkin_block", new PotatoCannonProjectileType.Builder()
.damage(6)
.reloadTicks(15)
.knockback(2.0f)
@ -199,9 +216,10 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.soundPitch(0.9f)
.onBlockHit(new PlaceBlockOnGround(Blocks.PUMPKIN))
.registerAndAssign(ctx, Blocks.PUMPKIN);
.addItems(Blocks.PUMPKIN)
.build());
create("pumpkin_pie")
register(ctx, "pumpkin_pie", new PotatoCannonProjectileType.Builder()
.damage(7)
.reloadTicks(15)
.knockback(0.05f)
@ -209,18 +227,20 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.sticky()
.soundPitch(1.1f)
.registerAndAssign(ctx, Items.PUMPKIN_PIE);
.addItems(Items.PUMPKIN_PIE)
.build());
create("cake")
register(ctx, "cake", new PotatoCannonProjectileType.Builder()
.damage(8)
.reloadTicks(15)
.knockback(0.1f)
.velocity(1.1f)
.renderTumbling()
.sticky()
.registerAndAssign(ctx, Items.CAKE);
.addItems(Items.CAKE)
.build());
create("blaze_cake")
register(ctx, "blaze_cake", new PotatoCannonProjectileType.Builder()
.damage(15)
.reloadTicks(20)
.knockback(0.3f)
@ -228,18 +248,20 @@ public class AllPotatoProjectileTypes {
.renderTumbling()
.sticky()
.preEntityHit(SetOnFire.seconds(12))
.registerAndAssign(ctx, AllItems.BLAZE_CAKE.get());
.addItems(AllItems.BLAZE_CAKE.get())
.build());
create("fish")
register(ctx, "fish", new PotatoCannonProjectileType.Builder()
.damage(4)
.knockback(0.6f)
.velocity(1.3f)
.renderTowardMotion(140, 1)
.sticky()
.soundPitch(1.3f)
.registerAndAssign(ctx, Items.COD, Items.COOKED_COD, Items.SALMON, Items.COOKED_SALMON, Items.TROPICAL_FISH);
.addItems(Items.COD, Items.COOKED_COD, Items.SALMON, Items.COOKED_SALMON, Items.TROPICAL_FISH)
.build());
create("pufferfish")
register(ctx, "pufferfish", new PotatoCannonProjectileType.Builder()
.damage(4)
.knockback(0.4f)
.velocity(1.1f)
@ -247,9 +269,10 @@ public class AllPotatoProjectileTypes {
.sticky()
.onEntityHit(new FoodEffects(Foods.PUFFERFISH, false))
.soundPitch(1.1f)
.registerAndAssign(ctx, Items.PUFFERFISH);
.addItems(Items.PUFFERFISH)
.build());
create("suspicious_stew")
register(ctx, "suspicious_stew", new PotatoCannonProjectileType.Builder()
.damage(3)
.reloadTicks(40)
.knockback(0.2f)
@ -257,10 +280,11 @@ public class AllPotatoProjectileTypes {
.renderTowardMotion(140, 1)
.dropStack(Items.BOWL.getDefaultInstance())
.onEntityHit(SuspiciousStew.INSTANCE)
.registerAndAssign(ctx, Items.SUSPICIOUS_STEW);
.addItems(Items.SUSPICIOUS_STEW)
.build());
}
private static PotatoCannonProjectileType.Builder create(String name) {
return new PotatoCannonProjectileType.Builder(Create.asResource(name));
private static void register(BootstapContext<PotatoCannonProjectileType> ctx, String name, PotatoCannonProjectileType type) {
ctx.register(ResourceKey.create(CreateRegistries.POTATO_PROJECTILE_TYPE, Create.asResource(name)), type);
}
}

View file

@ -11,15 +11,14 @@ import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.CreateClient;
import com.simibubi.create.api.equipment.potatoCannon.PotatoCannonProjectileType;
import com.simibubi.create.api.registry.CreateRegistries;
import com.simibubi.create.content.equipment.armor.BacktankUtil;
import com.simibubi.create.content.equipment.zapper.ShootableGadgetItemMethods;
import com.simibubi.create.foundation.item.CustomArmPoseItem;
import com.simibubi.create.foundation.item.render.SimpleCustomRenderer;
import com.simibubi.create.foundation.utility.CreateLang;
import com.simibubi.create.foundation.utility.GlobalRegistryAccess;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.math.VecHelper;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
@ -28,6 +27,7 @@ import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Holder;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
@ -51,35 +51,28 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
import net.minecraftforge.server.ServerLifecycleHooks;
public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmPoseItem {
public static ItemStack CLIENT_CURRENT_AMMO = ItemStack.EMPTY;
public static final int MAX_DAMAGE = 100;
public PotatoCannonItem(Properties properties) {
super(properties.defaultDurability(MAX_DAMAGE));
}
@Override
public boolean canAttackBlock(BlockState state, Level world, BlockPos pos, Player player) {
return false;
@Nullable
public static Ammo getAmmo(Player player, ItemStack heldStack) {
ItemStack ammoStack = player.getProjectile(heldStack);
if (ammoStack.isEmpty()) {
return null;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment == Enchantments.POWER_ARROWS)
return true;
if (enchantment == Enchantments.PUNCH_ARROWS)
return true;
if (enchantment == Enchantments.FLAMING_ARROWS)
return true;
if (enchantment == Enchantments.MOB_LOOTING)
return true;
if (enchantment == AllEnchantments.POTATO_RECOVERY.get())
return true;
return super.canApplyAtEnchantingTable(stack, enchantment);
Optional<Holder.Reference<PotatoCannonProjectileType>> optionalType = PotatoCannonProjectileType.getTypeForItem(player.level().registryAccess(), ammoStack.getItem());
if (optionalType.isEmpty()) {
return null;
}
return new Ammo(ammoStack, optionalType.get().get());
}
@Override
@ -87,39 +80,23 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
return use(context.getLevel(), context.getPlayer(), context.getHand()).getResult();
}
@Override
public boolean isBarVisible(ItemStack stack) {
return BacktankUtil.isBarVisible(stack, maxUses());
}
@Override
public int getBarWidth(ItemStack stack) {
return BacktankUtil.getBarWidth(stack, maxUses());
}
@Override
public int getBarColor(ItemStack stack) {
return BacktankUtil.getBarColor(stack, maxUses());
}
private int maxUses() {
return AllConfigs.server().equipment.maxPotatoCannonShots.get();
}
public boolean isCannon(ItemStack stack) {
return stack.getItem() instanceof PotatoCannonItem;
}
@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
return findAmmoInInventory(level, player, stack).map(itemStack -> {
if (ShootableGadgetItemMethods.shouldSwap(player, stack, hand, this::isCannon))
return InteractionResultHolder.fail(stack);
ItemStack heldStack = player.getItemInHand(hand);
if (ShootableGadgetItemMethods.shouldSwap(player, heldStack, hand, s -> s.getItem() instanceof PotatoCannonItem)) {
return InteractionResultHolder.fail(heldStack);
}
Ammo ammo = getAmmo(player, heldStack);
if (ammo == null) {
return InteractionResultHolder.pass(heldStack);
}
ItemStack ammoStack = ammo.stack();
PotatoCannonProjectileType projectileType = ammo.type();
if (level.isClientSide) {
CreateClient.POTATO_CANNON_RENDER_HANDLER.dontAnimateItem(hand);
return InteractionResultHolder.success(stack);
return InteractionResultHolder.success(heldStack);
}
Vec3 barrelPos = ShootableGadgetItemMethods.getGunBarrelVec(player, hand == InteractionHand.MAIN_HAND,
@ -129,13 +106,6 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
.subtract(player.position()
.add(0, player.getEyeHeight(), 0));
PotatoCannonProjectileType projectileType = PotatoCannonProjectileType.getTypeForStack(level, itemStack)
.orElseGet(() ->
level.registryAccess()
.lookupOrThrow(CreateRegistries.POTATO_PROJECTILE_TYPE)
.getOrThrow(AllPotatoProjectileTypes.FALLBACK)
.value()
);
Vec3 lookVec = player.getLookAngle();
Vec3 motion = lookVec.add(correction)
.normalize()
@ -148,10 +118,12 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
Vec3 sprayBase = VecHelper.rotate(new Vec3(0, 0.1, 0), 360 * level.getRandom().nextFloat(), Axis.Z);
float sprayChange = 360f / projectileType.split();
ItemStack ammoStackCopy = ammoStack.copy();
for (int i = 0; i < projectileType.split(); i++) {
PotatoProjectileEntity projectile = AllEntityTypes.POTATO_PROJECTILE.create(level);
projectile.setItem(itemStack);
projectile.setEnchantmentEffectsFromCannon(stack);
projectile.setItem(ammoStackCopy);
projectile.setEnchantmentEffectsFromCannon(heldStack);
Vec3 splitMotion = motion;
if (spray) {
@ -170,73 +142,49 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
}
if (!player.isCreative()) {
itemStack.shrink(1);
if (itemStack.isEmpty())
player.getInventory().removeItem(itemStack);
ammoStack.shrink(1);
if (ammoStack.isEmpty())
player.getInventory().removeItem(ammoStack);
}
if (!BacktankUtil.canAbsorbDamage(player, maxUses()))
stack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(hand));
heldStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(hand));
Integer cooldown =
findAmmoInInventory(level, player, stack).flatMap(i -> PotatoCannonProjectileType.getTypeForStack(level, i))
.map(potatoCannonProjectileType -> potatoCannonProjectileType.reloadTicks())
.orElse(10);
ShootableGadgetItemMethods.applyCooldown(player, stack, hand, this::isCannon, cooldown);
ShootableGadgetItemMethods.applyCooldown(player, heldStack, hand, s -> s.getItem() instanceof PotatoCannonItem, projectileType.reloadTicks());
ShootableGadgetItemMethods.sendPackets(player,
b -> new PotatoCannonPacket(barrelPos, lookVec.normalize(), itemStack, hand, soundPitch, b));
return InteractionResultHolder.success(stack);
})
.orElse(InteractionResultHolder.pass(stack));
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return slotChanged || newStack.getItem() != oldStack.getItem();
}
private Optional<ItemStack> findAmmoInInventory(Level level, Player player, ItemStack held) {
ItemStack findAmmo = player.getProjectile(held);
return PotatoCannonProjectileType.getTypeForStack(level, findAmmo)
.map($ -> findAmmo);
}
@OnlyIn(Dist.CLIENT)
public static Optional<ItemStack> getAmmoforPreview(ItemStack cannon) {
if (AnimationTickHolder.getTicks() % 3 != 0)
return Optional.of(CLIENT_CURRENT_AMMO)
.filter(stack -> !stack.isEmpty());
LocalPlayer player = Minecraft.getInstance().player;
CLIENT_CURRENT_AMMO = ItemStack.EMPTY;
if (player == null)
return Optional.empty();
ItemStack findAmmo = player.getProjectile(cannon);
Optional<ItemStack> found = PotatoCannonProjectileType.getTypeForStack(Minecraft.getInstance().level, findAmmo)
.map($ -> findAmmo);
found.ifPresent(stack -> CLIENT_CURRENT_AMMO = stack);
return found;
b -> new PotatoCannonPacket(barrelPos, lookVec.normalize(), ammoStack, hand, soundPitch, b));
return InteractionResultHolder.success(heldStack);
}
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null) {
super.appendHoverText(stack, level, tooltip, flag);
return;
}
Ammo ammo = getAmmo(player, stack);
if (ammo == null) {
super.appendHoverText(stack, level, tooltip, flag);
return;
}
ItemStack ammoStack = ammo.stack();
PotatoCannonProjectileType type = ammo.type();
int power = stack.getEnchantmentLevel(Enchantments.POWER_ARROWS);
int punch = stack.getEnchantmentLevel(Enchantments.PUNCH_ARROWS);
final float additionalDamageMult = 1 + power * .2f;
final float additionalKnockback = punch * .5f;
getAmmoforPreview(stack).ifPresent(ammo -> {
String _attack = "potato_cannon.ammo.attack_damage";
String _reload = "potato_cannon.ammo.reload_ticks";
String _knockback = "potato_cannon.ammo.knockback";
tooltip.add(CommonComponents.EMPTY);
tooltip.add(Component.translatable(ammo.getDescriptionId()).append(Component.literal(":"))
tooltip.add(Component.translatable(ammoStack.getDescriptionId()).append(Component.literal(":"))
.withStyle(ChatFormatting.GRAY));
PotatoCannonProjectileType type = PotatoCannonProjectileType.getTypeForStack(Minecraft.getInstance().level, ammo)
.get();
MutableComponent spacing = CommonComponents.space();
ChatFormatting green = ChatFormatting.GREEN;
ChatFormatting darkGreen = ChatFormatting.DARK_GREEN;
@ -260,17 +208,65 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
tooltip.add(spacing.plainCopy()
.append(CreateLang.translateDirect(_knockback, knockback)
.withStyle(darkGreen)));
});
super.appendHoverText(stack, level, tooltip, flag);
}
@Override
public boolean canAttackBlock(BlockState state, Level world, BlockPos pos, Player player) {
return false;
}
@Override
public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) {
return slotChanged || newStack.getItem() != oldStack.getItem();
}
@Override
public Predicate<ItemStack> getAllSupportedProjectiles() {
Level level = ServerLifecycleHooks.getCurrentServer().getLevel(Level.OVERWORLD);
return stack -> PotatoCannonProjectileType.getTypeForStack(level, stack)
return stack -> PotatoCannonProjectileType.getTypeForItem(GlobalRegistryAccess.getOrThrow(), stack.getItem())
.isPresent();
}
@Override
public int getDefaultProjectileRange() {
return 15;
}
@Override
public boolean canApplyAtEnchantingTable(ItemStack stack, Enchantment enchantment) {
if (enchantment == Enchantments.POWER_ARROWS)
return true;
if (enchantment == Enchantments.PUNCH_ARROWS)
return true;
if (enchantment == Enchantments.FLAMING_ARROWS)
return true;
if (enchantment == Enchantments.MOB_LOOTING)
return true;
if (enchantment == AllEnchantments.POTATO_RECOVERY.get())
return true;
return super.canApplyAtEnchantingTable(stack, enchantment);
}
@Override
public boolean isBarVisible(ItemStack stack) {
return BacktankUtil.isBarVisible(stack, maxUses());
}
@Override
public int getBarWidth(ItemStack stack) {
return BacktankUtil.getBarWidth(stack, maxUses());
}
@Override
public int getBarColor(ItemStack stack) {
return BacktankUtil.getBarColor(stack, maxUses());
}
private static int maxUses() {
return AllConfigs.server().equipment.maxPotatoCannonShots.get();
}
@Override
public boolean onEntitySwing(ItemStack stack, LivingEntity entity) {
return true;
@ -290,15 +286,12 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
return null;
}
@Override
public int getDefaultProjectileRange() {
return 15;
}
@Override
@OnlyIn(Dist.CLIENT)
public void initializeClient(Consumer<IClientItemExtensions> consumer) {
consumer.accept(SimpleCustomRenderer.create(this, new PotatoCannonItemRenderer()));
}
public record Ammo(ItemStack stack, PotatoCannonProjectileType type) {
}
}

View file

@ -5,47 +5,69 @@ import com.mojang.math.Axis;
import com.simibubi.create.AllItems;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonItem.Ammo;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModel;
import com.simibubi.create.foundation.item.render.CustomRenderedItemModelRenderer;
import com.simibubi.create.foundation.item.render.PartialItemModelRenderer;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.client.IItemDecorator;
public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer {
public static final IItemDecorator DECORATOR = (guiGraphics, font, stack, xOffset, yOffset) -> {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null) {
return false;
}
Ammo ammo = PotatoCannonItem.getAmmo(player, stack);
if (ammo == null || AllItems.POTATO_CANNON.is(ammo.stack())) {
return false;
}
PoseStack poseStack = guiGraphics.pose();
poseStack.pushPose();
poseStack.translate(xOffset, yOffset + 8, 100);
poseStack.scale(.5f, .5f, .5f);
guiGraphics.renderItem(ammo.stack(), 0, 0);
poseStack.popPose();
return false;
};
protected static final PartialModel COG = PartialModel.of(Create.asResource("item/potato_cannon/cog"));
@Override
protected void render(ItemStack stack, CustomRenderedItemModel model, PartialItemModelRenderer renderer,
ItemDisplayContext transformType, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
Minecraft mc = Minecraft.getInstance();
ItemRenderer itemRenderer = mc.getItemRenderer();
renderer.render(model.getOriginalModel(), light);
Minecraft mc = Minecraft.getInstance();
LocalPlayer player = mc.player;
boolean mainHand = player.getMainHandItem() == stack;
boolean offHand = player.getOffhandItem() == stack;
float angle = AnimationTickHolder.getRenderTime() * -2.5f;
if (player != null) {
boolean inMainHand = player.getMainHandItem() == stack;
boolean inOffHand = player.getOffhandItem() == stack;
if (inMainHand || inOffHand) {
boolean leftHanded = player.getMainArm() == HumanoidArm.LEFT;
float offset = .5f / 16;
float worldTime = AnimationTickHolder.getRenderTime() / 10;
float angle = worldTime * -25;
float speed = CreateClient.POTATO_CANNON_RENDER_HANDLER.getAnimation(mainHand ^ leftHanded,
float speed = CreateClient.POTATO_CANNON_RENDER_HANDLER.getAnimation(inMainHand ^ leftHanded,
AnimationTickHolder.getPartialTicks());
if (mainHand || offHand)
angle += 360 * Mth.clamp(speed * 5, 0, 1);
}
}
angle %= 360;
float offset = .5f / 16;
ms.pushPose();
ms.translate(0, offset, 0);
@ -53,20 +75,5 @@ public class PotatoCannonItemRenderer extends CustomRenderedItemModelRenderer {
ms.translate(0, -offset, 0);
renderer.render(COG.get(), light);
ms.popPose();
if (transformType == ItemDisplayContext.GUI) {
PotatoCannonItem.getAmmoforPreview(stack).ifPresent(ammo -> {
if (AllItems.POTATO_CANNON.is(ammo)) return;
PoseStack localMs = new PoseStack();
localMs.translate(-1 / 4f, -1 / 4f, 1);
localMs.scale(.5f, .5f, .5f);
TransformStack.of(localMs)
.rotateYDegrees(-34);
itemRenderer.renderStatic(ammo, ItemDisplayContext.GUI, light, OverlayTexture.NO_OVERLAY, localMs,
buffer, mc.level, 0);
});
}
}
}

View file

@ -1,7 +1,6 @@
package com.simibubi.create.content.equipment.potatoCannon;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.equipment.zapper.ShootableGadgetRenderHandler;
import com.simibubi.create.foundation.particle.AirParticleData;
@ -26,8 +25,7 @@ public class PotatoCannonRenderHandler extends ShootableGadgetRenderHandler {
@Override
protected boolean appliesTo(ItemStack stack) {
return AllItems.POTATO_CANNON.get()
.isCannon(stack);
return stack.getItem() instanceof PotatoCannonItem;
}
public void beforeShoot(float nextPitch, Vec3 location, Vec3 motion, ItemStack stack) {

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.equipment.potatoCannon;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllSoundEvents;
@ -58,28 +59,17 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
protected float additionalKnockback = 0;
protected float recoveryChance = 0;
public PotatoProjectileEntity(EntityType<? extends AbstractHurtingProjectile> type, Level world) {
super(type, world);
}
public ItemStack getItem() {
return stack;
public PotatoProjectileEntity(EntityType<? extends AbstractHurtingProjectile> type, Level level) {
super(type, level);
}
public void setItem(ItemStack stack) {
this.stack = stack;
}
public PotatoCannonProjectileType getProjectileType() {
if (type == null)
type = PotatoCannonProjectileType.getTypeForStack(level(), stack)
.orElseGet(() ->
level().registryAccess()
.lookupOrThrow(CreateRegistries.POTATO_PROJECTILE_TYPE)
.getOrThrow(AllPotatoProjectileTypes.FALLBACK)
.value()
);
return type;
type = PotatoCannonProjectileType.getTypeForItem(level().registryAccess(), stack.getItem())
.orElseGet(() -> level().registryAccess()
.registryOrThrow(CreateRegistries.POTATO_PROJECTILE_TYPE)
.getHolderOrThrow(AllPotatoProjectileTypes.FALLBACK))
.value();
}
public void setEnchantmentEffectsFromCannon(ItemStack cannon) {
@ -98,9 +88,18 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
recoveryChance = .125f + recovery * .125f;
}
public ItemStack getItem() {
return stack;
}
@Nullable
public PotatoCannonProjectileType getProjectileType() {
return type;
}
@Override
public void readAdditionalSaveData(CompoundTag nbt) {
stack = ItemStack.of(nbt.getCompound("Item"));
setItem(ItemStack.of(nbt.getCompound("Item")));
additionalDamageMult = nbt.getFloat("AdditionalDamage");
additionalKnockback = nbt.getFloat("AdditionalKnockback");
recoveryChance = nbt.getFloat("Recovery");
@ -116,6 +115,7 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
super.addAdditionalSaveData(nbt);
}
@Nullable
public Entity getStuckEntity() {
if (stuckEntity == null)
return null;
@ -136,27 +136,26 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
if (getStuckEntity() != null)
return stuckRenderer;
return getProjectileType().renderMode();
return type.renderMode();
}
@Override
public void tick() {
PotatoCannonProjectileType projectileType = getProjectileType();
Entity stuckEntity = getStuckEntity();
if (stuckEntity != null) {
if (getY() < stuckEntity.getY() - 0.1) {
pop(position());
kill();
} else {
stuckFallSpeed += 0.007 * projectileType.gravityMultiplier();
stuckFallSpeed += 0.007 * type.gravityMultiplier();
stuckOffset = stuckOffset.add(0, -stuckFallSpeed, 0);
Vec3 pos = stuckEntity.position()
.add(stuckOffset);
setPos(pos.x, pos.y, pos.z);
}
} else {
setDeltaMovement(getDeltaMovement().add(0, -0.05 * projectileType.gravityMultiplier(), 0)
.scale(projectileType.drag()));
setDeltaMovement(getDeltaMovement().add(0, -0.05 * type.gravityMultiplier(), 0)
.scale(type.drag()));
}
super.tick();
@ -186,9 +185,8 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
Vec3 hit = ray.getLocation();
Entity target = ray.getEntity();
PotatoCannonProjectileType projectileType = getProjectileType();
float damage = projectileType.damage() * additionalDamageMult;
float knockback = projectileType.knockback() + additionalKnockback;
float damage = type.damage() * additionalDamageMult;
float knockback = type.knockback() + additionalKnockback;
Entity owner = this.getOwner();
if (!target.isAlive())
@ -211,7 +209,7 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
if (target instanceof WitherBoss && ((WitherBoss) target).isPowered())
return;
if (projectileType.preEntityHit(stack, ray))
if (type.preEntityHit(stack, ray))
return;
boolean targetIsEnderman = target.getType() == EntityType.ENDERMAN;
@ -229,11 +227,11 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
if (targetIsEnderman)
return;
if (!projectileType.onEntityHit(stack, ray) && onServer) {
if (!type.onEntityHit(stack, ray) && onServer) {
if (random.nextDouble() <= recoveryChance) {
recoverItem();
} else {
spawnAtLocation(projectileType.dropStack());
spawnAtLocation(type.dropStack());
}
}
@ -297,7 +295,7 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
protected void onHitBlock(BlockHitResult ray) {
Vec3 hit = ray.getLocation();
pop(hit);
if (!getProjectileType().onBlockHit(level(), stack, ray) && !level().isClientSide) {
if (!type.onBlockHit(level(), stack, ray) && !level().isClientSide) {
if (random.nextDouble() <= recoveryChance) {
recoverItem();
} else {

View file

@ -6,9 +6,8 @@ import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
public class PotatoRecoveryEnchantment extends Enchantment {
public PotatoRecoveryEnchantment(Rarity p_i46731_1_, EnchantmentCategory p_i46731_2_, EquipmentSlot[] p_i46731_3_) {
super(p_i46731_1_, p_i46731_2_, p_i46731_3_);
public PotatoRecoveryEnchantment(Rarity rarity, EnchantmentCategory category, EquipmentSlot[] slots) {
super(rarity, category, slots);
}
@Override
@ -20,5 +19,4 @@ public class PotatoRecoveryEnchantment extends Enchantment {
public boolean canApplyAtEnchantingTable(ItemStack stack) {
return stack.getItem() instanceof PotatoCannonItem;
}
}

View file

@ -26,7 +26,6 @@ import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.recipe.RecipeConditions;
import com.simibubi.create.foundation.recipe.RecipeFinder;
import com.simibubi.create.foundation.utility.AbstractBlockBreakQueue;
import com.simibubi.create.foundation.utility.TreeCutter;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.math.VecHelper;

View file

@ -10,7 +10,6 @@ import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.foundation.damageTypes.CreateDamageSources;
import com.simibubi.create.foundation.utility.AbstractBlockBreakQueue;
import com.simibubi.create.foundation.utility.TreeCutter;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
@ -25,6 +24,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.ItemHandlerHelper;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.content.kinetics.saw;
import java.util.ArrayList;
import java.util.Collections;
@ -18,6 +18,7 @@ import com.simibubi.create.AllTags;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.compat.Mods;
import com.simibubi.create.compat.dynamictrees.DynamicTree;
import com.simibubi.create.foundation.utility.AbstractBlockBreakQueue;
import net.createmod.catnip.data.Iterate;
import net.minecraft.core.BlockPos;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation;
import java.util.List;
@ -12,6 +12,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.registries.ForgeRegistries;
public class CreateNBTProcessors {

View file

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.events;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllPackets;
import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
@ -27,6 +28,7 @@ import com.simibubi.create.content.equipment.clipboard.ClipboardValueSettingsHan
import com.simibubi.create.content.equipment.extendoGrip.ExtendoGripRenderHandler;
import com.simibubi.create.content.equipment.goggles.GoggleOverlayRenderer;
import com.simibubi.create.content.equipment.hats.CreateHatArmorLayer;
import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonItemRenderer;
import com.simibubi.create.content.equipment.toolbox.ToolboxHandlerClient;
import com.simibubi.create.content.equipment.zapper.ZapperItem;
import com.simibubi.create.content.equipment.zapper.terrainzapper.WorldshaperRenderHandler;
@ -71,11 +73,11 @@ import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.TickBasedCache;
import com.simibubi.create.infrastructure.config.AllConfigs;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.config.ui.BaseConfigScreen;
import net.createmod.catnip.levelWrappers.WrappedClientLevel;
import net.createmod.catnip.render.DefaultSuperRenderTypeBuffer;
import net.createmod.catnip.render.SuperRenderTypeBuffer;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.levelWrappers.WrappedClientLevel;
import net.createmod.ponder.foundation.PonderTooltipHandler;
import net.minecraft.client.Camera;
import net.minecraft.client.Minecraft;
@ -90,12 +92,14 @@ import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.material.Fluid;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
import net.minecraftforge.client.event.RegisterGuiOverlaysEvent;
import net.minecraftforge.client.event.RegisterItemDecorationsEvent;
import net.minecraftforge.client.event.RenderLevelStageEvent;
import net.minecraftforge.client.event.RenderLevelStageEvent.Stage;
import net.minecraftforge.client.event.ViewportEvent;
@ -370,6 +374,11 @@ public class ClientEvents {
event.registerAbove(VanillaGuiOverlay.HOTBAR.id(), "toolbox", ToolboxHandlerClient.OVERLAY);
}
@SubscribeEvent
public static void registerItemDecorations(RegisterItemDecorationsEvent event) {
event.register(AllItems.POTATO_CANNON, PotatoCannonItemRenderer.DECORATOR);
}
@SubscribeEvent
public static void onLoadComplete(FMLLoadCompleteEvent event) {
ModContainer createContainer = ModList.get()

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.foundation.model;
import java.util.ArrayList;
import java.util.List;
@ -17,6 +17,7 @@ import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.client.event.ModelEvent;
import net.minecraftforge.eventbus.api.IEventBus;

View file

@ -1,26 +0,0 @@
package com.simibubi.create.foundation.utility;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.client.renderer.BiomeColors;
import net.minecraft.world.level.GrassColor;
import net.minecraft.world.level.block.RedStoneWireBlock;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class ColorHandlers {
public static BlockColor getGrassyBlock() {
return (state, world, pos, layer) -> pos != null && world != null ? BiomeColors.getAverageGrassColor(world, pos)
: GrassColor.get(0.5D, 1.0D);
}
public static ItemColor getGrassyItem() {
return (stack, layer) -> GrassColor.get(0.5D, 1.0D);
}
public static BlockColor getRedstonePower() {
return (state, world, pos, layer) -> RedStoneWireBlock
.getColorForPower(pos != null && world != null ? state.getValue(BlockStateProperties.POWER) : 0);
}
}

View file

@ -0,0 +1,51 @@
package com.simibubi.create.foundation.utility;
import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.core.RegistryAccess;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.server.ServerLifecycleHooks;
public final class GlobalRegistryAccess {
private static Supplier<@Nullable RegistryAccess> supplier;
static {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> supplier = () -> {
ClientPacketListener packetListener = Minecraft.getInstance().getConnection();
if (packetListener == null) {
return null;
}
return packetListener.registryAccess();
});
if (supplier == null) {
supplier = () -> {
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
if (server == null) {
return null;
}
return server.registryAccess();
};
}
}
@Nullable
public static RegistryAccess get() {
return supplier.get();
}
public static RegistryAccess getOrThrow() {
RegistryAccess registryAccess = get();
if (registryAccess == null) {
throw new IllegalStateException("Could not get RegistryAccess");
}
return registryAccess;
}
}

View file

@ -1,8 +0,0 @@
package com.simibubi.create.foundation.utility;
import net.minecraft.core.BlockPos;
@FunctionalInterface
public interface ICoordinate {
float get(BlockPos from);
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.utility;
package com.simibubi.create.infrastructure;
import static com.simibubi.create.AllBlocks.ADJUSTABLE_CHAIN_GEARSHIFT;
import static com.simibubi.create.AllBlocks.ANDESITE_ENCASED_SHAFT;
@ -65,6 +65,7 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.material.Fluid;
import net.minecraftforge.common.ForgeMod;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;