diff --git a/src/b_bot.c b/src/b_bot.c index d1465f891d481dd8314507b8f6b5e2c795abb1dd..57f7623042d318df981af823ac59d1865c44fb75 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -631,7 +631,8 @@ void B_HandleFlightIndicator(player_t *player) } // otherwise, update its visibility - if (P_IsLocalPlayer(player->botleader)) + tails->hnext->drawonlyforplayer = player->botleader; // Hide it from the other player in splitscreen, and yourself when spectating + if (P_IsLocalPlayer(player->botleader)) // Only display it on your own view. Don't display it for spectators tails->hnext->flags2 &= ~MF2_DONTDRAW; else tails->hnext->flags2 |= MF2_DONTDRAW; diff --git a/src/g_game.c b/src/g_game.c index 15b1e10816318ffef1f1ed530a6c9cc0751b2c46..8264fbe6bb0826409d142d0b519ad7fa2d319ca2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1441,6 +1441,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // I assume this is netgame-safe because gunslinger spawns this for only the local player...... *sweats intensely* newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); + newtarget->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating if (player->mo && P_AproxDistance( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index ed5736fa7f06292be4df17759de81bc2a517ced1..838e2f53ba6088e599bbedc4fbd7b20bfa1edfcb 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -689,11 +689,12 @@ static int lib_pSpawnLockOn(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (state >= NUMSTATES) return luaL_error(L, "state %d out of range (0 - %d)", state, NUMSTATES-1); - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockon); visual->flags2 |= MF2_DONTDRAW; + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating P_SetMobjStateNF(visual, state); } return 0; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 851c569d27f093cd7000f465fa1b60e4ffd4769e..fd8dcec92599b81c8e0cefbc0f5a095181a64d84 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -44,6 +44,8 @@ enum mobj_e { mobj_spritexoffset, mobj_spriteyoffset, mobj_floorspriteslope, + mobj_drawonlyforplayer, + mobj_dontdrawforviewmobj, mobj_touching_sectorlist, mobj_subsector, mobj_floorz, @@ -122,6 +124,8 @@ static const char *const mobj_opt[] = { "spritexoffset", "spriteyoffset", "floorspriteslope", + "drawonlyforplayer", + "dontdrawforviewmobj", "touching_sectorlist", "subsector", "floorz", @@ -262,6 +266,17 @@ static int mobj_get(lua_State *L) case mobj_floorspriteslope: LUA_PushUserdata(L, mo->floorspriteslope, META_SLOPE); break; + case mobj_drawonlyforplayer: + LUA_PushUserdata(L, mo->drawonlyforplayer, META_PLAYER); + break; + case mobj_dontdrawforviewmobj: + if (mo->dontdrawforviewmobj && P_MobjWasRemoved(mo->dontdrawforviewmobj)) + { // don't put invalid mobj back into Lua. + P_SetTarget(&mo->dontdrawforviewmobj, NULL); + return 0; + } + LUA_PushUserdata(L, mo->dontdrawforviewmobj, META_MOBJ); + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: @@ -551,6 +566,24 @@ static int mobj_set(lua_State *L) break; case mobj_floorspriteslope: return NOSET; + case mobj_drawonlyforplayer: + if (lua_isnil(L, 3)) + mo->drawonlyforplayer = NULL; + else + { + player_t *drawonlyforplayer = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); + mo->drawonlyforplayer = drawonlyforplayer; + } + break; + case mobj_dontdrawforviewmobj: + if (lua_isnil(L, 3)) + P_SetTarget(&mo->dontdrawforviewmobj, NULL); + else + { + mobj_t *dontdrawforviewmobj = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ)); + P_SetTarget(&mo->dontdrawforviewmobj, dontdrawforviewmobj); + } + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: diff --git a/src/p_mobj.c b/src/p_mobj.c index a25b5643bb158992ff2246b31c1ee1bf0d8a1515..4ca59285f7fc46bbfeb6e2373b50eb4eae33637d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6882,6 +6882,7 @@ void P_RunOverlays(void) mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); mo->scale = mo->destscale = mo->target->scale; mo->angle = (mo->target->player ? mo->target->player->drawangle : mo->target->angle) + mo->movedir; + P_SetTarget(&mo->dontdrawforviewmobj, mo->target->dontdrawforviewmobj); // Hide the overlay from the view that its target is hidden from - But don't copy drawonlyforplayer! if (!(mo->state->frame & FF_ANIMATE)) zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); @@ -7951,11 +7952,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) return; } - if (!camera.chase) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - P_UnsetThingPosition(mobj); { fixed_t radius = FixedMul(10*mobj->info->speed, mobj->target->scale); diff --git a/src/p_mobj.h b/src/p_mobj.h index 6a5ab84c410eaaa88a6ec00aeffe1aaf41556622..9c598f59e3ce155e66a3155c4c95bd7712f839c7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -334,6 +334,8 @@ typedef struct mobj_s // Player and mobj sprites in multiplayer modes are modified // using an internal color lookup table for re-indexing. UINT16 color; // This replaces MF_TRANSLATION. Use 0 for default (no translation). + struct player_s *drawonlyforplayer; // If set, hides the mobj for everyone except this player and their spectators + struct mobj_s *dontdrawforviewmobj; // If set, hides the mobj if dontdrawforviewmobj is the current camera (first-person player or awayviewmobj) // Interaction info, by BLOCKMAP. // Links in blocks (if needed). diff --git a/src/p_saveg.c b/src/p_saveg.c index 76f1661acee724c8b710939590a8d4dbb139a303..8f11e63e58a25ba43ff6f78f3d9713332330e402 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1553,30 +1553,32 @@ typedef enum typedef enum { - MD2_CUSVAL = 1, - MD2_CVMEM = 1<<1, - MD2_SKIN = 1<<2, - MD2_COLOR = 1<<3, - MD2_SCALESPEED = 1<<4, - MD2_EXTVAL1 = 1<<5, - MD2_EXTVAL2 = 1<<6, - MD2_HNEXT = 1<<7, - MD2_HPREV = 1<<8, - MD2_FLOORROVER = 1<<9, - MD2_CEILINGROVER = 1<<10, - MD2_SLOPE = 1<<11, - MD2_COLORIZED = 1<<12, - MD2_MIRRORED = 1<<13, - MD2_SPRITEROLL = 1<<14, - MD2_SHADOWSCALE = 1<<15, - MD2_RENDERFLAGS = 1<<16, - MD2_BLENDMODE = 1<<17, - MD2_SPRITEXSCALE = 1<<18, - MD2_SPRITEYSCALE = 1<<19, - MD2_SPRITEXOFFSET = 1<<20, - MD2_SPRITEYOFFSET = 1<<21, - MD2_FLOORSPRITESLOPE = 1<<22, - MD2_DISPOFFSET = 1<<23 + MD2_CUSVAL = 1, + MD2_CVMEM = 1<<1, + MD2_SKIN = 1<<2, + MD2_COLOR = 1<<3, + MD2_SCALESPEED = 1<<4, + MD2_EXTVAL1 = 1<<5, + MD2_EXTVAL2 = 1<<6, + MD2_HNEXT = 1<<7, + MD2_HPREV = 1<<8, + MD2_FLOORROVER = 1<<9, + MD2_CEILINGROVER = 1<<10, + MD2_SLOPE = 1<<11, + MD2_COLORIZED = 1<<12, + MD2_MIRRORED = 1<<13, + MD2_SPRITEROLL = 1<<14, + MD2_SHADOWSCALE = 1<<15, + MD2_RENDERFLAGS = 1<<16, + MD2_BLENDMODE = 1<<17, + MD2_SPRITEXSCALE = 1<<18, + MD2_SPRITEYSCALE = 1<<19, + MD2_SPRITEXOFFSET = 1<<20, + MD2_SPRITEYOFFSET = 1<<21, + MD2_FLOORSPRITESLOPE = 1<<22, + MD2_DISPOFFSET = 1<<23, + MD2_DRAWONLYFORPLAYER = 1<<24, + MD2_DONTDRAWFORVIEWMOBJ = 1<<25 } mobj_diff2_t; typedef enum @@ -1811,6 +1813,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) || (slope->normal.z != FRACUNIT)) diff2 |= MD2_FLOORSPRITESLOPE; } + if (mobj->drawonlyforplayer) + diff2 |= MD2_DRAWONLYFORPLAYER; + if (mobj->dontdrawforviewmobj) + diff2 |= MD2_DONTDRAWFORVIEWMOBJ; if (mobj->dispoffset != mobj->info->dispoffset) diff2 |= MD2_DISPOFFSET; @@ -1988,6 +1994,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, slope->normal.y); WRITEFIXED(save_p, slope->normal.z); } + if (diff2 & MD2_DRAWONLYFORPLAYER) + WRITEUINT8(save_p, mobj->drawonlyforplayer-players); + if (diff2 & MD2_DONTDRAWFORVIEWMOBJ) + WRITEUINT32(save_p, mobj->dontdrawforviewmobj->mobjnum); if (diff2 & MD2_DISPOFFSET) WRITEINT32(save_p, mobj->dispoffset); @@ -3044,6 +3054,10 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.y = READFIXED(save_p); slope->normal.z = READFIXED(save_p); } + if (diff2 & MD2_DRAWONLYFORPLAYER) + mobj->drawonlyforplayer = &players[READUINT8(save_p)]; + if (diff2 & MD2_DONTDRAWFORVIEWMOBJ) + mobj->dontdrawforviewmobj = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_DISPOFFSET) mobj->dispoffset = READINT32(save_p); else @@ -4063,6 +4077,13 @@ static void P_RelinkPointers(void) if (mobj->type == MT_HOOP || mobj->type == MT_HOOPCOLLIDE || mobj->type == MT_HOOPCENTER) continue; + if (mobj->dontdrawforviewmobj) + { + temp = (UINT32)(size_t)mobj->dontdrawforviewmobj; + mobj->dontdrawforviewmobj = NULL; + if (!P_SetTarget(&mobj->dontdrawforviewmobj, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "dontdrawforviewmobj not found on %d\n", mobj->type); + } if (mobj->tracer) { temp = (UINT32)(size_t)mobj->tracer; diff --git a/src/p_user.c b/src/p_user.c index 62dd2fcb24e23367f55349fed517ea5c67925c46..889e887c14ea2e28898896118b951782312965c8 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -398,6 +398,7 @@ void P_GiveFinishFlags(player_t *player) angle += FixedAngle(120*FRACUNIT); P_SetTarget(&flag->target, player->mo); + P_SetTarget(&flag->dontdrawforviewmobj, player->mo); // Hide the flag in first-person } } @@ -1840,6 +1841,7 @@ void P_SpawnShieldOrb(player_t *player) shieldobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, orbtype); shieldobj->flags2 |= MF2_SHIELD; P_SetTarget(&shieldobj->target, player->mo); + P_SetTarget(&shieldobj->dontdrawforviewmobj, player->mo); // Hide the shield in first-person if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PINK) { shieldobj->color = SKINCOLOR_PINK; @@ -1964,6 +1966,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) mobj_t *ghost = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_GHOST); P_SetTarget(&ghost->target, mobj); + P_SetTarget(&ghost->dontdrawforviewmobj, mobj); // Hide the ghost in first-person P_SetScale(ghost, mobj->scale); ghost->destscale = mobj->scale; @@ -2009,6 +2012,7 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) mobj_t *ghost2 = P_SpawnGhostMobj(mobj->player->followmobj); P_SetTarget(&ghost2->tracer, ghost); P_SetTarget(&ghost->tracer, ghost2); + P_SetTarget(&ghost2->dontdrawforviewmobj, mobj); // Hide the follow-ghost for the non-follow object ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); } @@ -3123,39 +3127,41 @@ static void P_DoBubbleBreath(player_t *player) // static void P_DoPlayerHeadSigns(player_t *player) { + mobj_t *sign = NULL; + if (G_TagGametype()) { - // If you're "IT", show a big "IT" over your head for others to see. - if (player->pflags & PF_TAGIT && !P_IsLocalPlayer(player)) + // If you're "IT", show a big "IT" over your head for others to see, including spectators + // (and even yourself if you spectate someone else). + if (player->pflags & PF_TAGIT && (!P_IsLocalPlayer(player) || consoleplayer != displayplayer || splitscreen)) { - mobj_t* it = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); - it->x = player->mo->x; - it->y = player->mo->y; - it->z = player->mo->z; - it->old_x = player->mo->old_x; - it->old_y = player->mo->old_y; - it->old_z = player->mo->old_z; + sign = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_TAG); + sign->x = player->mo->x; + sign->y = player->mo->y; + sign->z = player->mo->z; + sign->old_x = player->mo->old_x; + sign->old_y = player->mo->old_y; + sign->old_z = player->mo->old_z; if (!(player->mo->eflags & MFE_VERTICALFLIP)) { - it->z += player->mo->height; - it->old_z += player->mo->height; + sign->z += player->mo->height; + sign->old_z += player->mo->height; } else { - it->z -= mobjinfo[MT_TAG].height; - it->old_z -= mobjinfo[MT_TAG].height; + sign->z -= mobjinfo[MT_TAG].height; + sign->old_z -= mobjinfo[MT_TAG].height; } } } else if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh). { - // Spawn a got-flag message over the head of the player that - // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer]) + // Spawn a got-flag message over the head of the player that has it + // (but not on your own screen if you have the flag, unless you're spectating). + if (!P_IsLocalPlayer(player) || consoleplayer != displayplayer || splitscreen) { fixed_t zofs; - mobj_t *sign; boolean player_is_flipped = (player->mo->eflags & MFE_VERTICALFLIP) > 0; zofs = player->mo->momz; @@ -3187,6 +3193,43 @@ static void P_DoPlayerHeadSigns(player_t *player) sign->frame = 2|FF_FULLBRIGHT; } } + + if (!P_MobjWasRemoved(sign) && splitscreen) // Hide the sign from yourself in splitscreen - In single-screen, it wouldn't get spawned if it shouldn't be visible + { + if (player == &players[displayplayer]) + sign->drawonlyforplayer = &players[secondarydisplayplayer]; + else + sign->drawonlyforplayer = &players[displayplayer]; + +#ifdef QUADS + if (splitscreen > 1) // Can be seen by at least two local views, so we need an extra copy of the sign + { + UINT32 signframe = sign->frame; // Copy the flag frame + sign = P_SpawnMobjFromMobj(sign, 0, 0, 0, MT_TAG); + if (P_MobjWasRemoved(sign)) + return; + + sign->frame = signframe; + if (player == &players[displayplayer] || player == &players[secondarydisplayplayer]) + sign->drawonlyforplayer = &players[thirddisplayplayer]; + else + sign->drawonlyforplayer = &players[secondarydisplayplayer]; + + if (splitscreen > 2) // Can be seen by three local views + { + sign = P_SpawnMobjFromMobj(sign, 0, 0, 0, MT_TAG); + if (P_MobjWasRemoved(sign)) + return; + + sign->frame = signframe; + if (player != &players[fourthdisplayplayer]) + sign->drawonlyforplayer = &players[fourthdisplayplayer]; + else + sign->drawonlyforplayer = &players[thirddisplayplayer]; + } + } +#endif + } } // @@ -4707,10 +4750,11 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) mobj_t *lockon = P_LookForEnemies(player, false, true); if (lockon) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockon); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating } } if ((cmd->buttons & BT_SPIN) && !(player->pflags & PF_SPINDOWN)) @@ -5054,7 +5098,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { if ((lockonshield = P_LookForEnemies(player, false, false))) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { boolean dovis = true; if (lockonshield == lockonthok) @@ -5068,6 +5112,7 @@ static boolean P_PlayerShieldThink(player_t *player, ticcmd_t *cmd, mobj_t *lock { visual = P_SpawnMobj(lockonshield->x, lockonshield->y, lockonshield->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockonshield); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating P_SetMobjStateNF(visual, visual->info->spawnstate+1); } } @@ -5171,10 +5216,11 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockonthok = P_LookForEnemies(player, true, false))) { - if (P_IsLocalPlayer(player)) // Only display it on your own view. + if (P_IsLocalPlayer(player)) // Only display it on your own view. Don't display it for spectators { visual = P_SpawnMobj(lockonthok->x, lockonthok->y, lockonthok->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker P_SetTarget(&visual->target, lockonthok); + visual->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating } } @@ -11084,17 +11130,30 @@ static void P_MinecartThink(player_t *player) // Mark interpolation; the old positions need to be relative to the displacement from the minecart _after_ it's moved. // This isn't quite correct (it captures the landing wobble) but it works well enough + // Additionally, hide other players' marks if (detleft) { - detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2); - detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2); - detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2); + if (P_IsLocalPlayer(player)) + { + detleft->old_x = detleft->x - (minecart->old_x - minecart->old_x2); + detleft->old_y = detleft->y - (minecart->old_y - minecart->old_y2); + detleft->old_z = detleft->z - (minecart->old_z - minecart->old_z2); + detleft->drawonlyforplayer = player; // Hide it from the other player in splitscreen, and yourself when spectating + } + else // Don't see others' marks when spectating others + P_RemoveMobj(detleft); // Lock-on markers are only spawned client-side, so this SHOULD be safe too... } if (detright) { - detright->old_x = detright->x - (minecart->old_x - minecart->old_x2); - detright->old_y = detright->y - (minecart->old_y - minecart->old_y2); - detright->old_z = detright->z - (minecart->old_z - minecart->old_z2); + if (P_IsLocalPlayer(player)) + { + detright->old_x = detright->x - (minecart->old_x - minecart->old_x2); + detright->old_y = detright->y - (minecart->old_y - minecart->old_y2); + detright->old_z = detright->z - (minecart->old_z - minecart->old_z2); + detright->drawonlyforplayer = player; + } + else + P_RemoveMobj(detleft); } } else @@ -11386,12 +11445,15 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) for (i = -1; i < 2; i += 2) { + mobj_t *bubble; offsetH = i*P_ReturnThrustX(fume, fume->movedir, radiusV); offsetV = i*P_ReturnThrustY(fume, fume->movedir, radiusV); x = mo->x + radiusX + FixedMul(offsetH, factorX); y = mo->y + radiusY + FixedMul(offsetH, factorY); z = mo->z + heightoffset + offsetV; - P_SpawnMobj(x, y, z, MT_SMALLBUBBLE)->scale = mo->scale >> 1; + bubble = P_SpawnMobj(x, y, z, MT_SMALLBUBBLE); + bubble->scale = mo->scale >> 1; + P_SetTarget(&bubble->dontdrawforviewmobj, mo); // Hide the bubble in first-person } fume->movefactor = 0; @@ -11460,7 +11522,11 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) // If dashmode is high enough, spawn a trail if (player->normalspeed >= skins[player->skin].normalspeed*2) - P_SpawnGhostMobj(fume); + { + mobj_t *ghost = P_SpawnGhostMobj(fume); + if (!P_MobjWasRemoved(ghost)) + P_SetTarget(&ghost->dontdrawforviewmobj, mo); // Hide the trail in first-person + } } // @@ -12104,14 +12170,6 @@ void P_PlayerThink(player_t *player) gmobj->tracer->frame |= tr_trans70<<FF_TRANSSHIFT; } } - - // Hide the mobj from our sights if we're the displayplayer and chasecam is off, - // or secondarydisplayplayer and chasecam2 is off. - // Why not just not spawn the mobj? Well, I'd rather only flirt with - // consistency so much... - if ((player == &players[displayplayer] && !camera.chase) - || (splitscreen && player == &players[secondarydisplayplayer] && !camera2.chase)) - gmobj->flags2 |= MF2_DONTDRAW; } #endif diff --git a/src/r_things.c b/src/r_things.c index 248357e11fb0dc54f7c727cc75d01616dfb42d63..eee284d46f8e2ddb0383b97be71584a801c27386 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -3322,9 +3322,14 @@ void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) boolean R_ThingVisible (mobj_t *thing) { return (!( - thing->sprite == SPR_NULL || - ( thing->flags2 & (MF2_DONTDRAW) ) || - (r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing))) + (thing->sprite == SPR_NULL) || // Don't draw null-sprites + (thing->flags2 & MF2_DONTDRAW) || // Don't draw MF2_LINKDRAW objects + (thing->drawonlyforplayer && thing->drawonlyforplayer != viewplayer) || // Don't draw other players' personal objects + (r_viewmobj && ( + (r_viewmobj == thing) || // Don't draw first-person players or awayviewmobj objects + (r_viewmobj->player && r_viewmobj->player->followmobj == thing) || // Don't draw first-person players' followmobj + (r_viewmobj == thing->dontdrawforviewmobj) // Don't draw objects that are hidden for the current view + )) )); }