forked from FabricMC/fabric
add flammable block registry, *2ObjectMap.clear to remove Fabric overrides (#75)
This commit is contained in:
parent
004281cdac
commit
a585b4833e
10 changed files with 399 additions and 9 deletions
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.registry;
|
||||
|
||||
import net.fabricmc.fabric.api.util.Block2ObjectMap;
|
||||
import net.fabricmc.fabric.impl.registry.FlammableBlockRegistryImpl;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.tag.Tag;
|
||||
|
||||
public interface FlammableBlockRegistry extends Block2ObjectMap<FlammableBlockRegistry.Entry> {
|
||||
static FlammableBlockRegistry getDefaultInstance() {
|
||||
return getInstance(Blocks.FIRE);
|
||||
}
|
||||
|
||||
static FlammableBlockRegistry getInstance(Block block) {
|
||||
return FlammableBlockRegistryImpl.getInstance(block);
|
||||
}
|
||||
|
||||
default void add(Block block, int burn, int spread) {
|
||||
this.add(block, new Entry(burn, spread));
|
||||
}
|
||||
|
||||
default void add(Tag<Block> tag, int burn, int spread) {
|
||||
this.add(tag, new Entry(burn, spread));
|
||||
}
|
||||
|
||||
public static final class Entry {
|
||||
private final int burn, spread;
|
||||
|
||||
public Entry(int burn, int spread) {
|
||||
this.burn = burn;
|
||||
this.spread = spread;
|
||||
}
|
||||
|
||||
public int getBurnChance() {
|
||||
return burn;
|
||||
}
|
||||
|
||||
public int getSpreadChance() {
|
||||
return spread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof Entry)) {
|
||||
return false;
|
||||
} else {
|
||||
Entry other = (Entry) o;
|
||||
return other.burn == burn && other.spread == spread;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return burn * 11 + spread;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
package net.fabricmc.fabric.api.util;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemProvider;
|
||||
import net.minecraft.tag.Tag;
|
||||
|
||||
|
@ -26,4 +27,6 @@ public interface Block2ObjectMap<V> {
|
|||
void add(Tag<Block> tag, V value);
|
||||
void remove(Block block);
|
||||
void remove(Tag<Block> tag);
|
||||
void clear(Block block);
|
||||
void clear(Tag<Block> tag);
|
||||
}
|
||||
|
|
|
@ -26,4 +26,6 @@ public interface Item2ObjectMap<V> {
|
|||
void add(Tag<Item> tag, V value);
|
||||
void remove(ItemProvider item);
|
||||
void remove(Tag<Item> tag);
|
||||
void clear(ItemProvider item);
|
||||
void clear(Tag<Item> tag);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ import net.minecraft.item.Item;
|
|||
import net.minecraft.item.ItemProvider;
|
||||
import net.minecraft.tag.Tag;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CompostingChanceRegistryImpl implements CompostingChanceRegistry {
|
||||
@Override
|
||||
public Float get(ItemProvider item) {
|
||||
|
@ -47,4 +50,14 @@ public class CompostingChanceRegistryImpl implements CompostingChanceRegistry {
|
|||
public void remove(Tag<Item> tag) {
|
||||
throw new UnsupportedOperationException("Tags currently not supported!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(ItemProvider item) {
|
||||
throw new UnsupportedOperationException("CompostingChanceRegistry operates directly on the vanilla map - clearing not supported!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(Tag<Item> tag) {
|
||||
throw new UnsupportedOperationException("CompostingChanceRegistry operates directly on the vanilla map - clearing not supported!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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.impl.registry;
|
||||
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
|
||||
public interface FireBlockHooks {
|
||||
FlammableBlockRegistry.Entry fabric_getVanillaEntry(Block block);
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* 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.impl.registry;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
|
||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||
import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.resource.ResourceType;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FlammableBlockRegistryImpl implements FlammableBlockRegistry, IdentifiableResourceReloadListener {
|
||||
private static final FlammableBlockRegistry.Entry REMOVED = new FlammableBlockRegistry.Entry(0, 0);
|
||||
private static final Map<Block, FlammableBlockRegistryImpl> REGISTRIES = new HashMap<>();
|
||||
private static final Collection<Identifier> RELOAD_DEPS = Collections.singletonList(ResourceReloadListenerKeys.TAGS);
|
||||
private static int idCounter = 0;
|
||||
|
||||
private final Map<Block, FlammableBlockRegistry.Entry> registeredEntriesBlock = new HashMap<>();
|
||||
private final Map<Tag<Block>, FlammableBlockRegistry.Entry> registeredEntriesTag = new HashMap<>();
|
||||
private final Map<Block, FlammableBlockRegistry.Entry> computedEntries = new HashMap<>();
|
||||
private final Object2IntMap<Block> computedBurnChances = new Object2IntOpenHashMap<>();
|
||||
private final Object2IntMap<Block> computedSpreadChances = new Object2IntOpenHashMap<>();
|
||||
private final Identifier id;
|
||||
private final Block key;
|
||||
private boolean tagsPresent = false;
|
||||
|
||||
private FlammableBlockRegistryImpl(Block key) {
|
||||
ResourceManagerHelper.get(ResourceType.DATA).addReloadListener(this);
|
||||
this.id = new Identifier("fabric:private/fire_registry_" + (++idCounter));
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResourceReload(ResourceManager var1) {
|
||||
reload();
|
||||
tagsPresent = true;
|
||||
}
|
||||
|
||||
private void reload() {
|
||||
computedEntries.clear();
|
||||
// tags take precedence before blocks
|
||||
for (Tag<Block> tag : registeredEntriesTag.keySet()) {
|
||||
FlammableBlockRegistry.Entry entry = registeredEntriesTag.get(tag);
|
||||
for (Block block : tag.values()) {
|
||||
computedEntries.put(block, entry);
|
||||
}
|
||||
}
|
||||
computedEntries.putAll(registeredEntriesBlock);
|
||||
|
||||
computedBurnChances.clear();
|
||||
computedSpreadChances.clear();
|
||||
|
||||
for (Block block : computedEntries.keySet()) {
|
||||
FlammableBlockRegistry.Entry entry = computedEntries.get(block);
|
||||
computedBurnChances.put(block, entry.getBurnChance());
|
||||
computedSpreadChances.put(block, entry.getSpreadChance());
|
||||
}
|
||||
}
|
||||
|
||||
// User-facing fire registry interface - queries vanilla fire block
|
||||
@Override
|
||||
public Entry get(Block block) {
|
||||
Entry entry = computedEntries.get(block);
|
||||
if (entry != null) {
|
||||
return entry;
|
||||
} else {
|
||||
return ((FireBlockHooks) key).fabric_getVanillaEntry(block);
|
||||
}
|
||||
}
|
||||
|
||||
public Entry getFabric(Block block) {
|
||||
return computedEntries.get(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Block block, Entry value) {
|
||||
registeredEntriesBlock.put(block, value);
|
||||
|
||||
if (tagsPresent) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Tag<Block> tag, Entry value) {
|
||||
registeredEntriesTag.put(tag, value);
|
||||
|
||||
if (tagsPresent) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Block block) {
|
||||
add(block, REMOVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove(Tag<Block> tag) {
|
||||
add(tag, REMOVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(Block block) {
|
||||
registeredEntriesBlock.remove(block);
|
||||
|
||||
if (tagsPresent) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(Tag<Block> tag) {
|
||||
registeredEntriesTag.remove(tag);
|
||||
|
||||
if (tagsPresent) {
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
public static FlammableBlockRegistryImpl getInstance(Block block) {
|
||||
if (!(block instanceof FireBlockHooks)) {
|
||||
throw new RuntimeException("Not a hookable fire block: " + block);
|
||||
}
|
||||
|
||||
return REGISTRIES.computeIfAbsent(block, FlammableBlockRegistryImpl::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getFabricId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> getFabricDependencies() {
|
||||
return RELOAD_DEPS;
|
||||
}
|
||||
}
|
|
@ -70,16 +70,18 @@ public class FuelRegistryImpl implements FuelRegistry {
|
|||
add(tag, 0);
|
||||
}
|
||||
|
||||
public void apply(Map<Item, Integer> map) {
|
||||
for (ItemProvider item : itemCookTimes.keySet()) {
|
||||
int time = itemCookTimes.getInt(item);
|
||||
if (time <= 0) {
|
||||
map.remove(item.getItem());
|
||||
} else {
|
||||
map.put(item.getItem(), time);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void clear(ItemProvider item) {
|
||||
itemCookTimes.removeInt(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(Tag<Item> tag) {
|
||||
tagCookTimes.removeInt(tag);
|
||||
}
|
||||
|
||||
public void apply(Map<Item, Integer> map) {
|
||||
// tags take precedence before blocks
|
||||
for (Tag<Item> tag : tagCookTimes.keySet()) {
|
||||
int time = tagCookTimes.getInt(tag);
|
||||
if (time <= 0) {
|
||||
|
@ -92,5 +94,14 @@ public class FuelRegistryImpl implements FuelRegistry {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ItemProvider item : itemCookTimes.keySet()) {
|
||||
int time = itemCookTimes.getInt(item);
|
||||
if (time <= 0) {
|
||||
map.remove(item.getItem());
|
||||
} else {
|
||||
map.put(item.getItem(), time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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.block;
|
||||
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||
import net.fabricmc.fabric.impl.registry.FireBlockHooks;
|
||||
import net.fabricmc.fabric.impl.registry.FlammableBlockRegistryImpl;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.FireBlock;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(FireBlock.class)
|
||||
public class MixinFireBlock implements FireBlockHooks {
|
||||
private FlammableBlockRegistryImpl fabric_registry;
|
||||
|
||||
@Shadow
|
||||
private int getSpreadChance(Block block_1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Shadow
|
||||
private int getBurnChance(Block block_1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Inject(at = @At("RETURN"), method = "<init>")
|
||||
private void afterConstruct(Block.Settings settings, CallbackInfo info) {
|
||||
fabric_registry = FlammableBlockRegistryImpl.getInstance((Block) (Object) this);
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "getBurnChance", cancellable = true)
|
||||
private void getFabricBurnChance(Block block, CallbackInfoReturnable info) {
|
||||
FlammableBlockRegistry.Entry entry = fabric_registry.getFabric(block);
|
||||
if (entry != null) {
|
||||
info.setReturnValue(entry.getBurnChance());
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "getSpreadChance", cancellable = true)
|
||||
private void getFabricSpreadChance(Block block, CallbackInfoReturnable info) {
|
||||
FlammableBlockRegistry.Entry entry = fabric_registry.getFabric(block);
|
||||
if (entry != null) {
|
||||
info.setReturnValue(entry.getSpreadChance());
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FlammableBlockRegistry.Entry fabric_getVanillaEntry(Block block) {
|
||||
return new FlammableBlockRegistry.Entry(getBurnChance(block), getSpreadChance(block));
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
"compatibilityLevel": "JAVA_8",
|
||||
"mixins": [
|
||||
"block.MixinBlockBuilder",
|
||||
"block.MixinFireBlock",
|
||||
"block.entity.MixinBlockEntity",
|
||||
"commands.MixinServerCommandManager",
|
||||
"container.MixinServerPlayerEntity",
|
||||
|
|
29
src/test/java/net/fabricmc/fabric/block/FireMod.java
Normal file
29
src/test/java/net/fabricmc/fabric/block/FireMod.java
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.block;
|
||||
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.registry.FlammableBlockRegistry;
|
||||
import net.minecraft.block.Blocks;
|
||||
|
||||
public class FireMod implements ModInitializer {
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
FlammableBlockRegistry.getDefaultInstance().add(Blocks.STONE, 100, 100);
|
||||
FlammableBlockRegistry.getDefaultInstance().remove(Blocks.OAK_PLANKS);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue