From: hgn Date: Wed, 21 May 2025 01:32:59 +0000 (+0100) Subject: yeaaaaaaaaaaa X-Git-Url: https://harrygodden.com/git/?a=commitdiff_plain;h=1fb0ecb189b091245344665f9432e2b30f8d9e2b;p=carveJwlIkooP6JGAAIwe30JlM.git yeaaaaaaaaaaa --- diff --git a/content_skaterift/maps/dev_tutorial/main.mdl b/content_skaterift/maps/dev_tutorial/main.mdl index 0282cad..d7beaab 100644 Binary files a/content_skaterift/maps/dev_tutorial/main.mdl and b/content_skaterift/maps/dev_tutorial/main.mdl differ diff --git a/content_skaterift/maps/mp_line1/main.mdl b/content_skaterift/maps/mp_line1/main.mdl index 019bc06..76975d9 100644 Binary files a/content_skaterift/maps/mp_line1/main.mdl and b/content_skaterift/maps/mp_line1/main.mdl differ diff --git a/content_skaterift/maps/mp_spawn/main.mdl b/content_skaterift/maps/mp_spawn/main.mdl index ca6fba1..940b7d6 100644 Binary files a/content_skaterift/maps/mp_spawn/main.mdl and b/content_skaterift/maps/mp_spawn/main.mdl differ diff --git a/content_skaterift/metascenes/battery_intro.ms b/content_skaterift/metascenes/battery_intro.ms deleted file mode 100644 index 831d89c..0000000 Binary files a/content_skaterift/metascenes/battery_intro.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch1s2.ms b/content_skaterift/metascenes/ch1s2.ms index dab0ebe..905d945 100644 Binary files a/content_skaterift/metascenes/ch1s2.ms and b/content_skaterift/metascenes/ch1s2.ms differ diff --git a/content_skaterift/metascenes/ch1s3.ms b/content_skaterift/metascenes/ch1s3.ms deleted file mode 100644 index 3d2576d..0000000 Binary files a/content_skaterift/metascenes/ch1s3.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch1s3b.ms b/content_skaterift/metascenes/ch1s3b.ms deleted file mode 100644 index e760242..0000000 Binary files a/content_skaterift/metascenes/ch1s3b.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch1s4.ms b/content_skaterift/metascenes/ch1s4.ms deleted file mode 100644 index 4a4901f..0000000 Binary files a/content_skaterift/metascenes/ch1s4.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch1s5.ms b/content_skaterift/metascenes/ch1s5.ms index 5fa5f81..c390b88 100644 Binary files a/content_skaterift/metascenes/ch1s5.ms and b/content_skaterift/metascenes/ch1s5.ms differ diff --git a/content_skaterift/metascenes/ch1s6a.ms b/content_skaterift/metascenes/ch1s6a.ms deleted file mode 100644 index cc1d3f0..0000000 Binary files a/content_skaterift/metascenes/ch1s6a.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2e1.ms b/content_skaterift/metascenes/ch2e1.ms deleted file mode 100644 index 5565ebf..0000000 Binary files a/content_skaterift/metascenes/ch2e1.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s1.ms b/content_skaterift/metascenes/ch2s1.ms deleted file mode 100644 index 5fa2d0a..0000000 Binary files a/content_skaterift/metascenes/ch2s1.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s2.ms b/content_skaterift/metascenes/ch2s2.ms deleted file mode 100644 index 43abc64..0000000 Binary files a/content_skaterift/metascenes/ch2s2.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s3a.ms b/content_skaterift/metascenes/ch2s3a.ms deleted file mode 100644 index 66b50d5..0000000 Binary files a/content_skaterift/metascenes/ch2s3a.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s4.ms b/content_skaterift/metascenes/ch2s4.ms deleted file mode 100644 index 8060b61..0000000 Binary files a/content_skaterift/metascenes/ch2s4.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s5.ms b/content_skaterift/metascenes/ch2s5.ms deleted file mode 100644 index 063c7f7..0000000 Binary files a/content_skaterift/metascenes/ch2s5.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch2s6.ms b/content_skaterift/metascenes/ch2s6.ms deleted file mode 100644 index 73ed57c..0000000 Binary files a/content_skaterift/metascenes/ch2s6.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch3s1.ms b/content_skaterift/metascenes/ch3s1.ms deleted file mode 100644 index 2091c2c..0000000 Binary files a/content_skaterift/metascenes/ch3s1.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch3s2.ms b/content_skaterift/metascenes/ch3s2.ms deleted file mode 100644 index 0990752..0000000 Binary files a/content_skaterift/metascenes/ch3s2.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch3s3.ms b/content_skaterift/metascenes/ch3s3.ms deleted file mode 100644 index 2e1c064..0000000 Binary files a/content_skaterift/metascenes/ch3s3.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch4s1.ms b/content_skaterift/metascenes/ch4s1.ms deleted file mode 100644 index 6e858e5..0000000 Binary files a/content_skaterift/metascenes/ch4s1.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch4s1a.ms b/content_skaterift/metascenes/ch4s1a.ms deleted file mode 100644 index 221baff..0000000 Binary files a/content_skaterift/metascenes/ch4s1a.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch4s2.ms b/content_skaterift/metascenes/ch4s2.ms deleted file mode 100644 index 031a3e9..0000000 Binary files a/content_skaterift/metascenes/ch4s2.ms and /dev/null differ diff --git a/content_skaterift/metascenes/ch4s3.ms b/content_skaterift/metascenes/ch4s3.ms deleted file mode 100644 index 5fe7a9f..0000000 Binary files a/content_skaterift/metascenes/ch4s3.ms and /dev/null differ diff --git a/content_skaterift/metascenes/grave/battery_intro.ms b/content_skaterift/metascenes/grave/battery_intro.ms new file mode 100644 index 0000000..831d89c Binary files /dev/null and b/content_skaterift/metascenes/grave/battery_intro.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s2.ms b/content_skaterift/metascenes/grave/ch1s2.ms new file mode 100644 index 0000000..dab0ebe Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s2.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s3.ms b/content_skaterift/metascenes/grave/ch1s3.ms new file mode 100644 index 0000000..3d2576d Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s3.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s3b.ms b/content_skaterift/metascenes/grave/ch1s3b.ms new file mode 100644 index 0000000..e760242 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s3b.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s4.ms b/content_skaterift/metascenes/grave/ch1s4.ms new file mode 100644 index 0000000..4a4901f Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s4.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s5.ms b/content_skaterift/metascenes/grave/ch1s5.ms new file mode 100644 index 0000000..5fa5f81 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s5.ms differ diff --git a/content_skaterift/metascenes/grave/ch1s6a.ms b/content_skaterift/metascenes/grave/ch1s6a.ms new file mode 100644 index 0000000..58ee0bf Binary files /dev/null and b/content_skaterift/metascenes/grave/ch1s6a.ms differ diff --git a/content_skaterift/metascenes/grave/ch2e1.ms b/content_skaterift/metascenes/grave/ch2e1.ms new file mode 100644 index 0000000..5565ebf Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2e1.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s1.ms b/content_skaterift/metascenes/grave/ch2s1.ms new file mode 100644 index 0000000..5fa2d0a Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s1.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s2.ms b/content_skaterift/metascenes/grave/ch2s2.ms new file mode 100644 index 0000000..43abc64 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s2.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s3a.ms b/content_skaterift/metascenes/grave/ch2s3a.ms new file mode 100644 index 0000000..66b50d5 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s3a.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s4.ms b/content_skaterift/metascenes/grave/ch2s4.ms new file mode 100644 index 0000000..8060b61 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s4.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s5.ms b/content_skaterift/metascenes/grave/ch2s5.ms new file mode 100644 index 0000000..063c7f7 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s5.ms differ diff --git a/content_skaterift/metascenes/grave/ch2s6.ms b/content_skaterift/metascenes/grave/ch2s6.ms new file mode 100644 index 0000000..73ed57c Binary files /dev/null and b/content_skaterift/metascenes/grave/ch2s6.ms differ diff --git a/content_skaterift/metascenes/grave/ch3s1.ms b/content_skaterift/metascenes/grave/ch3s1.ms new file mode 100644 index 0000000..2091c2c Binary files /dev/null and b/content_skaterift/metascenes/grave/ch3s1.ms differ diff --git a/content_skaterift/metascenes/grave/ch3s2.ms b/content_skaterift/metascenes/grave/ch3s2.ms new file mode 100644 index 0000000..0990752 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch3s2.ms differ diff --git a/content_skaterift/metascenes/grave/ch3s3.ms b/content_skaterift/metascenes/grave/ch3s3.ms new file mode 100644 index 0000000..2e1c064 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch3s3.ms differ diff --git a/content_skaterift/metascenes/grave/ch4rk.ms b/content_skaterift/metascenes/grave/ch4rk.ms new file mode 100644 index 0000000..d2c4efe Binary files /dev/null and b/content_skaterift/metascenes/grave/ch4rk.ms differ diff --git a/content_skaterift/metascenes/grave/ch4s1.ms b/content_skaterift/metascenes/grave/ch4s1.ms new file mode 100644 index 0000000..6e858e5 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch4s1.ms differ diff --git a/content_skaterift/metascenes/grave/ch4s1a.ms b/content_skaterift/metascenes/grave/ch4s1a.ms new file mode 100644 index 0000000..eb38e45 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch4s1a.ms differ diff --git a/content_skaterift/metascenes/grave/ch4s2.ms b/content_skaterift/metascenes/grave/ch4s2.ms new file mode 100644 index 0000000..8b4ccf3 Binary files /dev/null and b/content_skaterift/metascenes/grave/ch4s2.ms differ diff --git a/content_skaterift/metascenes/grave/ch4s3.ms b/content_skaterift/metascenes/grave/ch4s3.ms new file mode 100644 index 0000000..5fe7a9f Binary files /dev/null and b/content_skaterift/metascenes/grave/ch4s3.ms differ diff --git a/content_skaterift/metascenes/grave/intro.ms b/content_skaterift/metascenes/grave/intro.ms new file mode 100644 index 0000000..3488977 Binary files /dev/null and b/content_skaterift/metascenes/grave/intro.ms differ diff --git a/content_skaterift/metascenes/grave/skater.ms b/content_skaterift/metascenes/grave/skater.ms new file mode 100644 index 0000000..fab3de8 Binary files /dev/null and b/content_skaterift/metascenes/grave/skater.ms differ diff --git a/content_skaterift/metascenes/grave/test_scene.ms b/content_skaterift/metascenes/grave/test_scene.ms new file mode 100644 index 0000000..b5c5c1f Binary files /dev/null and b/content_skaterift/metascenes/grave/test_scene.ms differ diff --git a/content_skaterift/metascenes/grave/unlock_city.ms b/content_skaterift/metascenes/grave/unlock_city.ms new file mode 100644 index 0000000..001e689 Binary files /dev/null and b/content_skaterift/metascenes/grave/unlock_city.ms differ diff --git a/content_skaterift/metascenes/grave/unlock_docks.ms b/content_skaterift/metascenes/grave/unlock_docks.ms new file mode 100644 index 0000000..9e29743 Binary files /dev/null and b/content_skaterift/metascenes/grave/unlock_docks.ms differ diff --git a/content_skaterift/metascenes/grave/unlock_mtzero.ms b/content_skaterift/metascenes/grave/unlock_mtzero.ms new file mode 100644 index 0000000..c61668e Binary files /dev/null and b/content_skaterift/metascenes/grave/unlock_mtzero.ms differ diff --git a/content_skaterift/metascenes/grave/unlock_valley.ms b/content_skaterift/metascenes/grave/unlock_valley.ms new file mode 100644 index 0000000..77285f1 Binary files /dev/null and b/content_skaterift/metascenes/grave/unlock_valley.ms differ diff --git a/content_skaterift/metascenes/intro.ms b/content_skaterift/metascenes/intro.ms deleted file mode 100644 index 3488977..0000000 Binary files a/content_skaterift/metascenes/intro.ms and /dev/null differ diff --git a/content_skaterift/metascenes/skater.ms b/content_skaterift/metascenes/skater.ms index fab3de8..6f24ae1 100644 Binary files a/content_skaterift/metascenes/skater.ms and b/content_skaterift/metascenes/skater.ms differ diff --git a/content_skaterift/metascenes/test_scene.ms b/content_skaterift/metascenes/test_scene.ms deleted file mode 100644 index b5c5c1f..0000000 Binary files a/content_skaterift/metascenes/test_scene.ms and /dev/null differ diff --git a/content_skaterift/metascenes/unlock_city.ms b/content_skaterift/metascenes/unlock_city.ms deleted file mode 100644 index 001e689..0000000 Binary files a/content_skaterift/metascenes/unlock_city.ms and /dev/null differ diff --git a/content_skaterift/metascenes/unlock_docks.ms b/content_skaterift/metascenes/unlock_docks.ms index 9e29743..b9455cf 100644 Binary files a/content_skaterift/metascenes/unlock_docks.ms and b/content_skaterift/metascenes/unlock_docks.ms differ diff --git a/content_skaterift/metascenes/unlock_mtzero.ms b/content_skaterift/metascenes/unlock_mtzero.ms deleted file mode 100644 index c61668e..0000000 Binary files a/content_skaterift/metascenes/unlock_mtzero.ms and /dev/null differ diff --git a/content_skaterift/metascenes/unlock_valley.ms b/content_skaterift/metascenes/unlock_valley.ms deleted file mode 100644 index 77285f1..0000000 Binary files a/content_skaterift/metascenes/unlock_valley.ms and /dev/null differ diff --git a/content_skaterift/models/rk.mdl b/content_skaterift/models/rk.mdl new file mode 100644 index 0000000..92a2727 Binary files /dev/null and b/content_skaterift/models/rk.mdl differ diff --git a/content_skaterift/sound/cs/rk.ogg b/content_skaterift/sound/cs/rk.ogg new file mode 100644 index 0000000..933f4d6 Binary files /dev/null and b/content_skaterift/sound/cs/rk.ogg differ diff --git a/shaders/model_character_view.fs b/shaders/model_character_view.fs index 502d672..42fadcb 100644 --- a/shaders/model_character_view.fs +++ b/shaders/model_character_view.fs @@ -1,5 +1,6 @@ uniform sampler2D uTexMain; uniform vec3 uCamera; +uniform int uShadeless; in vec4 aColour; in vec2 aUv; @@ -16,23 +17,16 @@ vec3 character_clearskies_lighting( vec3 normal, float shadow, vec3 halfview ) { float fresnel = 1.0 - abs(dot(normal,halfview)); - vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, - g_sunset_phase ); - - + vec3 reflect_colour = mix( g_daysky_colour.rgb, g_sunset_colour.rgb, g_sunset_phase ); vec3 sky_reflection = 0.5 * fresnel * reflect_colour; - vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) - * g_sun_colour.rgb * g_day_phase; + vec3 light_sun = max(0.0, dot(normal,g_sun_dir.xyz)*0.5+0.5) * g_sun_colour.rgb * g_day_phase; float scaled_shadow = max( shadow, 1.0 - max(g_sun_dir.y,0.0) ); - vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, - g_sunset_phase ); - + vec3 ambient = mix( g_ambient_colour.rgb, g_sunset_ambient.rgb, g_sunset_phase ); return ambient + (light_sun + sky_reflection) * shadow; } -vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co, - float light_mask ) +vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co, float light_mask ) { if( g_light_preview == 1 ) diffuse = vec3(0.75); @@ -42,11 +36,8 @@ vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co, float fdist = length(halfview); halfview /= fdist; - float world_shadow = newlight_compute_sun_shadow( - co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) ); - - vec3 total_light = character_clearskies_lighting( - normal, min( light_mask, world_shadow ), halfview ); + float world_shadow = newlight_compute_sun_shadow( co, g_sun_dir.xyz * (1.0/(max(g_sun_dir.y,0.0)+0.2)) ); + vec3 total_light = character_clearskies_lighting( normal, min( light_mask, world_shadow ), halfview ); vec3 cube_coord = (co - g_cube_min.xyz) * g_cube_inv_range.xyz; cube_coord = floor( cube_coord ); @@ -70,14 +61,8 @@ vec3 character_compute_lighting( vec3 diffuse, vec3 normal, vec3 co, ivec3 coord = ivec3( cube_coord ); uvec4 index_sample = texelFetch( uLightsIndex, coord, 0 ); - total_light += - scene_calculate_packed_light_patch( index_sample.x, - halfview, co, normal ) - * light_mask; - total_light += - scene_calculate_packed_light_patch( index_sample.y, - halfview, co, normal ) - * light_mask; + total_light += scene_calculate_packed_light_patch( index_sample.x, halfview, co, normal ) * light_mask; + total_light += scene_calculate_packed_light_patch( index_sample.y, halfview, co, normal ) * light_mask; // Take a section of the sky function to give us a matching fog colour @@ -101,6 +86,9 @@ void main(){ vec3 diffuse = texture( uTexMain, aUv ).rgb; vec3 composite = character_compute_lighting( diffuse, qnorm, aWorldCo, 1.0 ); + if( uShadeless == 1 ) + composite = diffuse; + float dist = distance( aWorldCo, uCamera ) - 0.08; float opacity = clamp( dist*dist, 0.0, 1.0 ); diff --git a/skaterift_blender/sr_main.py b/skaterift_blender/sr_main.py index 0aca2e1..3346195 100644 --- a/skaterift_blender/sr_main.py +++ b/skaterift_blender/sr_main.py @@ -30,7 +30,7 @@ sr_entity_list = [ ('ent_ccmd', 'CCmd', '', 17 ), ('ent_objective', 'Objective', '', 18 ), ('ent_challenge', 'Challenge', '', 19 ), - ('ent_relay', 'Relay', '', 20 ), + ('ent_relay', 'DELETED0', '', 20 ), # reserved 21.. cubemap. ('ent_miniworld', 'Mini World', '', 22 ), ('ent_prop', 'Prop', '', 23 ), @@ -39,14 +39,15 @@ sr_entity_list = [ ('ent_glider', 'Glider', '', 26 ), ('ent_npc', 'npc', '', 27 ), # reserved 28.. armature - ('ent_script', 'Script', '', 29 ) + ('ent_script', 'Script', '', 29 ), + ('ent_cutscene', 'Cutscene', '', 30 ), ] MDL_VERSION_NR = 109 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \ 'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\ 'ent_miniworld', 'ent_region', 'ent_glider', 'ent_list',\ - 'ent_npc', 'ent_water', 'ent_script' ] + 'ent_npc', 'ent_water' ] def get_entity_enum_id( alias ): #{ @@ -177,6 +178,27 @@ class mdl_texture(Structure): ("glname",c_uint32)] #} +class ent_event_data_union(Union): +#{ + _fields_ = [("const_i32",c_int32), + ("const_f32",c_float), + ("const_entity_id",c_uint32), + ("const_pstr",c_uint32), + ("pstr_data_alias",c_uint32)] +#} + +class ent_event(Structure): +#{ + _fields_ = [("pstr_source_event",c_uint32), + ("pstr_recieve_event",c_uint32), + ("source_entity_id",c_uint32), + ("recieve_entity_id",c_uint32), + ("flags",c_uint32), + ("delay",c_float), + ("unused0",c_uint32), + ("data", ent_event_data_union )] +#} + class ent_spawn(Structure): #{ _fields_ = [("transform",mdl_transform), @@ -219,7 +241,7 @@ class ent_gate(Structure): ("submesh_start",c_uint32), # v102+ ("submesh_count",c_uint32), # v102+ (can be 0) ] - sr_functions = { 0: 'unlock' } + sr_functions = { 'lock': 0x1 } #} class ent_route_node(Structure): @@ -266,7 +288,7 @@ class ent_list(Structure): # used in ent_list class file_entity_ref(Structure): #{ - _fields_ = [("entity_id",c_uint32)] + _fields_ = [("entity_id",c_uint32),("pstr_alias",c_uint32)] #} class ent_checkpoint(Structure): @@ -291,22 +313,30 @@ class ent_route(Structure): ("id_camera",c_uint32), # v103+ ] - sr_functions = { 0: 'view' } + sr_functions = { 'view': 0x00 } #} -class ent_glider(Structure):#{ +class ent_glider(Structure): +#{ _fields_ = [("transform",mdl_transform), ("flags",c_uint32), ("cooldown",c_float)] - sr_functions = { 0: 'unlock', - 1: 'equip' } + sr_functions = { 'lock': 0x1, 'equip': 0x00 } #} -class ent_npc(Structure):#{ +class ent_npc(Structure): +#{ _fields_ = [("transform",mdl_transform), ("pstr_id",c_uint32), ("pstr_context_id",c_uint32)] - sr_functions = { 1: 'proximity', 0: 'interact', -1: 'unproximity' } + sr_functions = { 'proximity': 0x00, 'interact': 0x00 } +#} + +class ent_script(Structure): +#{ + _fields_ = [("pstr_script_name",c_uint32), + ("deleted0",c_uint32), + ("flags",c_uint32)] #} class ent_water(Structure): @@ -315,13 +345,13 @@ class ent_water(Structure): ("max_dist",c_float), ("reserved0",c_uint32), ("reserved1",c_uint32)] - sr_functions = { 0: "drown" } + sr_functions = { 'drown': 0x00 } #} class volume_trigger(Structure): #{ - _fields_ = [("event",c_uint32), - ("event_leave",c_int32)] + _fields_ = [("blank",c_uint32), + ("blank2",c_int32)] #} class volume_particles(Structure): @@ -332,7 +362,7 @@ class volume_particles(Structure): class volume_interact(Structure): #{ - _fields_ = [("event",c_uint32), + _fields_ = [("blank",c_uint32), ("pstr_text",c_int32)] #} @@ -349,7 +379,7 @@ class ent_volume(Structure): ("to_world",(c_float*3)*4), ("to_local",(c_float*3)*4), ("flags",c_uint32), - ("target",c_uint32), + ("deleted0",c_uint32), ("_anon",volume_union)] #} @@ -365,6 +395,7 @@ class ent_audio(Structure): ("group",c_uint32), ("probability_curve",c_uint32), ("max_channels",c_uint32)] + sr_functions = { 'play': 0x00, 'spawn_particle': 0x00 } #} class ent_marker(Structure): @@ -444,8 +475,7 @@ class ent_skateshop(Structure): _fields_ = [("transform",mdl_transform), ("type",c_uint32), ("id_camera",c_uint32), ("_anonymous_union",ent_skateshop_anon_union)] - - sr_functions = { 0: 'view', -1: 'unview' } + sr_functions = { 'open': 0x00 } #} class ent_swspreview(Structure): @@ -457,8 +487,7 @@ class ent_swspreview(Structure): class ent_camera(Structure): #{ - _fields_ = [("co",c_float*3),("r",c_float*3), - ("fov",c_float)] + _fields_ = [("co",c_float*3),("r",c_float*3),("fov",c_float)] #} class ent_worldinfo(Structure): @@ -475,17 +504,11 @@ class ent_worldinfo(Structure): class ent_ccmd(Structure): #{ _fields_ = [("pstr_command",c_uint32)] + sr_functions = { 'exec': 0x00 } #} -class ent_script(Structure): +class ent_objective(Structure): #{ - _fields_ = [("pstr_script_name",c_uint32), - ("entity_list_id",c_uint32), - ("flags",c_uint32)] -#} - - -class ent_objective(Structure):#{ _fields_ = [("transform",mdl_transform), ("submesh_start",c_uint32), ("submesh_count",c_uint32), ("flags",c_uint32), @@ -495,27 +518,23 @@ class ent_objective(Structure):#{ ("deleted1",c_int32), ("time_limit",c_float), ("pstr_description_ui",c_uint32)] - - sr_functions = { 0: 'trigger', - 2: 'show', - 3: 'hide' } + sr_functions = { 'trigger': 0x00, 'visibility': 0x1 } #} -class ent_challenge(Structure):#{ +class ent_challenge(Structure): +#{ _fields_ = [("transform",mdl_transform), ("pstr_alias",c_uint32), ("flags",c_uint32), - ("on_activate_id",c_uint32), - ("on_activate_event",c_int32), - ("on_complete_id",c_uint32), - ("on_complete_event",c_int32), + ("deleted0",c_uint32), + ("deleted1",c_int32), + ("deleted2",c_uint32), + ("deleted3",c_int32), ("first_objective_id",c_uint32), ("camera_id",c_uint32), ("status",c_uint32), ("reset_spawn_id",c_uint32)] - sr_functions = { 0: 'win', - 1: 'view', - -1: 'unview' } + sr_functions = { 'win': 0x00, 'view': 0x00 } #} class ent_region(Structure):#{ @@ -525,17 +544,12 @@ class ent_region(Structure):#{ ("flags",c_uint32), ("list_id",c_uint32), #105+ - ("target0",c_uint32*2)] - sr_functions = { 0: 'enter', 1: 'leave' } + ("deleted01",c_uint32*2)] + sr_functions = { 'set_active': 0x00 } #} -class ent_relay(Structure):#{ - _fields_ = [("targets",(c_uint32*2)*4), - ("targets_events",c_int32*4)] - sr_functions = { 0: 'trigger' } -#} - -class ent_cubemap(Structure):#{ +class ent_cubemap(Structure): +#{ _fields_ = [("co",c_float*3), ("resolution",c_uint32), #placeholder ("live",c_uint32), #placeholder @@ -545,16 +559,8 @@ class ent_cubemap(Structure):#{ ("placeholder",c_uint32*2)] #} -class ent_miniworld(Structure):#{ - _fields_ = [("transform",mdl_transform), - ("pstr_world",c_uint32), - ("camera",c_uint32), - ("proxy",c_uint32)] - - sr_functions = { 0: 'zone', 1: 'leave' } -#} - -class ent_prop(Structure):#{ +class ent_prop(Structure): +#{ _fields_ = [("transform",mdl_transform), ("submesh_start",c_uint32), ("submesh_count",c_uint32), @@ -564,12 +570,12 @@ class ent_prop(Structure):#{ def sr_filter_ent_type( obj, ent_types ): #{ - if obj == bpy.context.active_object: return False + # if obj == bpy.context.active_object: return False for c0 in obj.users_collection:#{ for c1 in bpy.context.active_object.users_collection:#{ if c0 == c1:#{ - return obj_ent_type( obj ) in ent_types + return (ent_types == None) or (obj_ent_type( obj ) in ent_types) #} #} #} @@ -1051,28 +1057,104 @@ class SR_INTERFACE(bpy.types.Panel): F'bpy.types.Light["{active_object.data.name}"].SR_data', \ [active_object.data.SR_data] ) #} - elif active_object.type in ['EMPTY','CURVE','MESH']:#{ + elif active_object.type in ['EMPTY','CURVE','MESH']: + #{ box.prop( active_object.SR_data, "ent_type" ) ent_type = active_object.SR_data.ent_type col = getattr( active_object.SR_data, ent_type, None ) if col != None and len(col)!=0: - _draw_prop_collection( \ - F'bpy.types.Object["{active_object.name}"].SR_data.{ent_type}[0]', \ - col ) + _draw_prop_collection( F'bpy.types.Object["{active_object.name}"].SR_data.{ent_type}[0]', col ) if active_object.type == 'MESH':#{ col = getattr( active_object.data.SR_data, ent_type, None ) if col != None and len(col)!=0: - _draw_prop_collection( \ - F'bpy.types.Mesh["{active_object.data.name}"].SR_data.{ent_type}[0]', \ - col ) + _draw_prop_collection( F'bpy.types.Mesh["{active_object.data.name}"].SR_data.{ent_type}[0]', col ) + #} + #} + #} + #} +#} + +class SR_MARKER_PANEL(bpy.types.Panel): +#{ + bl_idname = "DOPESHEET_EDITOR_PT_skate_rift" + bl_label = "Skate Rift" + bl_space_type = 'DOPESHEET_EDITOR' + bl_region_type = 'UI' + bl_category = "Skate Rift" + + def draw(_, context): + #{ + markers = context.scene.timeline_markers + if markers: + #{ + for tlm in markers: + #{ + if tlm.select: + #{ + box = _.layout.box() + box.label( text=F'Selected Marker: {tlm.name}' ) + + data = tlm.SR_data + box.prop( data, 'tipo' ) + + if data.tipo == '1': + box.prop( data, 'event_string' ) + + if data.tipo == '2': + #{ + box.prop( data, 'subtitle_person' ) + box.prop( data, 'subtitle_en' ) + + length = 0 + for j in range(len(data.subtitle_en)-1): + #{ + if data.subtitle_en[j:j+2] == '\\n': + length = -1 + else: + length += 1 + + if length > 50: + #{ + box.label( text='Warning, line too long!' ) + break + #} + #} + #} #} #} #} #} #} +class SR_ENTITY_PANEL(bpy.types.Panel): +#{ + bl_label="Skate Rift Entity" + bl_idname="OBJECT_PT_sr_entity" + bl_space_type='PROPERTIES' + bl_region_type='WINDOW' + bl_context="object" + + def draw(_,context): + #{ + active_object = bpy.context.active_object + if active_object == None: return + + box = _.layout.box() + row = box.row() + row.alignment = 'CENTER' + row.label( text="Outputs" ) + row.scale_y = 1.5 + box.template_list('SR_UL_ENT_EVENT_LIST', 'Outputs', active_object.SR_data, 'events', \ + active_object.SR_data, 'events_index', rows=5) + + row = box.row() + row.operator( 'skaterift.ent_event_new_entry', text='Add' ) + row.operator( 'skaterift.ent_event_del_entry', text='Remove' ) + #} +#} + class SR_MATERIAL_PANEL(bpy.types.Panel): #{ bl_label="Skate Rift material" @@ -1100,6 +1182,7 @@ class SR_MATERIAL_PANEL(bpy.types.Panel): _.layout.prop( active_mat.SR_data, "shader" ) _.layout.prop( active_mat.SR_data, "surface_prop" ) + _.layout.prop( active_mat.SR_data, "additive" ) _.layout.prop( active_mat.SR_data, "collision" ) if active_mat.SR_data.collision:#{ @@ -1621,15 +1704,23 @@ class SR_OT_ENT_LIST_DEL_ITEM(bpy.types.Operator):#{ class SR_OBJECT_ENT_LIST_ENTRY(bpy.types.PropertyGroup): #{ - target: bpy.props.PointerProperty( \ - type=bpy.types.Object, name='target' ) + target: bpy.props.PointerProperty( type=bpy.types.Object, name='target' ) + alias: bpy.props.StringProperty( name='alias' ) #} class SR_UL_ENT_LIST(bpy.types.UIList):#{ bl_idname = 'SR_UL_ENT_LIST' def draw_item(_,context,layout,data,item,icon,active_data,active_propname):#{ - layout.prop( item, 'target', text='', emboss=False ) + s0 = layout.split(factor=0.22) + c = s0.column() + c.prop( item, 'alias', text='', emboss=True ) + c = s0.column() + s1 = c.split( factor=0.7 ) + c = s1.column() + c.prop( item, 'target', text='', emboss=False ) + c = s1.column() + c.label( text=item.target.SR_data.ent_type if item.target else '' ) #} #} @@ -1702,41 +1793,41 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{ water_volume: bpy.props.BoolProperty( name="Water Volume" ) text: bpy.props.StringProperty() - @staticmethod - def inspect_target( layout, data, propname, evs = ['_event'], text='' ):#{ - box = layout.box() - box.prop( data[0], propname, text=text ) - - for evname in evs:#{ - row = box.row() - row.prop( data[0], propname + evname ) - - target = getattr( data[0], propname ) - if target:#{ - tipo = target.SR_data.ent_type - cls = globals()[ tipo ] - - table = getattr( cls, 'sr_functions', None ) - if table:#{ - index = getattr( data[0], propname + evname ) - if index in table: - row.label( text=table[index] ) - else: - row.label( text="undefined function" ) - #} - #} - else:#{ - row.label( text="..." ) - row.enabled=False - #} - #} - #} + # @staticmethod + # def inspect_target( layout, data, propname, evs = ['_event'], text='' ):#{ + # box = layout.box() + # box.prop( data[0], propname, text=text ) + + # for evname in evs:#{ + # row = box.row() + # row.prop( data[0], propname + evname ) + + # target = getattr( data[0], propname ) + # if target:#{ + # tipo = target.SR_data.ent_type + # cls = globals()[ tipo ] + + # table = getattr( cls, 'sr_functions', None ) + # if table:#{ + # index = getattr( data[0], propname + evname ) + # if index in table: + # row.label( text=table[index] ) + # else: + # row.label( text="undefined function" ) + # #} + # #} + # else:#{ + # row.label( text="..." ) + # row.enabled=False + # #} + # #} + # #} @staticmethod def sr_inspector( layout, data ): #{ layout.prop( data[0], 'subtype' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', ['_event','_event_leave'] ) + # SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', ['_event','_event_leave'] ) if data[0].subtype == '2': #{ layout.prop( data[0], 'text' ) @@ -1813,8 +1904,7 @@ class SR_OBJECT_ENT_AUDIO(bpy.types.PropertyGroup): c.label( text='Filepath' ) c = split.column() c.label( text='Chance' ) - layout.template_list('SR_UL_AUDIO_LIST', 'Files', \ - data[0], 'files', data[0], 'files_index', rows=5) + layout.template_list('SR_UL_AUDIO_LIST', 'Files', data[0], 'files', data[0], 'files_index', rows=5) row = layout.row() row.operator( 'skaterift.al_new_entry', text='Add' ) @@ -1967,10 +2057,14 @@ class SR_OBJECT_ENT_OBJECTIVE(bpy.types.PropertyGroup):#{ proxima: bpy.props.PointerProperty( \ type=bpy.types.Object, name="Next", \ poll=lambda self,obj: sr_filter_ent_type(obj,['ent_objective'])) + + ################### DELETED ############## target: bpy.props.PointerProperty( \ type=bpy.types.Object, name="Win", \ poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE)) target_event: bpy.props.IntProperty( name="Event/Method" ) + ################### DELETED ############## + time_limit: bpy.props.FloatProperty( name="Time Limit", default=1.0 ) filtrar: bpy.props.EnumProperty( name='Filter',\ items=[('0','none',''), @@ -1986,11 +2080,13 @@ class SR_OBJECT_ENT_OBJECTIVE(bpy.types.PropertyGroup):#{ (str(0x20|0x40),'grind_any',''), (str(0x80),'footplant',''), (str(0x100),'passthrough',''), + (str(0x200),'glider',''), ]) description: bpy.props.StringProperty( name="UI Description" ) @staticmethod - def sr_inspector( layout, data ):#{ + def sr_inspector( layout, data ): + #{ layout.prop( data[0], 'proxima' ) layout.prop( data[0], 'time_limit' ) layout.prop( data[0], 'filtrar' ) @@ -2014,6 +2110,7 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ time_limit: bpy.props.BoolProperty( name="Time Limit" ) is_story: bpy.props.BoolProperty( name="Is story event" ) + any_order: bpy.props.BoolProperty( name="Any order allowed" ) first: bpy.props.PointerProperty( \ type=bpy.types.Object, name="First Objective", \ @@ -2040,9 +2137,10 @@ class SR_OBJECT_ENT_CHALLENGE(bpy.types.PropertyGroup):#{ layout.prop( data[0], 'first', text=("First Objective") ) layout.prop( data[0], 'reset_spawn' ) layout.prop( data[0], 'time_limit' ) + layout.prop( data[0], 'any_order' ) # layout.prop( data[0], 'is_story' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', text="On Activate" ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'complete', text="On Complete" ) + # SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', text="On Activate" ) + # SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'complete', text="On Complete" ) #} #} @@ -2061,7 +2159,7 @@ class SR_OBJECT_ENT_REGION(bpy.types.PropertyGroup):#{ def sr_inspector( layout, data ):#{ layout.prop( data[0], 'title' ) layout.prop( data[0], 'zone_volume' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target0' ) + # SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target0' ) #} #} @@ -2083,23 +2181,173 @@ class SR_OBJECT_ENT_RELAY(bpy.types.PropertyGroup):#{ target1_event: bpy.props.IntProperty( name="Event" ) target2_event: bpy.props.IntProperty( name="Event" ) target3_event: bpy.props.IntProperty( name="Event" ) - - @staticmethod - def sr_inspector( layout, data ):#{ - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target0' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target1' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target2' ) - SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target3' ) - #} #} class SR_OBJECT_ENT_SCRIPT(bpy.types.PropertyGroup): #{ script_alias: bpy.props.StringProperty( name="Script alias" ) flags: bpy.props.IntProperty( name="Flags" ) - entity_list: bpy.props.PointerProperty( \ - type=bpy.types.Object, name="Entity List", \ - poll=lambda self,obj: sr_filter_ent_type(obj,['ent_list'])) + + #entity_list: bpy.props.PointerProperty( \ + # type=bpy.types.Object, name="Entity List", \ + # poll=lambda self,obj: sr_filter_ent_type(obj,['ent_list'])) +#} + +class SR_OBJECT_ENT_LOGIC(bpy.types.PropertyGroup): +#{ + tipo: bpy.props.EnumProperty( name='Type',\ + items=[(str(0x10),'AND',''), + (str(0x20),'NOT',''), + (str(0x40),'OR',''), + (str(0x100),'ATOM EQ STR',''), + #(str(0x200),'ATOM EQ INT',''), + (str(0x1000),'RISING TRIGGER',''), + ]) + + atom_alias: bpy.props.StringProperty( name="Atom Alias" ) + atom_enum_value: bpy.props.StringProperty( name="Atom Enum Value" ) + + source_entity: bpy.props.PointerProperty( type=bpy.types.Object, name="Source Entity", \ + poll=lambda self,obj: sr_filter_ent_type(obj,['ent_list','ent_logic'])) + + @staticmethod + def sr_inspector( layout, data ): + #{ + data = data[0] + layout.prop( data, 'tipo' ) + tipo = int( data.tipo ) + + if (tipo & (0x10|0x20|0x40|0x1000)) > 0: + #{ + layout.prop( data, 'source_entity' ) + #} + + if (tipo & (0x100|0x200)): + #{ + box = layout.box() + box.prop( data, 'atom_alias', text='Atom Alias' ) + + if tipo == 0x100: + box.prop( data, 'atom_enum_value', text='EQ' ) + #} + #} +#} + +class SR_OT_ENT_EVENT_NEW_ITEM(bpy.types.Operator): +#{ + bl_idname = "skaterift.ent_event_new_entry" + bl_label = "Add event" + + def execute(self, context): + #{ + active_object = context.active_object + active_object.SR_data.events.add() + return{'FINISHED'} + #} +#} + +class SR_OT_ENT_EVENT_DEL_ITEM(bpy.types.Operator): +#{ + bl_idname = "skaterift.ent_event_del_entry" + bl_label = "Remove event" + + @classmethod + def poll(cls, context): + #{ + return context.active_object.SR_data.events + #} + + def execute(self, context): + #{ + data = context.active_object.SR_data + data.events.remove( data.events_index ) + data.events_index = min(max(0,data.events_index-1), len(data.events)-1) + return{'FINISHED'} + #} +#} + +class SR_OBJECT_ENT_EVENT_ENTRY(bpy.types.PropertyGroup): +#{ + reciever: bpy.props.PointerProperty( type=bpy.types.Object, name='target', \ + poll=lambda self,obj: sr_filter_ent_type(obj,None) ) + source_event: bpy.props.StringProperty() + reciever_event: bpy.props.StringProperty() + delay: bpy.props.FloatProperty() + + arg_string: bpy.props.StringProperty() + arg_entity: bpy.props.PointerProperty( type=bpy.types.Object, name='target', \ + poll=lambda self,obj: sr_filter_ent_type(obj,None) ) + arg_float: bpy.props.FloatProperty() + arg_int: bpy.props.IntProperty() + arg_tipo: bpy.props.EnumProperty( name='Type', + items=[(str(0x00),'NUL',''), + (str(0x01),'INT',''), + (str(0x02),'FLT',''), + (str(0x04),'ENT',''), + (str(0x08),'STR',''), + (str(0x10),'VAR','')]) +#} + +class SR_UL_ENT_EVENT_LIST(bpy.types.UIList): +#{ + bl_idname = 'SR_UL_ENT_EVENT_LIST' + def draw_item(_,context,layout,data,item,icon,active_data,active_propname): + #{ + clicker = layout.column() + clicker.label( text='', icon='DECORATE_DRIVER' ) + clicker.ui_units_x = 1 + + src_ev = layout.column() + src_ev.prop( item, 'source_event', text='',emboss=True ) + src_ev.label( text='...' ) + + dely = layout.column() + if item.delay < 0.0: + dely.alert=True + dely.ui_units_x = 4 + dely.prop( item, 'delay', text='After' ) + + jf = layout.column() + jf.label( text='', icon='FORWARD' ) + jf.ui_units_x = 1 + + rec = layout.column() + if item.reciever == None: + rec.alert=True + rec.prop( item, 'reciever', text='',emboss=True ) + rec.label( text=(item.reciever.SR_data.ent_type if item.reciever else '') + \ + (' (self)' if item.reciever == context.active_object else '' ) ) + + rec_ev = layout.column() + errstr = None + if item.reciever: + #{ + tipo = item.reciever.SR_data.ent_type + cls = globals()[ tipo ] + table = getattr( cls, 'sr_functions', None ) + if table: + #{ + if item.reciever_event not in table: + #{ + rec_ev.alert=True + errstr = 'BAD FUNCTION ID' + #} + #} + #} + + rec_ev.prop( item, 'reciever_event', text='',emboss=True ) + if errstr: + rec_ev.label( text=errstr, icon='ERROR' ) + + tt = layout.column() + tt.prop( item, 'arg_tipo',text='',emboss=True ) + tipo = int(item.arg_tipo) + if tipo == 0x00: tt.label( text='CALL' ) + elif tipo == 0x01: tt.prop( item, 'arg_int', text='' ) + elif tipo == 0x02: tt.prop( item, 'arg_float', text='' ) + elif tipo == 0x04: tt.prop( item, 'arg_entity', text='' ) + elif tipo == 0x08: tt.prop( item, 'arg_string', text='' ) + #} #} class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): @@ -2115,8 +2363,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_font: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_FONT) ent_traffic: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_TRAFFIC) ent_skateshop: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_SKATESHOP) - ent_swspreview: \ - bpy.props.CollectionProperty(type=SR_OBJECT_ENT_WORKSHOP_PREVIEW) + ent_swspreview: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_WORKSHOP_PREVIEW) ent_worldinfo: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_WORLD_INFO) ent_ccmd: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CCMD) ent_objective: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_OBJECTIVE) @@ -2128,12 +2375,16 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup): ent_glider: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_GLIDER) ent_npc: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_NPC) ent_script: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_SCRIPT) + ent_logic: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_LOGIC) ent_type: bpy.props.EnumProperty( name="Type", items=sr_entity_list, update=sr_on_type_change ) + + events: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_EVENT_ENTRY) + events_index: bpy.props.IntProperty() #} class SR_MESH_PROPERTIES(bpy.types.PropertyGroup): @@ -2222,6 +2473,12 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup): ('6','sand (medium friction)','') ]) + additive: bpy.props.BoolProperty( \ + name="Additive rendering",\ + default=False,\ + description = "Draw without writing to depth in additive blending mode"\ + ) + collision: bpy.props.BoolProperty( \ name="Collisions Enabled",\ default=True,\ @@ -2314,6 +2571,22 @@ class SR_MATERIAL_PROPERTIES(bpy.types.PropertyGroup): tex_diffuse_rt: bpy.props.IntProperty( name="diffuse: RT index", default=-1 ) #} +class SR_MARKER_PROPERTIES(bpy.types.PropertyGroup): +#{ + tipo: bpy.props.EnumProperty(items=(('0', 'Camera', ""), + ('1', 'Event', ""), + ('2', 'Subtitle', ""), + ('3', 'Fadeout', "") )) + event_string: bpy.props.StringProperty( name="Event String" ) + subtitle_person: bpy.props.EnumProperty( items=(('0','Default',""), + ('1','JC',""), + ('2','Mike',""), + ('3','FBI',""), + ('4','Human Reserved',""), + ('5','Gino',"")) ) + subtitle_en: bpy.props.StringProperty( name="EN" ) +#} + # ---------------------------------------------------------------------------- # # # # GUI section # @@ -2324,8 +2597,7 @@ cv_view_draw_handler = None cv_view_pixel_handler = None cv_legacy = bpy.app.version < (4,0,0) -cv_view_shader = gpu.shader.from_builtin( '3D_SMOOTH_COLOR' if cv_legacy else \ - 'SMOOTH_COLOR') +cv_view_shader = gpu.shader.from_builtin( '3D_SMOOTH_COLOR' if cv_legacy else 'SMOOTH_COLOR') cv_view_verts = [] cv_view_colours = [] cv_view_course_i = 0 @@ -2850,11 +3122,6 @@ def cv_ent_volume( obj ): cc = (0,0,0) cv_draw_ucube( obj.matrix_world, cc, Vector((0.99,0.99,0.99)) ) - - if data.target: - #{ - cv_draw_arrow( obj.location, data.target.location, (1,1,1) ) - #} #} def cv_draw_route( route, dij ): @@ -2865,8 +3132,7 @@ def cv_draw_route( route, dij ): route.SR_data.ent_route[0].colour[1], route.SR_data.ent_route[0].colour[2]) - cv_draw_ucube(route.matrix_world,cc,Vector((0.5,-7.5,6)),\ - Vector((0,-6.5,5.5))) + cv_draw_ucube(route.matrix_world,cc,Vector((0.5,-7.5,6)),Vector((0,-6.5,5.5))) cv_draw_ucube(route.matrix_world,cc,pole, Vector(( 0.5, 0.5,0)) ) cv_draw_ucube(route.matrix_world,cc,pole, Vector(( 0.5,-13.5,0)) ) cv_draw_ucube(route.matrix_world,cc,hat, Vector((-0.5,-6.5, 12)) ) @@ -2874,7 +3140,8 @@ def cv_draw_route( route, dij ): checkpoints = route.SR_data.ent_route[0].gates - for i in range(len(checkpoints)):#{ + for i in range(len(checkpoints)): + #{ gi = checkpoints[i].target gj = checkpoints[(i+1)%len(checkpoints)].target @@ -2894,7 +3161,8 @@ def cv_draw_route( route, dij ): path = solve_graph( dij, gi.name, gj.name ) - if path:#{ + if path: + #{ cv_draw_arrow(gi.location,dij.points[path[0]],cc,1.5,False) cv_draw_arrow(dij.points[path[len(path)-1]],gj.location,cc,1.5,False) for j in range(len(path)-1):#{ @@ -2932,46 +3200,58 @@ def cv_draw():#{ route_curves = [] routes = [] - for obj in bpy.context.collection.objects:#{ - if obj.type == 'ARMATURE':#{ + for obj in bpy.context.collection.objects: + #{ + if obj.type == 'ARMATURE': + #{ if obj.data.pose_position == 'REST': draw_skeleton_helpers( obj ) #} - else:#{ + else: + #{ + for evi,ev in enumerate(obj.SR_data.events): + #{ + c = (0.2,0.2,0.2) + + if (obj == bpy.context.active_object) and (obj.SR_data.events_index == evi): + c = (0.3,0.7,1) + + if ev.reciever: + #{ + cv_draw_arrow( obj.location, ev.reciever.location, c ) + + if int(ev.arg_tipo) == 0x04: + #{ + if ev.arg_entity: + #{ + p0 = (obj.location+ev.reciever.location)*Vector((0.5,0.5,0.5)) + cv_draw_line_dotted( p0, ev.arg_entity.location, c ) + #} + #} + #} + #} + ent_type = obj_ent_type( obj ) - if ent_type == 'ent_gate':#{ + if ent_type == 'ent_gate': + #{ cv_ent_gate( obj ) route_gates += [obj] #} - elif ent_type == 'ent_route_node':#{ - if obj.type == 'CURVE':#{ + elif ent_type == 'ent_route_node': + #{ + if obj.type == 'CURVE': route_curves += [obj] - #} #} elif ent_type == 'ent_route': routes += [obj] - elif ent_type == 'ent_volume':#{ + elif ent_type == 'ent_volume': cv_ent_volume( obj ) - #} - elif ent_type == 'ent_objective':#{ + elif ent_type == 'ent_objective': + #{ data = obj.SR_data.ent_objective[0] - if data.proxima:#{ + if data.proxima: cv_draw_arrow( obj.location, data.proxima.location, (1,0.6,0.2) ) - #} - if data.target: - cv_draw_arrow( obj.location, data.target.location, (0,1,0) ) - #} - elif ent_type == 'ent_relay':#{ - data = obj.SR_data.ent_relay[0] - if data.target0: - cv_draw_arrow( obj.location, data.target0.location, (1,1,1) ) - if data.target1: - cv_draw_arrow( obj.location, data.target1.location, (1,1,1) ) - if data.target2: - cv_draw_arrow( obj.location, data.target2.location, (1,1,1) ) - if data.target3: - cv_draw_arrow( obj.location, data.target3.location, (1,1,1) ) #} elif ent_type == 'ent_list': #{ @@ -2985,27 +3265,8 @@ def cv_draw():#{ #} #} #} - elif ent_type == 'ent_script': - #{ - data = obj.SR_data.ent_script[0] - - cc = (0.9,0.0,0.7) - - cv_draw_ucube( obj.matrix_world, cc, Vector((0.1,0.1,0.1)) ) - cv_draw_ucube( obj.matrix_world, cc, Vector((0.2,0.2,0.2)) ) - - if data.entity_list: - #{ - cv_draw_arrow( obj.location, data.entity_list.location, cc ) - cv_draw_arrow( data.entity_list.location, obj.location, cc ) - #} - #} elif ent_type == 'ent_challenge':#{ data = obj.SR_data.ent_challenge[0] - if data.target: - cv_draw_arrow( obj.location, data.target.location, (0,0.4,0.8) ) - if data.complete: - cv_draw_arrow( obj.location, data.complete.location, (0.1,0.9,0) ) if data.first: cv_draw_arrow( obj.location, data.first.location, (1,0.6,0.2) ) if data.reset_spawn: @@ -3139,13 +3400,6 @@ def cv_draw():#{ if display1: cv_draw_ucube(display1.matrix_world, cc1, display_cu, display_co) #} - elif ent_type == 'ent_region': - #{ - data = obj.SR_data.ent_region[0] - if data.target0:#{ - cv_draw_arrow( obj.location, data.target0.location, (.5,.5,.5), 0.1 ) - #} - #} #} #} @@ -3165,29 +3419,62 @@ def pos3d_to_2d( pos ):#{ bpy.context.space_data.region_3d, pos ) #} -def cv_draw_pixel():#{ - if not bpy.context.scene.SR_data.gizmos: return +def cv_draw_pixel(): +#{ + if not bpy.context.scene.SR_data.gizmos: + return blf.size(0,10) blf.color(0, 1.0,1.0,1.0,0.9) blf.enable(0,blf.SHADOW) - blf.shadow(0,3,0.0,0.0,0.0,1.0) - for obj in bpy.context.collection.objects:#{ + blf.shadow(0,6,0.0,0.0,0.0,1.0) + for obj in bpy.context.collection.objects: + #{ ent_type = obj_ent_type( obj ) - - if ent_type != 'none':#{ + if ent_type != 'none': + #{ co = pos3d_to_2d( obj.location ) - if not co: continue + if not co: + continue + blf.position(0,co[0],co[1],0) blf.draw(0,ent_type) + + if ent_type == 'ent_logic': + #{ + data = obj.SR_data.ent_logic[0] + blf.color(0,0.6,0.9,0.3,1.0) + blf.position(0,co[0],co[1]-16,0) + + tipo = int(data.tipo) + if tipo == 0x10: + blf.draw(0, F'AND' ) + elif tipo == 0x20: + blf.draw(0, F'NOT' ) + elif tipo == 0x40: + blf.draw(0, F'OR') + elif tipo == 0x100: + blf.draw(0, F"atom('{data.atom_alias}') == '{data.atom_enum_value}'" ) + blf.color(0,1.0,1.0,1.0,1.0) + #} + if ent_type == 'ent_script': + #{ + data = obj.SR_data.ent_script[0] + blf.color(0,0.6,0.9,0.3,1.0) + blf.position(0,co[0],co[1]-16,0) + blf.draw(0, F"'{data.script_alias}'" ) + blf.color(0,1.0,1.0,1.0,1.0) + #} #} #} #} -classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ +classes = [ SR_INTERFACE, SR_MATERIAL_PANEL, SR_MARKER_PANEL, SR_ENTITY_PANEL, \ SR_COLLECTION_SETTINGS, SR_SCENE_SETTINGS, \ SR_COMPILE, SR_COMPILE_THIS,SR_COMPILE_METASCENE, SR_MIRROR_BONE_X,\ \ + SR_OT_ENT_EVENT_NEW_ITEM, SR_OT_ENT_EVENT_DEL_ITEM, \ + SR_OBJECT_ENT_EVENT_ENTRY, SR_UL_ENT_EVENT_LIST, \ SR_OBJECT_ENT_GATE, SR_MESH_ENT_GATE, SR_OBJECT_ENT_SPAWN, \ SR_OBJECT_ENT_ROUTE_ENTRY, SR_UL_ROUTE_NODE_LIST, \ SR_OBJECT_ENT_ROUTE, SR_OT_ROUTE_LIST_NEW_ITEM,\ @@ -3211,10 +3498,10 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\ SR_OBJECT_ENT_RELAY,SR_OBJECT_ENT_MINIWORLD,\ SR_OBJECT_ENT_LIST_ENTRY, SR_UL_ENT_LIST, SR_OBJECT_ENT_LIST, \ SR_OT_ENT_LIST_NEW_ITEM, SR_OT_ENT_LIST_DEL_ITEM,\ - SR_OBJECT_ENT_GLIDER, SR_OBJECT_ENT_NPC, SR_OBJECT_ENT_SCRIPT, \ + SR_OBJECT_ENT_GLIDER, SR_OBJECT_ENT_NPC, SR_OBJECT_ENT_SCRIPT, SR_OBJECT_ENT_LOGIC, \ \ SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, - SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \ + SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES, SR_MARKER_PROPERTIES \ ] def register(): @@ -3222,27 +3509,18 @@ def register(): for c in classes: bpy.utils.register_class(c) - bpy.types.Scene.SR_data = \ - bpy.props.PointerProperty(type=SR_SCENE_SETTINGS) - bpy.types.Collection.SR_data = \ - bpy.props.PointerProperty(type=SR_COLLECTION_SETTINGS) - - bpy.types.Object.SR_data = \ - bpy.props.PointerProperty(type=SR_OBJECT_PROPERTIES) - bpy.types.Light.SR_data = \ - bpy.props.PointerProperty(type=SR_LIGHT_PROPERTIES) - bpy.types.Bone.SR_data = \ - bpy.props.PointerProperty(type=SR_BONE_PROPERTIES) - bpy.types.Mesh.SR_data = \ - bpy.props.PointerProperty(type=SR_MESH_PROPERTIES) - bpy.types.Material.SR_data = \ - bpy.props.PointerProperty(type=SR_MATERIAL_PROPERTIES) + bpy.types.Scene.SR_data = bpy.props.PointerProperty(type=SR_SCENE_SETTINGS) + bpy.types.Collection.SR_data = bpy.props.PointerProperty(type=SR_COLLECTION_SETTINGS) + bpy.types.Object.SR_data = bpy.props.PointerProperty(type=SR_OBJECT_PROPERTIES) + bpy.types.Light.SR_data = bpy.props.PointerProperty(type=SR_LIGHT_PROPERTIES) + bpy.types.Bone.SR_data = bpy.props.PointerProperty(type=SR_BONE_PROPERTIES) + bpy.types.Mesh.SR_data = bpy.props.PointerProperty(type=SR_MESH_PROPERTIES) + bpy.types.Material.SR_data = bpy.props.PointerProperty(type=SR_MATERIAL_PROPERTIES) + bpy.types.TimelineMarker.SR_data = bpy.props.PointerProperty(type=SR_MARKER_PROPERTIES) global cv_view_draw_handler, cv_view_pixel_handler - cv_view_draw_handler = bpy.types.SpaceView3D.draw_handler_add(\ - cv_draw,(),'WINDOW','POST_VIEW') - cv_view_pixel_handler = bpy.types.SpaceView3D.draw_handler_add(\ - cv_draw_pixel,(),'WINDOW','POST_PIXEL') + cv_view_draw_handler = bpy.types.SpaceView3D.draw_handler_add( cv_draw,(),'WINDOW','POST_VIEW') + cv_view_pixel_handler = bpy.types.SpaceView3D.draw_handler_add( cv_draw_pixel,(),'WINDOW','POST_PIXEL') #} def unregister(): diff --git a/skaterift_blender/sr_mat.py b/skaterift_blender/sr_mat.py index 3539666..5f5a60f 100644 --- a/skaterift_blender/sr_mat.py +++ b/skaterift_blender/sr_mat.py @@ -197,7 +197,14 @@ def sr_compile_material( mat ): #} #} - if mat.SR_data.shader == 'standard': m.shader = 0 + if mat.SR_data.shader == 'standard': + #{ + m.shader = 0 + flags = 0 + if mat.SR_data.additive: + flags |= 0x20 + shader_prop_u32( msg, 'render_flags', flags ) + #} if mat.SR_data.shader == 'standard_cutout': m.shader = 1 if mat.SR_data.shader == 'foliage': m.shader = 10 if mat.SR_data.shader == 'terrain_blend': diff --git a/skaterift_blender/sr_mdl.py b/skaterift_blender/sr_mdl.py index f7383f2..75db221 100644 --- a/skaterift_blender/sr_mdl.py +++ b/skaterift_blender/sr_mdl.py @@ -570,7 +570,8 @@ def _mdl_compiler_compile_entities(): light.colour[3] = obj.data.energy sr_ent_push( light ) #} - elif ent_type == 'ent_camera': #{ + elif ent_type == 'ent_camera': + #{ cam = ent_camera() trans = mdl_transform() @@ -616,15 +617,18 @@ def _mdl_compiler_compile_entities(): cam.fov = obj.data.angle_y * 57.2958 sr_ent_push(cam) #} - elif ent_type == 'ent_gate': #{ + elif ent_type == 'ent_gate': + #{ gate = ent_gate() obj_data = obj.SR_data.ent_gate[0] mesh_data = obj.data.SR_data.ent_gate[0] flags = 0x0000 - if obj_data.tipo == 'default':#{ - if obj_data.target:#{ + if obj_data.tipo == 'default': + #{ + if obj_data.target: + #{ gate.target = _mdl_compiler.entity_ids[obj_data.target.name] flags |= 0x0001 #} @@ -637,15 +641,14 @@ def _mdl_compiler_compile_entities(): flags |= 0x0002 #} elif obj_data.tipo == 'passive': - #{ flags |= 0x80 - #} - if obj_data.flip: flags |= 0x0004 - if obj_data.custom:#{ + if obj_data.flip: + flags |= 0x0004 + if obj_data.custom: + #{ flags |= 0x0008 - gate.submesh_start, gate.submesh_count, _ = \ - mdl_compile_mesh_internal( obj ) + gate.submesh_start, gate.submesh_count, _ = mdl_compile_mesh_internal( obj ) #} if obj_data.locked: flags |= 0x0010 if obj_data.no_linkback: flags |= 0x0040 @@ -658,14 +661,15 @@ def _mdl_compiler_compile_entities(): q = [obj.matrix_local.to_quaternion(), (0,0,0,1)] co = [obj.matrix_world @ Vector((0,0,0)), (0,0,0)] - if obj_data.target:#{ + if obj_data.target: + #{ q[1] = obj_data.target.matrix_local.to_quaternion() co[1]= obj_data.target.matrix_world @ Vector((0,0,0)) #} # Setup transform - # - for x in range(2):#{ + for x in range(2): + #{ gate.co[x][0] = co[x][0] gate.co[x][1] = co[x][2] gate.co[x][2] = -co[x][1] @@ -677,7 +681,8 @@ def _mdl_compiler_compile_entities(): sr_ent_push( gate ) #} - elif ent_type == 'ent_spawn': #{ + elif ent_type == 'ent_spawn': + #{ spawn = ent_spawn() compile_obj_transform( obj, spawn.transform ) obj_data = obj.SR_data.ent_spawn[0] @@ -685,13 +690,15 @@ def _mdl_compiler_compile_entities(): spawn.flags = obj_data.flags sr_ent_push( spawn ) #} - elif ent_type == 'ent_water':#{ + elif ent_type == 'ent_water': + #{ water = ent_water() compile_obj_transform( obj, water.transform ) water.max_dist = 0.0 sr_ent_push( water ) #} - elif ent_type == 'ent_audio':#{ + elif ent_type == 'ent_audio': + #{ obj_data = obj.SR_data.ent_audio[0] audio = ent_audio() compile_obj_transform( obj, audio.transform ) @@ -759,22 +766,11 @@ def _mdl_compiler_compile_entities(): # volume.flags |= 0x4 compile_obj_transform( obj, volume.transform ) - if obj_data.target: - #{ - volume.target = sr_entity_id( obj_data.target ) - #} - if obj_data.subtype == '2': #{ volume.flags |= 0x8 - volume._anon.interact.event = obj_data.target_event volume._anon.interact.pstr_text = _af_pack_string( obj_data.text ) #} - else: - #{ - volume._anon.trigger.event = obj_data.target_event - volume._anon.trigger.event_leave = obj_data.target_event_leave - #} sr_ent_push(volume) #} @@ -823,7 +819,8 @@ def _mdl_compiler_compile_entities(): workshop_preview.id_camera = sr_entity_id( obj_data.cam ) sr_ent_push( workshop_preview ) #} - elif ent_type == 'ent_worldinfo':#{ + elif ent_type == 'ent_worldinfo': + #{ worldinfo = ent_worldinfo() obj_data = obj.SR_data.ent_worldinfo[0] worldinfo.pstr_name = _af_pack_string( obj_data.name ) @@ -853,26 +850,18 @@ def _mdl_compiler_compile_entities(): worldinfo.wind_scale = obj_data.wind_scale sr_ent_push( worldinfo ) #} - elif ent_type == 'ent_ccmd':#{ + elif ent_type == 'ent_ccmd': + #{ ccmd = ent_ccmd() obj_data = obj.SR_data.ent_ccmd[0] ccmd.pstr_command = _af_pack_string( obj_data.command ) sr_ent_push( ccmd ) #} - elif ent_type == 'ent_script':#{ - obj_data = obj.SR_data.ent_script[0] - script = ent_script() - script.pstr_script_name = _af_pack_string( obj_data.script_alias ) - script.entity_list_id = sr_entity_id( obj_data.entity_list ) - script.falgs = obj_data.flags - sr_ent_push( script ) - #} - elif ent_type == 'ent_objective':#{ + elif ent_type == 'ent_objective': + #{ objective = ent_objective() obj_data = obj.SR_data.ent_objective[0] objective.id_next = sr_entity_id( obj_data.proxima ) - # objective.id_win = sr_entity_id( obj_data.target ) - # objective.win_event = obj_data.target_event objective.filter = int(obj_data.filtrar) objective.filter2 = 0 objective.time_limit = obj_data.time_limit @@ -881,9 +870,7 @@ def _mdl_compiler_compile_entities(): objective.submesh_start, objective.submesh_count, _ = mdl_compile_mesh_internal( obj ) if obj_data.description != '': - #{ objective.pstr_description_ui = _af_pack_string( obj_data.description ) - #} sr_ent_push( objective ) #} @@ -896,10 +883,7 @@ def _mdl_compiler_compile_entities(): challenge.flags = 0x00 if obj_data.time_limit: challenge.flags |= 0x01 if obj_data.is_story: challenge.flags |= 0x02 - challenge.on_activate_id = sr_entity_id( obj_data.target ) - challenge.on_activate_event = obj_data.target_event - challenge.on_complete_id = sr_entity_id( obj_data.complete ) - challenge.on_complete_event = obj_data.complete_event + if obj_data.any_order: challenge.flags |= 0x08 challenge.first_objective_id = sr_entity_id( obj_data.first ) challenge.camera_id = sr_entity_id( obj_data.camera ) challenge.status = 0 @@ -923,37 +907,24 @@ def _mdl_compiler_compile_entities(): #{ list_entry = file_entity_ref() list_entry.entity_id = sr_entity_id( obj_data.entities[k].target ) + if obj_data.entities[k].alias: + list_entry.pstr_alias = _af_pack_string( obj_data.entities[k].alias ) sr_ent_push( list_entry ) lista.entity_ref_count += 1 #} #} sr_ent_push( lista ) #} - elif ent_type == 'ent_region':#{ + elif ent_type == 'ent_region': + #{ region = ent_region() obj_data = obj.SR_data.ent_region[0] compile_obj_transform( obj, region.transform ) - region.submesh_start, region.submesh_count, _ = \ - mdl_compile_mesh_internal( obj ) + region.submesh_start, region.submesh_count, _ = mdl_compile_mesh_internal( obj ) region.pstr_title = _af_pack_string( obj_data.title ) region.list_id = sr_entity_id( obj_data.zone_volume ) - region.target0[0] = sr_entity_id( obj_data.target0 ) - region.target0[1] = obj_data.target0_event sr_ent_push( region ) #} - elif ent_type == 'ent_relay':#{ - relay = ent_relay() - obj_data = obj.SR_data.ent_relay[0] - relay.targets[0][0] = sr_entity_id( obj_data.target0 ) - relay.targets[1][0] = sr_entity_id( obj_data.target1 ) - relay.targets[2][0] = sr_entity_id( obj_data.target2 ) - relay.targets[3][0] = sr_entity_id( obj_data.target3 ) - relay.targets[0][1] = obj_data.target0_event - relay.targets[1][1] = obj_data.target1_event - relay.targets[2][1] = obj_data.target2_event - relay.targets[3][1] = obj_data.target3_event - sr_ent_push( relay ) - #} elif ent_type == 'ent_glider': #{ glider = ent_glider() @@ -969,6 +940,14 @@ def _mdl_compiler_compile_entities(): npc.pstr_context_id = _af_pack_string( obj_data.context_id ) sr_ent_push( npc ) #} + elif ent_type == 'ent_script':#{ + obj_data = obj.SR_data.ent_script[0] + script = ent_script() + script.pstr_script_name = _af_pack_string( obj_data.script_alias ) + #script.entity_list_id = sr_entity_id( obj_data.entity_list ) + script.falgs = obj_data.flags + sr_ent_push( script ) + #} elif ent_type == 'ent_cubemap': #{ cubemap = ent_cubemap() @@ -980,24 +959,12 @@ def _mdl_compiler_compile_entities(): cubemap.live = 60 sr_ent_push( cubemap ) #} - elif ent_type == 'ent_miniworld': - #{ - miniworld = ent_miniworld() - obj_data = obj.SR_data.ent_miniworld[0] - - compile_obj_transform( obj, miniworld.transform ) - miniworld.pstr_world = _af_pack_string( obj_data.world ) - miniworld.proxy = sr_entity_id( obj_data.proxy ) - miniworld.camera = sr_entity_id( obj_data.camera ) - sr_ent_push( miniworld ) - #} elif ent_type == 'ent_prop': #{ prop = ent_prop() obj_data = obj.SR_data.ent_prop[0] compile_obj_transform( obj, prop.transform ) - prop.submesh_start, prop.submesh_count, _ = \ - mdl_compile_mesh_internal( obj ) + prop.submesh_start, prop.submesh_count, _ = mdl_compile_mesh_internal( obj ) prop.flags = obj_data.flags prop.pstr_alias = _af_pack_string( obj_data.alias ) sr_ent_push( prop ) @@ -1117,6 +1084,23 @@ def _mdl_compiler_compile_entities(): sr_ent_push(traffic) #} + + for evi,ev in enumerate(obj.SR_data.events): + #{ + event = ent_event() + event.pstr_source_event = _af_pack_string( ev.source_event ) + event.pstr_recieve_event = _af_pack_string( ev.reciever_event ) + event.source_entity_id = sr_entity_id( obj ) + event.recieve_entity_id = sr_entity_id( ev.reciever ) + event.delay = ev.delay + event.flags = int(ev.arg_tipo) + if event.flags == 0x01: event.data.const_i32 = ev.arg_int + if event.flags == 0x02: event.data.const_f32 = ev.arg_float + if event.flags == 0x04: event.data.const_entity_id = sr_entity_id( ev.arg_entity ) + if event.flags == 0x08: event.data.const_pstr = _af_pack_string( ev.arg_string ) + if event.flags == 0x10: event.data.pstr_data_alias = 0 + sr_ent_push(event) + #} #} #} diff --git a/skaterift_blender/sr_metascene.py b/skaterift_blender/sr_metascene.py index 5e31baa..b28fc62 100644 --- a/skaterift_blender/sr_metascene.py +++ b/skaterift_blender/sr_metascene.py @@ -63,21 +63,50 @@ class ms_track(Structure): ("semantic_type",c_uint32)] # runtime #} -class ms_strip(Structure): +class ms_strip_data(Structure): #{ - _fields_ = [("data_start",c_uint32), # keyframes in block mode, or tracks in - # curves mode. - ("data_count",c_uint32), # tracks in curves, bone count in kfs - ("data_mode",c_uint32), - ("offset",c_uint32), + _fields_ = [("start",c_uint32), + ("count",c_uint32), ("length",c_uint32), - ("pstr_name",c_uint32), #AKA Blender NLAStrip name - ("pstr_internal_name",c_uint32), #AKA Blender action name - ("instance_id",c_uint32),# 0 ... 0xfffffffe, or 0xffffffff - ("object_id",c_uint32), # First class: SR entity ID, - # Second class: instance override index + ("pstr_name",c_uint32), + ("pstr_internal_name",c_uint32), + ("instance_id",c_uint32), + ("object_id",c_uint32), + ("timing_offset",c_float)] +#} + +class ms_strip_data_camera(Structure): +#{ + _fields_ = [("entity_id",c_uint32)] +#} + +class ms_strip_data_subtitle(Structure): +#{ + _fields_ = [("pstr_en",c_uint32), + ("res0",c_uint32), + ("res1",c_uint32), + ("res2",c_uint32), + ("character",c_uint8)] +#} - ("timing_offset",c_float),] +class ms_strip_data_event(Structure): +#{ + _fields_ = [("pstr_string",c_uint32)] +#} + +class ms_strip_data_union(Union): +#{ + _fields_ = [("strip",ms_strip_data), + ("camera",ms_strip_data_camera), + ("subtitle",ms_strip_data_subtitle), + ("event",ms_strip_data_event)] +#} + +class ms_strip(Structure): +#{ + _fields_ = [("mode",c_uint8), + ("offset",c_uint32), + ("anon",ms_strip_data_union)] #} class ms_instance(Structure): @@ -93,21 +122,6 @@ class ms_override(Structure): ("transform",mdl_transform)] #} -def _metascene_action_cache( out_strip, action ): -#{ - if action.name in _ms_compiler.action_cache: - #{ - print( " Using cached action data" ) - ref = _ms_compiler.action_cache[ action.name ] - out_strip.data_start = ref.data_start - out_strip.data_count = ref.data_count - out_strip.data_mode = ref.data_mode - out_strip.pstr_internal_name = ref.pstr_internal_name - return True - #} - else: return False -#} - def _sr_metascene_dryrun(): #{ scene = bpy.context.scene @@ -179,11 +193,11 @@ def _metascene_comp_armature_range( obj, start, end, out_strip ): #{ bones = [_ for _ in sr_armature_bones( obj )] out_strip.offset = math.floor( start ) - out_strip.length = math.ceil( end - out_strip.offset ) - out_strip.timing_offset = 0.0 - out_strip.data_mode = 0 - out_strip.data_start = len( _ms_compiler.keyframes ) - out_strip.data_count = len( bones ) + out_strip.anon.strip.length = math.ceil( end - out_strip.offset ) + out_strip.anon.strip.timing_offset = 0.0 + out_strip.anon.strip.mode = 0x1 + out_strip.anon.strip.start = len( _ms_compiler.keyframes ) + out_strip.anon.strip.count = len( bones ) unfuck = Matrix([(1,0,0,0),(0,0,1,0),(0,-1,0,0),(0,0,0,1)]) @@ -242,9 +256,9 @@ def _metascene_comp_armature_range( obj, start, end, out_strip ): kf.q[1] = rq[3] kf.q[2] = -rq[2] kf.q[3] = rq[0] - kf.s[0] = 1.0 #sca[0] - kf.s[1] = 1.0 #sca[1] - kf.s[2] = 1.0 #sca[2] + kf.s[0] = sca[0] + kf.s[1] = sca[2] + kf.s[2] = sca[1] _ms_compiler.keyframes.append(kf) #} @@ -289,10 +303,11 @@ def _metascene_armature_anims( obj, instance_id, override_id ): obj.animation_data.action = action out_strip = ms_strip() - out_strip.pstr_name = _af_pack_string( NLAStrip.name ) - out_strip.pstr_internal_name = _af_pack_string( action.name ) - out_strip.instance_id = instance_id - out_strip.object_id = override_id + out_strip.mode = 0x1 + out_strip.anon.strip.pstr_name = _af_pack_string( NLAStrip.name ) + out_strip.anon.strip.pstr_internal_name = _af_pack_string( action.name ) + out_strip.anon.strip.instance_id = instance_id + out_strip.anon.strip.object_id = override_id _metascene_comp_armature_range( obj, int(NLAStrip.frame_start), int(NLAStrip.frame_end), out_strip ) @@ -348,10 +363,11 @@ def _metascene_armature_anims( obj, instance_id, override_id ): internal_name = F"{obj.name}.{strip_count}" out_strip = ms_strip() - out_strip.pstr_name = _af_pack_string( F"{obj.name}(amalg)" ) - out_strip.pstr_internal_name = _af_pack_string( internal_name ) - out_strip.instance_id = instance_id - out_strip.object_id = override_id + out_strip.mode = 0x1 + out_strip.anon.strip.pstr_name = _af_pack_string( F"{obj.name}(amalg)" ) + out_strip.anon.strip.pstr_internal_name = _af_pack_string( internal_name ) + out_strip.anon.strip.instance_id = instance_id + out_strip.anon.strip.object_id = override_id _metascene_comp_armature_range( obj, frame_start, frame, out_strip ) _ms_compiler.strips.append( out_strip ) @@ -372,12 +388,11 @@ def _metascene_armature_anims( obj, instance_id, override_id ): def _metascene_compile_action_curves( out_strip, action ): #{ - if _metascene_action_cache( out_strip, action ): return - - out_strip.data_mode = 1 - out_strip.data_start = len(_ms_compiler.tracks) - out_strip.data_count = len(action.fcurves) - out_strip.pstr_internal_name = _af_pack_string( action.name ) + #if _metascene_action_cache( out_strip, action ): return + out_strip.mode = 0x2 + out_strip.anon.strip.start = len(_ms_compiler.tracks) + out_strip.anon.strip.count = len(action.fcurves) + out_strip.anon.strip.pstr_internal_name = _af_pack_string( action.name ) for fcurve in action.fcurves: #{ @@ -445,13 +460,12 @@ def _metascene_camera_anims( obj, entity_id ): out_strip = ms_strip() _metascene_compile_action_curves( out_strip, NLAStrip.action ) - out_strip.instance_id = 0xffffffff - out_strip.object_id = entity_id - out_strip.offset = math.floor( NLAStrip.frame_start ) - out_strip.timing_offset = NLAStrip.action_frame_start - out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset ) - out_strip.pstr_name = _af_pack_string( NLAStrip.name ) - + out_strip.anon.strip.instance_id = 0xffffffff + out_strip.anon.strip.object_id = entity_id + out_strip.anon.strip.offset = math.floor( NLAStrip.frame_start ) + out_strip.anon.strip.timing_offset = NLAStrip.action_frame_start + out_strip.anon.strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset ) + out_strip.anon.strip.pstr_name = _af_pack_string( NLAStrip.name ) _ms_compiler.strips.append( out_strip ) #} #} @@ -467,12 +481,12 @@ def _metascene_camera_anims( obj, entity_id ): print( F" have strip {NLAStrip.name}" ) out_strip = ms_strip() _metascene_compile_action_curves( out_strip, NLAStrip.action ) - out_strip.instance_id = 0xffffffff - out_strip.object_id = entity_id - out_strip.offset = math.floor( NLAStrip.frame_start ) - out_strip.timing_offset = NLAStrip.action_frame_start - out_strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset ) - out_strip.pstr_name = _af_pack_string( NLAStrip.name ) + out_strip.anon.strip.instance_id = 0xffffffff + out_strip.anon.strip.object_id = entity_id + out_strip.anon.strip.offset = math.floor( NLAStrip.frame_start ) + out_strip.anon.strip.timing_offset = NLAStrip.action_frame_start + out_strip.anon.strip.length = math.ceil( NLAStrip.frame_end - out_strip.offset ) + out_strip.anon.strip.pstr_name = _af_pack_string( NLAStrip.name ) _ms_compiler.strips.append( out_strip ) #} #} @@ -600,15 +614,26 @@ def _sr_export_metascene( path ): #{ print( F"Marker {marker.name}: {marker.camera}" ) out_strip = ms_strip() - out_strip.data_start = 0 - out_strip.data_count = 0 - out_strip.data_mode = 2 + out_strip.mode = 0x10 << int(marker.SR_data.tipo) out_strip.offset = marker.frame - out_strip.length = 0 - out_strip.pstr_name = _af_pack_string( marker.name ) - out_strip.pstr_internal_name = 0 - out_strip.instance_id = 0xffffffff - out_strip.object_id = sr_entity_id( marker.camera ) + + if out_strip.mode == 0x10: + #{ + out_strip.anon.camera.entity_id = sr_entity_id( marker.camera ) + print( out_strip.anon.camera.entity_id ) + #} + + if out_strip.mode == 0x20: + #{ + out_strip.anon.event.pstr_string = _af_pack_string( marker.SR_data.event_string ) + #} + + if out_strip.mode == 0x40: + #{ + out_strip.anon.subtitle.pstr_en = _af_pack_string( marker.SR_data.subtitle_en.replace('\\n','\n') ) + out_strip.anon.subtitle.character = int( marker.SR_data.subtitle_person ) + #} + _ms_compiler.strips.append( out_strip ) #} diff --git a/src/2 b/src/2 new file mode 100644 index 0000000..4946ea0 --- /dev/null +++ b/src/2 @@ -0,0 +1,85 @@ +static bool _skaterift_script_valley( ent_script_event *event ) +{ + if( on_nugget_once( event, "ch4s1a_view" ) ) + { + /* ch4s1: Mike and you are first encountering the valley world */ + static const struct cs_subtitle EN[] = + { + { "m1", KCOL_MIKE "It's gotta be some kind of dream right?" }, + { "m2", KCOL_MIKE "I mean... Cambodia?" }, + { "m3", KCOL_MIKE "What are we even doing here?" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4s1a.ms", EN, 1 ); + } + + /* main region is completed (this is just the time trial as of 14.05.25, unlock ch4s2 */ + if( on_function_trigger( event, 27 ) ) + { + if( _skaterift_script_nugget_status( "ch4s2_view" ) == 0 ) + _skaterift_script_nugget_set( "ch4s2_view", 2 ); + } + + /* unlock the finale challenge stuff if we've seen ch4s1 (mike bails) */ + u64 status; + if( on_nugget_changed( event, "ch4s1_view", &status ) ) + { + _ent_list_set_visible( _ent_list_get_aliased( "finale:locked" ), status != 1 ); + _ent_list_set_visible( _ent_list_get_aliased( "finale:unlocked" ), status == 1 ); + } + + /* finale completed, trigger the exit movie */ + if( on_function_trigger( event, 21 ) ) + { + // TODOX1 + vg_success( "Exit for a movie\n" ); + } + + return 1; +} + +static bool _skaterift_script_ch4s2( ent_script_event *event ) +{ + /* ch4s2: Mike and you find the rocket, and talk to the FBI person. */ + u64 status; + if( on_nugget_changed( event, "ch4s2_view", &status ) ) + { + _ent_list_set_visible( event->entity_list, status == 2 ); + _ent_list_set_visible( _ent_list_get_aliased( "rocket" ), status >= 1 ); + } + + if( on_function_trigger( event, 0 ) ) + { + if( on_nugget_once( event, "ch4s2_view" ) ) + { + static const struct cs_subtitle EN[] = + { + { "m1", KCOL_MIKE "What the hell is that thing?" }, + { "f1", KCOL_FBI "Look man, all they told is that uhh" }, + { "f2", KCOL_FBI "they're sending you up to one of saturns moons.." }, + { "f3", KCOL_FBI "On that thing." }, + { "f4", KCOL_FBI "To help you on your mission." }, + { "f5", KCOL_FBI "You guys are more important than any person on earth right now" }, + { "f6", KCOL_FBI "According to the president." }, + { "f7", KCOL_FBI "But obviously this is some kind of joke I'm not in on." }, + { "f8", KCOL_FBI "I don't believe a word of it." }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4s2.ms", EN, 1 ); + } + } + + return 1; +} + +static bool _skaterift_script_ch4s1( ent_script_event *event ) +{ + /* ch4s1: (Yes, this comes after ch4s2), Mike is leaving, because JC hasn't shown up anywhere. */ + return 1; +} + +static bool _skaterift_script_ch4s3( ent_script_event *event ) +{ + // on venus + return 1; +} diff --git a/src/ent_challenge.c b/src/ent_challenge.c index b3aa492..02bbae2 100644 --- a/src/ent_challenge.c +++ b/src/ent_challenge.c @@ -5,29 +5,30 @@ #include "audio.h" #include "ent_region.h" -void _ent_challenge_complete( ent_challenge *challenge ) +void _ent_challenge_clear( ent_challenge *challenge ) { world_instance *world = &_world.main; - vg_info( "challenge( '%s' )\n", af_str( &world->meta.af, challenge->pstr_alias) ); - if( challenge->on_complete_id ) + u32 next = challenge->first_objective_id; + while( mdl_entity_id_type(next) == k_ent_objective ) { - ent_call call; - call.data = NULL; - call.function = challenge->on_complete_event; - call.id = challenge->on_complete_id; - entity_call( world, &call ); + u32 index = mdl_entity_id_id( next ); + ent_objective *objective = af_arritm(&world->ent_objective,index); + objective->flags |= k_ent_objective_hidden; + next = objective->id_next; } - - challenge->status = 1; } void _ent_challenge_win(void) { + _world_raise_event( _world.active_challenge_id, "complete" ); + world_instance *world = &_world.main; ent_challenge *challenge = af_arritm( &world->ent_challenge, mdl_entity_id_id( _world.active_challenge_id ) ); - _ent_challenge_complete( challenge ); + _ent_challenge_clear( challenge ); + challenge->status = 1; ent_region_re_eval( world ); +#if 0 struct ent_script_event event; struct script_event_completion_changed inf = { .entity_id = _world.active_challenge_id, @@ -36,6 +37,7 @@ void _ent_challenge_win(void) event.type = k_escript_event_completion_changed; event.info = &inf; ent_script_propogate_event( world, &event ); +#endif if( world_clear_event( k_world_event_challenge ) ) { @@ -45,56 +47,30 @@ void _ent_challenge_win(void) } } -entity_call_result ent_challenge_call( world_instance *world, ent_call *call ) +entity_event_result ent_challenge_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_challenge *challenge = af_arritm( &world->ent_challenge, index ); - - if( (_world.event == k_world_event_challenge) && (_world.challenge_state >= k_challenge_state_running) ) - { - return k_entity_call_result_OK; - } - else + world_instance *world = &_world.main; + ent_challenge *challenge = af_arritm( &world->ent_challenge, mdl_entity_id_id( event->recieve_entity_id ) ); + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "view" ) ) { - if( call->function == 1 ) /* view() */ + if( world_set_event( k_world_event_challenge ) ) { - if( localplayer.subsystem == k_player_subsystem_walk ) - { - if( !(challenge->flags & k_ent_challenge_locked) ) - { - if( world_set_event( k_world_event_challenge ) ) - { - _world.challenge_state = k_challenge_state_none; - _world.active_challenge_id = call->id; - gui_helper_reset( 1 ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "View Challenge" ); - } - } - } + srinput.state = k_input_state_resume; + gui_helper_reset( k_gui_helper_mode_clear ); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) + vg_strcat( &text, "Start" ); + if( gui_new_helper( input_button_list[k_srbind_mback], &text )) + vg_strcat( &text, "Exit" ); - return k_entity_call_result_OK; - } - else if( call->function == -1 ) /* unview() */ - { - if( _world.challenge_state < k_challenge_state_running ) - { - if( !(challenge->flags & k_ent_challenge_locked) ) - { - if( world_clear_event( k_world_event_challenge ) ) - { - _world.challenge_state = k_challenge_state_none; - _world.active_challenge_id = 0; - gui_helper_reset( k_gui_helper_mode_clear ); - } - } - } - return k_entity_call_result_OK; + localplayer.immobile = 1; + menu.disable_open = 1; + _world.challenge_state = k_challenge_state_viewing; + _world.active_challenge_id = event->recieve_entity_id; } - else - return k_entity_call_result_unhandled; + return k_entity_event_result_OK; } + else return k_entity_event_result_unhandled; } void _restart_active_challenge(void) @@ -116,7 +92,7 @@ void _restart_active_challenge(void) { u32 index = mdl_entity_id_id( next ); ent_objective *objective = af_arritm(&world->ent_objective,index); - objective->flags &= ~(k_ent_objective_passed|k_ent_objective_failed); + objective->flags &= ~(k_ent_objective_passed|k_ent_objective_failed|k_ent_objective_hidden); next = objective->id_next; v3_fill( objective->transform.s, 1.0f ); } @@ -184,24 +160,21 @@ void ent_challenge_update(void) localplayer.immobile = 0; /* TODO: Unify this probably after eating some potats */ menu.disable_open = 0; - _restart_active_challenge(); - - if( challenge->on_activate_id ) - { - ent_call call; - call.data = NULL; - call.function = challenge->on_activate_event; - call.id = challenge->on_activate_id; - entity_call( &_world.main, &call ); - } + _world_raise_event( _world.active_challenge_id, "activate" ); } else if( button_down( k_srbind_mback ) ) { - gui_helper_reset( k_gui_helper_mode_clear ); - _world.challenge_state = k_challenge_state_none; - localplayer.immobile = 0; /* TODO: Unify this probably after eating some potats */ - menu.disable_open = 0; - srinput.state = k_input_state_resume; + if( world_clear_event( k_world_event_challenge ) ) + { + _world.active_challenge_id = 0; + _world.challenge_target = NULL; + _world.challenge_timer = 0.0f; + gui_helper_reset( k_gui_helper_mode_clear ); + _world.challenge_state = k_challenge_state_none; + localplayer.immobile = 0; /* TODO: Unify this probably after eating some potats */ + menu.disable_open = 0; + srinput.state = k_input_state_resume; + } } } else if( _world.challenge_state == k_challenge_state_running ) @@ -224,10 +197,15 @@ void ent_challenge_update(void) } f32 max_dist = 100.0f; + if( localplayer.subsystem == k_player_subsystem_glide ) + max_dist = 500.0f; + if( min_dist2 > max_dist*max_dist ) { if( world_clear_event( k_world_event_challenge ) ) { + _ent_challenge_clear( challenge ); + _world.active_challenge_id = 0; _world.challenge_target = NULL; _world.challenge_timer = 0.0f; @@ -241,21 +219,6 @@ void ent_challenge_update(void) } else if( _world.challenge_state == k_challenge_state_none ) { - if( button_down( k_srbind_maccept ) ) - { - srinput.state = k_input_state_resume; - gui_helper_reset( k_gui_helper_mode_clear ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, "Start" ); - if( gui_new_helper( input_button_list[k_srbind_mback], &text )) - vg_strcat( &text, "Exit" ); - - localplayer.immobile = 1; - menu.disable_open = 1; - srinput.state = k_input_state_resume; - _world.challenge_state = k_challenge_state_viewing; - } } if( _world.challenge_state >= k_challenge_state_running ) diff --git a/src/ent_challenge.h b/src/ent_challenge.h index 88aef57..4c4b6fd 100644 --- a/src/ent_challenge.h +++ b/src/ent_challenge.h @@ -1,7 +1,7 @@ #pragma once #include "entity.h" -entity_call_result ent_challenge_call( world_instance *world, ent_call *call ); +entity_event_result ent_challenge_event( ent_event *event ); void _ent_challenge_ui( ui_context *ctx ); void _restart_active_challenge(void); void _ent_challenge_complete( ent_challenge *challenge ); diff --git a/src/ent_glider.c b/src/ent_glider.c index 2148b3d..60e599a 100644 --- a/src/ent_glider.c +++ b/src/ent_glider.c @@ -2,24 +2,29 @@ #include "entity.h" #include "player_glide.h" -entity_call_result ent_glider_call( world_instance *world, ent_call *call ) +entity_event_result ent_glider_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_glider *glider = af_arritm( &world->ent_glider, index ); - - if( call->function == 0 ) + world_instance *world = &_world.main; + ent_glider *glider = af_arritm( &world->ent_glider, mdl_entity_id_id( event->recieve_entity_id ) ); + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "lock" ) ) { - glider->flags |= 0x1; - return k_entity_call_result_OK; + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( event->flags == k_ent_event_data_const_i32 ) + { + if( event->data.const_i32 ) glider->flags &= ~((u32)1); + else glider->flags |= (u32)1; + return k_entity_event_result_OK; + } + else + return k_entity_event_result_invalid; } - else if( call->function == 1 ) + else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "equip" ) ) { if( glider->flags & 0x1 ) - { player_glide_equip_glider(); - } - return k_entity_call_result_OK; + + return k_entity_event_result_OK; } else - return k_entity_call_result_unhandled; + return k_entity_event_result_unhandled; } diff --git a/src/ent_glider.h b/src/ent_glider.h index 5815dda..d92b4d2 100644 --- a/src/ent_glider.h +++ b/src/ent_glider.h @@ -1,4 +1,4 @@ #pragma once #include "entity.h" -entity_call_result ent_glider_call( world_instance *world, ent_call *call ); +entity_event_result ent_glider_call( ent_event *event ); diff --git a/src/ent_list.c b/src/ent_list.c index 2dd69a8..e2f4701 100644 --- a/src/ent_list.c +++ b/src/ent_list.c @@ -84,6 +84,61 @@ void _ent_list_set_visible( ent_list *list, bool visible ) if( visible ) marker->flags &= ~((u32)k_ent_marker_flag_hidden); else marker->flags |= (u32)k_ent_marker_flag_hidden; } + else if( iter.type == k_ent_glider ) + { + ent_glider *glider = af_arritm( &world->ent_glider, iter.index ); + if( visible ) glider->flags |= 0x1; + else glider->flags &= ~((u32)0x1); + } + } +} + +bool _ent_list_check_completed( ent_list *list ) +{ + world_instance *world = &_world.main; + struct ent_list_iter iter; + _ent_list_iter_start( &iter, list, 0 ); + + while( _ent_list_iter( &iter ) ) + { + if( iter.type == k_ent_challenge ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, iter.index ); + if( challenge->status == 0 ) + return 0; + } + else if( iter.type == k_ent_route ) + { + ent_route *route = af_arritm( &world->ent_route, iter.index ); + if( !(route->flags & (k_ent_route_flag_achieve_silver|k_ent_route_flag_achieve_gold)) ) + return 0; + } } + + return 1; } +void _ent_list_set_as_targets( ent_list *list, bool yes ) +{ +#if 0 + world_instance *world = &_world.main; + struct ent_list_iter iter; + _ent_list_iter_start( &iter, list, 0 ); + + while( _ent_list_iter( &iter ) ) + { + if( iter.type == k_ent_challenge ) + { + ent_challenge *challenge = af_arritm( &world->ent_challenge, iter.index ); + if( yes ) challenge->flags |= (u32)k_ent_challenge_target; + else challenge->flags &= ~((u32)k_ent_challenge_target); + } + else if( iter.type == k_ent_route ) + { + ent_route *route = af_arritm( &world->ent_route, iter.index ); + if( yes ) route->flags |= (u32)k_ent_route_target; + else route->flags &= ~((u32)k_ent_route_target); + } + } +#endif +} diff --git a/src/ent_npc.c b/src/ent_npc.c index 311b0fe..269890f 100644 --- a/src/ent_npc.c +++ b/src/ent_npc.c @@ -31,7 +31,8 @@ struct player_pose pose; m4x3f *final_mtx; } - jc, mike; + humans[4]; + struct skeleton_anim anim_idle; enum npc_sub_state @@ -47,10 +48,18 @@ struct } _npc; -void _ent_npc_set_in_cutscene( enum npc npc_id, bool yes ) +static struct human_npc *human_npc( enum npc id ) +{ + if( (id > 0) && (id <= k_npc_human_reserved) ) + return &_npc.humans[ id-1 ]; + else return NULL; +} + +void _ent_npc_set_in_cutscene( enum npc id, bool yes ) { - if( npc_id == k_npc_jc ) - _npc.jc.in_cutscene = yes; + struct human_npc *human = human_npc(id); + if( human ) + human->in_cutscene = yes; } struct sub_context @@ -59,114 +68,145 @@ struct sub_context u32 alias_hash; const cs_subtitle *subtitles; } -static _gino_contexts[] = +static *_sub_contexts[] = { - /* HEAVEN world */ + [ k_npc_gino ] = (struct sub_context[]) { - "heaven:introduction", .subtitles = (const cs_subtitle[]) + /* HEAVEN world */ { - { "a1", KCOL_JESUS "Hmm.. I'm Gino, hello" }, - { "a2", KCOL_JESUS "Do you remember who you are?" }, - { "a3", KCOL_JESUS "Pick here.." }, - { NULL, NULL }, + "heaven:introduction", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Hmm.. I'm Gino, hello" }, + { "a2", KCOL_JESUS "Do you remember who you are?" }, + { "a3", KCOL_JESUS "Pick here.." }, + { NULL, NULL }, + }, }, - }, - { - "heaven:locked", .subtitles = (const cs_subtitle[]) { - { "a1", KCOL_JESUS "Welcome to almost Heaven.." }, - { "a2", KCOL_JESUS "The entrance is blocked.." }, - { "a3", KCOL_JESUS "You'll go back to earth for now.." }, - { "a4", KCOL_JESUS "There are people waiting for you.." }, - { "a5", KCOL_JESUS "I think.." }, - { NULL, NULL }, - } - }, - { - "heaven:shop", .subtitles = (const cs_subtitle[]) + "heaven:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Welcome to almost Heaven.." }, + { "a2", KCOL_JESUS "The entrance is blocked.." }, + { "a3", KCOL_JESUS "You'll go back to earth for now.." }, + { "a4", KCOL_JESUS "There are people waiting for you.." }, + { "a5", KCOL_JESUS "I think.." }, + { NULL, NULL }, + } + }, { - { "a1", KCOL_JESUS "Might want to pick up one of these.." }, - { "a2", KCOL_JESUS "See you at the center Island.." }, - { NULL, NULL }, - } - }, + "heaven:shop", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Might want to pick up one of these.." }, + { "a2", KCOL_JESUS "See you at the center Island.." }, + { NULL, NULL }, + } + }, - /* HUB world */ - { - "mtzero:locked", .subtitles = (const cs_subtitle[]) - { - { "a1", KCOL_JESUS "Someone put boxes here.." }, - { "a2", KCOL_JESUS "Hmm.." }, - { NULL, NULL }, - } - }, - { - "city:locked", .subtitles = (const cs_subtitle[]) + /* HUB world */ + { + "mtzero:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Someone put boxes here.." }, + { "a2", KCOL_JESUS "Hmm.." }, + { NULL, NULL }, + } + }, { - { "a1", KCOL_JESUS "Again with the boxes!" }, - { "a2", KCOL_JESUS "Who is doing that?" }, - { NULL, NULL }, - } - }, - { - "valley:locked", .subtitles = (const cs_subtitle[]) + "city:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Again with the boxes!" }, + { "a2", KCOL_JESUS "Who is doing that?" }, + { NULL, NULL }, + } + }, { - { "a1", KCOL_JESUS ".." }, - { "a2", KCOL_JESUS "You know what to do.." }, - { NULL, NULL }, - } - }, - { - "boardmaker", .subtitles = (const cs_subtitle[]) + "valley:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS ".." }, + { "a2", KCOL_JESUS "You know what to do.." }, + { NULL, NULL }, + } + }, { - { "a1", KCOL_JESUS "Now that you know how to make boards" }, - { "a2", KCOL_JESUS "We moved a workshop in upstairs.." }, - { "a3", KCOL_JESUS ":)" }, - { NULL, NULL }, - } - }, + "boardmaker", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "Now that you know how to make boards" }, + { "a2", KCOL_JESUS "We moved a workshop in upstairs.." }, + { "a3", KCOL_JESUS ":)" }, + { NULL, NULL }, + } + }, - /* VOLCANO world */ - { - "docks:locked", .subtitles = (const cs_subtitle[]) - { - { "a1", KCOL_JESUS "To get to the docks.." }, - { "a2", KCOL_JESUS "Hmm.." }, - { "a3", KCOL_JESUS "JC demands you do all the tasks here.." }, - { "a4", KCOL_JESUS "Before going home.." }, - { "a5", KCOL_JESUS "Take a look at the map.." }, - { NULL, NULL }, - } - }, + /* VOLCANO world */ + { + "docks:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "To get to the docks.." }, + { "a2", KCOL_JESUS "Hmm.." }, + { "a3", KCOL_JESUS "JC demands you do all the tasks here.." }, + { "a4", KCOL_JESUS "Before going home.." }, + { "a5", KCOL_JESUS "Take a look at the map.." }, + { NULL, NULL }, + } + }, - /* MTZERO WORLD */ - { - "battery:locked", .subtitles = (const cs_subtitle[]) + /* MTZERO WORLD */ + { + "battery:locked", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JESUS "See that..?" }, + { "a2", KCOL_JESUS "Hmm.." }, + { "a3", KCOL_JESUS "Big ramp over there.." }, + { NULL, NULL }, + } + }, + { NULL } + }, + [ k_npc_jc ] = (struct sub_context[]) + { { - { "a1", KCOL_JESUS "See that..?" }, - { "a2", KCOL_JESUS "Hmm.." }, - { "a3", KCOL_JESUS "Big ramp over there.." }, - { NULL, NULL }, - } + "jc:demo", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_JOHN "HELLO I AM JC" }, + { "a2", KCOL_JOHN "JC" }, + { "a3", KCOL_JOHN "IS ME" }, + { NULL, NULL }, + }, + }, + { NULL } }, -}, -_jc_contexts[] = -{ + [ k_npc_mike ] = (struct sub_context[]) { - "jc:demo", .subtitles = (const cs_subtitle[]) { - { "a1", KCOL_JOHN "HELLO I AM JC" }, - { "a2", KCOL_JOHN "JC" }, - { "a3", KCOL_JOHN "IS ME" }, - { NULL, NULL }, + "mike:demo", .subtitles = (const cs_subtitle[]) + { + { "a1", KCOL_MIKE "HELLO I AM MIKE" }, + { "a2", KCOL_MIKE "MIKE" }, + { "a3", KCOL_MIKE "IS ME" }, + { NULL, NULL }, + }, }, + { NULL } }, }; void _ent_npc_init(void) { - for( u32 i=0; ialias == NULL ) + break; + + context->alias_hash = vg_strdjb2( context->alias ); + } + } void *alloc = vg_mem.rtmemory; mdl_context *mdl = &_npc.gino.mdl; @@ -180,8 +220,11 @@ void _ent_npc_init(void) struct skeleton *sk = &localplayer.skeleton; u32 mtx_size = sizeof(m4x3f)*sk->bone_count; - _npc.jc.final_mtx = vg_linear_alloc( alloc, mtx_size ); - _npc.mike.final_mtx = vg_linear_alloc( alloc, mtx_size ); + for( u32 i=0; i<4; i ++ ) + { + struct human_npc *human = &_npc.humans[i]; + human->final_mtx = vg_linear_alloc( alloc, mtx_size ); + } player_get_anim( &_npc.anim_idle, "idle_lean+y" ); } @@ -192,20 +235,52 @@ void _ent_npc_reset(void) _npc.gino.command_t = 0.0; _npc.gino.current_entity_id = 0; - _npc.jc.alive = 0; - _npc.mike.alive = 0; - addon_cache_unwatch( k_addon_type_player, _npc.jc.playermodel_view_slot ); - addon_cache_unwatch( k_addon_type_player, _npc.mike.playermodel_view_slot ); + for( u32 i=0; i<4; i++ ) + { + struct human_npc *human = &_npc.humans[i]; + human->alive = 0; + addon_cache_unwatch( k_addon_type_player, human->playermodel_view_slot ); + } } -void _ent_npc_speech( enum npc npc_id, const cs_subtitle *subs ) +void _ent_npc_speech( enum npc npc_id, const char *speech_alias ) { + const char *alias = speech_alias; + u32 hash = vg_strdjb2( alias ); + + struct sub_context *contexts = _sub_contexts[ npc_id ]; + if( !contexts ) + { + vg_error( "npc_id %d has no speech contexts, but speech for '%s' was requested.\n", npc_id, speech_alias ); + return; + } + + const cs_subtitle *subtitles = NULL; + for( u32 i=0; i<1000; i ++ ) + { + struct sub_context *context = &contexts[i]; + if( context->alias == NULL ) + { + vg_error( "npc_id %d does not contain speech set '%s'\n", npc_id, speech_alias ); + return; + } + + if( (hash == context->alias_hash) && !strcmp(context->alias,alias) ) + { + subtitles = context->subtitles; + break; + } + } + + if( !subtitles ) + vg_fatal_error( "You fucked the context array up good job\n" ); + srinput.state = k_input_state_resume; - if( _npc.subtitles != subs ) + if( _npc.subtitles != subtitles ) { _npc.sub_state = k_npc_sub_off; _npc.sub_index = 0; - _npc.subtitles = subs; + _npc.subtitles = subtitles; } if( _npc.sub_state == k_npc_sub_reading ) @@ -295,20 +370,25 @@ void _ent_npc_preupdate(void) } } - if( _npc.jc.alive && (v3_dist2( localplayer.rb.co, _npc.jc.co ) < 40.0f*40.0f) ) + for( u32 i=0; i<4; i ++ ) { - ms_keyframe apose[32], bpose[32]; - struct skeleton *sk = &localplayer.skeleton; - player_pose *pose = &_npc.jc.pose; - pose->type = k_player_pose_type_ik; - pose->board.lean = 0.0f; - v3_copy( _npc.jc.co, pose->root_co ); - v4_copy( _npc.jc.q, pose->root_q ); - skeleton_sample_anim( sk, &_npc.anim_idle, vg.time*0.1f+0.4f, apose ); - skeleton_copy_pose( sk, apose, pose->keyframes ); - // no for JC. - // effect_blink_apply( &_npc.jc.effect_data.blink, pose, vg.time_delta ); - apply_full_skeleton_pose( sk, pose, _npc.jc.final_mtx ); + struct human_npc *human = &_npc.humans[i]; + if( human->alive && (v3_dist2( localplayer.rb.co, human->co ) < 40.0f*40.0f) ) + { + ms_keyframe apose[32], bpose[32]; + struct skeleton *sk = &localplayer.skeleton; + player_pose *pose = &human->pose; + pose->type = k_player_pose_type_ik; + pose->board.lean = 0.0f; + v3_copy( human->co, pose->root_co ); + v4_copy( human->q, pose->root_q ); + skeleton_sample_anim( sk, &_npc.anim_idle, vg.time*0.1f+0.4f, apose ); + skeleton_copy_pose( sk, apose, pose->keyframes ); + // no for JC. + if( i != (k_npc_jc-1) ) + effect_blink_apply( &human->effect_data.blink, pose, vg.time_delta ); + apply_full_skeleton_pose( sk, pose, human->final_mtx ); + } } } @@ -316,14 +396,18 @@ void _ent_npc_render( vg_camera *cam ) { world_instance *world = &_world.main; - if( _npc.jc.alive && (v3_dist2( localplayer.rb.co, _npc.jc.co ) < 40.0f*40.0f) ) + for( u32 i=0; i<4; i ++ ) { - if( !((_cutscene.state == k_cutscene_state_playing) && _npc.jc.in_cutscene) ) + struct human_npc *human = &_npc.humans[i]; + if( human->alive && (v3_dist2( localplayer.rb.co, human->co ) < 40.0f*40.0f) ) { - m4x3f *final_mtx = _npc.jc.final_mtx; - struct player_model *model = addon_cache_item_data( k_addon_type_player, _npc.jc.playermodel_view_slot, 1 ); - struct skeleton *sk = &localplayer.skeleton; - render_playermodel( cam, world, 0, model, sk, final_mtx ); + if( !((_cutscene.state == k_cutscene_state_playing) && human->in_cutscene) ) + { + m4x3f *final_mtx = human->final_mtx; + struct player_model *model = addon_cache_item_data( k_addon_type_player, human->playermodel_view_slot, 1 ); + struct skeleton *sk = &localplayer.skeleton; + render_playermodel( cam, world, 0, model, sk, final_mtx ); + } } } @@ -383,28 +467,52 @@ void _ent_npc_render( vg_camera *cam ) mdl_draw_submesh( &_npc.gino.mdl.submeshes[ _npc.gino.sm_hat ] ); } -entity_call_result ent_npc_call( world_instance *world, ent_call *call ) +entity_event_result ent_npc_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_npc *npc = af_arritm( &world->ent_npc, index ); + world_instance *world = &_world.main; + ent_npc *npc = af_arritm( &world->ent_npc, mdl_entity_id_id( event->recieve_entity_id ) ); + + const char *npc_aliases[] = + { + [k_npc_gino] = "gino", + [k_npc_jc] = "JC", + [k_npc_mike] = "mike", + [k_npc_fbi] = "fbi", + [k_npc_max] = NULL + }; + + enum npc npc_id = k_npc_none; + + for( u32 i=0; imeta.af, npc->pstr_id, npc_aliases[i] ) ) + { + npc_id = i; + break; + } + } + } - if( AF_STR_EQ( &world->meta.af, npc->pstr_id, "gino" ) ) + if( npc_id == k_npc_none ) { - /* interact */ - if( call->function == 0 ) + vg_warn( "No npc with alias: %s\n", af_str( &world->meta.af, npc->pstr_id ) ); + return k_entity_event_result_invalid; + } + + if( npc_id == k_npc_gino ) + { + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "interact" ) ) { - const char *alias = af_str( &world->meta.af, npc->pstr_context_id ); - u32 hash = vg_strdjb2( alias ); - for( u32 i=0; imeta.af, npc->pstr_context_id ) ); + return k_entity_event_result_OK; } - /* proximity */ - else if( call->function == 1 ) + else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "proximity" ) ) { - if( _npc.gino.current_entity_id != call->id ) + if( _npc.gino.current_entity_id != event->source_entity_id ) { - _npc.gino.current_entity_id = call->id; + _npc.gino.current_entity_id = event->source_entity_id; v3_copy( npc->transform.co, _npc.gino.p1 ); if( _npc.gino.state == k_gino_none ) v3_add( npc->transform.co, (v3f){0,30,0}, _npc.gino.p0 ); @@ -414,33 +522,37 @@ entity_call_result ent_npc_call( world_instance *world, ent_call *call ) _npc.gino.state = k_gino_intro; _npc.gino.command_t = vg.time; } + return k_entity_event_result_OK; } - - return k_entity_call_result_OK; + else return k_entity_event_result_unhandled; } - else if( AF_STR_EQ( &world->meta.af, npc->pstr_id, "JC" ) ) + else { - if( call->function == 0 ) + struct human_npc *human = human_npc( npc_id ); + VG_ASSERT( human ); + + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "interact" ) ) { - const char *alias = af_str( &world->meta.af, npc->pstr_context_id ); - u32 hash = vg_strdjb2( alias ); - for( u32 i=0; imeta.af, npc->pstr_context_id ) ); + return k_entity_event_result_OK; } - /* proximity */ - else if( call->function == 1 ) + else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "proximity" ) ) { - if( _npc.jc.alive == 0 ) + if( human->alive == 0 ) { - _npc.jc.alive = 1; - _npc.jc.playermodel_view_slot = addon_cache_create_viewer_from_uid( k_addon_type_player, "sr003-local-skaterift_john" ); + const char *addons[] = + { + [k_npc_jc] = "sr003-local-skaterift_john", + [k_npc_mike] = "sr003-local-skaterift_mike", + [k_npc_fbi] = "sr003-local-skaterift_fbi", + }; + human->alive = 1; + human->playermodel_view_slot = addon_cache_create_viewer_from_uid( k_addon_type_player, addons[npc_id] ); } - v3_copy( npc->transform.co, _npc.jc.co ); - q_copy( npc->transform.q, _npc.jc.q ); + v3_copy( npc->transform.co, human->co ); + q_copy( npc->transform.q, human->q ); + return k_entity_event_result_OK; } - return k_entity_call_result_OK; + else return k_entity_event_result_unhandled; } - - return k_entity_call_result_unhandled; } diff --git a/src/ent_npc.h b/src/ent_npc.h index 21e5e3d..32065cd 100644 --- a/src/ent_npc.h +++ b/src/ent_npc.h @@ -3,8 +3,11 @@ enum npc { k_npc_none = 0, - k_npc_gino, k_npc_jc, + k_npc_mike, + k_npc_fbi, + k_npc_human_reserved, + k_npc_gino, k_npc_max }; @@ -12,7 +15,7 @@ void _ent_npc_init(void); void _ent_npc_render( vg_camera *cam ); void _ent_npc_goto( v3f pos, i32 uid ); void _ent_npc_preupdate(void); -void _ent_npc_speech( enum npc npc_id, const cs_subtitle *subs ); +void _ent_npc_speech( enum npc npc_id, const char *speech_alias ); void _ent_npc_reset(void); void _ent_npc_set_in_cutscene( enum npc npc_id, bool yes ); -entity_call_result ent_npc_call( world_instance *world, ent_call *call ); +entity_event_result ent_npc_event( ent_event *event ); diff --git a/src/ent_objective.c b/src/ent_objective.c index d33c61a..afc3fcc 100644 --- a/src/ent_objective.c +++ b/src/ent_objective.c @@ -9,12 +9,50 @@ static void ent_objective_pass( world_instance *world, ent_objective *objective ) { + objective->flags |= k_ent_objective_passed; + + u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id ); + ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index ); + + if( challenge->flags & k_ent_challenge_any_order ) + { + bool winner = 1; + u32 next = challenge->first_objective_id; + while( mdl_entity_id_type(next) == k_ent_objective ) + { + u32 index = mdl_entity_id_id( next ); + ent_objective *objective = af_arritm( &world->ent_objective, index ); + if( !(objective->flags & k_ent_objective_passed) ) + { + winner = 0; + break; + } + next = objective->id_next; + } + + if( winner ) + { + vg_audio_lock(); + vg_audio_oneshot( &audio_challenge[2], 1.0f, 0.0f, 0, 0 ); + vg_audio_unlock(); + _ent_challenge_win(); + } + else + { + vg_info( "pass challenge point\n" ); + vg_audio_lock(); + vg_audio_oneshot_3d( &audio_challenge[0], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); + vg_audio_unlock(); + } + + return; + } + if( objective->id_next ) { u32 index = mdl_entity_id_id( objective->id_next ); ent_objective *next = af_arritm( &world->ent_objective, index ); _world.challenge_target = next; - objective->flags |= k_ent_objective_passed; if( next->filter & k_ent_objective_filter_passthrough ) ent_objective_pass( world, next ); @@ -39,28 +77,34 @@ static int ent_objective_check_filter( ent_objective *objective ) { if( objective->filter ) { - struct player_skate_state *s = &player_skate.state; - enum trick_type trick = s->trick_type; - u32 state = 0x00; + if( localplayer.subsystem == k_player_subsystem_skate ) + { + struct player_skate_state *s = &player_skate.state; + enum trick_type trick = s->trick_type; - if( trick == k_trick_type_shuvit ) - state |= k_ent_objective_filter_trick_shuvit; - if( trick == k_trick_type_treflip ) - state |= k_ent_objective_filter_trick_treflip; - if( trick == k_trick_type_kickflip ) - state |= k_ent_objective_filter_trick_kickflip; - - if( s->flip_rate < -0.0001f ) state |= k_ent_objective_filter_flip_back; - if( s->flip_rate > 0.0001f ) state |= k_ent_objective_filter_flip_front; + if( trick == k_trick_type_shuvit ) + state |= k_ent_objective_filter_trick_shuvit; + if( trick == k_trick_type_treflip ) + state |= k_ent_objective_filter_trick_treflip; + if( trick == k_trick_type_kickflip ) + state |= k_ent_objective_filter_trick_kickflip; + + if( s->flip_rate < -0.0001f ) state |= k_ent_objective_filter_flip_back; + if( s->flip_rate > 0.0001f ) state |= k_ent_objective_filter_flip_front; - if( s->activity == k_skate_activity_grind_5050 || - s->activity == k_skate_activity_grind_back50 || - s->activity == k_skate_activity_grind_front50 ) - state |= k_ent_objective_filter_grind_truck_any; + if( s->activity == k_skate_activity_grind_5050 || + s->activity == k_skate_activity_grind_back50 || + s->activity == k_skate_activity_grind_front50 ) + state |= k_ent_objective_filter_grind_truck_any; - if( s->activity == k_skate_activity_grind_boardslide ) - state |= k_ent_objective_filter_grind_board_any; + if( s->activity == k_skate_activity_grind_boardslide ) + state |= k_ent_objective_filter_grind_board_any; + } + else if( localplayer.subsystem == k_player_subsystem_glide ) + { + state |= k_ent_objective_filter_glider; + } return ((objective->filter & state) || !objective->filter) && ((objective->filter2 & state) || !objective->filter2); @@ -71,70 +115,66 @@ static int ent_objective_check_filter( ent_objective *objective ) } } -entity_call_result ent_objective_call( world_instance *world, ent_call *call ) +entity_event_result ent_objective_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_objective *objective = af_arritm( &world->ent_objective, index ); + world_instance *world = &_world.main; + ent_objective *objective = af_arritm( &world->ent_objective, mdl_entity_id_id( event->recieve_entity_id ) ); - if( call->function == 0 ) + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "trigger" ) ) { if( (_world.event == k_world_event_challenge) && (_world.challenge_state == k_challenge_state_running) ) { if( objective->flags & (k_ent_objective_hidden|k_ent_objective_passed|k_ent_objective_failed)) - { - return k_entity_call_result_OK; - } + return k_entity_event_result_OK; + + u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id ); + ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index ); - if( _world.challenge_target ) + if( challenge->flags & k_ent_challenge_any_order ) { - if( (_world.challenge_target == objective) && ent_objective_check_filter( objective )) - { + if( ent_objective_check_filter( objective ) ) ent_objective_pass( world, objective ); - } - else + + // else do nothing + } + else + { + if( _world.challenge_target ) { - vg_audio_lock(); - vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); - vg_audio_unlock(); - vg_error( "challenge failed, filter was not met\n" ); - objective->flags |= k_ent_objective_failed; - _world.challenge_state = k_challenge_state_fail; - - gui_helper_reset( k_gui_helper_mode_black_bars ); - vg_str str; - struct gui_helper *helper; - if( (helper = gui_new_helper(input_button_list[k_srbind_reset], &str)) ) + if( (_world.challenge_target == objective) && ent_objective_check_filter( objective )) + ent_objective_pass( world, objective ); + else { - vg_strcat( &str, "Retry" ); + vg_audio_lock(); + vg_audio_oneshot_3d( &audio_challenge[6], localplayer.rb.co, 30.0f, 1.0f, 0, 0 ); + vg_audio_unlock(); + vg_error( "challenge failed, filter was not met\n" ); + objective->flags |= k_ent_objective_failed; + _world.challenge_state = k_challenge_state_fail; + + gui_helper_reset( k_gui_helper_mode_black_bars ); + vg_str str; + struct gui_helper *helper; + if( (helper = gui_new_helper(input_button_list[k_srbind_reset], &str)) ) + vg_strcat( &str, "Retry" ); } } } } - return k_entity_call_result_OK; + return k_entity_event_result_OK; } - else if( call->function == 2 ) + else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "hide" ) ) { - objective->flags &= ~k_ent_objective_hidden; - - if( mdl_entity_id_type( objective->id_next ) == k_ent_objective ) + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( event->flags == k_ent_event_data_const_i32 ) { - call->id = objective->id_next; - entity_call( world, call ); + if( event->data.const_i32 ) objective->flags &= ~((u32)k_ent_objective_hidden); + else objective->flags |= (u32)k_ent_objective_hidden; + return k_entity_event_result_OK; } - return k_entity_call_result_OK; - } - else if( call->function == 3 ) - { - objective->flags |= k_ent_objective_hidden; - - if( mdl_entity_id_type( objective->id_next ) == k_ent_objective ) - { - call->id = objective->id_next; - entity_call( world, call ); - } - return k_entity_call_result_OK; + else + return k_entity_event_result_invalid; } - else - return k_entity_call_result_unhandled; + return k_entity_event_result_unhandled; } diff --git a/src/ent_objective.h b/src/ent_objective.h index 9d94772..e5e84ac 100644 --- a/src/ent_objective.h +++ b/src/ent_objective.h @@ -1,4 +1,4 @@ #pragma once #include "entity.h" #include "world.h" -entity_call_result ent_objective_call( world_instance *world, ent_call *call ); +entity_event_result ent_objective_event( ent_event *event ); diff --git a/src/ent_region.c b/src/ent_region.c index 94ea1ba..aa1a906 100644 --- a/src/ent_region.c +++ b/src/ent_region.c @@ -15,15 +15,16 @@ u32 region_spark_colour( u32 flags ) return 0x00; } -entity_call_result ent_region_call( world_instance *world, ent_call *call ) +entity_event_result ent_region_event( ent_event *event ) { - ent_region *region = af_arritm( &world->ent_region, mdl_entity_id_id(call->id) ); + world_instance *world = &_world.main; + ent_region *region = af_arritm( &world->ent_region, mdl_entity_id_id(event->recieve_entity_id) ); ent_list *challenge_list = NULL; if( region->v109.id_list != 0 ) challenge_list = af_arritm( &world->ent_list, mdl_entity_id_id( region->v109.id_list ) ); - if( call->function == 0 ) /* enter */ + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "set_active" ) ) { gui_location_print_ccmd( 1, (const char *[]){af_str( &world->meta.af, region->pstr_title)} ); vg_strncpy( af_str( &world->meta.af, region->pstr_title ), @@ -56,20 +57,9 @@ entity_call_result ent_region_call( world_instance *world, ent_call *call ) } } - return k_entity_call_result_OK; + return k_entity_event_result_OK; } - else if( call->function == 1 ) /* leave */ - { - for( u32 i=0; ient_route); i ++ ) - { - ent_route *route = af_arritm( &world->ent_route, i ); - route->flags |= k_ent_route_flag_out_of_zone; - } - localplayer.effect_data.spark.colour = 0x00; - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; + else return k_entity_event_result_unhandled; } /* @@ -120,36 +110,7 @@ void ent_region_re_eval( world_instance *world ) } } - /* run unlock triggers. v105+ */ - if( world->meta.version >= 105 ) - { - for( u32 j=0; jent_region ); j ++ ) - { - ent_region *region = af_arritm( &world->ent_region, j ); - if( region->flags & (k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver) ) - { - if( region->target0[0] ) - { - vg_info( "Trigger region unlock -> %u\n", region->target0[0] ); - - struct ent_region_unlock_data data = - { - .world_total = world_total, - .region_total = region->flags - }; - - ent_call call; - call.data = &data; - call.id = region->target0[0]; - call.function = region->target0[1]; - entity_call( world, &call ); - } - } - } - } - addon_reg *world_reg = addon_details( _world.main.addon_id ); - if( world_reg->flags & ADDON_REG_MTZERO ) { if( world_total & k_ent_route_flag_achieve_gold ) diff --git a/src/ent_region.h b/src/ent_region.h index 886858b..c55edd2 100644 --- a/src/ent_region.h +++ b/src/ent_region.h @@ -17,4 +17,4 @@ struct ent_region_unlock_data u32 region_spark_colour( u32 flags ); void ent_region_re_eval( world_instance *world ); -entity_call_result ent_region_call( world_instance *world, ent_call *call ); +entity_event_result ent_region_event( ent_event *event ); diff --git a/src/ent_relay.c b/src/ent_relay.c index e770ad5..711e71c 100644 --- a/src/ent_relay.c +++ b/src/ent_relay.c @@ -1,25 +1 @@ #include "ent_relay.h" - -entity_call_result ent_relay_call( world_instance *world, ent_call *call ) -{ - u32 index = mdl_entity_id_id( call->id ); - ent_relay *relay = af_arritm( &world->ent_relay, index ); - - if( call->function == 0 ) - { - for( u32 i=0; itargets); i++ ) - { - if( relay->targets[i][0] ) - { - ent_call call; - call.data = NULL; - call.function = relay->targets[i][1]; - call.id = relay->targets[i][0]; - entity_call( world, &call ); - } - } - return k_entity_call_result_OK; - } - else - return k_entity_call_result_unhandled; -} diff --git a/src/ent_relay.h b/src/ent_relay.h index 054570c..9030863 100644 --- a/src/ent_relay.h +++ b/src/ent_relay.h @@ -1,3 +1,2 @@ #pragma once #include "entity.h" -entity_call_result ent_relay_call( world_instance *world, ent_call *call ); diff --git a/src/ent_route.c b/src/ent_route.c index a99ff41..78b1a61 100644 --- a/src/ent_route.c +++ b/src/ent_route.c @@ -6,13 +6,13 @@ struct _ent_route _ent_route; -entity_call_result ent_route_call( world_instance *world, ent_call *call ) +entity_event_result ent_route_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_route *route = af_arritm( &world->ent_route, index ); + world_instance *world = &_world.main; + ent_route *route = af_arritm( &world->ent_route, mdl_entity_id_id( event->recieve_entity_id ) ); - if( call->function == 0 ) - { + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "view" ) ) + { if( world_set_event( k_world_event_route_leaderboard ) ) { menu_close(); @@ -21,15 +21,12 @@ entity_call_result ent_route_call( world_instance *world, ent_call *call ) if( gui_new_helper( input_button_list[k_srbind_mback], &text ) ) vg_strcat( &text, "Exit" ); - - _ent_route.viewing_route_id = call->id; + _ent_route.viewing_route_id = event->recieve_entity_id; localplayer.immobile = 1; } - - return k_entity_call_result_OK; + return k_entity_event_result_OK; } - - return k_entity_call_result_unhandled; + else return k_entity_event_result_unhandled; } void ent_route_preupdate(void) diff --git a/src/ent_route.h b/src/ent_route.h index efd5022..2c8f080 100644 --- a/src/ent_route.h +++ b/src/ent_route.h @@ -13,7 +13,7 @@ struct _ent_route } extern _ent_route; -entity_call_result ent_route_call( world_instance *world, ent_call *call ); +entity_event_result ent_route_event( ent_event *event ); void ent_route_preupdate(void); void ent_route_leaderboard_ui( ui_context *ctx, ui_rect ref_box, u32 route_index ); void _ent_route_imgui( ui_context *ctx ); diff --git a/src/ent_script.c b/src/ent_script.c index b63bad4..2e2a67c 100644 --- a/src/ent_script.c +++ b/src/ent_script.c @@ -87,32 +87,38 @@ void ent_script_update( world_instance *world ) void ent_script_start( world_instance *world ) { + /* internal start event */ struct ent_script_event event; event.type = k_escript_event_world_start; event.info = NULL; ent_script_propogate_event( world, &event ); + + /* external start event */ + for( u32 i=0; ient_script ); i ++ ) + _world_raise_event( mdl_entity_id( k_ent_script, i ), "start" ); } -entity_call_result ent_script_call( world_instance *world, ent_call *call ) +entity_event_result _ent_script_world_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); + world_instance *world = &_world.main; + u32 index = mdl_entity_id_id( event->recieve_entity_id ); ent_script *script = af_arritm( &world->ent_script, index ); if( script->flags & k_ent_script_flag_linked ) { - struct script_event_call info; - info.function_id = call->function; - - struct ent_script_event event; - ent_script_event_init( &event, world, index ); - event.type = k_escript_event_call; - event.info = &info; - _ent_script_table[ script->script_id ].jump( &event ); - return k_entity_call_result_OK; + struct script_event_world_io io_inf; + io_inf.event = event; + + struct ent_script_event script_event; + ent_script_event_init( &script_event, world, index ); + script_event.type = k_escript_event_world_event; + script_event.info = &io_inf; + _ent_script_table[ script->script_id ].jump( &script_event ); + return k_entity_event_result_OK; } else { - vg_error( "Call to script '%u', function '%d', but the script is not linked.\n", index, call->function ); - return k_entity_call_result_OK; + vg_error( "Call to script '%u', but the script is not linked.\n", index ); + return k_entity_event_result_OK; } } diff --git a/src/ent_script.h b/src/ent_script.h index 8fc559a..3e4457a 100644 --- a/src/ent_script.h +++ b/src/ent_script.h @@ -6,34 +6,41 @@ struct script_event_allocate void *userdata; }; -struct script_event_call +struct script_event_world_io { - i32 function_id; + ent_event *event; }; -struct script_event_nugget_changed +struct script_event_atom_changed { const char *alias; u64 value; }; +#if 0 +struct script_event_call +{ + i32 function_id; +}; + + struct script_event_completion_changed { u32 entity_id; u32 completion_flags; }; +#endif typedef struct ent_script_event ent_script_event; struct ent_script_event { enum escript_event { - k_escript_event_call = 0, + k_escript_event_world_event, k_escript_event_allocate, k_escript_event_update, k_escript_event_world_start, - k_escript_event_nugget_changed, - k_escript_event_completion_changed + k_escript_event_atom_changed, } type; void *info; @@ -55,4 +62,4 @@ void ent_script_propogate_event( world_instance *world, struct ent_script_event void ent_script_start( world_instance *world ); void ent_script_update( world_instance *world ); void ent_script_alloc( world_instance *world, void *heap ); -entity_call_result ent_script_call( world_instance *world, ent_call *call ); +entity_event_result _ent_script_world_event( ent_event *event ); diff --git a/src/ent_skateshop.c b/src/ent_skateshop.c index fa664fe..df78628 100644 --- a/src/ent_skateshop.c +++ b/src/ent_skateshop.c @@ -288,24 +288,6 @@ void ent_skateshop_update(void) else vg_fatal_error( "Unknown store (%u)\n", shop->type ); } - else - { - if( button_down( k_srbind_use ) ) - { - menu_close(); - ent_skateshop *shop = _skateshop.current_shop; - if( shop->type == k_skateshop_type_boardshop ) - { - skateshop_update_viewpage(); - skateshop_scan( k_addon_type_board ); - } - - gui_helper_reset( k_gui_helper_mode_clear ); - ent_skateshop_helpers_pickable( "Pick" ); - _skateshop.open = 1; - skateshop_playermod( 1 ); - } - } } static void skateshop_render_boardshop( ent_skateshop *shop, vg_camera *cam ) @@ -520,38 +502,32 @@ void ent_skateshop_render( vg_camera *cam ) } } -entity_call_result ent_skateshop_call( world_instance *world, ent_call *call ) +entity_event_result ent_skateshop_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_skateshop *shop = af_arritm( &world->ent_skateshop, index ); + world_instance *world = &_world.main; + ent_skateshop *shop = af_arritm( &world->ent_skateshop, mdl_entity_id_id( event->recieve_entity_id ) ); - if( call->function == 0 ) /* view() */ + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "open" ) ) { - if( localplayer.subsystem == k_player_subsystem_walk ) + if( world_set_event( k_world_event_shop ) ) { - if( world_set_event( k_world_event_shop ) ) + menu_close(); + _skateshop.current_shop = shop; + if( shop->type == k_skateshop_type_boardshop ) { - _skateshop.current_shop = shop; - gui_helper_reset( k_gui_helper_mode_black_bars ); - - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_use], &text )) - vg_strcat( &text, "Open Shop" ); + skateshop_update_viewpage(); + skateshop_scan( k_addon_type_board ); } - } - return k_entity_call_result_OK; - } - else if( call->function == -1 ) /* unview() */ - { - if( world_clear_event( k_world_event_shop ) ) - { - _skateshop.current_shop = NULL; + gui_helper_reset( k_gui_helper_mode_clear ); + ent_skateshop_helpers_pickable( "Pick" ); + _skateshop.open = 1; + skateshop_playermod( 1 ); } - return k_entity_call_result_OK; + + return k_entity_event_result_OK; } - else - return k_entity_call_result_unhandled; + else return k_entity_event_result_unhandled; } void ent_skateshop_gui( ui_context *ctx ) diff --git a/src/ent_skateshop.h b/src/ent_skateshop.h index 182bcd6..b913ed1 100644 --- a/src/ent_skateshop.h +++ b/src/ent_skateshop.h @@ -46,5 +46,5 @@ void ent_skateshop_render( vg_camera *cam ); void skateshop_autostart_loading(void); void skateshop_world_preupdate(void); -entity_call_result ent_skateshop_call( world_instance *world, ent_call *call ); +entity_event_result ent_skateshop_event( ent_event *event ); void skateshop_world_preview_preupdate(void); diff --git a/src/entity.c b/src/entity.c index 7a64422..2004502 100644 --- a/src/entity.c +++ b/src/entity.c @@ -14,62 +14,3 @@ #include -/* - * TODO: Does this really need to take a world parameter, now that we're only using one world? - */ -void entity_call( world_instance *world, ent_call *call ) -{ - u32 type = mdl_entity_id_type( call->id ), - index = mdl_entity_id_id( call->id ); - - fn_entity_call_handler table[] = { - [k_ent_volume] = ent_volume_call, - [k_ent_audio] = ent_audio_call, - [k_ent_skateshop] = ent_skateshop_call, - [k_ent_objective] = ent_objective_call, - [k_ent_ccmd] = ent_ccmd_call, - [k_ent_gate] = ent_gate_call, - [k_ent_relay] = ent_relay_call, - [k_ent_challenge] = ent_challenge_call, - [k_ent_route] = ent_route_call, - [k_ent_region] = ent_region_call, - [k_ent_glider] = ent_glider_call, - [k_ent_water] = ent_water_call, - [k_ent_script] = ent_script_call, - [k_ent_npc] = ent_npc_call, - }; - - if( type >= VG_ARRAY_LEN(table) ){ - vg_error( "call to entity type: %u is out of range\n", type ); - return; - } - - fn_entity_call_handler fn = table[ type ]; - - if( !fn ) - { - vg_error( "Entity type %u does not have a call handler, but was called anyway\n", type ); - return; - } - - enum entity_call_result res = fn( world, call ); - if( res == k_entity_call_result_unhandled ) - vg_warn( "Call to entity %u#%u was unhandled.\n", type, index ); -} - -ent_marker *ent_find_marker( mdl_context *mdl, array_file_ptr *arr, - const char *alias ) -{ - for( u32 i=0; iaf, marker->pstr_alias ), alias ) ) - { - return marker; - } - } - - return NULL; -} - diff --git a/src/entity.h b/src/entity.h index a50c137..40aecb4 100644 --- a/src/entity.h +++ b/src/entity.h @@ -62,7 +62,7 @@ enum entity_alias{ k_ent_ccmd = 17, k_ent_objective = 18, k_ent_challenge = 19, - k_ent_relay = 20, + k_ent_deleted0 = 20, //k_ent_relay = 20, k_ent_cubemap = 21, k_ent_miniworld = 22, k_ent_prop = 23, @@ -71,7 +71,7 @@ enum entity_alias{ k_ent_glider = 26, k_ent_npc = 27, k_ent_armature = 28, - k_ent_script = 29, + k_ent_script = 29, k_ent_max }; @@ -97,7 +97,7 @@ const char *_entity_alias_str[] = [k_ent_ccmd] = "ent_ccmd", [k_ent_objective] = "ent_objective", [k_ent_challenge] = "ent_challenge", - [k_ent_relay] = "ent_relay", + //[k_ent_relay] = "ent_relay", [k_ent_cubemap] = "ent_cubemap", [k_ent_miniworld] = "ent_miniworld", [k_ent_prop] = "ent_prop", @@ -108,15 +108,6 @@ const char *_entity_alias_str[] = [k_ent_script] = "ent_script" }; -typedef struct ent_call ent_call; -typedef enum entity_call_result entity_call_result; -enum entity_call_result -{ - k_entity_call_result_OK, - k_entity_call_result_unhandled, - k_entity_call_result_invalid -}; - static inline u32 mdl_entity_id_type( u32 entity_id ) { return (entity_id & 0x0fff0000) >> 16; @@ -132,13 +123,6 @@ static inline u32 mdl_entity_id( u32 type, u32 index ) return (type & 0xfffff)<<16 | (index & 0xfffff); } -enum entity_function -{ - k_ent_function_trigger, - k_ent_function_particle_spawn, - k_ent_function_trigger_leave -}; - enum ent_spawn_flag { k_ent_spawn_flag_locked = 0x1, @@ -148,26 +132,27 @@ enum ent_spawn_flag k_ent_spawn_flag_group_4 = 0x80 }; -struct ent_spawn{ +struct ent_spawn +{ mdl_transform transform; u32 pstr_name; u32 flags; }; -enum light_type{ +enum light_type +{ k_light_type_point = 0, k_light_type_spot = 1 }; -struct ent_light{ +struct ent_light +{ mdl_transform transform; u32 daytime, type; - v4f colour; float angle, range; - m4x3f inverse_world; v2f angle_sin_cos; }; @@ -197,7 +182,7 @@ struct ent_list struct file_entity_ref { - u32 entity_id; + u32 entity_id, pstr_alias; }; /* v102+ */ @@ -215,7 +200,8 @@ enum ent_gate_flag k_ent_gate_passive = 0x80 }; -struct ent_gate{ +struct ent_gate +{ u32 flags, target, key; @@ -273,11 +259,14 @@ enum ent_route_flag { k_ent_route_flag_achieve_gold = 0x2, k_ent_route_flag_out_of_zone = 0x10, - k_ent_region_flag_hasname = 0x20 + k_ent_region_flag_hasname = 0x20, + k_ent_route_flag_target = 0x40 }; -struct ent_route{ - union{ +struct ent_route +{ + union + { mdl_transform transform; u32 official_track_id; /* TODO: remove this */ } @@ -304,11 +293,11 @@ struct ent_route{ u32 flags; f64 best_laptime; f32 ui_stopper, ui_residual; - ui_px ui_first_block_width, ui_residual_block_w; }; -struct ent_water{ +struct ent_water +{ mdl_transform transform; float max_dist; u32 reserved0, reserved1; @@ -323,17 +312,19 @@ struct ent_audio_clip{ float probability; }; -struct volume_particles{ +struct volume_particles +{ u32 blank, blank2; }; -struct volume_trigger{ - i32 event, event_leave; +struct volume_trigger +{ + i32 blank, blank2; }; struct volume_interact { - i32 activate_event; + i32 blank; u32 pstr_text; }; @@ -349,10 +340,17 @@ enum ent_volume_flag { struct ent_volume { mdl_transform transform; - m4x3f to_world, to_local; + m4x3f to_world; + + union + { + m4x3f to_local; + v3f particle_co; + }; + u32 flags; - u32 target; + u32 deleted0; union { volume_trigger trigger; @@ -361,7 +359,8 @@ struct ent_volume }; }; -struct ent_audio{ +struct ent_audio +{ mdl_transform transform; u32 flags, clip_start, @@ -394,32 +393,38 @@ enum skateshop_type{ k_skateshop_type_server = 4 }; -struct ent_skateshop{ +struct ent_skateshop +{ mdl_transform transform; u32 type, id_camera; - union{ - struct{ + union + { + struct + { u32 id_display, id_info, id_rack; } boards; - struct{ + struct + { u32 id_display, id_info, id_rack; } character; - struct{ + struct + { u32 id_display, id_info; } worlds; - struct{ + struct + { u32 id_lever; } server; @@ -557,10 +562,8 @@ struct ent_worldinfo f32 wind_scale; }; -ent_marker *ent_find_marker( mdl_context *mdl, array_file_ptr *arr, - const char *alias ); - -enum channel_behaviour{ +enum channel_behaviour +{ k_channel_behaviour_unlimited = 0, k_channel_behaviour_discard_if_full = 1, k_channel_behaviour_crossfade_if_full = 2 @@ -633,7 +636,8 @@ enum ent_objective_filter{ k_ent_objective_filter_grind_truck_any| k_ent_objective_filter_grind_board_any, k_ent_objective_filter_footplant = 0x00000080, - k_ent_objective_filter_passthrough = 0x00000100 + k_ent_objective_filter_passthrough = 0x00000100, + k_ent_objective_filter_glider = 0x00000200 }; enum ent_objective_flag @@ -662,6 +666,8 @@ enum ent_challenge_flag k_ent_challenge_timelimit = 0x1, //k_ent_challenge_is_story = 0x2, k_ent_challenge_locked = 0x4, + k_ent_challenge_any_order = 0x8, + k_ent_challenge_target = 0x10 }; struct ent_challenge @@ -670,11 +676,10 @@ struct ent_challenge u32 pstr_alias, flags; - u32 on_activate_id; - u32 on_activate_event; - - u32 on_complete_id; - i32 on_complete_event; + u32 deleted0;//on_activate_id; + u32 deleted1;//on_activate_event; + u32 deleted2;//on_complete_id; + i32 deleted3;//on_complete_event; u32 first_objective_id; u32 camera_id; @@ -683,24 +688,13 @@ struct ent_challenge u32 reset_spawn_id; }; -struct ent_relay { - u32 targets[4][2]; - i32 targets_events[4]; -}; - -struct ent_cubemap { +struct ent_cubemap +{ v3f co; u32 resolution, live, texture_id, framebuffer_id, renderbuffer_id, placeholder[2]; }; -struct ent_miniworld { - mdl_transform transform; - u32 pstr_world; - u32 camera; - u32 proxy; -}; - enum prop_flag { k_prop_flag_hidden = 0x1, @@ -709,7 +703,8 @@ enum prop_flag k_prop_flag_spinning_fast = 0x8, }; -struct ent_prop { +struct ent_prop +{ mdl_transform transform; u32 submesh_start, submesh_count, flags, pstr_alias; }; @@ -726,10 +721,11 @@ struct ent_region }; /* 105+ */ - u32 target0[2]; + u32 deleted01[2]; }; -struct ent_glider { +struct ent_glider +{ mdl_transform transform; u32 flags; f32 cooldown; @@ -741,13 +737,43 @@ struct ent_npc u32 pstr_id, pstr_context_id; }; -#include "world.h" +typedef enum entity_event_result entity_event_result; +enum entity_event_result +{ + k_entity_event_result_OK, + k_entity_event_result_unhandled, + k_entity_event_result_invalid +}; -struct ent_call{ - u32 id; - i32 function; - void *data; +enum ent_event_flags +{ + k_ent_event_data_const_i32 = 0x1, + k_ent_event_data_const_f32 = 0x2, + k_ent_event_data_const_entity_id = 0x4, + k_ent_event_data_const_string = 0x8, + k_ent_event_data_data_alias = 0x10, + k_ent_event_data_v3f = 0x20 }; -typedef enum entity_call_result (*fn_entity_call_handler)( world_instance *, ent_call *); -void entity_call( world_instance *world, ent_call *call ); +typedef struct ent_event ent_event; +struct ent_event +{ + u32 pstr_source_event, + pstr_recieve_event, + source_entity_id, + recieve_entity_id, + flags; + + f32 delay; + u32 unused0; + + union + { + i32 const_i32; + f32 const_f32; + u32 const_entity_id; + u32 const_pstr; + u32 pstr_data_alias; + } + data; +}; diff --git a/src/menu.c b/src/menu.c index 7750eb8..67e1db7 100644 --- a/src/menu.c +++ b/src/menu.c @@ -387,7 +387,7 @@ void menu_update_world_list(void) if( world_map.superworld_list_selected == k_superworld_infinite ) world_map.selected_superworld_locked = 1; if( world_map.superworld_list_selected == k_superworld_venus_moon ) { - world_map.selected_superworld_locked = !_skaterift_script_nugget_status( "unlock_venus" ); + world_map.selected_superworld_locked = !_skaterift_atom_status( "unlock_venus" ); } if( world_map.selected_superworld_locked ) @@ -428,11 +428,11 @@ void menu_update_world_list(void) addon_reg *reg = addon_details( addon_id ); bool unlocked = 1; if( reg->flags & ADDON_REG_MTZERO ) - unlocked = _skaterift_script_nugget_status( "unlock_mtzero" )?1:0; + unlocked = _skaterift_atom_status( "unlock_mtzero" )?1:0; if( reg->flags & ADDON_REG_CITY ) - unlocked = _skaterift_script_nugget_status( "unlock_city" )?1:0; + unlocked = _skaterift_atom_status( "unlock_city" )?1:0; if( reg->flags & ADDON_REG_VALLEY ) - unlocked = _skaterift_script_nugget_status( "unlock_valley" )?1:0; + unlocked = _skaterift_atom_status( "unlock_valley" )?1:0; menu.world_list_entries[ menu.world_list_display_count ] = unlocked? addon_id: 0; @@ -836,6 +836,7 @@ void menu_gui( ui_context *ctx ) { if( world_clear_event( k_world_event_challenge ) ) { + _ent_challenge_clear( af_arritm( &_world.main.ent_challenge, mdl_entity_id_id( _world.active_challenge_id ) ) ); gui_helper_reset( k_gui_helper_mode_clear ); _world.challenge_state = k_challenge_state_none; _world.active_challenge_id = 0; @@ -984,6 +985,7 @@ n1: if( menu_button( ctx, a, R == 0, 1, "Skip" ) ) { _cutscene.fadeout = 1; + _cutscene.skipped = 1; _cutscene.fadeout_start = _cutscene.time; _cutscene.meta.info.end_frame = (f32)_cutscene.meta.info.framerate * (_cutscene.time + 0.25f); menu_close(); diff --git a/src/metascene.c b/src/metascene.c index 2867488..8aacd47 100644 --- a/src/metascene.c +++ b/src/metascene.c @@ -56,10 +56,9 @@ void _cutscene_unload(void) _cutscene.state = k_cutscene_state_unloading; _cutscene.player_binding = NULL; _cutscene.subtitle = NULL; - _cutscene.subtitle_length_warning = 0; - _cutscene.subtitle_list = NULL; - _cutscene.subtitle_index = 0; + _cutscene.raiser_entity = 0; _cutscene.fadeout = 0; + _cutscene.skipped = 0; _cutscene.fadeout_start = 0.0f; } @@ -111,18 +110,18 @@ NOT_IMPLEMENTED: vg_fatal_exit(); } -static void _cutscene_get_strip_asoc( ms_strip *strip, - struct cs_asoc *out_asoc ) +static void _cutscene_get_strip_asoc( ms_strip *strip, struct cs_asoc *out_asoc ) { - if( strip->instance_id == 0xffffffff ) + VG_ASSERT( strip->mode & k_ms_strip_mode_animation ); + if( strip->strip.instance_id == 0xffffffff ) { out_asoc->orig_data = NULL;// &_cutscene.meta; - out_asoc->entity_type = mdl_entity_id_type( strip->object_id ); - out_asoc->entity_index = mdl_entity_id_id( strip->object_id ); + out_asoc->entity_type = mdl_entity_id_type( strip->strip.object_id ); + out_asoc->entity_index = mdl_entity_id_id( strip->strip.object_id ); out_asoc->override = NULL; } else - _cutscene_override_asoc( strip->instance_id, strip->object_id, out_asoc ); + _cutscene_override_asoc( strip->strip.instance_id, strip->strip.object_id, out_asoc ); } static void sync_cutscene_loaded( void *userdata ) @@ -284,16 +283,20 @@ static void cutscene_load_thread( vg_async_task *task ) vg_async_call( &vg.main_tasks, sync_cutscene_loaded, NULL ); } -void _cutscene_load_and_play( const char *path, const cs_subtitle *subtitles, bool freeze_player ) +void _cutscene_load_and_play( const char *path, bool freeze_player, u32 raiser_entity ) { - VG_ASSERT( _cutscene.state == k_cutscene_state_none ); + if( _cutscene.state != k_cutscene_state_none ) + { + vg_error( "Tried to play cutscene '%s' while already playing one.\n", path ); + return; + } + + _cutscene.raiser_entity = raiser_entity; for( u32 i=0; itransform[3] ); shader_model_character_view_uPv( cam->mtx.pv ); shader_model_character_view_uDepthMode( 0 ); + shader_model_character_view_uShadeless( 0 ); WORLD_BIND_LIGHT_BUFFERS_UB0_TEX234( world, model_character_view ); @@ -330,6 +334,7 @@ void cutscene_render_instance( struct cs_instance *ins, world_instance *world, v u32 armature_id = 0x00; u32 material_id = 0x00; + bool using_additive = 0; for( u32 i=0; imesh_count; i ++ ) { @@ -342,12 +347,9 @@ void cutscene_render_instance( struct cs_instance *ins, world_instance *world, v u32 sk_index = mdl_entity_id_id( armature_id ); struct cs_skeleton *skele = &ref->skeletons[ sk_index ]; - m4x3f *skinning_data = ins->skinning_data + skele->skinning_offset; - glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, - skele->sk.bone_count, - 0, - (const GLfloat *)skinning_data ); + glUniformMatrix4x3fv( _uniform_model_character_view_uTransforms, skele->sk.bone_count, 0, + (const GLfloat *)skinning_data ); } for( u32 j=0; jsubmesh_count; j ++ ) @@ -365,11 +367,40 @@ void cutscene_render_instance( struct cs_instance *ins, world_instance *world, v mdl_texture *tex = &mdl->textures[ props->tex_diffuse-1 ]; glBindTexture( GL_TEXTURE_2D, tex->glname ); + + if( props->render_flags & k_material_render_additive ) + { + using_additive = 1; + glDepthMask(GL_FALSE); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + glBlendEquation(GL_FUNC_ADD); + glDisable( GL_CULL_FACE ); + shader_model_character_view_uShadeless( 1 ); + } + else + { + if( using_additive ) + { + using_additive = 0; + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + glEnable( GL_CULL_FACE ); + shader_model_character_view_uShadeless( 0 ); + } + } } mdl_draw_submesh( sm ); } } + + if( using_additive ) + { + shader_model_character_view_uShadeless( 0 ); + glDepthMask(GL_TRUE); + glDisable(GL_BLEND); + } } #define CS_LOCATION 0 @@ -382,11 +413,13 @@ struct cs_link_info u32 semantic_type; }; -static bool link_internal_datapath( struct cs_asoc *asoc, const char *datapath, - struct cs_link_info *out_link ) +static bool link_internal_datapath( struct cs_asoc *asoc, const char *datapath, struct cs_link_info *out_link ) { - VG_ASSERT( asoc->entity_type == k_ent_camera ); - + if( asoc->entity_type != k_ent_camera ) + { + vg_warn( "Failed link %d#%d:'%s'\n", asoc->entity_type, asoc->entity_index, datapath ); + VG_ASSERT( 0 ); + } ent_camera *cam = af_arritm( &_cutscene.meta.cameras, asoc->entity_index ); struct @@ -468,7 +501,7 @@ void cutscene_update( f32 delta ) _cutscene.state = k_cutscene_state_none; _cutscene.marker_this_frame = NULL; _cutscene.subtitle = NULL; - _cutscene.subtitle_length_warning = 0; + _cutscene.raiser_entity = 0; return; } @@ -486,7 +519,7 @@ void cutscene_update( f32 delta ) { struct cs_sampler *si = &_cutscene.samplers[i]; - if( frame > (si->strip->offset + si->strip->length) ) + if( frame > (si->strip->offset + si->strip->strip.length) ) move = 1; else { @@ -509,78 +542,35 @@ void cutscene_update( f32 delta ) if( frame < strip->offset ) break; - if( frame > strip->offset + strip->length ) - { - vg_warn( "Skipping?\n" ); - _cutscene.strip ++; - continue; - } - - if( strip->data_mode == 2 ) + if( strip->mode & k_ms_strip_mode_animation ) { - if( strip->object_id ) + if( frame > strip->offset + strip->strip.length ) { - struct cs_asoc asoc; - _cutscene_get_strip_asoc( strip, &asoc ); - - VG_ASSERT( asoc.entity_type == k_ent_camera ); - ent_camera *cam = af_arritm( &_cutscene.meta.cameras, asoc.entity_index ); - - _cutscene.active_camera = cam; + vg_warn( "Skipping?\n" ); + _cutscene.strip ++; + continue; } - //else - // _cutscene.active_camera = NULL; - const char *marker = af_str( &_cutscene.meta.af, strip->pstr_name ); - vg_info( "Cutscene marker: %s\n", marker ); - - bool absorbed = 0; - - if( vg_str_eq( marker, "$fadeout" ) ) - { - _cutscene.fadeout = 1; - _cutscene.fadeout_start = _cutscene.time; - absorbed = 1; - } - else if( _cutscene.subtitle_list ) + if( _cutscene.skipped == 2 ) { - const cs_subtitle *next = &_cutscene.subtitle_list[ _cutscene.subtitle_index ]; - - if( next->key ) - { - if( vg_str_eq( marker, next->key ) ) - { - _cutscene.subtitle = next->value; - _cutscene.subtitle_length_warning = 0; - _cutscene.subtitle_index ++; - absorbed = 1; - } - else if( vg_str_eq( marker, "$clear_subtitles" ) ) - { - _cutscene.subtitle = NULL; - _cutscene.subtitle_length_warning = 0; - absorbed = 1; - } - } + _cutscene.strip ++; + continue; } - if( !absorbed ) - _cutscene.marker_this_frame = marker; - } - else - { - if( strip->instance_id == 0xffffffff ) + if( strip->strip.instance_id == 0xffffffff ) { - vg_info( "+ Strip: '%s' entity: %u\n", af_str( &_cutscene.meta.af, strip->pstr_name ), strip->object_id ); + const char *strip_name = af_str( &_cutscene.meta.af, strip->strip.pstr_name ); + vg_info( "+ Strip: '%s' entity: %u\n", strip_name, strip->strip.object_id ); + /* internal link */ struct cs_asoc asoc; _cutscene_get_strip_asoc( strip, &asoc ); - if( strip->data_mode == 1 ) + if( strip->mode == k_ms_strip_mode_curves ) { - for( u32 j=0; jdata_count; j ++ ) + for( u32 j=0; jstrip.count; j ++ ) { - ms_track *track = af_arritm( &_cutscene.meta.tracks, strip->data_start + j ); + ms_track *track = af_arritm( &_cutscene.meta.tracks, strip->strip.start + j ); const char *datapath = af_str( &_cutscene.meta.af, track->pstr_datapath ); struct cs_link_info link; @@ -604,17 +594,12 @@ void cutscene_update( f32 delta ) else { /* external link */ - struct cs_instance *ins = &_cutscene.instances[ strip->instance_id ]; - + struct cs_instance *ins = &_cutscene.instances[ strip->strip.instance_id ]; struct cs_asoc asoc; _cutscene_get_strip_asoc( strip, &asoc ); VG_ASSERT( asoc.entity_type == 28 ); - if( strip->data_mode == 1 ) - { - VG_ASSERT(0); - } - else + if( strip->mode == k_ms_strip_mode_keyframes ) { VG_ASSERT( _cutscene.active_samplers < VG_ARRAY_LEN(_cutscene.samplers) ); @@ -627,6 +612,40 @@ void cutscene_update( f32 delta ) samp->skeleton.ref_sk = &skele->sk; samp->override = asoc.override; } + else + { + VG_ASSERT(0); + } + } + } + else + { + if( strip->mode == k_ms_strip_mode_camera ) + { + u32 type = mdl_entity_id_type( strip->camera.entity_id ), + index = mdl_entity_id_id( strip->camera.entity_id ); + VG_ASSERT( type == k_ent_camera ); + ent_camera *cam = af_arritm( &_cutscene.meta.cameras, index ); + _cutscene.active_camera = cam; + } + + if( strip->mode == k_ms_strip_mode_fadeout ) + { + _cutscene.fadeout = 1; + _cutscene.fadeout_start = _cutscene.time; + } + + if( strip->mode == k_ms_strip_mode_subtitle ) + { + // FIXME: COLOURS + _cutscene.subtitle = af_str( &_cutscene.meta.af, strip->subtitle.pstr_en ); + } + + if( strip->mode == k_ms_strip_mode_event ) + { + const char *str = af_str( &_cutscene.meta.af, strip->event.pstr_string ); + vg_info( "cutscene event: %s\n", str ); + _world_raise_event( _cutscene.raiser_entity, str ); } } @@ -634,17 +653,17 @@ void cutscene_update( f32 delta ) } /* sample da samplers */ - for( u32 i=0; i<_cutscene.active_samplers; i ++ ) + for( u32 i=0; i<_cutscene.active_samplers && (_cutscene.skipped != 2); i ++ ) { struct cs_sampler *samp = &_cutscene.samplers[ i ]; - if( samp->strip->data_mode == 0 ) + if( samp->strip->mode == k_ms_strip_mode_keyframes ) { struct skeleton_anim temp_anim = { .strip = samp->strip, .framerate = _cutscene.meta.info.framerate, - .keyframes_base = af_arritm( &_cutscene.meta.keyframes, samp->strip->data_start ) + .keyframes_base = af_arritm( &_cutscene.meta.keyframes, samp->strip->strip.start ) }; f32 t = _cutscene.time; @@ -673,7 +692,7 @@ void cutscene_update( f32 delta ) else { f32 scene_t = _cutscene.time * _cutscene.meta.info.framerate, - t = (f32)(scene_t - samp->strip->offset) + samp->strip->timing_offset; + t = (f32)(scene_t - samp->strip->offset) + samp->strip->strip.timing_offset; ms_curve_keyframe *kl = af_arritm( &_cutscene.meta.curves, samp->curves.track->keyframe_start + samp->curves.keyframe ), @@ -722,6 +741,14 @@ void cutscene_update( f32 delta ) if( scene_t >= end_t ) { + if( _cutscene.strip != af_arrcount(&_cutscene.meta.strips) ) + { + _cutscene.time = 9999999.9f; + _cutscene.skipped = 2; /* signal we can ignore animation strips, just want events for correctness */ + return; + } + _world_raise_event( _cutscene.raiser_entity, "end" ); + if( _cutscene.freeze_player ) localplayer.immobile = 0; @@ -784,7 +811,6 @@ void _cutscene_gui( ui_context *ctx ) ctx->font = &vgf_default_small; ctx->kern[1] = 16; ui_px scale = 2; - ui_rect box = { 0,0, 1000, 80*2 }; ui_rect_center( (ui_rect){0,0,vg.window_x,vg.window_y}, box ); box[1] = vg.window_y - (box[3] + 8); @@ -825,19 +851,7 @@ void _cutscene_gui( ui_context *ctx ) ui_fill( ctx, background_rect, ui_opacity( GUI_COL_DARK, 0.75f ) ); y += (ctx->font->sy)*scale + 16; - - if( !_cutscene.subtitle_length_warning && (length > 50) ) - { - vg_warn( "Subtitle text too long; '%s'\nLine limit 50chs, line was: %u\n", _cutscene.subtitle, length ); - _cutscene.subtitle_length_warning = 1; - } length = 0; - - if( !_cutscene.subtitle_length_warning && (lines == 2) && (c != '\0') ) - { - vg_warn( "Subtitle contains more than 2 lines; '%s'\n", _cutscene.subtitle ); - _cutscene.subtitle_length_warning = 1; - } lines ++; } @@ -899,7 +913,7 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane { ms_strip *strip = af_arritm(&_cutscene.meta.strips, i ); - if( strip->data_mode == 2 ) + if( !(strip->mode & k_ms_strip_mode_animation) ) { ui_rect box = { root[0]+strip->offset, root[1], 1, panel_r[3]-16 }; ui_fill( ctx, box, 0xff00ff00 ); @@ -909,7 +923,14 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane box[3] = 16; if( ui_clip( panel_r, box, box ) ) - ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), 1, k_ui_align_middle_left, 0 ); + { + if( strip->mode == k_ms_strip_mode_camera ) + ui_text( ctx, box, "Camera", 1, k_ui_align_middle_left, 0 ); + if( strip->mode == k_ms_strip_mode_subtitle ) + ui_text( ctx, box, "\"", 1, k_ui_align_middle_left, 0 ); + if( strip->mode == k_ms_strip_mode_fadeout ) + ui_text( ctx, box, "\\", 1, k_ui_align_middle_left, 0 ); + } continue; } @@ -917,7 +938,7 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane for( u32 k=0; koffset + usage[k]->length < strip->offset ) + if( usage[k]->offset + usage[k]->strip.length < strip->offset ) usage[k] = NULL; if( !usage[k] ) @@ -928,16 +949,15 @@ static void cb_cutscene_view( ui_context *ctx, ui_rect rect, struct vg_magi_pane } } - ui_rect box = { strip->offset, layer*32, strip->length, 30 }; + ui_rect box = { strip->offset, layer*32, strip->strip.length, 30 }; box[0] += root[0]; box[1] += root[1]; if( ui_clip( panel_r, box, box ) ) { - u32 colour = af_str_hash( &_cutscene.meta.af, strip->pstr_name ); - + u32 colour = af_str_hash( &_cutscene.meta.af, strip->strip.pstr_name ); ui_fill( ctx, box, colour | 0xff000000 ); - ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->pstr_name ), 1, k_ui_align_middle_center, 0 ); + ui_text( ctx, box, af_str( &_cutscene.meta.af, strip->strip.pstr_name ), 1, k_ui_align_middle_center, 0 ); } } diff --git a/src/metascene.h b/src/metascene.h index 7419468..0b157b6 100644 --- a/src/metascene.h +++ b/src/metascene.h @@ -52,18 +52,54 @@ struct ms_override mdl_transform transform; }; +enum ms_strip_mode +{ + k_ms_strip_mode_keyframes = 0x1, + k_ms_strip_mode_curves = 0x2, + k_ms_strip_mode_animation = 0x1|0x2, + + k_ms_strip_mode_camera = 0x10, + k_ms_strip_mode_event = 0x20, + k_ms_strip_mode_subtitle = 0x40, + k_ms_strip_mode_fadeout = 0x80, +}; + struct ms_strip { - u32 data_start, - data_count, - data_mode, - offset, - length, - pstr_name, - pstr_internal_name, - instance_id, - object_id; - f32 timing_offset; + u8 mode; + u32 offset; + + union + { + struct + { + u32 start, count, length, + pstr_name, + pstr_internal_name, + instance_id, object_id; + f32 timing_offset; + } + strip; + + struct + { + u32 entity_id; + } + camera; + + struct + { + u32 pstr_en, res0, res1, res2; + u8 character; + } + subtitle; + + struct + { + u32 pstr_string; + } + event; + }; }; struct ms_track @@ -86,6 +122,11 @@ struct cs_instance m4x3f *skinning_data; }; +struct cs_subtitle +{ + const char *key, *value; +}; + #include "skeleton.h" struct _cutscene @@ -159,19 +200,16 @@ struct _cutscene f32 time; bool fadeout; + u8 skipped; f32 fadeout_start, fadeout_cooldown; const char *marker_this_frame; const char *subtitle; - struct cs_subtitle - { - const char *key, *value; - } - const *subtitle_list; - u32 subtitle_index; bool subtitle_length_warning; bool freeze_player; + + u32 raiser_entity; } extern _cutscene; @@ -179,11 +217,10 @@ void metascene_load( ms_context *ms, const char *path, void *alloc ); void cutscene_init(void); void cutscene_render( world_instance *world, vg_camera *cam ); void cutscene_render_fadeout(void); -void _cutscene_load_and_play( const char *path, const cs_subtitle *subtitles, bool freeze_player ); +void _cutscene_load_and_play( const char *path, bool freeze_player, u32 raiser_entity ); void _cutscene_unload(void); void cutscene_update( f32 delta ); ent_camera *_cutscene_active_camera(void); void _cutscene_gui( ui_context *ctx ); -void _cutscene_set_subtitle_list( const cs_subtitle *subtitles ); struct cs_instance *_cutscene_get_first_model_instance( const char *mdl_name ); diff --git a/src/model.c b/src/model.c index f5a5370..961f80a 100644 --- a/src/model.c +++ b/src/model.c @@ -85,6 +85,7 @@ void *mdl_shader_standard( vg_msg *msg, void *alloc ) { struct shader_props_standard *props = vg_linear_alloc( alloc, sizeof(struct shader_props_standard) ); vg_msg_getkvintg( msg, "tex_diffuse", k_vg_msg_u32, &props->tex_diffuse, NULL ); + vg_msg_getkvintg( msg, "render_flags", k_vg_msg_u32, &props->render_flags, NULL ); return props; } diff --git a/src/player_glide.c b/src/player_glide.c index b132ea7..e7876ed 100644 --- a/src/player_glide.c +++ b/src/player_glide.c @@ -484,12 +484,12 @@ void player_glide_transition(void) localplayer.subsystem = k_player_subsystem_glide; localplayer.have_glider = 0; world_routes_clear( &_world.main ); - v3_copy( localplayer.rb.co, player_glide.rb.co ); f32 dir = v3_dot( localplayer.rb.v, localplayer.rb.to_world[2] ); - if( dir > 0.0f ){ + if( dir > 0.0f ) + { v4f qyaw; q_axis_angle( qyaw, (v3f){0,1,0}, VG_TAUf*0.5f ); q_mul( qyaw, localplayer.rb.q, player_glide.rb.q ); diff --git a/src/player_render.c b/src/player_render.c index 4393b12..904b77f 100644 --- a/src/player_render.c +++ b/src/player_render.c @@ -30,13 +30,14 @@ void player_get_anim( skeleton_anim *out_anim, const char *name ) for( u32 i=0; istrips ); i ++ ) { ms_strip *strip = af_arritm( &ms->strips, i ); - - if( af_str_eq( &ms->af, strip->pstr_name, name, hash ) ) + if( strip->mode != k_ms_strip_mode_keyframes ) + continue; + + if( af_str_eq( &ms->af, strip->strip.pstr_name, name, hash ) ) { out_anim->strip = strip; out_anim->framerate = localplayer.animations.info.framerate; - out_anim->keyframes_base = - af_arritm( &localplayer.animations.keyframes, strip->data_start ); + out_anim->keyframes_base = af_arritm( &localplayer.animations.keyframes, strip->strip.start ); return; } } @@ -567,6 +568,7 @@ void render_playermodel( vg_camera *cam, world_instance *world, shader_model_character_view_uCamera( cam->transform[3] ); shader_model_character_view_uPv( cam->mtx.pv ); shader_model_character_view_uDepthMode( depth_compare ); + shader_model_character_view_uShadeless( 0 ); if( depth_compare ) { depth_compare_bind( diff --git a/src/player_skate.c b/src/player_skate.c index 569ef94..53e6cf8 100644 --- a/src/player_skate.c +++ b/src/player_skate.c @@ -1262,8 +1262,8 @@ void player__skate_pre_update(void){ { localplayer.subsystem = k_player_subsystem_walk; - if( (state->activity <= k_skate_activity_air_to_grind) && - localplayer.have_glider ){ + if( (state->activity <= k_skate_activity_air_to_grind) && localplayer.have_glider ) + { player_glide_transition(); return; } @@ -3378,7 +3378,7 @@ void player__skate_pose( void *_animator, player_pose *pose ){ v3_copy( world_view[3], pose->root_co ); f32 t = animator->handplant_t, - frames = anim->strip->length-1, + frames = anim->strip->strip.length-1, length = animator->activity == k_skate_activity_handplant? frames / anim->framerate: 999999, diff --git a/src/player_walk.c b/src/player_walk.c index 270f392..ff43934 100644 --- a/src/player_walk.c +++ b/src/player_walk.c @@ -248,7 +248,7 @@ static int player_walk_scan_for_drop_in(void){ static bool player__preupdate_anim( struct skeleton_anim *anim, f32 *t, f32 speed ) { - f32 length = (f32)(anim->strip->length-1) / anim->framerate; + f32 length = (f32)(anim->strip->strip.length-1) / anim->framerate; *t += (vg.time_delta * speed) / length; if( *t >= 1.0f ) return 1; else return 0; @@ -856,7 +856,7 @@ static void player_walk_animate_drop_in(void) struct player_walk_animator *animator = &w->animator; struct skeleton_anim *anim = &w->anim_drop_in; - f32 length = (f32)(anim->strip->length-1) / anim->framerate, + f32 length = (f32)(anim->strip->strip.length-1) / anim->framerate, time = w->state.transition_t; f32 walk_yaw = vg_alerpf( w->state.drop_in_start_angle, @@ -940,8 +940,8 @@ void player__walk_animate(void){ } if( animator->run > 0.025f ){ - f32 walk_norm = 30.0f/(float)w->anim_walk.strip->length, - run_norm = 30.0f/(float)w->anim_run.strip->length, + f32 walk_norm = 30.0f/(float)w->anim_walk.strip->strip.length, + run_norm = 30.0f/(float)w->anim_run.strip->strip.length, l; if( animator->run <= k_walkspeed ) @@ -981,8 +981,7 @@ void player__walk_animate(void){ } } -static void player_walk_pose_sit( struct player_walk_animator *animator, - player_pose *pose ) +static void player_walk_pose_sit( struct player_walk_animator *animator, player_pose *pose ) { ms_keyframe bpose[32]; @@ -990,7 +989,7 @@ static void player_walk_pose_sit( struct player_walk_animator *animator, struct skeleton *sk = &localplayer.skeleton; f32 t = animator->transition_t, - st = t * ((f32)(w->anim_sit.strip->length-1)/30.0f); + st = t * ((f32)(w->anim_sit.strip->strip.length-1)/30.0f); skeleton_sample_anim( sk, &w->anim_sit, st, bpose ); v4f qy,qp; @@ -1026,7 +1025,7 @@ static void player_walk_pose_transition( struct player_walk *w = &player_walk; struct skeleton *sk = &localplayer.skeleton; - f32 length = (f32)(anim->strip->length-1) / anim->framerate, + f32 length = (f32)(anim->strip->strip.length-1) / anim->framerate, t = animator->transition_t * length, blend = 1.0f; @@ -1066,8 +1065,8 @@ void player__walk_pose( void *_animator, player_pose *pose ){ pose->board.lean = 0.0f; pose->type = k_player_pose_type_ik; - float walk_norm = (float)w->anim_walk.strip->length/30.0f, - run_norm = (float)w->anim_run.strip->length/30.0f, + float walk_norm = (float)w->anim_walk.strip->strip.length/30.0f, + run_norm = (float)w->anim_run.strip->strip.length/30.0f, t = animator->walk_timer; /* walk/run */ diff --git a/src/scripts/city.c b/src/scripts/city.c index 24b3d16..385a4de 100644 --- a/src/scripts/city.c +++ b/src/scripts/city.c @@ -1,6 +1,7 @@ static bool _skaterift_script_city( ent_script_event *event ) { - if( on_nugget_once( event, "ch3s1_view" ) ) +#if 0 + if( on_atom_once( event, "ch3s1_view" ) ) { static const struct cs_subtitle EN[] = { @@ -18,8 +19,8 @@ static bool _skaterift_script_city( ent_script_event *event ) // REgion complete if( on_function_trigger( event, 5 ) ) { - if( _skaterift_script_nugget_status( "ch3s2_view" ) == 0 ) - _skaterift_script_nugget_set( "ch3s2_view", 2 ); + if( _skaterift_atom_status( "ch3s2_view" ) == 0 ) + _skaterift_atom_set( "ch3s2_view", 2 ); } // On activate finale challenge @@ -30,31 +31,33 @@ static bool _skaterift_script_city( ent_script_event *event ) // On complete finale challenge if( on_function_trigger( event, 8 ) ) { - _skaterift_script_nugget_set( "city_finale", 3 ); - _skaterift_script_nugget_set( "ch3s3_view", 2 ); + _skaterift_atom_set( "city_finale", 3 ); + if( _skaterift_atom_status( "ch3s3_view" ) == 0 ) + _skaterift_atom_set( "ch3s3_view", 2 ); } u64 status; - if( on_nugget_changed( event, "city_finale", &status ) ) + if( on_atom_changed( event, "city_finale", &status ) ) { _ent_list_set_visible( _ent_list_get_aliased( "finale" ), status > 0 ); _ent_list_set_visible( _ent_list_get_aliased( "finale_marker" ), status == 2 ); } - +#endif return 1; } static bool _skaterift_script_ch3s2( ent_script_event *event ) { +#if 0 u64 status; - if( on_nugget_changed( event, "ch3s2_view", &status ) ) + if( on_atom_changed( event, "ch3s2_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch3s2_view" ) ) + if( on_atom_once( event, "ch3s2_view" ) ) { - _skaterift_script_nugget_set( "city_finale", 2 ); + _skaterift_atom_set( "city_finale", 2 ); static const struct cs_subtitle EN[] = { @@ -68,6 +71,7 @@ static bool _skaterift_script_ch3s2( ent_script_event *event ) _cutscene_load_and_play( "metascenes/ch3s2.ms", EN, 1 ); } } +#endif return 1; } @@ -78,6 +82,7 @@ struct script_ch3s3_waiter static bool _skaterift_script_ch3s3( ent_script_event *event ) { +#if 0 if( event->type == k_escript_event_allocate ) { struct script_event_allocate *event_info = event->info; @@ -89,14 +94,14 @@ static bool _skaterift_script_ch3s3( ent_script_event *event ) struct script_ch1s6a_waiter *waiter = event->userdata; u64 status; - if( on_nugget_changed( event, "ch3s3_view", &status ) ) + if( on_atom_changed( event, "ch3s3_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch3s3_view" ) ) + if( on_atom_once( event, "ch3s3_view" ) ) { - _skaterift_script_nugget_set( "unlock_valley", 1 ); + _skaterift_atom_set( "unlock_valley", 1 ); static const struct cs_subtitle EN[] = { @@ -151,5 +156,6 @@ static bool _skaterift_script_ch3s3( ent_script_event *event ) } } } +#endif return 1; } diff --git a/src/scripts/cutscene.c b/src/scripts/cutscene.c new file mode 100644 index 0000000..62dc14b --- /dev/null +++ b/src/scripts/cutscene.c @@ -0,0 +1,46 @@ +struct script_cutscene +{ + const char *path; + bool immobilize; +}; + +static bool _skaterift_script_cutscene( ent_script_event *event ) +{ + if( event->type == k_escript_event_allocate ) + { + struct script_event_allocate *event_info = event->info; + struct script_cutscene *cs = vg_linear_alloc( event_info->heap, sizeof(struct script_cutscene) ); + cs->path = NULL; + cs->immobilize = 1; + event_info->userdata = cs; + return 1; + } + + struct script_cutscene *cs = event->userdata; + + if( event->type == k_escript_event_world_event ) + { + struct script_event_world_io *inf = event->info; + world_instance *world = &_world.main; + + if( AF_STR_EQ( &world->meta.af, inf->event->pstr_recieve_event, "play" ) ) + { + _cutscene_load_and_play( cs->path, cs->immobilize, inf->event->recieve_entity_id ); + } + else if( AF_STR_EQ( &world->meta.af, inf->event->pstr_recieve_event, "immobilize" ) ) + { + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( inf->event->flags == k_ent_event_data_const_i32 ) + cs->immobilize = inf->event->data.const_i32; + else vg_error( "a300\n" ); + } + else if( AF_STR_EQ( &world->meta.af, inf->event->pstr_recieve_event, "path" ) ) + { + if( inf->event->flags == k_ent_event_data_const_string ) + cs->path = af_str( &world->meta.af, inf->event->data.const_pstr ); + else vg_error( "a300\n" ); + } + } + + return 1; +} diff --git a/src/scripts/explode.c b/src/scripts/explode.c new file mode 100644 index 0000000..cb8304e --- /dev/null +++ b/src/scripts/explode.c @@ -0,0 +1,47 @@ +static bool _skaterift_script_explode( ent_script_event *event ) +{ + if( event->type == k_escript_event_world_event ) + { + struct script_event_world_io *inf = event->info; + world_instance *world = &_world.main; + if( AF_STR_EQ( &world->meta.af, inf->event->pstr_recieve_event, "explode" ) ) + { + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( inf->event->flags & k_ent_event_data_const_entity_id ) + { + u32 breaklist_id = inf->event->data.const_entity_id; + if( mdl_entity_id_type( breaklist_id ) != k_ent_list ) + { + vg_error( "explode called with not a list\n" ); + return 0; + } + + ent_list *list = af_arritm( &world->ent_list, mdl_entity_id_id(breaklist_id) ); + _ent_list_set_visible( list, 0 ); + v3f where = {0,0,0}; + + struct ent_list_iter iter; + _ent_list_iter_start( &iter, list, 0 ); + + while( _ent_list_iter( &iter ) ) + { + if( iter.type == k_ent_marker ) + { + ent_marker *marker = af_arritm( &world->ent_marker, iter.index ); + for( u32 j=0; j<80; j ++ ) + { + particle_spawn_cone( &particles_env, marker->transform.co, + (v3f){0,1,0}, 1.2f, vg_randf64(&vg.rand) * 8.5f, 5.0f, 0xff76b6ea ); + } + v3_copy( marker->transform.co, where ); + } + } + vg_audio_lock(); + vg_audio_oneshot_3d( &audio_wood_break, where, 100.0f, 1.0f, 0, 0 ); + vg_audio_unlock(); + } + } + } + + return 1; +} diff --git a/src/scripts/generic.c b/src/scripts/generic.c index 97c008c..9b5bf47 100644 --- a/src/scripts/generic.c +++ b/src/scripts/generic.c @@ -17,7 +17,7 @@ static bool _skaterift_script_board_maker_unlock( ent_script_event *event ) } u64 status; - if( on_nugget_changed( event, "board_maker_unlock", &status ) ) + if( on_atom_changed( event, "board_maker_unlock", &status ) ) { struct board_maker_unlock_waiter *waiter = event->userdata; waiter->changed = 1; diff --git a/src/scripts/hub.c b/src/scripts/hub.c index 690e76c..5f9dfbe 100644 --- a/src/scripts/hub.c +++ b/src/scripts/hub.c @@ -5,6 +5,7 @@ struct script_hub static bool _skaterift_script_hub( ent_script_event *event ) { +#if 0 if( event->type == k_escript_event_allocate ) { struct script_event_allocate *event_info = event->info; @@ -16,54 +17,79 @@ static bool _skaterift_script_hub( ent_script_event *event ) struct script_hub *script_hub = event->userdata; - /* small text box pop up, the welcome thing. */ - if( on_function_trigger( event, 0 ) ) + if( on_completion_changed(event) ) { - if( on_nugget_once( event, "hub_info_view" ) ) - menu_open( k_menu_page_impromptu_guide ); - } + u64 progress = _skaterift_atom_status( "story" ); - struct - { - const char *ms, *nugget, *view_nugget, *list; - } - blocks[] = - { - { "metascenes/unlock_mtzero.ms", "unlock_mtzero", "unlock_mtzero_view", "mtzero:locked" }, - { "metascenes/unlock_city.ms", "unlock_city", "unlock_city_view", "city:locked" }, - { "metascenes/unlock_valley.ms", "unlock_valley", "unlock_valley_view", "valley:locked" }, - }; + /* blockers + * ------------------------------------------------------------------------ */ + struct + { + const char *ms, *stage, *view_atom, *list_name; + bool unlocked; + } + blocks[] = + { + { "metascenes/unlock_mtzero.ms", "mz", "unlock_mtzero_view", "mtzero:locked" }, + { "metascenes/unlock_city.ms", "city", "unlock_city_view", "city:locked" }, + { "metascenes/unlock_valley.ms", "valley", "unlock_valley_view", "valley:locked" }, + }; - for( u32 i=0; i= _skaterift_atom_enum_index( "story", blocks[i].stage, ATOM_MAX ) ) + { + blocks[i].unlocked = 1; + _ent_list_set_visible( list, 0 ); + highest_index = i; + } + else + _ent_list_set_visible( list, 1 ); + } + + if( highest_index != -1 ) { - ent_list *list = _ent_list_get_aliased( blocks[i].list ); - if( status == 1 ) + ent_list *list = _ent_list_get_aliased( blocks[highest_index].list_name ); + if( on_atom_once( event, blocks[highest_index].view_atom ) ) { - if( on_nugget_once( event, blocks[i].view_nugget ) ) - { - _cutscene_load_and_play( blocks[i].ms, NULL, 1 ); - script_hub->break_list = list; - } - else - _ent_list_set_visible( list, 0 ); + _cutscene_load_and_play( blocks[highest_index].ms, NULL, 1 ); + _ent_list_set_visible( list, 1 ); + script_hub->break_list = list; } + else + _ent_list_set_visible( list, 0 ); + } + + /* spawns locked behind the boxes + * ------------------------------------------------------------------------ */ + world_instance *world = &_world.main; + u32 spawns_allowed = 0; + if( blocks[0].unlocked ) spawns_allowed |= k_ent_spawn_flag_group_1; + if( blocks[1].unlocked ) spawns_allowed |= k_ent_spawn_flag_group_2; + if( blocks[2].unlocked ) spawns_allowed |= k_ent_spawn_flag_group_3; + for( u32 i=0; ient_spawn); i++ ) + { + ent_spawn *spawn = af_arritm( &world->ent_spawn, i ); + bool allow = 0; + + if( spawn->flags == 0 ) allow = 1; + if( spawn->flags & spawns_allowed ) allow = 1; + + if( allow ) spawn->flags &= ~(u32)k_ent_spawn_flag_locked; + else spawn->flags |= k_ent_spawn_flag_locked; } } if( on_cutscene_marker( event, "$break" ) ) _explode_template_boom( script_hub->break_list ); - if( event->type == k_escript_event_nugget_changed ) + if( on_world_start( event ) ) { + // TODO: Move these into atoms? world_instance *world = &_world.main; - - bool unlock_mtzero = _skaterift_script_nugget_status( "unlock_mtzero" ), - unlock_city = _skaterift_script_nugget_status( "unlock_city" ), - unlock_valley = _skaterift_script_nugget_status( "unlock_valley" ); - for( u32 i=0; ient_prop ); i ++ ) { ent_prop *prop = af_arritm( &world->ent_prop, i ); @@ -84,47 +110,23 @@ static bool _skaterift_script_hub( ent_script_event *event ) if( skaterift.achievements & 0x8 ) prop->flags &= ~0x1; } - - u32 spawns_allowed = 0; - if( unlock_mtzero ) spawns_allowed |= k_ent_spawn_flag_group_1; - if( unlock_city ) spawns_allowed |= k_ent_spawn_flag_group_2; - if( unlock_valley ) spawns_allowed |= k_ent_spawn_flag_group_3; - - for( u32 i=0; ient_spawn); i++ ) - { - ent_spawn *spawn = af_arritm( &world->ent_spawn, i ); - - bool allow = 0; - - if( spawn->flags == 0 ) allow = 1; - if( spawn->flags & spawns_allowed ) allow = 1; - - if( allow ) spawn->flags &= ~(u32)k_ent_spawn_flag_locked; - else spawn->flags |= k_ent_spawn_flag_locked; - } - - return 1; } - u64 status; - if( on_nugget_changed( event, "board_maker_unlock", &status ) ) + /* gino helper board maker thing + * ------------------------------------------------------------------------ */ + if( event->type == k_escript_event_atom_changed ) { - ent_list *list = _ent_list_get_aliased( "gino_board_maker" ); bool visible = 0; - - if( status ) - { - u64 view = _skaterift_script_nugget_status( "board_maker_hub_view" ); - if( view == 0 ) + if( _skaterift_atom_status( "board_maker_unlock" ) ) + if( _skaterift_atom_status( "board_maker_hub_view" ) == 0 ) visible = 1; - } - _ent_list_set_visible( list, visible ); + _ent_list_set_visible( _ent_list_get_aliased( "gino_board_maker" ), visble ); } if( on_function_trigger( event, 5 ) ) { - _skaterift_script_nugget_set( "board_maker_hub_view", 1 ); + _skaterift_atom_set( "board_maker_hub_view", 1 ); // Hide just the notifier struct ent_list_iter iter; @@ -136,6 +138,6 @@ static bool _skaterift_script_hub( ent_script_event *event ) marker->flags |= (u32)k_ent_marker_flag_hidden; } } - +#endif return 0; } diff --git a/src/scripts/mtzero.c b/src/scripts/mtzero.c index 3efeb4f..ef728d7 100644 --- a/src/scripts/mtzero.c +++ b/src/scripts/mtzero.c @@ -1,7 +1,8 @@ static bool _skaterift_script_mtzero( ent_script_event *event ) { +#if 0 /* intro movie */ - if( on_nugget_once( event, "ch2s1_view" ) ) + if( on_atom_once( event, "ch2s1_view" ) ) { static const struct cs_subtitle EN[] = { @@ -40,9 +41,10 @@ static bool _skaterift_script_mtzero( ent_script_event *event ) } if( requirements_met ) - if( _skaterift_script_nugget_status( "ch2s3_view" ) == 0 ) - _skaterift_script_nugget_set( "ch2s3_view", 2 ); + if( _skaterift_atom_status( "ch2s3_view" ) == 0 ) + _skaterift_atom_set( "ch2s3_view", 2 ); } +#endif return 1; } @@ -54,9 +56,10 @@ static bool _skaterift_script_mtzero_after( ent_script_event *event ) static bool _skaterift_script_ch2s2( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch2s2_view" ) ) + if( on_atom_once( event, "ch2s2_view" ) ) { static const struct cs_subtitle EN[] = { @@ -80,16 +83,18 @@ static bool _skaterift_script_ch2s2( ent_script_event *event ) } } u64 status; - if( on_nugget_changed( event, "ch2s2_view", &status ) ) + if( on_atom_changed( event, "ch2s2_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 0 ); +#endif return 1; } static bool _skaterift_script_ch2s3( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch2s3_view" ) ) + if( on_atom_once( event, "ch2s3_view" ) ) { static const struct cs_subtitle EN[] = { @@ -177,33 +182,37 @@ static bool _skaterift_script_ch2s3( ent_script_event *event ) } } u64 status; - if( on_nugget_changed( event, "ch2s3_view", &status ) ) + if( on_atom_changed( event, "ch2s3_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); +#endif return 1; } static bool _skaterift_script_ch2s5_before( ent_script_event *event ) { +#if 0 u64 status; - if( on_nugget_changed( event, "ch2s5_view", &status ) ) + if( on_atom_changed( event, "ch2s5_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); if( on_function_trigger( event, 0 ) ) { - _skaterift_script_nugget_set( "ch2s5_view", 3 ); + _skaterift_atom_set( "ch2s5_view", 3 ); skaterift_load_world_command( 1, (const char *[]){ "reload" } ); } +#endif return 1; } static bool _skaterift_script_ch2s5_after( ent_script_event *event ) { +#if 0 u64 status; - if( on_nugget_changed( event, "ch2s5_view", &status ) ) + if( on_atom_changed( event, "ch2s5_view", &status ) ) { if( status == 3 ) { - _skaterift_script_nugget_set( "ch2s5_view", 1 ); + _skaterift_atom_set( "ch2s5_view", 1 ); static const struct cs_subtitle EN[] = { { "m1", KCOL_MIKE "Hi mate, hows it goin?" }, @@ -221,6 +230,7 @@ static bool _skaterift_script_ch2s5_after( ent_script_event *event ) _cutscene_load_and_play( "metascenes/ch2s5.ms", EN, 1 ); } } +#endif return 1; } @@ -231,6 +241,7 @@ struct script_ch2s6_waiter static bool _skaterift_script_ch2s6( ent_script_event *event ) { +#if 0 if( event->type == k_escript_event_allocate ) { struct script_event_allocate *event_info = event->info; @@ -242,17 +253,17 @@ static bool _skaterift_script_ch2s6( ent_script_event *event ) struct script_ch2s6_waiter *waiter = event->userdata; u64 status; - if( on_nugget_changed( event, "ch2s6_view", &status ) ) + if( on_atom_changed( event, "ch2s6_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); // TODOX1: THERE ARE NO UNLOCK CONDITIONS FOR THIS YET! if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch2s6_view" ) ) + if( on_atom_once( event, "ch2s6_view" ) ) { - _skaterift_script_nugget_set( "unlock_city", 1 ); - _skaterift_script_nugget_set( "ch2s6_view", 1 ); + _skaterift_atom_set( "unlock_city", 1 ); + _skaterift_atom_set( "ch2s6_view", 1 ); static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Ello guys" }, @@ -287,16 +298,18 @@ static bool _skaterift_script_ch2s6( ent_script_event *event ) } } } +#endif return 1; } static bool _skaterift_script_ch2e1( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch2e1_view" ) ) + if( on_atom_once( event, "ch2e1_view" ) ) { - _skaterift_script_nugget_set( "board_maker_unlock", 1 ); + _skaterift_atom_set( "board_maker_unlock", 1 ); static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Hey bird I'm just working on some boards here." }, @@ -310,8 +323,9 @@ static bool _skaterift_script_ch2e1( ent_script_event *event ) } } u64 status; - if( on_nugget_changed( event, "ch2e1_view", &status ) ) + if( on_atom_changed( event, "ch2e1_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 2 ); +#endif return 1; } @@ -324,6 +338,7 @@ struct script_ch2s4_waiter static bool _skaterift_script_battery_jump( ent_script_event *event ) { +#if 0 if( event->type == k_escript_event_allocate ) { struct script_event_allocate *event_info = event->info; @@ -340,16 +355,16 @@ static bool _skaterift_script_battery_jump( ent_script_event *event ) if( on_function_trigger( event, 2 ) ) { - if( on_nugget_once( event, "ch2s4_view" ) ) + if( on_atom_once( event, "ch2s4_view" ) ) { - _skaterift_script_nugget_set( "ch2s5_view", 2 ); + _skaterift_atom_set( "ch2s5_view", 2 ); waiter->go = 1; } } /* viewed ch2s3 means we allowing this challenge now */ u64 status; - if( on_nugget_changed( event, "ch2s3_view", &status ) ) + if( on_atom_changed( event, "ch2s3_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 1 ); if( event->type == k_escript_event_update ) @@ -385,7 +400,7 @@ static bool _skaterift_script_battery_jump( ent_script_event *event ) if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "battery_jump_view" ) ) + if( on_atom_once( event, "battery_jump_view" ) ) { _cutscene_load_and_play( "metascenes/battery_intro.ms", NULL, 1 ); waiter->break_list = _ent_list_get_aliased( "battery:locked" ); @@ -395,8 +410,8 @@ static bool _skaterift_script_battery_jump( ent_script_event *event ) if( event->type == k_escript_event_world_start ) { _ent_list_set_visible( _ent_list_get_aliased( "battery:locked" ), - _skaterift_script_nugget_status( "battery_jump_view" ) == 0 ); + _skaterift_atom_status( "battery_jump_view" ) == 0 ); } - +#endif return 1; } diff --git a/src/scripts/tutorial_island.c b/src/scripts/tutorial_island.c index c8945f3..740fcf6 100644 --- a/src/scripts/tutorial_island.c +++ b/src/scripts/tutorial_island.c @@ -7,6 +7,24 @@ struct script_volcano static bool _skaterift_script_tutorial_island( ent_script_event *event ) { +#if 0 + if( on_advancement(event) ) + { + ent_list *region0_challenges = _ent_list_get_aliased( "region0" ); + bool region0_is_target = 0; + + u64 progress = _skaterift_atom_status( "story" ); + if( progress == _skaterift_atom_enum_index( "story", "volc" ) ) + { + if( _ent_list_check_completed( region0_challenges ) ) + region0_is_target = 0; + else + region0_is_target = 1; + } + + _ent_list_set_as_targets( region0_challenges, region0_is_target ); + } + if( event->type == k_escript_event_allocate ) { struct script_event_allocate *event_info = event->info; @@ -20,36 +38,37 @@ static bool _skaterift_script_tutorial_island( ent_script_event *event ) struct script_volcano *script_volcano = event->userdata; - if( on_cutscene_marker( event, "$break" ) ) - _explode_template_boom( script_volcano->break_list ); - - /* intro movie */ - if( on_nugget_once( event, "ch1s2_view" ) ) - { - static const struct cs_subtitle EN[] = { - { "john_1", KCOL_JOHN "Well, here we are. Home." }, - { "john_2", KCOL_JOHN "I mean, halfway home." }, - { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, - { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, - { NULL, NULL }, - }; - _cutscene_load_and_play( "metascenes/ch1s2.ms", EN, 1 ); - } - - /* all tasks completed (called from the region entity) */ - if( on_function_trigger( event, 2 ) ) + if( on_completion_changed(event) ) { - ent_list *list = _ent_list_get_aliased( "docks:locked" ); - if( on_nugget_once( event, "unlock_docks_view" ) ) + u64 progress = _skaterift_atom_status( "story" ); + if( progress == _skaterift_atom_enum_index( "story", "volc" ) ) { - vg_low( "waiting for stopped...\n" ); - _skaterift_script_nugget_set( "ch1s6a_view", 2 ); - script_volcano->docks_wait = 1; + static const struct cs_subtitle EN[] = { + { "john_1", KCOL_JOHN "Well, here we are. Home." }, + { "john_2", KCOL_JOHN "I mean, halfway home." }, + { "john_3", KCOL_JOHN "Obviously you've forgotten quite a bit, so we'll stop off here" }, + { "john_4", KCOL_JOHN "and I'll teach you some stuff again" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch1s2.ms", EN, 1 ); + _skaterift_atom_set_enum( "story", "volc:tutorial" ); + } + else if( progress == _skaterift_atom_enum_index( "story", "volc:tutorial" ) ) + { + if( _ent_list_check_completed( _ent_list_get_aliased( "region0" ) ) ) + { + _skaterift_atom_set_enum( "story", "volc:leaving" ); + vg_low( "waiting for stopped...\n" ); + script_volcano->docks_wait = 1; + } + } + else if( progress == _skaterift_atom_enum_index( "story", "volc:leaving" ) ) + { + _ent_list_set_visible( _ent_list_get_aliased( "docks:locked" ), 0 ); } - else - _ent_list_set_visible( list, 0 ); } + /* waiting for player to stop to blow up the docks */ if( event->type == k_escript_event_update ) { if( script_volcano->docks_wait ) @@ -72,14 +91,19 @@ static bool _skaterift_script_tutorial_island( ent_script_event *event ) } } + if( on_cutscene_marker( event, "$break" ) ) + _explode_template_boom( script_volcano->break_list ); +#endif + return 1; } static bool _skaterift_script_ch1s3( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 1 ) ) { - if( on_nugget_once( event, "ch1s3_view" ) ) + if( on_atom_once( event, "ch1s3_view" ) ) { static const struct cs_subtitle EN[] = { { "john_1", KCOL_JOHN "Alright so, fliptricks." }, @@ -95,7 +119,7 @@ static bool _skaterift_script_ch1s3( ent_script_event *event ) if( on_function_trigger( event, 2 ) ) { - if( on_nugget_once( event, "ch1s3b_view" ) ) + if( on_atom_once( event, "ch1s3b_view" ) ) { static const struct cs_subtitle EN[] = { { "john_1", KCOL_JOHN "That is it mate!" }, @@ -107,18 +131,26 @@ static bool _skaterift_script_ch1s3( ent_script_event *event ) } } + u64 progress; + if( on_atom_changed( event, "story", &progress ) ) + { + bool visible = progress == _skaterift_atom_enum_index( "story", "volc:tutorial" ); + _ent_list_set_visible( event->entity_list, visible ); + } + u64 viewed; - if( on_nugget_changed( event, "ch1s3_view", &viewed ) ) + if( on_atom_changed( event, "ch1s3_view", &viewed ) ) _ent_list_set_visible( event->entity_list, !viewed ); - +#endif return 1; } static bool _skaterift_script_ch1s4( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch1s4_view" ) ) + if( on_atom_once( event, "ch1s4_view" ) ) { static const struct cs_subtitle EN[] = { { "john_1", KCOL_JOHN "Remember these courses we were setting up?" }, @@ -134,17 +166,19 @@ static bool _skaterift_script_ch1s4( ent_script_event *event ) } u64 status; - if( on_nugget_changed( event, "ch1s4_view", &status ) ) + if( on_atom_changed( event, "ch1s4_view", &status ) ) _ent_list_set_visible( event->entity_list, status == 0 ); +#endif return 1; } static bool _skaterift_script_ch1s5( ent_script_event *event ) { +#if 0 if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch1s5_view" ) ) + if( on_atom_once( event, "ch1s5_view" ) ) { static const struct cs_subtitle EN[] = { /* 50ch| set cc=70 |################################################| */ @@ -189,37 +223,25 @@ static bool _skaterift_script_ch1s5( ent_script_event *event ) _cutscene_load_and_play( "metascenes/ch1s5.ms", EN, 1 ); } } +#endif return 1; } -struct script_ch1s6a_waiter -{ - bool go; -}; - static bool _skaterift_script_ch1s6a( ent_script_event *event ) { - if( event->type == k_escript_event_allocate ) +#if 0 + u64 progress; + if( on_atom_changed( event, "story", &progress ) ) { - struct script_event_allocate *event_info = event->info; - struct script_ch1s6a_waiter *waiter = vg_linear_alloc( event_info->heap, sizeof(struct script_ch1s6a_waiter) ); - waiter->go = 0; - event_info->userdata = waiter; - return 1; + bool visible = progress == _skaterift_atom_enum_index( "story", "volc:leaving" ); + _ent_list_set_visible( event->entity_list, visible ); } - struct script_ch1s6a_waiter *waiter = event->userdata; - u64 status; - if( on_nugget_changed( event, "ch1s6a_view", &status ) ) - _ent_list_set_visible( event->entity_list, status == 2 ); - if( on_function_trigger( event, 0 ) ) { - if( on_nugget_once( event, "ch1s6a_view" ) ) + _skaterift_atom_set_enum( "story", "mz" ); + static const struct cs_subtitle EN[] = { - _skaterift_script_nugget_set( "unlock_mtzero", 1 ); - - static const struct cs_subtitle EN[] = { { "j1", KCOL_JOHN "Eyyy! Looks like you're ready again.." }, { "j2", KCOL_JOHN "Didn't take long" }, { "j3", KCOL_JOHN "Just a short ferry ride back over to Mt.Zero now." }, @@ -230,22 +252,13 @@ static bool _skaterift_script_ch1s6a( ent_script_event *event ) { "j9", KCOL_JOHN "yknow, its our home!" }, { NULL, NULL }, - }; - _cutscene_load_and_play( "metascenes/ch1s6a.ms", EN, 1 ); - waiter->go = 1; - } + }; + _cutscene_load_and_play( "metascenes/ch1s6a.ms", EN, 1 ); } - if( event->type == k_escript_event_update ) - { - if( waiter->go ) - { - if( _cutscene.state == k_cutscene_state_none ) - { - waiter->go = 0; - skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } ); - } - } - } + if( on_cutscene_marker( event, "$ch1s6a_end" ) ) + skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } ); +#endif + return 1; } diff --git a/src/scripts/valley.c b/src/scripts/valley.c new file mode 100644 index 0000000..727be69 --- /dev/null +++ b/src/scripts/valley.c @@ -0,0 +1,183 @@ +#if 0 +struct script_valley_waiter +{ + bool go; +}; + +static bool _skaterift_script_valley( ent_script_event *event ) +{ + if( event->type == k_escript_event_allocate ) + { + struct script_event_allocate *event_info = event->info; + struct script_valley_waiter *waiter = vg_linear_alloc( event_info->heap, sizeof(struct script_valley_waiter) ); + waiter->go = 0; + event_info->userdata = waiter; + return 1; + } + struct script_valley_waiter *waiter = event->userdata; + + + + +#if 0 + + if( on_atom_once( event, "ch4s1a_view" ) ) + { + /* ch4s1: Mike and you are first encountering the valley world */ + static const struct cs_subtitle EN[] = + { + { "m1", KCOL_MIKE "It's gotta be some kind of dream right?" }, + { "m2", KCOL_MIKE "I mean... Cambodia?" }, + { "m3", KCOL_MIKE "What are we even doing here?" }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4s1a.ms", EN, 1 ); + } + + /* main region is completed (this is just the time trial as of 14.05.25, unlock ch4s2 cutscene */ + if( on_function_trigger( event, 27 ) ) + { + if( _skaterift_atom_status( "ch4s2_view" ) == 0 ) + _skaterift_atom_set( "ch4s2_view", 2 ); + } + + u64 status; + if( on_atom_changed( event, "valley_finale", &status ) ) + { + _ent_list_set_visible( _ent_list_get_aliased( "finale:locked" ), status != 1 ); + _ent_list_set_visible( _ent_list_get_aliased( "finale:unlocked" ), status == 1 ); + } + + /* finale completed, trigger the exit movie */ + if( on_function_trigger( event, 21 ) ) + { + _ent_list_set_visible( _ent_list_get_aliased( "rocket" ), 0 ); + _skaterift_atom_set( "unlock_venus", 1 ); + waiter->go = 1; + if( on_atom_once( event, "rocket_launch_view" ) ) + { + static const struct cs_subtitle EN[] = + { + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4rk.ms", EN, 1 ); + } + } + + if( on_cutscene_marker( event, "$fast" ) ) + k_day_length = 0.1f; + if( on_cutscene_marker( event, "$normal" ) ) + k_day_length = 30.0f; + + u64 _0, _1; + if( on_atom_changed( event, "valley_finale", &_0 ) || on_atom_changed( event, "unlock_venus", &_1 ) ) + { + // Notification & video tape + bool visible = _skaterift_atom_status( "valley_finale" ); + bool completed = _skaterift_atom_status( "unlock_venus" ); + _ent_list_set_visible( _ent_list_get_aliased( "finale_not_done" ), visible && !completed ); + } + + if( event->type == k_escript_event_update ) + { + if( waiter->go ) + { + if( _cutscene.state == k_cutscene_state_none ) + { + waiter->go = 0; + skaterift_load_world_command( 1, (const char *[]){ "sr002-local-venus" } ); + } + } + } + +#endif + return 1; +} + +static bool _skaterift_script_ch4s2( ent_script_event *event ) +{ + /* ch4s2: Mike and you find the rocket, and talk to the FBI person. */ + u64 status; + if( on_atom_changed( event, "ch4s2_view", &status ) ) + { + _ent_list_set_visible( event->entity_list, status == 2 ); + + bool launched = _skaterift_atom_status( "unlock_venus" ); + _ent_list_set_visible( _ent_list_get_aliased( "rocket" ), (status >= 1) && !(launched) ); + } + + if( on_function_trigger( event, 0 ) ) + { + if( on_atom_once( event, "ch4s2_view" ) ) + { + _skaterift_atom_set( "valley_cave", 1 ); + _ent_npc_set_in_cutscene( k_npc_fbi, 1 ); + + static const struct cs_subtitle EN[] = + { + { "m1", KCOL_MIKE "What the hell is that thing?" }, + { "f1", KCOL_FBI "Look man, all they told is that uhh" }, + { "f2", KCOL_FBI "they're sending you up to one of saturns moons.." }, + { "f3", KCOL_FBI "On that thing." }, + { "f4", KCOL_FBI "To help you on your mission." }, + { "f5", KCOL_FBI "You guys are more important than any person on earth right now" }, + { "f6", KCOL_FBI "According to the president." }, + { "f7", KCOL_FBI "But obviously this is some kind of joke I'm not in on." }, + { "f8", KCOL_FBI "I don't believe a word of it." }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4s2.ms", EN, 1 ); + } + } + + return 1; +} + +static bool _skaterift_script_ch4s1( ent_script_event *event ) +{ + u64 _0, _1; + if( on_atom_changed( event, "valley_cave", &_0 ) || on_atom_changed( event, "valley_finale", &_1 ) ) + { + // Notification & video tape + bool visible = _skaterift_atom_status( "valley_cave" ); + bool completed = _skaterift_atom_status( "valley_finale" ); + _ent_list_set_visible( _ent_list_get_aliased( "cave_not_done" ), visible && !completed ); + _ent_list_set_visible( event->entity_list, visible ); + } + + /* triggers on challenge activating */ + if( on_function_trigger( event, 3 ) ) + { + /* ch4s1: (Yes, this comes after ch4s2), Mike is leaving, because JC hasn't shown up anywhere. */ + if( on_atom_once( event, "ch4s1_view" ) ) + { + static const struct cs_subtitle EN[] = + { + { "m1", KCOL_MIKE "John hasn't turned up anywhere.." }, + { "m2", KCOL_MIKE "Not here, not back in Australia" }, + { "m3", KCOL_MIKE "nowhere?" }, + { "m4", KCOL_MIKE "I don't know how we can trust a single note.." }, + { "m5", KCOL_MIKE "I mean it is JC but.." }, + { "m6", KCOL_MIKE "Come on." }, + { "m7", KCOL_MIKE "I havn't seen him in weeks" }, + { "m8", KCOL_MIKE "I'm gonna go home," }, + { "m9", KCOL_MIKE "I'm bailing on this one man I'm sorry." }, + { NULL, NULL }, + }; + _cutscene_load_and_play( "metascenes/ch4s1.ms", EN, 1 ); + } + } + + /* triggers on challenge completed */ + if( on_function_trigger( event, 6 ) ) + _skaterift_atom_set( "valley_finale", 1 ); + + return 1; +} + +static bool _skaterift_script_ch4s3( ent_script_event *event ) +{ + // on venus + return 1; +} +#endif diff --git a/src/shader_props.h b/src/shader_props.h index 05f9ef0..43cf6ff 100644 --- a/src/shader_props.h +++ b/src/shader_props.h @@ -1,9 +1,15 @@ #pragma once #include "vg/vg_platform.h" +enum material_render_flag +{ + k_material_render_additive = 0x20 +}; + struct shader_props_standard { u32 tex_diffuse; + u32 render_flags; }; struct shader_props_terrain diff --git a/src/skaterift.c b/src/skaterift.c index b78e323..fea4120 100644 --- a/src/skaterift.c +++ b/src/skaterift.c @@ -348,8 +348,6 @@ static void render_scene(void) { } -m4x3f *_TEMP_VAR = NULL; /*FIXME*/ - static void skaterift_composite_maincamera(void) { /* world entity driven camera @@ -399,12 +397,6 @@ static void skaterift_composite_maincamera(void) vg_camera_update_transform( &g_render.cam ); - if( _TEMP_VAR ) - { - m4x3_copy( _TEMP_VAR[0], g_render.cam.transform ); - _TEMP_VAR = NULL; - } - vg_camera_update_view( &g_render.cam ); vg_camera_update_projection( &g_render.cam, vg.window_x, vg.window_y ); vg_camera_finalize( &g_render.cam ); diff --git a/src/skaterift_script.c b/src/skaterift_script.c index e70cef5..a585bda 100644 --- a/src/skaterift_script.c +++ b/src/skaterift_script.c @@ -6,570 +6,278 @@ #include "ent_script.h" - - -#if 0 - -#include "entity.h" -#include "ent_challenge.h" - - -static bool _skaterift_script_tutorial_setup( enum escript_event ev, const char *inf ) +const char *_script_linear_story[] = { - if( ev == k_escript_event_call ) - { - /* TODO: Attach event handler things - * update: we should switch away from the 'play' thing. And just call it 'call' - * then each individial script can decide if he wants to attach himself to the frame update - * or cutscene updates etc... - */ - - if( !_skaterift_script_already_viewed( k_escript_script_id_ch1s2 ) ) - { - _skaterift_script_hook_apply_action( k_escript_script_id_ch1s2, k_script_action_play ); - return 0; - } - else - { - return 1; - } - } - - return 0; -} + "start", + "volc", + "volc:tutorial", + "volc:leaving", + + "mz", + /* NOTES: we need to block the player in to force them to talk to mike so they don't get lost? Or at least put + * mike right in the way of where you gotta go. Perhaps on the docks. + */ + + "mz:town_region", + "mz:battery_jump", + "mz:leaving_pt1", + "mz:start_pt2", + "mz:megapark_region", + "mz:leaving_pt2", + + "city", + "city:main_region", + "city:finale", + "city:leaving", + + "valley", + "valley:main_region", + "valley:rocket_inspection", + "valley:cave", + "valley:finale", + "valley:leaving", + + NULL +}; -static bool _skaterift_script_ch4s1a( enum escript_event ev, const char *inf ) +struct script_save_atom { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "m1", KCOL_MIKE "This has gotta be some kindof dream right?" }, - { "m2", KCOL_MIKE "I mean... Cambodia?" }, - { "m3", KCOL_MIKE "What are we even doing here.?" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch4s1a.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } + const char *alias; - if( state == k_escript_state_playing ) + enum save_atom_type { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); - return 1; - } + k_atom_type_numeric, + k_atom_type_enum } - - return 0; + type; + + const char **enum_values; + u64 status; } - - -static bool _skaterift_script_ch4s1( enum escript_event ev, const char *inf ) +_skaterift_script_savedata[] = { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "m1", KCOL_MIKE "John hasn't turned up anywhere.." }, - { "m2", KCOL_MIKE "Not here, not back in Australia" }, - { "m3", KCOL_MIKE "nowhere?" }, - { "m4", KCOL_MIKE "I don't know how we can trust a single note.." }, - { "m5", KCOL_MIKE "I mean it is JC but.." }, - { "m6", KCOL_MIKE "Come on." }, - { "m7", KCOL_MIKE "I havn't seen him in weeks" }, - { "m8", KCOL_MIKE "I'm gonna go home," }, - { "m9", KCOL_MIKE "I'm bailing on this one man I'm sorry." }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); + { "story", k_atom_type_enum, _script_linear_story }, - return 0; - } - - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch4s1.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } + { "unlock_valley_view" }, + { "unlock_mtzero_view" }, + { "unlock_city_view" }, - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } + { "board_maker_unlock" }, + { "board_maker_hub_view" }, - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); - return 1; - } - } + { "ch1s3_view" }, + { "ch1s3b_view" }, + { "ch1s5_view" }, - return 0; -} +#if 0 + { "board_maker_unlock" }, + { "board_maker_hub_view" }, + { "intro_view" }, + { "hub_info_view" }, -static bool _skaterift_script_ch4s2( enum escript_event ev, const char *inf ) -{ - static u32 state, subtitle_id; - static struct cs_instance *override_inst; + { "ch1s2_view" }, + { "ch1s3_view" }, + { "ch1s3b_view" }, + { "ch1s4_view" }, + { "ch1s5_view" }, + { "ch1s6a_view" }, + { "unlock_docks_view" }, - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } + { "unlock_mtzero" }, + { "ch2s1_view" }, + { "ch2s2_view" }, + { "ch2s3_view" }, + { "battery_jump_view" }, + { "ch2s4_view" }, + { "ch2s5_view" }, /* is the trigger for the second map */ + { "ch2s6_view" }, + { "ch2e1_view" }, - if( ev == k_escript_event_cutscene_marker ) - { - struct sr_subtitle EN[] = { - { "m1", KCOL_MIKE "What the hell is that thing?" }, - { "f1", KCOL_FBI "Look man, all they told is that uhh" }, - { "f2", KCOL_FBI "they're sending you up to one of saturns moons.." }, - { "f3", KCOL_FBI "On that thing." }, - { "f4", KCOL_FBI "To help you on your mission." }, - { "f5", KCOL_FBI "You guys are more important than any person on earth right now" }, - { "f6", KCOL_FBI "According to the president." }, - { "f7", KCOL_FBI "But obviously this is some kind of joke I'm not in on." }, - { "f8", KCOL_FBI "I don't believe a word of it." }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); + { "unlock_city" }, + { "unlock_city_view" }, + { "ch3s1_view" }, + { "ch3s2_view" }, + { "ch3s3_view" }, + { "city_finale" }, - return 0; - } + { "unlock_valley" }, - /* scene - * --------------------------------------------------------------- */ + { "valley_progress" }, - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch4s2.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } + { "ch4s1a_view" }, + { "ch4s2_view" }, + { "valley_cave" }, + { "ch4s1_view" }, + { "valley_finale" }, + { "ch4s3_view" }, + { "rocket_launch_view" }, - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } + { "unlock_venus" }, +#endif +}; - if( state == k_escript_state_playing ) +struct script_save_atom *_skaterift_get_atom( const char *alias ) +{ + for( u32 i=0; ialias ) ) + return atom; } - - return 0; + return NULL; } -static bool _skaterift_script_ch4s3( enum escript_event ev, const char *inf ) +u64 _skaterift_atom_enum_index( const char *atom_alias, const char *value, u64 fallback_value ) { - static u32 state, subtitle_id; - static struct cs_instance *override_inst; - - if( ev == k_escript_event_call ) - { - state = k_escript_state_loading; - override_inst = NULL; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) + struct script_save_atom *atom = _skaterift_get_atom( atom_alias ); + if( !atom ) { - struct sr_subtitle EN[] = { - { "j1", KCOL_JOHN "Betcha didn't think ya'd see me here!!?" }, - { "j2", KCOL_JOHN "Did you miss me?" }, - { "j3", KCOL_JOHN "You're probably wondering how the hell I got up here myself right?" }, - { "j4", KCOL_JOHN "Well. I'm not gonna tell you." }, - { "j5", KCOL_JOHN "It was all a trick. A ROUSE!" }, - { "j6", KCOL_JOHN "Truth is, none of this is really real!" }, - { "j7", KCOL_JOHN "And I'm leaving you here." }, - { "j8", KCOL_JOHN "Cause its the only way I'm gonna get you to wake up." }, - { "j9", KCOL_JOHN "Sorry I had to do all this to you..." }, - { "j10",KCOL_JOHN "We can still be friends right?" }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); - + vg_error( "No atom aliased '%s'\n", atom_alias ); return 0; } - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) - { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/ch4s3.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } - } - - if( state == k_escript_state_initializing ) + VG_ASSERT( atom->type == k_atom_type_enum ); + if( value ) { - if( _cutscene.state == k_cutscene_state_ready ) + for( u32 i=0; i<32; i ++ ) { - _skaterift_script_bind_player(); - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } - - if( state == k_escript_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - state = k_escript_state_end; - vg_info( "test:state = end\n" ); - _cutscene_unload(); - return 1; + if( !atom->enum_values[i] ) + { + vg_warn( "Atom '%s' does't contain the value '%s'\n", atom->alias, value ); + return fallback_value; + } + if( !strcmp( atom->enum_values[i], value ) ) + return i; } + vg_warn( "Atom '%s' exceeds max enum values (%u)\n", atom->alias, 32 ); } - - return 0; + return fallback_value; } - -/* This is the development one */ -static bool _skaterift_script_test( enum escript_event ev, const char *inf ) +u64 _skaterift_atom_status( const char *atom_alias ) { - static u32 state; - static m4x3f *action_cam; - static bool action_mode; - static u32 subtitle_id; - - if( ev == k_escript_event_call ) + struct script_save_atom *atom = _skaterift_get_atom( atom_alias ); + if( !atom ) { - state = k_escript_state_loading; - action_cam = NULL; - action_mode = 0; - subtitle_id = 0; - vg_info( "test:state = loading\n" ); - } - - if( ev == k_escript_event_cutscene_marker ) - { - if( vg_str_eq( inf, "action_cam" ) ) - action_mode = 1; - - struct sr_subtitle EN[] = { - { "john_line_0", KCOL_JOHN "Mike mike mike, I need you to get over here now" }, - { "mike_line_0", KCOL_MIKE "What is it now JC?" }, - { "john_line_1", KCOL_JOHN "Well we were out here, shooting this massive gap right?" }, - { "john_line_1a",KCOL_JOHN "It was gonna be the perfect shot, and it was going so good" }, - { "john_line_2", KCOL_JOHN "Intro was perfect, got the perfect frame, angles lighting. PERFECT" }, - { "mike_line_1", KCOL_MIKE "Whatever mate, what happened?" }, - { "john_line_3", KCOL_JOHN "Uh yeah yeah, we were about 10 floors up right?" }, - { "john_line_3a",KCOL_JOHN "Yeah uhhh, they didn't make the gap." }, - { "john_line_4", KCOL_JOHN "And im im freaking out here man, it was worst case" }, - { "john_line_4a",KCOL_JOHN "I mean.. WORST CASE" }, - { "mike_line_2", KCOL_MIKE "yeaahkay, what are you doing calling me instead of an ambo?" }, - { "john_line_5", KCOL_JOHN "I thought you could help us!" }, - { "mike_line_3", KCOL_MIKE "Hang up, and call tripple zero mate" }, - { "mike_line_3a",KCOL_MIKE "Did you even check if they were okay?" }, - { "john_line_6", KCOL_JOHN "Holy crap, you're still alive!" }, - { "john_line_6a",KCOL_JOHN "Nevermind Mike, cheers" }, - { "john_line_7", KCOL_JOHN "Lets get out of here mate." }, - { NULL, NULL }, - }; - _skaterift_dialogue( EN, &subtitle_id, inf ); + vg_error( "No atom aliased '%s'\n", atom_alias ); return 0; } + else return atom->status; +} - /* scene - * --------------------------------------------------------------- */ - - if( state == k_escript_state_loading ) +void _skaterift_atom_set( const char *atom_alias, u64 value ) +{ + struct script_save_atom *atom = _skaterift_get_atom( atom_alias ); + if( !atom ) { - if( cmd_cutscene_load( 1, (const char *[]){ "metascenes/test_scene.ms" } ) ) - { - state = k_escript_state_initializing; - vg_info( "test:state = initializing\n" ); - } + vg_error( "No atom aliased '%s'\n", atom_alias ); + return; } - if( state == k_escript_state_initializing ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - _skaterift_script_bind_player(); - - struct cs_instance *boogie_inst = - _cutscene_get_first_model_instance( "models/boogie_van" ); - - if( boogie_inst ) - { - struct model_ref *mref = &_cutscene.refs[ boogie_inst->ref_id ]; - struct skeleton *sk = &mref->skeletons[0].sk; - - for( u32 i=0; ibone_count; i ++ ) - { - vg_info( "%s\n", sk->bones[i].name ); - if( !strcmp( sk->bones[i].name, "action_cam" ) ) - { - action_cam = boogie_inst->skinning_data + i; - break; - } - } + atom->status = value; - if( action_cam == NULL ) - { - vg_error( "test: Failed to find action cam bone" ); - return 1; - } - } - else - { - vg_error( "test: Failed to find boogie van" ); - return 1; - } + struct script_event_atom_changed info; + info.alias = atom_alias; + info.value = value; + struct ent_script_event event; + event.type = k_escript_event_atom_changed; + event.info = &info; + ent_script_propogate_event( &_world.main, &event ); +} - state = k_escript_state_playing; - vg_info( "test:state = playing\n" ); - _cutscene_play(); - } - } +void _skaterift_atom_set_enum( const char *atom_alias, const char *value ) +{ + _skaterift_atom_set( atom_alias, _skaterift_atom_enum_index( atom_alias, value, 0 ) ); +} - if( state == k_escript_state_playing ) +void _skaterift_script_write_savedata( vg_msg *sav ) +{ + for( u32 i=0; itype == k_atom_type_numeric ) + vg_msg_wkvnum( sav, atom->alias, k_vg_msg_u64, 1, &atom->status ); else - { - if( action_mode ) - _TEMP_VAR = action_cam; - } + vg_msg_wkvstr( sav, atom->alias, atom->enum_values[ atom->status ] ); } - - return 0; } -#endif - - -extern m4x3f *_TEMP_VAR; - -#if 0 -enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutscene *cutscene_template, - ent_script_event *event ) +void _skaterift_script_load_savedata( vg_msg *sav ) { - if( event->type == k_escript_event_allocate ) - { - struct script_event_allocate *event_info = event->info; - struct generic_cutscene *generic = vg_linear_alloc( event_info->heap, sizeof(struct generic_cutscene) ); - memcpy( generic, cutscene_template, sizeof(struct generic_cutscene) ); - event_info->userdata = generic; - return k_generic_cutscene_event_none; - } - else + for( u32 i=0; iuserdata; - - if( event->type == k_escript_event_update ) - { - if( generic->state == k_generic_cutscene_state_wake ) - { - if( _cutscene.state == k_cutscene_state_none ) - { - if( cmd_cutscene_load( 1, (const char *[]){ generic->metascene_path } ) ) - { - generic->state = k_generic_cutscene_state_init; - vg_info( "generic_cutscene:state = initializing\n" ); - } - } - - if( generic->trigger_start == 0 ) - { - generic->trigger_start = 1; - return k_generic_cutscene_event_start; - } - else - return k_generic_cutscene_event_none; - } - - if( generic->state == k_generic_cutscene_state_init ) - { - if( _cutscene.state == k_cutscene_state_ready ) - { - if( generic->subtitles ) - { - _cutscene_set_subtitle_list( generic->subtitles ); - } - - _skaterift_script_bind_player(); - _cutscene_play(); - generic->state = k_generic_cutscene_state_playing; - vg_info( "generic_template:state = playing\n" ); - return k_generic_cutscene_event_start; - } - } - - if( generic->state == k_generic_cutscene_state_playing ) - { - if( _cutscene.state == k_cutscene_state_done ) - { - generic->state = k_generic_cutscene_state_end; - - vg_info( "generic_template:state = end\n" ); - _cutscene_unload(); - - - return k_generic_cutscene_event_end; - } - } - - return k_generic_cutscene_event_none; - } + struct script_save_atom *atom = &_skaterift_script_savedata[i]; + if( atom->type == k_atom_type_numeric ) + vg_msg_getkvintg( sav, atom->alias, k_vg_msg_u64, &atom->status, NULL ); else - return k_generic_cutscene_event_none; + atom->status = _skaterift_atom_enum_index( atom->alias, vg_msg_getkvstr( sav, atom->alias ), 0 ); } } -void play_generic_cutscene( ent_script_event *event ) -{ - struct generic_cutscene *generic = event->userdata; - generic->state = k_generic_cutscene_state_wake; -} -#endif +/* script events + * ------------------------------------------------------------------------------------------------------------- */ bool on_cutscene_marker( ent_script_event *event, const char *marker ) { if( event->type != k_escript_event_allocate ) + { if( _cutscene.state == k_cutscene_state_playing ) + { if( _cutscene.marker_this_frame ) + { if( vg_str_eq( marker, _cutscene.marker_this_frame ) ) return 1; - + } + } + } return 0; } -bool on_nugget_changed( ent_script_event *event, const char *nugget_alias, u64 *out_value ) +bool on_world_start( ent_script_event *event ) +{ + return event->type == k_escript_event_world_start; +} + +bool on_atom_changed( ent_script_event *event, const char *atom_alias, u64 *out_value ) { - if( event->type == k_escript_event_nugget_changed ) + if( event->type == k_escript_event_atom_changed ) { - struct script_event_nugget_changed *nugget_info = event->info; - if( !strcmp( nugget_alias, nugget_info->alias ) ) + struct script_event_atom_changed *atom_info = event->info; + if( !strcmp( atom_alias, atom_info->alias ) ) { - *out_value = nugget_info->value; + *out_value = atom_info->value; return 1; } } else if( event->type == k_escript_event_world_start ) { - *out_value = _skaterift_script_nugget_status( nugget_alias ); + *out_value = _skaterift_atom_status( atom_alias ); return 1; } return 0; } +#if 0 bool on_function_trigger( ent_script_event *event, i32 function_id ) { if( event->type == k_escript_event_call ) { struct script_event_call *call_info = event->info; if( call_info->function_id == function_id ) - { return 1; - } } return 0; } -bool on_nugget_once( ent_script_event *event, const char *nugget_alias ) +bool on_atom_once( ent_script_event *event, const char *atom_alias ) { if( event->type != k_escript_event_allocate ) { - if( _skaterift_script_nugget_status( nugget_alias ) != 1 ) + if( _skaterift_atom_status( atom_alias ) != 1 ) { - _skaterift_script_nugget_set( nugget_alias, 1 ); + _skaterift_atom_set( atom_alias, 1 ); return 1; } } @@ -577,53 +285,18 @@ bool on_nugget_once( ent_script_event *event, const char *nugget_alias ) return 0; } -bool on_completion_changed( ent_script_event *event ) +bool on_advancement( ent_script_event *event ) { if( event->type == k_escript_event_completion_changed ) + return 1; + if( event->type == k_escript_event_world_start) return 1; - return 0; -} - -#if 0 -enum generic_cutscene_event optional_video_wrapper( const struct generic_cutscene *cutscene_template, - const char *nugget_alias, - u64 nugget_visible_value, - ent_script_event *event ) -{ - enum generic_cutscene_event cs_event = generic_cutscene_wrapper( cutscene_template, event ); - - u64 status; - if( on_nugget_changed( event, nugget_alias, &status ) ) - { - ent_list_set_visible( event->world, event->entity_list, status == nugget_visible_value ); - } - - if( on_function_trigger( event, 0 ) ) - { - if( on_nugget_once( event, nugget_alias ) ) - { - play_generic_cutscene( event ); - } - } - - return cs_event; -} - -enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutscene *cutscene_template, - const char *nugget_alias, - ent_script_event *event ) -{ - enum generic_cutscene_event cs_event = generic_cutscene_wrapper( cutscene_template, event ); - if( on_function_trigger( event, 0 ) ) - { - if( on_nugget_once( event, nugget_alias ) ) - { - play_generic_cutscene( event ); - } - } + u64 _0; + if( on_atom_changed( event, "story", &_0 ) ) + return 1; - return cs_event; + return 0; } #endif @@ -635,6 +308,37 @@ enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutsce #include "scripts/tutorial_island.c" #include "scripts/mtzero.c" #include "scripts/city.c" +#include "scripts/valley.c" + +#include "scripts/cutscene.c" +#include "scripts/explode.c" + +static bool _skaterift_atom_script( ent_script_event *event ) +{ + if( event->type == k_escript_event_world_event ) + { + struct script_event_world_io *inf = event->info; + world_instance *world = &_world.main; + + if( AF_STR_EQ( &world->meta.af, inf->event->pstr_recieve_event, "pass_once" ) ) + { + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( inf->event->flags & k_ent_event_data_const_string ) + { + const char *alias = af_str( &world->meta.af, inf->event->data.const_pstr ); + if( _skaterift_atom_status( alias ) != 1 ) + { + _skaterift_atom_set( alias, 1 ); + _world_raise_event( inf->event->recieve_entity_id, "pass" ); + } + else + _world_raise_event( inf->event->recieve_entity_id, "fail" ); + } + } + } + + return 1; +} /* -------------------------------------------------------------------------------------------------------------------- * function aliasing @@ -642,11 +346,15 @@ enum generic_cutscene_event challenge_video_wrapper( const struct generic_cutsce struct ent_script_table_entry _ent_script_table[] = { + { "cutscene", _skaterift_script_cutscene }, + { "explode", _skaterift_script_explode }, + { "atom", _skaterift_atom_script }, +#if 0 + { "hub", _skaterift_script_hub }, { "board_maker_unlock", _skaterift_script_board_maker_unlock }, { "board_maker", _skaterift_script_board_maker }, //{ "intro", _skaterift_script_intro }, - { "hub", _skaterift_script_hub }, { "tutorial_island", _skaterift_script_tutorial_island }, { "ch1s3", _skaterift_script_ch1s3 }, @@ -668,112 +376,17 @@ struct ent_script_table_entry _ent_script_table[] = { "ch3s2", _skaterift_script_ch3s2 }, { "ch3s3", _skaterift_script_ch3s3 }, - { NULL } -}; - -/* -------------------------------------------------------------------------------------------------------------------- - * save data - */ - -struct script_save_nugget -{ - const char *alias; - u64 status; -} -_skaterift_script_savedata[] = -{ - { "board_maker_unlock" }, - { "board_maker_hub_view" }, - { "intro_view" }, - { "hub_info_view" }, - - { "ch1s2_view" }, - { "ch1s3_view" }, - { "ch1s3b_view" }, - { "ch1s4_view" }, - { "ch1s5_view" }, - { "ch1s6a_view" }, - { "unlock_docks_view" }, - - { "unlock_mtzero" }, - { "unlock_mtzero_view" }, - { "ch2s1_view" }, - { "ch2s2_view" }, - { "ch2s3_view" }, - { "battery_jump_view" }, - { "ch2s4_view" }, - { "ch2s5_view" }, /* is the trigger for the second map */ - { "ch2s6_view" }, - { "ch2e1_view" }, - - { "unlock_city" }, - { "unlock_city_view" }, - { "ch3s1_view" }, - { "ch3s2_view" }, - { "ch3s3_view" }, - { "city_finale" }, - - { "unlock_valley" }, - { "unlock_valley_view" }, + { "valley", _skaterift_script_valley }, + { "ch4s2", _skaterift_script_ch4s2 }, + { "ch4s1", _skaterift_script_ch4s1 }, +#endif - { "unlock_venus" }, + { NULL } }; -u64 _skaterift_script_nugget_status( const char *nugget_alias ) -{ - for( u32 i=0; ialias ) ) - return nugget->status; - } - - vg_error( "No nugget named: '%s'\n", nugget_alias ); - return 0; -} - -void _skaterift_script_nugget_set( const char *nugget_alias, u64 value ) -{ - for( u32 i=0; ialias ) ) - { - nugget->status = value; - - struct script_event_nugget_changed info; - info.alias = nugget_alias; - info.value = value; - - struct ent_script_event event; - event.type = k_escript_event_nugget_changed; - event.info = &info; - - ent_script_propogate_event( &_world.main, &event ); - return; - } - } - vg_error( "No nugget named: '%s'\n", nugget_alias ); -} - -void _skaterift_script_write_savedata( vg_msg *sav ) -{ - for( u32 i=0; ialias, k_vg_msg_u64, 1, &nugget->status ); - } -} - -void _skaterift_script_load_savedata( vg_msg *sav ) -{ - for( u32 i=0; ialias, k_vg_msg_u64, &nugget->status, NULL ); - } -} +/* console eventts + * ------------------------------------------------------------------------------------------------------------- */ static int _skaterift_script_ccmd( int argc, const char *argv[] ) { @@ -783,7 +396,7 @@ static int _skaterift_script_ccmd( int argc, const char *argv[] ) return 0; } - if( !strcmp( argv[0], "nugget" ) ) + if( !strcmp( argv[0], "atom" ) ) { bool all = 0; if( !strcmp( argv[1], "all" ) ) @@ -791,11 +404,25 @@ static int _skaterift_script_ccmd( int argc, const char *argv[] ) for( u32 i=0; ialias ) ) + struct script_save_atom *atom = &_skaterift_script_savedata[i]; + if( all || !strcmp( argv[1], atom->alias ) ) { - if( argc==3 ) _skaterift_script_nugget_set( nugget->alias, atol(argv[2]) ); - else vg_info( "%s: %lu\n", nugget->alias, nugget->status ); + if( argc==3 ) + { + u64 value = 0; + if( atom->type == k_atom_type_numeric ) + value = atol(argv[2]); + else + value = _skaterift_atom_enum_index( atom->alias, argv[2], atom->status ); + _skaterift_atom_set( atom->alias, value ); + } + else + { + if( atom->type == k_atom_type_numeric ) + vg_info( "%s: %lu\n", atom->alias, atom->status ); + else + vg_info( "%s: '%s' (%lu)\n", atom->alias, atom->enum_values[ atom->status ], atom->status ); + } } } @@ -827,18 +454,18 @@ static void _skaterift_script_ccmd_poll( int argc, const char *argv[] ) if( argc == 1 ) { - console_suggest_score_text( "nugget", term, 0 ); + console_suggest_score_text( "atom", term, 0 ); console_suggest_score_text( "trigger", term, 0 ); } else if( argc == 2 ) { - if( !strcmp( argv[0], "nugget" ) ) + if( !strcmp( argv[0], "atom" ) ) { console_suggest_score_text( "all", term, 0 ); for( u32 i=0; ialias, term, 0 ); + struct script_save_atom *atom = &_skaterift_script_savedata[i]; + console_suggest_score_text( atom->alias, term, 0 ); } } else if( !strcmp( argv[0], "trigger" ) ) @@ -846,6 +473,25 @@ static void _skaterift_script_ccmd_poll( int argc, const char *argv[] ) console_suggest_score_text( "start", term, 0 ); } } + else if( argc == 3 ) + { + if( !strcmp( argv[0], "atom" ) ) + { + if( strcmp( argv[1], "all" ) ) + { + struct script_save_atom *atom = _skaterift_get_atom( argv[1] ); + if( atom->type == k_atom_type_enum ) + { + for( u32 i=0; i<32; i ++ ) + { + if( !atom->enum_values[i] ) + break; + console_suggest_score_text( atom->enum_values[i], term, 0 ); + } + } + } + } + } } void _skaterift_script_init(void) diff --git a/src/skaterift_script.h b/src/skaterift_script.h index 8cbad90..2cb58f9 100644 --- a/src/skaterift_script.h +++ b/src/skaterift_script.h @@ -1,39 +1,19 @@ #pragma once #include "ent_script.h" +#define ATOM_MAX 0xfffffffffffffffflu void _skaterift_script_init(void); void _skaterift_script_write_savedata( vg_msg *sav ); void _skaterift_script_load_savedata( vg_msg *sav ); -u64 _skaterift_script_nugget_status( const char *nugget_alias ); -void _skaterift_script_nugget_set( const char *nugget_alias, u64 value ); +u64 _skaterift_atom_status( const char *atom_alias ); +u64 _skaterift_atom_enum_index( const char *atom_alias, const char *value, u64 fallback_value ); +void _skaterift_atom_set( const char *atom_alias, u64 value ); +void _skaterift_atom_set_enum( const char *atom_alias, const char *value ); -#if 0 -struct generic_cutscene -{ - enum generic_cutscene_state - { - k_generic_cutscene_state_none, - k_generic_cutscene_state_wake, - k_generic_cutscene_state_init, - k_generic_cutscene_state_loading, - k_generic_cutscene_state_playing, - k_generic_cutscene_state_end - } - state; - const char *metascene_path; - const cs_subtitle *subtitles; - bool freeze_player; - bool trigger_start; -}; - -enum generic_cutscene_event -{ - k_generic_cutscene_event_none, - k_generic_cutscene_event_end, - k_generic_cutscene_event_start -}; - -enum generic_cutscene_event generic_cutscene_wrapper( const struct generic_cutscene *cutscene_template, ent_script_event *event ); -void play_generic_cutscene( ent_script_event *event ); -#endif +bool on_world_start( ent_script_event *event ); +bool on_atom_changed( ent_script_event *event, const char *atom_alias, u64 *out_value ); +bool on_cutscene_marker( ent_script_event *event, const char *marker ); +bool on_function_trigger( ent_script_event *event, i32 function_id ); +bool on_atom_once( ent_script_event *event, const char *atom_alias ); +bool on_advancement( ent_script_event *event ); diff --git a/src/skeleton.h b/src/skeleton.h index dc15a00..74b31b2 100644 --- a/src/skeleton.h +++ b/src/skeleton.h @@ -49,10 +49,9 @@ struct skeleton_anim static u32 skeleton_bone_id( struct skeleton *skele, const char *name ) { - for( u32 i=1; ibone_count; i++ ){ + for( u32 i=1; ibone_count; i++ ) if( !strcmp( skele->bones[i].name, name )) return i; - } vg_error( "skeleton_bone_id( *, \"%s\" );\n", name ); vg_fatal_error( "Bone does not exist\n" ); @@ -60,8 +59,7 @@ static u32 skeleton_bone_id( struct skeleton *skele, const char *name ) return 0; } -static void keyframe_copy_pose( ms_keyframe *kfa, ms_keyframe *kfb, - int num ) +static void keyframe_copy_pose( ms_keyframe *kfa, ms_keyframe *kfb, int num ) { for( int i=0; ico, offset, co ); @@ -83,8 +80,8 @@ static void keyframe_rotate_around( ms_keyframe *kf, q_normalize( kf->q ); } -static void keyframe_lerp( ms_keyframe *kfa, ms_keyframe *kfb, f32 t, - ms_keyframe *kfd ){ +static void keyframe_lerp( ms_keyframe *kfa, ms_keyframe *kfb, f32 t, ms_keyframe *kfd ) +{ v3_lerp( kfa->co, kfb->co, t, kfd->co ); q_nlerp( kfa->q, kfb->q, t, kfd->q ); v3_lerp( kfa->s, kfb->s, t, kfd->s ); @@ -93,13 +90,15 @@ static void keyframe_lerp( ms_keyframe *kfa, ms_keyframe *kfb, f32 t, /* * Lerp between two sets of keyframes and store in dest. Rotations use Nlerp. */ -static void keyframe_lerp_pose( ms_keyframe *kfa, ms_keyframe *kfb, - float t, ms_keyframe *kfd, int count ){ - if( t <= 0.0001f ){ +static void keyframe_lerp_pose( ms_keyframe *kfa, ms_keyframe *kfb, float t, ms_keyframe *kfd, int count ) +{ + if( t <= 0.0001f ) + { keyframe_copy_pose( kfa, kfd, count ); return; } - else if( t >= 0.9999f ){ + else if( t >= 0.9999f ) + { keyframe_copy_pose( kfb, kfd, count ); return; } @@ -108,16 +107,12 @@ static void keyframe_lerp_pose( ms_keyframe *kfa, ms_keyframe *kfb, keyframe_lerp( kfa+i, kfb+i, t, kfd+i ); } -static -void skeleton_lerp_pose( struct skeleton *skele, - ms_keyframe *kfa, ms_keyframe *kfb, float t, - ms_keyframe *kfd ) +static void skeleton_lerp_pose( struct skeleton *skele, ms_keyframe *kfa, ms_keyframe *kfb, float t, ms_keyframe *kfd ) { keyframe_lerp_pose( kfa, kfb, t, kfd, skele->bone_count-1 ); } -static void skeleton_copy_pose( struct skeleton *skele, - ms_keyframe *kfa, ms_keyframe *kfd ) +static void skeleton_copy_pose( struct skeleton *skele, ms_keyframe *kfa, ms_keyframe *kfd ) { keyframe_copy_pose( kfa, kfd, skele->bone_count-1 ); } @@ -128,34 +123,27 @@ static void skeleton_copy_pose( struct skeleton *skele, * * Time is in SECONDS */ -void skeleton_sample_anim( struct skeleton *skele, - skeleton_anim *anim, - float time, - ms_keyframe *output ) +void skeleton_sample_anim( struct skeleton *skele, skeleton_anim *anim, f32 time, ms_keyframe *output ) { ms_strip *strip = anim->strip; - f32 animtime = fmodf( time*anim->framerate, (f32)strip->length ), + f32 animtime = fmodf( time*anim->framerate, (f32)strip->strip.length ), animframe = floorf( animtime ), t = animtime - animframe; + u32 frame = (u32)animframe % strip->strip.length, + next = (frame+1) % strip->strip.length; - u32 frame = (u32)animframe % strip->length, - next = (frame+1) % strip->length; - - ms_keyframe *base = anim->keyframes_base + strip->data_count*frame, - *nbase = anim->keyframes_base + strip->data_count*next; + ms_keyframe *base = anim->keyframes_base + strip->strip.count*frame, + *nbase = anim->keyframes_base + strip->strip.count*next; skeleton_lerp_pose( skele, base, nbase, t, output ); } /* time is in SECONDS */ -int skeleton_sample_anim_clamped( struct skeleton *skele, - skeleton_anim *anim, - float time, - ms_keyframe *output ) +int skeleton_sample_anim_clamped( struct skeleton *skele, skeleton_anim *anim, f32 time, ms_keyframe *output ) { ms_strip *strip = anim->strip; - f32 end = (strip->length-1)/anim->framerate; + f32 end = (strip->strip.length-1)/anim->framerate; skeleton_sample_anim( skele, anim, vg_minf( end, time ), output ); if( time > end ) return 0; @@ -171,25 +159,26 @@ typedef enum anim_apply } anim_apply; -static -int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) +static int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) { struct skeleton_bone *sb = &skele->bones[ id ], *sp = &skele->bones[ sb->parent ]; - if( type == k_anim_apply_defer_ik ){ - if( ((sp->flags & k_bone_flag_ik) && !(sb->flags & k_bone_flag_ik)) - || sp->defer ) + if( type == k_anim_apply_defer_ik ) + { + if( ((sp->flags & k_bone_flag_ik) && !(sb->flags & k_bone_flag_ik)) || sp->defer ) { sb->defer = 1; return 0; } - else{ + else + { sb->defer = 0; return 1; } } - else if( type == k_anim_apply_deffered_only ){ + else if( type == k_anim_apply_deffered_only ) + { if( sb->defer ) return 1; else @@ -202,8 +191,7 @@ int should_apply_bone( struct skeleton *skele, u32 id, anim_apply type ) /* * Apply block of keyframes to skeletons final pose */ -static void skeleton_apply_pose( struct skeleton *skele, ms_keyframe *pose, - anim_apply passtype, m4x3f *final_mtx ) +static void skeleton_apply_pose( struct skeleton *skele, ms_keyframe *pose, anim_apply passtype, m4x3f *final_mtx ) { if( passtype == k_anim_apply_absolute ) { @@ -228,7 +216,6 @@ static void skeleton_apply_pose( struct skeleton *skele, ms_keyframe *pose, { struct skeleton_bone *sb = &skele->bones[i], *sp = &skele->bones[sb->parent]; - if( !should_apply_bone( skele, i, passtype ) ) continue; @@ -255,10 +242,10 @@ static void skeleton_apply_pose( struct skeleton *skele, ms_keyframe *pose, /* * Take the final matrices and decompose it into an absolute positioned anim */ -static void skeleton_decompose_mtx_absolute( struct skeleton *skele, - ms_keyframe *anim, - m4x3f *final_mtx ){ - for( u32 i=1; ibone_count; i++ ){ +static void skeleton_decompose_mtx_absolute( struct skeleton *skele, ms_keyframe *anim, m4x3f *final_mtx ) +{ + for( u32 i=1; ibone_count; i++ ) + { struct skeleton_bone *sb = &skele->bones[i]; ms_keyframe *kf = &anim[i-1]; m4x3_decompose( final_mtx[i], kf->co, kf->q, kf->s ); @@ -269,9 +256,7 @@ static void skeleton_decompose_mtx_absolute( struct skeleton *skele, * creates the reference inverse matrix for an IK bone, as it has an initial * intrisic rotation based on the direction that the IK is setup.. */ -static void skeleton_inverse_for_ik( struct skeleton *skele, - v3f ivaxis, - u32 id, m3x3f inverse ) +static void skeleton_inverse_for_ik( struct skeleton *skele, v3f ivaxis, u32 id, m3x3f inverse ) { v3_copy( ivaxis, inverse[0] ); v3_copy( skele->bones[id].end, inverse[1] ); @@ -286,9 +271,9 @@ static void skeleton_inverse_for_ik( struct skeleton *skele, static void skeleton_create_inverses( struct skeleton *skele ) { /* IK: inverse 'plane-bone space' axis '(^axis,^bone,...)[base] */ - for( u32 i=0; iik_count; i++ ){ + for( u32 i=0; iik_count; i++ ) + { struct skeleton_ik *ik = &skele->ik[i]; - m4x3f inverse; v3f iv0, iv1, ivaxis; v3_sub( skele->bones[ik->target].co, skele->bones[ik->lower].co, iv0 ); @@ -304,11 +289,10 @@ static void skeleton_create_inverses( struct skeleton *skele ) /* * Apply a model matrix to all bones, should be done last */ -static -void skeleton_apply_transform( struct skeleton *skele, m4x3f transform, - m4x3f *final_mtx ) +static void skeleton_apply_transform( struct skeleton *skele, m4x3f transform, m4x3f *final_mtx ) { - for( u32 i=0; ibone_count; i++ ){ + for( u32 i=0; ibone_count; i++ ) + { struct skeleton_bone *sb = &skele->bones[i]; m4x3_mul( transform, final_mtx[i], final_mtx[i] ); } @@ -318,13 +302,14 @@ void skeleton_apply_transform( struct skeleton *skele, m4x3f transform, * Apply an inverse matrix to all bones which maps vertices from bind space into * bone relative positions */ -static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx ){ - for( u32 i=0; ibone_count; i++ ){ +static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx ) +{ + for( u32 i=0; ibone_count; i++ ) + { struct skeleton_bone *sb = &skele->bones[i]; m4x3f inverse; m3x3_identity( inverse ); v3_negate( sb->co, inverse[3] ); - m4x3_mul( final_mtx[i], inverse, final_mtx[i] ); } } @@ -337,7 +322,6 @@ static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ) for( u32 i=0; iik_count; i++ ) { struct skeleton_ik *ik = &skele->ik[i]; - v3f v0, /* base -> target */ v1, /* base -> pole */ vaxis; @@ -366,12 +350,11 @@ static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ) v2f delta; v2_sub( end, base, delta ); - float - l1 = v3_length( skele->bones[ik->lower].end ), - l2 = v3_length( skele->bones[ik->upper].end ), - d = vg_clampf( v2_length(delta), fabsf(l1 - l2), l1+l2-0.00001f ), - c = acosf( (l1*l1 + d*d - l2*l2) / (2.0f*l1*d) ), - rot = atan2f( delta[1], delta[0] ) + c - VG_PIf/2.0f; + f32 l1 = v3_length( skele->bones[ik->lower].end ), + l2 = v3_length( skele->bones[ik->upper].end ), + d = vg_clampf( v2_length(delta), fabsf(l1 - l2), l1+l2-0.00001f ), + c = acosf( (l1*l1 + d*d - l2*l2) / (2.0f*l1*d) ), + rot = atan2f( delta[1], delta[0] ) + c - VG_PIf/2.0f; knee[0] = sinf(-rot) * l1; knee[1] = cosf(-rot) * l1; @@ -412,8 +395,7 @@ static void skeleton_apply_ik_pass( struct skeleton *skele, m4x3f *final_mtx ) * Applies the typical operations that you want for an IK rig: * Pose, IK, Pose(deferred), Inverses, Transform */ -static void skeleton_apply_standard( struct skeleton *skele, ms_keyframe *pose, - m4x3f transform, m4x3f *final_mtx ) +static void skeleton_apply_standard( struct skeleton *skele, ms_keyframe *pose, m4x3f transform, m4x3f *final_mtx ) { skeleton_apply_pose( skele, pose, k_anim_apply_defer_ik, final_mtx ); skeleton_apply_ik_pass( skele, final_mtx ); @@ -422,10 +404,7 @@ static void skeleton_apply_standard( struct skeleton *skele, ms_keyframe *pose, skeleton_apply_transform( skele, transform, final_mtx ); } -static void skeleton_alloc_from( struct skeleton *skele, - void *lin_alloc, - mdl_context *mdl, - mdl_armature *armature ) +static void skeleton_alloc_from( struct skeleton *skele, void *lin_alloc, mdl_context *mdl, mdl_armature *armature ) { skele->bone_count = armature->bone_count+1; skele->ik_count = 0; @@ -434,10 +413,8 @@ static void skeleton_alloc_from( struct skeleton *skele, for( u32 i=0; ibone_count; i++ ) { mdl_bone *bone = &mdl->bones[ armature->bone_start+i ]; - if( bone->flags & k_bone_flag_ik ) skele->ik_count ++; - if( bone->collider ) skele->collider_count ++; } @@ -452,13 +429,13 @@ static void skeleton_alloc_from( struct skeleton *skele, memset( skele->ik, 0, ik_size ); } -static void skeleton_fatal_err(void){ +static void skeleton_fatal_err(void) +{ vg_fatal_error( "Skeleton setup failed" ); } /* Setup a skeleton from model. mdl's metadata should stick around */ -void skeleton_setup( struct skeleton *skele, mdl_context *mdl, u32 index, - void *lin_alloc ) +void skeleton_setup( struct skeleton *skele, mdl_context *mdl, u32 index, void *lin_alloc ) { u32 ik_count = 0, collider_count = 0; skele->bone_count = 0; @@ -506,12 +483,13 @@ void skeleton_setup( struct skeleton *skele, mdl_context *mdl, u32 index, box_copy( bone->hitbox, sb->hitbox ); - if( bone->collider ){ - if( collider_count == skele->collider_count ){ + if( bone->collider ) + { + if( collider_count == skele->collider_count ) + { vg_error( "Too many collider bones\n" ); skeleton_fatal_err(); } - collider_count ++; } } @@ -528,10 +506,11 @@ void skeleton_setup( struct skeleton *skele, mdl_context *mdl, u32 index, vg_success( " %u colliders\n", skele->collider_count ); } -static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ){ - for( u32 i=1; ibone_count; i ++ ){ +static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ) +{ + for( u32 i=1; ibone_count; i ++ ) + { struct skeleton_bone *sb = &skele->bones[i]; - v3f p0, p1; v3_copy( sb->co, p0 ); v3_add( p0, sb->end, p1 ); @@ -539,13 +518,12 @@ static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ){ m4x3_mulv( final_mtx[i], p0, p0 ); m4x3_mulv( final_mtx[i], p1, p1 ); - if( sb->flags & k_bone_flag_deform ){ - if( sb->flags & k_bone_flag_ik ){ + if( sb->flags & k_bone_flag_deform ) + { + if( sb->flags & k_bone_flag_ik ) vg_line( p0, p1, 0xff0000ff ); - } - else{ + else vg_line( p0, p1, 0xffcccccc ); - } } else vg_line( p0, p1, 0xff00ffff ); diff --git a/src/world.h b/src/world.h index 066309d..d1d9017 100644 --- a/src/world.h +++ b/src/world.h @@ -179,6 +179,7 @@ struct world_instance ent_list, ent_npc, file_entity_ref, + ent_event, ent_script; GLuint *nonlocal_gates_cubemaps; diff --git a/src/world_entity.c b/src/world_entity.c index 33651d2..927e29c 100644 --- a/src/world_entity.c +++ b/src/world_entity.c @@ -129,8 +129,7 @@ void world_gen_entities_init( world_instance *world ) } else { - clip->_.clip.path = af_str( &world->meta.af, - clip->_.file.pstr_path ); + clip->_.clip.path = af_str( &world->meta.af, clip->_.file.pstr_path ); clip->_.clip.flags = audio->flags; clip->_.clip.any_data = NULL; clip->_.clip.size = 0; @@ -255,77 +254,15 @@ void world_default_spawn_pos( world_instance *world, v3f pos ) } } -entity_call_result ent_volume_call( world_instance *world, ent_call *call ) +static void ent_audio_trigger( ent_audio *audio, v3f sound_co ) { - u32 index = mdl_entity_id_id( call->id ); - ent_volume *volume = af_arritm( &world->ent_volume, index ); - - if( !volume->target ) - return k_entity_call_result_OK; - - if( call->function == k_ent_function_trigger ) - { - call->id = volume->target; - - if( volume->flags & k_ent_volume_flag_particles ) - { - float *co = alloca( sizeof(float)*3 ); - co[0] = vg_randf64(&vg.rand)*2.0f-1.0f; - co[1] = vg_randf64(&vg.rand)*2.0f-1.0f; - co[2] = vg_randf64(&vg.rand)*2.0f-1.0f; - m4x3_mulv( volume->to_world, co, co ); - - call->function = k_ent_function_particle_spawn; - call->data = co; - entity_call( world, call ); - } - else - { - call->function = volume->trigger.event; - entity_call( world, call ); - } - - return k_entity_call_result_OK; - } - else if( call->function == k_ent_function_trigger_leave ) - { - call->id = volume->target; - - if( volume->flags & k_ent_volume_flag_particles ) - vg_warn( "Invalid condition; calling leave on particle volume.\n" ); - else - { - call->function = volume->trigger.event_leave; - entity_call( world, call ); - } - - return k_entity_call_result_OK; - } - - return k_entity_call_result_unhandled; -} - -entity_call_result ent_audio_call( world_instance *world, ent_call *call ) -{ - u32 index = mdl_entity_id_id( call->id ); - ent_audio *audio = af_arritm( &world->ent_audio, index ); - - v3f sound_co; - - if( call->function == k_ent_function_particle_spawn ) - v3_copy( call->data, sound_co ); - else if( call->function == k_ent_function_trigger ) - v3_copy( audio->transform.co, sound_co ); - else - return k_entity_call_result_unhandled; - - float chance = vg_randf64(&vg.rand)*100.0f, - bar = 0.0f; + world_instance *world = &_world.main; + f32 chance = vg_randf64(&vg.rand)*100.0f, + bar = 0.0f; for( u32 i=0; iclip_count; i++ ) { - ent_audio_clip *clip = af_arritm( &world->ent_audio_clip, - audio->clip_start+i ); + ent_audio_clip *clip = af_arritm( &world->ent_audio_clip, audio->clip_start+i ); float mod = world->probabilities[ audio->probability_curve ], p = clip->probability * mod; @@ -398,26 +335,58 @@ entity_call_result ent_audio_call( world_instance *world, ent_call *call ) } vg_audio_unlock(); - return k_entity_call_result_OK; } } - return k_entity_call_result_OK; } +entity_event_result ent_audio_event( ent_event *event ) +{ + world_instance *world = &_world.main; + ent_audio *audio = af_arritm( &world->ent_audio, mdl_entity_id_id( event->recieve_entity_id ) ); + + v3f sound_co; + v3_copy( audio->transform.co, sound_co ); + + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "spawn_particle" ) ) + { + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( mdl_entity_id_type( event->source_entity_id ) == k_ent_volume ) + { + ent_volume *volume = af_arritm( &world->ent_volume, mdl_entity_id_id( event->source_entity_id ) ); + if( volume->flags & k_ent_volume_flag_particles ) + v3_copy( volume->particle_co, sound_co ); + else + { + vg_error( "Audio particle event; caller not an particle volume (%x).\n", event->source_entity_id ); + return k_entity_event_result_invalid; + } + } + else + { + vg_error( "Audio particle event; caller not an ent_volume (%x).\n", event->source_entity_id ); + return k_entity_event_result_invalid; + } + } + else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "play" ) ){} + else return k_entity_event_result_unhandled; + + ent_audio_trigger( audio, sound_co ); + return k_entity_event_result_OK; +} -entity_call_result ent_ccmd_call( world_instance *world, ent_call *call ) +entity_event_result ent_ccmd_event( ent_event *event ) { - if( call->function == k_ent_function_trigger ) + world_instance *world = &_world.main; + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "exec" ) ) { - u32 index = mdl_entity_id_id( call->id ); - ent_ccmd *ccmd = af_arritm( &world->ent_ccmd, index ); + ent_ccmd *ccmd = af_arritm( &world->ent_ccmd, mdl_entity_id_id( event->recieve_entity_id )); const char *cmd_text = af_str( &world->meta.af, ccmd->pstr_command ); vg_info( "ccmd: %s\n", cmd_text ); vg_execute_console_input( cmd_text, 0 ); - return k_entity_call_result_OK; + return k_entity_event_result_OK; } else - return k_entity_call_result_unhandled; + return k_entity_event_result_unhandled; } /* @@ -485,7 +454,7 @@ void entity_bh_expand_bound( void *user, boxf bound, u32 item_index ) vg_fatal_error( "Programming error\n" ); } -float entity_bh_centroid( void *user, u32 item_index, int axis ) +f32 entity_bh_centroid( void *user, u32 item_index, int axis ) { world_instance *world = user; @@ -632,13 +601,7 @@ void world_entity_start( world_instance *world, vg_msg *sav ) { ent_audio *audio = af_arritm(&world->ent_audio,i); if( audio->flags & AUDIO_FLAG_AUTO_START ) - { - ent_call call; - call.data = NULL; - call.function = k_ent_function_trigger; - call.id = mdl_entity_id( k_ent_audio, i ); - entity_call( world, &call ); - } + ent_audio_trigger( audio, audio->transform.co ); } /* read savedata @@ -648,12 +611,8 @@ void world_entity_start( world_instance *world, vg_msg *sav ) { ent_challenge *challenge = af_arritm( &world->ent_challenge, i ); const char *alias = af_str( &world->meta.af, challenge->pstr_alias ); - - u32 result; - vg_msg_getkvintg( sav, alias, k_vg_msg_u32, &result, NULL ); - - if( result ) - _ent_challenge_complete( challenge ); + vg_msg_getkvintg( sav, alias, k_vg_msg_u32, &challenge->status, NULL ); + _ent_challenge_clear( challenge ); } vg_msg routes_block = *sav; @@ -674,38 +633,16 @@ void world_entity_start( world_instance *world, vg_msg *sav ) f32 sections[ route->checkpoints_count ]; vg_msg_cmd cmd; if( vg_msg_getkvcmd( &route_info, "sections", &cmd ) ) - { vg_msg_cast( cmd.value, cmd.code, sections, k_vg_msg_f32 | vg_msg_count_bits(route->checkpoints_count) ); - } else - { for( u32 j=0; jcheckpoints_count; j ++ ) sections[j] = 0.0f; - } for( u32 j=0; jcheckpoints_count; j ++ ) { ent_checkpoint *cp = af_arritm( &world->ent_checkpoint, route->checkpoints_start + j ); cp->best_time = sections[j]; } - - /* LEGACY: check if steam achievements can give us a medal */ - if( steam_ready && steam_stats_ready ) - { - for( u32 j=0; jname, af_str(&world->meta.af,route->pstr_name))) - { - steamapi_bool set = 0; - if( SteamAPI_ISteamUserStats_GetAchievement( hSteamUserStats, inf->achievement_id, &set ) ) - { - if( set ) - route->flags |= k_ent_route_flag_achieve_silver; - } - } - } - } } } } @@ -749,3 +686,91 @@ void world_entity_serialize( world_instance *world, vg_msg *sav ) vg_msg_end_frame( sav ); } } + +void _world_raise_event( u32 caller, const char *event_alias ) +{ + world_instance *world = &_world.main; + u32 event_alias_hash = vg_strdjb2( event_alias ); + + if( mdl_entity_id_type( caller ) != k_ent_volume ) + vg_low( "%x raises [src_event '%s']\n", caller, event_alias ); + + for( u32 i=0; ient_event ); i ++ ) + { + ent_event *event = af_arritm( &world->ent_event, i ); + if( event->source_entity_id != caller ) + continue; + + if( af_str_eq( &world->meta.af, event->pstr_source_event, event_alias, event_alias_hash ) ) + { + u32 type = mdl_entity_id_type( event->recieve_entity_id ), + index = mdl_entity_id_id( event->recieve_entity_id ); + + entity_event_result (*table[])( ent_event *event ) = + { + [k_ent_audio] = ent_audio_event, + [k_ent_skateshop] = ent_skateshop_event, + [k_ent_objective] = ent_objective_event, + [k_ent_ccmd] = ent_ccmd_event, + [k_ent_gate] = ent_gate_event, + [k_ent_challenge] = ent_challenge_event, + [k_ent_route] = ent_route_event, + [k_ent_region] = ent_region_event, + [k_ent_glider] = ent_glider_event, + [k_ent_water] = ent_water_event, + [k_ent_npc] = ent_npc_event, + [k_ent_script] = _ent_script_world_event, + }; + + if( type >= VG_ARRAY_LEN(table) ) + { + vg_error( "call to entity type: %u is out of range\n", type ); + return; + } + + if( !table[type] ) + { + vg_error( "Entity type %u does not have a call handler, but was called anyway\n", type ); + return; + } + + if( event->flags & k_ent_event_data_const_string ) + { + vg_info( "[event '%s'] %x -> %x ('%s') with '%s'\n", + af_str( &world->meta.af, event->pstr_source_event ), event->source_entity_id, + event->recieve_entity_id, af_str( &world->meta.af, event->pstr_recieve_event ), + af_str( &world->meta.af, event->data.const_pstr ) ); + } + else if( event->flags & k_ent_event_data_const_i32 ) + { + vg_info( "[event '%s'] %x -> %x ('%s') with %d\n", + af_str( &world->meta.af, event->pstr_source_event ), event->source_entity_id, + event->recieve_entity_id, af_str( &world->meta.af, event->pstr_recieve_event ), + event->data.const_i32 ); + } + else if( event->flags & k_ent_event_data_const_f32 ) + { + vg_info( "[event '%s'] %x -> %x ('%s') with %ff\n", + af_str( &world->meta.af, event->pstr_source_event ), event->source_entity_id, + event->recieve_entity_id, af_str( &world->meta.af, event->pstr_recieve_event ), + event->data.const_f32 ); + } + else if( event->flags & k_ent_event_data_const_f32 ) + { + vg_info( "[event '%s'] %x -> %x ('%s') void\n", + af_str( &world->meta.af, event->pstr_source_event ), event->source_entity_id, + event->recieve_entity_id, af_str( &world->meta.af, event->pstr_recieve_event )); + } + + enum entity_event_result res = table[type]( event ); + + if( res == k_entity_event_result_unhandled ) + { + vg_warn( "Call to entity %x#%x was unhandled (no event '%s').\n", type, index, + af_str( &world->meta.af, event->pstr_recieve_event ) ); + } + else if( res == k_entity_event_result_invalid ) + vg_warn( "Call to entity %x#%x invalid.\n", type, index ); + } + } +} diff --git a/src/world_entity.h b/src/world_entity.h index edc85e1..7e392fe 100644 --- a/src/world_entity.h +++ b/src/world_entity.h @@ -11,9 +11,9 @@ void world_default_spawn_pos( world_instance *world, v3f pos ); void world_entity_start( world_instance *world, vg_msg *sav ); void world_entity_serialize( world_instance *world, vg_msg *sav ); -entity_call_result ent_volume_call( world_instance *world, ent_call *call ); -entity_call_result ent_audio_call( world_instance *world, ent_call *call ); -entity_call_result ent_ccmd_call( world_instance *world, ent_call *call ); +//entity_call_result ent_volume_call( world_instance *world, ent_call *call ); +//entity_call_result ent_audio_call( world_instance *world, ent_call *call ); +//entity_call_result ent_ccmd_call( world_instance *world, ent_call *call ); void entity_bh_expand_bound( void *user, boxf bound, u32 item_index ); float entity_bh_centroid( void *user, u32 item_index, int axis ); @@ -24,3 +24,4 @@ void entity_bh_closest( void *user, u32 item_index, v3f point, v3f closest ); void update_ach_models(void); extern bh_system bh_system_entity_list; +void _world_raise_event( u32 caller, const char *event_alias ); diff --git a/src/world_gate.c b/src/world_gate.c index 086aef4..c81a8a4 100644 --- a/src/world_gate.c +++ b/src/world_gate.c @@ -294,20 +294,23 @@ u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ) return 0; } -entity_call_result ent_gate_call( world_instance *world, ent_call *call ) +entity_event_result ent_gate_event( ent_event *event ) { - u32 index = mdl_entity_id_id( call->id ); - ent_gate *gate = af_arritm( &world->ent_gate, index ); - - if( call->function == 0 ) /* unlock() */ - { - gate->flags &= ~k_ent_gate_locked; - return k_entity_call_result_OK; - } - else + world_instance *world = &_world.main; + ent_gate *gate = af_arritm( &world->ent_gate, mdl_entity_id_id( event->recieve_entity_id ) ); + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "lock" ) ) { - return k_entity_call_result_unhandled; + // TODO: Make this dynamiclly fetched from a handler for the entity itself. (or not, fuck you) + if( event->flags == k_ent_event_data_const_i32 ) + { + if( event->data.const_i32 ) gate->flags &= ~((u32)k_ent_gate_locked); + else gate->flags |= (u32)k_ent_gate_locked; + return k_entity_event_result_OK; + } + else + return k_entity_event_result_invalid; } + else return k_entity_event_result_unhandled; } void nonlocal_gate_cubemap_path( addon_id world_addon_id, const char *gate_key, char path[256] ) diff --git a/src/world_gate.h b/src/world_gate.h index 135d856..a11fb00 100644 --- a/src/world_gate.h +++ b/src/world_gate.h @@ -27,7 +27,7 @@ int render_gate( world_instance *world, world_instance *world_inside, int gate_intersect( ent_gate *gate, v3f pos, v3f last ); u32 world_intersect_gates( world_instance *world, v3f pos, v3f last ); -entity_call_result ent_gate_call( world_instance *world, ent_call *call ); +entity_event_result ent_gate_event( ent_event *event ); void ent_gate_get_mdl_mtx( ent_gate *gate, m4x3f mmdl ); void world_link_gates( world_instance *world ); diff --git a/src/world_load.c b/src/world_load.c index b25e859..9eb7434 100644 --- a/src/world_load.c +++ b/src/world_load.c @@ -107,15 +107,14 @@ static void world_instance_load_mdl( world_instance *world, const char *path, vo AF_LOAD_ARRAY_STRUCT( af, &world->ent_ccmd, ent_ccmd, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_objective, ent_objective, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_challenge, ent_challenge, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_relay, ent_relay, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_cubemap, ent_cubemap, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_miniworld, ent_miniworld, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_prop, ent_prop, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_glider, ent_glider, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_list, ent_list, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->file_entity_ref, file_entity_ref, heap ); AF_LOAD_ARRAY_STRUCT( af, &world->ent_script, ent_script, heap ); - AF_LOAD_ARRAY_STRUCT( af, &world->ent_npc, ent_npc, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_event, ent_event, heap ); + AF_LOAD_ARRAY_STRUCT( af, &world->ent_npc, ent_npc, heap ); } array_file_ptr infos; @@ -530,7 +529,7 @@ void _world_loader_set_addon( addon_id addon_id ) addon_reg *reg = addon_details(addon_id); if( reg->flags & ADDON_REG_MTZERO ) { - u64 status = _skaterift_script_nugget_status( "ch2s5_view" ); + u64 status = _skaterift_atom_status( "ch2s5_view" ); /* we've seen the cutscene already (1), or about to play it on world load (3). * both of those statuses mean we load 'main'. */ diff --git a/src/world_render.c b/src/world_render.c index c60ecf1..5bd61c4 100644 --- a/src/world_render.c +++ b/src/world_render.c @@ -500,11 +500,16 @@ static void world_render_challenges( world_instance *world, struct world_pass *p u32 objective_count = 0, challenge_count = 0; + bool any_order = 0; + if( (_world.event == k_world_event_challenge) && (_world.challenge_state != k_challenge_state_none) ) { u32 challenge_index = mdl_entity_id_id( _world.active_challenge_id ); ent_challenge *challenge = af_arritm( &world->ent_challenge, challenge_index ); + if( challenge->flags & k_ent_challenge_any_order ) + any_order = 1; + shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } ); challenge_list[ challenge_count ++ ] = challenge_index; @@ -564,7 +569,7 @@ static void world_render_challenges( world_instance *world, struct world_pass *p vg_slewf(&objective->transform.s[0], target, vg.time_frame_delta*4.0f); scale = vg_smoothstepf( objective->transform.s[0] ); - if( (objective == _world.challenge_target) || passed ) + if( (objective == _world.challenge_target) || passed || any_order ) shader_scene_fxglow_uUvOffset( (v2f){ 16.0f/256.0f, 0.0f } ); else shader_scene_fxglow_uUvOffset( (v2f){ 8.0f/256.0f, 0.0f } ); diff --git a/src/world_routes.c b/src/world_routes.c index 0abcfef..2d4ccc4 100644 --- a/src/world_routes.c +++ b/src/world_routes.c @@ -26,7 +26,8 @@ void world_routes_clear( world_instance *world ) { - for( u32 i=0; ient_route ); i++ ){ + for( u32 i=0; ient_route ); i++ ) + { ent_route *route = af_arritm( &world->ent_route, i ); route->active_checkpoint = 0xffff; } @@ -34,7 +35,6 @@ void world_routes_clear( world_instance *world ) for( u32 i=0; ient_gate ); i++ ) { ent_gate *rg = af_arritm( &world->ent_gate, i ); - if( !(rg->flags & k_ent_gate_nonlocal) ) { rg->timing_version = 0; @@ -122,6 +122,7 @@ static void world_routes_time_lap( u32 route_index ) if( clean ) route->flags |= k_ent_route_flag_achieve_gold; ent_region_re_eval( world ); +#if 0 struct ent_script_event event; struct script_event_completion_changed inf = { .entity_id = mdl_entity_id( k_ent_route, route_index ), @@ -130,6 +131,7 @@ static void world_routes_time_lap( u32 route_index ) event.type = k_escript_event_completion_changed; event.info = &inf; ent_script_propogate_event( world, &event ); +#endif /* for steam achievements. */ if( route->anon.official_track_id != 0xffffffff ) diff --git a/src/world_volumes.c b/src/world_volumes.c index 6d7d859..c6b3dd2 100644 --- a/src/world_volumes.c +++ b/src/world_volumes.c @@ -8,8 +8,9 @@ void world_volumes_update( world_instance *world, v3f pos ) u32 j=0; for( u32 i=0; i<_world.active_trigger_volume_count; i++ ) { - i32 idx = _world.active_trigger_volumes[i]; - ent_volume *volume = af_arritm( &world->ent_volume, idx ); + i32 index = _world.active_trigger_volumes[i]; + u32 id = mdl_entity_id( k_ent_volume, index ); + ent_volume *volume = af_arritm( &world->ent_volume, index ); bool in_volume = 1; @@ -23,9 +24,10 @@ void world_volumes_update( world_instance *world, v3f pos ) if( in_volume ) { - _world.active_trigger_volumes[ j ++ ] = idx; + _world.active_trigger_volumes[ j ++ ] = index; boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}}; vg_line_boxf_transformed( volume->to_world, cube, 0xff00ccff ); + _world_raise_event( id, "stay" ); } else { @@ -39,21 +41,7 @@ void world_volumes_update( world_instance *world, v3f pos ) } } } - else - { - /* - * LEGACY BEHAVIOUR: < v104 does not have leave events - */ - if( world->meta.version >= 104 ) - { - ent_call basecall; - basecall.function = k_ent_function_trigger_leave; - basecall.id = mdl_entity_id( k_ent_volume, idx ); - basecall.data = NULL; - - entity_call( world, &basecall ); - } - } + _world_raise_event( id, "leave" ); } } _world.active_trigger_volume_count = j; @@ -96,17 +84,18 @@ void world_volumes_update( world_instance *world, v3f pos ) if( volume->flags & k_ent_volume_flag_particles ) { - vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff ); - for( int j=0; jto_world, co, volume->particle_co ); + _world_raise_event( id, "particle" ); } + + vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff ); + vg_line_cross( volume->particle_co, 0xffa0a0a0, 1.0f ); } else { @@ -132,24 +121,20 @@ void world_volumes_update( world_instance *world, v3f pos ) { if( localplayer.subsystem == k_player_subsystem_walk ) { - if( world_set_event( k_world_event_interact ) ) + if( _world.event == k_world_event_none ) { - gui_helper_reset( k_gui_helper_mode_black_bars ); - vg_str text; - if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) - vg_strcat( &text, af_str( &world->meta.af, volume->interact.pstr_text ) ); - _world_volumes.active_volume_interact = volume; + if( world_set_event( k_world_event_interact ) ) + { + gui_helper_reset( k_gui_helper_mode_black_bars ); + vg_str text; + if( gui_new_helper( input_button_list[k_srbind_maccept], &text )) + vg_strcat( &text, af_str( &world->meta.af, volume->interact.pstr_text ) ); + _world_volumes.active_volume_interact = id; + } } } } - else - { - ent_call basecall; - basecall.function = 0; - basecall.id = id; - basecall.data = NULL; - entity_call( world, &basecall ); - } + _world_raise_event( id, "enter" ); _world.active_trigger_volumes[ _world.active_trigger_volume_count ++ ] = index; } else @@ -160,36 +145,30 @@ next_volume:; if( _world.event == k_world_event_interact ) { - ent_volume *volume = _world_volumes.active_volume_interact; + u32 id = _world_volumes.active_volume_interact; + ent_volume *volume = af_arritm( &world->ent_volume, mdl_entity_id_id( id ) ); if( volume->flags & k_ent_volume_flag_disabled ) { /* might get turned off by another system eg scripts */ if( world_clear_event( k_world_event_interact ) ) { - _world_volumes.active_volume_interact = NULL; + _world_volumes.active_volume_interact = 0; gui_helper_reset( k_gui_helper_mode_clear ); } } else if( button_down( k_srbind_maccept ) ) { - if( volume->target ) + srinput.state = k_input_state_resume; + if( !(volume->flags & k_ent_volume_flag_repeatable) ) { - srinput.state = k_input_state_resume; - if( !(volume->flags & k_ent_volume_flag_repeatable) ) + if( world_clear_event( k_world_event_interact ) ) { - if( world_clear_event( k_world_event_interact ) ) - { - _world_volumes.active_volume_interact = NULL; - gui_helper_reset( k_gui_helper_mode_clear ); - } + _world_volumes.active_volume_interact = 0; + gui_helper_reset( k_gui_helper_mode_clear ); } - - ent_call call; - call.data = NULL; - call.function = volume->interact.activate_event; - call.id = volume->target; - entity_call( &_world.main, &call ); } + + _world_raise_event( id, "use" ); } } } diff --git a/src/world_volumes.h b/src/world_volumes.h index f9a7481..06ccf5f 100644 --- a/src/world_volumes.h +++ b/src/world_volumes.h @@ -4,7 +4,7 @@ struct _world_volumes { - ent_volume *active_volume_interact; + u32 active_volume_interact; } extern _world_volumes; diff --git a/src/world_water.c b/src/world_water.c index f9ced3f..e9e74ef 100644 --- a/src/world_water.c +++ b/src/world_water.c @@ -265,13 +265,13 @@ bool world_water_player_safe( world_instance *world, f32 allowance ) return 1; } -entity_call_result ent_water_call( world_instance *world, ent_call *call ) +entity_event_result ent_water_event( ent_event *event ) { - if( call->function == 0 ) + world_instance *world = &_world.main; + if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "drown" ) ) { world_water_drown(); - return k_entity_call_result_OK; + return k_entity_event_result_OK; } - - return k_entity_call_result_unhandled; + else return k_entity_event_result_unhandled; } diff --git a/src/world_water.h b/src/world_water.h index 7ff9af5..b2d753d 100644 --- a/src/world_water.h +++ b/src/world_water.h @@ -14,5 +14,5 @@ void world_water_init(void); void water_set_surface( world_instance *world, f32 height ); void render_water_texture( world_instance *world, vg_camera *cam ); void render_water_surface( world_instance *world, vg_camera *cam ); -entity_call_result ent_water_call( world_instance *world, ent_call *call ); +entity_event_result ent_water_event( ent_event *event ); bool world_water_player_safe( world_instance *world, f32 allowance );