cl.entities[i].state_current = defaultstate;
}
- if (gamemode == GAME_NEXUIZ)
+ if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
{
VectorSet(cl.playerstandmins, -16, -16, -24);
VectorSet(cl.playerstandmaxs, 16, 16, 45);
void CL_ExpandCSQCRenderEntities(int num)
{
+ int i;
int oldmaxcsqcrenderentities;
entity_render_t *oldcsqcrenderentities;
if (num >= cl.max_csqcrenderentities)
if (oldcsqcrenderentities)
{
memcpy(cl.csqcrenderentities, oldcsqcrenderentities, oldmaxcsqcrenderentities * sizeof(entity_render_t));
+ for (i = 0;i < r_refdef.scene.numentities;i++)
+ if(r_refdef.scene.entities[i] >= oldcsqcrenderentities && r_refdef.scene.entities[i] < (oldcsqcrenderentities + oldmaxcsqcrenderentities))
+ r_refdef.scene.entities[i] = cl.csqcrenderentities + (r_refdef.scene.entities[i] - oldcsqcrenderentities);
Mem_Free(oldcsqcrenderentities);
}
}
Host should be either "local" or a net address
=====================
*/
-void CL_EstablishConnection(const char *host)
+void CL_EstablishConnection(const char *host, int firstarg)
{
if (cls.state == ca_dedicated)
return;
+ // don't connect to a server if we're benchmarking a demo
+ if (COM_CheckParm("-benchmark"))
+ return;
+
// clear menu's connect error message
M_Update_Return_Reason("");
cls.demonum = -1;
cls.connect_trying = true;
cls.connect_remainingtries = 3;
cls.connect_nextsendtime = 0;
+
+ // only NOW, set connect_userinfo
+ if(firstarg >= 0)
+ {
+ int i;
+ *cls.connect_userinfo = 0;
+ for(i = firstarg; i+2 <= Cmd_Argc(); i += 2)
+ InfoString_SetValue(cls.connect_userinfo, sizeof(cls.connect_userinfo), Cmd_Argv(i), Cmd_Argv(i+1));
+ }
+ else if(firstarg < -1)
+ {
+ // -1: keep as is (reconnect)
+ // -2: clear
+ *cls.connect_userinfo = 0;
+ }
+
M_Update_Return_Reason("Trying to connect...");
+
// run several network frames to jump into the game quickly
//if (sv.active)
//{
void CL_ClearTempEntities (void)
{
r_refdef.scene.numtempentities = 0;
+ // grow tempentities buffer on request
+ if (r_refdef.scene.expandtempentities)
+ {
+ Con_Printf("CL_NewTempEntity: grow maxtempentities from %i to %i\n", r_refdef.scene.maxtempentities, r_refdef.scene.maxtempentities * 2);
+ r_refdef.scene.maxtempentities *= 2;
+ r_refdef.scene.tempentities = (entity_render_t *)Mem_Realloc(cls.permanentmempool, r_refdef.scene.tempentities, sizeof(entity_render_t) * r_refdef.scene.maxtempentities);
+ r_refdef.scene.expandtempentities = false;
+ }
}
entity_render_t *CL_NewTempEntity(double shadertime)
if (r_refdef.scene.numentities >= r_refdef.scene.maxentities)
return NULL;
if (r_refdef.scene.numtempentities >= r_refdef.scene.maxtempentities)
+ {
+ r_refdef.scene.expandtempentities = true; // will be reallocated next frame since current frame may have pointers set already
return NULL;
+ }
render = &r_refdef.scene.tempentities[r_refdef.scene.numtempentities++];
memset (render, 0, sizeof(*render));
r_refdef.scene.entities[r_refdef.scene.numentities++] = render;
int frame;
float origin[3], angles[3], lerp;
entity_t *t;
+ entity_render_t *r;
//entity_persistent_t *p = &e->persistent;
//entity_render_t *r = &e->render;
// skip inactive entities and world
return;
t = cl.entities + e->state_current.tagentity;
// if the tag entity is inactive, skip it
- if (!t->state_current.active)
- return;
- // update the parent first
- CL_UpdateNetworkEntity(t, recursionlimit - 1, interpolate);
+ if (t->state_current.active)
+ {
+ // update the parent first
+ CL_UpdateNetworkEntity(t, recursionlimit - 1, interpolate);
+ r = &t->render;
+ }
+ else
+ {
+ // it may still be a CSQC entity... trying to use its
+ // info from last render frame (better than nothing)
+ if(!cl.csqc_server2csqcentitynumber[e->state_current.tagentity])
+ return;
+ r = cl.csqcrenderentities + cl.csqc_server2csqcentitynumber[e->state_current.tagentity];
+ if(!r->entitynumber)
+ return; // neither CSQC nor legacy entity... can't attach
+ }
// make relative to the entity
- matrix = &t->render.matrix;
+ matrix = &r->matrix;
// some properties of the tag entity carry over
- e->render.flags |= t->render.flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL);
+ e->render.flags |= r->flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL);
// if a valid tagindex is used, make it relative to that tag instead
- // FIXME: use a model function to get tag info (need to handle skeletal)
- if (e->state_current.tagentity && e->state_current.tagindex >= 1 && t->render.model)
+ if (e->state_current.tagentity && e->state_current.tagindex >= 1 && r->model)
{
- if(!Mod_Alias_GetTagMatrix(t->render.model, t->render.frameblend, t->render.skeleton, e->state_current.tagindex - 1, &blendmatrix)) // i.e. no error
+ if(!Mod_Alias_GetTagMatrix(r->model, r->frameblend, r->skeleton, e->state_current.tagindex - 1, &blendmatrix)) // i.e. no error
{
// concat the tag matrices onto the entity matrix
- Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix);
+ Matrix4x4_Concat(&tempmatrix, &r->matrix, &blendmatrix);
// use the constructed tag matrix
matrix = &tempmatrix;
}
{
if (e->render.effects & EF_BRIGHTFIELD)
{
- if (gamemode == GAME_NEXUIZ)
+ if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
trailtype = EFFECT_TR_NEXUIZPLASMA;
else
CL_EntityParticles(e);
return;
// if the tag entity is inactive, skip it
if (!cl.entities[e->state_current.tagentity].state_current.active)
- return;
+ {
+ if(!cl.csqc_server2csqcentitynumber[e->state_current.tagentity])
+ return;
+ if(!cl.csqcrenderentities[cl.csqc_server2csqcentitynumber[e->state_current.tagentity]].entitynumber)
+ return;
+ // if we get here, it's properly csqc networked and attached
+ }
}
// create entity dlights associated with this entity
{
if (e->render.effects & EF_BRIGHTFIELD)
{
- if (gamemode == GAME_NEXUIZ)
+ if (gamemode == GAME_NEXUIZ || gamemode == GAME_XONOTIC)
trailtype = EFFECT_TR_NEXUIZPLASMA;
}
if (e->render.effects & EF_DIMLIGHT)
trace_t trace;
matrix4x4_t tempmatrix;
Matrix4x4_Transform(&e->render.matrix, muzzleflashorigin, v2);
- trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false);
+ trace = CL_TraceLine(origin, v2, MOVE_NOMONSTERS, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, true, false, NULL, false, false);
Matrix4x4_Normalize(&tempmatrix, &e->render.matrix);
Matrix4x4_SetOrigin(&tempmatrix, trace.endpos[0], trace.endpos[1], trace.endpos[2]);
Matrix4x4_Scale(&tempmatrix, 150, 1);
r_refdef.scene.numlights = 0;
r_refdef.view.matrix = identitymatrix;
r_refdef.view.quality = 1;
-
+
cl.num_brushmodel_entities = 0;
if (cls.state == ca_connected && cls.signon == SIGNONS)
*/
void CL_Init (void)
{
+
cls.levelmempool = Mem_AllocPool("client (per-level memory)", 0, NULL);
cls.permanentmempool = Mem_AllocPool("client (long term memory)", 0, NULL);
r_refdef.scene.maxentities = MAX_EDICTS + 256 + 512;
r_refdef.scene.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * r_refdef.scene.maxentities);
- r_refdef.scene.maxtempentities = MAX_TEMPENTITIES; // FIXME: make this grow
+ // max temp entities
+ r_refdef.scene.maxtempentities = MAX_TEMPENTITIES;
r_refdef.scene.tempentities = (entity_render_t *)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t) * r_refdef.scene.maxtempentities);
CL_InitInput ();