Skip to content

Commit

Permalink
fix prop placement
Browse files Browse the repository at this point in the history
  • Loading branch information
TropheusJ committed Jan 13, 2025
1 parent 835a5e9 commit cb70ad1
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package io.github.fusionflux.portalcubed.content.prop;

import io.github.fusionflux.portalcubed.content.prop.entity.Prop;
import net.minecraft.core.BlockPos;

import net.minecraft.world.entity.EntitySpawnReason;

import net.minecraft.world.level.gameevent.GameEvent;

import org.jetbrains.annotations.NotNull;

import net.minecraft.core.Direction;
import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.DispenserBlock;

Expand All @@ -18,13 +24,22 @@ public PropDispenseBehavior(PropItem item) {

@Override
@NotNull
protected ItemStack execute(BlockSource pointer, ItemStack stack) {
protected ItemStack execute(BlockSource source, ItemStack stack) {
if (!stack.is(this.item))
return stack;

ServerLevel level = pointer.level();
Direction direction = pointer.state().getValue(DispenserBlock.FACING);
this.item.use(level, pointer.pos().relative(direction), stack, null);
// based on DispenseItemBehavior for SpawnEggItems
Direction direction = source.state().getValue(DispenserBlock.FACING);
BlockPos pos = source.pos().relative(direction);
Integer variant = PropItem.getVariant(stack);

Prop prop = this.item.type.spawn(source.level(), pos, stack, null, EntitySpawnReason.DISPENSER, variant, direction != Direction.UP, false);

stack.shrink(1); // intentionally not in the if statement
if (prop != null) {
prop.gameEvent(GameEvent.ENTITY_PLACE, null);
}

return stack;
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package io.github.fusionflux.portalcubed.content.prop;

import java.util.List;
import java.util.Optional;

import io.github.fusionflux.portalcubed.content.prop.entity.Prop;

import net.minecraft.world.entity.EntitySpawnReason;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import io.github.fusionflux.portalcubed.content.PortalCubedDataComponents;
import net.minecraft.ChatFormatting;
import net.minecraft.Optionull;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
Expand All @@ -24,7 +26,7 @@
import net.minecraft.world.level.gameevent.GameEvent;

public class PropItem extends Item {
private final PropType type;
public final PropType type;

public PropItem(Properties settings, PropType type) {
super(settings);
Expand All @@ -34,56 +36,53 @@ public PropItem(Properties settings, PropType type) {
@Override
@NotNull
public InteractionResult useOn(UseOnContext context) {
if (context.getLevel() instanceof ServerLevel world) {
BlockPos clickedPos = context.getClickedPos();
Direction clickedFace = context.getClickedFace();
BlockState state = world.getBlockState(clickedPos);
// TODO: rework this when the game launches
// boolean invertY = false;
// if (!state.getCollisionShape(world, clickedPos).isEmpty()) {
// clickedPos = clickedPos.relative(clickedFace);
// invertY = clickedFace == Direction.UP;
// }

this.use(world, clickedPos, context.getItemInHand(), context.getPlayer());
if (!(context.getLevel() instanceof ServerLevel level))
return InteractionResult.SUCCESS;

// based on SpawnEggItem
ItemStack held = context.getItemInHand();
BlockPos pos = context.getClickedPos();
Direction face = context.getClickedFace();
BlockState state = level.getBlockState(pos);
Player player = context.getPlayer();

BlockPos effectivePos = pos;
if (!state.getCollisionShape(level, pos).isEmpty()) {
effectivePos = pos.relative(face);
}

boolean offsetYMore = !pos.equals(effectivePos) && face == Direction.UP;

Integer variant = getVariant(held);
Prop prop = this.type.spawn(level, effectivePos, held, player, EntitySpawnReason.SPAWN_ITEM_USE, variant, true, offsetYMore);
if (prop != null) {
held.shrink(1);
prop.gameEvent(GameEvent.ENTITY_PLACE, player);
}

return InteractionResult.SUCCESS;
}

@Override
@NotNull
public Component getName(ItemStack stack) {
return getVariant(stack)
.map(variant -> (Component) Component.translatable(this.getDescriptionId() + "." + variant))
.orElseGet(() -> super.getName(stack));
Integer variant = getVariant(stack);
return variant == null ? super.getName(stack) : Component.translatable(this.getDescriptionId() + "." + variant);
}

@Override
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> tooltipComponents, TooltipFlag flag) {
super.appendHoverText(stack, context, tooltipComponents, flag);
if (flag.isCreative() && (this.type.randomVariantOnSpawn && getVariant(stack).isEmpty()))
tooltipComponents.add(translate("tooltip.random").withStyle(ChatFormatting.GRAY));
}

public boolean use(ServerLevel world, BlockPos pos, ItemStack stack, @Nullable Player spawner) {
Optional<Integer> maybeVariant = getVariant(stack);
return Optionull.mapOrDefault(
this.type.spawn(world, pos, stack, spawner, maybeVariant.orElse(0), maybeVariant.isEmpty()),
prop -> {
stack.shrink(1);
prop.gameEvent(GameEvent.ENTITY_PLACE, spawner);
return true;
},
false
);
if (flag.isCreative() && (this.type.randomVariantOnSpawn && getVariant(stack) == null))
tooltipComponents.add(this.translate("tooltip.random").withStyle(ChatFormatting.GRAY));
}

public MutableComponent translate(String key) {
private MutableComponent translate(String key) {
return Component.translatable(this.getDescriptionId() + "." + key);
}

public static Optional<Integer> getVariant(ItemStack stack) {
return Optional.ofNullable(stack.get(PortalCubedDataComponents.PROP_VARIANT));
@Nullable
public static Integer getVariant(ItemStack stack) {
return stack.get(PortalCubedDataComponents.PROP_VARIANT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.util.Locale;
import java.util.function.Consumer;

import net.minecraft.Util;

import org.apache.commons.lang3.stream.IntStreams;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -92,19 +94,26 @@ public EntityType<Prop> entityType() {
}

@Nullable
public Prop spawn(ServerLevel world, BlockPos pos, @Nullable ItemStack stack, @Nullable Player player, int variant, boolean randomizeVariant) {
public Prop spawn(ServerLevel level, BlockPos pos, @Nullable ItemStack stack, @Nullable Player player,
EntitySpawnReason reason, @Nullable Integer variant, boolean offsetY, boolean offsetYMore) {
Consumer<Prop> consumer = prop -> {
prop.setVariantFromItem(variant);
prop.setVariant(!(randomizeVariant && randomVariantOnSpawn) ? variant : world.random.nextInt(variants.length - 1) + 1);
prop.setVariantFromItem(variant != null ? variant : 0);
boolean randomize = variant == null;
if (randomize && this.randomVariantOnSpawn) {
int randomVariant = Util.getRandom(this.variants, prop.getRandom());
prop.setVariant(randomVariant);
} else {
prop.setVariant(variant != null ? variant : 0);
}
};

return this.entityType().spawn(
world,
stack != null ? EntityType.appendDefaultStackConfig(consumer, world, stack, player) : consumer,
level,
stack != null ? EntityType.appendDefaultStackConfig(consumer, level, stack, player) : consumer,
pos,
EntitySpawnReason.SPAWN_ITEM_USE,
true,
true
reason,
offsetY,
offsetYMore
);
}

Expand Down

0 comments on commit cb70ad1

Please sign in to comment.