Skip to content

Commit d3c2335

Browse files
committed
v2.2.10: Modify Ammo advanced editor, ATV camera distance, check for update on startup, some bugfixes
1 parent 0557126 commit d3c2335

24 files changed

Lines changed: 675 additions & 279 deletions

modbuilder.spec

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,34 @@
11
# modbuilder.spec
2+
# -*- mode: python ; coding: utf-8 -*-
3+
4+
import os
5+
6+
REPO_ROOT = os.path.abspath(os.getcwd())
7+
SCRIPT_PATH = os.path.join(REPO_ROOT, "modbuilder.py")
8+
9+
datas = [
10+
(os.path.join(REPO_ROOT, "modbuilder/org"), "org"),
11+
(os.path.join(REPO_ROOT, "modbuilder/plugins/*.py"), "plugins"),
12+
(os.path.join(REPO_ROOT, "modbuilder/saves"), "saves"),
13+
(os.path.join(REPO_ROOT, "modbuilder/name_map.yaml"), "."),
14+
(os.path.join(REPO_ROOT, "deca/*.py"), "deca"),
15+
]
216

317
a = Analysis(
4-
['modbuilder.py'],
5-
pathex=['.'],
18+
[SCRIPT_PATH],
19+
pathex=[],
620
binaries=[],
7-
datas=[
8-
('modbuilder/org', 'org'),
9-
('modbuilder/plugins/*.py', 'plugins'),
10-
('modbuilder/saves', 'saves'),
11-
('deca/*.py', 'deca'),
12-
('modbuilder/name_map.yaml', '.'),
13-
],
21+
datas=datas,
1422
hiddenimports=[],
1523
hookspath=[],
24+
hooksconfig={},
1625
runtime_hooks=[],
1726
excludes=[],
27+
noarchive=False,
28+
optimize=1,
1829
)
1930

20-
pyz = PYZ(a.pure, a.zipped_data)
31+
pyz = PYZ(a.pure)
2132

2233
exe = EXE(
2334
pyz,
@@ -31,7 +42,7 @@ exe = EXE(
3142
upx=True,
3243
console=False,
3344
disable_windowed_traceback=False,
34-
argv_emulation=True,
45+
argv_emulation=False,
3546
target_arch=None,
3647
codesign_identity=None,
3748
entitlements_file=None,
@@ -40,7 +51,6 @@ exe = EXE(
4051
coll = COLLECT(
4152
exe,
4253
a.binaries,
43-
a.zipfiles,
4454
a.datas,
4555
strip=False,
4656
upx=True,

modbuilder/gui.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import math
2+
import webbrowser
23
import textwrap
34
from importlib.metadata import version
5+
from packaging.version import Version as package_version
6+
import requests
47

58
import FreeSimpleGUI as sg
69
from deepmerge import always_merger
@@ -28,6 +31,45 @@ def _get_mods(window: sg.Window) -> None:
2831
window.set_icon(logo.value) # fix taskbar icon if it didn't load properly
2932
window.refresh()
3033

34+
def _check_for_update() -> None:
35+
release_data = _get_latest_release()
36+
if release_data:
37+
latest_tag = release_data.get("tag_name", "").lstrip("v")
38+
if package_version(latest_tag) > package_version(__version__):
39+
_show_update_popup(release_data)
40+
41+
def _get_latest_release() -> dict:
42+
try:
43+
resp = requests.get("https://api.github.com/repos/RyMaxim/cotw-mod-builder/releases/latest", timeout=5)
44+
resp.raise_for_status()
45+
data = resp.json()
46+
return data
47+
except Exception as e:
48+
logger.info(f"Check for update failed: {e}")
49+
return {}
50+
51+
def _show_update_popup(release_data: dict) -> None:
52+
nexus_url = "https://www.nexusmods.com/thehuntercallofthewild/mods/410?tab=files"
53+
github_url = release_data["html_url"]
54+
layout = [
55+
[sg.Text(f"A newer version is available!", text_color="yellow")],
56+
[sg.Text(release_data["name"])],
57+
[sg.Button("NexusMods", key="-NEXUSMODS-"), sg.Button("GitHub", key="-GITHUB-")],
58+
]
59+
60+
window = sg.Window("Update Available", layout, icon=logo.value, modal=True)
61+
while True:
62+
event, _ = window.read()
63+
if event in (sg.WINDOW_CLOSED, "Close"):
64+
break
65+
elif event == "-NEXUSMODS-":
66+
webbrowser.open(nexus_url)
67+
break
68+
elif event == "-GITHUB-":
69+
webbrowser.open(github_url)
70+
break
71+
window.close()
72+
3173
def _mod_name_to_key(name: str) -> str:
3274
if name is None:
3375
return ""
@@ -402,6 +444,7 @@ def main() -> None:
402444

403445
window = sg.Window("COTW: Mod Builder - Revived", layout, resizable=True, font=DEFAULT_FONT, icon=logo.value, size=(1300, 800), finalize=True)
404446
_get_mods(window)
447+
_check_for_update()
405448

406449
while True:
407450
event, values = window.read()

modbuilder/modbuilder.spec

Lines changed: 0 additions & 48 deletions
This file was deleted.

modbuilder/mods.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ class StatWithOffset:
6060
offset: int
6161

6262
def __init__(self, stat: AdfValue | RtpcProperty = None, value: any = None, offset: int = None) -> None:
63-
if not stat and (value is None and offset is None):
63+
if stat is None and (value is None and offset is None):
6464
raise ValueError("Cannot create object: Missing stat or value + offset")
6565

6666
if value is not None:
@@ -72,7 +72,7 @@ def __init__(self, stat: AdfValue | RtpcProperty = None, value: any = None, offs
7272
if isinstance(self.value, bytes):
7373
self.value = self.value.decode("utf-8")
7474

75-
if offset:
75+
if offset is not None:
7676
self.offset = offset
7777
elif isinstance(stat, AdfValue):
7878
self.offset = stat.data_offset
@@ -173,6 +173,21 @@ def get_mod_option(mod_key: str, option_key: str) -> dict:
173173
return option
174174
return None
175175

176+
def get_mod_option_default(option_key: str, options: dict = None, mod_key: str = None) -> float:
177+
default = None
178+
if options is None and mod_key is None:
179+
raise ValueError(f"Unable to get default value for {option_key}: no options or mod_key provided. ")
180+
if options:
181+
for option in options:
182+
if option_key == get_mod_key_from_name(option["name"]):
183+
default = option["default"]
184+
if options is None:
185+
option = get_mod_option(option_key, mod_key)
186+
default = option["default"]
187+
if default is None:
188+
raise ValueError(f"Unable to get default value for {option_key}: no matching option found")
189+
return default
190+
176191
def list_mod_files() -> list[str]:
177192
return _get_mod_filenames()
178193

modbuilder/name_map.yaml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -749,15 +749,18 @@ optic:
749749
binoculars_01:
750750
name: Vantage 8x42 Binoculars
751751

752+
camera_01:
753+
name: Camera
754+
755+
night_vision_01:
756+
name: GenZero 8x50 Night Vision
757+
752758
rangefinder_01:
753759
name: Venture 5x30 Rangefinder
754760

755761
rangefinder_binoculars_01:
756762
name: Apexview 7x42 Rangefinder Binoculars
757763

758-
night_vision_01:
759-
name: GenZero 8x50 Night Vision
760-
761764
##########
762765

763766
### Weapon names that end in identifier numbers like _01, _02, etc. are cosmetic variants of the same weapon
730 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)