diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/state/MobSpawnerBlockEntityMixin.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/state/MobSpawnerBlockEntityMixin.java new file mode 100644 index 000000000..886fc80b0 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/implementations/block/state/MobSpawnerBlockEntityMixin.java @@ -0,0 +1,118 @@ +package com.dfsek.terra.fabric.mixin.implementations.block.state; + +import com.dfsek.terra.api.platform.block.state.MobSpawner; +import com.dfsek.terra.api.platform.block.state.SerialState; +import com.dfsek.terra.api.platform.entity.EntityType; +import com.dfsek.terra.fabric.TerraFabricPlugin; +import net.minecraft.block.entity.MobSpawnerBlockEntity; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.MobSpawnerLogic; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Implements; +import org.spongepowered.asm.mixin.Interface; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(MobSpawnerBlockEntity.class) +@Implements(@Interface(iface = MobSpawner.class, prefix = "terra$")) +public abstract class MobSpawnerBlockEntityMixin { + @Shadow + public abstract MobSpawnerLogic getLogic(); + + public EntityType terra$getSpawnedType() { + return (EntityType) Registry.ENTITY_TYPE.get(getLogic().getEntityId()); + } + + public void terra$setSpawnedType(@NotNull EntityType creatureType) { + getLogic().setEntityId((net.minecraft.entity.EntityType) creatureType); + } + + public int terra$getDelay() { + return 0; + } + + public void terra$setDelay(int delay) { + + } + + public int terra$getMinSpawnDelay() { + return 0; + } + + public void terra$setMinSpawnDelay(int delay) { + + } + + public int terra$getMaxSpawnDelay() { + return 0; + } + + public void terra$setMaxSpawnDelay(int delay) { + + } + + public int terra$getSpawnCount() { + return 0; + } + + public void terra$setSpawnCount(int spawnCount) { + + } + + public int terra$getMaxNearbyEntities() { + return 0; + } + + public void terra$setMaxNearbyEntities(int maxNearbyEntities) { + + } + + public int terra$getRequiredPlayerRange() { + return 0; + } + + public void terra$setRequiredPlayerRange(int requiredPlayerRange) { + + } + + public int terra$getSpawnRange() { + return 0; + } + + public void terra$setSpawnRange(int spawnRange) { + + } + + public void terra$applyState(String state) { + SerialState.parse(state).forEach((k, v) -> { + switch(k) { + case "type": + terra$setSpawnedType(TerraFabricPlugin.getInstance().getWorldHandle().getEntity(v)); + return; + case "delay": + terra$setDelay(Integer.parseInt(v)); + return; + case "min_delay": + terra$setMinSpawnDelay(Integer.parseInt(v)); + return; + case "max_delay": + terra$setMaxSpawnDelay(Integer.parseInt(v)); + return; + case "spawn_count": + terra$setSpawnCount(Integer.parseInt(v)); + return; + case "spawn_range": + terra$setSpawnRange(Integer.parseInt(v)); + return; + case "max_nearby": + terra$setMaxNearbyEntities(Integer.parseInt(v)); + return; + case "required_player_range": + terra$setRequiredPlayerRange(Integer.parseInt(v)); + return; + default: + throw new IllegalArgumentException("Invalid property: " + k); + } + }); + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricAdapter.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricAdapter.java index ba2acf1aa..60d1138a3 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricAdapter.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricAdapter.java @@ -3,6 +3,9 @@ package com.dfsek.terra.fabric.world; import com.dfsek.terra.api.math.vector.Vector3; import com.dfsek.terra.api.platform.block.BlockFace; import com.dfsek.terra.api.platform.block.BlockType; +import com.dfsek.terra.api.platform.block.state.Container; +import com.dfsek.terra.api.platform.block.state.MobSpawner; +import com.dfsek.terra.api.platform.block.state.Sign; import com.dfsek.terra.fabric.world.block.FabricBlockData; import com.dfsek.terra.fabric.world.block.FabricBlockType; import com.dfsek.terra.fabric.world.block.data.FabricDirectional; @@ -14,9 +17,14 @@ import com.dfsek.terra.fabric.world.block.data.FabricStairs; import com.dfsek.terra.fabric.world.block.data.FabricWaterlogged; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.LootableContainerBlockEntity; +import net.minecraft.block.entity.MobSpawnerBlockEntity; +import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.state.property.Properties; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.world.WorldAccess; import java.util.Arrays; @@ -71,4 +79,18 @@ public final class FabricAdapter { public static BlockType adapt(Block block) { return new FabricBlockType(block); } + + public static com.dfsek.terra.api.platform.block.state.BlockState adapt(com.dfsek.terra.api.platform.block.Block block) { + WorldAccess worldAccess = (WorldAccess) block.getLocation().getWorld(); + + BlockEntity entity = worldAccess.getBlockEntity(adapt(block.getLocation().toVector())); + if(entity instanceof SignBlockEntity) { + return (Sign) entity; + } else if(entity instanceof MobSpawnerBlockEntity) { + return (MobSpawner) entity; + } else if(entity instanceof LootableContainerBlockEntity) { + return (Container) entity; + } + return null; + } } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlock.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlock.java index 0db2e8daf..f17e80d5c 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlock.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/FabricBlock.java @@ -8,7 +8,6 @@ import com.dfsek.terra.api.platform.block.BlockType; import com.dfsek.terra.api.platform.block.state.BlockState; import com.dfsek.terra.api.platform.world.World; import com.dfsek.terra.fabric.world.FabricAdapter; -import com.dfsek.terra.fabric.world.block.state.FabricBlockState; import net.minecraft.block.FluidBlock; import net.minecraft.util.math.BlockPos; import net.minecraft.world.WorldAccess; @@ -35,7 +34,7 @@ public class FabricBlock implements Block { @Override public BlockState getState() { - return FabricBlockState.newInstance(this); + return FabricAdapter.adapt(this); } @Override diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricBlockState.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricBlockState.java deleted file mode 100644 index c82342fc0..000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricBlockState.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.dfsek.terra.fabric.world.block.state; - -import com.dfsek.terra.api.platform.block.Block; -import com.dfsek.terra.api.platform.block.BlockData; -import com.dfsek.terra.api.platform.block.state.BlockState; -import com.dfsek.terra.api.platform.block.state.Container; -import com.dfsek.terra.api.platform.block.state.Sign; -import com.dfsek.terra.fabric.world.FabricAdapter; -import com.dfsek.terra.fabric.world.block.FabricBlock; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.block.entity.LootableContainerBlockEntity; -import net.minecraft.block.entity.MobSpawnerBlockEntity; -import net.minecraft.block.entity.SignBlockEntity; -import net.minecraft.world.WorldAccess; - -public class FabricBlockState implements BlockState { - protected final BlockEntity blockEntity; - private final WorldAccess worldAccess; - - public FabricBlockState(BlockEntity blockEntity, WorldAccess worldAccess) { - this.blockEntity = blockEntity; - this.worldAccess = worldAccess; - } - - public static BlockState newInstance(Block block) { - WorldAccess worldAccess = (WorldAccess) block.getLocation().getWorld(); - - BlockEntity entity = worldAccess.getBlockEntity(FabricAdapter.adapt(block.getLocation().toVector())); - if(entity instanceof SignBlockEntity) { - return (Sign) entity; - } else if(entity instanceof MobSpawnerBlockEntity) { - return new FabricMobSpawner((MobSpawnerBlockEntity) entity, worldAccess); - } else if(entity instanceof LootableContainerBlockEntity) { - return (Container) entity; - } - return null; - } - - @Override - public BlockEntity getHandle() { - return blockEntity; - } - - @Override - public Block getBlock() { - return new FabricBlock(blockEntity.getPos(), blockEntity.getWorld()); - } - - @Override - public int getX() { - return blockEntity.getPos().getX(); - } - - @Override - public int getY() { - return blockEntity.getPos().getY(); - } - - @Override - public int getZ() { - return blockEntity.getPos().getZ(); - } - - @Override - public BlockData getBlockData() { - return FabricAdapter.adapt(blockEntity.getCachedState()); - } - - @Override - public boolean update(boolean applyPhysics) { - worldAccess.getChunk(blockEntity.getPos()).setBlockEntity(blockEntity.getPos(), blockEntity); - return true; - } -} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricMobSpawner.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricMobSpawner.java deleted file mode 100644 index 9ce0b3ba0..000000000 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricMobSpawner.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.dfsek.terra.fabric.world.block.state; - -import com.dfsek.terra.api.platform.block.state.MobSpawner; -import com.dfsek.terra.api.platform.block.state.SerialState; -import com.dfsek.terra.api.platform.entity.EntityType; -import com.dfsek.terra.fabric.TerraFabricPlugin; -import com.dfsek.terra.fabric.world.FabricAdapter; -import net.minecraft.block.entity.MobSpawnerBlockEntity; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.WorldAccess; -import org.jetbrains.annotations.NotNull; - -public class FabricMobSpawner extends FabricBlockState implements MobSpawner { // TODO: finish implementation / refactor API because bukkit doesnt expose most of the stuff spawners can do - - - public FabricMobSpawner(MobSpawnerBlockEntity blockEntity, WorldAccess worldAccess) { - super(blockEntity, worldAccess); - } - - @Override - public EntityType getSpawnedType() { - return (EntityType) Registry.ENTITY_TYPE.get(((MobSpawnerBlockEntity) blockEntity).getLogic().getEntityId()); - } - - @Override - public void setSpawnedType(@NotNull EntityType creatureType) { - ((MobSpawnerBlockEntity) blockEntity).getLogic().setEntityId((net.minecraft.entity.EntityType) creatureType); - } - - @Override - public int getDelay() { - return 0; - } - - @Override - public void setDelay(int delay) { - - } - - @Override - public int getMinSpawnDelay() { - return 0; - } - - @Override - public void setMinSpawnDelay(int delay) { - - } - - @Override - public int getMaxSpawnDelay() { - return 0; - } - - @Override - public void setMaxSpawnDelay(int delay) { - - } - - @Override - public int getSpawnCount() { - return 0; - } - - @Override - public void setSpawnCount(int spawnCount) { - - } - - @Override - public int getMaxNearbyEntities() { - return 0; - } - - @Override - public void setMaxNearbyEntities(int maxNearbyEntities) { - - } - - @Override - public int getRequiredPlayerRange() { - return 0; - } - - @Override - public void setRequiredPlayerRange(int requiredPlayerRange) { - - } - - @Override - public int getSpawnRange() { - return 0; - } - - @Override - public void setSpawnRange(int spawnRange) { - - } - - @Override - public void applyState(String state) { - SerialState.parse(state).forEach((k, v) -> { - switch(k) { - case "type": - setSpawnedType(TerraFabricPlugin.getInstance().getWorldHandle().getEntity(v)); - return; - case "delay": - setDelay(Integer.parseInt(v)); - return; - case "min_delay": - setMinSpawnDelay(Integer.parseInt(v)); - return; - case "max_delay": - setMaxSpawnDelay(Integer.parseInt(v)); - return; - case "spawn_count": - setSpawnCount(Integer.parseInt(v)); - return; - case "spawn_range": - setSpawnRange(Integer.parseInt(v)); - return; - case "max_nearby": - setMaxNearbyEntities(Integer.parseInt(v)); - return; - case "required_player_range": - setRequiredPlayerRange(Integer.parseInt(v)); - return; - default: - throw new IllegalArgumentException("Invalid property: " + k); - } - }); - } -} diff --git a/platforms/fabric/src/main/resources/terra.mixins.json b/platforms/fabric/src/main/resources/terra.mixins.json index 6f6743ddc..59bac2ea4 100644 --- a/platforms/fabric/src/main/resources/terra.mixins.json +++ b/platforms/fabric/src/main/resources/terra.mixins.json @@ -9,6 +9,7 @@ "implementations.ChunkGeneratorMixin", "implementations.block.BlockEntityMixin", "implementations.block.state.LootableContainerBlockEntityMixin", + "implementations.block.state.MobSpawnerBlockEntityMixin", "implementations.block.state.SignBlockEntityMixin", "implementations.chunk.ChunkRegionMixin", "implementations.chunk.WorldChunkMixin",