Skip to content

Commit

Permalink
Fixed|Doom: Updated IDMUS cheat handling re custom episodes
Browse files Browse the repository at this point in the history
The IDMUS cheat now respects custom episodes while also attempting
to interpret the given arguments in a vanilla compatible manner.
Obviously this is somewhat limited by the inflexible mechanics of
the cheat mechanism and the fixed/predefined semantics.

These changes mean that it is no longer possible to play music that
is not associated with a map using the IDMUS cheat. (However, these
can still be played using the "playmusic" command, which is a far
more flexible method in any case).

IssueID #1914
  • Loading branch information
danij-deng committed Nov 30, 2014
1 parent ffebf11 commit 012590a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
14 changes: 13 additions & 1 deletion doomsday/plugins/common/include/g_defs.h
Expand Up @@ -30,6 +30,18 @@
*/
ded_t &Defs();

/**
* Returns the total number of 'playable' episodes. A playable episode is one whos
* starting map is defined, and for which map data exists.
*/
int PlayableEpisodeCount();

/**
* Returns the unique identifier of the first playable episode. If no playable episodes
* are defined a zero-length string is returned.
*/
de::String FirstPlayableEpisodeId();

/**
* Translates a map warp number for the @em current episode to a unique map identifier.
*
Expand All @@ -44,7 +56,7 @@ ded_t &Defs();
* @return The unique identifier of the map. If no game session is in progress or the
* warp number is not found, the URI "Maps:" is returned.
*/
de::Uri TranslateMapWarpNumber(de::String const &episodeId, uint warpNumber);
de::Uri TranslateMapWarpNumber(de::String const &episodeId, int warpNumber);

extern "C" {
#endif
Expand Down
33 changes: 32 additions & 1 deletion doomsday/plugins/common/src/g_defs.cpp
Expand Up @@ -58,7 +58,38 @@ void GetDefState(char const *def, int *val)
if(*val < 0) *val = 0;
}

de::Uri TranslateMapWarpNumber(String const &episodeId, uint warpNumber)
int PlayableEpisodeCount()
{
int count = 0;
DictionaryValue::Elements const &episodesById = Defs().episodes.lookup("id").elements();
for(auto const &pair : episodesById)
{
Record const &episodeDef = *pair.second->as<RecordValue>().record();
de::Uri startMap(episodeDef.gets("startMap"), RC_NULL);
if(P_MapExists(startMap.compose().toUtf8().constData()))
{
count += 1;
}
}
return count;
}

String FirstPlayableEpisodeId()
{
DictionaryValue::Elements const &episodesById = Defs().episodes.lookup("id").elements();
for(auto const &pair : episodesById)
{
Record const &episodeDef = *pair.second->as<RecordValue>().record();
de::Uri startMap(episodeDef.gets("startMap"), RC_NULL);
if(P_MapExists(startMap.compose().toUtf8().constData()))
{
return episodeDef.gets("id");
}
}
return ""; // Not found.
}

de::Uri TranslateMapWarpNumber(String const &episodeId, int warpNumber)
{
if(Record const *rec = Defs().episodes.tryFind("id", episodeId))
{
Expand Down
34 changes: 27 additions & 7 deletions doomsday/plugins/doom/src/m_cheat.cpp
Expand Up @@ -30,6 +30,7 @@
#include "d_net.h"
#include "dmu_lib.h"
#include "g_eventsequence.h"
#include "g_defs.h"
#include "gamesession.h"
#include "hu_msg.h"
#include "p_user.h"
Expand All @@ -54,16 +55,35 @@ CHEAT_FUNC(Music)

player_t *plr = &players[player];

int musnum;
if(gameModeBits & GM_ANY_DOOM2)
musnum = (args[0] - '0') * 10 + (args[1] - '0');
int const numEpisodes = PlayableEpisodeCount();
if(!numEpisodes) return false;

// The number of episodes determines how to interpret the arguments.
/// @note Logic here aims to be somewhat vanilla compatible, yet offer
/// a limited degree of support for custom episodes. The "playmusic"
/// cmd is a far more flexible method of changing music.
String episodeId;
int warpNumber;
if(numEpisodes > 1)
{
episodeId = String::number(args[0]);
warpNumber = args[1];
}
else
musnum = (args[0] - '1') * 9 + (args[1] - '0');
{
episodeId = FirstPlayableEpisodeId();
warpNumber = (args[0] - '0') * 10 + (args[1] - '0');
}

if(S_StartMusicNum(musnum, true))
// Lookup and try to enqueue the Music for the referenced episode and map.
de::Uri const mapUri = TranslateMapWarpNumber(episodeId, warpNumber);
if(Record const *mapInfo = Defs().mapInfos.tryFind("id", mapUri.compose()))
{
P_SetMessage(plr, LMF_NO_HIDE, STSTR_MUS);
return true;
if(S_StartMusic(mapInfo->gets("music").toUtf8().constData(), true /*loop it*/))
{
P_SetMessage(plr, LMF_NO_HIDE, STSTR_MUS);
return true;
}
}

P_SetMessage(plr, LMF_NO_HIDE, STSTR_NOMUS);
Expand Down

0 comments on commit 012590a

Please sign in to comment.