diff --git a/include/QF/render.h b/include/QF/render.h index 061df782b..601e9d9aa 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -69,33 +69,21 @@ extern lightstyle_t r_lightstyle[MAX_LIGHTSTYLES]; typedef struct entity_s { - qboolean forcelink; // model changed - struct entity_state_s *baseline; // to fill in defaults in updates - double msgtime; // time of last update - vec3_t origin; vec3_t old_origin; vec3_t angles; - vec3_t msg_origins[2]; // last two updates (0 is newest) - vec3_t msg_angles[2]; // last two updates (0 is newest) struct model_s *model; // NULL = no model - struct model_s *_model; // for nq skin support int frame; byte *colormap; int skinnum; // for Alias models - int _skinnum; // for nq skin support struct skin_s *skin; - struct player_info_s *scoreboard; // identify player - float syncbase; // for client-side animations struct efrag_s *efrag; // linked list of efrags int visframe; // last frame this entity was // found in an active leaf - int effects; // light, particals, etc - - float colormod[3]; // color tint for model + vec3_t colormod; // color tint for model float alpha; // opacity (alpha) of the model float scale; // size scaler of the model float glow_size; // how big the glow is (can be negative) diff --git a/nq/include/client.h b/nq/include/client.h index 06b86b11c..d5e6891e8 100644 --- a/nq/include/client.h +++ b/nq/include/client.h @@ -31,18 +31,17 @@ #include -#include "QF/info.h" #include "QF/input.h" #include "QF/mathlib.h" #include "QF/model.h" #include "QF/sound.h" #include "QF/vfs.h" +#include "QF/render.h" +#include "game.h" #include "net.h" #include "protocol.h" #include "r_local.h" -#include "QF/render.h" -#include "game.h" typedef struct usercmd_s @@ -223,6 +222,19 @@ typedef struct } client_state_t; +typedef struct cl_entity_state_s { + entity_t *ent; + entity_state_t baseline; + int forcelink; + vec3_t msg_origins[2]; + vec3_t msg_angles[2]; + double msgtime; + int effects; + int colors; + struct model_s *model; + int skinnum; +} cl_entity_state_t; + /* cvars */ @@ -274,6 +286,7 @@ extern client_state_t cl; // FIXME, allocate dynamically extern entity_t cl_entities[MAX_EDICTS]; +extern cl_entity_state_t cl_baselines[MAX_EDICTS]; extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; extern int fps_count; diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 5cc42354d..ebd06b33c 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -86,9 +86,8 @@ client_state_t cl; // FIXME: put these on hunk? entity_t cl_entities[MAX_EDICTS]; -entity_state_t cl_baselines[MAX_EDICTS]; +cl_entity_state_t cl_baselines[MAX_EDICTS]; entity_t cl_static_entities[MAX_STATIC_ENTITIES]; -entity_state_t cl_static_entity_baselines[MAX_STATIC_ENTITIES]; void @@ -179,12 +178,13 @@ CL_ClearState (void) R_ClearParticles (); // FIXME: for R_ClearFires for (i = 0; i < MAX_EDICTS; i++) { - cl_entities[i].baseline = &cl_baselines[i]; - cl_entities[i].baseline->alpha = 255; - cl_entities[i].baseline->scale = 16; - cl_entities[i].baseline->glow_color = 254; - cl_entities[i].baseline->glow_size = 0; - cl_entities[i].baseline->colormod = 255; + cl_baselines[i].ent = &cl_entities[i]; + cl_entities[i].alpha = 255; + cl_entities[i].scale = 16; + cl_entities[i].glow_color = 254; + cl_entities[i].glow_size = 0; + cl_entities[i].colormod[0] = cl_entities[i].colormod[1] + = cl_entities[i].colormod[2] = 1; } } @@ -496,6 +496,7 @@ CL_RelinkEntities (void) { entity_t **_ent; entity_t *ent; + cl_entity_state_t *state; dlight_t *dl; float bobjrotate, frac, f, d; int i, j; @@ -526,44 +527,45 @@ CL_RelinkEntities (void) bobjrotate = anglemod (100 * cl.time); // start on the entity after the world - for (i = 1, ent = cl_entities + 1; i < cl.num_entities; i++, ent++) { + for (i = 1, state = cl_baselines + 1; i < cl.num_entities; i++, state++) { + ent = state->ent; if (!ent->model) { // empty slot - if (ent->forcelink) + if (state->forcelink) R_RemoveEfrags (ent); // just became empty continue; } // if the object wasn't included in the last packet, remove it - if (ent->msgtime != cl.mtime[0]) { + if (state->msgtime != cl.mtime[0]) { ent->model = NULL; continue; } VectorCopy (ent->origin, ent->old_origin); - if (ent->forcelink) { // the entity was not updated in the + if (state->forcelink) { // the entity was not updated in the // last message so move to the final spot - VectorCopy (ent->msg_origins[0], ent->origin); - VectorCopy (ent->msg_angles[0], ent->angles); + VectorCopy (state->msg_origins[0], ent->origin); + VectorCopy (state->msg_angles[0], ent->angles); ent->pose1 = ent->pose2 = -1; } else { // if the delta is large, assume a // teleport and don't lerp f = frac; for (j = 0; j < 3; j++) { - delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j]; + delta[j] = state->msg_origins[0][j] - state->msg_origins[1][j]; if (delta[j] > 100 || delta[j] < -100) f = 1; // assume a teleportation, not a motion } // interpolate the origin and angles for (j = 0; j < 3; j++) { - ent->origin[j] = ent->msg_origins[1][j] + f * delta[j]; + ent->origin[j] = state->msg_origins[1][j] + f * delta[j]; - d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; + d = state->msg_angles[0][j] - state->msg_angles[1][j]; if (d > 180) d -= 360; else if (d < -180) d += 360; - ent->angles[j] = ent->msg_angles[1][j] + f * d; + ent->angles[j] = state->msg_angles[1][j] + f * d; } } @@ -578,9 +580,9 @@ CL_RelinkEntities (void) if (ent->model->flags & EF_ROTATE) ent->angles[1] = bobjrotate; - if (ent->effects & EF_BRIGHTFIELD) + if (state->baseline.effects & EF_BRIGHTFIELD) R_EntityParticles (ent); - if (ent->effects & EF_MUZZLEFLASH) { + if (state->baseline.effects & EF_MUZZLEFLASH) { vec3_t fv, rv, uv; dl = R_AllocDlight (i); @@ -596,9 +598,9 @@ CL_RelinkEntities (void) dl->color[1] = 0.1; dl->color[2] = 0.05; } - CL_NewDlight (i, ent->origin, ent->effects); - if (VectorDistance_fast(ent->msg_origins[1], ent->origin) > (256*256)) - VectorCopy (ent ->origin, ent->msg_origins[1]); + CL_NewDlight (i, ent->origin, state->baseline.effects); + if (VectorDistance_fast(state->msg_origins[1], ent->origin) > (256*256)) + VectorCopy (ent ->origin, state->msg_origins[1]); if (ent->model->flags & EF_ROCKET) { dl = R_AllocDlight (i); VectorCopy (ent->origin, dl->origin); @@ -619,7 +621,7 @@ CL_RelinkEntities (void) else if (ent->model->flags & EF_TRACER3) R_VoorTrail (ent); - ent->forcelink = false; + state->forcelink = false; if (i == cl.viewentity && !chase_active->int_val) { continue; @@ -725,8 +727,6 @@ Force_CenterView_f (void) void CL_Init (void) { - int i; - SZ_Alloc (&cls.message, 1024); CL_InitInput (); @@ -743,8 +743,4 @@ CL_Init (void) Cmd_AddCommand ("demolist", Con_Demolist_DEM_f, "List available demos"); Cmd_AddCommand ("force_centerview", Force_CenterView_f, "force the view " "to be level"); - - for (i = 0; i < MAX_STATIC_ENTITIES; i++) { - cl_static_entities[i].baseline = &cl_static_entity_baselines[i]; - } } diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index f5a283241..0552b3a8c 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -105,19 +105,21 @@ char *svc_strings[] = { This error checks and tracks the total number of entities */ -entity_t * +cl_entity_state_t * CL_EntityNum (int num) { if (num >= cl.num_entities) { if (num >= MAX_EDICTS) Host_Error ("CL_EntityNum: %i is an invalid number", num); while (cl.num_entities <= num) { + cl_baselines[cl.num_entities].ent = + &cl_entities[cl.num_entities]; cl_entities[cl.num_entities].colormap = vid.colormap8; cl.num_entities++; } } - return &cl_entities[num]; + return &cl_baselines[num]; } void @@ -328,6 +330,7 @@ void CL_ParseUpdate (int bits) { entity_t *ent; + cl_entity_state_t *state; int modnum, num, skin, i; model_t *model; qboolean forcelink; @@ -349,13 +352,14 @@ CL_ParseUpdate (int bits) else num = MSG_ReadByte (net_message); - ent = CL_EntityNum (num); + state = CL_EntityNum (num); + ent = state->ent; for (i = 0; i < 16; i++) if (bits & (1 << i)) bitcounts[i]++; - if (ent->msgtime != cl.mtime[1]) + if (state->msgtime != cl.mtime[1]) forcelink = true; // no previous frame to lerp from else forcelink = false; @@ -369,14 +373,14 @@ CL_ParseUpdate (int bits) ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1; } - ent->msgtime = cl.mtime[0]; + state->msgtime = cl.mtime[0]; if (bits & U_MODEL) { modnum = MSG_ReadByte (net_message); if (modnum >= MAX_MODELS) Host_Error ("CL_ParseModel: bad modnum"); } else - modnum = ent->baseline->modelindex; + modnum = state->baseline.modelindex; model = cl.model_precache[modnum]; if (model != ent->model) { @@ -397,12 +401,12 @@ CL_ParseUpdate (int bits) if (bits & U_FRAME) ent->frame = MSG_ReadByte (net_message); else - ent->frame = ent->baseline->frame; + ent->frame = state->baseline.frame; if (bits & U_COLORMAP) i = MSG_ReadByte (net_message); else - i = ent->baseline->colormap; + i = state->baseline.colormap; if (!i) ent->colormap = vid.colormap8; else { @@ -414,7 +418,7 @@ CL_ParseUpdate (int bits) if (bits & U_SKIN) skin = MSG_ReadByte (net_message); else - skin = ent->baseline->skin; + skin = state->baseline.skin; if (skin != ent->skinnum) { ent->skinnum = skin; //XXX if (num > 0 && num <= cl.maxclients) @@ -422,73 +426,73 @@ CL_ParseUpdate (int bits) } if (bits & U_EFFECTS) - ent->effects = MSG_ReadByte (net_message); + state->effects = MSG_ReadByte (net_message); else - ent->effects = ent->baseline->effects; + state->effects = state->baseline.effects; // shift the known values for interpolation - VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); - VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); + VectorCopy (state->msg_origins[0], state->msg_origins[1]); + VectorCopy (state->msg_angles[0], state->msg_angles[1]); if (bits & U_ORIGIN1) - ent->msg_origins[0][0] = MSG_ReadCoord (net_message); + state->msg_origins[0][0] = MSG_ReadCoord (net_message); else - ent->msg_origins[0][0] = ent->baseline->origin[0]; + state->msg_origins[0][0] = state->baseline.origin[0]; if (bits & U_ANGLE1) - ent->msg_angles[0][0] = MSG_ReadAngle (net_message); + state->msg_angles[0][0] = MSG_ReadAngle (net_message); else - ent->msg_angles[0][0] = ent->baseline->angles[0]; + state->msg_angles[0][0] = state->baseline.angles[0]; if (bits & U_ORIGIN2) - ent->msg_origins[0][1] = MSG_ReadCoord (net_message); + state->msg_origins[0][1] = MSG_ReadCoord (net_message); else - ent->msg_origins[0][1] = ent->baseline->origin[1]; + state->msg_origins[0][1] = state->baseline.origin[1]; if (bits & U_ANGLE2) - ent->msg_angles[0][1] = MSG_ReadAngle (net_message); + state->msg_angles[0][1] = MSG_ReadAngle (net_message); else - ent->msg_angles[0][1] = ent->baseline->angles[1]; + state->msg_angles[0][1] = state->baseline.angles[1]; if (bits & U_ORIGIN3) - ent->msg_origins[0][2] = MSG_ReadCoord (net_message); + state->msg_origins[0][2] = MSG_ReadCoord (net_message); else - ent->msg_origins[0][2] = ent->baseline->origin[2]; + state->msg_origins[0][2] = state->baseline.origin[2]; if (bits & U_ANGLE3) - ent->msg_angles[0][2] = MSG_ReadAngle (net_message); + state->msg_angles[0][2] = MSG_ReadAngle (net_message); else - ent->msg_angles[0][2] = ent->baseline->angles[2]; + state->msg_angles[0][2] = state->baseline.angles[2]; if (bits & U_NOLERP) - ent->forcelink = true; + state->forcelink = true; if (forcelink) { // didn't have an update last message - VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); - VectorCopy (ent->msg_origins[0], ent->origin); - VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); - VectorCopy (ent->msg_angles[0], ent->angles); - ent->forcelink = true; + VectorCopy (state->msg_origins[0], state->msg_origins[1]); + VectorCopy (state->msg_origins[0], ent->origin); + VectorCopy (state->msg_angles[0], state->msg_angles[1]); + VectorCopy (state->msg_angles[0], ent->angles); + state->forcelink = true; } } void -CL_ParseBaseline (entity_t *ent) +CL_ParseBaseline (cl_entity_state_t *state) { int i; - ent->baseline->modelindex = MSG_ReadByte (net_message); - ent->baseline->frame = MSG_ReadByte (net_message); - ent->baseline->colormap = MSG_ReadByte (net_message); - ent->baseline->skin = MSG_ReadByte (net_message); + state->baseline.modelindex = MSG_ReadByte (net_message); + state->baseline.frame = MSG_ReadByte (net_message); + state->baseline.colormap = MSG_ReadByte (net_message); + state->baseline.skin = MSG_ReadByte (net_message); for (i = 0; i < 3; i++) { - ent->baseline->origin[i] = MSG_ReadCoord (net_message); - ent->baseline->angles[i] = MSG_ReadAngle (net_message); + state->baseline.origin[i] = MSG_ReadCoord (net_message); + state->baseline.angles[i] = MSG_ReadAngle (net_message); } // LordHavoc: set up the baseline to account for new effects (alpha, // colormod, etc) - ent->baseline->alpha = 255; - ent->baseline->scale = 16; - ent->baseline->glow_color = 254; - ent->baseline->glow_size = 0; - ent->baseline->colormod = 255; + state->baseline.alpha = 255; + state->baseline.scale = 16; + state->baseline.glow_color = 254; + state->baseline.glow_size = 0; + state->baseline.colormod = 255; } /* @@ -598,6 +602,7 @@ CL_ParseClientdata (int bits) void CL_ParseStatic (void) { + cl_entity_state_t state; entity_t *ent; int i; @@ -606,24 +611,24 @@ CL_ParseStatic (void) Host_Error ("Too many static entities"); ent = &cl_static_entities[i]; cl.num_statics++; - CL_ParseBaseline (ent); + CL_ParseBaseline (&state); // copy it to the current state - ent->model = cl.model_precache[ent->baseline->modelindex]; - ent->frame = ent->baseline->frame; + ent->model = cl.model_precache[state.baseline.modelindex]; + ent->frame = state.baseline.frame; ent->colormap = vid.colormap8; - ent->skinnum = ent->baseline->skin; - ent->effects = ent->baseline->effects; + ent->skinnum = state.baseline.skin; +//FIXME ent->effects = state.baseline.effects; - ent->alpha = ent->baseline->alpha / 255.0; - ent->scale = ent->baseline->scale / 16.0; - ent->glow_color = ent->baseline->glow_color; - ent->glow_size = ent->baseline->glow_size; + ent->alpha = state.baseline.alpha / 255.0; + ent->scale = state.baseline.scale / 16.0; + ent->glow_color = state.baseline.glow_color; + ent->glow_size = state.baseline.glow_size; //FIXME need to get this from baseline ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1; - VectorCopy (ent->baseline->origin, ent->origin); - VectorCopy (ent->baseline->angles, ent->angles); + VectorCopy (state.baseline.origin, ent->origin); + VectorCopy (state.baseline.angles, ent->angles); R_AddEfrags (ent); } diff --git a/nq/source/host_skin.c b/nq/source/host_skin.c index 922892e1f..67ed39707 100644 --- a/nq/source/host_skin.c +++ b/nq/source/host_skin.c @@ -127,7 +127,7 @@ CL_NewTranslation (int slot, skin_t *skin) int top, bottom; byte *dest; model_t *model; - entity_t *entity; + cl_entity_state_t *state; int skinnum; if (slot > cl.maxclients) @@ -137,9 +137,9 @@ CL_NewTranslation (int slot, skin_t *skin) dest = player->translations; top = (player->colors & 0xf0) >> 4; bottom = player->colors & 15; - entity = &cl_entities[1 + slot]; - model = entity->model; - skinnum = entity->skinnum; + state = &cl_baselines[1 + slot]; + model = state->ent->model; + skinnum = state->ent->skinnum; memset (skin, 0, sizeof (*skin)); //XXX external skins not yet supported @@ -150,13 +150,13 @@ CL_NewTranslation (int slot, skin_t *skin) skin->data.texels = 0; //FIXME if (player->colors == player->_colors - && entity->model == entity->_model - && entity->skinnum == entity->_skinnum) + && model == state->model + && skinnum == state->skinnum) return; player->_colors = player->colors; - entity->_model = entity->model; - entity->_skinnum = entity->skinnum; + state->model = model; + state->skinnum = skinnum; Skin_Set_Translate (top, bottom, dest); Skin_Do_Translation_Model (model, skinnum, slot, skin); diff --git a/qw/source/cl_ents.c b/qw/source/cl_ents.c index c1d0e0d3a..37de557b3 100644 --- a/qw/source/cl_ents.c +++ b/qw/source/cl_ents.c @@ -64,9 +64,14 @@ static struct predicted_player { vec3_t origin; // predicted origin } predicted_players[MAX_CLIENTS]; -entity_t cl_packet_ents[512]; // FIXME: magic number -entity_t cl_flag_ents[MAX_CLIENTS]; + +#define MAX_PROJECTILES 32 +int cl_num_projectiles; + entity_t cl_player_ents[MAX_CLIENTS]; +entity_t cl_flag_ents[MAX_CLIENTS]; +entity_t cl_projectiles[MAX_PROJECTILES]; +entity_t cl_packet_ents[512]; // FIXME: magic number void @@ -392,6 +397,7 @@ CL_LinkPacketEntities (void) entity_state_t *s1; model_t *model; packet_entities_t *pack; + player_info_t *info; pack = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].packet_entities; @@ -432,15 +438,15 @@ CL_LinkPacketEntities (void) && cl.players[s1->colormap - 1].name[0] && !strcmp ((*ent)->model->name, "progs/player.mdl")) { (*ent)->colormap = cl.players[s1->colormap - 1].translations; - (*ent)->scoreboard = &cl.players[s1->colormap - 1]; + info = &cl.players[s1->colormap - 1]; } else { (*ent)->colormap = vid.colormap8; - (*ent)->scoreboard = NULL; + info = NULL; } - if ((*ent)->scoreboard && !(*ent)->scoreboard->skin) - Skin_Find ((*ent)->scoreboard); - if ((*ent)->scoreboard && (*ent)->scoreboard->skin) { + if (info && !info->skin) + Skin_Find (info); + if (info && info->skin) { (*ent)->skin = Skin_NewTempSkin (); if ((*ent)->skin) { i = s1->colormap - 1; @@ -531,15 +537,6 @@ CL_LinkPacketEntities (void) /* PROJECTILE PARSING / LINKING */ -typedef struct { - int modelindex; - entity_t ent; -} projectile_t; - -#define MAX_PROJECTILES 32 -projectile_t cl_projectiles[MAX_PROJECTILES]; -int cl_num_projectiles; - void CL_ClearProjectiles (void) { @@ -556,7 +553,7 @@ CL_ParseProjectiles (void) { byte bits[6]; int i, c, j; - projectile_t *pr; + entity_t *pr; c = MSG_ReadByte (net_message); for (i = 0; i < c; i++) { @@ -569,12 +566,13 @@ CL_ParseProjectiles (void) pr = &cl_projectiles[cl_num_projectiles]; cl_num_projectiles++; - pr->modelindex = cl_spikeindex; - pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096; - pr->ent.origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096; - pr->ent.origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096; - pr->ent.angles[0] = 360 * (bits[4] >> 4) / 16; - pr->ent.angles[1] = 360 * bits[5] / 256; + pr->model = cl.model_precache[cl_spikeindex]; + pr->colormap = vid.colormap8; + pr->origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096; + pr->origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096; + pr->origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096; + pr->angles[0] = 360 * (bits[4] >> 4) / 16; + pr->angles[1] = 360 * bits[5] / 256; } } @@ -583,30 +581,16 @@ CL_LinkProjectiles (void) { int i; entity_t **ent; - projectile_t *pr; + entity_t *pr; for (i = 0, pr = cl_projectiles; i < cl_num_projectiles; i++, pr++) { - if (pr->modelindex < 1) + if (!pr->model) continue; - // grab an entity to fill in ent = R_NewEntity (); if (!ent) break; // object list is full - *ent = &pr->ent; - (*ent)->model = cl.model_precache[pr->modelindex]; - (*ent)->skinnum = 0; - (*ent)->frame = 0; - (*ent)->colormap = vid.colormap8; - (*ent)->scoreboard = NULL; - (*ent)->skin = NULL; - // LordHavoc: Endy had neglected to do this as part of the QSG - // VERSION 2 stuff - (*ent)->glow_size = 0; - (*ent)->glow_color = 254; - (*ent)->alpha = 1; - (*ent)->scale = 1; - (*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1; + *ent = pr; } } @@ -651,9 +635,10 @@ CL_ParsePlayerinfo (void) state->velocity[i] = 0; } if (flags & PF_MODEL) - state->modelindex = MSG_ReadByte (net_message); + i = MSG_ReadByte (net_message); else - state->modelindex = cl_playerindex; + i = cl_playerindex; + state->modelindex = i; if (flags & PF_SKINNUM) state->skinnum = MSG_ReadByte (net_message); @@ -790,7 +775,7 @@ CL_LinkPlayers (void) // the player object never gets added if (j == cl.playernum) { - if (!Cam_DrawPlayer (-1)) + if (!Cam_DrawPlayer (-1)) // XXX continue; } else { if (!Cam_DrawPlayer (j)) @@ -816,17 +801,17 @@ CL_LinkPlayers (void) ent->model = cl.model_precache[state->modelindex]; ent->skinnum = state->skinnum; ent->colormap = info->translations; - if (state->modelindex == cl_playerindex) - ent->scoreboard = info; // use custom skin - else - ent->scoreboard = NULL; - - if (ent->scoreboard && !ent->scoreboard->skin) - Skin_Find (ent->scoreboard); - if (ent->scoreboard && ent->scoreboard->skin) { - ent->skin = Skin_NewTempSkin (); - if (ent->skin) { - CL_NewTranslation (j, ent->skin); + if (state->modelindex == cl_playerindex) { //XXX + // use custom skin + if (!info->skin) + Skin_Find (info); + if (info && info->skin) { + ent->skin = Skin_NewTempSkin (); + if (ent->skin) { + CL_NewTranslation (j, ent->skin); + } + } else { + ent->skin = NULL; } } else { ent->skin = NULL;