def main():
    parser = ArgumentParser(description="List particle systems in particle files")
    parser.add_argument("input_file", type=FileType("rb"), help="Input file, e.g. input.pcf")
    parser.add_argument("--full", action="store_true")
    args = parser.parse_args()

    p = PCF(include_attributes=args.full)
    p.unpack(args.input_file)

    if not args.full:
        for e in p["elements"]:
            if e["type"].data == "DmeParticleSystemDefinition":
                print(e["name"].data.lower())
    else:
        main_element = p["elements"][0]
        assert main_element["type"].data == "DmElement"
        assert len(main_element.attribute) == 1
        main_attribute = main_element.attribute[0]
        assert main_attribute["name"].data == "particleSystemDefinitions"
        assert main_attribute["type"].data == 15
        psdl = main_attribute["data"]
        counter = Counter()
        for i in range(len(psdl)):
            psd = psdl[i].data
            recursive_count(psd, counter)
        for i in range(len(psdl)):
            psd = psdl[i].data
            name = psd["name"].data.lower()
            if counter[name] != 2:
                recursive_print(psd, 0, counter)
def main():
    parser = ArgumentParser(description="List particle systems in particle files")
    parser.add_argument("input_file", type=FileType("rb"), help="Input file, e.g. input.pcf")
    parser.add_argument("--full", action="store_true")
    args = parser.parse_args()

    p = PCF(include_attributes=args.full)
    p.unpack(args.input_file)

    if not args.full:
        for e in p["elements"]:
            if e["type"].data == "DmeParticleSystemDefinition":
                print(e["name"].data.lower())
    else:
        main_element = p["elements"][0]
        assert main_element["type"].data == "DmElement"
        assert len(main_element.attribute) == 1
        main_attribute = main_element.attribute[0]
        assert main_attribute["name"].data == "particleSystemDefinitions"
        assert main_attribute["type"].data == 15
        psdl = main_attribute["data"]
        counter = Counter()
        for i in range(len(psdl)):
            psd = psdl[i].data
            recursive_count(psd, counter)
        for i in range(len(psdl)):
            psd = psdl[i].data
            name = psd["name"].data.lower()
            if counter[name] != 2:
                recursive_print(psd, 0, counter)
Exemple #3
0
def edit_particle_file(f, file):
    p = PCF()
    with open(source_file(file), "rb") as s:
        p.unpack(s)
    p.minimize()
    main_element = p["elements"][0]
    assert main_element["type"].data == "DmElement"
    assert len(main_element.attribute) == 1
    main_attribute = main_element.attribute[0]
    assert main_attribute["name"].data == "particleSystemDefinitions"
    assert main_attribute["type"].data == 15
    psdl = main_attribute["data"]
    for i in range(len(psdl)):
        f(psdl, i)

    if nohats_dir:
        dest = nohats_file(file)
        dest_dir = dirname(dest)
        if not exists(dest_dir):
            makedirs(dest_dir)
        with open(dest, "wb") as s:
            p.full_pack(s)
    else:
        s = FakeWriteStream()
        p.full_pack(s)
Exemple #4
0
def get_particle_file_systems(d, units, npc_heroes):
    files = []

    with open(dota_file("particles/particles_manifest.txt"), "rt", encoding="utf-8") as s:
        l = s.readline().rstrip("\n")
        l = "\"" + l + "\""
        l += s.read()
    m = load(StringIO(l))
    for k, v in m["particles_manifest"]:
        assert k == "file", k
        if v.startswith("!"):
            v = v[1:]
        files.append(v)

    for id, item in chain(units["DOTAUnits"], npc_heroes["DOTAHeroes"]):
        if "ParticleFile" in item and item["ParticleFile"] not in files:
            files.append(item["ParticleFile"])

    with open(dota_file("scripts/precache.txt"), "rt", encoding="utf-8") as s:
        p = load(s)
        for k, v in p["precache"]:
            if k == "particlefile" and v not in files:
                files.append(v)

    for id, item in d["items_game"]["items"]:
        if "particle_file" in item and item["particle_file"] not in files:
            files.append(item["particle_file"])

    for id, v in d["items_game"]["attribute_controlled_attached_particles"]:
        if v.get("resource") is not None and v["resource"] not in files:
            files.append(v["resource"])

    for k, v in d["items_game"]["asset_modifiers"]:
        if "file" in v and v["file"] not in files:
            files.append(v["file"])

    particle_file_systems = OrderedDict()
    for file in files:
        if not exists(source_file(file)):
            print("Warning: referenced particle file '{}' doesn't exist.".format(file), file=stderr)
            continue
        particle_file_systems[file] = []
        pcf = PCF(include_attributes=False)
        with open(source_file(file), "rb") as s:
            pcf.unpack(s)
        for e in pcf["elements"]:
            if e["type"].data == "DmeParticleSystemDefinition":
                system_name = e["name"].data.lower()
                if system_name not in particle_file_systems[file]:
                    particle_file_systems[file].append(system_name)
                else:
                    print("Warning: double particle system definition '{}' in '{}'".format(system_name, file), file=stderr)

    return particle_file_systems
