some gate improvements
authorhgn <hgodden00@gmail.com>
Fri, 21 Jul 2023 01:35:50 +0000 (02:35 +0100)
committerhgn <hgodden00@gmail.com>
Fri, 21 Jul 2023 01:35:50 +0000 (02:35 +0100)
14 files changed:
blender_export.py
entity.h
maps_src/mp_spawn/main.mdl
model.h
player.c
player_skate.c
shaders/model_gate.h
shaders/model_gate.vs
world_entity.c
world_gate.c
world_gate.h
world_gen.c
world_render.c
world_routes.c

index 820c49ac05e6f721af4ca38ab7f02e200bb5e616..8eb39a365dba70129c69776182175b39a30ea90f 100644 (file)
@@ -39,6 +39,8 @@ sr_entity_list = [
    ('ent_challenge',    'Challenge',      '', 18 )
 ]
 
+MDL_VERSION_NR = 102
+
 def get_entity_enum_id( alias ):
 #{
    for et in sr_entity_list:#{
@@ -186,7 +188,7 @@ class version_refcount_union(Union):
 
 class ent_gate(Structure):
 #{
-   _fields_ = [("type",c_uint32),
+   _fields_ = [("flags",c_uint32),
                ("target", c_uint32),
                ("key",c_uint32),
                ("dimensions", c_float*3),
@@ -197,7 +199,10 @@ class ent_gate(Structure):
                ("_anonymous_union",version_refcount_union),
                ("timing_time",c_double),
                ("routes",c_uint16*4),
-               ("route_count",c_uint8)]
+               ("route_count",c_uint8),
+               ("submesh_start",c_uint32), # v102+ 
+               ("submesh_count",c_uint32), # v102+ (can be 0)
+               ]
 #}
 
 class ent_route_node(Structure):
@@ -1572,6 +1577,12 @@ def sr_compile( collection ):
          if ent_type == 'ent_font_variant': continue
          if ent_type == 'ent_menuitem': continue
          if ent_type == 'ent_challenge': continue
+
+         #TODO: This is messy.
+         if ent_type == 'ent_gate':#{
+            obj_data = obj.SR_data.ent_gate[0]
+            if obj_data.custom: continue
+         #}
          #--------------------------
 
          print( F'[SR] {i: 3}/{mesh_count} {obj.name:<40}', end='\r' )
@@ -1619,18 +1630,27 @@ def sr_compile( collection ):
             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:#{
                   gate.target = sr_compile.entity_ids[obj_data.target.name]
-                  gate.type = 1
+                  flags |= 0x0001
                #}
             #}
             elif obj_data.tipo == 'nonlocal':#{
                gate.target = 0
                gate.key = sr_compile_string(obj_data.key)
-               gate.type = 2
+               flags |= 0x0002
+            #}
+
+            if obj_data.flip:   flags |= 0x0004
+            if obj_data.custom:#{
+               flags |= 0x0008
+               gate.submesh_start, gate.submesh_count, _ = \
+                     sr_compile_mesh_internal( obj )
             #}
-            else: gate.type = 0
+            gate.flags = flags
             
             gate.dimensions[0] = mesh_data.dimensions[0]
             gate.dimensions[1] = mesh_data.dimensions[1]
@@ -1996,7 +2016,7 @@ def sr_compile( collection ):
    os.makedirs(os.path.dirname(path),exist_ok=True)
    fp = open( path, "wb" )
    header = mdl_header()
-   header.version = 101
+   header.version = MDL_VERSION_NR
    sr_array_title( header.arrays, \
                    'index', len(file_array_instructions), \
                    sizeof(mdl_array), header_size )
@@ -2380,7 +2400,10 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup):
 
    key: bpy.props.StringProperty()
    tipo: bpy.props.EnumProperty(items=(('default', 'Default', ""),
-                                       ('nonlocal', 'Non-Local', ""),))
+                                       ('nonlocal', 'Non-Local', "")))
+
+   flip: bpy.props.BoolProperty( name="Flip exit", default=False )
+   custom: bpy.props.BoolProperty( name="Mesh is surface", default=False )
 
    @staticmethod
    def sr_inspector( layout, data ):
@@ -2390,6 +2413,10 @@ class SR_OBJECT_ENT_GATE(bpy.types.PropertyGroup):
 
       if   data[0].tipo == 'default':  box.prop( data[0], 'target' )
       elif data[0].tipo == 'nonlocal': box.prop( data[0], 'key' )
