[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 skin_s *skin;
struct entity_s *flag_ent;
int spectator;
int stats[MAX_CL_STATS]; // health, etc
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
CL_AddFlagModels (entity_t *ent, int team, int key)
CL_UpdateFlagModels (entity_t *ent, int key)
{
static float flag_offsets[] = {
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];
if (cl_flagindex == -1) {
fent->active = 0;
if (!fent->active) {
return;
}
fent->active = 1;
f = 14.0;
if (ent->animation.frame >= 29 && ent->animation.frame <= 40) {
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)) {
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_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.skinnum = team;
r_funcs->R_EnqueueEntity (fent);//FIXME should use efrag (needs smarter
// handling //in the player code)
return fent;
}
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;
entity_t *ent;
frame_t *frame;
player_info_t *info;
player_info_t *player;
player_state_t exact;
player_state_t *state;
qboolean clientplayer;
@ -360,15 +378,18 @@ CL_LinkPlayers (void)
frame = &cl.frames[cl.parsecount & UPDATE_MASK];
for (j = 0, info = cl.players, state = frame->playerstate; j < MAX_CLIENTS;
j++, info++, state++) {
for (j = 0, player = cl.players, state = frame->playerstate;
j < MAX_CLIENTS; j++, player++, state++) {
ent = &cl_player_ents[j];
if (ent->visibility.efrag)
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)
continue; // not present this frame
if (!info->name || !info->name->value[0])
if (!player->name || !player->name->value[0])
continue;
// spawn light flashes, even ones coming from invisible objects
@ -380,7 +401,7 @@ CL_LinkPlayers (void)
org = state->pls.es.origin;
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);
VectorCopy (org, dl->origin);
dl->radius = 100;
@ -447,7 +468,7 @@ CL_LinkPlayers (void)
if (state->pls.es.modelindex == cl_playerindex) { //XXX
// use custom skin
ent->renderer.skin = info->skin;
ent->renderer.skin = player->skin;
ent->renderer.min_light = min (cl.fbskins, cl_fb_players->value);
@ -459,13 +480,23 @@ CL_LinkPlayers (void)
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
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
if (state->pls.es.effects & EF_FLAG1)
CL_AddFlagModels (ent, 0, j);
else if (state->pls.es.effects & EF_FLAG2)
CL_AddFlagModels (ent, 1, j);
if (player->flag_ent) {
CL_UpdateFlagModels (ent, j);
r_funcs->R_AddEfrags (&cl.worldmodel->brush, player->flag_ent);
}
}
}