parent
569a44307e
commit
2f48ac6fd2
218
dodo.py
218
dodo.py
@ -1,77 +1,151 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from yaml import safe_load
|
from doit import get_var
|
||||||
|
|
||||||
|
DOIT_CONFIG = {
|
||||||
|
'default_tasks': ['build'],
|
||||||
|
'action_string_formatting': 'new'
|
||||||
|
}
|
||||||
|
|
||||||
def files(p):
|
def files(p):
|
||||||
for i in p:
|
for i in p:
|
||||||
if i.is_file():
|
if i.is_file():
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
|
class RawFiles(list):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.src_path = Path(kwargs.pop('src_path'))
|
||||||
|
self.image_path = Path(kwargs.pop('image_path'))
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Patchwork(dict):
|
def sources(self):
|
||||||
|
for i in self:
|
||||||
|
yield self.src_path/i
|
||||||
|
def targets(self):
|
||||||
|
for i in self:
|
||||||
|
yield self.image_path/i
|
||||||
|
|
||||||
|
class BasePatchwork(dict):
|
||||||
patches_path = None
|
patches_path = None
|
||||||
patchwork_path = None
|
patchwork_path = None
|
||||||
|
vanilla_path = None
|
||||||
def __init__(self, *arkg, **kwargs):
|
def __init__(self, *arkg, **kwargs):
|
||||||
self.patches_path = Path(kwargs.pop("patches_path"))
|
self.patches_path = Path(kwargs.pop('patches_path'))
|
||||||
self.patchwork_path = Path(kwargs.pop("patchwork_path"))
|
self.patchwork_path = Path(kwargs.pop('patchwork_path'))
|
||||||
|
self.vanilla_path = Path(kwargs.pop('vanilla_path'))
|
||||||
super().__init__(*arkg, **kwargs)
|
super().__init__(*arkg, **kwargs)
|
||||||
patchwork_mkdir = 'mkdir -p {}/{}'
|
|
||||||
def targets(self):
|
def targets(self):
|
||||||
for i in self.keys():
|
for i in self.keys():
|
||||||
yield self.patchwork_path/i
|
yield self.patchwork_path/i
|
||||||
def tasks(self, vanilla_path):
|
def key_vanilla(self, orig_key):
|
||||||
|
return self.vanilla_path/orig_key
|
||||||
|
def key_target(self, orig_key):
|
||||||
|
return self.patchwork_path/orig_key
|
||||||
|
def tasks(self, actions):
|
||||||
|
def repack_action(action, **kwargs):
|
||||||
|
if callable(action):
|
||||||
|
return (action, [], kwargs)
|
||||||
|
elif isinstance(action, str):
|
||||||
|
return action.format(**kwargs)
|
||||||
|
else:
|
||||||
|
return action
|
||||||
for k, v in self.items():
|
for k, v in self.items():
|
||||||
yield (
|
original = self.vanilla_path/k
|
||||||
[ self.patches_path/v, vanilla_path/k ], # src ( patch file, orig file )
|
patch = self.patches_path/v
|
||||||
[ self.patchwork_path/k ], #dst ( patched file )
|
target = self.patchwork_path/k
|
||||||
[
|
yield {
|
||||||
|
'name' : k,
|
||||||
|
'file_dep' : [ original, patch ],
|
||||||
|
'targets' : [ target ],
|
||||||
|
'actions' : [ repack_action(action, original=original, patch=patch, target=target)
|
||||||
|
for action in actions ],
|
||||||
|
'clean' : True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Patchwork(BasePatchwork):
|
||||||
|
def tasks_(self, actions):
|
||||||
|
for k, v in self.items():
|
||||||
|
yield {
|
||||||
|
'name' : k,
|
||||||
|
'file_dep' : [ self.patches_path/v, self.vanilla_path/k ],
|
||||||
|
'targets' : [ self.patchwork_path/k ],
|
||||||
|
'actions' : [
|
||||||
f"mkdir -p {self.patchwork_path}/{Path(k).parent}",
|
f"mkdir -p {self.patchwork_path}/{Path(k).parent}",
|
||||||
f"patch -u --binary -N -o '{self.patchwork_path}/{k}' "\
|
f"patch -u --binary -N -o '{self.patchwork_path}/{k}' "\
|
||||||
f"'{vanilla_path}/{k}' '{self.patches_path}/{v}'"
|
f"'{self.vanilla_path}/{k}' '{self.patches_path}/{v}'"
|
||||||
] # action ( mkdir, patch )
|
], # action ( mkdir, patch )
|
||||||
)
|
'clean' : True
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ScriptedPatchwork(dict):
|
class ScriptedPatchwork(BasePatchwork):
|
||||||
def __init__(self, source_file):
|
def __init__(self, *args, **kwargs):
|
||||||
with open(source_file) as s:
|
from yaml import safe_load
|
||||||
super().__init__(safe_load(s))
|
file = kwargs.pop('source_file')
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
with open(file) as s:
|
||||||
|
for key, data in safe_load(s).items():
|
||||||
|
discovered_source = next((Path(self.vanilla_path)/'history'/'states').glob(f"{key}*"))
|
||||||
|
relative_path = discovered_source.relative_to(self.vanilla_path)
|
||||||
|
self[relative_path] = data
|
||||||
|
|
||||||
|
class RasterPatchwork(BasePatchwork):
|
||||||
|
pass
|
||||||
|
|
||||||
mod_name = 'randchgs'
|
mod_name = 'randchgs'
|
||||||
mod_install_path = 'C:/Users/User/Documents/Paradox Interactive/Hearts of Iron IV/mod/randchgs'
|
mod_install_path = get_var('descriptor_mod_path', 'C:/Users/User/Documents/Paradox Interactive/Hearts of Iron IV/mod/randchgs')
|
||||||
dir_vanilla = Path("../vanilla/v1.13.4")
|
dir_vanilla = Path(get_var('vanilla_path', '../vanilla/current'))
|
||||||
dir_image = Path('build/image')
|
dir_image = Path('build/image')
|
||||||
dir_modimage = Path(f"{dir_image}/{mod_name}")
|
dir_modimage = dir_image/mod_name
|
||||||
dir_src_raw = Path('src/raw')
|
dir_src_raw = Path('src/raw')
|
||||||
dir_src_raw_files = list(files(Path(dir_src_raw).rglob("*")))
|
dir_src_raw_files = RawFiles(
|
||||||
|
files(Path(dir_src_raw).rglob("*")),
|
||||||
|
src_path = dir_src_raw,
|
||||||
|
image_path = dir_image
|
||||||
|
)
|
||||||
dir_patches_path = Path('src/patches')
|
dir_patches_path = Path('src/patches')
|
||||||
dir_patchwork_path = Path('build/patched')
|
dir_patchwork_path = Path('build/patched')
|
||||||
|
|
||||||
patchwork = Patchwork({
|
patchwork = Patchwork(
|
||||||
|
{
|
||||||
'map/definition.csv': 'map_definition.patch',
|
'map/definition.csv': 'map_definition.patch',
|
||||||
'history/countries/ISR - Israel.txt': 'history_countries_ISR.patch',
|
'history/countries/ISR - Israel.txt': 'history_countries_ISR.patch',
|
||||||
},
|
'history/states/454-Israel.txt': 'history_states_454.patch',
|
||||||
|
},
|
||||||
patches_path = dir_patches_path,
|
patches_path = dir_patches_path,
|
||||||
patchwork_path = dir_patchwork_path
|
patchwork_path = dir_patchwork_path,
|
||||||
|
vanilla_path = dir_vanilla
|
||||||
)
|
)
|
||||||
|
|
||||||
patchwork_scripted = ScriptedPatchwork(dir_patches_path/'extrapoint.yaml')
|
patchwork_scripted = ScriptedPatchwork(
|
||||||
|
source_file = dir_patches_path/'extrapoint.yaml',
|
||||||
|
patches_path = '.',
|
||||||
|
patchwork_path = dir_patchwork_path,
|
||||||
|
vanilla_path = dir_vanilla
|
||||||
|
)
|
||||||
|
|
||||||
dir_image_files = [ f"{dir_modimage}/{f.relative_to(dir_src_raw)}" for f in dir_src_raw_files ] + \
|
patchwork_raster = RasterPatchwork(
|
||||||
[ f"{dir_modimage}/{f.relative_to(patchwork.patchwork_path)}" for f in patchwork.targets() ]
|
{
|
||||||
|
'map/terrain.bmp' : 'terrain.bmp',
|
||||||
|
},
|
||||||
|
patches_path = dir_patches_path,
|
||||||
|
patchwork_path = dir_patchwork_path,
|
||||||
|
vanilla_path = dir_vanilla
|
||||||
|
)
|
||||||
|
|
||||||
DOIT_CONFIG = {
|
|
||||||
'default_tasks': ['build'],
|
|
||||||
'action_string_formatting': 'both'
|
|
||||||
}
|
|
||||||
|
|
||||||
def history_states_path(state_id):
|
def collect_image_files(patchworks, dir_modimage):
|
||||||
history_state_file = next((Path(dir_vanilla)/'history'/'states').glob(f"{state_id}*"))
|
for pw in patchworks:
|
||||||
return {
|
for target in pw:
|
||||||
'src' : history_state_file,
|
yield dir_modimage/target
|
||||||
'dest': Path(dir_patchwork_path)/history_state_file.relative_to(dir_vanilla)
|
dir_image_files = list(collect_image_files(
|
||||||
}
|
[patchwork, patchwork_scripted, patchwork_raster],
|
||||||
|
dir_modimage=dir_modimage
|
||||||
|
))
|
||||||
|
dir_image_files += [ dir_modimage/f.relative_to(dir_src_raw) for f in dir_src_raw_files ]
|
||||||
|
|
||||||
|
|
||||||
def task_patch_history_states_scripted():
|
def task_patch_history_states_scripted():
|
||||||
def history_state_patch(task, provinces):
|
def history_state_patch(task, provinces):
|
||||||
@ -80,8 +154,7 @@ def task_patch_history_states_scripted():
|
|||||||
target.parent.mkdir(parents=True, exist_ok=True)
|
target.parent.mkdir(parents=True, exist_ok=True)
|
||||||
seen_history = False
|
seen_history = False
|
||||||
wrote_history = False
|
wrote_history = False
|
||||||
with source.open(newline='') as infile:
|
with source.open(newline='') as infile, target.open('w') as outfile:
|
||||||
with target.open('w') as outfile:
|
|
||||||
for line_in in infile:
|
for line_in in infile:
|
||||||
outfile.write(line_in)
|
outfile.write(line_in)
|
||||||
seen_history = seen_history or ( 'history' in line_in )
|
seen_history = seen_history or ( 'history' in line_in )
|
||||||
@ -93,33 +166,48 @@ def task_patch_history_states_scripted():
|
|||||||
"\t\t}\r\n"\
|
"\t\t}\r\n"\
|
||||||
)
|
)
|
||||||
wrote_history = True
|
wrote_history = True
|
||||||
for state_id, state_data in patchwork_scripted.items():
|
for state_src, state_data in patchwork_scripted.items():
|
||||||
files = history_states_path(state_id)
|
|
||||||
yield {
|
yield {
|
||||||
'name' : f"{state_id}",
|
'name' : state_src,
|
||||||
'file_dep' : [ files['src'] ],
|
'file_dep' : [ patchwork_scripted.key_vanilla(state_src) ],
|
||||||
'targets' : [ files['dest'] ],
|
'targets' : [ patchwork_scripted.key_target(state_src) ],
|
||||||
'actions' : [ ( history_state_patch, [], {'provinces' : state_data}) ],
|
'actions' : [ ( history_state_patch, [], {'provinces' : state_data}) ],
|
||||||
'clean' : True
|
'clean' : True
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def task_patch_raster():
|
||||||
|
def raster_patch(target, original, patch):
|
||||||
|
from PIL import Image
|
||||||
|
with Image.open(original) as base, Image.open(patch) as patch:
|
||||||
|
def mask():
|
||||||
|
for bg, p in zip(base.tobytes(), patch.tobytes()):
|
||||||
|
if p == 35:
|
||||||
|
yield bg
|
||||||
|
else:
|
||||||
|
yield p
|
||||||
|
|
||||||
|
output = Image.frombytes(base.mode, base.size, bytes(mask()))
|
||||||
|
output.putpalette(base.palette)
|
||||||
|
output.save(target)
|
||||||
|
output.close()
|
||||||
|
|
||||||
|
yield from patchwork_raster.tasks([raster_patch])
|
||||||
|
|
||||||
def task_patch():
|
def task_patch():
|
||||||
for src, dest, patch in patchwork.tasks(dir_vanilla):
|
def mkdir(target, original, patch):
|
||||||
yield {
|
Path(target).parent.mkdir(parents=True, exist_ok=True)
|
||||||
'name' : f"{dest[0]}",
|
yield from patchwork.tasks([
|
||||||
'file_dep' : src,
|
mkdir,
|
||||||
'targets' : dest,
|
"patch -u --binary -N -o '{target}' '{original}' '{patch}'"
|
||||||
'actions' : patch,
|
])
|
||||||
'clean' : True
|
|
||||||
}
|
|
||||||
|
|
||||||
def task_image():
|
def task_image():
|
||||||
filelist = dir_src_raw_files + list(patchwork.targets())
|
filelist = dir_src_raw_files + \
|
||||||
|
list(patchwork.targets()) + \
|
||||||
|
list(patchwork_scripted.targets()) + \
|
||||||
|
list(patchwork_raster.targets())
|
||||||
return {
|
return {
|
||||||
'file_dep' : filelist +
|
'file_dep' : filelist,
|
||||||
[ history_states_path(state_id)['dest']
|
|
||||||
for state_id in patchwork_scripted.keys() ],
|
|
||||||
'targets' : dir_image_files,
|
'targets' : dir_image_files,
|
||||||
'actions' : [f"mkdir -p {dir_modimage}",
|
'actions' : [f"mkdir -p {dir_modimage}",
|
||||||
f"rsync -rv {dir_src_raw}/ {patchwork.patchwork_path}/"\
|
f"rsync -rv {dir_src_raw}/ {patchwork.patchwork_path}/"\
|
||||||
@ -128,7 +216,6 @@ def task_image():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def task_image_mod():
|
def task_image_mod():
|
||||||
dep = 'src/raw/descriptor.mod'
|
|
||||||
def prepare_modname_mod(task):
|
def prepare_modname_mod(task):
|
||||||
source = Path(next(iter(task.file_dep)))
|
source = Path(next(iter(task.file_dep)))
|
||||||
target = Path(task.targets[0])
|
target = Path(task.targets[0])
|
||||||
@ -136,9 +223,9 @@ def task_image_mod():
|
|||||||
with source.open() as s:
|
with source.open() as s:
|
||||||
with target.open('w') as o:
|
with target.open('w') as o:
|
||||||
o.write(s.read())
|
o.write(s.read())
|
||||||
o.write(f"path=\"{mod_install_path}\"")
|
o.write(f"\npath=\"{mod_install_path}\"\n")
|
||||||
return {
|
return {
|
||||||
'file_dep' : [ dep ],
|
'file_dep' : [ 'src/raw/descriptor.mod' ],
|
||||||
'targets' : [f"{dir_image}/{mod_name}.mod" ],
|
'targets' : [f"{dir_image}/{mod_name}.mod" ],
|
||||||
'actions' : [ prepare_modname_mod ],
|
'actions' : [ prepare_modname_mod ],
|
||||||
'clean' : True
|
'clean' : True
|
||||||
@ -146,15 +233,10 @@ def task_image_mod():
|
|||||||
|
|
||||||
def task_build():
|
def task_build():
|
||||||
return {
|
return {
|
||||||
'task_dep' : [ 'image' ],
|
|
||||||
'file_dep' : [f"{dir_image}/{mod_name}.mod" ] + dir_image_files,
|
'file_dep' : [f"{dir_image}/{mod_name}.mod" ] + dir_image_files,
|
||||||
'targets' : [f"{dir_image}/{mod_name}.zip" ],
|
'targets' : [f"{dir_image}/{mod_name}.zip" ],
|
||||||
'actions' : [f"cd {dir_image} && zip -r {mod_name}.zip {mod_name}",
|
'actions' : [ "rm -f %(targets)s",
|
||||||
|
f"cd {dir_image} && zip -r {mod_name}.zip {mod_name}",
|
||||||
f"cd {dir_image} && zip -r {mod_name}.zip {mod_name}.mod" ],
|
f"cd {dir_image} && zip -r {mod_name}.zip {mod_name}.mod" ],
|
||||||
'clean' : True
|
'clean' : [ 'rm -rf build' ]
|
||||||
}
|
|
||||||
|
|
||||||
def task_purge_build():
|
|
||||||
return {
|
|
||||||
'actions' : [ 'rm -rf build' ]
|
|
||||||
}
|
}
|
||||||
|
42
src/patches/history_states_454.patch
Normal file
42
src/patches/history_states_454.patch
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
--- ../vanilla/v1.13.4/history/states/454-Israel.txt 2023-11-12 00:08:53.206004927 +0400
|
||||||
|
+++ build/patched/history/states/454-Israel.txt 2023-11-16 13:23:39.618844427 +0400
|
||||||
|
@@ -4,7 +4,13 @@
|
||||||
|
name="STATE_454" #Palestine
|
||||||
|
manpower = 933142
|
||||||
|
|
||||||
|
- state_category = rural
|
||||||
|
+ state_category = metropolis
|
||||||
|
+
|
||||||
|
+ resources={
|
||||||
|
+ steel = 15
|
||||||
|
+ tungsten = 10
|
||||||
|
+ aluminium = 15
|
||||||
|
+ }
|
||||||
|
|
||||||
|
history={
|
||||||
|
owner = ENG
|
||||||
|
@@ -17,7 +23,7 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
victory_points = {
|
||||||
|
- 1086 1
|
||||||
|
+ 1086 10
|
||||||
|
}
|
||||||
|
victory_points = {
|
||||||
|
4206 1
|
||||||
|
@@ -25,6 +31,9 @@
|
||||||
|
victory_points = {
|
||||||
|
1065 1
|
||||||
|
}
|
||||||
|
+ victory_points = {
|
||||||
|
+ 1015 1
|
||||||
|
+ }
|
||||||
|
add_core_of = PAL
|
||||||
|
add_core_of = ISR
|
||||||
|
}
|
||||||
|
@@ -34,4 +43,5 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
local_supplies=0.0
|
||||||
|
+ manpower = 7527019
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
state={
|
|
||||||
id=454
|
|
||||||
name="STATE_454" #Palestine
|
|
||||||
manpower = 933142
|
|
||||||
|
|
||||||
state_category = metropolis
|
|
||||||
|
|
||||||
resources={
|
|
||||||
steel = 15
|
|
||||||
tungsten = 10
|
|
||||||
aluminium = 15
|
|
||||||
}
|
|
||||||
|
|
||||||
history={
|
|
||||||
owner = ENG
|
|
||||||
buildings = {
|
|
||||||
infrastructure = 3 #was: 5
|
|
||||||
industrial_complex = 1
|
|
||||||
air_base = 2
|
|
||||||
4206 = {
|
|
||||||
naval_base = 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
victory_points = {
|
|
||||||
1086 10
|
|
||||||
}
|
|
||||||
victory_points = {
|
|
||||||
4206 1
|
|
||||||
}
|
|
||||||
victory_points = {
|
|
||||||
1065 1
|
|
||||||
}
|
|
||||||
victory_points = {
|
|
||||||
1015 1
|
|
||||||
}
|
|
||||||
add_core_of = PAL
|
|
||||||
add_core_of = ISR
|
|
||||||
}
|
|
||||||
|
|
||||||
provinces={
|
|
||||||
1015 1065 1086 1201 4088 4206 7107 7176 11970 1
|
|
||||||
}
|
|
||||||
|
|
||||||
local_supplies=0.0
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user