Ejemplo n.º 1
0
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')
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)