X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=svvm_cmds.c;h=da749e3de90d5743c82a12a1df326d55d48017d5;hb=13192ac6081831489c47e1b50642d9e2cc354376;hp=40d6c1755a5ae3f56ab4f1a08eda1a6499910bef;hpb=9cc276c2e36a6fc6cfafd8a0fb6df85e2f644c07;p=xonotic%2Fdarkplaces.git diff --git a/svvm_cmds.c b/svvm_cmds.c index 40d6c175..da749e3d 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -111,6 +111,7 @@ char *vm_sv_extensions = "DP_TE_SMALLFLASH " "DP_TE_SPARK " "DP_TE_STANDARDEFFECTBUILTINS " +"DP_TRACE_HITCONTENTSMASK_SURFACEINFO " "DP_VIEWZOOM " "EXT_BITSHIFT " //"EXT_CSQC " // not ready yet @@ -323,7 +324,7 @@ void PF_particle (void) dir = PRVM_G_VECTOR(OFS_PARM1); color = PRVM_G_FLOAT(OFS_PARM2); count = PRVM_G_FLOAT(OFS_PARM3); - SV_StartParticle (org, dir, color, count); + SV_StartParticle (org, dir, (int)color, (int)count); } @@ -368,8 +369,8 @@ void PF_ambientsound (void) else MSG_WriteByte (&sv.signon, soundnum); - MSG_WriteByte (&sv.signon, vol*255); - MSG_WriteByte (&sv.signon, attenuation*64); + MSG_WriteByte (&sv.signon, (int)(vol*255)); + MSG_WriteByte (&sv.signon, (int)(attenuation*64)); } @@ -397,9 +398,9 @@ void PF_sound (void) float attenuation; entity = PRVM_G_EDICT(OFS_PARM0); - channel = PRVM_G_FLOAT(OFS_PARM1); + channel = (int)PRVM_G_FLOAT(OFS_PARM1); sample = PRVM_G_STRING(OFS_PARM2); - volume = PRVM_G_FLOAT(OFS_PARM3) * 255; + volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255); attenuation = PRVM_G_FLOAT(OFS_PARM4); if (volume < 0 || volume > 255) @@ -431,14 +432,18 @@ void PF_traceline (void) trace_t trace; int move; prvm_edict_t *ent; + prvm_eval_t *val; prog->xfunction->builtinsprofile += 30; v1 = PRVM_G_VECTOR(OFS_PARM0); v2 = PRVM_G_VECTOR(OFS_PARM1); - move = PRVM_G_FLOAT(OFS_PARM2); + move = (int)PRVM_G_FLOAT(OFS_PARM2); ent = PRVM_G_EDICT(OFS_PARM3); + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2])) + PRVM_ERROR("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent)); + trace = SV_Move (v1, vec3_origin, vec3_origin, v2, move, ent); prog->globals.server->trace_allsolid = trace.allsolid; @@ -453,7 +458,23 @@ void PF_traceline (void) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); - // FIXME: add trace_endcontents + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents))) + val->_float = trace.startsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents))) + val->_float = trace.hitsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags))) + val->_float = trace.hitq3surfaceflags; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename))) + { + if (trace.hittexture) + { + char *s = VM_GetTempString(); + strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH); + val->string = PRVM_SetEngineString(s); + } + else + val->string = 0; + } } @@ -475,6 +496,7 @@ void PF_tracebox (void) trace_t trace; int move; prvm_edict_t *ent; + prvm_eval_t *val; prog->xfunction->builtinsprofile += 30; @@ -482,9 +504,12 @@ void PF_tracebox (void) m1 = PRVM_G_VECTOR(OFS_PARM1); m2 = PRVM_G_VECTOR(OFS_PARM2); v2 = PRVM_G_VECTOR(OFS_PARM3); - move = PRVM_G_FLOAT(OFS_PARM4); + move = (int)PRVM_G_FLOAT(OFS_PARM4); ent = PRVM_G_EDICT(OFS_PARM5); + if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v1[2]) || IS_NAN(v2[2])) + PRVM_ERROR("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", PRVM_NAME, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent)); + trace = SV_Move (v1, m1, m2, v2, move, ent); prog->globals.server->trace_allsolid = trace.allsolid; @@ -499,6 +524,23 @@ void PF_tracebox (void) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents))) + val->_float = trace.startsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents))) + val->_float = trace.hitsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags))) + val->_float = trace.hitq3surfaceflags; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename))) + { + if (trace.hittexture) + { + char *s = VM_GetTempString(); + strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH); + val->string = PRVM_SetEngineString(s); + } + else + val->string = 0; + } } extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore); @@ -507,6 +549,7 @@ void PF_tracetoss (void) trace_t trace; prvm_edict_t *ent; prvm_edict_t *ignore; + prvm_eval_t *val; prog->xfunction->builtinsprofile += 600; @@ -529,6 +572,23 @@ void PF_tracetoss (void) prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent); else prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts); + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents))) + val->_float = trace.startsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents))) + val->_float = trace.hitsupercontents; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags))) + val->_float = trace.hitq3surfaceflags; + if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename))) + { + if (trace.hittexture) + { + char *s = VM_GetTempString(); + strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH); + val->string = PRVM_SetEngineString(s); + } + else + val->string = 0; + } } @@ -859,7 +919,7 @@ void PF_lightstyle (void) client_t *client; int j; - style = PRVM_G_FLOAT(OFS_PARM0); + style = (int)PRVM_G_FLOAT(OFS_PARM0); val = PRVM_G_STRING(OFS_PARM1); if( (unsigned) style >= MAX_LIGHTSTYLES ) { @@ -1123,7 +1183,7 @@ sizebuf_t *WriteDest (void) prvm_edict_t *ent; extern sizebuf_t *sv2csqcbuf; - dest = PRVM_G_FLOAT(OFS_PARM0); + dest = (int)PRVM_G_FLOAT(OFS_PARM0); switch (dest) { case MSG_BROADCAST: @@ -1157,22 +1217,22 @@ sizebuf_t *WriteDest (void) void PF_WriteByte (void) { - MSG_WriteByte (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteByte (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteChar (void) { - MSG_WriteChar (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteChar (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteShort (void) { - MSG_WriteShort (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteShort (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteLong (void) { - MSG_WriteLong (WriteDest(), PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteLong (WriteDest(), (int)PRVM_G_FLOAT(OFS_PARM1)); } void PF_WriteAngle (void) @@ -1221,18 +1281,18 @@ void PF_makestatic (void) if (large) { MSG_WriteByte (&sv.signon,svc_spawnstatic2); - MSG_WriteShort (&sv.signon, ent->fields.server->modelindex); - MSG_WriteShort (&sv.signon, ent->fields.server->frame); + MSG_WriteShort (&sv.signon, (int)ent->fields.server->modelindex); + MSG_WriteShort (&sv.signon, (int)ent->fields.server->frame); } else { MSG_WriteByte (&sv.signon,svc_spawnstatic); - MSG_WriteByte (&sv.signon, ent->fields.server->modelindex); - MSG_WriteByte (&sv.signon, ent->fields.server->frame); + MSG_WriteByte (&sv.signon, (int)ent->fields.server->modelindex); + MSG_WriteByte (&sv.signon, (int)ent->fields.server->frame); } - MSG_WriteByte (&sv.signon, ent->fields.server->colormap); - MSG_WriteByte (&sv.signon, ent->fields.server->skin); + MSG_WriteByte (&sv.signon, (int)ent->fields.server->colormap); + MSG_WriteByte (&sv.signon, (int)ent->fields.server->skin); for (i=0 ; i<3 ; i++) { MSG_WriteCoord(&sv.signon, ent->fields.server->origin[i], sv.protocol); @@ -1331,7 +1391,7 @@ void VM_AutoSentStats_Clear (void) { if(vm_autosentstats) { - free(vm_autosentstats); + Z_Free(vm_autosentstats); vm_autosentstats = NULL; vm_autosentstats_last = -1; } @@ -1413,7 +1473,7 @@ void VM_SV_WriteAutoSentStats (client_t *client, prvm_edict_t *ent, sizebuf_t *m break; //integer case 8: - v = PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ? + v = (int)PRVM_E_FLOAT(ent, vm_autosentstats[i].fieldoffset); //[515]: use PRVM_E_INT ? if (!send) stats[i+32] = v; else @@ -1439,15 +1499,15 @@ void PF_SV_AddStat (void) if(!vm_autosentstats) { - vm_autosentstats = malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t)); + vm_autosentstats = (autosentstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(autosentstat_t)); if(!vm_autosentstats) { Con_Printf("PF_SV_AddStat: not enough memory\n"); return; } } - i = PRVM_G_FLOAT(OFS_PARM0); - type = PRVM_G_FLOAT(OFS_PARM1); + i = (int)PRVM_G_FLOAT(OFS_PARM0); + type = (int)PRVM_G_FLOAT(OFS_PARM1); off = PRVM_G_INT (OFS_PARM2); i -= 32; @@ -1514,7 +1574,7 @@ void PF_setcolor (void) prvm_eval_t *val; entnum = PRVM_G_EDICTNUM(OFS_PARM0); - i = PRVM_G_FLOAT(OFS_PARM1); + i = (int)PRVM_G_FLOAT(OFS_PARM1); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) { @@ -1558,7 +1618,7 @@ void PF_effect (void) i = SV_ModelIndex(s, 1); if (!i) PF_WARNING("effect: model not precached\n"); - SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4)); + SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_blood (void) @@ -1596,7 +1656,7 @@ void PF_te_bloodshower (void) // speed MSG_WriteCoord(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2), sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); } void PF_te_explosionrgb (void) @@ -1632,9 +1692,9 @@ void PF_te_particlecube (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4)); // gravity true/false MSG_WriteByte(&sv.datagram, ((int) PRVM_G_FLOAT(OFS_PARM5)) != 0); // randomvel @@ -1660,9 +1720,9 @@ void PF_te_particlerain (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_particlesnow (void) @@ -1684,9 +1744,9 @@ void PF_te_particlesnow (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2)[2], sv.protocol); // count - MSG_WriteShort(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); + MSG_WriteShort(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM3), 65535)); // color - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM4)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM4)); } void PF_te_spark (void) @@ -1768,13 +1828,13 @@ void PF_te_customflash (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // radius - MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255)); + MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM1) / 8 - 1, 255)); // lifetime - MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255)); + MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_FLOAT(OFS_PARM2) * 256 - 1, 255)); // color - MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255)); - MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255)); - MSG_WriteByte(&sv.datagram, bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255)); + MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[0] * 255, 255)); + MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[1] * 255, 255)); + MSG_WriteByte(&sv.datagram, (int)bound(0, PRVM_G_VECTOR(OFS_PARM3)[2] * 255, 255)); } void PF_te_gunshot (void) @@ -1876,8 +1936,8 @@ void PF_te_explosion2 (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM0)[2], sv.protocol); // color - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM1)); - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2)); } void PF_te_lightning1 (void) @@ -1966,23 +2026,23 @@ void PF_te_flamejet (void) MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[1], sv.protocol); MSG_WriteCoord(&sv.datagram, PRVM_G_VECTOR(OFS_PARM1)[2], sv.protocol); // count - MSG_WriteByte(&sv.datagram, PRVM_G_FLOAT(OFS_PARM2)); + MSG_WriteByte(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM2)); } -void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out) +void clippointtosurface(model_t *model, msurface_t *surface, vec3_t p, vec3_t out) { int i, j, k; float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist; const int *e; bestdist = 1000000000; VectorCopy(p, out); - for (i = 0, e = (surface->groupmesh->data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3) + for (i = 0, e = (model->surfmesh.data_element3i + 3 * surface->num_firsttriangle);i < surface->num_triangles;i++, e += 3) { // clip original point to each triangle of the surface and find the // triangle that is closest - v[0] = surface->groupmesh->data_vertex3f + e[0] * 3; - v[1] = surface->groupmesh->data_vertex3f + e[1] * 3; - v[2] = surface->groupmesh->data_vertex3f + e[2] * 3; + v[0] = model->surfmesh.data_vertex3f + e[0] * 3; + v[1] = model->surfmesh.data_vertex3f + e[1] * 3; + v[2] = model->surfmesh.data_vertex3f + e[2] * 3; TriangleNormal(v[0], v[1], v[2], facenormal); VectorNormalize(facenormal); offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal); @@ -2005,16 +2065,19 @@ void clippointtosurface(msurface_t *surface, vec3_t p, vec3_t out) } } -static msurface_t *getsurface(prvm_edict_t *ed, int surfacenum) +static model_t *getmodel(prvm_edict_t *ed) { int modelindex; - model_t *model; if (!ed || ed->priv.server->free) return NULL; - modelindex = ed->fields.server->modelindex; + modelindex = (int)ed->fields.server->modelindex; if (modelindex < 1 || modelindex >= MAX_MODELS) return NULL; - model = sv.models[modelindex]; + return sv.models[modelindex]; +} + +static msurface_t *getsurface(model_t *model, int surfacenum) +{ if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces) return NULL; return model->data_surfaces + surfacenum + model->firstmodelsurface; @@ -2024,9 +2087,10 @@ static msurface_t *getsurface(prvm_edict_t *ed, int surfacenum) //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434; void PF_getsurfacenumpoints(void) { + model_t *model; msurface_t *surface; // return 0 if no such surface - if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) { PRVM_G_FLOAT(OFS_RETURN) = 0; return; @@ -2039,50 +2103,51 @@ void PF_getsurfacenumpoints(void) void PF_getsurfacepoint(void) { prvm_edict_t *ed; + model_t *model; msurface_t *surface; int pointnum; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); - if (!ed || ed->priv.server->free) - return; - if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // note: this (incorrectly) assumes it is a simple polygon - pointnum = PRVM_G_FLOAT(OFS_PARM2); + pointnum = (int)PRVM_G_FLOAT(OFS_PARM2); if (pointnum < 0 || pointnum >= surface->num_vertices) return; // FIXME: implement rotation/scaling - VectorAdd(&(surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN)); + VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacenormal, // #436 vector(entity e, float s) getsurfacenormal = #436; void PF_getsurfacenormal(void) { + model_t *model; msurface_t *surface; vec3_t normal; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); - if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling // note: this (incorrectly) assumes it is a simple polygon // note: this only returns the first triangle, so it doesn't work very // well for curved surfaces or arbitrary meshes - TriangleNormal((surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex), (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 3, (surface->groupmesh->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal); + TriangleNormal((model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex), (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 3, (model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal); VectorNormalize(normal); VectorCopy(normal, PRVM_G_VECTOR(OFS_RETURN)); } //PF_getsurfacetexture, // #437 string(entity e, float s) getsurfacetexture = #437; void PF_getsurfacetexture(void) { + model_t *model; msurface_t *surface; PRVM_G_INT(OFS_RETURN) = 0; - if (!(surface = getsurface(PRVM_G_EDICT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = getmodel(PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(surface->texture->name); } //PF_getsurfacenearpoint, // #438 float(entity e, vector p) getsurfacenearpoint = #438; void PF_getsurfacenearpoint(void) { - int surfacenum, best, modelindex; + int surfacenum, best; vec3_t clipped, p; vec_t dist, bestdist; prvm_edict_t *ed; @@ -2095,11 +2160,8 @@ void PF_getsurfacenearpoint(void) if (!ed || ed->priv.server->free) return; - modelindex = ed->fields.server->modelindex; - if (modelindex < 1 || modelindex >= MAX_MODELS) - return; - model = sv.models[modelindex]; - if (!model->num_surfaces) + model = getmodel(ed); + if (!model || !model->num_surfaces) return; // FIXME: implement rotation/scaling @@ -2117,7 +2179,7 @@ void PF_getsurfacenearpoint(void) if (dist < bestdist) { // it is, check the nearest point on the actual geometry - clippointtosurface(surface, p, clipped); + clippointtosurface(model, surface, p, clipped); VectorSubtract(clipped, p, clipped); dist += VectorLength2(clipped); if (dist < bestdist) @@ -2134,17 +2196,16 @@ void PF_getsurfacenearpoint(void) void PF_getsurfaceclippedpoint(void) { prvm_edict_t *ed; + model_t *model; msurface_t *surface; vec3_t p, out; VectorClear(PRVM_G_VECTOR(OFS_RETURN)); ed = PRVM_G_EDICT(OFS_PARM0); - if (!ed || ed->priv.server->free) - return; - if (!(surface = getsurface(ed, PRVM_G_FLOAT(OFS_PARM1)))) + if (!(model = getmodel(ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1)))) return; // FIXME: implement rotation/scaling VectorSubtract(PRVM_G_VECTOR(OFS_PARM2), ed->fields.server->origin, p); - clippointtosurface(surface, p, out); + clippointtosurface(model, surface, p, out); // FIXME: implement rotation/scaling VectorAdd(out, ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN)); } @@ -2200,7 +2261,7 @@ void PF_setattachment (void) modelindex = (int)tagentity->fields.server->modelindex; if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex])) { - v->_float = Mod_Alias_GetTagIndexForName(model, tagentity->fields.server->skin, tagname); + v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname); if (v->_float == 0) Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name); } @@ -2217,12 +2278,12 @@ int SV_GetTagIndex (prvm_edict_t *e, const char *tagname) int i; model_t *model; - i = e->fields.server->modelindex; + i = (int)e->fields.server->modelindex; if (i < 1 || i >= MAX_MODELS) return -1; model = sv.models[i]; - return Mod_Alias_GetTagIndexForName(model, e->fields.server->skin, tagname); + return Mod_Alias_GetTagIndexForName(model, (int)e->fields.server->skin, tagname); }; void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix) @@ -2242,7 +2303,7 @@ int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out int frame; model_t *model; if (tagindex >= 0 - && (modelindex = ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS + && (modelindex = (int)ent->fields.server->modelindex) >= 1 && modelindex < MAX_MODELS && (model = sv.models[(int)ent->fields.server->modelindex]) && model->animscenes) { @@ -2252,7 +2313,7 @@ int SV_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out frame = 0; return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out); } - Matrix4x4_CreateIdentity(out); + *out = identitymatrix; return 0; } @@ -2274,7 +2335,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) matrix4x4_t entitymatrix, tagmatrix, attachmatrix; model_t *model; - Matrix4x4_CreateIdentity(out); // warnings and errors return identical matrix + *out = identitymatrix; // warnings and errors return identical matrix if (ent == prog->edicts) return 1; @@ -2287,7 +2348,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) model = sv.models[modelindex]; - Matrix4x4_CreateIdentity(&tagmatrix); + tagmatrix = identitymatrix; // DP_GFX_QUAKE3MODELTAGS, scan all chain and stop on unattached entity attachloop = 0; for (;;) @@ -2305,7 +2366,7 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) // next iteration we process the parent entity if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_entity)) && val->edict) { - tagindex = PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index)->_float; + tagindex = (int)PRVM_GETEDICTFIELDVALUE(ent, eval_tag_index)->_float; ent = PRVM_EDICT_NUM(val->edict); } else @@ -2434,6 +2495,9 @@ void PF_spawnclient (void) { prog->xfunction->builtinsprofile += 100; SV_ConnectClient (i, NULL); + // this has to be set or else ClientDisconnect won't be called + // we assume the qc will call ClientConnect... + svs.clients[i].clientconnectcalled = true; ed = PRVM_EDICT_NUM(i + 1); break; } @@ -2693,7 +2757,7 @@ NULL, // #476 NULL, // #477 NULL, // #478 NULL, // #479 -e10, e10 // #471-499 (LordHavoc) +e10, e10 // #480-499 (LordHavoc) }; const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);