wip: block tweaker

This commit is contained in:
Bixilon 2020-12-29 16:48:54 +01:00
parent 9a263e44ed
commit 4f46f98c64
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
12 changed files with 119 additions and 8 deletions

View File

@ -20,10 +20,12 @@ import java.util.Objects;
public class ModIdentifier {
protected final String mod;
protected final String identifier;
public final String fullIdentifier;
public ModIdentifier(String mod, String identifier) {
this.mod = mod;
this.identifier = identifier;
this.fullIdentifier = mod + ":" + identifier;
}
public ModIdentifier(String fullIdentifier) {
@ -31,15 +33,17 @@ public class ModIdentifier {
if (split.length == 1) {
this.mod = ProtocolDefinition.DEFAULT_MOD;
this.identifier = fullIdentifier;
return;
} else {
this.mod = split[0];
this.identifier = split[1];
}
this.mod = split[0];
this.identifier = split[1];
this.fullIdentifier = this.mod + ":" + this.identifier;
}
public ModIdentifier(ModIdentifier identifier) {
this.mod = identifier.getMod();
this.identifier = identifier.getIdentifier();
this.fullIdentifier = identifier.getFullIdentifier();
}
public static ModIdentifier getIdentifier(String identifier) throws IllegalArgumentException {
@ -60,7 +64,7 @@ public class ModIdentifier {
}
public String getFullIdentifier() {
return String.format("%s:%s", this.mod, this.identifier);
return this.fullIdentifier;
}
@Override

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.mappings.blocks;
import de.bixilon.minosoft.data.mappings.ModIdentifier;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Objects;
@ -34,6 +35,12 @@ public class Block extends ModIdentifier {
this.rotation = BlockRotations.NONE;
}
public Block(String fullIdentifier, BlockProperties... properties) {
super(fullIdentifier);
this.properties = new HashSet<>(Arrays.asList(properties));
this.rotation = BlockRotations.NONE;
}
public Block(String mod, String identifier, BlockRotations rotation) {
super(mod, identifier);
this.properties = new HashSet<>();

View File

@ -0,0 +1,12 @@
package de.bixilon.minosoft.data.mappings.tweaker;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties;
public final class TweakBlocks {
public static final Block GRASS_BLOCK_SNOWY_YES = new Block("grass", BlockProperties.GRASS_SNOWY_YES);
public static final Block GRASS_BLOCK_SNOWY_NO = new Block("grass", BlockProperties.GRASS_SNOWY_NO);
public static final Block SNOW = new Block("snow");
public static final Block SNOW_LAYER = new Block("snow_layer");
}

View File

@ -11,7 +11,7 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.mappings;
package de.bixilon.minosoft.data.mappings.tweaker;
import de.bixilon.minosoft.data.entities.EntityMetaData;
import de.bixilon.minosoft.data.entities.EntityMetaDataFields;
@ -19,6 +19,14 @@ import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.animal.horse.*;
import de.bixilon.minosoft.data.entities.entities.monster.*;
import de.bixilon.minosoft.data.entities.entities.vehicle.*;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import de.bixilon.minosoft.data.world.Chunk;
import de.bixilon.minosoft.data.world.ChunkSection;
import de.bixilon.minosoft.data.world.InChunkLocation;
import de.bixilon.minosoft.data.world.InChunkSectionLocation;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import java.util.Map;
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_1_8_9;
@ -81,4 +89,47 @@ public class VersionTweaker {
}
return fakeClass;
}
public static Chunk transformChunk(Chunk chunk, int versionId) {
// some blocks need to be tweaked. eg. Grass with a snow block on top becomes snowy grass block
if (versionId >= ProtocolDefinition.FLATTING_VERSION_ID) {
return chunk;
}
for (Map.Entry<Byte, ChunkSection> sectionEntry : chunk.getSections().entrySet()) {
for (Map.Entry<InChunkSectionLocation, Block> blockEntry : sectionEntry.getValue().getBlocks().entrySet()) {
Block newBlock = transformBlock(blockEntry.getValue(), chunk, blockEntry.getKey(), sectionEntry.getKey());
if (newBlock == blockEntry.getValue()) {
continue;
}
sectionEntry.getValue().setBlock(blockEntry.getKey(), newBlock);
}
}
return chunk;
}
public static Block transformBlock(Block originalBlock, Chunk chunk, InChunkLocation location) {
return transformBlock(originalBlock, chunk, location.getInChunkSectionLocation(), (byte) (location.getY() / ProtocolDefinition.SECTION_HEIGHT_Y));
}
public static Block transformBlock(Block originalBlock, Chunk chunk, InChunkSectionLocation location, byte sectionHeight) {
switch (originalBlock.getFullIdentifier()) {
case "minecraft:grass" -> {
Block above = getBlockAbove(chunk, location, sectionHeight);
if (above == null) {
break;
}
if (above.equals(TweakBlocks.SNOW) || above.equals(TweakBlocks.SNOW_LAYER)) {
return TweakBlocks.GRASS_BLOCK_SNOWY_YES;
} else {
return TweakBlocks.GRASS_BLOCK_SNOWY_NO;
}
}
// ToDo: all blocks. e.g. doors, etc
}
return originalBlock;
}
private static Block getBlockAbove(Chunk chunk, InChunkSectionLocation location, byte sectionHeight) {
return chunk.getBlock(location.getInChunkLocation(sectionHeight));
}
}

View File

@ -82,4 +82,8 @@ public class Chunk {
public void setBlockEntityData(HashMap<InChunkLocation, BlockEntityMetaData> blockEntities) {
blockEntities.forEach(this::setBlockEntityData);
}
public HashMap<Byte, ChunkSection> getSections() {
return this.sections;
}
}

View File

@ -12,6 +12,8 @@
*/
package de.bixilon.minosoft.data.world
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
/**
* Chunk X, Y and Z location (max 16x16x16)
*/
@ -20,4 +22,8 @@ data class InChunkSectionLocation(val x: Int, val y: Int, val z: Int) {
override fun toString(): String {
return "($x $y $z)"
}
fun getInChunkLocation(sectionHeight: Byte): InChunkLocation {
return InChunkLocation(x, y + ProtocolDefinition.SECTION_HEIGHT_Y * sectionHeight, z)
}
}

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.data.world.BlockPosition;
import de.bixilon.minosoft.data.world.Chunk;
import de.bixilon.minosoft.logging.Log;
@ -50,7 +51,14 @@ public class PacketBlockChange extends ClientboundPacket {
}
connection.fireEvent(new BlockChangeEvent(connection, this));
chunk.setBlock(getPosition().getInChunkLocation(), getBlock());
// tweak
if (!connection.getVersion().isFlattened()) {
Block block = VersionTweaker.transformBlock(getBlock(), chunk, getPosition().getInChunkLocation());
chunk.setBlock(getPosition().getInChunkLocation(), block);
} else {
chunk.setBlock(getPosition().getInChunkLocation(), getBlock());
}
}
@Override

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.data.world.Chunk;
import de.bixilon.minosoft.data.world.ChunkLocation;
import de.bixilon.minosoft.logging.Log;
@ -78,6 +79,8 @@ public class PacketChunkBulk extends ClientboundPacket {
@Override
public void handle(Connection connection) {
this.chunks.values().forEach((chunk) -> VersionTweaker.transformChunk(chunk, connection.getVersion().getVersionId()));
getChunks().forEach(((location, chunk) -> connection.fireEvent(new ChunkDataChangeEvent(connection, location, chunk))));
connection.getPlayer().getWorld().setChunks(getChunks());

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.entities.block.BlockEntityMetaData;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.data.world.BlockPosition;
import de.bixilon.minosoft.data.world.Chunk;
import de.bixilon.minosoft.data.world.ChunkLocation;
@ -114,6 +115,8 @@ public class PacketChunkData extends ClientboundPacket {
@Override
public void handle(Connection connection) {
getBlockEntities().forEach(((position, compoundTag) -> connection.fireEvent(new BlockEntityMetaDataChangeEvent(connection, position, null, compoundTag))));
VersionTweaker.transformChunk(this.chunk, connection.getVersion().getVersionId());
connection.fireEvent(new ChunkDataChangeEvent(connection, this));
connection.getPlayer().getWorld().setChunk(getLocation(), getChunk());

View File

@ -14,6 +14,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.data.world.Chunk;
import de.bixilon.minosoft.data.world.ChunkLocation;
import de.bixilon.minosoft.data.world.InChunkLocation;
@ -24,6 +25,7 @@ import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import java.util.HashMap;
import java.util.Map;
import static de.bixilon.minosoft.protocol.protocol.ProtocolVersions.*;
@ -86,6 +88,17 @@ public class PacketMultiBlockChange extends ClientboundPacket {
}
connection.fireEvent(new MultiBlockChangeEvent(connection, this));
chunk.setBlocks(getBlocks());
// tweak
if (!connection.getVersion().isFlattened()) {
for (Map.Entry<InChunkLocation, Block> entry : getBlocks().entrySet()) {
Block block = VersionTweaker.transformBlock(entry.getValue(), chunk, entry.getKey());
if (block == entry.getValue()) {
continue;
}
chunk.setBlock(entry.getKey(), block);
}
}
}
@Override

View File

@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.entities.Location;
import de.bixilon.minosoft.data.entities.Velocity;
import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.UnknownEntityException;
import de.bixilon.minosoft.data.mappings.VersionTweaker;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent;
import de.bixilon.minosoft.protocol.network.Connection;

View File

@ -19,7 +19,7 @@ import de.bixilon.minosoft.data.entities.Objects;
import de.bixilon.minosoft.data.entities.Velocity;
import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.entities.entities.UnknownEntityException;
import de.bixilon.minosoft.data.mappings.VersionTweaker;
import de.bixilon.minosoft.data.mappings.tweaker.VersionTweaker;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.modding.event.events.EntitySpawnEvent;
import de.bixilon.minosoft.protocol.network.Connection;