def split_dmm(args): if not os.path.isfile(args.map): print('File {0} does not exist.'.format(args.mine)) sys.exit(1) if not os.path.isfile(args.project): print('DM Environment File {0} does not exist.'.format(args.project)) sys.exit(1) dmm = Map(forgiving_atom_lookups=True) dmm.Load(args.map, format='dmm') #fmt = DMMFormat(dmm) nz = len(dmm.zLevels) for z in range(nz): basename, ext = os.path.splitext(args.map) outfile = '{0}-{1}{2}'.format(basename, z + 1, ext) print('>>> Splitting z={}/{} to {}'.format(z + 1, nz, outfile)) output = Map(forgiving_atom_lookups=True) currentZLevel = dmm.zLevels[z] newZLevel = output.CreateZLevel(currentZLevel.height, currentZLevel.width) #newZLevel.initial_load=True for y in range(currentZLevel.width): for x in range(currentZLevel.height): newTile = newZLevel.GetTile(x, y) for atom in currentZLevel.GetTile(x, y).GetAtoms(): newTile.AppendAtom(atom.copy(toNewMap=True)) #newZLevel.initial_load=False output.Save(outfile, format='dmm')
def transcribe_dmm(args): if not os.path.isfile(args.subject): print('File {0} does not exist.'.format(args.subject)) sys.exit(1) if not os.path.isfile(args.project): print('DM Environment File {0} does not exist.'.format(args.project)) sys.exit(1) dmm = Map(forgiving_atom_lookups=True) basename, ext = os.path.splitext(args.subject) outfile = '{0}.trans{1}'.format(basename, ext) dmm.Load(args.subject, format='dmm') dmm.Save(outfile, format='dmm', serialize_cleanly=True)
def patch_dmm(args): print(repr(args.patches)) for i in range(len(args.patches[0])): patch = args.patches[0][i] if not os.path.isfile(patch): print('File {0} does not exist.'.format(patch)) sys.exit(1) if not os.path.isfile(args.map): print('File {0} does not exist.'.format(args.mine)) sys.exit(1) if not os.path.isfile(args.project): print('DM Environment File {0} does not exist.'.format(args.project)) sys.exit(1) dmm = Map(forgiving_atom_lookups=True) dmm.Load(args.map, format='dmm') fmt = DMMFormat(dmm) context = None added = 0 removed = 0 currentpatch = '' def changeMarker(ln): a = Atom('/obj/effect/byondtools/changed') a.setProperty('tag', '{}:{}'.format(currentpatch, ln), flags=PropertyFlags.MAP_SPECIFIED) return a def printReport(context, added, removed): if context is not None: x, y, z = context print(' Z={} +{} -{}'.format(z, added, removed)) REG_INSTRUCTION = re.compile( r'^(?P<change>[\+\-])(?P<amount>[0-9\*]+)?\s+(?P<atom>/.*)') for i in range(len(args.patches[0])): patch = args.patches[0][i] print('* Applying {}...'.format(patch)) currentpatch = patch with open(patch) as f: ln = 0 lz = -1 skip_block = False for line in f: ln += 1 line = line.strip() if line == '': continue if line.startswith('#'): continue if line.startswith('<') and line.endswith('>'): strcoords = line.strip('<>').split(',') newcoords = [] for coord in strcoords: newcoords += [int(coord)] if context is not None and lz != context[2]: printReport(context, added, removed) lz = context[2] added = removed = 0 context = newcoords skip_block = False continue if line.startswith('@') and not skip_block: # @CHECK before-hash after-hash atoms-block x, y, z = context if line.startswith('@CHECK'): _, beforehash, afterhash, serdata = line.split(' ', 3) if args.clobber: #print('WARNING: <{},{},{}> has changed and will be overwritten. (--clobber)'.format(x, y, z)) t = fmt.consumeTileChunk(serdata, cache=False) t.AppendAtom(changeMarker(ln)) dmm.SetTileAt(x, y, z, t) skip_block = True continue curhash = dmm.GetTileAt(x, y, z).GetHash() if afterhash == curhash: print( 'Skipping <{},{},{}> (already what we expected)' .format(x, y, z)) skip_block = True continue #else: print('PRE {} != {}: OK'.format(curhash,afterhash)) if beforehash != curhash: print( 'WARNING: <{},{},{}> has changed. Operations on this tile may not be accurate!' .format(x, y, z)) continue #else: print('OLD {} == {}: OK'.format(curhash,beforehash)) if not skip_block and (line.startswith('+') or line.startswith('-')): if line == '-ALL': dmm.SetTileAt(x, y, z, dmm.CreateTile()) continue m = REG_INSTRUCTION.match(line) if m is None: print('{}:{}: MALFORMED INSTRUCTION: {}'.format( args.patch, ln, line)) sys.exit(1) amount = m.group('amount') if amount == '*': amount = 9999 else: amount = int(m.group('amount') or 1) change = m.group('change') atom = fmt.consumeAtom(m.group('atom'), ln) atom.filename = args.patch atom.line = ln if atom is None: print( '{}:{}: WARNING: Unable to parse instance specified by chunk {}' .format(args.patch, ln, m.group('atom'))) continue x, y, z = context if x == 0 and y == 0 and z == 0: print('WE AT <0,0,0> SOMEFIN WRONG') if z >= len(dmm.zLevels): continue tile = dmm.GetTileAt(x, y, z) if change == '-': for _ in range(amount): if tile.CountAtom(atom) > 0: tile.RemoveAtom(atom, hash=False) removed += 1 else: break elif change == '+': for _ in range(amount): tile.AppendAtom(atom, hash=False) added += amount tile.UpdateHash() # dmm.SetTileAt(x, y, z, tile) # print('{} - {}'.format((x,y,z),tile)) printReport(context, added, removed) print('Saving...') dmm.Save(args.output if args.output else args.map)