('ent_npc', 'npc', '', 27 ),
# reserved 28.. armature
('ent_script', 'Script', '', 29 ),
- ('ent_cutscene', 'Cutscene', '', 30 ),
+ ('ent_atom', 'Atom', '', 30 ),
+ ('ent_cutscene', 'Cutscene', '', 31 ),
]
MDL_VERSION_NR = 109
_fields_ = [("entity_ref_start",c_uint16),("entity_ref_count",c_uint16),
("alias_type",c_uint8),("none0",c_uint8),("none1",c_uint8),("none2",c_uint8),
("pstr_alias",c_uint32) ]
+ sr_functions = { 'visible': 0x01 }
#}
# used in ent_list
("flags",c_uint32)]
#}
+class ent_atom(Structure):
+#{
+ _fields_ = [("pstr_alias",c_uint32),
+ ("flags",c_uint32)]
+ sr_functions = { 'set': 0x1, 'pass_equal': 0x1, 'pass_greater': 0x1, 'set_or': 0x1, 'set_and': 0x1 }
+ sr_events = [ 'changed', 'true', 'false' ]
+#}
+
+class ent_cutscene(Structure):
+#{
+ _fields_ = [("pstr_path",c_uint32),
+ ("flags",c_uint32)]
+
+ sr_functions = { 'play': 0x00 }
+ sr_events = [ 'start', 'end' ]
+#}
+
class ent_water(Structure):
#{
_fields_ = [("transform",mdl_transform),
def sr_filter_ent_type( obj, ent_types ):
#{
- # 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 (ent_types == None) or (obj_ent_type( obj ) in ent_types)
- #}
- #}
- #}
-
- return False
+ return (ent_types == None) or (obj_ent_type( obj ) in ent_types)
#}
def v4_dot( a, b ):#{
# poll=lambda self,obj: sr_filter_ent_type(obj,['ent_list']))
#}
+class SR_OBJECT_ENT_ATOM(bpy.types.PropertyGroup):
+#{
+ alias: bpy.props.StringProperty( name="Alias" )
+ mundial: bpy.props.BoolProperty( name="Global" )
+ scrap: bpy.props.BoolProperty( name="Scrap" )
+#}
+
+class SR_OBJECT_ENT_CUTSCENE( bpy.types.PropertyGroup ):
+#{
+ path: bpy.props.StringProperty( name="Path" )
+ freeze_player: bpy.props.BoolProperty( name="Freeze Player" )
+#}
+
class SR_OBJECT_ENT_LOGIC(bpy.types.PropertyGroup):
#{
tipo: bpy.props.EnumProperty( name='Type',\
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_atom: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_ATOM)
+ ent_cutscene: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CUTSCENE)
ent_type: bpy.props.EnumProperty(
name="Type",
blf.draw(0, F"'{data.script_alias}'" )
blf.color(0,1.0,1.0,1.0,1.0)
#}
+ if ent_type == 'ent_atom':
+ #{
+ data = obj.SR_data.ent_atom[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.alias}'" )
+ blf.color(0,1.0,1.0,1.0,1.0)
+ #}
+ if ent_type == 'ent_cutscene':
+ #{
+ data = obj.SR_data.ent_cutscene[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.path}'" )
+ blf.color(0,1.0,1.0,1.0,1.0)
+ #}
#}
#}
#}
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_LOGIC, \
+ SR_OBJECT_ENT_ATOM, SR_OBJECT_ENT_CUTSCENE, \
\
SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES,
SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES, SR_MARKER_PROPERTIES \
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
+ script.flags = obj_data.flags
sr_ent_push( script )
#}
+ elif ent_type == 'ent_atom':#{
+ obj_data = obj.SR_data.ent_atom[0]
+ atom = ent_atom()
+ if not obj_data.scrap:
+ atom.pstr_alias = _af_pack_string( obj_data.alias )
+ atom.flags = 0x00
+ if obj_data.mundial:
+ atom.flags |= 0x1
+ if obj_data.scrap:
+ atom.flags |= 0x2
+ sr_ent_push( atom )
+ #}
+ elif ent_type == 'ent_cutscene':#{
+ obj_data = obj.SR_data.ent_cutscene[0]
+ cs = ent_cutscene()
+ cs.pstr_path = _af_pack_string( obj_data.path )
+ cs.flags = 0x00
+ if obj_data.freeze_player:
+ cs.flags |= 0x1
+ sr_ent_push( cs )
+ #}
elif ent_type == 'ent_cubemap':
#{
cubemap = ent_cubemap()
--- /dev/null
+#include "ent_atom.h"
+
+struct _atom
+{
+ struct atom_list
+ {
+ atom atoms[32];
+ u32 count;
+ }
+ lists[k_atom_list_max];
+}
+_atom;
+
+const char *_ent_atom_name( u32 atom_entity_id )
+{
+ world_instance *world = &_world.main;
+ ent_atom *atom = af_arritm( &world->ent_atom, mdl_entity_id_id( atom_entity_id ) );
+
+ if( atom->flags & k_ent_atom_scrap )
+ return "<anonymous>";
+ else
+ return af_str( &world->meta.af, atom->pstr_alias );
+}
+
+i32 _ent_atom_get( u32 atom_entity_id )
+{
+ VG_ASSERT( mdl_entity_id_type(atom_entity_id) == k_ent_atom );
+ world_instance *world = &_world.main;
+ ent_atom *atom = af_arritm( &world->ent_atom, mdl_entity_id_id( atom_entity_id ) );
+
+ if( atom->flags & k_ent_atom_scrap )
+ return atom->scrap_value;
+ else
+ {
+ const char *alias = af_str( &world->meta.af, atom->pstr_alias );
+ return _atom_get( (atom->flags & k_ent_atom_global)? k_atom_list_global: k_atom_list_world, alias );
+ }
+}
+
+void _ent_atom_set( u32 atom_entity_id, i32 value )
+{
+ VG_ASSERT( mdl_entity_id_type(atom_entity_id) == k_ent_atom );
+ world_instance *world = &_world.main;
+ ent_atom *atom = af_arritm( &world->ent_atom, mdl_entity_id_id( atom_entity_id ) );
+
+ if( atom->flags & k_ent_atom_scrap )
+ {
+ atom->scrap_value = value;
+ // Scraps are on their own, only needs to broadcast these to itself and no one else.
+ _world_raise_event( atom_entity_id, "changed" );
+ _world_raise_event( atom_entity_id, value? "true": "false" );
+ }
+ else
+ {
+ enum e_atom_list list = (atom->flags & k_ent_atom_global)? k_atom_list_global: k_atom_list_world;
+ const char *alias = af_str( &world->meta.af, atom->pstr_alias );
+ _atom_set( list, alias, value );
+ _atom_notify( list, alias );
+ }
+}
+
+entity_event_result _ent_atom_event( ent_event *event )
+{
+ world_instance *world = &_world.main;
+ bool pass = 0, fail = 0;
+
+ if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "pass_equal" ) )
+ {
+ if( event->flags & k_ent_event_data_const_i32 )
+ {
+ pass = _ent_atom_get( event->recieve_entity_id ) == (u64)event->data.const_i32;
+ fail = !pass;
+ }
+ else return k_entity_event_result_invalid;
+ }
+ else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "pass_greater" ) )
+ {
+ if( event->flags & k_ent_event_data_const_i32 )
+ {
+ pass = _ent_atom_get( event->recieve_entity_id ) > (u64)event->data.const_i32;
+ fail = !pass;
+ }
+ else return k_entity_event_result_invalid;
+ }
+ else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "set" ) )
+ {
+ if( event->flags & k_ent_event_data_const_i32 )
+ {
+ _ent_atom_set( event->recieve_entity_id, event->data.const_i32 );
+ vg_info( KBLU "Value of atom '%s' is now %d\n", _ent_atom_name( event->recieve_entity_id ), event->data.const_i32 );
+ }
+ else return k_entity_event_result_invalid;
+ }
+ else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "set_or" ) )
+ {
+ if( event->flags & k_ent_event_data_const_i32 )
+ {
+ i32 new = _ent_atom_get( event->recieve_entity_id ) | event->data.const_i32;
+ _ent_atom_set( event->recieve_entity_id, new );
+ vg_info( KBLU "Value of atom '%s' is now %d\n", _ent_atom_name( event->recieve_entity_id ), new );
+ }
+ else return k_entity_event_result_invalid;
+ }
+ else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "set_and" ) )
+ {
+ if( event->flags & k_ent_event_data_const_i32 )
+ {
+ i32 new = _ent_atom_get( event->recieve_entity_id ) | event->data.const_i32;
+ _ent_atom_set( event->recieve_entity_id, new );
+ vg_info( KBLU "Value of atom '%s' is now %d\n", _ent_atom_name( event->recieve_entity_id ), new );
+ }
+ else return k_entity_event_result_invalid;
+ }
+ else return k_entity_event_result_unhandled;
+
+ if( pass ) _world_raise_event( event->recieve_entity_id, "pass" );
+ if( fail ) _world_raise_event( event->recieve_entity_id, "fail" );
+ return k_entity_event_result_OK;
+}
+
+void serialize_atoms( enum e_atom_list list, vg_msg *msg )
+{
+ for( u32 i=0; i<_atom.lists[list].count; i ++ )
+ {
+ atom *a = &_atom.lists[list].atoms[i];
+ vg_msg_wkvnum( msg, a->alias, k_vg_msg_i32, 1, &a->status );
+ }
+}
+
+static atom *_atom_internal( enum e_atom_list list, const char *alias )
+{
+ struct atom_list *l = &_atom.lists[list];
+ for( u32 i=0; i<l->count; i ++ )
+ {
+ atom *a = &l->atoms[i];
+ if( !strcmp( a->alias, alias ) )
+ return a;
+ }
+ return NULL;
+}
+
+i32 _atom_get( enum e_atom_list list, const char *alias )
+{
+ atom *a = _atom_internal( list, alias );
+ if( a ) return a->status;
+ else return 0;
+}
+
+void _atom_notify( enum e_atom_list list, const char *alias )
+{
+ i32 value = _atom_get( list, alias );
+
+ world_instance *world = &_world.main;
+ for( u32 i=0; i<af_arrcount( &world->ent_atom ); i ++ )
+ {
+ ent_atom *atom = af_arritm( &world->ent_atom, i );
+ if( af_str_eq( &world->meta.af, atom->pstr_alias, alias, vg_strdjb2(alias)) )
+ {
+ _world_raise_event( mdl_entity_id( k_ent_atom, i ), "changed" );
+ _world_raise_event( mdl_entity_id( k_ent_atom, i ), value? "true": "false" );
+ }
+ }
+}
+
+void _atom_set( enum e_atom_list list, const char *alias, i32 value )
+{
+ atom *a = _atom_internal( list, alias );
+ if( !a )
+ {
+ struct atom_list *l = &_atom.lists[list];
+ if( l->count == VG_ARRAY_LEN( l->atoms ) )
+ {
+ vg_error( "Too many atoms in list %d! READS WILL BE 0!\n", list );
+ return;
+ }
+
+ a = &l->atoms[ l->count ++ ];
+ a->status = 0;
+ vg_strncpy( alias, a->alias, sizeof(a->alias), k_strncpy_overflow_fatal );
+ }
+
+ a->status = value;
+}
+
+void _atom_list_clear( enum e_atom_list list )
+{
+ _atom.lists[ list ].count = 0;
+}
+
+static int _ent_atom_ccmd( int argc, const char *argv[] )
+{
+ if( argc < 2 )
+ {
+ vg_error( "Usage: atom <scope> <alias> <optional set-value>\n" );
+ return 0;
+ }
+
+ world_instance *world = &_world.main;
+ enum e_atom_list list = k_atom_list_max;
+
+ if( !strcmp( argv[0], "world" ) ) list = k_atom_list_world;
+ else if( !strcmp( argv[0], "global" ) ) list = k_atom_list_global;
+ else
+ {
+ vg_error( "No atom list '%s'\n", argv[0] );
+ return 0;
+ }
+
+ if( !strcmp( argv[1], "list" ) )
+ {
+ struct atom_list *l = &_atom.lists[ list ];
+ for( u32 i=0; i<l->count; i ++ )
+ {
+ atom *a = &l->atoms[i];
+ vg_info( "%s: %d\n", a->alias, a->status );
+ }
+ }
+
+ if( !strcmp( argv[1], "set" ) )
+ {
+ if( argc==4 )
+ {
+ _atom_set( list, argv[2], atoi( argv[3] ) );
+ _atom_notify( list, argv[2] );
+ }
+ else
+ vg_error( "atom <scope> set <name> <value\n" );
+ }
+
+ return 1;
+}
+
+static void _ent_atom_ccmd_poll( int argc, const char *argv[] )
+{
+ const char *term = argv[argc-1];
+ world_instance *world = &_world.main;
+
+ if( argc == 1 )
+ {
+ console_suggest_score_text( "world", term, 0 );
+ console_suggest_score_text( "global", term, 0 );
+ }
+
+ if( argc == 2 )
+ {
+ console_suggest_score_text( "list", term, 0 );
+ console_suggest_score_text( "set", term, 0 );
+ }
+}
+
+void _ent_atom_init(void)
+{
+ vg_console_reg_cmd( "atom", _ent_atom_ccmd, _ent_atom_ccmd_poll );
+}
+
--- /dev/null
+#pragma once
+
+enum e_atom_list
+{
+ k_atom_list_global,
+ k_atom_list_world,
+ k_atom_list_max
+};
+
+typedef struct atom atom;
+struct atom
+{
+ char alias[48];
+ i32 status;
+};
+
+void serialize_atoms( enum e_atom_list list, vg_msg *msg );
+
+void _atom_list_clear( enum e_atom_list list );
+i32 _atom_get( enum e_atom_list list, const char *alias );
+void _atom_set( enum e_atom_list list, const char *alias, i32 value );
+void _atom_notify( enum e_atom_list list, const char *alias );
+void _atom_notify_list( enum e_atom_list list );
+
+entity_event_result _ent_atom_event( ent_event *event );
+void _ent_atom_init(void);
void _ent_challenge_win(void)
{
_world_raise_event( _world.active_challenge_id, "complete" );
+ _world_raise_event( _world.active_challenge_id, "true" );
world_instance *world = &_world.main;
ent_challenge *challenge = af_arritm( &world->ent_challenge, mdl_entity_id_id( _world.active_challenge_id ) );
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,
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 ) )
{
menu.disable_open = 0;
_world_raise_event( _world.active_challenge_id, "activate" );
+ _restart_active_challenge();
}
else if( button_down( k_srbind_mback ) )
{
ctx->font = &vgf_default_small;
}
}
+
+static int _skaterift_challenge_ccmd( int argc, const char *argv[] )
+{
+ if( argc < 1 )
+ {
+ vg_error( "Usage: challenge <index/'all'> <optional set-value>\n" );
+ return 0;
+ }
+
+ bool all = 0;
+ if( !strcmp( argv[0], "all" ) )
+ all = 1;
+
+ world_instance *world = &_world.main;
+
+ u32 index = 0;
+ for( u32 i=0; i<af_arrcount( &world->ent_challenge ); i ++ )
+ {
+ ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
+ const char *alias = af_str( &world->meta.af, challenge->pstr_alias );
+
+ if( all || (atoi( argv[0] ) == index) )
+ {
+ if( argc==2 )
+ {
+ challenge->status = atoi( argv[1] );
+ ent_region_re_eval( world );
+
+ struct ent_script_event event;
+ struct script_event_completion_changed inf = {
+ .entity_id = mdl_entity_id( k_ent_challenge, i ),
+ .completion_flags = 0
+ };
+ event.type = k_escript_event_completion_changed;
+ event.info = &inf;
+ ent_script_propogate_event( world, &event );
+ }
+ else
+ vg_info( "[challenge %u '%s'] %u\n", index, alias, challenge->status );
+ }
+
+ index ++;
+ }
+ for( u32 i=0; i<af_arrcount( &world->ent_route ); i ++ )
+ {
+ ent_route *route = af_arritm( &world->ent_route, i );
+ const char *alias = af_str( &world->meta.af, route->pstr_name );
+
+ if( all || (atoi( argv[0] ) == index) )
+ {
+ if( argc==2 )
+ {
+ route->flags &= ~((u32)(k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver));
+
+ if( !strcmp( argv[1], "silver" ) )
+ route->flags |= (u32)(k_ent_route_flag_achieve_silver);
+ if( !strcmp( argv[1], "gold" ) )
+ route->flags |= (u32)(k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver);
+ ent_region_re_eval( world );
+
+ struct ent_script_event event;
+ struct script_event_completion_changed inf = {
+ .entity_id = mdl_entity_id( k_ent_route, i ),
+ .completion_flags = route->flags
+ };
+ event.type = k_escript_event_completion_changed;
+ event.info = &inf;
+ ent_script_propogate_event( world, &event );
+ }
+ else
+ vg_info( "[route %u '%s'] %s%s\n", index, alias,
+ (route->flags & k_ent_route_flag_achieve_silver? "SILVER": "_____"),
+ (route->flags & k_ent_route_flag_achieve_gold? "_GOLD": "_____" ) );
+ }
+
+ index ++;
+ }
+ return 1;
+}
+
+void _ent_challenge_init(void)
+{
+ vg_console_reg_cmd( "challenge", _skaterift_challenge_ccmd, NULL );
+}
void _restart_active_challenge(void);
void _ent_challenge_complete( ent_challenge *challenge );
void _ent_challenge_win(void);
+void _ent_challenge_init(void);
--- /dev/null
+#include "ent_cutscene.h"
+
+entity_event_result _ent_cutscene_event( ent_event *event )
+{
+ world_instance *world = &_world.main;
+ ent_cutscene *cs = af_arritm( &world->ent_cutscene, mdl_entity_id_id( event->recieve_entity_id ) );
+
+ if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "play" ) )
+ {
+ const char *path = af_str( &world->meta.af, cs->pstr_path );
+ _cutscene_load_and_play( path, (cs->flags & k_ent_cutscene_freeze_player), event->recieve_entity_id );
+
+ return k_entity_event_result_OK;
+ }
+ else return k_entity_event_result_unhandled;
+}
--- /dev/null
+#pragma once
+
+entity_event_result _ent_cutscene_event( ent_event *event );
}
else if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "equip" ) )
{
- if( glider->flags & 0x1 )
+ if( !(glider->flags & k_ent_glider_flag_locked) )
player_glide_equip_glider();
-
return k_entity_event_result_OK;
}
else
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);
+ if( visible ) glider->flags &= ~((u32)0x1);
+ else glider->flags |= 0x1;
}
}
}
return 1;
}
-void _ent_list_set_as_targets( ent_list *list, bool yes )
+entity_event_result _ent_list_world_event( ent_event *event )
{
-#if 0
world_instance *world = &_world.main;
- struct ent_list_iter iter;
- _ent_list_iter_start( &iter, list, 0 );
+ ent_list *list = af_arritm( &world->ent_list, mdl_entity_id_id( event->recieve_entity_id ) );
- while( _ent_list_iter( &iter ) )
+ if( AF_STR_EQ( &world->meta.af, event->pstr_recieve_event, "visible" ) )
{
- if( iter.type == k_ent_challenge )
+ // 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 )
{
- 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);
+ _ent_list_set_visible( list, event->data.const_i32 );
+ return k_entity_event_result_OK;
}
+ else
+ return k_entity_event_result_invalid;
}
-#endif
+ else return k_entity_event_result_unhandled;
}
void _ent_list_iter_start( struct ent_list_iter *iter, ent_list *list, enum entity_alias filter_type );
bool _ent_list_iter( struct ent_list_iter *iter );
void _ent_list_set_visible( ent_list *list, bool visible );
+entity_event_result _ent_list_world_event( ent_event *event );
+bool _ent_list_check_completed( ent_list *list );
+void _ent_list_set_as_targets( ent_list *list, bool yes );
#pragma once
+#define KCOL_JOHN KNRM
+#define KCOL_MIKE KBLU
+#define KCOL_PRES KYEL
+#define KCOL_FBI KGRN
+#define KCOL_JESUS KMAG
+
enum npc
{
k_npc_none = 0,
else
return k_entity_event_result_invalid;
}
+ else
return k_entity_event_result_unhandled;
}
region->flags = combined;
world_total &= combined;
+
+ if( region->flags & k_ent_route_flag_achieve_silver )
+ _world_raise_event( mdl_entity_id( k_ent_region, j ), "silver" );
+ if( region->flags & k_ent_route_flag_achieve_gold )
+ _world_raise_event( mdl_entity_id( k_ent_region, j ), "gold" );
}
}
}
_ent_script;
-static void ent_script_event_init( ent_script_event *event, world_instance *world, u32 script_index )
+#include "scripts/explode.c"
+#include "scripts/tutorial_island.c"
+#include "scripts/board_maker.c"
+
+struct ent_script_table_entry _ent_script_table[] =
{
- event->userdata = _ent_script.userdata_array[ script_index ];
- event->world = world;
+ { "explode", _skaterift_script_explode },
+ { "volc_main", _skaterift_script_volc },
+ { "board_maker", _skaterift_script_board_maker },
+ { NULL }
+};
+static void ent_script_event_init( ent_script_event *event, world_instance *world, u32 script_index )
+{
ent_script *script = af_arritm( &world->ent_script, script_index );
- if( script->entity_list_id )
- event->entity_list = af_arritm( &world->ent_list, mdl_entity_id_id( script->entity_list_id ) );
- else
- event->entity_list = NULL;
-
+ event->userdata = _ent_script.userdata_array[ script_index ];
+ event->script_entity_id = mdl_entity_id( k_ent_script, script_index );
event->script_alias = _ent_script_table[ script->script_id ].alias;
}
ent_script_propogate_event( world, &event );
}
+#if 0
void ent_script_start( world_instance *world )
{
- /* internal start event */
+ /* init before world start */
+ for( u32 i=0; i<af_arrcount( &world->ent_script ); i ++ )
+ _world_raise_event( mdl_entity_id( k_ent_script, i ), "init" );
+
+ /* real world 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; i<af_arrcount( &world->ent_script ); i ++ )
- _world_raise_event( mdl_entity_id( k_ent_script, i ), "start" );
}
+#endif
entity_event_result _ent_script_world_event( ent_event *event )
{
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
k_escript_event_world_event,
k_escript_event_allocate,
k_escript_event_update,
+#if 0
k_escript_event_world_start,
k_escript_event_atom_changed,
+#endif
+ k_escript_event_completion_changed
}
type;
void *info;
void *userdata;
- ent_list *entity_list;
- world_instance *world;
const char *script_alias;
+ u32 script_entity_id;
};
struct ent_script_table_entry
if( button_down( k_srbind_mback ) )
{
- _skateshop.open = 0;
- gui_helper_reset( k_gui_helper_mode_clear );
- skateshop_playermod( 0 );
- srinput.state = k_input_state_resume;
- return;
+ if( world_clear_event( k_world_event_shop ) )
+ {
+ _skateshop.open = 0;
+ gui_helper_reset( k_gui_helper_mode_clear );
+ skateshop_playermod( 0 );
+ srinput.state = k_input_state_resume;
+ return;
+ }
}
/* override camera positioning
if( button_down( k_srbind_maccept ) )
{
- gui_helper_reset( k_gui_helper_mode_clear );
- skateshop_playermod( 0 );
- _skateshop.open = 0;
+ if( world_clear_event( k_world_event_shop ) )
+ {
+ gui_helper_reset( k_gui_helper_mode_clear );
+ skateshop_playermod( 0 );
+ _skateshop.open = 0;
+ }
}
}
else if( shop->type == k_skateshop_type_server )
}
else if( shop->type == k_skateshop_type_charshop )
{
- _skateshop.open = 0;
- gui_helper_reset( k_gui_helper_mode_clear );
- skateshop_playermod( 0 );
- srinput.state = k_input_state_resume;
+ if( world_clear_event( k_world_event_shop ) )
+ {
+ _skateshop.open = 0;
+ gui_helper_reset( k_gui_helper_mode_clear );
+ skateshop_playermod( 0 );
+ srinput.state = k_input_state_resume;
+ }
}
}
k_ent_npc = 27,
k_ent_armature = 28,
k_ent_script = 29,
+ k_ent_atom = 30,
+ k_ent_cutscene = 31,
k_ent_max
};
[k_ent_glider] = "ent_glider",
[k_ent_npc] = "ent_npc",
[k_ent_armature] = "mdl_armature",
- [k_ent_script] = "ent_script"
+ [k_ent_script] = "ent_script",
+ [k_ent_atom] = "ent_atom",
+ [k_ent_cutscene] = "ent_cutscene"
};
static inline u32 mdl_entity_id_type( u32 entity_id )
u32 flags;
};
+enum ent_atom_flag
+{
+ k_ent_atom_global = 0x1,
+ k_ent_atom_scrap = 0x2
+};
+
+typedef struct ent_atom ent_atom;
+struct ent_atom
+{
+ union
+ {
+ u32 pstr_alias;
+ i32 scrap_value;
+ };
+
+ u32 flags;
+};
+
+enum ent_cutscene_flag
+{
+ k_ent_cutscene_freeze_player = 0x1,
+};
+
+typedef struct ent_cutscene ent_cutscene;
+struct ent_cutscene
+{
+ u32 pstr_path,
+ flags;
+};
+
enum ent_objective_filter{
k_ent_objective_filter_none = 0x00000000,
k_ent_objective_filter_trick_shuvit = 0x00000001,
u32 deleted01[2];
};
+enum ent_glider_flag
+{
+ k_ent_glider_flag_locked = 0x1
+};
struct ent_glider
{
mdl_transform transform;
#include "control_overlay.h"
#include "network.h"
#include "shaders/model_menu.h"
+#include "ent_atom.h"
struct global_menu menu = { .skip_starter = 0, .prof_row = -1 };
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_atom_status( "unlock_venus" );
+ world_map.selected_superworld_locked = !_atom_get( k_atom_list_global, "unlock_venus" );
}
if( world_map.selected_superworld_locked )
addon_reg *reg = addon_details( addon_id );
bool unlocked = 1;
if( reg->flags & ADDON_REG_MTZERO )
- unlocked = _skaterift_atom_status( "unlock_mtzero" )?1:0;
+ unlocked = _atom_get( k_atom_list_global, "unlock_mtzero" )?1:0;
if( reg->flags & ADDON_REG_CITY )
- unlocked = _skaterift_atom_status( "unlock_city" )?1:0;
+ unlocked = _atom_get( k_atom_list_global, "unlock_city" )?1:0;
if( reg->flags & ADDON_REG_VALLEY )
- unlocked = _skaterift_atom_status( "unlock_valley" )?1:0;
+ unlocked = _atom_get( k_atom_list_global, "unlock_valley" )?1:0;
menu.world_list_entries[ menu.world_list_display_count ] = unlocked? addon_id: 0;
for( u32 i=0; i<_cutscene.unique_refs; i ++ )
mdl_sync_std_unload( &_cutscene.refs[i].mdl );
+ _cutscene.unique_refs = 0;
_cutscene.active_camera = NULL;
_cutscene.strip = 0;
_cutscene.time = 0.0f;
vg_async_call( &vg.main_tasks, sync_cutscene_loaded, NULL );
}
-void _cutscene_load_and_play( const char *path, bool freeze_player, u32 raiser_entity )
+bool _cutscene_load_and_play( const char *path, bool freeze_player, u32 raiser_entity )
{
if( _cutscene.state != k_cutscene_state_none )
{
vg_error( "Tried to play cutscene '%s' while already playing one.\n", path );
- return;
+ return 0;
}
_cutscene.raiser_entity = raiser_entity;
struct cutscene_load_info *info = (void *)task->data;
strcpy( info->path, path );
vg_async_task_dispatch( task, cutscene_load_thread );
+ return 1;
}
/*
void cutscene_update( f32 delta )
{
+ if( _cutscene.state == k_cutscene_state_unloading )
+ {
+ if( !vg_audio_flagged_stopped( AUDIO_FLAG_CUTSCENE ) )
+ return;
+
+ vg_allocator_free( _cutscene.arena );
+ _cutscene.arena = NULL;
+ _cutscene.state = k_cutscene_state_none;
+ _cutscene.marker_this_frame = NULL;
+ _cutscene.subtitle = NULL;
+ _cutscene.raiser_entity = 0;
+ return;
+ }
+
if( _cutscene.state == k_cutscene_state_ready )
{
_cutscene.player_binding = _cutscene_get_first_model_instance( "models/ch_none" );
}
}
vg_audio_unlock();
- }
-
- if( _cutscene.state == k_cutscene_state_unloading )
- {
- if( !vg_audio_flagged_stopped( AUDIO_FLAG_CUTSCENE ) )
- return;
-
- vg_allocator_free( _cutscene.arena );
- _cutscene.arena = NULL;
- _cutscene.state = k_cutscene_state_none;
- _cutscene.marker_this_frame = NULL;
- _cutscene.subtitle = NULL;
- _cutscene.raiser_entity = 0;
- return;
+ _world_raise_event( _cutscene.raiser_entity, "start" );
}
if( _cutscene.state != k_cutscene_state_playing )
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, bool freeze_player, u32 raiser_entity );
+bool _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);
}
vg_msg_end_frame( &sav );
- /* script / story information */
- vg_msg_frame( &sav, "story" );
+ vg_msg_frame( &sav, "atoms" );
{
- _skaterift_script_write_savedata( &sav );
+ serialize_atoms( k_atom_list_global, &sav );
}
vg_msg_end_frame( &sav );
vg_msg_frame( &sav, "player" );
{
- vg_msg_wkvnum( &sav, "position", k_vg_msg_float|k_vg_msg_32b, 3,
- localplayer.rb.co );
+ vg_msg_wkvnum( &sav, "position", k_vg_msg_float|k_vg_msg_32b, 3, localplayer.rb.co );
+ }
+ vg_msg_end_frame( &sav );
+
+ vg_msg_frame( &sav, "atoms" );
+ {
+ serialize_atoms( k_atom_list_world, &sav );
}
vg_msg_end_frame( &sav );
}
else
group = alloca( save_data_size );
- group->file_count = 2;
+ group->file_count = 1;
skaterift_populate_main_savedata( &group->files[0] );
- skaterift_populate_world_savedata( &group->files[1] );
+
+ if( (_world.loader_state == k_world_loader_done) || (_world.loader_state == k_world_loader_saving_current) )
+ skaterift_populate_world_savedata( &group->files[ group->file_count ++ ] );
if( async )
vg_async_task_dispatch( task, savedata_group_write_task );
kvsav.cur = orig;
- if( vg_msg_seekframe( &kvsav, "story" ) )
+ if( vg_msg_seekframe( &kvsav, "atoms" ) )
{
- _skaterift_script_load_savedata( &kvsav );
+ vg_msg_cmd cmd;
+ while( vg_msg_next( &kvsav, &cmd ) )
+ {
+ if( cmd.code == k_vg_msg_endframe ) break;
+ i32 value = 0;
+ vg_msg_cast( cmd.value, cmd.code, &value, k_vg_msg_i32 );
+ _atom_set( k_atom_list_global, cmd.key, value );
+ }
}
else
{
--- /dev/null
+static bool _skaterift_script_board_maker( 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, "open" ) )
+ {
+ // 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 list_id = inf->event->data.const_entity_id;
+ if( mdl_entity_id_type( list_id ) != k_ent_list )
+ {
+ vg_error( "board maker called with not a list\n" );
+ return 0;
+ }
+ ent_list *list = af_arritm( &world->ent_list, mdl_entity_id_id(list_id) );
+
+ if( world_set_event( k_world_event_board_maker ) )
+ {
+ struct ent_list_iter iter;
+ _ent_list_iter_start( &iter, list, k_ent_marker );
+ while( _ent_list_iter( &iter ) )
+ {
+ ent_marker *marker = af_arritm( &world->ent_marker, iter.index );
+ const char *alias = af_str( &world->meta.af, marker->pstr_alias );
+
+ if( !strcmp( alias, "$board_position" ) )
+ v3_copy( marker->transform.co, _board_maker.origin );
+ else if( !strcmp( alias, "$camera_position" ) )
+ v3_copy( marker->transform.co, _board_maker.camera_pos );
+ }
+ _board_maker_open();
+ }
+ }
+ }
+ }
+ return 1;
+}
-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;
-}
static bool _skaterift_script_board_maker_unlock( ent_script_event *event )
{
+#if 0
if( event->type == k_escript_event_allocate )
{
struct script_event_allocate *event_info = event->info;
}
}
}
-
+#endif
return 1;
}
+#if 0
static bool _skaterift_script_board_maker( ent_script_event *event )
{
if( on_function_trigger( event, 0 ) )
}
return 1;
}
+#endif
struct script_volcano
{
- ent_list *break_list;
bool docks_wait;
f32 stopped_timer;
};
-static bool _skaterift_script_tutorial_island( ent_script_event *event )
+static bool _skaterift_script_volc( 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;
- struct script_volcano *script_volcano = vg_linear_alloc( event_info->heap, sizeof(struct script_volcano) );
- script_volcano->break_list = NULL;
- script_volcano->docks_wait = 0;
- script_volcano->stopped_timer = 0.0f;
- event_info->userdata = script_volcano;
+ struct script_volcano *v = vg_linear_alloc( event_info->heap, sizeof(struct script_volcano) );
+ v->docks_wait = 0;
+ v->stopped_timer = 0.0f;
+ event_info->userdata = v;
return 1;
}
+ struct script_volcano *v = event->userdata;
- struct script_volcano *script_volcano = event->userdata;
-
- if( on_completion_changed(event) )
+ if( event->type == k_escript_event_world_event )
{
- u64 progress = _skaterift_atom_status( "story" );
- if( progress == _skaterift_atom_enum_index( "story", "volc" ) )
- {
- 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" ) )
+ 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, "unlock_docks" ) )
{
- _ent_list_set_visible( _ent_list_get_aliased( "docks:locked" ), 0 );
+ v->docks_wait = 1;
}
}
/* waiting for player to stop to blow up the docks */
if( event->type == k_escript_event_update )
{
- if( script_volcano->docks_wait )
+ if( v->docks_wait )
{
if( localplayer.subsystem == k_player_subsystem_walk )
{
if( v3_length2( localplayer.rb.v ) < 1.0f )
{
- script_volcano->stopped_timer += vg.time_frame_delta;
- if( script_volcano->stopped_timer > 3.0f )
+ v->stopped_timer += vg.time_frame_delta;
+ if( v->stopped_timer > 3.0f )
{
- script_volcano->docks_wait = 0;
- _cutscene_load_and_play( "metascenes/unlock_docks.ms", NULL, 1 );
- script_volcano->break_list = _ent_list_get_aliased( "docks:locked" );
+ v->docks_wait = 0;
+ _atom_set( k_atom_list_world, "unlock_docks", 1 );
+ _atom_notify( k_atom_list_world, "unlock_docks" );
}
}
else
- script_volcano->stopped_timer = 0.0f;
+ v->stopped_timer = 0.0f;
}
}
}
- 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_atom_once( event, "ch1s3_view" ) )
- {
- static const struct cs_subtitle EN[] = {
- { "john_1", KCOL_JOHN "Alright so, fliptricks." },
- { "john_2", KCOL_JOHN "We spent ages practicing these before" },
- { "john_3", KCOL_JOHN "Shouldn't take you long to get it again" },
- { "john_4", KCOL_JOHN "see if you can get a tre-flip down there" },
- { NULL, NULL },
- };
- _cutscene_load_and_play( "metascenes/ch1s3.ms", EN, 1 );
- _ent_npc_set_in_cutscene( k_npc_jc, 1 );
- }
- }
-
- if( on_function_trigger( event, 2 ) )
- {
- if( on_atom_once( event, "ch1s3b_view" ) )
- {
- static const struct cs_subtitle EN[] = {
- { "john_1", KCOL_JOHN "That is it mate!" },
- { "john_2", KCOL_JOHN "You have still got it!" },
- { NULL, NULL },
- };
- _cutscene_load_and_play( "metascenes/ch1s3b.ms", EN, 1 );
- _ent_npc_set_in_cutscene( k_npc_jc, 1 );
- }
- }
-
- 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_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_atom_once( event, "ch1s4_view" ) )
- {
- static const struct cs_subtitle EN[] = {
- { "john_1", KCOL_JOHN "Remember these courses we were setting up?" },
- { "john_2", KCOL_JOHN "Nah?" },
- { "john_3", KCOL_JOHN "Alright well uh, to jog your memory.." },
- { "john_4", KCOL_JOHN "Get yourself down through the gates as quick as possible" },
- { "john_5", KCOL_JOHN "Thats it." },
- { "john_6", KCOL_JOHN "Give it a shot mate" },
- { NULL, NULL },
- };
- _cutscene_load_and_play( "metascenes/ch1s4.ms", EN, 1 );
- }
- }
-
- u64 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_atom_once( event, "ch1s5_view" ) )
- {
- static const struct cs_subtitle EN[] = {
- /* 50ch| set cc=70 |################################################| */
- { "j1", KCOL_JOHN "Alright, well then" },
- { "j2", KCOL_JOHN "You're gonna need to play close attention to\n"
- "this part" },
-
- { "j3", KCOL_JOHN "because its difficult.." },
- { "j4", KCOL_JOHN "It's gonna take some practice until it clicks" },
- { "j5", KCOL_JOHN "Right as you like, go across the transition \n"
- "of the ramp," },
-
- { "j6", KCOL_JOHN "Right here," },
- { "j7", KCOL_JOHN "you need to pump to gain some momentum." },
- { "j8", KCOL_JOHN "What I mean right, watch" },
- { "j9", KCOL_JOHN "just as I'm going into the base of the ramp" },
- { "j10",KCOL_JOHN "I'm storing up some energy here by crouching down" },
- { "j11",KCOL_JOHN "Right as I go across this point" },
- { "j12",KCOL_JOHN "I'm almost jumping back up, adding some uwpwards\n"
- "momentum" },
-
- { "j13",KCOL_JOHN "Then as the board comes up to this angle.." },
- { "j14",KCOL_JOHN "that upwards momentum is transferred \n"
- "into my speed" },
-
- { "j15",KCOL_JOHN "Same principle works, same way in the \n"
- "other direction" },
-
- { "j16",KCOL_JOHN "Now, like I'm saying" },
- { "j17",KCOL_JOHN "this might take you a little bit until it clicks" },
-
- { "j18",KCOL_JOHN "But once it does you'll feel it. You'll know!" },
-
- { "j19",KCOL_JOHN "And I uhh, set a target for you" },
- { "j20",KCOL_JOHN "right up there.." },
- { "j21",KCOL_JOHN "Thats how we'll know you're back on form." },
-
- { "j22",KCOL_JOHN "Come see me at the docks once you've got it." },
-
- { NULL, NULL },
- };
- _cutscene_load_and_play( "metascenes/ch1s5.ms", EN, 1 );
- }
- }
-#endif
- return 1;
-}
-
-static bool _skaterift_script_ch1s6a( ent_script_event *event )
-{
-#if 0
- u64 progress;
- if( on_atom_changed( event, "story", &progress ) )
- {
- bool visible = progress == _skaterift_atom_enum_index( "story", "volc:leaving" );
- _ent_list_set_visible( event->entity_list, visible );
- }
-
- if( on_function_trigger( event, 0 ) )
- {
- _skaterift_atom_set_enum( "story", "mz" );
- 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." },
- { "j4", KCOL_JOHN "Oh right, Mt.Zero.. You really don't remember anything do you?" },
- { "j5", KCOL_JOHN "Its where we live." },
- { "j7", KCOL_JOHN "Yknow it's where the woodshop is," },
- { "j8", KCOL_JOHN "It's where we skate, where Mike is," },
- { "j9", KCOL_JOHN "yknow, its our home!" },
-
- { NULL, NULL },
- };
- _cutscene_load_and_play( "metascenes/ch1s6a.ms", EN, 1 );
- }
-
- if( on_cutscene_marker( event, "$ch1s6a_end" ) )
- skaterift_load_world_command( 1, (const char *[]){ "sr002-local-dev_hub" } );
-#endif
-
return 1;
}
#include "ent_route.h"
#include "ent_npc.h"
#include "ent_list.h"
+#include "ent_atom.h"
struct skaterift_globals skaterift =
{
vg_loader_step( network_init, network_end );
- _skaterift_script_init();
vg_loader_set_user_information( "Initializing subsystems" );
vg_console_reg_cmd( "load_world", skaterift_load_world_command, NULL );
vg_console_reg_var( "immobile", &localplayer.immobile, k_var_dtype_i32, 0 );
vg_loader_step( skaterift_load_player_content, NULL );
vg_loader_step( _replay2_init, NULL );
vg_loader_step( _ent_npc_init, NULL );
+ vg_loader_step( _ent_atom_init, NULL );
+ vg_loader_step( _ent_challenge_init, NULL );
vg_loader_set_user_information( "Compiling shaders" );
vg_bake_shaders();
#include "user_profile.c"
#include "ent_npc.c"
#include "ent_list.c"
+#include "ent_cutscene.c"
+#include "ent_atom.c"
//TODO
//#include "vg/submodules/hashmap.c/hashmap.c"
-#define KCOL_JOHN KNRM
-#define KCOL_MIKE KBLU
-#define KCOL_PRES KYEL
-#define KCOL_FBI KGRN
-#define KCOL_JESUS KMAG
+#if 0
#include "ent_script.h"
_skaterift_script_savedata[] =
{
{ "story", k_atom_type_enum, _script_linear_story },
+ { "unlock_docks_view" },
{ "unlock_valley_view" },
{ "unlock_mtzero_view" },
{ "ch1s3_view" },
{ "ch1s3b_view" },
+ { "ch1s4_view" },
{ "ch1s5_view" },
#if 0
atom->status = value;
+#if 0
struct script_event_atom_changed info;
info.alias = atom_alias;
info.value = value;
event.type = k_escript_event_atom_changed;
event.info = &info;
ent_script_propogate_event( &_world.main, &event );
+#endif
}
void _skaterift_atom_set_enum( const char *atom_alias, const char *value )
return 0;
}
-
-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;
-
- u64 _0;
- if( on_atom_changed( event, "story", &_0 ) )
- return 1;
-
- return 0;
-}
#endif
#include "scripts/generic.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
- */
-
-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 },
-
- { "tutorial_island", _skaterift_script_tutorial_island },
- { "ch1s3", _skaterift_script_ch1s3 },
- { "ch1s4", _skaterift_script_ch1s4 },
- { "ch1s5", _skaterift_script_ch1s5 },
- { "ch1s6a", _skaterift_script_ch1s6a },
-
- { "mtzero", _skaterift_script_mtzero },
- { "mtzero_after", _skaterift_script_mtzero_after },
- { "ch2s2", _skaterift_script_ch2s2 },
- { "ch2s3", _skaterift_script_ch2s3 },
- { "battery_jump", _skaterift_script_battery_jump },
- { "ch2s5_before", _skaterift_script_ch2s5_before },
- { "ch2s5_after", _skaterift_script_ch2s5_after },
- { "ch2s6", _skaterift_script_ch2s6 },
- { "ch2e1", _skaterift_script_ch2e1 },
-
- { "city", _skaterift_script_city },
- { "ch3s2", _skaterift_script_ch3s2 },
- { "ch3s3", _skaterift_script_ch3s3 },
-
- { "valley", _skaterift_script_valley },
- { "ch4s2", _skaterift_script_ch4s2 },
- { "ch4s1", _skaterift_script_ch4s1 },
-#endif
-
- { NULL }
-};
-
-
/* console eventts
* ------------------------------------------------------------------------------------------------------------- */
return 0;
}
+ bool all = 0;
+ if( !strcmp( argv[1], "all" ) )
+ all = 1;
+
+ world_instance *world = &_world.main;
+
if( !strcmp( argv[0], "atom" ) )
{
- bool all = 0;
- if( !strcmp( argv[1], "all" ) )
- all = 1;
-
for( u32 i=0; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
struct script_save_atom *atom = &_skaterift_script_savedata[i];
return 1;
}
+ else if( !strcmp( argv[0], "challenge" ) )
+ {
+ u32 index = 0;
+ for( u32 i=0; i<af_arrcount( &world->ent_challenge ); i ++ )
+ {
+ ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
+ const char *alias = af_str( &world->meta.af, challenge->pstr_alias );
+
+ if( all || (atoi( argv[1] ) == index) )
+ {
+ if( argc==3 )
+ {
+ challenge->status = atoi( argv[2] );
+ ent_region_re_eval( world );
+
+ struct ent_script_event event;
+ struct script_event_completion_changed inf = {
+ .entity_id = mdl_entity_id( k_ent_challenge, i ),
+ .completion_flags = 0
+ };
+ event.type = k_escript_event_completion_changed;
+ event.info = &inf;
+ ent_script_propogate_event( world, &event );
+ }
+ else
+ vg_info( "[challenge %u '%s'] %u\n", index, alias, challenge->status );
+ }
+
+ index ++;
+ }
+ for( u32 i=0; i<af_arrcount( &world->ent_route ); i ++ )
+ {
+ ent_route *route = af_arritm( &world->ent_route, i );
+ const char *alias = af_str( &world->meta.af, route->pstr_name );
+
+ if( all || (atoi( argv[1] ) == index) )
+ {
+ if( argc==3 )
+ {
+ route->flags &= ~((u32)(k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver));
+
+ if( !strcmp( argv[2], "silver" ) )
+ route->flags |= (u32)(k_ent_route_flag_achieve_silver);
+
+ if( !strcmp( argv[2], "gold" ) )
+ route->flags |= (u32)(k_ent_route_flag_achieve_gold|k_ent_route_flag_achieve_silver);
+ ent_region_re_eval( world );
+
+ struct ent_script_event event;
+ struct script_event_completion_changed inf = {
+ .entity_id = mdl_entity_id( k_ent_route, i ),
+ .completion_flags = route->flags
+ };
+ event.type = k_escript_event_completion_changed;
+ event.info = &inf;
+ ent_script_propogate_event( world, &event );
+ }
+ else
+ vg_info( "[route %u '%s'] %s%s\n", index, alias,
+ (route->flags & k_ent_route_flag_achieve_silver? "SILVER": "_____"),
+ (route->flags & k_ent_route_flag_achieve_gold? "_GOLD": "_____" ) );
+ }
+
+ index ++;
+ }
+ return 1;
+ }
else if( !strcmp( argv[0], "trigger" ) )
{
if( !strcmp( argv[1], "start" ) )
static void _skaterift_script_ccmd_poll( int argc, const char *argv[] )
{
const char *term = argv[argc-1];
+ world_instance *world = &_world.main;
if( argc == 1 )
{
console_suggest_score_text( "atom", term, 0 );
console_suggest_score_text( "trigger", term, 0 );
+ console_suggest_score_text( "challenge", term, 0 );
}
else if( argc == 2 )
{
{
console_suggest_score_text( "start", term, 0 );
}
+ else if( !strcmp( argv[0], "challenge" ) )
+ {
+ // CANT DO THIS WHILE WE DONT HAVE STRING ESCAPING IN THE CONSOLE
+#if 0
+ for( u32 i=0; i<af_arrcount( &world->ent_challenge ); i ++ )
+ {
+ ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
+ console_suggest_score_text( af_str( &world->meta.af, challenge->pstr_alias ), term, 0 );
+ }
+ for( u32 i=0; i<af_arrcount( &world->ent_route ); i ++ )
+ {
+ ent_route *route = af_arritm( &world->ent_route, i );
+ console_suggest_score_text( af_str( &world->meta.af, route->pstr_name ), term, 0 );
+ }
+#endif
+ }
}
else if( argc == 3 )
{
}
}
}
+ else if( !strcmp( argv[0], "challenge" ) )
+ {
+ // CANT DO THIS WHILE WE DONT HAVE STRING ESCAPING IN THE CONSOLE
+#if 0
+ for( u32 i=0; i<af_arrcount( &world->ent_route ); i ++ )
+ {
+ ent_route *route = af_arritm( &world->ent_route, i );
+ const char *alias = af_str( &world->meta.af, route->pstr_name );
+ if( !strcmp( argv[1], alias ) )
+ {
+ console_suggest_score_text( "silver", term, 0 );
+ console_suggest_score_text( "gold", term, 0 );
+ break;
+ }
+ }
+#endif
+ }
}
}
{
vg_console_reg_cmd( "script", _skaterift_script_ccmd, _skaterift_script_ccmd_poll );
}
+
+
+#endif
#pragma once
+#if 0
#include "ent_script.h"
#define ATOM_MAX 0xfffffffffffffffflu
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 );
+#endif
struct world_instance
{
bool complete;
-
addon_id addon_id;
void *heap;
ent_npc,
file_entity_ref,
ent_event,
- ent_script;
+ ent_script,
+ ent_atom,
+ ent_cutscene;
GLuint *nonlocal_gates_cubemaps;
u32 nonlocal_gate_count;
#include "ent_glider.h"
#include "ent_region.h"
#include "ent_camera.h"
+#include "ent_atom.h"
+#include "ent_cutscene.h"
#include "input.h"
#include "player_walk.h"
.cast_ray = NULL
};
+static void _event_trigger( ent_event *event );
+
void world_gen_entities_init( world_instance *world )
{
/* lights */
{
vg_info( "Start instance %p\n", world );
+ for( u32 i=0; i<af_arrcount( &world->ent_event ); i ++ )
+ {
+ ent_event *event = af_arritm( &world->ent_event, i );
+ if( AF_STR_EQ( &world->meta.af, event->pstr_source_event, "init" ) )
+ _event_trigger( event );
+ }
+
world->probabilities[ k_probability_curve_constant ] = 1.0f;
for( u32 i=0; i<af_arrcount(&world->ent_audio); i++ )
{
}
}
+ vg_msg_cursor orig = sav->cur;
+ if( vg_msg_seekframe( sav, "atoms" ) )
+ {
+ vg_msg_cmd cmd;
+ while( vg_msg_next( sav, &cmd ) )
+ {
+ if( cmd.code == k_vg_msg_endframe ) break;
+ i32 value = 0;
+ vg_msg_cast( cmd.value, cmd.code, &value, k_vg_msg_i32 );
+ _atom_set( k_atom_list_world, cmd.key, value );
+ }
+ }
+
ent_region_re_eval( world );
- ent_script_start( world );
+
+ /* true/false initializers
+ * ----------------------------------------------------------------------------------- */
+ for( u32 i=0; i<af_arrcount( &world->ent_atom ); i ++ )
+ {
+ ent_atom *atom = af_arritm( &world->ent_atom, i );
+ i32 value;
+ if( atom->flags & k_ent_atom_scrap )
+ value = atom->scrap_value;
+ else
+ {
+ enum e_atom_list list = (atom->flags & k_ent_atom_global)? k_atom_list_global: k_atom_list_world;
+ value = _atom_get( list, af_str( &world->meta.af, atom->pstr_alias ) );
+ }
+ _world_raise_event( mdl_entity_id( k_ent_atom, i ), "changed" );
+ _world_raise_event( mdl_entity_id( k_ent_atom, i ), value? "true": "false" );
+ }
+ for( u32 i=0; i<af_arrcount(&world->ent_challenge); i++ )
+ {
+ ent_challenge *challenge = af_arritm( &world->ent_challenge, i );
+ _world_raise_event( mdl_entity_id( k_ent_challenge, i ), challenge->status? "true": "false" );
+ }
+
+ sav->cur = orig;
}
void world_entity_serialize( world_instance *world, vg_msg *sav )
world_instance *world = &_world.main;
u32 event_alias_hash = vg_strdjb2( event_alias );
- if( mdl_entity_id_type( caller ) != k_ent_volume )
+ bool log = 1;
+
+ if( mdl_entity_id_type( caller ) == k_ent_volume )
+ {
+ if( !strcmp( event_alias, "stay" ) ||
+ !strcmp( event_alias, "particle") )
+ {
+ log = 0;
+ }
+ }
+
+ if( log )
vg_low( "%x raises [src_event '%s']\n", caller, event_alias );
for( u32 i=0; i<af_arrcount( &world->ent_event ); i ++ )
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 );
+ _event_trigger( event );
+ }
+}
- 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;
- }
+static void _event_trigger( ent_event *event )
+{
+ world_instance *world = &_world.main;
+ 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,
+ [k_ent_list] = _ent_list_world_event,
+ [k_ent_cutscene] = _ent_cutscene_event,
+ [k_ent_atom] = _ent_atom_event,
+ };
- if( !table[type] )
- {
- vg_error( "Entity type %u does not have a call handler, but was called anyway\n", type );
- return;
- }
+ if( type >= VG_ARRAY_LEN(table) )
+ {
+ vg_error( "call to entity type: %u is out of range\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 ));
- }
+ 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 );
+ 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 );
- }
+ 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 );
}
+
#include "vg/vg_loader.h"
#include "vg/vg_io.h"
#include <string.h>
+#include "ent_atom.h"
/*
* load the .mdl file located in path as a world instance
AF_LOAD_ARRAY_STRUCT( af, &world->ent_script, ent_script, heap );
AF_LOAD_ARRAY_STRUCT( af, &world->ent_event, ent_event, heap );
AF_LOAD_ARRAY_STRUCT( af, &world->ent_npc, ent_npc, heap );
+ AF_LOAD_ARRAY_STRUCT( af, &world->ent_atom, ent_atom, heap );
+ AF_LOAD_ARRAY_STRUCT( af, &world->ent_cutscene, ent_cutscene, heap );
}
array_file_ptr infos;
{
if( !vg_audio_flagged_stopped( AUDIO_FLAG_WORLD|AUDIO_FLAG_CUTSCENE ) )
return;
+
+ if( _cutscene.state != k_cutscene_state_none )
+ {
+ cutscene_update( 0.0f );
+ return;
+ }
world_instance_free_graphics_data( &_world.main );
_world.main.complete = 0;
vg_str folder_str;
vg_strnull( &folder_str, info->path, sizeof(info->path) );
info->OK = addon_get_content_folder( _world.load_addon, &folder_str );
+ _atom_list_clear( k_atom_list_world );
vg_async_task_dispatch( task, skaterift_world_load_t1 );
}
}
else
{
- if( _cutscene.state != k_cutscene_state_none )
- {
+ if( (_cutscene.state != k_cutscene_state_none) && (_cutscene.state != k_cutscene_state_unloading) )
_cutscene_unload();
- }
+
vg_audio_fadeout_flagged_audio( AUDIO_FLAG_WORLD, 1.0f );
}
addon_reg *reg = addon_details(addon_id);
if( reg->flags & ADDON_REG_MTZERO )
{
- u64 status = _skaterift_atom_status( "ch2s5_view" );
+ i32 status = _atom_get( k_atom_list_global, "mtzero_part2" );
/* we've seen the cutscene already (1), or about to play it on world load (3).
* both of those statuses mean we load 'main'. */
for( u32 j=0; j<glider_count; j ++ )
{
ent_glider *glider = af_arritm( &world->ent_glider, glider_list[j] );
-
- if( !(glider->flags & 0x1) )
+ if( glider->flags & k_ent_glider_flag_locked )
continue;
m4x3f mdl;
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 ),
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 )
(fabsf(local[1]) <= 1.0f) &&
(fabsf(local[2]) <= 1.0f) )
{
+ bool enter = 1;
if( volume->flags & k_ent_volume_flag_interact )
{
if( localplayer.subsystem == k_player_subsystem_walk )
}
}
}
+ else enter = 0;
+ }
+
+ if( enter )
+ {
+ _world_raise_event( id, "enter" );
+ _world.active_trigger_volumes[ _world.active_trigger_volume_count ++ ] = index;
}
- _world_raise_event( id, "enter" );
- _world.active_trigger_volumes[ _world.active_trigger_volume_count ++ ] = index;
}
else
vg_line_boxf_transformed( volume->to_world, cube, 0xffcccccc );