]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - pr_cmds.c
fixed crash when ent->skinnum >= model->numskins
[xonotic/darkplaces.git] / pr_cmds.c
index c002f3cfe5eb2571c27f8a5b149ae337ea299e38..14cc29349246755887b6ce0ca27c0b1589198cb1 100644 (file)
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -37,58 +37,62 @@ cvar_t      sv_aim = {CVAR_SAVE, "sv_aim", "2"}; //"0.93"}; // LordHavoc: disabled au
 char *PF_VarString (int        first)
 {
        int             i;
-       static char out[256];
+       static char out[4096]; // FIXME: buffer overflow potential
 
        out[0] = 0;
-       for (i=first ; i<pr_argc ; i++)
-       {
+       for (i = first;i < pr_argc;i++)
                strcat (out, G_STRING((OFS_PARM0+i*3)));
-       }
        return out;
 }
 
-char *ENGINE_EXTENSIONS = "\
-DP_ENT_ALPHA \
-DP_ENT_COLORMOD \
-DP_ENT_DELTACOMPRESS \
-DP_ENT_GLOW \
-DP_ENT_SCALE \
-DP_ENT_VIEWMODEL \
-DP_GFX_FOG \
-DP_HALFLIFE_MAP \
-DP_INPUTBUTTONS \
-DP_MONSTERWALK \
-DP_MOVETYPEFOLLOW \
-DP_SOLIDCORPSE \
-DP_REGISTERCVAR \
-DP_SPRITE32 \
-DP_SV_DRAWONLYTOCLIENT \
-DP_SV_NODRAWTOCLIENT \
-DP_SV_EXTERIORMODELTOCLIENT \
-DP_SV_SETCOLOR \
-DP_SV_EFFECT \
-DP_TE_BLOOD \
-DP_TE_BLOODSHOWER \
-DP_TE_EXPLOSIONRGB \
-DP_TE_PARTICLECUBE \
-DP_TE_PARTICLERAIN \
-DP_TE_PARTICLESNOW \
-DP_TE_SPARK \
-DP_QC_CHANGEPITCH \
-DP_QC_COPYENTITY \
-DP_QC_ETOS \
-DP_QC_FINDFLOAT \
-DP_QC_FINDCHAIN \
-DP_QC_FINDCHAINFLOAT \
-DP_QC_GETLIGHT \
-DP_QC_SINCOSSQRTPOW \
-DP_QC_MINMAXBOUND \
-DP_QC_RANDOMVEC \
-DP_QC_TRACEBOX \
-DP_QC_TRACETOSS \
-DP_QUAKE2_MODEL \
-NEH_CMD_PLAY2 \
-";
+char *ENGINE_EXTENSIONS =
+"DP_ENT_ALPHA "
+"DP_ENT_CUSTOMCOLORMAP "
+"DP_ENT_EXTERIORMODELTOCLIENT "
+"DP_ENT_LOWPRECISION "
+"DP_ENT_GLOW "
+"DP_ENT_SCALE "
+"DP_ENT_VIEWMODEL "
+"DP_GFX_FOG "
+"DP_HALFLIFE_MAP "
+"DP_INPUTBUTTONS "
+"DP_MONSTERWALK "
+"DP_MOVETYPEFOLLOW "
+"DP_QC_CHANGEPITCH "
+"DP_QC_COPYENTITY "
+"DP_QC_ETOS "
+"DP_QC_FINDCHAIN "
+"DP_QC_FINDCHAINFLOAT "
+"DP_QC_FINDFLOAT "
+"DP_QC_GETLIGHT "
+"DP_QC_MINMAXBOUND "
+"DP_QC_RANDOMVEC "
+"DP_QC_SINCOSSQRTPOW "
+"DP_QC_TRACEBOX "
+"DP_QC_TRACETOSS "
+"DP_QC_VECTORVECTORS "
+"DP_QUAKE2_MODEL "
+"DP_REGISTERCVAR "
+"DP_SOLIDCORPSE "
+"DP_SPRITE32 "
+"DP_SV_DRAWONLYTOCLIENT "
+"DP_SV_EFFECT "
+"DP_SV_EXTERIORMODELTOCLIENT "
+"DP_SV_NODRAWTOCLIENT "
+"DP_SV_PLAYERPHYSICS "
+"DP_SV_SETCOLOR "
+"DP_SV_SLOWMO "
+"DP_TE_BLOOD "
+"DP_TE_BLOODSHOWER "
+"DP_TE_EXPLOSIONRGB "
+"DP_TE_PARTICLECUBE "
+"DP_TE_PARTICLERAIN "
+"DP_TE_PARTICLESNOW "
+"DP_TE_SPARK "
+"NEH_CMD_PLAY2 "
+"NEH_RESTOREGAME "
+"TW_SV_STEPCONTROL "
+;
 
 qboolean checkextension(char *name)
 {
@@ -168,13 +172,9 @@ void PF_objerror (void)
        ed = PROG_TO_EDICT(pr_global_struct->self);
        ED_Print (ed);
        ED_Free (ed);
-
-// LordHavoc: bug fix - no longer kills server
-//     Host_Error ("Program error");
 }
 
 