+
+      flags = box.box()
+      flags.prop( data[0], 'flip' )
+      flags.prop( data[0], 'custom' )
    #}
 #}
 
index 05294f3b58809d3c800f7af03623d849370487c8..da2341e5618149e1788acb63febdbb821607adf3 100644 (file)
--- a/entity.h
+++ b/entity.h
@@ -91,15 +91,27 @@ struct ent_light{
    v2f angle_sin_cos;
 };
 
+/* v101 */
+#if 0
 enum gate_type{
    k_gate_type_unlinked = 0,
    k_gate_type_teleport = 1,
    k_gate_type_nonlocal_unlinked = 2,
    k_gate_type_nonlocel = 3
 };
+#endif
+
+/* v102+ */
+enum ent_gate_flag{
+   k_ent_gate_linked      = 0x1, /* this is a working portal */
+   k_ent_gate_nonlocal    = 0x2, /* use the key string to link this portal.
+                                       NOTE: if set, it adds the flip flag. */
+   k_ent_gate_flip        = 0x4, /* flip direction 180* for exiting portal */
+   k_ent_gate_custom_mesh = 0x8, /* use a custom submesh instead of default */
+};
 
 struct ent_gate{
-   u32 type,
+   u32 flags,
        target, 
        key;
 
@@ -122,6 +134,9 @@ struct ent_gate{
    double timing_time;
    u16 routes[4];       /* routes that pass through this gate */
    u8 route_count;
+
+   /* v102+ */
+   u32 submesh_start, submesh_count;
 };
 
 struct ent_route_node{
index 5df1a39b3706c460754163a903c43bcb8e51874b..4467e7b18e3e9baa1dfc01a7350a1cafcce6296b 100644 (file)
Binary files a/maps_src/mp_spawn/main.mdl and b/maps_src/mp_spawn/main.mdl differ
diff --git a/model.h b/model.h
index 6ff0a857eaf9d036b1fa050511844ddeb0790fe3..f9ec815dfc78a42f63b0b1e4cdb323c81be96920 100644 (file)
--- a/model.h
+++ b/model.h
@@ -7,7 +7,8 @@
 
 #include "skaterift.h"
 
-#define MDL_VERSION_NR 101
+#define MDL_VERSION_MIN 101
+#define MDL_VERSION_NR 102
 
 enum mdl_shader
 {
@@ -414,10 +415,10 @@ VG_STATIC void mdl_open( mdl_context *mdl, const char *path, void *lin_alloc )
    if( l != 1 )
       mdl_load_fatal_corrupt( mdl );
 
-   if( mdl->info.version < MDL_VERSION_NR ){
+   if( mdl->info.version < MDL_VERSION_MIN ){
       vg_warn( "For model: %s\n", path );
-      vg_warn( "  version: %u (current: %u)\n", mdl->info.version
-               MDL_VERSION_NR );
+      vg_warn( "  version: %u (min: %u, current: %u)\n"
+               mdl->info.version, MDL_VERSION_MIN, MDL_VERSION_NR );
 
       vg_fatal_error( "Legacy model version incompatable" );
    }
index b67e050abd8807c832b1cc4fa0cd86f5025acc7a..ab393197b29b374df31e39813dcbf4d66210f8ae 100644 (file)
--- a/player.c
+++ b/player.c
@@ -164,7 +164,7 @@ void player__pass_gate( player_instance *player, ent_gate *gate )
 
    m4x3_mulv( gate->transport, player->cam.pos, player->cam.pos );
 
-   if( gate->type == k_gate_type_nonlocel )
+   if( gate->flags & k_ent_gate_nonlocal )
       world_static.active_world = gate->target;
 
    audio_lock();
index ac1423962e8f52113ceaed2bc788219e6fbe2371..baa1ce713116ed266d3afb00af5711b00bb0a99f 100644 (file)
@@ -499,7 +499,7 @@ void player__approximate_best_trajectory( player_instance *player )
                m4x3_mulv( gate->transport, launch_co, launch_co );
                m3x3_mul( gate->transport, basis, basis );
 
-               if( gate->type == k_gate_type_nonlocel ){
+               if( gate->flags & k_ent_gate_nonlocal ){
                   trace_world = &world_static.worlds[ gate->target ];
                }
             }
index fc9c1ea326b904532f78be6249efb0e78f08e549..cd2c29b1832e962282c610737a33461b6413476a 100644 (file)
@@ -12,9 +12,6 @@ static struct vg_shader _shader_model_gate = {
 "layout (location=0) in vec3 a_co;\n"
 "layout (location=1) in vec3 a_norm;\n"
 "layout (location=2) in vec2 a_uv;\n"
-"layout (location=3) in vec4 a_colour;\n"
-"layout (location=4) in vec4 a_weights;\n"
-"layout (location=5) in ivec4 a_groups;\n"
 "\n"
 "uniform mat4 uPv;\n"
 "uniform mat4x3 uMdl;\n"
index edea94d1ce9a77330a12cbe353181ba2344853df..ce70d5271cc2625b94323a96f098b5fbca4c792e 100644 (file)
@@ -1,9 +1,6 @@
 layout (location=0) in vec3 a_co;
 layout (location=1) in vec3 a_norm;
 layout (location=2) in vec2 a_uv;
-layout (location=3) in vec4 a_colour;
-layout (location=4) in vec4 a_weights;
-layout (location=5) in ivec4 a_groups;
 
 uniform mat4 uPv;
 uniform mat4x3 uMdl;
index db1d244f490506165b3e45a9744aae764fdd3bb3..7e285d44a54731ea3cd73e93885ff10ed6d70d74 100644 (file)
@@ -26,7 +26,7 @@ VG_STATIC void world_gen_entities_init(void){
    for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, j );
 
-      if( gate->type == k_gate_type_teleport ){
+      if( !(gate->flags & k_ent_gate_nonlocal) ) {
          gate_transform_update( gate );
       }
    }
index a61bc162811e9462572201cef0488a396240934c..a4cf8fdc703e8b21ae976918e924bbb5206fb671 100644 (file)
 /*
  * Update the transform matrices for gate
  */
-VG_STATIC void gate_transform_update( ent_gate *gate )
-{
+VG_STATIC void gate_transform_update( ent_gate *gate ){
+   if( gate->flags & k_ent_gate_flip ){
+      v4f qflip;
+      q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf );
+      q_mul( gate->q[1], qflip, gate->q[1] );
+   }
+
    m4x3f to_local, recv_to_world;
 
    q_m3x3( gate->q[0], gate->to_world );
@@ -32,9 +37,6 @@ VG_STATIC void gate_transform_update( ent_gate *gate )
    q_m3x3( gate->q[1], recv_to_world );
    v3_copy( gate->co[1], recv_to_world[3] );
    m4x3_mul( recv_to_world, to_local, gate->transport );
-
-   m3x3_scale( gate->to_world, (v3f){ gate->dimensions[0], 
-                                      gate->dimensions[1], 1.0f } );
 }
 
 VG_STATIC void world_gates_init(void)
@@ -69,7 +71,7 @@ VG_STATIC void world_gates_init(void)
 /*
  * Render the view through a gate
  */
-VG_STATIC int render_gate( world_instance *world_inside,
+VG_STATIC int render_gate( world_instance *world, world_instance *world_inside,
                            ent_gate *gate, camera *cam, int layer_depth )
 {
    v3f viewdir, gatedir;
@@ -89,19 +91,20 @@ VG_STATIC int render_gate( world_instance *world_inside,
       return 0;
 
    {
-      v3f a,b,c,d;
+      f32 w = gate->dimensions[0],
+          h = gate->dimensions[1];
 
-      m4x3_mulv( gate->to_world, (v3f){-1.0f,-1.0f,0.0f}, a );
-      m4x3_mulv( gate->to_world, (v3f){ 1.0f,-1.0f,0.0f}, b );
-      m4x3_mulv( gate->to_world, (v3f){ 1.0f, 1.0f,0.0f}, c );
-      m4x3_mulv( gate->to_world, (v3f){-1.0f, 1.0f,0.0f}, d );
+      v3f a,b,c,d;
+      m4x3_mulv( gate->to_world, (v3f){-w,-h,0.0f}, a );
+      m4x3_mulv( gate->to_world, (v3f){ w,-h,0.0f}, b );
+      m4x3_mulv( gate->to_world, (v3f){ w, h,0.0f}, c );
+      m4x3_mulv( gate->to_world, (v3f){-w, h,0.0f}, d );
 
       vg_line( a,b, 0xffffa000 );
       vg_line( b,c, 0xffffa000 );
       vg_line( c,d, 0xffffa000 );
       vg_line( d,a, 0xffffa000 );
-
-      vg_line2( gate->co[0], gate->co[1], 0xff0000ff, 0x00000000 );
+      vg_line( gate->co[0], gate->co[1], 0xff0000ff );
    }
 
    /* update gate camera */
@@ -131,7 +134,6 @@ VG_STATIC int render_gate( world_instance *world_inside,
    {
       shader_model_gate_use();
       shader_model_gate_uPv( cam->mtx.pv );
-      shader_model_gate_uMdl( gate->to_world );
       shader_model_gate_uCam( cam->pos );
       shader_model_gate_uColour( (v4f){0.0f,1.0f,0.0f,0.0f} );
       shader_model_gate_uTime( vg.time*0.25f );
@@ -143,13 +145,33 @@ VG_STATIC int render_gate( world_instance *world_inside,
       glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );  
       glStencilFunc( GL_ALWAYS, 1, 0xFF ); 
       glStencilMask( 0xFF );
+      glDisable( GL_CULL_FACE );
+
+      m4x3f mmdl;
+      m4x3_copy( gate->to_world, mmdl );
+      
+      if( gate->flags & k_ent_gate_custom_mesh ){
+         mesh_bind( &world->mesh_no_collide );
+         for( u32 i=0; i<gate->submesh_count; i++ ){
+            mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                          gate->submesh_start+i );
+            mdl_draw_submesh( sm );
+         }
+      }
+      else {
+         m3x3_scale( mmdl, (v3f){ gate->dimensions[0], 
+                                  gate->dimensions[1], 1.0f } );
+
+         mesh_bind( &world_gates.mesh );
+         mdl_draw_submesh( &world_gates.sm_surface );
+      }
 
-      mesh_bind( &world_gates.mesh );
-      mdl_draw_submesh( &world_gates.sm_surface );
+      shader_model_gate_uMdl( mmdl );
 
       glClear( GL_DEPTH_BUFFER_BIT );
       glStencilFunc( GL_EQUAL, 1, 0xFF );
       glStencilMask( 0x00 ); 
+      glEnable( GL_CULL_FACE );
    }
 
    render_world( world_inside, &world_gates.cam, layer_depth );
@@ -225,7 +247,8 @@ VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last )
    v2f xy;
 
    if( gate_intersect_plane( gate, pos, last, xy ) ){
-      if( fabsf(xy[0]) <= 1.0f && fabsf(xy[1]) <= 1.0f ){
+      if( (fabsf(xy[0]) <= gate->dimensions[0]) && 
+          (fabsf(xy[1]) <= gate->dimensions[1]) ){
          return 1;
       }
    }
@@ -237,15 +260,13 @@ VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last )
  * Intersect all gates in the world
  */
 VG_STATIC ent_gate *world_intersect_gates( world_instance *world,
-                                           v3f pos, v3f last )
-{
+                                           v3f pos, v3f last ){
    for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, i );
-      if( gate->type == k_gate_type_unlinked ||
-          gate->type == k_gate_type_nonlocal_unlinked )
-         continue;
 
-      if( gate->type == k_gate_type_nonlocel ){
+      if( !(gate->flags & k_ent_gate_linked) ) continue;
+
+      if( gate->flags & k_ent_gate_nonlocal ){
          if( world_loader.state != k_world_loader_none ){
             continue;
          }
@@ -262,13 +283,12 @@ VG_STATIC ent_gate *world_intersect_gates( world_instance *world,
 /* 
  * detatches any nonlocal gates 
  */
-VG_STATIC void world_unlink_nonlocal( world_instance *world )
-{
+VG_STATIC void world_unlink_nonlocal( world_instance *world ){
    for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, j );
 
-      if( gate->type == k_gate_type_nonlocel ){
-         gate->type = k_gate_type_nonlocal_unlinked;
+      if( gate->flags & k_ent_gate_nonlocal ){
+         gate->flags &= ~k_ent_gate_linked;
       }
    }
 }
@@ -284,51 +304,66 @@ VG_STATIC void world_link_nonlocal_async( void *payload, u32 size )
    for( u32 j=0; j<mdl_arrcount(&world->ent_gate); j ++ ){
       ent_gate *gate = mdl_arritm( &world->ent_gate, j );
 
-      if( gate->type == k_gate_type_nonlocal_unlinked ){
-         const char *key = mdl_pstr( &world->meta, gate->key );
-         vg_info( "key: %s\n", key );
+      if( !(gate->flags & k_ent_gate_nonlocal) ) continue;
+      if( gate->flags & k_ent_gate_linked ) continue;
+
+      const char *key = mdl_pstr( &world->meta, gate->key );
+      vg_info( "key: %s\n", key );
+
+      for( u32 i=0; i<vg_list_size(world_static.worlds); i++ ){
+         world_instance *other = &world_static.worlds[i];
+         if( other == world ) continue;
+         if( other->status != k_world_status_loaded ) continue;
+         vg_info( "Checking world %u for key matches\n", i );
+
+         for( u32 j=0; j<mdl_arrcount( &other->ent_gate ); j++ ){
+            ent_gate *gate2 = mdl_arritm( &other->ent_gate, j );
 
-         for( u32 i=0; i<vg_list_size(world_static.worlds); i++ ){
-            world_instance *other = &world_static.worlds[i];
-            if( other == world ) continue;
-            if( other->status != k_world_status_loaded ) continue;
-            vg_info( "Checking world %u for key matches\n", i );
+            if( !(gate2->flags & k_ent_gate_nonlocal) ) continue;
+            if( gate2->flags & k_ent_gate_linked ) continue;
 
-            for( u32 j=0; j<mdl_arrcount( &other->ent_gate ); j++ ){
-               ent_gate *gate2 = mdl_arritm( &other->ent_gate, j );
-               if( gate2->type != k_gate_type_nonlocal_unlinked ) continue;
+            const char *key2 = mdl_pstr( &other->meta, gate2->key );
+            vg_info( " key2: %s\n", key2 );
 
-               const char *key2 = mdl_pstr( &other->meta, gate2->key );
-               vg_info( " key2: %s\n", key2 );
+            if( strcmp( key, key2 ) ) continue;
 
-               if( strcmp( key, key2 ) ) continue;
+            vg_success( "Non-local matching pair '%s' found. (%u:%u)\n",
+                         key, world_id, i );
 
-               vg_success( "Non-local matching pair '%s' found. (%u:%u)\n",
-                            key, world_id, i );
-                  
-               gate->type = k_gate_type_nonlocel;
-               gate2->type = k_gate_type_nonlocel;
-               gate->target = i;
-               gate2->target = world_id;
+            gate->flags |= k_ent_gate_linked;
+            gate2->flags |= k_ent_gate_linked;
+            gate->target = i;
+            gate2->target = world_id;
 
-               v3_copy( gate->co[0], gate2->co[1] );
-               v3_copy( gate2->co[0], gate->co[1] );
-               v4_copy( gate->q[0], gate2->q[1] );
-               v4_copy( gate2->q[0], gate->q[1] );
+            v3_copy( gate->co[0], gate2->co[1] );
+            v3_copy( gate2->co[0], gate->co[1] );
+            v4_copy( gate->q[0], gate2->q[1] );
+            v4_copy( gate2->q[0], gate->q[1] );
 
+            if( other->meta.info.version >= 102 ){
+               gate->flags |= k_ent_gate_flip;
+               gate2->flags |= k_ent_gate_flip;
+            }
+            else {
+               /* LEGACY BEHAVIOUR: v101
+                *   this would flip both the client worlds portal's entrance and
+                *   exit. effectively the clients portal would be the opposite 
+                *   to the hub worlds one. new behaviour is to just flip the 
+                *   destinations so the rules are consistent in each world.
+                */
                v4f qflip;
                q_axis_angle( qflip, (v3f){0.0f,1.0f,0.0f}, VG_PIf );
                q_mul( gate->q[0], qflip, gate->q[0] );
                q_mul( gate->q[1], qflip, gate->q[1] );
+            }
 
-               gate_transform_update( gate );
-               gate_transform_update( gate2 );
+            gate_transform_update( gate );
+            gate_transform_update( gate2 );
 
-               goto matched;
-            }
+            goto matched;
          }
-matched:;
       }
+matched:;
    }
 }
 
index b45c70d86c0f1ce3efb3896d1fa11dd79a3a97cc..4b3299aded23d2e47caf2b18388c361268e7e873 100644 (file)
@@ -20,7 +20,7 @@ VG_STATIC void world_gates_init(void);
 VG_STATIC void gate_transform_update( ent_gate *gate );
 VG_STATIC void world_link_nonlocal_async( void *payload, u32 size );
 VG_STATIC void world_unlink_nonlocal( world_instance *world );
-VG_STATIC int render_gate( world_instance *world_inside,
+VG_STATIC int render_gate( world_instance *world, world_instance *world_inside,
                            ent_gate *gate, camera *cam, int layer_depth );
 
 VG_STATIC int gate_intersect( ent_gate *gate, v3f pos, v3f last );
index c31c2c2dd904955be10e8c7fde126cdfd2b2438e..5f7b9a362e7b3fc294b4e6a5d13cd3ce00847f6c 100644 (file)
@@ -282,6 +282,19 @@ VG_STATIC void world_gen_generate_meshes(void)
       }
    }
 
+   /* unpack gate models */
+   for( u32 i=0; i<mdl_arrcount( &world->ent_gate ); i++ ){
+      ent_gate *gate = mdl_arritm( &world->ent_gate, i );
+
+      if( !(gate->flags & k_ent_gate_custom_mesh) ) continue;
+
+      for( u32 j=0; j<gate->submesh_count; j ++ ){
+         mdl_submesh *sm = mdl_arritm( &world->meta.submeshs, 
+                                       gate->submesh_start+j );
+         world_unpack_submesh_dynamic( world, &world->scene_no_collide, sm );
+      }
+   }
+
    vg_async_dispatch( call, async_scene_upload );
 }
 
index a33d774cbfbfeeeb1f10c0d156e47515ae015d1b..a7ff25ccf3639c1eff192e104e13064c30139937 100644 (file)
@@ -520,7 +520,7 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam,
    for( u32 i=0; i<mdl_arrcount(&world->ent_gate); i++ ){
       ent_gate *gi = mdl_arritm( &world->ent_gate, i );
 
-      if( gi->type == k_gate_type_unlinked )
+      if( !(gi->flags & k_ent_gate_linked) )
          continue;
 
       float dist = v3_dist2( gi->co[0], cam->transform[3] );
@@ -533,25 +533,20 @@ VG_STATIC void render_world_gates( world_instance *world, camera *cam,
       }
    }
    
+   world->rendering_gate = gate;
    if( gate ){
-      /* should really be set in fixed update since its used in the physics
-       * of most systems. too bad! */
-      world->rendering_gate = gate;
-
-      if( gate->type == k_gate_type_teleport ){
-         render_gate( world, gate, cam, layer_depth );
-      }
-      else if( gate->type == k_gate_type_nonlocel ){
+      if( gate->flags & k_ent_gate_nonlocal ){
          if( world_loader.state != k_world_loader_none ){
             world->rendering_gate = NULL;
             return;
          }
 
          world_instance *dest_world = &world_static.worlds[ gate->target ];
-         render_gate( dest_world, gate, cam, layer_depth );
+         render_gate( world, dest_world, gate, cam, layer_depth );
+      }
+      else{
+         render_gate( world, world, gate, cam, layer_depth );
       }
-      else
-         world->rendering_gate = NULL;
    }
 }
 
index d2816d111ba4a4a45ddb4dbb26224911b734ac01..44d055b1686409fa68015036d5993f194ce29028 100644 (file)
@@ -133,7 +133,7 @@ VG_STATIC void world_routes_activate_entry_gate( world_instance *world,
    world_static.last_use = world_static.time;
 
    /* disable all routes and leave the world */
-   if( rg->type == k_gate_type_nonlocel ){
+   if( rg->flags & k_ent_gate_nonlocal ){
       for( u32 i=0; i<mdl_arrcount(&world->ent_route); i++ ){
          ent_route *route = mdl_arritm( &world->ent_route, i );
          route->active_checkpoint = 0xffff;
@@ -912,7 +912,8 @@ VG_STATIC void world_gen_routes_ent_init(void)
             }
          }
 
-         if( gate->type == k_gate_type_teleport ){
+         if( (gate->flags & k_ent_gate_linked) &
+            !(gate->flags & k_ent_gate_nonlocal) ){
             gate = mdl_arritm(&world->ent_gate, gate->target );
 
             for( u32 k=0; k<4; k++ ){