("blank2",c_uint32)]
#}
+class volume_interact(Structure):
+#{
+ _fields_ = [("event",c_uint32),
+ ("pstr_text",c_int32)]
+#}
+
class volume_union(Union):
#{
_fields_ = [("trigger",volume_trigger),
- ("particles",volume_particles)]
+ ("particles",volume_particles),
+ ("interact",volume_interact)]
#}
class ent_volume(Structure):
subtype: bpy.props.EnumProperty(
name="Subtype",
items=[('0','Trigger',''),
- ('1','Particles (0.1s)','')]
+ ('1','Particles (0.1s)',''),
+ ('2','Interact','')]
)
target: bpy.props.PointerProperty( \
target_event_leave: bpy.props.IntProperty( name="Leave Ev", default=-1 )
auto_run: bpy.props.BoolProperty( name="Auto Run" )
+ text: bpy.props.StringProperty()
@staticmethod
def inspect_target( layout, data, propname, evs = ['_event'], text='' ):#{
#}
@staticmethod
- def sr_inspector( layout, data ):#{
+ def sr_inspector( layout, data ):
+ #{
layout.prop( data[0], 'subtype' )
SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', ['_event','_event_leave'] )
- layout.prop( data[0], 'auto_run' )
+ if data[0].subtype == '2':
+ layout.prop( data[0], 'text' )
#}
#}
data = obj.SR_data.ent_volume[0]
- if data.subtype == '0':#{
- cv_draw_ucube( obj.matrix_world, (0,1,0), Vector((0.99,0.99,0.99)) )
+ if data.subtype == '0':
+ cc = (0,1,0)
+ elif data.subtype == '1':
+ cc = (1,1,0)
+ elif data.subtype == '2':
+ cc = (1,0,0)
+ else:
+ cc = (0,0,0)
- if data.target:#{
- cv_draw_arrow( obj.location, data.target.location, (1,1,1) )
- #}
- #}
- elif data.subtype == '1':#{
- cv_draw_ucube( obj.matrix_world, (1,1,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) )
- #}
+ if data.target:
+ #{
+ cv_draw_arrow( obj.location, data.target.location, (1,1,1) )
#}
#}
#}
sr_ent_push( audio )
#}
- elif ent_type == 'ent_volume':#{
+ elif ent_type == 'ent_volume':
+ #{
obj_data = obj.SR_data.ent_volume[0]
volume = ent_volume()
- volume.flags = int(obj_data.subtype)
- if obj_data.auto_run:
- volume.flags |= 0x4
+ volume.flags = 0x00
+
+ if obj_data.subtype == '1':
+ volume.flags |= 0x1
+
+ #if obj_data.auto_run:
+ # volume.flags |= 0x4
compile_obj_transform( obj, volume.transform )
- if obj_data.target:#{
+ 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
#}
.path = "sound/gate_ambient.ogg"
};
+audio_clip audio_wood_break =
+{
+.path = "sound/woodbreak.ogg"
+};
+
audio_clip audio_rewind[] = {
{ .path = "sound/rewind_start.ogg" },
{ .path = "sound/rewind_end_1.5.ogg" },
audio_clip_loadn( &audio_gate_pass, 1, NULL );
audio_clip_loadn( &audio_gate_lap, 1, NULL );
audio_clip_loadn( &audio_gate_ambient, 1, NULL );
+ audio_clip_loadn( &audio_wood_break, 1, NULL );
audio_clip_loadn( audio_jumps, VG_ARRAY_LEN(audio_jumps), NULL );
audio_clip_loadn( audio_lands, VG_ARRAY_LEN(audio_lands), NULL );
typedef struct ent_audio_clip ent_audio_clip;
typedef struct volume_particles volume_particles;
typedef struct volume_trigger volume_trigger;
+typedef struct volume_interact volume_interact;
typedef struct ent_volume ent_volume;
typedef struct ent_audio ent_audio;
typedef struct ent_marker ent_marker;
i32 event, event_leave;
};
+struct volume_interact
+{
+ i32 activate_event;
+ u32 pstr_text;
+};
+
enum ent_volume_flag {
k_ent_volume_flag_particles = 0x1,
k_ent_volume_flag_disabled = 0x2,
- k_ent_volume_flag_autorun = 0x4
+ k_ent_volume_flag_interact = 0x8
};
-struct ent_volume{
+struct ent_volume
+{
mdl_transform transform;
m4x3f to_world, to_local;
u32 flags;
u32 target;
- union{
+ union
+ {
volume_trigger trigger;
+ volume_interact interact;
volume_particles particles;
};
};
u32 camera_id;
u32 status;
- u32 visible_when_unlocked_id;
};
struct ent_relay {
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( "ch4s3" );
+ world_map.selected_superworld_locked = !_skaterift_script_nugget_status( "unlock_venus" );
}
if( world_map.selected_superworld_locked )
bool unlocked = 1;
if( reg->flags & ADDON_REG_MTZERO )
- unlocked = _skaterift_script_nugget_status( "ch2s1" )?1:0;
+ unlocked = _skaterift_script_nugget_status( "unlock_mtzero" )?1:0;
if( reg->flags & ADDON_REG_CITY )
- unlocked = _skaterift_script_nugget_status( "ch3s1" )?1:0;
+ unlocked = _skaterift_script_nugget_status( "unlock_city" )?1:0;
if( reg->flags & ADDON_REG_VALLEY )
- unlocked = _skaterift_script_nugget_status( "ch4s1a" )?1:0;
+ unlocked = _skaterift_script_nugget_status( "unlock_valley" )?1:0;
menu.world_list_entries[ menu.world_list_display_count ] = unlocked? reg: NULL;
{
glEnable(GL_BLEND);
glDisable(GL_DEPTH_TEST);
- glDepthMask(GL_FALSE);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendEquation(GL_FUNC_ADD);
.width = 0.25f
};
-void particle_spawn( particle_system *sys, v3f co, v3f v,
- f32 lifetime, u32 colour )
+void particle_spawn( particle_system *sys, v3f co, v3f v, f32 lifetime, u32 colour )
{
- if( sys->alive == sys->max ) return;
+ if( sys->alive == sys->max )
+ return;
particle *p = &sys->array[ sys->alive ++ ];
v3_copy( co, p->co );
v3f co, v3f dir, f32 angle, f32 speed,
f32 lifetime, u32 colour )
{
- if( sys->alive == sys->max ) return;
+ if( sys->alive == sys->max )
+ return;
particle *p = &sys->array[ sys->alive ++ ];
--- /dev/null
+void _explode_template_boom( ent_script_event *event )
+{
+ ent_list_set_visible( event->world, event->entity_list, 0 );
+
+ v3f where = {0,0,0};
+
+ ent_list *list = event->entity_list;
+ for( u32 i=0; i<list->entity_ref_count; i ++ )
+ {
+ file_entity_ref *ref = af_arritm( &event->world->file_entity_ref, list->entity_ref_start + i );
+
+ u32 type = mdl_entity_id_type( ref->entity_id ),
+ index = mdl_entity_id_id( ref->entity_id );
+
+ if( type == k_ent_marker )
+ {
+ ent_marker *marker = af_arritm( &event->world->ent_marker, 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();
+}
+
+static bool _skaterift_script_blocker_break_template( ent_script_event *event,
+ const struct generic_cutscene *cutscene_template,
+ const char *once_nugget_trigger )
+{
+ static const struct generic_cutscene cutscene =
+ {
+ .metascene_path = "metascenes/unlock_docks.ms",
+ .freeze_player = 1,
+ };
+ generic_cutscene_wrapper( &cutscene, event );
+
+ if( on_function_trigger( event, 1 ) )
+ {
+ vg_error( "Show required objectives here\n" );
+ }
+
+ if( on_function_trigger( event, 2 ) )
+ {
+ if( on_nugget_once( event, "unlock_docks_view" ) )
+ {
+ play_generic_cutscene( event );
+ }
+ else
+ {
+ ent_list_set_visible( event->world, event->entity_list, 0 );
+ }
+ }
+
+ if( on_cutscene_marker( event, "$break" ) )
+ {
+ }
+
+ return 1;
+}
if( skaterift.achievements & 0x8 )
prop->flags &= ~0x1;
+#if 0
if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "main_island_block" ) )
if( unlock_mtzero )
prop->flags |= k_prop_flag_hidden;
if( AF_STR_EQ( &world->meta.af, prop->pstr_alias, "valley_block" ) )
if( unlock_valley )
prop->flags |= k_prop_flag_hidden;
+#endif
}
u32 spawns_allowed = 0;
return 0;
}
+static void _hub_blocker_template( ent_script_event *event, const char *unlock, const char *guard )
+{
+ u64 status;
+ if( on_nugget_changed( event, unlock, &status ) )
+ {
+ if( status )
+ {
+ if( on_nugget_once( event, guard ) )
+ {
+ play_generic_cutscene( event );
+ }
+ else
+ {
+ ent_list_set_visible( event->world, event->entity_list, 0 );
+ }
+ }
+ }
+
+ if( on_cutscene_marker( event, "$break" ) )
+ {
+ _explode_template_boom( event );
+ }
+
+}
+
+static bool _skaterift_script_unlock_mtzero( ent_script_event *event )
+{
+ static const struct generic_cutscene cutscene =
+ {
+ .metascene_path = "metascenes/unlock_mtzero.ms",
+ .freeze_player = 1,
+ };
+ generic_cutscene_wrapper( &cutscene, event );
+ _hub_blocker_template( event, "unlock_mtzero", "unlock_mtzero_view" );
+ return 1;
+}
+
+static bool _skaterift_script_unlock_city( ent_script_event *event )
+{
+ static const struct generic_cutscene cutscene =
+ {
+ .metascene_path = "metascenes/unlock_city.ms",
+ .freeze_player = 1,
+ };
+ generic_cutscene_wrapper( &cutscene, event );
+ _hub_blocker_template( event, "unlock_city", "unlock_city_view" );
+ return 1;
+}
+
+static bool _skaterift_script_unlock_valley( ent_script_event *event )
+{
+ static const struct generic_cutscene cutscene =
+ {
+ .metascene_path = "metascenes/unlock_valley.ms",
+ .freeze_player = 1,
+ };
+ generic_cutscene_wrapper( &cutscene, event );
+ _hub_blocker_template( event, "unlock_valley", "unlock_valley_view" );
+ return 1;
+}
if( on_cutscene_marker( event, "$break" ) )
{
- ent_list_set_visible( event->world, event->entity_list, 0 );
+ _explode_template_boom( event );
}
return 1;
_skaterift_script_nugget_set( "unlock_mtzero", 1 );
}
- if( cs_event == k_generic_cutscene_event_end )
+ return 1;
+}
+
+static bool _skaterift_script_final_portal( ent_script_event *event )
+{
+ u64 status;
+ if( on_nugget_changed( event, "unlock_mtzero", &status ) )
{
- /* move level to the hub */
- }
+ world_instance *world = event->world;
+ file_entity_ref *ref = af_arritm( &world->file_entity_ref, event->entity_list->entity_ref_start );
+
+ u32 type = mdl_entity_id_type( ref->entity_id ),
+ index = mdl_entity_id_id( ref->entity_id );
+ ent_gate *gate = af_arritm( &event->world->ent_gate, index );
+ if( status ) gate->flags &= ~((u32)k_ent_gate_locked);
+ else gate->flags |= (u32)k_ent_gate_locked;
+ }
return 1;
}
return cs_event;
}
+#include "scripts/blocker_break.c"
#include "scripts/heaven.c"
#include "scripts/hub.c"
#include "scripts/tutorial_island.c"
{ "ch1s5", _skaterift_script_ch1s5 },
{ "ch1s6a", _skaterift_script_ch1s6a },
{ "unlock_docks", _skaterift_script_unlock_docks },
+ { "final_portal", _skaterift_script_final_portal },
+
+ { "unlock_mtzero", _skaterift_script_unlock_mtzero },
+ { "unlock_city", _skaterift_script_unlock_city },
+ { "unlock_valley", _skaterift_script_unlock_valley },
+
{ NULL }
};
{ "unlock_docks_view" },
{ "unlock_mtzero" },
+ { "unlock_mtzero_view" },
+
{ "unlock_city" },
- { "unlock_valley" }
+ { "unlock_city_view" },
+
+ { "unlock_valley" },
+ { "unlock_valley_view" },
+
+ { "unlock_venus" },
};
u64 _skaterift_script_nugget_status( const char *nugget_alias )
k_world_event_none = 0,
k_world_event_challenge,
k_world_event_shop,
- k_world_event_route_leaderboard
+ k_world_event_route_leaderboard,
+ k_world_event_interact
}
event;
}
ent_region_re_eval( world );
- world_volumes_start( world );
ent_script_start( world );
}
#include "world_volumes.h"
-void world_volumes_start( world_instance *world )
-{
- for( u32 i=0; i<af_arrcount(&world->ent_volume); i ++ )
- {
- ent_volume *volume = af_arritm( &world->ent_volume, i );
-
- if( volume->flags & k_ent_volume_flag_autorun )
- {
- ent_call basecall;
- basecall.id = mdl_entity_id( k_ent_volume, i );
- basecall.data = NULL;
- basecall.function = 0;
- entity_call( world, &basecall );
- }
- }
-}
+struct _world_volumes _world_volumes;
void world_volumes_update( world_instance *world, v3f pos )
{
}
else
{
- /*
- * LEGACY BEHAVIOUR: < v104 does not have leave events
- */
- if( world->meta.version >= 104 )
+ if( volume->flags & k_ent_volume_flag_interact )
{
- 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 );
+ if( _world.event == k_world_event_interact )
+ {
+ if( world_clear_event( k_world_event_interact ) )
+ {
+ gui_helper_reset( k_gui_helper_mode_clear );
+ }
+ }
+ }
+ 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 );
+ }
}
}
}
continue;
ent_volume *volume = af_arritm( &world->ent_volume, index );
+ vg_line_cross( volume->to_world[3], 0xffffffff, 1.0f );
+ boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
if( volume->flags & k_ent_volume_flag_disabled )
+ {
+ vg_line_boxf_transformed( volume->to_world, cube, 0xff000000 );
continue;
+ }
- boxf cube = {{-1.0f,-1.0f,-1.0f},{1.0f,1.0f,1.0f}};
if( volume->flags & k_ent_volume_flag_particles )
{
vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
(fabsf(local[1]) <= 1.0f) &&
(fabsf(local[2]) <= 1.0f) )
{
- ent_call basecall;
- basecall.function = 0;
- basecall.id = id;
- basecall.data = NULL;
-
- entity_call( world, &basecall );
- _world.active_trigger_volumes[
- _world.active_trigger_volume_count ++ ] = index;
+ if( volume->flags & k_ent_volume_flag_interact )
+ {
+ 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 = volume;
+ }
+ }
+ else
+ {
+ ent_call basecall;
+ basecall.function = 0;
+ basecall.id = id;
+ basecall.data = NULL;
+ entity_call( world, &basecall );
+ }
+ _world.active_trigger_volumes[ _world.active_trigger_volume_count ++ ] = index;
}
else
vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );
}
next_volume:;
}
+
+ if( _world.event == k_world_event_interact )
+ {
+ if( button_down( k_srbind_maccept ) )
+ {
+ ent_volume *volume = _world_volumes.active_volume_interact;
+ if( volume->target )
+ {
+ srinput.state = k_input_state_resume;
+
+ ent_call call;
+ call.data = NULL;
+ call.function = volume->interact.activate_event;
+ call.id = volume->target;
+ entity_call( &_world.main, &call );
+
+ if( world_clear_event( k_world_event_interact ) )
+ {
+ _world_volumes.active_volume_interact = NULL;
+ gui_helper_reset( k_gui_helper_mode_clear );
+ }
+ }
+ }
+ }
}
#include "world.h"
#include "vg/vg_bvh.h"
+struct _world_volumes
+{
+ ent_volume *active_volume_interact;
+}
+extern _world_volumes;
+
void world_volumes_update( world_instance *world, v3f pos );
void world_volumes_start( world_instance *world );