mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-03-04 06:44:40 +01:00
More work on potato cannon projectile types
This commit is contained in:
parent
8dd17cf7c2
commit
ac20501426
22 changed files with 439 additions and 415 deletions
|
@ -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())))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,22 +51,188 @@ 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));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Ammo getAmmo(Player player, ItemStack heldStack) {
|
||||
ItemStack ammoStack = player.getProjectile(heldStack);
|
||||
if (ammoStack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
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
|
||||
public InteractionResult useOn(UseOnContext context) {
|
||||
return use(context.getLevel(), context.getPlayer(), context.getHand()).getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
|
||||
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(heldStack);
|
||||
}
|
||||
|
||||
Vec3 barrelPos = ShootableGadgetItemMethods.getGunBarrelVec(player, hand == InteractionHand.MAIN_HAND,
|
||||
new Vec3(.75f, -0.15f, 1.5f));
|
||||
Vec3 correction =
|
||||
ShootableGadgetItemMethods.getGunBarrelVec(player, hand == InteractionHand.MAIN_HAND, new Vec3(-.05f, 0, 0))
|
||||
.subtract(player.position()
|
||||
.add(0, player.getEyeHeight(), 0));
|
||||
|
||||
Vec3 lookVec = player.getLookAngle();
|
||||
Vec3 motion = lookVec.add(correction)
|
||||
.normalize()
|
||||
.scale(2)
|
||||
.scale(projectileType.velocityMultiplier());
|
||||
|
||||
float soundPitch = projectileType.soundPitch() + (level.getRandom().nextFloat() - .5f) / 4f;
|
||||
|
||||
boolean spray = projectileType.split() > 1;
|
||||
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(ammoStackCopy);
|
||||
projectile.setEnchantmentEffectsFromCannon(heldStack);
|
||||
|
||||
Vec3 splitMotion = motion;
|
||||
if (spray) {
|
||||
float imperfection = 40 * (level.getRandom().nextFloat() - 0.5f);
|
||||
Vec3 sprayOffset = VecHelper.rotate(sprayBase, i * sprayChange + imperfection, Axis.Z);
|
||||
splitMotion = splitMotion.add(VecHelper.lookAt(sprayOffset, motion));
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
projectile.recoveryChance = 0;
|
||||
|
||||
projectile.setPos(barrelPos.x, barrelPos.y, barrelPos.z);
|
||||
projectile.setDeltaMovement(splitMotion);
|
||||
projectile.setOwner(player);
|
||||
level.addFreshEntity(projectile);
|
||||
}
|
||||
|
||||
if (!player.isCreative()) {
|
||||
ammoStack.shrink(1);
|
||||
if (ammoStack.isEmpty())
|
||||
player.getInventory().removeItem(ammoStack);
|
||||
}
|
||||
|
||||
if (!BacktankUtil.canAbsorbDamage(player, maxUses()))
|
||||
heldStack.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(hand));
|
||||
|
||||
ShootableGadgetItemMethods.applyCooldown(player, heldStack, hand, s -> s.getItem() instanceof PotatoCannonItem, projectileType.reloadTicks());
|
||||
ShootableGadgetItemMethods.sendPackets(player,
|
||||
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;
|
||||
|
||||
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(ammoStack.getDescriptionId()).append(Component.literal(":"))
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
MutableComponent spacing = CommonComponents.space();
|
||||
ChatFormatting green = ChatFormatting.GREEN;
|
||||
ChatFormatting darkGreen = ChatFormatting.DARK_GREEN;
|
||||
|
||||
float damageF = type.damage() * additionalDamageMult;
|
||||
MutableComponent damage = Component.literal(damageF == Mth.floor(damageF) ? "" + Mth.floor(damageF) : "" + damageF);
|
||||
MutableComponent reloadTicks = Component.literal("" + type.reloadTicks());
|
||||
MutableComponent knockback =
|
||||
Component.literal("" + (type.knockback() + additionalKnockback));
|
||||
|
||||
damage = damage.withStyle(additionalDamageMult > 1 ? green : darkGreen);
|
||||
knockback = knockback.withStyle(additionalKnockback > 0 ? green : darkGreen);
|
||||
reloadTicks = reloadTicks.withStyle(darkGreen);
|
||||
|
||||
tooltip.add(spacing.plainCopy()
|
||||
.append(CreateLang.translateDirect(_attack, damage)
|
||||
.withStyle(darkGreen)));
|
||||
tooltip.add(spacing.plainCopy()
|
||||
.append(CreateLang.translateDirect(_reload, reloadTicks)
|
||||
.withStyle(darkGreen)));
|
||||
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() {
|
||||
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)
|
||||
|
@ -82,11 +248,6 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
|
|||
return super.canApplyAtEnchantingTable(stack, enchantment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult useOn(UseOnContext context) {
|
||||
return use(context.getLevel(), context.getPlayer(), context.getHand()).getResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBarVisible(ItemStack stack) {
|
||||
return BacktankUtil.isBarVisible(stack, maxUses());
|
||||
|
@ -102,175 +263,10 @@ public class PotatoCannonItem extends ProjectileWeaponItem implements CustomArmP
|
|||
return BacktankUtil.getBarColor(stack, maxUses());
|
||||
}
|
||||
|
||||
private int maxUses() {
|
||||
private static 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);
|
||||
|
||||
if (level.isClientSide) {
|
||||
CreateClient.POTATO_CANNON_RENDER_HANDLER.dontAnimateItem(hand);
|
||||
return InteractionResultHolder.success(stack);
|
||||
}
|
||||
|
||||
Vec3 barrelPos = ShootableGadgetItemMethods.getGunBarrelVec(player, hand == InteractionHand.MAIN_HAND,
|
||||
new Vec3(.75f, -0.15f, 1.5f));
|
||||
Vec3 correction =
|
||||
ShootableGadgetItemMethods.getGunBarrelVec(player, hand == InteractionHand.MAIN_HAND, new Vec3(-.05f, 0, 0))
|
||||
.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()
|
||||
.scale(2)
|
||||
.scale(projectileType.velocityMultiplier());
|
||||
|
||||
float soundPitch = projectileType.soundPitch() + (level.getRandom().nextFloat() - .5f) / 4f;
|
||||
|
||||
boolean spray = projectileType.split() > 1;
|
||||
Vec3 sprayBase = VecHelper.rotate(new Vec3(0, 0.1, 0), 360 * level.getRandom().nextFloat(), Axis.Z);
|
||||
float sprayChange = 360f / projectileType.split();
|
||||
|
||||
for (int i = 0; i < projectileType.split(); i++) {
|
||||
PotatoProjectileEntity projectile = AllEntityTypes.POTATO_PROJECTILE.create(level);
|
||||
projectile.setItem(itemStack);
|
||||
projectile.setEnchantmentEffectsFromCannon(stack);
|
||||
|
||||
Vec3 splitMotion = motion;
|
||||
if (spray) {
|
||||
float imperfection = 40 * (level.getRandom().nextFloat() - 0.5f);
|
||||
Vec3 sprayOffset = VecHelper.rotate(sprayBase, i * sprayChange + imperfection, Axis.Z);
|
||||
splitMotion = splitMotion.add(VecHelper.lookAt(sprayOffset, motion));
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
projectile.recoveryChance = 0;
|
||||
|
||||
projectile.setPos(barrelPos.x, barrelPos.y, barrelPos.z);
|
||||
projectile.setDeltaMovement(splitMotion);
|
||||
projectile.setOwner(player);
|
||||
level.addFreshEntity(projectile);
|
||||
}
|
||||
|
||||
if (!player.isCreative()) {
|
||||
itemStack.shrink(1);
|
||||
if (itemStack.isEmpty())
|
||||
player.getInventory().removeItem(itemStack);
|
||||
}
|
||||
|
||||
if (!BacktankUtil.canAbsorbDamage(player, maxUses()))
|
||||
stack.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.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;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void appendHoverText(ItemStack stack, @Nullable Level level, List<Component> tooltip, TooltipFlag flag) {
|
||||
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(":"))
|
||||
.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;
|
||||
|
||||
float damageF = type.damage() * additionalDamageMult;
|
||||
MutableComponent damage = Component.literal(damageF == Mth.floor(damageF) ? "" + Mth.floor(damageF) : "" + damageF);
|
||||
MutableComponent reloadTicks = Component.literal("" + type.reloadTicks());
|
||||
MutableComponent knockback =
|
||||
Component.literal("" + (type.knockback() + additionalKnockback));
|
||||
|
||||
damage = damage.withStyle(additionalDamageMult > 1 ? green : darkGreen);
|
||||
knockback = knockback.withStyle(additionalKnockback > 0 ? green : darkGreen);
|
||||
reloadTicks = reloadTicks.withStyle(darkGreen);
|
||||
|
||||
tooltip.add(spacing.plainCopy()
|
||||
.append(CreateLang.translateDirect(_attack, damage)
|
||||
.withStyle(darkGreen)));
|
||||
tooltip.add(spacing.plainCopy()
|
||||
.append(CreateLang.translateDirect(_reload, reloadTicks)
|
||||
.withStyle(darkGreen)));
|
||||
tooltip.add(spacing.plainCopy()
|
||||
.append(CreateLang.translateDirect(_knockback, knockback)
|
||||
.withStyle(darkGreen)));
|
||||
});
|
||||
super.appendHoverText(stack, level, tooltip, flag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<ItemStack> getAllSupportedProjectiles() {
|
||||
Level level = ServerLifecycleHooks.getCurrentServer().getLevel(Level.OVERWORLD);
|
||||
return stack -> PotatoCannonProjectileType.getTypeForStack(level, stack)
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
@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) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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,
|
||||
AnimationTickHolder.getPartialTicks());
|
||||
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 speed = CreateClient.POTATO_CANNON_RENDER_HANDLER.getAnimation(inMainHand ^ leftHanded,
|
||||
AnimationTickHolder.getPartialTicks());
|
||||
angle += 360 * Mth.clamp(speed * 5, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -6,19 +6,17 @@ 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
|
||||
public int getMaxLevel() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canApplyAtEnchantingTable(ItemStack stack) {
|
||||
return stack.getItem() instanceof PotatoCannonItem;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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 {
|
||||
|
@ -29,7 +30,7 @@ public class CreateNBTProcessors {
|
|||
if (!data.contains("Book", Tag.TAG_COMPOUND))
|
||||
return data;
|
||||
CompoundTag book = data.getCompound("Book");
|
||||
|
||||
|
||||
// Writable books can't have click events, so they're safe to keep
|
||||
ResourceLocation writableBookResource = ForgeRegistries.ITEMS.getKey(Items.WRITABLE_BOOK);
|
||||
if (writableBookResource != null && book.getString("id").equals(writableBookResource.toString()))
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ICoordinate {
|
||||
float get(BlockPos from);
|
||||
}
|
|
@ -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;
|
Loading…
Add table
Reference in a new issue