turbo chaos
[carveJwlIkooP6JGAAIwe30JlM.git] / blender_export.py
index 2e202adac8c6a4032867003b036952697a7d1807..4b7cf7f0441809e5bed7a87c52dce3ab4dced40d 100644 (file)
@@ -39,12 +39,15 @@ sr_entity_list = [
    ('ent_ccmd',         'CCmd',           '', 17 ),
    ('ent_objective',    'Objective',      '', 18 ),
    ('ent_challenge',    'Challenge',      '', 19 ),
-   ('ent_relay',        'Relay',          '', 20 )
+   ('ent_relay',        'Relay',          '', 20 ),
+   ('ent_miniworld',    'Mini World',     '', 22 ),
+   ('ent_prop',         'Prop',           '', 23 )
 ]
 
-MDL_VERSION_NR = 102
+MDL_VERSION_NR = 104
 SR_TRIGGERABLE = [ 'ent_audio', 'ent_ccmd', 'ent_gate', 'ent_challenge', \
-                   'ent_relay', 'ent_skateshop', 'ent_objective' ]
+                   'ent_relay', 'ent_skateshop', 'ent_objective', 'ent_route',\
+                   'ent_miniworld' ]
 
 def get_entity_enum_id( alias ):
 #{
@@ -263,7 +266,11 @@ class ent_route(Structure):
                ("factive",c_float),
                ("board_transform",(c_float*3)*4),
                ("sm",mdl_submesh),
-               ("latest_pass",c_double)]
+               ("latest_pass",c_double),
+               ("id_camera",c_uint32), # v103+ 
+               ]
+
+   sr_functions = { 0: 'view' }
 #}
 
 class ent_water(Structure):
@@ -277,7 +284,7 @@ class ent_water(Structure):
 class volume_trigger(Structure):
 #{
    _fields_ = [("event",c_uint32),
-               ("blank",c_uint32)]
+               ("event_leave",c_uint32)]
 #}
 
 class volume_particles(Structure):
@@ -410,7 +417,8 @@ class ent_menuitem_slider(Structure):
 #}
 class ent_menuitem_button(Structure):
 #{
-   _fields_ = [("pstr",c_uint32)]
+   _fields_ = [("pstr",c_uint32),
+               ("stack_behaviour",c_uint32)]
 #}
 class ent_menuitem_checkmark(Structure):
 #{
@@ -424,13 +432,19 @@ class ent_menuitem_page(Structure):
                ("id_entrypoint",c_uint32),
                ("id_viewpoint",c_uint32)]
 #}
+class ent_menuitem_binding(Structure):
+#{
+   _fields_ = [("pstr_bind",c_uint32),
+               ("font_variant",c_uint32)]
+#}
 class ent_menuitem_anon_union(Union):
 #{
    _fields_ = [("slider",ent_menuitem_slider),
                ("button",ent_menuitem_button),
                ("checkmark",ent_menuitem_checkmark),
                ("page",ent_menuitem_page),
-               ("visual",ent_menuitem_visual)]
+               ("visual",ent_menuitem_visual),
+               ("binding",ent_menuitem_binding)]
 #}
 class ent_menuitem(Structure):
 #{
@@ -456,7 +470,8 @@ class ent_worldinfo(Structure):
    _fields_ = [("pstr_name",c_uint32),
                ("pstr_author",c_uint32),    # unused
                ("pstr_desc",c_uint32),      # unused
-               ("timezone",c_float)]
+               ("timezone",c_float),
+               ("pstr_skybox",c_uint32)]
 #}
 
 class ent_ccmd(Structure):
@@ -510,6 +525,22 @@ class ent_cubemap(Structure):#{
                ("placeholder",c_uint32*2)]
 #}
 
+class ent_miniworld(Structure):#{
+   _fields_ = [("transform",mdl_transform),
+               ("pstr_world",c_uint32),
+               ("camera",c_uint32),
+               ("proxy",c_uint32)]
+
+   sr_functions = { 0: 'zone', 1: 'leave' }
+#}
+
+class ent_prop(Structure):#{
+   _fields_ = [("transform",mdl_transform),
+               ("submesh_start",c_uint32),
+               ("submesh_count",c_uint32),
+               ("flags",c_uint32)]
+#}
+
 def obj_ent_type( obj ):
 #{
    if obj.type == 'ARMATURE': return 'mdl_armature'
@@ -1321,9 +1352,10 @@ def sr_compile_menus( collection ):
                sr_compile_mesh_internal( obj )
       #}
 
-      if item.type == 1 or item.type == 2:#{
+      if item.type == 1 or item.type == 2 or item.type == 7:#{
          item_button = item._anonymous_union.button
          item_button.pstr = sr_compile_string( obj_data.string )
