rewrote block rotation in terms of a giant lookup table
This commit is contained in:
parent
df1b8b93c2
commit
a98f59b636
349
blockrotation.py
349
blockrotation.py
@ -1,100 +1,257 @@
|
||||
from materials import alphaMaterials
|
||||
from numpy import array
|
||||
from numpy import array, arange, zeros
|
||||
|
||||
def genericRotation(cls):
|
||||
rotation = arange(16, dtype='uint8')
|
||||
rotation[cls.North] = cls.West
|
||||
rotation[cls.West] = cls.South
|
||||
rotation[cls.South] = cls.East
|
||||
rotation[cls.East] = cls.North
|
||||
return rotation
|
||||
|
||||
def genericEastWestFlip(cls):
|
||||
rotation = arange(16, dtype='uint8')
|
||||
rotation[cls.West] = cls.East
|
||||
rotation[cls.East] = cls.West
|
||||
return rotation
|
||||
|
||||
def genericNorthSouthFlip(cls):
|
||||
rotation = arange(16, dtype='uint8')
|
||||
rotation[cls.South] = cls.North
|
||||
rotation[cls.North] = cls.South
|
||||
return rotation
|
||||
|
||||
rotationClasses = [];
|
||||
|
||||
def genericFlipRotation(cls):
|
||||
cls.rotateLeft = genericRotation(cls)
|
||||
cls.flipEastWest = genericEastWestFlip(cls)
|
||||
cls.flipNorthSouth = genericNorthSouthFlip(cls)
|
||||
rotationClasses.append(cls)
|
||||
|
||||
class Torch:
|
||||
blocktypes = [
|
||||
alphaMaterials.materialNamed("Torch"),
|
||||
alphaMaterials.materialNamed("Redstone Torch (on)"),
|
||||
alphaMaterials.materialNamed("Redstone Torch (off)"),
|
||||
]
|
||||
|
||||
South = 1
|
||||
North = 2
|
||||
West = 3
|
||||
East = 4
|
||||
|
||||
genericFlipRotation(Torch)
|
||||
|
||||
class Ladder:
|
||||
blocktypes = [alphaMaterials.materialNamed("Ladder")]
|
||||
|
||||
East = 2
|
||||
West = 3
|
||||
North = 4
|
||||
South = 5
|
||||
genericFlipRotation(Ladder)
|
||||
|
||||
class Stair:
|
||||
blocktypes = [
|
||||
alphaMaterials.materialNamed("Wooden Stair"),
|
||||
alphaMaterials.materialNamed("Stone Stair"),
|
||||
]
|
||||
|
||||
South = 0
|
||||
North = 1
|
||||
West = 2
|
||||
East = 3
|
||||
genericFlipRotation(Stair)
|
||||
|
||||
class WallSign:
|
||||
blocktypes = [alphaMaterials.materialNamed("Wall Sign")]
|
||||
|
||||
East = 2
|
||||
West = 3
|
||||
North = 4
|
||||
South = 5
|
||||
genericFlipRotation(WallSign)
|
||||
|
||||
class Furnace:
|
||||
blocktypes = [
|
||||
alphaMaterials.materialNamed("Furnace"),
|
||||
alphaMaterials.materialNamed("Lit Furnace"),
|
||||
]
|
||||
East = 2
|
||||
West = 3
|
||||
North = 4
|
||||
South = 5
|
||||
genericFlipRotation(Furnace)
|
||||
|
||||
class Pumpkin:
|
||||
blocktypes = [
|
||||
alphaMaterials.materialNamed("Pumpkin"),
|
||||
alphaMaterials.materialNamed("Glowing Pumpkin"),
|
||||
]
|
||||
|
||||
East = 0
|
||||
South = 1
|
||||
West = 2
|
||||
North = 3
|
||||
genericFlipRotation(Pumpkin)
|
||||
|
||||
class Rail:
|
||||
blocktypes = [alphaMaterials.materialNamed("Rail")]
|
||||
|
||||
EastWest = 0
|
||||
NorthSouth = 1
|
||||
South = 2
|
||||
North = 3
|
||||
East = 4
|
||||
West = 5
|
||||
|
||||
Northeast = 6
|
||||
Southeast = 7
|
||||
Southwest = 8
|
||||
Northwest = 9
|
||||
Rail.rotateLeft = genericRotation(Rail)
|
||||
Rail.rotateLeft[Rail.Northeast] = Rail.Northwest
|
||||
Rail.rotateLeft[Rail.Southeast] = Rail.Northeast
|
||||
Rail.rotateLeft[Rail.Southwest] = Rail.Southeast
|
||||
Rail.rotateLeft[Rail.Northwest] = Rail.Southwest
|
||||
|
||||
Rail.rotateLeft[Rail.NorthSouth] = Rail.EastWest
|
||||
Rail.rotateLeft[Rail.EastWest] = Rail.NorthSouth
|
||||
|
||||
Rail.flipEastWest = genericEastWestFlip(Rail)
|
||||
Rail.flipEastWest[Rail.Northeast] = Rail.Northwest
|
||||
Rail.flipEastWest[Rail.Northwest] = Rail.Northeast
|
||||
Rail.flipEastWest[Rail.Southwest] = Rail.Southeast
|
||||
Rail.flipEastWest[Rail.Southeast] = Rail.Southwest
|
||||
|
||||
Rail.flipNorthSouth = genericNorthSouthFlip(Rail)
|
||||
Rail.flipNorthSouth[Rail.Northeast] = Rail.Southeast
|
||||
Rail.flipNorthSouth[Rail.Southeast] = Rail.Northeast
|
||||
Rail.flipNorthSouth[Rail.Southwest] = Rail.Northwest
|
||||
Rail.flipNorthSouth[Rail.Northwest] = Rail.Southwest
|
||||
rotationClasses.append(Rail)
|
||||
|
||||
def applyThrownBit(array):
|
||||
array[8:16] = array[0:8] | 0x8
|
||||
|
||||
class Lever:
|
||||
blocktypes = [alphaMaterials.materialNamed("Lever")]
|
||||
ThrownBit = 0x8
|
||||
South = 1
|
||||
North = 2
|
||||
West = 3
|
||||
East = 4
|
||||
EastWest = 5
|
||||
NorthSouth = 6
|
||||
Lever.rotateLeft = genericRotation(Lever)
|
||||
Lever.rotateLeft[Lever.NorthSouth] = Lever.EastWest
|
||||
Lever.rotateLeft[Lever.EastWest] = Lever.NorthSouth
|
||||
Lever.flipEastWest = genericEastWestFlip(Lever)
|
||||
Lever.flipNorthSouth = genericNorthSouthFlip(Lever)
|
||||
applyThrownBit(Lever.rotateLeft)
|
||||
applyThrownBit(Lever.flipEastWest)
|
||||
applyThrownBit(Lever.flipNorthSouth)
|
||||
rotationClasses.append(Lever)
|
||||
|
||||
class Button:
|
||||
blocktypes = [alphaMaterials.materialNamed("Stone Button")]
|
||||
PressedBit = 0x8
|
||||
South = 1
|
||||
North = 2
|
||||
West = 3
|
||||
East = 4
|
||||
Button.rotateLeft = genericRotation(Button)
|
||||
Button.flipEastWest = genericEastWestFlip(Button)
|
||||
Button.flipNorthSouth = genericNorthSouthFlip(Button)
|
||||
applyThrownBit(Button.rotateLeft)
|
||||
applyThrownBit(Button.flipEastWest)
|
||||
applyThrownBit(Button.flipNorthSouth)
|
||||
rotationClasses.append(Button)
|
||||
|
||||
class SignPost:
|
||||
blocktypes = [alphaMaterials.materialNamed("Sign")]
|
||||
#west is 0, increasing clockwise
|
||||
|
||||
rotateLeft = arange(16, dtype='uint8')
|
||||
rotateLeft -= 4
|
||||
rotateLeft &= 0xf
|
||||
|
||||
flipEastWest = arange(16, dtype='uint8')
|
||||
flipNorthSouth = arange(16, dtype='uint8')
|
||||
pass
|
||||
|
||||
rotationClasses.append(SignPost)
|
||||
|
||||
class Door:
|
||||
blocktypes = [
|
||||
alphaMaterials.materialNamed("Iron Door"),
|
||||
alphaMaterials.materialNamed("Wooden Door"),
|
||||
]
|
||||
TopHalfBit = 0x8
|
||||
SwungCCWBit = 0x4
|
||||
|
||||
Northeast = 0
|
||||
Southeast = 1
|
||||
Southwest = 2
|
||||
Northwest = 3
|
||||
|
||||
rotateLeft = arange(16, dtype='uint8')
|
||||
|
||||
Door.rotateLeft[Door.Northeast] = Door.Northwest
|
||||
Door.rotateLeft[Door.Southeast] = Door.Northeast
|
||||
Door.rotateLeft[Door.Southwest] = Door.Southeast
|
||||
Door.rotateLeft[Door.Northwest] = Door.Southwest
|
||||
|
||||
Door.rotateLeft[4:8] = Door.rotateLeft[0:4] | 0x4
|
||||
Door.rotateLeft[8:16] = Door.rotateLeft[0:8] | 0x8
|
||||
|
||||
#when flipping horizontally, swing the doors so they at least look the same
|
||||
|
||||
Door.flipEastWest = arange(16, dtype='uint8')
|
||||
Door.flipEastWest[Door.Northeast] = Door.Northwest
|
||||
Door.flipEastWest[Door.Northwest] = Door.Northeast
|
||||
Door.flipEastWest[Door.Southwest] = Door.Southeast
|
||||
Door.flipEastWest[Door.Southeast] = Door.Southwest
|
||||
Door.flipEastWest[4:8] = Door.flipEastWest[0:4]
|
||||
Door.flipEastWest[0:4] = Door.flipEastWest[4:8] | 0x4
|
||||
Door.flipEastWest[8:16] = Door.flipEastWest[0:8] | 0x8
|
||||
|
||||
Door.flipNorthSouth = arange(16, dtype='uint8')
|
||||
Door.flipNorthSouth[Door.Northeast] = Door.Southeast
|
||||
Door.flipNorthSouth[Door.Northwest] = Door.Southwest
|
||||
Door.flipNorthSouth[Door.Southwest] = Door.Southwest
|
||||
Door.flipNorthSouth[Door.Southeast] = Door.Northeast
|
||||
Door.flipNorthSouth[4:8] = Door.flipNorthSouth[0:4]
|
||||
Door.flipNorthSouth[0:4] = Door.flipNorthSouth[4:8] | 0x4
|
||||
Door.flipNorthSouth[8:16] = Door.flipNorthSouth[0:8] | 0x8
|
||||
|
||||
rotationClasses.append(Door)
|
||||
|
||||
|
||||
def masterRotationTable(rotationFunc):
|
||||
# compute a 256x16 table mapping each possible blocktype/data combination to
|
||||
# the resulting data when the block is rotated
|
||||
table = zeros( (256, 16), dtype='uint8')
|
||||
table[:] = arange(16, dtype='uint8')
|
||||
for cls in rotationClasses:
|
||||
for blocktype in cls.blocktypes:
|
||||
table[blocktype] = rotationFunc(cls)
|
||||
|
||||
return table
|
||||
|
||||
class BlockRotation:
|
||||
rotateLeft = masterRotationTable(lambda cls:cls.rotateLeft);
|
||||
flipEastWest = masterRotationTable(lambda cls:cls.flipEastWest);
|
||||
flipNorthSouth = masterRotationTable(lambda cls:cls.flipNorthSouth);
|
||||
|
||||
|
||||
|
||||
def FlipEastWest(blocks, data):
|
||||
pass
|
||||
|
||||
def RotateLeft(blocks, data):
|
||||
|
||||
# Torches
|
||||
torchRotation = array([0, 4, 3, 1, 2, 5,
|
||||
6, 7,
|
||||
|
||||
8, 9, 10, 11, 12, 13, 14, 15], dtype='uint8');
|
||||
|
||||
torchIndexes = (blocks == alphaMaterials.materialNamed("Torch"))
|
||||
torchIndexes |= ( (blocks == alphaMaterials.materialNamed("Redstone Torch (on)")) |
|
||||
(blocks == alphaMaterials.materialNamed("Redstone Torch (off)")) )
|
||||
|
||||
print "Rotating torches: ", len(torchIndexes.nonzero()[0]);
|
||||
data[torchIndexes] = torchRotation[data[torchIndexes]]
|
||||
|
||||
|
||||
# Rails
|
||||
railRotation = array([1, 0, 4, 5, 3, 2, 9, 6,
|
||||
7, 8,
|
||||
|
||||
10, 11, 12, 13, 14, 15], dtype='uint8');
|
||||
|
||||
railIndexes = (blocks == alphaMaterials.materialNamed("Rail"))
|
||||
print "Rotating rails: ", len(railIndexes.nonzero()[0]);
|
||||
data[railIndexes] = railRotation[data[railIndexes]]
|
||||
|
||||
|
||||
# Ladders
|
||||
ladderRotation = array([0, 1, 4, 5, 3, 2,
|
||||
|
||||
6, 7, #xxx more ladders
|
||||
8, 9, 10, 11, 12, 13, 14, 15], dtype='uint8');
|
||||
|
||||
ladderIndexes = (blocks == alphaMaterials.materialNamed("Ladder"))
|
||||
print "Rotating ladders: ", len(ladderIndexes.nonzero()[0]);
|
||||
data[ladderIndexes] = ladderRotation[data[ladderIndexes]]
|
||||
|
||||
|
||||
# Standing signs
|
||||
signIndexes = (blocks == alphaMaterials.materialNamed("Sign"))
|
||||
print "Rotating signs: ", len(signIndexes.nonzero()[0]);
|
||||
data[signIndexes] -= 4
|
||||
data[signIndexes] &= 0xf
|
||||
|
||||
|
||||
# Wall signs
|
||||
wallSignRotation = array([0, 1, 4, 5, 3, 2, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15], dtype='uint8');
|
||||
|
||||
wallSignIndexes = (blocks == alphaMaterials.materialNamed("Wall Sign"))
|
||||
print "Rotating wallsigns: ", len(wallSignIndexes.nonzero()[0]);
|
||||
data[wallSignIndexes] = wallSignRotation[data[wallSignIndexes]]
|
||||
|
||||
|
||||
# Levers
|
||||
leverRotation = array([0, 4, 3, 1, 2, 6, 5, 7,
|
||||
8, 12, 11, 9, 10, 14, 13, 15], dtype='uint8') #thrown levers
|
||||
|
||||
leverIndexes = (blocks == alphaMaterials.materialNamed("Lever"))
|
||||
print "Rotating levers: ", len(leverIndexes.nonzero()[0]);
|
||||
data[leverIndexes] = leverRotation[data[leverIndexes]]
|
||||
|
||||
|
||||
# Doors
|
||||
doorRotation = array([3, 0, 1, 2,
|
||||
7, 4, 5, 6, #swung door
|
||||
11, 8, 9, 10, #top half
|
||||
15, 12, 13, 14], dtype='uint8') #top half swung
|
||||
|
||||
doorIndexes = (blocks == alphaMaterials.materialNamed("Iron Door") ) | (blocks == alphaMaterials.materialNamed("Wooden Door"))
|
||||
print "Rotating doors: ", len(doorIndexes.nonzero()[0]);
|
||||
data[doorIndexes] = doorRotation[data[doorIndexes]]
|
||||
|
||||
|
||||
# Buttons
|
||||
buttonRotation = array([0, 4, 3, 1, 2, 5, 6, 7,
|
||||
8, 12, 11, 9, 10, 13, 14, 15], dtype='uint8') #pressed buttons, unusual
|
||||
|
||||
buttonIndexes = (blocks == alphaMaterials.materialNamed("Stone Button"))
|
||||
print "Rotating buttons: ", len(buttonIndexes.nonzero()[0]);
|
||||
data[buttonIndexes] = buttonRotation[data[buttonIndexes]]
|
||||
|
||||
|
||||
# Stairs
|
||||
stairRotation = array([3, 2, 0, 1, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15], dtype='uint8')
|
||||
|
||||
stairIndexes = (blocks == alphaMaterials.materialNamed("Wooden Stair")) | (blocks == alphaMaterials.materialNamed("Stone Stair"))
|
||||
print "Rotating stairs: ", len(stairIndexes.nonzero()[0]);
|
||||
data[stairIndexes] = stairRotation[data[stairIndexes]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
data[:] = BlockRotation.rotateLeft[blocks, data]
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user