[#153] Rewrite block settings implementation

This commit is contained in:
InsomniaKitten 2019-05-11 12:41:32 +02:00 committed by Adrian Siekierka
parent 1e132eb7f1
commit f9da36279b
6 changed files with 236 additions and 210 deletions

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.block;
import net.fabricmc.fabric.mixin.builders.BlockSettingsHooks;
import net.minecraft.block.Block.Settings;
import net.minecraft.block.MaterialColor;
import net.minecraft.item.Item;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.tag.Tag;
import net.minecraft.util.Identifier;
public final class BlockSettingsExtensions {
private BlockSettingsExtensions() {
}
public static void breakByHand(Settings settings, boolean breakByHand) {
FabricBlockSettings.computeExtraData(settings).breakByHand(breakByHand);
}
public static void breakByTool(Settings settings, Tag<Item> tag, int miningLevel) {
FabricBlockSettings.computeExtraData(settings).addMiningLevel(tag, miningLevel);
}
public static void hardness(Settings settings, float hardness) {
((BlockSettingsHooks) settings).setHardness(hardness);
}
public static void resistance(Settings settings, float resistance) {
((BlockSettingsHooks) settings).setResistance(Math.max(0.0F, resistance));
}
public static void collidable(Settings settings, boolean collidable) {
((BlockSettingsHooks) settings).setCollidable(collidable);
}
public static void materialColor(Settings settings, MaterialColor materialColor) {
((BlockSettingsHooks) settings).setMaterialColor(materialColor);
}
public static void drops(Settings settings, Identifier dropTableId) {
((BlockSettingsHooks) settings).setDropTableId(dropTableId);
}
public static void sounds(Settings settings, BlockSoundGroup soundGroup) {
((BlockSettingsHooks) settings).invokeSounds(soundGroup);
}
public static void lightLevel(Settings settings, int lightLevel) {
((BlockSettingsHooks) settings).invokeLightLevel(lightLevel);
}
public static void breakInstantly(Settings settings) {
((BlockSettingsHooks) settings).invokeBreakInstantly();
}
public static void strength(Settings settings, float strength) {
((BlockSettingsHooks) settings).invokeStrength(strength);
}
public static void ticksRandomly(Settings settings) {
((BlockSettingsHooks) settings).invokeTicksRandomly();
}
public static void dynamicBounds(Settings settings) {
((BlockSettingsHooks) settings).invokeHasDynamicBounds();
}
public static void dropsNothing(Settings settings) {
((BlockSettingsHooks) settings).invokeDropsNothing();
}
}

View file

@ -17,7 +17,6 @@
package net.fabricmc.fabric.api.block;
import net.fabricmc.fabric.api.event.registry.BlockConstructedCallback;
import net.fabricmc.fabric.impl.block.FabricBlockSettingsDelegate;
import net.fabricmc.fabric.impl.tools.ToolManager;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
@ -27,7 +26,6 @@ import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.tag.Tag;
import net.minecraft.util.DyeColor;
import net.minecraft.util.Identifier;
import net.minecraft.world.loot.LootTables;
import java.util.ArrayList;
import java.util.HashMap;
@ -48,36 +46,49 @@ public class FabricBlockSettings {
BlockConstructedCallback.EVENT.register(FabricBlockSettings::onBuild);
}
protected final Block.Settings delegate;
private final FabricBlockSettingsDelegate castDelegate;
private static final Map<Block.Settings, ExtraData> EXTRA_DATA = new HashMap<>();
private static class MiningInformation {
private final Tag<Item> tag;
private final int miningLevel;
protected final Block.Settings delegate;
MiningInformation(Tag<Item> tag, int miningLevel) {
this.tag = tag;
this.miningLevel = miningLevel;
}
static final class ExtraData {
private final List<MiningLevel> miningLevels = new ArrayList<>();
/* @Nullable */ private Boolean breakByHand;
private ExtraData(Block.Settings settings) {
}
void breakByHand(boolean breakByHand) {
this.breakByHand = breakByHand;
}
void addMiningLevel(Tag<Item> tag, int level) {
miningLevels.add(new MiningLevel(tag, level));
}
}
private static class Information {
private Boolean breakByHand;
private List<MiningInformation> miningInformation = new ArrayList<>();
}
private static final class MiningLevel {
private final Tag<Item> tag;
private final int level;
private static Map<Block.Settings, Information> info = new HashMap<>();
MiningLevel(Tag<Item> tag, int level) {
this.tag = tag;
this.level = level;
}
}
static ExtraData computeExtraData(Block.Settings settings) {
return EXTRA_DATA.computeIfAbsent(settings, ExtraData::new);
}
private static void onBuild(Block.Settings settings, Block block) {
// TODO: Load only if fabric-mining-levels present
Information i = info.get(settings);
if (i != null) {
if (i.breakByHand != null) {
ToolManager.entry(block).setBreakByHand(i.breakByHand);
ExtraData data = EXTRA_DATA.get(settings);
if (data != null) {
if (data.breakByHand != null) {
ToolManager.entry(block).setBreakByHand(data.breakByHand);
}
for (MiningInformation mi : i.miningInformation) {
ToolManager.entry(block).putBreakByTool(mi.tag, mi.miningLevel);
for (MiningLevel tml : data.miningLevels) {
ToolManager.entry(block).putBreakByTool(tml.tag, tml.level);
}
}
}
@ -92,7 +103,6 @@ public class FabricBlockSettings {
protected FabricBlockSettings(final Block.Settings delegate) {
this.delegate = delegate;
castDelegate = (FabricBlockSettingsDelegate) delegate;
}
public static FabricBlockSettings of(Material material) {
@ -111,99 +121,110 @@ public class FabricBlockSettings {
return new FabricBlockSettings(base);
}
public static FabricBlockSettings copyOf(Block.Settings settings) {
return new FabricBlockSettings(settings);
}
/* FABRIC HELPERS */
public FabricBlockSettings breakByHand(boolean value) {
info.computeIfAbsent(delegate, (k) -> new Information()).breakByHand = value;
public FabricBlockSettings breakByHand(boolean breakByHand) {
computeExtraData(delegate).breakByHand(breakByHand);
return this;
}
public FabricBlockSettings breakByTool(Tag<Item> tag) {
return breakByTool(tag, 0);
}
public FabricBlockSettings breakByTool(Tag<Item> tag, int miningLevel) {
info.computeIfAbsent(delegate, (k) -> new Information()).miningInformation.add(
new MiningInformation(tag, miningLevel)
);
computeExtraData(delegate).addMiningLevel(tag, miningLevel);
return this;
}
public FabricBlockSettings breakByTool(Tag<Item> tag) {
return breakByTool(tag, 0);
}
/* DELEGATE WRAPPERS */
public FabricBlockSettings materialColor(MaterialColor color) {
castDelegate.fabric_setMaterialColor(color);
BlockSettingsExtensions.materialColor(delegate, color);
return this;
}
public FabricBlockSettings materialColor(DyeColor color) {
return this.materialColor(color.getMaterialColor());
return materialColor(color.getMaterialColor());
}
public FabricBlockSettings collidable(boolean value) {
castDelegate.fabric_setCollidable(value);
public FabricBlockSettings collidable(boolean collidable) {
BlockSettingsExtensions.collidable(delegate, collidable);
return this;
}
public FabricBlockSettings noCollision() {
return collidable(false);
delegate.noCollision();
return this;
}
public FabricBlockSettings sounds(BlockSoundGroup group) {
castDelegate.fabric_setSoundGroup(group);
BlockSettingsExtensions.sounds(delegate, group);
return this;
}
public FabricBlockSettings ticksRandomly() {
castDelegate.fabric_setRandomTicks(true);
BlockSettingsExtensions.ticksRandomly(delegate);
return this;
}
public FabricBlockSettings lightLevel(int value) {
castDelegate.fabric_setLightLevel(value);
public FabricBlockSettings lightLevel(int lightLevel) {
BlockSettingsExtensions.lightLevel(delegate, lightLevel);
return this;
}
public FabricBlockSettings hardness(float value) {
castDelegate.fabric_setHardness(value);
public FabricBlockSettings hardness(float hardness) {
BlockSettingsExtensions.hardness(delegate, hardness);
return this;
}
public FabricBlockSettings resistance(float value) {
castDelegate.fabric_setResistance(value);
public FabricBlockSettings resistance(float resistance) {
BlockSettingsExtensions.resistance(delegate, resistance);
return this;
}
public FabricBlockSettings strength(float hardness, float resistance) {
castDelegate.fabric_setHardness(hardness);
castDelegate.fabric_setResistance(resistance);
delegate.strength(hardness, resistance);
return this;
}
public FabricBlockSettings breakInstantly() {
return hardness(0.0F);
}
public FabricBlockSettings dropsNothing() {
return this.drops(LootTables.EMPTY);
}
public FabricBlockSettings dropsLike(Block block) {
return this.drops(block.getDropTableId());
}
public FabricBlockSettings drops(Identifier id) {
castDelegate.fabric_setDropTable(id);
BlockSettingsExtensions.breakInstantly(delegate);
return this;
}
public FabricBlockSettings friction(float value) {
castDelegate.fabric_setFriction(value);
public FabricBlockSettings dropsNothing() {
BlockSettingsExtensions.dropsNothing(delegate);
return this;
}
public FabricBlockSettings dropsLike(Block block) {
delegate.dropsLike(block);
return this;
}
public FabricBlockSettings drops(Identifier dropTableId) {
BlockSettingsExtensions.drops(delegate, dropTableId);
return this;
}
@Deprecated
public FabricBlockSettings friction(float friction) {
delegate.slipperiness(friction);
return this;
}
public FabricBlockSettings slipperiness(float value) {
delegate.slipperiness(value);
return this;
}
public FabricBlockSettings dynamicBounds() {
castDelegate.fabric_setDynamicBounds(true);
BlockSettingsExtensions.dynamicBounds(delegate);
return this;
}

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.impl.block;
import net.minecraft.block.MaterialColor;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
public interface FabricBlockSettingsDelegate {
void fabric_setMaterialColor(MaterialColor color);
void fabric_setCollidable(boolean value);
void fabric_setSoundGroup(BlockSoundGroup group);
void fabric_setLightLevel(int value);
void fabric_setHardness(float value);
void fabric_setResistance(float value);
void fabric_setRandomTicks(boolean value);
void fabric_setFriction(float value);
void fabric_setDropTable(Identifier id);
void fabric_setDynamicBounds(boolean value);
}

View file

@ -0,0 +1,64 @@
/*
* Copyright (c) 2016, 2017, 2018 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.builders;
import net.minecraft.block.Block;
import net.minecraft.block.MaterialColor;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(Block.Settings.class)
public interface BlockSettingsHooks {
@Accessor
void setHardness(float hardness);
@Accessor
void setResistance(float resistance);
@Accessor
void setCollidable(boolean collidable);
@Accessor
void setMaterialColor(MaterialColor materialColor);
@Accessor
void setDropTableId(Identifier dropTableId);
@Invoker
Block.Settings invokeSounds(BlockSoundGroup group);
@Invoker
Block.Settings invokeLightLevel(int lightLevel);
@Invoker
Block.Settings invokeBreakInstantly();
@Invoker
Block.Settings invokeStrength(float strength);
@Invoker
Block.Settings invokeTicksRandomly();
@Invoker
Block.Settings invokeHasDynamicBounds();
@Invoker
Block.Settings invokeDropsNothing();
}

View file

@ -1,102 +0,0 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.mixin.builders;
import net.fabricmc.fabric.impl.block.FabricBlockSettingsDelegate;
import net.minecraft.block.Block;
import net.minecraft.block.Material;
import net.minecraft.block.MaterialColor;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(Block.Settings.class)
public class MixinBlockBuilder implements FabricBlockSettingsDelegate {
@Shadow
private Material material;
@Shadow
private MaterialColor materialColor;
@Shadow
private boolean collidable;
@Shadow
private BlockSoundGroup soundGroup;
@Shadow
private int luminance;
@Shadow
private float resistance;
@Shadow
private float hardness;
@Shadow
private boolean randomTicks;
@Shadow
private float slipperiness;
@Shadow
private Identifier dropTableId;
@Shadow
private boolean dynamicBounds;
@Override
public void fabric_setMaterialColor(MaterialColor color) {
materialColor = color;
}
@Override
public void fabric_setCollidable(boolean value) {
collidable = value;
}
@Override
public void fabric_setSoundGroup(BlockSoundGroup group) {
soundGroup = group;
}
@Override
public void fabric_setLightLevel(int value) {
luminance = value;
}
@Override
public void fabric_setHardness(float value) {
hardness = value;
}
@Override
public void fabric_setResistance(float value) {
resistance = Math.max(0.0f, value);
}
@Override
public void fabric_setRandomTicks(boolean value) {
randomTicks = value;
}
@Override
public void fabric_setFriction(float value) {
slipperiness = value;
}
@Override
public void fabric_setDropTable(Identifier id) {
dropTableId = id;
}
@Override
public void fabric_setDynamicBounds(boolean value) {
dynamicBounds = value;
}
}

View file

@ -3,8 +3,8 @@
"package": "net.fabricmc.fabric.mixin.builders",
"compatibilityLevel": "JAVA_8",
"mixins": [
"BlockSettingsHooks",
"MixinBlock",
"MixinBlockBuilder",
"MixinItem"
],
"injectors": {