+         item_button.stack_behaviour = int( obj_data.stack_behaviour )
       #}
       elif item.type == 0:#{
          item_visual = item._anonymous_union.visual
@@ -1351,6 +1383,11 @@ def sr_compile_menus( collection ):
          item_page.id_entrypoint = sr_entity_id( obj_data.newloc )
          item_page.id_viewpoint = sr_entity_id( obj_data.camera )
       #}
+      elif item.type == 6:#{
+         item_binding = item._anonymous_union.binding
+         item_binding.pstr_bind = sr_compile_string( obj_data.string )
+         item_binding.font_variant = obj_data.font_variant
+      #}
 
       if obj_data.link0:
          item.id_links[0] = sr_entity_id( obj_data.link0 )
@@ -1637,6 +1674,7 @@ def sr_compile( collection ):
          # entity ignore mesh list
          #
          if ent_type == 'ent_traffic': continue
+         if ent_type == 'ent_prop': continue
          if ent_type == 'ent_font': continue
          if ent_type == 'ent_font_variant': continue
          if ent_type == 'ent_menuitem': continue
@@ -1813,6 +1851,7 @@ def sr_compile( collection ):
             if obj_data.target:#{
                volume.target = sr_entity_id( obj_data.target )
                volume._anon.trigger.event = obj_data.target_event
+               volume._anon.trigger.event_leave = obj_data.target_event_leave
             #}
 
             sr_ent_push(volume)
@@ -1862,6 +1901,7 @@ def sr_compile( collection ):
             worldinfo.pstr_author = sr_compile_string( obj_data.author )
             worldinfo.pstr_desc = sr_compile_string( obj_data.desc )
             worldinfo.timezone = obj_data.timezone
+            worldinfo.pstr_skybox = sr_compile_string( obj_data.skybox )
             sr_ent_push( worldinfo )
          #}
          elif ent_type == 'ent_ccmd':#{
@@ -1925,6 +1965,24 @@ def sr_compile( collection ):
             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 = sr_compile_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()
+            compile_obj_transform( obj, prop.transform )
+            prop.submesh_start, prop.submesh_count, _ = \
+                  sr_compile_mesh_internal( obj )
+            prop.flags = 0
+            sr_ent_push( prop )
+         #}
       #}
    #}
 
@@ -1976,6 +2034,7 @@ def sr_compile( collection ):
          route.pstr_name = sr_compile_string( obj_data.alias )
          route.checkpoints_start = checkpoint_count
          route.checkpoints_count = 0
+         route.id_camera = sr_entity_id( obj_data.cam )
 
          for ci in range(3):
             route.colour[ci] = obj_data.colour[ci]
@@ -2560,6 +2619,17 @@ class SR_OBJECT_ENT_ROUTE_ENTRY(bpy.types.PropertyGroup):
                poll=lambda self,obj: sr_filter_ent_type(obj,['ent_gate']))
 #}
 
+class SR_OBJECT_ENT_MINIWORLD(bpy.types.PropertyGroup):
+#{
+   world: bpy.props.StringProperty( name='world UID' )
+   proxy: bpy.props.PointerProperty( \
+               type=bpy.types.Object, name='proxy', \
+               poll=lambda self,obj: sr_filter_ent_type(obj,['ent_prop']))
+   camera: bpy.props.PointerProperty( \
+           type=bpy.types.Object, name="Camera", \
+           poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera']))
+#}
+
 class SR_UL_ROUTE_NODE_LIST(bpy.types.UIList):
 #{
    bl_idname = 'SR_UL_ROUTE_NODE_LIST'
@@ -2876,11 +2946,16 @@ class SR_OBJECT_ENT_ROUTE(bpy.types.PropertyGroup):
           name="Alias",\
           default="Untitled Course")
 