Exemple #5
0
        def edit(psdl, i):
            psd = psdl[i].data
            assert psd["type"].data == "DmeParticleSystemDefinition"
            name = psd["name"].data.lower()
            if name in replacements:
                if replacements[name] is None:
                    psd.attribute.data = []
                else:
                    replacement_file, replacement_system = replacements[name]
                    o = PCF()
                    with open(source_file(replacement_file), "rb") as s:
                        o.unpack(s)
                    for e in o["elements"]:
                        if e["type"].data == "DmeParticleSystemDefinition" and e["name"].data.lower() == replacement_system:
                            psd.attribute.data = e.attribute.data
                            break
                    else:
                        assert False, "Could not find system {} in file {}".format(replacement_system, replacement_file)

                del replacements[name]
Exemple #6
0
def main(src, dest):
    p = PCF()
    with open(src, "rb") as s:
        p.unpack(s)
    p.minimize()
    main_element = p["elements"][0]
    assert main_element["type"].data == "DmElement"
    assert len(main_element.attribute) == 1
    main_attribute = main_element.attribute[0]
    assert main_attribute["name"].data == "particleSystemDefinitions"
    assert main_attribute["type"].data == 15
    psdl = main_attribute["data"]
    for i in range(len(psdl)):
        psd = psdl[i].data
        recursive_edit(psd, psdl)

    with open(dest, "wb") as s:
        p.full_pack(s)
Exemple #7
0
def fix_particles(d, defaults, default_ids, visuals, sockets, units, npc_heroes):
    visuals, particle_replacements = get_particle_replacements(d, defaults, visuals, sockets, default_ids)

    particle_file_systems = get_particle_file_systems(d, units, npc_heroes)

    particlesystem_files = {}
    for file, systems in particle_file_systems.items():
        for system in systems:
            particlesystem_files.setdefault(system, [])
            particlesystem_files[system].append(file)

    file_replacements = OrderedDict()
    for system, default_system in particle_replacements.items():
        if system not in particlesystem_files:
            print("Warning: system '{}' is not in any particle file".format(system), file=stderr)
            continue
        system_files = particlesystem_files[system]
        if default_system is None:
            default_system_files = []
        else:
            default_system_files = particlesystem_files.get(default_system, [])
            if default_system_files == []:
                if "_active" in default_system or "_passive" in default_system:
                    # pseudo-system for item triggered particle effects
                    pass
                else:
                    print("Warning: default system '{}' is not in any particle file".format(default_system), file=stderr)

        for file in system_files:
            file_replacements.setdefault(file, OrderedDict())
            if default_system_files == []:
                file_replacements[file][system] = None
            else:
                # TODO: figure out the right choice when len(default_system_files) > 1
                file_replacements[file][system] = (default_system_files[0], default_system)

    for file, replacements in file_replacements.items():
        print("{}:".format(file))
        for system, replacement in replacements.items():
            if replacement is None:
                print("\t{} -> None".format(system))
            else:
                replacement_file, replacement_system = replacement
                print("\t{} -> {} ({})".format(system, replacement_system, replacement_file))

        p = PCF()
        with open(dota_file(file), "rb") as s:
            p.unpack(s)
        p.minimize()
        main_element = p["elements"][0]
        assert main_element["type"].data == "DmElement"
        assert len(main_element.attribute) == 1
        main_attribute = main_element.attribute[0]
        assert main_attribute["name"].data == "particleSystemDefinitions"
        assert main_attribute["type"].data == 15
        psdl = main_attribute["data"]
        for i in range(len(psdl)):
            psd = psdl[i].data
            assert psd["type"].data == "DmeParticleSystemDefinition"
            name = psd["name"].data
            if name in replacements:
                if replacements[name] is None:
                    psd.attribute.data = []
                else:
                    replacement_file, replacement_system = replacements[name]
                    o = PCF()
                    with open(dota_file(replacement_file), "rb") as s:
                        o.unpack(s)
                    for e in o["elements"]:
                        if e["type"].data == "DmeParticleSystemDefinition" and e["name"].data == replacement_system:
                            psd.attribute.data = e.attribute.data
                            break
                del replacements[name]
        assert not replacements

        if nohats_dir:
            dest = nohats_file(file)
            dest_dir = dirname(dest)
            if not exists(dest_dir):
                makedirs(dest_dir)
            with open(dest, "wb") as s:
                p.full_pack(s)
        else:
            s = FakeWriteStream(0, file)
            p.full_pack(s)

    return visuals
