mirror of
https://github.com/GTNewHorizons/ForgeRelocation.git
synced 2026-11-13 00:47:36 +00:00
Fixed movement desc packets being discarded
- Added callback hook for movement events
This commit is contained in:
1 parent
d6731ef60b
commit
e5d3aa0561
11 files changed
+334
-108
No files matched your search
@@ -27,14 +27,14 @@ public interface IFrame
|
||||
* @param x The x coordinate.
|
||||
* @param y The y coordinate.
|
||||
* @param z The z coordinate.
|
||||
* @param side The side of the block, as a ForgeDirection
|
||||
* @return True if the side can stick on to another block.
|
||||
* @param side The side of this block, as a ForgeDirection
|
||||
* @return True if the side can grab another block.
|
||||
*/
|
||||
boolean stickOut(World w, int x, int y, int z, int side);
|
||||
|
||||
/**
|
||||
* Used to check if this frame block can be grabbed on the
|
||||
* given side from another frame.
|
||||
* given side by another frame.
|
||||
*
|
||||
* Convention requires that this method yields the same result
|
||||
* on both client and server.
|
||||
@@ -43,8 +43,8 @@ public interface IFrame
|
||||
* @param x The x coordinate.
|
||||
* @param y The y coordinate.
|
||||
* @param z The z coordinate.
|
||||
* @param side The side of the block, as a ForgeDirection
|
||||
* @return True if the side can be stuck onto by a frame block.
|
||||
* @param side The side of this block, as a ForgeDirection
|
||||
* @return True if the side can be grabbed by a frame block.
|
||||
*/
|
||||
boolean stickIn(World w, int x, int y, int z, int side);
|
||||
}
|
||||
@@ -125,6 +125,7 @@ class TileMotor extends InstancedBlockTile with TTileOrient with IFrame
|
||||
r.push()
|
||||
r.setWorld(world)
|
||||
r.setDirection(getMoveDir)
|
||||
r.setSpeed(1/16D)
|
||||
r.addBlocks(blocks)
|
||||
r.execute()
|
||||
r.pop()
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2015.
|
||||
* Created by MrTJP.
|
||||
* All rights reserved.
|
||||
*/
|
||||
package mrtjp.relocation.api;
|
||||
|
||||
/**
|
||||
* Interface that can be used by things that wish to receive events for
|
||||
* a move that they executed. This interface is passed into the {@link Relocator}
|
||||
* during movement construction.
|
||||
*
|
||||
* For example, a motor may wish to know when the movement completes. In which case,
|
||||
* the motor tile itself would implement this interface and pass itself into the
|
||||
* Relocator.
|
||||
*
|
||||
* These methods are only called server-side. Clients will not receive any of
|
||||
* these events, as this class is registered during the execution of a move, which
|
||||
* can only happen server-side.
|
||||
*
|
||||
*/
|
||||
public interface IMovementCallback
|
||||
{
|
||||
/**
|
||||
* Called once move starts. The descriptor contains methods that
|
||||
* describe the state of the current movement that this callback
|
||||
* was registered to.
|
||||
*
|
||||
* This descriptor is properly weak-referenced, keep or discard it
|
||||
* at your own leasure.
|
||||
*
|
||||
* @param desc The movement descriptor for the current move.
|
||||
*/
|
||||
void setDescriptor(IMovementDescriptor desc);
|
||||
|
||||
/**
|
||||
* Called when the movement starts, when the animation starts playing.
|
||||
*/
|
||||
void onMovementStarted();
|
||||
|
||||
/**
|
||||
* Called when the movement completes, and all blocks have moved over.
|
||||
*/
|
||||
void onMovementFinished();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2015.
|
||||
* Created by MrTJP.
|
||||
* All rights reserved.
|
||||
*/
|
||||
package mrtjp.relocation.api;
|
||||
|
||||
/**
|
||||
* This is the interface of the object that is given to an {@link IMovementCallback} so
|
||||
* it may access movement information whenever it needs to during the movement.
|
||||
*
|
||||
* Results of all methods is only valid during movement, undefined otherwise. Use
|
||||
* isMoving() to check before using any values from this.
|
||||
*/
|
||||
public interface IMovementDescriptor
|
||||
{
|
||||
/**
|
||||
* @return True if the structure is moving.
|
||||
*/
|
||||
boolean isMoving();
|
||||
|
||||
/**
|
||||
* @return The progress of the movement scaled between 0 and 1.
|
||||
*/
|
||||
double getProgress();
|
||||
|
||||
/**
|
||||
* @return The size of the moving structure, zero if it is no longer moving.
|
||||
*/
|
||||
int getSize();
|
||||
}
|
||||
@@ -16,10 +16,8 @@ import java.util.Set;
|
||||
public abstract class Relocator
|
||||
{
|
||||
/**
|
||||
* Pushes the instance of the Relocator onto the stack.
|
||||
* Pushes an instance of the Relocator onto the stack.
|
||||
* Must be called before using any methods.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is already on the stack.
|
||||
*/
|
||||
public abstract void push();
|
||||
|
||||
@@ -27,7 +25,7 @@ public abstract class Relocator
|
||||
* Pops the instance of the Relocator off the stack.
|
||||
* Must be called after you are done using this.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is not on the stack.
|
||||
* @throws IllegalStateException If there is no Relocator on the stack.
|
||||
*/
|
||||
public abstract void pop();
|
||||
|
||||
@@ -35,6 +33,7 @@ public abstract class Relocator
|
||||
* Sets the world for the movement.
|
||||
*
|
||||
* @param world The world in which the movement will occure.
|
||||
* @throws IllegalStateException If the world was already set.
|
||||
*/
|
||||
public abstract void setWorld(World world);
|
||||
|
||||
@@ -45,9 +44,32 @@ public abstract class Relocator
|
||||
* @param dir The direction to move the blocks.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is not on the stack.
|
||||
* @throws IllegalStateException If the direction was already set.
|
||||
*/
|
||||
public abstract void setDirection(int dir);
|
||||
|
||||
/**
|
||||
* Sets the speed of the movement. Must be greater than 0 and
|
||||
* less than 1.
|
||||
*
|
||||
* @param speed The speed of the movement, in meters/tick.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is not on the stack.
|
||||
* @throws IllegalStateException If the speed was already set.
|
||||
*/
|
||||
public abstract void setSpeed(double speed);
|
||||
|
||||
/**
|
||||
* Sets a callback object that receives events during the actual move.
|
||||
* This is optional and is not required to be set.
|
||||
*
|
||||
* @param callback The callback to register for this move.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is not on the stack.
|
||||
* @throws IllegalStateException If a callback was already set.
|
||||
*/
|
||||
public abstract void setCallback(IMovementCallback callback);
|
||||
|
||||
/**
|
||||
* Following methods are used to add blocks to the queue.
|
||||
*
|
||||
@@ -64,6 +86,8 @@ public abstract class Relocator
|
||||
* @return True if the movement was successfully started.
|
||||
*
|
||||
* @throws IllegalStateException If the Relocator is not on the stack.
|
||||
* @throws IllegalStateException If any of the required parameters are not set
|
||||
* or are invalid.
|
||||
*/
|
||||
public abstract boolean execute();
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import net.minecraft.world.World
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
class BlockMovingRow extends InstancedBlock("relocation.BlockMovingRow", Material.iron)
|
||||
class BlockMovingRow extends InstancedBlock("relocation.blockmovingrow", Material.iron)
|
||||
{
|
||||
setHardness(-1F)
|
||||
setStepSound(Block.soundTypeGravel)
|
||||
@@ -33,10 +33,14 @@ object TileMovingRow
|
||||
w.setBlock(r.pos.x, r.pos.y, r.pos.z, RelocationMod.blockMovingRow, 0, 3)
|
||||
}
|
||||
|
||||
def getBoxFor(w:World, r:BlockRow, progress:Double) =
|
||||
def getBoxFor(w:World, r:BlockRow, progress:Double):Cuboid6 =
|
||||
{
|
||||
val p = r.pos.copy.offset(r.moveDir^1)
|
||||
w.getBlock(p.x, p.y, p.z).getCollisionBoundingBoxFromPool(w, p.x, p.y, p.z) match
|
||||
val bl = w.getBlock(p.x, p.y, p.z)
|
||||
|
||||
if (bl == RelocationMod.blockMovingRow) return Cuboid6.full.copy()
|
||||
|
||||
bl.getCollisionBoundingBoxFromPool(w, p.x, p.y, p.z) match
|
||||
{
|
||||
case aabb:AxisAlignedBB => new Cuboid6(aabb).sub(new Vector3(r.pos))
|
||||
.add(new Vector3(BlockCoord.sideOffsets(r.moveDir))*progress)
|
||||
|
||||
@@ -17,6 +17,7 @@ object RelocationEventHandler
|
||||
def worldUnload(event:WorldEvent.Unload)
|
||||
{
|
||||
RelocationSPH.onWorldUnload(event.world)
|
||||
MovementManager2.onWorldUnload(event.world)
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
@@ -40,13 +41,6 @@ object RelocationEventHandler
|
||||
MovementManager2.onTick(false)
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def clientTick(event:TickEvent.ClientTickEvent)
|
||||
{
|
||||
if (event.phase == TickEvent.Phase.END)
|
||||
MovementManager2.onTick(true)
|
||||
}
|
||||
}
|
||||
|
||||
object RelocationClientEventHandler
|
||||
@@ -64,4 +58,11 @@ object RelocationClientEventHandler
|
||||
{
|
||||
MovingRenderer.onRenderWorldEvent()
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def clientTick(event:TickEvent.ClientTickEvent)
|
||||
{
|
||||
if (event.phase == TickEvent.Phase.END)
|
||||
MovementManager2.onTick(true)
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,10 @@
|
||||
*/
|
||||
package mrtjp.relocation.handler
|
||||
|
||||
import java.util.{Set => JSet}
|
||||
|
||||
import codechicken.lib.vec.BlockCoord
|
||||
import mrtjp.relocation.api.{BlockPos, ITileMover, RelocationAPI, Relocator}
|
||||
import mrtjp.relocation.api.{ITileMover, RelocationAPI}
|
||||
import mrtjp.relocation.{MovementManager2, MovingTileRegistry}
|
||||
import net.minecraft.world.World
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
import scala.collection.mutable.{Set => MSet}
|
||||
|
||||
object RelocationAPI_Impl extends RelocationAPI
|
||||
{
|
||||
var isPreInit = true
|
||||
@@ -41,73 +35,4 @@ object RelocationAPI_Impl extends RelocationAPI
|
||||
|
||||
override def isMoving(world:World, x:Int, y:Int, z:Int) =
|
||||
MovementManager2.isMoving(world, x, y, z)
|
||||
}
|
||||
|
||||
object Relocator_Impl extends Relocator
|
||||
{
|
||||
private var enabled = false
|
||||
|
||||
private var world:World = null
|
||||
private var dir = -1
|
||||
private val blocks = MSet[BlockCoord]()
|
||||
|
||||
private def assertState()
|
||||
{
|
||||
if (!enabled) throw new IllegalStateException("Relocator must be on the stack before use.")
|
||||
}
|
||||
|
||||
override def push()
|
||||
{
|
||||
if (enabled) throw new IllegalStateException("Relocator is already on the stack.")
|
||||
enabled = true
|
||||
}
|
||||
|
||||
override def pop()
|
||||
{
|
||||
if (!enabled) throw new IllegalStateException("Relocator is not on the stack.")
|
||||
enabled = false
|
||||
world = null
|
||||
dir = -1
|
||||
blocks.clear()
|
||||
}
|
||||
|
||||
override def setWorld(w:World)
|
||||
{
|
||||
assertState()
|
||||
if (world != null) throw new IllegalStateException("World already set.")
|
||||
world = w
|
||||
}
|
||||
|
||||
override def setDirection(d:Int)
|
||||
{
|
||||
assertState()
|
||||
if (dir != -1) throw new IllegalStateException("Direction already set.")
|
||||
dir = d
|
||||
}
|
||||
|
||||
override def addBlock(x:Int, y:Int, z:Int)
|
||||
{
|
||||
assertState()
|
||||
blocks += new BlockCoord(x, y, z)
|
||||
}
|
||||
|
||||
override def addBlock(bc:BlockPos)
|
||||
{
|
||||
addBlock(bc.x, bc.y, bc.z)
|
||||
}
|
||||
|
||||
override def addBlocks(blocks:JSet[BlockPos])
|
||||
{
|
||||
for (b <- blocks) addBlock(b)
|
||||
}
|
||||
|
||||
override def execute() =
|
||||
{
|
||||
assertState()
|
||||
if (world == null) throw new IllegalStateException("World must be set before move.")
|
||||
if (world.isRemote) throw new IllegalStateException("Movements cannot be executed client-side.")
|
||||
if (dir == -1) throw new IllegalStateException("Direction must be set before move.")
|
||||
if (blocks.isEmpty) throw new IllegalStateException("At least 1 block is required for move.")
|
||||
MovementManager2.tryStartMove(world, blocks.toSet, dir)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2015.
|
||||
* Created by MrTJP.
|
||||
* All rights reserved.
|
||||
*/
|
||||
package mrtjp.relocation.handler
|
||||
|
||||
import java.util.{Set => JSet}
|
||||
|
||||
import codechicken.lib.vec.BlockCoord
|
||||
import mrtjp.relocation.MovementManager2
|
||||
import mrtjp.relocation.api.{IMovementCallback, BlockPos, Relocator}
|
||||
import net.minecraft.world.World
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
import scala.collection.mutable.{Set => MSet, Stack => MStack}
|
||||
|
||||
class RelocationRun
|
||||
{
|
||||
var world:World = null
|
||||
var dir = -1
|
||||
var speed = 0.0
|
||||
var callback:IMovementCallback = null
|
||||
val blocks = MSet[BlockCoord]()
|
||||
|
||||
def clear()
|
||||
{
|
||||
world = null
|
||||
dir = -1
|
||||
speed = 0
|
||||
callback = null
|
||||
blocks.clear()
|
||||
}
|
||||
}
|
||||
|
||||
object Relocator_Impl extends Relocator
|
||||
{
|
||||
var mainStack = new MStack[RelocationRun]()
|
||||
var tempStack = new MStack[RelocationRun]()
|
||||
|
||||
private def assertState()
|
||||
{
|
||||
if (mainStack.isEmpty) throw new IllegalStateException("Relocator stack is empty.")
|
||||
}
|
||||
|
||||
override def push()
|
||||
{
|
||||
val r = if (tempStack.isEmpty) new RelocationRun else tempStack.pop()
|
||||
mainStack.push(r)
|
||||
}
|
||||
|
||||
override def pop()
|
||||
{
|
||||
assertState()
|
||||
val r = mainStack.pop()
|
||||
r.clear()
|
||||
tempStack.push(r)
|
||||
}
|
||||
|
||||
override def setWorld(world:World)
|
||||
{
|
||||
assertState()
|
||||
val top = mainStack.top
|
||||
if (top.world != null) throw new IllegalStateException("World already set.")
|
||||
top.world = world
|
||||
}
|
||||
|
||||
override def setDirection(dir:Int)
|
||||
{
|
||||
assertState()
|
||||
val top = mainStack.top
|
||||
if (top.dir != -1) throw new IllegalStateException("Direction already set.")
|
||||
top.dir = dir
|
||||
}
|
||||
|
||||
override def setSpeed(speed:Double)
|
||||
{
|
||||
assertState()
|
||||
val top = mainStack.top
|
||||
if (top.speed > 0) throw new IllegalStateException("Speed already set.")
|
||||
top.speed = speed
|
||||
}
|
||||
|
||||
|
||||
override def setCallback(callback:IMovementCallback)
|
||||
{
|
||||
assertState()
|
||||
val top = mainStack.top
|
||||
if (top.callback != null) throw new IllegalStateException("Callback already set.")
|
||||
top.callback = callback
|
||||
}
|
||||
|
||||
override def addBlock(x:Int, y:Int, z:Int)
|
||||
{
|
||||
assertState()
|
||||
mainStack.top.blocks += new BlockCoord(x, y, z)
|
||||
}
|
||||
|
||||
override def addBlock(bc:BlockPos)
|
||||
{
|
||||
addBlock(bc.x, bc.y, bc.z)
|
||||
}
|
||||
|
||||
override def addBlocks(blocks:JSet[BlockPos])
|
||||
{
|
||||
for (b <- blocks) addBlock(b)
|
||||
}
|
||||
|
||||
override def execute() =
|
||||
{
|
||||
assertState()
|
||||
val top = mainStack.top
|
||||
if (top.world == null) throw new IllegalStateException("World must be set before move.")
|
||||
if (top.world.isRemote) throw new IllegalStateException("Movements cannot be executed client-side.")
|
||||
if (top.dir == -1) throw new IllegalStateException("Direction must be set before move.")
|
||||
if (top.speed <= 0) throw new IllegalStateException("Speed must be greater than 0.")
|
||||
if (top.speed >= 1) throw new IllegalStateException("Speed must be less than 1.")
|
||||
if (top.blocks.isEmpty) throw new IllegalStateException("No blocks queued for move.")
|
||||
MovementManager2.tryStartMove(top.world, top.blocks.toSet, top.dir, top.speed, top.callback)
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,15 @@ object RelocationSPH extends RelocationPH with IServerPacketHandler
|
||||
def onWorldUnload(world:World)
|
||||
{
|
||||
if(!world.isRemote)
|
||||
{
|
||||
updateMap.remove(world)
|
||||
if (chunkWatchers.nonEmpty)
|
||||
{
|
||||
val players = getServerPlayers
|
||||
for (p <- players) if (p.worldObj.provider.dimensionId == world.provider.dimensionId)
|
||||
chunkWatchers.remove(p.getEntityId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def onChunkWatch(p:EntityPlayer, c:ChunkCoordIntPair)
|
||||
|
||||
@@ -10,12 +10,14 @@ import codechicken.lib.packet.PacketCustom
|
||||
import codechicken.lib.vec.BlockCoord
|
||||
import mrtjp.core.math.MathLib
|
||||
import mrtjp.core.world.WorldLib
|
||||
import mrtjp.relocation.handler.{RelocationSPH, RelocationConfig}
|
||||
import mrtjp.relocation.api.{IMovementCallback, IMovementDescriptor}
|
||||
import mrtjp.relocation.handler.{RelocationConfig, RelocationSPH}
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.world.{ChunkCoordIntPair, World}
|
||||
import net.minecraftforge.common.DimensionManager
|
||||
|
||||
import scala.collection.mutable.{HashMap => MHashMap, MultiMap => MMultiMap, Set => MSet}
|
||||
import scala.ref.WeakReference
|
||||
|
||||
object MovementManager2
|
||||
{
|
||||
@@ -48,6 +50,7 @@ object MovementManager2
|
||||
val struct = new BlockStruct
|
||||
struct.id = id
|
||||
struct.readDesc(in)
|
||||
addStructToWorld(w, struct)
|
||||
id = in.readUShort()
|
||||
}
|
||||
}
|
||||
@@ -58,8 +61,8 @@ object MovementManager2
|
||||
val struct = new BlockStruct
|
||||
struct.id = in.readUShort()
|
||||
struct.readDesc(in)
|
||||
getWorldStructs(w).addStruct(struct)
|
||||
for (b <- struct.allBlocks)
|
||||
addStructToWorld(w, struct)
|
||||
for (b <- struct.allBlocks) //rerender all moving blocks
|
||||
w.func_147479_m(b.x, b.y, b.z)
|
||||
case 2 =>
|
||||
val id = in.readUShort()
|
||||
@@ -88,10 +91,16 @@ object MovementManager2
|
||||
|
||||
def isMoving(w:World, x:Int, y:Int, z:Int) = getWorldStructs(w).contains(x, y, z)
|
||||
|
||||
def addStructToWorld(w:World, b:BlockStruct)
|
||||
{
|
||||
getWorldStructs(w).addStruct(b)
|
||||
b.onAdded(w)
|
||||
}
|
||||
|
||||
def getEnclosedStructure(w:World, x:Int, y:Int, z:Int) =
|
||||
getWorldStructs(w).structs.find(_.contains(x, y, z)).orNull
|
||||
|
||||
def tryStartMove(w:World, blocks:Set[BlockCoord], moveDir:Int):Boolean =
|
||||
def tryStartMove(w:World, blocks:Set[BlockCoord], moveDir:Int, speed:Double, c:IMovementCallback):Boolean =
|
||||
{
|
||||
if (blocks.size > RelocationConfig.moveLimit) return false
|
||||
|
||||
@@ -117,8 +126,10 @@ object MovementManager2
|
||||
|
||||
val struct = new BlockStruct
|
||||
struct.id = BlockStruct.claimID()
|
||||
struct.speed = speed
|
||||
struct.rows = rows
|
||||
getWorldStructs(w).addStruct(struct)
|
||||
struct.callback = WeakReference(c)
|
||||
addStructToWorld(w, struct)
|
||||
sendStruct(w, struct)
|
||||
|
||||
true
|
||||
@@ -156,9 +167,9 @@ object MovementManager2
|
||||
|
||||
def cycleMove(w:World, struct:BlockStruct)
|
||||
{
|
||||
for (r <- struct.rows) r.doMove(w)
|
||||
for (r <- struct.rows) r.postMove(w)
|
||||
for (r <- struct.rows) r.endMove(w)
|
||||
struct.doMove(w)
|
||||
struct.postMove(w)
|
||||
struct.endMove(w)
|
||||
|
||||
Utils.rescheduleTicks(w, struct.preMoveBlocks, struct.allBlocks, struct.moveDir)
|
||||
|
||||
@@ -184,8 +195,8 @@ class WorldStructs
|
||||
|
||||
def removeFinished() =
|
||||
{
|
||||
val finished = structs.filter(_.finished)
|
||||
structs = structs.filterNot(_.finished)
|
||||
val finished = structs.filter(_.isFinished)
|
||||
structs = structs.filterNot(_.isFinished)
|
||||
finished
|
||||
}
|
||||
|
||||
@@ -213,12 +224,34 @@ object BlockStruct
|
||||
}
|
||||
}
|
||||
|
||||
class MoveDesc(b:WeakReference[BlockStruct]) extends IMovementDescriptor
|
||||
{
|
||||
def this(b:BlockStruct) = this(new WeakReference(b))
|
||||
|
||||
override def isMoving = b match {
|
||||
case WeakReference(b:BlockStruct) => !b.isFinished
|
||||
case _ => false
|
||||
}
|
||||
|
||||
override def getProgress = b match {
|
||||
case WeakReference(b:BlockStruct) => b.progress
|
||||
case _ => -1
|
||||
}
|
||||
|
||||
override def getSize = b match {
|
||||
case WeakReference(b:BlockStruct) => b.allBlocks.size
|
||||
case _ => 0
|
||||
}
|
||||
}
|
||||
|
||||
class BlockStruct
|
||||
{
|
||||
var id = -1
|
||||
var progress = 0.0D
|
||||
var speed = 1/16D
|
||||
var rows:Set[BlockRow] = Set.empty
|
||||
var callback = WeakReference[IMovementCallback](null)
|
||||
|
||||
var progress = 0.0D
|
||||
|
||||
lazy val allBlocks = rows.flatMap(_.allBlocks)
|
||||
lazy val preMoveBlocks = rows.flatMap(_.preMoveBlocks)
|
||||
@@ -228,8 +261,9 @@ class BlockStruct
|
||||
|
||||
def contains(x:Int, y:Int, z:Int) = rows.exists(_.contains(x, y, z))
|
||||
|
||||
def push(){ progress = (progress+speed) min 1.0D }
|
||||
def finished = progress >= 1.0D
|
||||
def push(){ progress = math.min(1.0, progress+speed) }
|
||||
|
||||
def isFinished = progress >= 1.0D
|
||||
|
||||
def getChunks:Set[ChunkCoordIntPair] =
|
||||
{
|
||||
@@ -239,6 +273,37 @@ class BlockStruct
|
||||
c.result()
|
||||
}
|
||||
|
||||
def onAdded(w:World)
|
||||
{
|
||||
if (!w.isRemote) callback match
|
||||
{
|
||||
case WeakReference(c) =>
|
||||
c.setDescriptor(new MoveDesc(this))
|
||||
c.onMovementStarted()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
def doMove(w:World)
|
||||
{
|
||||
for (r <- rows) r.doMove(w)
|
||||
}
|
||||
|
||||
def postMove(w:World)
|
||||
{
|
||||
for (r <- rows) r.postMove(w)
|
||||
}
|
||||
|
||||
def endMove(w:World)
|
||||
{
|
||||
for (r <- rows) r.endMove(w)
|
||||
if (!w.isRemote) callback match
|
||||
{
|
||||
case WeakReference(c) => c.onMovementFinished()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
override def equals(obj:scala.Any) = obj match
|
||||
{
|
||||
case that:BlockStruct => id == that.id
|
||||
@@ -280,6 +345,7 @@ class BlockRow(val pos:BlockCoord, val moveDir:Int, val size:Int)
|
||||
import MathLib.{basis, normal, shift}
|
||||
|
||||
import math.{max, min}
|
||||
|
||||
if (normal(x, y, z, moveDir) == normal(pos, moveDir))
|
||||
{
|
||||
val b1 = basis(pos, moveDir)
|
||||
|
||||
Reference in new issue
Block a user