diff --git a/blockrotation.py b/blockrotation.py index 5cb7656..93bc24c 100644 --- a/blockrotation.py +++ b/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]] - - - - - - - \ No newline at end of file + data[:] = BlockRotation.rotateLeft[blocks, data] + +