uniform sampler2D uTexMain;
uniform vec3 uCamera;
+uniform int uShadeless;
in vec4 aColour;
in vec2 aUv;
{
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);
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 );
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
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 );
('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 ),
('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 ):
#{
("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),
("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):
# 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):
("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):
("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):
class volume_interact(Structure):
#{
- _fields_ = [("event",c_uint32),
+ _fields_ = [("blank",c_uint32),
("pstr_text",c_int32)]
#}
("to_world",(c_float*3)*4),
("to_local",(c_float*3)*4),
("flags",c_uint32),
- ("target",c_uint32),
+ ("deleted0",c_uint32),
("_anon",volume_union)]
#}
("group",c_uint32),
("probability_curve",c_uint32),
("max_channels",c_uint32)]
+ sr_functions = { 'play': 0x00, 'spawn_particle': 0x00 }
#}
class ent_marker(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):
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):
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),
("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):#{
("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
("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),
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)
#}
#}
#}
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"
_.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:#{
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 '' )
#}
#}
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' )
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' )
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',''),
(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' )
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", \
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" )
#}
#}
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' )
#}
#}
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):
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)
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):
('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,\
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 #
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
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 ):
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)) )
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
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):#{
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':
#{
#}
#}
#}
- 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:
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 )
- #}
- #}
#}
#}
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,\
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():
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():
#}
#}
- 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':
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()
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
#}
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
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]
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]
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 )
# 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)
#}
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 )
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
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 )
#}
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
#{
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()
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()
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 )
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)
+ #}
#}
#}
("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):
("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
#{
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)])
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)
#}
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 )
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 )
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:
#{
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 )
#}
#}
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 )
#}
#}
#{
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 )
#}
--- /dev/null
+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;
+}
#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,
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 ) )
{
}
}
-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)
{
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 );
}
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 )
}
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;
}
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 )
#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 );
#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;
}
#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 );
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
+}
player_pose pose;
m4x3f *final_mtx;
}
- jc, mike;
+ humans[4];
+
struct skeleton_anim anim_idle;
enum npc_sub_state
}
_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
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; i<VG_ARRAY_LEN(_gino_contexts); i ++ )
- _gino_contexts[i].alias_hash = vg_strdjb2( _gino_contexts[i].alias );
+ for( u32 i=0; i<k_npc_max; i ++ )
+ {
+ struct sub_context *contexts = _sub_contexts[ i ];
+ if( !contexts )
+ continue;
+
+ for( u32 i=0; i<1000; i ++ )
+ {
+ struct sub_context *context = &contexts[i];
+ if( context->alias == NULL )
+ break;
+
+ context->alias_hash = vg_strdjb2( context->alias );
+ }
+ }
void *alloc = vg_mem.rtmemory;
mdl_context *mdl = &_npc.gino.mdl;
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" );
}
_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 )
}
}
- 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 );
+ }
}
}
{
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 );
+ }
}
}
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; i<k_npc_max; i ++ )
+ {
+ if( npc_aliases[i] )
+ {
+ if( AF_STR_EQ( &world->meta.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; i<VG_ARRAY_LEN(_gino_contexts); i ++ )
- if( (hash == _gino_contexts[i].alias_hash) && !strcmp(_gino_contexts[i].alias,alias) )
- _ent_npc_speech( k_npc_gino, _gino_contexts[i].subtitles );
+ _ent_npc_speech( npc_id, af_str( &world->meta.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 );
_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; i<VG_ARRAY_LEN(_jc_contexts); i ++ )
- if( (hash == _jc_contexts[i].alias_hash) && !strcmp(_jc_contexts[i].alias,alias) )
- _ent_npc_speech( k_npc_gino, _jc_contexts[i].subtitles );
+ _ent_npc_speech( npc_id, af_str( &world->meta.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;
}
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
};
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 );
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 );
{
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);
}
}
-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;
}
#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 );
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 ),
}
}
- return k_entity_call_result_OK;
+ return k_entity_event_result_OK;
}
- else if( call->function == 1 ) /* leave */
- {
- for( u32 i=0; i<af_arrcount(&world->ent_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;
}
/*
}
}
- /* run unlock triggers. v105+ */
- if( world->meta.version >= 105 )
- {
- for( u32 j=0; j<af_arrcount( &world->ent_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 )
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 );
#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; i<VG_ARRAY_LEN(relay->targets); 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;
-}
#pragma once
#include "entity.h"
-entity_call_result ent_relay_call( world_instance *world, ent_call *call );
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();
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)
}
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 );
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; i<af_arrcount( &world->ent_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;
}
}
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;
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 );
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 )
}
}
-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 )
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);
#include <string.h>
-/*
- * 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; i<af_arrcount(arr); i++ )
- {
- ent_marker *marker = af_arritm( arr, i );
-
- if( !strcmp( af_str( &mdl->af, marker->pstr_alias ), alias ) )
- {
- return marker;
- }
- }
-
- return NULL;
-}
-
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,
k_ent_glider = 26,
k_ent_npc = 27,
k_ent_armature = 28,
- k_ent_script = 29,
+ k_ent_script = 29,
k_ent_max
};
[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",
[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;
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,
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;
};
struct file_entity_ref
{
- u32 entity_id;
+ u32 entity_id, pstr_alias;
};
/* v102+ */
k_ent_gate_passive = 0x80
};
-struct ent_gate{
+struct ent_gate
+{
u32 flags,
target,
key;
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 */
}
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;
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;
};
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;
};
};
-struct ent_audio{
+struct ent_audio
+{
mdl_transform transform;
u32 flags,
clip_start,
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;
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
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
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
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;
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,
k_prop_flag_spinning_fast = 0x8,
};
-struct ent_prop {
+struct ent_prop
+{
mdl_transform transform;
u32 submesh_start, submesh_count, flags, pstr_alias;
};
};
/* 105+ */
- u32 target0[2];
+ u32 deleted01[2];
};
-struct ent_glider {
+struct ent_glider
+{
mdl_transform transform;
u32 flags;
f32 cooldown;
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;
+};
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 )
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;
{
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;
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();
_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;
}
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 )
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; i<k_npc_max; i ++ )
_ent_npc_set_in_cutscene( i, 0 );
_cutscene.state = k_cutscene_state_loading;
- _cutscene.subtitle_list = subtitles;
- _cutscene.subtitle_index = 0;
_cutscene.time = 0.0f;
_cutscene.strip = 0;
_cutscene.active_samplers = 0;
shader_model_character_view_uCamera( cam->transform[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 );
u32 armature_id = 0x00;
u32 material_id = 0x00;
+ bool using_additive = 0;
for( u32 i=0; i<mdl->mesh_count; i ++ )
{
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; j<mesh->submesh_count; j ++ )
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
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
_cutscene.state = k_cutscene_state_none;
_cutscene.marker_this_frame = NULL;
_cutscene.subtitle = NULL;
- _cutscene.subtitle_length_warning = 0;
+ _cutscene.raiser_entity = 0;
return;
}
{
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
{
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; j<strip->data_count; j ++ )
+ for( u32 j=0; j<strip->strip.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;
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) );
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 );
}
}
}
/* 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;
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 ),
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;
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);
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 ++;
}
{
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 );
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;
}
for( u32 k=0; k<VG_ARRAY_LEN(usage); k ++ )
{
if( usage[k] )
- if( usage[k]->offset + usage[k]->length < strip->offset )
+ if( usage[k]->offset + usage[k]->strip.length < strip->offset )
usage[k] = NULL;
if( !usage[k] )
}
}
- 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 );
}
}
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
m4x3f *skinning_data;
};
+struct cs_subtitle
+{
+ const char *key, *value;
+};
+
#include "skeleton.h"
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;
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 );
{
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;
}
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 );
for( u32 i=0; i<af_arrcount( &ms->strips ); 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;
}
}
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(
{
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;
}
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,
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;
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,
}
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 )
}
}
-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];
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;
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;
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 */
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[] =
{
// 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
// 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[] =
{
_cutscene_load_and_play( "metascenes/ch3s2.ms", EN, 1 );
}
}
+#endif
return 1;
}
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;
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[] =
{
}
}
}
+#endif
return 1;
}
--- /dev/null
+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;
+}
--- /dev/null
+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;
+}
}
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;
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;
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<VG_ARRAY_LEN(blocks); i ++ )
- {
- u64 status;
- if( on_nugget_changed( event, blocks[i].nugget, &status ) )
+ i32 highest_index = -1;
+ for( i32 i=0; i<VG_ARRAY_LEN(blocks); i ++ )
+ {
+ blocks[i].unlocked = 0;
+ ent_list *list = _ent_list_get_aliased( blocks[i].list_name );
+ if( progress >= _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; i<af_arrcount(&world->ent_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; i<af_arrcount( &world->ent_prop ); i ++ )
{
ent_prop *prop = af_arritm( &world->ent_prop, i );
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; i<af_arrcount(&world->ent_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;
marker->flags |= (u32)k_ent_marker_flag_hidden;
}
}
-
+#endif
return 0;
}
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[] =
{
}
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;
}
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[] =
{
}
}
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[] =
{
}
}
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?" },
_cutscene_load_and_play( "metascenes/ch2s5.ms", EN, 1 );
}
}
+#endif
return 1;
}
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;
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" },
}
}
}
+#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." },
}
}
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;
}
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;
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 )
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" );
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;
}
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;
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 )
}
}
+ 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." },
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!" },
}
}
+ 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?" },
}
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 |################################################| */
_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." },
{ "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;
}
--- /dev/null
+#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
#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
{
}
-m4x3f *_TEMP_VAR = NULL; /*FIXME*/
-
static void skaterift_composite_maincamera(void)
{
/* world entity driven camera
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 );
#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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
- if( _cutscene.state == k_cutscene_state_done )
- {
- state = k_escript_state_end;
- vg_info( "test:state = end\n" );
- _cutscene_unload();
- return 1;
- }
+ struct script_save_atom *atom = &_skaterift_script_savedata[i];
+ if( !strcmp( alias, atom->alias ) )
+ 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; i<sk->bone_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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
- if( _cutscene.state == k_cutscene_state_done )
- {
- state = k_escript_state_end;
- vg_info( "test:state = end\n" );
- _cutscene_unload();
- return 1;
- }
+ struct script_save_atom *atom = &_skaterift_script_savedata[i];
+ if( atom->type == 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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
- struct generic_cutscene *generic = event->userdata;
-
- 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;
}
}
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
#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
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 },
{ "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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
- {
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- if( !strcmp( nugget_alias, nugget->alias ) )
- 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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
- {
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- if( !strcmp( nugget_alias, nugget->alias ) )
- {
- 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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
- {
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- vg_msg_wkvnum( sav, nugget->alias, k_vg_msg_u64, 1, &nugget->status );
- }
-}
-
-void _skaterift_script_load_savedata( vg_msg *sav )
-{
- for( u32 i=0; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
- {
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- vg_msg_getkvintg( sav, nugget->alias, k_vg_msg_u64, &nugget->status, NULL );
- }
-}
+/* console eventts
+ * ------------------------------------------------------------------------------------------------------------- */
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" ) )
for( u32 i=0; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- if( all || !strcmp( argv[1], nugget->alias ) )
+ 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 );
+ }
}
}
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; i<VG_ARRAY_LEN( _skaterift_script_savedata ); i ++ )
{
- struct script_save_nugget *nugget = &_skaterift_script_savedata[i];
- console_suggest_score_text( nugget->alias, 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" ) )
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)
#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 );
static u32 skeleton_bone_id( struct skeleton *skele, const char *name )
{
- for( u32 i=1; i<skele->bone_count; i++ ){
+ for( u32 i=1; i<skele->bone_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" );
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; i<num; i++ )
kfb[i] = kfa[i];
/* apply a rotation from the perspective of root */
-static void keyframe_rotate_around( ms_keyframe *kf,
- v3f origin, v3f offset, v4f q )
+static void keyframe_rotate_around( ms_keyframe *kf, v3f origin, v3f offset, v4f q )
{
v3f v0, co;
v3_add( kf->co, offset, co );
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 );
/*
* 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;
}
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 );
}
*
* 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;
}
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
/*
* 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 )
{
{
struct skeleton_bone *sb = &skele->bones[i],
*sp = &skele->bones[sb->parent];
-
if( !should_apply_bone( skele, i, passtype ) )
continue;
/*
* 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; i<skele->bone_count; i++ ){
+static void skeleton_decompose_mtx_absolute( struct skeleton *skele, ms_keyframe *anim, m4x3f *final_mtx )
+{
+ for( u32 i=1; i<skele->bone_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 );
* 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] );
static void skeleton_create_inverses( struct skeleton *skele )
{
/* IK: inverse 'plane-bone space' axis '(^axis,^bone,...)[base] */
- for( u32 i=0; i<skele->ik_count; i++ ){
+ for( u32 i=0; i<skele->ik_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 );
/*
* 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; i<skele->bone_count; i++ ){
+ for( u32 i=0; i<skele->bone_count; i++ )
+ {
struct skeleton_bone *sb = &skele->bones[i];
m4x3_mul( transform, final_mtx[i], final_mtx[i] );
}
* 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; i<skele->bone_count; i++ ){
+static void skeleton_apply_inverses( struct skeleton *skele, m4x3f *final_mtx )
+{
+ for( u32 i=0; i<skele->bone_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] );
}
}
for( u32 i=0; i<skele->ik_count; i++ )
{
struct skeleton_ik *ik = &skele->ik[i];
-
v3f v0, /* base -> target */
v1, /* base -> pole */
vaxis;
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;
* 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 );
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;
for( u32 i=0; i<armature->bone_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 ++;
}
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;
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 ++;
}
}
vg_success( " %u colliders\n", skele->collider_count );
}
-static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx ){
- for( u32 i=1; i<skele->bone_count; i ++ ){
+static void skeleton_debug( struct skeleton *skele, m4x3f *final_mtx )
+{
+ for( u32 i=1; i<skele->bone_count; i ++ )
+ {
struct skeleton_bone *sb = &skele->bones[i];
-
v3f p0, p1;
v3_copy( sb->co, p0 );
v3_add( p0, sb->end, p1 );
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 );
ent_list,
ent_npc,
file_entity_ref,
+ ent_event,
ent_script;
GLuint *nonlocal_gates_cubemaps;
}
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;
}
}
-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; i<audio->clip_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;
}
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;
}
/*
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;
{
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
{
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;
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; j<route->checkpoints_count; j ++ )
sections[j] = 0.0f;
- }
for( u32 j=0; j<route->checkpoints_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; j<VG_ARRAY_LEN(track_infos); j ++ )
- {
- struct track_info *inf = &track_infos[j];
- if( !strcmp( inf->name, 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;
- }
- }
- }
- }
}
}
}
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; i<af_arrcount( &world->ent_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 );
+ }
+ }
+}
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 );
void update_ach_models(void);
extern bh_system bh_system_entity_list;
+void _world_raise_event( u32 caller, const char *event_alias );
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] )
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 );
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;
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'. */
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;
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 } );
void world_routes_clear( world_instance *world )
{
- for( u32 i=0; i<af_arrcount( &world->ent_route ); i++ ){
+ for( u32 i=0; i<af_arrcount( &world->ent_route ); i++ )
+ {
ent_route *route = af_arritm( &world->ent_route, i );
route->active_checkpoint = 0xffff;
}
for( u32 i=0; i<af_arrcount( &world->ent_gate ); i++ )
{
ent_gate *rg = af_arritm( &world->ent_gate, i );
-
if( !(rg->flags & k_ent_gate_nonlocal) )
{
rg->timing_version = 0;
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 )
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;
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
{
}
}
}
- 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;
if( volume->flags & k_ent_volume_flag_particles )
{
- vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );
-
for( int j=0; j<random_ticks; j++ )
{
- ent_call basecall;
- basecall.id = id;
- basecall.data = NULL;
- basecall.function = 0;
-
- entity_call( world, &basecall );
+ v3f co;
+ 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, 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
{
{
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
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" );
}
}
}
struct _world_volumes
{
- ent_volume *active_volume_interact;
+ u32 active_volume_interact;
}
extern _world_volumes;
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;
}
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 );