Exemple #8
0
def main():
    parser = ArgumentParser(
        description="Replace or delete particle systems in particle files")
    parser.add_argument("output_file",
                        type=FileType("wb"),
                        help="Output file, e.g. output.pcf")
    parser.add_argument("input_file",
                        type=FileType("rb"),
                        help="Input file, e.g. input.pcf")
    parser.add_argument(
        "--delete",
        "-d",
        action="append",
        metavar="NAME",
        default=[],
        help="Replace particle system NAME with an empty particle system.")
    parser.add_argument(
        "--replace",
        "-r",
        nargs=3,
        action="append",
        metavar=("NAME", "SOURCE_FILE", "SOURCE_NAME"),
        help=
        "Replace particle system NAME with particle system SOURCE_NAME from SOURCE_FILE.",
        default=[])
    parser.add_argument(
        "--file",
        "-f",
        type=FileType("r"),
        help=
        "Read the lines of FILE for commands. Line format: COMMAND NAME [SOURCE_FILE SOURCE_NAME], where COMMAND is delete or replace."
    )
    args = parser.parse_args()

    replacements = OrderedDict()

    def add_replacement(name, r):
        assert name not in replacements, "Double definition for particle system {}".format(
            name)
        replacements[name] = r

    for name in args.delete:
        add_replacement(name, None)
    for (name, source_file, source_name) in args.replace:
        add_replacement(name, (source_file, source_name))

    if args.file:
        for line in args.file:
            l = line.split()
            assert len(l) >= 1, "No command in line: {}".format(line)
            command = l[0]

            if command == "delete":
                assert len(
                    l) == 2, "Wrong number of arguments in line: {}".format(
                        line)
                add_replacement(l[1], None)
            elif command == "replace":
                assert len(
                    l) == 4, "Wrong number of arguments in line: {}".format(
                        line)
                add_replacement(l[1], (expanduser(l[2]), l[3]))
            else:
                assert False, "Invalid command {} in line: {}".format(
                    command, line)

    p = PCF()
    p.unpack(args.input_file)
    p.minimize()

    main_element = p["elements"][0]
    assert main_element["type"].data == "DmElement"
    assert len(main_element.attribute) == 1
    main_attribute = main_element.attribute[0]
    assert main_attribute["name"].data == "particleSystemDefinitions"
    assert main_attribute["type"].data == 15
    psl = main_attribute["data"]
    for ps in psl:
        psd = ps.data
        assert psd["type"].data == "DmeParticleSystemDefinition"
        name = psd["name"].data.lower()
        if name in replacements:
            if replacements[name] is None:
                psd.attribute.data = []
            else:
                replacement_file, replacement_system = replacements[name]
                o = PCF()
                with open(replacement_file, "rb") as s:
                    o.unpack(s)
                for e in o["elements"]:
                    if e["type"].data == "DmeParticleSystemDefinition" and e[
                            "name"].data.lower() == replacement_system:
                        psd.attribute.data = e.attribute.data
                        break
                else:
                    assert False, "Could not find system {} in file {}".format(
                        replacement_system, replacement_file)

            del replacements[name]

    p.full_pack(args.output_file)