cargo, partly
This commit is contained in:
parent
fe6e55a891
commit
8b97873f57
39
constants.py
39
constants.py
@ -1,3 +1,11 @@
|
||||
from enum import Enum
|
||||
|
||||
LANGUAGES = {
|
||||
"english": ("en", r"[strings]\strings_english.str"),
|
||||
"korean": ("kr", r"[strings]\strings_korean.str"),
|
||||
}
|
||||
DEFAULT_LANGUAGE = "english"
|
||||
|
||||
COUNTRYS = {}
|
||||
|
||||
DLC_NAMES = {
|
||||
@ -62,3 +70,34 @@ DLC_OVERRIDES = {
|
||||
"UI_VEHICLE_ZIKZ_612H_MASTODONT_NAME": "dlc_mastodon",
|
||||
"UI_VEHICLE_KENWORTH_W990_NAME": "dlc_w990",
|
||||
}
|
||||
|
||||
|
||||
class TruckInfo(str, Enum):
|
||||
ALWAYS = "UI_TRUCK_INFO_ALWAYS"
|
||||
CAPABLE = "UI_TRUCK_INFO_CAPABLE"
|
||||
NOT_AVAILABLE = "UI_TRUCK_INFO_NA"
|
||||
SWITCHABLE = "UI_TRUCK_INFO_ON_OFF"
|
||||
|
||||
|
||||
class TruckAddonCategory(str, Enum):
|
||||
ALL_WHEEL_DRIVE = "awd"
|
||||
BUBBLE_HEAD = "bubble_head"
|
||||
BUMPER = "bumper"
|
||||
CURTAIN = "curtain"
|
||||
DIFF_LOCK = "diff_lock"
|
||||
EXHAUST = "exhaust"
|
||||
FRAME_ADDON = "frame_addons"
|
||||
FENDERS = "fenders"
|
||||
FENDER_FRONT = "fender_front"
|
||||
FENDER_REAR = "fender_rear"
|
||||
GRILL = "grill"
|
||||
HOOD_ORNAMENT = "hood_ornament"
|
||||
MIRROR_MOUNT = "mirror_mount"
|
||||
MISCELLANEOUS = "miscellenious"
|
||||
REAR = "rear"
|
||||
SNORKEL = "snorkel"
|
||||
STICKER = "sticker"
|
||||
STICKER_EXTERIOR = "sticker_exterior"
|
||||
STICKER_WINDSHIELD = "sticker_windshield"
|
||||
TOP = "top"
|
||||
WHEEL_ADDON = "wheel_addon"
|
||||
|
||||
230
loader.py
230
loader.py
@ -1,5 +1,5 @@
|
||||
from __future__ import annotations
|
||||
from constants import DLC_OVERRIDES
|
||||
from constants import *
|
||||
from decimal import Decimal, ROUND_HALF_UP
|
||||
from enum import Enum
|
||||
from html import parser as html_parser
|
||||
@ -10,13 +10,6 @@ import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
LOAD_LIST = "pak.load_list"
|
||||
LANGUAGES = {
|
||||
"english": ("en", r"[strings]\strings_english.str"),
|
||||
"korean": ("kr", r"[strings]\strings_korean.str"),
|
||||
}
|
||||
DEFAULT_LANGUAGE = "english"
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
html_parser.starttagopen = re.compile("<[a-zA-Z_]")
|
||||
html_parser.endtagopen = re.compile("</[a-zA-Z_]")
|
||||
@ -59,37 +52,6 @@ locatestarttagend_tolerant = re.compile(
|
||||
endtagfind = re.compile(r"</\s*([a-zA-Z_][-.a-zA-Z0-9:_]*)\s*>")
|
||||
|
||||
|
||||
class TruckInfo(str, Enum):
|
||||
ALWAYS = "UI_TRUCK_INFO_ALWAYS"
|
||||
CAPABLE = "UI_TRUCK_INFO_CAPABLE"
|
||||
NOT_AVAILABLE = "UI_TRUCK_INFO_NA"
|
||||
SWITCHABLE = "UI_TRUCK_INFO_ON_OFF"
|
||||
|
||||
|
||||
class TruckAddonCategory(str, Enum):
|
||||
ALL_WHEEL_DRIVE = "awd"
|
||||
BUBBLE_HEAD = "bubble_head"
|
||||
BUMPER = "bumper"
|
||||
CURTAIN = "curtain"
|
||||
DIFF_LOCK = "diff_lock"
|
||||
EXHAUST = "exhaust"
|
||||
FRAME_ADDON = "frame_addons"
|
||||
FENDERS = "fenders"
|
||||
FENDER_FRONT = "fender_front"
|
||||
FENDER_REAR = "fender_rear"
|
||||
GRILL = "grill"
|
||||
HOOD_ORNAMENT = "hood_ornament"
|
||||
MIRROR_MOUNT = "mirror_mount"
|
||||
MISCELLANEOUS = "miscellenious"
|
||||
REAR = "rear"
|
||||
SNORKEL = "snorkel"
|
||||
STICKER = "sticker"
|
||||
STICKER_EXTERIOR = "sticker_exterior"
|
||||
STICKER_WINDSHIELD = "sticker_windshield"
|
||||
TOP = "top"
|
||||
WHEEL_ADDON = "wheel_addon"
|
||||
|
||||
|
||||
def get_initial_pak_path():
|
||||
return os.path.join(
|
||||
str(os.path.expanduser("~")),
|
||||
@ -219,10 +181,10 @@ class SnowrunnerClass:
|
||||
self.load_desc(data.children["uidesc"])
|
||||
|
||||
def load_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(f"load_data() in {self.__class__.__name__}()")
|
||||
|
||||
def update_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
raise NotImplementedError()
|
||||
raise NotImplementedError(f"update_data() in {self.__class__.__name__}()")
|
||||
|
||||
def ignore_attr(self, name: str) -> None:
|
||||
self.__attrs_handled.add(name.lower())
|
||||
@ -252,7 +214,7 @@ class SnowrunnerClass:
|
||||
self.load_desc(data.children[name.lower()])
|
||||
return
|
||||
|
||||
if name == "GameData":
|
||||
if name.lower() == "gamedata":
|
||||
self.load_game_data(data.children[name.lower()])
|
||||
return
|
||||
|
||||
@ -274,9 +236,7 @@ class SnowrunnerClass:
|
||||
)
|
||||
|
||||
def loading_finished(self, data: SnowRunnerXNLNode):
|
||||
attr_set = set(data.attrs.keys())
|
||||
if "_template" in attr_set:
|
||||
attr_set.remove("_template")
|
||||
attr_set = set(data.attrs.keys()) - {"_template"}
|
||||
if len(attr_set - self.__attrs_handled) > 0:
|
||||
logger.error(
|
||||
f"{self.__class__.__name__}(): Unhandled Attributes: {[attr_set - self.__attrs_handled]}, (Handled: {[self.__attrs_handled]}, Exist: {[attr_set]}"
|
||||
@ -357,15 +317,18 @@ class SnowrunnerClass:
|
||||
class AddonSlots(SnowrunnerClass):
|
||||
def __init__(self, pak_loader: InitialPakLoader):
|
||||
super().__init__(pak_loader=pak_loader)
|
||||
self.AllowedCargo = None
|
||||
self.InitialOffset = "(0;0;0)"
|
||||
self.Quantity = 0
|
||||
self.UseTrailerFrame = False
|
||||
|
||||
def load_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.load_attr(data, "AllowedCargo")
|
||||
self.load_attr(data, "InitialOffset")
|
||||
self.load_attr(data, "Quantity")
|
||||
self.load_attr(data, "UseTrailerFrame")
|
||||
self.ignore_attr("OffsetStep")
|
||||
self.ignore_attr("ParentFrame")
|
||||
self.ignore_attr("ParentFrames")
|
||||
self.loading_finished(data)
|
||||
|
||||
@ -436,10 +399,10 @@ class Body(SnowrunnerClass):
|
||||
self.load_attr(data, "Friction")
|
||||
self.load_attr(data, "Mass")
|
||||
self.load_attr(data, "Name")
|
||||
self.load_attr(data, "IsCapsuleCDT")
|
||||
self.load_attr(data, "DamageMult")
|
||||
self.load_attr(data, "RollingFrictionMultiplier")
|
||||
self.load_attr(data, "ImpactType")
|
||||
self.load_attr(data, "IsCapsuleCDT")
|
||||
self.load_attr(data, "LinearDamping")
|
||||
self.load_attr(data, "AngularDamping")
|
||||
self.load_attr(data, "UseDirtTint")
|
||||
@ -461,8 +424,17 @@ class Body(SnowrunnerClass):
|
||||
self.load_attr(data, "NetSyncUseGravity")
|
||||
self.load_attr(data, "NoPackWheels")
|
||||
self.ignore_attr("ExplicitParentFrame")
|
||||
self.ignore_attr("FrictionPreset")
|
||||
self.ignore_attr("HideDistance")
|
||||
self.ignore_attr("IsComplexPhysModel")
|
||||
self.ignore_attr("IsGameAsphalt")
|
||||
self.ignore_attr("IsStaticSoil")
|
||||
self.ignore_attr("NetSync")
|
||||
self.ignore_attr("ParentFrame")
|
||||
self.ignore_attr("SCapsuleCdt")
|
||||
self.ignore_attr("ShadowHideDistance")
|
||||
self.ignore_attr("template")
|
||||
|
||||
self.load_child(data, "Body", always_as_list=True)
|
||||
self.ignore_child("Constraint")
|
||||
self.ignore_child("Motor")
|
||||
@ -581,16 +553,21 @@ class FuelMass(SnowrunnerClass):
|
||||
class GameData(SnowrunnerClass):
|
||||
def __init__(self, pak_loader: InitialPakLoader):
|
||||
super().__init__(pak_loader=pak_loader)
|
||||
self.AddonSlots = None
|
||||
self.AddonSockets = None
|
||||
self.CameraPreset = None
|
||||
self.Category = None
|
||||
self.Country = ""
|
||||
self.ExcludeAddons = ""
|
||||
self.ExcludedCargoTypes = ""
|
||||
self.InstallSlot = None
|
||||
self.InstallSocket = None
|
||||
self.IsCustomizable = False
|
||||
self.IsDoubleTrailer = False
|
||||
self.IsQuest = False
|
||||
self.LoadType = None
|
||||
self.LoadAddons = None
|
||||
self.PackSlotsNumber = 0
|
||||
self.Price = 0
|
||||
self.UnlockByRank = -1
|
||||
self.UnlockByExploration = False
|
||||
@ -635,29 +612,43 @@ class GameData(SnowrunnerClass):
|
||||
self.load_attr(data, "RecreateOnZoneChange")
|
||||
self.load_attr(data, "TrialsToUnlock")
|
||||
self.load_attr(data, "IncludedCargoTypes")
|
||||
self.load_attr(data, "PackSlotsNumber")
|
||||
self.load_attr(data, "LoadAddons")
|
||||
if "loadtype" in data.attrs:
|
||||
self.LoadType = self.pak.get_object(SnowrunnerGameObjectType.CARGO_TYPE, data.attrs["loadtype"])
|
||||
self.ignore_attr("LoadType")
|
||||
|
||||
self.ignore_attr("_noinherit")
|
||||
self.ignore_attr("AddonUnlockByObjective")
|
||||
self.ignore_attr("FrameAlign")
|
||||
self.ignore_attr("FrameAlignOffset")
|
||||
self.ignore_attr("LegacyAlignementTruckAfterGateway")
|
||||
self.ignore_attr("ManualLoadSpawnOffsetX")
|
||||
self.ignore_attr("ManualLoadSpawnOffsetY")
|
||||
self.ignore_attr("Recallable")
|
||||
self.ignore_attr("ResetTruckAfterGateway")
|
||||
|
||||
self.children = data.children
|
||||
self.load_child(data, "AddonSockets", always_as_list=True)
|
||||
self.load_child(data, "AddonSlots")
|
||||
self.load_child(data, "UiDesc")
|
||||
if "installsocket" in data.children:
|
||||
self.InstallSocket = data.children["installsocket"].attrs.get("type", self.InstallSocket)
|
||||
if self.InstallSocket is None:
|
||||
self.load_child(data, "InstallSocket")
|
||||
elif "installsocket" in data.children:
|
||||
self.InstallSocket.update_data(data.children["installsocket"])
|
||||
self.ignore_child("InstallSocket")
|
||||
|
||||
self.ignore_child("AddonSlots")
|
||||
if self.InstallSlot is None:
|
||||
self.load_child(data, "InstallSlot")
|
||||
elif "installslot" in data.children:
|
||||
self.InstallSlot.update_data(data.children["installslot"])
|
||||
self.ignore_child("InstallSlot")
|
||||
self.ignore_child("AddonType")
|
||||
self.ignore_child("CenteringAngularVelocity")
|
||||
self.ignore_child("CraneSocket")
|
||||
self.ignore_child("CustomizationCameras")
|
||||
self.ignore_child("GearboxParams")
|
||||
self.ignore_child("InstallSlot")
|
||||
self.ignore_child("LoadArea")
|
||||
self.ignore_child("LoadPoint")
|
||||
self.ignore_child("LongLogsAlignTarget")
|
||||
self.ignore_child("RequiredAddon")
|
||||
self.ignore_child("RequiredAddonType")
|
||||
@ -794,7 +785,7 @@ class InstallSlot(SnowrunnerClass):
|
||||
super().__init__(pak_loader=pak_loader)
|
||||
self.CargoAddonSubtype = ""
|
||||
self.CargoLength = 0
|
||||
self.CargoType = ""
|
||||
self.CargoType = None
|
||||
self.CargoValue = 1
|
||||
self.ManualLoads = 0
|
||||
self.NoPackWheels = False
|
||||
@ -803,7 +794,9 @@ class InstallSlot(SnowrunnerClass):
|
||||
def load_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.load_attr(data, "CargoAddonSubtype")
|
||||
self.load_attr(data, "CargoLength")
|
||||
self.load_attr(data, "CargoType")
|
||||
if "cargotype" in data.attrs:
|
||||
self.CargoType = self.pak.get_object(SnowrunnerGameObjectType.CARGO_TYPE, data.attrs["cargotype"])
|
||||
self.ignore_attr("CargoType")
|
||||
self.load_attr(data, "CargoValue")
|
||||
self.load_attr(data, "ManualLoads")
|
||||
self.load_attr(data, "NoPackWheels")
|
||||
@ -823,12 +816,66 @@ class InstallSocket(SnowrunnerClass):
|
||||
self.ignore_attr("Price") # SERIOUSLY, SABER
|
||||
self.ignore_attr("UnlockByRank") # VALIDATE
|
||||
self.ignore_attr("UnlockByExploration") # YOUR INPUTS
|
||||
self.ignore_attr("CablesPos")
|
||||
self.load_attr(data, "CameraPreset")
|
||||
self.load_attr(data, "Type")
|
||||
self.load_attr(data, "ParentFrame")
|
||||
self.load_attr(data, "Offset")
|
||||
self.loading_finished(data)
|
||||
|
||||
def update_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.load_data(data)
|
||||
|
||||
|
||||
class ModelBrand(SnowrunnerClass):
|
||||
def __init__(self, pak_loader: InitialPakLoader):
|
||||
super().__init__(pak_loader=pak_loader)
|
||||
self.PhysicsModel = None
|
||||
|
||||
def load_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.ignore_attr("acceptzoneborderdecals")
|
||||
self.ignore_attr("applynormalinreference")
|
||||
self.ignore_attr("breaktype")
|
||||
self.ignore_attr("castnightlightmapshadow")
|
||||
self.ignore_attr("castdaylightmapshadow")
|
||||
self.ignore_attr("clipcamera")
|
||||
self.ignore_attr("clipcamerabridge")
|
||||
self.ignore_attr("dayshadowoffsetmult")
|
||||
self.ignore_attr("deactivationphantomext")
|
||||
self.ignore_attr("deleteonbreak")
|
||||
self.ignore_attr("disableshadows")
|
||||
self.ignore_attr("distskippercentage")
|
||||
self.ignore_attr("dynamicmodel")
|
||||
self.ignore_attr("dynamicmodeldistactivation")
|
||||
self.ignore_attr("fence")
|
||||
self.ignore_attr("inbackground")
|
||||
self.ignore_attr("instanced")
|
||||
self.ignore_attr("instancedmodel")
|
||||
self.ignore_attr("instancedasmodel")
|
||||
self.ignore_attr("IsComplexPhysModel")
|
||||
self.ignore_attr("iskeepphysmodelalways")
|
||||
self.ignore_attr("nightlightingshadowsallowcap")
|
||||
self.ignore_attr("nosoftcontacts")
|
||||
self.ignore_attr("skipextrablocks")
|
||||
self.ignore_attr("usephysicsforinstancing")
|
||||
|
||||
self.load_child(data, "GameData")
|
||||
self.load_child(data, "PhysicsModel")
|
||||
self.ignore_child("AnimSubset")
|
||||
self.ignore_child("LandMark")
|
||||
self.ignore_child("MeshLod")
|
||||
self.ignore_child("Occlusion")
|
||||
self.ignore_child("PreBuild")
|
||||
self.ignore_child("SnapPoint")
|
||||
self.ignore_child("StaticLight")
|
||||
self.ignore_child("StaticLights")
|
||||
self.ignore_child("Subset")
|
||||
self.ignore_child("TrackEvents")
|
||||
self.loading_finished(data)
|
||||
|
||||
def update_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.load_data(data)
|
||||
|
||||
|
||||
class Multiplier(SnowrunnerClass):
|
||||
def __init__(self, pak_loader: InitialPakLoader):
|
||||
@ -861,6 +908,7 @@ class PhysicsModel(SnowrunnerClass):
|
||||
self.load_attr(data, "_noinherit")
|
||||
self.load_attr(data, "Mesh")
|
||||
self.load_child(data, "Body")
|
||||
self.ignore_child("Constraint")
|
||||
self.ignore_child("FarmingBoundingBox1")
|
||||
self.ignore_child("FarmingBoundingBox2")
|
||||
self.ignore_child("FarmingBoundingBox3")
|
||||
@ -869,6 +917,7 @@ class PhysicsModel(SnowrunnerClass):
|
||||
self.ignore_child("FarmingBoundingBox6")
|
||||
self.ignore_child("FarmingBoundingBox7")
|
||||
self.ignore_child("FarmingBoundingBox8")
|
||||
self.ignore_child("Flare")
|
||||
self.ignore_child("NetSync")
|
||||
self.loading_finished(data)
|
||||
|
||||
@ -888,15 +937,19 @@ class RequiredAddon(SnowrunnerClass):
|
||||
class Socket(SnowrunnerClass):
|
||||
def __init__(self, pak_loader: InitialPakLoader):
|
||||
super().__init__(pak_loader=pak_loader)
|
||||
self.InCockpit = False
|
||||
self.Names = ""
|
||||
self.NamesBlock = ""
|
||||
self.InCockpit: bool = False
|
||||
self.Names: list[str] = []
|
||||
self.NamesBlock: list[str] = []
|
||||
self.RequiredHitches = None
|
||||
|
||||
def load_data(self, data: SnowRunnerXNLNode) -> None:
|
||||
self.load_attr(data, "InCockpit")
|
||||
self.load_attr(data, "Names")
|
||||
self.load_attr(data, "NamesBlock")
|
||||
if "names" in data.attrs:
|
||||
self.Names = [x.strip() for x in data.attrs["names"].split(",")]
|
||||
self.ignore_attr("Names")
|
||||
if "namesblock" in data.attrs:
|
||||
self.NamesBlock = [x.strip() for x in data.attrs["namesblock"].split(",")]
|
||||
self.ignore_attr("NamesBlock")
|
||||
self.ignore_attr("AddonShift")
|
||||
self.ignore_attr("Dir")
|
||||
self.ignore_attr("Offset")
|
||||
@ -988,6 +1041,8 @@ class Truck(SnowrunnerClass):
|
||||
self.TruckData = None
|
||||
self.Type = "Truck"
|
||||
self.WaterMass = None
|
||||
self.__addon_socket_names = None
|
||||
self.__truck_addon_list = None
|
||||
|
||||
@property
|
||||
def TireCount(self) -> int:
|
||||
@ -1030,15 +1085,23 @@ class Truck(SnowrunnerClass):
|
||||
)
|
||||
|
||||
def get_addon_socket_names(self) -> list[str]:
|
||||
return [s.Names for s in [y for x in self.GameData.AddonSockets for y in x.Socket]]
|
||||
if self.__addon_socket_names is None:
|
||||
self.__addon_socket_names = [
|
||||
n for s in [y for x in self.GameData.AddonSockets for y in x.Socket] for n in s.Names
|
||||
]
|
||||
|
||||
return self.__addon_socket_names
|
||||
|
||||
def get_available_truck_addons(self, category: TruckAddonCategory) -> list[TruckAddon]:
|
||||
return [
|
||||
if self.__truck_addon_list is None:
|
||||
self.__truck_addon_list = [
|
||||
ta
|
||||
for ta in self.pak.get_object_list(SnowrunnerGameObjectType.TRUCK_ADDON)
|
||||
if ta.GameData.InstallSocket in self.get_addon_socket_names() and ta.GameData.Category == category
|
||||
if ta.GameData.InstallSocket and ta.GameData.InstallSocket.Type in self.get_addon_socket_names()
|
||||
]
|
||||
|
||||
return [x for x in self.__truck_addon_list if x.GameData.Category == category]
|
||||
|
||||
def get_default_truck_addons(self) -> list[TruckAddon]:
|
||||
return [x.DefaultAddon for x in self.GameData.AddonSockets if x.DefaultAddon is not None]
|
||||
|
||||
@ -1632,6 +1695,7 @@ TYPE_CLASS_MATRIX = {
|
||||
"gearboxvariants": GearboxVariants,
|
||||
"installslot": InstallSlot,
|
||||
"installsocket": InstallSocket,
|
||||
"modelbrand": ModelBrand,
|
||||
"multiplier": Multiplier,
|
||||
"physicsmodel": PhysicsModel,
|
||||
"requiredaddon": RequiredAddon,
|
||||
@ -1674,6 +1738,7 @@ class SnowrunnerGameObjectType(str, Enum):
|
||||
GEARBOX_VARIANTS = "gearboxvariants"
|
||||
INSTALL_SLOT = "installslot"
|
||||
INSTALL_SOCKET = "installsocket"
|
||||
MODEL_BRAND = "modelbrand"
|
||||
MULTIPLIER = "multiplier"
|
||||
PHYSICS_MODEL = "physicsmodel"
|
||||
REQUIRED_ADDON = "requiredaddon"
|
||||
@ -1712,6 +1777,7 @@ class SnowrunnerGameObjectType(str, Enum):
|
||||
class InitialPakLoader:
|
||||
game_data_load_order = [
|
||||
"cargotype",
|
||||
"modelbrand",
|
||||
"enginevariants",
|
||||
"gearboxvariants",
|
||||
"suspensionsetvariants",
|
||||
@ -1754,7 +1820,6 @@ class InitialPakLoader:
|
||||
"materialtype",
|
||||
"mainheadlight",
|
||||
"model",
|
||||
"modelbrand",
|
||||
"motor",
|
||||
"mudguard",
|
||||
"mudtype",
|
||||
@ -1861,28 +1926,23 @@ class InitialPakLoader:
|
||||
if not isinstance(sub_data, list) and "_template" in sub_data.attrs:
|
||||
defer.append((tp_name, sub_data))
|
||||
continue
|
||||
|
||||
template = self.load_class(object_type=object_type, data=sub_data, dlc_name=dlc_name)
|
||||
if isinstance(template, list):
|
||||
template = template[-1]
|
||||
if local:
|
||||
self.templates_local[category][tp_name] = self.load_class(
|
||||
object_type=object_type,
|
||||
data=sub_data,
|
||||
dlc_name=dlc_name,
|
||||
)
|
||||
self.templates_local[category][tp_name] = template
|
||||
else:
|
||||
self.templates[category][tp_name] = self.load_class(
|
||||
object_type=object_type, data=sub_data, dlc_name=dlc_name
|
||||
)
|
||||
self.templates[category][tp_name] = template
|
||||
if defer:
|
||||
for tp_name, sub_data in defer:
|
||||
template = self.load_class(object_type=object_type, data=sub_data, dlc_name=dlc_name)
|
||||
if isinstance(template, list):
|
||||
template = template[-1]
|
||||
if local:
|
||||
self.templates_local[category][tp_name] = self.load_class(
|
||||
object_type=object_type,
|
||||
data=sub_data,
|
||||
dlc_name=dlc_name,
|
||||
)
|
||||
self.templates_local[category][tp_name] = template
|
||||
else:
|
||||
self.templates[category][tp_name] = self.load_class(
|
||||
object_type=object_type, data=sub_data, dlc_name=dlc_name
|
||||
)
|
||||
self.templates[category][tp_name] = template
|
||||
|
||||
elif category in self.ignore_categories:
|
||||
pass # Ignore for now
|
||||
@ -1892,17 +1952,18 @@ class InitialPakLoader:
|
||||
|
||||
def get_template(self, object_type: SnowrunnerGameObjectType, name: str) -> SnowrunnerClass:
|
||||
name = name.lower()
|
||||
if object_type in self.templates_local and name in self.templates_local[object_type]:
|
||||
if name in self.templates_local[object_type]:
|
||||
return self.templates_local[object_type][name]
|
||||
elif object_type in self.templates and name in self.templates[object_type]:
|
||||
elif name in self.templates[object_type]:
|
||||
return self.templates[object_type][name]
|
||||
else:
|
||||
logger.error(f"Unknown Template requested: {name} in {object_type.name}")
|
||||
sys.exit(1)
|
||||
logger.warning(f"Unknown Template requested: {name} in {object_type.name}")
|
||||
return SnowrunnerClass(pak_loader=self)
|
||||
|
||||
def get_object(
|
||||
self, object_type: SnowrunnerGameObjectType, name: str, lazy: bool = False
|
||||
) -> SnowrunnerClass | None:
|
||||
FAIL_NAMES = ["CargoBarrelsMasut", "CargoServiceSparePartsTown", "LongLogs", "MediumLogs", "ShortLogs"]
|
||||
# name = name.lower()
|
||||
if object_type in self.game_data:
|
||||
if name in self.game_data[object_type]:
|
||||
@ -1912,7 +1973,7 @@ class InitialPakLoader:
|
||||
if getattr(v, "Name", "<UNKNOWN>") == name:
|
||||
return v
|
||||
|
||||
if lazy:
|
||||
if lazy or name in FAIL_NAMES:
|
||||
return None
|
||||
|
||||
logger.error(f"Unknown Game Data Object requested: {name} in {object_type.name}")
|
||||
@ -1921,6 +1982,9 @@ class InitialPakLoader:
|
||||
def get_object_list(self, object_type: SnowrunnerGameObjectType) -> list:
|
||||
return list(self.game_data[object_type].values())
|
||||
|
||||
def get_object_list_with_ref(self, object_type: SnowrunnerGameObjectType) -> list[tuple[str, SnowrunnerClass]]:
|
||||
return list(self.game_data[object_type].items())
|
||||
|
||||
def get_sorted_object_list(
|
||||
self, object_type: SnowrunnerGameObjectType, language: LanguageLoader
|
||||
) -> list[tuple[str, SnowrunnerClass]]:
|
||||
|
||||
128
output.py
128
output.py
@ -6,8 +6,6 @@ from loader import (
|
||||
LanguageLoader,
|
||||
SnowrunnerGameObjectType,
|
||||
TruckAddonCategory,
|
||||
GameData,
|
||||
SnowrunnerClass,
|
||||
)
|
||||
from logging import getLogger
|
||||
|
||||
@ -32,6 +30,8 @@ def get_head(language: LanguageLoader, category: str, name: str | None = None) -
|
||||
<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'>
|
||||
@ -423,7 +423,7 @@ def write_frame_addons(pak: InitialPakLoader, destination_directory: str, langua
|
||||
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 in x[1].get_addon_socket_names()
|
||||
if x[1].Type == "Truck" and frame_addon.GameData.InstallSocket.Type in x[1].get_addon_socket_names()
|
||||
]
|
||||
if not available_trucks:
|
||||
continue
|
||||
@ -459,6 +459,118 @@ def write_frame_addons(pak: InitialPakLoader, destination_directory: str, langua
|
||||
)
|
||||
|
||||
|
||||
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)
|
||||
@ -479,3 +591,13 @@ def create_html(pak: InitialPakLoader, destination_directory: str = "output/"):
|
||||
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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user