diff --git a/src/p_inter.c b/src/p_inter.c index 7c65c6315..0c714178a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -156,6 +156,40 @@ boolean P_CanPickupItem(player_t *player, UINT8 weapon) return true; } +boolean P_CanPickupEmblem(player_t *player, INT32 emblemID) +{ + if (emblemID < 0 || emblemID >= MAXEMBLEMS) + { + // Invalid emblem ID, can't pickup. + return false; + } + + if (demo.playback) + { + // Never collect emblems in replays. + return false; + } + + if (player->bot) + { + // Your nefarious opponent puppy can't grab these for you. + return false; + } + + return true; +} + +boolean P_EmblemWasCollected(INT32 emblemID) +{ + if (emblemID < 0 || emblemID >= numemblems) + { + // Invalid emblem ID, can't pickup. + return true; + } + + return gamedata->collected[emblemID]; +} + /** Takes action based on a ::MF_SPECIAL thing touched by a player. * Actually, this just checks a few things (heights, toucher->player, no * objectplace, no dead or disappearing things) @@ -501,12 +535,24 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) // Secret emblem thingy case MT_EMBLEM: { - if (demo.playback || special->health > MAXEMBLEMS) + boolean gotcollected = false; + + if (!P_CanPickupEmblem(player, special->health - 1)) return; - gamedata->collected[special->health-1] = true; - M_UpdateUnlockablesAndExtraEmblems(true); - G_SaveGameData(); + if (P_IsLocalPlayer(player) && !gamedata->collected[special->health-1]) + { + gamedata->collected[special->health-1] = gotcollected = true; + M_UpdateUnlockablesAndExtraEmblems(true); + G_SaveGameData(); + } + + if (netgame) + { + // Don't delete the object in netgames, just fade it. + return; + } + break; } diff --git a/src/p_local.h b/src/p_local.h index 9bc92cb64..572ff7ad0 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -544,6 +544,8 @@ void P_CheckPointLimit(void); boolean P_CheckRacers(void); boolean P_CanPickupItem(player_t *player, UINT8 weapon); +boolean P_CanPickupEmblem(player_t *player, INT32 emblemID); +boolean P_EmblemWasCollected(INT32 emblemID); // // P_SPEC diff --git a/src/p_mobj.c b/src/p_mobj.c index 4f447ebc9..2e0f4dbfc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6825,6 +6825,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } break; case MT_EMBLEM: + if (P_EmblemWasCollected(mobj->health - 1) || !P_CanPickupEmblem(&players[consoleplayer], mobj->health - 1)) + { + mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); + } + else + { + mobj->frame &= ~FF_TRANSMASK; + } if (mobj->flags2 & MF2_NIGHTSPULL) P_NightsItemChase(mobj); break; @@ -11969,24 +11977,13 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting mobj->color = (UINT16)emcolor; - if (gamedata->collected[j]) - { - P_UnsetThingPosition(mobj); - mobj->flags |= MF_NOCLIP; - mobj->flags &= ~MF_SPECIAL; - mobj->flags |= MF_NOBLOCKMAP; - mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); - P_SetThingPosition(mobj); - } - else - { - mobj->frame &= ~FF_TRANSMASK; + mobj->frame &= ~FF_TRANSMASK; - if (emblemlocations[j].type == ET_GLOBAL) - { - mobj->reactiontime = emblemlocations[j].var; - } + if (emblemlocations[j].type == ET_GLOBAL) + { + mobj->reactiontime = emblemlocations[j].var; } + return true; }