BloodMagic/src/main/java/WayofTime/bloodmagic/item/ItemRitualDiviner.java

564 lines
21 KiB
Java
Raw Normal View History

package WayofTime.bloodmagic.item;
2017-08-15 21:30:48 -07:00
import WayofTime.bloodmagic.BloodMagic;
import WayofTime.bloodmagic.apibutnotreally.Constants;
import WayofTime.bloodmagic.apibutnotreally.registry.RitualRegistry;
import WayofTime.bloodmagic.apibutnotreally.ritual.EnumRuneType;
import WayofTime.bloodmagic.apibutnotreally.ritual.Ritual;
import WayofTime.bloodmagic.apibutnotreally.ritual.RitualComponent;
import WayofTime.bloodmagic.apibutnotreally.soul.EnumDemonWillType;
import WayofTime.bloodmagic.apibutnotreally.util.helper.RitualHelper;
2017-08-15 21:30:48 -07:00
import WayofTime.bloodmagic.client.IVariantProvider;
import WayofTime.bloodmagic.core.RegistrarBloodMagicBlocks;
import WayofTime.bloodmagic.tile.TileMasterRitualStone;
import WayofTime.bloodmagic.util.ChatUtil;
import WayofTime.bloodmagic.util.Utils;
import WayofTime.bloodmagic.util.handler.event.ClientHandler;
import WayofTime.bloodmagic.util.helper.TextHelper;
import com.google.common.base.Strings;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
2017-08-15 20:21:54 -07:00
import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
2017-01-01 22:26:42 -08:00
import net.minecraft.util.*;
2016-03-18 16:31:55 -04:00
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
2016-03-16 01:10:33 -07:00
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.lwjgl.input.Keyboard;
2017-08-15 21:30:48 -07:00
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
2017-08-15 21:30:48 -07:00
public class ItemRitualDiviner extends Item implements IVariantProvider {
2017-01-02 01:18:29 -08:00
public static final String tooltipBase = "tooltip.bloodmagic.diviner.";
2017-08-15 21:30:48 -07:00
public static String[] names = {"normal", "dusk", "dawn"};
2017-08-15 21:30:48 -07:00
public ItemRitualDiviner() {
setUnlocalizedName(BloodMagic.MODID + ".ritualDiviner");
setCreativeTab(BloodMagic.TAB_BM);
setHasSubtypes(true);
setMaxStackSize(1);
}
@Override
2017-08-15 21:30:48 -07:00
public String getUnlocalizedName(ItemStack stack) {
return super.getUnlocalizedName(stack) + names[stack.getItemDamage()];
}
@Override
2017-08-15 21:30:48 -07:00
public String getHighlightTip(ItemStack stack, String displayName) {
if (Strings.isNullOrEmpty(getCurrentRitual(stack)))
return displayName;
Ritual ritual = RitualRegistry.getRitualForId(getCurrentRitual(stack));
if (ritual == null)
return displayName;
return displayName + ": " + TextHelper.localize(ritual.getUnlocalizedName());
}
@Override
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public void getSubItems(CreativeTabs creativeTab, NonNullList<ItemStack> list) {
2017-08-15 20:21:54 -07:00
if (!isInCreativeTab(creativeTab))
return;
for (int i = 0; i < names.length; i++)
2017-08-15 20:21:54 -07:00
list.add(new ItemStack(this, 1, i));
}
@Override
2017-08-15 21:30:48 -07:00
public EnumActionResult onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
2017-01-01 22:26:42 -08:00
ItemStack stack = player.getHeldItem(hand);
2017-08-15 21:30:48 -07:00
if (player.isSneaking()) {
if (world.isRemote) {
trySetDisplayedRitual(stack, world, pos);
}
2016-06-24 17:16:26 -04:00
return EnumActionResult.SUCCESS;
2017-08-15 21:30:48 -07:00
} else if (addRuneToRitual(stack, world, pos, player)) {
if (world.isRemote) {
spawnParticles(world, pos.up(), 15);
}
return EnumActionResult.SUCCESS;
// TODO: Have the diviner automagically build the ritual
}
return EnumActionResult.PASS;
}
/**
* Adds a single rune to the ritual.
2017-08-15 21:30:48 -07:00
*
* @param stack - The Ritual Diviner stack
* @param world - The World
* @param pos - Block Position of the MRS.
* @param player - The Player attempting to place the ritual
* @return - True if a rune was successfully added
*/
2017-08-15 21:30:48 -07:00
public boolean addRuneToRitual(ItemStack stack, World world, BlockPos pos, EntityPlayer player) {
TileEntity tile = world.getTileEntity(pos);
2017-08-15 21:30:48 -07:00
if (tile instanceof TileMasterRitualStone) {
Ritual ritual = RitualRegistry.getRitualForId(this.getCurrentRitual(stack));
2017-08-15 21:30:48 -07:00
if (ritual != null) {
EnumFacing direction = getDirection(stack);
2017-08-15 21:30:48 -07:00
for (RitualComponent component : ritual.getComponents()) {
if (!canPlaceRitualStone(component.getRuneType(), stack)) {
return false;
}
BlockPos offset = component.getOffset(direction);
BlockPos newPos = pos.add(offset);
IBlockState state = world.getBlockState(newPos);
Block block = state.getBlock();
2017-08-15 21:30:48 -07:00
if (RitualHelper.isRune(world, newPos)) {
if (RitualHelper.isRuneType(world, newPos, component.getRuneType())) {
if (world.isRemote) {
undisplayHologram();
}
2017-08-15 21:30:48 -07:00
} else {
// Replace existing ritual stone
RitualHelper.setRuneType(world, newPos, component.getRuneType());
return true;
}
2017-08-15 21:30:48 -07:00
} else if (block.isAir(state, world, newPos) || block.isReplaceable(world, newPos)) {
if (!consumeStone(stack, world, player)) {
return false;
}
int meta = component.getRuneType().ordinal();
IBlockState newState = RegistrarBloodMagicBlocks.RITUAL_STONE.getStateFromMeta(meta);
world.setBlockState(newPos, newState);
return true;
2017-08-15 21:30:48 -07:00
} else {
return false; // TODO: Possibly replace the block with a
// ritual stone
}
}
}
}
return false;
}
2016-06-24 17:16:26 -04:00
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public void trySetDisplayedRitual(ItemStack itemStack, World world, BlockPos pos) {
TileEntity tile = world.getTileEntity(pos);
2017-08-15 21:30:48 -07:00
if (tile instanceof TileMasterRitualStone) {
Ritual ritual = RitualRegistry.getRitualForId(this.getCurrentRitual(itemStack));
TileMasterRitualStone masterRitualStone = (TileMasterRitualStone) tile;
2017-08-15 21:30:48 -07:00
if (ritual != null) {
EnumFacing direction = getDirection(itemStack);
2016-06-24 17:16:26 -04:00
ClientHandler.setRitualHolo(masterRitualStone, ritual, direction, true);
}
}
2016-06-24 17:16:26 -04:00
}
2016-06-24 17:16:26 -04:00
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public void undisplayHologram() {
2016-06-24 17:16:26 -04:00
ClientHandler.setRitualHoloToNull();
}
// TODO: Make this work for any IRitualStone
2017-08-15 21:30:48 -07:00
public boolean consumeStone(ItemStack stack, World world, EntityPlayer player) {
if (player.capabilities.isCreativeMode) {
return true;
}
2017-01-01 22:26:42 -08:00
NonNullList<ItemStack> inventory = player.inventory.mainInventory;
2017-08-15 21:30:48 -07:00
for (ItemStack newStack : inventory) {
2017-01-01 22:26:42 -08:00
if (newStack.isEmpty()) {
continue;
}
Item item = newStack.getItem();
2017-08-15 21:30:48 -07:00
if (item instanceof ItemBlock) {
Block block = ((ItemBlock) item).getBlock();
2017-08-15 21:30:48 -07:00
if (block == RegistrarBloodMagicBlocks.RITUAL_STONE) {
2017-01-01 22:26:42 -08:00
newStack.shrink(1);
return true;
}
}
}
return false;
}
@Override
@SideOnly(Side.CLIENT)
2017-08-15 21:30:48 -07:00
public void addInformation(ItemStack stack, World world, List<String> tooltip, ITooltipFlag flag) {
if (!stack.hasTagCompound())
return;
Ritual ritual = RitualRegistry.getRitualForId(this.getCurrentRitual(stack));
2017-08-15 21:30:48 -07:00
if (ritual != null) {
2017-01-02 01:18:29 -08:00
tooltip.add(TextHelper.localize("tooltip.bloodmagic.diviner.currentRitual") + TextHelper.localize(ritual.getUnlocalizedName()));
boolean sneaking = Keyboard.isKeyDown(Keyboard.KEY_RSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT);
boolean extraInfo = sneaking && Keyboard.isKeyDown(Keyboard.KEY_M);
2017-08-15 21:30:48 -07:00
if (extraInfo) {
tooltip.add("");
2017-08-15 21:30:48 -07:00
for (EnumDemonWillType type : EnumDemonWillType.values()) {
if (TextHelper.canTranslate(ritual.getUnlocalizedName() + "." + type.getName().toLowerCase() + ".info")) {
tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect(ritual.getUnlocalizedName() + "." + type.getName().toLowerCase() + ".info"))));
}
}
2017-08-15 21:30:48 -07:00
} else if (sneaking) {
tooltip.add(TextHelper.localize(tooltipBase + "currentDirection", Utils.toFancyCasing(getDirection(stack).getName())));
tooltip.add("");
ArrayList<RitualComponent> componentList = ritual.getComponents();
int blankRunes = 0;
int airRunes = 0;
int waterRunes = 0;
int fireRunes = 0;
int earthRunes = 0;
int duskRunes = 0;
int dawnRunes = 0;
int totalRunes = componentList.size();
2017-08-15 21:30:48 -07:00
for (RitualComponent component : componentList) {
switch (component.getRuneType()) {
case BLANK:
blankRunes++;
break;
case AIR:
airRunes++;
break;
case EARTH:
earthRunes++;
break;
case FIRE:
fireRunes++;
break;
case WATER:
waterRunes++;
break;
case DUSK:
duskRunes++;
break;
case DAWN:
dawnRunes++;
break;
}
}
if (blankRunes > 0)
tooltip.add(EnumRuneType.BLANK.colorCode + TextHelper.localize(tooltipBase + "blankRune", blankRunes));
if (waterRunes > 0)
tooltip.add(EnumRuneType.WATER.colorCode + TextHelper.localize(tooltipBase + "waterRune", waterRunes));
if (airRunes > 0)
tooltip.add(EnumRuneType.AIR.colorCode + TextHelper.localize(tooltipBase + "airRune", airRunes));
if (fireRunes > 0)
tooltip.add(EnumRuneType.FIRE.colorCode + TextHelper.localize(tooltipBase + "fireRune", fireRunes));
if (earthRunes > 0)
tooltip.add(EnumRuneType.EARTH.colorCode + TextHelper.localize(tooltipBase + "earthRune", earthRunes));
if (duskRunes > 0)
tooltip.add(EnumRuneType.DUSK.colorCode + TextHelper.localize(tooltipBase + "duskRune", duskRunes));
if (dawnRunes > 0)
tooltip.add(EnumRuneType.DAWN.colorCode + TextHelper.localize(tooltipBase + "dawnRune", dawnRunes));
tooltip.add("");
tooltip.add(TextHelper.localize(tooltipBase + "totalRune", totalRunes));
2017-08-15 21:30:48 -07:00
} else {
tooltip.add("");
2017-08-15 21:30:48 -07:00
if (TextHelper.canTranslate(ritual.getUnlocalizedName() + ".info")) {
tooltip.addAll(Arrays.asList(TextHelper.cutLongString(TextHelper.localizeEffect(ritual.getUnlocalizedName() + ".info"))));
tooltip.add("");
}
tooltip.add(TextHelper.localizeEffect(tooltipBase + "extraInfo"));
tooltip.add(TextHelper.localizeEffect(tooltipBase + "extraExtraInfo"));
}
}
}
@Override
2017-08-15 21:30:48 -07:00
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, EnumHand hand) {
2017-01-01 22:26:42 -08:00
ItemStack stack = player.getHeldItem(hand);
2016-04-24 10:06:28 -07:00
RayTraceResult ray = this.rayTrace(world, player, false);
2017-08-15 21:30:48 -07:00
if (ray != null && ray.typeOfHit == RayTraceResult.Type.BLOCK) {
return new ActionResult<ItemStack>(EnumActionResult.PASS, stack);
}
2017-08-15 21:30:48 -07:00
if (player.isSneaking()) {
if (!world.isRemote) {
cycleRitual(stack, player);
}
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, stack);
}
return new ActionResult<ItemStack>(EnumActionResult.PASS, stack);
}
@Override
2017-08-15 21:30:48 -07:00
public boolean onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) {
if (entityLiving instanceof EntityPlayer) {
EntityPlayer player = (EntityPlayer) entityLiving;
2017-01-01 22:26:42 -08:00
RayTraceResult ray = this.rayTrace(player.getEntityWorld(), player, false);
2017-08-15 21:30:48 -07:00
if (ray != null && ray.typeOfHit == RayTraceResult.Type.BLOCK) {
return false;
}
2017-08-15 21:30:48 -07:00
if (!player.isSwingInProgress) {
if (player.isSneaking()) {
cycleRitualBackwards(stack, player);
2017-08-15 21:30:48 -07:00
} else {
cycleDirection(stack, player);
}
}
}
return false;
}
2016-03-16 01:10:33 -07:00
@Override
2017-08-15 21:30:48 -07:00
public List<Pair<Integer, String>> getVariants() {
2016-03-16 01:10:33 -07:00
List<Pair<Integer, String>> ret = new ArrayList<Pair<Integer, String>>();
ret.add(new ImmutablePair<Integer, String>(0, "type=basic"));
ret.add(new ImmutablePair<Integer, String>(1, "type=dusk"));
ret.add(new ImmutablePair<Integer, String>(2, "type=dawn"));
return ret;
}
2017-08-15 21:30:48 -07:00
public void cycleDirection(ItemStack stack, EntityPlayer player) {
EnumFacing direction = getDirection(stack);
EnumFacing newDirection;
2017-08-15 21:30:48 -07:00
switch (direction) {
case NORTH:
newDirection = EnumFacing.EAST;
break;
case EAST:
newDirection = EnumFacing.SOUTH;
break;
case SOUTH:
newDirection = EnumFacing.WEST;
break;
case WEST:
newDirection = EnumFacing.NORTH;
break;
default:
newDirection = EnumFacing.NORTH;
}
setDirection(stack, newDirection);
notifyDirectionChange(newDirection, player);
}
2017-08-15 21:30:48 -07:00
public void notifyDirectionChange(EnumFacing direction, EntityPlayer player) {
ChatUtil.sendNoSpam(player, TextHelper.localize(tooltipBase + "currentDirection", Utils.toFancyCasing(direction.getName())));
}
2017-08-15 21:30:48 -07:00
public void setDirection(ItemStack stack, EnumFacing direction) {
if (!stack.hasTagCompound()) {
stack.setTagCompound(new NBTTagCompound());
}
NBTTagCompound tag = stack.getTagCompound();
tag.setInteger(Constants.NBT.DIRECTION, direction.getIndex());
}
2017-08-15 21:30:48 -07:00
public EnumFacing getDirection(ItemStack stack) {
if (!stack.hasTagCompound()) {
stack.setTagCompound(new NBTTagCompound());
return EnumFacing.NORTH;
}
NBTTagCompound tag = stack.getTagCompound();
int dir = tag.getInteger(Constants.NBT.DIRECTION);
2017-08-15 21:30:48 -07:00
if (dir == 0) {
return EnumFacing.NORTH;
}
return EnumFacing.VALUES[tag.getInteger(Constants.NBT.DIRECTION)];
}
/**
* Cycles the selected ritual to the next available ritual that is enabled.
2017-08-15 21:30:48 -07:00
*
* @param stack - The ItemStack of the ritual diviner
* @param player - The player using the ritual diviner
*/
2017-08-15 21:30:48 -07:00
public void cycleRitual(ItemStack stack, EntityPlayer player) {
String key = getCurrentRitual(stack);
List<String> idList = RitualRegistry.getOrderedIds();
String firstId = "";
boolean foundId = false;
boolean foundFirst = false;
2017-08-15 21:30:48 -07:00
for (String str : idList) {
Ritual ritual = RitualRegistry.getRitualForId(str);
2017-08-15 21:30:48 -07:00
if (!RitualRegistry.ritualEnabled(ritual) || !canDivinerPerformRitual(stack, ritual)) {
continue;
}
2017-08-15 21:30:48 -07:00
if (!foundFirst) {
firstId = str;
foundFirst = true;
}
2017-08-15 21:30:48 -07:00
if (foundId) {
setCurrentRitual(stack, str);
notifyRitualChange(str, player);
return;
2017-08-15 21:30:48 -07:00
} else {
if (str.equals(key)) {
foundId = true;
continue;
}
}
}
2017-08-15 21:30:48 -07:00
if (foundFirst) {
setCurrentRitual(stack, firstId);
notifyRitualChange(firstId, player);
}
}
/**
* Does the same as cycleRitual but instead cycles backwards.
2017-08-15 21:30:48 -07:00
*
* @param stack
* @param player
*/
2017-08-15 21:30:48 -07:00
public void cycleRitualBackwards(ItemStack stack, EntityPlayer player) {
String key = getCurrentRitual(stack);
List<String> idList = RitualRegistry.getOrderedIds();
String firstId = "";
boolean foundId = false;
boolean foundFirst = false;
2017-08-15 21:30:48 -07:00
for (int i = idList.size() - 1; i >= 0; i--) {
String str = idList.get(i);
Ritual ritual = RitualRegistry.getRitualForId(str);
2017-08-15 21:30:48 -07:00
if (!RitualRegistry.ritualEnabled(ritual) || !canDivinerPerformRitual(stack, ritual)) {
continue;
}
2017-08-15 21:30:48 -07:00
if (!foundFirst) {
firstId = str;
foundFirst = true;
}
2017-08-15 21:30:48 -07:00
if (foundId) {
setCurrentRitual(stack, str);
notifyRitualChange(str, player);
return;
2017-08-15 21:30:48 -07:00
} else {
if (str.equals(key)) {
foundId = true;
continue;
}
}
}
2017-08-15 21:30:48 -07:00
if (foundFirst) {
setCurrentRitual(stack, firstId);
notifyRitualChange(firstId, player);
}
}
2017-08-15 21:30:48 -07:00
public boolean canDivinerPerformRitual(ItemStack stack, Ritual ritual) {
if (ritual == null) {
return false;
}
ArrayList<RitualComponent> components = ritual.getComponents();
2017-08-15 21:30:48 -07:00
for (RitualComponent component : components) {
if (!canPlaceRitualStone(component.getRuneType(), stack)) {
return false;
}
}
return true;
}
2017-08-15 21:30:48 -07:00
public void notifyRitualChange(String key, EntityPlayer player) {
Ritual ritual = RitualRegistry.getRitualForId(key);
2017-08-15 21:30:48 -07:00
if (ritual != null) {
player.sendStatusMessage(new TextComponentTranslation(ritual.getUnlocalizedName()), true);
}
}
2017-08-15 21:30:48 -07:00
public void setCurrentRitual(ItemStack stack, String key) {
if (!stack.hasTagCompound()) {
stack.setTagCompound(new NBTTagCompound());
}
NBTTagCompound tag = stack.getTagCompound();
tag.setString(Constants.NBT.CURRENT_RITUAL, key);
}
2017-08-15 21:30:48 -07:00
public String getCurrentRitual(ItemStack stack) {
if (!stack.hasTagCompound()) {
stack.setTagCompound(new NBTTagCompound());
}
NBTTagCompound tag = stack.getTagCompound();
return tag.getString(Constants.NBT.CURRENT_RITUAL);
}
2017-08-15 21:30:48 -07:00
public boolean canPlaceRitualStone(EnumRuneType rune, ItemStack stack) {
int meta = stack.getItemDamage();
2017-08-15 21:30:48 -07:00
switch (rune) {
case BLANK:
case AIR:
case EARTH:
case FIRE:
case WATER:
return true;
case DUSK:
return meta >= 1;
case DAWN:
return meta >= 2;
}
return false;
}
2017-08-15 21:30:48 -07:00
public static void spawnParticles(World worldIn, BlockPos pos, int amount) {
2016-03-18 16:50:33 -04:00
IBlockState state = worldIn.getBlockState(pos);
Block block = worldIn.getBlockState(pos).getBlock();
2017-08-15 21:30:48 -07:00
if (block.isAir(state, worldIn, pos)) {
for (int i = 0; i < amount; ++i) {
double d0 = itemRand.nextGaussian() * 0.02D;
double d1 = itemRand.nextGaussian() * 0.02D;
double d2 = itemRand.nextGaussian() * 0.02D;
2016-03-18 16:50:33 -04:00
worldIn.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, (double) ((float) pos.getX() + itemRand.nextFloat()), (double) pos.getY() + (double) itemRand.nextFloat(), (double) ((float) pos.getZ() + itemRand.nextFloat()), d0, d1, d2, new int[0]);
}
2017-08-15 21:30:48 -07:00
} else {
for (int i1 = 0; i1 < amount; ++i1) {
double d0 = itemRand.nextGaussian() * 0.02D;
double d1 = itemRand.nextGaussian() * 0.02D;
double d2 = itemRand.nextGaussian() * 0.02D;
worldIn.spawnParticle(EnumParticleTypes.VILLAGER_HAPPY, (double) ((float) pos.getX() + itemRand.nextFloat()), (double) pos.getY() + (double) itemRand.nextFloat() * 1.0f, (double) ((float) pos.getZ() + itemRand.nextFloat()), d0, d1, d2, new int[0]);
}
}
}
}