Yagoki Posted April 14, 2016 Posted April 14, 2016 I have created a new tile entity which is supposed to detect entities dying around it. This functionality works fine when the tile has just been created, however when the world gets re-loaded the tile does not get created on the server stopping it from working. My assumption is that it is down to my attempted use of block states to define which have tile entities. If anyone has suggestions for fixing this it would be much appreciated Github: TileEntity package com.yagoki.mtech.block.tileentity import net.minecraft.entity.boss.{EntityDragon, EntityWither} import net.minecraft.entity.{EntityCreature, EntityLivingBase} import net.minecraft.entity.monster.EntityMob import net.minecraft.entity.passive.{EntityTameable, EntityVillager} import net.minecraft.entity.player.EntityPlayer import net.minecraft.nbt.NBTTagCompound import net.minecraft.util.ITickable import net.minecraft.util.math.AxisAlignedBB import scala.collection.JavaConversions._ import com.yagoki.mtech.util.MathUtil._ /** * Created by Ben on 06/04/2016. */ class TileEntityObelisk extends SimpleTileEntity with ITickable { private var _power: Int = 0 def power = _power def power_=(v: Int) = { _power = v // TODO: remove debug println(power) if (!this.getWorld.isRemote) this.getWorld.scheduleUpdate(this.getPos, this.getBlockType, 1) } override def update(): Unit = { val ents: List[EntityLivingBase] = this.getWorld.getEntitiesWithinAABB(classOf[EntityLivingBase], new AxisAlignedBB(this.getPos-(4, 2, 4), this.getPos+(4, 2, 4)).addCoord(.5, .5, .5)).toList ents foreach { e => if (!e.isEntityAlive) power += lifeValForEntity(e) } } def lifeValForEntity(e: EntityLivingBase): Int = e match { case _: EntityPlayer => 0 case _: EntityDragon => 160 case _: EntityWither => 80 case _: EntityTameable => 16 case _: EntityVillager => 8 case _: EntityMob => 2 case _: EntityCreature => 4 case _ => 1 } override def writeToNBT(compound: NBTTagCompound): Unit = { super.writeToNBT(compound) compound.setInteger("power", power) } override def readFromNBT(compound: NBTTagCompound): Unit = { super.readFromNBT(compound) power = compound.getInteger("power") } } Github: Block package com.yagoki.mtech.block import com.yagoki.mtech.block.ModBlocks.SimpleTile import net.minecraft.block.Block import net.minecraft.block.state.{BlockStateContainer, IBlockState} import net.minecraft.init.Blocks import net.minecraft.tileentity.TileEntity import net.minecraft.util.math.{AxisAlignedBB, BlockPos} import net.minecraft.world.{IBlockAccess, World} /** * Created by Ben on 07/04/2016. */ trait BlockObelisk extends SimpleTile { override def isOpaqueCube(state: IBlockState): Boolean = false override def isFullCube(state: IBlockState): Boolean = false def bbFromState(state: IBlockState): AxisAlignedBB = getMetaFromState(state) match { case 0 => new AxisAlignedBB(1/16D, 0, 1/16D, 15/16D, 1, 15/16D) case 1 => new AxisAlignedBB(2/16D, 0, 2/16D, 14/16D, 1, 14/16D) case 2 => new AxisAlignedBB(3/16D, 0, 3/16D, 13/16D, 1, 13/16D) } override def getBoundingBox(state: IBlockState, source: IBlockAccess, pos: BlockPos): AxisAlignedBB = bbFromState(state) override def getMetaFromState(state: IBlockState): Int = state.getValue(ModBlocks.TIER) override def getStateFromMeta(meta: Int): IBlockState = this.getDefaultState.withProperty[integer, Integer](ModBlocks.TIER, meta) override def createBlockState(): BlockStateContainer = new BlockStateContainer(this, ModBlocks.TIER) override def onNeighborBlockChange(world: World, pos: BlockPos, state: IBlockState, neighborBlock: Block): Unit = { val zeroPoint: Int = -state.getValue(ModBlocks.TIER) val obeliskBlocks = (zeroPoint to (zeroPoint+2)).map(i => world.getBlockState(pos.add(0, i, 0))) if (!obeliskBlocks.forall(s => s.getBlock == Blocks.sandstone || s.getBlock == ModBlocks("blockObelisk").get)) world.setBlockState(pos, Blocks.sandstone.getDefaultState) } override def createTileEntity(world: World, state: IBlockState): TileEntity = this.createNewTileEntity(world, getMetaFromState(state)) override def createNewTileEntity(world: World, i: Int): TileEntity = i match { case 0 => super.createNewTileEntity(world, i) } } all other files are on my github so look as you need Quote github
BusyBeever Posted April 14, 2016 Posted April 14, 2016 Why are u coding in scala and not java? Anyway my guess would be that you arnet registering the tile entity, thats why it wont get reloaded when loading from disk. show ur registration of the te? Quote
Yagoki Posted April 14, 2016 Author Posted April 14, 2016 Tile entity is registered in the ModBlocks object. this is not the issue. I can see assignment happening to the the variable power on the client side but no such luck on the server Before world restart [21:41:50] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: tile for 0 [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: tile for 0 [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:44:33] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:44:33] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 0 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 4 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 8 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 4 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 8 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 12 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 12 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 16 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 16 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 20 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 20 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 24 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 24 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 28 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 28 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 32 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 32 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 36 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 36 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 40 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 40 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 44 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 44 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 48 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 48 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 52 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 52 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 56 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 56 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 60 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 60 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 64 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 64 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 68 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 68 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 72 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 72 [21:44:43] [server thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 76 [21:44:43] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 76 [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: tile for 0 [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=0] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=1] [21:42:02] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: mtech:blockObelisk[tier=2] [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 4 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 8 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 12 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 16 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 20 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 24 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 28 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 32 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 36 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 40 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 44 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 48 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 52 [21:42:09] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 56 [21:42:10] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 60 [21:42:10] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 64 [21:42:10] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 68 [21:42:10] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 72 [21:42:10] [Client thread/INFO] [sTDOUT]: [scala.Console$:println:148]: 76 you can see that when the world restarts there are no longer updates getting posted from the server thread as for my use of scala, it's nicer to code in (in my opinion) and has a lot of useful tools, a better interface system (see traits), implicit functions, among other things. mostly just a personal preference Quote github
Yagoki Posted April 14, 2016 Author Posted April 14, 2016 thanks for the advice on proper practices, was just going by what I could see in vanilla implementations. Still doesn't fix the issue though... Quote github
Yagoki Posted April 14, 2016 Author Posted April 14, 2016 update has been pushed. break-point triggered on both ends if the tile is placed, but only on client if through world load Quote github
Yagoki Posted April 15, 2016 Author Posted April 15, 2016 the tile are not getting saved. The client side tile is created at world load and I can force the tile to be loaded on the server by calling world.getTileEntity on the server side from an item use or some such still no idea what is causing this. receiving no errors stating that the tile entity is missing a mapping so it's not an issue with the registering from what I can tell. The methods createTileEntity and hasTileEntity are not called from the server following world load until world.getTileEntity is called. seems to be true for all my tile entities, but somehow never noticed it before. Possible forge problem? Quote github
Yagoki Posted April 15, 2016 Author Posted April 15, 2016 can confirm. even tried extending TileEntity explicitly in the Obelisk TE class to be sure but no change. Reveal hidden contents Quote github
Yagoki Posted April 15, 2016 Author Posted April 15, 2016 Found the issue. was down to a NPE that i wasn't noticing as it wasn't killing the system, kept assuming the stack-trace was part of the authentication exception which always happens when first launched (caused by ). this was causing the readFromNBT to fail every time from the server. fixed it by amending this statement with a check for hasWorldObj in the setter for power if (this.hasWorldObj && !this.getWorld.isRemote) this.getWorld.scheduleUpdate(this.getPos, this.getBlockType, 1) it's always the simple things that seem to catch me out the most... Quote github
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.