Fixed: MUSINFO was not multiplayer-aware

- Move MUSINFO change request out of FLevelLocals and into player_t. This
  allows the MusicChanger actors to change music for each player
  independantly. This is similar to PrBoom+, which switches depending on
  the displayplayer. The difference being, we don't actually track the
  music other players are listening to. (Which might not be a bad idea to
  implement at some point.)
- Moved a few fields in player_t for better packing.
This commit is contained in:
Randy Heit 2015-03-26 23:19:05 -05:00
parent 9cd6aae902
commit 3463b87876
7 changed files with 58 additions and 42 deletions

View File

@ -443,10 +443,15 @@ public:
FName LastDamageType; // [RH] For damage-specific pain and death sounds
//Added by MC:
TObjPtr<DBot> Bot;
TObjPtr<AActor> MUSINFOactor; // For MUSINFO purposes
SBYTE MUSINFOtics;
bool settings_controller; // Player can control game settings.
SBYTE crouching;
SBYTE crouchdir;
//Added by MC:
TObjPtr<DBot> Bot;
float BlendR; // [RH] Final blending values
float BlendG;
@ -458,8 +463,6 @@ public:
int MinPitch; // Viewpitch limits (negative is up, positive is down)
int MaxPitch;
SBYTE crouching;
SBYTE crouchdir;
fixed_t crouchfactor;
fixed_t crouchoffset;
fixed_t crouchviewdelta;

View File

@ -1457,7 +1457,9 @@ void G_SerializeLevel (FArchive &arc, bool hubLoad)
if (SaveVersion >= 3313)
{
arc << level.nextmusic;
// This is a player property now
int nextmusic;
arc << nextmusic;
}
// Hub transitions must keep the current total time

View File

@ -412,7 +412,6 @@ struct FLevelLocals
int musicorder;
int cdtrack;
unsigned int cdid;
int nextmusic; // For MUSINFO purposes
FTextureID skytexture1;
FTextureID skytexture2;

View File

@ -4480,7 +4480,8 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
p->mo->ResetAirSupply(false);
p->Uncrouch();
p->MinPitch = p->MaxPitch = 0; // will be filled in by PostBeginPlay()/netcode
p->MUSINFOactor = NULL;
p->MUSINFOtics = -1;
p->velx = p->vely = 0; // killough 10/98: initialize bobbing to 0.

View File

@ -309,7 +309,9 @@ player_t::player_t()
ConversationNPC(0),
ConversationPC(0),
ConversationNPCAngle(0),
ConversationFaceTalker(0)
ConversationFaceTalker(0),
MUSINFOactor(0),
MUSINFOtics(-1)
{
memset (&cmd, 0, sizeof(cmd));
memset (frags, 0, sizeof(frags));
@ -400,6 +402,8 @@ player_t &player_t::operator=(const player_t &p)
ConversationPC = p.ConversationPC;
ConversationNPCAngle = p.ConversationNPCAngle;
ConversationFaceTalker = p.ConversationFaceTalker;
MUSINFOactor = p.MUSINFOactor;
MUSINFOtics = p.MUSINFOtics;
return *this;
}
@ -430,6 +434,7 @@ size_t player_t::FixPointers (const DObject *old, DObject *rep)
if (*&PremorphWeapon == old) PremorphWeapon = static_cast<AWeapon *>(rep), changed++;
if (*&ConversationNPC == old) ConversationNPC = replacement, changed++;
if (*&ConversationPC == old) ConversationPC = replacement, changed++;
if (*&MUSINFOactor == old) MUSINFOactor = replacement, changed++;
return changed;
}
@ -443,6 +448,7 @@ size_t player_t::PropagateMark()
GC::Mark(ReadyWeapon);
GC::Mark(ConversationNPC);
GC::Mark(ConversationPC);
GC::Mark(MUSINFOactor);
GC::Mark(PremorphWeapon);
if (PendingWeapon != WP_NOCHANGE)
{
@ -2331,6 +2337,30 @@ void P_PlayerThink (player_t *player)
player->crouchoffset = -FixedMul(player->mo->ViewHeight, (FRACUNIT - player->crouchfactor));
// MUSINFO stuff
if (player->MUSINFOtics >= 0 && player->MUSINFOactor != NULL)
{
if (--player->MUSINFOtics < 0)
{
if (player - players == consoleplayer)
{
if (player->MUSINFOactor->args[0] != 0)
{
FName *music = level.info->MusicMap.CheckKey(player->MUSINFOactor->args[0]);
if (music != NULL)
{
S_ChangeMusic(music->GetChars(), player->MUSINFOactor->args[1]);
}
}
else
{
S_ChangeMusic("*");
}
}
DPrintf("MUSINFO change for player %d to %d\n", (int)(player - players), player->MUSINFOactor->args[0]);
}
}
if (player->playerstate == PST_DEAD)
{
@ -3105,6 +3135,10 @@ void player_t::Serialize (FArchive &arc)
{
userinfo.SkinChanged(skinname, CurrentPlayerClass);
}
if (SaveVersion >= 4522)
{
arc << MUSINFOactor << MUSINFOtics;
}
}

View File

@ -2348,7 +2348,6 @@ class AMusicChanger : public ASectorAction
DECLARE_CLASS (AMusicChanger, ASectorAction)
public:
virtual bool DoTriggerAction (AActor *triggerer, int activationType);
virtual void Tick();
virtual void PostBeginPlay();
};
@ -2356,49 +2355,27 @@ IMPLEMENT_CLASS(AMusicChanger)
bool AMusicChanger::DoTriggerAction (AActor *triggerer, int activationType)
{
if (activationType & SECSPAC_Enter)
if (activationType & SECSPAC_Enter && triggerer->player != NULL)
{
if (args[0] == 0 || level.info->MusicMap.CheckKey(args[0]))
{
level.nextmusic = args[0];
reactiontime = 30;
if (triggerer->player->MUSINFOactor != this)
{
triggerer->player->MUSINFOactor = this;
triggerer->player->MUSINFOtics = 30;
}
}
return Super::DoTriggerAction (triggerer, activationType);
}
void AMusicChanger::Tick()
{
Super::Tick();
if (reactiontime > -1 && --reactiontime == 0)
{
// Is it our music that's queued for being played?
if (level.nextmusic == args[0])
{
if (args[0] != 0)
{
FName *music = level.info->MusicMap.CheckKey(args[0]);
if (music != NULL)
{
S_ChangeMusic(music->GetChars(), args[1]);
}
}
else
{
S_ChangeMusic("*");
}
}
}
}
void AMusicChanger::PostBeginPlay()
{
// The music changer should consider itself activated if the player
// spawns in its sector as well as if it enters the sector during a P_TryMove.
Super::PostBeginPlay();
if (players[consoleplayer].mo && players[consoleplayer].mo->Sector == this->Sector)
for (int i = 0; i < MAXPLAYERS; ++i)
{
TriggerAction(players[consoleplayer].mo, SECSPAC_Enter);
if (playeringame[i] && players[i].mo && players[i].mo->Sector == this->Sector)
{
TriggerAction(players[i].mo, SECSPAC_Enter);
}
}
}

View File

@ -76,7 +76,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got.
#define SAVEVER 4521
#define SAVEVER 4522
#define SAVEVERSTRINGIFY2(x) #x
#define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)