Integrate delivered HQ memory, finite physical convoy and RHS WCS dependencies

This commit is contained in:
2026-09-20 02:55:30 +02:00
parent e7b4141f69
commit a2aab17171
230 changed files with 37976 additions and 139 deletions
+9 -5
View File
@@ -16,6 +16,7 @@ sys.dont_write_bytecode = True
from source_manifest import addon_manifest
from project_schema import parse_project
from external_addons import policy as external_policy, direct_for, resource_allowed, ALLOWED
from release_check import audit, read_json, evidence_path
ROOT = Path(__file__).resolve().parents[1]
@@ -35,7 +36,7 @@ README = '''# DEVELOPMENT SOURCE BUNDLE — Escapists Rereintroduced
This ZIP contains authored source and editable resources for all five successor
addon projects. It is NOT a native .pak, a qualified release, or a published mod.
No original Escapists or installed vanilla assets are redistributed. Vanilla asset
No original Escapists, installed vanilla or third-party assets are redistributed. Vanilla asset
references require a separately installed, compatible Arma Reforger and Workbench.
Extract into a NEW development folder, never over an existing mission/project.
@@ -50,7 +51,7 @@ Companion scenario: {C1E20667DCE324ED}Missions/ERR_Everon.conf
Use the installed engine's normal project/scenario workflow. This archive has not
been compiled by its bundler; no native caches or binaries are included.
Target: vanilla Everon, up to 12 players. This remains development source.
Target: Everon, up to 12 players; Core is vanilla-only and full AI requires the listed external addons. This remains development source.
Manual prison/scavenging/radio/extraction play, remote joins/reconnects and
ownership, twelve connected players, aircraft support, repeated companion cleanup,
matched-workload FPS improvement and release qualification require separate
@@ -120,13 +121,14 @@ def inventory(root):
def validate(payload, root):
projects = {}
external = external_policy(root)
own_ids = read_json(evidence_path(root, 'docs/addons.json'))
if own_ids != {name: item[1] for name, item in PROJECTS.items()}:
raise ValueError('successor identity catalog differs from the five owned projects')
for name, (identity, guid, deps) in PROJECTS.items():
text = payload.get(f'addons/{name}/addon.gproj', b'').decode('utf-8')
match = parse_project(text, allow_core_menu=name == 'core')
expected = {BASE, *(PROJECTS[d][1] for d in deps)}
expected = {BASE, *(PROJECTS[d][1] for d in deps), *direct_for(name)}
found = re.findall(r'"([A-F0-9]{16})"', match[4]) if match else []
if not match or match[1] != identity or match[2] != guid or set(found) != expected or len(found) != len(expected):
raise ValueError(f'identity/dependency closure mismatch: {name}')
@@ -156,12 +158,13 @@ def validate(payload, root):
raise ValueError(f'resource lacks successor metadata: {name}')
owner = name.split('/')[1]
visible = {owner, *PROJECTS[owner][2]}
if 'ai' in visible: visible.update(ALLOWED)
for guid, resource in re.findall(r'\{([A-F0-9]{16})\}([^"\n]+)', text):
if guid in resources:
path, target = resources[guid]
if path != resource or target not in visible:
raise ValueError(f'resource outside project dependency closure: {name}')
elif vanilla.get(resource) != guid:
elif vanilla.get(resource) != guid and not resource_allowed(external,visible,guid,resource):
raise ValueError(f'unresolved or nonvanilla resource: {name}')
return projects
@@ -185,7 +188,8 @@ def build(root=ROOT, mode='development'):
raise ValueError('Not release-qualified after collection:\n - ' + '\n - '.join(blockers))
if inventory(root) != before:
raise ValueError('addon tree changed during collection')
payload['BUNDLE-README.md'] = README.encode('utf-8')
payload['BUNDLE-README.md'] = (README + '\nThe AI/full scenario requires the separately installed authorized addons listed in EXTERNAL-ADDONS.json. Their assets are not bundled. Core remains vanilla-only.\n').encode('utf-8')
payload['EXTERNAL-ADDONS.json'] = json.dumps(external_policy(root),indent=2,sort_keys=True).encode('utf-8')
manifest = {'schema_version': 1, 'kind': 'DEVELOPMENT SOURCE BUNDLE',
'native_build': False, 'release_package': False, 'projects': projects,
'files': {name: hashlib.sha256(data).hexdigest() for name, data in sorted(payload.items())}}