From 70493f68dcb74b36eb6fd8cc024a4f96691c6122 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 23 Oct 2016 12:32:12 -0200 Subject: [PATCH 1/6] Remove BlockProperties --- .../v18/wrapper/block/backward/BWBlock.java | 14 +- .../v18/wrapper/block/forward/FWBlock.java | 28 ++- .../wrapper/block/forward/FWBlockSound.java | 58 +++++ .../block/forward/MCBlockProperties.java | 116 --------- .../wrapper/block/forward/ProxyMaterial.java | 34 +++ src/main/java/nova/core/block/Block.java | 6 +- .../core/block/component/BlockProperties.java | 142 ----------- .../core/block/component/BlockProperty.java | 231 ++++++++++++++++++ src/main/java/nova/core/item/ItemBlock.java | 6 +- 9 files changed, 358 insertions(+), 277 deletions(-) create mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java delete mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java create mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java delete mode 100644 src/main/java/nova/core/block/component/BlockProperties.java create mode 100644 src/main/java/nova/core/block/component/BlockProperty.java diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java index b5180821d..a7d70ff25 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/backward/BWBlock.java @@ -31,7 +31,7 @@ import net.minecraft.util.BlockPos; import net.minecraft.world.IBlockAccess; import nova.core.block.Block; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.block.component.LightEmitter; import nova.core.component.misc.Collider; import nova.core.component.transform.BlockTransform; @@ -39,6 +39,7 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.retention.Store; +import nova.core.sound.Sound; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v18.wrapper.block.world.BWWorld; @@ -66,11 +67,12 @@ public BWBlock(net.minecraft.block.Block block, World world, Vector3D pos) { transform.setWorld(world); transform.setPosition(pos); - BlockProperties blockMaterial = components.add(new BlockProperties()); - blockMaterial.setLightTransmission(!mcBlock.getMaterial().blocksLight()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.PLACE, mcBlock.stepSound.getPlaceSound()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.BREAK, mcBlock.stepSound.getBreakSound()); - blockMaterial.setBlockSound(BlockProperties.BlockSoundTrigger.WALK, mcBlock.stepSound.getStepSound()); + components.add(new BlockProperty.Opacity().setLightTransmission(!mcBlock.getMaterial().blocksLight())); + + BlockProperty.BlockSound blockSound = components.add(new BlockProperty.BlockSound()); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound("", mcBlock.stepSound.getPlaceSound())); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound("", mcBlock.stepSound.getBreakSound())); + blockSound.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound("", mcBlock.stepSound.getStepSound())); components.add(new LightEmitter()).setEmittedLevel(() -> mcBlock.getLightValue(getMcBlockAccess(), new BlockPos(x(), y(), z())) / 15.0F); components.add(new Collider(this)) diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 593f7a376..36d9eb71a 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -20,6 +20,7 @@ package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; +import net.minecraft.block.material.MapColor; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; @@ -37,11 +38,12 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; import nova.core.block.Stateful; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.block.component.LightEmitter; import nova.core.component.Updater; import nova.core.component.misc.Collider; import nova.core.retention.Storable; +import nova.core.sound.Sound; import nova.core.util.Direction; import nova.core.util.shape.Cuboid; import nova.core.wrapper.mc.forge.v18.util.WrapperEvent; @@ -72,18 +74,28 @@ public class FWBlock extends net.minecraft.block.Block { public BlockPos lastExtendedStatePos; private Map harvestedBlocks = new HashMap<>(); + private static Material getMcMaterial(BlockFactory factory) { + Block dummy = factory.build(); + if (dummy.components.has(BlockProperty.Opacity.class)) { + // TODO allow color selection + return new ProxyMaterial(MapColor.grayColor, dummy.components.get(BlockProperty.Opacity.class)); + } else { + return Material.piston; + } + } + public FWBlock(BlockFactory factory) { //TODO: Hack build() method - super(factory.build().components.has(BlockProperties.class) ? new MCBlockProperties(factory.build().components.get(BlockProperties.class)).toMcMaterial() : Material.piston); + super(getMcMaterial(factory)); this.factory = factory; this.dummy = factory.build(); - if (this.getMaterial() instanceof MCBlockProperties.ProxyMaterial) { - this.stepSound = ((MCBlockProperties.ProxyMaterial) this.getMaterial()).getSoundType(); + if (dummy.components.has(BlockProperty.BlockSound.class)) { + this.stepSound = new FWBlockSound(dummy.components.get(BlockProperty.BlockSound.class)); } else { - BlockProperties properties = dummy.components.add(new BlockProperties()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.BREAK, soundTypeStone.getBreakSound()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.PLACE, soundTypeStone.getPlaceSound()); - properties.setBlockSound(BlockProperties.BlockSoundTrigger.WALK, soundTypeStone.getStepSound()); + BlockProperty.BlockSound properties = dummy.components.add(new BlockProperty.BlockSound()); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.BREAK, new Sound("", soundTypeStone.getBreakSound())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE, new Sound("", soundTypeStone.getPlaceSound())); + properties.setBlockSound(BlockProperty.BlockSound.BlockSoundTrigger.WALK, new Sound("", soundTypeStone.getStepSound())); this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java new file mode 100644 index 000000000..f7f1326ab --- /dev/null +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java @@ -0,0 +1,58 @@ +package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; + +import net.minecraft.block.Block; +import nova.core.block.component.BlockProperty.BlockSound; +import nova.core.sound.Sound; + +/** + * @author winsock, soniex2 + */ +public class FWBlockSound extends Block.SoundType { + private final BlockSound blockSound; + + /** + * Construct a new FWBlockSound + * @param blockSound The BlockSound to use. + */ + public FWBlockSound(BlockSound blockSound) { + super("", 1f, 1f); + this.blockSound = blockSound; + } + + @Override + public String getBreakSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.BREAK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.BREAK); + if (sound.domain.isEmpty() && !sound.name.contains(".")) { + return "dig." + sound.name; + } + return sound.getID(); + } + return super.getBreakSound(); + } + + @Override + public String getStepSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.WALK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.WALK); + if (sound.domain.isEmpty() && !sound.name.contains(".")) { + return "step." + sound.name; + } + return sound.getID(); + } + return super.getStepSound(); + } + + @Override + public String getPlaceSound() { + if (blockSound.blockSoundSoundMap.containsKey(BlockSound.BlockSoundTrigger.WALK)) { + Sound sound = blockSound.blockSoundSoundMap.get(BlockSound.BlockSoundTrigger.WALK); + if (sound.domain.isEmpty()) { + return sound.name; + } + return sound.getID(); + } + // By default MC uses the block break sound for block placement + return this.getBreakSound(); + } +} diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java deleted file mode 100644 index 45dcacf47..000000000 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/MCBlockProperties.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 - * - * This file is part of NOVA. - * - * NOVA 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. - * - * NOVA 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 NOVA. If not, see . - */ - -package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; - -import net.minecraft.block.Block; -import net.minecraft.block.material.MapColor; -import net.minecraft.block.material.Material; -import nova.core.block.component.BlockProperties; -import nova.core.sound.Sound; - -/** - * Created by winsock on 7/2/15. - */ -public class MCBlockProperties extends BlockProperties { - private Material mcMaterial = null; - - public MCBlockProperties() { - } - - public MCBlockProperties(BlockProperties copy) { - this.blockSoundSoundMap = copy.blockSoundSoundMap; - this.customDefinedSounds = copy.customDefinedSounds; - this.allowsLightThrough = copy.allowsLightThrough; - } - - public Material toMcMaterial() { - if (mcMaterial == null) { - // TODO: We most likely should offer a way to set the color. - mcMaterial = new ProxyMaterial(MapColor.grayColor); - } - return mcMaterial; - } - - public class ProxyMaterial extends Material { - private final FWBlockSound sound = new FWBlockSound(); - - public ProxyMaterial(MapColor color) { - super(color); - } - - @Override - public boolean blocksLight() { - return !MCBlockProperties.this.allowsLightThrough; - } - - @Override - public boolean isOpaque() { - return !MCBlockProperties.this.allowsLightThrough; - } - - public Block.SoundType getSoundType() { - return sound; - } - - private class FWBlockSound extends Block.SoundType { - public FWBlockSound() { - super("", 1f, 1f); - } - - @Override - public String getBreakSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.BREAK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.BREAK); - if (sound.domain.isEmpty() && !sound.name.contains(".")) { - return "dig." + sound.name; - } - return sound.getID(); - } - return super.getBreakSound(); - } - - @Override - public String getStepSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.WALK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.WALK); - if (sound.domain.isEmpty() && !sound.name.contains(".")) { - return "step." + sound.name; - } - return sound.getID(); - } - return super.getStepSound(); - } - - @Override - public String getPlaceSound() { - if (MCBlockProperties.this.blockSoundSoundMap.containsKey(BlockSoundTrigger.WALK)) { - Sound sound = MCBlockProperties.this.blockSoundSoundMap.get(BlockSoundTrigger.WALK); - if (sound.domain.isEmpty()) { - return sound.name; - } - return sound.getID(); - } - // By default MC uses the block break sound for block placement - return this.getBreakSound(); - } - } - } -} diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java new file mode 100644 index 000000000..a5b6cfc4b --- /dev/null +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/ProxyMaterial.java @@ -0,0 +1,34 @@ +package nova.core.wrapper.mc.forge.v18.wrapper.block.forward; + +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.Material; +import nova.core.block.component.BlockProperty; +import nova.core.block.component.BlockProperty.Opacity; + +/** + * @author soniex2 + */ +public class ProxyMaterial extends Material { + private final Opacity opacity; + + /** + * Construct a new proxy material. + * @param color The map color. + * @param opacity The Opacity to use. + */ + public ProxyMaterial(MapColor color, Opacity opacity) { + super(color); + this.opacity = opacity; + } + + @Override + public boolean blocksLight() { + return opacity.allowsLightThrough; + } + + @Override + public boolean isOpaque() { + return opacity.allowsLightThrough; + } + +} diff --git a/src/main/java/nova/core/block/Block.java b/src/main/java/nova/core/block/Block.java index fa298f9d7..7b7f4fb6a 100644 --- a/src/main/java/nova/core/block/Block.java +++ b/src/main/java/nova/core/block/Block.java @@ -20,6 +20,7 @@ package nova.core.block; +import nova.core.block.component.BlockProperty; import nova.core.component.ComponentProvider; import nova.core.component.misc.FactoryProvider; import nova.core.component.transform.BlockTransform; @@ -104,7 +105,7 @@ public final int z() { * @return The breaking difficulty. */ public double getHardness() { - return 1; + return components.getOp(BlockProperty.Hardness.class).orElseGet(BlockProperty.Hardness::new).getHardness(); } /** @@ -113,7 +114,7 @@ public double getHardness() { * @return The resistance. */ public double getResistance() { - return 1; + return components.getOp(BlockProperty.Resistance.class).orElseGet(BlockProperty.Resistance::new).getResistance(); } /** @@ -127,6 +128,7 @@ public boolean canReplace() { /** * Called when an ItemBlock tries to place a block in this position whether to displace the place position or not. * If the ItemBlock does not displace the position, it will replace this block. + * TODO move out into BlockProperty * @return True if by right clicking on this block, the placement of the new block should be displaced. */ public boolean shouldDisplacePlacement() { diff --git a/src/main/java/nova/core/block/component/BlockProperties.java b/src/main/java/nova/core/block/component/BlockProperties.java deleted file mode 100644 index 9e7ff1d4a..000000000 --- a/src/main/java/nova/core/block/component/BlockProperties.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2015 NOVA, All rights reserved. - * This library is free software, licensed under GNU Lesser General Public License version 3 - * - * This file is part of NOVA. - * - * NOVA 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. - * - * NOVA 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 NOVA. If not, see . - */ - -package nova.core.block.component; - -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; -import nova.core.component.Component; -import nova.core.sound.Sound; - -import java.util.Optional; - -/** - * This optional component is for properties that alter a blocks function - * These properties are intended to effect all blocks of one type. - * TODO: Make a component for blocks that have instance properties. E.G. In Minecraft NBT data - * - Note(winsock): I think instance block data storage is an agnostic voxel game feature that goes beyond just 'dumb' blocks - * Created by winsock on 7/2/15. - */ -public class BlockProperties extends Component { - - public BiMap blockSoundSoundMap = HashBiMap.create(); - public Optional> customDefinedSounds; - /** - * This boolean determines if the block should allow light through itself or not. - */ - public boolean allowsLightThrough = false; - - /** - * Sets a sound to play on a specified trigger. Note to set a @see{BlockSoundTrigger.CUSTOM_TRIGGER} use @see{BlockProperties.setCustomBlockSound(String,Sound)} - * - * @param trigger The trigger to set the sound for - * @param sound The sound to play on the triggering of the trigger - * @return This instance for chaining if desired. - */ - public BlockProperties setBlockSound(BlockSoundTrigger trigger, Sound sound) { - if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { - return this; - } - blockSoundSoundMap.put(trigger, sound); - return this; - } - - public BlockProperties setBlockSound(BlockSoundTrigger trigger, String soundResourceString) { - return setBlockSound(trigger, new Sound("", soundResourceString)); - } - - /** - * Sets a sound to an id of choice - * - * @param id The custom id for the sound - * @param sound The sound to associate with the id - * @return This instance for chaining if desired. - */ - public BlockProperties setCustomBlockSound(String id, Sound sound) { - if (!customDefinedSounds.isPresent()) { - customDefinedSounds = Optional.of(HashBiMap.create()); - } - customDefinedSounds.get().put(id, sound); - return this; - } - - /** - * Get the sound associated with a trigger - * - * @param trigger The trigger to get the sound for - * @return The sound object associated with the trigger - */ - public Sound getSound(BlockSoundTrigger trigger) { - if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { - return null; - } - if (blockSoundSoundMap.containsKey(trigger)) { - return blockSoundSoundMap.get(trigger); - } - return null; - } - - /** - * Get the sound associated with a custom Id - * - * @param customId The custom id of the sound - * @return The sound object associated with the custom Id - */ - public Sound getCustomSound(String customId) { - if (!customDefinedSounds.isPresent()) { - return null; - } - if (customDefinedSounds.get().containsKey(customId)) { - return customDefinedSounds.get().get(customId); - } - return null; - } - - /** - * Sets that the block should allow light through - * - * @return This instance for chaining if desired. - */ - public BlockProperties setTransparent() { - allowsLightThrough = true; - return this; - } - - /** - * Sets if light should be transmitted through this block - * - * @param allowLightThrough Boolean flag if light should be allowed through - * @return This instance for chaining if desired. - */ - public BlockProperties setLightTransmission(boolean allowLightThrough) { - this.allowsLightThrough = allowLightThrough; - return this; - } - - /** - * Triggers for sounds to play on the location of a block - */ - public enum BlockSoundTrigger { - BREAK, - PLACE, - WALK, - CUSTOM_TRIGGER - } -} diff --git a/src/main/java/nova/core/block/component/BlockProperty.java b/src/main/java/nova/core/block/component/BlockProperty.java new file mode 100644 index 000000000..c8ffcb8ff --- /dev/null +++ b/src/main/java/nova/core/block/component/BlockProperty.java @@ -0,0 +1,231 @@ +package nova.core.block.component; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import nova.core.component.Component; +import nova.core.sound.Sound; + +import java.util.Optional; + +/** + * Block properties. + * + * @author soniex2 + */ +public interface BlockProperty { + /** + * The breaking difficulty of a block, or how long it takes to break a block. + * Tools and armour may make the block break faster or slower than this. + *

+ * The standard, regular block hardness is 1. {@code Double.POSITIVE_INFINITY} is unbreakable. + *

+ */ + public static class Hardness extends Component implements BlockProperty { + private double hardness = 1.0; + + /** + * Sets the breaking difficulty. + * + * @param hardness The breaking difficulty. + * @return This instance for chaining if desired. + */ + public Hardness setHardness(double hardness) { + this.hardness = hardness; + return this; + } + + /** + * Gets the breaking difficulty. + * + * @return The breaking difficulty. + */ + public double getHardness() { + return hardness; + } + } + + /** + * The blast resistance of a block. + *

+ * The standard, regular block resistance is 1. {@link Double#POSITIVE_INFINITY} is unexplodable. + *

+ */ + public static class Resistance extends Component implements BlockProperty { + private double resistance = 1.0; + + /** + * Sets the blast resistance + * + * @param resistance The blast resistance. + * @return This instance for chaining if desired. + */ + public Resistance setResistance(double resistance) { + this.resistance = resistance; + return this; + } + + /** + * Gets the blast resistance. + * + * @return The blast resistance. + */ + public double getResistance() { + return resistance; + } + } + + /** + * The block sounds associated with a block. + * + * @author winsock + */ + public static class BlockSound extends Component implements BlockProperty { + public BiMap blockSoundSoundMap = HashBiMap.create(); + public Optional> customDefinedSounds; + + /** + * Sets a sound to play on a specified trigger. Note to set a {@link BlockSoundTrigger#CUSTOM_TRIGGER} use {@link BlockSound#setCustomBlockSound(String,Sound)} + * + * @param trigger The trigger to set the sound for + * @param sound The sound to play on the triggering of the trigger + * @return This instance for chaining if desired. + */ + public BlockSound setBlockSound(BlockSoundTrigger trigger, Sound sound) { + if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { + return this; + } + blockSoundSoundMap.put(trigger, sound); + return this; + } + + /** + * Sets a sound to an id of choice + * + * @param id The custom id for the sound + * @param sound The sound to associate with the id + * @return This instance for chaining if desired. + */ + public BlockSound setCustomBlockSound(String id, Sound sound) { + if (!customDefinedSounds.isPresent()) { + customDefinedSounds = Optional.of(HashBiMap.create()); + } + customDefinedSounds.get().put(id, sound); + return this; + } + + /** + * Get the sound associated with a trigger + * + * @param trigger The trigger to get the sound for + * @return The sound object associated with the trigger + */ + public Sound getSound(BlockSoundTrigger trigger) { + if (trigger == BlockSoundTrigger.CUSTOM_TRIGGER) { + return null; + } + if (blockSoundSoundMap.containsKey(trigger)) { + return blockSoundSoundMap.get(trigger); + } + return null; + } + + /** + * Get the sound associated with a custom Id + * + * @param customId The custom id of the sound + * @return The sound object associated with the custom Id + */ + public Sound getCustomSound(String customId) { + if (!customDefinedSounds.isPresent()) { + return null; + } + if (customDefinedSounds.get().containsKey(customId)) { + return customDefinedSounds.get().get(customId); + } + return null; + } + + /** + * Triggers for sounds to play on the location of a block + */ + public enum BlockSoundTrigger { + BREAK, + PLACE, + WALK, + CUSTOM_TRIGGER + } + + } + + /** + * The opacity associated with a block. + * + * @author winsock + */ + public static class Opacity extends Component implements BlockProperty { + // TODO maybe consider a double for opacity? Where 0 is 100% transparent and 1 is 100% opaque? + + /** + * This boolean determines if the block should allow light through itself or not. + */ + public boolean allowsLightThrough = false; + + /** + * Sets that the block should allow light through + * + * @return This instance for chaining if desired. + */ + public Opacity setTransparent() { + allowsLightThrough = true; + return this; + } + + /** + * Sets if light should be transmitted through this block + * + * @param allowLightThrough Boolean flag if light should be allowed through + * @return This instance for chaining if desired. + */ + public Opacity setLightTransmission(boolean allowLightThrough) { + this.allowsLightThrough = allowLightThrough; + return this; + } + } + + // TODO +// /** +// * Indicates whether the block is replaceable. +// */ +// public static final class Replaceable extends Component implements BlockProperty { +// /** +// * Singleton for Replaceable. +// */ +// private static Replaceable theInstance = null; +// +// /** +// * Gets the singleton for Replaceable. +// * +// * @return The singleton for Replaceable. +// */ +// public static Replaceable instance() { +// if (theInstance == null) { +// theInstance = new Replaceable(); +// } +// +// return theInstance; +// } +// +// private Replaceable() { +// } +// +// @Override +// public boolean equals(Object o) { +// return this == o || o instanceof Replaceable; +// } +// +// @Override +// public int hashCode() { +// return Replaceable.class.hashCode(); +// } +// } +} diff --git a/src/main/java/nova/core/item/ItemBlock.java b/src/main/java/nova/core/item/ItemBlock.java index 62e9e013d..f30af52f5 100644 --- a/src/main/java/nova/core/item/ItemBlock.java +++ b/src/main/java/nova/core/item/ItemBlock.java @@ -20,7 +20,7 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; -import nova.core.block.component.BlockProperties; +import nova.core.block.component.BlockProperty; import nova.core.entity.Entity; import nova.core.util.Direction; import nova.core.world.World; @@ -67,8 +67,8 @@ protected boolean onPostPlace(Entity entity, World world, Vector3D placePos, Dir if (opBlock.isPresent() && opBlock.get().sameType(blockFactory)) { //TODO: What if the block is NOT placed by a player? opBlock.get().events.publish(new Block.PlaceEvent(entity, side, hit, this)); - if (opBlock.get().components.has(BlockProperties.class)) { - world.playSoundAtPosition(placePos, opBlock.get().components.get(BlockProperties.class).getSound(BlockProperties.BlockSoundTrigger.PLACE)); + if (opBlock.get().components.has(BlockProperty.BlockSound.class)) { + world.playSoundAtPosition(placePos, opBlock.get().components.get(BlockProperty.BlockSound.class).getSound(BlockProperty.BlockSound.BlockSoundTrigger.PLACE)); } } From 5e56559d932bca50a691d69bf6e7b545825dfaac Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Wed, 26 Oct 2016 22:06:35 -0200 Subject: [PATCH 2/6] String -> Identifier. WIP. --- .../v17/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v17/recipes/RecipeConverter.java | 2 +- .../v17/wrapper/block/BlockConverter.java | 2 +- .../v17/wrapper/block/forward/FWBlock.java | 4 +- .../v17/wrapper/block/world/BWWorld.java | 8 ++- .../v17/wrapper/entity/backward/BWEntity.java | 6 +- .../v17/wrapper/entity/forward/FWEntity.java | 4 +- .../mc/forge/v17/wrapper/item/BWItem.java | 2 +- .../mc/forge/v17/wrapper/item/FWItem.java | 2 +- .../forge/v17/wrapper/item/ItemConverter.java | 4 +- .../v18/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v18/recipes/RecipeConverter.java | 2 +- .../v18/wrapper/block/BlockConverter.java | 2 +- .../v18/wrapper/block/forward/FWBlock.java | 4 +- .../wrapper/block/forward/FWBlockSound.java | 6 +- .../v18/wrapper/block/world/BWWorld.java | 8 ++- .../v18/wrapper/entity/backward/BWEntity.java | 6 +- .../v18/wrapper/entity/forward/FWEntity.java | 4 +- .../mc/forge/v18/wrapper/item/BWItem.java | 2 +- .../mc/forge/v18/wrapper/item/FWItem.java | 2 +- .../forge/v18/wrapper/item/ItemConverter.java | 4 +- src/main/java/nova/core/block/Block.java | 5 +- .../java/nova/core/component/Category.java | 8 ++- .../java/nova/core/component/Component.java | 8 ++- .../java/nova/core/component/fluid/Fluid.java | 10 ++-- .../nova/core/component/misc/Damageable.java | 8 ++- src/main/java/nova/core/entity/Entity.java | 10 ++-- src/main/java/nova/core/item/Item.java | 5 +- src/main/java/nova/core/item/ItemFactory.java | 2 +- src/main/java/nova/core/item/ItemManager.java | 4 +- src/main/java/nova/core/network/Packet.java | 55 +++++++++++++++++-- .../crafting/CraftingRecipeManager.java | 4 +- .../recipes/crafting/OreItemIngredient.java | 3 +- src/main/java/nova/core/render/Asset.java | 8 ++- .../java/nova/core/render/RenderManager.java | 8 +-- .../nova/core/render/texture/Texture.java | 8 ++- src/main/java/nova/core/retention/Data.java | 36 ++++++++++-- .../java/nova/core/retention/Storable.java | 6 +- src/main/java/nova/core/sound/Sound.java | 2 +- .../nova/core/util/id/AbstractIdentifier.java | 46 ++++++++++++++++ .../nova/core/util/id/ClassIdentifier.java | 32 +++++++++++ .../nova/core/util/{ => id}/Identifiable.java | 4 +- .../java/nova/core/util/id/Identifier.java | 19 +++++++ .../nova/core/util/id/StringIdentifier.java | 18 ++++++ .../nova/core/util/id/UUIDIdentifier.java | 29 ++++++++++ .../util/{ => id}/UniqueIdentifiable.java | 6 +- .../java/nova/core/util/registry/Factory.java | 9 ++- .../core/util/registry/FactoryManager.java | 2 +- .../nova/core/util/registry/Registry.java | 6 +- src/main/java/nova/core/world/World.java | 2 +- .../java/nova/core/util/MockIdentifiable.java | 10 +++- .../java/nova/core/util/RegistryTest.java | 6 +- src/test/java/nova/testutils/FakeWorld.java | 6 +- 53 files changed, 359 insertions(+), 104 deletions(-) create mode 100644 src/main/java/nova/core/util/id/AbstractIdentifier.java create mode 100644 src/main/java/nova/core/util/id/ClassIdentifier.java rename src/main/java/nova/core/util/{ => id}/Identifiable.java (96%) create mode 100644 src/main/java/nova/core/util/id/Identifier.java create mode 100644 src/main/java/nova/core/util/id/StringIdentifier.java create mode 100644 src/main/java/nova/core/util/id/UUIDIdentifier.java rename src/main/java/nova/core/util/{ => id}/UniqueIdentifiable.java (87%) diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java index 97582befa..ddf1fbe86 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID()); + super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java index 298f3d266..f02af76db 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java index 58b2c817a..9e7c845cc 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java @@ -136,7 +136,7 @@ private void registerNovaBlock(BlockFactory blockFactory) { FWBlock blockWrapper = new FWBlock(blockFactory); blockFactoryMap.put(blockFactory, blockWrapper); NovaMinecraft.proxy.registerBlock(blockWrapper); - GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID()); + GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); // TODO? if (blockWrapper.dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java index 123d2e4f9..b4710f806 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java @@ -91,7 +91,7 @@ public FWBlock(BlockFactory factory) { this.factory = factory; this.dummy = factory.build(); this.blockClass = dummy.getClass(); - this.setBlockName(dummy.getID()); + this.setBlockName(dummy.getID().asString()); // TODO? // Recalculate super constructor things after loading the block properly this.opaque = isOpaqueCube(); @@ -169,7 +169,7 @@ public boolean hasTileEntity(int metadata) { @Override public TileEntity createTileEntity(World world, int metadata) { - return FWTileLoader.loadTile(dummy.getID()); + return FWTileLoader.loadTile(dummy.getID().asString()); // TODO? } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java index 28f892222..858f4bc37 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/world/BWWorld.java @@ -29,6 +29,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; @@ -144,12 +146,12 @@ public Optional getEntity(String uniqueID) { } @Override - public String getID() { - return world().provider.getDimensionName(); + public Identifier getID() { + return new StringIdentifier(world().provider.getDimensionName()); } @Override public void playSoundAtPosition(Vector3D position, Sound sound) { - world().playSound(position.getX(), position.getY(), position.getZ(), sound.getID(), sound.pitch, sound.volume, false); + world().playSound(position.getX(), position.getY(), position.getZ(), sound.getID().asString(), sound.pitch, sound.volume, false); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java index bc58ff023..83dda3ee3 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/backward/BWEntity.java @@ -28,6 +28,8 @@ import nova.core.entity.Entity; import nova.core.entity.component.Living; import nova.core.entity.component.Player; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.wrapper.mc.forge.v17.wrapper.entity.forward.MCEntityTransform; import nova.core.wrapper.mc.forge.v17.wrapper.inventory.BWInventory; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -88,8 +90,8 @@ public String getUsername() { } @Override - public String getID() { - return entity.getGameProfile().getId().toString(); + public Identifier getID() { + return new UUIDIdentifier(entity.getGameProfile().getId()); } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java index 02a7bb50e..9e4a91a4b 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java @@ -75,13 +75,13 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID()); + nbt.setString("novaID", wrapped.getID().asString()); // TODO? } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID(); + String id = wrapped.getID().asString(); // TODO? char[] chars = id.toCharArray(); buffer.writeInt(chars.length); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java index 9bb8b6925..08fd8ebae 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java @@ -97,6 +97,6 @@ public net.minecraft.item.ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID(); + return getID().asString(); // TODO? } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java index 7c4e8c8ec..ebc78662b 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); + setUnlocalizedName(item.getID().asString()); // TODO? setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java index 969162193..17b988425 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java @@ -106,7 +106,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID()).get(); + ItemFactory itemFactory = Game.items().get(item.getID().asString()).get(); // TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -202,7 +202,7 @@ private void registerNOVAItem(ItemFactory itemFactory) { // Don't register ItemBlocks twice if (!(dummy instanceof ItemBlock)) { NovaMinecraft.proxy.registerItem((FWItem) itemWrapper); - GameRegistry.registerItem(itemWrapper, itemFactory.getID()); + GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); // TODO? if (dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java index 72116bf5e..40701caf8 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID()); + super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java index cd616f714..8547f577c 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java index 17514f534..680d891bb 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java @@ -136,7 +136,7 @@ public boolean canReplace() { private void registerNovaBlock(BlockFactory blockFactory) { FWBlock blockWrapper = new FWBlock(blockFactory); blockFactoryMap.put(blockFactory, blockWrapper); - GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID()); + GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); NovaMinecraft.proxy.postRegisterBlock(blockWrapper); if (blockWrapper.dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 36d9eb71a..8a3a4c6f6 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -99,7 +99,7 @@ public FWBlock(BlockFactory factory) { this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); - this.setUnlocalizedName(dummy.getID()); + this.setUnlocalizedName(dummy.getID().asString()); // TODO? // Recalculate super constructor things after loading the block properly this.fullBlock = isOpaqueCube(); @@ -179,7 +179,7 @@ public boolean hasTileEntity(IBlockState state) { @Override public TileEntity createTileEntity(World world, IBlockState state) { - FWTile fwTile = FWTileLoader.loadTile(dummy.getID()); + FWTile fwTile = FWTileLoader.loadTile(dummy.getID().asString()); // TODO? if (lastExtendedStatePos != null) { fwTile.block.components.getOrAdd(new MCBlockTransform(dummy, Game.natives().toNova(world), new Vector3D(lastExtendedStatePos.getX(), lastExtendedStatePos.getY(), lastExtendedStatePos.getZ()))); lastExtendedStatePos = null; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java index f7f1326ab..b62c264db 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java @@ -26,7 +26,7 @@ public String getBreakSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "dig." + sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } return super.getBreakSound(); } @@ -38,7 +38,7 @@ public String getStepSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "step." + sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } return super.getStepSound(); } @@ -50,7 +50,7 @@ public String getPlaceSound() { if (sound.domain.isEmpty()) { return sound.name; } - return sound.getID(); + return sound.getID().asString(); // TODO? } // By default MC uses the block break sound for block placement return this.getBreakSound(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java index d53baf619..36eea8f77 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/world/BWWorld.java @@ -31,6 +31,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; @@ -153,12 +155,12 @@ public Optional getEntity(String uniqueID) { } @Override - public String getID() { - return world().provider.getDimensionName(); + public Identifier getID() { + return new StringIdentifier(world().provider.getDimensionName()); } @Override public void playSoundAtPosition(Vector3D position, Sound sound) { - world().playSoundEffect(position.getX(), position.getY(), position.getZ(), sound.getID(), sound.volume, sound.pitch); + world().playSoundEffect(position.getX(), position.getY(), position.getZ(), sound.getID().asString(), sound.volume, sound.pitch); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java index eb68b58ff..acb33bc20 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/backward/BWEntity.java @@ -28,6 +28,8 @@ import nova.core.entity.Entity; import nova.core.entity.component.Living; import nova.core.entity.component.Player; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.wrapper.mc.forge.v18.wrapper.entity.forward.MCEntityTransform; import nova.core.wrapper.mc.forge.v18.wrapper.inventory.BWInventory; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -88,8 +90,8 @@ public String getUsername() { } @Override - public String getID() { - return entity.getGameProfile().getId().toString(); + public Identifier getID() { + return new UUIDIdentifier(entity.getGameProfile().getId()); } @Override diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java index d01763dc2..72ae58935 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java @@ -75,13 +75,13 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID()); + nbt.setString("novaID", wrapped.getID().asString()); // TODO? } @Override public void writeSpawnData(ByteBuf buffer) { //Write the ID of the entity to client - String id = wrapped.getID(); + String id = wrapped.getID().asString(); // TODO? char[] chars = id.toCharArray(); buffer.writeInt(chars.length); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java index 7476b9d26..490c5b996 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java @@ -66,6 +66,6 @@ public ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID(); + return getID().asString(); // TODO? } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java index 6ce3b84a4..61b7b9adc 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID()); + setUnlocalizedName(item.getID().asString()); // TODO? setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java index 793bb2fd1..2b5c54df3 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java @@ -107,7 +107,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID()).get(); + ItemFactory itemFactory = Game.items().get(item.getID().asString()).get();// TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -204,7 +204,7 @@ private void registerNOVAItem(ItemFactory itemFactory) { // Don't register ItemBlocks twice if (!(dummy instanceof ItemBlock)) { NovaMinecraft.proxy.registerItem((FWItem) itemWrapper); - GameRegistry.registerItem(itemWrapper, itemFactory.getID()); + GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); if (dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/src/main/java/nova/core/block/Block.java b/src/main/java/nova/core/block/Block.java index 7b7f4fb6a..1e0e04bf4 100644 --- a/src/main/java/nova/core/block/Block.java +++ b/src/main/java/nova/core/block/Block.java @@ -30,7 +30,8 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.util.Direction; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import nova.core.world.World; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -59,7 +60,7 @@ public final BlockFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } diff --git a/src/main/java/nova/core/component/Category.java b/src/main/java/nova/core/component/Category.java index 95c8002d4..f8cd3a0df 100644 --- a/src/main/java/nova/core/component/Category.java +++ b/src/main/java/nova/core/component/Category.java @@ -21,7 +21,9 @@ package nova.core.component; import nova.core.item.Item; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import java.util.Optional; @@ -46,7 +48,7 @@ public Category(String name) { } @Override - public String getID() { - return name; + public Identifier getID() { + return new StringIdentifier(name); } } diff --git a/src/main/java/nova/core/component/Component.java b/src/main/java/nova/core/component/Component.java index df2ecd0d4..a0a854b6a 100644 --- a/src/main/java/nova/core/component/Component.java +++ b/src/main/java/nova/core/component/Component.java @@ -21,7 +21,9 @@ package nova.core.component; import nova.core.component.exception.ComponentException; -import nova.core.util.Identifiable; +import nova.core.util.id.ClassIdentifier; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; /** * Base interface for all Components. @@ -51,7 +53,7 @@ public void onProviderChange() { } @Override - public String getID() { - return getClass().getSimpleName(); + public Identifier getID() { + return new ClassIdentifier(getClass()); } } diff --git a/src/main/java/nova/core/component/fluid/Fluid.java b/src/main/java/nova/core/component/fluid/Fluid.java index 809e968ca..675c36a57 100644 --- a/src/main/java/nova/core/component/fluid/Fluid.java +++ b/src/main/java/nova/core/component/fluid/Fluid.java @@ -24,7 +24,9 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.retention.Store; -import nova.core.util.Identifiable; +import nova.core.util.id.AbstractIdentifier; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.Optional; @@ -126,7 +128,7 @@ public boolean sameType(Fluid stack) { } @Override - public final String getID() { + public final Identifier getID() { return factory.getID(); } @@ -138,12 +140,12 @@ public int hashCode() { @Override public void save(Data data) { Storable.super.save(data); - data.put("id", factory.getID()); + data.put("id", factory.getID().asString()); // TODO? } @Override public void load(Data data) { Storable.super.load(data); - factory = Game.fluids().get(data.get("id")).get(); + factory = Game.fluids().get(data.get("id")).get(); // FIXME } } diff --git a/src/main/java/nova/core/component/misc/Damageable.java b/src/main/java/nova/core/component/misc/Damageable.java index 5f4c63c7d..e5e6c9771 100644 --- a/src/main/java/nova/core/component/misc/Damageable.java +++ b/src/main/java/nova/core/component/misc/Damageable.java @@ -21,7 +21,9 @@ package nova.core.component.misc; import nova.core.component.Component; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; /** * Applied to objects that can take damage. @@ -46,8 +48,8 @@ public DamageType(String name) { } @Override - public String getID() { - return name; + public Identifier getID() { + return new StringIdentifier(name); } } } diff --git a/src/main/java/nova/core/entity/Entity.java b/src/main/java/nova/core/entity/Entity.java index c0943e100..e8edd4958 100644 --- a/src/main/java/nova/core/entity/Entity.java +++ b/src/main/java/nova/core/entity/Entity.java @@ -24,8 +24,10 @@ import nova.core.component.ComponentProvider; import nova.core.component.misc.FactoryProvider; import nova.core.component.transform.EntityTransform; -import nova.core.util.Identifiable; -import nova.core.util.UniqueIdentifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.UniqueIdentifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.UUIDIdentifier; import nova.core.world.World; import org.apache.commons.math3.geometry.euclidean.threed.Rotation; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; @@ -96,12 +98,12 @@ public final EntityFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } @Override - public String getUniqueID() { + public UUIDIdentifier getUniqueID() { return components.get(UniqueIdentifiable.class).getUniqueID(); } } diff --git a/src/main/java/nova/core/item/Item.java b/src/main/java/nova/core/item/Item.java index 61f6c86e1..255314bc7 100644 --- a/src/main/java/nova/core/item/Item.java +++ b/src/main/java/nova/core/item/Item.java @@ -27,7 +27,8 @@ import nova.core.render.Color; import nova.core.retention.Storable; import nova.core.util.Direction; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import java.util.List; @@ -50,7 +51,7 @@ public final ItemFactory getFactory() { } @Override - public final String getID() { + public final Identifier getID() { return getFactory().getID(); } diff --git a/src/main/java/nova/core/item/ItemFactory.java b/src/main/java/nova/core/item/ItemFactory.java index a31f83599..976b927ac 100644 --- a/src/main/java/nova/core/item/ItemFactory.java +++ b/src/main/java/nova/core/item/ItemFactory.java @@ -24,7 +24,7 @@ import nova.core.retention.Data; import nova.core.retention.Storable; import nova.core.util.registry.Factory; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import java.util.function.Function; import java.util.function.Supplier; diff --git a/src/main/java/nova/core/item/ItemManager.java b/src/main/java/nova/core/item/ItemManager.java index d31b79dcb..a95d91e6c 100644 --- a/src/main/java/nova/core/item/ItemManager.java +++ b/src/main/java/nova/core/item/ItemManager.java @@ -58,11 +58,11 @@ public ItemFactory register(ItemFactory factory) { } public ItemFactory getItemFromBlock(BlockFactory block) { - return registry.get(block.getID()).get(); + return registry.get(block.getID().asString()).get(); // TODO } public Optional getBlockFromItem(Item item) { - return blockManager.get().get(item.getID()); + return blockManager.get().get(item.getID().asString()); // TODO } @Override diff --git a/src/main/java/nova/core/network/Packet.java b/src/main/java/nova/core/network/Packet.java index 2ad0c0484..258c5c60f 100644 --- a/src/main/java/nova/core/network/Packet.java +++ b/src/main/java/nova/core/network/Packet.java @@ -26,16 +26,12 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.IntStream; /** * A packet of data that is writable or readable. + * * @author Calclavia */ public interface Packet { @@ -47,6 +43,7 @@ public interface Packet { /** * Sets the ID of this packet, allowing it to be sent accordingly. + * * @return The packet itself. */ Packet setID(int id); @@ -58,6 +55,7 @@ public interface Packet { /** * Writes an arbitrary object, automatically finding the relevant class. + * * @param data Object to write * @return This packet */ @@ -82,6 +80,8 @@ default Packet write(Object data) { writeString((String) data); } else if (data instanceof Enum) { writeEnum((Enum) data); + } else if (data instanceof Class) { + writeClass((Class) data); } else if (data instanceof Optional) { writeOptional((Optional) data); } else if (data instanceof Data) { @@ -101,6 +101,8 @@ default Packet write(Object data) { } else if (data instanceof Vector2D) { writeDouble(((Vector2D) data).getX()); writeDouble(((Vector2D) data).getY()); + } else if (data instanceof UUID) { + writeString(data.toString()); } else { throw new IllegalArgumentException("Packet attempt to write an invalid object: " + data); } @@ -115,6 +117,7 @@ default Packet write(Object data) { /** * Sets the specified boolean at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 1} in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 1} @@ -125,6 +128,7 @@ default Packet write(Object data) { * Sets the specified byte at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 1} in this buffer. * The 24 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 1} @@ -135,6 +139,7 @@ default Packet write(Object data) { * Sets the specified 16-bit short integer at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} * in this buffer. The 16 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 2} @@ -144,6 +149,7 @@ default Packet write(Object data) { /** * Sets the specified 32-bit integer at the current {@code writerIndex} * and increases the {@code writerIndex} by {@code 4} in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 4} @@ -154,6 +160,7 @@ default Packet write(Object data) { * Sets the specified 64-bit long integer at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 8} @@ -164,6 +171,7 @@ default Packet write(Object data) { * Sets the specified 2-byte UTF-16 character at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 2} * in this buffer. The 16 high-order bits of the specified value are ignored. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 2} @@ -174,6 +182,7 @@ default Packet write(Object data) { * Sets the specified 32-bit floating point number at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 4} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 4} @@ -184,6 +193,7 @@ default Packet write(Object data) { * Sets the specified 64-bit floating point number at the current * {@code writerIndex} and increases the {@code writerIndex} by {@code 8} * in this buffer. + * * @param value Data to write * @return This packet * @throws IndexOutOfBoundsException if {@code this.writableBytes} is less than {@code 8} @@ -199,6 +209,11 @@ default Packet writeEnum(Enum data) { return this; } + default Packet writeClass(Class data) { + writeString(data.getName()); + return this; + } + default int getType(Class compare) { return IntStream .range(0, Data.dataTypes.length) @@ -258,6 +273,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a boolean at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -266,6 +282,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a byte at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -274,6 +291,7 @@ default Packet writeOptional(Optional optional) { /** * Gets an unsigned byte at the current {@code readerIndex} and increases * the {@code readerIndex} by {@code 1} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 1} */ @@ -282,6 +300,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 16-bit short integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 2} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 2} */ @@ -290,6 +309,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 32-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -298,6 +318,7 @@ default Packet writeOptional(Optional optional) { /** * Gets an unsigned 32-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -306,6 +327,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 64-bit integer at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 8} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 8} */ @@ -314,6 +336,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 2-byte UTF-16 character at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 2} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 2} */ @@ -322,6 +345,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 32-bit floating point number at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 4} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 4} */ @@ -330,6 +354,7 @@ default Packet writeOptional(Optional optional) { /** * Gets a 64-bit floating point number at the current {@code readerIndex} * and increases the {@code readerIndex} by {@code 8} in this buffer. + * * @return Data read from this packet * @throws IndexOutOfBoundsException if {@code this.readableBytes} is less than {@code 8} */ @@ -426,6 +451,20 @@ default Vector3D readVector3D() { return new Vector3D(readDouble(), readDouble(), readDouble()); } + default Class readClass() { + try { + String classClassName = readString(); + Class classClass = (Class) Class.forName(classClassName); + return classClass; + } catch (Exception e) { + throw new NetworkException("Failed to read enum.", e); + } + } + + default UUID readUUID() { + return UUID.fromString(readString()); + } + default T read(Class clazz) { if (clazz == Boolean.class || clazz == boolean.class) { return (T) Boolean.valueOf(readBoolean()); @@ -459,6 +498,10 @@ else if (Syncable.class.isAssignableFrom(clazz)) { return (T) readVector3D(); } else if (Vector2D.class.isAssignableFrom(clazz)) { return (T) readVector2D(); + } else if (Class.class.isAssignableFrom(clazz)) { + return (T) readClass(); + } else if (UUID.class.isAssignableFrom(clazz)) { + return (T) readUUID(); } else if (List.class.isAssignableFrom(clazz)) { return (T) readList(); } else if (Set.class.isAssignableFrom(clazz)) { diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java index 6648c79ce..4587cbc5d 100644 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java @@ -24,6 +24,7 @@ import nova.core.recipes.RecipeAddedEvent; import nova.core.recipes.RecipeManager; import nova.core.recipes.RecipeRemovedEvent; +import nova.core.util.id.Identifier; import java.util.ArrayList; import java.util.Collection; @@ -37,6 +38,7 @@ * @author Stan Hebben */ public class CraftingRecipeManager { + // TODO switch this to using Identifiers private final RecipeManager recipeManager; private final List dynamicRecipes; private final Multimap staticRecipes; @@ -86,7 +88,7 @@ public Optional getRecipe(CraftingGrid grid) { return Optional.empty(); } - String firstItemId = firstItem.get().getID(); + String firstItemId = firstItem.get().getID().asString(); // TODO (this is BAD) if (!staticRecipes.containsKey(firstItemId)) { return Optional.empty(); } diff --git a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java index 6a4661d8e..52d3a473c 100644 --- a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java @@ -21,6 +21,7 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.ArrayList; @@ -46,7 +47,7 @@ public String getName() { @Override public Optional> getPossibleItemIds() { - return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).collect(Collectors.toList())); + return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).map(Identifier::asString).collect(Collectors.toList())); // TODO? } @Override diff --git a/src/main/java/nova/core/render/Asset.java b/src/main/java/nova/core/render/Asset.java index b5f9b96ec..5aafccaa4 100644 --- a/src/main/java/nova/core/render/Asset.java +++ b/src/main/java/nova/core/render/Asset.java @@ -20,7 +20,9 @@ package nova.core.render; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; /** * @author Calclavia @@ -48,7 +50,7 @@ public boolean equals(Object obj) { } @Override - public final String getID() { - return domain + ":" + name; + public final Identifier getID() { + return new StringIdentifier(domain + ":" + name); } } diff --git a/src/main/java/nova/core/render/RenderManager.java b/src/main/java/nova/core/render/RenderManager.java index c25f6b8eb..4098a8c87 100644 --- a/src/main/java/nova/core/render/RenderManager.java +++ b/src/main/java/nova/core/render/RenderManager.java @@ -43,7 +43,7 @@ public abstract class RenderManager extends Manager { public final Registry modelProviders = new Registry<>(); public ItemTexture registerTexture(ItemTexture texture) { - Optional itemTexture = itemTextures.get(texture.getID()); + Optional itemTexture = itemTextures.get(texture.getID().asString()); // TODO? if (itemTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return itemTexture.get(); @@ -53,7 +53,7 @@ public ItemTexture registerTexture(ItemTexture texture) { } public BlockTexture registerTexture(BlockTexture texture) { - Optional blockTexture = blockTextures.get(texture.getID()); + Optional blockTexture = blockTextures.get(texture.getID().asString()); // TODO? if (blockTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return blockTexture.get(); @@ -63,7 +63,7 @@ public BlockTexture registerTexture(BlockTexture texture) { } public EntityTexture registerTexture(EntityTexture texture) { - Optional entityTexture = entityTextures.get(texture.getID()); + Optional entityTexture = entityTextures.get(texture.getID().asString()); // TODO? if (entityTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return entityTexture.get(); @@ -73,7 +73,7 @@ public EntityTexture registerTexture(EntityTexture texture) { } public ModelProvider registerModel(ModelProvider modelProvider) { - Optional modelProviderCheck = modelProviders.get(modelProvider.getID()); + Optional modelProviderCheck = modelProviders.get(modelProvider.getID().asString()); // TODO? if (modelProviderCheck.isPresent()) { Game.logger().error("Attempt to register the same model twice: " + modelProvider); return modelProviderCheck.get(); diff --git a/src/main/java/nova/core/render/texture/Texture.java b/src/main/java/nova/core/render/texture/Texture.java index ee7596cfa..4c62b3c32 100644 --- a/src/main/java/nova/core/render/texture/Texture.java +++ b/src/main/java/nova/core/render/texture/Texture.java @@ -18,7 +18,9 @@ * along with NOVA. If not, see . */package nova.core.render.texture; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.math.Vector2DUtil; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; @@ -60,8 +62,8 @@ public String toString() { } @Override - public final String getID() { - return getResource(); + public final Identifier getID() { + return new StringIdentifier(getResource()); } @Override diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index 71d689c74..f3e2cea52 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -23,10 +23,7 @@ import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; +import java.util.*; /** * The data class is capable of storing named data. @@ -66,7 +63,9 @@ public class Data extends HashMap { Data.class, Collection.class, Vector3D.class, - Vector2D.class }; + Vector2D.class, + Class.class, + UUID.class }; public String className; @@ -108,6 +107,10 @@ public static Object unserialize(Data data) { return new Vector3D(data.get("x"), data.get("y"), data.get("z")); } else if (clazz == Vector2D.class) { return new Vector2D(data.get("x"), (double) data.get("y")); + } else if (clazz == UUID.class) { + return UUID.fromString(data.get("uuid")); + } else if (clazz == Class.class) { + return Class.forName(data.get("name")); } else { return unserialize(clazz, data); } @@ -165,6 +168,14 @@ public Object put(String key, Object value) { vectorData.put("x", ((Vector2D) value).getX()); vectorData.put("y", ((Vector2D) value).getY()); value = vectorData; + } else if (value instanceof UUID) { + Data uuidData = new Data(UUID.class); + uuidData.put("uuid", value.toString()); + value = uuidData; + } else if (value instanceof Class) { + Data classData = new Data(Class.class); + classData.put("name", ((Class) value).getName()); + value = classData; } else if (value instanceof Storable) { value = serialize((Storable) value); } @@ -214,4 +225,19 @@ public T getStorable(String key) { } } + public Class getClass(String key) { + Data classData = get(key); + try { + @SuppressWarnings("unchecked") + Class classClass = (Class) Class.forName(classData.className); + return classClass; + } catch (Exception e) { + throw new DataException(e); + } + } + + public UUID getUUID(String key) { + Data data = get(key); + return UUID.fromString(data.get("uuid")); + } } diff --git a/src/main/java/nova/core/retention/Storable.java b/src/main/java/nova/core/retention/Storable.java index 84fcfbed7..2e1fdb586 100644 --- a/src/main/java/nova/core/retention/Storable.java +++ b/src/main/java/nova/core/retention/Storable.java @@ -61,11 +61,11 @@ default void load(Data data) { if (data.containsKey(name)) { try { field.setAccessible(true); - Class type = field.getType(); + Class type = field.getType(); // FIXME Object fieldValue = field.get(this); Object value = data.get(name); - if (Storable.class.isAssignableFrom(type) || value instanceof Data) { - if (fieldValue instanceof Storable && value instanceof Data) { + if (Storable.class.isAssignableFrom(type) || value instanceof Data) { // FIXME should test things based on `data` + if (fieldValue instanceof Storable && value instanceof Data) { // this one is fine tho //We already have an instance. Don't need to create the object. ((Storable) fieldValue).load((Data) value); } else { diff --git a/src/main/java/nova/core/sound/Sound.java b/src/main/java/nova/core/sound/Sound.java index 127bc23d3..6dc35697d 100644 --- a/src/main/java/nova/core/sound/Sound.java +++ b/src/main/java/nova/core/sound/Sound.java @@ -21,7 +21,7 @@ package nova.core.sound; import nova.core.render.Asset; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; /** * An object representing a sound. (including the modification to pitch and volume, etc...) diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java new file mode 100644 index 000000000..651b5438d --- /dev/null +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -0,0 +1,46 @@ +package nova.core.util.id; + +import nova.core.retention.Data; +import nova.core.retention.Storable; +import nova.core.retention.Store; + +/** + * Basic implementation of Identifier. + * + * @author soniex2 + */ +public abstract class AbstractIdentifier implements Identifier { + /** + * The ID. + */ + protected final T id; + + /** + * Constructs a new AbstractIdentifier. + * + * @param id The ID. + */ + public AbstractIdentifier(T id) { + this.id = id; + } + + @Override + public String asString() { + return id.toString(); + } + + @Override + public String toString() { + return id.toString(); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + @Override + public boolean equals(Object o) { + return this == o || (o != null && getClass() == o.getClass() && id.equals(((AbstractIdentifier) o).id)); + } +} diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java new file mode 100644 index 000000000..8fbc7466c --- /dev/null +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -0,0 +1,32 @@ +package nova.core.util.id; + +/** + * A Class Identifier. + * + * @author soniex2 + */ +public final class ClassIdentifier extends AbstractIdentifier> implements Identifier { + + /** + * Constructs a new ClassIdentifier. + * + * @param id The Class. + */ + public ClassIdentifier(Class id) { + super(id); + } + + @Override + public String asString() { + return id.getSimpleName(); + } + + /** + * Returns this Identifier's Class. + * + * @return The Class. + */ + public Class asClass() { + return id; + } +} diff --git a/src/main/java/nova/core/util/Identifiable.java b/src/main/java/nova/core/util/id/Identifiable.java similarity index 96% rename from src/main/java/nova/core/util/Identifiable.java rename to src/main/java/nova/core/util/id/Identifiable.java index e98159e43..3ff8c86ff 100644 --- a/src/main/java/nova/core/util/Identifiable.java +++ b/src/main/java/nova/core/util/id/Identifiable.java @@ -18,7 +18,7 @@ * along with NOVA. If not, see . */ -package nova.core.util; +package nova.core.util.id; /** * A generic interface signifying that this object is identifiable @@ -30,7 +30,7 @@ public interface Identifiable { * * @return the ID */ - String getID(); + Identifier getID(); /** * Compares the ID of the Identifialbes diff --git a/src/main/java/nova/core/util/id/Identifier.java b/src/main/java/nova/core/util/id/Identifier.java new file mode 100644 index 000000000..7453cef99 --- /dev/null +++ b/src/main/java/nova/core/util/id/Identifier.java @@ -0,0 +1,19 @@ +package nova.core.util.id; + +/** + * The interface for all identifiers. + *

+ * Implementations should override {@link Object#equals(Object)}, {@link Object#hashCode()} and {@link Object#toString()}. + *

+ * + * @author soniex2 + */ +public interface Identifier { + /** + * Converts this Identifier into a String. + * The output from this method may be different than {@link Object#toString()}. + * + * @return A string representation of this Identifier. + */ + String asString(); +} diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java new file mode 100644 index 000000000..f52b45030 --- /dev/null +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -0,0 +1,18 @@ +package nova.core.util.id; + +/** + * A String Identifier. + * + * @author soniex2 + */ +public final class StringIdentifier extends AbstractIdentifier implements Identifier { + + /** + * Constructs a new StringIdentifier. + * + * @param id The String. + */ + public StringIdentifier(String id) { + super(id); + } +} diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java new file mode 100644 index 000000000..754c214fd --- /dev/null +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -0,0 +1,29 @@ +package nova.core.util.id; + +import java.util.UUID; + +/** + * An UUID Identifier. + * + * @author soniex2 + */ +public final class UUIDIdentifier extends AbstractIdentifier implements Identifier { + + /** + * Constructs a new UUIDIdentifier. + * + * @param id The UUID. + */ + public UUIDIdentifier(UUID id) { + super(id); + } + + /** + * Returns this Identifier's UUID. + * + * @return The UUID. + */ + public UUID asUUID() { + return id; + } +} diff --git a/src/main/java/nova/core/util/UniqueIdentifiable.java b/src/main/java/nova/core/util/id/UniqueIdentifiable.java similarity index 87% rename from src/main/java/nova/core/util/UniqueIdentifiable.java rename to src/main/java/nova/core/util/id/UniqueIdentifiable.java index a795892d1..ae37ad60f 100644 --- a/src/main/java/nova/core/util/UniqueIdentifiable.java +++ b/src/main/java/nova/core/util/id/UniqueIdentifiable.java @@ -18,7 +18,9 @@ * along with NOVA. If not, see . */ -package nova.core.util; +package nova.core.util.id; + +import nova.core.util.id.UUIDIdentifier; /** * A generic interface signifying that this object is uniquely identifiable @@ -30,5 +32,5 @@ public interface UniqueIdentifiable { * * @return the ID */ - String getUniqueID(); + UUIDIdentifier getUniqueID(); // TODO maybe this should return a simple Identifier } diff --git a/src/main/java/nova/core/util/registry/Factory.java b/src/main/java/nova/core/util/registry/Factory.java index 7ce169d1e..2034a3168 100644 --- a/src/main/java/nova/core/util/registry/Factory.java +++ b/src/main/java/nova/core/util/registry/Factory.java @@ -20,7 +20,10 @@ package nova.core.util.registry; -import nova.core.util.Identifiable; +import nova.core.component.ComponentProvider; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import java.util.function.Function; import java.util.function.Supplier; @@ -78,7 +81,7 @@ public T build() { return processor.apply(constructor.get()); } - public String getID() { - return id; + public Identifier getID() { + return new StringIdentifier(id); } } diff --git a/src/main/java/nova/core/util/registry/FactoryManager.java b/src/main/java/nova/core/util/registry/FactoryManager.java index 20a38d558..8c2281833 100644 --- a/src/main/java/nova/core/util/registry/FactoryManager.java +++ b/src/main/java/nova/core/util/registry/FactoryManager.java @@ -20,7 +20,7 @@ package nova.core.util.registry; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import java.util.Optional; import java.util.function.Supplier; diff --git a/src/main/java/nova/core/util/registry/Registry.java b/src/main/java/nova/core/util/registry/Registry.java index bf25553d9..24e724416 100644 --- a/src/main/java/nova/core/util/registry/Registry.java +++ b/src/main/java/nova/core/util/registry/Registry.java @@ -19,7 +19,8 @@ */package nova.core.util.registry; import com.google.common.collect.HashBiMap; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import java.util.Iterator; import java.util.Optional; @@ -32,6 +33,7 @@ * @param The object type */ public class Registry implements Iterable { + // TODO maybe index by Identifier? Could be nice when the game uses int IDs (e.g. very old versions of minecraft). private final HashBiMap objects = HashBiMap.create(); public Registry() { @@ -45,7 +47,7 @@ public Registry() { * @return Given object */ public T register(T object) { - objects.put(object.getID(), object); + objects.put(object.getID().asString(), object); return object; } diff --git a/src/main/java/nova/core/world/World.java b/src/main/java/nova/core/world/World.java index d89565221..22832ac35 100644 --- a/src/main/java/nova/core/world/World.java +++ b/src/main/java/nova/core/world/World.java @@ -24,7 +24,7 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; -import nova.core.util.Identifiable; +import nova.core.util.id.Identifiable; import nova.core.util.shape.Cuboid; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.threed.Vector3D; diff --git a/src/test/java/nova/core/util/MockIdentifiable.java b/src/test/java/nova/core/util/MockIdentifiable.java index a69500bc8..33569e31c 100644 --- a/src/test/java/nova/core/util/MockIdentifiable.java +++ b/src/test/java/nova/core/util/MockIdentifiable.java @@ -20,6 +20,10 @@ package nova.core.util; +import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; + public class MockIdentifiable implements Identifiable { String ID; @@ -28,12 +32,12 @@ public MockIdentifiable(String ID) { } @Override - public String getID() { - return ID; + public Identifier getID() { + return new StringIdentifier(ID); } @Override public String toString() { - return getID(); + return getID().asString(); } } diff --git a/src/test/java/nova/core/util/RegistryTest.java b/src/test/java/nova/core/util/RegistryTest.java index 79afd10d8..9e80a9313 100644 --- a/src/test/java/nova/core/util/RegistryTest.java +++ b/src/test/java/nova/core/util/RegistryTest.java @@ -20,6 +20,8 @@ package nova.core.util; +import nova.core.util.id.Identifiable; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.Registry; import org.junit.Test; @@ -41,8 +43,8 @@ public void testRegistry() throws Exception { assertThat(registry.contains("ID1")).isTrue(); assertThat(registry.contains("ID2")).isTrue(); - assertThat(registry.get("ID1").get().getID()).isEqualTo("ID1"); - assertThat(registry.get("ID2").get().getID()).isEqualTo("ID2"); + assertThat(registry.get("ID1").get().getID()).isEqualTo(new StringIdentifier("ID1")); + assertThat(registry.get("ID2").get().getID()).isEqualTo(new StringIdentifier("ID2")); assertThat(registry.get("ID1").get()).isEqualTo(id1); assertThat(registry.get("ID2").get()).isEqualTo(id2); diff --git a/src/test/java/nova/testutils/FakeWorld.java b/src/test/java/nova/testutils/FakeWorld.java index c4443bdb5..522e878ab 100644 --- a/src/test/java/nova/testutils/FakeWorld.java +++ b/src/test/java/nova/testutils/FakeWorld.java @@ -28,6 +28,8 @@ import nova.core.entity.EntityFactory; import nova.core.item.Item; import nova.core.sound.Sound; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.shape.Cuboid; import nova.core.world.World; import nova.internal.core.Game; @@ -131,7 +133,7 @@ public void playSoundAtPosition(Vector3D position, Sound sound) { } @Override - public String getID() { - return "fakeWorld"; + public Identifier getID() { + return new StringIdentifier("fakeWorld"); } } From 4d35bba4bc79ac57dd6efcc1ef9064c54d502298 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 8 Jan 2017 19:10:18 -0200 Subject: [PATCH 3/6] Tweak identifiers a bit. --- .../mc/forge/v17/launcher/NovaMinecraft.java | 2 + .../identifier/IdentifierConverter.java | 32 +++++ .../mc/forge/v18/launcher/NovaMinecraft.java | 2 + .../identifier/IdentifierConverter.java | 32 +++++ .../nova/core/util/id/AbstractIdentifier.java | 10 +- .../util/id/NamespacedStringIdentifier.java | 136 ++++++++++++++++++ 6 files changed, 208 insertions(+), 6 deletions(-) create mode 100644 minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/identifier/IdentifierConverter.java create mode 100644 minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/identifier/IdentifierConverter.java create mode 100644 src/main/java/nova/core/util/id/NamespacedStringIdentifier.java diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/launcher/NovaMinecraft.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/launcher/NovaMinecraft.java index 5201d012d..679d24d03 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/launcher/NovaMinecraft.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/launcher/NovaMinecraft.java @@ -49,6 +49,7 @@ import nova.core.wrapper.mc.forge.v17.wrapper.cuboid.CuboidConverter; import nova.core.wrapper.mc.forge.v17.wrapper.data.DataWrapper; import nova.core.wrapper.mc.forge.v17.wrapper.entity.EntityConverter; +import nova.core.wrapper.mc.forge.v17.wrapper.identifier.IdentifierConverter; import nova.core.wrapper.mc.forge.v17.wrapper.inventory.InventoryConverter; import nova.core.wrapper.mc.forge.v17.wrapper.item.ItemConverter; import nova.core.wrapper.mc.forge.v17.wrapper.item.OreDictionaryIntegration; @@ -120,6 +121,7 @@ public void preInit(FMLPreInitializationEvent evt) { Game.natives().registerConverter(new WorldConverter()); Game.natives().registerConverter(new CuboidConverter()); Game.natives().registerConverter(new InventoryConverter()); + Game.natives().registerConverter(new IdentifierConverter()); /** * Initiate recipe and ore dictionary integration diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/identifier/IdentifierConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/identifier/IdentifierConverter.java new file mode 100644 index 000000000..6381c231a --- /dev/null +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/identifier/IdentifierConverter.java @@ -0,0 +1,32 @@ +package nova.core.wrapper.mc.forge.v17.wrapper.identifier; + +import net.minecraft.util.ResourceLocation; +import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.NamespacedStringIdentifier; + +/** + * @author soniex2 + */ +public class IdentifierConverter implements NativeConverter { + + @Override + public Class getNovaSide() { + return NamespacedStringIdentifier.class; + } + + @Override + public Class getNativeSide() { + return ResourceLocation.class; + } + + @Override + public NamespacedStringIdentifier toNova(ResourceLocation nativeObj) { + return new NamespacedStringIdentifier(nativeObj.toString()); + } + + @Override + public ResourceLocation toNative(NamespacedStringIdentifier novaObj) { + NamespacedStringIdentifier.NamespacedString ns = novaObj.asNamespacedString(); + return new ResourceLocation(ns.getNamespace(), ns.getName()); + } +} diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/launcher/NovaMinecraft.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/launcher/NovaMinecraft.java index eb0a0f321..c371d63b0 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/launcher/NovaMinecraft.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/launcher/NovaMinecraft.java @@ -50,6 +50,7 @@ import nova.core.wrapper.mc.forge.v18.wrapper.cuboid.CuboidConverter; import nova.core.wrapper.mc.forge.v18.wrapper.data.DataWrapper; import nova.core.wrapper.mc.forge.v18.wrapper.entity.EntityConverter; +import nova.core.wrapper.mc.forge.v18.wrapper.identifier.IdentifierConverter; import nova.core.wrapper.mc.forge.v18.wrapper.inventory.InventoryConverter; import nova.core.wrapper.mc.forge.v18.wrapper.item.ItemConverter; import nova.core.wrapper.mc.forge.v18.wrapper.item.OreDictionaryIntegration; @@ -122,6 +123,7 @@ public void preInit(FMLPreInitializationEvent evt) { Game.natives().registerConverter(new CuboidConverter()); Game.natives().registerConverter(new InventoryConverter()); Game.natives().registerConverter(new VectorConverter()); + Game.natives().registerConverter(new IdentifierConverter()); /** * Initiate recipe and ore dictionary integration diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/identifier/IdentifierConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/identifier/IdentifierConverter.java new file mode 100644 index 000000000..86e99d961 --- /dev/null +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/identifier/IdentifierConverter.java @@ -0,0 +1,32 @@ +package nova.core.wrapper.mc.forge.v18.wrapper.identifier; + +import net.minecraft.util.ResourceLocation; +import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.NamespacedStringIdentifier; + +/** + * @author soniex2 + */ +public class IdentifierConverter implements NativeConverter { + + @Override + public Class getNovaSide() { + return NamespacedStringIdentifier.class; + } + + @Override + public Class getNativeSide() { + return ResourceLocation.class; + } + + @Override + public NamespacedStringIdentifier toNova(ResourceLocation nativeObj) { + return new NamespacedStringIdentifier(nativeObj.toString()); + } + + @Override + public ResourceLocation toNative(NamespacedStringIdentifier novaObj) { + NamespacedStringIdentifier.NamespacedString ns = novaObj.asNamespacedString(); + return new ResourceLocation(ns.getNamespace(), ns.getName()); + } +} diff --git a/src/main/java/nova/core/util/id/AbstractIdentifier.java b/src/main/java/nova/core/util/id/AbstractIdentifier.java index 651b5438d..e1ba4d65a 100644 --- a/src/main/java/nova/core/util/id/AbstractIdentifier.java +++ b/src/main/java/nova/core/util/id/AbstractIdentifier.java @@ -1,8 +1,6 @@ package nova.core.util.id; -import nova.core.retention.Data; -import nova.core.retention.Storable; -import nova.core.retention.Store; +import java.util.Objects; /** * Basic implementation of Identifier. @@ -21,7 +19,7 @@ public abstract class AbstractIdentifier implements Identifier { * @param id The ID. */ public AbstractIdentifier(T id) { - this.id = id; + this.id = Objects.requireNonNull(id); } @Override @@ -35,12 +33,12 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return id.hashCode(); } @Override - public boolean equals(Object o) { + public final boolean equals(Object o) { return this == o || (o != null && getClass() == o.getClass() && id.equals(((AbstractIdentifier) o).id)); } } diff --git a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java new file mode 100644 index 000000000..50efe425d --- /dev/null +++ b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java @@ -0,0 +1,136 @@ +package nova.core.util.id; + +import java.util.Objects; + +/** + * A namespace:name identifier + * + * @author soniex2 + */ +public class NamespacedStringIdentifier extends AbstractIdentifier { + + /** + * Constructs a new NamespacedStringIdentifier. + * + * @param namespace The namespace. + * @param name The name. + */ + public NamespacedStringIdentifier(String namespace, String name) { + super(new NamespacedString(namespace, name)); + } + + /** + * Constructs a new NamespacedStringIdentifier. + * + * @param namespacedname The colon-separated namespaced name. + */ + public NamespacedStringIdentifier(String namespacedname) { + super(new NamespacedString(namespacedname)); + } + + /** + * Constructs a new NamespacedStringIdentifier. + * + * @param namespacedstring The NamespacedString. + */ + public NamespacedStringIdentifier(NamespacedString namespacedstring) { + super(namespacedstring); + } + + /** + * Returns the namespaced string. + * + * @return The namespaced string. + */ + public NamespacedString asNamespacedString() { + return id; + } + + public static final class NamespacedString { + private final String namespace; + private final String name; + + /** + * Constructs a new NamespacedString. + * + * @param namespace The namespace. + * @param name The name. + */ + public NamespacedString(String namespace, String name) { + if (namespace.contains(":")) { + throw new IllegalArgumentException("Namespace must not contain a colon"); + } + this.namespace = Objects.requireNonNull(namespace).intern(); + this.name = Objects.requireNonNull(name).intern(); + } + + /** + * Constructs a new NamespacedString. + * + * @param namespacedname The colon-separated namespaced name. + */ + public NamespacedString(String namespacedname) { + this(nsOf(namespacedname), nameOf(namespacedname)); + } + + /** + * Returns the namespace. + * + * @return The namespace. + */ + public String getNamespace() { + return namespace; + } + + /** + * Returns the name. + * + * @return The name. + */ + public String getName() { + return name; + } + + @Override + public String toString() { + return namespace + ":" + name; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + NamespacedString that = (NamespacedString) o; + + if (!namespace.equals(that.namespace)) + return false; + return name.equals(that.name); + } + + @Override + public int hashCode() { + return 31 * namespace.hashCode() + name.hashCode(); + } + + private static String nameOf(String namespacedname) { + int index = namespacedname.indexOf(':'); + if (index < 0) { + return namespacedname; + } else { + return namespacedname.substring(index + 1); + } + } + + private static String nsOf(String namespacedname) { + int index = namespacedname.indexOf(':'); + if (index < 0) { + return ""; + } else { + return namespacedname.substring(0, index); + } + } + } +} From 7dbb6617b01e3362f281f108830d22c1b5987d1f Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 8 Jan 2017 23:16:39 -0200 Subject: [PATCH 4/6] Clean up TODOs --- .../v17/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v17/recipes/RecipeConverter.java | 2 +- .../v17/wrapper/block/BlockConverter.java | 7 ++-- .../v17/wrapper/block/forward/FWBlock.java | 4 +- .../wrapper/block/forward/FWTileLoader.java | 10 +++-- .../v17/wrapper/entity/EntityConverter.java | 7 +++- .../v17/wrapper/entity/forward/FWEntity.java | 29 ++++++++++++-- .../mc/forge/v17/wrapper/item/BWItem.java | 2 +- .../forge/v17/wrapper/item/BWItemFactory.java | 11 +++++- .../mc/forge/v17/wrapper/item/FWItem.java | 2 +- .../forge/v17/wrapper/item/ItemConverter.java | 13 ++++--- .../v18/recipes/MinecraftItemIngredient.java | 2 +- .../mc/forge/v18/recipes/RecipeConverter.java | 2 +- .../v18/wrapper/block/BlockConverter.java | 6 ++- .../v18/wrapper/block/forward/FWBlock.java | 4 +- .../wrapper/block/forward/FWBlockSound.java | 6 +-- .../wrapper/block/forward/FWTileLoader.java | 10 +++-- .../v18/wrapper/entity/EntityConverter.java | 7 +++- .../v18/wrapper/entity/forward/FWEntity.java | 29 ++++++++++++-- .../mc/forge/v18/wrapper/item/BWItem.java | 2 +- .../forge/v18/wrapper/item/BWItemFactory.java | 16 +++++++- .../mc/forge/v18/wrapper/item/FWItem.java | 2 +- .../forge/v18/wrapper/item/ItemConverter.java | 14 ++++--- .../java/nova/core/block/BlockFactory.java | 9 +++-- .../java/nova/core/block/BlockManager.java | 6 ++- .../java/nova/core/component/fluid/Fluid.java | 4 +- .../core/component/fluid/FluidFactory.java | 7 ++-- .../core/component/fluid/FluidManager.java | 8 ++-- .../java/nova/core/entity/EntityFactory.java | 7 ++-- .../java/nova/core/entity/EntityManager.java | 3 +- src/main/java/nova/core/item/ItemFactory.java | 7 ++-- src/main/java/nova/core/item/ItemManager.java | 9 +++-- .../core/item/event/ItemIDNotFoundEvent.java | 5 ++- .../core/recipes/crafting/CraftingRecipe.java | 3 +- .../crafting/CraftingRecipeManager.java | 13 +++---- .../core/recipes/crafting/ItemIngredient.java | 5 ++- .../recipes/crafting/OreItemIngredient.java | 4 +- .../crafting/ShapedCraftingRecipe.java | 9 +++-- .../crafting/SpecificItemIngredient.java | 11 +++--- src/main/java/nova/core/render/Asset.java | 4 +- .../java/nova/core/render/RenderManager.java | 8 ++-- .../nova/core/render/texture/Texture.java | 8 ++-- src/main/java/nova/core/retention/Data.java | 39 ++++++++++++++++++- .../nova/core/retention/DataConverter.java | 10 +++++ .../nova/core/retention/DataConvertible.java | 14 +++++++ .../nova/core/util/id/ClassIdentifier.java | 23 +++++++++++ .../util/id/NamespacedStringIdentifier.java | 25 ++++++++++-- .../nova/core/util/id/StringIdentifier.java | 17 ++++++++ .../nova/core/util/id/UUIDIdentifier.java | 17 ++++++++ .../java/nova/core/util/registry/Factory.java | 15 +++---- .../core/util/registry/FactoryManager.java | 5 ++- .../nova/core/util/registry/Registry.java | 11 +++--- .../java/nova/core/world/WorldFactory.java | 7 ++-- .../java/nova/core/world/WorldManager.java | 3 +- .../java/nova/core/util/RayTraceTest.java | 5 ++- .../java/nova/core/util/RegistryTest.java | 14 +++---- .../wrappertests/NovaLauncherTestFactory.java | 3 +- 57 files changed, 384 insertions(+), 143 deletions(-) create mode 100644 src/main/java/nova/core/retention/DataConverter.java create mode 100644 src/main/java/nova/core/retention/DataConvertible.java diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java index ddf1fbe86..80ca24af7 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? + super(((Item) Game.natives().toNova(itemStack)).getID()); // TODO? } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java index f02af76db..298f3d266 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java index 9e7c845cc..bd48ca1ca 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/BlockConverter.java @@ -32,6 +32,7 @@ import nova.core.event.BlockEvent; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v17.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v17.wrapper.block.backward.BWBlock; @@ -107,7 +108,7 @@ private void registerMinecraftToNOVA() { BlockManager blockManager = Game.blocks(); net.minecraft.block.Block.blockRegistry.forEach(obj -> blockManager.register( - new BlockFactory(net.minecraft.block.Block.blockRegistry.getNameForObject(obj).toString(), + new BlockFactory(new StringIdentifier(net.minecraft.block.Block.blockRegistry.getNameForObject(obj)), () -> new BWBlock((net.minecraft.block.Block) obj), evt -> { }) ) @@ -118,7 +119,7 @@ private void registerNOVAToMinecraft() { BlockManager blockManager = Game.blocks(); //Register air block - BlockFactory airBlock = new BlockFactory("air", () -> new BWBlock(Blocks.air) { + BlockFactory airBlock = new BlockFactory(new StringIdentifier("air"), () -> new BWBlock(Blocks.air) { @Override public boolean canReplace() { return true; @@ -136,7 +137,7 @@ private void registerNovaBlock(BlockFactory blockFactory) { FWBlock blockWrapper = new FWBlock(blockFactory); blockFactoryMap.put(blockFactory, blockWrapper); NovaMinecraft.proxy.registerBlock(blockWrapper); - GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); // TODO? + GameRegistry.registerBlock(blockWrapper, FWItemBlock.class, blockFactory.getID().asString()); if (blockWrapper.dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java index b4710f806..5656eae8c 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWBlock.java @@ -91,7 +91,7 @@ public FWBlock(BlockFactory factory) { this.factory = factory; this.dummy = factory.build(); this.blockClass = dummy.getClass(); - this.setBlockName(dummy.getID().asString()); // TODO? + this.setBlockName(dummy.getID().asString()); // Recalculate super constructor things after loading the block properly this.opaque = isOpaqueCube(); @@ -169,7 +169,7 @@ public boolean hasTileEntity(int metadata) { @Override public TileEntity createTileEntity(World world, int metadata) { - return FWTileLoader.loadTile(dummy.getID().asString()); // TODO? + return FWTileLoader.loadTile(dummy.getID()); } @Override diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java index 64c75e154..2c5ec60df 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/block/forward/FWTileLoader.java @@ -23,6 +23,8 @@ import net.minecraft.nbt.NBTTagCompound; import nova.core.block.Block; import nova.core.block.BlockFactory; +import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v17.asm.lib.ComponentInjector; import nova.internal.core.Game; @@ -40,8 +42,8 @@ private FWTileLoader() { public static FWTile loadTile(NBTTagCompound data) { try { - String blockID = data.getString("novaID"); - Block block = createBlock(blockID); + Data blockID = Game.natives().toNova(data.getCompoundTag("novaID")); + Block block = createBlock((Identifier) Data.unserialize(blockID)); FWTile tile = injector.inject(block, new Class[0], new Object[0]); tile.setBlock(block); return tile; @@ -50,7 +52,7 @@ public static FWTile loadTile(NBTTagCompound data) { } } - public static FWTile loadTile(String blockID) { + public static FWTile loadTile(Identifier blockID) { try { Block block = createBlock(blockID); FWTile tile = injector.inject(block, new Class[] { String.class }, new Object[] { blockID }); @@ -61,7 +63,7 @@ public static FWTile loadTile(String blockID) { } } - private static Block createBlock(String blockID) { + private static Block createBlock(Identifier blockID) { Optional blockFactory = Game.blocks().get(blockID); if (blockFactory.isPresent()) { return blockFactory.get().build(); diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java index 1fcb3a453..b86f98d64 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/EntityConverter.java @@ -26,6 +26,9 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.ClassIdentifier; +import nova.core.util.id.Identifier; +import nova.core.util.id.NamespacedStringIdentifier; import nova.core.wrapper.mc.forge.v17.wrapper.entity.backward.BWEntity; import nova.core.wrapper.mc.forge.v17.wrapper.entity.backward.BWEntityFX; import nova.core.wrapper.mc.forge.v17.wrapper.entity.forward.FWEntity; @@ -55,7 +58,7 @@ public Entity toNova(net.minecraft.entity.Entity mcEntity) { //TODO: Make this BWRegistry non-lazy //Lazy registry - String id = mcEntity.getClass().getName(); + Identifier id = new ClassIdentifier(mcEntity.getClass()); Optional entityFactory = Game.entities().get(id); if (entityFactory.isPresent()) { @@ -84,6 +87,6 @@ public void preInit() { */ //Look up for particle factory and pass it into BWEntityFX - BWEntityFX.fxMap.forEach((k, v) -> Game.entities().register(Game.info().name + ":" + k, () -> new BWEntityFX(k))); + BWEntityFX.fxMap.forEach((k, v) -> Game.entities().register(new NamespacedStringIdentifier(Game.info().name, k), () -> new BWEntityFX(k))); } } \ No newline at end of file diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java index 9e4a91a4b..5775d49b8 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/entity/forward/FWEntity.java @@ -30,9 +30,12 @@ import nova.core.component.transform.EntityTransform; import nova.core.entity.Entity; import nova.core.entity.EntityFactory; +import nova.core.network.Packet; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.Identifier; import nova.core.util.shape.Cuboid; +import nova.core.wrapper.mc.forge.v17.network.MCPacket; import nova.core.wrapper.mc.forge.v17.wrapper.data.DataWrapper; import nova.internal.core.Game; @@ -64,7 +67,9 @@ protected void readEntityFromNBT(NBTTagCompound nbt) { } if (wrapped == null) { //This entity was saved to disk. - setWrapped(Game.entities().get(nbt.getString("novaID")).get().build()); + NBTTagCompound novaId = nbt.getCompoundTag("novaID"); + Data d = Game.natives().toNova(novaId); + setWrapped(Game.entities().get((Identifier) Data.unserialize(d)).get().build()); } } @@ -75,22 +80,39 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID().asString()); // TODO? + Data data = new Data(); + data.put("novaID", wrapped.getID()); + NBTTagCompound novaId = new NBTTagCompound(); + DataWrapper.instance().toNative(novaId, data); + nbt.setTag("novaID", novaId); } @Override public void writeSpawnData(ByteBuf buffer) { + Packet packet = new MCPacket(buffer); + Data data = new Data(); + data.put("novaID", wrapped.getID()); + packet.writeData(data); + + /* //Write the ID of the entity to client - String id = wrapped.getID().asString(); // TODO? + String id = wrapped.getID(); char[] chars = id.toCharArray(); buffer.writeInt(chars.length); for (char c : chars) buffer.writeChar(c); + */ } @Override public void readSpawnData(ByteBuf buffer) { + Packet packet = new MCPacket(buffer); + Data d = packet.readData(); + + setWrapped(Game.entities().get((Identifier) Data.unserialize(d)).get().build()); + + /* //Load the client ID String id = ""; int length = buffer.readInt(); @@ -98,6 +120,7 @@ public void readSpawnData(ByteBuf buffer) { id += buffer.readChar(); setWrapped(Game.entities().get(id).get().build()); + */ } public Entity getWrapped() { diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java index 08fd8ebae..ac6dd4aaa 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItem.java @@ -97,6 +97,6 @@ public net.minecraft.item.ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID().asString(); // TODO? + return getID().asString(); } } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java index fa9f5ae35..a0a7e2885 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/BWItemFactory.java @@ -21,10 +21,14 @@ package nova.core.wrapper.mc.forge.v17.wrapper.item; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import nova.core.component.misc.FactoryProvider; import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.retention.Data; +import nova.core.util.id.Identifier; +import nova.core.util.id.NamespacedStringIdentifier; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; /** @@ -36,8 +40,13 @@ public class BWItemFactory extends ItemFactory { private final net.minecraft.item.Item item; private final int meta; + private static Identifier idFromItem(net.minecraft.item.Item item, int meta) { + // 1.7 used strings instead of ResourceLocation. + return new StringIdentifier(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : "")); + } + public BWItemFactory(net.minecraft.item.Item item, int meta) { - super(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : ""), () -> new BWItem(item, meta, null)); + super(idFromItem(item, meta), () -> new BWItem(item, meta, null)); this.item = item; this.meta = meta; diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java index ebc78662b..23eb6731b 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID().asString()); // TODO? + setUnlocalizedName(item.getID().asString()); setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java index 17b988425..f158eff99 100644 --- a/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java +++ b/minecraft/1.7/src/main/java/nova/core/wrapper/mc/forge/v17/wrapper/item/ItemConverter.java @@ -35,6 +35,7 @@ import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v17.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v17.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v17.wrapper.block.BlockConverter; @@ -106,7 +107,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID().asString()).get(); // TODO? + ItemFactory itemFactory = Game.items().get(item.getID()).get(); // TODO? FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -133,7 +134,7 @@ public ItemStack toNative(ItemFactory itemFactory) { return result; } - public ItemStack toNative(String id) { + public ItemStack toNative(Identifier id) { return toNative(Game.items().get(id).get().build().setCount(1)); } @@ -202,7 +203,7 @@ private void registerNOVAItem(ItemFactory itemFactory) { // Don't register ItemBlocks twice if (!(dummy instanceof ItemBlock)) { NovaMinecraft.proxy.registerItem((FWItem) itemWrapper); - GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); // TODO? + GameRegistry.registerItem(itemWrapper, itemFactory.getID().asString()); if (dummy.components.has(Category.class) && FMLCommonHandler.instance().getSide().isClient()) { //Add into creative tab @@ -239,14 +240,14 @@ private void onIDNotFound(ItemIDNotFoundEvent event) { // if item minecraft:planks:2 is detected, this code will register minecraft:planks:2 dynamically // we cannot do this up front since there is **NO** reliable way to get the sub-items of an item - int lastColon = event.id.lastIndexOf(':'); + int lastColon = event.id.asString().lastIndexOf(':'); if (lastColon < 0) { return; } try { - int meta = Integer.parseInt(event.id.substring(lastColon + 1)); - String itemID = event.id.substring(0, lastColon); + int meta = Integer.parseInt(event.id.asString().substring(lastColon + 1)); + String itemID = event.id.asString().substring(0, lastColon); net.minecraft.item.Item item = (net.minecraft.item.Item) net.minecraft.item.Item.itemRegistry.getObject(itemID); if (item == null || !item.getHasSubtypes()) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java index 40701caf8..34873b89f 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/MinecraftItemIngredient.java @@ -29,6 +29,6 @@ */ public class MinecraftItemIngredient extends SpecificItemIngredient { public MinecraftItemIngredient(net.minecraft.item.ItemStack itemStack) { - super(((Item) Game.natives().toNova(itemStack)).getID().asString()); // TODO? + super(((Item) Game.natives().toNova(itemStack)).getID()); // TODO? } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java index 8547f577c..cd616f714 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/recipes/RecipeConverter.java @@ -84,7 +84,7 @@ private static ItemIngredient getIngredient(Object ingredient) { if (ingredient == null) { return null; } else if (ingredient instanceof ItemStack) { - return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID().asString()); // TODO? + return new SpecificItemIngredient(((Item) Game.natives().toNova(ingredient)).getID()); } else if (ingredient instanceof String) { return new OreItemIngredient((String) ingredient); } else if (ingredient instanceof List) { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java index 680d891bb..aba205a81 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/BlockConverter.java @@ -32,6 +32,7 @@ import nova.core.event.BlockEvent; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.StringIdentifier; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v18.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v18.wrapper.block.backward.BWBlock; @@ -108,7 +109,8 @@ private void registerMinecraftToNOVA() { BlockManager blockManager = Game.blocks(); net.minecraft.block.Block.blockRegistry.forEach(obj -> blockManager.register( - new BlockFactory(net.minecraft.block.Block.blockRegistry.getNameForObject(obj).toString(), + // TODO check + new BlockFactory(Game.natives().toNova(net.minecraft.block.Block.blockRegistry.getNameForObject(obj)), () -> new BWBlock((net.minecraft.block.Block) obj), evt -> { }) ) @@ -119,7 +121,7 @@ private void registerNOVAToMinecraft() { BlockManager blockManager = Game.blocks(); //Register air block - BlockFactory airBlock = new BlockFactory("air", () -> new BWBlock(Blocks.air) { + BlockFactory airBlock = new BlockFactory(new StringIdentifier("air"), () -> new BWBlock(Blocks.air) { @Override public boolean canReplace() { return true; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java index 8a3a4c6f6..4074e7785 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlock.java @@ -99,7 +99,7 @@ public FWBlock(BlockFactory factory) { this.stepSound = soundTypeStone; } this.blockClass = dummy.getClass(); - this.setUnlocalizedName(dummy.getID().asString()); // TODO? + this.setUnlocalizedName(dummy.getID().asString()); // Recalculate super constructor things after loading the block properly this.fullBlock = isOpaqueCube(); @@ -179,7 +179,7 @@ public boolean hasTileEntity(IBlockState state) { @Override public TileEntity createTileEntity(World world, IBlockState state) { - FWTile fwTile = FWTileLoader.loadTile(dummy.getID().asString()); // TODO? + FWTile fwTile = FWTileLoader.loadTile(dummy.getID()); if (lastExtendedStatePos != null) { fwTile.block.components.getOrAdd(new MCBlockTransform(dummy, Game.natives().toNova(world), new Vector3D(lastExtendedStatePos.getX(), lastExtendedStatePos.getY(), lastExtendedStatePos.getZ()))); lastExtendedStatePos = null; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java index b62c264db..3d97adda7 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWBlockSound.java @@ -26,7 +26,7 @@ public String getBreakSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "dig." + sound.name; } - return sound.getID().asString(); // TODO? + return sound.getID().asString(); } return super.getBreakSound(); } @@ -38,7 +38,7 @@ public String getStepSound() { if (sound.domain.isEmpty() && !sound.name.contains(".")) { return "step." + sound.name; } - return sound.getID().asString(); // TODO? + return sound.getID().asString(); } return super.getStepSound(); } @@ -50,7 +50,7 @@ public String getPlaceSound() { if (sound.domain.isEmpty()) { return sound.name; } - return sound.getID().asString(); // TODO? + return sound.getID().asString(); } // By default MC uses the block break sound for block placement return this.getBreakSound(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java index 907633c88..42cab8d1b 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/block/forward/FWTileLoader.java @@ -24,6 +24,8 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; import nova.core.component.Updater; +import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v18.asm.lib.ComponentInjector; import nova.internal.core.Game; @@ -42,8 +44,8 @@ private FWTileLoader() { public static FWTile loadTile(NBTTagCompound data) { try { - String blockID = data.getString("novaID"); - Block block = createBlock(blockID); + Data blockID = Game.natives().toNova(data.getCompoundTag("novaID")); + Block block = createBlock((Identifier) Data.unserialize(blockID)); FWTile tile = (block instanceof Updater) ? updaterInjector.inject(block, new Class[0], new Object[0]) : injector.inject(block, new Class[0], new Object[0]); tile.setBlock(block); return tile; @@ -52,7 +54,7 @@ public static FWTile loadTile(NBTTagCompound data) { } } - public static FWTile loadTile(String blockID) { + public static FWTile loadTile(Identifier blockID) { try { Block block = createBlock(blockID); FWTile tile = (block instanceof Updater) ? updaterInjector.inject(block, new Class[] { String.class }, new Object[] { blockID }) : injector.inject(block, new Class[] { @@ -64,7 +66,7 @@ public static FWTile loadTile(String blockID) { } } - private static Block createBlock(String blockID) { + private static Block createBlock(Identifier blockID) { Optional blockFactory = Game.blocks().get(blockID); if (blockFactory.isPresent()) { return blockFactory.get().build(); diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java index 23c7ad671..e0f3658e6 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/EntityConverter.java @@ -27,6 +27,9 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; +import nova.core.util.id.ClassIdentifier; +import nova.core.util.id.Identifier; +import nova.core.util.id.NamespacedStringIdentifier; import nova.core.wrapper.mc.forge.v18.wrapper.entity.backward.BWEntity; import nova.core.wrapper.mc.forge.v18.wrapper.entity.backward.BWEntityFX; import nova.core.wrapper.mc.forge.v18.wrapper.entity.forward.FWEntity; @@ -56,7 +59,7 @@ public Entity toNova(net.minecraft.entity.Entity mcEntity) { //TODO: Make this BWRegistry non-lazy //Lazy registry - String id = mcEntity.getClass().getName(); + Identifier id = new ClassIdentifier(mcEntity.getClass()); Optional entityFactory = Game.entities().get(id); if (entityFactory.isPresent()) { @@ -85,7 +88,7 @@ public void preInit() { */ //Look up for particle factory and pass it into BWEntityFX for (EnumParticleTypes type : EnumParticleTypes.values()) { - Game.entities().register(Game.info().name + ":" + type.getParticleName(), () -> new BWEntityFX(type.getParticleID())); + Game.entities().register(new NamespacedStringIdentifier(Game.info().name, type.getParticleName()), () -> new BWEntityFX(type.getParticleID())); } } } \ No newline at end of file diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java index 72ae58935..6d2871a37 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/entity/forward/FWEntity.java @@ -30,9 +30,12 @@ import nova.core.component.transform.EntityTransform; import nova.core.entity.Entity; import nova.core.entity.EntityFactory; +import nova.core.network.Packet; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.Identifier; import nova.core.util.shape.Cuboid; +import nova.core.wrapper.mc.forge.v18.network.MCPacket; import nova.core.wrapper.mc.forge.v18.wrapper.data.DataWrapper; import nova.internal.core.Game; @@ -64,7 +67,9 @@ protected void readEntityFromNBT(NBTTagCompound nbt) { } if (wrapped == null) { //This entity was saved to disk. - setWrapped(Game.entities().get(nbt.getString("novaID")).get().build()); + NBTTagCompound novaId = nbt.getCompoundTag("novaID"); + Data d = Game.natives().toNova(novaId); + setWrapped(Game.entities().get((Identifier) Data.unserialize(d)).get().build()); } } @@ -75,22 +80,39 @@ protected void writeEntityToNBT(NBTTagCompound nbt) { ((Storable) wrapped).save(data); DataWrapper.instance().toNative(nbt, data); } - nbt.setString("novaID", wrapped.getID().asString()); // TODO? + Data data = new Data(); + data.put("novaID", wrapped.getID()); + NBTTagCompound novaId = new NBTTagCompound(); + DataWrapper.instance().toNative(novaId, data); + nbt.setTag("novaID", novaId); } @Override public void writeSpawnData(ByteBuf buffer) { + Packet packet = new MCPacket(buffer); + Data data = new Data(); + data.put("novaID", wrapped.getID()); + packet.writeData(data); + + /* //Write the ID of the entity to client - String id = wrapped.getID().asString(); // TODO? + String id = wrapped.getID(); char[] chars = id.toCharArray(); buffer.writeInt(chars.length); for (char c : chars) buffer.writeChar(c); + */ } @Override public void readSpawnData(ByteBuf buffer) { + Packet packet = new MCPacket(buffer); + Data d = packet.readData(); + + setWrapped(Game.entities().get((Identifier) Data.unserialize(d)).get().build()); + + /* //Load the client ID String id = ""; int length = buffer.readInt(); @@ -98,6 +120,7 @@ public void readSpawnData(ByteBuf buffer) { id += buffer.readChar(); setWrapped(Game.entities().get(id).get().build()); + */ } public Entity getWrapped() { diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java index 490c5b996..da8cfc6b5 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItem.java @@ -66,6 +66,6 @@ public ItemStack makeItemStack(int stackSize) { @Override public String toString() { - return getID().asString(); // TODO? + return getID().asString(); } } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java index e28085d10..aa97ed2ae 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/BWItemFactory.java @@ -21,10 +21,13 @@ package nova.core.wrapper.mc.forge.v18.wrapper.item; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.ResourceLocation; import nova.core.component.misc.FactoryProvider; import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.retention.Data; +import nova.core.util.id.Identifier; +import nova.core.util.id.NamespacedStringIdentifier; import nova.internal.core.Game; /** @@ -36,8 +39,19 @@ public class BWItemFactory extends ItemFactory { private final net.minecraft.item.Item item; private final int meta; + private static Identifier idFromItem(net.minecraft.item.Item item, int meta) { + // We don't use Game().natives().toNova() here because we need to add stuff to the identifier + ResourceLocation resloc = (ResourceLocation) net.minecraft.item.Item.itemRegistry.getNameForObject(item); + String namespace = resloc.getResourceDomain(); + String name = resloc.getResourcePath(); + if (item.getHasSubtypes()) { + name = name + ":" + meta; + } + return new NamespacedStringIdentifier(namespace, name); + } + public BWItemFactory(net.minecraft.item.Item item, int meta) { - super(net.minecraft.item.Item.itemRegistry.getNameForObject(item) + (item.getHasSubtypes() ? ":" + meta : ""), () -> new BWItem(item, meta, null)); + super(idFromItem(item, meta), () -> new BWItem(item, meta, null)); this.item = item; this.meta = meta; diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java index 61b7b9adc..3f8ae89a8 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/FWItem.java @@ -38,7 +38,7 @@ public class FWItem extends net.minecraft.item.Item implements ItemWrapperMethod public FWItem(ItemFactory item) { this.itemFactory = item; - setUnlocalizedName(item.getID().asString()); // TODO? + setUnlocalizedName(item.getID().asString()); setMaxStackSize(item.build().getMaxCount()); } diff --git a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java index 2b5c54df3..715032225 100644 --- a/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java +++ b/minecraft/1.8/src/main/java/nova/core/wrapper/mc/forge/v18/wrapper/item/ItemConverter.java @@ -36,6 +36,7 @@ import nova.core.loader.Loadable; import nova.core.nativewrapper.NativeConverter; import nova.core.retention.Data; +import nova.core.util.id.Identifier; import nova.core.wrapper.mc.forge.v18.launcher.NovaMinecraft; import nova.core.wrapper.mc.forge.v18.util.ModCreativeTab; import nova.core.wrapper.mc.forge.v18.wrapper.block.BlockConverter; @@ -107,7 +108,7 @@ public ItemStack toNative(Item item) { if (item instanceof BWItem) { return ((BWItem) item).makeItemStack(item.count()); } else { - ItemFactory itemFactory = Game.items().get(item.getID().asString()).get();// TODO? + ItemFactory itemFactory = Game.items().get(item.getID()).get(); FWNBTTagCompound tag = new FWNBTTagCompound(item); MinecraftItemMapping mapping = get(itemFactory); @@ -134,7 +135,7 @@ public ItemStack toNative(ItemFactory itemFactory) { return result; } - public ItemStack toNative(String id) { + public ItemStack toNative(Identifier id) { return toNative(Game.items().get(id).get().build().setCount(1)); } @@ -241,14 +242,17 @@ private void onIDNotFound(ItemIDNotFoundEvent event) { // if item minecraft:planks:2 is detected, this code will register minecraft:planks:2 dynamically // we cannot do this up front since there is **NO** reliable way to get the sub-items of an item - int lastColon = event.id.lastIndexOf(':'); + int lastColon = event.id.asString().lastIndexOf(':'); if (lastColon < 0) { return; } try { - int meta = Integer.parseInt(event.id.substring(lastColon + 1)); - String itemID = event.id.substring(0, lastColon); + int meta = Integer.parseInt(event.id.asString().substring(lastColon + 1)); + // FML will magically convert this result into a ResourceLocation for you, + // which simplifies our end. + // Any Identifier-related fluff would only be strictness checks. + String itemID = event.id.asString().substring(0, lastColon); net.minecraft.item.Item item = (net.minecraft.item.Item) net.minecraft.item.Item.itemRegistry.getObject(itemID); if (item == null || !item.getHasSubtypes()) { diff --git a/src/main/java/nova/core/block/BlockFactory.java b/src/main/java/nova/core/block/BlockFactory.java index 29e947504..8a8111964 100644 --- a/src/main/java/nova/core/block/BlockFactory.java +++ b/src/main/java/nova/core/block/BlockFactory.java @@ -24,6 +24,7 @@ import nova.core.event.BlockEvent; import nova.core.event.bus.EventListener; import nova.core.item.ItemBlock; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import nova.internal.core.Game; @@ -35,11 +36,11 @@ * @author Calclavia */ public class BlockFactory extends Factory { - public BlockFactory(String id, Supplier constructor, Function processor) { + public BlockFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public BlockFactory(String id, Supplier constructor) { + public BlockFactory(Identifier id, Supplier constructor) { this(id, constructor, evt -> { Game.items().register(id, () -> new ItemBlock(evt.blockFactory)); }); @@ -51,7 +52,7 @@ public BlockFactory(String id, Supplier constructor) { * @param constructor The constructor function * @param postCreate Function for registering item blocks */ - public BlockFactory(String id, Supplier constructor, EventListener postCreate) { + public BlockFactory(Identifier id, Supplier constructor, EventListener postCreate) { super(id, constructor); postCreate(postCreate); } @@ -61,7 +62,7 @@ protected void postCreate(EventListener postCreate) { } @Override - protected BlockFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected BlockFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new BlockFactory(id, constructor, processor); } diff --git a/src/main/java/nova/core/block/BlockManager.java b/src/main/java/nova/core/block/BlockManager.java index 41a28f90f..b5f27151f 100644 --- a/src/main/java/nova/core/block/BlockManager.java +++ b/src/main/java/nova/core/block/BlockManager.java @@ -21,6 +21,8 @@ package nova.core.block; import nova.core.event.BlockEvent; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -38,7 +40,7 @@ private BlockManager(Registry registry) { * @return The air block factory */ public BlockFactory getAirBlock() { - return get("air").get(); + return get(new StringIdentifier("air")).get(); } /** @@ -47,7 +49,7 @@ public BlockFactory getAirBlock() { * @return Dummy block */ @Override - public BlockFactory register(String id, Supplier constructor) { + public BlockFactory register(Identifier id, Supplier constructor) { return register(new BlockFactory(id, constructor)); } diff --git a/src/main/java/nova/core/component/fluid/Fluid.java b/src/main/java/nova/core/component/fluid/Fluid.java index 675c36a57..0eda1cc46 100644 --- a/src/main/java/nova/core/component/fluid/Fluid.java +++ b/src/main/java/nova/core/component/fluid/Fluid.java @@ -140,12 +140,12 @@ public int hashCode() { @Override public void save(Data data) { Storable.super.save(data); - data.put("id", factory.getID().asString()); // TODO? + data.put("id", factory.getID()); } @Override public void load(Data data) { Storable.super.load(data); - factory = Game.fluids().get(data.get("id")).get(); // FIXME + factory = Game.fluids().get(data.getDataConvertible("id")).get(); } } diff --git a/src/main/java/nova/core/component/fluid/FluidFactory.java b/src/main/java/nova/core/component/fluid/FluidFactory.java index 4b5af7ced..b6353d764 100644 --- a/src/main/java/nova/core/component/fluid/FluidFactory.java +++ b/src/main/java/nova/core/component/fluid/FluidFactory.java @@ -20,6 +20,7 @@ package nova.core.component.fluid; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -30,11 +31,11 @@ */ public class FluidFactory extends Factory { - public FluidFactory(String id, Supplier constructor, Function processor) { + public FluidFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public FluidFactory(String id, Supplier constructor) { + public FluidFactory(Identifier id, Supplier constructor) { super(id, constructor); } @@ -46,7 +47,7 @@ public Fluid build() { } @Override - protected FluidFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected FluidFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new FluidFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/component/fluid/FluidManager.java b/src/main/java/nova/core/component/fluid/FluidManager.java index f5a1b2d73..1759a5ff6 100644 --- a/src/main/java/nova/core/component/fluid/FluidManager.java +++ b/src/main/java/nova/core/component/fluid/FluidManager.java @@ -20,6 +20,8 @@ package nova.core.component.fluid; +import nova.core.util.id.Identifier; +import nova.core.util.id.StringIdentifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; @@ -32,12 +34,12 @@ public class FluidManager extends FactoryManager fluidRegistry) { super(fluidRegistry); //TODO: Too Minecraft specific. Implementation should be hidden. - this.water = register("water", Fluid::new); - this.lava = register("lava", Fluid::new); + this.water = register(new StringIdentifier("water"), Fluid::new); + this.lava = register(new StringIdentifier("lava"), Fluid::new); } @Override - public FluidFactory register(String id, Supplier constructor) { + public FluidFactory register(Identifier id, Supplier constructor) { return register(new FluidFactory(id, constructor)); } diff --git a/src/main/java/nova/core/entity/EntityFactory.java b/src/main/java/nova/core/entity/EntityFactory.java index 7a1712b7e..c7c352189 100644 --- a/src/main/java/nova/core/entity/EntityFactory.java +++ b/src/main/java/nova/core/entity/EntityFactory.java @@ -21,6 +21,7 @@ package nova.core.entity; import nova.core.component.misc.FactoryProvider; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -31,16 +32,16 @@ * @author Calclavia */ public class EntityFactory extends Factory { - public EntityFactory(String id, Supplier constructor, Function processor) { + public EntityFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public EntityFactory(String id, Supplier constructor) { + public EntityFactory(Identifier id, Supplier constructor) { super(id, constructor); } @Override - protected EntityFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected EntityFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new EntityFactory(id, constructor, processor); } diff --git a/src/main/java/nova/core/entity/EntityManager.java b/src/main/java/nova/core/entity/EntityManager.java index c49ec3731..91cc06ecb 100644 --- a/src/main/java/nova/core/entity/EntityManager.java +++ b/src/main/java/nova/core/entity/EntityManager.java @@ -20,6 +20,7 @@ package nova.core.entity; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -38,7 +39,7 @@ private EntityManager(Registry registry) { * @return The entity factory */ @Override - public EntityFactory register(String id, Supplier constructor) { + public EntityFactory register(Identifier id, Supplier constructor) { return register(new EntityFactory(id, constructor)); } diff --git a/src/main/java/nova/core/item/ItemFactory.java b/src/main/java/nova/core/item/ItemFactory.java index 976b927ac..ff7ec53fd 100644 --- a/src/main/java/nova/core/item/ItemFactory.java +++ b/src/main/java/nova/core/item/ItemFactory.java @@ -23,6 +23,7 @@ import nova.core.component.misc.FactoryProvider; import nova.core.retention.Data; import nova.core.retention.Storable; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import nova.core.util.id.Identifiable; @@ -33,11 +34,11 @@ * @author Calclavia */ public class ItemFactory extends Factory implements Identifiable { - public ItemFactory(String id, Supplier constructor, Function processor) { + public ItemFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public ItemFactory(String id, Supplier constructor) { + public ItemFactory(Identifier id, Supplier constructor) { super(id, constructor); } @@ -74,7 +75,7 @@ public Data save(Item item) { } @Override - protected ItemFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected ItemFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new ItemFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/item/ItemManager.java b/src/main/java/nova/core/item/ItemManager.java index a95d91e6c..85841a55c 100644 --- a/src/main/java/nova/core/item/ItemManager.java +++ b/src/main/java/nova/core/item/ItemManager.java @@ -24,6 +24,7 @@ import nova.core.block.BlockManager; import nova.core.event.bus.CancelableEvent; import nova.core.item.event.ItemIDNotFoundEvent; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -46,7 +47,7 @@ private ItemManager(Registry itemRegistry, Supplier b * @return Dummy item */ @Override - public ItemFactory register(String id, Supplier constructor) { + public ItemFactory register(Identifier id, Supplier constructor) { return register(new ItemFactory(id, constructor)); } @@ -58,15 +59,15 @@ public ItemFactory register(ItemFactory factory) { } public ItemFactory getItemFromBlock(BlockFactory block) { - return registry.get(block.getID().asString()).get(); // TODO + return registry.get(block.getID()).get(); } public Optional getBlockFromItem(Item item) { - return blockManager.get().get(item.getID().asString()); // TODO + return blockManager.get().get(item.getID()); } @Override - public Optional get(String name) { + public Optional get(Identifier name) { if (!registry.contains(name)) { ItemIDNotFoundEvent event = new ItemIDNotFoundEvent(name); Game.events().publish(event); diff --git a/src/main/java/nova/core/item/event/ItemIDNotFoundEvent.java b/src/main/java/nova/core/item/event/ItemIDNotFoundEvent.java index 160eaf06b..5ff0bdf10 100644 --- a/src/main/java/nova/core/item/event/ItemIDNotFoundEvent.java +++ b/src/main/java/nova/core/item/event/ItemIDNotFoundEvent.java @@ -20,16 +20,17 @@ import nova.core.event.bus.Event; import nova.core.item.ItemFactory; +import nova.core.util.id.Identifier; /** * @author Stan */ public class ItemIDNotFoundEvent extends Event { - public final String id; + public final Identifier id; private ItemFactory remappedFactory = null; - public ItemIDNotFoundEvent(String id) { + public ItemIDNotFoundEvent(Identifier id) { this.id = id; } diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java index 5703176f4..d0f72233f 100755 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipe.java @@ -22,6 +22,7 @@ import nova.core.item.Item; import nova.core.recipes.Recipe; +import nova.core.util.id.Identifier; import java.util.Collection; import java.util.Optional; @@ -73,7 +74,7 @@ public interface CraftingRecipe extends Recipe { * * @return The items */ - default Optional> getPossibleItemsInFirstSlot() { + default Optional> getPossibleItemsInFirstSlot() { return Optional.empty(); } } diff --git a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java index 4587cbc5d..77eafda4c 100644 --- a/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java +++ b/src/main/java/nova/core/recipes/crafting/CraftingRecipeManager.java @@ -38,10 +38,9 @@ * @author Stan Hebben */ public class CraftingRecipeManager { - // TODO switch this to using Identifiers private final RecipeManager recipeManager; private final List dynamicRecipes; - private final Multimap staticRecipes; + private final Multimap staticRecipes; public CraftingRecipeManager(RecipeManager recipeManager) { this.recipeManager = recipeManager; @@ -88,7 +87,7 @@ public Optional getRecipe(CraftingGrid grid) { return Optional.empty(); } - String firstItemId = firstItem.get().getID().asString(); // TODO (this is BAD) + Identifier firstItemId = firstItem.get().getID(); if (!staticRecipes.containsKey(firstItemId)) { return Optional.empty(); } @@ -107,9 +106,9 @@ public Optional getRecipe(CraftingGrid grid) { // ####################### private void onCraftingRecipeAdded(RecipeAddedEvent e) { - Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); + Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); if (possibleFirstItemIds.isPresent()) { - for (String itemId : possibleFirstItemIds.get()) { + for (Identifier itemId : possibleFirstItemIds.get()) { staticRecipes.put(itemId, e.getRecipe()); } } else { @@ -118,9 +117,9 @@ private void onCraftingRecipeAdded(RecipeAddedEvent void onCraftingRecipeRemoved(RecipeRemovedEvent e) { - Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); + Optional> possibleFirstItemIds = e.getRecipe().getPossibleItemsInFirstSlot(); if (possibleFirstItemIds.isPresent()) { - for (String itemId : possibleFirstItemIds.get()) { + for (Identifier itemId : possibleFirstItemIds.get()) { staticRecipes.remove(itemId, e.getRecipe()); } } else { diff --git a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java index 5aa41d22e..a53ca3d3b 100755 --- a/src/main/java/nova/core/recipes/crafting/ItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/ItemIngredient.java @@ -21,6 +21,7 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifier; import java.util.Collection; import java.util.Optional; @@ -38,7 +39,7 @@ public interface ItemIngredient { * @param itemId item ID * @return ingredient */ - static ItemIngredient forItem(String itemId) { + static ItemIngredient forItem(Identifier itemId) { return new SpecificItemIngredient(itemId); } @@ -58,7 +59,7 @@ static ItemIngredient forDictionary(String id) { * * @return possible items */ - Optional> getPossibleItemIds(); + Optional> getPossibleItemIds(); /** * Returns a list of example items. This list could be used to render diff --git a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java index 52d3a473c..9db60d659 100644 --- a/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/OreItemIngredient.java @@ -46,8 +46,8 @@ public String getName() { } @Override - public Optional> getPossibleItemIds() { - return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).map(Identifier::asString).collect(Collectors.toList())); // TODO? + public Optional> getPossibleItemIds() { + return Optional.of(Game.itemDictionary().get(name).stream().map(Item::getID).collect(Collectors.toList())); } @Override diff --git a/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java b/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java index dfd095fc8..06b3d43a3 100755 --- a/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java +++ b/src/main/java/nova/core/recipes/crafting/ShapedCraftingRecipe.java @@ -21,6 +21,7 @@ package nova.core.recipes.crafting; import nova.core.item.Item; +import nova.core.util.id.Identifier; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; import java.util.Collection; @@ -270,19 +271,19 @@ public void consumeItems(CraftingGrid craftingGrid) { } @Override - public Optional> getPossibleItemsInFirstSlot() { + public Optional> getPossibleItemsInFirstSlot() { if (isMirrored()) { - Optional> optionsForFirstItem = ingredients[0].getPossibleItemIds(); + Optional> optionsForFirstItem = ingredients[0].getPossibleItemIds(); if (!optionsForFirstItem.isPresent()) { return Optional.empty(); } - Optional> optionsForSecondItem = ingredients[lastIngredientIndexOnFirstLine].getPossibleItemIds(); + Optional> optionsForSecondItem = ingredients[lastIngredientIndexOnFirstLine].getPossibleItemIds(); if (!optionsForSecondItem.isPresent()) { return Optional.empty(); } - Set result = new HashSet<>(); + Set result = new HashSet<>(); result.addAll(optionsForFirstItem.get()); result.addAll(optionsForSecondItem.get()); return Optional.of(result); diff --git a/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java b/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java index d3b2330ca..6e2c4d914 100644 --- a/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java +++ b/src/main/java/nova/core/recipes/crafting/SpecificItemIngredient.java @@ -21,6 +21,7 @@ import nova.core.item.Item; import nova.core.item.ItemFactory; import nova.core.util.exception.RegistrationException; +import nova.core.util.id.Identifier; import nova.internal.core.Game; import java.util.Collection; @@ -32,18 +33,18 @@ * @author Stan Hebben */ public class SpecificItemIngredient implements ItemIngredient { - private final String itemId; + private final Identifier itemId; - public SpecificItemIngredient(String itemId) { + public SpecificItemIngredient(Identifier itemId) { this.itemId = itemId; } - public String getItemId() { + public Identifier getItemId() { return itemId; } @Override - public Optional> getPossibleItemIds() { + public Optional> getPossibleItemIds() { return Optional.of(Collections.singleton(itemId)); } @@ -96,7 +97,7 @@ public int hashCode() { return itemId.hashCode(); } - private Item getItem(String itemId) { + private Item getItem(Identifier itemId) { Optional itemFactory = Game.items().get(itemId); if (itemFactory.isPresent()) { diff --git a/src/main/java/nova/core/render/Asset.java b/src/main/java/nova/core/render/Asset.java index 5aafccaa4..75bf1228c 100644 --- a/src/main/java/nova/core/render/Asset.java +++ b/src/main/java/nova/core/render/Asset.java @@ -22,7 +22,7 @@ import nova.core.util.id.Identifiable; import nova.core.util.id.Identifier; -import nova.core.util.id.StringIdentifier; +import nova.core.util.id.NamespacedStringIdentifier; /** * @author Calclavia @@ -51,6 +51,6 @@ public boolean equals(Object obj) { @Override public final Identifier getID() { - return new StringIdentifier(domain + ":" + name); + return new NamespacedStringIdentifier(domain, name); } } diff --git a/src/main/java/nova/core/render/RenderManager.java b/src/main/java/nova/core/render/RenderManager.java index 4098a8c87..c25f6b8eb 100644 --- a/src/main/java/nova/core/render/RenderManager.java +++ b/src/main/java/nova/core/render/RenderManager.java @@ -43,7 +43,7 @@ public abstract class RenderManager extends Manager { public final Registry modelProviders = new Registry<>(); public ItemTexture registerTexture(ItemTexture texture) { - Optional itemTexture = itemTextures.get(texture.getID().asString()); // TODO? + Optional itemTexture = itemTextures.get(texture.getID()); if (itemTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return itemTexture.get(); @@ -53,7 +53,7 @@ public ItemTexture registerTexture(ItemTexture texture) { } public BlockTexture registerTexture(BlockTexture texture) { - Optional blockTexture = blockTextures.get(texture.getID().asString()); // TODO? + Optional blockTexture = blockTextures.get(texture.getID()); if (blockTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return blockTexture.get(); @@ -63,7 +63,7 @@ public BlockTexture registerTexture(BlockTexture texture) { } public EntityTexture registerTexture(EntityTexture texture) { - Optional entityTexture = entityTextures.get(texture.getID().asString()); // TODO? + Optional entityTexture = entityTextures.get(texture.getID()); if (entityTexture.isPresent()) { Game.logger().error("Attempt to register the same texture twice: " + texture); return entityTexture.get(); @@ -73,7 +73,7 @@ public EntityTexture registerTexture(EntityTexture texture) { } public ModelProvider registerModel(ModelProvider modelProvider) { - Optional modelProviderCheck = modelProviders.get(modelProvider.getID().asString()); // TODO? + Optional modelProviderCheck = modelProviders.get(modelProvider.getID()); if (modelProviderCheck.isPresent()) { Game.logger().error("Attempt to register the same model twice: " + modelProvider); return modelProviderCheck.get(); diff --git a/src/main/java/nova/core/render/texture/Texture.java b/src/main/java/nova/core/render/texture/Texture.java index 4c62b3c32..0fcfd3248 100644 --- a/src/main/java/nova/core/render/texture/Texture.java +++ b/src/main/java/nova/core/render/texture/Texture.java @@ -16,11 +16,13 @@ * * You should have received a copy of the GNU General Public License * along with NOVA. If not, see . - */package nova.core.render.texture; + */ + +package nova.core.render.texture; import nova.core.util.id.Identifiable; import nova.core.util.id.Identifier; -import nova.core.util.id.StringIdentifier; +import nova.core.util.id.NamespacedStringIdentifier; import nova.core.util.math.Vector2DUtil; import nova.internal.core.Game; import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; @@ -63,7 +65,7 @@ public String toString() { @Override public final Identifier getID() { - return new StringIdentifier(getResource()); + return new NamespacedStringIdentifier(domain, resource); } @Override diff --git a/src/main/java/nova/core/retention/Data.java b/src/main/java/nova/core/retention/Data.java index f3e2cea52..3044dc7e2 100755 --- a/src/main/java/nova/core/retention/Data.java +++ b/src/main/java/nova/core/retention/Data.java @@ -42,6 +42,7 @@ * - Enumerator * - Storable (Converted into Data) * - Data + * * @author Calclavia */ //TODO: Add collection and array support @@ -81,6 +82,7 @@ public Data(Class clazz) { /** * Saves an object, serializing its data. * This map can be reloaded and its class with be reconstructed. + * * @param obj The object to store. * @return The data of the object with */ @@ -95,6 +97,7 @@ public static Data serialize(Storable obj) { /** * Loads an object from its stored data, with an unknown class. * The class of the object must be stored within the data. + * * @param data The data * @return The object loaded with given data. */ @@ -102,7 +105,7 @@ public static Object unserialize(Data data) { try { Class clazz = (Class) Class.forName((String) data.get("class")); if (clazz.isEnum()) { - return Enum.valueOf(clazz, data.get("value")); + return Enum.valueOf(clazz, (String) data.get("value")); } else if (clazz == Vector3D.class) { return new Vector3D(data.get("x"), data.get("y"), data.get("z")); } else if (clazz == Vector2D.class) { @@ -111,6 +114,11 @@ public static Object unserialize(Data data) { return UUID.fromString(data.get("uuid")); } else if (clazz == Class.class) { return Class.forName(data.get("name")); + } else if (clazz.isAnnotationPresent(DataConvertible.class)) { + DataConvertible annotation = (DataConvertible) clazz.getAnnotation(DataConvertible.class); + DataConverter dataConverter = annotation.value().newInstance(); + Object o = dataConverter.fromData(data); + return clazz.cast(o); // throws ClassCastException if your DataConverter is bad. } else { return unserialize(clazz, data); } @@ -122,6 +130,7 @@ public static Object unserialize(Data data) { /** * Loads an object from its stored data, given its class. + * * @param clazz - The class to load * @param data - The data * @return The object loaded with given data. @@ -151,7 +160,7 @@ public Object put(String key, Object value) { assert key != null && value != null; assert !key.equals("class"); final Object check = value; - assert Arrays.stream(dataTypes).anyMatch(clazz -> clazz.isAssignableFrom(check.getClass())); + assert Arrays.stream(dataTypes).anyMatch(clazz -> clazz.isAssignableFrom(check.getClass())) || check.getClass().isAnnotationPresent(DataConvertible.class); if (value instanceof Enum) { Data enumData = new Data(value.getClass()); @@ -176,6 +185,16 @@ public Object put(String key, Object value) { Data classData = new Data(Class.class); classData.put("name", ((Class) value).getName()); value = classData; + } else if (value.getClass().isAnnotationPresent(DataConvertible.class)) { + try { + DataConvertible annotation = value.getClass().getAnnotation(DataConvertible.class); + DataConverter dataConverter = annotation.value().newInstance(); + Data d = new Data(value.getClass()); + dataConverter.toData(value, d); + value = d; + } catch (Exception e) { + throw new DataException(e); + } } else if (value instanceof Storable) { value = serialize((Storable) value); } @@ -191,6 +210,22 @@ public T get(String key) { return (T) super.get(key); } + @SuppressWarnings("unchecked") + public T getDataConvertible(String key) { + Data data = get(key); + try { + @SuppressWarnings("unchecked") + Class clazz = (Class) Class.forName(data.className); + DataConvertible dataConvertible = clazz.getAnnotation(DataConvertible.class); + if (dataConvertible == null) { + throw new ClassCastException(); + } + return (T) dataConvertible.value().newInstance().fromData(data); + } catch (Exception e) { + throw new DataException(e); + } + } + public > T getEnum(String key) { Data enumData = get(key); try { diff --git a/src/main/java/nova/core/retention/DataConverter.java b/src/main/java/nova/core/retention/DataConverter.java new file mode 100644 index 000000000..4f41d0e4a --- /dev/null +++ b/src/main/java/nova/core/retention/DataConverter.java @@ -0,0 +1,10 @@ +package nova.core.retention; + +/** + * @author soniex2 + */ +public interface DataConverter { + Object fromData(Data d); + + void toData(Object o, Data data); +} diff --git a/src/main/java/nova/core/retention/DataConvertible.java b/src/main/java/nova/core/retention/DataConvertible.java new file mode 100644 index 000000000..09978ef9b --- /dev/null +++ b/src/main/java/nova/core/retention/DataConvertible.java @@ -0,0 +1,14 @@ +package nova.core.retention; + +import java.lang.annotation.*; + +/** + * Annotation for **immutable** objects that can be converted to/from Data. + * @author soniex2 + */ +@Documented +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface DataConvertible { + Class value(); +} diff --git a/src/main/java/nova/core/util/id/ClassIdentifier.java b/src/main/java/nova/core/util/id/ClassIdentifier.java index 8fbc7466c..ff7ad1122 100644 --- a/src/main/java/nova/core/util/id/ClassIdentifier.java +++ b/src/main/java/nova/core/util/id/ClassIdentifier.java @@ -1,10 +1,16 @@ package nova.core.util.id; +import nova.core.retention.Data; +import nova.core.retention.DataConverter; +import nova.core.retention.DataConvertible; +import nova.core.retention.DataException; + /** * A Class Identifier. * * @author soniex2 */ +@DataConvertible(ClassIdentifier.Converter.class) public final class ClassIdentifier extends AbstractIdentifier> implements Identifier { /** @@ -29,4 +35,21 @@ public String asString() { public Class asClass() { return id; } + + public static final class Converter implements DataConverter { + @Override + public Object fromData(Data d) { + try { + Class c = Class.forName(d.get("value")); + return new ClassIdentifier(c); + } catch (ClassNotFoundException e) { + throw new DataException(e); + } + } + + @Override + public void toData(Object o, Data data) { + data.put("value", ((ClassIdentifier) o).asClass().getName()); + } + } } diff --git a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java index 50efe425d..68a108629 100644 --- a/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java +++ b/src/main/java/nova/core/util/id/NamespacedStringIdentifier.java @@ -1,5 +1,9 @@ package nova.core.util.id; +import nova.core.retention.Data; +import nova.core.retention.DataConverter; +import nova.core.retention.DataConvertible; + import java.util.Objects; /** @@ -7,7 +11,8 @@ * * @author soniex2 */ -public class NamespacedStringIdentifier extends AbstractIdentifier { +@DataConvertible(NamespacedStringIdentifier.Converter.class) +public final class NamespacedStringIdentifier extends AbstractIdentifier { /** * Constructs a new NamespacedStringIdentifier. @@ -105,9 +110,7 @@ public boolean equals(Object o) { NamespacedString that = (NamespacedString) o; - if (!namespace.equals(that.namespace)) - return false; - return name.equals(that.name); + return namespace.equals(that.namespace) && name.equals(that.name); } @Override @@ -133,4 +136,18 @@ private static String nsOf(String namespacedname) { } } } + + public static final class Converter implements DataConverter { + @Override + public Object fromData(Data d) { + return new NamespacedStringIdentifier(d.get("namespace"), d.get("name")); + } + + @Override + public void toData(Object o, Data data) { + NamespacedStringIdentifier id = (NamespacedStringIdentifier) o; + data.put("namespace", id.asNamespacedString().getNamespace()); + data.put("name", id.asNamespacedString().getName()); + } + } } diff --git a/src/main/java/nova/core/util/id/StringIdentifier.java b/src/main/java/nova/core/util/id/StringIdentifier.java index f52b45030..5e26c8cf4 100644 --- a/src/main/java/nova/core/util/id/StringIdentifier.java +++ b/src/main/java/nova/core/util/id/StringIdentifier.java @@ -1,10 +1,15 @@ package nova.core.util.id; +import nova.core.retention.Data; +import nova.core.retention.DataConverter; +import nova.core.retention.DataConvertible; + /** * A String Identifier. * * @author soniex2 */ +@DataConvertible(StringIdentifier.Converter.class) public final class StringIdentifier extends AbstractIdentifier implements Identifier { /** @@ -15,4 +20,16 @@ public final class StringIdentifier extends AbstractIdentifier implement public StringIdentifier(String id) { super(id); } + + public static final class Converter implements DataConverter { + @Override + public Object fromData(Data d) { + return new StringIdentifier(d.get("value")); + } + + @Override + public void toData(Object o, Data data) { + data.put("value", ((StringIdentifier) o).asString()); + } + } } diff --git a/src/main/java/nova/core/util/id/UUIDIdentifier.java b/src/main/java/nova/core/util/id/UUIDIdentifier.java index 754c214fd..dfa26b8b4 100644 --- a/src/main/java/nova/core/util/id/UUIDIdentifier.java +++ b/src/main/java/nova/core/util/id/UUIDIdentifier.java @@ -1,5 +1,9 @@ package nova.core.util.id; +import nova.core.retention.Data; +import nova.core.retention.DataConverter; +import nova.core.retention.DataConvertible; + import java.util.UUID; /** @@ -7,6 +11,7 @@ * * @author soniex2 */ +@DataConvertible(UUIDIdentifier.Converter.class) public final class UUIDIdentifier extends AbstractIdentifier implements Identifier { /** @@ -26,4 +31,16 @@ public UUIDIdentifier(UUID id) { public UUID asUUID() { return id; } + + public static final class Converter implements DataConverter { + @Override + public Object fromData(Data d) { + return new UUIDIdentifier(UUID.fromString(d.get("value"))); + } + + @Override + public void toData(Object o, Data data) { + data.put("value", ((UUIDIdentifier) o).asString()); + } + } } diff --git a/src/main/java/nova/core/util/registry/Factory.java b/src/main/java/nova/core/util/registry/Factory.java index 2034a3168..f4c5bbc07 100644 --- a/src/main/java/nova/core/util/registry/Factory.java +++ b/src/main/java/nova/core/util/registry/Factory.java @@ -20,23 +20,22 @@ package nova.core.util.registry; -import nova.core.component.ComponentProvider; import nova.core.util.id.Identifiable; import nova.core.util.id.Identifier; -import nova.core.util.id.StringIdentifier; import java.util.function.Function; import java.util.function.Supplier; /** * Factories are immutable object builders that create objects. + * * @param The self type * @param Type of produced object * @author Calclavia */ public abstract class Factory, T extends Identifiable> implements Identifiable { //The ID of the factory - protected final String id; + protected final Identifier id; //The constructor function protected final Supplier constructor; @@ -49,22 +48,24 @@ public abstract class Factory, T extends Identifiable> i * and with a processor that is capable of mutating the instantiated object after its initialization. * * A factory's processor may be modified to allow specific customization of instantiated objects before it is used. + * * @param id The identifier for this factory type * @param constructor The construction function * @param processor The processor function */ - public Factory(String id, Supplier constructor, Function processor) { + public Factory(Identifier id, Supplier constructor, Function processor) { this.id = id; this.constructor = constructor; this.processor = processor; } - public Factory(String id, Supplier constructor) { + public Factory(Identifier id, Supplier constructor) { this(id, constructor, obj -> obj); } /** * Adds a processor to the factory + * * @param processor A processor that mutates the construction * @return Self */ @@ -72,7 +73,7 @@ public S process(Function processor) { return selfConstructor(id, constructor, this.processor.compose(processor)); } - protected abstract S selfConstructor(String id, Supplier constructor, Function processor); + protected abstract S selfConstructor(Identifier id, Supplier constructor, Function processor); /** * @return A new instance of T based on the construction method @@ -82,6 +83,6 @@ public T build() { } public Identifier getID() { - return new StringIdentifier(id); + return id; } } diff --git a/src/main/java/nova/core/util/registry/FactoryManager.java b/src/main/java/nova/core/util/registry/FactoryManager.java index 8c2281833..a03be1971 100644 --- a/src/main/java/nova/core/util/registry/FactoryManager.java +++ b/src/main/java/nova/core/util/registry/FactoryManager.java @@ -21,6 +21,7 @@ package nova.core.util.registry; import nova.core.util.id.Identifiable; +import nova.core.util.id.Identifier; import java.util.Optional; import java.util.function.Supplier; @@ -44,7 +45,7 @@ public FactoryManager(Registry registry) { * @param constructor Instance supplier {@link Supplier} * @return The factory */ - public abstract F register(String id, Supplier constructor); + public abstract F register(Identifier id, Supplier constructor); /** * Register a new object construction factory. @@ -61,7 +62,7 @@ public F register(F factory) { * @param name Registered name * @return The object */ - public Optional get(String name) { + public Optional get(Identifier name) { return registry.get(name); } } diff --git a/src/main/java/nova/core/util/registry/Registry.java b/src/main/java/nova/core/util/registry/Registry.java index 24e724416..7e0c7bb34 100644 --- a/src/main/java/nova/core/util/registry/Registry.java +++ b/src/main/java/nova/core/util/registry/Registry.java @@ -33,8 +33,7 @@ * @param The object type */ public class Registry implements Iterable { - // TODO maybe index by Identifier? Could be nice when the game uses int IDs (e.g. very old versions of minecraft). - private final HashBiMap objects = HashBiMap.create(); + private final HashBiMap objects = HashBiMap.create(); public Registry() { @@ -47,7 +46,7 @@ public Registry() { * @return Given object */ public T register(T object) { - objects.put(object.getID().asString(), object); + objects.put(object.getID(), object); return object; } @@ -57,7 +56,7 @@ public T register(T object) { * @param ID the id to find. * @return true if the registry contains the object with the given ID. */ - public boolean contains(String ID) { + public boolean contains(Identifier ID) { return objects.containsKey(ID); } @@ -67,7 +66,7 @@ public boolean contains(String ID) { * @param ID the id to find. * @return the object found or empty Optional if not found. */ - public Optional get(String ID) { + public Optional get(Identifier ID) { return Optional.ofNullable(objects.get(ID)); } @@ -77,7 +76,7 @@ public Optional get(String ID) { * @param object the object to find. * @return the name of the object or empty Optional if not found. */ - public Optional getName(T object) { + public Optional getName(T object) { return Optional.ofNullable(objects.inverse().get(object)); } diff --git a/src/main/java/nova/core/world/WorldFactory.java b/src/main/java/nova/core/world/WorldFactory.java index cf53aaf80..2ede5b5fe 100644 --- a/src/main/java/nova/core/world/WorldFactory.java +++ b/src/main/java/nova/core/world/WorldFactory.java @@ -20,6 +20,7 @@ package nova.core.world; +import nova.core.util.id.Identifier; import nova.core.util.registry.Factory; import java.util.function.Function; @@ -30,16 +31,16 @@ * @author Calclavia */ public class WorldFactory extends Factory { - public WorldFactory(String id, Supplier constructor, Function processor) { + public WorldFactory(Identifier id, Supplier constructor, Function processor) { super(id, constructor, processor); } - public WorldFactory(String id, Supplier constructor) { + public WorldFactory(Identifier id, Supplier constructor) { super(id, constructor); } @Override - protected WorldFactory selfConstructor(String id, Supplier constructor, Function processor) { + protected WorldFactory selfConstructor(Identifier id, Supplier constructor, Function processor) { return new WorldFactory(id, constructor, processor); } } diff --git a/src/main/java/nova/core/world/WorldManager.java b/src/main/java/nova/core/world/WorldManager.java index 1f2c4bd82..c038e49a9 100644 --- a/src/main/java/nova/core/world/WorldManager.java +++ b/src/main/java/nova/core/world/WorldManager.java @@ -22,6 +22,7 @@ import nova.core.event.WorldEvent; import nova.core.event.bus.GlobalEvents; +import nova.core.util.id.Identifier; import nova.core.util.registry.FactoryManager; import nova.core.util.registry.Registry; import nova.internal.core.Game; @@ -48,7 +49,7 @@ public WorldManager(Registry registry, GlobalEvents events) { } @Override - public WorldFactory register(String id, Supplier constructor) { + public WorldFactory register(Identifier id, Supplier constructor) { return register(new WorldFactory(id, constructor)); } diff --git a/src/test/java/nova/core/util/RayTraceTest.java b/src/test/java/nova/core/util/RayTraceTest.java index 0815f904b..34d24771b 100755 --- a/src/test/java/nova/core/util/RayTraceTest.java +++ b/src/test/java/nova/core/util/RayTraceTest.java @@ -27,6 +27,7 @@ import nova.core.entity.EntityFactory; import nova.core.loader.Loadable; import nova.core.loader.Mod; +import nova.core.util.id.StringIdentifier; import nova.core.util.math.RotationUtil; import nova.internal.core.Game; import nova.internal.core.launch.NovaLauncher; @@ -145,7 +146,7 @@ public static class RayTraceMod implements Loadable { @Override public void preInit() { solid = Game.blocks().register( - "solid", + new StringIdentifier("solid"), () -> { Block solid = new Block(); solid.components.add(new Collider(solid)); @@ -153,7 +154,7 @@ public void preInit() { } ); - testEntity = Game.entities().register("test", Entity::new); + testEntity = Game.entities().register(new StringIdentifier("test"), Entity::new); } } } diff --git a/src/test/java/nova/core/util/RegistryTest.java b/src/test/java/nova/core/util/RegistryTest.java index 9e80a9313..edfb76017 100644 --- a/src/test/java/nova/core/util/RegistryTest.java +++ b/src/test/java/nova/core/util/RegistryTest.java @@ -40,18 +40,18 @@ public void testRegistry() throws Exception { registry.register(id1); registry.register(id2); - assertThat(registry.contains("ID1")).isTrue(); - assertThat(registry.contains("ID2")).isTrue(); + assertThat(registry.contains(new StringIdentifier("ID1"))).isTrue(); + assertThat(registry.contains(new StringIdentifier("ID2"))).isTrue(); - assertThat(registry.get("ID1").get().getID()).isEqualTo(new StringIdentifier("ID1")); - assertThat(registry.get("ID2").get().getID()).isEqualTo(new StringIdentifier("ID2")); + assertThat(registry.get(new StringIdentifier("ID1")).get().getID()).isEqualTo(new StringIdentifier("ID1")); + assertThat(registry.get(new StringIdentifier("ID2")).get().getID()).isEqualTo(new StringIdentifier("ID2")); - assertThat(registry.get("ID1").get()).isEqualTo(id1); - assertThat(registry.get("ID2").get()).isEqualTo(id2); + assertThat(registry.get(new StringIdentifier("ID1")).get()).isEqualTo(id1); + assertThat(registry.get(new StringIdentifier("ID2")).get()).isEqualTo(id2); assertThat(registry.iterator()).containsOnly(id1, id2); - assertThat(registry.get("None").isPresent()).isFalse(); + assertThat(registry.get(new StringIdentifier("None")).isPresent()).isFalse(); } } diff --git a/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java b/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java index 131897439..2b509a753 100644 --- a/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java +++ b/src/test/java/nova/wrappertests/NovaLauncherTestFactory.java @@ -22,6 +22,7 @@ import nova.core.block.Block; import nova.core.block.BlockFactory; +import nova.core.util.id.StringIdentifier; import nova.internal.core.Game; import nova.internal.core.bootstrap.DependencyInjectionEntryPoint; import nova.internal.core.launch.NovaLauncher; @@ -82,7 +83,7 @@ public NovaLauncher createLauncher() { /** * Register fake air block */ - Game.blocks().register(new BlockFactory("air", Block::new, evt -> {})); + Game.blocks().register(new BlockFactory(new StringIdentifier("air"), Block::new, evt -> {})); launcher.generateDependencies(); launcher.load(); From e46e93d812bda9110c8458606e25856c39c2e452 Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Sun, 8 Jan 2017 23:21:17 -0200 Subject: [PATCH 5/6] Fix accidental markdown in javadoc --- src/main/java/nova/core/retention/DataConvertible.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/nova/core/retention/DataConvertible.java b/src/main/java/nova/core/retention/DataConvertible.java index 09978ef9b..5d1e38005 100644 --- a/src/main/java/nova/core/retention/DataConvertible.java +++ b/src/main/java/nova/core/retention/DataConvertible.java @@ -3,7 +3,7 @@ import java.lang.annotation.*; /** - * Annotation for **immutable** objects that can be converted to/from Data. + * Annotation for immutable objects that can be converted to/from Data. * @author soniex2 */ @Documented From 4f5cef8bd415ef751a4848d08571a1c205b0ca0f Mon Sep 17 00:00:00 2001 From: SoniEx2 Date: Mon, 9 Jan 2017 17:23:59 -0200 Subject: [PATCH 6/6] Add some unit tests --- .../core/retention/DataConvertibleTest.java | 46 +++++++++++++ .../nova/core/util/id/IdentifierTest.java | 64 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/test/java/nova/core/retention/DataConvertibleTest.java create mode 100644 src/test/java/nova/core/util/id/IdentifierTest.java diff --git a/src/test/java/nova/core/retention/DataConvertibleTest.java b/src/test/java/nova/core/retention/DataConvertibleTest.java new file mode 100644 index 000000000..fca56a92f --- /dev/null +++ b/src/test/java/nova/core/retention/DataConvertibleTest.java @@ -0,0 +1,46 @@ +package nova.core.retention; + +import org.junit.Test; + +import static nova.testutils.NovaAssertions.assertThat; + +/** + * @author soniex2 + */ +public class DataConvertibleTest { + + @DataConvertible(AnImmutableObject.Converter.class) + public static class AnImmutableObject { + private final String data; + + public AnImmutableObject(String data) { + this.data = data; + } + + public String getData() { + return data; + } + + public static class Converter implements DataConverter { + @Override + public Object fromData(Data d) { + return new AnImmutableObject(d.get("data")); + } + + @Override + public void toData(Object o, Data data) { + data.put("data", ((AnImmutableObject) o).getData()); + } + } + } + + @Test + public void testDataConvertible() { + AnImmutableObject o = new AnImmutableObject("hello"); + Data d = new Data(); + d.put("anImmutableObject", o); + AnImmutableObject other = d.getDataConvertible("anImmutableObject"); + assertThat(o).isEqualToComparingFieldByField(other); + assertThat(o).isNotSameAs(other); + } +} diff --git a/src/test/java/nova/core/util/id/IdentifierTest.java b/src/test/java/nova/core/util/id/IdentifierTest.java new file mode 100644 index 000000000..8d8ea3ce7 --- /dev/null +++ b/src/test/java/nova/core/util/id/IdentifierTest.java @@ -0,0 +1,64 @@ +package nova.core.util.id; + +import nova.testutils.NovaAssertions; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static nova.testutils.NovaAssertions.assertThat; + +/** + * @author soniex2 + */ +public class IdentifierTest { + + @Test + public void testStringIdentifierComparison() { + StringIdentifier a1 = new StringIdentifier("a"); + StringIdentifier a2 = new StringIdentifier("a"); + StringIdentifier b = new StringIdentifier("b"); + assertThat(a1).isEqualTo(a2); + assertThat(a1).isNotEqualTo(b); + assertThat(a1.hashCode()).isEqualTo(a2.hashCode()); + assertThat(a1.asString()).isEqualTo(a2.asString()); + assertThat(a1.asString()).isNotEqualTo(b.asString()); + } + + @Test + public void testMixedIdentifierMap() { + Map map = new HashMap<>(); + + map.put(new StringIdentifier(StringIdentifier.class.getName()), "StringIdentifier class name"); + map.put(new ClassIdentifier(StringIdentifier.class), "StringIdentifier class"); + + assertThat(map.get(new StringIdentifier(StringIdentifier.class.getName()))).isEqualTo("StringIdentifier class name"); + assertThat(map.get(new StringIdentifier(StringIdentifier.class.getName()))).isNotEqualTo(map.get(new ClassIdentifier(StringIdentifier.class))); + assertThat(map.get(new ClassIdentifier(StringIdentifier.class))).isEqualTo("StringIdentifier class"); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidNamespace() { + NamespacedStringIdentifier nsi = new NamespacedStringIdentifier("nova:nova", "nova"); + } + + @Test + public void testStringVsNamespace() { + NamespacedStringIdentifier nsi = new NamespacedStringIdentifier("", "a"); + StringIdentifier si = new StringIdentifier("a"); + assertThat(nsi).isNotEqualTo(si); + } + + @Test + public void testUUID() { + UUIDIdentifier a = new UUIDIdentifier(UUID.fromString("27b8a073-a6ed-4455-b144-92000c7394b7")); + UUIDIdentifier b = new UUIDIdentifier(UUID.fromString("27b8a073-a6ed-4455-b144-92000c7394b7")); + UUIDIdentifier c = new UUIDIdentifier(UUID.randomUUID()); + + assertThat(a).isEqualTo(b); + assertThat(a.hashCode()).isEqualTo(b.hashCode()); + assertThat(a.asUUID()).isEqualTo(UUID.fromString("27b8a073-a6ed-4455-b144-92000c7394b7")); + assertThat(a).isNotEqualTo(c); // this has a 1 in 2^122 chance of failing. it's *fine*. + } +}