Skip to content
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package com.fouristhenumber.utilitiesinexcess.common.items;

import static com.fouristhenumber.utilitiesinexcess.config.items.InversionConfig.awakenedInversionDurability;
import static com.fouristhenumber.utilitiesinexcess.config.items.InversionConfig.chestSplashPotionsValid;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

import net.minecraft.block.Block;
Expand Down Expand Up @@ -35,47 +37,36 @@
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.living.LivingSpawnEvent;

import org.apache.logging.log4j.Level;
import org.jetbrains.annotations.NotNull;

import com.fouristhenumber.utilitiesinexcess.ModItems;
import com.fouristhenumber.utilitiesinexcess.common.entities.EntitySiegeProperty;
import com.fouristhenumber.utilitiesinexcess.config.items.InversionConfig;
import com.fouristhenumber.utilitiesinexcess.utils.ItemStackBaseCompare;

import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.registry.GameRegistry;

public class ItemInversionSigilActive extends Item {

private static final String DURABILITY_NBT_KEY = "RemainingUses";
private static final int BEACON_SEARCH_RADIUS = 6;
private final int[][] LIGHTNING_POSITIONS = { { 0, 0 }, { -5, 0 }, { 5, 0 }, { 0, -5 }, { 0, 5 } };

private final ItemStack[] CHEST_NORTH_CONTENTS = { new ItemStack(Blocks.stone), new ItemStack(Items.brick),
new ItemStack(Blocks.glass), new ItemStack(Items.cooked_fished), new ItemStack(Blocks.hardened_clay),
new ItemStack(Items.dye, 1, 2), new ItemStack(Items.coal, 1, 1), new ItemStack(Items.cooked_beef),
new ItemStack(Items.iron_ingot), new ItemStack(Items.cooked_chicken), new ItemStack(Items.gold_ingot),
new ItemStack(Items.baked_potato), new ItemStack(Items.cooked_porkchop), new ItemStack(Items.netherbrick) };
private HashSet<ItemStackBaseCompare> CHEST_NORTH_CONTENTS = new HashSet<>();

private final int[] POTION_IDS = { 8193, 8194, 8195, 8196, 8197, 8198, 8200, 8201, 8202, 8204, 8205, 8206, 8225,
8226, 8228, 8229, 8232, 8233, 8234, 8236, 8257, 8258, 8259, 8260, 8262, 8264, 8265, 8267, 8268, 8269, 8270 };
private HashSet<ItemStackBaseCompare> CHEST_EAST_CONTENTS = new HashSet<>();

private final ItemStack[] CHEST_EAST_CONTENTS = new ItemStack[62];
private HashSet<ItemStackBaseCompare> CHEST_SOUTH_CONTENTS = new HashSet<>();

private final ItemStack[] CHEST_SOUTH_CONTENTS = { new ItemStack(Blocks.grass), new ItemStack(Blocks.lapis_ore),
new ItemStack(Blocks.dirt), new ItemStack(Blocks.obsidian), new ItemStack(Blocks.sand),
new ItemStack(Blocks.diamond_ore), new ItemStack(Blocks.gravel), new ItemStack(Blocks.redstone_ore),
new ItemStack(Blocks.gold_ore), new ItemStack(Blocks.clay), new ItemStack(Blocks.iron_ore),
new ItemStack(Blocks.emerald_ore), new ItemStack(Blocks.coal_ore) };

private final ItemStack[] CHEST_WEST_CONTENTS = { new ItemStack(Items.record_13),
new ItemStack(Items.record_mellohi), new ItemStack(Items.record_cat), new ItemStack(Items.record_stal),
new ItemStack(Items.record_blocks), new ItemStack(Items.record_strad), new ItemStack(Items.record_chirp),
new ItemStack(Items.record_ward), new ItemStack(Items.record_far), new ItemStack(Items.record_11),
new ItemStack(Items.record_mall), new ItemStack(Items.record_wait) };
private HashSet<ItemStackBaseCompare> CHEST_WEST_CONTENTS = new HashSet<>();

public ItemInversionSigilActive() {
super();
Expand All @@ -84,10 +75,25 @@ public ItemInversionSigilActive() {
setMaxStackSize(1);
setContainerItem(this);

for (int i = 0; i < 31; i++) {
CHEST_EAST_CONTENTS[2 * i] = new ItemStack(Items.potionitem, 1, POTION_IDS[i]);
CHEST_EAST_CONTENTS[2 * i + 1] = new ItemStack(Items.potionitem, 1, POTION_IDS[i] + 8192);
}
CHEST_NORTH_CONTENTS = getValidChestContents(
ForgeDirection.NORTH,
InversionConfig.northChestValidItems,
InversionConfig.northChestRequiredItems);

CHEST_EAST_CONTENTS = getValidChestContents(
ForgeDirection.EAST,
InversionConfig.eastChestValidItems,
InversionConfig.eastChestRequiredItems);

CHEST_SOUTH_CONTENTS = getValidChestContents(
ForgeDirection.SOUTH,
InversionConfig.southChestValidItems,
InversionConfig.southChestRequiredItems);

CHEST_WEST_CONTENTS = getValidChestContents(
ForgeDirection.WEST,
InversionConfig.westChestValidItems,
InversionConfig.westChestRequiredItems);

ItemInversionSigilActiveEvents eventHandler = new ItemInversionSigilActiveEvents();
MinecraftForge.EVENT_BUS.register(eventHandler);
Expand All @@ -96,6 +102,74 @@ public ItemInversionSigilActive() {
.register(eventHandler);
}

private int parseItemMetaFromString(String string) {
try {
return Integer.parseInt(string);
} catch (NumberFormatException ignored) {
return -1;
}
}

private HashSet<ItemStackBaseCompare> getValidChestContents(ForgeDirection direction, String[] itemIds,
int itemReq) {
HashSet<ItemStackBaseCompare> validChestContents = new HashSet<>();
for (String itemId : itemIds) {
String[] itemIdSplit = itemId.split(":");
ItemStack validChestItemStack = null;
if (itemIdSplit.length == 2) {
validChestItemStack = new ItemStack(GameRegistry.findItem(itemIdSplit[0], itemIdSplit[1]));
} else if (itemIdSplit.length == 3) {
Item validChestItem = GameRegistry.findItem(itemIdSplit[0], itemIdSplit[1]);
int validChestItemMeta = parseItemMetaFromString(itemIdSplit[2]);
validChestItemStack = new ItemStack(validChestItem, 1, validChestItemMeta);
if (validChestItem == Items.potionitem && chestSplashPotionsValid) {
ItemStack splashPotion = new ItemStack(validChestItem, 1, validChestItemMeta + 8192);
boolean successfulAdd = validChestContents.add(new ItemStackBaseCompare(splashPotion));
if (successfulAdd) {
FMLLog.log(
Level.DEBUG,
"Used splash potion %s as siege requirement from item id %s.",
StatCollector.translateToLocal(splashPotion.getDisplayName()),
itemId);
} else {
FMLLog.log(
Level.DEBUG,
"Could not add splash potion %s as siege requirement from item id %s since it was a duplicate!",
StatCollector.translateToLocal(splashPotion.getDisplayName()),
itemId);
}
}
}
if (validChestItemStack == null) {
FMLLog.log(Level.WARN, "Could not parse item id %s for the %s ritual!", itemId, direction.toString());
continue;
}
boolean successfulAdd = validChestContents.add(new ItemStackBaseCompare(validChestItemStack));
if (successfulAdd) {
FMLLog.log(
Level.DEBUG,
"Used item %s as siege requirement from item id %s.",
StatCollector.translateToLocal(validChestItemStack.getDisplayName()),
itemId);
} else {
FMLLog.log(
Level.DEBUG,
"Could not add item %s as siege requirement from item id %s since it was a duplicate!",
StatCollector.translateToLocal(validChestItemStack.getDisplayName()),
itemId);
}
}
if (itemReq > validChestContents.size()) {
FMLLog.log(
Level.WARN,
"There are only %s valid items for the %s ritual, but there are %s required items! The ritual will be impossible!",
validChestContents.size(),
direction.toString(),
itemReq);
}
return validChestContents;
}

private EntitySiegeProperty getProperties(EntityPlayer player) {
return (EntitySiegeProperty) player.getExtendedProperties(EntitySiegeProperty.PROP_KEY);
}
Expand Down Expand Up @@ -209,18 +283,14 @@ private void startSiege(World world, int beaconX, int beaconY, int beaconZ, Enti
curentity.setDead();
}
}
for (int i = 0; i < LIGHTNING_POSITIONS.length; i++) {
for (int[] lightningPosition : LIGHTNING_POSITIONS) {
EntityLightningBolt lightningBolt = new EntityLightningBolt(
world,
beaconX + LIGHTNING_POSITIONS[i][0] + 0.5,
beaconX + lightningPosition[0] + 0.5,
beaconY + 0.5,
beaconZ + LIGHTNING_POSITIONS[i][1] + 0.5);
beaconZ + lightningPosition[1] + 0.5);
world.addWeatherEffect(lightningBolt);
world.setBlock(
beaconX + LIGHTNING_POSITIONS[i][0],
beaconY,
beaconZ + LIGHTNING_POSITIONS[i][1],
Blocks.air);
world.setBlock(beaconX + lightningPosition[0], beaconY, beaconZ + lightningPosition[1], Blocks.air);
}
}

Expand All @@ -245,29 +315,22 @@ private void endSiege(boolean won, EntityPlayer player) {
}
}

