diff --git a/ComponentDefinitions.py b/ComponentDefinitions.py new file mode 100644 index 00000000..7dc16bba --- /dev/null +++ b/ComponentDefinitions.py @@ -0,0 +1,264 @@ +components = { + 'COMPONENT_TYPE_CONTROLLABLE_PHYSICS': 1, + 'COMPONENT_TYPE_RENDER': 2, + 'COMPONENT_TYPE_SIMPLE_PHYSICS': 3, + 'COMPONENT_TYPE_CHARACTER': 4, + 'COMPONENT_TYPE_SCRIPT': 5, + 'COMPONENT_TYPE_BOUNCER': 6, + 'COMPONENT_TYPE_DESTROYABLE': 7, + 'COMPONENT_TYPE_GHOST': 8, + 'COMPONENT_TYPE_SKILL': 9, + 'COMPONENT_TYPE_SPAWNER': 10, + 'COMPONENT_TYPE_ITEM': 11, + 'COMPONENT_TYPE_MODULAR_BUILD': 12, + 'COMPONENT_TYPE_BUILD_CONTROLLER': 13, + 'COMPONENT_TYPE_REBUILD_ACTIVATOR': 14, + 'COMPONENT_TYPE_ICON_ONLY': 15, + 'COMPONENT_TYPE_VENDOR': 16, + 'COMPONENT_TYPE_INVENTORY': 17, + 'COMPONENT_TYPE_PROJECTILE_PHYSICS': 18, + 'COMPONENT_TYPE_SHOOTING_GALLERY': 19, + 'COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS': 20, + 'COMPONENT_TYPE_DROP_EFFECT': 21, + 'COMPONENT_TYPE_CHEST': 22, + 'COMPONENT_TYPE_COLLECTIBLE': 23, + 'COMPONENT_TYPE_BLUEPRINT': 24, + 'COMPONENT_TYPE_MOVING_PLATFORM': 25, + 'COMPONENT_TYPE_PET': 26, + 'COMPONENT_TYPE_PLATFORM_BOUNDARY': 27, + 'COMPONENT_TYPE_MODULE': 28, + 'COMPONENT_TYPE_ARCADE': 29, + 'COMPONENT_TYPE_HAVOK_VEHICLE_PHYSICS': 30, + 'COMPONENT_TYPE_MOVEMENT_AI': 31, + 'COMPONENT_TYPE_EXHIBIT': 32, + 'COMPONENT_TYPE_OVERHEAD_ICON': 33, + 'COMPONENT_TYPE_PET_CONTROL': 34, + 'COMPONENT_TYPE_MINIFIG': 35, + 'COMPONENT_TYPE_PROPERTY': 36, + 'COMPONENT_TYPE_PET_CREATOR': 37, + 'COMPONENT_TYPE_MODEL_BUILDER': 38, + 'COMPONENT_TYPE_SCRIPTED_ACTIVITY': 39, + 'COMPONENT_TYPE_PHANTOM_PHYSICS': 40, + 'COMPONENT_TYPE_SPRING_PAD': 41, + 'COMPONENT_TYPE_MODEL': 42, + 'COMPONENT_TYPE_PROPERTY_ENTRANCE': 43, + 'COMPONENT_TYPE_FX': 44, + 'COMPONENT_TYPE_PROPERTY_MANAGEMENT': 45, + 'COMPONENT_TYPE_VEHICLE_PHYSICS': 46, + 'COMPONENT_TYPE_PHYSICS_SYSTEM': 47, + 'COMPONENT_TYPE_REBUILD': 48, + 'COMPONENT_TYPE_SWITCH': 49, + 'COMPONENT_TYPE_ZONE_CONTROL': 50, + 'COMPONENT_TYPE_CHANGELING': 51, + 'COMPONENT_TYPE_CHOICE_BUILD': 52, + 'COMPONENT_TYPE_PACKAGE': 53, + 'COMPONENT_TYPE_SOUND_REPEATER': 54, + 'COMPONENT_TYPE_SOUND_AMBIENT_2D': 55, + 'COMPONENT_TYPE_SOUND_AMBIENT_3D': 56, + 'COMPONENT_TYPE_PRECONDITION': 57, + 'COMPONENT_TYPE_PLAYER_FLAG': 58, + 'COMPONENT_TYPE_CUSTOM_BUILD_ASSEMBLY': 59, + 'COMPONENT_TYPE_BASE_COMBAT_AI': 60, + 'COMPONENT_TYPE_MODULE_ASSEMBLY': 61, + 'COMPONENT_TYPE_SHOWCASE_MODEL_HANDLER': 62, + 'COMPONENT_TYPE_RACING_MODULE': 63, + 'COMPONENT_TYPE_GENERIC_ACTIVATOR': 64, + 'COMPONENT_TYPE_PROPERTY_VENDOR': 65, + 'COMPONENT_TYPE_HF_LIGHT_DIRECTION_GADGET': 66, + 'COMPONENT_TYPE_ROCKET_LAUNCH': 67, + 'COMPONENT_TYPE_ROCKET_LANDING_COMPONENT': 68, + 'COMPONENT_TYPE_TRIGGER': 69, + 'COMPONENT_TYPE_DROPPED_LOOT': 70, + 'COMPONENT_TYPE_RACING_CONTROL': 71, + 'COMPONENT_TYPE_FACTION_TRIGGER': 72, + 'COMPONENT_TYPE_MISSION_OFFER': 73, + 'COMPONENT_TYPE_RACING_STATS': 74, + 'COMPONENT_TYPE_LUP_EXHIBIT': 75, + 'COMPONENT_TYPE_BBB': 76, + 'COMPONENT_TYPE_SOUND_TRIGGER': 77, + 'COMPONENT_TYPE_PROXIMITY_MONITOR': 78, + 'COMPONENT_TYPE_RACING_SOUND_TRIGGER': 79, + 'COMPONENT_TYPE_CHAT': 80, + 'COMPONENT_TYPE_FRIENDS_LIST': 81, + 'COMPONENT_TYPE_GUILD': 82, + 'COMPONENT_TYPE_LOCAL_SYSTEM': 83, + 'COMPONENT_TYPE_MISSION': 84, + 'COMPONENT_TYPE_MUTUABLE_MODEL_BEHAVIORS': 85, + 'COMPONENT_TYPE_PATHFINDING_CONTROL': 86, + 'COMPONENT_TYPE_PLAYER_PET_TAMING': 87, + 'COMPONENT_TYPE_PROPERTY_EDITOR': 88, + 'COMPONENT_TYPE_SKINNED_RENDER': 89, + 'COMPONENT_TYPE_SLASH_COMMAND': 90, + 'COMPONENT_TYPE_STATUS_EFFECT': 91, + 'COMPONENT_TYPE_TEAMS': 92, + 'COMPONENT_TYPE_TEXT_EFFECT': 93, + 'COMPONENT_TYPE_TRADE': 94, + 'COMPONENT_TYPE_USER_CONTROL': 95, + 'COMPONENT_TYPE_IGNORE_LIST': 96, + 'COMPONENT_TYPE_ROCKET_LAUNCH_LUP': 97, + 'COMPONENT_TYPE_BUFF': 98, + 'COMPONENT_TYPE_INTERACTION_MANAGER': 99, + 'COMPONENT_TYPE_DONATION_VENDOR': 100, + 'COMPONENT_TYPE_COMBAT_MEDIATOR': 101, + 'COMPONENT_TYPE_ACHIEVEMENT_VENDOR': 102, + 'COMPONENT_TYPE_GATE_RUSH': 103, + 'COMPONENT_TYPE_RAIL_ACTIVATOR': 104, + 'COMPONENT_TYPE_ROLLER': 105, + 'COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT': 106, + 'COMPONENT_TYPE_CRAFTING': 107, + 'COMPONENT_TYPE_POSSESSABLE': 108, + 'COMPONENT_TYPE_LEVEL_PROGRESSION': 109, + 'COMPONENT_TYPE_POSSESSOR': 110, + 'COMPONENT_TYPE_MOUNT_CONTROL': 111, + 'UNKNOWN_112': 112, + 'COMPONENT_TYPE_PROPERTY_PLAQUE': 113, + 'COMPONENT_TYPE_BUILD_BORDER': 114, + 'UNKNOWN_115': 115, + 'COMPONENT_TYPE_CULLING_PLANE': 116, + 'INVALID': 4294967295 +} + +component_initialization_order = [ + 'COMPONENT_TYPE_POSSESSABLE', + 'COMPONENT_TYPE_BLUEPRINT', + 'COMPONENT_TYPE_MODULE_ASSEMBLY', + 'COMPONENT_TYPE_CONTROLLABLE_PHYSICS', + 'COMPONENT_TYPE_PROJECTILE_PHYSICS', + 'COMPONENT_TYPE_PHYSICS_SYSTEM', + 'COMPONENT_TYPE_VEHICLE_PHYSICS', + 'COMPONENT_TYPE_HAVOK_VEHICLE_PHYSICS', + 'COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS', + 'COMPONENT_TYPE_SIMPLE_PHYSICS', + 'COMPONENT_TYPE_PHANTOM_PHYSICS', + 'COMPONENT_TYPE_DESTROYABLE', + 'COMPONENT_TYPE_MINIFIG', + 'COMPONENT_TYPE_CHARACTER', + 'COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT', + 'COMPONENT_TYPE_POSSESSOR', + 'COMPONENT_TYPE_MOUNT_CONTROL', + 'COMPONENT_TYPE_PET', + 'COMPONENT_TYPE_INVENTORY', + 'COMPONENT_TYPE_PROXIMITY_MONITOR', + 'COMPONENT_TYPE_MOVEMENT_AI', + 'COMPONENT_TYPE_SCRIPT', + 'COMPONENT_TYPE_SKILL', + 'COMPONENT_TYPE_BASE_COMBAT_AI', + 'COMPONENT_TYPE_SPAWNER', + 'COMPONENT_TYPE_ITEM', + 'COMPONENT_TYPE_REBUILD', + 'COMPONENT_TYPE_BUILD_BORDER', + 'COMPONENT_TYPE_MODULE', + 'COMPONENT_TYPE_BUILD_CONTROLLER', + 'COMPONENT_TYPE_REBUILD_ACTIVATOR', + 'COMPONENT_TYPE_MODULAR_BUILD', + 'COMPONENT_TYPE_MISSION_OFFER', + 'COMPONENT_TYPE_VENDOR', + 'COMPONENT_TYPE_DONATION_VENDOR', + 'COMPONENT_TYPE_ACHIEVEMENT_VENDOR', + 'COMPONENT_TYPE_SHOOTING_GALLERY', + 'COMPONENT_TYPE_ROLLER', + 'COMPONENT_TYPE_SCRIPTED_ACTIVITY', + 'COMPONENT_TYPE_COLLECTIBLE', + 'COMPONENT_TYPE_MOVING_PLATFORM', + 'COMPONENT_TYPE_CHANGELING', + 'COMPONENT_TYPE_CHOICE_BUILD', + 'COMPONENT_TYPE_PACKAGE', + 'COMPONENT_TYPE_PLATFORM_BOUNDARY', + 'COMPONENT_TYPE_HF_LIGHT_DIRECTION_GADGET', + 'COMPONENT_TYPE_CULLING_PLANE', + 'COMPONENT_TYPE_EXHIBIT', + 'COMPONENT_TYPE_LUP_EXHIBIT', + 'COMPONENT_TYPE_PROPERTY', + 'COMPONENT_TYPE_PROPERTY_PLAQUE', + 'COMPONENT_TYPE_MODEL', + 'COMPONENT_TYPE_PROPERTY_ENTRANCE', + 'COMPONENT_TYPE_ROCKET_LAUNCH_LUP', + 'COMPONENT_TYPE_PROPERTY_MANAGEMENT', + 'COMPONENT_TYPE_RAIL_ACTIVATOR', + 'COMPONENT_TYPE_BOUNCER', + 'COMPONENT_TYPE_SPRING_PAD', + 'COMPONENT_TYPE_SWITCH', + 'COMPONENT_TYPE_ZONE_CONTROL', + 'COMPONENT_TYPE_MODEL_BUILDER', + 'COMPONENT_TYPE_SOUND_REPEATER', + 'COMPONENT_TYPE_CHEST', + 'COMPONENT_TYPE_SHOWCASE_MODEL_HANDLER', + 'COMPONENT_TYPE_ARCADE', + 'COMPONENT_TYPE_RENDER', + 'COMPONENT_TYPE_SOUND_AMBIENT_2D', + 'COMPONENT_TYPE_SOUND_AMBIENT_3D', + 'COMPONENT_TYPE_SOUND_TRIGGER', + 'COMPONENT_TYPE_RACING_SOUND_TRIGGER', + 'COMPONENT_TYPE_CUSTOM_BUILD_ASSEMBLY', + 'COMPONENT_TYPE_GENERIC_ACTIVATOR', + 'COMPONENT_TYPE_PROPERTY_VENDOR', + 'COMPONENT_TYPE_ROCKET_LAUNCH', + 'COMPONENT_TYPE_ROCKET_LANDING_COMPONENT', + 'COMPONENT_TYPE_FACTION_TRIGGER', + 'COMPONENT_TYPE_RACING_CONTROL', + 'COMPONENT_TYPE_GATE_RUSH', + 'COMPONENT_TYPE_BBB', + 'COMPONENT_TYPE_CRAFTING' +] +component_order_as_ints = {} + +component_int_to_name = {} + +for component in component_initialization_order: + component_order_as_ints[components[component]] = component + +for component in components: + component_int_to_name[components[component]] = component + +class GameObject: + type = "" + +class ObjectLoadState: + createdGameObject = GameObject() + components = [] + hasPhysicsComponent = False + hasDestroyable = False + hasPathfindingComponent = False + hasProximityMonitorComponent = False + hasScriptComponent = False + hasDroppedLootComponent = False + hasModelbehaviors = False + somethingOrNothing = False + physicsComponentId = -1 + +# Begin custom attributes + serializedOrder = [] + hasMissionOffer = False + +class NiPoint3: + x = 0.0 + y = 0.0 + z = 0.0 + +class NiQuaternion: + w = 0.0 + x = 0.0 + y = 0.0 + z = 0.0 + +class LoadObject: + objId = 0 + owner = 0 + lotToSpawn = 0 + isLocalPlayer = False + hasDropEffect = False + bIsSmashable = False + dynamicPhysics = False + spawnPosition = NiPoint3() + spawnRotation = NiQuaternion() + scale = 0.0 + legoBrickID = 0 + legoColorID = 0 + configData = {} + isHFPaletteObject = False + objType = 0 + useSimplePhysics = False + bDelayedLoad = False + +# Don't know the name yet of this + field8_0x20 = True diff --git a/ComponentFactories.py b/ComponentFactories.py new file mode 100644 index 00000000..980d44ee --- /dev/null +++ b/ComponentFactories.py @@ -0,0 +1,408 @@ +import ComponentDefinitions as cd + +def ApplyComponentWhitelist(): + # Dont care to actually do this, just want the call for now. + pass + +def ControllablePhysFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasModelbehaviors: + if not loadObject.hasDropEffect: + if not loadObject.useSimplePhysics: + objectLoadState.components.append('CONTROLLABLE_PHYSICS') + else: + objectLoadState.components.append('SIMPLE_PHYSICS') + else: + loadObject.physicsComponentId = componentId + +def RenderFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if loadObject.lotToSpawn == 176: + return + gmlevel = loadObject.configData.get('gmlevel', 0) + if gmlevel > 0 and gmlevel < 6: + componentId = 9940 # Override the componentId of the render component to be 9940, the Mythran Render Component + renderDisabled = loadObject.configData.get('renderDisabled', False) + if renderDisabled: + return + if objectLoadState.createdGameObject.type == 'BlockingVolume': + return + rejectedLots = [5937, 5938, 9741, 9742, 9862, 9863] + if loadObject.lotToSpawn in rejectedLots: + return + if loadObject.lotToSpawn == 6368: + FxFactory(loadObject, objectLoadState, componentId) + return + FxFactory(loadObject, objectLoadState, componentId) + defaultWrapperAsset = "" + hasNifAsset = False + hasKfmAsset = False + allowRenderWrapping = False + nifName = loadObject.configData.get('nif_name', '') + if nifName == '': + print('TODO query cdc for this data in the Render component') + nifName = 'mesh/something.nif' # if empty get nifname as the render_asset column of the RenderComponent table from the database + if nifName[-1] == 'f': + hasNifAsset = True + elif nifName[-1] == 'm': + hasKfmAsset = True + if defaultWrapperAsset != '': + if defaultWrapperAsset[-1] == 'm': + allowRenderWrapping = not loadObject.configData.get('preventRenderWrapping', False) + if allowRenderWrapping or hasKfmAsset or (not defaultWrapperAsset == 'PrimitiveModels' and not hasNifAsset and not loadObject.configData.get('CreateNULLRender', False)): + objectLoadState.components.append('SKINNED_RENDER') + else: + objectLoadState.components.append('RENDER') + +def FxFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('FX') + +def SimplePhysFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasModelbehaviors: + objectLoadState.physicsComponentId = componentId + return + if not loadObject.hasDropEffect: + return + markedAsPhantom = loadObject.configData.get('markedAsPhantom', False) + if markedAsPhantom: + objectLoadState.components.append('PHANTOM_PHYSICS') + else: + objectLoadState.components.append('SIMPLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def CharacterFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('POSSESSOR') + objectLoadState.components.append('MOUNT_CONTROL') + objectLoadState.components.append('PET_CREATOR') + objectLoadState.components.append('LEVEL_PROGRESSION') + objectLoadState.components.append('PLAYER_FORCED_MOVEMENT') + objectLoadState.components.append('CHARACTER') + +def ScriptFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int, add_pathfinding_control: bool): + custom_script_client = loadObject.configData.get('custom_script_client', '') + custom_script_server = loadObject.configData.get('custom_script_server', '') + if componentId == 0 and custom_script_client == '' and custom_script_server == '': + return + objectLoadState.components.append('SCRIPT') + + if not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + + if not objectLoadState.hasPathfindingComponent and add_pathfinding_control: + objectLoadState.components.append('PATHFINDING_CONTROL') + objectLoadState.hasPathfindingComponent = True + +def BouncerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('BOUNCER') + +def DestroyableFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('STATUS_EFFECT') + objectLoadState.components.append('BUFF') + objectLoadState.components.append('DESTROYABLE') + objectLoadState.hasDestroyable = True + +def SkillFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SKILL') + +def SpawnerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SPAWNER') + # If game state is happy flower + spawntemplate = loadObject.configData.get('spawntemplate', '') + + print('TODO query cdc for this data in the Spawner component') + render_asset = loadObject.configData.get('render_asset', 'test.nif') # Get this from RenderComponent table + render_id = loadObject.configData.get('render_id', '') # Get this from RenderComponent table + + if render_asset[-1] == 'f': + objectLoadState.components.append('SKINNED_RENDER') + else: + objectLoadState.components.append('RENDER') + +def ItemFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ITEM') + +def ModularBuildFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MODULAR_BUILD') + +def BuildControllerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('BUILD_CONTROLLER') + +def VendorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + objectLoadState.components.append('VENDOR') + +def InventoryFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('INVENTORY') + +def ProjectilePhysicsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not loadObject.hasDropEffect: + objectLoadState.components.append('PROJECTILE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def ShootingGalleryFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SHOOTING_GALLERY') + +def RigibBodyPhantomPhysicsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('RIGID_BODY_PHANTOM_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def ChestFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('CHEST') + +def CollectibleFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('COLLECTIBLE') + if not objectLoadState.hasDestroyable: + objectLoadState.components.append('DESTROYABLE') + objectLoadState.hasDestroyable = True + +def BlueprintFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('BLUEPRINT') + +def MovingPlatformFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MOVING_PLATFORM') + +def PetFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + inInventory = loadObject.configData.get('inInventory', False) + if inInventory: + return + + if not objectLoadState.hasPathfindingComponent: + objectLoadState.components.append('PATHFINDING_CONTROL') + objectLoadState.hasPathfindingComponent = True + objectLoadState.components.append('PET') + +def PlatformBoundaryFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PLATFORM_BOUNDARY') + +def ModuleFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MODULE') + +def ArcadeFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ARCADE') + +def HavokVehiclePhysicsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + use_simple_physics = loadObject.configData.get('use_simple_physics', False) + if use_simple_physics: + objectLoadState.components.append('SIMPLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + else: + objectWorldState = loadObject.configData.get('objectWorldState', '') + if objectWorldState == 0 or objectWorldState != 2: + objectLoadState.components.append('HAVOK_VEHICLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def MovementAiFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MOVEMENT_AI') + +def ExhibitFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + # Sorry aron, doesnt do anything :( + pass + +def MinifigFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MINIFIG') + +def PropertyFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PROPERTY') + +def ModelBuilderFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MODEL_BUILDER') + +def ScriptedActivityFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SCRIPTED_ACTIVITY') + +def PhantomPhysicsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not loadObject.hasDropEffect: + objectLoadState.components.append('PHANTOM_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def SpringPadFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SPRING_PAD') + +def ModelFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + modelType = loadObject.configData.get('modelType', 0) + if not objectLoadState.hasModelbehaviors: + if not objectLoadState.hasPhysicsComponent: + objectLoadState.components.append('SIMPLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + elif not objectLoadState.hasPhysicsComponent: + if modelType == 0: + objectLoadState.components.append('CONTROLLABLE_PHYSICS') + else: + objectLoadState.components.append('SIMPLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + if modelType != 0 and not objectLoadState.hasPathfindingComponent: + objectLoadState.components.append('PATHFINDING_CONTROL') + objectLoadState.hasPathfindingComponent = True + + hasPropertyObjectID = loadObject.configData.get('propertyObjectID', 0) != 0 + inInventory = loadObject.configData.get('inInventory', False) + if hasPropertyObjectID and inInventory: + objectLoadState.components.append('MODEL_BEHAVIORS') + else: + objectLoadState.components.append('MUTABLE_MODEL_BEHAVIORS') + +def PropertyEntranceFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PROPERTY_ENTRANCE') + +def PropertyManagementFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PROPERTY_MANAGEMENT') + +def VehiclePhysicsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('VEHICLE_PHYSICS') + objectLoadState.hasPhysicsComponent = True + +def PhysicsSystemFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasModelbehaviors: + if not loadObject.hasDropEffect: + objectLoadState.components.append('PHYSICS_SYSTEM') + objectLoadState.hasPhysicsComponent = True + +def RebuildFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('REBUILD') + if not objectLoadState.hasDestroyable: + objectLoadState.components.append('DESTROYABLE') + objectLoadState.hasDestroyable = True + loadObject.bIsSmashable = True + +def BaseCombatAiFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int, add_pathfinding_control: bool): + if not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + + if not objectLoadState.hasPathfindingComponent and add_pathfinding_control: + objectLoadState.components.append('PATHFINDING_CONTROL') + objectLoadState.hasPathfindingComponent = True + + objectLoadState.components.append('BASE_COMBAT_AI') + +def ProximityMonitorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + print('TODO query cdc for this data in prox mon') + # There must be a row for this component in the ProximityMonitorComponent table to get this component + LoadOnClient = loadObject.configData.get('LoadOnClient', False) # Get this from ProximityMonitorComponent table if you know there is a column for it + if LoadOnClient: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + +def DonationVendorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + objectLoadState.components.append('DONATION_VENDOR') + +def AchievmentVendorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + + objectLoadState.components.append('ACHIEVEMENT_VENDOR') + +def CraftingFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + # Game verson must be above 999 for this to work! + gameVersion = 1000 + if gameVersion > 999: + objectLoadState.components.append('CRAFTING') + +# Technically Possessable and Possessor are the exact same thing +def PossessableFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('POSSESSABLE') + +def PossessorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('POSSESSOR') + +def PropertyPlaqueFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PROPERTY_PLAQUE') + +def BuildBorderFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('BUILD_BORDER') + +def CullingPlaneFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('CULLING_PLANE') + +def GateRushFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('GATE_RUSH') + +def RailActivatorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('RAIL_ACTIVATOR') + +def RollerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ROLLER') + +def PlayerForcedMovementFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PLAYER_FORCED_MOVEMENT') + +def RacingSoundTriggerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('RACING_SOUND_TRIGGER') + +def RocketLaunchLupFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ROCKET_LAUNCH_LUP') + + +def ModuleAssemblyFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MODULE_ASSEMBLY') + +def ShowcaseModelHandlerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SHOWCASE_MODEL_HANDLER') + +def GenericActivatorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('GENERIC_ACTIVATOR') + +def PropertyVendorFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('PROPERTY_VENDOR') + +def RocketLaunchFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ROCKET_LAUNCH') + +def RocketLandingComponentFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ROCKET_LANDING_COMPONENT') + +def RacingControlFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('RACING_CONTROL') + +def FactionTriggerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('FACTION_TRIGGER') + +def MissionOfferFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('MISSION_OFFER') + objectLoadState.hasMissionOffer = True + +def RacingStatsFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('RACING_STATS') + +def LupExhibitFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('LUP_EXHIBIT') + +def BBBFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('BBB') + +def SoundTriggerFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SOUND_TRIGGER') + +def SwitchFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SWITCH') + +def ZoneControlFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('ZONE_CONTROL') + +def ChanglingFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('CHANGELING') + +def ChoiceBuildFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('CHOICE_BUILD') + +def PackageFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + # Literally returns nothing + pass + +def SoundRepeaterFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SOUND_REPEATER') + +def SoundAmbient2DFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + if loadObject.isLocalPlayer: + objectLoadState.components.append('SOUND_AMBIENT_2D') + +def SoundAmbient3DFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('SOUND_AMBIENT_3D') + +def CustomBuildAssemblyFactory(loadObject: cd.LoadObject, objectLoadState: cd.ObjectLoadState, componentId: int): + objectLoadState.components.append('CUSTOM_BUILD_ASSEMBLY') diff --git a/DoObjectPreLoad.py b/DoObjectPreLoad.py new file mode 100644 index 00000000..fc71220c --- /dev/null +++ b/DoObjectPreLoad.py @@ -0,0 +1,306 @@ +import ComponentDefinitions as cd +import ComponentFactories as cf + +# If we have any of these components, we need pathfinding control +def CheckIfNeedsPathfindingControl(components_to_load: dict): + add_pathfinding_control = cd.components['COMPONENT_TYPE_CONTROLLABLE_PHYSICS'] in components_to_load + add_pathfinding_control |= cd.components['COMPONENT_TYPE_PROJECTILE_PHYSICS'] in components_to_load + add_pathfinding_control |= cd.components['COMPONENT_TYPE_HAVOK_VEHICLE_PHYSICS'] in components_to_load + add_pathfinding_control |= cd.components['COMPONENT_TYPE_VEHICLE_PHYSICS'] in components_to_load + return add_pathfinding_control + +def DoObjectPreLoad(components_to_load: dict): + isHfActive = False + cf.ApplyComponentWhitelist() + objectLoadState = cd.ObjectLoadState() + loadObject = cd.LoadObject() + + for componentType in cd.component_order_as_ints.keys(): + try: + componentId = components_to_load[componentType] + except KeyError: + continue + try: + match cd.component_int_to_name[componentType]: + case 'COMPONENT_TYPE_CONTROLLABLE_PHYSICS': + if objectLoadState.hasDroppedLootComponent: continue + cf.ControllablePhysFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RENDER': + cf.RenderFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SIMPLE_PHYSICS': + if objectLoadState.hasDroppedLootComponent: continue + cf.SimplePhysFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CHARACTER': + cf.CharacterFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SCRIPT': + cf.ScriptFactory(loadObject, objectLoadState, componentId, CheckIfNeedsPathfindingControl(components_to_load)) + + case 'COMPONENT_TYPE_BOUNCER': + cf.BouncerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_DESTROYABLE': + cf.DestroyableFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SKILL': + cf.SkillFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SPAWNER': + cf.SpawnerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ITEM': + cf.ItemFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MODULAR_BUILD': + cf.ModularBuildFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_BUILD_CONTROLLER': + cf.BuildControllerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_VENDOR': + cf.VendorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_INVENTORY': + cf.InventoryFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROJECTILE_PHYSICS': + if objectLoadState.hasDroppedLootComponent: continue + cf.ProjectilePhysicsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SHOOTING_GALLERY': + cf.ShootingGalleryFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RIGID_BODY_PHANTOM_PHYSICS': + cf.RigibBodyPhantomPhysicsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CHEST': + cf.ChestFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_COLLECTIBLE': + cf.CollectibleFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_BLUEPRINT': + cf.BlueprintFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MOVING_PLATFORM': + cf.MovingPlatformFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PET': + cf.PetFactory(loadObject, objectLoadState, componentId) + print('Deleting COMPONENT_TYPE_MODEL and COMPONENT_TYPE_ITEM due to COMPONENT_TYPE_PET being loaded') + toDel = cd.components['COMPONENT_TYPE_MODEL'] + del components_to_load[toDel] + toDel = cd.components['COMPONENT_TYPE_ITEM'] + del components_to_load[toDel] + + case 'COMPONENT_TYPE_PLATFORM_BOUNDARY': + cf.PlatformBoundaryFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MODULE': + cf.ModuleFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ARCADE': + cf.ArcadeFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_HAVOK_VEHICLE_PHYSICS': + cf.HavokVehiclePhysicsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MOVEMENT_AI': + cf.MovementAiFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_EXHIBIT': + cf.ExhibitFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MINIFIG': + cf.MinifigFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROPERTY': + cf.PropertyFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MODEL_BUILDER': + cf.ModelBuilderFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SCRIPTED_ACTIVITY': + cf.ScriptedActivityFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PHANTOM_PHYSICS': + if objectLoadState.hasDroppedLootComponent: continue + cf.PhantomPhysicsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SPRING_PAD': + cf.SpringPadFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MODEL': + cf.ModelFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROPERTY_ENTRANCE': + cf.PropertyEntranceFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROPERTY_MANAGEMENT': + cf.PropertyManagementFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_VEHICLE_PHYSICS': + cf.VehiclePhysicsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PHYSICS_SYSTEM': + cf.PhysicsSystemFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_REBUILD': + cf.RebuildFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SWITCH': + cf.SwitchFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ZONE_CONTROL': + cf.ZoneControlFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CHANGELING': + cf.ChanglingFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CHOICE_BUILD': + cf.ChoiceBuildFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PACKAGE': + cf.PackageFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SOUND_REPEATER': + cf.SoundRepeaterFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SOUND_AMBIENT_2D': + cf.SoundAmbient2DFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SOUND_AMBIENT_3D': + cf.SoundAmbient3DFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CUSTOM_BUILD_ASSEMBLY': + cf.CustomBuildAssemblyFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_BASE_COMBAT_AI': + cf.BaseCombatAiFactory(loadObject, objectLoadState, componentId, CheckIfNeedsPathfindingControl(components_to_load)) + + case 'COMPONENT_TYPE_MODULE_ASSEMBLY': + cf.ModuleAssemblyFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SHOWCASE_MODEL_HANDLER': + cf.ShowcaseModelHandlerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_GENERIC_ACTIVATOR': + cf.GenericActivatorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROPERTY_VENDOR': + cf.PropertyVendorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ROCKET_LAUNCH': + cf.RocketLaunchFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ROCKET_LANDING_COMPONENT': + cf.RocketLandingComponentFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RACING_CONTROL': + cf.RacingControlFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_FACTION_TRIGGER': + cf.FactionTriggerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_MISSION_OFFER': + cf.MissionOfferFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RACING_STATS': + cf.RacingStatsFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_LUP_EXHIBIT': + cf.LupExhibitFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_BBB': + cf.BBBFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_SOUND_TRIGGER': + cf.SoundTriggerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROXIMITY_MONITOR': + cf.ProximityMonitorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RACING_SOUND_TRIGGER': + cf.RacingSoundTriggerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ROCKET_LAUNCH_LUP': + cf.RocketLaunchLupFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_DONATION_VENDOR': + cf.DonationVendorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ACHIEVEMENT_VENDOR': + cf.AchievmentVendorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_GATE_RUSH': + cf.GateRushFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_RAIL_ACTIVATOR': + cf.RailActivatorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_ROLLER': + cf.RollerFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PLAYER_FORCED_MOVEMENT': + cf.PlayerForcedMovementFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CRAFTING': + cf.CraftingFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_POSSESSABLE': + cf.PossessableFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_POSSESSOR': + cf.PossessorFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_PROPERTY_PLAQUE': + cf.PropertyPlaqueFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_BUILD_BORDER': + cf.BuildBorderFactory(loadObject, objectLoadState, componentId) + + case 'COMPONENT_TYPE_CULLING_PLANE': + cf.CullingPlaneFactory(loadObject, objectLoadState, componentId) + + except KeyError: + print(f'Unknown component: {componentType}') + + if not 'is_smashable' in loadObject.configData and loadObject.bIsSmashable: + loadObject.configData['is_smashable'] = True + + is_smashable = loadObject.configData['is_smashable'] + if is_smashable and not objectLoadState.hasDestroyable and loadObject.lotToSpawn != 176: + objectLoadState.components.append('DESTROYABLE') + + if objectLoadState.hasMissionOffer and not objectLoadState.hasProximityMonitorComponent: + objectLoadState.components.append('PROXIMITY_MONITOR') + objectLoadState.hasProximityMonitorComponent = True + + if loadObject.field8_0x20 and loadObject.owner != 0: + objectLoadState.components.append('OVERHEAD_ICON') + + trigger_id = loadObject.configData.get('trigger_id', 0) + if trigger_id != 0: + objectLoadState.components.append('TRIGGER') + + return objectLoadState + +components_to_load = {} + +# Testing code to load all components +for i in range(110): + components_to_load[i] = i + +objectLoadState = DoObjectPreLoad(components_to_load) + +# Convert the components to ints +components_to_int = [] +for component in objectLoadState.components: + components_to_int.append([cd.components[f'COMPONENT_TYPE_{component}'], component]) + +# Print out the components in a more readable format +for comp in components_to_int: + print(comp[0], comp[1]) diff --git a/__pycache__/ComponentDefinitions.cpython-310.pyc b/__pycache__/ComponentDefinitions.cpython-310.pyc new file mode 100644 index 00000000..12bcc76f Binary files /dev/null and b/__pycache__/ComponentDefinitions.cpython-310.pyc differ diff --git a/__pycache__/ComponentFactories.cpython-310.pyc b/__pycache__/ComponentFactories.cpython-310.pyc new file mode 100644 index 00000000..77a68997 Binary files /dev/null and b/__pycache__/ComponentFactories.cpython-310.pyc differ