def LoadLayer(self, idx, layerdata): """ Loads a specific object layer from a bytes object """ objcount = len(layerdata) // 16 objstruct = struct.Struct('>HhhHHB') offset = 0 z = (2 - idx) * 8192 layer = self.layers[idx] append = layer.append unpack = objstruct.unpack_from for i in range(objcount): data = unpack(layerdata, offset) # Just for clarity, assigning these things to variables explaining what they are tileset = (data[0] >> 12) & 3 type = data[0] & 255 layer = idx x = data[1] y = data[2] width = data[3] height = data[4] z = z objdata = data[5] append(ObjectItem(tileset, type, layer, x, y, width, height, z, objdata)) z += 1 offset += 16
def LoadLayer(self, idx, layerdata): """ Loads a specific object layer from a string """ objcount = len(layerdata) // 10 objstruct = struct.Struct('>HHHHH') offset = 0 z = (2 - idx) * 8192 layer = self.layers[idx] append = layer.append unpack = objstruct.unpack_from for i in range(objcount): data = unpack(layerdata, offset) append(ObjectItem(data[0] >> 12, data[0] & 4095, idx, data[1], data[2], data[3], data[4], z)) z += 1 offset += 10
def sliceObj(obj, px=None, py=None): """ Slices this object into 1x1 objects. """ if not obj or (obj.width == 1 and obj.height == 1): if obj not in QuickPaintOperations.object_optimize_database and obj: QuickPaintOperations.object_optimize_database.append(obj) return obj out_obj = None mw = globals.mainWindow objx = obj.objx objy = obj.objy w = obj.width h = obj.height l = obj.layer ts = obj.tileset t = obj.original_type atd_archive = [] if hasattr(obj, 'atd_archive') and obj.atd_archive: atd_archive = obj.atd_archive skip = [] x = 0 y = 0 if obj.objdata: for row in obj.objdata: x = 0 for tile in row: if tile == -1: skip.append((x, y)) x += 1 y += 1 if obj in globals.Area.layers[obj.layer]: obj.delete() obj.setSelected(False) mw.scene.removeItem(obj) if obj in QuickPaintOperations.object_optimize_database: QuickPaintOperations.object_optimize_database.remove(obj) for y in range(h): for x in range(w): if (x, y) in skip: continue layer = globals.Area.layers[l] ln = globals.CurrentLayer if len(layer) == 0: z = (2 - ln) * 8192 else: z = layer[-1].zValue() + 1 objBehindThisOne = QuickPaintOperations.sliceObj( QuickPaintOperations.searchObj(ln, x + objx, y + objy), x + objx, y + objy) if objBehindThisOne is not None: objBehindThisOne.delete() objBehindThisOne.setSelected(False) if objBehindThisOne in QuickPaintOperations.object_optimize_database: QuickPaintOperations.object_optimize_database.remove( objBehindThisOne) mw.scene.removeItem(objBehindThisOne) from items import ObjectItem sobj = ObjectItem(ts, t, l, x + objx, y + objy, 1, 1, z, 0) del ObjectItem atd = list( filter(lambda i: i[0] == x and i[1] == y, atd_archive)) if atd is not None and len(atd) > 0: sobj.modifiedForSize = atd[0][2] sobj.autoTileType = atd[0][3] layer.append(sobj) if sobj not in QuickPaintOperations.object_optimize_database: QuickPaintOperations.object_optimize_database.append(sobj) sobj.positionChanged = mw.HandleObjPosChange mw.scene.addItem(sobj) if sobj.objx == px and sobj.objy == py: out_obj = sobj return out_obj
def AddObj(ln, layer, x, y, z): """ Adds an object to the level and automatically fixes the tiles of islands it may be touching. """ if globals.mainWindow.quickPaint is not None and globals.mainWindow.quickPaint.scene is not None: qpscn = globals.mainWindow.quickPaint.scene qp_data = qpscn.object_database if qp_data['base']['i'] is not None and qp_data['base'][ 'ts'] is not None and qp_data['base']['t'] is not None: mw = globals.mainWindow objBehindThisOne = QuickPaintOperations.searchObj(ln, x, y) while objBehindThisOne is not None: objBehindThisOne.delete() if objBehindThisOne in QuickPaintOperations.object_optimize_database: QuickPaintOperations.object_optimize_database.remove( objBehindThisOne) objBehindThisOne.setSelected(False) mw.scene.removeItem(objBehindThisOne) objBehindThisOne = QuickPaintOperations.searchObj(ln, x, y) from items import ObjectItem obj = ObjectItem(qp_data['base']['ts'], qp_data['base']['t'], ln, x, y, 1, 1, z, 0) del ObjectItem layer.append(obj) obj.positionChanged = mw.HandleObjPosChange if obj not in QuickPaintOperations.object_optimize_database: QuickPaintOperations.object_optimize_database.append(obj) mw.scene.addItem(obj) # This next function has to repeated multiple times at multiple places in and around this object. # Otherwise, you will leave artifacts when painting with bigger objects. QuickPaintOperations.autoTileObj(ln, obj) for r in range(QuickPaintOperations._getMaxSize(qp_data) + 2): for a in range(-r, r): sobj = QuickPaintOperations.searchObj( ln, obj.objx + a, obj.objy - r) if sobj is not None: QuickPaintOperations.autoTileObj(ln, sobj) for a in range(-r, r): sobj = QuickPaintOperations.searchObj( ln, obj.objx + r, obj.objy + a) if sobj is not None: QuickPaintOperations.autoTileObj(ln, sobj) for a in range(-r, r): sobj = QuickPaintOperations.searchObj( ln, obj.objx - a, obj.objy + r) if sobj is not None: QuickPaintOperations.autoTileObj(ln, sobj) for a in range(-r, r): sobj = QuickPaintOperations.searchObj( ln, obj.objx - r, obj.objy - a) if sobj is not None: QuickPaintOperations.autoTileObj(ln, sobj)