2015-11-02 20:39:44 +00:00
|
|
|
package WayofTime.bloodmagic.api.ritual;
|
2015-10-31 20:47:43 +00:00
|
|
|
|
2016-04-11 01:19:18 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
2016-04-11 02:09:32 +00:00
|
|
|
import java.util.Map.Entry;
|
2016-04-11 01:19:18 +00:00
|
|
|
|
2015-11-03 02:00:48 +00:00
|
|
|
import lombok.EqualsAndHashCode;
|
2015-10-31 20:47:43 +00:00
|
|
|
import lombok.Getter;
|
|
|
|
import lombok.RequiredArgsConstructor;
|
2015-12-29 21:00:26 +00:00
|
|
|
import lombok.ToString;
|
2015-10-31 20:47:43 +00:00
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
2015-12-29 21:00:26 +00:00
|
|
|
import net.minecraft.item.ItemStack;
|
2016-01-09 20:31:30 +00:00
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
2016-04-11 02:09:32 +00:00
|
|
|
import net.minecraft.nbt.NBTTagList;
|
2016-03-17 20:00:44 +00:00
|
|
|
import net.minecraft.util.math.BlockPos;
|
2016-04-11 01:19:18 +00:00
|
|
|
import net.minecraft.util.text.ITextComponent;
|
|
|
|
import net.minecraft.util.text.TextComponentTranslation;
|
2015-12-29 21:00:26 +00:00
|
|
|
import net.minecraft.world.World;
|
2016-07-12 20:57:22 +00:00
|
|
|
import WayofTime.bloodmagic.api.soul.DemonWillHolder;
|
2016-04-11 19:36:27 +00:00
|
|
|
import WayofTime.bloodmagic.api.soul.EnumDemonWillType;
|
2016-07-11 23:47:19 +00:00
|
|
|
import WayofTime.bloodmagic.demonAura.WorldDemonWillHandler;
|
2015-10-31 20:47:43 +00:00
|
|
|
|
2015-12-29 21:00:26 +00:00
|
|
|
/**
|
|
|
|
* Abstract class for creating new rituals. Rituals need be registered with
|
|
|
|
* {@link WayofTime.bloodmagic.api.registry.RitualRegistry#registerRitual(Ritual, String)}
|
|
|
|
*/
|
2015-10-31 20:47:43 +00:00
|
|
|
@Getter
|
|
|
|
@RequiredArgsConstructor
|
2016-07-11 01:51:17 +00:00
|
|
|
@EqualsAndHashCode(exclude = { "modableRangeMap", "ritualComponents", "renderer", "volumeRangeMap", "horizontalRangeMap", "verticalRangeMap" })
|
2015-12-29 21:00:26 +00:00
|
|
|
@ToString
|
2015-12-30 20:34:40 +00:00
|
|
|
public abstract class Ritual
|
|
|
|
{
|
|
|
|
public final ArrayList<RitualComponent> ritualComponents = new ArrayList<RitualComponent>();
|
|
|
|
private final String name;
|
|
|
|
private final int crystalLevel;
|
|
|
|
private final int activationCost;
|
|
|
|
private final RitualRenderer renderer;
|
|
|
|
private final String unlocalizedName;
|
|
|
|
|
2015-12-31 13:01:39 +00:00
|
|
|
protected final Map<String, AreaDescriptor> modableRangeMap = new HashMap<String, AreaDescriptor>();
|
2016-04-11 12:26:41 +00:00
|
|
|
protected final Map<String, Integer> volumeRangeMap = new HashMap<String, Integer>();
|
|
|
|
protected final Map<String, Integer> horizontalRangeMap = new HashMap<String, Integer>();
|
|
|
|
protected final Map<String, Integer> verticalRangeMap = new HashMap<String, Integer>();
|
2015-12-30 20:34:40 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param name
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The name of the ritual
|
2015-12-30 20:34:40 +00:00
|
|
|
* @param crystalLevel
|
2016-01-02 22:56:37 +00:00
|
|
|
* - Required Activation Crystal tier
|
2015-12-30 20:34:40 +00:00
|
|
|
* @param activationCost
|
2016-01-02 22:56:37 +00:00
|
|
|
* - Base LP cost for activating the ritual
|
2015-12-30 20:34:40 +00:00
|
|
|
*/
|
|
|
|
public Ritual(String name, int crystalLevel, int activationCost, String unlocalizedName)
|
|
|
|
{
|
|
|
|
this(name, crystalLevel, activationCost, null, unlocalizedName);
|
|
|
|
}
|
|
|
|
|
2016-01-09 20:31:30 +00:00
|
|
|
public void readFromNBT(NBTTagCompound tag)
|
|
|
|
{
|
2016-04-11 02:09:32 +00:00
|
|
|
NBTTagList tags = tag.getTagList("areas", 10);
|
|
|
|
if (tags.hasNoTags())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2016-01-09 20:31:30 +00:00
|
|
|
|
2016-04-11 02:09:32 +00:00
|
|
|
for (int i = 0; i < tags.tagCount(); i++)
|
|
|
|
{
|
|
|
|
NBTTagCompound newTag = tags.getCompoundTagAt(i);
|
|
|
|
String rangeKey = newTag.getString("key");
|
|
|
|
|
|
|
|
NBTTagCompound storedTag = newTag.getCompoundTag("area");
|
|
|
|
AreaDescriptor desc = this.getBlockRange(rangeKey);
|
|
|
|
if (desc != null)
|
|
|
|
{
|
|
|
|
desc.readFromNBT(storedTag);
|
|
|
|
}
|
|
|
|
}
|
2016-01-09 20:31:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void writeToNBT(NBTTagCompound tag)
|
|
|
|
{
|
2016-04-11 02:09:32 +00:00
|
|
|
NBTTagList tags = new NBTTagList();
|
|
|
|
|
|
|
|
for (Entry<String, AreaDescriptor> entry : modableRangeMap.entrySet())
|
|
|
|
{
|
|
|
|
NBTTagCompound newTag = new NBTTagCompound();
|
|
|
|
newTag.setString("key", entry.getKey());
|
|
|
|
NBTTagCompound storedTag = new NBTTagCompound();
|
|
|
|
|
|
|
|
entry.getValue().writeToNBT(storedTag);
|
|
|
|
|
|
|
|
newTag.setTag("area", storedTag);
|
|
|
|
|
|
|
|
tags.appendTag(newTag);
|
|
|
|
}
|
2016-01-09 20:31:30 +00:00
|
|
|
|
2016-04-11 02:09:32 +00:00
|
|
|
tag.setTag("areas", tags);
|
2016-01-09 20:31:30 +00:00
|
|
|
}
|
|
|
|
|
2015-12-30 20:34:40 +00:00
|
|
|
/**
|
|
|
|
* Called when the player attempts to activate the ritual.
|
|
|
|
*
|
|
|
|
* {@link WayofTime.bloodmagic.tile.TileMasterRitualStone#activateRitual(ItemStack, EntityPlayer, Ritual)}
|
|
|
|
*
|
|
|
|
* @param masterRitualStone
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The {@link IMasterRitualStone} that the ritual is bound to
|
2015-12-30 20:34:40 +00:00
|
|
|
* @param player
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The activating player
|
2016-02-18 17:11:29 +00:00
|
|
|
* @param owner
|
|
|
|
* - Owner of the crystal activating this ritual, or the current
|
|
|
|
* owner of the ritual if being reactivated.
|
2015-12-30 20:34:40 +00:00
|
|
|
* @return - Whether activation was successful
|
|
|
|
*/
|
2016-02-18 17:11:29 +00:00
|
|
|
public boolean activateRitual(IMasterRitualStone masterRitualStone, EntityPlayer player, String owner)
|
2015-12-30 20:34:40 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called every {@link #getRefreshTime()} ticks while active.
|
|
|
|
*
|
|
|
|
* {@link WayofTime.bloodmagic.tile.TileMasterRitualStone#performRitual(World, BlockPos)}
|
|
|
|
*
|
|
|
|
* @param masterRitualStone
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The {@link IMasterRitualStone} that the ritual is bound to
|
2015-12-30 20:34:40 +00:00
|
|
|
*/
|
|
|
|
public abstract void performRitual(IMasterRitualStone masterRitualStone);
|
|
|
|
|
|
|
|
/**
|
2016-03-02 20:56:57 +00:00
|
|
|
* Called when the ritual is stopped for a given {@link Ritual.BreakType}.
|
2015-12-30 20:34:40 +00:00
|
|
|
*
|
2016-03-02 20:56:57 +00:00
|
|
|
* {@link WayofTime.bloodmagic.tile.TileMasterRitualStone#stopRitual(Ritual.BreakType)}
|
2015-12-30 20:34:40 +00:00
|
|
|
*
|
|
|
|
* @param masterRitualStone
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The {@link IMasterRitualStone} that the ritual is bound to
|
2015-12-30 20:34:40 +00:00
|
|
|
* @param breakType
|
2016-01-02 22:56:37 +00:00
|
|
|
* - The type of break that caused the stoppage.
|
2015-12-30 20:34:40 +00:00
|
|
|
*/
|
|
|
|
public void stopRitual(IMasterRitualStone masterRitualStone, BreakType breakType)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to set the amount of LP drained every {@link #getRefreshTime()}
|
|
|
|
* ticks.
|
|
|
|
*
|
|
|
|
* @return - The amount of LP drained per refresh
|
|
|
|
*/
|
|
|
|
public abstract int getRefreshCost();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to set the refresh rate of the ritual. (How often
|
|
|
|
* {@link #performRitual(IMasterRitualStone)} is called.
|
|
|
|
*
|
|
|
|
* @return - How often to perform the effect in ticks.
|
|
|
|
*/
|
|
|
|
public int getRefreshTime()
|
|
|
|
{
|
|
|
|
return 20;
|
|
|
|
}
|
|
|
|
|
2015-12-30 21:19:50 +00:00
|
|
|
public void addBlockRange(String range, AreaDescriptor defaultRange)
|
2015-12-30 20:34:40 +00:00
|
|
|
{
|
|
|
|
modableRangeMap.put(range, defaultRange);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-12-31 18:50:38 +00:00
|
|
|
* Used to grab the range of a ritual for a given effect.
|
2015-12-30 20:34:40 +00:00
|
|
|
*
|
|
|
|
* @param range
|
2016-01-02 22:56:37 +00:00
|
|
|
* - Range that needs to be pulled.
|
2015-12-31 18:50:38 +00:00
|
|
|
* @return -
|
2015-12-30 20:34:40 +00:00
|
|
|
*/
|
2015-12-30 21:19:50 +00:00
|
|
|
public AreaDescriptor getBlockRange(String range)
|
2015-12-30 20:34:40 +00:00
|
|
|
{
|
|
|
|
if (modableRangeMap.containsKey(range))
|
|
|
|
{
|
|
|
|
return modableRangeMap.get(range);
|
|
|
|
}
|
|
|
|
|
2015-12-30 21:19:50 +00:00
|
|
|
return null;
|
2015-12-30 20:34:40 +00:00
|
|
|
}
|
|
|
|
|
2016-04-11 01:19:18 +00:00
|
|
|
public List<String> getListOfRanges()
|
|
|
|
{
|
|
|
|
return new ArrayList<String>(modableRangeMap.keySet());
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getNextBlockRange(String range)
|
|
|
|
{
|
|
|
|
List<String> rangeList = getListOfRanges();
|
|
|
|
|
|
|
|
if (rangeList.isEmpty())
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rangeList.contains(range))
|
|
|
|
{
|
|
|
|
return rangeList.get(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
boolean hasMatch = false;
|
|
|
|
|
|
|
|
for (String rangeCheck : rangeList)
|
|
|
|
{
|
|
|
|
if (hasMatch)
|
|
|
|
{
|
|
|
|
return rangeCheck;
|
|
|
|
} else if (rangeCheck.equals(range))
|
|
|
|
{
|
|
|
|
hasMatch = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rangeList.get(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean setBlockRangeByBounds(String range, IMasterRitualStone master, BlockPos offset1, BlockPos offset2)
|
|
|
|
{
|
|
|
|
AreaDescriptor descriptor = this.getBlockRange(range);
|
2016-07-12 20:57:22 +00:00
|
|
|
World world = master.getWorldObj();
|
|
|
|
BlockPos masterPos = master.getBlockPos();
|
|
|
|
DemonWillHolder holder = WorldDemonWillHandler.getWillHolder(world, masterPos);
|
|
|
|
if (canBlockRangeBeModified(range, descriptor, master, offset1, offset2, holder))
|
2016-04-11 01:19:18 +00:00
|
|
|
{
|
|
|
|
descriptor.modifyAreaByBlockPositions(offset1, offset2);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-07-12 20:57:22 +00:00
|
|
|
protected boolean canBlockRangeBeModified(String range, AreaDescriptor descriptor, IMasterRitualStone master, BlockPos offset1, BlockPos offset2, DemonWillHolder holder)
|
2016-04-11 01:19:18 +00:00
|
|
|
{
|
2016-07-11 01:51:17 +00:00
|
|
|
List<EnumDemonWillType> willConfig = master.getActiveWillConfig();
|
2016-07-12 20:57:22 +00:00
|
|
|
int maxVolume = getMaxVolumeForRange(range, willConfig, holder);
|
|
|
|
int maxVertical = getMaxVerticalRadiusForRange(range, willConfig, holder);
|
|
|
|
int maxHorizontal = getMaxHorizontalRadiusForRange(range, willConfig, holder);
|
2016-04-11 12:26:41 +00:00
|
|
|
|
|
|
|
return (maxVolume <= 0 || descriptor.getVolumeForOffsets(offset1, offset2) <= maxVolume) && descriptor.isWithinRange(offset1, offset2, maxVertical, maxHorizontal);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void setMaximumVolumeAndDistanceOfRange(String range, int volume, int horizontalRadius, int verticalRadius)
|
|
|
|
{
|
|
|
|
volumeRangeMap.put(range, volume);
|
|
|
|
horizontalRangeMap.put(range, horizontalRadius);
|
|
|
|
verticalRangeMap.put(range, verticalRadius);
|
2016-04-11 01:19:18 +00:00
|
|
|
}
|
|
|
|
|
2016-04-11 19:36:27 +00:00
|
|
|
protected boolean checkDescriptorIsWithinRange(AreaDescriptor descriptor, int maxVolume, int maxHorizontal, int maxVertical)
|
|
|
|
{
|
|
|
|
return descriptor.getVolume() <= maxVolume && descriptor.isWithinRange(maxVertical, maxHorizontal);
|
|
|
|
}
|
|
|
|
|
2016-07-12 20:57:22 +00:00
|
|
|
public int getMaxVolumeForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
|
2016-04-11 19:36:27 +00:00
|
|
|
{
|
|
|
|
return volumeRangeMap.get(range);
|
|
|
|
}
|
|
|
|
|
2016-07-12 20:57:22 +00:00
|
|
|
public int getMaxVerticalRadiusForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
|
2016-04-11 19:36:27 +00:00
|
|
|
{
|
|
|
|
return verticalRangeMap.get(range);
|
|
|
|
}
|
|
|
|
|
2016-07-12 20:57:22 +00:00
|
|
|
public int getMaxHorizontalRadiusForRange(String range, List<EnumDemonWillType> activeTypes, DemonWillHolder holder)
|
2016-04-11 19:36:27 +00:00
|
|
|
{
|
|
|
|
return horizontalRangeMap.get(range);
|
|
|
|
}
|
|
|
|
|
2016-04-11 01:19:18 +00:00
|
|
|
public ITextComponent getErrorForBlockRangeOnFail(EntityPlayer player, String range, IMasterRitualStone master, BlockPos offset1, BlockPos offset2)
|
|
|
|
{
|
2016-04-11 12:26:41 +00:00
|
|
|
AreaDescriptor descriptor = this.getBlockRange(range);
|
|
|
|
if (descriptor == null)
|
|
|
|
{
|
|
|
|
return new TextComponentTranslation("ritual.BloodMagic.blockRange.tooBig", "?");
|
|
|
|
}
|
2016-07-12 20:57:22 +00:00
|
|
|
|
|
|
|
List<EnumDemonWillType> willConfig = master.getActiveWillConfig();
|
|
|
|
DemonWillHolder holder = WorldDemonWillHandler.getWillHolder(master.getWorldObj(), master.getBlockPos());
|
|
|
|
|
|
|
|
int maxVolume = this.getMaxVolumeForRange(range, willConfig, holder);
|
|
|
|
int maxVertical = this.getMaxVerticalRadiusForRange(range, willConfig, holder);
|
|
|
|
int maxHorizontal = this.getMaxHorizontalRadiusForRange(range, willConfig, holder);
|
2016-04-11 12:26:41 +00:00
|
|
|
|
|
|
|
if (maxVolume > 0 && descriptor.getVolumeForOffsets(offset1, offset2) > maxVolume)
|
|
|
|
{
|
|
|
|
return new TextComponentTranslation("ritual.BloodMagic.blockRange.tooBig", maxVolume);
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
return new TextComponentTranslation("ritual.BloodMagic.blockRange.tooFar", maxVertical, maxHorizontal);
|
|
|
|
}
|
2016-04-11 01:19:18 +00:00
|
|
|
}
|
|
|
|
|
2016-07-11 23:47:19 +00:00
|
|
|
public ITextComponent[] provideInformationOfRitualToPlayer(EntityPlayer player)
|
2016-04-11 01:19:18 +00:00
|
|
|
{
|
2016-07-11 23:47:19 +00:00
|
|
|
return new ITextComponent[] { new TextComponentTranslation(this.getUnlocalizedName() + ".info") };
|
2016-04-11 01:19:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public ITextComponent provideInformationOfRangeToPlayer(EntityPlayer player, String range)
|
|
|
|
{
|
|
|
|
if (getListOfRanges().contains(range))
|
|
|
|
{
|
|
|
|
return new TextComponentTranslation(this.getUnlocalizedName() + "." + range + ".info");
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
return new TextComponentTranslation("ritual.BloodMagic.blockRange.noRange");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-30 20:34:40 +00:00
|
|
|
/**
|
|
|
|
* @return a list of {@link RitualComponent} for checking the ritual.
|
|
|
|
*/
|
|
|
|
public abstract ArrayList<RitualComponent> getComponents();
|
|
|
|
|
2016-01-11 23:07:06 +00:00
|
|
|
public void addRune(ArrayList<RitualComponent> components, int offset1, int y, int offset2, EnumRuneType rune)
|
2015-12-30 20:34:40 +00:00
|
|
|
{
|
|
|
|
components.add(new RitualComponent(new BlockPos(offset1, y, offset2), rune));
|
2016-01-11 23:07:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void addOffsetRunes(ArrayList<RitualComponent> components, int offset1, int offset2, int y, EnumRuneType rune)
|
|
|
|
{
|
|
|
|
addRune(components, offset1, y, offset2, rune);
|
|
|
|
addRune(components, offset2, y, offset1, rune);
|
|
|
|
addRune(components, offset1, y, -offset2, rune);
|
|
|
|
addRune(components, -offset2, y, offset1, rune);
|
|
|
|
addRune(components, -offset1, y, offset2, rune);
|
|
|
|
addRune(components, offset2, y, -offset1, rune);
|
|
|
|
addRune(components, -offset1, y, -offset2, rune);
|
|
|
|
addRune(components, -offset2, y, -offset1, rune);
|
2015-12-30 20:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void addCornerRunes(ArrayList<RitualComponent> components, int offset, int y, EnumRuneType rune)
|
|
|
|
{
|
2016-01-11 23:07:06 +00:00
|
|
|
addRune(components, offset, y, offset, rune);
|
|
|
|
addRune(components, offset, y, -offset, rune);
|
|
|
|
addRune(components, -offset, y, -offset, rune);
|
|
|
|
addRune(components, -offset, y, offset, rune);
|
2015-12-30 20:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void addParallelRunes(ArrayList<RitualComponent> components, int offset, int y, EnumRuneType rune)
|
|
|
|
{
|
2016-01-11 23:07:06 +00:00
|
|
|
addRune(components, offset, y, 0, rune);
|
|
|
|
addRune(components, -offset, y, 0, rune);
|
|
|
|
addRune(components, 0, y, -offset, rune);
|
|
|
|
addRune(components, 0, y, offset, rune);
|
2015-12-30 20:34:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public enum BreakType
|
|
|
|
{
|
2016-01-02 22:56:37 +00:00
|
|
|
REDSTONE,
|
|
|
|
BREAK_MRS,
|
|
|
|
BREAK_STONE,
|
|
|
|
ACTIVATE,
|
|
|
|
DEACTIVATE,
|
|
|
|
EXPLOSION,
|
2015-12-30 20:34:40 +00:00
|
|
|
}
|
2015-12-31 18:50:38 +00:00
|
|
|
|
2016-07-11 23:47:19 +00:00
|
|
|
public double getWillRespectingConfig(World world, BlockPos pos, EnumDemonWillType type, List<EnumDemonWillType> willConfig)
|
|
|
|
{
|
|
|
|
return willConfig.contains(type) ? WorldDemonWillHandler.getCurrentWill(world, pos, type) : 0;
|
|
|
|
}
|
|
|
|
|
2015-12-31 13:01:39 +00:00
|
|
|
public abstract Ritual getNewCopy();
|
2015-10-31 20:47:43 +00:00
|
|
|
}
|