-
 /*
 ==============
 PF_makevectors
@@ -225,80 +225,12 @@ void PF_setorigin (void)
 
 void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate)
 {
-       /*
-       float   *angles;
-       vec3_t  rmin, rmax;
-       float   bounds[2][3];
-       float   xvector[2], yvector[2];
-       float   a;
-       vec3_t  base, transformed;
-       int             i, j, k, l;
-       */
        int             i;
        
        for (i=0 ; i<3 ; i++)
                if (min[i] > max[i])
                        PR_RunError ("backwards mins/maxs");
 
-       /*
-       rotate = false;         // FIXME: implement rotation properly again
-
-       if (!rotate)
-       {
-               VectorCopy (min, rmin);
-               VectorCopy (max, rmax);
-       }
-       else
-       {
-       // find min / max for rotations
-               angles = e->v.angles;
-               
-               a = angles[1]/180 * M_PI;
-
-               xvector[0] = cos(a);
-               xvector[1] = sin(a);
-               yvector[0] = -sin(a);
-               yvector[1] = cos(a);
-               
-               VectorCopy (min, bounds[0]);
-               VectorCopy (max, bounds[1]);
-
-               rmin[0] = rmin[1] = rmin[2] = 9999;
-               rmax[0] = rmax[1] = rmax[2] = -9999;
-               
-               for (i=0 ; i<= 1 ; i++)
-               {
-                       base[0] = bounds[i][0];
-                       for (j=0 ; j<= 1 ; j++)
-                       {
-                               base[1] = bounds[j][1];
-                               for (k=0 ; k<= 1 ; k++)
-                               {
-                                       base[2] = bounds[k][2];
-                                       
-                               // transform the point
-                                       transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
-                                       transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
-                                       transformed[2] = base[2];
-                                       
-                                       for (l=0 ; l<3 ; l++)
-                                       {
-                                               if (transformed[l] < rmin[l])
-                                                       rmin[l] = transformed[l];
-                                               if (transformed[l] > rmax[l])
-                                                       rmax[l] = transformed[l];
-                                       }
-                               }
-                       }
-               }
-       }
-       
-// set derived values
-       VectorCopy (rmin, e->v.mins);
-       VectorCopy (rmax, e->v.maxs);
-       VectorSubtract (max, min, e->v.size);
-       */
-       
 // set derived values
        VectorCopy (min, e->v.mins);
        VectorCopy (max, e->v.maxs);
@@ -356,24 +288,11 @@ void PF_setmodel (void)
 
 
        e->v.model = m - pr_strings;
-       e->v.modelindex = i; //SV_ModelIndex (m);
+       e->v.modelindex = i;
 
-       mod = sv.models[ (int)e->v.modelindex];  // Mod_ForName (m, true);
+       mod = sv.models[ (int)e->v.modelindex];
 
        if (mod)
-       /*
-       { // LordHavoc: corrected model bounding box, but for compatibility that means I have to break it here
-               vec3_t min, max;
-               if (mod->type == ALIASTYPE_MDL)
-               {
-                       min[0] = min[1] = min[2] = -16;
-                       max[0] = max[1] = max[2] = 16;
-                       SetMinMaxSize (e, min, max, true);
-               }
-               else
-                       SetMinMaxSize (e, mod->mins, mod->maxs, true);
-       }
-       */
                SetMinMaxSize (e, mod->normalmins, mod->normalmaxs, true);
        else
                SetMinMaxSize (e, vec3_origin, vec3_origin, true);
