diff --git a/.aiignore b/.aiignore new file mode 100644 index 0000000..56f70bf --- /dev/null +++ b/.aiignore @@ -0,0 +1,4 @@ +run/ +build/ +.gradle/ +assets/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c1ea5..58671a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.0.9 + +* Created new GeckoLib texture for server rack +* Created new texture for the server (2U) +* Rewrote server rack logic +* Created server item +* Moved processor unit into server item +* Allowed server racks to accept servers +* Updated server rack UI texture +* Render servers inside the server racks +* Add server recipe +* Fix computer so it produces cycles again but accepting only processor units +* Added tooltip to server to show how many and which CPUs it has +* Fix shift click stack upgrade into compiler +* Added creative battery with infinite energy and INT max capacity +* Creative battery now automatically pushes energy to adjacent blocks + ## 0.0.8 * Fixed a crash when GuideMe is not installed diff --git a/CREDITS.MD b/CREDITS.MD index e20f82e..a102c59 100644 --- a/CREDITS.MD +++ b/CREDITS.MD @@ -1,7 +1,4 @@ -# Datacenter and server ambience sounds - -## Sound Effect - -* -by [freesound_community](https://pixabay.com/users/freesound_community-46691455/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=31360) -from [Pixabay](https://pixabay.com) +* Sound Effect + by [freesound_community](https://pixabay.com/users/freesound_community-46691455/?utm_source=link-attribution&utm_medium=referral&utm_campaign=music&utm_content=31360) + from [Pixabay](https://pixabay.com) +* Video trailer for the mod by [lammycz](https://www.fiverr.com/lammycz) diff --git a/build.gradle b/build.gradle index 87dd469..5ff344a 100644 --- a/build.gradle +++ b/build.gradle @@ -218,7 +218,7 @@ dependencies { //localRuntime "curse.maven:powah-633483:6830067" // Pipez - //localRuntime "curse.maven:pipez-443900:5609056" + localRuntime "curse.maven:pipez-443900:5609056" // Mekanism, Mekanism generators //localRuntime "curse.maven:mekanism-268560:7132168" diff --git a/gradle.properties b/gradle.properties index f3fe7ce..81226e6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -29,7 +29,7 @@ mod_name=LogiCore # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=MIT # The mod version. See https://semver.org/ -mod_version=0.0.8 +mod_version=0.0.9 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/src/generated/resources/assets/logicore/models/item/creative_battery.json b/src/generated/resources/assets/logicore/models/item/creative_battery.json new file mode 100644 index 0000000..d92efca --- /dev/null +++ b/src/generated/resources/assets/logicore/models/item/creative_battery.json @@ -0,0 +1,3 @@ +{ + "parent": "logicore:block/creative_battery" +} \ No newline at end of file diff --git a/src/generated/resources/assets/logicore/models/item/server_rack.json b/src/generated/resources/assets/logicore/models/item/server_rack.json index 8e7755d..052f2e7 100644 --- a/src/generated/resources/assets/logicore/models/item/server_rack.json +++ b/src/generated/resources/assets/logicore/models/item/server_rack.json @@ -1,3 +1,3 @@ { "parent": "logicore:block/server_rack" -} \ No newline at end of file +} diff --git a/src/generated/resources/data/justdirethings/tags/block/eclipsegate_deny.json b/src/generated/resources/data/justdirethings/tags/block/eclipsegate_deny.json index beaa2d0..3266fbe 100644 --- a/src/generated/resources/data/justdirethings/tags/block/eclipsegate_deny.json +++ b/src/generated/resources/data/justdirethings/tags/block/eclipsegate_deny.json @@ -11,6 +11,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:research_station", "logicore:repair_station", "logicore:recycler" diff --git a/src/generated/resources/data/justdirethings/tags/block/phase_deny.json b/src/generated/resources/data/justdirethings/tags/block/phase_deny.json index beaa2d0..3266fbe 100644 --- a/src/generated/resources/data/justdirethings/tags/block/phase_deny.json +++ b/src/generated/resources/data/justdirethings/tags/block/phase_deny.json @@ -11,6 +11,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:research_station", "logicore:repair_station", "logicore:recycler" diff --git a/src/generated/resources/data/justdirethings/tags/block/swapper_deny.json b/src/generated/resources/data/justdirethings/tags/block/swapper_deny.json index beaa2d0..3266fbe 100644 --- a/src/generated/resources/data/justdirethings/tags/block/swapper_deny.json +++ b/src/generated/resources/data/justdirethings/tags/block/swapper_deny.json @@ -11,6 +11,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:research_station", "logicore:repair_station", "logicore:recycler" diff --git a/src/generated/resources/data/logicore/advancement/recipes/redstone/server.json b/src/generated/resources/data/logicore/advancement/recipes/redstone/server.json new file mode 100644 index 0000000..7287afc --- /dev/null +++ b/src/generated/resources/data/logicore/advancement/recipes/redstone/server.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_processor": { + "conditions": { + "items": [ + { + "items": "logicore:processor_unit_basic" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "logicore:server" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_processor" + ] + ], + "rewards": { + "recipes": [ + "logicore:server" + ] + } +} diff --git a/src/generated/resources/data/logicore/loot_table/blocks/creative_battery.json b/src/generated/resources/data/logicore/loot_table/blocks/creative_battery.json new file mode 100644 index 0000000..4816962 --- /dev/null +++ b/src/generated/resources/data/logicore/loot_table/blocks/creative_battery.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "logicore:creative_battery" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "logicore:blocks/creative_battery" +} diff --git a/src/generated/resources/data/logicore/recipe/server.json b/src/generated/resources/data/logicore/recipe/server.json new file mode 100644 index 0000000..6c99f01 --- /dev/null +++ b/src/generated/resources/data/logicore/recipe/server.json @@ -0,0 +1,30 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "redstone", + "key": { + "G": { + "item": "minecraft:gold_ingot" + }, + "I": { + "item": "minecraft:iron_ingot" + }, + "P": { + "item": "logicore:processor_unit_basic" + }, + "Q": { + "tag": "c:gems/quartz" + }, + "R": { + "tag": "c:dusts/redstone" + } + }, + "pattern": [ + "IRI", + "QPQ", + "GRG" + ], + "result": { + "count": 1, + "id": "logicore:server" + } +} diff --git a/src/generated/resources/data/logicore/tags/block/recycler_blacklist.json b/src/generated/resources/data/logicore/tags/block/recycler_blacklist.json index c32b6b7..95fc8f5 100644 --- a/src/generated/resources/data/logicore/tags/block/recycler_blacklist.json +++ b/src/generated/resources/data/logicore/tags/block/recycler_blacklist.json @@ -11,6 +11,7 @@ "logicore:research_station", "logicore:small_battery", "logicore:medium_battery", - "logicore:large_battery" + "logicore:large_battery", + "logicore:creative_battery" ] } diff --git a/src/generated/resources/data/logicore/tags/block/valid_datacenter_inner_block.json b/src/generated/resources/data/logicore/tags/block/valid_datacenter_inner_block.json index 414b7da..af2d2a3 100644 --- a/src/generated/resources/data/logicore/tags/block/valid_datacenter_inner_block.json +++ b/src/generated/resources/data/logicore/tags/block/valid_datacenter_inner_block.json @@ -4,6 +4,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:server_rack", "logicore:computer", "logicore:data_cable", diff --git a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json index 3ae4892..1e4fc47 100644 --- a/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/block/mineable/pickaxe.json @@ -11,6 +11,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:research_station", "logicore:repair_station", "logicore:recycler" diff --git a/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json b/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json index 3ae4892..1e4fc47 100644 --- a/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json +++ b/src/generated/resources/data/minecraft/tags/block/needs_iron_tool.json @@ -11,6 +11,7 @@ "logicore:small_battery", "logicore:medium_battery", "logicore:large_battery", + "logicore:creative_battery", "logicore:research_station", "logicore:repair_station", "logicore:recycler" diff --git a/src/main/java/dev/gacbl/logicore/Config.java b/src/main/java/dev/gacbl/logicore/Config.java index 80b567f..1f0e366 100644 --- a/src/main/java/dev/gacbl/logicore/Config.java +++ b/src/main/java/dev/gacbl/logicore/Config.java @@ -63,6 +63,8 @@ public class Config { public static final ModConfigSpec.ConfigValue MEDIUM_BATTERY_TRANSFER_RATE; public static final ModConfigSpec.ConfigValue LARGE_BATTERY_CAPACITY; public static final ModConfigSpec.ConfigValue LARGE_BATTERY_TRANSFER_RATE; + public static final ModConfigSpec.ConfigValue CREATIVE_BATTERY_CAPACITY; + public static final ModConfigSpec.ConfigValue CREATIVE_BATTERY_TRANSFER_RATE; // Processor Units public static final ModConfigSpec.ConfigValue BASIC_CPU_RATE; @@ -110,11 +112,11 @@ public class Config { SERVER_RACK_CYCLE_CAPACITY = BUILDER .comment(" How many cycles can be stored in the server rack") - .defineInRange("cycle_capacity", 1_000_000, 1, 1_000_000_000); + .defineInRange("cycle_capacity", 10_000_000, 1, 1_000_000_000); SERVER_RACK_FE_CAPACITY = BUILDER .comment(" How much FE can be stored in the server rack") - .defineInRange("fe_capacity", 100_000, 1, 1_000_000); + .defineInRange("fe_capacity", 10_000_000, 1, 1_000_000_000); SERVER_RACK_DATACENTER_BOOST = BUILDER .comment(" How much of a boost in cycle production the server rack gets from being in datacenter") @@ -177,7 +179,7 @@ public class Config { BUILDER.push("Cloud interface"); CI_MAX_TRANSFER_RATE = BUILDER .comment(" How many cycles per tick are transferred to and from the cloud.") - .defineInRange("cycles_processed_per_tick", 100_000L, 1L, 1_000_000_000L); + .defineInRange("cycles_processed_per_tick", 1_000_000L, 1L, 1_000_000_000L); BUILDER.pop(); // @@ -279,6 +281,17 @@ public class Config { .comment(" Maximum I/O rate of the battery") .defineInRange("large_battery_transfer_rate", 100_000_000, 1, Integer.MAX_VALUE); + BUILDER.pop(); + + BUILDER.push("Creative"); + CREATIVE_BATTERY_CAPACITY = BUILDER + .comment(" Maximum capacity of the battery") + .defineInRange("creative_battery_capacity", Integer.MAX_VALUE, 1, Integer.MAX_VALUE); + + CREATIVE_BATTERY_TRANSFER_RATE = BUILDER + .comment(" Maximum I/O rate of the battery") + .defineInRange("creative_battery_transfer_rate", Integer.MAX_VALUE, 1, Integer.MAX_VALUE); + BUILDER.pop(); BUILDER.pop(); // diff --git a/src/main/java/dev/gacbl/logicore/LogiCore.java b/src/main/java/dev/gacbl/logicore/LogiCore.java index feac270..708dcc6 100644 --- a/src/main/java/dev/gacbl/logicore/LogiCore.java +++ b/src/main/java/dev/gacbl/logicore/LogiCore.java @@ -24,6 +24,7 @@ import dev.gacbl.logicore.blocks.research_station.ResearchStationBlockEntityRenderer; import dev.gacbl.logicore.blocks.research_station.ResearchStationModule; import dev.gacbl.logicore.blocks.research_station.ui.ResearchStationScreen; +import dev.gacbl.logicore.blocks.serverrack.ServerRackBlockEntityRenderer; import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; import dev.gacbl.logicore.blocks.serverrack.ui.ServerRackScreen; import dev.gacbl.logicore.core.IntegrationUtils; @@ -32,6 +33,8 @@ import dev.gacbl.logicore.data.CreativeTabModule; import dev.gacbl.logicore.items.pickaxe.CyclePickModule; import dev.gacbl.logicore.items.processorunit.ProcessorUnitModule; +import dev.gacbl.logicore.items.server.ServerModule; +import dev.gacbl.logicore.items.server.ui.ServerScreen; import dev.gacbl.logicore.items.stack_upgrade.StackUpgradeModule; import dev.gacbl.logicore.items.wrench.WrenchModule; import dev.gacbl.logicore.network.PacketHandler; @@ -86,6 +89,7 @@ public LogiCore(IEventBus modEventBus, ModContainer modContainer) { CyclePickModule.register(modEventBus); RepairStationModule.register(modEventBus); RecyclerModule.register(modEventBus); + ServerModule.register(modEventBus); IntegrationUtils.registerEvents(); PacketHandler.register(modEventBus); @@ -134,6 +138,7 @@ public static void registerScreens(RegisterMenuScreensEvent event) { event.register(RepairStationModule.REPAIR_STATION_MENU.get(), RepairStationScreen::new); event.register(RecyclerModule.RECYCLER_MENU.get(), RecyclerScreen::new); event.register(DatacenterModule.DATACENTER_CONTROLLER_MENU.get(), DatacenterControllerScreen::new); + event.register(ServerModule.SERVER_MENU.get(), ServerScreen::new); } @SubscribeEvent @@ -143,6 +148,7 @@ public static void registerRenderers(EntityRenderersEvent.RegisterRenderers even event.registerBlockEntityRenderer(BatteryModule.BATTERY_BE.get(), BatteryFillRenderer::new); event.registerBlockEntityRenderer(RepairStationModule.REPAIR_STATION_BE.get(), RepairStationBlockEntityRenderer::new); event.registerBlockEntityRenderer(RecyclerModule.RECYCLER_BE.get(), context -> new RecyclerBlockRenderer()); + event.registerBlockEntityRenderer(ServerRackModule.SERVER_RACK_BLOCK_ENTITY.get(), ServerRackBlockEntityRenderer::new); } @SubscribeEvent diff --git a/src/main/java/dev/gacbl/logicore/api/compat/jade/providers/CoreCycleProvider.java b/src/main/java/dev/gacbl/logicore/api/compat/jade/providers/CoreCycleProvider.java index 68b23a8..6fe950f 100644 --- a/src/main/java/dev/gacbl/logicore/api/compat/jade/providers/CoreCycleProvider.java +++ b/src/main/java/dev/gacbl/logicore/api/compat/jade/providers/CoreCycleProvider.java @@ -1,12 +1,16 @@ package dev.gacbl.logicore.api.compat.jade.providers; import dev.gacbl.logicore.LogiCore; +import dev.gacbl.logicore.blocks.serverrack.ServerRackBlock; import dev.gacbl.logicore.blocks.serverrack.ServerRackBlockEntity; import dev.gacbl.logicore.core.CoreCycleProviderBlockEntity; +import dev.gacbl.logicore.core.Utils; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; import snownee.jade.api.BlockAccessor; import snownee.jade.api.IBlockComponentProvider; import snownee.jade.api.IServerDataProvider; @@ -31,8 +35,12 @@ public void appendTooltip(ITooltip tooltip, BlockAccessor accessor, IPluginConfi max = accessor.getServerData().getLong("MaxCycles"); } - tooltip.add(Component.translatable("tooltip.logicore.cycles", String.format("%,d", cycles), String.format("%,d", max))); - tooltip.add(Component.translatable("tooltip.logicore.processors", count, ServerRackBlockEntity.RACK_CAPACITY)); + if (!accessor.getPlayer().isCrouching()) { + tooltip.add(Component.translatable("tooltip.logicore.cycles", Utils.formatValues(cycles), Utils.formatValues(max))); + } else { + tooltip.add(Component.translatable("tooltip.logicore.cycles", String.format("%,d", cycles), String.format("%,d", max))); + } + tooltip.add(Component.translatable("tooltip.logicore.processors", count, ServerRackBlockEntity.RACK_CAPACITY * 9)); } @Override @@ -44,17 +52,25 @@ public boolean shouldRequestData(BlockAccessor accessor) { @Override public void appendServerData(CompoundTag data, BlockAccessor accessor) { - CoreCycleProviderBlockEntity rackBlockEntity = (CoreCycleProviderBlockEntity) accessor.getBlockEntity(); + CoreCycleProviderBlockEntity blockEntity = (CoreCycleProviderBlockEntity) accessor.getBlockEntity(); + if (accessor.getBlock() instanceof ServerRackBlock) { + BlockState state = accessor.getBlockState(); + if (state.getValue(ServerRackBlock.HALF) == DoubleBlockHalf.LOWER) { + blockEntity = (CoreCycleProviderBlockEntity) accessor.getBlockEntity(); + } else { + blockEntity = (CoreCycleProviderBlockEntity) accessor.getLevel().getBlockEntity(accessor.getPosition().below()); + } + } - if (rackBlockEntity == null) { - rackBlockEntity = (CoreCycleProviderBlockEntity) accessor.getLevel().getBlockEntity(accessor.getPosition().below()); + if (blockEntity == null) { + blockEntity = (CoreCycleProviderBlockEntity) accessor.getLevel().getBlockEntity(accessor.getPosition().below()); } - if (rackBlockEntity == null) return; + if (blockEntity == null) return; - data.putInt("Count", rackBlockEntity.getProcessorCount()); - data.putLong("Cycles", rackBlockEntity.getCycleStorage().getCyclesAvailable()); - data.putLong("MaxCycles", rackBlockEntity.getCycleStorage().getCycleCapacity()); + data.putInt("Count", blockEntity.getProcessorCount()); + data.putLong("Cycles", blockEntity.getCycleStorage().getCyclesAvailable()); + data.putLong("MaxCycles", blockEntity.getCycleStorage().getCycleCapacity()); } @Override diff --git a/src/main/java/dev/gacbl/logicore/blocks/battery/BaseBatteryEntity.java b/src/main/java/dev/gacbl/logicore/blocks/battery/BaseBatteryEntity.java index 4b17e57..b579692 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/battery/BaseBatteryEntity.java +++ b/src/main/java/dev/gacbl/logicore/blocks/battery/BaseBatteryEntity.java @@ -1,6 +1,7 @@ package dev.gacbl.logicore.blocks.battery; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.protocol.Packet; @@ -10,6 +11,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.energy.EnergyStorage; import net.neoforged.neoforge.energy.IEnergyStorage; import org.jetbrains.annotations.NotNull; @@ -18,7 +20,7 @@ import java.util.Objects; public class BaseBatteryEntity extends BlockEntity { - private final EnergyStorage energyStorage; + private final IEnergyStorage energyStorage; private int lastSyncedEnergy = -1; public BaseBatteryEntity(BlockPos pos, BlockState blockState) { @@ -26,7 +28,11 @@ public BaseBatteryEntity(BlockPos pos, BlockState blockState) { if (blockState.getBlock() instanceof BatteryBlock batteryBlock) { BatteryTier tier = batteryBlock.getTier(); - this.energyStorage = new EnergyStorage(tier.capacity.get(), tier.maxTransfer.get(), tier.maxTransfer.get()); + if (tier == BatteryTier.CREATIVE) { + this.energyStorage = new CreativeEnergyStorage(); + } else { + this.energyStorage = new EnergyStorage(tier.capacity.get(), tier.maxTransfer.get(), tier.maxTransfer.get()); + } } else { this.energyStorage = new EnergyStorage(1000, 100, 100); } @@ -39,20 +45,31 @@ public IEnergyStorage getEnergyStorage() { @Override protected void saveAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { super.saveAdditional(tag, registries); - tag.put("energy", this.energyStorage.serializeNBT(registries)); + if (this.energyStorage instanceof EnergyStorage es) { + tag.put("energy", es.serializeNBT(registries)); + } } @Override protected void loadAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { super.loadAdditional(tag, registries); - if (tag.contains("energy", 3) && tag.get("energy") != null) { - this.energyStorage.deserializeNBT(registries, Objects.requireNonNull(tag.get("energy"))); + if (tag.contains("energy") && tag.get("energy") != null && this.energyStorage instanceof EnergyStorage es) { + es.deserializeNBT(registries, Objects.requireNonNull(tag.get("energy"))); } } public static void serverTick(Level level, BlockPos blockPos, BlockState blockState, BaseBatteryEntity batteryBlockEntity) { if (level.isClientSide) return; + if (batteryBlockEntity.energyStorage instanceof CreativeEnergyStorage) { + for (Direction direction : Direction.values()) { + IEnergyStorage target = level.getCapability(Capabilities.EnergyStorage.BLOCK, blockPos.relative(direction), direction.getOpposite()); + if (target != null && target.canReceive()) { + target.receiveEnergy(Integer.MAX_VALUE, false); + } + } + } + int currentEnergy = batteryBlockEntity.energyStorage.getEnergyStored(); if (currentEnergy != batteryBlockEntity.lastSyncedEnergy) { batteryBlockEntity.lastSyncedEnergy = currentEnergy; diff --git a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryBlock.java b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryBlock.java index 24aed8b..e5c6246 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryBlock.java +++ b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryBlock.java @@ -103,9 +103,18 @@ public void appendHoverText(@NotNull ItemStack stack, Item.@NotNull TooltipConte capacity = Config.LARGE_BATTERY_CAPACITY.get(); transferRate = Config.LARGE_BATTERY_TRANSFER_RATE.get(); } + case CREATIVE -> { + capacity = Config.CREATIVE_BATTERY_CAPACITY.get(); + transferRate = Config.CREATIVE_BATTERY_TRANSFER_RATE.get(); + } } - tooltipComponents.add(Component.translatable("tooltip.logicore.battery_capacity", Utils.formatValues(capacity))); - tooltipComponents.add(Component.translatable("tooltip.logicore.battery_transfer_rate", Utils.formatValues(transferRate))); + if (tier == BatteryTier.CREATIVE) { + tooltipComponents.add(Component.translatable("tooltip.logicore.battery_capacity", Component.translatable("tooltip.logicore.infinite"))); + tooltipComponents.add(Component.translatable("tooltip.logicore.battery_transfer_rate", Component.translatable("tooltip.logicore.infinite"))); + } else { + tooltipComponents.add(Component.translatable("tooltip.logicore.battery_capacity", Utils.formatValues(capacity))); + tooltipComponents.add(Component.translatable("tooltip.logicore.battery_transfer_rate", Utils.formatValues(transferRate))); + } } } diff --git a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryModule.java b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryModule.java index d9eca81..ab31cfa 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryModule.java +++ b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryModule.java @@ -20,12 +20,14 @@ public class BatteryModule { public static final DeferredBlock BATTERY_SMALL = registerBattery("small_battery", BatteryTier.SMALL); public static final DeferredBlock BATTERY_MEDIUM = registerBattery("medium_battery", BatteryTier.MEDIUM); public static final DeferredBlock BATTERY_LARGE = registerBattery("large_battery", BatteryTier.LARGE); + public static final DeferredBlock BATTERY_CREATIVE = registerBattery("creative_battery", BatteryTier.CREATIVE); public static final DeferredHolder, BlockEntityType> BATTERY_BE = BLOCK_ENTITIES.register("battery", () -> BlockEntityType.Builder.of(BaseBatteryEntity::new, BATTERY_SMALL.get(), BATTERY_MEDIUM.get(), - BATTERY_LARGE.get() + BATTERY_LARGE.get(), + BATTERY_CREATIVE.get() ).build(null)); public static void register(IEventBus modEventBus) { diff --git a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryTier.java b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryTier.java index cdb2270..a971149 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryTier.java +++ b/src/main/java/dev/gacbl/logicore/blocks/battery/BatteryTier.java @@ -8,7 +8,8 @@ public enum BatteryTier implements StringRepresentable { SMALL("small", Config.SMALL_BATTERY_CAPACITY, Config.SMALL_BATTERY_TRANSFER_RATE), MEDIUM("medium", Config.MEDIUM_BATTERY_CAPACITY, Config.MEDIUM_BATTERY_TRANSFER_RATE), - LARGE("large", Config.LARGE_BATTERY_CAPACITY, Config.LARGE_BATTERY_TRANSFER_RATE); + LARGE("large", Config.LARGE_BATTERY_CAPACITY, Config.LARGE_BATTERY_TRANSFER_RATE), + CREATIVE("creative", Config.CREATIVE_BATTERY_CAPACITY, Config.CREATIVE_BATTERY_TRANSFER_RATE); public static final StringRepresentable.StringRepresentableCodec CODEC = StringRepresentable.fromEnum(BatteryTier::values); diff --git a/src/main/java/dev/gacbl/logicore/blocks/battery/CreativeEnergyStorage.java b/src/main/java/dev/gacbl/logicore/blocks/battery/CreativeEnergyStorage.java new file mode 100644 index 0000000..3193ca9 --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/blocks/battery/CreativeEnergyStorage.java @@ -0,0 +1,35 @@ +package dev.gacbl.logicore.blocks.battery; + +import net.neoforged.neoforge.energy.IEnergyStorage; + +public class CreativeEnergyStorage implements IEnergyStorage { + @Override + public int receiveEnergy(int maxReceive, boolean simulate) { + return maxReceive; + } + + @Override + public int extractEnergy(int maxExtract, boolean simulate) { + return maxExtract; + } + + @Override + public int getEnergyStored() { + return Integer.MAX_VALUE; + } + + @Override + public int getMaxEnergyStored() { + return Integer.MAX_VALUE; + } + + @Override + public boolean canExtract() { + return true; + } + + @Override + public boolean canReceive() { + return true; + } +} diff --git a/src/main/java/dev/gacbl/logicore/blocks/compiler/ui/CompilerMenu.java b/src/main/java/dev/gacbl/logicore/blocks/compiler/ui/CompilerMenu.java index 6a3d2b6..9c97301 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/compiler/ui/CompilerMenu.java +++ b/src/main/java/dev/gacbl/logicore/blocks/compiler/ui/CompilerMenu.java @@ -54,12 +54,12 @@ public CompilerMenu(int i, Inventory inventory, RegistryFriendlyByteBuf registry @Override public @NotNull ItemStack quickMoveStack(@NotNull Player playerIn, int pIndex) { - ItemStack sourceStack = ItemStack.EMPTY; + ItemStack copyOfSourceStack = ItemStack.EMPTY; Slot sourceSlot = slots.get(pIndex); - if (sourceSlot.hasItem()) { - ItemStack copyStack = sourceSlot.getItem(); - sourceStack = copyStack.copy(); + if (sourceSlot != null && sourceSlot.hasItem()) { + ItemStack sourceStack = sourceSlot.getItem(); + copyOfSourceStack = sourceStack.copy(); // Player Inventory (0-35) if (pIndex < 36) { @@ -77,20 +77,20 @@ public CompilerMenu(int i, Inventory inventory, RegistryFriendlyByteBuf registry } } - if (sourceStack.getCount() == 0) { + if (sourceStack.isEmpty()) { sourceSlot.set(ItemStack.EMPTY); } else { sourceSlot.setChanged(); } - if (sourceStack.getCount() == copyStack.getCount()) { + if (sourceStack.getCount() == copyOfSourceStack.getCount()) { return ItemStack.EMPTY; } sourceSlot.onTake(playerIn, sourceStack); } - return sourceStack; + return copyOfSourceStack; } public int getProgress() { diff --git a/src/main/java/dev/gacbl/logicore/blocks/computer/ComputerBlockEntity.java b/src/main/java/dev/gacbl/logicore/blocks/computer/ComputerBlockEntity.java index 91b4285..79e49c8 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/computer/ComputerBlockEntity.java +++ b/src/main/java/dev/gacbl/logicore/blocks/computer/ComputerBlockEntity.java @@ -20,7 +20,7 @@ import org.jetbrains.annotations.Nullable; public class ComputerBlockEntity extends CoreCycleProviderBlockEntity implements MenuProvider { - public static final int RACK_CAPACITY = 9; + public static final int COMPUTER_CPU_CAPACITY = 9; public ComputerBlockEntity(BlockPos pos, BlockState state) { super( @@ -52,7 +52,7 @@ public int getProcessorCount() { @Override public int getMaxProcessorCount() { - return RACK_CAPACITY; + return COMPUTER_CPU_CAPACITY; } @Override @@ -68,7 +68,7 @@ protected void loadAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Pr updateProcessorCountCache(); } - private final ItemStackHandler itemHandler = new ItemStackHandler(RACK_CAPACITY) { + private final ItemStackHandler itemHandler = new ItemStackHandler(COMPUTER_CPU_CAPACITY) { @Override protected void onContentsChanged(int slot) { updateProcessorCountCache(); @@ -86,7 +86,6 @@ public int getSlotLimit(int slot) { } }; - @Override public ItemStackHandler getItemHandler() { return this.itemHandler; } diff --git a/src/main/java/dev/gacbl/logicore/blocks/datacable/DataCableBlock.java b/src/main/java/dev/gacbl/logicore/blocks/datacable/DataCableBlock.java index b825f64..705cd09 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/datacable/DataCableBlock.java +++ b/src/main/java/dev/gacbl/logicore/blocks/datacable/DataCableBlock.java @@ -12,6 +12,7 @@ import dev.gacbl.logicore.blocks.repair_station.RepairStationBlock; import dev.gacbl.logicore.blocks.research_station.ResearchStationBlock; import dev.gacbl.logicore.blocks.serverrack.ServerRackBlock; +import dev.gacbl.logicore.core.ModTags; import dev.gacbl.logicore.items.processorunit.ProcessorUnitModule; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -158,7 +159,7 @@ private boolean canConnectTo(BlockGetter level, BlockPos pos, Direction directio BlockState state = level.getBlockState(pos); Block block = state.getBlock(); - if (block instanceof DataCableBlock) { + if (state.is(ModTags.Blocks.IS_ENERGY_GENERATOR) || block instanceof DataCableBlock) { return true; } diff --git a/src/main/java/dev/gacbl/logicore/blocks/datacable/cable_network/ComputationNetwork.java b/src/main/java/dev/gacbl/logicore/blocks/datacable/cable_network/ComputationNetwork.java index 35b70f0..3f67289 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/datacable/cable_network/ComputationNetwork.java +++ b/src/main/java/dev/gacbl/logicore/blocks/datacable/cable_network/ComputationNetwork.java @@ -19,7 +19,7 @@ import java.util.*; public class ComputationNetwork { - private static final int MAX_PULL_PER_SOURCE_PER_TICK = 50000; + private static final int MAX_PULL_PER_SOURCE_PER_TICK = 1_000_000; private final Set cables = new HashSet<>(); private final Set providers = new HashSet<>(); diff --git a/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlock.java b/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlock.java index 047267e..87237d1 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlock.java +++ b/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlock.java @@ -2,7 +2,6 @@ import com.mojang.serialization.MapCodec; import dev.gacbl.logicore.blocks.serverrack.ServerRackBlock; -import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.data.recipes.RecipeCategory; @@ -41,7 +40,7 @@ protected GeneratorBlock(Properties properties) { super(properties); this.registerDefaultState(this.stateDefinition.any() .setValue(FACING, Direction.NORTH) - .setValue(ServerRackModule.GENERATING, false)); + .setValue(ServerRackBlock.GENERATING, false)); } public static ShapedRecipeBuilder getRecipe() { @@ -62,7 +61,7 @@ public static ShapedRecipeBuilder getRecipe() { @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(ServerRackModule.GENERATING); + builder.add(ServerRackBlock.GENERATING); builder.add(FACING); } diff --git a/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlockEntity.java b/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlockEntity.java index 15bb6c6..fc27a48 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlockEntity.java +++ b/src/main/java/dev/gacbl/logicore/blocks/generator/GeneratorBlockEntity.java @@ -1,7 +1,7 @@ package dev.gacbl.logicore.blocks.generator; import dev.gacbl.logicore.blocks.generator.ui.GeneratorMenu; -import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; +import dev.gacbl.logicore.blocks.serverrack.ServerRackBlock; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.HolderLookup; @@ -132,7 +132,7 @@ public static void serverTick(Level level, BlockPos pos, BlockState state, Gener currentlyGenerating = false; setChanged(level, pos, state); be.isGenerating = currentlyGenerating; - level.setBlock(pos, state.setValue(ServerRackModule.GENERATING, be.isGenerating), 3); + level.setBlock(pos, state.setValue(ServerRackBlock.GENERATING, be.isGenerating), 3); return; } @@ -181,7 +181,7 @@ public static void serverTick(Level level, BlockPos pos, BlockState state, Gener if (wasGenerating != currentlyGenerating) { be.isGenerating = currentlyGenerating; - level.setBlock(pos, state.setValue(ServerRackModule.GENERATING, be.isGenerating), 3); + level.setBlock(pos, state.setValue(ServerRackBlock.GENERATING, be.isGenerating), 3); setChanged(level, pos, state); } } diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlock.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlock.java index 86d0e1c..0257a04 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlock.java +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlock.java @@ -1,19 +1,13 @@ package dev.gacbl.logicore.blocks.serverrack; import com.mojang.serialization.MapCodec; -import dev.gacbl.logicore.Config; -import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; import dev.gacbl.logicore.items.processorunit.ProcessorUnitModule; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.particles.ParticleTypes; import net.minecraft.data.recipes.RecipeCategory; import net.minecraft.data.recipes.ShapedRecipeBuilder; import net.minecraft.resources.ResourceLocation; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; import net.minecraft.tags.ItemTags; -import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.ItemInteractionResult; @@ -31,33 +25,34 @@ import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; -import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.*; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; -import net.neoforged.neoforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public class ServerRackBlock extends BaseEntityBlock { +public class ServerRackBlock extends BaseEntityBlock implements EntityBlock { public static final VoxelShape SHAPE = Block.box(0.0D, 0.0D, 0.0D, 16.0D, 16.0D, 16.0D); public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING; public static final EnumProperty HALF = BlockStateProperties.DOUBLE_BLOCK_HALF; public static final MapCodec CODEC = simpleCodec(ServerRackBlock::new); + public static final BooleanProperty GENERATING = BooleanProperty.create("generating"); + public static final BooleanProperty DOOR_OPENING = BooleanProperty.create("door_opening"); + public static final BooleanProperty DOOR_CLOSING = BooleanProperty.create("door_closing"); public ServerRackBlock(Properties properties) { super(properties); this.registerDefaultState(this.stateDefinition.any() .setValue(FACING, Direction.NORTH) .setValue(HALF, DoubleBlockHalf.LOWER) - .setValue(ServerRackModule.GENERATING, false)); + .setValue(GENERATING, false) + .setValue(DOOR_CLOSING, false) + .setValue(DOOR_OPENING, false)); } public static ShapedRecipeBuilder getRecipe() { - return ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, ServerRackModule.SERVER_RACK_BLOCK.get()) + return ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, ServerRackModule.SERVER_RACK.get()) .pattern("REQ") .pattern("EPE") .pattern("QER") @@ -74,7 +69,7 @@ public static ShapedRecipeBuilder getRecipe() { @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { - builder.add(FACING, HALF, ServerRackModule.GENERATING); + builder.add(FACING, HALF, GENERATING, DOOR_CLOSING, DOOR_OPENING); } @Nullable @@ -86,7 +81,9 @@ public BlockState getStateForPlacement(BlockPlaceContext context) { return this.defaultBlockState() .setValue(FACING, context.getHorizontalDirection().getOpposite()) .setValue(HALF, DoubleBlockHalf.LOWER) - .setValue(ServerRackModule.GENERATING, false); + .setValue(GENERATING, false) + .setValue(DOOR_CLOSING, false) + .setValue(DOOR_OPENING, false); } return null; } @@ -102,8 +99,8 @@ public void setPlacedBy(@NotNull Level level, @NotNull BlockPos pos, @NotNull Bl } @Override - public @NotNull RenderShape getRenderShape(@NotNull BlockState state) { - return RenderShape.MODEL; + protected @NotNull RenderShape getRenderShape(@NotNull BlockState state) { + return RenderShape.ENTITYBLOCK_ANIMATED; } @Override @@ -135,42 +132,21 @@ public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState sta @Override protected @NotNull ItemInteractionResult useItemOn(@NotNull ItemStack stack, @NotNull BlockState state, @NotNull Level level, @NotNull BlockPos pos, @NotNull Player player, @NotNull InteractionHand hand, @NotNull BlockHitResult hitResult) { - if (level.isClientSide()) return super.useItemOn(stack, state, level, pos, player, hand, hitResult); BlockPos bePos = state.getValue(HALF) == DoubleBlockHalf.LOWER ? pos : pos.below(); - - if (stack.getItem() instanceof ProcessorUnitItem) { - if (level.getBlockEntity(bePos) instanceof ServerRackBlockEntity rack) { - ItemStackHandler handler = rack.getItemHandler(); - boolean inserted = false; - for (int slot = 0; slot < handler.getSlots(); slot++) { - ItemStack s = rack.getItemHandler().getStackInSlot(slot); - if (s.isEmpty() && !stack.isEmpty()) { - rack.getItemHandler().setStackInSlot(slot, new ItemStack(stack.getItem(), 1)); - stack.shrink(1); - inserted = true; - } - } - - if (inserted) { - level.playSound(null, pos, SoundEvents.ITEM_PICKUP, SoundSource.BLOCKS, 1.0f, 1.0f); - level.sendBlockUpdated(pos, state, state, Block.UPDATE_ALL); - return ItemInteractionResult.CONSUME; - } - } + BlockEntity be = level.getBlockEntity(bePos); + if (be instanceof ServerRackBlockEntity serverRack) { + return serverRack.handleItemClick(stack, player, hitResult); } return super.useItemOn(stack, state, level, pos, player, hand, hitResult); } @Override protected @NotNull InteractionResult useWithoutItem(@NotNull BlockState state, Level level, @NotNull BlockPos pos, @NotNull Player player, @NotNull BlockHitResult hit) { - if (!level.isClientSide) { - BlockPos bePos = state.getValue(HALF) == DoubleBlockHalf.LOWER ? pos : pos.below(); - BlockEntity be = level.getBlockEntity(bePos); + BlockPos bePos = state.getValue(HALF) == DoubleBlockHalf.LOWER ? pos : pos.below(); + BlockEntity be = level.getBlockEntity(bePos); - if (be instanceof ServerRackBlockEntity serverRack) { - player.openMenu(serverRack, bePos); - return InteractionResult.CONSUME; - } + if (be instanceof ServerRackBlockEntity serverRack) { + return serverRack.handleRightClick(player, hit); } return InteractionResult.SUCCESS; } @@ -244,40 +220,4 @@ protected void onPlace(@NotNull BlockState state, @NotNull Level level, @NotNull level.updateNeighborsAt(pos.above(), this); level.updateNeighborsAt(pos.below(), this); } - - @Override - public void animateTick(BlockState state, @NotNull Level level, @NotNull BlockPos pos, @NotNull RandomSource random) { - if (!state.getValue(ServerRackModule.GENERATING) || !Config.SERVER_RACK_PRODUCES_PARTICLES.get()) { - return; - } - - if (random.nextInt(5) == 0) { - Direction facing = state.getValue(FACING); - Direction left = facing.getCounterClockWise(); - Direction right = facing.getClockWise(); - - BlockPos leftPos = pos.relative(left); - if (level.getBlockState(leftPos).isAir()) { - spawnSmokeAt(level, pos, left, random); - } - - BlockPos rightPos = pos.relative(right); - if (level.getBlockState(rightPos).isAir()) { - spawnSmokeAt(level, pos, right, random); - } - } - } - - private void spawnSmokeAt(Level level, BlockPos pos, Direction direction, RandomSource random) { - double x = pos.getX() + 0.5D; - double y = pos.getY(); - double z = pos.getZ() + 0.5D; - - x += direction.getStepX() * 0.6D; - z += direction.getStepZ() * 0.6D; - - y += (random.nextDouble() * 0.8D) + 0.1D; - - level.addParticle(ParticleTypes.LARGE_SMOKE, x, y, z, 0.0D, 0.0D, 0.0D); - } } diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntity.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntity.java index 7c5fee2..6415c8b 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntity.java +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntity.java @@ -4,23 +4,41 @@ import dev.gacbl.logicore.blocks.serverrack.ui.ServerRackMenu; import dev.gacbl.logicore.core.CoreCycleProviderBlockEntity; import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; +import dev.gacbl.logicore.items.server.ServerItem; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; +import net.minecraft.core.component.DataComponents; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.Containers; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.player.Inventory; import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemContainerContents; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; +import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.items.ItemStackHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import software.bernie.geckolib.animatable.GeoBlockEntity; +import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.animatable.instance.SingletonAnimatableInstanceCache; +import software.bernie.geckolib.animation.*; -public class ServerRackBlockEntity extends CoreCycleProviderBlockEntity implements MenuProvider { +public class ServerRackBlockEntity extends CoreCycleProviderBlockEntity implements MenuProvider, GeoBlockEntity { public static final int RACK_CAPACITY = 9; + private final AnimatableInstanceCache cache = new SingletonAnimatableInstanceCache(this); + private int serverCacheCount = 0; + private int totalProcessorCount = 0; + private int doorTimer = 0; public ServerRackBlockEntity(BlockPos pos, BlockState state) { super( @@ -34,6 +52,111 @@ public ServerRackBlockEntity(BlockPos pos, BlockState state) { ); } + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar controllers) { + controllers.add(new AnimationController<>(this, "controller", 0, this::predicate)); + } + + private PlayState predicate(AnimationState recyclerBlockEntityAnimationState) { + if (level != null) { + BlockState state = level.getBlockState(worldPosition); + if (state.getBlock() instanceof ServerRackBlock) { + if (state.getValue(ServerRackBlock.DOOR_OPENING)) { + recyclerBlockEntityAnimationState.setAndContinue(RawAnimation.begin().then("door_open", Animation.LoopType.HOLD_ON_LAST_FRAME)); + } else if (state.getValue(ServerRackBlock.DOOR_CLOSING)) { + recyclerBlockEntityAnimationState.setAndContinue(RawAnimation.begin().then("door_close", Animation.LoopType.HOLD_ON_LAST_FRAME)); + } else { + recyclerBlockEntityAnimationState.setAndContinue(RawAnimation.begin().then("idle", Animation.LoopType.PLAY_ONCE)); + } + } + } + return PlayState.CONTINUE; + } + + public InteractionResult handleRightClick(Player player, BlockHitResult hit) { + if (level == null || level.isClientSide) return InteractionResult.SUCCESS; + + BlockState state = level.getBlockState(worldPosition); + if (!(state.getBlock() instanceof ServerRackBlock)) return InteractionResult.PASS; + + boolean isOpening = state.getValue(ServerRackBlock.DOOR_OPENING); + + if (!isOpening) { + if (player.isShiftKeyDown()) { + player.openMenu(this, worldPosition); + return InteractionResult.CONSUME; + } + + updateDoorStates(state, true, false); + level.playSound(null, worldPosition, SoundEvents.IRON_DOOR_OPEN, SoundSource.BLOCKS, 1.0f, 1.0f); + return InteractionResult.SUCCESS; + } else { + if (!player.isShiftKeyDown()) { + updateDoorStates(state, false, true); + level.playSound(null, worldPosition, SoundEvents.IRON_DOOR_CLOSE, SoundSource.BLOCKS, 1.0f, 1.0f); + return InteractionResult.SUCCESS; + } else { + player.openMenu(this, worldPosition); + return InteractionResult.CONSUME; + } + } + } + + public ItemInteractionResult handleItemClick(ItemStack stack, Player player, BlockHitResult hit) { + if (level == null) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + + if (stack.getItem() instanceof ServerItem) { + if (level.isClientSide) return ItemInteractionResult.SUCCESS; + + BlockState state = level.getBlockState(worldPosition); + if (!state.getValue(ServerRackBlock.DOOR_OPENING)) { + handleRightClick(player, hit); + return ItemInteractionResult.SUCCESS; + } + + ItemStackHandler handler = getItemHandler(); + for (int slot = 0; slot < handler.getSlots(); slot++) { + if (handler.getStackInSlot(slot).isEmpty()) { + handler.setStackInSlot(slot, stack.split(1)); + level.playSound(null, worldPosition, SoundEvents.ITEM_PICKUP, SoundSource.BLOCKS, 1.0f, 1.0f); + level.sendBlockUpdated(worldPosition, state, state, Block.UPDATE_ALL); + return ItemInteractionResult.CONSUME; + } + } + } + + return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; + } + + private void updateDoorStates(BlockState state, boolean opening, boolean closing) { + if (level == null) return; + BlockState newState = state.setValue(ServerRackBlock.DOOR_OPENING, opening) + .setValue(ServerRackBlock.DOOR_CLOSING, closing); + level.setBlock(worldPosition, newState, Block.UPDATE_ALL); + + BlockPos above = worldPosition.above(); + BlockState aboveState = level.getBlockState(above); + if (aboveState.is(state.getBlock()) && aboveState.getValue(ServerRackBlock.HALF) == DoubleBlockHalf.UPPER) { + level.setBlock(above, aboveState.setValue(ServerRackBlock.DOOR_OPENING, opening) + .setValue(ServerRackBlock.DOOR_CLOSING, closing), Block.UPDATE_ALL); + } + } + + @Override + protected boolean canGenerate() { + if (level == null) return false; + BlockState state = getBlockState(); + if (state.getBlock() instanceof ServerRackBlock) { + return !state.getValue(ServerRackBlock.DOOR_OPENING) && !state.getValue(ServerRackBlock.DOOR_CLOSING); + } + return super.canGenerate(); + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return cache; + } + @Override public @NotNull Component getDisplayName() { return Component.translatable("block.logicore.server_rack"); @@ -47,37 +170,24 @@ public AbstractContainerMenu createMenu(int containerId, @NotNull Inventory play @Override public int getProcessorCount() { - return this.cachedProcessorCount; + return this.totalProcessorCount; } @Override public int getMaxProcessorCount() { - return RACK_CAPACITY; - } - - @Override - protected void saveAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - tag.put("inventory", itemHandler.serializeNBT(registries)); - } - - @Override - protected void loadAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); - itemHandler.deserializeNBT(registries, tag.getCompound("inventory")); - updateProcessorCountCache(); + return RACK_CAPACITY * 9; } private final ItemStackHandler itemHandler = new ItemStackHandler(RACK_CAPACITY) { @Override protected void onContentsChanged(int slot) { - updateProcessorCountCache(); + updateServerCache(); setChanged(); } @Override public boolean isItemValid(int slot, @NotNull ItemStack stack) { - return stack.getItem() instanceof ProcessorUnitItem; + return stack.getItem() instanceof ServerItem; } @Override @@ -91,6 +201,19 @@ public ItemStackHandler getItemHandler() { return this.itemHandler; } + @Override + protected void saveAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + tag.put("inventory", itemHandler.serializeNBT(registries)); + } + + @Override + protected void loadAdditional(@NotNull CompoundTag tag, @NotNull HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + itemHandler.deserializeNBT(registries, tag.getCompound("inventory")); + updateServerCache(); + } + public void dropContents() { if (this.level == null) return; for (int i = 0; i < itemHandler.getSlots(); i++) { @@ -98,13 +221,63 @@ public void dropContents() { } } - private void updateProcessorCountCache() { - int count = 0; + private void updateServerCache() { + int servers = 0; + int processors = 0; + for (int i = 0; i < itemHandler.getSlots(); i++) { + ItemStack stack = itemHandler.getStackInSlot(i); + if (!stack.isEmpty() && stack.getItem() instanceof ServerItem) { + servers++; + ItemContainerContents contents = stack.get(DataComponents.CONTAINER); + if (contents != null) { + for (ItemStack innerStack : contents.nonEmptyItems()) { + if (innerStack.getItem() instanceof ProcessorUnitItem) { + processors++; + } + } + } + } + } + this.serverCacheCount = servers; + this.totalProcessorCount = processors; + } + + @Override + public int calculateBaseCycleGeneration() { + long cyclesToGenerate = BASE_CYCLE_GENERATION; for (int i = 0; i < itemHandler.getSlots(); i++) { - if (!itemHandler.getStackInSlot(i).isEmpty()) { - count++; + ItemStack stack = itemHandler.getStackInSlot(i); + if (!stack.isEmpty() && stack.getItem() instanceof ServerItem) { + ItemContainerContents contents = stack.get(DataComponents.CONTAINER); + if (contents != null) { + for (ItemStack innerStack : contents.nonEmptyItems()) { + if (innerStack.getItem() instanceof ProcessorUnitItem processor) { + cyclesToGenerate += CYCLES_PER_PROCESSOR + processor.tier.cycleRate.get(); + } + } + } + } + } + + // Natural generation: reward populated racks with efficiency boost + // 1.0 + (serverCount - 1) * 0.05 => 1.4x boost at 9 servers + double efficiency = 1.0 + (Math.max(0, serverCacheCount - 1) * 0.05); + + return (int) (cyclesToGenerate * efficiency); + } + + public static void serverTick(net.minecraft.world.level.Level level, BlockPos pos, BlockState state, ServerRackBlockEntity be) { + BlockState currentState = state; + if (state.getValue(ServerRackBlock.DOOR_CLOSING)) { + be.doorTimer++; + if (be.doorTimer >= 20) { + be.updateDoorStates(state, false, false); + be.doorTimer = 0; + currentState = level.getBlockState(pos); } + } else { + be.doorTimer = 0; } - this.cachedProcessorCount = count; + CoreCycleProviderBlockEntity.serverTick(level, pos, currentState, be); } } diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntityRenderer.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntityRenderer.java new file mode 100644 index 0000000..d80690a --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackBlockEntityRenderer.java @@ -0,0 +1,56 @@ +package dev.gacbl.logicore.blocks.serverrack; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import dev.gacbl.logicore.blocks.serverrack.client.ServerRackBlockRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.ItemStackHandler; +import org.jetbrains.annotations.NotNull; + +public class ServerRackBlockEntityRenderer extends ServerRackBlockRenderer { + private final ItemRenderer itemRenderer; + + public ServerRackBlockEntityRenderer(BlockEntityRendererProvider.Context context) { + super(); + this.itemRenderer = context.getItemRenderer(); + } + + @Override + public void render(@NotNull ServerRackBlockEntity pBlockEntity, float pPartialTick, @NotNull PoseStack pPoseStack, @NotNull MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) { + super.render(pBlockEntity, pPartialTick, pPoseStack, pBufferSource, pPackedLight, pPackedOverlay); + + ItemStackHandler handler = pBlockEntity.getItemHandler(); + Direction facing = pBlockEntity.getBlockState().getValue(ServerRackBlock.FACING); + + pPoseStack.pushPose(); + + // Center and rotate based on block facing + pPoseStack.translate(0.5, 0, 0.5); + pPoseStack.mulPose(Axis.YP.rotationDegrees(-facing.toYRot())); + pPoseStack.translate(-0.5, 0, -0.5); + + for (int i = 0; i < handler.getSlots(); i++) { + ItemStack stack = handler.getStackInSlot(i); + if (!stack.isEmpty()) { + pPoseStack.pushPose(); + + double yOffset = 1.8 - (i * 0.185); + double zOffset = 0.42; + + pPoseStack.translate(0.5, yOffset, zOffset); + pPoseStack.mulPose(Axis.YP.rotationDegrees(180)); + + this.itemRenderer.renderStatic(stack, ItemDisplayContext.FIXED, pPackedLight, pPackedOverlay, pPoseStack, pBufferSource, pBlockEntity.getLevel(), 0); + + pPoseStack.popPose(); + } + } + + pPoseStack.popPose(); + } +} diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackLootTableProvider.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackLootTableProvider.java index 872b948..c23ca4b 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackLootTableProvider.java +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackLootTableProvider.java @@ -20,7 +20,7 @@ public ServerRackLootTableProvider(HolderLookup.Provider registries) { @Override protected void generate() { this.add( - ServerRackModule.SERVER_RACK_BLOCK.get(), + ServerRackModule.SERVER_RACK.get(), block -> createSinglePropConditionTable( block, BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.LOWER ) diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackModule.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackModule.java index 9e59baa..b691f56 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackModule.java +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ServerRackModule.java @@ -10,12 +10,12 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.material.MapColor; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; +import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; public class ServerRackModule { @@ -24,20 +24,22 @@ public class ServerRackModule { public static final DeferredRegister> BLOCK_ENTITIES = DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, LogiCore.MOD_ID); public static final DeferredRegister> MENUS = DeferredRegister.create(BuiltInRegistries.MENU, LogiCore.MOD_ID); - public static final BooleanProperty GENERATING = BooleanProperty.create("generating"); - - public static final net.neoforged.neoforge.registries.DeferredHolder SERVER_RACK_BLOCK = + public static final DeferredHolder SERVER_RACK = BLOCKS.register("server_rack", () -> new ServerRackBlock(BlockBehaviour.Properties.of() - .mapColor(MapColor.METAL).strength(2.0f).requiresCorrectToolForDrops().noOcclusion())); + .mapColor(MapColor.METAL) + .strength(3.0F, 3.0F) + .requiresCorrectToolForDrops() + .noOcclusion() + )); - public static final net.neoforged.neoforge.registries.DeferredHolder SERVER_RACK_ITEM = - ITEMS.register("server_rack", () -> new BlockItem(SERVER_RACK_BLOCK.get(), new Item.Properties())); + public static final DeferredHolder SERVER_RACK_ITEM = + ITEMS.register("server_rack", () -> new BlockItem(SERVER_RACK.get(), new Item.Properties())); - public static final net.neoforged.neoforge.registries.DeferredHolder, BlockEntityType> SERVER_RACK_BLOCK_ENTITY = + public static final DeferredHolder, BlockEntityType> SERVER_RACK_BLOCK_ENTITY = BLOCK_ENTITIES.register("server_rack", () -> BlockEntityType.Builder.of( - ServerRackBlockEntity::new, SERVER_RACK_BLOCK.get()).build(null)); + ServerRackBlockEntity::new, SERVER_RACK.get()).build(null)); - public static final net.neoforged.neoforge.registries.DeferredHolder, MenuType> SERVER_RACK_MENU = + public static final DeferredHolder, MenuType> SERVER_RACK_MENU = MENUS.register("server_rack_menu", () -> IMenuTypeExtension.create(ServerRackMenu::new)); public static void register(IEventBus modEventBus) { diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockModel.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockModel.java new file mode 100644 index 0000000..65714c5 --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockModel.java @@ -0,0 +1,18 @@ +package dev.gacbl.logicore.blocks.serverrack.client; + +import dev.gacbl.logicore.LogiCore; +import dev.gacbl.logicore.blocks.serverrack.ServerRackBlockEntity; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.model.DefaultedBlockGeoModel; + +public class ServerRackBlockModel extends DefaultedBlockGeoModel { + public ServerRackBlockModel() { + super(ResourceLocation.fromNamespaceAndPath(LogiCore.MOD_ID, "server_rack")); + } + + @Override + public RenderType getRenderType(ServerRackBlockEntity animatable, ResourceLocation texture) { + return RenderType.entityTranslucent(getTextureResource(animatable)); + } +} diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockRenderer.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockRenderer.java new file mode 100644 index 0000000..26b9fd1 --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/client/ServerRackBlockRenderer.java @@ -0,0 +1,10 @@ +package dev.gacbl.logicore.blocks.serverrack.client; + +import dev.gacbl.logicore.blocks.serverrack.ServerRackBlockEntity; +import software.bernie.geckolib.renderer.GeoBlockRenderer; + +public class ServerRackBlockRenderer extends GeoBlockRenderer { + public ServerRackBlockRenderer() { + super(new ServerRackBlockModel()); + } +} diff --git a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ui/ServerRackMenu.java b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ui/ServerRackMenu.java index d5f7a3d..19e8ebc 100644 --- a/src/main/java/dev/gacbl/logicore/blocks/serverrack/ui/ServerRackMenu.java +++ b/src/main/java/dev/gacbl/logicore/blocks/serverrack/ui/ServerRackMenu.java @@ -3,7 +3,7 @@ import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; import dev.gacbl.logicore.core.CoreCycleProviderBlockEntity; import dev.gacbl.logicore.core.ui.MyAbstractContainerMenu; -import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; +import dev.gacbl.logicore.items.server.ServerItem; import net.minecraft.core.BlockPos; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.world.entity.player.Inventory; @@ -32,7 +32,7 @@ public ServerRackMenu(int containerId, Inventory playerInventory, BlockEntity en this.addSlot(new SlotItemHandler(((CoreCycleProviderBlockEntity) this.blockEntity).getItemHandler(), row, startX + row * slotSize, startY) { @Override public boolean mayPlace(@NotNull ItemStack stack) { - return stack.getItem() instanceof ProcessorUnitItem; + return super.mayPlace(stack); } @Override @@ -64,7 +64,7 @@ public ServerRackMenu(int i, Inventory inventory, RegistryFriendlyByteBuf regist if (index < rackStartIndex) { // We are in Player Inventory (0-35) // Try to move ProcessorUnits to the Rack - if (slotStack.getItem() instanceof ProcessorUnitItem) { + if (slotStack.getItem() instanceof ServerItem) { if (!this.moveItemStackTo(slotStack, rackStartIndex, rackEndIndex, false)) { return ItemStack.EMPTY; } diff --git a/src/main/java/dev/gacbl/logicore/core/CoreCycleProviderBlockEntity.java b/src/main/java/dev/gacbl/logicore/core/CoreCycleProviderBlockEntity.java index e34be2a..9b1a248 100644 --- a/src/main/java/dev/gacbl/logicore/core/CoreCycleProviderBlockEntity.java +++ b/src/main/java/dev/gacbl/logicore/core/CoreCycleProviderBlockEntity.java @@ -5,7 +5,6 @@ import dev.gacbl.logicore.api.computation.ICycleStorage; import dev.gacbl.logicore.api.multiblock.AbstractSealedController; import dev.gacbl.logicore.blocks.serverrack.ServerRackBlock; -import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; import dev.gacbl.logicore.network.PacketHandler; import dev.gacbl.logicore.network.payload.SyncCycleDataPayload; @@ -28,20 +27,20 @@ import java.util.Objects; public abstract class CoreCycleProviderBlockEntity extends BlockEntity implements ICycleProvider { - private int BASE_CYCLE_GENERATION; - private int CYCLES_PER_PROCESSOR; - private int FE_PER_CYCLE; + protected int BASE_CYCLE_GENERATION; + protected int CYCLES_PER_PROCESSOR; + protected int FE_PER_CYCLE; - private EnergyStorage energyStorage; - private CycleStorage cycleStorage; + protected EnergyStorage energyStorage; + protected CycleStorage cycleStorage; public boolean isGenerating = false; public BlockPos dataCenterController = null; - private boolean hasDataCenterBoost = false; + protected boolean hasDataCenterBoost = false; - private int dataCenterBoost = 0; + protected int dataCenterBoost = 0; protected int cachedProcessorCount = 0; @@ -170,11 +169,11 @@ public static void serverTick(Level level, BlockPos pos, BlockState state, CoreC } be.generateCycles(); - if (state.hasProperty(ServerRackModule.GENERATING)) { - boolean currentGeneratingState = state.getValue(ServerRackModule.GENERATING); + if (state.hasProperty(ServerRackBlock.GENERATING)) { + boolean currentGeneratingState = state.getValue(ServerRackBlock.GENERATING); if (be.isGenerating != currentGeneratingState) { - level.setBlock(pos, state.setValue(ServerRackModule.GENERATING, be.isGenerating), 3); + level.setBlock(pos, state.setValue(ServerRackBlock.GENERATING, be.isGenerating), 3); if (state.hasProperty(ServerRackBlock.HALF)) { updateOtherHalf(level, pos, state, be.isGenerating); } @@ -189,12 +188,16 @@ private static void updateOtherHalf(Level level, BlockPos pos, BlockState state, BlockState otherState = level.getBlockState(otherPos); if (otherState.getBlock() instanceof ServerRackBlock) { - level.setBlock(otherPos, otherState.setValue(ServerRackModule.GENERATING, isWorking), 3); + level.setBlock(otherPos, otherState.setValue(ServerRackBlock.GENERATING, isWorking), 3); } } + protected boolean canGenerate() { + return true; + } + private void generateCycles() { - if (this.level == null || this.level.isClientSide) { + if (this.level == null || this.level.isClientSide || !canGenerate()) { isGenerating = false; return; } @@ -220,7 +223,7 @@ private void generateCycles() { long feCost = Math.min(cyclesToGenerate * FE_PER_CYCLE, 99_999L); if (hasDataCenterBoost) { - cyclesToGenerate += 100; + cyclesToGenerate += dataCenterBoost; } boolean prevGenerating = isGenerating; diff --git a/src/main/java/dev/gacbl/logicore/data/CreativeTabModule.java b/src/main/java/dev/gacbl/logicore/data/CreativeTabModule.java index 8320b25..3546853 100644 --- a/src/main/java/dev/gacbl/logicore/data/CreativeTabModule.java +++ b/src/main/java/dev/gacbl/logicore/data/CreativeTabModule.java @@ -15,6 +15,7 @@ import dev.gacbl.logicore.blocks.serverrack.ServerRackModule; import dev.gacbl.logicore.items.pickaxe.CyclePickModule; import dev.gacbl.logicore.items.processorunit.ProcessorUnitModule; +import dev.gacbl.logicore.items.server.ServerModule; import dev.gacbl.logicore.items.stack_upgrade.StackUpgradeModule; import dev.gacbl.logicore.items.wrench.WrenchModule; import net.minecraft.core.registries.Registries; @@ -49,11 +50,13 @@ public class CreativeTabModule { output.accept(BatteryModule.BATTERY_SMALL.get()); output.accept(BatteryModule.BATTERY_MEDIUM.get()); output.accept(BatteryModule.BATTERY_LARGE.get()); + output.accept(BatteryModule.BATTERY_CREATIVE.get()); output.accept(StackUpgradeModule.STACK_UPGRADE.get()); output.accept(ResearchStationModule.RESEARCH_STATION.get()); output.accept(CyclePickModule.CYCLE_PICK.get()); output.accept(RepairStationModule.REPAIR_STATION.get()); output.accept(RecyclerModule.RECYCLER.get()); + output.accept(ServerModule.SERVER.get()); }) .build()); diff --git a/src/main/java/dev/gacbl/logicore/data/ModBlockTagProvider.java b/src/main/java/dev/gacbl/logicore/data/ModBlockTagProvider.java index 5963e57..9ad22da 100644 --- a/src/main/java/dev/gacbl/logicore/data/ModBlockTagProvider.java +++ b/src/main/java/dev/gacbl/logicore/data/ModBlockTagProvider.java @@ -33,13 +33,13 @@ public ModBlockTagProvider(PackOutput output, CompletableFuture batteryItems = BatteryModule.ITEMS.getEntries().stream() .map(Holder::value) @@ -89,6 +93,8 @@ protected void buildRecipes(@NotNull RecipeOutput recipeOutput) { index.set(0); BatteryModule.BLOCKS.getEntries().forEach(blockHolder -> { + if (blockHolder.get() instanceof BatteryBlock batteryBlock && batteryBlock.getTier() == BatteryTier.CREATIVE) + return; int i = index.getAndIncrement(); ItemLike coreIngredient = (i == 0) ? ProcessorUnitModule.PROCESSOR_UNIT_BASIC.get() : batteryItems.get(i - 1); Item gold = (i == 0) ? Items.GOLD_INGOT : (i == 2) ? Items.DIAMOND_BLOCK : Items.GOLD_BLOCK; diff --git a/src/main/java/dev/gacbl/logicore/items/processorunit/ProcessorUnitModule.java b/src/main/java/dev/gacbl/logicore/items/processorunit/ProcessorUnitModule.java index 86efc6e..5ef80b2 100644 --- a/src/main/java/dev/gacbl/logicore/items/processorunit/ProcessorUnitModule.java +++ b/src/main/java/dev/gacbl/logicore/items/processorunit/ProcessorUnitModule.java @@ -4,14 +4,15 @@ import net.minecraft.core.registries.Registries; import net.minecraft.world.item.Item; import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; public class ProcessorUnitModule { public static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, LogiCore.MOD_ID); - public static final net.neoforged.neoforge.registries.DeferredHolder PROCESSOR_UNIT_BASIC = ITEMS.register("processor_unit_basic", () -> new ProcessorUnitItem(ProcessorUnitTier.BASIC)); - public static final net.neoforged.neoforge.registries.DeferredHolder PROCESSOR_UNIT_ADVANCE = ITEMS.register("processor_unit_advance", () -> new ProcessorUnitItem(ProcessorUnitTier.ADVANCED)); - public static final net.neoforged.neoforge.registries.DeferredHolder PROCESSOR_UNIT_ULTIMATE = ITEMS.register("processor_unit_ultimate", () -> new ProcessorUnitItem(ProcessorUnitTier.ULTIMATE)); + public static final DeferredHolder PROCESSOR_UNIT_BASIC = ITEMS.register("processor_unit_basic", () -> new ProcessorUnitItem(ProcessorUnitTier.BASIC)); + public static final DeferredHolder PROCESSOR_UNIT_ADVANCE = ITEMS.register("processor_unit_advance", () -> new ProcessorUnitItem(ProcessorUnitTier.ADVANCED)); + public static final DeferredHolder PROCESSOR_UNIT_ULTIMATE = ITEMS.register("processor_unit_ultimate", () -> new ProcessorUnitItem(ProcessorUnitTier.ULTIMATE)); public static void register(IEventBus modEventBus) { ITEMS.register(modEventBus); diff --git a/src/main/java/dev/gacbl/logicore/items/server/ServerItem.java b/src/main/java/dev/gacbl/logicore/items/server/ServerItem.java new file mode 100644 index 0000000..4c85f27 --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/items/server/ServerItem.java @@ -0,0 +1,86 @@ +package dev.gacbl.logicore.items.server; + +import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; +import dev.gacbl.logicore.items.processorunit.ProcessorUnitModule; +import dev.gacbl.logicore.items.processorunit.ProcessorUnitTier; +import dev.gacbl.logicore.items.server.ui.ServerMenu; +import net.minecraft.core.NonNullList; +import net.minecraft.core.component.DataComponents; +import net.minecraft.data.recipes.RecipeCategory; +import net.minecraft.data.recipes.ShapedRecipeBuilder; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.ItemTags; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.ItemContainerContents; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.List; + +public class ServerItem extends Item { + public ServerItem() { + super(new Item.Properties() + .stacksTo(1) + .component(DataComponents.CONTAINER, ItemContainerContents.fromItems(NonNullList.withSize(9, ItemStack.EMPTY))) + ); + } + + @Override + public @NotNull InteractionResultHolder use(@NotNull Level level, @NotNull Player player, @NotNull InteractionHand usedHand) { + ItemStack stack = player.getItemInHand(usedHand); + if (!level.isClientSide) { + player.openMenu(new SimpleMenuProvider( + (windowId, playerInventory, playerEntity) -> new ServerMenu(windowId, playerInventory, stack), + Component.translatable("item.logicore.server") + )); + } + return InteractionResultHolder.success(stack); + } + + public static ShapedRecipeBuilder getRecipe() { + return ShapedRecipeBuilder.shaped(RecipeCategory.REDSTONE, ServerModule.SERVER.get()) + .pattern("IRI") + .pattern("QPQ") + .pattern("GRG") + .define('Q', ItemTags.create(ResourceLocation.fromNamespaceAndPath("c", "gems/quartz"))) + .define('R', ItemTags.create(ResourceLocation.fromNamespaceAndPath("c", "dusts/redstone"))) + .define('G', Items.GOLD_INGOT) + .define('I', Items.IRON_INGOT) + .define('P', ProcessorUnitModule.PROCESSOR_UNIT_BASIC.get()); + } + + @Override + public void appendHoverText(@NotNull ItemStack stack, @NotNull TooltipContext context, @NotNull List tooltipComponents, @NotNull TooltipFlag tooltipFlag) { + super.appendHoverText(stack, context, tooltipComponents, tooltipFlag); + + ItemContainerContents contents = stack.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY); + HashMap cpuCount = new HashMap<>(); + for (int i = 0; i < contents.getSlots(); i++) { + Item it = contents.getStackInSlot(i).getItem(); + if (it instanceof ProcessorUnitItem item) { + cpuCount.put(item.tier.name, cpuCount.getOrDefault(item.tier.name, 0) + 1); + } + } + + if (cpuCount.containsKey(ProcessorUnitTier.BASIC.name)) { + tooltipComponents.add(Component.translatable("cpu.tooltip.logicore.basic_tier_count", cpuCount.get(ProcessorUnitTier.BASIC.name))); + } + + if (cpuCount.containsKey(ProcessorUnitTier.ADVANCED.name)) { + tooltipComponents.add(Component.translatable("cpu.tooltip.logicore.advance_tier_count", cpuCount.get(ProcessorUnitTier.ADVANCED.name))); + } + + if (cpuCount.containsKey(ProcessorUnitTier.ULTIMATE.name)) { + tooltipComponents.add(Component.translatable("cpu.tooltip.logicore.ultimate_tier_count", cpuCount.get(ProcessorUnitTier.ULTIMATE.name))); + } + } +} diff --git a/src/main/java/dev/gacbl/logicore/items/server/ServerModule.java b/src/main/java/dev/gacbl/logicore/items/server/ServerModule.java new file mode 100644 index 0000000..3b2a6af --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/items/server/ServerModule.java @@ -0,0 +1,25 @@ +package dev.gacbl.logicore.items.server; + +import dev.gacbl.logicore.LogiCore; +import dev.gacbl.logicore.items.server.ui.ServerMenu; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.item.Item; +import net.neoforged.bus.api.IEventBus; +import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; +import net.neoforged.neoforge.registries.DeferredHolder; +import net.neoforged.neoforge.registries.DeferredRegister; + +public class ServerModule { + public static final DeferredRegister ITEMS = DeferredRegister.create(Registries.ITEM, LogiCore.MOD_ID); + public static final DeferredRegister> MENUS = DeferredRegister.create(BuiltInRegistries.MENU, LogiCore.MOD_ID); + + public static final DeferredHolder SERVER = ITEMS.register("server", ServerItem::new); + public static final DeferredHolder, MenuType> SERVER_MENU = MENUS.register("server_menu", () -> IMenuTypeExtension.create((windowId, inv, data) -> new ServerMenu(windowId, inv, inv.player.getMainHandItem()))); + + public static void register(IEventBus modEventBus) { + ITEMS.register(modEventBus); + MENUS.register(modEventBus); + } +} diff --git a/src/main/java/dev/gacbl/logicore/items/server/ui/ServerMenu.java b/src/main/java/dev/gacbl/logicore/items/server/ui/ServerMenu.java new file mode 100644 index 0000000..b104867 --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/items/server/ui/ServerMenu.java @@ -0,0 +1,58 @@ +package dev.gacbl.logicore.items.server.ui; + +import dev.gacbl.logicore.core.ui.MyAbstractContainerMenu; +import dev.gacbl.logicore.items.processorunit.ProcessorUnitItem; +import dev.gacbl.logicore.items.server.ServerModule; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.SimpleContainer; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.SimpleContainerData; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.component.ItemContainerContents; +import org.jetbrains.annotations.NotNull; + +public class ServerMenu extends MyAbstractContainerMenu { + private final ItemStack serverStack; + private final SimpleContainer container; + + public ServerMenu(int containerId, Inventory playerInventory, ItemStack stack) { + super(ServerModule.SERVER_MENU.get(), containerId, playerInventory, null, new SimpleContainerData(2)); + this.serverStack = stack; + this.TE_INVENTORY_SLOT_COUNT = 9; + + ItemContainerContents contents = stack.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY); + this.container = new SimpleContainer(TE_INVENTORY_SLOT_COUNT); + contents.copyInto(container.getItems()); + + for (int i = 0; i < TE_INVENTORY_SLOT_COUNT; i++) { + this.addSlot(new Slot(container, i, 36 + i * 18, 89) { + @Override + public void setChanged() { + super.setChanged(); + saveToItem(); + } + + @Override + public boolean mayPlace(@NotNull ItemStack stack) { + return stack.getItem() instanceof ProcessorUnitItem; + } + + @Override + public int getMaxStackSize(@NotNull ItemStack stack) { + return 1; + } + }); + } + } + + private void saveToItem() { + serverStack.set(DataComponents.CONTAINER, ItemContainerContents.fromItems(container.getItems())); + } + + @Override + public boolean stillValid(Player player) { + return player.getMainHandItem() == serverStack; + } +} diff --git a/src/main/java/dev/gacbl/logicore/items/server/ui/ServerScreen.java b/src/main/java/dev/gacbl/logicore/items/server/ui/ServerScreen.java new file mode 100644 index 0000000..21c462b --- /dev/null +++ b/src/main/java/dev/gacbl/logicore/items/server/ui/ServerScreen.java @@ -0,0 +1,15 @@ +package dev.gacbl.logicore.items.server.ui; + +import dev.gacbl.logicore.core.ui.MyAbstractContainerScreen; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Inventory; + +public class ServerScreen extends MyAbstractContainerScreen { + public ServerScreen(ServerMenu menu, Inventory playerInventory, Component title) { + super(menu, playerInventory, title); + this.titleLabelX = leftPos + 90; + this.titleLabelY = topPos + 14; + setTexture("textures/gui/server_ui.png"); + renderInventoryLabel = false; + } +} diff --git a/src/main/resources/assets/logicore/animations/block/server_rack.animation.json b/src/main/resources/assets/logicore/animations/block/server_rack.animation.json new file mode 100644 index 0000000..770d101 --- /dev/null +++ b/src/main/resources/assets/logicore/animations/block/server_rack.animation.json @@ -0,0 +1,53 @@ +{ + "format_version": "1.8.0", + "animations": { + "idle": { + "loop": true + }, + "door_open": { + "loop": "hold_on_last_frame", + "animation_length": 1, + "bones": { + "door": { + "rotation": { + "0.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + }, + "1.0": { + "post": { + "vector": [0, -90, 0] + }, + "lerp_mode": "catmullrom" + } + } + } + } + }, + "door_close": { + "loop": "hold_on_last_frame", + "animation_length": 1, + "bones": { + "door": { + "rotation": { + "0.0": { + "post": { + "vector": [0, -90, 0] + }, + "lerp_mode": "catmullrom" + }, + "1.0": { + "post": { + "vector": [0, 0, 0] + }, + "lerp_mode": "catmullrom" + } + } + } + } + } + }, + "geckolib_format_version": 2 +} diff --git a/src/main/resources/assets/logicore/blockstates/creative_battery.json b/src/main/resources/assets/logicore/blockstates/creative_battery.json new file mode 100644 index 0000000..77f192c --- /dev/null +++ b/src/main/resources/assets/logicore/blockstates/creative_battery.json @@ -0,0 +1,8 @@ +{ + "variants": { + "facing=north": {"model": "logicore:block/creative_battery"}, + "facing=south": {"model": "logicore:block/creative_battery", "y": 180}, + "facing=west": {"model": "logicore:block/creative_battery", "y": 270}, + "facing=east": {"model": "logicore:block/creative_battery", "y": 90} + } +} diff --git a/src/main/resources/assets/logicore/blockstates/server_rack.json b/src/main/resources/assets/logicore/blockstates/server_rack.json index 046aeb1..2cd1e65 100644 --- a/src/main/resources/assets/logicore/blockstates/server_rack.json +++ b/src/main/resources/assets/logicore/blockstates/server_rack.json @@ -1,64 +1,22 @@ { "variants": { - "facing=north,half=lower,generating=false": { - "model": "logicore:block/server_rack_bottom" - }, - "facing=south,half=lower,generating=false": { - "model": "logicore:block/server_rack_bottom", - "y": 180 - }, - "facing=west,half=lower,generating=false": { - "model": "logicore:block/server_rack_bottom", - "y": 270 - }, - "facing=east,half=lower,generating=false": { - "model": "logicore:block/server_rack_bottom", - "y": 90 - }, - "facing=north,half=upper,generating=false": { - "model": "logicore:block/server_rack_top" - }, - "facing=south,half=upper,generating=false": { - "model": "logicore:block/server_rack_top", - "y": 180 - }, - "facing=west,half=upper,generating=false": { - "model": "logicore:block/server_rack_top", - "y": 270 - }, - "facing=east,half=upper,generating=false": { - "model": "logicore:block/server_rack_top", - "y": 90 + "facing=north,half=lower": { + "model": "logicore:block/server_rack" }, - "facing=north,half=lower,generating=true": { - "model": "logicore:block/server_rack_bottom_on" - }, - "facing=south,half=lower,generating=true": { - "model": "logicore:block/server_rack_bottom_on", + "facing=south,half=lower": { + "model": "logicore:block/server_rack", "y": 180 }, - "facing=west,half=lower,generating=true": { - "model": "logicore:block/server_rack_bottom_on", + "facing=west,half=lower": { + "model": "logicore:block/server_rack", "y": 270 }, - "facing=east,half=lower,generating=true": { - "model": "logicore:block/server_rack_bottom_on", + "facing=east,half=lower": { + "model": "logicore:block/server_rack", "y": 90 }, - "facing=north,half=upper,generating=true": { - "model": "logicore:block/server_rack_top_on" - }, - "facing=south,half=upper,generating=true": { - "model": "logicore:block/server_rack_top_on", - "y": 180 - }, - "facing=west,half=upper,generating=true": { - "model": "logicore:block/server_rack_top_on", - "y": 270 - }, - "facing=east,half=upper,generating=true": { - "model": "logicore:block/server_rack_top_on", - "y": 90 + "": { + "model": "logicore:block/server_rack" } } } diff --git a/src/main/resources/assets/logicore/geo/block/server_rack.geo.json b/src/main/resources/assets/logicore/geo/block/server_rack.geo.json new file mode 100644 index 0000000..1677c5f --- /dev/null +++ b/src/main/resources/assets/logicore/geo/block/server_rack.geo.json @@ -0,0 +1,221 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.server_rack", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 3, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { + "name": "beams", + "pivot": [7.5, 17, 7.5], + "cubes": [ + { + "origin": [7, 1, 7], + "size": [1, 31, 1], + "uv": { + "north": {"uv": [4, 60], "uv_size": [1, 30]}, + "east": {"uv": [5, 60], "uv_size": [1, 30]}, + "south": {"uv": [6, 60], "uv_size": [1, 30]}, + "west": {"uv": [7, 60], "uv_size": [1, 30]}, + "up": {"uv": [54, 61], "uv_size": [1, 1]}, + "down": {"uv": [55, 62], "uv_size": [1, -1]} + } + }, + { + "origin": [7, 1, -8], + "size": [1, 31, 1], + "uv": { + "north": {"uv": [0, 60], "uv_size": [1, 30]}, + "east": {"uv": [1, 60], "uv_size": [1, 30]}, + "south": {"uv": [2, 60], "uv_size": [1, 30]}, + "west": {"uv": [3, 60], "uv_size": [1, 30]}, + "up": {"uv": [54, 60], "uv_size": [1, 1]}, + "down": {"uv": [55, 61], "uv_size": [1, -1]} + } + }, + { + "origin": [-8, 1, -8], + "size": [1, 31, 1], + "uv": { + "north": {"uv": [8, 60], "uv_size": [1, 30]}, + "east": {"uv": [9, 60], "uv_size": [1, 30]}, + "south": {"uv": [10, 60], "uv_size": [1, 30]}, + "west": {"uv": [11, 60], "uv_size": [1, 30]}, + "up": {"uv": [54, 62], "uv_size": [1, 1]}, + "down": {"uv": [55, 63], "uv_size": [1, -1]} + } + }, + { + "origin": [-8, 1, 7], + "size": [1, 31, 1], + "uv": { + "north": {"uv": [12, 60], "uv_size": [1, 30]}, + "east": {"uv": [13, 60], "uv_size": [1, 30]}, + "south": {"uv": [14, 60], "uv_size": [1, 30]}, + "west": {"uv": [15, 60], "uv_size": [1, 30]}, + "up": {"uv": [54, 63], "uv_size": [1, 1]}, + "down": {"uv": [55, 64], "uv_size": [1, -1]} + } + } + ] + }, + { + "name": "floor_ceiling", + "pivot": [8, 1, -8], + "cubes": [ + { + "origin": [-8, 1, -8], + "size": [16, 0, 16], + "inflate": 0.02, + "uv": { + "north": {"uv": [22, 60], "uv_size": [16, 1]}, + "east": {"uv": [38, 60], "uv_size": [16, 1]}, + "south": {"uv": [22, 61], "uv_size": [16, 1]}, + "west": {"uv": [38, 61], "uv_size": [16, 1]}, + "up": {"uv": [56, 0], "uv_size": [16, 16]}, + "down": {"uv": [56, 32], "uv_size": [16, -16]} + } + }, + { + "origin": [-8, 32, -8], + "size": [16, 0, 16], + "inflate": 0.02, + "uv": { + "north": {"uv": [22, 62], "uv_size": [16, 1]}, + "east": {"uv": [38, 62], "uv_size": [16, 1]}, + "south": {"uv": [22, 63], "uv_size": [16, 1]}, + "west": {"uv": [38, 63], "uv_size": [16, 1]}, + "up": {"uv": [56, 32], "uv_size": [16, 16]}, + "down": {"uv": [56, 64], "uv_size": [16, -16]} + } + } + ] + }, + { + "name": "wall_panels", + "pivot": [0, 16, 8], + "cubes": [ + { + "origin": [-7, 1, 7], + "size": [14, 31, 1], + "uv": { + "north": {"uv": [0, 0], "uv_size": [14, 30]}, + "east": {"uv": [16, 60], "uv_size": [1, 30]}, + "south": {"uv": [14, 0], "uv_size": [14, 30]}, + "west": {"uv": [17, 60], "uv_size": [1, 30]}, + "up": {"uv": [22, 64], "uv_size": [14, 1]}, + "down": {"uv": [36, 65], "uv_size": [14, -1]} + } + }, + { + "origin": [1, 1, -1], + "size": [14, 31, 1], + "pivot": [8, 16, 0], + "rotation": [0, 90, 0], + "uv": { + "north": {"uv": [28, 0], "uv_size": [14, 30]}, + "east": {"uv": [18, 60], "uv_size": [1, 30]}, + "south": {"uv": [0, 30], "uv_size": [14, 30]}, + "west": {"uv": [19, 60], "uv_size": [1, 30]}, + "up": {"uv": [50, 64], "uv_size": [14, 1]}, + "down": {"uv": [64, 65], "uv_size": [14, -1]} + } + }, + { + "origin": [-14, 1, -1], + "size": [14, 31, 1], + "pivot": [-7, 16, 0], + "rotation": [0, 90, 0], + "uv": { + "north": {"uv": [14, 30], "uv_size": [14, 30]}, + "east": {"uv": [20, 60], "uv_size": [1, 30]}, + "south": {"uv": [28, 0], "uv_size": [14, 30]}, + "west": {"uv": [21, 60], "uv_size": [1, 30]}, + "up": {"uv": [22, 65], "uv_size": [14, 1]}, + "down": {"uv": [36, 66], "uv_size": [14, -1]} + } + } + ] + }, + { + "name": "door", + "pivot": [7, 16, -8], + "cubes": [ + { + "origin": [-7, 1, -8], + "size": [14, 31, 0], + "uv": { + "north": {"uv": [42, 0], "uv_size": [14, 30]}, + "east": {"uv": [0, 0], "uv_size": [0, 30]}, + "south": {"uv": [56, 0], "uv_size": [-14, 30]}, + "west": {"uv": [0, 0], "uv_size": [0, 30]}, + "up": {"uv": [0, 0], "uv_size": [14, 0]}, + "down": {"uv": [0, 0], "uv_size": [14, 0]} + } + } + ] + }, + { + "name": "legs", + "pivot": [6.5, 0.5, 6.5], + "cubes": [ + { + "origin": [6, 0, 6], + "size": [1, 1, 1], + "uv": { + "north": {"uv": [1, 1], "uv_size": [1, 1]}, + "east": {"uv": [1, 1], "uv_size": [1, 1]}, + "south": {"uv": [0, 1], "uv_size": [1, 1]}, + "west": {"uv": [0, 1], "uv_size": [1, 1]}, + "up": {"uv": [1, 1], "uv_size": [-1, -1]}, + "down": {"uv": [1, 2], "uv_size": [-1, -1]} + } + }, + { + "origin": [6, 0, -7], + "size": [1, 1, 1], + "uv": { + "north": {"uv": [1, 1], "uv_size": [1, 1]}, + "east": {"uv": [1, 1], "uv_size": [1, 1]}, + "south": {"uv": [0, 1], "uv_size": [1, 1]}, + "west": {"uv": [0, 1], "uv_size": [1, 1]}, + "up": {"uv": [1, 1], "uv_size": [-1, -1]}, + "down": {"uv": [1, 2], "uv_size": [-1, -1]} + } + }, + { + "origin": [-7, 0, -7], + "size": [1, 1, 1], + "uv": { + "north": {"uv": [1, 1], "uv_size": [1, 1]}, + "east": {"uv": [1, 1], "uv_size": [1, 1]}, + "south": {"uv": [0, 1], "uv_size": [1, 1]}, + "west": {"uv": [0, 1], "uv_size": [1, 1]}, + "up": {"uv": [1, 1], "uv_size": [-1, -1]}, + "down": {"uv": [1, 2], "uv_size": [-1, -1]} + } + }, + { + "origin": [-7, 0, 6], + "size": [1, 1, 1], + "uv": { + "north": {"uv": [1, 1], "uv_size": [1, 1]}, + "east": {"uv": [1, 1], "uv_size": [1, 1]}, + "south": {"uv": [0, 1], "uv_size": [1, 1]}, + "west": {"uv": [0, 1], "uv_size": [1, 1]}, + "up": {"uv": [1, 1], "uv_size": [-1, -1]}, + "down": {"uv": [1, 2], "uv_size": [-1, -1]} + } + } + ] + } + ] + } + ] +} diff --git a/src/main/resources/assets/logicore/lang/en_us.json b/src/main/resources/assets/logicore/lang/en_us.json index 3d01c91..fe600c9 100644 --- a/src/main/resources/assets/logicore/lang/en_us.json +++ b/src/main/resources/assets/logicore/lang/en_us.json @@ -7,6 +7,7 @@ "block.logicore.datacenter_port": "Datacenter port", "block.logicore.drone_bay": "Drone bay", "block.logicore.generator": "Generator", + "block.logicore.creative_battery": "Creative battery", "block.logicore.large_battery": "Large battery", "block.logicore.medium_battery": "Medium battery", "block.logicore.recycler": "Recycler", @@ -53,6 +54,7 @@ "sounds.logicore.datacenter.ambient": "Datacenter hum", "tooltip.item.logicore.stack_upgrade": "Increases number of compiled items and cost by 4", "tooltip.logicore.battery_capacity": "Max capacity: %s FE", + "tooltip.logicore.infinite": "Infinite", "tooltip.logicore.battery_transfer_rate": "Max I/O: %s FE", "tooltip.logicore.compiler.stack_upgrades_max": "Stack upgrades: %s / %s", "tooltip.logicore.cpus": "Installed CPUs: %s / %s", @@ -82,5 +84,9 @@ "ui.tooltip.logicore.cycles_modifier": "Modifier:", "ui.tooltip.logicore.cycles_produced": "Produced:", "ui.tooltip.logicore.cycles_storage": "%s / %s", - "ui.tooltip.logicore.fe_per_tick": "Fe per tick:" + "ui.tooltip.logicore.fe_per_tick": "Fe per tick:", + "item.logicore.server": "Server", + "cpu.tooltip.logicore.basic_tier_count": "§6Basic CPUs: %d", + "cpu.tooltip.logicore.advance_tier_count": "§2Advance CPUs: %d", + "cpu.tooltip.logicore.ultimate_tier_count": "§5Ultimate CPUs: %d" } diff --git a/src/main/resources/assets/logicore/models/block/creative_battery.json b/src/main/resources/assets/logicore/models/block/creative_battery.json new file mode 100644 index 0000000..ac6262a --- /dev/null +++ b/src/main/resources/assets/logicore/models/block/creative_battery.json @@ -0,0 +1,7 @@ +{ + "parent": "logicore:block/battery_base", + "textures": { + "end": "logicore:block/battery_top_bottom", + "side": "logicore:block/creative_battery" + } +} diff --git a/src/main/resources/assets/logicore/models/block/server_rack.json b/src/main/resources/assets/logicore/models/block/server_rack.json index 99f355c..53560d4 100644 --- a/src/main/resources/assets/logicore/models/block/server_rack.json +++ b/src/main/resources/assets/logicore/models/block/server_rack.json @@ -1,71 +1,110 @@ { - "texture_size": [16, 32], + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "texture_size": [32, 32], "textures": { - "particle": "logicore:block/server_rack_front", - "side": "logicore:block/server_rack_side", - "top": "logicore:block/server_rack_top", - "front": "logicore:block/server_rack_front", - "front2": "logicore:block/server_rack_front2", - "back": "logicore:block/server_rack_back", - "particles": "logicore:block/server_rack_sides_texture" + "0": "logicore:item/server_rack_item", + "particle": "logicore:item/server_rack_item" }, "elements": [ - { - "from": [0, 0, 0], - "to": [16, 32, 16], - "faces": { - "north": {"uv": [0, 0, 16, 16],"texture": "#front"}, - "east": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, - "down": {"uv": [0, 0, 16, 16], "texture": "#top"} - } - } + { + "from": [4, 1, 4], + "to": [12, 16, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8.5, 12]}, + "faces": { + "north": {"uv": [0, 0, 4, 7.5], "texture": "#0"}, + "east": {"uv": [4, 0, 8, 7.5], "texture": "#0"}, + "south": {"uv": [0, 7.5, 4, 15], "texture": "#0"}, + "west": {"uv": [4, 7.5, 8, 15], "texture": "#0"}, + "up": {"uv": [12, 4, 8, 0], "texture": "#0"}, + "down": {"uv": [12, 4, 8, 8], "texture": "#0"} + } + }, + { + "from": [5, 0, 5], + "to": [6, 1, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [5.5, 0.5, 5.5]}, + "faces": { + "north": {"uv": [8, 8, 8.5, 8.5], "texture": "#0"}, + "east": {"uv": [8, 8.5, 8.5, 9], "texture": "#0"}, + "south": {"uv": [8.5, 8, 9, 8.5], "texture": "#0"}, + "west": {"uv": [8.5, 8.5, 9, 9], "texture": "#0"}, + "up": {"uv": [8.5, 9.5, 8, 9], "texture": "#0"}, + "down": {"uv": [9.5, 8, 9, 8.5], "texture": "#0"} + } + }, + { + "from": [5, 0, 10], + "to": [6, 1, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [5.5, 0.5, 10.5]}, + "faces": { + "north": {"uv": [8.5, 9, 9, 9.5], "texture": "#0"}, + "east": {"uv": [9, 8.5, 9.5, 9], "texture": "#0"}, + "south": {"uv": [9, 9, 9.5, 9.5], "texture": "#0"}, + "west": {"uv": [8, 9.5, 8.5, 10], "texture": "#0"}, + "up": {"uv": [10, 8.5, 9.5, 8], "texture": "#0"}, + "down": {"uv": [9, 9.5, 8.5, 10], "texture": "#0"} + } + }, + { + "from": [10, 0, 10], + "to": [11, 1, 11], + "rotation": {"angle": 0, "axis": "y", "origin": [10.5, 0.5, 10.5]}, + "faces": { + "north": {"uv": [9.5, 8.5, 10, 9], "texture": "#0"}, + "east": {"uv": [9, 9.5, 9.5, 10], "texture": "#0"}, + "south": {"uv": [9.5, 9, 10, 9.5], "texture": "#0"}, + "west": {"uv": [9.5, 9.5, 10, 10], "texture": "#0"}, + "up": {"uv": [8.5, 10.5, 8, 10], "texture": "#0"}, + "down": {"uv": [10.5, 8, 10, 8.5], "texture": "#0"} + } + }, + { + "from": [10, 0, 5], + "to": [11, 1, 6], + "rotation": {"angle": 0, "axis": "y", "origin": [10.5, 0.5, 5.5]}, + "faces": { + "north": {"uv": [8.5, 10, 9, 10.5], "texture": "#0"}, + "east": {"uv": [10, 8.5, 10.5, 9], "texture": "#0"}, + "south": {"uv": [9, 10, 9.5, 10.5], "texture": "#0"}, + "west": {"uv": [10, 9, 10.5, 9.5], "texture": "#0"}, + "up": {"uv": [10, 10.5, 9.5, 10], "texture": "#0"}, + "down": {"uv": [10.5, 9.5, 10, 10], "texture": "#0"} + } + } ], "display": { "thirdperson_righthand": { - "scale": [0.2, 0.2, 0.2] + "rotation": [0, -180, 0], + "translation": [0, 2.5, 0], + "scale": [0.5, 0.5, 0.5] }, "thirdperson_lefthand": { - "scale": [0.2, 0.2, 0.2] + "rotation": [0, -180, 0], + "translation": [0, 2.5, 0], + "scale": [0.5, 0.5, 0.5] }, "firstperson_righthand": { "rotation": [0, -180, 0], - "scale": [0.2, 0.2, 0.2] + "translation": [0, 2.5, 0], + "scale": [0.5, 0.5, 0.5] }, "firstperson_lefthand": { "rotation": [0, -180, 0], - "scale": [0.2, 0.2, 0.2] + "translation": [0, 2.5, 0], + "scale": [0.5, 0.5, 0.5] }, "ground": { - "scale": [0.2, 0.2, 0.2] + "scale": [0.25, 0.25, 0.25] }, "gui": { - "rotation": [0, -175, 0], - "translation": [0, -3.25, 0], - "scale": [0.4, 0.4, 0.4] - }, - "head": { - "translation": [0, 10, 0], - "scale": [0.5, 0.5, 0.5] - }, - "fixed": { - "rotation": [0, -1, 0], - "translation": [0, -3.5, 0], - "scale": [0.5, 0.5, 0.5] + "rotation": [32, -141, 0], + "translation": [0, -0.5, -3.25], + "scale": [0.7, 0.7, 0.7] }, "on_shelf": { - "rotation": [0, -180, 0], - "scale": [0.5, 0.5, 0.5] - } - }, - "groups": [ - { - "name": "rack", - "origin": [0, 0, 0], - "color": 0, - "children": [0] + "rotation": [0, -180, 0] } - ] + } } diff --git a/src/main/resources/assets/logicore/models/block/server_rack_bottom.json b/src/main/resources/assets/logicore/models/block/server_rack_bottom.json deleted file mode 100644 index 2ca8c8a..0000000 --- a/src/main/resources/assets/logicore/models/block/server_rack_bottom.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "texture_size": [16, 16], - "textures": { - "particle": "logicore:block/server_rack_front_bottom", - "side": "logicore:block/server_rack_side_bottom", - "top": "logicore:block/server_rack_top", - "front": "logicore:block/server_rack_front_bottom", - "back": "logicore:block/server_rack_back_bottom", - "particles": "logicore:block/server_rack_side_bottom" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": {"uv": [0, 0, 16, 16], "texture": "#front"}, - "east": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, - "down": {"uv": [0, 0, 16, 16], "texture": "#top"} - } - } - ] -} diff --git a/src/main/resources/assets/logicore/models/block/server_rack_bottom_on.json b/src/main/resources/assets/logicore/models/block/server_rack_bottom_on.json deleted file mode 100644 index 5a0d724..0000000 --- a/src/main/resources/assets/logicore/models/block/server_rack_bottom_on.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "logicore:block/server_rack_bottom", - "textures": { - "front": "logicore:block/server_rack_front_bottom_on" - } -} diff --git a/src/main/resources/assets/logicore/models/block/server_rack_top.json b/src/main/resources/assets/logicore/models/block/server_rack_top.json deleted file mode 100644 index 0612e62..0000000 --- a/src/main/resources/assets/logicore/models/block/server_rack_top.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "texture_size": [16, 16], - "textures": { - "particle": "logicore:block/server_rack_front_top", - "side": "logicore:block/server_rack_side_top", - "top": "logicore:block/server_rack_top", - "front": "logicore:block/server_rack_front_top", - "back": "logicore:block/server_rack_back_top", - "particles": "logicore:block/server_rack_side_top" - }, - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 16, 16], - "faces": { - "north": {"uv": [0, 0, 16, 16], "texture": "#front"}, - "east": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "south": {"uv": [0, 0, 16, 16], "texture": "#back"}, - "west": {"uv": [0, 0, 16, 16], "texture": "#side"}, - "up": {"uv": [0, 0, 16, 16], "texture": "#top"}, - "down": {"uv": [0, 0, 16, 16], "texture": "#top"} - } - } - ] -} diff --git a/src/main/resources/assets/logicore/models/block/server_rack_top_on.json b/src/main/resources/assets/logicore/models/block/server_rack_top_on.json deleted file mode 100644 index d9f1f92..0000000 --- a/src/main/resources/assets/logicore/models/block/server_rack_top_on.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "parent": "logicore:block/server_rack_top", - "textures": { - "front": "logicore:block/server_rack_front_top_on" - } -} diff --git a/src/main/resources/assets/logicore/models/item/server.json b/src/main/resources/assets/logicore/models/item/server.json new file mode 100644 index 0000000..906cb56 --- /dev/null +++ b/src/main/resources/assets/logicore/models/item/server.json @@ -0,0 +1,110 @@ +{ + "format_version": "1.9.0", + "credit": "Made with Blockbench", + "ambientocclusion": false, + "texture_size": [32, 32], + "textures": { + "0": "logicore:item/server", + "particle": "logicore:item/server" + }, + "elements": [ + { + "from": [2, 0, 0], + "to": [14, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 0, 6.5]}, + "faces": { + "north": {"uv": [7, 0, 14, 1], "texture": "#0"}, + "east": {"uv": [7, 2, 13.5, 3], "texture": "#0"}, + "south": {"uv": [7, 1, 14, 2], "texture": "#0"}, + "west": {"uv": [7, 3, 13.5, 4], "texture": "#0"}, + "up": {"uv": [7, 6.5, 0, 0], "texture": "#0"}, + "down": {"uv": [7, 6.5, 0, 13], "texture": "#0"} + } + }, + { + "from": [1, 0, 0], + "to": [2, 2, 0], + "rotation": {"angle": 0, "axis": "y", "origin": [1.5, 1, 0]}, + "faces": { + "north": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "east": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "south": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "west": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "up": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "down": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"} + } + }, + { + "from": [14, 0, 0], + "to": [15, 2, 0], + "rotation": {"angle": 0, "axis": "y", "origin": [14.5, 1, 0]}, + "faces": { + "north": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "east": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "south": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "west": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "up": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "down": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"} + } + }, + { + "from": [14, 1, 13], + "to": [15, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [14.5, 1, 13]}, + "faces": { + "north": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "east": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "south": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "west": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "up": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "down": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"} + } + }, + { + "from": [1, 1, 13], + "to": [2, 2, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [1.5, 1, 13]}, + "faces": { + "north": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "east": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "south": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "west": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "up": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"}, + "down": {"uv": [7.25, 4.125, 7.75, 5.125], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "translation": [0, 5.5, -2.5], + "scale": [0.6875, 1, 0.6875] + }, + "thirdperson_lefthand": { + "translation": [0, 5.5, -2.5], + "scale": [0.6875, 1, 0.6875] + }, + "firstperson_righthand": { + "translation": [0, 5.5, -2.5], + "scale": [0.6875, 1, 0.6875] + }, + "firstperson_lefthand": { + "translation": [0, 5.5, -2.5], + "scale": [0.6875, 1, 0.6875] + }, + "ground": { + "translation": [0, 4, 0], + "scale": [0.7, 0.7, 0.7] + }, + "gui": { + "rotation": [21, -140, -1], + "translation": [-1, 5, 0], + "scale": [0.8, 0.8, 0.8] + }, + "fixed": { + "translation": [0, 7.25, 0] + }, + "on_shelf": { + "rotation": [0, -180, 0] + } + } +} diff --git a/src/main/resources/assets/logicore/textures/block/creative_battery.png b/src/main/resources/assets/logicore/textures/block/creative_battery.png new file mode 100644 index 0000000..868e4bc Binary files /dev/null and b/src/main/resources/assets/logicore/textures/block/creative_battery.png differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack.png b/src/main/resources/assets/logicore/textures/block/server_rack.png new file mode 100644 index 0000000..359fb62 Binary files /dev/null and b/src/main/resources/assets/logicore/textures/block/server_rack.png differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_back.png b/src/main/resources/assets/logicore/textures/block/server_rack_back.png deleted file mode 100644 index 48bfff6..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_back.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_back_bottom.png b/src/main/resources/assets/logicore/textures/block/server_rack_back_bottom.png deleted file mode 100644 index 54d53c3..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_back_bottom.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_back_top.png b/src/main/resources/assets/logicore/textures/block/server_rack_back_top.png deleted file mode 100644 index f95d4c9..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_back_top.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front.png b/src/main/resources/assets/logicore/textures/block/server_rack_front.png deleted file mode 100644 index 1b1a016..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_front.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom.png b/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom.png deleted file mode 100644 index 3c0d26e..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png b/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png deleted file mode 100644 index 48c37f0..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png.mcmeta b/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png.mcmeta deleted file mode 100644 index 74bf814..0000000 --- a/src/main/resources/assets/logicore/textures/block/server_rack_front_bottom_on.png.mcmeta +++ /dev/null @@ -1,5 +0,0 @@ -{ - "animation": { - "frametime": 4 - } -} diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_top.png b/src/main/resources/assets/logicore/textures/block/server_rack_front_top.png deleted file mode 100644 index 46c18a9..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_front_top.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png b/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png deleted file mode 100644 index bfe6080..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png.mcmeta b/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png.mcmeta deleted file mode 100644 index 10c3a8f..0000000 --- a/src/main/resources/assets/logicore/textures/block/server_rack_front_top_on.png.mcmeta +++ /dev/null @@ -1,5 +0,0 @@ -{ - "animation": { - "frametime": 2 - } -} diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_side.png b/src/main/resources/assets/logicore/textures/block/server_rack_side.png deleted file mode 100644 index 53bfbae..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_side.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_side_bottom.png b/src/main/resources/assets/logicore/textures/block/server_rack_side_bottom.png deleted file mode 100644 index 16202c6..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_side_bottom.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_side_top.png b/src/main/resources/assets/logicore/textures/block/server_rack_side_top.png deleted file mode 100644 index 63e049c..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_side_top.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/block/server_rack_top.png b/src/main/resources/assets/logicore/textures/block/server_rack_top.png deleted file mode 100644 index cbe97dc..0000000 Binary files a/src/main/resources/assets/logicore/textures/block/server_rack_top.png and /dev/null differ diff --git a/src/main/resources/assets/logicore/textures/gui/server_rack_gui.png b/src/main/resources/assets/logicore/textures/gui/server_rack_gui.png index d988e75..d214b22 100644 Binary files a/src/main/resources/assets/logicore/textures/gui/server_rack_gui.png and b/src/main/resources/assets/logicore/textures/gui/server_rack_gui.png differ diff --git a/src/main/resources/assets/logicore/textures/gui/server_ui.png b/src/main/resources/assets/logicore/textures/gui/server_ui.png new file mode 100644 index 0000000..86e8685 Binary files /dev/null and b/src/main/resources/assets/logicore/textures/gui/server_ui.png differ diff --git a/src/main/resources/assets/logicore/textures/item/cycle_pick.png b/src/main/resources/assets/logicore/textures/item/cycle_pick.png index 0206cb3..904f91f 100644 Binary files a/src/main/resources/assets/logicore/textures/item/cycle_pick.png and b/src/main/resources/assets/logicore/textures/item/cycle_pick.png differ diff --git a/src/main/resources/assets/logicore/textures/item/old_cycle_pick.png b/src/main/resources/assets/logicore/textures/item/old_cycle_pick.png new file mode 100644 index 0000000..0206cb3 Binary files /dev/null and b/src/main/resources/assets/logicore/textures/item/old_cycle_pick.png differ diff --git a/src/main/resources/assets/logicore/textures/item/server.png b/src/main/resources/assets/logicore/textures/item/server.png new file mode 100644 index 0000000..03b25ec Binary files /dev/null and b/src/main/resources/assets/logicore/textures/item/server.png differ diff --git a/src/main/resources/assets/logicore/textures/item/server_rack_item.png b/src/main/resources/assets/logicore/textures/item/server_rack_item.png new file mode 100644 index 0000000..8c36a3c Binary files /dev/null and b/src/main/resources/assets/logicore/textures/item/server_rack_item.png differ