604 lines
31 KiB
Python
604 lines
31 KiB
Python
from __future__ import annotations
|
||
import os
|
||
from constants import DLC_NAMES
|
||
from loader import (
|
||
InitialPakLoader,
|
||
LanguageLoader,
|
||
SnowrunnerGameObjectType,
|
||
TruckAddonCategory,
|
||
)
|
||
from logging import getLogger
|
||
|
||
logger = getLogger(__name__)
|
||
|
||
|
||
def get_head(language: LanguageLoader, category: str, name: str | None = None) -> str:
|
||
return f"""<!DOCTYPE html>\n<html lang='{language.Ident}'>\n""" + (
|
||
f"""
|
||
<head>
|
||
<title>SnowRunnerDB - {category}"""
|
||
+ (f""" - {name}""" if name is not None else "")
|
||
+ f"""</title>
|
||
<meta charset="utf-8">
|
||
<link rel="stylesheet" href="style.css">
|
||
<link href="https://cdn.datatables.net/v/dt/dt-3.0.1/datatables.min.css" rel="stylesheet">
|
||
<script src="https://cdn.datatables.net/v/dt/dt-3.0.1/datatables.min.js"></script>
|
||
</head>
|
||
<body>
|
||
<div id='navi_lang'></div>
|
||
<div id='categories'>
|
||
<ul id='navi_cat'>
|
||
<li><a href="/{language.Name}/trucks/">Trucks</a></li>
|
||
<li><a href="/{language.Name}/frame_addons/">Frame Addons</a></li>
|
||
<li><a href="/{language.Name}/trailers/">Trailers</a></li>
|
||
<li><a href="/{language.Name}/cargo_types/">Cargo Types</a></li>
|
||
</ul>
|
||
</div>
|
||
<div id='content'>
|
||
"""
|
||
)
|
||
|
||
|
||
def get_footer():
|
||
return f"""
|
||
</div>
|
||
</body>\n</html>\n
|
||
"""
|
||
|
||
|
||
def write_html(
|
||
file_path: str | os.PathLike, language: LanguageLoader, content: str, category: str, name: str | None = None
|
||
):
|
||
with open(file_path, "w") as f:
|
||
f.write(get_head(language=language, category=category, name=name))
|
||
f.write(content)
|
||
f.write(get_footer())
|
||
|
||
|
||
def write_trucks(pak: InitialPakLoader, destination_directory: str, language: LanguageLoader):
|
||
index_content = " <h1>Trucks</h1>\n"
|
||
index_content += f" <table id='truck_index' class='display'>\n"
|
||
index_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Class</th>\n"
|
||
f" <th>DLC</th>\n"
|
||
f" <th>Unlock by</th>\n"
|
||
f" <th>Region</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Weight</th>\n"
|
||
f" <th>Drivetrain</th>\n"
|
||
f" <th>AWD</th>\n"
|
||
f" <th>DiffLock</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
index_content += f" <tbody>\n"
|
||
|
||
for reference, truck in pak.get_sorted_object_list(SnowrunnerGameObjectType.TRUCK, language):
|
||
if truck.Type != "Truck":
|
||
continue
|
||
|
||
truck_file = os.path.join(destination_directory, reference + ".html")
|
||
truck_content = f" <h1>{truck.get_translated_ui_name(language)}</h1>"
|
||
truck_content += f" <table>\n"
|
||
try:
|
||
truck_content += f" <tr><td>DLC</td><td>{DLC_NAMES[truck.DLC]}</td></tr>\n"
|
||
except KeyError:
|
||
print(f"DEBUG: DLC {truck.DLC} for Truck {truck.get_translated_ui_name(language)}")
|
||
exit(1)
|
||
truck_content += f" <tr><td>Weight</td><td>{truck.Weight}kg</td></tr>\n"
|
||
truck_content += f" <tr><td>AWD</td><td>{language[truck.AWDInfo.value]}</td></tr>\n"
|
||
truck_content += f" <tr><td>DiffLock</td><td>{language[truck.DiffLockInfo.value]}</td></tr>\n"
|
||
truck_content += f" <tr><td>Def Engine</td><td>{truck.TruckData.DefaultEngine.get_translated_ui_name(language)}</td></tr>\n"
|
||
truck_content += f" <tr><td>Def Gearbox</td><td>{truck.TruckData.DefaultGearbox.get_translated_ui_name(language)}</td></tr>\n"
|
||
truck_content += f" <tr><td>Def Suspension</td><td>{truck.TruckData.DefaultSuspension.get_translated_ui_name(language)}</td></tr>\n"
|
||
truck_content += f" <tr><td>Def Winch</td><td>{truck.TruckData.DefaultWinch.get_translated_ui_name(language)}</td></tr>\n"
|
||
truck_content += f" <tr><td>Def Tire</td><td>{truck.TruckData.Wheels.DefaultTire.get_translated_ui_name(language)}</td></tr>\n"
|
||
truck_content += f" </table>\n"
|
||
|
||
# Engines
|
||
truck_content += f" <h2>Engines</h2>\n"
|
||
engines = [x for y in truck.TruckData.Engines for x in y.Engine]
|
||
truck_content += f" <table id='engines' data-order='[[2, \"asc\"]]'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Base Fuel Consumption</th>\n"
|
||
f" <th>Torque</th>\n"
|
||
f" <th>Power-to-Weight</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
truck_content += f" <tbody>\n"
|
||
# Power2Weight
|
||
# Power2Fuel
|
||
for engine in sorted(engines, key=lambda x: x.Torque):
|
||
truck_content += (
|
||
f" <tr>"
|
||
f" <td>{engine.get_translated_ui_name(language)}</td>"
|
||
f" <td>{engine.GameData.Price}</th>"
|
||
f" <td>{engine.GameData.get_unlock_str()}</td>"
|
||
f" <td>{engine.FuelConsumption}</td>"
|
||
f" <td>{engine.Torque}</td>"
|
||
f" <td>{engine.Torque / truck.Weight:.2f}</td>"
|
||
f" </tr>\n"
|
||
)
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
# Gearboxes
|
||
gearboxes = [y for x in truck.TruckData.Gearboxes for y in x.Gearbox]
|
||
max_gear_count = max(len(x.Gear) for x in gearboxes)
|
||
|
||
truck_content += f" <h2>Gearboxes</h2>\n"
|
||
truck_content += f" <h3>General</h3>\n"
|
||
truck_content += f" <table id='gearboxes_general'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Fine-Tunable</th>\n"
|
||
f" <th>L-</th>\n"
|
||
f" <th>L</th>\n"
|
||
f" <th>L+</th>\n"
|
||
f" <th>H</th>\n"
|
||
f" <th>Gears</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
truck_content += f" <tbody>\n"
|
||
for gearbox in sorted(gearboxes, key=lambda x: x.get_translated_ui_name(language)):
|
||
truck_content += f" <tr>\n"
|
||
truck_content += f" <td>{gearbox.get_translated_ui_name(language)}</td>\n"
|
||
truck_content += f" <td>{gearbox.Price}</td>\n"
|
||
truck_content += f" <td>{gearbox.GameData.get_unlock_str()}</td>\n"
|
||
truck_content += (
|
||
f" <td>{'✓' if gearbox.GearboxParams.IsManualLowGear else '˙'}</td>\n"
|
||
)
|
||
truck_content += (
|
||
f" <td>{'✓' if gearbox.GearboxParams.IsLowerMinusGearExists else '˙'}</td>\n"
|
||
)
|
||
truck_content += (
|
||
f" <td>{'✓' if gearbox.GearboxParams.IsLowerGearExists else '˙'}</td>\n"
|
||
)
|
||
truck_content += (
|
||
f" <td>{'✓' if gearbox.GearboxParams.IsLowerPlusGearExists else '˙'}</td>\n"
|
||
)
|
||
truck_content += (
|
||
f" <td>{'✓' if gearbox.GearboxParams.IsHighGearExists else '˙'}</td>\n"
|
||
)
|
||
truck_content += f" <td>{len(gearbox.Gear)}</td>\n"
|
||
truck_content += f" </tr>\n"
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
truck_content += f" <h3>Fuel Consumption</h3>\n"
|
||
truck_content += f" <table id='gearboxes_fuel'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Fuel Consumption</th>\n"
|
||
f" <th>AWD Fuel Modifier</th>\n"
|
||
)
|
||
for i in range(max_gear_count):
|
||
gear_num = str(i + 1) if i > 0 else "L+/1"
|
||
truck_content += f" <th>{gear_num}</th>\n"
|
||
truck_content += f" </tr></thead>\n"
|
||
truck_content += f" <tbody>\n"
|
||
|
||
for gearbox in sorted(gearboxes, key=lambda x: x.get_translated_ui_name(language)):
|
||
truck_content += f" <tr>\n"
|
||
truck_content += f" <td>{gearbox.get_translated_ui_name(language)}</td>\n"
|
||
truck_content += f" <td>{gearbox.FuelConsumption}</td>\n"
|
||
truck_content += f" <td>{gearbox.AWDConsumptionModifier}</td>\n"
|
||
for i in range(max_gear_count):
|
||
if i >= len(gearbox.Gear):
|
||
truck_content += f" <td>-</td>\n"
|
||
else:
|
||
truck_content += f" <td>{gearbox.Gear[i].FuelModifier}</td>\n"
|
||
truck_content += f" </tr>\n"
|
||
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
# Suspensions
|
||
truck_content += f" <h2>Suspensions</h2>\n"
|
||
|
||
# Wheels
|
||
truck_content += f" <h2>Tires</h2>\n"
|
||
wheel_cat = {}
|
||
scales = set()
|
||
for cw in truck.TruckData.CompatibleWheels:
|
||
scales.add(cw.get_size_in_inches())
|
||
damage_cap = cw.TruckWheels.DamageCapacity
|
||
width = int(cw.TruckWheels.Width * cw.Scale * 100)
|
||
mass = cw.TruckWheels.Mass
|
||
# FIXME: cw.TruckWheels.GameData.ReadMassScale (affects the truck mass for dualies)
|
||
for tt in cw.TruckWheels.TruckTires.TruckTire:
|
||
if tt.Mass > 0:
|
||
mass = tt.Mass
|
||
if tt.Width > 0:
|
||
width = int(tt.Width * cw.Scale * 100)
|
||
|
||
cat = tt.WheelFriction.get_translated_ui_name(language)
|
||
if cat not in wheel_cat:
|
||
wheel_cat[cat] = {}
|
||
wheel_cat[cat][tt.UiName] = (damage_cap, width, mass, tt)
|
||
# Mud_Performance=
|
||
# Truck_Weight / (Tire_Count×(Tire_Diameter×Width×Softness)) * Tire_Mud_Rating
|
||
|
||
for cat in sorted(wheel_cat):
|
||
truck_content += f" <h3>{cat}</h3>\n"
|
||
truck_content += f" <table>\n"
|
||
truck_content += f" <tr><th colspan='4'> </th><th colspan='3'>Friction</th></tr>\n"
|
||
truck_content += f" <tr><th>Name</th><th>Price</th><th>Mass</th><th>Width</th><th>Asphalt</th><th>Off-Road</th><th>Mud</th></tr>\n"
|
||
for damage_cap, width, mass, tt in sorted(
|
||
wheel_cat[cat].values(), key=lambda v: v[3].get_translated_ui_name(language)
|
||
):
|
||
truck_content += f" <tr><td>{tt.get_translated_ui_name(language)}</td><td>{tt.GameData.Price}</td><td>{mass}kg</td><td>{width}cm</td><td>{tt.WheelFriction.BodyFrictionAsphalt}</td><td>{tt.WheelFriction.BodyFriction}</td><td>{tt.WheelFriction.SubstanceFriction}</td></tr>\n"
|
||
|
||
truck_content += f" </table>\n"
|
||
|
||
scales = ", ".join(['%d"' % x for x in sorted(scales)])
|
||
truck_content += f" <h4>Available Tire Sizes: {scales}</h4>\n"
|
||
|
||
# Winches
|
||
truck_content += f" <h2>Winches</h2>\n"
|
||
|
||
# Diff. Lock
|
||
diff_lock_addons = truck.get_available_truck_addons(TruckAddonCategory.DIFF_LOCK)
|
||
if diff_lock_addons:
|
||
truck_content += f" <h2>Diff. Lock</h2>\n"
|
||
truck_content += f" <table id='diff_lock'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" </tr></thead><tbody>\n"
|
||
)
|
||
for addon in sorted(diff_lock_addons, key=lambda v: v.get_translated_ui_name(language)):
|
||
truck_content += (
|
||
f" <tr>\n"
|
||
f" <td>{addon.get_translated_ui_name(language)}</td>\n"
|
||
f" <td>{addon.Price}</td>\n"
|
||
f" <td>{addon.GameData.get_unlock_str()}</td>\n"
|
||
f" </tr>\n"
|
||
)
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
# Spare Wheel (if any)
|
||
# Snorkel (if any)
|
||
snorkel_addons = truck.get_available_truck_addons(TruckAddonCategory.SNORKEL)
|
||
if snorkel_addons:
|
||
truck_content += f" <h2>Snorkel</h2>\n"
|
||
truck_content += f" <table id='snorkel'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Mass</th>\n"
|
||
f" </tr></thead><tbody>\n"
|
||
)
|
||
for addon in sorted(snorkel_addons, key=lambda v: v.get_translated_ui_name(language)):
|
||
truck_content += (
|
||
f" <tr>\n"
|
||
f" <td>{addon.get_translated_ui_name(language)}</td>\n"
|
||
f" <td>{addon.Price}</td>\n"
|
||
f" <td>{addon.GameData.get_unlock_str()}</td>\n"
|
||
f" <td>{addon.PhysicsModel.Weight}kg</td>\n"
|
||
f" </tr>\n"
|
||
)
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
# AWD
|
||
awd_addons = truck.get_available_truck_addons(TruckAddonCategory.ALL_WHEEL_DRIVE)
|
||
if awd_addons:
|
||
truck_content += f" <h2>AWD</h2>\n"
|
||
truck_content += f" <table id='awd'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Mass</th>\n"
|
||
f" </tr></thead><tbody>\n"
|
||
)
|
||
for addon in sorted(awd_addons, key=lambda v: v.get_translated_ui_name(language)):
|
||
truck_content += (
|
||
f" <tr>\n"
|
||
f" <td>{addon.get_translated_ui_name(language)}</td>\n"
|
||
f" <td>{addon.Price}</td>\n"
|
||
f" <td>{addon.GameData.get_unlock_str()}</td>\n"
|
||
f" <td>{addon.PhysicsModel.Weight}kg</td>\n"
|
||
f" </tr>\n"
|
||
)
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
# Frame Addons
|
||
|
||
truck_content += f" <h2>Frame Addons</h2>\n"
|
||
truck_content += f" <table id='frame_addons'>\n"
|
||
truck_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Mass</th>\n"
|
||
f" <th>Cargo Slots</th>\n"
|
||
f" <th>Repair Points</th>\n"
|
||
f" <th>Spare Wheels</th>\n"
|
||
f" <th>Fuel Capacity</th>\n"
|
||
f" <th>Water Capacity</th>\n"
|
||
f" </tr></thead><tbody>\n"
|
||
)
|
||
for truck_addon in sorted(
|
||
truck.get_available_truck_addons(TruckAddonCategory.FRAME_ADDON),
|
||
key=lambda v: v.get_translated_ui_name(language),
|
||
):
|
||
truck_content += f" <tr>\n"
|
||
truck_content += f" <td>{truck_addon.get_translated_ui_name(language)}</td>\n"
|
||
truck_content += f" <td>{truck_addon.Price}</td>\n"
|
||
truck_content += f" <td>{truck_addon.GameData.get_unlock_str()}</td>\n"
|
||
truck_content += f" <td>{truck_addon.PhysicsModel.Weight}kg</td>\n"
|
||
truck_content += f" <td>{truck_addon.AddonSlots.Quantity if truck_addon.AddonSlots is not None else ' '}</td>\n"
|
||
truck_content += f" <td>{truck_addon.TruckData.RepairsCapacity if truck_addon.TruckData is not None and truck_addon.TruckData.RepairsCapacity > 0 else ' '}</td>\n"
|
||
truck_content += f" <td>{truck_addon.TruckData.WheelRepairsCapacity if truck_addon.TruckData is not None and truck_addon.TruckData.WheelRepairsCapacity > 0 else ' '}</td>\n"
|
||
truck_content += f" <td>{truck_addon.TruckData.FuelCapacity if truck_addon.TruckData is not None and truck_addon.TruckData.FuelCapacity > 0 else ' '}</td>\n"
|
||
truck_content += f" <td>{truck_addon.TruckData.WaterCapacity if truck_addon.TruckData is not None and truck_addon.TruckData.WaterCapacity > 0 else ' '}</td>\n"
|
||
truck_content += f" </tr>\n"
|
||
truck_content += f" </tbody></table>\n"
|
||
|
||
truck_content += f" <script>\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#engines', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#gearboxes_general', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#gearboxes_fuel', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#diff_lock', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#snorkel', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#awd', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += " document.addEventListener('DOMContentLoaded', function() {new DataTable('#frame_addons', {info: false, paging: false, searching: false});});\n"
|
||
truck_content += f" </script>\n"
|
||
|
||
write_html(
|
||
truck_file,
|
||
language=language,
|
||
content=truck_content,
|
||
category="Trucks",
|
||
name=truck.get_translated_ui_name(language),
|
||
)
|
||
|
||
index_content += (
|
||
f" <tr>\n"
|
||
f" <td><a href='{reference}.html'>{truck.get_translated_ui_name(language)}</a></td>\n"
|
||
f" <td>{language.get_sanitized(truck.TruckData.TruckType)}</td>\n"
|
||
f" <td>{DLC_NAMES[truck.DLC]}</td>\n"
|
||
f" <td>{truck.GameData.get_unlock_str()}</td>\n"
|
||
f" <td>{truck.GameData.Country}</td>\n"
|
||
f" <td>{truck.get_shop_price()}</td>\n"
|
||
f" <td>{truck.Weight}</td>\n"
|
||
f" <td>{truck.DriveTrain}</td>\n"
|
||
f" <td>{language[truck.AWDInfo.value]}</td>\n"
|
||
f" <td>{language[truck.DiffLockInfo.value]}</td>\n"
|
||
f" </tr>\n"
|
||
)
|
||
|
||
index_content += f" </tbody></table>\n"
|
||
index_content += " <script>document.addEventListener('DOMContentLoaded', function() {new DataTable('#truck_index', {paging: false});});</script>\n"
|
||
|
||
write_html(
|
||
os.path.join(destination_directory, "index.html"), language=language, content=index_content, category="Trucks"
|
||
)
|
||
|
||
|
||
def write_frame_addons(pak: InitialPakLoader, destination_directory: str, language: LanguageLoader):
|
||
index_content = " <h1>Frame Addons</h1>\n"
|
||
index_content += f" <table id='frame_addons' class='display'>\n"
|
||
index_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Mass</th>\n"
|
||
f" <th>Cargo Slots</th>\n"
|
||
f" <th>Repair Points</th>\n"
|
||
f" <th>Spare Wheels</th>\n"
|
||
f" <th>Fuel Capacity</th>\n"
|
||
f" <th>Water Capacity</th>\n"
|
||
f" <th>Available for</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
index_content += f" <tbody>\n"
|
||
|
||
for _, frame_addon in pak.get_sorted_object_list(SnowrunnerGameObjectType.TRUCK_ADDON, language=language):
|
||
if frame_addon.GameData.Category != TruckAddonCategory.FRAME_ADDON:
|
||
continue
|
||
|
||
if (
|
||
"TRANSLATION NOT FOUND" in frame_addon.get_translated_ui_name(language)
|
||
or len(frame_addon.get_translated_ui_name(language))
|
||
> 100 # This is a hidden frame addon where somebody swapped UI_NAME and UI_DESC
|
||
):
|
||
continue # FIXME: How To better detect Hidden Frame Addons not shown in game?
|
||
# Also e.g. Mack Defense has a Spare Wheel Addon that's always installed and not shown in game?!
|
||
|
||
available_trucks = [
|
||
x
|
||
for x in pak.get_sorted_object_list(SnowrunnerGameObjectType.TRUCK, language=language)
|
||
if x[1].Type == "Truck" and frame_addon.GameData.InstallSocket.Type in x[1].get_addon_socket_names()
|
||
]
|
||
if not available_trucks:
|
||
continue
|
||
|
||
index_content += f" <tr>\n"
|
||
index_content += f" <td>{frame_addon.get_translated_ui_name(language)}</td>\n"
|
||
index_content += f" <td>{frame_addon.Price}</td>\n"
|
||
index_content += f" <td>{frame_addon.GameData.get_unlock_str()}</td>\n"
|
||
index_content += f" <td>{frame_addon.PhysicsModel.Weight}kg</td>\n"
|
||
index_content += f" <td>{frame_addon.AddonSlots.Quantity if frame_addon.AddonSlots is not None else ' '}</td>\n"
|
||
index_content += f" <td>{frame_addon.TruckData.RepairsCapacity if frame_addon.TruckData is not None and frame_addon.TruckData.RepairsCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{frame_addon.TruckData.WheelRepairsCapacity if frame_addon.TruckData is not None and frame_addon.TruckData.WheelRepairsCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{frame_addon.TruckData.FuelCapacity if frame_addon.TruckData is not None and frame_addon.TruckData.FuelCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{frame_addon.TruckData.WaterCapacity if frame_addon.TruckData is not None and frame_addon.TruckData.WaterCapacity > 0 else ' '}</td>\n"
|
||
|
||
truck_links = ", ".join(
|
||
f'<a href="../trucks/{ref}.html">{truck.get_translated_ui_name(language)}</a>'
|
||
for ref, truck in available_trucks
|
||
)
|
||
index_content += f" <td>{truck_links}</td>\n"
|
||
|
||
index_content += f" </tr>\n"
|
||
|
||
index_content += f" </tbody>\n"
|
||
index_content += f" </table>\n"
|
||
index_content += " <script>document.addEventListener('DOMContentLoaded', function() {new DataTable('#frame_addons', {paging: false});});</script>\n"
|
||
|
||
write_html(
|
||
os.path.join(destination_directory, "index.html"),
|
||
language=language,
|
||
content=index_content,
|
||
category="Frame Addons",
|
||
)
|
||
|
||
|
||
def write_trailers(pak: InitialPakLoader, destination_directory: str, language: LanguageLoader):
|
||
index_content = " <h1>Trailers</h1>\n"
|
||
index_content += f" <table id='trailers' class='display'>\n"
|
||
index_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Price</th>\n"
|
||
f" <th>Unlock By</th>\n"
|
||
f" <th>Quest</th>\n"
|
||
f" <th>Mass</th>\n"
|
||
f" <th>Hitch</th>\n"
|
||
f" <th>Cargo Slots</th>\n"
|
||
f" <th>Repair Points</th>\n"
|
||
f" <th>Spare Wheels</th>\n"
|
||
f" <th>Fuel Capacity</th>\n"
|
||
f" <th>Water Capacity</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
index_content += f" <tbody>\n"
|
||
|
||
for ref, trailer in pak.get_sorted_object_list(SnowrunnerGameObjectType.TRUCK, language=language):
|
||
if trailer.Type != "Trailer":
|
||
continue
|
||
|
||
index_content += f" <tr>\n"
|
||
index_content += f" <td>{trailer.get_translated_ui_name(language)}</td>\n"
|
||
index_content += f" <td>{trailer.Price}</td>\n"
|
||
index_content += f" <td>{trailer.GameData.get_unlock_str()}</td>\n"
|
||
index_content += f" <td>{trailer.GameData.IsQuest}</td>\n"
|
||
index_content += f" <td>{trailer.PhysicsModel.Weight}kg</td>\n"
|
||
index_content += f" <td>{trailer.GameData.InstallSocket.Type}</td>\n"
|
||
if trailer.GameData.AddonSlots is None:
|
||
index_content += f" <td> </td>\n"
|
||
else:
|
||
if isinstance(trailer.GameData.AddonSlots, list):
|
||
index_content += f" <td>{sum(x.Quantity for x in trailer.GameData.AddonSlots)}</td>\n"
|
||
else:
|
||
index_content += f" <td>{trailer.GameData.AddonSlots.Quantity}</td>\n"
|
||
index_content += f" <td>{trailer.TruckData.RepairsCapacity if trailer.TruckData is not None and trailer.TruckData.RepairsCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{trailer.TruckData.WheelRepairsCapacity if trailer.TruckData is not None and trailer.TruckData.WheelRepairsCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{trailer.TruckData.FuelCapacity if trailer.TruckData is not None and trailer.TruckData.FuelCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" <td>{trailer.TruckData.WaterCapacity if trailer.TruckData is not None and trailer.TruckData.WaterCapacity > 0 else ' '}</td>\n"
|
||
index_content += f" </tr>\n"
|
||
|
||
index_content += f" </tbody>\n"
|
||
index_content += f" </table>\n"
|
||
index_content += " <script>document.addEventListener('DOMContentLoaded', function() {new DataTable('#trailers', {paging: false});});</script>\n"
|
||
|
||
write_html(
|
||
os.path.join(destination_directory, "index.html"),
|
||
language=language,
|
||
content=index_content,
|
||
category="Trailers",
|
||
)
|
||
|
||
|
||
def write_cargo_types(pak: InitialPakLoader, destination_directory: str, language: LanguageLoader):
|
||
index_content = " <h1>Trailers</h1>\n"
|
||
index_content += f" <table id='cargo_types' class='display'>\n"
|
||
index_content += (
|
||
f" <thead><tr>\n"
|
||
f" <th>Name</th>\n"
|
||
f" <th>Mass (unpacked)</th>\n"
|
||
f" <th>Mass (packed)</th>\n"
|
||
f" <th>Cargo Slots</th>\n"
|
||
f" </tr></thead>\n"
|
||
)
|
||
index_content += f" <tbody>\n"
|
||
|
||
for _, cargo_type in pak.get_sorted_object_list(SnowrunnerGameObjectType.CARGO_TYPE, language=language):
|
||
install_addons = [
|
||
x
|
||
for x in pak.get_object_list(SnowrunnerGameObjectType.TRUCK_ADDON)
|
||
if x.GameData.InstallSlot is not None and x.GameData.InstallSlot.CargoType == cargo_type
|
||
]
|
||
if not install_addons:
|
||
continue
|
||
|
||
if len(install_addons) > 1:
|
||
# FIXME: These are Logs
|
||
continue
|
||
|
||
install_addon = install_addons[0]
|
||
if install_addon.PhysicsModel is None:
|
||
continue # FIXME: Water, Fuel
|
||
|
||
model_brands = [
|
||
x
|
||
for x in pak.get_object_list(SnowrunnerGameObjectType.MODEL_BRAND)
|
||
if x.GameData is not None and x.GameData.LoadType == cargo_type
|
||
]
|
||
model_brand = model_brands[-1]
|
||
|
||
index_content += f" <tr>\n"
|
||
index_content += f" <td>{cargo_type.get_translated_ui_name(language)}</td>\n"
|
||
index_content += f" <td>{model_brand.PhysicsModel.Weight}</td>\n"
|
||
index_content += f" <td>{install_addon.PhysicsModel.Weight}</td>\n"
|
||
index_content += f" <td>{install_addon.GameData.InstallSlot.CargoLength}</td>\n"
|
||
index_content += f" </tr>\n"
|
||
|
||
index_content += f" </tbody>\n"
|
||
index_content += f" </table>\n"
|
||
index_content += " <script>document.addEventListener('DOMContentLoaded', function() {new DataTable('#cargo_types', {paging: false});});</script>\n"
|
||
|
||
write_html(
|
||
os.path.join(destination_directory, "index.html"),
|
||
language=language,
|
||
content=index_content,
|
||
category="Cargo Types",
|
||
)
|
||
|
||
|
||
def create_html(pak: InitialPakLoader, destination_directory: str = "output/"):
|
||
if not os.path.exists(destination_directory):
|
||
os.mkdir(destination_directory)
|
||
|
||
logger.info("Writing HTML Output")
|
||
for language_name, language_data in pak.languages.items():
|
||
logger.info(f" - {language_name}")
|
||
language_path = os.path.join(destination_directory, language_name)
|
||
if not os.path.exists(language_path):
|
||
os.mkdir(language_path)
|
||
|
||
truck_path = os.path.join(destination_directory, language_name, "trucks")
|
||
if not os.path.exists(truck_path):
|
||
os.mkdir(truck_path)
|
||
write_trucks(pak=pak, destination_directory=truck_path, language=language_data)
|
||
|
||
frame_addon_path = os.path.join(destination_directory, language_name, "frame_addons")
|
||
if not os.path.exists(frame_addon_path):
|
||
os.mkdir(frame_addon_path)
|
||
write_frame_addons(pak=pak, destination_directory=frame_addon_path, language=language_data)
|
||
|
||
trailers_path = os.path.join(destination_directory, language_name, "trailers")
|
||
if not os.path.exists(trailers_path):
|
||
os.mkdir(trailers_path)
|
||
write_trailers(pak=pak, destination_directory=trailers_path, language=language_data)
|
||
|
||
cargo_types_path = os.path.join(destination_directory, language_name, "cargo_types")
|
||
if not os.path.exists(cargo_types_path):
|
||
os.mkdir(cargo_types_path)
|
||
write_cargo_types(pak=pak, destination_directory=cargo_types_path, language=language_data)
|