@@ -727,8 +646,6 @@ break()
 */
 void PF_break (void)
 {
-//     Con_Printf ("break statement\n");
-//     *(int *)-4 = 0; // dump to debugger
        PR_RunError ("break statement");
 }
 
@@ -858,12 +775,12 @@ void PF_checkpos (void)
 
 //============================================================================
 
-byte   checkpvs[MAX_MAP_LEAFS/8];
+qbyte checkpvs[MAX_MAP_LEAFS/8];
 
 int PF_newcheckclient (int check)
 {
        int             i;
-       byte    *pvs;
+       qbyte   *pvs;
        edict_t *ent;
        mleaf_t *leaf;
        vec3_t  org;
@@ -1055,16 +972,18 @@ findradius (origin, radius)
 */
 void PF_findradius (void)
 {
-       edict_t *ent, *chain;
-       float   rad;
-       float   *org;
-       vec3_t  eorg;
-       int             i, j;
+       edict_t *ent, *chain;
+       float radius;
+       float radius2;
+       float *org;
+       float eorg[3];
+       int i;
 
        chain = (edict_t *)sv.edicts;
        
        org = G_VECTOR(OFS_PARM0);
-       rad = G_FLOAT(OFS_PARM1);
+       radius = G_FLOAT(OFS_PARM1);
+       radius2 = radius * radius;
 
        ent = NEXT_EDICT(sv.edicts);
        for (i=1 ; i<sv.num_edicts ; i++, ent = NEXT_EDICT(ent))
@@ -1073,9 +992,13 @@ void PF_findradius (void)
                        continue;
                if (ent->v.solid == SOLID_NOT)
                        continue;
-               for (j=0 ; j<3 ; j++)
-                       eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5);                  
-               if (Length(eorg) > rad)
+
+               // LordHavoc: compare against bounding box rather than center,
+               // and use DotProduct instead of Length, major speedup
+               eorg[0] = (org[0] - ent->v.origin[0]) - bound(ent->v.mins[0], (org[0] - ent->v.origin[0]), ent->v.maxs[0]);
+               eorg[1] = (org[1] - ent->v.origin[1]) - bound(ent->v.mins[1], (org[1] - ent->v.origin[1]), ent->v.maxs[1]);
+               eorg[2] = (org[2] - ent->v.origin[2]) - bound(ent->v.mins[2], (org[2] - ent->v.origin[2]), ent->v.maxs[2]);
+               if (DotProduct(eorg, eorg) > radius2)
                        continue;
                        
                ent->v.chain = EDICT_TO_PROG(chain);
@@ -1117,12 +1040,6 @@ void PF_ftos (void)
        v = G_FLOAT(OFS_PARM0);
 
        s = PR_GetTempString();
-       /*
-       if (v == (int)v)
-               sprintf (s, "%d",(int)v);
-       else
-               sprintf (s, "%5.1f",v);
-       */
        // LordHavoc: ftos improvement
        sprintf (s, "%g", v);
        G_INT(OFS_RETURN) = s - pr_strings;
@@ -1314,7 +1231,7 @@ void PF_precache_sound (void)
 {
        char    *s;
        int             i;
-       
+
        if (sv.state != ss_loading)
                PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions");
 
@@ -1439,12 +1356,12 @@ void PF_droptofloor (void)
        edict_t         *ent;
        vec3_t          end;
        trace_t         trace;
-       
+
        ent = PROG_TO_EDICT(pr_global_struct->self);
 
        VectorCopy (ent->v.origin, end);
        end[2] -= 256;
-       
+
        trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
 
        if (trace.fraction == 1 || trace.allsolid)
@@ -1456,6 +1373,8 @@ void PF_droptofloor (void)
                ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
                ent->v.groundentity = EDICT_TO_PROG(trace.ent);
                G_FLOAT(OFS_RETURN) = 1;
+               // if support is destroyed, keep suspended (gross hack for floating items in various maps)
+               ent->suspendedinairflag = true;
        }
 }
 
