activity_sdk_lua_contract.cpp 33 KB

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