private boolean checkChest(TileEntityChest chest, ItemStack[] itemsToCheck, int requiredAmount) {
int foundItemsAmount = 0;
boolean[] hasItem = new boolean[itemsToCheck.length];
private boolean checkChest(TileEntityChest chest, HashSet<ItemStackBaseCompare> itemsToCheck, int requiredAmount) {
HashSet<ItemStackBaseCompare> confirmedItems = new HashSet<>();
for (int i = 0; i < chest.getSizeInventory(); i++) {
ItemStack stack = chest.getStackInSlot(i);
for (int j = 0; j < itemsToCheck.length; j++) {
if (stack != null && ItemStack.areItemStacksEqual(stack, itemsToCheck[j])) {
hasItem[j] = true;
break;
}
}
}
for (int i = 0; i < itemsToCheck.length; i++) {
if (hasItem[i]) {
foundItemsAmount++;
if (stack == null) continue;
ItemStackBaseCompare stackCustomCompare = new ItemStackBaseCompare(stack);
if (itemsToCheck.contains(stackCustomCompare)) {
confirmedItems.add(stackCustomCompare);
}
}
return foundItemsAmount >= requiredAmount;
return confirmedItems.size() >= requiredAmount;
}

private boolean checkChestInDirection(ForgeDirection direction, int beaconX, int beaconY, int beaconZ,
World world) {
ItemStack[] contents;
HashSet<ItemStackBaseCompare> contents;
int requiredAmount;

if (direction == ForgeDirection.NORTH) {
Expand Down Expand Up @@ -452,7 +515,7 @@ public void whenPlayerLeavesEnd(PlayerEvent.PlayerChangedDimensionEvent event) {
}

@SubscribeEvent(priority = EventPriority.NORMAL)
public void whenPlayerLeavesEnd2(PlayerEvent.PlayerRespawnEvent event) {
public void whenPlayerLeavesEndAlternate(PlayerEvent.PlayerRespawnEvent event) {
if (getProperties(event.player).siege) {
event.player.addChatMessage(new ChatComponentTranslation("chat.pseudo_inversion_ritual.leftEnd"));
endSiege(false, event.player);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,62 @@ public class InversionConfig {

@Config.Comment("Amount of unique items in the list the north chest has to contain for the pseudo-inversion ritual")
@Config.DefaultInt(12)
@Config.RangeInt(min = 1, max = 14)
@Config.RangeInt(min = 1, max = 10000)
public static int northChestRequiredItems;

@Config.Comment("List of valid items the north chest can contain. Must be item ids in the form 'modid:itemname:meta'")
@Config.DefaultStringList(
value = { "minecraft:stone", "minecraft:brick", "minecraft:glass", "minecraft:cooked_fished",
"minecraft:hardened_clay", "minecraft:dye:2", "minecraft:coal:1", "minecraft:cooked_beef",
"minecraft:iron_ingot", "minecraft:cooked_chicken", "minecraft:gold_ingot", "minecraft:baked_potato",
"minecraft:cooked_porkchop", "minecraft:netherbrick" })
public static String[] northChestValidItems;

@Config.Comment("Amount of unique items in the list the east chest has to contain for the pseudo-inversion ritual")
@Config.DefaultInt(12)
@Config.RangeInt(min = 1, max = 27)
@Config.RangeInt(min = 1, max = 10000)
public static int eastChestRequiredItems;

@Config.Comment("List of valid items the east chest can contain. Must be item ids in the form 'modid:itemname:meta'. Enable splash potions with chestSplashPotionsValid (applies for other chests too).")
@Config.DefaultStringList(
value = { "minecraft:potion:8193", "minecraft:potion:8194", "minecraft:potion:8195", "minecraft:potion:8196",
"minecraft:potion:8197", "minecraft:potion:8198", "minecraft:potion:8200", "minecraft:potion:8201",
"minecraft:potion:8202", "minecraft:potion:8204", "minecraft:potion:8205", "minecraft:potion:8206",
"minecraft:potion:8225", "minecraft:potion:8226", "minecraft:potion:8228", "minecraft:potion:8229",
"minecraft:potion:8232", "minecraft:potion:8233", "minecraft:potion:8234", "minecraft:potion:8236",
"minecraft:potion:8257", "minecraft:potion:8258", "minecraft:potion:8259", "minecraft:potion:8260",
"minecraft:potion:8262", "minecraft:potion:8264", "minecraft:potion:8265", "minecraft:potion:8267",
"minecraft:potion:8268", "minecraft:potion:8269", "minecraft:potion:8270" })
public static String[] eastChestValidItems;

@Config.Comment("Amount of unique items in the list the south chest has to contain for the pseudo-inversion ritual")
@Config.DefaultInt(12)
@Config.RangeInt(min = 1, max = 13)
@Config.RangeInt(min = 1, max = 10000)
public static int southChestRequiredItems;

@Config.Comment("List of valid items the south chest can contain. Must be item ids in the form 'modid:itemname:meta'")
@Config.DefaultStringList(
value = { "minecraft:grass", "minecraft:lapis_ore", "minecraft:dirt", "minecraft:obsidian", "minecraft:sand",
"minecraft:diamond_ore", "minecraft:gravel", "minecraft:redstone_ore", "minecraft:gold_ore",
"minecraft:clay", "minecraft:iron_ore", "minecraft:emerald_ore", "minecraft:coal_ore" })
public static String[] southChestValidItems;

@Config.Comment("Amount of unique items in the list the west chest has to contain for the pseudo-inversion ritual")
@Config.DefaultInt(12)
@Config.RangeInt(min = 1, max = 12)
@Config.RangeInt(min = 1, max = 10000)
public static int westChestRequiredItems;

@Config.Comment("List of valid items the west chest can contain. Must be item ids in the form 'modid:itemname:meta'")
@Config.DefaultStringList(
value = { "minecraft:record_13", "minecraft:record_mellohi", "minecraft:record_cat", "minecraft:record_stal",
"minecraft:record_blocks", "minecraft:record_strad", "minecraft:record_chirp", "minecraft:record_ward",
"minecraft:record_far", "minecraft:record_11", "minecraft:record_mall", "minecraft:record_wait" })
public static String[] westChestValidItems;

@Config.Comment("Whether or not vanilla splash potions should also be valid if a regular potion of the same type is found.")
@Config.DefaultBoolean(true)
public static boolean chestSplashPotionsValid;

@Config.Comment("Amount of mobs needed to kill to pass the siege of the ritual")
@Config.DefaultInt(100)
@Config.RangeInt(min = 4)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.fouristhenumber.utilitiesinexcess.utils;

import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;

/**
* Wrapper class of ItemStack that compares with itemStack Item, Count and Damage.
*/

public class ItemStackBaseCompare {

public ItemStackBaseCompare(ItemStack itemStack) {
item = itemStack.getItem();
count = itemStack.stackSize;
damage = itemStack.getItemDamage();
}

Item item;
int count;
int damage;

@Override
public boolean equals(Object o) {
if (!(o instanceof ItemStackBaseCompare that)) return false;
return count == that.count && damage == that.damage && item.equals(that.item);
}

@Override
public int hashCode() {
int result = 1;
result = 31 * result + (item != null ? item.hashCode() : 0);
result = 31 * result + count;
result = 31 * result + damage;
return result;
}
}