@@ -1472,17 +1391,17 @@ void PF_lightstyle (void)
        char    *val;
        client_t        *client;
        int                     j;
-       
+
        style = G_FLOAT(OFS_PARM0);
        val = G_STRING(OFS_PARM1);
 
 // change the string in sv
        sv.lightstyles[style] = val;
-       
+
 // send message to all clients on this server
        if (sv.state != ss_active)
                return;
-       
+
        for (j=0, client = svs.clients ; j<svs.maxclients ; j++, client++)
                if (client->active || client->spawned)
                {
@@ -1528,7 +1447,7 @@ PF_pointcontents
 */
 void PF_pointcontents (void)
 {
-       G_FLOAT(OFS_RETURN) = SV_PointContents (G_VECTOR(OFS_PARM0));
+       G_FLOAT(OFS_RETURN) = Mod_PointInLeaf(G_VECTOR(OFS_PARM0), sv.worldmodel)->contents;
 }
 
 /*
@@ -1542,7 +1461,7 @@ void PF_nextent (void)
 {
        int             i;
        edict_t *ent;
-       
+
        i = G_EDICTNUM(OFS_PARM0);
        while (1)
        {
@@ -1577,7 +1496,7 @@ void PF_aim (void)
        trace_t tr;
        float   dist, bestdist;
        float   speed;
-       
+
        ent = G_EDICT(OFS_PARM0);
        speed = G_FLOAT(OFS_PARM1);
 
@@ -1588,8 +1507,8 @@ void PF_aim (void)
        VectorCopy (pr_global_struct->v_forward, dir);
        VectorMA (start, 2048, dir, end);
        tr = SV_Move (start, vec3_origin, vec3_origin, end, MOVE_NORMAL, ent);
-       if (tr.ent && tr.ent->v.takedamage == DAMAGE_AIM
-       && (!teamplay.integer || ent->v.team <=0 || ent->v.team != tr.ent->v.team) )
+       if (tr.ent && ((edict_t *)tr.ent)->v.takedamage == DAMAGE_AIM
+       && (!teamplay.integer || ent->v.team <=0 || ent->v.team != ((edict_t *)tr.ent)->v.team) )
        {
                VectorCopy (pr_global_struct->v_forward, G_VECTOR(OFS_RETURN));
                return;
@@ -1600,7 +1519,7 @@ void PF_aim (void)
        VectorCopy (dir, bestdir);
        bestdist = sv_aim.value;
        bestent = NULL;
-       
+
        check = NEXT_EDICT(sv.edicts);
        for (i=1 ; i<sv.num_edicts ; i++, check = NEXT_EDICT(check) )
        {
@@ -1625,7 +1544,7 @@ void PF_aim (void)
                        bestent = check;
                }
        }
-       
+
        if (bestent)
        {
                VectorSubtract (bestent->v.origin, ent->v.origin, dir);
@@ -1633,7 +1552,7 @@ void PF_aim (void)
                VectorScale (pr_global_struct->v_forward, dist, end);
                end[2] = dir[2];
                VectorNormalize (end);
-               VectorCopy (end, G_VECTOR(OFS_RETURN)); 
+               VectorCopy (end, G_VECTOR(OFS_RETURN));
        }
        else
        {
@@ -1652,12 +1571,12 @@ void PF_changeyaw (void)
 {
        edict_t         *ent;
        float           ideal, current, move, speed;
-       
+
        ent = PROG_TO_EDICT(pr_global_struct->self);
        current = ANGLEMOD(ent->v.angles[1]);
        ideal = ent->v.ideal_yaw;
        speed = ent->v.yaw_speed;
-       
+
        if (current == ideal)
                return;
        move = ideal - current;
@@ -1681,7 +1600,7 @@ void PF_changeyaw (void)
                if (move < -speed)
                        move = -speed;
        }
-       
+
        ent->v.angles[1] = ANGLEMOD (current + move);
 }
 
@@ -1695,7 +1614,7 @@ void PF_changepitch (void)
        edict_t         *ent;
        float           ideal, current, move, speed;
        eval_t          *val;
-       
+
        ent = G_EDICT(OFS_PARM0);
        current = ANGLEMOD( ent->v.angles[0] );
        if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch)))
@@ -1712,7 +1631,7 @@ void PF_changepitch (void)
                PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch");
                return;
        }
-       
+
        if (current == ideal)
                return;
        move = ideal - current;
@@ -1736,7 +1655,7 @@ void PF_changepitch (void)
                if (move < -speed)
                        move = -speed;
        }
-       
+
        ent->v.angles[0] = ANGLEMOD (current + move);
 }
 
@@ -1764,17 +1683,17 @@ sizebuf_t *WriteDest (void)
        {
        case MSG_BROADCAST:
                return &sv.datagram;
-       
+
        case MSG_ONE:
                ent = PROG_TO_EDICT(pr_global_struct->msg_entity);
                entnum = NUM_FOR_EDICT(ent);
                if (entnum < 1 || entnum > svs.maxclients)
                        PR_RunError ("WriteDest: not a client");
                return &svs.clients[entnum-1].message;
-               
+
        case MSG_ALL:
                return &sv.reliable_datagram;
-       
+
        case MSG_INIT:
                return &sv.signon;
 
@@ -1782,7 +1701,7 @@ sizebuf_t *WriteDest (void)
                PR_RunError ("WriteDest: bad destination");
                break;
        }
-       
+
        return NULL;
 }
 
@@ -1835,7 +1754,7 @@ void PF_makestatic (void)
 {
        edict_t *ent;
        int             i, large;
-       
+
        ent = G_EDICT(OFS_PARM0);
 
        large = false;
@@ -1905,7 +1824,7 @@ void PF_changelevel (void)
        if (svs.changelevel_issued)
                return;
        svs.changelevel_issued = true;
-       
+
        s = G_STRING(OFS_PARM0);
        Cbuf_AddText (va("changelevel %s\n",s));
 }
@@ -1944,7 +1863,7 @@ void PF_randomvec (void)
                temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
        }
        while (DotProduct(temp, temp) >= 1);
-       VectorCopy (temp, G_VECTOR(OFS_RETURN));        
+       VectorCopy (temp, G_VECTOR(OFS_RETURN));
 }
 
 void SV_LightPoint (vec3_t color, vec3_t p);
@@ -1966,7 +1885,7 @@ void PF_GetLight (void)
        vec_t*          p;
        p = G_VECTOR(OFS_PARM0);
        SV_LightPoint (color, p);
-       VectorCopy (color, G_VECTOR(OFS_RETURN));       
+       VectorCopy (color, G_VECTOR(OFS_RETURN));
 }
 
 #define MAX_QC_CVARS 128
@@ -1975,15 +1894,15 @@ int currentqc_cvar;
 
 void PF_registercvar (void)
 {
-       char    *name, *value;
-       cvar_t  *variable;
-       name = G_STRING(OFS_PARM1);
-       value = G_STRING(OFS_PARM2);
+       char *name, *value;
+       cvar_t *variable;
+       name = G_STRING(OFS_PARM0);
+       value = G_STRING(OFS_PARM1);
        G_FLOAT(OFS_RETURN) = 0;
 // first check to see if it has already been defined
        if (Cvar_FindVar (name))
                return;
-       
+
 // check for overlap with a command
        if (Cmd_Exists (name))
        {
@@ -1996,15 +1915,13 @@ void PF_registercvar (void)
 
 // copy the name and value
        variable = &qc_cvar[currentqc_cvar++];
-       variable->name = Z_Malloc (strlen(name)+1);     
+       variable->name = Z_Malloc (strlen(name)+1);
        strcpy (variable->name, name);
-       variable->string = Z_Malloc (strlen(value)+1);  
+       variable->string = Z_Malloc (strlen(value)+1);
        strcpy (variable->string, value);
        variable->value = atof (value);
-       
-// link the variable in
-       variable->next = cvar_vars;
-       cvar_vars = variable;
+
+       Cvar_RegisterVariable(variable);
        G_FLOAT(OFS_RETURN) = 1; // success
 }
 
@@ -2709,3 +2626,4 @@ PF_te_plasmaburn,         // #433
 
 builtin_t *pr_builtins = pr_builtin;
 int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]);
+