rewrote block rotation in terms of a giant lookup table

This commit is contained in:
David Vierra 2010-12-23 18:26:36 -10:00
parent df1b8b93c2
commit a98f59b636

View File

@ -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]