That's one heck of a commit you've got there...
I may have got a bit behind with version control. A lot behind, in fact. Maybe I'll go back and split this sometime - then again, I probably won't. But hey, at least it's here!
This commit is contained in:
@@ -1,17 +1,14 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.event.SpellBindEvent;
|
||||
import electroblob.wizardry.item.IWorkbenchItem;
|
||||
import electroblob.wizardry.item.ItemArcaneTome;
|
||||
import electroblob.wizardry.item.ItemArmourUpgrade;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.registry.WizardryAdvancementTriggers;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
@@ -21,6 +18,9 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class ContainerArcaneWorkbench extends Container {
|
||||
|
||||
/** The arcane workbench tile entity associated with this container. */
|
||||
@@ -42,20 +42,21 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
ItemStack wand = tileentity.getStackInSlot(CENTRE_SLOT);
|
||||
|
||||
for(int i = 0; i < 8; i++){
|
||||
Slot slot = new SlotItemList(tileentity, i, -999, -999, 1, WizardryItems.spell_book);
|
||||
Slot slot = new SlotItemClassList(tileentity, i, -999, -999, 1, ItemSpellBook.class);
|
||||
this.addSlotToContainer(slot);
|
||||
}
|
||||
|
||||
this.addSlotToContainer(new SlotItemList(tileentity, CRYSTAL_SLOT, 8, 88, 64, WizardryItems.magic_crystal))
|
||||
this.addSlotToContainer(new SlotItemList(tileentity, CRYSTAL_SLOT, 13, 101, 64,
|
||||
WizardryItems.magic_crystal, WizardryItems.crystal_shard, WizardryItems.grand_crystal))
|
||||
.setBackgroundName(EMPTY_SLOT_CRYSTAL.toString());
|
||||
|
||||
this.addSlotToContainer(new SlotWorkbenchItem(tileentity, CENTRE_SLOT, 80, 64, this));
|
||||
|
||||
Set<Item> upgrades = new HashSet<Item>(WandHelper.getSpecialUpgrades()); // Can't be done statically.
|
||||
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades()); // Can't be done statically.
|
||||
upgrades.add(WizardryItems.arcane_tome);
|
||||
upgrades.add(WizardryItems.armour_upgrade);
|
||||
|
||||
this.addSlotToContainer(new SlotItemList(tileentity, UPGRADE_SLOT, 8, 106, 1, upgrades.toArray(new Item[0])))
|
||||
this.addSlotToContainer(new SlotItemList(tileentity, UPGRADE_SLOT, 147, 17, 1, upgrades.toArray(new Item[0])))
|
||||
.setBackgroundName(EMPTY_SLOT_UPGRADE.toString());
|
||||
|
||||
for(int x = 0; x < 9; x++){
|
||||
@@ -142,9 +143,9 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
for(int i = 0; i < spellSlots; i++){
|
||||
|
||||
float angle = i * (2 * (float)Math.PI)/spellSlots;
|
||||
int x = centreX + (int)(Math.round(SLOT_RADIUS * MathHelper.sin(angle)));
|
||||
int x = centreX + Math.round(SLOT_RADIUS * MathHelper.sin(angle));
|
||||
// -cos because +y is downwards
|
||||
int y = centreY + (int)(Math.round(SLOT_RADIUS * -MathHelper.cos(angle)));
|
||||
int y = centreY + Math.round(SLOT_RADIUS * -MathHelper.cos(angle));
|
||||
|
||||
showSlot(i, x, y);
|
||||
}
|
||||
@@ -159,17 +160,22 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
}
|
||||
|
||||
// FIXME: It only seems to be syncing correctly when a stack is put into the slot, not taken out.
|
||||
// This is because markDirty isn't called in the tileentity, I think.
|
||||
// This is because markDirty isn't called in the tileentity, I think.
|
||||
this.tileentity.sync();
|
||||
}
|
||||
|
||||
// FIXME: Shift-clicking a stack of special upgrades when in the arcane workbench causes the whole stack to be
|
||||
// transferred when it should be just one (this is a bug with vanilla as well - try putting a stack of
|
||||
// bottles into a brewing stand). I have at least made it so only one gets used now, so it has no impact on
|
||||
// the game.
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(EntityPlayer player, int clickedSlotId){
|
||||
|
||||
ItemStack remainder = ItemStack.EMPTY;
|
||||
Slot slot = (Slot)this.inventorySlots.get(clickedSlotId);
|
||||
Slot slot = this.inventorySlots.get(clickedSlotId);
|
||||
|
||||
if(slot != null && slot.getHasStack()){
|
||||
|
||||
ItemStack stack = slot.getStack(); // The stack that was there originally
|
||||
remainder = stack.copy(); // A copy of that stack
|
||||
|
||||
@@ -189,14 +195,13 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
if(stack.getItem() instanceof ItemSpellBook){
|
||||
minSlotId = 0;
|
||||
maxSlotId = CRYSTAL_SLOT - 1;
|
||||
}else if(stack.getItem() == WizardryItems.magic_crystal){
|
||||
}else if(getSlot(CRYSTAL_SLOT).isItemValid(stack)){
|
||||
minSlotId = CRYSTAL_SLOT;
|
||||
maxSlotId = CRYSTAL_SLOT;
|
||||
}else if(stack.getItem() instanceof IWorkbenchItem){
|
||||
}else if(getSlot(CENTRE_SLOT).isItemValid(stack)){
|
||||
minSlotId = CENTRE_SLOT;
|
||||
maxSlotId = CENTRE_SLOT;
|
||||
}else if(stack.getItem() instanceof ItemArcaneTome || stack.getItem() instanceof ItemArmourUpgrade
|
||||
|| WandHelper.isWandUpgrade(stack.getItem())){
|
||||
}else if(getSlot(UPGRADE_SLOT).isItemValid(stack)){
|
||||
minSlotId = UPGRADE_SLOT;
|
||||
maxSlotId = UPGRADE_SLOT;
|
||||
}else{
|
||||
@@ -257,8 +262,10 @@ public class ContainerArcaneWorkbench extends Container {
|
||||
|
||||
if(((IWorkbenchItem)centre.getStack().getItem())
|
||||
.onApplyButtonPressed(player, centre, this.getSlot(CRYSTAL_SLOT), this.getSlot(UPGRADE_SLOT), spellBooks)){
|
||||
|
||||
// Probably don't need to do anything here, unless we're going to use packets to control the animation
|
||||
|
||||
if(player instanceof EntityPlayerMP){
|
||||
WizardryAdvancementTriggers.arcane_workbench.trigger((EntityPlayerMP)player, centre.getStack());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Simple extension of {@link Slot} which only accepts items from an array of item classes defined in the constructor.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 1.0
|
||||
*/
|
||||
public class SlotItemClassList extends Slot {
|
||||
|
||||
private final Class<? extends Item>[] itemClasses;
|
||||
private int stackLimit;
|
||||
|
||||
@SafeVarargs
|
||||
public SlotItemClassList(IInventory inventory, int index, int x, int y, int stackLimit, Class<? extends Item>... allowedItemClasses){
|
||||
super(inventory, index, x, y);
|
||||
this.itemClasses = allowedItemClasses;
|
||||
this.stackLimit = stackLimit;
|
||||
}
|
||||
|
||||
public int getSlotStackLimit(){
|
||||
return stackLimit;
|
||||
}
|
||||
|
||||
public boolean isItemValid(ItemStack stack){
|
||||
|
||||
for(Class<? extends Item> itemClass : itemClasses){
|
||||
if(itemClass.isAssignableFrom(stack.getItem().getClass())){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -6,18 +6,18 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
/**
|
||||
* Simple extension of {@link Slot} which only accepts items from an array defined in the constructor.
|
||||
* Simple extension of {@link Slot} which only accepts items from an array of items defined in the constructor.
|
||||
*
|
||||
* @author Electroblob
|
||||
* @since Wizardry 1.0
|
||||
*/
|
||||
public class SlotItemList extends Slot {
|
||||
|
||||
private Item[] items;
|
||||
private final Item[] items;
|
||||
private int stackLimit;
|
||||
|
||||
public SlotItemList(IInventory par1iInventory, int index, int x, int y, int stackLimit, Item... allowedItems){
|
||||
super(par1iInventory, index, x, y);
|
||||
public SlotItemList(IInventory inventory, int index, int x, int y, int stackLimit, Item... allowedItems){
|
||||
super(inventory, index, x, y);
|
||||
this.items = allowedItems;
|
||||
this.stackLimit = stackLimit;
|
||||
}
|
||||
@@ -27,11 +27,13 @@ public class SlotItemList extends Slot {
|
||||
}
|
||||
|
||||
public boolean isItemValid(ItemStack stack){
|
||||
for(int i = 0; i < items.length; i++){
|
||||
if(stack.getItem() == this.items[i]){
|
||||
|
||||
for(Item item : items){
|
||||
if(stack.getItem() == item){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public class SlotWorkbenchItem extends Slot {
|
||||
|
||||
@Override
|
||||
public int getSlotStackLimit(){
|
||||
return 1;
|
||||
return 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.item.ItemWand;
|
||||
import electroblob.wizardry.item.ItemWizardArmour;
|
||||
import electroblob.wizardry.item.IManaStoringItem;
|
||||
import electroblob.wizardry.item.IWorkbenchItem;
|
||||
import electroblob.wizardry.item.ItemCrystal;
|
||||
import electroblob.wizardry.item.ItemSpellBook;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryItems;
|
||||
import electroblob.wizardry.util.WandHelper;
|
||||
@@ -26,16 +25,15 @@ import net.minecraftforge.common.util.Constants.NBT;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class TileEntityArcaneWorkbench extends TileEntity implements IInventory, ITickable {
|
||||
|
||||
/** The inventory of the arcane workbench. */
|
||||
private NonNullList<ItemStack> inventory;
|
||||
/** Controls the rotation of the rune. */
|
||||
/** Controls the rotating rune and floating wand animations. */
|
||||
public float timer = 0;
|
||||
/** Controls the change of yOffset. */
|
||||
public int yTimer = 0;
|
||||
/** Controls the height of the wand. */
|
||||
public int yOffset = 300;
|
||||
|
||||
public TileEntityArcaneWorkbench(){
|
||||
inventory = NonNullList.withSize(ContainerArcaneWorkbench.UPGRADE_SLOT + 1, ItemStack.EMPTY);
|
||||
@@ -44,8 +42,6 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
@Override
|
||||
public void onLoad(){
|
||||
timer = 0;
|
||||
yTimer = 0;
|
||||
yOffset = 300;
|
||||
}
|
||||
|
||||
/** Called to manually sync the tile entity with clients. */
|
||||
@@ -56,29 +52,18 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
ItemStack itemstack = this.getStackInSlot(ContainerArcaneWorkbench.CENTRE_SLOT);
|
||||
ItemStack stack = this.getStackInSlot(ContainerArcaneWorkbench.CENTRE_SLOT);
|
||||
|
||||
// Decrements wand damage (increases mana) every 1.5 seconds if it has a condenser upgrade
|
||||
if(itemstack.getItem() instanceof ItemWand && !this.world.isRemote && itemstack.isItemDamaged()
|
||||
&& this.world.getWorldTime() % electroblob.wizardry.constants.Constants.CONDENSER_TICK_INTERVAL == 0){
|
||||
if(stack.getItem() instanceof IManaStoringItem && !this.world.isRemote && !((IManaStoringItem)stack.getItem()).isManaFull(stack)
|
||||
&& this.world.getTotalWorldTime() % electroblob.wizardry.constants.Constants.CONDENSER_TICK_INTERVAL == 0){
|
||||
// If the upgrade level is 0, this does nothing anyway.
|
||||
itemstack.setItemDamage(
|
||||
itemstack.getItemDamage() - WandHelper.getUpgradeLevel(itemstack, WizardryItems.condenser_upgrade));
|
||||
((IManaStoringItem)stack.getItem()).rechargeMana(stack, WandHelper.getUpgradeLevel(stack, WizardryItems.condenser_upgrade));
|
||||
}
|
||||
|
||||
// The server doesn't care what these are, and there's no need for them to be synced or saved.
|
||||
if(this.world.isRemote){
|
||||
if(timer < 359){
|
||||
timer++;
|
||||
}else{
|
||||
timer = 0;
|
||||
}
|
||||
if(yOffset > 0){
|
||||
yTimer--;
|
||||
}else{
|
||||
yTimer++;
|
||||
}
|
||||
yOffset += yTimer;
|
||||
timer++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,17 +155,16 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
if(itemstack == ItemStack.EMPTY) return true;
|
||||
|
||||
if(slotNumber >= 0 && slotNumber < ContainerArcaneWorkbench.CRYSTAL_SLOT){
|
||||
return itemstack.getItem() == WizardryItems.spell_book;
|
||||
return itemstack.getItem() instanceof ItemSpellBook;
|
||||
|
||||
}else if(slotNumber == ContainerArcaneWorkbench.CRYSTAL_SLOT){
|
||||
return itemstack.getItem() == WizardryItems.magic_crystal;
|
||||
return itemstack.getItem() instanceof ItemCrystal;
|
||||
|
||||
}else if(slotNumber == ContainerArcaneWorkbench.CENTRE_SLOT){
|
||||
return (itemstack.getItem() instanceof ItemWand || itemstack.getItem() instanceof ItemWizardArmour
|
||||
|| itemstack.getItem() == WizardryItems.blank_scroll);
|
||||
return itemstack.getItem() instanceof IWorkbenchItem;
|
||||
|
||||
}else if(slotNumber == ContainerArcaneWorkbench.UPGRADE_SLOT){
|
||||
Set<Item> upgrades = new HashSet<Item>(WandHelper.getSpecialUpgrades());
|
||||
Set<Item> upgrades = new HashSet<>(WandHelper.getSpecialUpgrades());
|
||||
upgrades.add(WizardryItems.arcane_tome);
|
||||
upgrades.add(WizardryItems.armour_upgrade);
|
||||
return upgrades.contains(itemstack.getItem());
|
||||
@@ -197,16 +181,12 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
|
||||
NBTTagList tagList = tagCompound.getTagList("Inventory", NBT.TAG_COMPOUND);
|
||||
for(int i = 0; i < tagList.tagCount(); i++){
|
||||
NBTTagCompound tag = (NBTTagCompound)tagList.getCompoundTagAt(i);
|
||||
NBTTagCompound tag = tagList.getCompoundTagAt(i);
|
||||
byte slot = tag.getByte("Slot");
|
||||
if(slot >= 0 && slot < getSizeInventory()){
|
||||
setInventorySlotContents(slot, new ItemStack(tag));
|
||||
}
|
||||
}
|
||||
|
||||
// timer = tagCompound.getFloat("timer");
|
||||
// yTimer = tagCompound.getInteger("yTimer");
|
||||
// yOffset = tagCompound.getInteger("yOffset");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -226,10 +206,6 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
}
|
||||
|
||||
tagCompound.setTag("Inventory", itemList);
|
||||
// tagCompound.setFloat("timer", timer);
|
||||
// tagCompound.setInteger("yTimer", yTimer);
|
||||
// tagCompound.setInteger("yOffset", yOffset);
|
||||
|
||||
return tagCompound;
|
||||
}
|
||||
|
||||
@@ -249,6 +225,7 @@ public class TileEntityArcaneWorkbench extends TileEntity implements IInventory,
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox(){
|
||||
AxisAlignedBB bb = INFINITE_EXTENT_AABB;
|
||||
Block type = getBlockType();
|
||||
|
||||
@@ -19,6 +19,11 @@ public class TileEntityMagicLight extends TileEntityTimer {
|
||||
randomiser2[0] = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderInPass(int pass){
|
||||
return pass == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
|
||||
@@ -1,43 +1,26 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.UUID;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ITickable;
|
||||
|
||||
public class TileEntityPlayerSave extends TileEntity implements ITickable {
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.UUID;
|
||||
|
||||
/** The entity that created this construct */
|
||||
private WeakReference<EntityLivingBase> caster;
|
||||
public class TileEntityPlayerSave extends TileEntity {
|
||||
|
||||
/**
|
||||
* The UUID of the caster. Note that this is only for loading purposes; during normal updates the actual entity
|
||||
* instance is stored (so that getEntityByUUID is not called constantly), so this will not always be synced (this is
|
||||
* why it is private).
|
||||
*/
|
||||
/** The UUID of the caster. As of Wizardry 4.2, this <b>is</b> synced, and rather than storing the caster
|
||||
* instance via a weak reference, it is fetched from the UUID each time it is needed in
|
||||
* {@link TileEntityPlayerSave#getCaster()}. */
|
||||
private UUID casterUUID;
|
||||
|
||||
public TileEntityPlayerSave(){}
|
||||
|
||||
public TileEntityPlayerSave(EntityLivingBase caster){
|
||||
this.caster = new WeakReference<EntityLivingBase>(caster);
|
||||
}
|
||||
|
||||
public TileEntityPlayerSave(){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
if(this.getCaster() == null && this.casterUUID != null){
|
||||
Entity entity = WizardryUtilities.getEntityByUUID(world, casterUUID);
|
||||
if(entity instanceof EntityLivingBase){
|
||||
this.caster = new WeakReference<EntityLivingBase>((EntityLivingBase)entity);
|
||||
}
|
||||
}
|
||||
this.casterUUID = caster.getUniqueID();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,7 +35,7 @@ public class TileEntityPlayerSave extends TileEntity implements ITickable {
|
||||
super.writeToNBT(tagCompound);
|
||||
|
||||
if(this.getCaster() != null){
|
||||
tagCompound.setUniqueId("casterUUID", this.getCaster().getUniqueID());
|
||||
tagCompound.setUniqueId("casterUUID", casterUUID);
|
||||
}
|
||||
|
||||
return tagCompound;
|
||||
@@ -63,12 +46,21 @@ public class TileEntityPlayerSave extends TileEntity implements ITickable {
|
||||
* may no longer exist are: entity died or was deleted, mob despawned, player logged out, entity teleported to
|
||||
* another dimension, or this construct simply had no caster in the first place.
|
||||
*/
|
||||
@Nullable
|
||||
public EntityLivingBase getCaster(){
|
||||
return caster == null ? null : caster.get();
|
||||
|
||||
Entity entity = WizardryUtilities.getEntityByUUID(world, casterUUID);
|
||||
|
||||
if(entity != null && !(entity instanceof EntityLivingBase)){ // Should never happen
|
||||
Wizardry.logger.warn("{} has a non-living owner!", this);
|
||||
entity = null;
|
||||
}
|
||||
|
||||
return (EntityLivingBase)entity;
|
||||
}
|
||||
|
||||
public void setCaster(EntityLivingBase caster){
|
||||
this.caster = new WeakReference<EntityLivingBase>(caster);
|
||||
public void setCaster(@Nullable EntityLivingBase caster){
|
||||
this.casterUUID = caster == null ? null : caster.getUniqueID();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.block.BlockThorns;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SPacketUpdateTileEntity;
|
||||
import net.minecraft.util.ITickable;
|
||||
|
||||
public class TileEntityPlayerSaveTimed extends TileEntityPlayerSave implements ITickable {
|
||||
|
||||
public int timer = 0;
|
||||
public int maxTimer;
|
||||
|
||||
public TileEntityPlayerSaveTimed(int maxTimer){
|
||||
this.maxTimer = maxTimer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
timer++;
|
||||
|
||||
if(timer > maxTimer && !this.world.isRemote){
|
||||
this.world.destroyBlock(pos, false);
|
||||
}
|
||||
|
||||
if(timer % 2 == 0 && world.getBlockState(pos).getValue(BlockThorns.AGE) < BlockThorns.GROWTH_STAGES - 1){
|
||||
world.setBlockState(pos, world.getBlockState(pos).withProperty(BlockThorns.AGE, world.getBlockState(pos).getValue(BlockThorns.AGE) + 1), 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void setLifetime(int lifetime){
|
||||
this.maxTimer = lifetime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound tagCompound){
|
||||
super.readFromNBT(tagCompound);
|
||||
timer = tagCompound.getInteger("timer");
|
||||
maxTimer = tagCompound.getInteger("maxTimer");
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound tagCompound){
|
||||
super.writeToNBT(tagCompound);
|
||||
tagCompound.setInteger("timer", timer);
|
||||
tagCompound.setInteger("maxTimer", maxTimer);
|
||||
return tagCompound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final NBTTagCompound getUpdateTag(){
|
||||
return this.writeToNBT(new NBTTagCompound());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SPacketUpdateTileEntity getUpdatePacket(){
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
writeToNBT(tag);
|
||||
return new SPacketUpdateTileEntity(pos, 1, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt){
|
||||
NBTTagCompound tag = pkt.getNbtCompound();
|
||||
readFromNBT(tag);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
package electroblob.wizardry.tileentity;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
import electroblob.wizardry.block.BlockPedestal;
|
||||
import electroblob.wizardry.entity.living.EntityEvilWizard;
|
||||
import electroblob.wizardry.entity.living.EntityWizard;
|
||||
import electroblob.wizardry.packet.PacketConquerShrine;
|
||||
import electroblob.wizardry.packet.WizardryPacketHandler;
|
||||
import electroblob.wizardry.potion.PotionContainment;
|
||||
import electroblob.wizardry.registry.WizardryBlocks;
|
||||
import electroblob.wizardry.registry.WizardryPotions;
|
||||
import electroblob.wizardry.registry.WizardrySounds;
|
||||
import electroblob.wizardry.spell.ArcaneLock;
|
||||
import electroblob.wizardry.util.NBTExtras;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.potion.PotionEffect;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.common.util.Constants;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TileEntityShrineCore extends TileEntity implements ITickable {
|
||||
|
||||
private static final double ACTIVATION_RADIUS = 5;
|
||||
|
||||
private boolean activated = false;
|
||||
private AxisAlignedBB containmentField;
|
||||
private final UUID[] linkedWizards = new UUID[3];
|
||||
private TileEntity linkedContainer;
|
||||
private BlockPos linkedContainerPos; // Temporary stores the container position read from NBT until the world is set
|
||||
|
||||
@Override
|
||||
public void setPos(BlockPos pos){
|
||||
super.setPos(pos);
|
||||
initContainmentField(pos);
|
||||
}
|
||||
|
||||
private void initContainmentField(BlockPos pos){
|
||||
float r = PotionContainment.getContainmentDistance(0);
|
||||
this.containmentField = new AxisAlignedBB(-r, -r, -r, r, r, r).offset(WizardryUtilities.getCentre(pos));
|
||||
}
|
||||
|
||||
public void linkContainer(TileEntity container){
|
||||
this.linkedContainer = container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
if(this.linkedContainer == null && this.linkedContainerPos != null){
|
||||
this.linkContainer(world.getTileEntity(this.linkedContainerPos));
|
||||
}
|
||||
|
||||
double x = this.pos.getX() + 0.5;
|
||||
double y = this.pos.getY() + 0.5;
|
||||
double z = this.pos.getZ() + 0.5;
|
||||
|
||||
if(!activated && world.getClosestPlayer(x, y, z, ACTIVATION_RADIUS, false) != null){
|
||||
|
||||
this.activated = true;
|
||||
|
||||
if(world.isRemote){
|
||||
ParticleBuilder.create(Type.SPHERE).pos(x, y + 1, z).clr(0xf06495).scale(5).time(12).spawn(world);
|
||||
}
|
||||
|
||||
world.playSound(x, y, z,
|
||||
WizardrySounds.BLOCK_PEDESTAL_ACTIVATE, SoundCategory.BLOCKS, 1.5f, 1, false);
|
||||
|
||||
if(!world.isRemote){
|
||||
|
||||
EntityEvilWizard[] wizards = new EntityEvilWizard[linkedWizards.length];
|
||||
|
||||
for(int i = 0; i < linkedWizards.length; i++){
|
||||
|
||||
EntityEvilWizard wizard = new EntityEvilWizard(world);
|
||||
|
||||
float angle = world.rand.nextFloat() * 2 * (float)Math.PI;
|
||||
double x1 = this.pos.getX() + 0.5 + 5 * MathHelper.sin(angle);
|
||||
double z1 = this.pos.getZ() + 0.5 + 5 * MathHelper.cos(angle);
|
||||
Integer y1 = WizardryUtilities.getNearestFloor(world, new BlockPos(x1, this.pos.getY(), z1), 8);
|
||||
if(y1 == null){
|
||||
// Fallback to the position of the shrine core if it failed to find a position (unlikely)
|
||||
x1 = this.pos.getX() + 1; // Offset it so the wizard isn't inside the block
|
||||
y1 = this.pos.getY();
|
||||
z1 = this.pos.getZ();
|
||||
}
|
||||
|
||||
wizard.setLocationAndAngles(x1, y1 + 0.5, z1, 0, 0);
|
||||
wizard.setElement(world.getBlockState(pos).getValue(BlockPedestal.ELEMENT));
|
||||
wizard.onInitialSpawn(world.getDifficultyForLocation(pos), null);
|
||||
wizard.hasStructure = true;
|
||||
|
||||
world.spawnEntity(wizard);
|
||||
wizards[i] = wizard;
|
||||
linkedWizards[i] = wizard.getUniqueID();
|
||||
}
|
||||
|
||||
for(EntityEvilWizard wizard : wizards) wizard.groupUUIDs.addAll(Arrays.asList(linkedWizards));
|
||||
}
|
||||
|
||||
containNearbyTargets();
|
||||
}
|
||||
|
||||
if(activated && world.getTotalWorldTime() % 20L == 0) containNearbyTargets();
|
||||
|
||||
if(activated && areWizardsDead() && !world.isRemote){
|
||||
conquer();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean areWizardsDead(){
|
||||
|
||||
for(UUID uuid : linkedWizards){
|
||||
Entity entity = WizardryUtilities.getEntityByUUID(world, uuid);
|
||||
if(entity instanceof EntityEvilWizard && entity.isEntityAlive()) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void conquer(){
|
||||
|
||||
double x = this.pos.getX() + 0.5;
|
||||
double y = this.pos.getY() + 0.5;
|
||||
double z = this.pos.getZ() + 0.5;
|
||||
|
||||
if(!world.isRemote){
|
||||
WizardryPacketHandler.net.sendToAllAround(new PacketConquerShrine.Message(this.pos),
|
||||
new NetworkRegistry.TargetPoint(this.world.provider.getDimension(), x, y, z, 64));
|
||||
}
|
||||
|
||||
world.setBlockState(pos, WizardryBlocks.runestone_pedestal.getDefaultState()
|
||||
.withProperty(BlockPedestal.ELEMENT, world.getBlockState(pos).getValue(BlockPedestal.ELEMENT)));
|
||||
|
||||
world.markTileEntityForRemoval(this);
|
||||
|
||||
if(!world.isRemote){
|
||||
if(linkedContainer != null) NBTExtras.removeUniqueId(linkedContainer.getTileData(), ArcaneLock.NBT_KEY);
|
||||
}else{
|
||||
TileEntity tileEntity = world.getTileEntity(this.pos.up());
|
||||
if(tileEntity != null){ // Bit of a dirty fix but it's only visual, so meh
|
||||
NBTExtras.removeUniqueId(tileEntity.getTileData(), ArcaneLock.NBT_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
world.playSound(x, y, z, WizardrySounds.BLOCK_PEDESTAL_CONQUER, SoundCategory.BLOCKS, 1, 1, false);
|
||||
|
||||
if(world.isRemote){
|
||||
ParticleBuilder.create(Type.SPHERE).scale(5).pos(x, y + 1, z).clr(0xf06495).time(12).spawn(world);
|
||||
for(int i=0; i<5; i++){
|
||||
float brightness = 0.8f + world.rand.nextFloat() * 0.2f;
|
||||
ParticleBuilder.create(Type.SPARKLE, world.rand, x, y + 1, z, 1, true)
|
||||
.clr(1, brightness, brightness).spawn(world);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void containNearbyTargets(){
|
||||
|
||||
List<EntityLivingBase> entities = world.getEntitiesWithinAABB(EntityLivingBase.class, containmentField,
|
||||
e -> e instanceof EntityPlayer || e instanceof EntityWizard || e instanceof EntityEvilWizard);
|
||||
|
||||
for(EntityLivingBase entity : entities){
|
||||
entity.addPotionEffect(new PotionEffect(WizardryPotions.containment, 219));
|
||||
entity.getEntityData().setTag(PotionContainment.ENTITY_TAG, NBTUtil.createPosTag(this.pos));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound compound){
|
||||
|
||||
compound.setBoolean("activated", this.activated);
|
||||
if(linkedContainer != null) compound.setTag("linkedContainerPos", NBTUtil.createPosTag(linkedContainer.getPos()));
|
||||
|
||||
NBTTagList tagList = new NBTTagList();
|
||||
for(UUID uuid : linkedWizards){
|
||||
if(uuid != null) tagList.appendTag(NBTUtil.createUUIDTag(uuid));
|
||||
}
|
||||
compound.setTag("wizards", tagList);
|
||||
|
||||
return super.writeToNBT(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound compound){
|
||||
|
||||
this.activated = compound.getBoolean("activated");
|
||||
this.linkedContainerPos = NBTUtil.getPosFromTag(compound.getCompoundTag("linkedContainerPos"));
|
||||
|
||||
NBTTagList tagList = compound.getTagList("wizards", Constants.NBT.TAG_COMPOUND);
|
||||
int i = 0;
|
||||
for(NBTBase tag : tagList){
|
||||
if(tag instanceof NBTTagCompound) linkedWizards[i++] = NBTUtil.getUUIDFromTag((NBTTagCompound)tag);
|
||||
else Wizardry.logger.warn("Unexpected tag type in NBT tag list of compound tags!");
|
||||
}
|
||||
|
||||
super.readFromNBT(compound);
|
||||
// Must be after super
|
||||
initContainmentField(this.pos);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public class TileEntityStatue extends TileEntity implements ITickable {
|
||||
|
||||
public EntityLiving creature;
|
||||
private NBTTagCompound entityCompound;
|
||||
private String entityName;
|
||||
private ResourceLocation entityName;
|
||||
private float entityYawHead;
|
||||
private float entityYawOffset;
|
||||
public boolean isIce;
|
||||
@@ -95,8 +95,7 @@ public class TileEntityStatue extends TileEntity implements ITickable {
|
||||
|
||||
// System.out.println(entityName);
|
||||
if(this.creature == null && entityName != null){
|
||||
this.creature = (EntityLiving)EntityList.createEntityByIDFromName(new ResourceLocation(this.entityName),
|
||||
this.world);
|
||||
this.creature = (EntityLiving)EntityList.createEntityByIDFromName(this.entityName, this.world);
|
||||
if(this.creature != null){
|
||||
this.creature.readFromNBT(entityCompound);
|
||||
this.creature.rotationYawHead = this.entityYawHead;
|
||||
@@ -133,7 +132,7 @@ public class TileEntityStatue extends TileEntity implements ITickable {
|
||||
position = tagCompound.getInteger("position");
|
||||
parts = tagCompound.getInteger("parts");
|
||||
entityCompound = tagCompound.getCompoundTag("entity");
|
||||
entityName = tagCompound.getString("entityName");
|
||||
entityName = new ResourceLocation(tagCompound.getString("entityName"));
|
||||
timer = tagCompound.getInteger("timer");
|
||||
lifetime = tagCompound.getInteger("lifetime");
|
||||
isIce = tagCompound.getBoolean("isIce");
|
||||
@@ -149,7 +148,7 @@ public class TileEntityStatue extends TileEntity implements ITickable {
|
||||
entityCompound = new NBTTagCompound();
|
||||
if(creature != null){
|
||||
creature.writeToNBT(entityCompound);
|
||||
tagCompound.setString("entityName", EntityList.getEntityString(creature));
|
||||
tagCompound.setString("entityName", EntityList.getKey(creature).toString());
|
||||
tagCompound.setFloat("entityYawHead", creature.rotationYawHead);
|
||||
tagCompound.setFloat("entityYawOffset", creature.renderYawOffset);
|
||||
}
|
||||
|
||||
@@ -22,11 +22,10 @@ public class TileEntityTimer extends TileEntity implements ITickable {
|
||||
|
||||
@Override
|
||||
public void update(){
|
||||
|
||||
timer++;
|
||||
if(!this.world.isRemote){
|
||||
// System.out.println("Timer: " + timer + "/" + maxTimer);
|
||||
}
|
||||
if(timer > maxTimer && !this.world.isRemote){// && this.world.getBlockId(xCoord, yCoord, zCoord) ==
|
||||
|
||||
if(maxTimer > 0 && timer > maxTimer && !this.world.isRemote){// && this.world.getBlockId(xCoord, yCoord, zCoord) ==
|
||||
// Wizardry.magicLight.blockID){
|
||||
if(this.getBlockType() instanceof BlockVanishingCobweb){
|
||||
// destroyBlock breaks the block as if broken by a player, with sound and particles.
|
||||
|
||||
Reference in New Issue
Block a user