X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=cl_main.c;h=d07b186a66563abaec53368c1e03fe2bc8267b6e;hb=4961d09f5d00c8e40cc16e3bfb0db0de25d96abd;hp=f41d1a1b5782da5c3ec40216547ebc6271ae3e40;hpb=e0101fa69476bb99506cc168f0a58e39608b33df;p=xonotic%2Fdarkplaces.git diff --git a/cl_main.c b/cl_main.c index f41d1a1b..d07b186a 100644 --- a/cl_main.c +++ b/cl_main.c @@ -52,7 +52,7 @@ cvar_t m_side = {CVAR_SAVE, "m_side","0.8","mouse side speed multiplier"}; cvar_t freelook = {CVAR_SAVE, "freelook", "1","mouse controls pitch instead of forward/back"}; cvar_t cl_autodemo = {CVAR_SAVE, "cl_autodemo", "0", "records every game played, using the date/time and map name to name the demo file" }; -cvar_t cl_autodemo_nameformat = {CVAR_SAVE, "cl_autodemo_nameformat", "%Y-%m-%d_%H-%M", "The format of the cl_autodemo filename, followed by the map name" }; +cvar_t cl_autodemo_nameformat = {CVAR_SAVE, "cl_autodemo_nameformat", "autodemos/%Y-%m-%d_%H-%M", "The format of the cl_autodemo filename, followed by the map name" }; cvar_t r_draweffects = {0, "r_draweffects", "1","renders temporary sprite effects"}; @@ -67,7 +67,7 @@ cvar_t cl_stainmaps_clearonload = {CVAR_SAVE, "cl_stainmaps_clearonload", "1","c cvar_t cl_beams_polygons = {CVAR_SAVE, "cl_beams_polygons", "1","use beam polygons instead of models"}; cvar_t cl_beams_quakepositionhack = {CVAR_SAVE, "cl_beams_quakepositionhack", "1", "makes your lightning gun appear to fire from your waist (as in Quake and QuakeWorld)"}; -cvar_t cl_beams_instantaimhack = {CVAR_SAVE, "cl_beams_instantaimhack", "1", "makes your lightning gun aiming update instantly"}; +cvar_t cl_beams_instantaimhack = {CVAR_SAVE, "cl_beams_instantaimhack", "0", "makes your lightning gun aiming update instantly"}; cvar_t cl_beams_lightatend = {CVAR_SAVE, "cl_beams_lightatend", "0", "make a light at the end of the beam"}; cvar_t cl_noplayershadow = {CVAR_SAVE, "cl_noplayershadow", "0","hide player shadow"}; @@ -110,6 +110,9 @@ void CL_ClearState(void) // reset the view zoom interpolation cl.mviewzoom[0] = cl.mviewzoom[1] = 1; + // set up the float version of the stats array for easier access to float stats + cl.statsf = (float *)cl.stats; + cl.num_entities = 0; cl.num_static_entities = 0; cl.num_temp_entities = 0; @@ -338,9 +341,9 @@ void CL_Disconnect(void) Con_DPrint("Sending clc_disconnect\n"); MSG_WriteByte(&buf, clc_disconnect); } - NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol); - NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol); - NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol); + NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000); + NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000); + NetConn_SendUnreliableMessage(cls.netcon, &buf, cls.protocol, 10000); NetConn_Close(cls.netcon); cls.netcon = NULL; } @@ -436,6 +439,24 @@ static void CL_PrintEntities_f(void) } } +/* +=============== +CL_ModelIndexList_f + +List all models in the client modelindex +=============== +*/ +static void CL_ModelIndexList_f(void) +{ + int nModelIndexCnt = 1; + + while(cl.model_precache[nModelIndexCnt] && nModelIndexCnt != MAX_MODELS) + { // Valid Model + Con_Printf("%i : %s\n", nModelIndexCnt, cl.model_precache[nModelIndexCnt]->name); + nModelIndexCnt++; + } +} + //static const vec3_t nomodelmins = {-16, -16, -16}; //static const vec3_t nomodelmaxs = {16, 16, 16}; void CL_UpdateRenderEntity(entity_render_t *ent) @@ -503,7 +524,7 @@ static float CL_LerpPoint(void) { float f; - if (cl_nettimesyncmode.integer == 3) + if (cl_nettimesyncboundmode.integer == 1) cl.time = bound(cl.mtime[1], cl.time, cl.mtime[0]); // LordHavoc: lerp in listen games as the server is being capped below the client (usually) @@ -799,6 +820,7 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags = e->state_current.flags; e->render.effects = e->state_current.effects; VectorScale(e->state_current.colormod, (1.0f / 32.0f), e->render.colormod); + e->render.entitynumber = e - cl.entities; if (e->state_current.flags & RENDER_COLORMAPPED) { int cb; @@ -892,11 +914,13 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat // also don't use the predicted location if fixangle was set on both of // the most recent server messages, as that cause means you are spectating // someone or watching a cutscene of some sort + if (cl_nolerp.integer || cls.timedemo) + interpolate = false; if (e == cl.entities + cl.playerentity && cl.movement_predicted && (!cl.fixangle[1] || !cl.fixangle[0])) { lerp = (cl.time - cl.movement_time[2]) / (cl.movement_time[0] - cl.movement_time[1]); lerp = bound(0, lerp, 1); - if (!interpolate || cl_nolerp.integer || cl.fixangle[0]) + if (!interpolate) lerp = 1; VectorLerp(cl.movement_oldorigin, lerp, cl.movement_origin, origin); VectorSet(angles, 0, cl.viewangles[1], 0); @@ -924,17 +948,11 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.model = cl.model_precache[e->state_current.modelindex]; if (e->render.model) { + // models can set flags such as EF_ROCKET + e->render.effects |= e->render.model->effects; // if model is alias or this is a tenebrae-like dlight, reverse pitch direction if (e->render.model->type == mod_alias) angles[0] = -angles[0]; - if ((e->render.model->flags & EF_ROTATE) && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL))) - { - angles[1] = ANGLEMOD(100*cl.time); - if (cl_itembobheight.value) - origin[2] += (cos(cl.time * cl_itembobspeed.value * (2.0 * M_PI)) + 1.0) * 0.5 * cl_itembobheight.value; - } - // transfer certain model flags to effects - e->render.effects |= e->render.model->flags2 & (EF_FULLBRIGHT | EF_ADDITIVE); if ((e->render.effects & EF_SELECTABLE) && cl.cmd.cursor_entitynumber == e->state_current.number) VectorScale(e->render.colormod, 2, e->render.colormod); } @@ -942,6 +960,13 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat else if (e->state_current.lightpflags & PFLAGS_FULLDYNAMIC) angles[0] = -angles[0]; + if ((e->render.effects & EF_ROTATE) && !(e->render.flags & RENDER_VIEWMODEL)) + { + angles[1] = ANGLEMOD(100*cl.time); + if (cl_itembobheight.value) + origin[2] += (cos(cl.time * cl_itembobspeed.value * (2.0 * M_PI)) + 1.0) * 0.5 * cl_itembobheight.value; + } + // animation lerp if (e->render.frame2 == e->state_current.frame) { @@ -1001,6 +1026,8 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat && !(e->render.flags & RENDER_VIEWMODEL) && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer))) e->render.flags |= RENDER_SHADOW; + if (e->render.flags & RENDER_VIEWMODEL) + e->render.flags |= RENDER_NOSELFSHADOW; } // creates light and trails from an entity @@ -1024,7 +1051,7 @@ void CL_UpdateNetworkEntityTrail(entity_t *e) // entity is in the world... trailtype = EFFECT_NONE; // LordHavoc: if the entity has no effects, don't check each - if (e->render.effects & (EF_BRIGHTFIELD | EF_FLAME | EF_STARDUST | EF_FLAG1QW | EF_FLAG2QW)) + if (e->render.effects & (EF_BRIGHTFIELD | EF_FLAME | EF_STARDUST)) { if (e->render.effects & EF_BRIGHTFIELD) { @@ -1037,40 +1064,41 @@ void CL_UpdateNetworkEntityTrail(entity_t *e) CL_ParticleTrail(EFFECT_EF_FLAME, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true); if (e->render.effects & EF_STARDUST) CL_ParticleTrail(EFFECT_EF_STARDUST, bound(0, cl.time - cl.oldtime, 0.1), origin, origin, vec3_origin, vec3_origin, NULL, 0, false, true); - if (e->render.effects & (EF_FLAG1QW | EF_FLAG2QW)) - { - // these are only set on player entities - CL_AddQWCTFFlagModel(e, (e->render.effects & EF_FLAG2QW) != 0); - } + } + if (e->render.internaleffects & (INTEF_FLAG1QW | INTEF_FLAG2QW)) + { + // these are only set on player entities + CL_AddQWCTFFlagModel(e, (e->render.internaleffects & INTEF_FLAG2QW) != 0); } // muzzleflash fades over time if (e->persistent.muzzleflash > 0) e->persistent.muzzleflash -= bound(0, cl.time - cl.oldtime, 0.1) * 20; - // LordHavoc: if the model has no flags, don't check each - if (e->render.model && e->render.model->flags && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL))) + // LordHavoc: if the entity has no effects, don't check each + if (e->render.model && e->render.effects && !(e->render.flags & RENDER_VIEWMODEL)) { - if (e->render.model->flags & EF_GIB) + if (e->render.effects & EF_GIB) trailtype = EFFECT_TR_BLOOD; - else if (e->render.model->flags & EF_ZOMGIB) + else if (e->render.effects & EF_ZOMGIB) trailtype = EFFECT_TR_SLIGHTBLOOD; - else if (e->render.model->flags & EF_TRACER) + else if (e->render.effects & EF_TRACER) trailtype = EFFECT_TR_WIZSPIKE; - else if (e->render.model->flags & EF_TRACER2) + else if (e->render.effects & EF_TRACER2) trailtype = EFFECT_TR_KNIGHTSPIKE; - else if (e->render.model->flags & EF_ROCKET) + else if (e->render.effects & EF_ROCKET) trailtype = EFFECT_TR_ROCKET; - else if (e->render.model->flags & EF_GRENADE) + else if (e->render.effects & EF_GRENADE) { // LordHavoc: e->render.alpha == -1 is for Nehahra dem compatibility (cigar smoke) trailtype = e->render.alpha == -1 ? EFFECT_TR_NEHAHRASMOKE : EFFECT_TR_GRENADE; } - else if (e->render.model->flags & EF_TRACER3) + else if (e->render.effects & EF_TRACER3) trailtype = EFFECT_TR_VORESPIKE; } // do trails if (e->render.flags & RENDER_GLOWTRAIL) trailtype = EFFECT_TR_GLOWTRAIL; - if (trailtype) + // check if a trail is allowed (it is not after a teleport for example) + if (trailtype && e->persistent.trail_allowed) { float len; vec3_t vel; @@ -1081,6 +1109,9 @@ void CL_UpdateNetworkEntityTrail(entity_t *e) VectorScale(vel, len, vel); CL_ParticleTrail(trailtype, 1, e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true); } + // now that the entity has survived one trail update it is allowed to + // leave a real trail on later frames + e->persistent.trail_allowed = true; VectorCopy(origin, e->persistent.trail_origin); } @@ -1119,7 +1150,7 @@ void CL_UpdateNetworkCollisionEntities(void) // start on the entity after the world cl.num_brushmodel_entities = 0; - for (i = 1;i < cl.num_entities;i++) + for (i = cl.maxclients + 1;i < cl.num_entities;i++) { if (cl.entities_active[i]) { @@ -1128,7 +1159,7 @@ void CL_UpdateNetworkCollisionEntities(void) { // do not interpolate the bmodels for this CL_UpdateNetworkEntity(ent, 32, false); - cl.brushmodel_entities[cl.num_brushmodel_entities++] = ent->state_current.number; + cl.brushmodel_entities[cl.num_brushmodel_entities++] = i; } } } @@ -1185,7 +1216,7 @@ void CL_UpdateViewModel(void) ent->state_current.modelindex = 0; } ent->state_current.alpha = cl.entities[cl.viewentity].state_current.alpha; - ent->state_current.effects = EF_NOSHADOW | (cl.entities[cl.viewentity].state_current.effects & (EF_ADDITIVE | EF_REFLECTIVE | EF_FULLBRIGHT | EF_NODEPTHTEST)); + ent->state_current.effects = EF_NOSHADOW | (cl.entities[cl.viewentity].state_current.effects & (EF_ADDITIVE | EF_FULLBRIGHT | EF_NODEPTHTEST)); // reset animation interpolation on weaponmodel if model changed if (ent->state_previous.modelindex != ent->state_current.modelindex) @@ -1208,12 +1239,7 @@ void CL_LinkNetworkEntity(entity_t *e) // skip inactive entities and world if (!e->state_current.active || e == cl.entities) return; - if (e->render.flags & RENDER_VIEWMODEL && !e->state_current.tagentity) - { - if (!r_drawviewmodel.integer || chase_active.integer || r_refdef.envmap) - return; - } - else + if (e->state_current.tagentity) { // if the tag entity is currently impossible, skip it if (e->state_current.tagentity >= cl.num_entities) @@ -1296,24 +1322,24 @@ void CL_LinkNetworkEntity(entity_t *e) R_RTLight_Update(&r_refdef.lights[r_refdef.numlights++], false, &tempmatrix, color, -1, NULL, true, 0, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); } // LordHavoc: if the model has no flags, don't check each - if (e->render.model && e->render.model->flags && (!e->state_current.tagentity && !(e->render.flags & RENDER_VIEWMODEL))) + if (e->render.model && e->render.effects && !(e->render.flags & RENDER_VIEWMODEL)) { - if (e->render.model->flags & EF_GIB) + if (e->render.effects & EF_GIB) trailtype = EFFECT_TR_BLOOD; - else if (e->render.model->flags & EF_ZOMGIB) + else if (e->render.effects & EF_ZOMGIB) trailtype = EFFECT_TR_SLIGHTBLOOD; - else if (e->render.model->flags & EF_TRACER) + else if (e->render.effects & EF_TRACER) trailtype = EFFECT_TR_WIZSPIKE; - else if (e->render.model->flags & EF_TRACER2) + else if (e->render.effects & EF_TRACER2) trailtype = EFFECT_TR_KNIGHTSPIKE; - else if (e->render.model->flags & EF_ROCKET) + else if (e->render.effects & EF_ROCKET) trailtype = EFFECT_TR_ROCKET; - else if (e->render.model->flags & EF_GRENADE) + else if (e->render.effects & EF_GRENADE) { // LordHavoc: e->render.alpha == -1 is for Nehahra dem compatibility (cigar smoke) trailtype = e->render.alpha == -1 ? EFFECT_TR_NEHAHRASMOKE : EFFECT_TR_GRENADE; } - else if (e->render.model->flags & EF_TRACER3) + else if (e->render.effects & EF_TRACER3) trailtype = EFFECT_TR_VORESPIKE; } // LordHavoc: customizable glow @@ -1357,6 +1383,10 @@ void CL_LinkNetworkEntity(entity_t *e) if (trailtype) CL_ParticleTrail(trailtype, 0, origin, origin, vec3_origin, vec3_origin, NULL, e->state_current.glowcolor, true, false); + // don't show viewmodels in certain situations + if (e->render.flags & RENDER_VIEWMODEL) + if (!r_drawviewmodel.integer || chase_active.integer || r_refdef.envmap) + return; // don't show entities with no modelindex (note: this still shows // entities which have a modelindex that resolved to a NULL model) if (e->render.model && !(e->render.effects & EF_NODRAW) && r_refdef.numentities < r_refdef.maxentities) @@ -1368,7 +1398,6 @@ void CL_LinkNetworkEntity(entity_t *e) void CL_RelinkWorld(void) { entity_t *ent = &cl.entities[0]; - cl.brushmodel_entities[cl.num_brushmodel_entities++] = 0; // FIXME: this should be done at load ent->render.matrix = identitymatrix; CL_UpdateRenderEntity(&ent->render); @@ -1679,17 +1708,13 @@ void CSQC_RelinkAllEntities (int drawmask) /* =============== -CL_ReadFromServer +CL_UpdateWorld -Read all incoming data from the server +Update client game world for a new frame =============== */ -int CL_ReadFromServer(void) +void CL_UpdateWorld(void) { - CL_ReadDemoMessage(); - CL_SendMove(); - - r_refdef.time = cl.time; r_refdef.extraupdate = !r_speeds.integer; r_refdef.numentities = 0; r_refdef.numlights = 0; @@ -1706,12 +1731,9 @@ int CL_ReadFromServer(void) V_DriftPitch(); V_FadeViewFlashs(); - if (cl.movement_predicted) - { - // if prediction is enabled we have to update all the collidable - // network entities before the prediction code can be run - CL_UpdateNetworkCollisionEntities(); - } + // if prediction is enabled we have to update all the collidable + // network entities before the prediction code can be run + CL_UpdateNetworkCollisionEntities(); // now update the player prediction CL_ClientMovement_Replay(); @@ -1735,13 +1757,9 @@ int CL_ReadFromServer(void) // move particles CL_MoveParticles(); R_MoveExplosions(); - - // update the r_refdef time again because cl.time may have changed in - // CL_LerpPoint() - r_refdef.time = cl.time; } - return 0; + r_refdef.time = cl.time; } // LordHavoc: pausedemo command @@ -1782,11 +1800,9 @@ For program optimization static void CL_TimeRefresh_f (void) { int i; - float timestart, timedelta, oldangles[3]; + float timestart, timedelta; r_refdef.extraupdate = false; - VectorCopy(cl.viewangles, oldangles); - VectorClear(cl.viewangles); timestart = Sys_DoubleTime(); for (i = 0;i < 128;i++) @@ -1796,7 +1812,6 @@ static void CL_TimeRefresh_f (void) } timedelta = Sys_DoubleTime() - timestart; - VectorCopy(oldangles, cl.viewangles); Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta); } @@ -2188,6 +2203,9 @@ void CL_Init (void) Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "watch a demo file"); Cmd_AddCommand ("timedemo", CL_TimeDemo_f, "play back a demo as fast as possible and save statistics to benchmark.log"); + // Support Client-side Model Index List + Cmd_AddCommand ("cl_modelindexlist", CL_ModelIndexList_f, "list all models in the client modelindex"); + Cvar_RegisterVariable (&cl_autodemo); Cvar_RegisterVariable (&cl_autodemo_nameformat);