Calibrate and install GPS lane weighting archive
This commit is contained in:
Executable
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from collections import Counter
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from patch_traffic_lanes import FLAGS, as_int, has_flag, looks_like_lane
|
||||
|
||||
|
||||
def visit(value: Any):
|
||||
if isinstance(value, dict):
|
||||
lanes = value.get("lanes")
|
||||
if isinstance(lanes, list) and any(looks_like_lane(lane) for lane in lanes):
|
||||
for lane in lanes:
|
||||
if looks_like_lane(lane):
|
||||
yield lane
|
||||
for child in value.values():
|
||||
yield from visit(child)
|
||||
elif isinstance(value, list):
|
||||
for child in value:
|
||||
yield from visit(child)
|
||||
|
||||
|
||||
def bucket(flags: int) -> str:
|
||||
if has_flag(flags, "Highway"):
|
||||
return "highway"
|
||||
if has_flag(flags, "Pavement"):
|
||||
return "pavement"
|
||||
if has_flag(flags, "CrossWalk"):
|
||||
return "crosswalk"
|
||||
if has_flag(flags, "Road"):
|
||||
return "road"
|
||||
return "other"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("json_file", type=Path)
|
||||
args = parser.parse_args()
|
||||
|
||||
data = json.loads(args.json_file.read_text(encoding="utf-8"))
|
||||
speeds: dict[str, Counter[int]] = {
|
||||
"all": Counter(),
|
||||
"highway": Counter(),
|
||||
"road": Counter(),
|
||||
"pavement": Counter(),
|
||||
"crosswalk": Counter(),
|
||||
"other": Counter(),
|
||||
}
|
||||
flags_counter: Counter[int] = Counter()
|
||||
|
||||
for lane in visit(data):
|
||||
flags = as_int(lane.get("flags"))
|
||||
speed = as_int(lane.get("maxSpeed"))
|
||||
if flags is None or speed is None:
|
||||
continue
|
||||
speeds["all"][speed] += 1
|
||||
speeds[bucket(flags)][speed] += 1
|
||||
flags_counter[flags] += 1
|
||||
|
||||
for name, counter in speeds.items():
|
||||
print(f"{name}: {sum(counter.values())} lanes")
|
||||
print(" " + ", ".join(f"{speed}:{count}" for speed, count in counter.most_common(20)))
|
||||
|
||||
print("top flags:")
|
||||
for flags, count in flags_counter.most_common(20):
|
||||
names = [name for name, bit in FLAGS.items() if flags & bit]
|
||||
print(f" {flags}: {count} ({', '.join(names)})")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -2,36 +2,41 @@
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 3 ]]; then
|
||||
echo "usage: $0 <game-dir> <archive-or-archive-dir> <work-dir>" >&2
|
||||
echo "usage: $0 <game-dir> <archive-or-archive-dir> <work-dir> [resource-regex] [resource-path] [mod-name]" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
game_dir=$1
|
||||
archive_path=$2
|
||||
work_dir=$3
|
||||
container=${CP77_TOOLBOX_CONTAINER:-2077}
|
||||
tool='${HOME}/.dotnet/tools/cp77tools'
|
||||
resource_regex=${4:-'all\.traffic_persistent$'}
|
||||
resource_path=${5:-'base/worlds/03_night_city/sectors/_generated/traffic/all.traffic_persistent'}
|
||||
mod_name=${6:-zz_edge_weight_gps}
|
||||
|
||||
raw_dir="${work_dir}/01_raw"
|
||||
json_dir="${work_dir}/02_json"
|
||||
patched_json_dir="${work_dir}/03_json_patched"
|
||||
patched_raw_dir="${work_dir}/04_raw_patched"
|
||||
pack_root="${work_dir}/${mod_name}"
|
||||
packed_dir="${work_dir}/05_packed"
|
||||
resource_dir=$(dirname "${resource_path}")
|
||||
resource_file=$(basename "${resource_path}")
|
||||
|
||||
mkdir -p "${raw_dir}" "${json_dir}" "${patched_json_dir}" "${patched_raw_dir}" "${packed_dir}"
|
||||
mkdir -p "${raw_dir}" "${json_dir}" "${patched_json_dir}" "${patched_raw_dir}" "${pack_root}/${resource_dir}" "${packed_dir}"
|
||||
|
||||
toolbox run --container "${container}" bash -lc \
|
||||
"${tool} extract '$archive_path' --gamepath '$game_dir' --outpath '$raw_dir' --regex 'traffic.*persistent|persistent.*traffic|traffic.*lane|world.*traffic'"
|
||||
tools/cp77_toolbox.sh extract "${archive_path}" \
|
||||
--gamepath "${game_dir}" \
|
||||
--outpath "${raw_dir}" \
|
||||
--regex "${resource_regex}"
|
||||
|
||||
toolbox run --container "${container}" bash -lc \
|
||||
"${tool} convert serialize '$raw_dir' --outpath '$json_dir'"
|
||||
tools/cp77_toolbox.sh convert serialize "${raw_dir}" --outpath "${json_dir}"
|
||||
|
||||
python3 tools/patch_traffic_lanes.py "${json_dir}" "${patched_json_dir}" --copy-unchanged
|
||||
|
||||
toolbox run --container "${container}" bash -lc \
|
||||
"${tool} convert deserialize '$patched_json_dir' --outpath '$patched_raw_dir'"
|
||||
tools/cp77_toolbox.sh convert deserialize "${patched_json_dir}" --outpath "${patched_raw_dir}"
|
||||
|
||||
toolbox run --container "${container}" bash -lc \
|
||||
"${tool} pack '$patched_raw_dir' --outpath '$packed_dir'"
|
||||
cp "${patched_raw_dir}/${resource_file}" "${pack_root}/${resource_path}"
|
||||
|
||||
tools/cp77_toolbox.sh pack "${pack_root}" --outpath "${packed_dir}"
|
||||
|
||||
echo "packed archive output: ${packed_dir}"
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
set -euo pipefail
|
||||
|
||||
container="${CP77_TOOLBOX_CONTAINER:-2077}"
|
||||
tool='${HOME}/.dotnet/tools/cp77tools'
|
||||
tool="${HOME}/.dotnet/tools/cp77tools"
|
||||
|
||||
exec toolbox run --container "${container}" bash -lc "${tool} $*"
|
||||
exec toolbox run --container "${container}" "${tool}" "$@"
|
||||
|
||||
@@ -8,11 +8,10 @@ fi
|
||||
|
||||
archive_path=$1
|
||||
output=${2:-traffic-resources.txt}
|
||||
container=${CP77_TOOLBOX_CONTAINER:-2077}
|
||||
tool='${HOME}/.dotnet/tools/cp77tools'
|
||||
|
||||
toolbox run --container "${container}" bash -lc \
|
||||
"${tool} archive --list --regex 'traffic.*persistent|persistent.*traffic|traffic.*lane|world.*traffic' '$archive_path'" \
|
||||
tools/cp77_toolbox.sh archive --list \
|
||||
--regex 'traffic.*persistent|persistent.*traffic|traffic.*lane|world.*traffic' \
|
||||
"${archive_path}" \
|
||||
> "${output}"
|
||||
|
||||
echo "wrote ${output}"
|
||||
|
||||
@@ -208,8 +208,8 @@ def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("input", type=Path, help="WolvenKit JSON file or export directory")
|
||||
parser.add_argument("output", type=Path, help="Patched JSON file or output directory")
|
||||
parser.add_argument("--highway-speed", type=int, default=90)
|
||||
parser.add_argument("--road-speed-floor", type=int, default=45)
|
||||
parser.add_argument("--highway-speed", type=int, default=25)
|
||||
parser.add_argument("--road-speed-floor", type=int, default=15)
|
||||
parser.add_argument("--non-highway-cap", type=int, default=None)
|
||||
parser.add_argument("--copy-unchanged", action="store_true")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
|
||||
Reference in New Issue
Block a user