Individual emblems mode

This commit is contained in:
Sally Coolatta 2022-02-28 10:58:18 -05:00
parent 49fa46d80e
commit 303d636f8e
8 changed files with 110 additions and 53 deletions

View file

@ -3839,6 +3839,10 @@ void readmaincfg(MYFILE *f)
{
useContinues = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "SHAREEMBLEMS"))
{
shareEmblems = (UINT8)(value || word2[0] == 'T' || word2[0] == 'Y');
}
else if (fastcmp(word, "GAMEDATA"))
{

View file

@ -543,9 +543,12 @@ extern UINT8 useBlackRock;
extern UINT8 use1upSound;
extern UINT8 maxXtraLife; // Max extra lives from rings
extern UINT8 useContinues;
#define continuesInSession (!multiplayer && (ultimatemode || (useContinues && !marathonmode) || (!modeattacking && !(cursaveslot > 0))))
extern UINT8 shareEmblems;
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
// For racing

View file

@ -215,6 +215,7 @@ UINT8 ammoremovaltics = 2*TICRATE;
UINT8 use1upSound = 0;
UINT8 maxXtraLife = 2; // Max extra lives from rings
UINT8 useContinues = 0; // Set to 1 to enable continues outside of no-save scenarioes
UINT8 shareEmblems = 0; // Set to 1 to share all picked up emblems in multiplayer
UINT8 introtoplay;
UINT8 creditscutscene;

View file

@ -164,6 +164,62 @@ boolean P_CanPickupItem(player_t *player, boolean weapon)
return true;
}
boolean P_CanPickupEmblem(player_t *player, INT32 emblemID)
{
emblem_t *emblem = NULL;
if (emblemID < 0 || emblemID >= numemblems)
{
// Invalid emblem ID, can't pickup.
return false;
}
emblem = &emblemlocations[emblemID];
if (demoplayback)
{
// Never collect emblems in replays.
return false;
}
if (player->bot && player->bot != BOT_MPAI)
{
// Your little lap-dog can't grab these for you.
return false;
}
if (emblem->type == ET_SKIN)
{
INT32 skinnum = M_EmblemSkinNum(emblem);
if (player->skin != skinnum)
{
// Incorrect skin to pick up this emblem.
return false;
}
}
return true;
}
boolean P_EmblemWasCollected(INT32 emblemID)
{
if (emblemID < 0 || emblemID >= numemblems)
{
// Invalid emblem ID, can't pickup.
return true;
}
if (shareEmblems && !serverGamedata->collected[emblemID])
{
// It can be worth collecting again if we're sharing emblems
// and the server doesn't have it.
return false;
}
return clientGamedata->collected[emblemID];
}
//
// P_DoNightsScore
//
@ -738,25 +794,41 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Secret emblem thingy
case MT_EMBLEM:
{
if (demoplayback || (player->bot && player->bot != BOT_MPAI) || special->health <= 0 || special->health > MAXEMBLEMS)
return;
mobj_t *spark = NULL;
boolean prevCollected;
if (emblemlocations[special->health-1].type == ET_SKIN)
if (!P_CanPickupEmblem(player, special->health - 1))
{
INT32 skinnum = M_EmblemSkinNum(&emblemlocations[special->health-1]);
if (player->skin != skinnum)
{
return;
}
return;
}
clientGamedata->collected[special->health-1] = serverGamedata->collected[special->health-1] = true;
prevCollected = P_EmblemWasCollected(special->health - 1);
M_SilentUpdateUnlockablesAndEmblems(serverGamedata);
M_UpdateUnlockablesAndExtraEmblems(clientGamedata);
G_SaveGameData(clientGamedata);
break;
if (((player - players) == serverplayer) || shareEmblems)
{
serverGamedata->collected[special->health-1] = true;
M_SilentUpdateUnlockablesAndEmblems(serverGamedata);
}
if (P_IsLocalPlayer(player) || shareEmblems)
{
clientGamedata->collected[special->health-1] = true;
M_UpdateUnlockablesAndExtraEmblems(clientGamedata);
G_SaveGameData(clientGamedata);
}
// This always spawns the object to prevent mobjnum issues,
// but makes the effect invisible to whoever it doesn't matter to.
spark = P_SpawnMobjFromMobj(special, 0, 0, 0, MT_SPARK);
if (prevCollected == false && P_EmblemWasCollected(special->health - 1) == true)
{
S_StartSound(special, special->info->deathsound);
}
else
{
spark->flags2 |= MF2_DONTDRAW;
}
return;
}
// CTF Flags

View file

@ -510,6 +510,8 @@ void P_ClearStarPost(INT32 postnum);
void P_ResetStarposts(void);
boolean P_CanPickupItem(player_t *player, boolean weapon);
boolean P_CanPickupEmblem(player_t *player, INT32 emblemID);
boolean P_EmblemWasCollected(INT32 emblemID);
void P_DoNightsScore(player_t *player);
void P_DoMatchSuper(player_t *player);

View file

@ -9716,6 +9716,11 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
A_AttractChase(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;
@ -12146,7 +12151,6 @@ static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj)
INT32 j;
emblem_t* emblem = M_GetLevelEmblems(gamemap);
skincolornum_t emcolor;
boolean validEmblem = true;
while (emblem)
{
@ -12171,47 +12175,19 @@ 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;
validEmblem = true;
mobj->frame &= ~FF_TRANSMASK;
if (!netgame)
if (emblemlocations[j].type == ET_GLOBAL)
{
validEmblem = !serverGamedata->collected[j];
if (emblemlocations[j].type == ET_SKIN && !multiplayer)
mobj->reactiontime = emblemlocations[j].var;
if (emblemlocations[j].var & GE_NIGHTSITEM)
{
INT32 skinnum = M_EmblemSkinNum(&emblemlocations[j]);
if (players[0].skin != skinnum)
{
validEmblem = false;
}
mobj->flags |= MF_NIGHTSITEM;
mobj->flags &= ~MF_SPECIAL;
mobj->flags2 |= MF2_DONTDRAW;
}
}
if (validEmblem == false)
{
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;
if (emblemlocations[j].type == ET_GLOBAL)
{
mobj->reactiontime = emblemlocations[j].var;
if (emblemlocations[j].var & GE_NIGHTSITEM)
{
mobj->flags |= MF_NIGHTSITEM;
mobj->flags &= ~MF_SPECIAL;
mobj->flags2 |= MF2_DONTDRAW;
}
}
}
return true;
}

View file

@ -876,7 +876,7 @@ static void P_SpawnMapThings(boolean spawnemblems)
size_t i;
mapthing_t *mt;
// Spawn axis points first so they are at the front of the list for fast searching.
// Spawn axis points first so they are at the front of the list for fast searching.
for (i = 0, mt = mapthings; i < nummapthings; i++, mt++)
{
switch (mt->type)

View file

@ -2563,9 +2563,8 @@ static void ST_doItemFinderIconsAndSound(void)
emblems[stemblems++] = i;
if (!(clientGamedata->collected[i] && serverGamedata->collected[i]))
if (!P_EmblemWasCollected(i))
{
// It can be worth collecting again if the server doesn't have it.
++stunfound;
}