diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index f826b41d6..93bda3c3c 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -1443,7 +1443,7 @@ public class AllBlocks { public static final BlockEntry TRACK = REGISTRATE.block("track", TrackBlock::new) .initialProperties(Material.STONE) - .properties(p -> p.color(MaterialColor.NONE) + .properties(p -> p.color(MaterialColor.METAL) .strength(0.8F) .sound(SoundType.METAL) .noOcclusion()) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationBlock.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationBlock.java index f6c5b8480..7fafdd15c 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationBlock.java @@ -20,6 +20,8 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.MapItem; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -31,6 +33,7 @@ import net.minecraft.world.level.block.state.StateDefinition.Builder; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.pathfinder.PathComputationType; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; @@ -64,7 +67,7 @@ public class StationBlock extends Block implements ITE, IWren updateWater(pLevel, pState, pCurrentPos); return pState; } - + @Override public FluidState getFluidState(BlockState pState) { return fluidState(pState); @@ -108,6 +111,25 @@ public class StationBlock extends Block implements ITE, IWren if (AllItems.WRENCH.isIn(itemInHand)) return InteractionResult.PASS; + if (itemInHand.getItem() == Items.FILLED_MAP) { + return onTileEntityUse(pLevel, pPos, station -> { + if (pLevel.isClientSide) + return InteractionResult.SUCCESS; + + if (station.getStation() == null || station.getStation().getId() == null) + return InteractionResult.FAIL; + + MapItemSavedData savedData = MapItem.getSavedData(itemInHand, pLevel); + if (!(savedData instanceof StationMapData stationMapData)) + return InteractionResult.FAIL; + + if (!stationMapData.toggleStation(pLevel, pPos, station)) + return InteractionResult.FAIL; + + return InteractionResult.SUCCESS; + }); + } + InteractionResult result = onTileEntityUse(pLevel, pPos, station -> { ItemStack autoSchedule = station.getAutoSchedule(); if (autoSchedule.isEmpty()) diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMapData.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMapData.java new file mode 100644 index 000000000..db92d8248 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMapData.java @@ -0,0 +1,12 @@ +package com.simibubi.create.content.logistics.trains.management.edgePoint.station; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.LevelAccessor; + +public interface StationMapData { + + boolean toggleStation(LevelAccessor level, BlockPos pos, StationTileEntity stationTileEntity); + + void loadStationMarker(StationMarker marker); + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMarker.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMarker.java new file mode 100644 index 000000000..19537e096 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationMarker.java @@ -0,0 +1,84 @@ +package com.simibubi.create.content.logistics.trains.management.edgePoint.station; + +import java.util.Objects; +import java.util.Optional; + +import com.simibubi.create.AllTileEntities; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.saveddata.maps.MapDecoration; + +public class StationMarker { + + private final BlockPos pos; + private final Component name; + + public StationMarker(BlockPos pos, Component name) { + this.pos = pos; + this.name = name; + } + + public static StationMarker load(CompoundTag tag) { + BlockPos pos = NbtUtils.readBlockPos(tag.getCompound("pos")); + Component name = Component.Serializer.fromJson(tag.getString("name")); + if (name == null) name = TextComponent.EMPTY; + + return new StationMarker(pos, name); + } + + public static StationMarker fromWorld(BlockGetter level, BlockPos pos) { + Optional stationOption = AllTileEntities.TRACK_STATION.get(level, pos); + + if (stationOption.isEmpty() || stationOption.get().getStation() == null) + return null; + + String name = stationOption.get().getStation().name; + return new StationMarker(pos, new TextComponent(name)); + } + + public CompoundTag save() { + CompoundTag tag = new CompoundTag(); + tag.put("pos", NbtUtils.writeBlockPos(this.pos)); + tag.putString("name", Component.Serializer.toJson(this.name)); + + return tag; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + StationMarker that = (StationMarker) o; + + if (!pos.equals(that.pos)) return false; + return name.equals(that.name); + } + + @Override + public int hashCode() { + return Objects.hash(this.pos, this.name); + } + + public BlockPos getPos() { + return this.pos; + } + + public Component getName() { + return name; + } + + public MapDecoration.Type getType() { + //todo replace with own type + return MapDecoration.Type.MANSION; + } + + public String getId() { + return "create:station-" + this.pos.getX() + "," + this.pos.getY() + "," + this.pos.getZ(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/block/ProperWaterloggedBlock.java b/src/main/java/com/simibubi/create/foundation/block/ProperWaterloggedBlock.java index e6d98c12d..e6439e5fd 100644 --- a/src/main/java/com/simibubi/create/foundation/block/ProperWaterloggedBlock.java +++ b/src/main/java/com/simibubi/create/foundation/block/ProperWaterloggedBlock.java @@ -20,7 +20,7 @@ import net.minecraft.world.level.material.Fluids; */ public interface ProperWaterloggedBlock extends SimpleWaterloggedBlock { - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; default FluidState fluidState(BlockState state) { return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : Fluids.EMPTY.defaultFluidState(); @@ -35,14 +35,13 @@ public interface ProperWaterloggedBlock extends SimpleWaterloggedBlock { return withWater(ctx.getLevel(), placementState, ctx.getClickedPos()); } - public static BlockState withWater(LevelAccessor level, BlockState placementState, BlockPos pos) { + static BlockState withWater(LevelAccessor level, BlockState placementState, BlockPos pos) { if (placementState == null) return null; if (!(placementState.getBlock() instanceof SimpleWaterloggedBlock)) - return null; + return placementState; FluidState ifluidstate = level.getFluidState(pos); - return placementState.setValue(BlockStateProperties.WATERLOGGED, - Boolean.valueOf(ifluidstate.getType() == Fluids.WATER)); + return placementState.setValue(BlockStateProperties.WATERLOGGED, ifluidstate.getType() == Fluids.WATER); } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/MapItemSavedDataMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/MapItemSavedDataMixin.java new file mode 100644 index 000000000..5ebacee3d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/MapItemSavedDataMixin.java @@ -0,0 +1,144 @@ +package com.simibubi.create.foundation.mixin; + +import java.util.Iterator; +import java.util.Map; + +import javax.annotation.Nullable; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.google.common.collect.Maps; +import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationMapData; +import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationMarker; +import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity; + +import net.minecraft.core.BlockPos; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.saveddata.maps.MapDecoration; +import net.minecraft.world.level.saveddata.maps.MapItemSavedData; + +@Mixin(MapItemSavedData.class) +public class MapItemSavedDataMixin implements StationMapData { + + @Final + @Shadow + public int x; + + @Final + @Shadow + public int z; + + @Final + @Shadow + public byte scale; + + private final Map stationMarkers = Maps.newHashMap(); + + @Inject( + method = "save(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/nbt/CompoundTag;", + at = @At("RETURN") + ) + public void save(CompoundTag compound, CallbackInfoReturnable cir) { + + ListTag listTag = new ListTag(); + for (StationMarker stationMarker : this.stationMarkers.values()) { + listTag.add(stationMarker.save()); + } + + cir.getReturnValue().put("create:stations", listTag); + } + + @Inject( + method = "load(Lnet/minecraft/nbt/CompoundTag;)Lnet/minecraft/world/level/saveddata/maps/MapItemSavedData;", + at = @At("RETURN") + ) + private static void load(CompoundTag compound, CallbackInfoReturnable cir) { + MapItemSavedData mapData = cir.getReturnValue(); + StationMapData stationMapData = (StationMapData) mapData; + + ListTag listTag = compound.getList("create:stations", 10); + for (int k = 0; k < listTag.size(); ++k) { + StationMarker stationMarker = StationMarker.load(listTag.getCompound(k)); + stationMapData.loadStationMarker(stationMarker); + } + } + + @Override + public void loadStationMarker(StationMarker marker) { + stationMarkers.put(marker.getId(), marker); + addDecoration(marker.getType(), null, marker.getId(), marker.getPos().getX(), marker.getPos().getZ(), 180.0D, marker.getName()); + } + + @Shadow + private void addDecoration(MapDecoration.Type pType, @Nullable LevelAccessor pLevel, String pDecorationName, double pLevelX, double pLevelZ, double pRotation, @Nullable Component pName) { + throw new AssertionError(); + } + + @Shadow + private void removeDecoration(String pIdentifier) { + throw new AssertionError(); + } + + @Shadow + public boolean isTrackedCountOverLimit(int pTrackedCount) { + throw new AssertionError(); + } + + @Override + public boolean toggleStation(LevelAccessor level, BlockPos pos, StationTileEntity stationTileEntity) { + double xCenter = pos.getX() + 0.5D; + double zCenter = pos.getZ() + 0.5D; + int scaleMultiplier = 1 << this.scale; + + double localX = (xCenter - (double) this.x) / (double) scaleMultiplier; + double localZ = (zCenter - (double) this.z) / (double) scaleMultiplier; + + if (localX < -63.0D || localX > 63.0D || localZ < -63.0D || localZ > 63.0D) + return false; + + StationMarker marker = StationMarker.fromWorld(level, pos); + if (marker == null) + return false; + + if (this.stationMarkers.remove(marker.getId(), marker)) { + this.removeDecoration(marker.getId()); + return true; + } + + if (!this.isTrackedCountOverLimit(256)) { + this.stationMarkers.put(marker.getId(), marker); + this.addDecoration(marker.getType(), level, marker.getId(), xCenter, zCenter, 180.0D, marker.getName()); + } + + return false; + } + + @Inject( + method = "checkBanners(Lnet/minecraft/world/level/BlockGetter;II)V", + at = @At("RETURN") + ) + public void checkBanners(BlockGetter pReader, int pX, int pZ, CallbackInfo ci) { + Iterator iterator = this.stationMarkers.values().iterator(); + + while (iterator.hasNext()) { + StationMarker marker = iterator.next(); + if (marker.getPos().getX() == pX && marker.getPos().getZ() == pZ) { + StationMarker other = StationMarker.fromWorld(pReader, marker.getPos()); + if (!marker.equals(other)) { + iterator.remove(); + this.removeDecoration(marker.getId()); + } + } + } + } +} diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index e7905533e..7a3d95863 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -1,31 +1,32 @@ { - "required": true, - "priority": 1100, - "package": "com.simibubi.create.foundation.mixin", - "compatibilityLevel": "JAVA_16", - "refmap": "create.refmap.json", - "mixins": [ - "CustomItemUseEffectsMixin", - "accessor.AbstractProjectileDispenseBehaviorAccessor", - "accessor.DispenserBlockAccessor", - "accessor.FallingBlockEntityAccessor", - "accessor.ServerLevelAccessor", - "accessor.LivingEntityAccessor" - ], - "client": [ - "DestroyProgressMixin", - "EntityContraptionInteractionMixin", - "FixNormalScalingMixin", - "HeavyBootsOnPlayerMixin", - "ModelDataRefreshMixin", - "WindowResizeMixin", - "GameRendererMixin", - "accessor.AgeableListModelAccessor", - "accessor.GameRendererAccessor", - "accessor.ParticleEngineAccessor" - ], - "injectors": { - "defaultRequire": 1 - }, - "minVersion": "0.8" + "required": true, + "priority": 1100, + "package": "com.simibubi.create.foundation.mixin", + "compatibilityLevel": "JAVA_16", + "refmap": "create.refmap.json", + "mixins": [ + "CustomItemUseEffectsMixin", + "MapItemSavedDataMixin", + "accessor.AbstractProjectileDispenseBehaviorAccessor", + "accessor.DispenserBlockAccessor", + "accessor.FallingBlockEntityAccessor", + "accessor.LivingEntityAccessor", + "accessor.ServerLevelAccessor" + ], + "client": [ + "DestroyProgressMixin", + "EntityContraptionInteractionMixin", + "FixNormalScalingMixin", + "GameRendererMixin", + "HeavyBootsOnPlayerMixin", + "ModelDataRefreshMixin", + "WindowResizeMixin", + "accessor.AgeableListModelAccessor", + "accessor.GameRendererAccessor", + "accessor.ParticleEngineAccessor" + ], + "injectors": { + "defaultRequire": 1 + }, + "minVersion": "0.8" }