Skip to content

Commit 679c3c2

Browse files
committed
For now parse block properties from data
1 parent 81b5c64 commit 679c3c2

File tree

19 files changed

+623
-60
lines changed

19 files changed

+623
-60
lines changed

api/src/main/java/org/cloudburstmc/api/block/BlockBehaviors.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ private BlockBehaviors() {
104104

105105
public static final BehaviorKey<Float, Float> GET_TRANSLUCENCY = DataKey.behavior(Identifier.parse("get_translucency"), Float.class);
106106

107-
public static final BehaviorKey<Boolean, Boolean> IS_SOLID = DataKey.behavior(Identifier.parse("is_solid"), Boolean.class);
107+
public static final BehaviorKey<BooleanBlockBehavior, BooleanBlockBehavior.Executor> IS_SOLID = DataKey.behavior(Identifier.parse("is_solid"), BooleanBlockBehavior.class, BooleanBlockBehavior.Executor.class);
108108

109109
public static final BehaviorKey<Boolean, Boolean> IS_LIQUID = DataKey.behavior(Identifier.parse("is_liquid"), Boolean.class);
110110

@@ -124,7 +124,7 @@ private BlockBehaviors() {
124124

125125
public static final BehaviorKey<ColorBlockBehavior, ColorBlockBehavior.Executor> GET_COLOR = DataKey.behavior(Identifier.parse("get_color"), ColorBlockBehavior.class, ColorBlockBehavior.Executor.class);
126126

127-
public static final BehaviorKey<Integer, Integer> GET_LIGHT = DataKey.behavior(Identifier.parse("get_light"), Integer.class);
127+
public static final BehaviorKey<IntBlockBehavior, IntBlockBehavior.Executor> GET_LIGHT = DataKey.behavior(Identifier.parse("get_light"), IntBlockBehavior.class, IntBlockBehavior.Executor.class);
128128

129129
public static final BehaviorKey<Boolean, Boolean> IS_ALWAYS_DESTROYABLE = DataKey.behavior(Identifier.parse("is_always_destroyable"), Boolean.class);
130130

@@ -146,11 +146,11 @@ private BlockBehaviors() {
146146

147147
public static final BehaviorKey<FloatBlockBehavior, FloatBlockBehavior.Executor> GET_LIQUID_HEIGHT = DataKey.behavior(Identifier.parse("get_fluid_height"), FloatBlockBehavior.class, FloatBlockBehavior.Executor.class);
148148

149-
public static final BehaviorKey<Float, Float> GET_RESISTANCE = DataKey.behavior(Identifier.parse("get_resistance"), Float.class);
149+
public static final BehaviorKey<FloatBlockBehavior, FloatBlockBehavior.Executor> GET_RESISTANCE = DataKey.behavior(Identifier.parse("get_resistance"), FloatBlockBehavior.class, FloatBlockBehavior.Executor.class);
150150

151151
public static final BehaviorKey<EntityBlockBehavior, EntityBlockBehavior.Executor> ON_ENTITY_COLLIDE = DataKey.behavior(Identifier.parse("on_entity_collide"), EntityBlockBehavior.class, EntityBlockBehavior.Executor.class);
152152

153-
public static final BehaviorKey<Integer, Integer> GET_FILTERED_LIGHT = DataKey.behavior(Identifier.parse("get_filtered_light"), Integer.class, Integer.class);
153+
public static final BehaviorKey<IntBlockBehavior, IntBlockBehavior.Executor> GET_FILTERED_LIGHT = DataKey.behavior(Identifier.parse("get_filtered_light"), IntBlockBehavior.class, IntBlockBehavior.Executor.class);
154154

155155
public static final BehaviorKey<Boolean, Boolean> CAN_DAMAGE_ITEM = DataKey.behavior(Identifier.parse("can_damage_item"), Boolean.class);
156156

server/src/main/java/org/cloudburstmc/server/block/BlockPalette.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.cloudburstmc.server.block;
22

3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
35
import com.google.common.base.Preconditions;
46
import com.google.common.collect.ImmutableList;
57
import com.google.common.collect.ImmutableMap;
@@ -14,6 +16,8 @@
1416
import org.cloudburstmc.api.block.BlockType;
1517
import org.cloudburstmc.api.block.trait.BlockTrait;
1618
import org.cloudburstmc.api.util.Identifier;
19+
import org.cloudburstmc.api.util.AxisAlignedBB;
20+
import org.cloudburstmc.api.util.SimpleAxisAlignedBB;
1721
import org.cloudburstmc.blockstateupdater.BlockStateUpdaters;
1822
import org.cloudburstmc.nbt.*;
1923
import org.cloudburstmc.protocol.common.DefinitionRegistry;
@@ -63,6 +67,8 @@ public boolean equals(NbtMap a, NbtMap b) {
6367
private final SortedMap<String, Set<NbtMap>> sortedPalette = new Object2ReferenceRBTreeMap<>();
6468
//private final Reference2ReferenceMap<Identifier, BlockState> stateMap = new Reference2ReferenceOpenHashMap<>();
6569

70+
private final BlockPropertyCache propertyCache = new BlockPropertyCache(this);
71+
6672
public void addBlock(BlockType type, BlockSerializer serializer) {
6773
if (this.defaultStateMap.containsKey(type.getId())) {
6874
log.warn("Duplicate block type: {}", type);
@@ -157,6 +163,12 @@ public void generateRuntimeIds() {
157163
this.runtimeDefinitionMap.put(i, definition);
158164
this.stateDefinitionMap.putIfAbsent(state, definition);
159165
}
166+
167+
propertyCache.loadProperties();
168+
}
169+
170+
public BlockPropertyCache getPropertyCache() {
171+
return propertyCache;
160172
}
161173

162174
public Map<String, Set<Object>> getVanillaTraitMap() {
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package org.cloudburstmc.server.block;
2+
3+
import org.checkerframework.checker.nullness.qual.Nullable;
4+
import org.cloudburstmc.api.block.BlockState;
5+
import org.cloudburstmc.api.util.AxisAlignedBB;
6+
7+
public final class BlockProperties {
8+
9+
private BlockProperties() {
10+
throw new AssertionError("Cannot instantiate utility class");
11+
}
12+
13+
private static BlockPropertyCache getCache() {
14+
return BlockPalette.INSTANCE.getPropertyCache();
15+
}
16+
17+
public static float getFloat(String propertyName, BlockState state, float defaultValue) {
18+
Float value = getCache().getFloatProperty(propertyName, state);
19+
return value != null ? value : defaultValue;
20+
}
21+
22+
public static float getHardness(BlockState state) {
23+
return getFloat(BlockPropertyNames.HARDNESS, state, 1.0f);
24+
}
25+
26+
public static float getExplosionResistance(BlockState state) {
27+
return getFloat(BlockPropertyNames.EXPLOSION_RESISTANCE, state, 0.0f);
28+
}
29+
30+
public static float getFriction(BlockState state) {
31+
return getFloat(BlockPropertyNames.FRICTION, state, 0.6f);
32+
}
33+
34+
public static float getThickness(BlockState state) {
35+
return getFloat(BlockPropertyNames.THICKNESS, state, 0.0f);
36+
}
37+
38+
public static float getTranslucency(BlockState state) {
39+
return getFloat(BlockPropertyNames.TRANSLUCENCY, state, 0.0f);
40+
}
41+
42+
public static int getInt(String propertyName, BlockState state, int defaultValue) {
43+
Integer value = getCache().getIntProperty(propertyName, state);
44+
return value != null ? value : defaultValue;
45+
}
46+
47+
public static int getLightEmission(BlockState state) {
48+
return getInt(BlockPropertyNames.LIGHT_EMISSION, state, 0);
49+
}
50+
51+
public static int getLightDampening(BlockState state) {
52+
return getInt(BlockPropertyNames.LIGHT_DAMPENING, state, 15);
53+
}
54+
55+
public static int getBurnOdds(BlockState state) {
56+
return getInt(BlockPropertyNames.BURN_ODDS, state, 0);
57+
}
58+
59+
public static int getFlameOdds(BlockState state) {
60+
return getInt(BlockPropertyNames.FLAME_ODDS, state, 0);
61+
}
62+
63+
public static boolean getBoolean(String propertyName, BlockState state, boolean defaultValue) {
64+
Boolean value = getCache().getBooleanProperty(propertyName, state);
65+
return value != null ? value : defaultValue;
66+
}
67+
68+
public static boolean isSolid(BlockState state) {
69+
return getBoolean(BlockPropertyNames.IS_SOLID, state, true);
70+
}
71+
72+
public static boolean requiresCorrectToolForDrops(BlockState state) {
73+
return getBoolean(BlockPropertyNames.REQUIRES_CORRECT_TOOL_FOR_DROPS, state, false);
74+
}
75+
76+
public static boolean canContainLiquidSource(BlockState state) {
77+
return getBoolean(BlockPropertyNames.CAN_CONTAIN_LIQUID_SOURCE, state, false);
78+
}
79+
80+
@Nullable
81+
public static String getString(String propertyName, BlockState state, @Nullable String defaultValue) {
82+
String value = getCache().getStringProperty(propertyName, state);
83+
return value != null ? value : defaultValue;
84+
}
85+
86+
@Nullable
87+
public static String getMapColor(BlockState state) {
88+
return getString(BlockPropertyNames.MAP_COLOR, state, null);
89+
}
90+
91+
@Nullable
92+
public static String getTintMethod(BlockState state) {
93+
return getString(BlockPropertyNames.TINT_METHOD, state, null);
94+
}
95+
96+
@Nullable
97+
public static String getLiquidReactionOnTouch(BlockState state) {
98+
return getString(BlockPropertyNames.LIQUID_REACTION_ON_TOUCH, state, null);
99+
}
100+
101+
@Nullable
102+
public static AxisAlignedBB getCollisionShape(BlockState state) {
103+
return getCache().getCollisionShape(state);
104+
}
105+
106+
@Nullable
107+
public static AxisAlignedBB getCollisionShape(String identifier) {
108+
return getCache().getCollisionShape(identifier);
109+
}
110+
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
package org.cloudburstmc.server.block;
2+
3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import lombok.extern.log4j.Log4j2;
6+
import org.checkerframework.checker.nullness.qual.Nullable;
7+
import org.cloudburstmc.api.block.BlockState;
8+
import org.cloudburstmc.api.util.AxisAlignedBB;
9+
import org.cloudburstmc.api.util.Identifier;
10+
import org.cloudburstmc.api.util.SimpleAxisAlignedBB;
11+
import org.cloudburstmc.server.Bootstrap;
12+
13+
import java.io.IOException;
14+
import java.io.InputStream;
15+
import java.util.HashMap;
16+
import java.util.List;
17+
import java.util.Map;
18+
import java.util.function.Function;
19+
20+
@Log4j2
21+
public class BlockPropertyCache {
22+
23+
private final BlockPalette palette;
24+
private final Map<String, AxisAlignedBB> blockNameToCollisionShape = new HashMap<>();
25+
private final Map<String, Map<String, Float>> floatProperties = new HashMap<>();
26+
private final Map<String, Map<String, Integer>> intProperties = new HashMap<>();
27+
private final Map<String, Map<String, Boolean>> booleanProperties = new HashMap<>();
28+
private final Map<String, Map<String, String>> stringProperties = new HashMap<>();
29+
30+
public BlockPropertyCache(BlockPalette palette) {
31+
this.palette = palette;
32+
}
33+
34+
public void loadProperties() {
35+
InputStream stream = Bootstrap.class.getClassLoader().getResourceAsStream("data/block_properties.json");
36+
37+
try (stream) {
38+
try {
39+
if (stream == null) {
40+
log.warn("Unable to load block_properties.json - blocks will use default properties");
41+
return;
42+
}
43+
44+
ObjectMapper mapper = new ObjectMapper();
45+
List<BlockStateData> blockStates = mapper.readValue(stream, new TypeReference<>() {
46+
});
47+
for (BlockStateData data : blockStates) {
48+
String blockName = data.getName();
49+
50+
if (blockName == null) {
51+
continue;
52+
}
53+
54+
if (data.getCollisionShape() != null) {
55+
AxisAlignedBB boundingBox;
56+
if (data.getCollisionShape().isEmpty()) {
57+
boundingBox = new SimpleAxisAlignedBB(0, 0, 0, 0, 0, 0);
58+
} else {
59+
List<Double> shape = data.getCollisionShape().get(0);
60+
if (shape.size() >= 6) {
61+
boundingBox = new SimpleAxisAlignedBB(
62+
shape.get(0).floatValue(), shape.get(1).floatValue(), shape.get(2).floatValue(),
63+
shape.get(3).floatValue(), shape.get(4).floatValue(), shape.get(5).floatValue()
64+
);
65+
} else {
66+
continue;
67+
}
68+
}
69+
70+
blockNameToCollisionShape.put(blockName, boundingBox);
71+
}
72+
73+
storeFloatProperty(BlockPropertyNames.HARDNESS, blockName, (float) data.getHardness());
74+
storeFloatProperty(BlockPropertyNames.EXPLOSION_RESISTANCE, blockName, (float) data.getExplosionResistance());
75+
storeFloatProperty(BlockPropertyNames.FRICTION, blockName, (float) data.getFriction());
76+
storeFloatProperty(BlockPropertyNames.THICKNESS, blockName, (float) data.getThickness());
77+
storeFloatProperty(BlockPropertyNames.TRANSLUCENCY, blockName, (float) data.getTranslucency());
78+
79+
storeIntProperty(BlockPropertyNames.LIGHT_EMISSION, blockName, data.getLightEmission());
80+
storeIntProperty(BlockPropertyNames.LIGHT_DAMPENING, blockName, data.getLightDampening());
81+
storeIntProperty(BlockPropertyNames.BURN_ODDS, blockName, data.getBurnOdds());
82+
storeIntProperty(BlockPropertyNames.FLAME_ODDS, blockName, data.getFlameOdds());
83+
84+
storeBooleanProperty(BlockPropertyNames.IS_SOLID, blockName, data.isSolid());
85+
storeBooleanProperty(BlockPropertyNames.REQUIRES_CORRECT_TOOL_FOR_DROPS, blockName, data.isRequiresCorrectToolForDrops());
86+
storeBooleanProperty(BlockPropertyNames.CAN_CONTAIN_LIQUID_SOURCE, blockName, data.isCanContainLiquidSource());
87+
88+
storeStringProperty(BlockPropertyNames.MAP_COLOR, blockName, data.getMapColor());
89+
storeStringProperty(BlockPropertyNames.TINT_METHOD, blockName, data.getTintMethod());
90+
storeStringProperty(BlockPropertyNames.LIQUID_REACTION_ON_TOUCH, blockName, data.getLiquidReactionOnTouch());
91+
}
92+
} catch (IOException e) {
93+
log.error("Failed to load block_properties.json", e);
94+
}
95+
} catch (IOException e) {
96+
log.error("Failed to close block_properties.json stream", e);
97+
}
98+
}
99+
100+
private void storeFloatProperty(String propertyName, String blockName, float value) {
101+
floatProperties.computeIfAbsent(propertyName, k -> new HashMap<>()).put(blockName, value);
102+
}
103+
104+
private void storeIntProperty(String propertyName, String blockName, int value) {
105+
intProperties.computeIfAbsent(propertyName, k -> new HashMap<>()).put(blockName, value);
106+
}
107+
108+
private void storeBooleanProperty(String propertyName, String blockName, boolean value) {
109+
booleanProperties.computeIfAbsent(propertyName, k -> new HashMap<>()).put(blockName, value);
110+
}
111+
112+
private void storeStringProperty(String propertyName, String blockName, String value) {
113+
if (value != null) {
114+
stringProperties.computeIfAbsent(propertyName, k -> new HashMap<>()).put(blockName, value);
115+
}
116+
}
117+
118+
@Nullable
119+
public AxisAlignedBB getCollisionShape(String identifier) {
120+
return blockNameToCollisionShape.get(identifier);
121+
}
122+
123+
@Nullable
124+
public AxisAlignedBB getCollisionShape(BlockState blockState) {
125+
return getProperty(blockState, blockNameToCollisionShape::get);
126+
}
127+
128+
@Nullable
129+
public Float getFloatProperty(String propertyName, String identifier) {
130+
Map<String, Float> propertyMap = floatProperties.get(propertyName);
131+
return propertyMap != null ? propertyMap.get(identifier) : null;
132+
}
133+
134+
@Nullable
135+
public Float getFloatProperty(String propertyName, BlockState blockState) {
136+
return getProperty(blockState, id -> getFloatProperty(propertyName, id));
137+
}
138+
139+
@Nullable
140+
public Integer getIntProperty(String propertyName, String identifier) {
141+
Map<String, Integer> propertyMap = intProperties.get(propertyName);
142+
return propertyMap != null ? propertyMap.get(identifier) : null;
143+
}
144+
145+
@Nullable
146+
public Integer getIntProperty(String propertyName, BlockState blockState) {
147+
return getProperty(blockState, id -> getIntProperty(propertyName, id));
148+
}
149+
150+
@Nullable
151+
public Boolean getBooleanProperty(String propertyName, String identifier) {
152+
Map<String, Boolean> propertyMap = booleanProperties.get(propertyName);
153+
return propertyMap != null ? propertyMap.get(identifier) : null;
154+
}
155+
156+
@Nullable
157+
public Boolean getBooleanProperty(String propertyName, BlockState blockState) {
158+
return getProperty(blockState, id -> getBooleanProperty(propertyName, id));
159+
}
160+
161+
@Nullable
162+
public String getStringProperty(String propertyName, String identifier) {
163+
Map<String, String> propertyMap = stringProperties.get(propertyName);
164+
return propertyMap != null ? propertyMap.get(identifier) : null;
165+
}
166+
167+
@Nullable
168+
public String getStringProperty(String propertyName, BlockState blockState) {
169+
return getProperty(blockState, id -> getStringProperty(propertyName, id));
170+
}
171+
172+
@Nullable
173+
private <T> T getProperty(BlockState blockState, Function<String, T> propertyGetter) {
174+
if (blockState == null) {
175+
return null;
176+
}
177+
178+
Identifier id = palette.getIdentifier(blockState);
179+
if (id != null) {
180+
T value = propertyGetter.apply(id.toString());
181+
if (value != null) {
182+
return value;
183+
}
184+
}
185+
186+
Identifier typeId = blockState.getType().getId();
187+
if (typeId != null) {
188+
return propertyGetter.apply(typeId.toString());
189+
}
190+
191+
return null;
192+
}
193+
}

0 commit comments

Comments
 (0)