22 #include "refresh/models.h"
54 static int entity_ctr;
55 ent->
id = ++entity_ctr;
61 ent->prev_frame = state->frame;
65 if (state->event == EV_PLAYER_TELEPORT ||
66 state->event == EV_OTHER_TELEPORT ||
67 (state->renderfx & (RF_FRAMELERP | RF_BEAM))) {
75 VectorCopy(state->old_origin, ent->
prev.origin);
82 int event = state->event;
86 if (state->event != ent->
current.event)
94 if (state->modelindex != ent->
current.modelindex
95 || state->modelindex2 != ent->
current.modelindex2
96 || state->modelindex3 != ent->
current.modelindex3
97 || state->modelindex4 != ent->
current.modelindex4
98 || event == EV_PLAYER_TELEPORT
99 || event == EV_OTHER_TELEPORT
110 ent->prev_frame = state->frame;
119 if (state->frame != ent->
current.frame) {
120 ent->prev_frame = ent->
current.frame;
122 Com_DDPrintf(
"[%d] anim start %d: %d --> %d [%d]\n",
123 ent->anim_start, state->number,
124 ent->prev_frame, state->frame,
163 if (state->solid != PACKED_BSP) {
166 MSG_UnpackSolid32(state->solid, ent->
mins, ent->
maxs);
168 MSG_UnpackSolid16(state->solid, ent->
mins, ent->
maxs);
175 VectorScale(
cl.
frame.
ps.pmove.origin, 0.125f, origin_v);
213 case EV_ITEM_RESPAWN:
217 case EV_PLAYER_TELEPORT:
244 cl.keytime =
cl.keyservertime = 0;
252 cl.oldkeyframe.valid = qfalse;
253 cl.oldkeyframe.ps =
cl.keyframe.ps;
269 if (
cl.
frame.
ps.pmove.pm_type < PM_DEAD &&
296 player_state_t *ps, *ops;
305 if (!oldframe->
valid)
308 oldnum = frame->
number - framediv;
309 if (oldframe->
number != oldnum)
313 if (abs(ops->pmove.origin[0] - ps->pmove.origin[0]) > 256 * 8 ||
314 abs(ops->pmove.origin[1] - ps->pmove.origin[1]) > 256 * 8 ||
315 abs(ops->pmove.origin[2] - ps->pmove.origin[2]) > 256 * 8) {
324 ent->event_frame > oldnum &&
325 ent->event_frame <= frame->
number &&
327 (ent->
current.event == EV_PLAYER_TELEPORT
328 || ent->
current.event == EV_OTHER_TELEPORT)) {
333 if ((ops->pmove.pm_flags ^ ps->pmove.pm_flags) & PMF_TELEPORT_BIT)
361 entity_state_t *state;
374 cl.keyservertime = (framenum /
cl.framediv) * BASE_FRAMETIME;
409 VectorClear(
cl.
frame.
ps.pmove.delta_angles);
430 void CL_CheckEntityPresent(
int entnum,
const char *what)
445 "SERVER BUG: %s on entity %d last seen %d frames ago\n",
449 "SERVER BUG: %s on entity %d never seen before\n",
466 #define RESERVED_ENTITIY_GUN 1
467 #define RESERVED_ENTITIY_SHADERBALLS 2
468 #define RESERVED_ENTITIY_COUNT 3
475 if (!strcmp(
fs_game->string,
"rogue")) {
478 if (renderfx & RF_SHELL_HALF_DAM) {
480 if (renderfx & (RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE))
481 renderfx &= ~RF_SHELL_HALF_DAM;
484 if (renderfx & RF_SHELL_DOUBLE) {
486 if (renderfx & (RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_GREEN))
487 renderfx &= ~RF_SHELL_DOUBLE;
489 if (renderfx & RF_SHELL_RED)
490 renderfx |= RF_SHELL_BLUE;
492 else if (renderfx & RF_SHELL_BLUE) {
494 if (renderfx & RF_SHELL_GREEN)
495 renderfx &= ~RF_SHELL_BLUE;
497 renderfx |= RF_SHELL_GREEN;
521 unsigned int effects, renderfx;
524 autorotate = anglemod(
cl.
time * 0.1f);
527 autoanim = 2 *
cl.
time / 1000;
529 memset(&ent, 0,
sizeof(ent));
538 effects = s1->effects;
539 renderfx = s1->renderfx;
542 if (effects & EF_ANIM01)
543 ent.frame = autoanim & 1;
544 else if (effects & EF_ANIM23)
545 ent.frame = 2 + (autoanim & 1);
546 else if (effects & EF_ANIM_ALL)
547 ent.frame = autoanim;
548 else if (effects & EF_ANIM_ALLFAST)
549 ent.frame =
cl.
time / 100;
551 ent.frame = s1->frame;
554 if (effects & EF_PENT) {
556 effects |= EF_COLOR_SHELL;
557 renderfx |= RF_SHELL_RED;
560 if (effects & EF_QUAD) {
562 effects |= EF_COLOR_SHELL;
563 renderfx |= RF_SHELL_BLUE;
566 if (effects & EF_DOUBLE) {
567 effects &= ~EF_DOUBLE;
568 effects |= EF_COLOR_SHELL;
569 renderfx |= RF_SHELL_DOUBLE;
572 if (effects & EF_HALF_DAMAGE) {
573 effects &= ~EF_HALF_DAMAGE;
574 effects |= EF_COLOR_SHELL;
575 renderfx |= RF_SHELL_HALF_DAM;
580 renderfx &= ~RF_GLOW;
582 ent.oldframe = cent->
prev.frame;
585 if (renderfx & RF_FRAMELERP) {
588 VectorCopy(cent->
current.origin, ent.origin);
589 VectorCopy(cent->
current.old_origin, ent.oldorigin);
590 }
else if (renderfx & RF_BEAM) {
592 LerpVector(cent->
prev.origin, cent->
current.origin,
594 LerpVector(cent->
prev.old_origin, cent->
current.old_origin,
603 LerpVector(cent->
prev.origin, cent->
current.origin,
605 VectorCopy(ent.origin, ent.oldorigin);
610 if (cent->prev_frame != s1->frame) {
611 int delta =
cl.
time - cent->anim_start;
614 if (delta > BASE_FRAMETIME) {
615 Com_DDPrintf(
"[%d] anim end %d: %d --> %d\n",
617 cent->prev_frame, s1->frame);
618 cent->prev_frame = s1->frame;
620 }
else if (delta > 0) {
621 frac = delta * BASE_1_FRAMETIME;
622 Com_DDPrintf(
"[%d] anim run %d: %d --> %d [%f]\n",
624 cent->prev_frame, s1->frame,
630 ent.oldframe = cent->prev_frame;
631 ent.backlerp = 1.0 - frac;
636 if ((effects & EF_GIB) && !
cl_gibs->integer) {
643 if (renderfx & RF_BEAM) {
646 ent.skinnum = (s1->skinnum >> ((rand() % 4) * 8)) & 0xff;
650 if (s1->modelindex == 255) {
655 ent.model = ci->
model;
656 if (!ent.skin || !ent.model) {
661 if (renderfx & RF_USE_DISGUISE) {
662 char buffer[MAX_QPATH];
665 ent.skin = R_RegisterSkin(buffer);
668 ent.skinnum = s1->skinnum;
672 renderfx |= RF_NOSHADOW;
677 if ((renderfx & RF_TRANSLUCENT) && !(renderfx & RF_BEAM))
681 if ((effects & EF_COLOR_SHELL))
684 ent.flags = renderfx;
687 if (effects & EF_ROTATE) {
689 ent.angles[1] = autorotate;
691 }
else if (effects & EF_SPINNINGLIGHTS) {
696 ent.angles[1] = anglemod(
cl.
time / 2) + s1->angles[1];
700 VectorMA(ent.origin, 64,
forward, start);
705 LerpAngles(cent->
prev.angles, cent->
current.angles,
709 if (s1->modelindex == 255 &&
cl_rollhack->integer) {
710 ent.angles[ROLL] = -ent.angles[ROLL];
714 int base_entity_flags = 0;
717 if (effects & EF_FLAG1)
719 else if (effects & EF_FLAG2)
721 else if (effects & EF_TAGTRAIL)
723 else if (effects & EF_TRACKERTRAIL)
724 V_AddLight(ent.origin, 225, -1.0, -1.0, -1.0);
729 base_entity_flags |= RF_VIEWERMODEL;
738 vec3_t angles = { 0.f, ent.angles[1], 0.f };
742 float offset = -15.f;
743 VectorMA(ent.origin, offset,
forward, ent.origin);
744 VectorMA(ent.oldorigin, offset,
forward, ent.oldorigin);
748 if (!s1->modelindex) {
752 if (effects & EF_BFG) {
753 ent.flags |= RF_TRANSLUCENT;
757 if (effects & EF_PLASMA) {
758 ent.flags |= RF_TRANSLUCENT;
762 if (effects & EF_SPHERETRANS) {
763 ent.flags |= RF_TRANSLUCENT;
764 if (effects & EF_TRACKERTRAIL)
770 ent.flags |= base_entity_flags;
773 if ((effects & EF_COLOR_SHELL) &&
vid_rtx->integer) {
775 ent.flags |= renderfx;
783 if (ent.model && !(ent.model & 0x80000000) &&
786 if (model->model_class == MCLASS_FLARE)
788 float phase = (float)
cl.
time * 0.03f + (
float)ent.id;
789 float anim = sinf(phase);
791 float offset = anim * 1.5f + 5.f;
792 float brightness = anim * 0.2f + 0.8f;
795 VectorCopy(ent.origin,
origin);
798 V_AddLightEx(
origin, 500.f, 1.6f * brightness, 1.0f * brightness, 0.2f * brightness, 5.f);
803 if ((effects & EF_COLOR_SHELL) && !
vid_rtx->integer) {
805 ent.flags = renderfx | RF_TRANSLUCENT | base_entity_flags;
812 ent.flags = base_entity_flags;
816 if (s1->modelindex2) {
817 if (s1->modelindex2 == 255) {
820 i = (s1->skinnum >> 8);
836 ent.flags = RF_TRANSLUCENT;
839 if ((effects & EF_COLOR_SHELL) &&
vid_rtx->integer) {
840 ent.flags |= renderfx;
846 ent.flags = base_entity_flags;
850 if (s1->modelindex3) {
855 if (s1->modelindex4) {
860 if (effects & EF_POWERSCREEN) {
864 ent.flags |= (RF_TRANSLUCENT | RF_SHELL_GREEN);
870 if (effects & ~EF_ROTATE) {
871 if (effects & EF_ROCKET) {
875 V_AddLight(ent.origin, 200, 0.6f, 0.4f, 0.12f);
876 }
else if (effects & EF_BLASTER) {
877 if (effects & EF_TRACKER) {
879 V_AddLight(ent.origin, 200, 0.1f, 0.4f, 0.12f);
882 V_AddLight(ent.origin, 200, 0.6f, 0.4f, 0.12f);
884 }
else if (effects & EF_HYPERBLASTER) {
885 if (effects & EF_TRACKER)
886 V_AddLight(ent.origin, 200, 0.1f, 0.4f, 0.12f);
888 V_AddLight(ent.origin, 200, 0.6f, 0.4f, 0.12f);
889 }
else if (effects & EF_GIB) {
891 }
else if (effects & EF_GRENADE) {
895 }
else if (effects & EF_FLIES) {
897 }
else if (effects & EF_BFG) {
898 if (effects & EF_ANIM_ALLFAST) {
903 static const int bfg_lightramp[6] = {300, 400, 600, 300, 150, 75};
905 i = s1->frame; clamp(i, 0, 5);
906 i = bfg_lightramp[i];
909 const vec3_t nvgreen = { 0.2716f, 0.5795f, 0.04615f };
910 V_AddLightEx(ent.origin, i, nvgreen[0], nvgreen[1], nvgreen[2], 20.f);
911 }
else if (effects & EF_TRAP) {
915 i = (rand() % 100) + 100;
918 }
else if (effects & EF_FLAG1) {
921 }
else if (effects & EF_FLAG2) {
924 }
else if (effects & EF_TAGTRAIL) {
927 }
else if (effects & EF_TRACKERTRAIL) {
928 if (effects & EF_TRACKER) {
937 V_AddLight(ent.origin, 155, -1.0, -1.0, -1.0);
939 }
else if (effects & EF_TRACKER) {
942 }
else if (effects & EF_GREENGIB) {
944 }
else if (effects & EF_IONRIPPER) {
947 }
else if (effects & EF_BLUEHYPERBLASTER) {
949 }
else if (effects & EF_PLASMA) {
950 if (effects & EF_ANIM_ALLFAST) {
977 if (ent->
current.effects & EF_PENT)
978 flags |= RF_SHELL_RED;
979 if (ent->
current.effects & EF_QUAD)
980 flags |= RF_SHELL_BLUE;
981 if (ent->
current.effects & EF_DOUBLE)
982 flags |= RF_SHELL_DOUBLE;
983 if (ent->
current.effects & EF_HALF_DAMAGE)
984 flags |= RF_SHELL_HALF_DAM;
996 player_state_t *ps, *ops;
1013 memset(&gun, 0,
sizeof(gun));
1027 for (i = 0; i < 3; i++) {
1028 gun.origin[i] =
cl.
refdef.vieworg[i] + ops->gunoffset[i] +
1030 gun.angles[i] =
cl.
refdef.viewangles[i] + LerpAngle(ops->gunangles[i],
1036 vec_t ofs = (90 - ps->fov) * 0.2f;
1037 VectorMA(gun.origin, ofs,
cl.
v_forward, gun.origin);
1042 vec3_t view_dir, right_dir, up_dir;
1043 vec3_t gun_real_pos, gun_tip;
1044 const float gun_length = 28.f;
1045 const float gun_right = 10.f;
1046 const float gun_up = -5.f;
1048 static vec3_t mins = { -4, -4, -4 }, maxs = { 4, 4, 4 };
1051 VectorMA(gun.origin, gun_right, right_dir, gun_real_pos);
1052 VectorMA(gun_real_pos, gun_up, up_dir, gun_real_pos);
1053 VectorMA(gun_real_pos, gun_length, view_dir, gun_tip);
1055 CM_BoxTrace(&trace, gun_real_pos, gun_tip, mins, maxs,
cl.
bsp->nodes, MASK_SOLID);
1057 if (trace.fraction != 1.0f)
1059 VectorMA(trace.endpos, -gun_length, view_dir, gun.origin);
1060 VectorMA(gun.origin, -gun_right, right_dir, gun.origin);
1061 VectorMA(gun.origin, -gun_up, up_dir, gun.origin);
1065 VectorCopy(gun.origin, gun.oldorigin);
1071 gun.frame = ps->gunframe;
1072 if (gun.frame == 0) {
1075 gun.oldframe = ops->gunframe;
1080 gun.flags = RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
1082 gun.flags |= RF_LEFTHAND;
1087 gun.flags |= RF_TRANSLUCENT;
1095 gun.flags |= shell_flags;
1099 if (model && strstr(model->name,
"v_flareg"))
1105 if (shell_flags && !
vid_rtx->integer) {
1107 gun.flags |= shell_flags | RF_TRANSLUCENT;
1114 player_state_t *ps, *ops;
1125 LerpAngles(ops->kick_angles, ps->kick_angles, lerp, kickangles);
1143 float fscale, rscale;
1144 float dist, angle,
range;
1146 static vec3_t mins = { -4, -4, -4 }, maxs = { 4, 4, 4 };
1149 if (
cl.
frame.
ps.stats[STAT_HEALTH] <= 0) {
1158 cl.
refdef.viewangles[PITCH] *= 0.5f;
1163 fscale = cos(angle);
1164 rscale = sin(angle);
1169 mins, maxs,
cl.
bsp->nodes, MASK_SOLID);
1170 if (trace.fraction != 1.0f) {
1171 VectorCopy(trace.endpos,
cl.
refdef.vieworg);
1174 VectorSubtract(focus,
cl.
refdef.vieworg, focus);
1175 dist = sqrt(focus[0] * focus[0] + focus[1] * focus[1]);
1177 cl.
refdef.viewangles[PITCH] = -180 / M_PI * atan2(focus[2], dist);
1207 #if USE_SMOOTH_DELTA_ANGLES
1208 static inline float LerpShort(
int a2,
int a1,
float frac)
1210 if (a1 - a2 > 32768)
1212 if (a2 - a1 > 32768)
1214 return a2 + frac * (a1 - a2);
1228 if (
info_uf->integer & UF_LOCALFOV)
1231 if (!(
info_uf->integer & UF_PLAYERFOV)) {
1239 return ofov + lerp * (nfov - ofov);
1253 player_state_t *ps, *ops;
1284 cl.
refdef.vieworg[0] = ops->pmove.origin[0] * 0.125f +
1285 lerp * (ps->pmove.origin[0] - ops->pmove.origin[0]) * 0.125f;
1286 cl.
refdef.vieworg[1] = ops->pmove.origin[1] * 0.125f +
1287 lerp * (ps->pmove.origin[1] - ops->pmove.origin[1]) * 0.125f;
1288 cl.
refdef.vieworg[2] = ops->pmove.origin[2] * 0.125f +
1289 lerp * (ps->pmove.origin[2] - ops->pmove.origin[2]) * 0.125f;
1294 LerpAngles(ops->viewangles, ps->viewangles, lerp,
cl.
refdef.viewangles);
1295 }
else if (ps->pmove.pm_type < PM_DEAD) {
1298 }
else if (ops->pmove.pm_type < PM_DEAD &&
cls.
serverProtocol > PROTOCOL_VERSION_DEFAULT) {
1304 LerpAngles(ops->viewangles, ps->viewangles, lerp,
cl.
refdef.viewangles);
1307 #if USE_SMOOTH_DELTA_ANGLES
1308 cl.delta_angles[0] = LerpShort(ops->pmove.delta_angles[0], ps->pmove.delta_angles[0], lerp);
1309 cl.delta_angles[1] = LerpShort(ops->pmove.delta_angles[1], ps->pmove.delta_angles[1], lerp);
1310 cl.delta_angles[2] = LerpShort(ops->pmove.delta_angles[2], ps->pmove.delta_angles[2], lerp);
1314 Vector4Copy(ps->blend,
cl.
refdef.blend);
1317 ps = &
cl.keyframe.ps;
1318 ops = &
cl.oldkeyframe.ps;
1320 lerp =
cl.keylerpfrac;
1327 LerpVector(ops->viewoffset, ps->viewoffset, lerp, viewoffset);
1348 #if CL_RTX_SHADERBALLS
1349 extern qhandle_t cl_dev_shaderballs;
1350 vec3_t cl_dev_shaderballs_pos = { 0 };
1352 void CL_AddShaderBalls(
void)
1354 if (cl_dev_shaderballs != -1 &&
vid_rtx->integer)
1358 if (model != NULL && model->meshes != NULL)
1360 entity_t entity = { 0 };
1361 entity.model = cl_dev_shaderballs;
1362 VectorCopy(cl_dev_shaderballs_pos, entity.origin);
1389 CL_AddLightStyles();
1391 #if CL_RTX_SHADERBALLS
1392 CL_AddShaderBalls();
1410 if (entnum < 0 || entnum >= MAX_EDICTS) {
1411 Com_Error(ERR_DROP,
"%s: bad entnum: %d", __func__, entnum);
1426 if (ent->
current.solid == PACKED_BSP) {
1429 VectorAvg(cm->mins, cm->maxs, mid);
1430 VectorAdd(org, mid, org);