block properties: refactor and improve block properties

This commit is contained in:
Bixilon 2021-03-15 00:53:27 +01:00
parent 28d9f9bbdc
commit daa52f08c5
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
25 changed files with 832 additions and 569 deletions

View File

@ -15,9 +15,9 @@ package de.bixilon.minosoft.data.commands.parser
import de.bixilon.minosoft.data.commands.CommandStringReader
import de.bixilon.minosoft.data.commands.parser.exceptions.*
import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties
import de.bixilon.minosoft.data.mappings.blocks.BlockRotations
import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
import de.bixilon.minosoft.protocol.network.Connection
class BlockStateParser : CommandParser() {
@ -38,22 +38,25 @@ class BlockStateParser : CommandParser() {
val propertyMap = stringReader.readProperties()
var rotation: BlockRotations? = null
val allProperties = HashSet<BlockProperties>()
for (pair in propertyMap) {
val allProperties: MutableMap<BlockProperties, Any> = mutableMapOf()
for ((groupName, value) in propertyMap) {
if (pair.key == "facing" || pair.key == "rotation" || pair.key == "orientation" || pair.key == "axis") {
if (BlockState.ROTATION_PROPERTIES.contains(groupName)) {
if (rotation != null) {
throw BlockPropertyDuplicatedCommandParseException(stringReader, pair.key)
throw BlockPropertyDuplicatedCommandParseException(stringReader, groupName)
}
rotation = BlockRotations.ROTATION_MAPPING[pair.value]
rotation = BlockRotations.ROTATION_MAPPING[value]
if (rotation == null) {
throw UnknownBlockPropertyCommandParseException(stringReader, pair.value)
throw UnknownBlockPropertyCommandParseException(stringReader, value)
}
continue
}
val blockPropertyKey = BlockProperties.PROPERTIES_MAPPING[pair.key] ?: throw UnknownBlockPropertyCommandParseException(stringReader, pair.key)
val blockProperty = blockPropertyKey[pair.value] ?: throw UnknownBlockPropertyCommandParseException(stringReader, pair.value)
allProperties.add(blockProperty)
val (parsedGroup, parsedValue) = try {
BlockProperties.parseProperty(groupName, value)
} catch (exception: Throwable) {
throw UnknownBlockPropertyCommandParseException(stringReader, value)
}
allProperties[parsedGroup] = parsedValue
}
for (state in block.states) {
if (state.bareEquals(BlockState(block, allProperties, rotation ?: BlockRotations.NONE))) {

View File

@ -1,520 +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 java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public enum BlockProperties {
// rails, doors, daylight sensor, ...
REDSTONE_POWERED_YES,
REDSTONE_POWERED_NO,
REDSTONE_INVERTED_YES,
REDSTONE_INVERTED_NO,
// furnace, candles, redstone torches, ...
GENERAL_LIT_YES,
GENERAL_LIT_NO,
// sign, fence, trapdoors, stairs, ...
GENERAL_WATERLOGGED_YES,
GENERAL_WATERLOGGED_NO,
// stairs
STAIR_DIRECTIONAL_STRAIGHT("shape", "straight"),
STAIR_DIRECTIONAL_INNER_LEFT("shape", "inner_left"),
STAIR_DIRECTIONAL_INNER_RIGHT("shape", "inner_right"),
STAIR_DIRECTIONAL_OUTER_LEFT("shape", "outer_left"),
STAIR_DIRECTIONAL_OUTER_RIGHT("shape", "outer_right"),
STAIR_HALF_TOP,
STAIR_HALF_BOTTOM,
// slabs
SLAB_TYPE_TOP,
SLAB_TYPE_BOTTOM,
SLAB_TYPE_DOUBLE,
// farmland
FARMLAND_MOISTURE_LEVEL_0,
FARMLAND_MOISTURE_LEVEL_1,
FARMLAND_MOISTURE_LEVEL_2,
FARMLAND_MOISTURE_LEVEL_3,
FARMLAND_MOISTURE_LEVEL_4,
FARMLAND_MOISTURE_LEVEL_5,
FARMLAND_MOISTURE_LEVEL_6,
FARMLAND_MOISTURE_LEVEL_7,
// plants, stairs
PLANT_HALF_UPPER,
PLANT_HALF_LOWER,
// fluids
FLUID_LEVEL_0("level"),
FLUID_LEVEL_1("level"),
FLUID_LEVEL_2("level"),
FLUID_LEVEL_3("level"),
FLUID_LEVEL_4("level"),
FLUID_LEVEL_5("level"),
FLUID_LEVEL_6("level"),
FLUID_LEVEL_7("level"),
FLUID_LEVEL_8("level"),
FLUID_LEVEL_9("level"),
FLUID_LEVEL_10("level"),
FLUID_LEVEL_11("level"),
FLUID_LEVEL_12("level"),
FLUID_LEVEL_13("level"),
FLUID_LEVEL_14("level"),
FLUID_LEVEL_15("level"),
// bee hive
HONEY_LEVEL_0("honey_level"),
HONEY_LEVEL_1("honey_level"),
HONEY_LEVEL_2("honey_level"),
HONEY_LEVEL_3("honey_level"),
HONEY_LEVEL_4("honey_level"),
HONEY_LEVEL_5("honey_level"),
// pistons
PISTON_EXTENDED_YES,
PISTON_EXTENDED_NO,
// piston head
PISTON_TYPE_NORMAL,
PISTON_TYPE_STICKY,
PISTON_SHORT_YES,
PISTON_SHORT_NO,
// rails
RAILS_DIRECTION_NORTH_SOUTH("shape", "north_south"),
RAILS_DIRECTION_SOUTH_EAST("shape", "south_east"),
RAILS_DIRECTION_SOUTH_WEST("shape", "south_west"),
RAILS_DIRECTION_NORTH_WEST("shape", "north_west"),
RAILS_DIRECTION_NORTH_EAST("shape", "north_east"),
RAILS_DIRECTION_EAST_WEST("shape", "east_west"),
RAILS_DIRECTION_ASCENDING_EAST("shape", "ascending_east"),
RAILS_DIRECTION_ASCENDING_WEST("shape", "ascending_west"),
RAILS_DIRECTION_ASCENDING_NORTH("shape", "ascending_north"),
RAILS_DIRECTION_ASCENDING_SOUTH("shape", "ascending_south"),
// grass, mycelium
GRASS_SNOWY_YES,
GRASS_SNOWY_NO,
// bamboo, sapling, plants
PLANTS_STAGE_LEVEL_0,
PLANTS_STAGE_LEVEL_1,
// dispenser
DISPENSER_TRIGGERED_YES,
DISPENSER_TRIGGERED_NO,
// leaves
LEAVES_DISTANCE_LEVEL_0,
LEAVES_DISTANCE_LEVEL_1,
LEAVES_DISTANCE_LEVEL_2,
LEAVES_DISTANCE_LEVEL_3,
LEAVES_DISTANCE_LEVEL_4,
LEAVES_DISTANCE_LEVEL_5,
LEAVES_DISTANCE_LEVEL_6,
LEAVES_DISTANCE_LEVEL_7,
LEAVES_PERSISTENT_YES,
LEAVES_PERSISTENT_NO,
// bed
BED_PART_HEAD,
BED_PART_FOOT,
BED_OCCUPIED_YES,
BED_OCCUPIED_NO,
// tnt
TNT_UNSTABLE_YES,
TNT_UNSTABLE_NO,
// door
DOOR_HINGE_LEFT,
DOOR_HINGE_RIGHT,
DOOR_OPEN_YES,
DOOR_OPEN_NO,
// fire
FIRE_POSITION_NORTH_YES,
FIRE_POSITION_NORTH_NO,
FIRE_POSITION_SOUTH_YES,
FIRE_POSITION_SOUTH_NO,
FIRE_POSITION_EAST_YES,
FIRE_POSITION_EAST_NO,
FIRE_POSITION_WEST_YES,
FIRE_POSITION_WEST_NO,
FIRE_POSITION_UP_YES,
FIRE_POSITION_UP_NO,
FIRE_POSITION_DOWN_YES,
FIRE_POSITION_DOWN_NO,
FIRE_AGE_LEVEL_0,
FIRE_AGE_LEVEL_1,
FIRE_AGE_LEVEL_2,
FIRE_AGE_LEVEL_3,
FIRE_AGE_LEVEL_4,
FIRE_AGE_LEVEL_5,
FIRE_AGE_LEVEL_6,
FIRE_AGE_LEVEL_7,
FIRE_AGE_LEVEL_8,
FIRE_AGE_LEVEL_9,
FIRE_AGE_LEVEL_10,
FIRE_AGE_LEVEL_11,
FIRE_AGE_LEVEL_12,
FIRE_AGE_LEVEL_13,
FIRE_AGE_LEVEL_14,
FIRE_AGE_LEVEL_15,
FIRE_AGE_LEVEL_16,
FIRE_AGE_LEVEL_17,
FIRE_AGE_LEVEL_18,
FIRE_AGE_LEVEL_19,
FIRE_AGE_LEVEL_20,
FIRE_AGE_LEVEL_21,
FIRE_AGE_LEVEL_22,
FIRE_AGE_LEVEL_23,
FIRE_AGE_LEVEL_24,
FIRE_AGE_LEVEL_25,
// noteblock
NOTEBLOCK_INSTRUMENT_HARP,
NOTEBLOCK_INSTRUMENT_BASE_DRUM("instrument", "basedrum"),
NOTEBLOCK_INSTRUMENT_SNARE,
NOTEBLOCK_INSTRUMENT_HAT,
NOTEBLOCK_INSTRUMENT_BASS,
NOTEBLOCK_INSTRUMENT_FLUTE,
NOTEBLOCK_INSTRUMENT_BELL,
NOTEBLOCK_INSTRUMENT_GUITAR,
NOTEBLOCK_INSTRUMENT_CHIME,
NOTEBLOCK_INSTRUMENT_XYLOPHONE,
NOTEBLOCK_INSTRUMENT_IRON_XYLOPHONE("instrument", "iron_xylophone"),
NOTEBLOCK_INSTRUMENT_COW_BELL("instrument", "cow_bell"),
NOTEBLOCK_INSTRUMENT_DIDGERIDOO,
NOTEBLOCK_INSTRUMENT_BIT,
NOTEBLOCK_INSTRUMENT_BANJO,
NOTEBLOCK_INSTRUMENT_PLING,
NOTEBLOCK_NOTE_LEVEL_0,
NOTEBLOCK_NOTE_LEVEL_1,
NOTEBLOCK_NOTE_LEVEL_2,
NOTEBLOCK_NOTE_LEVEL_3,
NOTEBLOCK_NOTE_LEVEL_4,
NOTEBLOCK_NOTE_LEVEL_5,
NOTEBLOCK_NOTE_LEVEL_6,
NOTEBLOCK_NOTE_LEVEL_7,
NOTEBLOCK_NOTE_LEVEL_8,
NOTEBLOCK_NOTE_LEVEL_9,
NOTEBLOCK_NOTE_LEVEL_10,
NOTEBLOCK_NOTE_LEVEL_11,
NOTEBLOCK_NOTE_LEVEL_12,
NOTEBLOCK_NOTE_LEVEL_13,
NOTEBLOCK_NOTE_LEVEL_14,
NOTEBLOCK_NOTE_LEVEL_15,
NOTEBLOCK_NOTE_LEVEL_16,
NOTEBLOCK_NOTE_LEVEL_17,
NOTEBLOCK_NOTE_LEVEL_18,
NOTEBLOCK_NOTE_LEVEL_19,
NOTEBLOCK_NOTE_LEVEL_20,
NOTEBLOCK_NOTE_LEVEL_21,
NOTEBLOCK_NOTE_LEVEL_22,
NOTEBLOCK_NOTE_LEVEL_23,
NOTEBLOCK_NOTE_LEVEL_24,
// redstone
REDSTONE_POWER_0,
REDSTONE_POWER_1,
REDSTONE_POWER_2,
REDSTONE_POWER_3,
REDSTONE_POWER_4,
REDSTONE_POWER_5,
REDSTONE_POWER_6,
REDSTONE_POWER_7,
REDSTONE_POWER_8,
REDSTONE_POWER_9,
REDSTONE_POWER_10,
REDSTONE_POWER_11,
REDSTONE_POWER_12,
REDSTONE_POWER_13,
REDSTONE_POWER_14,
REDSTONE_POWER_15,
REDSTONE_POSITION_NORTH_NONE("north", "none"),
REDSTONE_POSITION_NORTH_LOW("north", "low"),
REDSTONE_POSITION_NORTH_UP("north", "up"),
REDSTONE_POSITION_NORTH_SIDE("north", "side"),
REDSTONE_POSITION_NORTH_TALL("north", "tall"),
REDSTONE_POSITION_WEST_NONE("west", "none"),
REDSTONE_POSITION_WEST_LOW("west", "low"),
REDSTONE_POSITION_WEST_UP("west", "up"),
REDSTONE_POSITION_WEST_SIDE("west", "side"),
REDSTONE_POSITION_WEST_TALL("west", "tall"),
REDSTONE_POSITION_SOUTH_NONE("south", "none"),
REDSTONE_POSITION_SOUTH_LOW("south", "low"),
REDSTONE_POSITION_SOUTH_UP("south", "up"),
REDSTONE_POSITION_SOUTH_SIDE("south", "side"),
REDSTONE_POSITION_SOUTH_TALL("south", "tall"),
REDSTONE_POSITION_EAST_NONE("east", "none"),
REDSTONE_POSITION_EAST_LOW("east", "low"),
REDSTONE_POSITION_EAST_UP("east", "up"),
REDSTONE_POSITION_EAST_SIDE("east", "side"),
REDSTONE_POSITION_EAST_TALL("east", "tall"),
// snow
SNOW_LAYERS_LEVEL_1,
SNOW_LAYERS_LEVEL_2,
SNOW_LAYERS_LEVEL_3,
SNOW_LAYERS_LEVEL_4,
SNOW_LAYERS_LEVEL_5,
SNOW_LAYERS_LEVEL_6,
SNOW_LAYERS_LEVEL_7,
SNOW_LAYERS_LEVEL_8,
// fence
FENCE_IN_WALL_YES("in_wall"),
FENCE_IN_WALL_NO("in_wall"),
// scaffolding
SCAFFOLDING_BOTTOM_YES,
SCAFFOLDING_BOTTOM_NO,
// tripwire
TRIPWIRE_DISARMED_YES,
TRIPWIRE_DISARMED_NO,
TRIPWIRE_IN_AIR_YES("in_air"),
TRIPWIRE_IN_AIR_NO("in_air"),
// tripwire hook
TRIPWIRE_ATTACHED_YES,
TRIPWIRE_ATTACHED_NO,
// structure block, comparator
STRUCTURE_BLOCK_MODE_SAVE("mode", "save"),
STRUCTURE_BLOCK_MODE_LOAD("mode", "load"),
STRUCTURE_BLOCK_MODE_CORNER("mode", "corner"),
STRUCTURE_BLOCK_MODE_DATA("mode", "data"),
STRUCTURE_BLOCK_MODE_COMPARE("mode", "compare"),
STRUCTURE_BLOCK_MODE_SUBTRACT("mode", "subtract"),
// command block
COMMAND_BLOCK_CONDITIONAL_YES,
COMMAND_BLOCK_CONDITIONAL_NO,
// double column
BUBBLE_COLUMN_DRAG_YES("drag"), // whirlpool
BUBBLE_COLUMN_DRAG_NO("drag"), // upwards
// bell
BELL_ATTACHMENT_FLOOR,
BELL_ATTACHMENT_CEILING,
BELL_ATTACHMENT_SINGLE_WALL("attachment", "single_wall"),
BELL_ATTACHMENT_DOUBLE_WALL("attachment", "double_wall"),
// lantern
LANTERN_HANGING_YES,
LANTERN_HANGING_NO,
// sea pickle
SEA_PICKLE_PICKLES_LEVEL_1,
SEA_PICKLE_PICKLES_LEVEL_2,
SEA_PICKLE_PICKLES_LEVEL_3,
SEA_PICKLE_PICKLES_LEVEL_4,
// lectern
LECTERN_BOOK_YES("has_book"),
LECTERN_BOOK_NO("has_book"),
// brewing stand
BREWING_STAND_BOTTLE_0_YES("has_bottle_0"),
BREWING_STAND_BOTTLE_0_NO("has_bottle_0"),
BREWING_STAND_BOTTLE_1_YES("has_bottle_1"),
BREWING_STAND_BOTTLE_1_NO("has_bottle_1"),
BREWING_STAND_BOTTLE_2_YES("has_bottle_2"),
BREWING_STAND_BOTTLE_2_NO("has_bottle_2"),
// chest
CHEST_TYPE_SINGLE,
CHEST_TYPE_LEFT,
CHEST_TYPE_RIGHT,
// cake
CAKES_BITES_LEVEL_0,
CAKES_BITES_LEVEL_1,
CAKES_BITES_LEVEL_2,
CAKES_BITES_LEVEL_3,
CAKES_BITES_LEVEL_4,
CAKES_BITES_LEVEL_5,
CAKES_BITES_LEVEL_6,
// bamboo
BAMBOO_LEAVES_NONE,
BAMBOO_LEAVES_SMALL,
BAMBOO_LEAVES_LARGE,
// repeater
REPEATER_LOCKED_YES,
REPEATER_LOCKED_NO,
REPEATER_DELAY_LEVEL_1,
REPEATER_DELAY_LEVEL_2,
REPEATER_DELAY_LEVEL_3,
REPEATER_DELAY_LEVEL_4,
// end portal frame
PORTAL_FRAME_EYE_YES,
PORTAL_FRAME_EYE_NO,
// jukebox
JUKEBOX_HAS_RECORD_YES("has_record"),
JUKEBOX_HAS_RECORD_NO("has_record"),
// campfire
CAMPFIRE_SIGNAL_FIRE_YES("signal_fire"),
CAMPFIRE_SIGNAL_FIRE_NO("signal_fire"),
// turtle eggs
TURTLE_EGGS_EGGS_LEVEL_1("eggs"),
TURTLE_EGGS_EGGS_LEVEL_2("eggs"),
TURTLE_EGGS_EGGS_LEVEL_3("eggs"),
TURTLE_EGGS_EGGS_LEVEL_4("eggs"),
TURTLE_EGGS_HATCH_LEVEL_0("hatch"),
TURTLE_EGGS_HATCH_LEVEL_1("hatch"),
TURTLE_EGGS_HATCH_LEVEL_2("hatch"),
// respawn anchor
RESPAWN_ANCHOR_CHARGES_LEVEL_0,
RESPAWN_ANCHOR_CHARGES_LEVEL_1,
RESPAWN_ANCHOR_CHARGES_LEVEL_2,
RESPAWN_ANCHOR_CHARGES_LEVEL_3,
RESPAWN_ANCHOR_CHARGES_LEVEL_4,
// candles
CANDLE_CANDLES_LEVEL_1,
CANDLE_CANDLES_LEVEL_2,
CANDLE_CANDLES_LEVEL_3,
CANDLE_CANDLES_LEVEL_4,
// grindstone
GRINDSTONE_FACE_FLOOR,
GRINDSTONE_FACE_WALL,
GRINDSTONE_FACE_CEILING,
// hopper
HOPPER_ENABLED_YES,
HOPPER_ENABLED_NO,
// button
BUTTON_FACE_FLOOR,
BUTTON_FACE_WALL,
BUTTON_FACE_CEILING,
POINTED_DRIPSTONE_THICKNESS_TIP_MERGE("thickness", "tip_merge"),
POINTED_DRIPSTONE_THICKNESS_TIP("thickness", "tip"),
POINTED_DRIPSTONE_THICKNESS_FRUSTUM("thickness", "frustum"),
POINTED_DRIPSTONE_THICKNESS_MIDDLE("thickness", "middle"),
POINTED_DRIPSTONE_THICKNESS_BASE("thickness", "base"),
POINTED_DRIPSTONE_VERTICAL_DIRECTION_UP("vertical_direction", "up"),
POINTED_DRIPSTONE_VERTICAL_DIRECTION_DOWN("vertical_direction", "down"),
LEGACY_LEAVES_BLOCK_UPDATE_YES("block_update"),
LEGACY_LEAVES_BLOCK_UPDATE_NO("block_update"),
// is smooth cobble stone in < 17w46a a thing? probably (double cobble stone slab is smooth so ... (and even more))
LEGACY_SMOOTH_YES,
LEGACY_SMOOTH_NO,
SCULK_SENSOR_PHASE_INACTIVE("sculk_sensor_phase", "inactive"),
SCULK_SENSOR_PHASE_ACTIVE("sculk_sensor_phase", "active"),
SCULK_SENSOR_PHASE_COOLDOWN("sculk_sensor_phase", "cooldown"),
DRIPSTONE_TILT_NONE,
DRIPSTONE_TILT_UNSTABLE,
DRIPSTONE_TILT_PARTIAL,
DRIPSTONE_TILT_FULL,
CAVE_VINES_BERRIES_YES,
CAVE_VINES_BERRIES_NO,
;
public static final HashMap<String, HashMap<Object, BlockProperties>> PROPERTIES_MAPPING = new HashMap<>();
static {
// add all to hashmap
for (BlockProperties property : values()) {
if (!PROPERTIES_MAPPING.containsKey(property.getGroup())) {
PROPERTIES_MAPPING.put(property.getGroup(), new HashMap<>());
}
PROPERTIES_MAPPING.get(property.getGroup()).put(property.getValue(), property);
}
}
private final String group;
private final Object value;
BlockProperties() {
final String name = name();
final List<String> split = Arrays.asList(name.split("_"));
if (name.contains("LEVEL")) {
// level with int values
int levelIndex = split.indexOf("LEVEL");
this.group = split.get(levelIndex - 1).toLowerCase();
} else if (split.size() == 3) {
// TYPE_NAME_VALUE
this.group = split.get(1).toLowerCase();
} else if (name.endsWith("YES") || name.endsWith("NO")) {
this.group = split.get(split.size() - 2).toLowerCase();
} else {
throw new IllegalArgumentException(String.format("Could not find group automatically: %s", name));
}
this.value = getValueByName(name);
}
BlockProperties(String group) {
this.group = group;
this.value = getValueByName(name());
}
BlockProperties(String group, String value) {
this.group = group;
this.value = value;
}
private static Object getValueByName(String name) {
final List<String> split = Arrays.asList(name.split("_"));
if (name.contains("LEVEL")) {
// level with int values
return Integer.parseInt(split.get(split.indexOf("LEVEL") + 1));
} else if (name.endsWith("YES")) {
return true;
} else if (name.endsWith("NO")) {
return false;
} else if (split.size() == 3) {
String value = split.get(2).toLowerCase();
try {
return Integer.parseInt(value);
} catch (Exception ignored) {
return value;
}
} else {
throw new IllegalArgumentException(String.format("Could not find value automatically: %s", name));
}
}
public String getGroup() {
return this.group;
}
public Object getValue() {
return this.value;
}
}

View File

@ -17,6 +17,7 @@ import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import de.bixilon.minosoft.Minosoft
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.data.world.BlockPosition
import de.bixilon.minosoft.gui.rendering.TintColorCalculator
@ -29,7 +30,7 @@ import kotlin.random.Random
data class BlockState(
val owner: Block,
val properties: Set<BlockProperties> = setOf(),
val properties: Map<BlockProperties, Any> = mapOf(),
val rotation: BlockRotations = BlockRotations.NONE,
val renders: Set<BlockRenderInterface> = setOf(),
val tintColor: RGBColor? = null,
@ -71,16 +72,21 @@ data class BlockState(
return false
}
}
for (property in obj.properties) {
if (!properties.contains(property)) {
return false
}
for ((property, value) in obj.properties) {
properties[property]?.let {
if (it != value) {
return false
}
} ?: return false
return true
}
return true
}
return if (obj is ResourceLocation) {
super.equals(obj)
} else false
} else {
false
}
}
override fun toString(): String {
@ -125,7 +131,7 @@ data class BlockState(
fun deserialize(owner: Block, data: JsonObject, models: Map<ResourceLocation, BlockModel>): BlockState {
val (rotation, properties) = data["properties"]?.asJsonObject?.let {
getProperties(it)
} ?: Pair(BlockRotations.NONE, mutableSetOf())
} ?: Pair(BlockRotations.NONE, mutableMapOf())
val renders: MutableSet<BlockRenderInterface> = mutableSetOf()
data["render"]?.let {
@ -164,17 +170,17 @@ data class BlockState(
return BlockState(
owner = owner,
properties = properties.toSet(),
properties = properties.toMap(),
rotation = rotation,
renders = renders.toSet(),
tintColor = tintColor
)
}
private fun getProperties(json: JsonObject) : Pair<BlockRotations, MutableSet<BlockProperties>> {
private fun getProperties(json: JsonObject): Pair<BlockRotations, MutableMap<BlockProperties, Any>> {
var rotation = BlockRotations.NONE
val properties = mutableSetOf<BlockProperties>()
for ((propertyName, propertyJsonValue) in json.entrySet()) {
val properties: MutableMap<BlockProperties, Any> = mutableMapOf()
for ((propertyGroup, propertyJsonValue) in json.entrySet()) {
check(propertyJsonValue is JsonPrimitive) { "Not a json primitive!" }
val propertyValue: Any = when {
propertyJsonValue.isBoolean -> {
@ -193,13 +199,14 @@ data class BlockState(
}
}
try {
if (propertyName in ROTATION_PROPERTIES) {
if (propertyGroup in ROTATION_PROPERTIES) {
rotation = BlockRotations.ROTATION_MAPPING[propertyValue]!!
} else {
properties.add(BlockProperties.PROPERTIES_MAPPING[propertyName]!![propertyValue]!!)
val (blockProperty, value) = BlockProperties.parseProperty(propertyGroup, propertyValue)
properties[blockProperty] = value
}
} catch (exception: NullPointerException) {
throw NullPointerException("Invalid block property $propertyName or value $propertyValue")
throw NullPointerException("Invalid block property $propertyGroup or value $propertyValue")
}
}
return Pair(rotation, properties)
@ -210,4 +217,11 @@ data class BlockState(
renders.add(BlockRenderer(data, model))
}
}
// properties
fun isPowered(): Boolean? {
return properties[BlockProperties.POWERED] as Boolean?
}
// ToDo
}

View File

@ -0,0 +1,34 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class Attachments {
FLOOR,
WALL,
CEILING,
SINGLE_WALL,
DOUBLE_WALL,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, Attachments> = KUtil.getEnumValues(values())
override fun serialize(value: Any): Attachments {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class BambooLeaves {
NONE,
SMALL,
LARGE,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, BambooLeaves> = KUtil.getEnumValues(values())
override fun serialize(value: Any): BambooLeaves {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class BedParts {
HEAD,
FOOT,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, BedParts> = KUtil.getEnumValues(values())
override fun serialize(value: Any): BedParts {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,148 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BooleanBlocKPropertiesSerializer
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.IntBlockPropertiesSerializer
enum class BlockProperties {
POWERED(BooleanBlocKPropertiesSerializer),
TRIGGERED(BooleanBlocKPropertiesSerializer),
INVERTED(BooleanBlocKPropertiesSerializer),
LIT(BooleanBlocKPropertiesSerializer),
WATERLOGGED(BooleanBlocKPropertiesSerializer),
STAIR_DIRECTIONAL("shape", Shapes),
STAIR_HALF("half", Halves),
SLAB_TYPE("type", Halves),
MOISTURE_LEVEL("moisture", IntBlockPropertiesSerializer),
FLUID_LEVEL("level", IntBlockPropertiesSerializer),
HONEY_LEVEL("honey_level", IntBlockPropertiesSerializer),
PISTON_EXTENDED("extended", BooleanBlocKPropertiesSerializer),
PISTON_TYPE("type", PistonTypes),
PISTON_SHORT("short", BooleanBlocKPropertiesSerializer),
RAILS_SHAPE("shape", Shapes),
SNOWY(BooleanBlocKPropertiesSerializer),
STAGE(IntBlockPropertiesSerializer),
DISTANCE(IntBlockPropertiesSerializer),
LEAVES_PERSISTENT("persistent", BooleanBlocKPropertiesSerializer),
BED_PART("part", BedParts),
BED_OCCUPIED("occupied", BooleanBlocKPropertiesSerializer),
TNT_UNSTABLE("unstable", BooleanBlocKPropertiesSerializer),
DOOR_HINGE("hinge", Sides),
DOOR_OPEN("open", BooleanBlocKPropertiesSerializer),
AGE(IntBlockPropertiesSerializer),
INSTRUMENT(Instruments),
NOTE(IntBlockPropertiesSerializer),
REDSTONE_POWER("power", IntBlockPropertiesSerializer),
MULTIPART_NORTH("north", MultipartDirectionParser),
MULTIPART_WEST("west", MultipartDirectionParser),
MULTIPART_SOUTH("south", MultipartDirectionParser),
MULTIPART_EAST("east", MultipartDirectionParser),
MULTIPART_UP("up", MultipartDirectionParser),
MULTIPART_DOWN("down", MultipartDirectionParser),
SNOW_LAYERS("layers", IntBlockPropertiesSerializer),
FENCE_IN_WALL("in_wall", BooleanBlocKPropertiesSerializer),
SCAFFOLDING_BOTTOM("bottom", BooleanBlocKPropertiesSerializer),
TRIPWIRE_DISARMED("disarmed", BooleanBlocKPropertiesSerializer),
TRIPWIRE_IN_AIR("in_air", BooleanBlocKPropertiesSerializer),
TRIPWIRE_ATTACHED("attached", BooleanBlocKPropertiesSerializer),
STRUCTURE_BLOCK_MODE("mode", StructureBlockModes),
COMMAND_BLOCK_CONDITIONAL("conditional", BooleanBlocKPropertiesSerializer),
BUBBLE_COLUMN_DRAG("drag", BooleanBlocKPropertiesSerializer),
BELL_ATTACHMENT("attachment", Attachments),
LANTERN_HANGING("hanging", BooleanBlocKPropertiesSerializer),
SEA_PICKLE_PICKLES("pickles", IntBlockPropertiesSerializer),
LECTERN_BOOK("has_book", BooleanBlocKPropertiesSerializer),
BREWING_STAND_BOTTLE_0("has_bottle_0", BooleanBlocKPropertiesSerializer),
BREWING_STAND_BOTTLE_1("has_bottle_1", BooleanBlocKPropertiesSerializer),
BREWING_STAND_BOTTLE_2("has_bottle_2", BooleanBlocKPropertiesSerializer),
CHEST_TYPE("type", ChestTypes),
CAKE_BITES("bites", IntBlockPropertiesSerializer),
BAMBOO_LEAVES("leaves", BambooLeaves),
REPEATER_LOCKED("locked", BooleanBlocKPropertiesSerializer),
REPEATER_DELAY("delay", IntBlockPropertiesSerializer),
PORTA_FRAME_EYE("eye", BooleanBlocKPropertiesSerializer),
JUKEBOX_HAS_RECORD("has_record", BooleanBlocKPropertiesSerializer),
CAMPFIRE_SIGNAL_FIRE("signal_fire", BooleanBlocKPropertiesSerializer),
TURTLE_EGS_EGGS("eggs", IntBlockPropertiesSerializer),
TURTLE_EGGS_HATCH("hatch", IntBlockPropertiesSerializer),
RESPAWN_ANCHOR_CHARGES("charges", IntBlockPropertiesSerializer),
CANDLES(IntBlockPropertiesSerializer),
FACE("face", Attachments),
HOPPER_ENABLED("enabled", BooleanBlocKPropertiesSerializer),
DRIPSTONE_THICKNESS("thickness", Thicknesses),
LEGACY_BLOCK_UPDATE("block_update", BooleanBlocKPropertiesSerializer),
LEGACY_SMOOTH("smooth", BooleanBlocKPropertiesSerializer),
SCULK_SENSOR_PHASE("sculk_sensor_phase", SensorPhases),
DRIPSTONE_TILT("tilt", Tilts),
CAVE_VINES_BERRIES(BooleanBlocKPropertiesSerializer),
;
val group: String
val serializer: BlockPropertiesSerializer
constructor(group: String, serializer: BlockPropertiesSerializer) {
this.group = group
this.serializer = serializer
}
constructor(serializer: BlockPropertiesSerializer) {
this.group = name.toLowerCase()
this.serializer = serializer
}
companion object {
private val PROPERTIES: Map<String, List<BlockProperties>> = run {
val map: MutableMap<String, MutableList<BlockProperties>> = mutableMapOf()
for (value in values()) {
val list = map.getOrPut(value.group, { mutableListOf() })
list.add(value)
}
return@run map.toMap()
}
fun parseProperty(group: String, value: Any): Pair<BlockProperties, Any> {
PROPERTIES[group]?.let {
var retProperty: BlockProperties? = null
var retValue: Any? = null
for (blockProperty in it) {
retValue = try {
blockProperty.serializer.serialize(value)
} catch (exception: Throwable) {
continue
}
retProperty = blockProperty
}
if (retProperty == null || retValue == null) {
throw IllegalArgumentException("Can not parse value $value for group $group")
}
return Pair(retProperty, retValue)
} ?: throw IllegalArgumentException("Can not find group: $group")
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class ChestTypes {
SINGLE,
LEFT,
RIGHT,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, ChestTypes> = KUtil.getEnumValues(values())
override fun serialize(value: Any): ChestTypes {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,46 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
enum class Halves(
vararg val aliases: Any,
) {
UPPER("top"),
LOWER("bottom"),
DOUBLE,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<Any, Halves>
init {
val names: MutableMap<Any, Halves> = mutableMapOf()
for (value in values()) {
names[value.name.toLowerCase()] = value
for (alias in value.aliases) {
names[alias] = value
}
}
NAME_MAP = names.toMap()
}
override fun serialize(value: Any): Halves {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,59 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
enum class Instruments(
vararg val aliases: String,
) {
HARP,
BASE_DRUM("basedrum"),
SNARE,
HAT,
BASS,
FLUTE,
BELL,
GUITAR,
CHIME,
XYLOPHONE,
IRON_XYLOPHONE,
COW_BELL,
DIDGERIDOO,
BIT,
BANJO,
PLING,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<Any, Instruments>
init {
val names: MutableMap<Any, Instruments> = mutableMapOf()
for (value in values()) {
names[value.name.toLowerCase()] = value
for (alias in value.aliases) {
names[alias] = value
}
}
NAME_MAP = names.toMap()
}
override fun serialize(value: Any): Instruments {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,48 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
enum class MultipartDirectionParser(
vararg val aliases: Any,
) {
NONE(false),
LOW,
UP,
SIDE(true),
TALL,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<Any, MultipartDirectionParser>
init {
val names: MutableMap<Any, MultipartDirectionParser> = mutableMapOf()
for (value in values()) {
names[value.name.toLowerCase()] = value
for (alias in value.aliases) {
names[alias] = value
}
}
NAME_MAP = names.toMap()
}
override fun serialize(value: Any): MultipartDirectionParser {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class PistonTypes {
NORMAL,
STICKY,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, PistonTypes> = KUtil.getEnumValues(values())
override fun serialize(value: Any): PistonTypes {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,32 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class SensorPhases {
INACTIVE,
ACTIVE,
COOLDOWN,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, SensorPhases> = KUtil.getEnumValues(values())
override fun serialize(value: Any): SensorPhases {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,44 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class Shapes {
STRAIGHT,
INNER_LEFT,
INNER_RIGHT,
OUTER_LEFT,
OUTER_RIGHT,
NORTH_SOUTH,
SOUTH_EAST,
SOUTH_WEST,
NORTH_WEST,
NORTH_EAST,
EAST_WEST,
ASCENDING_EAST,
ASCENDING_WEST,
ASCENDING_NORTH,
ASCENDING_SOUTH,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, Shapes> = KUtil.getEnumValues(values())
override fun serialize(value: Any): Shapes {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,31 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class Sides {
LEFT,
RIGHT,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, Sides> = KUtil.getEnumValues(values())
override fun serialize(value: Any): Sides {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class StructureBlockModes {
SAVE,
LOAD,
CORNER,
DATA,
COMPARE,
SUBTRACT,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, StructureBlockModes> = KUtil.getEnumValues(values())
override fun serialize(value: Any): StructureBlockModes {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,36 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class Thicknesses {
TIP_MERGE,
TIP,
FRUSTUM,
MIDDLE,
BASE,
UP,
DOWN,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, Thicknesses> = KUtil.getEnumValues(values())
override fun serialize(value: Any): Thicknesses {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,33 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties
import de.bixilon.minosoft.data.mappings.blocks.properties.serializer.BlockPropertiesSerializer
import de.bixilon.minosoft.util.KUtil
enum class Tilts {
NONE,
UNSTABLE,
PARTIAL,
FULL,
;
companion object : BlockPropertiesSerializer {
private val NAME_MAP: Map<String, Tilts> = KUtil.getEnumValues(values())
override fun serialize(value: Any): Tilts {
return NAME_MAP[value] ?: throw IllegalArgumentException("No such property: $value")
}
}
}

View File

@ -0,0 +1,19 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties.serializer
interface BlockPropertiesSerializer {
fun serialize(value: Any): Any
}

View File

@ -0,0 +1,28 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties.serializer
object BooleanBlocKPropertiesSerializer : BlockPropertiesSerializer {
override fun serialize(value: Any): Boolean {
if (value is Boolean) {
return value
}
return when (value) {
"true" -> true
"false" -> false
else -> throw IllegalArgumentException("Not a boolean: $value")
}
}
}

View File

@ -0,0 +1,21 @@
/*
* Minosoft
* Copyright (C) 2021 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.properties.serializer
object IntBlockPropertiesSerializer : BlockPropertiesSerializer {
override fun serialize(value: Any): Int {
return value as Int
}
}

View File

@ -14,12 +14,12 @@ package de.bixilon.minosoft.data.mappings.tweaker
import de.bixilon.minosoft.data.mappings.ResourceLocation
import de.bixilon.minosoft.data.mappings.blocks.Block
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties
import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
object TweakBlocks {
val GRASS_BLOCK_SNOWY_YES = BlockState(Block(ResourceLocation("grass")), setOf(BlockProperties.GRASS_SNOWY_YES))
val GRASS_BLOCK_SNOWY_NO = BlockState(Block(ResourceLocation("grass")), setOf(BlockProperties.GRASS_SNOWY_NO))
val GRASS_BLOCK_SNOWY_YES = BlockState(Block(ResourceLocation("grass")), mapOf(BlockProperties.SNOWY to true))
val GRASS_BLOCK_SNOWY_NO = BlockState(Block(ResourceLocation("grass")), mapOf(BlockProperties.SNOWY to false))
val SNOW_RESOURCE_LOCATION = ResourceLocation("snow")
val SNOW_LAYER_RESOURCE_LOCAION = ResourceLocation("snow_layer")

View File

@ -17,12 +17,12 @@ import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties
import de.bixilon.minosoft.data.mappings.blocks.BlockRotations
import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
open class BlockCondition {
private var blockProperties: MutableList<MutableList<MutableSet<BlockProperties>>> = mutableListOf() // in order of OR AND OR
private var blockProperties: MutableList<MutableList<MutableMap<BlockProperties, Any>>> = mutableListOf() // in order of OR AND OR
private var rotation: BlockRotations = BlockRotations.NONE
constructor(data: JsonElement) {
@ -41,8 +41,8 @@ open class BlockCondition {
constructor()
private fun addToProperties(data: JsonObject) {
val current: MutableList<MutableSet<BlockProperties>> = mutableListOf()
for ((propertyName, propertyJsonValue) in data.entrySet()) {
val current: MutableList<MutableMap<BlockProperties, Any>> = mutableListOf()
for ((groupName, propertyJsonValue) in data.entrySet()) {
check(propertyJsonValue is JsonPrimitive) { "Not a json primitive!" }
val propertyValue: Any = when {
propertyJsonValue.isBoolean -> {
@ -61,19 +61,20 @@ open class BlockCondition {
}
}
try {
if (propertyName in BlockState.ROTATION_PROPERTIES) {
if (groupName in BlockState.ROTATION_PROPERTIES) {
rotation = BlockRotations.ROTATION_MAPPING[propertyValue]!!
} else {
BlockProperties.PROPERTIES_MAPPING[propertyName]?.get(propertyValue)?.let {
current.add(mutableSetOf(it))
} ?: kotlin.run {
try {
current.add(mutableMapOf(BlockProperties.parseProperty(groupName, propertyValue)))
} catch (exception: Throwable) {
if (propertyValue is String) {
val propertyString: String = propertyValue
if (propertyString.contains("|")) {
val parts = propertyString.split("|")
val properties = mutableSetOf<BlockProperties>()
val properties: MutableMap<BlockProperties, Any> = mutableMapOf()
for (part in parts) {
properties.add(BlockProperties.PROPERTIES_MAPPING[propertyName]!![part]!!)
val (property, value) = BlockProperties.parseProperty(groupName, part)
properties[property] = value
}
current.add(properties)
}
@ -81,19 +82,19 @@ open class BlockCondition {
}
}
} catch (exception: NullPointerException) {
throw NullPointerException("Invalid block property $propertyName with value $propertyValue")
throw NullPointerException("Invalid block property $groupName with value $propertyValue")
}
}
blockProperties.add(current)
}
open fun contains(testProperties: MutableSet<BlockProperties>, testRotation: BlockRotations): Boolean {
open fun contains(testProperties: Map<BlockProperties, Any>, testRotation: BlockRotations): Boolean {
if (rotation != BlockRotations.NONE && rotation != testRotation) {
return false
}
outerLoop@ for (propertiesSubSet in blockProperties) {
for (properties in propertiesSubSet) {
if (testProperties.intersect(properties).isEmpty()) {
if (testProperties.keys.intersect(properties.keys).isEmpty()) { // ToDo: Just keys or also values???
continue@outerLoop
}
}
@ -104,7 +105,7 @@ open class BlockCondition {
companion object {
val TRUE_CONDITION: BlockCondition = object : BlockCondition() {
override fun contains(testProperties: MutableSet<BlockProperties>, testRotation: BlockRotations): Boolean {
override fun contains(testProperties: Map<BlockProperties, Any>, testRotation: BlockRotations): Boolean {
return true
}
}

View File

@ -1,8 +1,8 @@
package de.bixilon.minosoft.gui.rendering.chunk.models.renderable
import de.bixilon.minosoft.data.Directions
import de.bixilon.minosoft.data.mappings.blocks.BlockProperties
import de.bixilon.minosoft.data.mappings.blocks.BlockState
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.text.RGBColor
import de.bixilon.minosoft.data.world.BlockPosition
import de.bixilon.minosoft.data.world.World
@ -14,7 +14,6 @@ import de.bixilon.minosoft.gui.rendering.textures.Texture
import de.bixilon.minosoft.gui.rendering.util.VecUtil
import glm_.glm
import glm_.mat4x4.Mat4
import glm_.toInt
import glm_.vec2.Vec2
import glm_.vec3.Vec3
import glm_.vec4.Vec4
@ -171,10 +170,8 @@ class FluidRenderer(private val stillTextureName: String, private val flowingTex
}
private fun getLevel(blockState: BlockState): Float {
for (property in blockState.properties) {
if (property.group == "level") {
return (8 - property.value.toInt) * (1f / 8f) - 0.125f
}
blockState.properties[BlockProperties.FLUID_LEVEL]?.let {
return (8 - it as Int) * (1f / 8f) - 0.125f
}
return 0.8125f
}
@ -186,7 +183,7 @@ class FluidRenderer(private val stillTextureName: String, private val flowingTex
if (blockState.owner.resourceLocation.full.contains(regex)) {
return true
}
if (blockState.properties.contains(BlockProperties.GENERAL_WATERLOGGED_YES)) {
if (blockState.properties[BlockProperties.WATERLOGGED] == true) {
return true
}
return false

View File

@ -0,0 +1,27 @@
/*
* Minosoft
* Copyright (C) 2021 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.util
object KUtil {
fun <T : Enum<*>> getEnumValues(values: Array<T>): Map<String, T> {
val ret: MutableMap<String, T> = mutableMapOf()
for (value in values) {
ret[value.name.toLowerCase()] = value
}
return ret.toMap()
}
}