blockId: Map all available block states to it

This commit is contained in:
Bixilon 2020-12-19 15:31:06 +01:00
parent 0fbf4ec67f
commit 2be01a1282
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 105 additions and 103 deletions

View File

@ -14,8 +14,8 @@
package de.bixilon.minosoft.data;
public enum Mappings {
BLOCKS,
REGISTRIES,
BLOCKS,
ENTITIES;
public String getFilename() {

View File

@ -13,13 +13,34 @@
package de.bixilon.minosoft.data.mappings;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import java.util.HashSet;
public class BlockId extends ModIdentifier {
private final HashSet<Block> blocks;
public BlockId(String mod, String identifier, HashSet<Block> blocks) {
super(mod, identifier);
this.blocks = blocks;
}
public BlockId(String mod, String identifier) {
super(mod, identifier);
this.blocks = new HashSet<>();
}
public BlockId(String fullIdentifier) {
super(fullIdentifier);
this.blocks = new HashSet<>();
}
public BlockId(ModIdentifier identifier) {
super(identifier);
this.blocks = new HashSet<>();
}
public HashSet<Block> getBlocks() {
return this.blocks;
}
}

View File

@ -37,6 +37,11 @@ public class ModIdentifier {
this.identifier = split[1];
}
public ModIdentifier(ModIdentifier identifier) {
this.mod = identifier.getMod();
this.identifier = identifier.getIdentifier();
}
public String getMod() {
return this.mod;
}

View File

@ -1,96 +0,0 @@
/*
* Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.data.mappings.blocks;
import com.google.common.collect.HashBiMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import de.bixilon.minosoft.config.StaticConfiguration;
import java.util.HashSet;
public class Blocks {
public static HashBiMap<Integer, Block> load(String mod, JsonObject json, boolean metaData) {
HashBiMap<Integer, Block> versionMapping = HashBiMap.create(json.size() * 10);
for (String identifierName : json.keySet()) {
JsonObject identifierJSON = json.getAsJsonObject(identifierName);
JsonArray statesArray = identifierJSON.getAsJsonArray("states");
for (int i = 0; i < statesArray.size(); i++) {
JsonObject statesJSON = statesArray.get(i).getAsJsonObject();
Block block;
if (statesJSON.has("properties")) {
// properties are optional
JsonObject propertiesJSON = statesJSON.getAsJsonObject("properties");
BlockRotations rotation = BlockRotations.NONE;
if (propertiesJSON.has("facing")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("facing").getAsString());
propertiesJSON.remove("facing");
} else if (propertiesJSON.has("rotation")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("rotation").getAsString());
propertiesJSON.remove("rotation");
} else if (propertiesJSON.has("orientation")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("orientation").getAsString());
propertiesJSON.remove("orientation");
} else if (propertiesJSON.has("axis")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("axis").getAsString());
propertiesJSON.remove("axis");
}
HashSet<BlockProperties> properties = new HashSet<>();
for (String propertyName : propertiesJSON.keySet()) {
if (StaticConfiguration.DEBUG_MODE) {
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName) == null) {
throw new RuntimeException(String.format("Unknown block property: %s (identifier=%s)", propertyName, identifierName));
}
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()) == null) {
throw new RuntimeException(String.format("Unknown block property: %s -> %s (identifier=%s)", propertyName, propertiesJSON.get(propertyName).getAsString(), identifierName));
}
}
properties.add(BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()));
}
block = new Block(mod, identifierName, properties, rotation);
} else {
// no properties, directly add block
block = new Block(mod, identifierName);
}
int blockId = getBlockId(statesJSON, metaData);
if (StaticConfiguration.DEBUG_MODE) {
checkAndCrashIfBlockIsIn(blockId, identifierName, versionMapping);
}
versionMapping.put(blockId, block);
}
}
return versionMapping;
}
private static int getBlockId(JsonObject json, boolean metaData) {
int blockId = json.get("id").getAsInt();
if (metaData) {
blockId <<= 4;
if (json.has("meta")) {
// old format (with metadata)
blockId |= json.get("meta").getAsByte();
}
}
return blockId;
}
private static void checkAndCrashIfBlockIsIn(int blockId, String identifierName, HashBiMap<Integer, Block> versionMapping) {
if (versionMapping.containsKey(blockId)) {
throw new RuntimeException(String.format("Block Id %s is already present for %s! (identifier=%s)", blockId, versionMapping.get(blockId), identifierName));
}
}
}

View File

@ -17,6 +17,7 @@ import com.google.common.collect.HashBiMap;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import de.bixilon.minosoft.config.StaticConfiguration;
import de.bixilon.minosoft.data.EntityClassMappings;
import de.bixilon.minosoft.data.Mappings;
import de.bixilon.minosoft.data.entities.EntityInformation;
@ -24,7 +25,8 @@ import de.bixilon.minosoft.data.entities.EntityMetaDataFields;
import de.bixilon.minosoft.data.entities.entities.Entity;
import de.bixilon.minosoft.data.mappings.*;
import de.bixilon.minosoft.data.mappings.blocks.Block;
import de.bixilon.minosoft.data.mappings.blocks.Blocks;
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties;
import de.bixilon.minosoft.data.mappings.blocks.BlockRotations;
import de.bixilon.minosoft.data.mappings.particle.Particle;
import de.bixilon.minosoft.data.mappings.statistics.Statistic;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
@ -66,6 +68,24 @@ public class VersionMapping {
this.parentMapping = parentMapping;
}
private static int getBlockId(JsonObject json, boolean metaData) {
int blockId = json.get("id").getAsInt();
if (metaData) {
blockId <<= 4;
if (json.has("meta")) {
// old format (with metadata)
blockId |= json.get("meta").getAsByte();
}
}
return blockId;
}
private static void checkAndCrashIfBlockIsIn(int blockId, String identifierName, HashBiMap<Integer, Block> versionMapping) {
if (versionMapping.containsKey(blockId)) {
throw new RuntimeException(String.format("Block Id %s is already present for %s! (identifier=%s)", blockId, versionMapping.get(blockId), identifierName));
}
}
public Motive getMotiveByIdentifier(String identifier) {
if (this.parentMapping != null) {
Motive motive = this.parentMapping.getMotiveByIdentifier(identifier);
@ -373,7 +393,59 @@ public class VersionMapping {
if (data == null) {
break;
}
this.blockMap = Blocks.load(mod, data, !version.isFlattened());
for (String identifierName : data.keySet()) {
JsonObject identifierJSON = data.getAsJsonObject(identifierName);
JsonArray statesArray = identifierJSON.getAsJsonArray("states");
for (int i = 0; i < statesArray.size(); i++) {
JsonObject statesJSON = statesArray.get(i).getAsJsonObject();
Block block;
if (statesJSON.has("properties")) {
// properties are optional
JsonObject propertiesJSON = statesJSON.getAsJsonObject("properties");
BlockRotations rotation = BlockRotations.NONE;
if (propertiesJSON.has("facing")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("facing").getAsString());
propertiesJSON.remove("facing");
} else if (propertiesJSON.has("rotation")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("rotation").getAsString());
propertiesJSON.remove("rotation");
} else if (propertiesJSON.has("orientation")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("orientation").getAsString());
propertiesJSON.remove("orientation");
} else if (propertiesJSON.has("axis")) {
rotation = BlockRotations.ROTATION_MAPPING.get(propertiesJSON.get("axis").getAsString());
propertiesJSON.remove("axis");
}
HashSet<BlockProperties> properties = new HashSet<>();
for (String propertyName : propertiesJSON.keySet()) {
if (StaticConfiguration.DEBUG_MODE) {
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName) == null) {
throw new RuntimeException(String.format("Unknown block property: %s (identifier=%s)", propertyName, identifierName));
}
if (BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()) == null) {
throw new RuntimeException(String.format("Unknown block property: %s -> %s (identifier=%s)", propertyName, propertiesJSON.get(propertyName).getAsString(), identifierName));
}
}
properties.add(BlockProperties.PROPERTIES_MAPPING.get(propertyName).get(propertiesJSON.get(propertyName).getAsString()));
}
block = new Block(mod, identifierName, properties, rotation);
// map block id
this.blockIdMap.get(this.blockIdMap.inverse().get(new BlockId(block))).getBlocks().add(block);
} else {
// no properties, directly add block
block = new Block(mod, identifierName);
}
int blockId = getBlockId(statesJSON, !version.isFlattened());
if (StaticConfiguration.DEBUG_MODE) {
checkAndCrashIfBlockIsIn(blockId, identifierName, this.blockMap);
}
this.blockMap.put(blockId, block);
}
}
}
case ENTITIES -> {
if (data == null) {
@ -492,7 +564,7 @@ public class VersionMapping {
return true;
}
}
return this.itemMap.containsValue(new Item(identifier.getFullIdentifier()));
return this.itemMap.containsValue(identifier);
}
public boolean doesBlockExist(ModIdentifier identifier) {
@ -501,7 +573,7 @@ public class VersionMapping {
return true;
}
}
return this.blockIdMap.containsValue(new BlockId(identifier.getFullIdentifier()));
return this.blockIdMap.containsValue(identifier);
}
public boolean doesEnchantmentExist(ModIdentifier identifier) {
@ -510,7 +582,7 @@ public class VersionMapping {
return true;
}
}
return this.enchantmentMap.containsValue(new Enchantment(identifier.getFullIdentifier()));
return this.enchantmentMap.containsValue(identifier);
}
public boolean doesMobEffectExist(ModIdentifier identifier) {
@ -519,6 +591,6 @@ public class VersionMapping {
return true;
}
}
return this.mobEffectMap.containsValue(new MobEffect(identifier.getFullIdentifier()));
return this.mobEffectMap.containsValue(identifier);
}
}