127 lines
4.8 KiB
Python
127 lines
4.8 KiB
Python
|
|
from __future__ import print_function
|
|
import os.path as path
|
|
import subprocess, tarfile
|
|
import os
|
|
walk_dir = os.walk
|
|
|
|
Import("env platform data_dir install_dir")
|
|
|
|
# Data
|
|
|
|
env.Install(path.join(data_dir, "cursors"), Glob("cursors/*.gif"))
|
|
env.Install(path.join(data_dir, "dialogs"), Glob("dialogs/*.xml"))
|
|
env.Install(path.join(data_dir, "fonts"), Glob("fonts/*.ttf") + Glob("fonts/*.bdf"))
|
|
env.Install(path.join(data_dir, "graphics"), Glob("graphics/*.png"))
|
|
env.Install(path.join(data_dir, "sounds"), Glob("sounds/*.wav"))
|
|
env.Install(path.join(data_dir, "strings"), Glob("strings/*.txt"))
|
|
|
|
env.Install(path.join(data_dir, "shaders"), Glob("#src/gfx/mask.*"))
|
|
|
|
# Scenarios
|
|
|
|
def scenario_changed(header, target, prev_ni, _repo_node):
|
|
'''Decide whether to repackage a scenario'''
|
|
if not path.exists(str(target)): return True
|
|
last_packaged = path.getmtime(str(target))
|
|
scen_dir = path.dirname(str(header))
|
|
for dir, _, files in walk_dir(scen_dir):
|
|
for fname in files:
|
|
fname = path.join(dir, fname)
|
|
last_modified = path.getmtime(fname)
|
|
if last_modified > last_packaged:
|
|
print(f'{fname} is newer than {target} ({path.getmtime(fname)} > {last_packaged})')
|
|
return True
|
|
return False
|
|
|
|
def pack_scenario(target, source, env):
|
|
prev_dir = path.abspath('.')
|
|
for i in range(min(len(target), len(source))):
|
|
abspath = path.dirname(source[i].abspath)
|
|
with tarfile.open(target[i].abspath, 'w:gz') as tar:
|
|
for dir, subdirs, files in walk_dir(abspath):
|
|
cur_dir = dir.replace(abspath, 'scenario')
|
|
for fname in files:
|
|
if fname.startswith('.'): continue
|
|
cur_file = path.join(cur_dir, fname)
|
|
tar.add(path.join(dir, fname), arcname = cur_file)
|
|
scen_env = env.Clone()
|
|
scen_env.Append(BUILDERS={"BuildScenario": Builder(action=pack_scenario, suffix=".boes", src_suffix="")})
|
|
|
|
scen_env.Decider(scenario_changed)
|
|
scen_env.BuildScenario('#build/rsrc/bases/bladbase.boes', 'bases/bladbase/header.exs')
|
|
scen_env.BuildScenario('#build/rsrc/bases/cavebase.boes', 'bases/cavebase/header.exs')
|
|
scen_env.BuildScenario('#build/rsrc/scenarios/busywork.boes', 'scenarios/busywork/header.exs')
|
|
scen_env.BuildScenario('#build/rsrc/scenarios/valleydy.boes', 'scenarios/valleydy/header.exs')
|
|
scen_env.BuildScenario('#build/rsrc/scenarios/stealth.boes', 'scenarios/stealth/header.exs')
|
|
scen_env.BuildScenario('#build/rsrc/scenarios/zakhazi.boes', 'scenarios/zakhazi/header.exs')
|
|
|
|
env.Install(path.join(install_dir, "Blades of Exile Scenarios"), Glob("#build/rsrc/scenarios/*.boes"))
|
|
env.Install(path.join(install_dir, "Blades of Exile Base"), Glob("#build/rsrc/bases/*.boes"))
|
|
|
|
# Validate dialogs
|
|
|
|
have_xmllint = False
|
|
|
|
if str(platform) == "win32":
|
|
have_xmllint = (subprocess.call(['where', '/Q', 'xmllint']) == 0)
|
|
else:
|
|
check_xmllint = subprocess.run(['which', 'xmllint'], capture_output=True)
|
|
have_xmllint = (check_xmllint.returncode == 0 and len(check_xmllint.stdout) != 0)
|
|
|
|
if have_xmllint:
|
|
xmllint_command = ('xmllint', '--nonet', '--noout', '--schema', '../schemas/dialog.xsd')
|
|
else:
|
|
print('xmllint not found! skipping xmllint step')
|
|
|
|
if have_xmllint: # This is separate so that alternate xml validators could be used
|
|
def validate_dialog(target, source, env):
|
|
PIPE = subprocess.PIPE
|
|
with open(target[0].abspath, 'w') as log:
|
|
src_name = path.basename(source[0].path)
|
|
cmd_line = xmllint_command + (src_name,)
|
|
print(*cmd_line)
|
|
p = subprocess.Popen(cmd_line,
|
|
stdin=PIPE, stdout=PIPE, stderr=PIPE,
|
|
cwd=source[0].Dir('.').abspath
|
|
)
|
|
out, err = p.communicate()
|
|
print(err, end='')
|
|
print(err, file=log)
|
|
return p.returncode
|
|
# We use these .log files as dummy targets, basically (though they also store the validation results)
|
|
env.Append(BUILDERS={"ValidateDialogXml": Builder(action=validate_dialog,suffix='.log',src_suffix='.xml')})
|
|
for dlg in Glob('dialogs/*.xml'):
|
|
dlg = path.basename(dlg.path).split('.')[0]
|
|
env.ValidateDialogXml(path.join("#build/dialogs", dlg), path.join("dialogs", dlg))
|
|
else:
|
|
print("Note: Skipping XML dialog validation since no validator tool was found.")
|
|
|
|
# Assign custom icons
|
|
|
|
if str(platform) == "darwin":
|
|
def set_dir_icon(env, target, source):
|
|
env.Command(target, source, action = [
|
|
Mkdir("build/rsrc/icons"),
|
|
"sips -i $SOURCE --out build/rsrc/icons/${SOURCE.file}",
|
|
"DeRez -only icns build/rsrc/icons/${SOURCE.file} > \
|
|
build/rsrc/icons/${SOURCE.filebase}.rsrc",
|
|
"Rez -append build/rsrc/icons/${SOURCE.filebase}.rsrc -o $TARGET",
|
|
"SetFile -a C ${TARGET.dir}",
|
|
"chflags hidden $TARGET",
|
|
])
|
|
env.AddMethod(set_dir_icon, "SetDirIcon")
|
|
icons = {
|
|
'': 'boeresources.icns',
|
|
'dialogs/': 'boeresources.icns',
|
|
'strings/': 'boeresources.icns',
|
|
'cursors/': 'boegraphics.icns',
|
|
'graphics/': 'boegraphics.icns',
|
|
'sounds/': 'boesounds.icns',
|
|
}
|
|
for dir, icon in icons.items():
|
|
env.SetDirIcon(
|
|
path.join("#build/Blades of Exile/data", dir, 'Icon\r'),
|
|
path.join("icons/mac/", icon)
|
|
)
|