[qw] Use efrags for carried flags

This sorts out the unwanted use of R_EnqueueEntity, which will help with
removing another global (r_ent_queue), which is necessary for threaded
multi-pass rendering (ie, shadows).
This commit is contained in:
Bill Currie 2021-07-22 19:35:12 +09:00
parent e799a7ae45
commit 30dc82f290
2 changed files with 66 additions and 33 deletions

View file

@ -50,6 +50,8 @@ typedef struct player_info_s {
struct info_key_s *skinname; struct info_key_s *skinname;
struct skin_s *skin; struct skin_s *skin;
struct entity_s *flag_ent;
int spectator; int spectator;
int stats[MAX_CL_STATS]; // health, etc int stats[MAX_CL_STATS]; // health, etc
int prevcount; int prevcount;

View file

@ -278,16 +278,8 @@ CL_LinkPacketEntities (void)
} }
} }
/*
CL_AddFlagModels
Called when the CTF flags are set. Flags are effectively temp entities.
NOTE: this must be called /after/ the entity has been transformed as it
uses the entity's transform matrix to get the frame vectors
*/
static void static void
CL_AddFlagModels (entity_t *ent, int team, int key) CL_UpdateFlagModels (entity_t *ent, int key)
{ {
static float flag_offsets[] = { static float flag_offsets[] = {
16.0, 22.0, 26.0, 25.0, 24.0, 18.0, // 29-34 axpain 16.0, 22.0, 26.0, 25.0, 24.0, 18.0, // 29-34 axpain
@ -298,12 +290,10 @@ CL_AddFlagModels (entity_t *ent, int team, int key)
fent = &cl_flag_ents[key]; fent = &cl_flag_ents[key];
if (cl_flagindex == -1) { if (!fent->active) {
fent->active = 0;
return; return;
} }
fent->active = 1;
f = 14.0; f = 14.0;
if (ent->animation.frame >= 29 && ent->animation.frame <= 40) { if (ent->animation.frame >= 29 && ent->animation.frame <= 40) {
f = flag_offsets[ent->animation.frame - 29]; f = flag_offsets[ent->animation.frame - 29];
@ -315,23 +305,51 @@ CL_AddFlagModels (entity_t *ent, int team, int key)
} }
} }
vec4f_t position = { 22, -f, -16, 1}; vec4f_t scale = { 1, 1, 1, 1 };
// -45 degree roll (x is forward)
vec4f_t rotation = { -0.382683432, 0, 0, 0.923879533 };
vec4f_t position = { -f, -22, 0, 1};
Transform_SetLocalPosition (fent->transform, position);
Transform_SetLocalTransform (fent->transform, scale, rotation, position);
position = Transform_GetWorldPosition (fent->transform);
position[3] -= 16;
Transform_SetWorldPosition (fent->transform, position);
}
static entity_t *
CL_AddFlagModels (entity_t *ent, int team, int key)
{
entity_t *fent;
fent = &cl_flag_ents[key];
if (cl_flagindex == -1) {
fent->active = 0;
return 0;
}
fent->active = 1;
if (!Transform_GetParent (fent->transform)) { if (!Transform_GetParent (fent->transform)) {
vec4f_t scale = { 1, 1, 1, 1 };
// -45 degree roll (x is forward)
vec4f_t rotation = { -0.382683432, 0, 0, 0.923879533 };
Transform_SetParent (fent->transform, ent->transform); Transform_SetParent (fent->transform, ent->transform);
Transform_SetLocalTransform (fent->transform, scale, rotation,
position);
} else {
Transform_SetLocalPosition (fent->transform, position);
} }
CL_UpdateFlagModels (ent, key);
fent->renderer.model = cl.model_precache[cl_flagindex]; fent->renderer.model = cl.model_precache[cl_flagindex];
fent->renderer.skinnum = team; fent->renderer.skinnum = team;
r_funcs->R_EnqueueEntity (fent);//FIXME should use efrag (needs smarter return fent;
// handling //in the player code) }
static void
CL_RemoveFlagModels (int key)
{
entity_t *fent;
fent = &cl_flag_ents[key];
fent->active = 0;
Transform_SetParent (fent->transform, 0);
} }
/* /*
@ -347,7 +365,7 @@ CL_LinkPlayers (void)
int msec, oldphysent, j; int msec, oldphysent, j;
entity_t *ent; entity_t *ent;
frame_t *frame; frame_t *frame;
player_info_t *info; player_info_t *player;
player_state_t exact; player_state_t exact;
player_state_t *state; player_state_t *state;
qboolean clientplayer; qboolean clientplayer;
@ -360,15 +378,18 @@ CL_LinkPlayers (void)
frame = &cl.frames[cl.parsecount & UPDATE_MASK]; frame = &cl.frames[cl.parsecount & UPDATE_MASK];
for (j = 0, info = cl.players, state = frame->playerstate; j < MAX_CLIENTS; for (j = 0, player = cl.players, state = frame->playerstate;
j++, info++, state++) { j < MAX_CLIENTS; j++, player++, state++) {
ent = &cl_player_ents[j]; ent = &cl_player_ents[j];
if (ent->visibility.efrag) if (ent->visibility.efrag)
r_funcs->R_RemoveEfrags (ent); r_funcs->R_RemoveEfrags (ent);
if (player->flag_ent && player->flag_ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (player->flag_ent);
}
if (state->messagenum != cl.parsecount) if (state->messagenum != cl.parsecount)
continue; // not present this frame continue; // not present this frame
if (!info->name || !info->name->value[0]) if (!player->name || !player->name->value[0])
continue; continue;
// spawn light flashes, even ones coming from invisible objects // spawn light flashes, even ones coming from invisible objects
@ -380,7 +401,7 @@ CL_LinkPlayers (void)
org = state->pls.es.origin; org = state->pls.es.origin;
clientplayer = false; clientplayer = false;
} }
if (info->chat && info->chat->value[0] != '0') { if (player->chat && player->chat->value[0] != '0') {
dlight_t *dl = r_funcs->R_AllocDlight (j + 1); dlight_t *dl = r_funcs->R_AllocDlight (j + 1);
VectorCopy (org, dl->origin); VectorCopy (org, dl->origin);
dl->radius = 100; dl->radius = 100;
@ -447,7 +468,7 @@ CL_LinkPlayers (void)
if (state->pls.es.modelindex == cl_playerindex) { //XXX if (state->pls.es.modelindex == cl_playerindex) { //XXX
// use custom skin // use custom skin
ent->renderer.skin = info->skin; ent->renderer.skin = player->skin;
ent->renderer.min_light = min (cl.fbskins, cl_fb_players->value); ent->renderer.min_light = min (cl.fbskins, cl_fb_players->value);
@ -459,13 +480,23 @@ CL_LinkPlayers (void)
ent->renderer.skin = 0; ent->renderer.skin = 0;
} }
int flag_state = state->pls.es.effects & (EF_FLAG1 | EF_FLAG2);
if (player->flag_ent && !flag_state) {
CL_RemoveFlagModels (j);
player->flag_ent = 0;
} else if (!player->flag_ent && flag_state) {
if (flag_state & EF_FLAG1)
player->flag_ent = CL_AddFlagModels (ent, 0, j);
else if (flag_state & EF_FLAG2)
player->flag_ent = CL_AddFlagModels (ent, 1, j);
}
// stuff entity in map // stuff entity in map
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent); r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
if (player->flag_ent) {
if (state->pls.es.effects & EF_FLAG1) CL_UpdateFlagModels (ent, j);
CL_AddFlagModels (ent, 0, j); r_funcs->R_AddEfrags (&cl.worldmodel->brush, player->flag_ent);
else if (state->pls.es.effects & EF_FLAG2) }
CL_AddFlagModels (ent, 1, j);
} }
} }