File: vehicleDef.py

package info (click to toggle)
cataclysm-dda 0.H-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 710,808 kB
  • sloc: cpp: 524,019; python: 11,580; sh: 1,228; makefile: 1,169; xml: 507; javascript: 150; sql: 56; exp: 41; perl: 37
file content (128 lines) | stat: -rwxr-xr-x 3,501 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python3

import json
import argparse
from math import hypot
import re
import os

args = argparse.ArgumentParser(
    description="Generate a json definition for a vehicle "
    "in a Cataclysm DDA save file.")
args.add_argument(
    "save", action="store", help="specify save file containing vehicle")
args.add_argument(
    "vehicle", nargs="?", help="specify name of vehicle", default=None)
argsDict = vars(args.parse_args())


def writeVehicleTemplates(templates):
    with open("vehicles.json", "w", encoding="utf-8") as vehicleDefJson:
        json.dump(templates, vehicleDefJson, indent=4, ensure_ascii=False)
        print("Vehicle defs written.")


def getVehicleTemplates():
    vehicles = []
    for root, directories, filenames in os.walk(argsDict["save"]):
        for filename in filenames:
            path = os.path.join(root, filename)
            if path.endswith(".map"):
                vehicles += getVehicleInstances(path)

    allTemplates = []
    for vehicle in vehicles:
        vehicleDef = buildVehicleDef(vehicle)
        if vehicleDef not in allTemplates:
            allTemplates.append(vehicleDef)

    return allTemplates


def getVehicleInstances(mapPath):
    vehicles = []
    with open(mapPath, encoding="utf-8") as mapFile:
        mapData = json.load(mapFile)
        for i in range(0, len(mapData)):
            for vehicle in mapData[i]["vehicles"]:
                if argsDict["vehicle"] is not None:
                    if argsDict["vehicle"] == vehicle["name"]:
                        vehicles.append(vehicle)
                        print(f"Found \"{vehicle['name']}\"")
                else:
                    vehicles.append(vehicle)
                    print(f"Found \"{vehicle['name']}\"")

    return vehicles


def buildVehicleDef(vehicle):
    partsDef = []
    itemsDef = []
    for part in vehicle["parts"]:
        part_variant = ""
        if "variant" in part:
            part_variant = "_" + part["variant"]

        partsDef.append({
            "x": part["mount_dx"],
            "y": part["mount_dy"],
            "part": part["id"] + part_variant
        })

        for item in part["items"]:
            itemsDef.append({
                "x": part["mount_dx"],
                "y": part["mount_dy"],
                "chance": 100,
                "items": [item["typeid"]]
            })

    frames = [
        p for p in partsDef
        if re.match(r'(xl|hd|folding_)?frame', p["part"]) is not None
    ]
    everythingElse = [
        p for p in partsDef
        if re.match(r'(xl|hd|folding_)?frame', p["part"]) is None
    ]

    frames = sortFrames(frames)

    itemsDef.sort(key=lambda i: (i["x"], i["y"]))

    vehicleDef = {
        "id": vehicle["name"],
        "type": "vehicle",
        "name": vehicle["name"],
        "parts": frames + everythingElse,
        "items": itemsDef
    }

    return vehicleDef


def sortFrames(frames):
    sortedFrames = []
    sortedFrames.append(frames.pop())

    while len(frames) > 0:
        nextFrame = frames.pop()
        found = False
        for lastFrame in sortedFrames:
            if adjacent(lastFrame, nextFrame):
                sortedFrames.append(nextFrame)
                found = True
                break

        if not found:
            frames.insert(0, nextFrame)

    return sortedFrames


def adjacent(frame1, frame2):
    return hypot(frame1["x"] - frame2["x"], frame1["y"] - frame2["y"]) == 1


writeVehicleTemplates(getVehicleTemplates())