q3bsp is still not working yet, but getting closer
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 Aug 2003 03:48:13 +0000 (03:48 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 Aug 2003 03:48:13 +0000 (03:48 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3395 d7cf8633-e32d-0410-b094-e92efae38249

cl_main.c
gl_rsurf.c
host_cmd.c
model_brush.c
model_shared.h
portals.c
pr_cmds.c
r_light.c
snd_dma.c
sv_main.c
world.c

index 368a78f..f46a90c 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -603,7 +603,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                if (e->render.model)
                {
                        Mod_CheckLoaded(e->render.model);
-                       if (e->render.model->type != mod_brush)
+                       if (e->render.model->type == mod_alias || e->render.model->type == mod_sprite)
                                angles[0] = -angles[0];
                        if (e->render.model->flags & EF_ROTATE)
                        {
@@ -791,7 +791,7 @@ void CL_LinkNetworkEntity(entity_t *e)
                // as soon as player is known we can call V_CalcRefDef
                if ((e - cl_entities) == cl.viewentity)
                        V_CalcRefdef();
-               if (e->render.model && e->render.model->name[0] == '*' && e->render.model->type == mod_brush)
+               if (e->render.model && e->render.model->name[0] == '*' && e->render.model->brush.TraceBox)
                        cl_brushmodel_entities[cl_num_brushmodel_entities++] = &e->render;
                // don't show entities with no modelindex (note: this still shows
                // entities which have a modelindex that resolved to a NULL model)
index 4582d8c..892193e 100644 (file)
@@ -532,7 +532,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
        entity_render_t *ent;
        model_t *model;
        vec3_t org;
-       if (cl.worldmodel == NULL)
+       if (cl.worldmodel == NULL || !cl.worldmodel->brushq1.nodes)
                return;
        fcolor[0] = cr1;
        fcolor[1] = cg1;
@@ -553,7 +553,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
                if (model && model->name[0] == '*')
                {
                        Mod_CheckLoaded(model);
-                       if (model->type == mod_brush)
+                       if (model->brushq1.nodes)
                        {
                                Matrix4x4_Transform(&ent->inversematrix, origin, org);
                                R_StainNode(model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode, model, org, radius, fcolor);
@@ -1748,13 +1748,13 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
        }
 }
 
-void R_WorldVisibility (entity_render_t *ent)
+void R_WorldVisibility(entity_render_t *ent)
 {
        vec3_t modelorg;
        mleaf_t *viewleaf;
 
        Matrix4x4_Transform(&ent->inversematrix, r_origin, modelorg);
-       viewleaf = ent->model ? ent->model->brushq1.PointInLeaf(ent->model, modelorg) : NULL;
+       viewleaf = (ent->model && ent->model->brushq1.PointInLeaf) ? ent->model->brushq1.PointInLeaf(ent->model, modelorg) : NULL;
        R_PVSUpdate(ent, viewleaf);
 
        if (!viewleaf)
@@ -1766,18 +1766,23 @@ void R_WorldVisibility (entity_render_t *ent)
                R_PortalWorldNode (ent, viewleaf);
 }
 
-void R_DrawWorld (entity_render_t *ent)
+void R_DrawWorld(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
-       R_PrepareSurfaces(ent);
-       R_DrawSurfaces(ent, SHADERSTAGE_SKY, ent->model->brushq1.pvstexturechains);
-       R_DrawSurfaces(ent, SHADERSTAGE_NORMAL, ent->model->brushq1.pvstexturechains);
-       if (r_drawportals.integer)
-               R_DrawPortals(ent);
+       if (!ent->model->brushq1.numleafs && ent->model->Draw)
+               ent->model->Draw(ent);
+       else
+       {
+               R_PrepareSurfaces(ent);
+               R_DrawSurfaces(ent, SHADERSTAGE_SKY, ent->model->brushq1.pvstexturechains);
+               R_DrawSurfaces(ent, SHADERSTAGE_NORMAL, ent->model->brushq1.pvstexturechains);
+               if (r_drawportals.integer)
+                       R_DrawPortals(ent);
+       }
 }
 
-void R_Model_Brush_DrawSky (entity_render_t *ent)
+void R_Model_Brush_DrawSky(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
@@ -1786,7 +1791,7 @@ void R_Model_Brush_DrawSky (entity_render_t *ent)
        R_DrawSurfaces(ent, SHADERSTAGE_SKY, ent->model->brushq1.pvstexturechains);
 }
 
-void R_Model_Brush_Draw (entity_render_t *ent)
+void R_Model_Brush_Draw(entity_render_t *ent)
 {
        if (ent->model == NULL)
                return;
@@ -1897,6 +1902,53 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
        }
 }
 
+void R_Q3BSP_DrawFace_Mesh(entity_render_t *ent, q3mface_t *face)
+{
+       const surfmesh_t *mesh;
+       rmeshstate_t m;
+       memset(&m, 0, sizeof(m));
+       GL_BlendFunc(GL_ONE, GL_ZERO);
+       GL_DepthMask(true);
+       GL_DepthTest(true);
+       m.tex[0] = R_GetTexture(face->texture->skin.base);
+       m.pointer_texcoord[0] = face->data_texcoordtexture2f;
+       if (face->lightmaptexture)
+       {
+               m.tex[1] = R_GetTexture(face->lightmaptexture);
+               m.pointer_texcoord[1] = face->data_texcoordlightmap2f;
+               m.texrgbscale[1] = 2;
+               GL_Color(r_colorscale, r_colorscale, r_colorscale, 1);
+       }
+       else
+       {
+               m.texrgbscale[0] = 2;
+               GL_ColorPointer(face->data_color4f);
+       }
+       R_Mesh_State_Texture(&m);
+       GL_VertexPointer(face->data_vertex3f);
+       R_Mesh_Draw(mesh->numverts, mesh->numtriangles, mesh->element3i);
+}
+
+void R_Q3BSP_DrawFace_Patch(entity_render_t *ent, q3mface_t *face)
+{
+}
+
+void R_Q3BSP_DrawFace(entity_render_t *ent, q3mface_t *face)
+{
+       switch(face->type)
+       {
+               case Q3FACETYPE_POLYGON:
+               case Q3FACETYPE_MESH:
+                       R_Q3BSP_DrawFace_Mesh(ent, face);
+                       break;
+               case Q3FACETYPE_PATCH:
+                       R_Q3BSP_DrawFace_Patch(ent, face);
+                       break;
+               case Q3FACETYPE_FLARE:
+                       break;
+       }
+}
+
 /*
 void R_Q3BSP_DrawSky(entity_render_t *ent)
 {
@@ -1905,6 +1957,12 @@ void R_Q3BSP_DrawSky(entity_render_t *ent)
 
 void R_Q3BSP_Draw(entity_render_t *ent)
 {
+       int i;
+       q3mface_t *face;
+       model_t *model;
+       model = ent->model;
+       for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+               R_Q3BSP_DrawFace(ent, face);
 }
 
 /*
index 43633d8..fb4486f 100644 (file)
@@ -24,6 +24,9 @@ int current_skill;
 char sv_spawnmap[MAX_QPATH];
 char sv_loadgame[MAX_OSPATH];
 
+cvar_t sv_cheats = {0, "sv_cheats", "0"};
+qboolean allowcheats = false;
+
 mfunction_t *ED_FindFunction (char *name);
 
 /*
@@ -109,8 +112,14 @@ void Host_God_f (void)
                return;
        }
 
-       if (pr_global_struct->deathmatch || !sv_player)
+       if (!sv_player)
+               return;
+
+       if (!allowcheats)
+       {
+               SV_ClientPrintf("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
                return;
+       }
 
        sv_player->v->flags = (int)sv_player->v->flags ^ FL_GODMODE;
        if (!((int)sv_player->v->flags & FL_GODMODE) )
@@ -127,9 +136,15 @@ void Host_Notarget_f (void)
                return;
        }
 
-       if (pr_global_struct->deathmatch || !sv_player)
+       if (!sv_player)
                return;
 
+       if (!allowcheats)
+       {
+               SV_ClientPrintf("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
+               return;
+       }
+
        sv_player->v->flags = (int)sv_player->v->flags ^ FL_NOTARGET;
        if (!((int)sv_player->v->flags & FL_NOTARGET) )
                SV_ClientPrintf ("notarget OFF\n");
@@ -147,9 +162,15 @@ void Host_Noclip_f (void)
                return;
        }
 
-       if (pr_global_struct->deathmatch || !sv_player)
+       if (!sv_player)
                return;
 
+       if (!allowcheats)
+       {
+               SV_ClientPrintf("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
+               return;
+       }
+
        if (sv_player->v->movetype != MOVETYPE_NOCLIP)
        {
                noclip_anglehack = true;
@@ -179,9 +200,15 @@ void Host_Fly_f (void)
                return;
        }
 
-       if (pr_global_struct->deathmatch || !sv_player)
+       if (!sv_player)
                return;
 
+       if (!allowcheats)
+       {
+               SV_ClientPrintf("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
+               return;
+       }
+
        if (sv_player->v->movetype != MOVETYPE_FLY)
        {
                sv_player->v->movetype = MOVETYPE_FLY;
@@ -537,6 +564,7 @@ void Host_PerformLoadGame(char *name)
        str = FS_Getline (f);
        sscanf (str, "%f\n",&time);
 
+       allowcheats = sv_cheats.integer != 0;
        SV_SpawnServer (mapname);
        if (!sv.active)
        {
@@ -1172,15 +1200,7 @@ void Host_Kick_f (void)
        int i;
        qboolean byNumber = false;
 
-       if (cmd_source == src_command)
-       {
-               if (!sv.active)
-               {
-                       Cmd_ForwardToServer ();
-                       return;
-               }
-       }
-       else if (pr_global_struct->deathmatch)
+       if (cmd_source != src_command || !sv.active)
                return;
 
        save = host_client;
@@ -1268,9 +1288,15 @@ void Host_Give_f (void)
                return;
        }
 
-       if (pr_global_struct->deathmatch || !sv_player)
+       if (!sv_player)
                return;
 
+       if (!allowcheats)
+       {
+               SV_ClientPrintf("No cheats allowed, use sv_cheats 1 and restart level to enable.\n");
+               return;
+       }
+
        t = Cmd_Argv(1);
        v = atoi (Cmd_Argv(2));
 
@@ -1617,7 +1643,10 @@ void Host_PerformSpawnServerAndLoadGame(void)
        if (sv_loadgame[0])
                Host_PerformLoadGame(sv_loadgame);
        else if (sv_spawnmap[0])
+       {
+               allowcheats = sv_cheats.integer != 0;
                SV_SpawnServer(sv_spawnmap);
+       }
        sv_loadgame[0] = 0;
        sv_spawnmap[0] = 0;
        if (sv.active && cls.state == ca_disconnected)
@@ -1688,5 +1717,7 @@ void Host_InitCommands (void)
        Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
        Cmd_AddCommand ("spawn", Host_Spawn_f);
        Cmd_AddCommand ("begin", Host_Begin_f);
+
+       Cvar_RegisterVariable(&sv_cheats);
 }
 
index a1bcd56..5530052 100644 (file)
@@ -3619,6 +3619,7 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
        q3mbrush_t *out;
        int i, j, k, m, n, c, count, numpoints, numplanes;
        winding_t *w;
+       mplane_t plane;
        colpointf_t pointsbuf[256*3];
        colplanef_t planesbuf[256], colplanef;
 
@@ -3651,12 +3652,23 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
                numplanes = 0;
                for (j = 0;j < out->numbrushsides;j++)
                {
+                       // for some reason the planes are all flipped compared to what I
+                       // would expect, so this has to negate them...
+
                        // create a huge polygon for the plane
-                       w = BaseWindingForPlane(out->firstbrushside[j].plane);
+                       VectorNegate(out->firstbrushside[j].plane->normal, plane.normal);
+                       plane.dist = -out->firstbrushside[j].plane->dist;
+                       w = BaseWindingForPlane(&plane);
                        // clip it by all other planes
                        for (k = 0;k < out->numbrushsides && w;k++)
+                       {
                                if (k != j)
-                                       w = ClipWinding(w, out->firstbrushside[k].plane, true);
+                               {
+                                       VectorNegate(out->firstbrushside[k].plane->normal, plane.normal);
+                                       plane.dist = -out->firstbrushside[k].plane->dist;
+                                       w = ClipWinding(w, &plane, true);
+                               }
+                       }
                        // if nothing is left, skip it
                        // FIXME: should keep count of how many were skipped and report
                        // it, just for sake of statistics
@@ -3666,7 +3678,7 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
                        for (k = 0;k < w->numpoints;k++)
                        {
                                for (m = 0;m < numpoints;m++)
-                                       if (VectorDistance2(w->points[k * 3], pointsbuf[m * 3].v) < DIST_EPSILON)
+                                       if (VectorDistance2(w->points[k], pointsbuf[m].v) < DIST_EPSILON)
                                                break;
                                if (m == numpoints)
                                {
@@ -3678,7 +3690,7 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
                                                goto failedtomakecolbrush;
                                        }
                                        // add the new one
-                                       VectorCopy(w->points[k * 3], pointsbuf[numpoints * 3].v);
+                                       VectorCopy(w->points[k], pointsbuf[numpoints].v);
                                        numpoints++;
                                }
                        }
@@ -3707,8 +3719,8 @@ static void Mod_Q3BSP_LoadBrushes(lump_t *l)
                if (numplanes && numpoints)
                {
                        out->colbrushf = Collision_AllocBrushFloat(loadmodel->mempool, numpoints, numplanes);
-                       memcpy(out->colbrushf->points, pointsbuf, numpoints * sizeof(float[3]));
-                       memcpy(out->colbrushf->planes, planesbuf, numplanes * sizeof(mplane_t));
+                       memcpy(out->colbrushf->points, pointsbuf, numpoints * sizeof(colpointf_t));
+                       memcpy(out->colbrushf->planes, planesbuf, numplanes * sizeof(colplanef_t));
                }
                // return from errors to here
                failedtomakecolbrush:;
@@ -3751,8 +3763,8 @@ static void Mod_Q3BSP_LoadVertices(lump_t *l)
                Host_Error("Mod_Q3BSP_LoadVertices: funny lump size in %s",loadmodel->name);
        loadmodel->brushq3.num_vertices = count = l->filelen / sizeof(*in);
        loadmodel->brushq3.data_vertex3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
-       loadmodel->brushq3.data_texturetexcoord2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
-       loadmodel->brushq3.data_lightmaptexcoord2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
+       loadmodel->brushq3.data_texcoordtexture2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
+       loadmodel->brushq3.data_texcoordlightmap2f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[2]));
        loadmodel->brushq3.data_svector3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
        loadmodel->brushq3.data_tvector3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
        loadmodel->brushq3.data_normal3f = Mem_Alloc(loadmodel->mempool, count * sizeof(float[3]));
@@ -3763,10 +3775,10 @@ static void Mod_Q3BSP_LoadVertices(lump_t *l)
                loadmodel->brushq3.data_vertex3f[i * 3 + 0] = LittleFloat(in->origin3f[0]);
                loadmodel->brushq3.data_vertex3f[i * 3 + 1] = LittleFloat(in->origin3f[1]);
                loadmodel->brushq3.data_vertex3f[i * 3 + 2] = LittleFloat(in->origin3f[2]);
-               loadmodel->brushq3.data_texturetexcoord2f[i * 2 + 0] = LittleFloat(in->texcoord2f[0]);
-               loadmodel->brushq3.data_texturetexcoord2f[i * 2 + 1] = LittleFloat(in->texcoord2f[1]);
-               loadmodel->brushq3.data_lightmaptexcoord2f[i * 2 + 0] = LittleFloat(in->lightmap2f[0]);
-               loadmodel->brushq3.data_lightmaptexcoord2f[i * 2 + 1] = LittleFloat(in->lightmap2f[1]);
+               loadmodel->brushq3.data_texcoordtexture2f[i * 2 + 0] = LittleFloat(in->texcoord2f[0]);
+               loadmodel->brushq3.data_texcoordtexture2f[i * 2 + 1] = LittleFloat(in->texcoord2f[1]);
+               loadmodel->brushq3.data_texcoordlightmap2f[i * 2 + 0] = LittleFloat(in->lightmap2f[0]);
+               loadmodel->brushq3.data_texcoordlightmap2f[i * 2 + 1] = LittleFloat(in->lightmap2f[1]);
                // svector/tvector are calculated later in face loading
                loadmodel->brushq3.data_svector3f[i * 3 + 0] = 0;
                loadmodel->brushq3.data_svector3f[i * 3 + 1] = 0;
@@ -3914,8 +3926,8 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                case Q3FACETYPE_POLYGON:
                case Q3FACETYPE_MESH:
                        out->data_vertex3f = loadmodel->brushq3.data_vertex3f + out->firstvertex * 3;
-                       out->data_texturetexcoord2f = loadmodel->brushq3.data_texturetexcoord2f + out->firstvertex * 2;
-                       out->data_lightmaptexcoord2f = loadmodel->brushq3.data_lightmaptexcoord2f + out->firstvertex * 2;
+                       out->data_texcoordtexture2f = loadmodel->brushq3.data_texcoordtexture2f + out->firstvertex * 2;
+                       out->data_texcoordlightmap2f = loadmodel->brushq3.data_texcoordlightmap2f + out->firstvertex * 2;
                        out->data_svector3f = loadmodel->brushq3.data_svector3f + out->firstvertex * 3;
                        out->data_tvector3f = loadmodel->brushq3.data_tvector3f + out->firstvertex * 3;
                        out->data_normal3f = loadmodel->brushq3.data_normal3f + out->firstvertex * 3;
@@ -4253,7 +4265,8 @@ void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *node, cons
                q3mleaf_t *leaf;
                leaf = (q3mleaf_t *)node;
                for (i = 0;i < leaf->numleafbrushes;i++)
-                       Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, leaf->firstleafbrush[i]->colbrushf, leaf->firstleafbrush[i]->colbrushf);
+                       if (leaf->firstleafbrush[i]->colbrushf)
+                               Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, leaf->firstleafbrush[i]->colbrushf, leaf->firstleafbrush[i]->colbrushf);
        }
 }
 
@@ -4281,7 +4294,8 @@ void Mod_Q3BSP_TraceBox(model_t *model, trace_t *trace, const vec3_t boxstartmin
                Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace, model->brushq3.data_nodes, thisbrush_start, thisbrush_end);
        else
                for (i = 0;i < model->brushq3.num_brushes;i++)
-                       Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, model->brushq3.data_brushes[i].colbrushf, model->brushq3.data_brushes[i].colbrushf);
+                       if (model->brushq3.data_brushes[i].colbrushf)
+                               Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, model->brushq3.data_brushes[i].colbrushf, model->brushq3.data_brushes[i].colbrushf);
 }
 
 
@@ -4337,7 +4351,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer)
        int i;
        q3dheader_t *header;
 
-       mod->type = mod_brushq2;
+       mod->type = mod_brushq3;
 
        header = (q3dheader_t *)buffer;
 
@@ -4385,6 +4399,30 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer)
        Mod_Q3BSP_LoadNodes(&header->lumps[Q3LUMP_NODES]);
        Mod_Q3BSP_LoadLightGrid(&header->lumps[Q3LUMP_LIGHTGRID]);
        Mod_Q3BSP_LoadPVS(&header->lumps[Q3LUMP_PVS]);
+       loadmodel->brush.numsubmodels = loadmodel->brushq3.num_models;
+
+       for (i = 0;i < loadmodel->brushq3.num_models;i++)
+       {
+               if (i == 0)
+                       mod = loadmodel;
+               else
+               {
+                       char name[10];
+                       // LordHavoc: only register submodels if it is the world
+                       // (prevents bsp models from replacing world submodels)
+                       if (!loadmodel->isworldmodel)
+                               continue;
+                       // duplicate the basic information
+                       sprintf(name, "*%i", i);
+                       mod = Mod_FindName(name);
+                       *mod = *loadmodel;
+                       strcpy(mod->name, name);
+                       // textures and memory belong to the main model
+                       mod->texturepool = NULL;
+                       mod->mempool = NULL;
+               }
+               mod->brushq3.data_thismodel = loadmodel->brushq3.data_models + i;
+       }
 }
 
 void Mod_IBSP_Load(model_t *mod, void *buffer)
index 3dbbb0c..0507588 100644 (file)
@@ -348,8 +348,8 @@ typedef struct q3mface_s
        int patchsize[2];
 
        float *data_vertex3f;
-       float *data_texturetexcoord2f;
-       float *data_lightmaptexcoord2f;
+       float *data_texcoordtexture2f;
+       float *data_texcoordlightmap2f;
        float *data_svector3f;
        float *data_tvector3f;
        float *data_normal3f;
@@ -383,7 +383,7 @@ typedef struct model_brushq3_s
        int num_models;
        q3mmodel_t *data_models;
        // each submodel gets its own model struct so this is different for each.
-       q3mmodel_t data_thismodel;
+       q3mmodel_t *data_thismodel;
 
        int num_brushes;
        q3mbrush_t *data_brushes;
@@ -393,8 +393,8 @@ typedef struct model_brushq3_s
 
        int num_vertices;
        float *data_vertex3f;
-       float *data_texturetexcoord2f;
-       float *data_lightmaptexcoord2f;
+       float *data_texcoordtexture2f;
+       float *data_texcoordlightmap2f;
        float *data_svector3f;
        float *data_tvector3f;
        float *data_normal3f;
index dff58ae..df4cd32 100644 (file)
--- a/portals.c
+++ b/portals.c
@@ -469,12 +469,18 @@ void Portal_Visibility(model_t *model, const vec3_t eye, qbyte *leafmark, qbyte
 
        // if there is no model, it can not block visibility
        if (model == NULL)
-               Host_Error("Portal_Visibility: NULL model\n");
+       {
+               Con_Printf("Portal_Visibility: NULL model\n");
+               return;
+       }
 
        Mod_CheckLoaded(model);
 
-       if (model->type != mod_brush)
-               Host_Error("Portal_Visibility: not a brush model\n");
+       if (!model->brushq1.numportals)
+       {
+               Con_Printf("Portal_Visibility: not a brush model\n");
+               return;
+       }
 
        // put frustum planes (if any) into tinyplane format at start of buffer
        for (i = 0;i < numfrustumplanes;i++)
index 0f801f8..faf7b17 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -2542,8 +2542,6 @@ static msurface_t *getsurface(edict_t *ed, int surfnum)
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return NULL;
        model = sv.models[modelindex];
-       if (model->type != mod_brush)
-               return NULL;
        if (surfnum < 0 || surfnum >= model->brushq1.nummodelsurfaces)
                return NULL;
        return model->brushq1.surfaces + surfnum + model->brushq1.firstmodelsurface;
@@ -2623,7 +2621,7 @@ void PF_getsurfacenearpoint(void)
        if (modelindex < 1 || modelindex >= MAX_MODELS)
                return;
        model = sv.models[modelindex];
-       if (model->type != mod_brush)
+       if (!model->brushq1.numsurfaces)
                return;
 
        // FIXME: implement rotation/scaling
index 5cc2697..04f9a75 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -265,7 +265,7 @@ void R_MarkLights(entity_render_t *ent)
        int i, bit, bitindex;
        rdlight_t *rd;
        vec3_t lightorigin;
-       if (!gl_flashblend.integer && r_dynamic.integer && ent->model)
+       if (!gl_flashblend.integer && r_dynamic.integer && ent->model && ent->model->brushq1.numleafs)
        {
                for (i = 0, rd = r_dlight;i < r_numdlights;i++, rd++)
                {
index 89cf157..6be221a 100644 (file)
--- a/snd_dma.c
+++ b/snd_dma.c
@@ -408,7 +408,7 @@ void SND_Spatialize(channel_t *ch, int isstatic)
                {
                        //Con_Printf("-- entnum %i origin %f %f %f neworigin %f %f %f\n", ch->entnum, ch->origin[0], ch->origin[1], ch->origin[2], cl_entities[ch->entnum].state_current.origin[0], cl_entities[ch->entnum].state_current.origin[1], cl_entities[ch->entnum].state_current.origin[2]);
                        VectorCopy(cl_entities[ch->entnum].state_current.origin, ch->origin);
-                       if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->type == mod_brush)
+                       if (cl_entities[ch->entnum].state_current.modelindex && cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->brush.TraceBox)
                                VectorMAMAM(1.0f, ch->origin, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmins, 0.5f, cl.model_precache[cl_entities[ch->entnum].state_current.modelindex]->normalmaxs, ch->origin);
                }
 
index e9f1c33..8c17d6f 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -506,7 +506,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                        }
 
                        // don't try to cull embedded brush models with this, they're sometimes huge (spanning several rooms)
-                       if (sv_cullentities_trace.integer && (model == NULL || model->type != mod_brush || model->name[0] != '*'))
+                       if (sv_cullentities_trace.integer && (model == NULL || model->brush.TraceBox == NULL || model->name[0] != '*'))
                        {
                                // LordHavoc: test random offsets, to maximize chance of detection
                                testorigin[0] = lhrandom(entmins[0], entmaxs[0]);
diff --git a/world.c b/world.c
index 373ac3e..530fb2a 100644 (file)
--- a/world.c
+++ b/world.c
@@ -345,7 +345,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                if (model != NULL)
                {
                        Mod_CheckLoaded(model);
-                       if (model->type != mod_brush)
+                       if (!model->brush.TraceBox)
                                Host_Error("SOLID_BSP with non-BSP model\n");
 
                        if (ent->v->angles[0] || ent->v->angles[2] || ent->v->avelocity[0] || ent->v->avelocity[2])
@@ -470,7 +470,7 @@ trace_t SV_ClipMoveToEntity(edict_t *ent, const vec3_t start, const vec3_t mins,
                        Host_Error("SV_ClipMoveToEntity: invalid modelindex\n");
 
                Mod_CheckLoaded(model);
-               if (model->type != mod_brush)
+               if (!model->brush.TraceBox)
                {
                        Con_Printf ("SV_ClipMoveToEntity: SOLID_BSP with a non bsp model, entity dump:\n");
                        ED_Print (ent);