package com.thebrokenrail.reliccraft.data; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.SpawnReason; import net.minecraft.entity.mob.ZombieEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.thrown.PotionEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.potion.PotionUtil; import net.minecraft.potion.Potions; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.registry.Registry; import net.minecraft.world.World; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; public class Actions { private static final Map actions = new HashMap<>(); public static void register(String id, Action action) { actions.put(id, action); } public static Action get(String id) { return actions.get(id); } private static String getRandomAction(int budget, Random random) { List options = new ArrayList<>(); for (Map.Entry entry : actions.entrySet()) { if (budget >= entry.getValue().getCost()) { options.add(entry.getKey()); } } if (options.size() < 1) { return null; } else { return options.get(random.nextInt(options.size())); } } public static String[] getRandomActions(Random random) { List chosen = new ArrayList<>(); int amount = random.nextInt(3) + 1; for (int i = 0; i < amount; i++) { int budget = random.nextInt(100) + 1; String action = getRandomAction(budget, random); if (action != null) { chosen.add(action); } } return chosen.toArray(new String[0]); } public static class HalfHeartAction implements Action { @Override public int getCost() { return 0; } @Override public void execute(World world, Entity attacker, Entity target) { if (target instanceof LivingEntity) { ((LivingEntity) target).setHealth(1f); } } @Override public void execute(World world, Entity attacker, BlockPos pos) { PotionEntity entity = new PotionEntity(world, pos.getX(), pos.getY(), pos.getZ()); entity.setItem(PotionUtil.setPotion(new ItemStack(Items.LINGERING_POTION), Potions.STRONG_HARMING)); world.spawnEntity(entity); } } public static class SwapBlockAction implements Action { @Override public void execute(World world, Entity attacker, Entity target) { execute(world, attacker, target.getBlockPos().down()); } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos) && world.canPlayerModifyAt((PlayerEntity) attacker, attacker.getBlockPos().down())) { BlockState state1 = world.getBlockState(attacker.getBlockPos().down()); BlockState state2 = world.getBlockState(pos); world.setBlockState(attacker.getBlockPos().down(), state2); world.setBlockState(pos, state1); } } @Override public int getCost() { return 0; } } public static class DirtAction implements Action { @Override public int getCost() { return 25; } @Override public void execute(World world, Entity attacker, Entity target) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, target.getBlockPos())) { target.remove(); target.kill(); world.setBlockState(target.getBlockPos(), Blocks.DIRT.getDefaultState()); } } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) { world.setBlockState(pos, Blocks.DIRT.getDefaultState()); } } } public static class NetherAction implements Action { @Override public int getCost() { return 25; } @Override public void execute(World world, Entity attacker, Entity target) { BlockPos pos = target.getBlockPos(); BlockState state = world.getBlockState(pos); world.setBlockState(pos, Blocks.NETHER_PORTAL.getDefaultState()); target.changeDimension(((ServerWorld) world).getServer().getWorld(world.getRegistryKey() == World.NETHER ? World.OVERWORLD : World.NETHER)); world.setBlockState(pos, state); } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) { world.setBlockState(pos, Blocks.LAVA.getDefaultState()); } } } public static class EndAction implements Action { @Override public int getCost() { return 50; } @Override public void execute(World world, Entity attacker, Entity target) { target.changeDimension(((ServerWorld) world).getServer().getWorld(world.getRegistryKey() == World.END ? World.OVERWORLD : World.END)); } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) { world.setBlockState(pos, Blocks.END_STONE.getDefaultState()); } } } public static class DiamondAction extends ConversionAction { @Override public int getCost() { return 75; } @Override public Item getTargetItem() { return Items.GOLD_INGOT; } @Override public Item getConvertedItem() { return Items.DIAMOND; } @Override public Block getTargetBlock() { return Blocks.GOLD_BLOCK; } @Override public Block getConvertedBlock() { return Blocks.DIAMOND_BLOCK; } } public abstract static class ConversionAction implements Action { @Override public abstract int getCost(); public abstract Item getTargetItem(); public abstract Item getConvertedItem(); public abstract Block getTargetBlock(); public abstract Block getConvertedBlock(); @Override public void execute(World world, Entity attacker, Entity target) { if (target instanceof PlayerEntity) { PlayerEntity player = (PlayerEntity) target; for (int i = 0; i < player.inventory.size(); i++) { ItemStack stack = player.inventory.getStack(i); if (stack.getItem() == getTargetItem()) { player.inventory.setStack(i, new ItemStack(getConvertedItem(), stack.getCount())); } } } } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos) && world.getBlockState(pos).getBlock() == getTargetBlock()) { world.setBlockState(pos, getConvertedBlock().getDefaultState()); } } } public static class GoldAction extends ConversionAction { @Override public int getCost() { return 45; } @Override public Item getTargetItem() { return Items.COAL; } @Override public Item getConvertedItem() { return Items.GOLD_INGOT; } @Override public Block getTargetBlock() { return Blocks.COAL_BLOCK; } @Override public Block getConvertedBlock() { return Blocks.GOLD_BLOCK; } } public static class BedrockAction implements Action { @Override public int getCost() { return 95; } @Override public void execute(World world, Entity attacker, Entity target) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, attacker.getBlockPos())) { target.remove(); target.kill(); world.setBlockState(target.getBlockPos(), Blocks.BEDROCK.getDefaultState()); } } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) { world.setBlockState(pos, Blocks.BEDROCK.getDefaultState()); } } } public static class HealAction implements Action { @Override public int getCost() { return 0; } @Override public void execute(World world, Entity attacker, Entity target) { if (target instanceof LivingEntity) { ((LivingEntity) target).heal(Float.MAX_VALUE); } } @Override public void execute(World world, Entity attacker, BlockPos pos) { PotionEntity entity = new PotionEntity(world, pos.getX(), pos.getY(), pos.getZ()); entity.setItem(PotionUtil.setPotion(new ItemStack(Items.LINGERING_POTION), Potions.STRONG_HEALING)); world.spawnEntity(entity); } } public static class ZombifyAction implements Action { @Override public void execute(World world, Entity attacker, Entity target) { ZombieEntity zombie = new ZombieEntity(world); zombie.updatePosition(target.getX(), target.getY(), target.getZ()); world.spawnEntity(zombie); target.remove(); target.kill(); } @Override public void execute(World world, Entity attacker, BlockPos pos) { ZombieEntity zombie = new ZombieEntity(world); zombie.updatePosition(attacker.getX(), attacker.getY(), attacker.getZ()); world.spawnEntity(zombie); attacker.remove(); attacker.kill(); } @Override public int getCost() { return 15; } } public static class RandomAction implements Action { @Override public void execute(World world, Entity attacker, Entity target) { if (!target.removed) { target.remove(); target.kill(); } int entityID = new Random().nextInt(Registry.ENTITY_TYPE.getIds().size()); EntityType entityType = Registry.ENTITY_TYPE.get(entityID); if (entityType.isSummonable()) { Entity entity = entityType.spawn(world, null, null, convertToPlayer(attacker), target.getBlockPos(), SpawnReason.CONVERSION, false, false); if (entity != null) { entity.updatePosition(target.getX(), target.getY(), target.getZ()); } else { execute(world, attacker, target); } } else { execute(world, attacker, target); } } @Override public void execute(World world, Entity attacker, BlockPos pos) { if (attacker instanceof PlayerEntity && world.canPlayerModifyAt((PlayerEntity) attacker, pos)) { int blockID = new Random().nextInt(Registry.BLOCK.getIds().size()); Block block = Registry.BLOCK.get(blockID); world.setBlockState(pos, block.getDefaultState()); } } @Override public int getCost() { return 36; } } static { register("half_heart_action", new HalfHeartAction()); register("swap_block_action", new SwapBlockAction()); register("heal_action", new HealAction()); register("bedrock_action", new BedrockAction()); register("gold_action", new GoldAction()); register("diamond_action", new DiamondAction()); register("end_action", new EndAction()); register("nether_action", new NetherAction()); register("dirt_action", new DirtAction()); register("zombify_action", new ZombifyAction()); register("random_action", new RandomAction()); } }