diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/MobSpawnerLogicAccessor.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/MobSpawnerLogicAccessor.java new file mode 100644 index 000000000..15c213f38 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/mixin/MobSpawnerLogicAccessor.java @@ -0,0 +1,12 @@ +package com.dfsek.terra.fabric.mixin; + +import net.minecraft.util.Identifier; +import net.minecraft.world.MobSpawnerLogic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(MobSpawnerLogic.class) +public interface MobSpawnerLogicAccessor { + @Invoker + Identifier callGetEntityId(); +} 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 743c15550..0c2b5857b 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 @@ -2,6 +2,7 @@ package com.dfsek.terra.fabric.world; import com.dfsek.terra.api.math.vector.Vector3; import com.dfsek.terra.api.platform.block.BlockType; +import com.dfsek.terra.api.platform.entity.EntityType; import com.dfsek.terra.fabric.world.block.FabricBlockData; import com.dfsek.terra.fabric.world.block.FabricBlockType; import com.dfsek.terra.fabric.world.block.data.FabricMultipleFacing; @@ -9,6 +10,7 @@ import com.dfsek.terra.fabric.world.block.data.FabricOrientable; import com.dfsek.terra.fabric.world.block.data.FabricSlab; import com.dfsek.terra.fabric.world.block.data.FabricStairs; import com.dfsek.terra.fabric.world.block.data.FabricWaterlogged; +import com.dfsek.terra.fabric.world.entity.FabricEntityType; import com.dfsek.terra.fabric.world.handles.world.FabricWorldHandle; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -48,4 +50,12 @@ public final class FabricAdapter { return worldHandle.getWorld(); } + public static EntityType adapt(net.minecraft.entity.EntityType entityType) { + return new FabricEntityType(entityType); + } + + public static net.minecraft.entity.EntityType adapt(EntityType entityType) { + return ((FabricEntityType) entityType).getHandle(); + } + } diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricWorldHandle.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricWorldHandle.java index 08e3e8e4a..cccdaa8ae 100644 --- a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricWorldHandle.java +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/FabricWorldHandle.java @@ -9,6 +9,10 @@ import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import net.minecraft.block.BlockState; import net.minecraft.command.argument.BlockArgumentParser; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +import java.util.Locale; public class FabricWorldHandle implements WorldHandle { @Override @@ -35,6 +39,8 @@ public class FabricWorldHandle implements WorldHandle { @Override public EntityType getEntity(String id) { - return null; + Identifier identifier = Identifier.tryParse(id); + if(identifier == null) identifier = Identifier.tryParse("minecraft:" + id.toLowerCase(Locale.ROOT)); + return FabricAdapter.adapt(Registry.ENTITY_TYPE.get(identifier)); } } 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 index 09c09ed95..24ede5b8f 100644 --- 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 @@ -8,7 +8,9 @@ import com.dfsek.terra.fabric.world.block.FabricBlock; import com.dfsek.terra.fabric.world.block.FabricBlockData; import com.dfsek.terra.fabric.world.handles.world.FabricWorldHandle; import net.minecraft.block.AbstractSignBlock; +import net.minecraft.block.SpawnerBlock; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.MobSpawnerBlockEntity; import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.world.WorldAccess; @@ -28,6 +30,9 @@ public class FabricBlockState implements BlockState { if(block1 instanceof AbstractSignBlock) { SignBlockEntity signBlockEntity = (SignBlockEntity) worldAccess.getBlockEntity(FabricAdapter.adapt(block.getLocation().toVector())); return new FabricSign(signBlockEntity, worldAccess); + } else if(block1 instanceof SpawnerBlock) { + MobSpawnerBlockEntity mobSpawnerBlockEntity = (MobSpawnerBlockEntity) worldAccess.getBlockEntity(FabricAdapter.adapt(block.getLocation().toVector())); + return new FabricMobSpawner(mobSpawnerBlockEntity, worldAccess); } return null; } 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 new file mode 100644 index 000000000..8f9f3d2ee --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/block/state/FabricMobSpawner.java @@ -0,0 +1,134 @@ +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.mixin.MobSpawnerLogicAccessor; +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 FabricAdapter.adapt(Registry.ENTITY_TYPE.get(((MobSpawnerLogicAccessor) ((MobSpawnerBlockEntity) blockEntity).getLogic()).callGetEntityId())); + } + + @Override + public void setSpawnedType(@NotNull EntityType creatureType) { + ((MobSpawnerBlockEntity) blockEntity).getLogic().setEntityId(FabricAdapter.adapt(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/java/com/dfsek/terra/fabric/world/entity/FabricEntity.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/entity/FabricEntity.java new file mode 100644 index 000000000..72cbf83b4 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/entity/FabricEntity.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.fabric.world.entity; + +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.platform.entity.Entity; + +public class FabricEntity implements Entity { + @Override + public void sendMessage(String message) { + + } + + @Override + public Object getHandle() { + return null; + } + + @Override + public Location getLocation() { + return null; + } +} diff --git a/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/entity/FabricEntityType.java b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/entity/FabricEntityType.java new file mode 100644 index 000000000..31d6aceb1 --- /dev/null +++ b/platforms/fabric/src/main/java/com/dfsek/terra/fabric/world/entity/FabricEntityType.java @@ -0,0 +1,16 @@ +package com.dfsek.terra.fabric.world.entity; + +import com.dfsek.terra.api.platform.entity.EntityType; + +public class FabricEntityType implements EntityType { + private final net.minecraft.entity.EntityType type; + + public FabricEntityType(net.minecraft.entity.EntityType type) { + this.type = type; + } + + @Override + public net.minecraft.entity.EntityType getHandle() { + return type; + } +} diff --git a/platforms/fabric/src/main/resources/terra.mixins.json b/platforms/fabric/src/main/resources/terra.mixins.json index fda32e1f8..6bf2e183f 100644 --- a/platforms/fabric/src/main/resources/terra.mixins.json +++ b/platforms/fabric/src/main/resources/terra.mixins.json @@ -4,6 +4,7 @@ "package": "com.dfsek.terra.fabric.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ + "MobSpawnerLogicAccessor", "StateAccessor" ], "client": [