diff --git a/src/main/java/com/minelittlepony/unicopia/UBlocks.java b/src/main/java/com/minelittlepony/unicopia/UBlocks.java index 549ef11c..c36b0d0b 100644 --- a/src/main/java/com/minelittlepony/unicopia/UBlocks.java +++ b/src/main/java/com/minelittlepony/unicopia/UBlocks.java @@ -57,7 +57,7 @@ public class UBlocks { public static final Block apple_leaves = new BlockFruitLeaves(Unicopia.MODID, "apple_leaves", apple_tree) .setBaseGrowthChance(1200) .setTint(0xFFEE81) - .setHarvestFruit(w -> UItems.apple.getRandomApple(w.rand, null)) + .setHarvestFruit(w -> UItems.apple.getRandomApple()) .setUnharvestFruit(w -> new ItemStack(UItems.rotten_apple)); static void init(IForgeRegistry registry) { diff --git a/src/main/java/com/minelittlepony/unicopia/UItems.java b/src/main/java/com/minelittlepony/unicopia/UItems.java index 3b9dc81e..99ff6cd6 100644 --- a/src/main/java/com/minelittlepony/unicopia/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/UItems.java @@ -1,6 +1,7 @@ package com.minelittlepony.unicopia; import com.minelittlepony.unicopia.item.ItemApple; +import com.minelittlepony.unicopia.item.ItemAppleMultiType; import com.minelittlepony.unicopia.item.ItemCereal; import com.minelittlepony.unicopia.item.ItemCloud; import com.minelittlepony.unicopia.item.ItemCurse; @@ -52,11 +53,11 @@ import com.minelittlepony.unicopia.forgebullshit.OreReplacer; import com.minelittlepony.unicopia.forgebullshit.RegistryLockSpinner; public class UItems { - public static final ItemApple apple = new ItemApple("minecraft", "apple") + public static final ItemAppleMultiType apple = new ItemAppleMultiType("minecraft", "apple") .setSubTypes("apple", "green", "sweet", "sour") .setTypeRarities(10, 20, 10, 30); - public static final ItemApple zap_apple = new ItemZapApple(Unicopia.MODID, "zap_apple") + public static final ItemAppleMultiType zap_apple = new ItemZapApple(Unicopia.MODID, "zap_apple") .setSubTypes("zap_apple", "red", "green", "sweet", "sour", "zap"); public static final ItemApple rotten_apple = new ItemRottenApple(Unicopia.MODID, "rotten_apple"); diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemApple.java b/src/main/java/com/minelittlepony/unicopia/item/ItemApple.java index 059d6ba8..c146e6c9 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ItemApple.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemApple.java @@ -1,84 +1,71 @@ package com.minelittlepony.unicopia.item; import java.util.List; -import java.util.Random; +import java.util.function.Supplier; import javax.annotation.Nullable; import com.minelittlepony.unicopia.UItems; import com.minelittlepony.unicopia.edibles.IEdible; import com.minelittlepony.unicopia.edibles.Toxicity; -import com.minelittlepony.unicopia.forgebullshit.IMultiItem; +import com.minelittlepony.util.collection.Pool; +import com.minelittlepony.util.collection.Weighted; import net.minecraft.block.BlockPlanks; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.ItemFood; import net.minecraft.item.ItemStack; -import net.minecraft.util.NonNullList; import net.minecraft.world.World; -public class ItemApple extends ItemFood implements IMultiItem, IEdible { +public class ItemApple extends ItemFood implements IEdible { - private int[] typeRarities = new int[0]; + public static final Pool>> typeVariantMap = Pool.of(BlockPlanks.EnumType.OAK, + BlockPlanks.EnumType.OAK, new Weighted>() + .put(1, () -> new ItemStack(UItems.rotten_apple)) + .put(2, () -> new ItemStack(UItems.apple, 1, 1)) + .put(3, () -> new ItemStack(UItems.apple, 1, 0)), + BlockPlanks.EnumType.SPRUCE, new Weighted>() + .put(1, () -> new ItemStack(UItems.apple, 1, 3)) + .put(2, () -> new ItemStack(UItems.apple, 1, 1)) + .put(3, () -> new ItemStack(UItems.apple, 1, 2)) + .put(4, () -> new ItemStack(UItems.rotten_apple)), + BlockPlanks.EnumType.BIRCH, new Weighted>() + .put(1, () -> new ItemStack(UItems.rotten_apple)) + .put(2, () -> new ItemStack(UItems.apple, 1, 2)) + .put(5, () -> new ItemStack(UItems.apple, 1, 1)), + BlockPlanks.EnumType.JUNGLE, new Weighted>() + .put(5, () -> new ItemStack(UItems.apple, 1, 1)) + .put(2, () -> new ItemStack(UItems.apple, 1, 2)) + .put(1, () -> new ItemStack(UItems.apple, 1, 3)), + BlockPlanks.EnumType.ACACIA, new Weighted>() + .put(1, () -> new ItemStack(UItems.rotten_apple)) + .put(2, () -> new ItemStack(UItems.apple, 1, 2)) + .put(5, () -> new ItemStack(UItems.apple, 1, 1)), + BlockPlanks.EnumType.DARK_OAK, new Weighted>() + .put(1, () -> new ItemStack(UItems.rotten_apple)) + .put(2, () -> new ItemStack(UItems.apple, 1, 2)) + .put(5, () -> new ItemStack(UItems.zap_apple) + ) + ); - private String[] subTypes = new String[0]; - - private String[] variants = subTypes; - - public ItemStack getRandomApple(Random rand, Object variant) { - - int[] rarity = typeRarities; - - int result = 0; - - for (int i = 0; i < rarity.length && i < subTypes.length; i++) { - if (rand.nextInt(rarity[i]) == 0) { - result++; - } - } - - if (variant == BlockPlanks.EnumType.JUNGLE) { - result = oneOr(result, 0, 1); - } - - if (variant == BlockPlanks.EnumType.BIRCH) { - result = oneOr(result, 0, 2); - } - - if (variant == BlockPlanks.EnumType.SPRUCE) { - if (result == 0) { - return new ItemStack(UItems.rotten_apple, 1); - } - } - - if (variant == BlockPlanks.EnumType.DARK_OAK) { - if (result == 1) { - return new ItemStack(UItems.zap_apple, 1); - } - } - - if (variant == BlockPlanks.EnumType.ACACIA) { - result = oneOr(result, 0, 4); - } - - return new ItemStack(this, 1, result); + public static ItemStack getRandomItemStack(Object variant) { + return typeVariantMap.getOptional(variant) + .flatMap(Weighted::get) + .map(Supplier::get) + .orElse(ItemStack.EMPTY); } - int oneOr(int initial, int a, int b) { - if (initial == a) { - return b; - } + public ItemStack getRandomApple() { + return getRandomApple(null); + } - if (initial == b) { - return a; - } - - return initial; + public ItemStack getRandomApple(Object variant) { + return getRandomItemStack(variant); } public ItemApple(String domain, String name) { super(4, 3, false); + setTranslationKey(name); if (!"minecraft".contentEquals(domain)) { @@ -86,69 +73,11 @@ public class ItemApple extends ItemFood implements IMultiItem, IEdible { } } - public ItemApple setSubTypes(String... types) { - setHasSubtypes(types.length > 0); - setMaxDamage(0); - - subTypes = types; - variants = new String[subTypes.length]; - - setTranslationKey(variants[0] = types[0]); - - for (int i = 1; i < variants.length; i++) { - variants[i] = variants[0] + "_" + subTypes[i % subTypes.length]; - } - return this; - } - - public ItemApple setTypeRarities(int ... rarity) { - typeRarities = rarity; - return this; - } - - @Override - public String[] getVariants() { - return variants; - } - - @Override - public void getSubItems(CreativeTabs tab, NonNullList items) { - if (isInCreativeTab(tab)) { - items.add(new ItemStack(this, 1, 0)); - - for (int i = 1; i < subTypes.length; i++) { - items.add(new ItemStack(this, 1, i)); - } - } - } - @Override public void addInformation(ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) { tooltip.add(getToxicityLevel(stack).getTooltip()); } - @Override - public int getMetadata(ItemStack stack) { - if (getHasSubtypes()) { - return super.getMetadata(stack) % subTypes.length; - } - - return super.getMetadata(stack); - } - - @Override - public String getTranslationKey(ItemStack stack) { - if (getHasSubtypes()) { - int meta = Math.max(0, stack.getMetadata() % subTypes.length); - - if (meta > 0) { - return super.getTranslationKey(stack) + "." + subTypes[meta]; - } - } - - return super.getTranslationKey(stack); - } - @Override public Toxicity getToxicityLevel(ItemStack stack) { return Toxicity.SAFE; diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemAppleMultiType.java b/src/main/java/com/minelittlepony/unicopia/item/ItemAppleMultiType.java new file mode 100644 index 00000000..e39f2d00 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemAppleMultiType.java @@ -0,0 +1,86 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.forgebullshit.IMultiItem; + +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.ItemStack; +import net.minecraft.util.NonNullList; + +public class ItemAppleMultiType extends ItemApple implements IMultiItem { + + private int[] typeRarities = new int[0]; + + private String[] subTypes = new String[0]; + + private String[] variants = subTypes; + + public ItemAppleMultiType(String domain, String name) { + super(domain, name); + } + + public ItemAppleMultiType setSubTypes(String... types) { + setHasSubtypes(types.length > 0); + setMaxDamage(0); + + subTypes = types; + variants = new String[types.length]; + + setTranslationKey(variants[0] = types[0]); + + for (int i = 1; i < variants.length; i++) { + variants[i] = variants[0] + "_" + types[i % types.length]; + } + return this; + } + + @Override + public String[] getVariants() { + return variants; + } + + protected int[] getTypeRarities() { + return typeRarities; + } + + protected String[] getSubTypes() { + return subTypes; + } + + public ItemAppleMultiType setTypeRarities(int ... rarity) { + typeRarities = rarity; + return this; + } + + @Override + public void getSubItems(CreativeTabs tab, NonNullList items) { + if (isInCreativeTab(tab)) { + items.add(new ItemStack(this, 1, 0)); + + for (int i = 1; i < getSubTypes().length; i++) { + items.add(new ItemStack(this, 1, i)); + } + } + } + + @Override + public int getMetadata(ItemStack stack) { + if (getHasSubtypes()) { + return super.getMetadata(stack) % getSubTypes().length; + } + + return super.getMetadata(stack); + } + + @Override + public String getTranslationKey(ItemStack stack) { + if (getHasSubtypes()) { + int meta = Math.max(0, stack.getMetadata() % getSubTypes().length); + + if (meta > 0) { + return super.getTranslationKey(stack) + "." + getSubTypes()[meta]; + } + } + + return super.getTranslationKey(stack); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/ItemZapApple.java b/src/main/java/com/minelittlepony/unicopia/item/ItemZapApple.java index c6f6fe65..fb64716c 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ItemZapApple.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ItemZapApple.java @@ -21,7 +21,7 @@ import net.minecraft.util.NonNullList; import net.minecraft.util.math.RayTraceResult; import net.minecraft.world.World; -public class ItemZapApple extends ItemApple { +public class ItemZapApple extends ItemAppleMultiType { public ItemZapApple(String domain, String name) { super(domain, name); diff --git a/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java b/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java index 7b9899bc..e6ffb639 100644 --- a/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java +++ b/src/main/java/com/minelittlepony/unicopia/power/PowerStomp.java @@ -62,12 +62,12 @@ public class PowerStomp implements IPower { @Override public int getWarmupTime(IPlayer player) { - return 0; + return 3; } @Override public int getCooldownTime(IPlayer player) { - return 500; + return 50; } @Override @@ -77,7 +77,8 @@ public class PowerStomp implements IPower { @Override public PowerStomp.Data tryActivate(IPlayer player) { - RayTraceResult mop = VecHelper.getObjectMouseOver(player.getOwner(), 2, 1); + RayTraceResult mop = VecHelper.getObjectMouseOver(player.getOwner(), 6, 1); + if (mop != null && mop.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos pos = mop.getBlockPos(); IBlockState state = player.getWorld().getBlockState(pos); @@ -332,7 +333,7 @@ public class PowerStomp implements IPower { } private ItemStack getApple(World w, IBlockState log) { - return UItems.apple.getRandomApple(w.rand, getVariant(log)); + return UItems.apple.getRandomApple(getVariant(log)); } private int measureTree(World w, IBlockState log, BlockPos pos) { diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java index f7b167cf..eeba1651 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellFire.java @@ -6,8 +6,8 @@ import com.minelittlepony.unicopia.Predicates; import com.minelittlepony.unicopia.entity.IMagicals; import com.minelittlepony.util.MagicalDamageSource; import com.minelittlepony.util.PosHelper; -import com.minelittlepony.util.blockstate.IStateMapping; -import com.minelittlepony.util.blockstate.StateMapList; +import com.minelittlepony.util.collection.IStateMapping; +import com.minelittlepony.util.collection.StateMapList; import com.minelittlepony.util.shape.IShape; import com.minelittlepony.util.shape.Sphere; import com.minelittlepony.util.vector.VecHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java index 45fc21ef..6655d4c9 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellIce.java @@ -3,8 +3,8 @@ package com.minelittlepony.unicopia.spell; import com.minelittlepony.unicopia.UMaterials; import com.minelittlepony.util.MagicalDamageSource; import com.minelittlepony.util.PosHelper; -import com.minelittlepony.util.blockstate.IStateMapping; -import com.minelittlepony.util.blockstate.StateMapList; +import com.minelittlepony.util.collection.IStateMapping; +import com.minelittlepony.util.collection.StateMapList; import com.minelittlepony.util.shape.IShape; import com.minelittlepony.util.shape.Sphere; import com.minelittlepony.util.vector.VecHelper; diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java index 2d927ae6..67012a51 100644 --- a/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java +++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellInferno.java @@ -1,8 +1,8 @@ package com.minelittlepony.unicopia.spell; import com.minelittlepony.util.MagicalDamageSource; -import com.minelittlepony.util.blockstate.IStateMapping; -import com.minelittlepony.util.blockstate.StateMapList; +import com.minelittlepony.util.collection.IStateMapping; +import com.minelittlepony.util.collection.StateMapList; import com.minelittlepony.util.shape.IShape; import com.minelittlepony.util.shape.Sphere; diff --git a/src/main/java/com/minelittlepony/util/blockstate/IStateMapping.java b/src/main/java/com/minelittlepony/util/collection/IStateMapping.java similarity index 98% rename from src/main/java/com/minelittlepony/util/blockstate/IStateMapping.java rename to src/main/java/com/minelittlepony/util/collection/IStateMapping.java index 891ff948..53a76eaa 100644 --- a/src/main/java/com/minelittlepony/util/blockstate/IStateMapping.java +++ b/src/main/java/com/minelittlepony/util/collection/IStateMapping.java @@ -1,4 +1,4 @@ -package com.minelittlepony.util.blockstate; +package com.minelittlepony.util.collection; import java.util.function.Function; import java.util.function.Predicate; diff --git a/src/main/java/com/minelittlepony/util/collection/Pool.java b/src/main/java/com/minelittlepony/util/collection/Pool.java new file mode 100644 index 00000000..4eac3407 --- /dev/null +++ b/src/main/java/com/minelittlepony/util/collection/Pool.java @@ -0,0 +1,48 @@ +package com.minelittlepony.util.collection; + +import java.util.HashMap; +import java.util.Optional; + +public class Pool extends HashMap { + private static final long serialVersionUID = -4794854344664655790L; + + private final K defaultKey; + + @SuppressWarnings("unchecked") + public static Pool of(K def, Object...entries) { + Pool result = new Pool<>(def); + + for (int i = 0; i < entries.length - 1; i += 2) { + result.put((K)entries[i], (V)entries[i + 1]); + } + + return result; + } + + public Pool(K defKey) { + defaultKey = defKey; + } + + public Pool add(K key, V value) { + put(key, value); + + return this; + } + + @Override + public V get(Object key) { + if (!containsKey(key)) { + key = defaultKey; + } + + return super.get(key); + } + + public Optional getOptional(K key) { + if (!containsKey(key)) { + return Optional.empty(); + } + + return Optional.ofNullable(get(key)); + } +} diff --git a/src/main/java/com/minelittlepony/util/blockstate/StateMapList.java b/src/main/java/com/minelittlepony/util/collection/StateMapList.java similarity index 97% rename from src/main/java/com/minelittlepony/util/blockstate/StateMapList.java rename to src/main/java/com/minelittlepony/util/collection/StateMapList.java index be5b6d6f..3f2461da 100644 --- a/src/main/java/com/minelittlepony/util/blockstate/StateMapList.java +++ b/src/main/java/com/minelittlepony/util/collection/StateMapList.java @@ -1,4 +1,4 @@ -package com.minelittlepony.util.blockstate; +package com.minelittlepony.util.collection; import java.util.ArrayList; import java.util.function.Predicate; diff --git a/src/main/java/com/minelittlepony/util/collection/Weighted.java b/src/main/java/com/minelittlepony/util/collection/Weighted.java new file mode 100644 index 00000000..f00bc673 --- /dev/null +++ b/src/main/java/com/minelittlepony/util/collection/Weighted.java @@ -0,0 +1,82 @@ +package com.minelittlepony.util.collection; + +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.function.Consumer; + +import javax.annotation.Nonnull; +import javax.annotation.concurrent.Immutable; + +import com.google.common.collect.Lists; + +public class Weighted { + + private static final Random rand = new Random(); + + private float totalWeight = 0; + + private final List entries = Lists.newArrayList(); + + public static Weighted of(Consumer> constructor) { + Weighted result = new Weighted<>(); + + constructor.accept(result); + + return result; + } + + public Weighted put(int weight, @Nonnull T value) { + entries.add(new Entry(weight, value)); + + totalWeight += weight; + + recalculate(); + + return this; + } + + private void recalculate() { + float rangeStart = 0; + + for (Entry i : entries) { + i.min = rangeStart; + i.max = rangeStart + (i.weight/totalWeight); + + rangeStart = i.max; + } + } + + public Optional get() { + if (entries.isEmpty()) { + return Optional.empty(); + } + + float random = rand.nextFloat(); + + return entries.stream() + .filter(i -> random >= i.min && random <= i.max) + .map(Entry::getResult) + .findFirst(); + } + + @Immutable + class Entry { + + final float weight; + + final T result; + + float min; + float max; + + Entry(int weight, T result) { + this.weight = weight; + this.result = result; + } + + T getResult() { + return result; + } + } +}