From 7c32cada418adb6ed4dbedea1b946f99dd85446e Mon Sep 17 00:00:00 2001 From: ellieisjelly Date: Fri, 5 Jan 2024 22:27:37 -0300 Subject: [PATCH] Initial work on SabotageChests --- .../java/me/ellieis/Sabotage/Sabotage.java | 15 +++- .../Sabotage/game/custom/SabotageBlocks.java | 68 +++++++++++++++++++ .../Sabotage/game/custom/SabotageItems.java | 19 ++++++ .../game/custom/blocks/SabotageChest.java | 29 ++++++++ .../blocks/SabotageChestBlockEntity.java | 13 ++++ .../game/custom/items/SabotageChest.java | 11 +++ .../Sabotage/game/map/SabotageMap.java | 25 +++++-- .../Sabotage/game/phase/SabotageActive.java | 10 +++ .../data/sabotage/games/sabotage.json | 2 +- .../resources/data/sabotage/lang/en_us.json | 2 + 10 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 src/main/java/me/ellieis/Sabotage/game/custom/SabotageBlocks.java create mode 100644 src/main/java/me/ellieis/Sabotage/game/custom/SabotageItems.java create mode 100644 src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChest.java create mode 100644 src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChestBlockEntity.java create mode 100644 src/main/java/me/ellieis/Sabotage/game/custom/items/SabotageChest.java diff --git a/src/main/java/me/ellieis/Sabotage/Sabotage.java b/src/main/java/me/ellieis/Sabotage/Sabotage.java index 55c6887..10fdb90 100644 --- a/src/main/java/me/ellieis/Sabotage/Sabotage.java +++ b/src/main/java/me/ellieis/Sabotage/Sabotage.java @@ -1,22 +1,33 @@ package me.ellieis.Sabotage; import me.ellieis.Sabotage.game.config.SabotageConfig; +import me.ellieis.Sabotage.game.custom.SabotageBlocks; +import me.ellieis.Sabotage.game.custom.SabotageItems; +import me.ellieis.Sabotage.game.phase.SabotageActive; import me.ellieis.Sabotage.game.phase.SabotageWaiting; import net.fabricmc.api.ModInitializer; - import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xyz.nucleoid.plasmid.game.GameType; +import java.util.ArrayList; +import java.util.List; + public class Sabotage implements ModInitializer { public static final String MOD_ID = "sabotage"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - private static final Identifier SABOTAGE_ID = new Identifier(MOD_ID, "sabotage"); + public static final Identifier SABOTAGE_ID = new Identifier(MOD_ID, "sabotage"); public static final GameType GAME_TYPE = GameType.register(SABOTAGE_ID, SabotageConfig.CODEC, SabotageWaiting::Open); + public static final List activeGames = new ArrayList<>(); @Override public void onInitialize() { + SabotageBlocks.register(); + SabotageItems.register(); + } + public static Identifier identifier(String value) { + return new Identifier(MOD_ID, value); } } \ No newline at end of file diff --git a/src/main/java/me/ellieis/Sabotage/game/custom/SabotageBlocks.java b/src/main/java/me/ellieis/Sabotage/game/custom/SabotageBlocks.java new file mode 100644 index 0000000..e6e9cd1 --- /dev/null +++ b/src/main/java/me/ellieis/Sabotage/game/custom/SabotageBlocks.java @@ -0,0 +1,68 @@ +package me.ellieis.Sabotage.game.custom; + +import eu.pb4.polymer.core.api.block.PolymerBlockUtils; +import me.ellieis.Sabotage.Sabotage; +import me.ellieis.Sabotage.game.custom.blocks.SabotageChest; +import me.ellieis.Sabotage.game.custom.blocks.SabotageChestBlockEntity; +import me.ellieis.Sabotage.game.phase.SabotageActive; +import net.fabricmc.fabric.api.event.player.UseBlockCallback; +import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.BlockEntityType; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.ActionResult; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.world.World; + + +public class SabotageBlocks { + public static final Block SABOTAGE_CHEST = new SabotageChest(AbstractBlock.Settings.copy(Blocks.CHEST).dropsNothing(), Blocks.CHEST); + + public static final BlockEntityType SABOTAGE_CHEST_ENTITY = FabricBlockEntityTypeBuilder.create(SabotageChestBlockEntity::new, SABOTAGE_CHEST).build(null); + public static void register() { + register("sabotage_chest", SABOTAGE_CHEST); + + registerBlockEntity("sabotage_chest_block_entity", SABOTAGE_CHEST_ENTITY); + + UseBlockCallback.EVENT.register(SabotageBlocks::onBlockUse); + } + + private static ActionResult onBlockUse(PlayerEntity plr, World world, Hand hand, BlockHitResult blockHitResult) { + boolean isInGame = false; + + for (SabotageActive game : Sabotage.activeGames) { + if (game.getWorld().equals(world)) { + isInGame = true; + break; + } + } + if (isInGame) { + if (blockHitResult != null) { + Block block = world.getBlockState(blockHitResult.getBlockPos()).getBlock(); + if (block instanceof SabotageChest) { + plr.playSound(SoundEvents.BLOCK_CHEST_CLOSE, SoundCategory.BLOCKS, 1, 1.2f); + world.setBlockState(blockHitResult.getBlockPos(), Blocks.AIR.getDefaultState()); + return ActionResult.FAIL; + } + } + } + return ActionResult.PASS; + } + + private static T register(String id, T block) { + return Registry.register(Registries.BLOCK, Sabotage.identifier(id), block); + } + private static BlockEntityType registerBlockEntity(String id, BlockEntityType type) { + Registry.register(Registries.BLOCK_ENTITY_TYPE, Sabotage.identifier(id), type); + PolymerBlockUtils.registerBlockEntity(SABOTAGE_CHEST_ENTITY); + return type; + } +} diff --git a/src/main/java/me/ellieis/Sabotage/game/custom/SabotageItems.java b/src/main/java/me/ellieis/Sabotage/game/custom/SabotageItems.java new file mode 100644 index 0000000..f0c8f58 --- /dev/null +++ b/src/main/java/me/ellieis/Sabotage/game/custom/SabotageItems.java @@ -0,0 +1,19 @@ +package me.ellieis.Sabotage.game.custom; + +import me.ellieis.Sabotage.Sabotage; +import me.ellieis.Sabotage.game.custom.items.SabotageChest; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; + +public class SabotageItems { + public static final Item SABOTAGE_CHEST = new SabotageChest(SabotageBlocks.SABOTAGE_CHEST, new Item.Settings(), Items.CHEST); + + public static void register() { + register("sabotage_chest", SABOTAGE_CHEST); + } + private static T register(String id, T item) { + return Registry.register(Registries.ITEM, Sabotage.identifier(id), item); + } +} diff --git a/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChest.java b/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChest.java new file mode 100644 index 0000000..cae4a94 --- /dev/null +++ b/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChest.java @@ -0,0 +1,29 @@ +package me.ellieis.Sabotage.game.custom.blocks; + +import eu.pb4.polymer.core.api.block.PolymerBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockEntityProvider; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.math.BlockPos; +import org.jetbrains.annotations.Nullable; + +public class SabotageChest extends Block implements BlockEntityProvider, PolymerBlock { + private final Block virtualBlock; + + public SabotageChest(Settings settings, Block virtualBlock) { + super(settings); + + this.virtualBlock = virtualBlock; + } + + @Override + public Block getPolymerBlock(BlockState state) { + return this.virtualBlock; + } + @Nullable + @Override + public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { + return new SabotageChestBlockEntity(pos, state); + } +} diff --git a/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChestBlockEntity.java b/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChestBlockEntity.java new file mode 100644 index 0000000..bd0ce14 --- /dev/null +++ b/src/main/java/me/ellieis/Sabotage/game/custom/blocks/SabotageChestBlockEntity.java @@ -0,0 +1,13 @@ +package me.ellieis.Sabotage.game.custom.blocks; + +import me.ellieis.Sabotage.game.custom.SabotageBlocks; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.util.math.BlockPos; + +public class SabotageChestBlockEntity extends BlockEntity { + + public SabotageChestBlockEntity(BlockPos pos, BlockState state) { + super(SabotageBlocks.SABOTAGE_CHEST_ENTITY, pos, state); + } +} diff --git a/src/main/java/me/ellieis/Sabotage/game/custom/items/SabotageChest.java b/src/main/java/me/ellieis/Sabotage/game/custom/items/SabotageChest.java new file mode 100644 index 0000000..6b4068c --- /dev/null +++ b/src/main/java/me/ellieis/Sabotage/game/custom/items/SabotageChest.java @@ -0,0 +1,11 @@ +package me.ellieis.Sabotage.game.custom.items; + +import eu.pb4.polymer.core.api.item.PolymerBlockItem; +import net.minecraft.block.Block; +import net.minecraft.item.Item; + +public class SabotageChest extends PolymerBlockItem { + public SabotageChest(Block block, Settings settings, Item virtualItem) { + super(block, settings, virtualItem); + } +} diff --git a/src/main/java/me/ellieis/Sabotage/game/map/SabotageMap.java b/src/main/java/me/ellieis/Sabotage/game/map/SabotageMap.java index 014daca..bdb7645 100644 --- a/src/main/java/me/ellieis/Sabotage/game/map/SabotageMap.java +++ b/src/main/java/me/ellieis/Sabotage/game/map/SabotageMap.java @@ -1,22 +1,26 @@ package me.ellieis.Sabotage.game.map; +import me.ellieis.Sabotage.game.custom.blocks.SabotageChest; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.text.Text; -import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.gen.chunk.ChunkGenerator; - +import xyz.nucleoid.map_templates.BlockBounds; import xyz.nucleoid.map_templates.MapTemplate; import xyz.nucleoid.map_templates.TemplateRegion; import xyz.nucleoid.plasmid.game.GameOpenException; import xyz.nucleoid.plasmid.game.world.generator.TemplateChunkGenerator; import xyz.nucleoid.plasmid.util.PlayerRef; -import java.util.*; -import java.util.stream.Stream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; public class SabotageMap { private final MapTemplate template; @@ -29,8 +33,19 @@ public SabotageMap(MapTemplate template) { if (this.spawns.isEmpty()) { throw new GameOpenException(Text.literal("Failed to load spawns")); } - } + // generate chest positions from placed SabotageChests + template.getBounds().forEach(blockPos -> { + Block block = template.getBlockState(blockPos).getBlock(); + if (block instanceof SabotageChest) { + template.getMetadata().addRegion("chest", BlockBounds.ofBlock(blockPos)); + template.setBlockState(blockPos, Blocks.AIR.getDefaultState()); + } + }); + } + public void generateChests() { + // to-do: generate chests from added chest regions + } public MapTemplate getTemplate() { return this.template; } diff --git a/src/main/java/me/ellieis/Sabotage/game/phase/SabotageActive.java b/src/main/java/me/ellieis/Sabotage/game/phase/SabotageActive.java index 5d49200..69afc9c 100644 --- a/src/main/java/me/ellieis/Sabotage/game/phase/SabotageActive.java +++ b/src/main/java/me/ellieis/Sabotage/game/phase/SabotageActive.java @@ -3,6 +3,7 @@ import com.google.common.collect.ImmutableSet; import eu.pb4.sidebars.api.Sidebar; import eu.pb4.sidebars.api.lines.SidebarLine; +import me.ellieis.Sabotage.Sabotage; import me.ellieis.Sabotage.game.EndReason; import me.ellieis.Sabotage.game.GameStates; import me.ellieis.Sabotage.game.Roles; @@ -80,6 +81,10 @@ public SabotageActive(SabotageConfig config, GameSpace gameSpace, SabotageMap ma this.detectives = new MutablePlayerSet(gameSpace.getServer()); this.innocents = new MutablePlayerSet(gameSpace.getServer()); this.karmaManager = new KarmaManager(gameSpace); + Sabotage.activeGames.add(this); + } + public ServerWorld getWorld() { + return world; } private static void gameStartedRules(GameActivity activity) { activity.allow(GameRuleType.FALL_DAMAGE); @@ -301,6 +306,7 @@ public static void Open(GameSpace gameSpace, ServerWorld world, SabotageMap map, activity.listen(ReplacePlayerChatEvent.EVENT, game::onChat); activity.listen(GamePlayerEvents.REMOVE, game::onPlayerRemove); activity.listen(GamePlayerEvents.OFFER, game::onOffer); + activity.listen(GameActivityEvents.DESTROY, game::onDestroy); PlayerSet plrs = game.gameSpace.getPlayers(); plrs.showTitle(Text.literal(Integer.toString(game.config.countdownTime())).formatted(Formatting.GOLD), 20); @@ -397,6 +403,10 @@ private PlayerOfferResult onOffer(PlayerOffer offer) { }); } + private void onDestroy(GameCloseReason gameCloseReason) { + Sabotage.activeGames.remove(this); + } + private void onPlayerRemove(ServerPlayerEntity plr) { Roles role = getPlayerRole(plr); if (role == Roles.SABOTEUR) { diff --git a/src/main/resources/data/sabotage/games/sabotage.json b/src/main/resources/data/sabotage/games/sabotage.json index e577a15..2728f11 100644 --- a/src/main/resources/data/sabotage/games/sabotage.json +++ b/src/main/resources/data/sabotage/games/sabotage.json @@ -1,6 +1,6 @@ { "type": "sabotage:sabotage", - "map": "sabotage:lobby", + "map": "sabotage:testmap", "countdown_time": 5, "grace_period": 15, "time_limit": 100, diff --git a/src/main/resources/data/sabotage/lang/en_us.json b/src/main/resources/data/sabotage/lang/en_us.json index a677e8c..cd34174 100644 --- a/src/main/resources/data/sabotage/lang/en_us.json +++ b/src/main/resources/data/sabotage/lang/en_us.json @@ -1,5 +1,7 @@ { "gameType.sabotage.sabotage": "Sabotage", + "block.sabotage.sabotage_chest": "Sabotage Chest", + "sabotage.waiting": "Waiting for players.", "sabotage.full": "Game is full.", "sabotage.sidebar.countdown": "Get ready!",