+   cam: bpy.props.PointerProperty( \
+           type=bpy.types.Object, name="Viewpoint", \
+           poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera']))
+
    @staticmethod
    def sr_inspector( layout, data ):
    #{
       layout.prop( data[0], 'alias' )
       layout.prop( data[0], 'colour' )
+      layout.prop( data[0], 'cam' )
 
       layout.label( text='Checkpoints' )
       layout.template_list('SR_UL_ROUTE_NODE_LIST', 'Checkpoints', \
@@ -2902,40 +2977,44 @@ class SR_OBJECT_ENT_VOLUME(bpy.types.PropertyGroup):#{
    target: bpy.props.PointerProperty( \
            type=bpy.types.Object, name="Target", \
            poll=lambda self,obj: sr_filter_ent_type(obj,SR_TRIGGERABLE))
-   target_event: bpy.props.IntProperty( name="Event/Method" )
+   target_event: bpy.props.IntProperty( name="Enter Ev" )
+   target_event_leave: bpy.props.IntProperty( name="Leave Ev" )
 
    @staticmethod
-   def inspect_target( layout, data, propname ):#{
+   def inspect_target( layout, data, propname, evs = ['_event'] ):#{
       box = layout.box()
       box.prop( data[0], propname )
 
-      row = box.row()
-      row.prop( data[0], propname + '_event')
-
-      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+'_event')
-            if index in table:
-               row.label( text=table[index] )
-            else:
-               row.label( text="undefined function" )
+      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
          #}
-      #}
-      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' )
+      SR_OBJECT_ENT_VOLUME.inspect_target( layout, data, 'target', \
+            ['_event','_event_leave'] )
    #}
 #}
 
@@ -3129,6 +3208,10 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
    newloc: bpy.props.PointerProperty( \
            type=bpy.types.Object, name="New location", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_menuitem']))
+   stack_behaviour: bpy.props.EnumProperty( name='Stack Behaviour',
+                                 items=[('0','append',''),
+                                        ('1','replace','')])
+
    camera: bpy.props.PointerProperty( \
            type=bpy.types.Object, name="Camera", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_camera']))
@@ -3147,6 +3230,8 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
            type=bpy.types.Object, name="Checked", \
            poll=lambda self,obj: sr_filter_ent_type(obj,['ent_menuitem']))
 
+   font_variant: bpy.props.IntProperty( name="Font Variant" )
+
    string: bpy.props.StringProperty( name="String" )
    tipo: bpy.props.EnumProperty( name='Type',
                                  items=[('0','visual',''),
@@ -3154,7 +3239,9 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
                                         ('2','page button',''),
                                         ('3','toggle', ''),
                                         ('4','slider',''),
-                                        ('5','page','')])
+                                        ('5','page',''),
+                                        ('6','binding',''),
+                                        ('7','visual(no colourize)','')])
 
    @staticmethod
    def sr_inspector( layout, data ):
@@ -3163,7 +3250,7 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
       box = layout.box()
       box.prop( data, 'tipo' )
 
-      if data.tipo == '0':#{
+      if data.tipo == '0' or data.tipo == '7':#{
          box.prop( data, 'string', text='Name' )
          return
       #}
@@ -3172,7 +3259,7 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
       #}
       elif data.tipo == '2':#{
          box.prop( data, 'string', text='Page' )
-         box.prop( data, 'newloc' )
+         box.prop( data, 'stack_behaviour' )
       #}
       elif data.tipo == '3':#{
          box.prop( data, 'string', text='Data (i32)' )
@@ -3195,6 +3282,11 @@ class SR_OBJECT_ENT_MENU_ITEM(bpy.types.PropertyGroup):
          box.prop( data, 'camera', text='Viewpoint' )
          return
       #}
+      elif data.tipo == '6':#{
+         box.prop( data, 'string', text='ID' )
+         box.prop( data, 'font_variant' )
+         return
+      #}
       
       box = box.box()
       box.label( text="Links" )
@@ -3211,6 +3303,7 @@ class SR_OBJECT_ENT_WORLD_INFO(bpy.types.PropertyGroup):
    desc: bpy.props.StringProperty(name="Description")
    author: bpy.props.StringProperty(name="Author")
    timezone: bpy.props.FloatProperty(name="Timezone(hrs) (UTC0 +hrs)")
+   skybox: bpy.props.StringProperty(name="Skybox")
 #}
 
 class SR_OBJECT_ENT_CCMD(bpy.types.PropertyGroup):
@@ -3334,6 +3427,7 @@ class SR_OBJECT_PROPERTIES(bpy.types.PropertyGroup):
    ent_objective: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_OBJECTIVE)
    ent_challenge: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_CHALLENGE)
    ent_relay: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_RELAY)
+   ent_miniworld: bpy.props.CollectionProperty(type=SR_OBJECT_ENT_MINIWORLD)
 
    ent_type: bpy.props.EnumProperty(
       name="Type",
@@ -4561,7 +4655,7 @@ classes = [ SR_INTERFACE, SR_MATERIAL_PANEL,\
             SR_OBJECT_ENT_WORKSHOP_PREVIEW,SR_OBJECT_ENT_MENU_ITEM,\
             SR_OBJECT_ENT_WORLD_INFO,SR_OBJECT_ENT_CCMD,\
             SR_OBJECT_ENT_OBJECTIVE,SR_OBJECT_ENT_CHALLENGE,\
-            SR_OBJECT_ENT_RELAY,\
+            SR_OBJECT_ENT_RELAY,SR_OBJECT_ENT_MINIWORLD,\
             \
             SR_OBJECT_PROPERTIES, SR_LIGHT_PROPERTIES, SR_BONE_PROPERTIES, 
             SR_MESH_PROPERTIES, SR_MATERIAL_PROPERTIES \