activity_sdk_lua_contract.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. #include <algorithm>
  2. #include <array>
  3. #include <cstdio>
  4. #include <vector>
  5. #include "../../../middleware/bap/activity_message/auth_schema_catalog.h"
  6. #include "activity_sdk_lua_artifacts_internal.h"
  7. namespace sunrise::client::content::activity::sdk_generation::lua_artifacts::internal {
  8. /** Emits only generated activity identity and panel-data declarations. */
  9. bool render_contract_files(const Source& source, Bundle& output) noexcept {
  10. try {
  11. const Value manifest = object({
  12. {"schema", string("sunrise-activity-sdk-v8")},
  13. {"format_version", number(format::kVersion)},
  14. {"sdk_build_id", string(digest_hex(source.sdkBuildSha256, true))},
  15. {"sdk_payload_sha256", string(digest_hex(source.sdkPayloadSha256, false))},
  16. {"content_key", string(digest_hex(source.contentKeySha256, true))},
  17. {"logical_ir_sha256", string(digest_hex(source.logicalIrSha256, false))},
  18. {"counts",
  19. object({
  20. {"activities", number(source.activities.size())},
  21. {"slots", number(source.slots.size())},
  22. {"states", number(source.states.size())},
  23. {"squads", number(source.squads.size())},
  24. {"authored_scene_resources", number(source.authoredSceneResources.size())},
  25. {"authored_scene_squad_edges", number(source.authoredSceneSquadEdges.size())},
  26. {"task_targets", number(source.taskTargets.size())},
  27. {"dialogue_cue_texts", number(source.dialogueCueTexts.size())},
  28. {"directive_elements", number(source.directiveElements.size())},
  29. {"behavior_programs", number(source.behaviorPrograms.size())},
  30. {"behavior_inputs", number(source.behaviorInputs.size())},
  31. {"behavior_channel_writes", number(source.behaviorChannelWrites.size())},
  32. {"behavior_owners", number(source.behaviorOwners.size())},
  33. {"behavior_activity_bindings", number(source.behaviorActivityBindings.size())},
  34. {"actor_message_schemas", number(source.actorMessageSchemas.size())},
  35. {"actor_command_definitions", number(source.actorCommandDefinitions.size())},
  36. {"actor_behavior_profiles", number(source.actorBehaviorProfiles.size())},
  37. {"simulation_event_definitions", number(source.simulationEventDefinitions.size())},
  38. {"runtime_schemas", number(source.runtimeSchemas.size())},
  39. {"runtime_fields", number(source.runtimeFields.size())},
  40. {"runtime_type_definitions", number(source.runtimeTypeDefinitions.size())},
  41. {"sobject_rsats", number(source.sobjectRsats.size())},
  42. {"sobject_rsat_descriptors", number(source.sobjectRsatDescriptors.size())},
  43. {"entity_type_definitions", number(source.entityTypeDefinitions.size())},
  44. {"sobject_rsat_field_bindings", number(source.sobjectRsatFieldBindings.size())},
  45. {"actor_state_names", number(source.actorStateNames.size())},
  46. {"actor_sequence_tables", number(source.actorSequenceTables.size())},
  47. {"actor_sequence_entries", number(source.actorSequenceEntries.size())},
  48. {"actor_sequence_bindings", number(source.actorSequenceBindings.size())},
  49. {"authored_scene_event_keys", number(source.authoredSceneEventKeys.size())},
  50. })},
  51. });
  52. if (!render_json(manifest, 0, output.manifestJson)) {
  53. return false;
  54. }
  55. output.manifestJson.push_back('\n');
  56. output.activitySdkModule =
  57. R"lua(-- Generated LuaLS declarations and stable SDK enums. Do not edit.
  58. ---@enum SunriseEventKind
  59. local EventKind = {
  60. SENSOR_SENSE_UPDATED = 0,
  61. CLIENT_STATE_CHANGED = 1,
  62. CLIENT_MESSAGE_RECEIVED = 2,
  63. AUTH_STATE_COMMITTED = 3,
  64. AUTH_STATE_TRANSPORT_STAGED = 4,
  65. AUTH_STATE_CANCELED = 5,
  66. INCIDENT_RECEIVED = 6,
  67. INCIDENT_QUEUED = 7,
  68. INCIDENT_TRANSPORT_STAGED = 8,
  69. INCIDENT_CANCELED = 9,
  70. INCIDENT_REFUSED = 10,
  71. SCRIPTABLE_OVERRIDE_COMMITTED = 11,
  72. SCRIPTABLE_OVERRIDE_TRANSPORT_STAGED = 12,
  73. SCRIPTABLE_OVERRIDE_CANCELED = 13,
  74. OPERATOR_REFUSED = 14,
  75. TIMER_ELAPSED = 15,
  76. EFFECT_RESULT = 16,
  77. PHASE_ENTERED = 17,
  78. TRIGGER_ENTERED = 18,
  79. TRIGGER_EXITED = 19,
  80. SQUAD_STATE = 20,
  81. ENTITY_SPAWNED = 21,
  82. ENTITY_DIED = 22,
  83. SCENE_FINISHED = 23,
  84. OBJECTIVE_PROGRESS = 24,
  85. ENTITY_SLOTS_REQUESTED = 25,
  86. SESSION_JOINED = 26,
  87. SESSION_LEFT = 27,
  88. PLAYER_TRIGGER = 28,
  89. CINEMATIC_STARTED = 29,
  90. CINEMATIC_TERMINATED = 30,
  91. GHOST_LINK_STATE = 31,
  92. ACTOR_PATH_STATE = 32,
  93. OBJECT_INTERACTED = 33,
  94. CINEMATIC_SKIP_REQUESTED = 34,
  95. FIRETEAM_STATE = 35,
  96. OBJECT_STATE = 36,
  97. DAMAGE_STATE = 37,
  98. SQUAD_PROVOKED = 38,
  99. DEVICE_STATE = 39,
  100. REGION_CHANGED = 40,
  101. }
  102. ---@class SunriseEvent
  103. ---@field kind SunriseEventKind
  104. ---@field sequence string
  105. ---@field source_generation string
  106. ---@field attempt_generation string
  107. ---@field mission_sequence string? Input order; absent on delivery lifecycle events.
  108. ---@field slot SunriseSlot?
  109. ---@alias SunriseEventHandler fun(context: any, state: SunriseState, event: SunriseEvent)
  110. ---@class SunrisePlayerTriggerEvent: SunriseEvent
  111. ---@field registry_key integer
  112. ---@field object_tag integer
  113. ---@field slot_type integer
  114. ---@field slot_index integer
  115. ---@field volume_registry_key integer
  116. ---@field volume_slot_type integer
  117. ---@field volume_slot_index integer
  118. ---@field resolved_object_id integer
  119. ---@class SunriseCinematicEvent: SunriseEvent
  120. ---@field registry_key integer
  121. ---@field object_tag integer
  122. ---@field slot_type integer
  123. ---@field slot_index integer
  124. ---@field runtime_object_id string
  125. ---@field event_value number
  126. ---@class SunriseEntitySlotsRequestedEvent: SunriseEvent
  127. ---@field requested_count integer
  128. ---@class SunriseObjectStateEvent: SunriseEvent
  129. ---@field generation integer
  130. ---@field present boolean
  131. ---@field alive boolean
  132. ---@field interaction_open boolean
  133. ---@field owner_known boolean
  134. ---@field has_owner boolean
  135. ---@field owner_key string?
  136. ---@class SunriseGhostLinkLevel
  137. ---@field generation integer
  138. ---@field progress number
  139. ---@field active boolean
  140. ---@class SunriseRegionChangedEvent: SunriseEvent
  141. ---@field region_index integer
  142. ---@field previous_region_index integer?
  143. ---@class SunriseSquadStateEvent: SunriseEvent
  144. ---@field task_cost fun(self: SunriseSquadStateEvent, )lua"
  145. R"lua(args: {group: SunriseCombatTaskGroup}): number|nil, boolean
  146. ---@field task_group fun(self: SunriseSquadStateEvent, )lua"
  147. R"lua(args: {objective: SunriseSlot}): SunriseCombatTaskGroup|nil, boolean
  148. ---@class SunriseDeviceStateEvent: SunriseEvent
  149. ---@field registry_key integer
  150. ---@field object_tag integer
  151. ---@field slot_type integer
  152. ---@field slot_index integer
  153. ---@field position number?
  154. ---@field power number?
  155. ---@field lock number?
  156. ---@field position_sequence integer?
  157. ---@field power_sequence integer?
  158. ---@field lock_sequence integer?
  159. ---@field first_report boolean
  160. ---@field reset boolean
  161. ---@field applied_request fun(self: SunriseDeviceStateEvent, )lua"
  162. R"lua(args: {channel: any}): SunriseRequestKey|nil
  163. ---@class SunriseProgram
  164. ---@field on_start? fun(context: any, state: SunriseState)
  165. ---@field on_load? fun(context: any, state: SunriseState)
  166. ---@field on_event_sensor_sense_updated? SunriseEventHandler
  167. ---@field on_event_client_state_changed? SunriseEventHandler
  168. ---@field on_event_client_message_received? SunriseEventHandler
  169. ---@field on_event_auth_state_committed? SunriseEventHandler
  170. ---@field on_event_auth_state_transport_staged? SunriseEventHandler
  171. ---@field on_event_auth_state_canceled? SunriseEventHandler
  172. ---@field on_event_incident_received? SunriseEventHandler
  173. ---@field on_event_incident_queued? SunriseEventHandler
  174. ---@field on_event_incident_transport_staged? SunriseEventHandler
  175. ---@field on_event_incident_canceled? SunriseEventHandler
  176. ---@field on_event_incident_refused? SunriseEventHandler
  177. ---@field on_event_scriptable_override_committed? SunriseEventHandler
  178. ---@field on_event_scriptable_override_transport_staged? SunriseEventHandler
  179. ---@field on_event_scriptable_override_canceled? SunriseEventHandler
  180. ---@field on_event_operator_refused? SunriseEventHandler
  181. ---@field on_event_timer_elapsed? SunriseEventHandler
  182. ---@field on_event_effect_result? SunriseEventHandler
  183. ---@field on_event_phase_entered? SunriseEventHandler
  184. ---@field on_event_trigger_entered? SunriseEventHandler
  185. ---@field on_event_trigger_exited? SunriseEventHandler
  186. ---@field on_event_squad_state? SunriseEventHandler
  187. ---@field on_event_squad_provoked? SunriseEventHandler
  188. ---@field on_event_region_changed? fun(ctx: any, state: SunriseState, )lua"
  189. R"lua(event: SunriseRegionChangedEvent)
  190. ---@field on_event_device_state? fun(ctx: any, state: SunriseState, event: SunriseDeviceStateEvent)
  191. ---@field on_event_entity_spawned? fun(context: any, state: SunriseState, event: SunriseEvent)
  192. ---@field on_event_entity_died? fun(context: any, state: SunriseState, event: SunriseEvent)
  193. ---@field on_event_scene_finished? fun(context: any, state: SunriseState, event: SunriseEvent)
  194. ---@field on_event_objective_progress? fun(context: any, state: SunriseState, event: SunriseEvent)
  195. ---@field on_event_entity_slots_requested? fun(context: any, state: SunriseState, )lua"
  196. R"lua(event: SunriseEntitySlotsRequestedEvent)
  197. ---@field on_event_session_joined? fun(context: any, state: SunriseState, event: SunriseEvent)
  198. ---@field on_event_session_left? fun(context: any, state: SunriseState, event: SunriseEvent)
  199. ---@field on_event_player_trigger? fun(context: any, state: SunriseState, )lua"
  200. R"lua(event: SunrisePlayerTriggerEvent)
  201. ---@field on_event_cinematic_started? fun(context: any, state: SunriseState, )lua"
  202. R"lua(event: SunriseCinematicEvent)
  203. ---@field on_event_cinematic_terminated? fun(context: any, state: SunriseState, )lua"
  204. R"lua(event: SunriseCinematicEvent)
  205. ---@field on_event_actor_path_state? SunriseEventHandler
  206. ---@field on_event_ghost_link_state? SunriseEventHandler
  207. ---@field on_event_object_interacted? fun(context: any, state: SunriseState, )lua"
  208. R"lua(event: SunriseObjectStateEvent)
  209. ---@field on_event_fireteam_state? SunriseEventHandler
  210. ---@field on_event_object_state? fun(context: any, state: SunriseState, )lua"
  211. R"lua(event: SunriseObjectStateEvent)
  212. ---@field on_event_damage_state? SunriseEventHandler
  213. ---@field on_event_cinematic_skip_requested? fun(context: any, state: SunriseState, )lua"
  214. R"lua(event: SunriseCinematicEvent)
  215. ---@class SunriseVector3
  216. ---@field x number
  217. ---@field y number
  218. ---@field z number
  219. ---@class SunriseSlot
  220. ---@field id string
  221. ---@field name string
  222. ---@field index integer
  223. ---@field type integer
  224. ---@field component_class integer
  225. ---@field sense_schema integer
  226. ---@field auth_schema integer
  227. ---@field auth_type string|nil
  228. ---@field auth_min_bits integer|nil
  229. ---@field auth_max_bits integer|nil
  230. ---@field auth_component_offset integer|nil
  231. ---@field auth_dynamic boolean|nil
  232. ---@field auth_writable boolean|nil
  233. ---@field unresourced boolean|nil
  234. ---@field set_object_active fun(SunriseSlot, SunriseObjectArguments?): SunriseRequestKey
  235. ---@field applied fun(self: SunriseSlot, args: {channel: any}): boolean
  236. ---@field run_atoms fun(self: SunriseSlot, )lua"
  237. R"lua(args: {spawn: boolean?, atoms: table[]}): SunriseRequestKey
  238. ---@field assign_combat_objective fun(self: SunriseSlot, )lua"
  239. R"lua(args: {objective: SunriseSlot, )lua"
  240. R"lua(task_group: SunriseCombatTaskGroup?, reconsider: boolean?, )lua"
  241. R"lua(reserved: boolean?, )lua"
  242. R"lua(refresh_player_awareness: boolean?}): SunriseRequestKey
  243. ---@field play_actor_path fun(self: SunriseSlot, )lua"
  244. R"lua(args: {path: SunriseSlot, spawn: boolean?}): SunriseRequestKey
  245. ---@field play_actor_action fun(self: SunriseSlot, )lua"
  246. R"lua(args: {ability: SunriseActorAbility, )lua"
  247. R"lua(target: SunriseSlot?, spawn: boolean?}): SunriseRequestKey
  248. ---@field retire_actor fun(self: SunriseSlot, args: table?): SunriseRequestKey
  249. ---@field set_darkness_zone fun(self: SunriseSlot, args: {enabled: boolean, )lua"
  250. R"lua(wipe_seconds: integer?}): SunriseRequestKey
  251. ---@field set_interactable_object fun(self: SunriseSlot, args: {track_owner: boolean?, )lua"
  252. R"lua(active: boolean?, used: boolean?}): SunriseRequestKey
  253. ---@field set_ghost_link fun(self: SunriseSlot, args: {active: boolean?}): SunriseRequestKey
  254. ---@field ghost_link fun(self: SunriseSlot, args: table?): SunriseGhostLinkLevel|nil
  255. ---@field set_music_section fun(self: SunriseSlot, args: {section: integer, )lua"
  256. R"lua(enabled: boolean?}): SunriseRequestKey
  257. ---@field watch_damage fun(self: SunriseSlot, args: {target: SunriseSlot}): SunriseRequestKey
  258. ---@field set_occupancy_condition fun(self: SunriseSlot, )lua"
  259. R"lua(args: {value: integer, filter: SunriseSlot?}): SunriseRequestKey
  260. ---@field generate_map fun(self: SunriseSlot, args: {record: integer?, seed: integer?, )lua"
  261. R"lua(mode: integer?, enabled: boolean?, anchors: table[]?, values: integer[]?, )lua"
  262. R"lua(reals: number[]?, state_key: integer?}): SunriseRequestKey
  263. ---@field set_object_filter fun(self: SunriseSlot, args: {players: boolean?, )lua"
  264. R"lua(target: SunriseSlot?, inside: SunriseSlot?, )lua"
  265. R"lua(inside_any: SunriseSlot[]?}): SunriseRequestKey
  266. ---@field bind_combatant_to_squad fun(self: SunriseSlot): SunriseRequestKey
  267. ---@field transition fun(SunriseSlot, SunriseDeviceTransitionArguments): SunriseRequestKey
  268. ---@field set_channel fun(self: SunriseSlot, )lua"
  269. R"lua(args: {channel: any, value: any, snap: boolean?}): SunriseRequestKey
  270. ---@field fire_trigger fun(self: SunriseSlot): SunriseRequestKey
  271. ---@field disarm_trigger fun(self: SunriseSlot): SunriseRequestKey
  272. ---@field sequences fun(self: SunriseSlot): SunriseActorSequences
  273. ---@field play_sequence fun(self: SunriseSlot, args: {sequence: SunriseActorSequence}?): )lua"
  274. R"lua(SunriseRequestKey
  275. ---@field set_cinematic_active fun(SunriseSlot, SunriseCinematicArguments?): SunriseRequestKey
  276. ---@field reset_objectives fun(self: SunriseSlot): SunriseRequestKey
  277. ---@field advance_task fun(self: SunriseSlot): SunriseRequestKey
  278. ---@field play_performance fun(self: SunriseSlot, args: {state: table?}?): SunriseRequestKey
  279. ---@field play_dialogue_cue fun(SunriseSlot, SunriseDialogueCueArguments): SunriseRequestKey
  280. ---@field set_directive fun(SunriseSlot, SunriseDirectiveArguments): SunriseRequestKey
  281. ---@field clear_directives fun(self: SunriseSlot): SunriseRequestKey
  282. ---@field set_public_event_state fun(SunriseSlot, SunrisePublicEventArguments): SunriseRequestKey
  283. ---@class SunriseRequestKey
  284. ---@class SunriseCinematicArguments
  285. ---@field active? boolean
  286. ---@class SunriseObjectArguments
  287. ---@field active? boolean
  288. ---@field with? string[] Up to 63 more type-4 slots sent on the same request.
  289. ---@class SunriseDialogueCueArguments
  290. ---@field cue integer
  291. ---@field filter? SunriseSlot
  292. ---@class SunriseDeviceTransitionArguments
  293. ---@field transition any Generated device transition value.
  294. ---@field snap? boolean Jump to the end value instead of moving.
  295. ---@class SunriseDirective
  296. ---@field id string
  297. ---@field slot_row integer
  298. ---@field name_hash integer
  299. ---@field element integer
  300. ---@field title string
  301. ---@field description string Empty when the element was authored without one.
  302. ---@field progress string|nil Label shown before the counter, when authored.
  303. ---@field counter boolean|nil True when the HUD shows the lane's progress values.
  304. ---@class SunriseDirectiveArguments
  305. ---@field directive SunriseDirective Generated mission directive declaration.
  306. ---@field state? integer Defaults to 0, the native enter state.
  307. ---@field progress? integer[] One to four lane values, current then maximum first; the element must declare a counter.
  308. ---@field audience? SunriseSlot Authored type-70 engagement sensor for the mission banner.
  309. ---@field navpoint? SunriseSlot Authored type-47 navigation marker.
  310. ---@field waypoint? SunriseSlot Authored type-60 volume; inside it the HUD marker hides.
  311. ---@class SunrisePublicEventArguments
  312. ---@field state? integer Shown unchanged by the HUD directive that names this sensor. Defaults to 0.
  313. ---@field player? string Decimal player key of the watched player. Defaults to context.player_key.
  314. ---@field area SunriseSlot The object whose zone list bounds the event area.
  315. ---@field leave_seconds number Seconds outside that area before the client reports Sense 1.
  316. ---@class SunriseState
  317. ---@field id string
  318. ---@field ordinal integer
  319. ---@field slice_set_index integer Authored package slice-set base.
  320. ---@field region_index integer Effective membership region for this state ordinal.
  321. ---@field hash integer
  322. ---@field value integer
  323. ---@class SunriseSquadAnchor: SunriseVector3
  324. ---@field point integer
  325. ---@class SunriseSquadMember
  326. ---@field actor_class integer|nil
  327. ---@field behavior_config integer|nil
  328. ---@field default_faction integer|nil
  329. ---@class SunriseSquad
  330. ---@field id string
  331. ---@field slot integer
  332. ---@field spawner_config integer
  333. ---@field spawn_rule_config integer
  334. ---@field members SunriseSquadMember[]
  335. ---@field anchors SunriseSquadAnchor[]
  336. ---@class SunriseScene
  337. ---@field id string
  338. ---@field slot integer
  339. ---@field config_tag integer
  340. ---@field resource_tag integer
  341. ---@field activate fun(self: SunriseScene, args: {spawn: boolean?}?): SunriseRequestKey
  342. ---@field stop fun(self: SunriseScene, args: table?): SunriseRequestKey
  343. ---@field send_event fun(self: SunriseScene, args: {key: integer}): SunriseRequestKey
  344. ---@field event_keys integer[]|nil
  345. ---@class SunriseTaskTarget
  346. ---@field id string
  347. ---@field task_slot integer
  348. ---@field objective_slot integer
  349. ---@field objective_bit integer
  350. ---@field config_tag integer
  351. ---@class SunriseTriggerVolume
  352. ---@field names string[]
  353. ---@field registry_key integer
  354. ---@field slot_type integer
  355. ---@field slot_index integer
  356. ---@field position SunriseVector3
  357. ---@field minimum SunriseVector3
  358. ---@field maximum SunriseVector3
  359. ---@field shape_tag integer
  360. ---@field shape_index integer
  361. ---@field active integer
  362. ---@class SunriseActorAbility
  363. ---@field slot_row integer
  364. ---@field group_hash integer
  365. ---@field request_hash integer
  366. ---@class SunriseCombatTaskGroup
  367. ---@field slot_row integer
  368. ---@field group_index integer
  369. ---@class SunriseMission
  370. ---@field name string
  371. ---@field id string
  372. ---@field tag integer
  373. ---@field states table<string, SunriseState>
  374. ---@field slots table<string, SunriseSlot>
  375. ---@field squads table<string, SunriseSquad>
  376. ---@field scenes table<string, SunriseScene>
  377. ---@field tasks table<string, SunriseTaskTarget>
  378. ---@field trigger_volumes SunriseTriggerVolume[]
  379. ---@field State table<string, integer>
  380. ---@field Slot table<string, string>
  381. ---@field Auth table<string, table<string, string>> Auth slots grouped by their native Auth type.
  382. ---@field Squad table<string, string>
  383. ---@field Scene table<string, string> Exact occurrence-bound authored scene identities.
  384. ---@field Task table<string, string>
  385. ---@field TaskGroup table<string, table<string, SunriseCombatTaskGroup>>
  386. ---@field ActorAbility table<string, table<string, table<string, SunriseActorAbility>>>
  387. ---@field TriggerVolume table<string, SunriseTriggerVolume>
  388. ---@field Directive table<string, SunriseDirective>
  389. ---@class SunriseActivity
  390. ---@field client_teleport_reset integer
  391. ---@field name string
  392. ---@field display_name string
  393. ---@field id string
  394. ---@field index integer
  395. ---@field definition_hash integer
  396. ---@field activity_root_tag integer
  397. ---@field scenario_tag integer
  398. ---@field matchmaking_config_tag integer
  399. ---@field mission SunriseMission|nil
  400. local sdk = {}
  401. sdk.EventKind = EventKind
  402. sdk.SlotType = {
  403. SQUAD = 1,
  404. SEQUENCE = 5,
  405. CINEMATIC = 6,
  406. DEVICE = 23,
  407. TRIGGER = 31,
  408. TASK = 38,
  409. SCENE = 43,
  410. TRIGGER_VOLUME = 60,
  411. }
  412. return sdk
  413. )lua";
  414. const std::size_t returnOffset = output.activitySdkModule.rfind("return sdk\n");
  415. if (returnOffset == std::string::npos) {
  416. return false;
  417. }
  418. std::string authTypes = "---@class SunriseAuthType\n"
  419. "---@field name string\n"
  420. "---@field slot_type integer\n"
  421. "---@field schema integer\n"
  422. "---@field struct_bytes integer\n"
  423. "---@field min_bits integer\n"
  424. "---@field max_bits integer\n"
  425. "---@field component_offset integer|nil\n"
  426. "---@field dynamic boolean\n"
  427. "---@field writable boolean\n\n"
  428. "---@type table<string, SunriseAuthType>\n"
  429. "sdk.AuthType = {\n";
  430. std::array<char, 320> authLine{};
  431. for (const auto& auth : middleware::bap::activity_message::auth_schema_catalog::kTypes) {
  432. const int written = auth.hasContiguousMirror
  433. ? std::snprintf(authLine.data(),
  434. authLine.size(),
  435. " [\"%.*s\"] = { name = \"%.*s\", "
  436. "slot_type = %u, schema = 0x%08X, "
  437. "struct_bytes = %u, min_bits = %u, "
  438. "max_bits = %u, component_offset = %u, "
  439. "dynamic = %s, writable = %s },\n",
  440. static_cast<int>(auth.name.size()),
  441. auth.name.data(),
  442. static_cast<int>(auth.name.size()),
  443. auth.name.data(),
  444. auth.slotType,
  445. auth.schema,
  446. auth.structBytes,
  447. auth.minimumBits,
  448. auth.maximumBits,
  449. auth.componentOffset,
  450. auth.hasDynamicBody ? "true" : "false",
  451. auth.writable ? "true" : "false")
  452. : std::snprintf(authLine.data(),
  453. authLine.size(),
  454. " [\"%.*s\"] = { name = \"%.*s\", "
  455. "slot_type = %u, schema = 0x%08X, "
  456. "struct_bytes = %u, min_bits = %u, "
  457. "max_bits = %u, component_offset = nil, "
  458. "dynamic = %s, writable = %s },\n",
  459. static_cast<int>(auth.name.size()),
  460. auth.name.data(),
  461. static_cast<int>(auth.name.size()),
  462. auth.name.data(),
  463. auth.slotType,
  464. auth.schema,
  465. auth.structBytes,
  466. auth.minimumBits,
  467. auth.maximumBits,
  468. auth.hasDynamicBody ? "true" : "false",
  469. auth.writable ? "true" : "false");
  470. if (written <= 0 || static_cast<std::size_t>(written) >= authLine.size()) {
  471. return false;
  472. }
  473. authTypes.append(authLine.data(), static_cast<std::size_t>(written));
  474. }
  475. authTypes.append(R"lua(}
  476. ---@class SunriseType2LaneClientRef
  477. ---@field registry_key integer
  478. ---@field slot_type integer
  479. ---@field slot_index integer
  480. sdk.CombatantLanePrimarySchema = {
  481. REF_BYTE = 0x80807F7F,
  482. U32 = 0x80807F7E,
  483. REAL32 = 0x80807F7D,
  484. REF_BYTE_BOOL = 0x80807F7A,
  485. EMPTY = 0x80807F79,
  486. U6 = 0x80807F80,
  487. U32_BOOL = 0x80807F78,
  488. U32_REAL32 = 0x80807F81,
  489. ALTERNATE_REF_BYTE = 0x80807F77,
  490. TRIPLE_U32_REF_MODES = 0x80807F76,
  491. }
  492. sdk.CombatantLaneSecondarySchema = {
  493. EMPTY_A = 0x80807F8B,
  494. EMPTY_B = 0x80807F8A,
  495. QUANTIZED_11 = 0x80807F89,
  496. }
  497. -- Authored behavior-condition classes embedded in package behavior graphs.
  498. sdk.AuthoredBehaviorFilterClass = {
  499. ACTIVITY_FLAG = 0x80804D83,
  500. ACTOR = 0x80804D82,
  501. AIRBORNE = 0x80804D81,
  502. CHANNEL = 0x80804D7D,
  503. HAS_PARENT = 0x80804D80,
  504. DAMAGE_OWNER = 0x80804D7C,
  505. DEAD = 0x80804D7B,
  506. DISTANCE = 0x80804D7A,
  507. FACTION = 0x80804D78,
  508. FACTION_RELATIONSHIP = 0x80804D76,
  509. HOP_ON = 0x80804D75,
  510. LINE_OF_SIGHT = 0x80804D74,
  511. OBJECT_LABEL = 0x80804D73,
  512. OBJECT_TYPE = 0x80804D72,
  513. PLAYER = 0x80804D71,
  514. RESOURCE = 0x80804D5F,
  515. SAME_OBJECT = 0x80802F95,
  516. SCOREBOARD_STAT = 0x80804D5E,
  517. TEAM_SIDE = 0x80804D5D,
  518. COMPOSITE = 0x80809310,
  519. EXTERNAL = 0x8080930F,
  520. }
  521. -- Compact code-34 Auth predicate schemas. These are a separate runtime registry.
  522. sdk.ObjectFilterPredicateSchema = {
  523. MODE_U32_A = 0x80809571,
  524. MODE_U32_B = 0x80809572,
  525. MODE_ONLY_A = 0x80809573,
  526. UNREGISTERED_MODE_SLOT_REF = 0x80809574,
  527. MODE_U32_C = 0x80809575,
  528. MODE_FLAG_SLOT_REF = 0x80809576,
  529. MODE_SLOT_REF_A = 0x80809577,
  530. MODE_SLOT_REF_B = 0x80809578,
  531. MODE_SLOT_REF_C = 0x80809579,
  532. MODE_I32 = 0x8080957A,
  533. MODE_SLOT_REF_D = 0x8080957B,
  534. MODE_U32_D = 0x8080957C,
  535. MODE_ONLY_B = 0x8080957D,
  536. }
  537. ---@class SunriseObjectFilterModeOnly
  538. ---@field mode integer
  539. ---@class SunriseObjectFilterModeU32: SunriseObjectFilterModeOnly
  540. ---@field value integer
  541. ---@class SunriseObjectFilterModeSlotRef: SunriseObjectFilterModeOnly
  542. ---@field reference SunriseType2LaneClientRef
  543. ---@class SunriseObjectFilterModeFlagSlotRef: SunriseObjectFilterModeSlotRef
  544. ---@field flag boolean
  545. )lua");
  546. append_actor_sequence_contract(source, authTypes);
  547. output.activitySdkModule.insert(returnOffset, authTypes);
  548. output.behaviorModule =
  549. "-- Generated compiled behavior declarations. Do not edit.\n"
  550. "local behavior = {}\n\n"
  551. "behavior.InputSelector = { TARGET_OBJECT = 0, CONTEXT_PRIMARY_OBJECT = 1, "
  552. "CONTEXT_SECONDARY_OBJECT = 2 }\n"
  553. "behavior.InputRole = { ACTION = 1, CONDITION_LEFT = 2, CONDITION_RIGHT = 3 }\n\n"
  554. "behavior.Program = {\n";
  555. std::array<char, 320> line{};
  556. for (const format::BehaviorProgram& row : source.behaviorPrograms) {
  557. const int written = std::snprintf(
  558. line.data(),
  559. line.size(),
  560. " ROOT_%08X = { tag = 0x%08X, first_input = %u, input_count = %u, "
  561. "first_write = %u, write_count = %u, node_count = %u, expression_count = %u },\n",
  562. row.rootTag,
  563. row.rootTag,
  564. row.inputs.first,
  565. row.inputs.count,
  566. row.channelWrites.first,
  567. row.channelWrites.count,
  568. row.nodeCount,
  569. row.expressionCount);
  570. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  571. return false;
  572. }
  573. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  574. }
  575. output.behaviorModule.append("}\n\nbehavior.Channel = {\n");
  576. std::vector<std::uint32_t> behaviorChannels{};
  577. behaviorChannels.reserve(source.behaviorInputs.size()
  578. + source.behaviorChannelWrites.size());
  579. for (const format::BehaviorInput& row : source.behaviorInputs) {
  580. behaviorChannels.push_back(row.channelHash);
  581. }
  582. for (const format::BehaviorChannelWrite& row : source.behaviorChannelWrites) {
  583. behaviorChannels.push_back(row.channelHash);
  584. }
  585. std::sort(behaviorChannels.begin(), behaviorChannels.end());
  586. behaviorChannels.erase(std::unique(behaviorChannels.begin(), behaviorChannels.end()),
  587. behaviorChannels.end());
  588. for (const std::uint32_t channel : behaviorChannels) {
  589. const int written = std::snprintf(
  590. line.data(), line.size(), " CHANNEL_%08X = 0x%08X,\n", channel, channel);
  591. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  592. return false;
  593. }
  594. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  595. }
  596. output.behaviorModule.append("}\n\nbehavior.Input = {\n");
  597. for (const format::BehaviorInput& row : source.behaviorInputs) {
  598. const int written =
  599. std::snprintf(line.data(),
  600. line.size(),
  601. " { program = %u, node_offset = 0x%X, expression_offset = 0x%X, "
  602. "channel = behavior.Channel.CHANNEL_%08X, input_or_mode = \"%llu\", "
  603. "native_override = %d, "
  604. "active_field = %u, selector = %u, role = %u },\n",
  605. row.programIndex,
  606. row.nodeOffset,
  607. row.expressionOffset,
  608. row.channelHash,
  609. static_cast<unsigned long long>(row.inputOrMode),
  610. row.nativeOverride,
  611. row.activeField,
  612. static_cast<unsigned int>(row.selector),
  613. static_cast<unsigned int>(row.role));
  614. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  615. return false;
  616. }
  617. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  618. }
  619. output.behaviorModule.append("}\n\nbehavior.ChannelWrite = {\n");
  620. for (const format::BehaviorChannelWrite& row : source.behaviorChannelWrites) {
  621. const int written = std::snprintf(line.data(),
  622. line.size(),
  623. " { program = %u, node_offset = 0x%X, "
  624. "channel = behavior.Channel.CHANNEL_%08X },\n",
  625. row.programIndex,
  626. row.nodeOffset,
  627. row.channelHash);
  628. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  629. return false;
  630. }
  631. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  632. }
  633. output.behaviorModule.append("}\n\nbehavior.SubmissionKind = { ACTIVE_NATIVE = 0, PASSIVE "
  634. "= 1, UNRESOLVED = 2 }\n\nbehavior.Owner = {\n");
  635. for (const format::BehaviorOwner& row : source.behaviorOwners) {
  636. const int written =
  637. std::snprintf(line.data(),
  638. line.size(),
  639. " { program = %u, actor_class = %u, config = 0x%08X, "
  640. "config_offset = 0x%X, build = %u, descriptor = %u, subtype = "
  641. "0x%08X, kind = %u },\n",
  642. row.programIndex,
  643. row.actorClassIndex,
  644. row.configTag,
  645. row.configFieldOffset,
  646. row.buildOrdinal,
  647. row.descriptorOrdinal,
  648. row.submitterSubtype,
  649. static_cast<unsigned int>(row.submissionKind));
  650. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  651. return false;
  652. }
  653. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  654. }
  655. output.behaviorModule.append("}\n\nbehavior.ActivityBinding = {\n");
  656. for (const format::BehaviorActivityBinding& row : source.behaviorActivityBindings) {
  657. const int written = std::snprintf(line.data(),
  658. line.size(),
  659. " { owner = %u, squad = %u, member = %u, scenario "
  660. "= %u, occurrence = %u, state = %u, object = %u },\n",
  661. row.ownerIndex,
  662. row.squadIndex,
  663. row.squadMemberIndex,
  664. row.scenarioIndex,
  665. row.occurrenceIndex,
  666. row.stateIndex,
  667. row.objectIndex);
  668. if (written <= 0 || static_cast<std::size_t>(written) >= line.size()) {
  669. return false;
  670. }
  671. output.behaviorModule.append(line.data(), static_cast<std::size_t>(written));
  672. }
  673. output.behaviorModule.append("}\n\nreturn behavior\n");
  674. return true;
  675. } catch (...) {
  676. output.manifestJson.clear();
  677. output.activitySdkModule.clear();
  678. output.behaviorModule.clear();
  679. return false;
  680. }
  681. }
  682. } // namespace sunrise::client::content::activity::sdk_generation::lua_artifacts::internal