data = entdata;
if (!data)
return;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
if (com_token[0] != '{')
return; // error
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
if (com_token[0] == '}')
break; // end of worldspawn
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
strcpy(value, com_token);
if (!strcmp("sky", key))
static entity_frame_t entityframe;
void CL_ReadEntityFrame(void)
{
- entity_t *ent;
- int i;
- EntityFrame_Read(&cl.entitydatabase);
- EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
- for (i = 0;i < entityframe.numentities;i++)
+ if (dpprotocol == DPPROTOCOL_VERSION3)
{
- // copy the states
- ent = &cl_entities[entityframe.entitydata[i].number];
- ent->state_previous = ent->state_current;
- ent->state_current = entityframe.entitydata[i];
- CL_MoveLerpEntityStates(ent);
- // the entity lives again...
- entlife[ent->state_current.number] = 2;
- cl_entities_active[ent->state_current.number] = true;
+ int i;
+ entity_t *ent;
+ EntityFrame_Read(&cl.entitydatabase);
+ EntityFrame_FetchFrame(&cl.entitydatabase, EntityFrame_MostRecentlyRecievedFrameNum(&cl.entitydatabase), &entityframe);
+ for (i = 0;i < entityframe.numentities;i++)
+ {
+ // copy the states
+ ent = &cl_entities[entityframe.entitydata[i].number];
+ ent->state_previous = ent->state_current;
+ ent->state_current = entityframe.entitydata[i];
+ CL_MoveLerpEntityStates(ent);
+ // the entity lives again...
+ entlife[ent->state_current.number] = 2;
+ cl_entities_active[ent->state_current.number] = true;
+ }
}
+ else
+ EntityFrame4_CL_ReadFrame(&cl.entitydatabase4);
}
void CL_EntityUpdateSetup(void)
void CL_EntityUpdateEnd(void)
{
- int i;
- // disable entities that disappeared this frame
- for (i = 1;i < MAX_EDICTS;i++)
+ if (dpprotocol != DPPROTOCOL_VERSION4)
{
- // clear only the entities that were active last frame but not this
- // frame, don't waste time clearing all entities (which would cause
- // cache misses)
- if (entlife[i])
+ int i;
+ // disable entities that disappeared this frame
+ for (i = 1;i < MAX_EDICTS;i++)
{
- entlife[i]--;
- if (!entlife[i])
- cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
+ // clear only the entities that were active last frame but not this
+ // frame, don't waste time clearing all entities (which would cause
+ // cache misses)
+ if (entlife[i])
+ {
+ entlife[i]--;
+ if (!entlife[i])
+ cl_entities[i].state_previous.active = cl_entities[i].state_current.active = 0;
+ }
}
}
}
// entity database stuff
entity_database_t entitydatabase;
+ entity_database4_t entitydatabase4;
}
client_state_t;
if (cmd_argc == 1)
cmd_args = text;
- if (!COM_ParseToken (&text))
+ if (!COM_ParseToken(&text, false))
return;
if (cmd_argc < MAX_ARGS)
Parse a token out of a string
==============
*/
-int COM_ParseToken (const char **datapointer)
+int COM_ParseToken(const char **datapointer, int returnnewline)
{
int c;
int len;
// skip whitespace
skipwhite:
- while ((c = *data) <= ' ')
+ while ((c = *data) <= ' ' && (c != '\n' || !returnnewline))
{
if (c == 0)
{
data++;
}
-// skip // comments
- if (c=='/' && data[1] == '/')
+ // check if it's a comment
+ if (c == '/')
{
- while (*data && *data != '\n')
- data++;
- goto skipwhite;
+ // skip // comments
+ if (data[1] == '/')
+ {
+ while (*data && *data != '\n')
+ data++;
+ goto skipwhite;
+ }
+ // skip /* comments
+ if (data[1] == '*')
+ {
+ while (*data && *data != '*' && data[1] != '/')
+ data++;
+ goto skipwhite;
+ }
}
-
// handle quoted strings specially
if (c == '\"')
{
while (1)
{
c = *data++;
- if (c=='\"' || !c)
+ if (c == '\"' || !c)
{
com_token[len] = 0;
*datapointer = data;
}
// parse single characters
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
+ if (c == '{' || c == '}' || c == ')' || c == '(' || c == ']' || c == '[' || c == '\'' || c == ':' || c == ',' || c == ';' || c == '\n')
{
com_token[len] = c;
len++;
data++;
len++;
c = *data;
- if (c=='{' || c=='}'|| c==')'|| c=='(' || c=='\'' || c==':')
+ if (c == '{' || c == '}' || c == ')' || c == '(' || c == ']' || c == '[' || c == '\'' || c == ':' || c == ',' || c == ';')
break;
} while (c>32);
extern char com_token[1024];
-int COM_ParseToken (const char **data);
+int COM_ParseToken(const char **datapointer, int returnnewline);
extern int com_argc;
extern const char **com_argv;
Host_Error ("Loadgame buffer overflow");
buf[i] = 0;
start = buf;
- if (!COM_ParseToken(&start))
+ if (!COM_ParseToken(&start, false))
{
// end of file
break;
if (Cmd_Argc() > 2)
{
message = Cmd_Args();
- COM_ParseToken(&message);
+ COM_ParseToken(&message, false);
if (byNumber)
{
message++; // skip the #
memset(skin, 0, sizeof(*skin));
for (skinfileitem = skinfile->items;skinfileitem;skinfileitem = skinfileitem->next)
{
- if (!strcmp(skinfileitem->name, meshname))
+ // leave the skin unitialized (nodraw) if the replacement is "common/nodraw" or "textures/common/nodraw"
+ if (!strcmp(skinfileitem->name, meshname) && strcmp(skinfileitem->replacement, "common/nodraw") && strcmp(skinfileitem->replacement, "textures/common/nodraw"))
{
- if (!strcmp(skinfileitem->replacement, "common/nodraw"))
- {
- }
+ memset(&tempskinframe, 0, sizeof(tempskinframe));
+ if (Mod_LoadSkinFrame(&tempskinframe, skinfileitem->replacement, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE, true, false, true))
+ Mod_BuildAliasSkinFromSkinFrame(skin, &tempskinframe);
else
{
- memset(&tempskinframe, 0, sizeof(tempskinframe));
- if (Mod_LoadSkinFrame(&tempskinframe, skinfileitem->replacement, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE, true, false, true))
+ Con_Printf("mesh \"%s\": failed to load skin #%i \"%s\", falling back to mesh's internal shader name \"%s\"\n", meshname, i, skinfileitem->replacement, shadername);
+ if (Mod_LoadSkinFrame(&tempskinframe, shadername, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE, true, false, true))
Mod_BuildAliasSkinFromSkinFrame(skin, &tempskinframe);
else
{
- Con_Printf("mesh \"%s\": failed to load skin #%i \"%s\", falling back to mesh's internal shader name \"%s\"\n", meshname, i, skinfileitem->replacement, shadername);
- if (Mod_LoadSkinFrame(&tempskinframe, shadername, (r_mipskins.integer ? TEXF_MIPMAP : 0) | TEXF_ALPHA | TEXF_CLAMP | TEXF_PRECACHE, true, false, true))
- Mod_BuildAliasSkinFromSkinFrame(skin, &tempskinframe);
- else
- {
- Con_Printf("failed to load skin \"%s\"\n", shadername);
- Mod_BuildAliasSkinFromSkinFrame(skin, NULL);
- }
+ Con_Printf("failed to load skin \"%s\"\n", shadername);
+ Mod_BuildAliasSkinFromSkinFrame(skin, NULL);
}
}
}
// load the skins
if ((skinfiles = Mod_LoadSkinFiles()))
{
- loadmodel->alias.aliasdata_meshes->num_skins = totalskins = loadmodel->numskins = Mod_CountSkinFiles(skinfiles);
+ loadmodel->alias.aliasdata_meshes->num_skins = totalskins = loadmodel->numskins;
loadmodel->alias.aliasdata_meshes->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->alias.aliasdata_meshes->num_skins * sizeof(aliasskin_t));
Mod_BuildAliasSkinsFromSkinFiles(loadmodel->alias.aliasdata_meshes->data_skins, skinfiles, "default", "");
Mod_FreeSkinFiles(skinfiles);
inskin = (void*)(base + LittleLong(pinmodel->ofs_skins));
if ((skinfiles = Mod_LoadSkinFiles()))
{
- loadmodel->alias.aliasdata_meshes->num_skins = loadmodel->numskins = Mod_CountSkinFiles(skinfiles);
+ loadmodel->alias.aliasdata_meshes->num_skins = loadmodel->numskins;
loadmodel->alias.aliasdata_meshes->data_skins = Mem_Alloc(loadmodel->mempool, loadmodel->alias.aliasdata_meshes->num_skins * sizeof(aliasskin_t));
Mod_BuildAliasSkinsFromSkinFiles(loadmodel->alias.aliasdata_meshes->data_skins, skinfiles, "default", "");
Mod_FreeSkinFiles(skinfiles);
loadmodel->name, version, MD3VERSION);
skinfiles = Mod_LoadSkinFiles();
- loadmodel->numskins = Mod_CountSkinFiles(skinfiles);
if (loadmodel->numskins < 1)
loadmodel->numskins = 1;
loadmodel->alias.aliasnum_tagframes = loadmodel->numframes;
loadmodel->alias.aliasnum_tags = LittleLong(pinmodel->num_tags);
loadmodel->alias.aliasdata_tags = Mem_Alloc(loadmodel->mempool, loadmodel->alias.aliasnum_tagframes * loadmodel->alias.aliasnum_tags * sizeof(aliastag_t));
- for (i = 0, pintag = (md3tag_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_tags));i < loadmodel->alias.aliasnum_tagframes * loadmodel->alias.aliasnum_tags;i++, pinframe++)
+ for (i = 0, pintag = (md3tag_t *)((qbyte *)pinmodel + LittleLong(pinmodel->lump_tags));i < loadmodel->alias.aliasnum_tagframes * loadmodel->alias.aliasnum_tags;i++, pintag++)
{
strcpy(loadmodel->alias.aliasdata_tags[i].name, pintag->name);
Matrix4x4_CreateIdentity(&loadmodel->alias.aliasdata_tags[i].matrix);
for (j = 0;j < 3;j++)
{
for (k = 0;k < 3;k++)
- loadmodel->alias.aliasdata_tags[i].matrix.m[j][k] = LittleLong(pintag->rotationmatrix[j * 3 + k]);
- loadmodel->alias.aliasdata_tags[i].matrix.m[j][3] = LittleLong(pintag->origin[j]);
+ loadmodel->alias.aliasdata_tags[i].matrix.m[j][k] = LittleFloat(pintag->rotationmatrix[j * 3 + k]);
+ loadmodel->alias.aliasdata_tags[i].matrix.m[j][3] = LittleFloat(pintag->origin[j]);
}
+ //Con_Printf("model \"%s\" frame #%i tag #%i \"%s\"\n", loadmodel->name, i / loadmodel->alias.aliasnum_tags, i % loadmodel->alias.aliasnum_tags, loadmodel->alias.aliasdata_tags[i].name);
}
// load meshes
mesh->data_element3i[j] = LittleLong(((int *)((qbyte *)pinmesh + pinmesh->lump_elements))[j]);
for (j = 0;j < mesh->num_vertices;j++)
{
- mesh->data_texcoord2f[j * 2 + 0] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 0]);
- mesh->data_texcoord2f[j * 2 + 1] = LittleLong(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 1]);
+ mesh->data_texcoord2f[j * 2 + 0] = LittleFloat(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 0]);
+ mesh->data_texcoord2f[j * 2 + 1] = LittleFloat(((float *)((qbyte *)pinmesh + pinmesh->lump_texcoords))[j * 2 + 1]);
}
for (j = 0;j < mesh->num_vertices * mesh->num_frames;j++)
{
if (LittleLong(pinmesh->num_shaders) >= 1 && ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name[0])
Mod_BuildAliasSkinsFromSkinFiles(mesh->data_skins, skinfiles, pinmesh->name, ((md3shader_t *)((qbyte *) pinmesh + pinmesh->lump_shaders))->name);
else
- {
for (j = 0;j < mesh->num_skins;j++)
Mod_BuildAliasSkinFromSkinFrame(mesh->data_skins + j, NULL);
- }
}
Mod_CalcAliasModelBBoxes();
Mod_FreeSkinFiles(skinfiles);
int i, j, k;
if (!data)
return;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
if (com_token[0] != '{')
return; // error
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
if (com_token[0] == '}')
break; // end of worldspawn
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
return; // error
strcpy(value, com_token);
if (!strcmp("wad", key)) // for HalfLife maps
memcpy(loadmodel->brush.entities, mod_base + l->fileofs, l->filelen);
data = loadmodel->brush.entities;
// some Q3 maps override the lightgrid_cellsize with a worldspawn key
- if (data && COM_ParseToken(&data) && com_token[0] == '{')
+ if (data && COM_ParseToken(&data, false) && com_token[0] == '{')
{
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
if (com_token[0] == '}')
break; // end of worldspawn
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
strcpy(value, com_token);
if (!strcmp("gridsize", key))
skinfile_t *Mod_LoadSkinFiles(void)
{
- int i;
+ int i, words, numtags, line, tagsetsused = false, wordsoverflow;
char *text;
const char *data;
skinfile_t *skinfile, *first = NULL;
skinfileitem_t *skinfileitem;
- char command[MAX_QPATH], name[MAX_QPATH], replacement[MAX_QPATH];
- for (i = 0;(data = text = FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), true));i++)
+ char word[10][MAX_QPATH];
+ overridetagnameset_t tagsets[MAX_SKINS];
+ overridetagname_t tags[256];
+
+/*
+sample file:
+U_bodyBox,models/players/Legoman/BikerA2.tga
+U_RArm,models/players/Legoman/BikerA1.tga
+U_LArm,models/players/Legoman/BikerA1.tga
+U_armor,common/nodraw
+U_sword,common/nodraw
+U_shield,common/nodraw
+U_homb,common/nodraw
+U_backpack,common/nodraw
+U_colcha,common/nodraw
+tag_head,
+tag_weapon,
+tag_torso,
+*/
+ memset(tagsets, 0, sizeof(tagsets));
+ memset(word, 0, sizeof(word));
+ for (i = 0;i < MAX_SKINS && (data = text = FS_LoadFile(va("%s_%i.skin", loadmodel->name, i), true));i++)
{
+ numtags = 0;
skinfile = Mem_Alloc(tempmempool, sizeof(skinfile_t));
skinfile->next = first;
first = skinfile;
- for(;;)
+ for(line = 0;;line++)
{
- if (!COM_ParseToken(&data))
+ // parse line
+ if (!COM_ParseToken(&data, true))
break;
- strncpy(command, com_token, sizeof(command) - 1);
- command[sizeof(command) - 1] = 0;
- if (!strcmp(command, "replace"))
+ if (!strcmp(com_token, "\n"))
+ continue;
+ words = 0;
+ wordsoverflow = false;
+ do
{
- if (!COM_ParseToken(&data))
- {
- Con_Printf("Mod_LoadSkinFiles: parsing error (insufficient parameters to command \"%s\" in file \"%s_%i.skin\")\n", command, loadmodel->name, i);
- break;
- }
- strncpy(name, com_token, sizeof(name) - 1);
- name[sizeof(name) - 1] = 0;
- if (!COM_ParseToken(&data))
+ if (words < 10)
+ strncpy(word[words++], com_token, MAX_QPATH - 1);
+ else
+ wordsoverflow = true;
+ }
+ while (COM_ParseToken(&data, true) && strcmp(com_token, "\n"));
+ if (wordsoverflow)
+ {
+ Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: line with too many statements, skipping\n", loadmodel->name, i, line);
+ continue;
+ }
+ // words is always >= 1
+ if (!strcmp(word[0], "replace"))
+ {
+ if (words == 3)
{
- Con_Printf("Mod_LoadSkinFiles: parsing error (insufficient parameters to command \"%s\" in file \"%s_%i.skin\")\n", command, loadmodel->name, i);
- break;
+ Con_DPrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[1], word[2]);
+ skinfileitem = Mem_Alloc(tempmempool, sizeof(skinfileitem_t));
+ skinfileitem->next = skinfile->items;
+ skinfile->items = skinfileitem;
+ strncpy(skinfileitem->name, word[1], sizeof(skinfileitem->name) - 1);
+ strncpy(skinfileitem->replacement, word[2], sizeof(skinfileitem->replacement) - 1);
}
- strncpy(replacement, com_token, sizeof(replacement) - 1);
- replacement[sizeof(replacement) - 1] = 0;
+ else
+ Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: wrong number of parameters to command \"%s\", see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n", loadmodel->name, i, line, word[0]);
+ }
+ else if (words == 2 && !strcmp(word[1], ","))
+ {
+ // tag name, like "tag_weapon,"
+ Con_DPrintf("Mod_LoadSkinFiles: parsed tag #%i \"%s\"\n", numtags, word[0]);
+ memset(tags + numtags, 0, sizeof(tags[numtags]));
+ strncpy(tags[numtags].name, word[0], sizeof(tags[numtags].name) - 1);
+ numtags++;
+ }
+ else if (words == 3 && !strcmp(word[1], ","))
+ {
+ // mesh shader name, like "U_RArm,models/players/Legoman/BikerA1.tga"
+ Con_DPrintf("Mod_LoadSkinFiles: parsed mesh \"%s\" shader replacement \"%s\"\n", word[0], word[2]);
skinfileitem = Mem_Alloc(tempmempool, sizeof(skinfileitem_t));
skinfileitem->next = skinfile->items;
skinfile->items = skinfileitem;
- strncpy(skinfileitem->name, name, sizeof(skinfileitem->name) - 1);
- strncpy(skinfileitem->replacement, replacement, sizeof(skinfileitem->replacement) - 1);
+ strncpy(skinfileitem->name, word[0], sizeof(skinfileitem->name) - 1);
+ strncpy(skinfileitem->replacement, word[2], sizeof(skinfileitem->replacement) - 1);
}
else
- Con_Printf("Mod_LoadSkinFiles: parsing error (unknown command \"%s\" in file \"%s_%i.skin\")\n", command, loadmodel->name, i);
+ Con_Printf("Mod_LoadSkinFiles: parsing error in file \"%s_%i.skin\" on line #%i: does not look like tag or mesh specification, or replace command, see documentation in DP_GFX_SKINFILES extension in dpextensions.qc\n", loadmodel->name, i, line);
}
Mem_Free(text);
+
+ if (numtags)
+ {
+ overridetagnameset_t *t;
+ t = tagsets + i;
+ t->num_overridetagnames = numtags;
+ t->data_overridetagnames = Mem_Alloc(loadmodel->mempool, t->num_overridetagnames * sizeof(overridetagname_t));
+ memcpy(t->data_overridetagnames, tags, t->num_overridetagnames * sizeof(overridetagname_t));
+ tagsetsused = true;
+ }
+ }
+ if (tagsetsused)
+ {
+ loadmodel->data_overridetagnamesforskin = Mem_Alloc(loadmodel->mempool, i * sizeof(overridetagnameset_t));
+ memcpy(loadmodel->data_overridetagnamesforskin, tagsets, i * sizeof(overridetagnameset_t));
}
+ loadmodel->numskins = i;
return first;
}
#define MAX_SKINS 256
+typedef struct overridetagname_s
+{
+ char name[MAX_QPATH];
+}
+overridetagname_t;
+
+// a replacement set of tag names, per skin
+typedef struct overridetagnameset_s
+{
+ int num_overridetagnames;
+ overridetagname_t *data_overridetagnames;
+}
+overridetagnameset_t;
+
#define SHADOWMESHVERTEXHASH 1024
typedef struct shadowmeshvertexhash_s
{
model_brushq2_t brushq2;
*/
model_brushq3_t brushq3;
+ // skin files can have different tags for each skin
+ overridetagnameset_t *data_overridetagnamesforskin;
}
model_t;
tokens = Z_Malloc(strlen(str) * sizeof(char *));
max_tokens = strlen(str);
- for (p = str;COM_ParseToken(&p) && num_tokens < max_tokens;num_tokens++)
+ for (p = str;COM_ParseToken(&p, false) && num_tokens < max_tokens;num_tokens++)
{
tokens[num_tokens] = Z_Malloc(strlen(com_token) + 1);
strcpy(tokens[num_tokens], com_token);
if (modelindex >= 0 && modelindex < MAX_MODELS)
{
model = sv.models[modelindex];
- if (model->alias.aliasnum_tags)
+ if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames)
+ for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
+ if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
+ v->_float = i + 1;
+ if (v->_float == 0 && model->alias.aliasnum_tags)
for (i = 0;i < model->alias.aliasnum_tags;i++)
if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
v->_float = i + 1;
while (1)
{
// parse key
- if (!COM_ParseToken (&data))
+ if (!COM_ParseToken(&data, false))
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
break;
strcpy (keyname, com_token);
// parse value
- if (!COM_ParseToken (&data))
+ if (!COM_ParseToken(&data, false))
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
while (1)
{
// parse key
- if (!COM_ParseToken (&data))
+ if (!COM_ParseToken(&data, false))
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
break;
}
// parse value
- if (!COM_ParseToken (&data))
+ if (!COM_ParseToken(&data, false))
Host_Error ("ED_ParseEntity: EOF without closing brace");
if (com_token[0] == '}')
while (1)
{
// parse the opening brace
- if (!COM_ParseToken (&data))
+ if (!COM_ParseToken(&data, false))
break;
if (com_token[0] != '{')
Host_Error ("ED_LoadFromFile: found %s when expecting {",com_token);
d->currentcommit = NULL;
}
+extern void CL_MoveLerpEntityStates(entity_t *ent);
void EntityFrame4_CL_ReadFrame(entity_database4_t *d)
{
int i, n, number, referenceframenum, framenum;
}
else
EntityState_Read(&cl_entities[number].state_current, EntityFrame4_GetReferenceEntity(d, number), number);
+ CL_MoveLerpEntityStates(&cl_entities[number]);
+ cl_entities_active[number] = true;
if (d->currentcommit)
EntityFrame4_AddCommitEntity(d, &cl_entities[number].state_current);
}
data = cl.worldmodel->brush.entities;
if (!data)
return;
- for (entnum = 0;COM_ParseToken(&data) && com_token[0] == '{';entnum++)
+ for (entnum = 0;COM_ParseToken(&data, false) && com_token[0] == '{';entnum++)
{
light = 0;
origin[0] = origin[1] = origin[2] = 0;
islight = false;
while (1)
{
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
if (com_token[0] == '}')
break; // end of entity
strcpy(key, com_token);
while (key[strlen(key)-1] == ' ') // remove trailing spaces
key[strlen(key)-1] = 0;
- if (!COM_ParseToken(&data))
+ if (!COM_ParseToken(&data, false))
break; // error
strcpy(value, com_token);