140 lines
3.9 KiB
Python
140 lines
3.9 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
Module for high-level abstraction of tiles
|
||
|
"""
|
||
|
from collections import namedtuple
|
||
|
from .pydftypes import Rectangle
|
||
|
from .mixins import NoStart
|
||
|
from .decorators import suspend
|
||
|
|
||
|
class Point(object):
|
||
|
x = None
|
||
|
y = None
|
||
|
z = None
|
||
|
block = False
|
||
|
def __init__(self, x, y, z, block=False):
|
||
|
self.x = x
|
||
|
self.y = y
|
||
|
self.z = z
|
||
|
self.block = block
|
||
|
|
||
|
def get_block(self):
|
||
|
if not self.block:
|
||
|
return Point(self.x/16, self.y/16, self.z, True)
|
||
|
else:
|
||
|
return self
|
||
|
|
||
|
@property
|
||
|
def xyz(self):
|
||
|
return (self.x, self.y, self.z)
|
||
|
|
||
|
@property
|
||
|
def rect(self):
|
||
|
"""
|
||
|
Return block coords in form (x1, y1, x2, y2)
|
||
|
"""
|
||
|
block = self.get_block()
|
||
|
x1 = block.x * 16
|
||
|
y1 = block.y * 16
|
||
|
return Rectangle(x1, y1, x1+15, y1+15)
|
||
|
|
||
|
|
||
|
def __repr__(self):
|
||
|
b = ''
|
||
|
if self.block:
|
||
|
b = ', Block'
|
||
|
return "<Point(X:{0.x}, Y:{0.y}, Z:{0.z}{1})>".format(self, b)
|
||
|
|
||
|
class Block(NoStart):
|
||
|
"""
|
||
|
16x16 tiles block
|
||
|
"""
|
||
|
api = None
|
||
|
tiles = None
|
||
|
coords = None
|
||
|
x1 = None
|
||
|
y1 = None
|
||
|
def __init__(self, api, coords):
|
||
|
"""
|
||
|
api is instance of API, which is used for read/write operations
|
||
|
coords is Point object
|
||
|
"""
|
||
|
self.api = api
|
||
|
if not isinstance(coords, Point):
|
||
|
raise Exception(u"coords parameter should be Point")
|
||
|
|
||
|
coords = coords.get_block()
|
||
|
self.coords = coords
|
||
|
self.rect = self.coords.rect
|
||
|
self.reload()
|
||
|
|
||
|
@suspend
|
||
|
def reload(self):
|
||
|
tile_types = self.api.maps.Read_Tile_Types(point=self.coords)
|
||
|
tile_flags = self.api.maps.Read_Designations(point=self.coords)
|
||
|
if self.tiles:
|
||
|
for x in range(16):
|
||
|
for y in range(16):
|
||
|
self.tiles[x][y].update(ttype=tile_types[x][y], flags=tile_flags[x][y])
|
||
|
else:
|
||
|
self.tiles = []
|
||
|
for x in range(16):
|
||
|
row = []
|
||
|
for y in range(16):
|
||
|
row.append(Tile(self, tile_types[x][y], tile_flags[x][y], self.rect.x1 + x, self.rect.y1 + y, self.coords.z))
|
||
|
self.tiles.append(row)
|
||
|
|
||
|
@suspend
|
||
|
def save(self):
|
||
|
tile_types = map(lambda x:range(16), range(16))
|
||
|
tile_flags = map(lambda x:range(16), range(16))
|
||
|
for x in range(16):
|
||
|
for y in range(16):
|
||
|
tile_types[x][y] = self.tiles[x][y].ttype
|
||
|
tile_flags[x][y] = self.tiles[x][y].flags
|
||
|
self.api.maps.Write_Tile_Types(point=self.coords, tiles=tile_types)
|
||
|
# Designations are bugged
|
||
|
|
||
|
#self.api.maps.Write_Designations(point=self.coords, tiles=tile_flags)
|
||
|
|
||
|
def get_tile(self, x=0, y=0, z=0, point=None):
|
||
|
if point:
|
||
|
x, y, z = point.xyz
|
||
|
|
||
|
if z == self.coords.z and (self.rect.y1 <= y <= self.rect.y2) and (self.rect.x1 <= x <= self.rect.x2):
|
||
|
return self.tiles[x%16][y%16]
|
||
|
else:
|
||
|
raise Exception("This tile does not belong to this block")
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<Block(X:{2}-{4}, Y:{3}-{5}, Z:{1.z})>".format(self, self.coords, *self.coords.rect)
|
||
|
|
||
|
|
||
|
|
||
|
class Tile(object):
|
||
|
coords = None
|
||
|
block = None
|
||
|
ttype = None
|
||
|
temperature = None
|
||
|
flags = None
|
||
|
def __init__(self, block, ttype, flags, x=0, y=0, z=0, point=None):
|
||
|
self.ttype = ttype
|
||
|
self.flags = flags
|
||
|
if not point:
|
||
|
point = Point(x, y, z)
|
||
|
self.coords = point
|
||
|
self.block = block
|
||
|
|
||
|
def update(self, ttype, flags):
|
||
|
self.ttype = ttype
|
||
|
self.flags = flags
|
||
|
|
||
|
def reload(self):
|
||
|
self.block.reload()
|
||
|
|
||
|
def save(self):
|
||
|
self.block.save()
|
||
|
|
||
|
def __repr__(self):
|
||
|
return "<Tile({0.ttype} at {1.x}, {1.y}, {1.z})>".format(self, self.coords)
|