mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 04:01:31 +00:00
ID24 interlevel lumps implementation
This commit is contained in:
parent
2c9b8f4eec
commit
e88d912892
9 changed files with 605 additions and 65 deletions
|
@ -130,6 +130,24 @@ static FileReader OpenMusic(const char* musicname)
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MusicExists(const char* music_name)
|
||||||
|
{
|
||||||
|
if (music_name == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (FileExists(music_name))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int lumpnum;
|
||||||
|
lumpnum = mus_cb.FindMusic(music_name);
|
||||||
|
if (lumpnum == -1) lumpnum = fileSystem.CheckNumForName(music_name, FileSys::ns_music);
|
||||||
|
if (lumpnum != -1 && fileSystem.FileLength(lumpnum) != 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void S_SetMusicCallbacks(MusicCallbacks* cb)
|
void S_SetMusicCallbacks(MusicCallbacks* cb)
|
||||||
{
|
{
|
||||||
mus_cb = *cb;
|
mus_cb = *cb;
|
||||||
|
|
|
@ -45,6 +45,9 @@ bool S_StartMusic (const char *music_name);
|
||||||
// Start music using <music_name>, and set whether looping
|
// Start music using <music_name>, and set whether looping
|
||||||
bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false);
|
bool S_ChangeMusic (const char *music_name, int order=0, bool looping=true, bool force=false);
|
||||||
|
|
||||||
|
// Check if <music_name> exists
|
||||||
|
bool MusicExists(const char* music_name);
|
||||||
|
|
||||||
void S_RestartMusic ();
|
void S_RestartMusic ();
|
||||||
void S_MIDIDeviceChanged(int newdev);
|
void S_MIDIDeviceChanged(int newdev);
|
||||||
|
|
||||||
|
|
|
@ -197,7 +197,10 @@ void FSerializer::Close()
|
||||||
}
|
}
|
||||||
if (mErrors > 0)
|
if (mErrors > 0)
|
||||||
{
|
{
|
||||||
I_Error("%d errors parsing JSON", mErrors);
|
if (mLumpName.IsNotEmpty())
|
||||||
|
I_Error("%d errors parsing JSON lump %s", mErrors, mLumpName.GetChars());
|
||||||
|
else
|
||||||
|
I_Error("%d errors parsing JSON", mErrors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,6 +334,28 @@ bool FSerializer::HasObject(const char* name)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
bool FSerializer::IsKeyNull(const char* name)
|
||||||
|
{
|
||||||
|
if (isReading())
|
||||||
|
{
|
||||||
|
auto val = r->FindKey(name);
|
||||||
|
if (val != nullptr)
|
||||||
|
{
|
||||||
|
if (val->IsNull())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
void FSerializer::EndObject()
|
void FSerializer::EndObject()
|
||||||
{
|
{
|
||||||
if (isWriting())
|
if (isWriting())
|
||||||
|
|
|
@ -94,6 +94,7 @@ public:
|
||||||
void EndObject();
|
void EndObject();
|
||||||
bool HasKey(const char* name);
|
bool HasKey(const char* name);
|
||||||
bool HasObject(const char* name);
|
bool HasObject(const char* name);
|
||||||
|
bool IsKeyNull(const char* name);
|
||||||
bool BeginArray(const char *name);
|
bool BeginArray(const char *name);
|
||||||
void EndArray();
|
void EndArray();
|
||||||
unsigned GetSize(const char *group);
|
unsigned GetSize(const char *group);
|
||||||
|
@ -225,6 +226,7 @@ public:
|
||||||
|
|
||||||
int mErrors = 0;
|
int mErrors = 0;
|
||||||
int mObjectErrors = 0;
|
int mObjectErrors = 0;
|
||||||
|
FString mLumpName;
|
||||||
};
|
};
|
||||||
|
|
||||||
FSerializer& Serialize(FSerializer& arc, const char* key, char& value, char* defval);
|
FSerializer& Serialize(FSerializer& arc, const char* key, char& value, char* defval);
|
||||||
|
|
|
@ -164,6 +164,20 @@ bool CheckWarpTransMap (FString &mapname, bool substitute)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
|
bool SecretLevelVisited()
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
|
||||||
|
if ((wadlevelinfos[i].flags3 & LEVEL3_SECRET) && (wadlevelinfos[i].flags & LEVEL_VISITED))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
static int FindWadClusterInfo (int cluster)
|
static int FindWadClusterInfo (int cluster)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < wadclusterinfos.Size(); i++)
|
for (unsigned int i = 0; i < wadclusterinfos.Size(); i++)
|
||||||
|
@ -280,6 +294,8 @@ void level_info_t::Reset()
|
||||||
RedirectCVARMapName = "";
|
RedirectCVARMapName = "";
|
||||||
EnterPic = "";
|
EnterPic = "";
|
||||||
ExitPic = "";
|
ExitPic = "";
|
||||||
|
EnterAnim = "";
|
||||||
|
ExitAnim = "";
|
||||||
Intermission = NAME_None;
|
Intermission = NAME_None;
|
||||||
deathsequence = NAME_None;
|
deathsequence = NAME_None;
|
||||||
slideshow = NAME_None;
|
slideshow = NAME_None;
|
||||||
|
@ -1256,6 +1272,20 @@ DEFINE_MAP_OPTION(enterpic, true)
|
||||||
info->EnterPic = parse.sc.String;
|
info->EnterPic = parse.sc.String;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_MAP_OPTION(exitanim, true)
|
||||||
|
{
|
||||||
|
parse.ParseAssign();
|
||||||
|
parse.sc.MustGetString();
|
||||||
|
info->ExitAnim = parse.sc.String;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_MAP_OPTION(enteranim, true)
|
||||||
|
{
|
||||||
|
parse.ParseAssign();
|
||||||
|
parse.sc.MustGetString();
|
||||||
|
info->EnterAnim = parse.sc.String;
|
||||||
|
}
|
||||||
|
|
||||||
DEFINE_MAP_OPTION(specialaction, true)
|
DEFINE_MAP_OPTION(specialaction, true)
|
||||||
{
|
{
|
||||||
parse.ParseAssign();
|
parse.ParseAssign();
|
||||||
|
@ -2601,6 +2631,7 @@ void G_ParseMapInfo (FString basemapinfo)
|
||||||
{
|
{
|
||||||
int lump, lastlump = 0;
|
int lump, lastlump = 0;
|
||||||
level_info_t gamedefaults;
|
level_info_t gamedefaults;
|
||||||
|
TArray<FString> secretMaps;
|
||||||
|
|
||||||
int flags1 = 0, flags2 = 0;
|
int flags1 = 0, flags2 = 0;
|
||||||
if (gameinfo.gametype == GAME_Doom)
|
if (gameinfo.gametype == GAME_Doom)
|
||||||
|
@ -2717,5 +2748,23 @@ void G_ParseMapInfo (FString basemapinfo)
|
||||||
{
|
{
|
||||||
I_FatalError ("You cannot use clearskills in a MAPINFO if you do not define any new skills after it.");
|
I_FatalError ("You cannot use clearskills in a MAPINFO if you do not define any new skills after it.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find any and all secret maps.
|
||||||
|
for (unsigned int i = 0; i < wadlevelinfos.Size(); i++)
|
||||||
|
{
|
||||||
|
if (wadlevelinfos[i].NextSecretMap.IsNotEmpty() && wadlevelinfos[i].NextSecretMap != wadlevelinfos[i].NextMap)
|
||||||
|
{
|
||||||
|
secretMaps.Push(wadlevelinfos[i].NextSecretMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...and then mark them all as secret maps.
|
||||||
|
for (unsigned int i = 0; i < secretMaps.Size(); i++)
|
||||||
|
{
|
||||||
|
auto* li = FindLevelInfo(secretMaps[i].GetChars(), false);
|
||||||
|
if (li)
|
||||||
|
{
|
||||||
|
li->flags3 |= LEVEL3_SECRET;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -269,8 +269,9 @@ enum ELevelFlags : unsigned int
|
||||||
LEVEL3_NOSHADOWMAP = 0x00010000, // disables shadowmaps for a given level.
|
LEVEL3_NOSHADOWMAP = 0x00010000, // disables shadowmaps for a given level.
|
||||||
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
|
LEVEL3_AVOIDMELEE = 0x00020000, // global flag needed for proper MBF support.
|
||||||
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
|
LEVEL3_NOJUMPDOWN = 0x00040000, // only for MBF21. Inverse of MBF's dog_jumping flag.
|
||||||
LEVEL3_LIGHTCREATED = 0x00080000, // a light had been created in the last frame
|
LEVEL3_LIGHTCREATED = 0x00080000, // a light had been created in the last frame
|
||||||
LEVEL3_NOFOGOFWAR = 0x00100000, // disables effect of r_radarclipper CVAR on this map
|
LEVEL3_NOFOGOFWAR = 0x00100000, // disables effect of r_radarclipper CVAR on this map
|
||||||
|
LEVEL3_SECRET = 0x00200000, // level is a secret level
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -389,6 +390,8 @@ struct level_info_t
|
||||||
|
|
||||||
FString EnterPic;
|
FString EnterPic;
|
||||||
FString ExitPic;
|
FString ExitPic;
|
||||||
|
FString EnterAnim;
|
||||||
|
FString ExitAnim;
|
||||||
FString InterMusic;
|
FString InterMusic;
|
||||||
int intermusicorder;
|
int intermusicorder;
|
||||||
TMap <FName, std::pair<FString, int> > MapInterMusic;
|
TMap <FName, std::pair<FString, int> > MapInterMusic;
|
||||||
|
@ -488,6 +491,8 @@ level_info_t *FindLevelInfo (const char *mapname, bool allowdefault=true);
|
||||||
level_info_t *FindLevelByNum (int num);
|
level_info_t *FindLevelByNum (int num);
|
||||||
level_info_t *CheckLevelRedirect (level_info_t *info);
|
level_info_t *CheckLevelRedirect (level_info_t *info);
|
||||||
|
|
||||||
|
bool SecretLevelVisited();
|
||||||
|
|
||||||
FString CalcMapName (int episode, int level);
|
FString CalcMapName (int episode, int level);
|
||||||
|
|
||||||
void G_ClearMapinfo();
|
void G_ClearMapinfo();
|
||||||
|
|
|
@ -52,6 +52,8 @@ struct UMapEntry
|
||||||
char endpic[9] = "";
|
char endpic[9] = "";
|
||||||
char exitpic[9] = "";
|
char exitpic[9] = "";
|
||||||
char enterpic[9] = "";
|
char enterpic[9] = "";
|
||||||
|
char exitanim[9] = "";
|
||||||
|
char enteranim[9] = "";
|
||||||
char interbackdrop[9] = "FLOOR4_8";
|
char interbackdrop[9] = "FLOOR4_8";
|
||||||
char intermusic[9] = "";
|
char intermusic[9] = "";
|
||||||
int partime = 0;
|
int partime = 0;
|
||||||
|
@ -186,6 +188,14 @@ static int ParseStandardProperty(FScanner &scanner, UMapEntry *mape)
|
||||||
{
|
{
|
||||||
ParseLumpName(scanner, mape->enterpic);
|
ParseLumpName(scanner, mape->enterpic);
|
||||||
}
|
}
|
||||||
|
else if (!pname.CompareNoCase("exitanim"))
|
||||||
|
{
|
||||||
|
ParseLumpName(scanner, mape->exitanim);
|
||||||
|
}
|
||||||
|
else if (!pname.CompareNoCase("enteranim"))
|
||||||
|
{
|
||||||
|
ParseLumpName(scanner, mape->enteranim);
|
||||||
|
}
|
||||||
else if (!pname.CompareNoCase("nointermission"))
|
else if (!pname.CompareNoCase("nointermission"))
|
||||||
{
|
{
|
||||||
scanner.MustGetBoolToken();
|
scanner.MustGetBoolToken();
|
||||||
|
@ -443,6 +453,8 @@ void CommitUMapinfo(level_info_t *defaultinfo)
|
||||||
if (map.partime > 0) levelinfo->partime = map.partime;
|
if (map.partime > 0) levelinfo->partime = map.partime;
|
||||||
if (map.enterpic[0]) levelinfo->EnterPic = map.enterpic;
|
if (map.enterpic[0]) levelinfo->EnterPic = map.enterpic;
|
||||||
if (map.exitpic[0]) levelinfo->ExitPic = map.exitpic;
|
if (map.exitpic[0]) levelinfo->ExitPic = map.exitpic;
|
||||||
|
if (map.enteranim[0]) levelinfo->EnterAnim = map.enteranim;
|
||||||
|
if (map.exitanim[0]) levelinfo->ExitAnim = map.exitanim;
|
||||||
/* UMAPINFO's intermusic is for the text screen, not the summary.
|
/* UMAPINFO's intermusic is for the text screen, not the summary.
|
||||||
if (map.intermusic[0])
|
if (map.intermusic[0])
|
||||||
{
|
{
|
||||||
|
|
548
src/wi_stuff.cpp
548
src/wi_stuff.cpp
|
@ -57,6 +57,9 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
|
|
||||||
|
#include "serializer.h"
|
||||||
|
#include "s_music.h"
|
||||||
|
|
||||||
CVAR(Bool, wi_percents, true, CVAR_ARCHIVE)
|
CVAR(Bool, wi_percents, true, CVAR_ARCHIVE)
|
||||||
CVAR(Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
|
CVAR(Bool, wi_showtotaltime, true, CVAR_ARCHIVE)
|
||||||
CVAR(Bool, wi_noautostartmap, false, CVAR_USERINFO | CVAR_ARCHIVE)
|
CVAR(Bool, wi_noautostartmap, false, CVAR_USERINFO | CVAR_ARCHIVE)
|
||||||
|
@ -109,6 +112,8 @@ class DInterBackground : public DObject
|
||||||
{
|
{
|
||||||
ANIM_ALWAYS, // determined by patch entry
|
ANIM_ALWAYS, // determined by patch entry
|
||||||
ANIM_PIC, // continuous
|
ANIM_PIC, // continuous
|
||||||
|
ANIM_FRAME, // determined by frame properties
|
||||||
|
ANIM_NONE, // frozen (used for infinite duration frames)
|
||||||
|
|
||||||
// condition bitflags
|
// condition bitflags
|
||||||
ANIM_IFVISITED = 8,
|
ANIM_IFVISITED = 8,
|
||||||
|
@ -137,13 +142,41 @@ class DInterBackground : public DObject
|
||||||
FString Level;
|
FString Level;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct frame_t
|
||||||
|
{
|
||||||
|
FTextureID image;
|
||||||
|
uint32_t type;
|
||||||
|
// In tics!
|
||||||
|
int duration;
|
||||||
|
int max_duration;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ECondition
|
||||||
|
{
|
||||||
|
COND_NONE = 0, // None.
|
||||||
|
COND_GREATER = 1, // Parameter is greater than current map number.
|
||||||
|
COND_EQUAL = 2, // Parameter is equal to current map number.
|
||||||
|
COND_VISITED = 3, // Map number corresponding to parameter is visited.
|
||||||
|
COND_NOTSECRET = 4, // Current map is not a secret one.
|
||||||
|
COND_SECRETVISTED = 5, // Any secret map was visited.
|
||||||
|
COND_TALLY = 6, // Tally screen.
|
||||||
|
COND_ENTERING = 7, // "Entering" screen.
|
||||||
|
};
|
||||||
|
|
||||||
|
struct condition_t
|
||||||
|
{
|
||||||
|
ECondition condition;
|
||||||
|
int param;
|
||||||
|
};
|
||||||
|
|
||||||
struct in_anim_t
|
struct in_anim_t
|
||||||
{
|
{
|
||||||
int type; // Made an int so I can use '|'
|
int type; // Made an int so I can use '|'
|
||||||
int period; // period in tics between animations
|
int period; // period in tics between animations
|
||||||
yahpt_t loc; // location of animation
|
yahpt_t loc; // location of animation
|
||||||
int data; // ALWAYS: n/a, RANDOM: period deviation (<256)
|
int data; // ALWAYS: n/a, RANDOM: period deviation (<256)
|
||||||
TArray<FTextureID> frames; // actual graphics for frames of animations
|
TArray<frame_t> frames; // actual graphics for frames of animations
|
||||||
|
TArray<condition_t> conditions; // conditions to display the animation
|
||||||
|
|
||||||
// following must be initialized to zero before use!
|
// following must be initialized to zero before use!
|
||||||
int nexttic; // next value of bcnt (used in conjunction with period)
|
int nexttic; // next value of bcnt (used in conjunction with period)
|
||||||
|
@ -162,9 +195,15 @@ class DInterBackground : public DObject
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct in_layer_t
|
||||||
|
{
|
||||||
|
TArray<in_anim_t> anims;
|
||||||
|
TArray<condition_t> conditions; // conditions to display the animations.
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TArray<lnode_t> lnodes;
|
TArray<lnode_t> lnodes;
|
||||||
TArray<in_anim_t> anims;
|
TArray<in_layer_t> layers;
|
||||||
int bcnt = 0; // used for timing of background animation
|
int bcnt = 0; // used for timing of background animation
|
||||||
TArray<FTextureID> yah; // You Are Here graphic
|
TArray<FTextureID> yah; // You Are Here graphic
|
||||||
FTextureID splat{}; // splat
|
FTextureID splat{}; // splat
|
||||||
|
@ -174,12 +213,14 @@ private:
|
||||||
int bgwidth = -1;
|
int bgwidth = -1;
|
||||||
int bgheight = -1;
|
int bgheight = -1;
|
||||||
bool tilebackground = false;
|
bool tilebackground = false;
|
||||||
|
FString muslump;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DInterBackground(wbstartstruct_t *wbst);
|
DInterBackground(wbstartstruct_t *wbst);
|
||||||
bool LoadBackground(bool isenterpic);
|
bool LoadBackground(bool isenterpic);
|
||||||
|
bool IsUsingMusic();
|
||||||
void updateAnimatedBack();
|
void updateAnimatedBack();
|
||||||
void drawBackground(int state, bool drawsplat, bool snl_pointeron);
|
void drawBackground(int state, bool drawsplat, bool snl_pointeron);
|
||||||
|
|
||||||
|
@ -242,6 +283,70 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
// Draws the splats and the 'You are here' arrows
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
bool ConditionsMet(int state, TArray<condition_t>& conditions)
|
||||||
|
{
|
||||||
|
for (auto& condition : conditions)
|
||||||
|
{
|
||||||
|
switch (condition.condition)
|
||||||
|
{
|
||||||
|
case ECondition::COND_NONE:
|
||||||
|
break;
|
||||||
|
case ECondition::COND_EQUAL:
|
||||||
|
{
|
||||||
|
auto* li = FindLevelInfo(state != StatCount ? wbs->next.GetChars() : wbs->current.GetChars());
|
||||||
|
if (!li)
|
||||||
|
return false;
|
||||||
|
if (li->levelnum != condition.param)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ECondition::COND_GREATER:
|
||||||
|
{
|
||||||
|
auto* li = FindLevelInfo(state != StatCount ? wbs->next.GetChars() : wbs->current.GetChars());
|
||||||
|
if (!li)
|
||||||
|
return false;
|
||||||
|
if (li->levelnum <= condition.param)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ECondition::COND_VISITED:
|
||||||
|
{
|
||||||
|
auto* li = FindLevelByNum(condition.param);
|
||||||
|
if (li == NULL || !(li->flags & LEVEL_VISITED))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ECondition::COND_NOTSECRET:
|
||||||
|
{
|
||||||
|
auto* li = FindLevelInfo(state != StatCount ? wbs->next.GetChars() : wbs->current.GetChars());
|
||||||
|
if (!li)
|
||||||
|
return false;
|
||||||
|
if (li->flags3 & LEVEL3_SECRET)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ECondition::COND_SECRETVISTED:
|
||||||
|
if (!SecretLevelVisited())
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case ECondition::COND_TALLY:
|
||||||
|
if (state != StatCount)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case ECondition::COND_ENTERING:
|
||||||
|
if (state == StatCount)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DInterBackground:: DInterBackground(wbstartstruct_t *wbst)
|
DInterBackground:: DInterBackground(wbstartstruct_t *wbst)
|
||||||
|
@ -270,11 +375,13 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
{
|
{
|
||||||
const char* lumpname = nullptr;
|
const char* lumpname = nullptr;
|
||||||
const char* exitpic = nullptr;
|
const char* exitpic = nullptr;
|
||||||
|
const char* exitanim = nullptr;
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
in_anim_t an;
|
in_anim_t an;
|
||||||
lnode_t pt;
|
lnode_t pt;
|
||||||
FTextureID texture;
|
FTextureID texture;
|
||||||
bool noautostartmap = false;
|
bool noautostartmap = false;
|
||||||
|
bool id24anim = false;
|
||||||
|
|
||||||
bcnt = 0;
|
bcnt = 0;
|
||||||
|
|
||||||
|
@ -284,8 +391,17 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
level_info_t* li = FindLevelInfo(wbs->current.GetChars());
|
level_info_t* li = FindLevelInfo(wbs->current.GetChars());
|
||||||
if (li != nullptr)
|
if (li != nullptr)
|
||||||
{
|
{
|
||||||
exitpic = li->ExitPic.GetChars();
|
if (li->ExitAnim.IsNotEmpty())
|
||||||
if (li->ExitPic.IsNotEmpty()) tilebackground = false;
|
{
|
||||||
|
id24anim = true;
|
||||||
|
exitpic = li->ExitAnim.GetChars();
|
||||||
|
tilebackground = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
exitpic = li->ExitPic.GetChars();
|
||||||
|
if (li->ExitPic.IsNotEmpty()) tilebackground = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lumpname = exitpic;
|
lumpname = exitpic;
|
||||||
|
|
||||||
|
@ -294,8 +410,17 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
level_info_t* li = FindLevelInfo(wbs->next.GetChars());
|
level_info_t* li = FindLevelInfo(wbs->next.GetChars());
|
||||||
if (li != NULL)
|
if (li != NULL)
|
||||||
{
|
{
|
||||||
lumpname = li->EnterPic.GetChars();
|
if (li->EnterAnim.IsNotEmpty())
|
||||||
if (li->EnterPic.IsNotEmpty()) tilebackground = false;
|
{
|
||||||
|
id24anim = true;
|
||||||
|
lumpname = li->EnterAnim.GetChars();
|
||||||
|
tilebackground = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lumpname = li->EnterPic.GetChars();
|
||||||
|
if (li->EnterPic.IsNotEmpty()) tilebackground = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,12 +507,251 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
}
|
}
|
||||||
|
|
||||||
lnodes.Clear();
|
lnodes.Clear();
|
||||||
anims.Clear();
|
layers.Clear();
|
||||||
yah.Clear();
|
yah.Clear();
|
||||||
splat.SetInvalid();
|
splat.SetInvalid();
|
||||||
|
if (!id24anim)
|
||||||
|
layers.Resize(1);
|
||||||
|
|
||||||
|
if (id24anim)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int lumpnum = fileSystem.CheckNumForFullName(lumpname, true);
|
||||||
|
if (lumpnum == -1)
|
||||||
|
{
|
||||||
|
I_Error("Intermission animation lump %s not found!", lumpname);
|
||||||
|
}
|
||||||
|
auto data = fileSystem.ReadFile(lumpnum);
|
||||||
|
FSerializer jsonReader;
|
||||||
|
jsonReader.mLumpName = fileSystem.GetFileFullPath(lumpnum);
|
||||||
|
lumpname = jsonReader.mLumpName.GetChars();
|
||||||
|
if (jsonReader.OpenReader(data.string(), data.size()))
|
||||||
|
{
|
||||||
|
FString type = jsonReader.GetString("type");
|
||||||
|
if (type.Compare("interlevel"))
|
||||||
|
{
|
||||||
|
I_Error("Interlevel lump %s is not interlevel!", lumpname);
|
||||||
|
}
|
||||||
|
if (jsonReader.BeginObject("data"))
|
||||||
|
{
|
||||||
|
FString music = jsonReader.GetString("music");
|
||||||
|
if (music.IsEmpty())
|
||||||
|
{
|
||||||
|
I_Error("No music lump specified for intermission animation %s!", lumpname);
|
||||||
|
}
|
||||||
|
muslump = music;
|
||||||
|
if (!MusicExists(muslump.GetChars()))
|
||||||
|
{
|
||||||
|
I_Error("Music lump %s not found!", muslump.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for background lump.
|
||||||
|
FString backgroundimage = jsonReader.GetString("backgroundimage");
|
||||||
|
texture = TexMan.CheckForTexture(backgroundimage.GetChars(), ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
|
if (!texture.isValid())
|
||||||
|
{
|
||||||
|
if (backgroundimage.IsEmpty())
|
||||||
|
{
|
||||||
|
I_Error("No background image specified for intermission animation %s!", lumpname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
I_Error("Texture %s not found!", backgroundimage.GetChars());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jsonReader.IsKeyNull("layers") && jsonReader.BeginArray("layers"))
|
||||||
|
{
|
||||||
|
int size = jsonReader.ArraySize();
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
I_Error("Zero-length 'layers' array in %s", lumpname);
|
||||||
|
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
if (jsonReader.BeginObject(nullptr))
|
||||||
|
{
|
||||||
|
layers.Reserve(1);
|
||||||
|
auto& layer = layers.back();
|
||||||
|
if (!jsonReader.IsKeyNull("conditions") && jsonReader.BeginArray("conditions"))
|
||||||
|
{
|
||||||
|
int condition_size = jsonReader.ArraySize();
|
||||||
|
if (condition_size == 0)
|
||||||
|
{
|
||||||
|
I_Error("Condition array empty and not null for layer %d in lump %s", layers.Size(), lumpname);
|
||||||
|
}
|
||||||
|
for (int j = 0; j < condition_size; j++)
|
||||||
|
{
|
||||||
|
if (jsonReader.BeginObject(nullptr))
|
||||||
|
{
|
||||||
|
ECondition cond = COND_NONE;
|
||||||
|
int param = 0;
|
||||||
|
::Serialize(jsonReader, "condition", (int&)cond, nullptr);
|
||||||
|
::Serialize(jsonReader, "param", param, nullptr);
|
||||||
|
layer.conditions.Push(condition_t{ cond, param });
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read anims.
|
||||||
|
if (jsonReader.BeginArray("anims"))
|
||||||
|
{
|
||||||
|
int anim_size = jsonReader.ArraySize();
|
||||||
|
if (anim_size == 0)
|
||||||
|
{
|
||||||
|
I_Error("No animations defined for layer %d in lump %s", layers.Size(), lumpname);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < anim_size; j++)
|
||||||
|
{
|
||||||
|
if (jsonReader.BeginObject(nullptr))
|
||||||
|
{
|
||||||
|
layer.anims.Reserve(1);
|
||||||
|
auto& anim = layer.anims.back();
|
||||||
|
|
||||||
|
anim.Reset();
|
||||||
|
anim.type = ANIM_FRAME;
|
||||||
|
anim.ctr = 0;
|
||||||
|
anim.data = 0;
|
||||||
|
|
||||||
|
::Serialize(jsonReader, "x", anim.loc.x, nullptr);
|
||||||
|
::Serialize(jsonReader, "y", anim.loc.y, nullptr);
|
||||||
|
|
||||||
|
if (!jsonReader.IsKeyNull("conditions") && jsonReader.BeginArray("conditions"))
|
||||||
|
{
|
||||||
|
int condition_size = jsonReader.ArraySize();
|
||||||
|
if (condition_size == 0)
|
||||||
|
{
|
||||||
|
I_Error("Condition array empty and not null for anim %d, layer %d in lump %s", layer.anims.Size(), layers.Size(), lumpname);
|
||||||
|
}
|
||||||
|
for (int k = 0; k < condition_size; k++)
|
||||||
|
{
|
||||||
|
if (jsonReader.BeginObject(nullptr))
|
||||||
|
{
|
||||||
|
ECondition cond = COND_NONE;
|
||||||
|
int param = 0;
|
||||||
|
::Serialize(jsonReader, "condition", (int&)cond, nullptr);
|
||||||
|
::Serialize(jsonReader, "param", param, nullptr);
|
||||||
|
anim.conditions.Push(condition_t{ cond, param });
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonReader.BeginArray("frames"))
|
||||||
|
{
|
||||||
|
int frames = jsonReader.ArraySize();
|
||||||
|
|
||||||
|
if (frames == 0)
|
||||||
|
{
|
||||||
|
I_Error("No frames defined for anim %d, layer %d in lump %s", layer.anims.Size(), layers.Size(), lumpname);
|
||||||
|
}
|
||||||
|
for (int k = 0; k < frames; k++)
|
||||||
|
{
|
||||||
|
if (jsonReader.BeginObject(nullptr))
|
||||||
|
{
|
||||||
|
double duration = 0.0;
|
||||||
|
double maxduration = 0.0;
|
||||||
|
anim.frames.Reserve(1);
|
||||||
|
auto& frame = anim.frames.back();
|
||||||
|
|
||||||
|
::Serialize(jsonReader, "duration", duration, nullptr);
|
||||||
|
::Serialize(jsonReader, "maxduration", maxduration, nullptr);
|
||||||
|
::Serialize(jsonReader, "type", frame.type, nullptr);
|
||||||
|
|
||||||
|
FString image = jsonReader.GetString("image");
|
||||||
|
if (image.IsEmpty())
|
||||||
|
{
|
||||||
|
I_Error("No image defined for frame %d, anim %d, layer %d in lump %s", anim.frames.Size(), layer.anims.Size(), layers.Size(), lumpname);
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.image = TexMan.CheckForTexture(image.GetChars(), ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
|
if (!frame.image.isValid())
|
||||||
|
{
|
||||||
|
I_Error("Texture '%s' not found!", image.GetChars());
|
||||||
|
}
|
||||||
|
|
||||||
|
frame.duration = round(duration * (double)TICRATE);
|
||||||
|
frame.max_duration = round(maxduration * (double)TICRATE);
|
||||||
|
|
||||||
|
if (frame.duration <= 0 && duration > 0.0)
|
||||||
|
{
|
||||||
|
frame.duration = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.max_duration <= 0 && maxduration > 0.0)
|
||||||
|
{
|
||||||
|
frame.max_duration = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (anim.frames.Size() == 1)
|
||||||
|
{
|
||||||
|
if (frame.type & 0x1000)
|
||||||
|
{
|
||||||
|
frame.type &= ~0x1000;
|
||||||
|
anim.nexttic = 1 + (M_Random() % frame.duration);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (frame.type)
|
||||||
|
{
|
||||||
|
case 0x1:
|
||||||
|
anim.type = ANIM_NONE;
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
anim.nexttic = 1 + M_Random(frame.max_duration - frame.duration + 1) + frame.duration;
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
anim.nexttic = 1 + frame.duration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonReader.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsonReader.EndArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonReader.EndObject();
|
||||||
|
}
|
||||||
|
jsonReader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is deliberate. Errors coming from here shouldn't cause a console abort.
|
||||||
|
catch (CRecoverableError& error)
|
||||||
|
{
|
||||||
|
Printf(TEXTCOLOR_RED "Failed to parse intermission anim definition %s: %s.\nFalling back to non-anim definitions.\n", lumpname, error.GetMessage());
|
||||||
|
|
||||||
|
if (isenterpic)
|
||||||
|
li->EnterAnim = "";
|
||||||
|
else
|
||||||
|
li->ExitAnim = "";
|
||||||
|
|
||||||
|
return LoadBackground(isenterpic);
|
||||||
|
}
|
||||||
|
}
|
||||||
// a name with a starting '$' indicates an intermission script
|
// a name with a starting '$' indicates an intermission script
|
||||||
if (*lumpname != '$')
|
else if (*lumpname != '$')
|
||||||
{
|
{
|
||||||
texture = TexMan.CheckForTexture(lumpname, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
texture = TexMan.CheckForTexture(lumpname, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
}
|
}
|
||||||
|
@ -520,18 +884,20 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
if (!sc.CheckString("{"))
|
if (!sc.CheckString("{"))
|
||||||
{
|
{
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
an.frames.Push(TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny));
|
auto textureId = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
|
an.frames.Push(frame_t{ textureId, 0, 0, 0 });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (!sc.CheckString("}"))
|
while (!sc.CheckString("}"))
|
||||||
{
|
{
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
an.frames.Push(TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny));
|
auto textureId = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
|
an.frames.Push(frame_t{ textureId, 0, 0, 0 });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
an.ctr = -1;
|
an.ctr = -1;
|
||||||
anims.Push(an);
|
layers[0].anims.Push(an);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 13: // Pic
|
case 13: // Pic
|
||||||
|
@ -542,8 +908,8 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
an.loc.y = sc.Number;
|
an.loc.y = sc.Number;
|
||||||
sc.MustGetString();
|
sc.MustGetString();
|
||||||
an.frames.Reserve(1); // allocate exactly one element
|
an.frames.Reserve(1); // allocate exactly one element
|
||||||
an.frames[0] = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
an.frames[0].image = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch, FTextureManager::TEXMAN_TryAny);
|
||||||
anims.Push(an);
|
layers[0].anims.Push(an);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -554,6 +920,7 @@ bool DInterBackground::LoadBackground(bool isenterpic)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
Printf("Intermission script %s not found!\n", lumpname + 1);
|
Printf("Intermission script %s not found!\n", lumpname + 1);
|
||||||
texture = TexMan.GetTextureID("INTERPIC", ETextureType::MiscPatch);
|
texture = TexMan.GetTextureID("INTERPIC", ETextureType::MiscPatch);
|
||||||
}
|
}
|
||||||
|
@ -585,27 +952,59 @@ void DInterBackground::updateAnimatedBack()
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
bcnt++;
|
bcnt++;
|
||||||
for (i = 0; i<anims.Size(); i++)
|
if (bcnt == 1 && muslump.IsNotEmpty())
|
||||||
{
|
{
|
||||||
in_anim_t * a = &anims[i];
|
S_ChangeMusic(muslump.GetChars());
|
||||||
switch (a->type & ANIM_TYPE)
|
}
|
||||||
|
|
||||||
|
for (auto& layer : layers)
|
||||||
|
{
|
||||||
|
auto& anims = layer.anims;
|
||||||
|
for (i = 0; i < anims.Size(); i++)
|
||||||
{
|
{
|
||||||
case ANIM_ALWAYS:
|
in_anim_t* a = &anims[i];
|
||||||
if (bcnt >= a->nexttic)
|
switch (a->type & ANIM_TYPE)
|
||||||
{
|
{
|
||||||
if (++a->ctr >= (int)a->frames.Size())
|
case ANIM_NONE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ANIM_FRAME:
|
||||||
|
if (bcnt >= a->nexttic)
|
||||||
{
|
{
|
||||||
if (a->data == 0) a->ctr = 0;
|
if (++a->ctr >= (int)a->frames.Size())
|
||||||
else a->ctr--;
|
a->ctr = 0;
|
||||||
|
|
||||||
|
switch (a->frames[a->ctr].type & 0x7) {
|
||||||
|
case 0x1:
|
||||||
|
a->type &= ANIM_CONDITION;
|
||||||
|
a->type = ANIM_NONE;
|
||||||
|
break;
|
||||||
|
case 0x4:
|
||||||
|
a->nexttic = bcnt + M_Random(a->frames[a->ctr].max_duration - a->frames[a->ctr].duration + 1) + a->frames[a->ctr].duration;
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
a->nexttic = bcnt + a->frames[a->ctr].duration;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
a->nexttic = bcnt + a->period;
|
break;
|
||||||
|
case ANIM_ALWAYS:
|
||||||
|
if (bcnt >= a->nexttic)
|
||||||
|
{
|
||||||
|
if (++a->ctr >= (int)a->frames.Size())
|
||||||
|
{
|
||||||
|
if (a->data == 0) a->ctr = 0;
|
||||||
|
else a->ctr--;
|
||||||
|
}
|
||||||
|
a->nexttic = bcnt + a->period;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ANIM_PIC:
|
||||||
|
a->ctr = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
case ANIM_PIC:
|
|
||||||
a->ctr = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -656,51 +1055,59 @@ void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointe
|
||||||
ClearRect(twod, 0, 0, twod->GetWidth(), twod->GetHeight(), 0, 0);
|
ClearRect(twod, 0, 0, twod->GetWidth(), twod->GetHeight(), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i<anims.Size(); i++)
|
for (auto& layer : layers)
|
||||||
{
|
{
|
||||||
in_anim_t * a = &anims[i];
|
auto& anims = layer.anims;
|
||||||
level_info_t *li;
|
|
||||||
|
|
||||||
switch (a->type & ANIM_CONDITION)
|
if (!ConditionsMet(state, layer.conditions))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (i = 0; i < anims.Size(); i++)
|
||||||
{
|
{
|
||||||
case ANIM_IFVISITED:
|
in_anim_t* a = &anims[i];
|
||||||
li = FindLevelInfo(a->LevelName.GetChars());
|
level_info_t* li;
|
||||||
if (li == NULL || !(li->flags & LEVEL_VISITED)) continue;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ANIM_IFNOTVISITED:
|
switch (a->type & ANIM_CONDITION)
|
||||||
li = FindLevelInfo(a->LevelName.GetChars());
|
{
|
||||||
if (li == NULL || (li->flags & LEVEL_VISITED)) continue;
|
case ANIM_IFVISITED:
|
||||||
break;
|
li = FindLevelInfo(a->LevelName.GetChars());
|
||||||
|
if (li == NULL || !(li->flags & LEVEL_VISITED)) continue;
|
||||||
|
break;
|
||||||
|
|
||||||
// StatCount means 'leaving' - everything else means 'entering'!
|
case ANIM_IFNOTVISITED:
|
||||||
case ANIM_IFENTERING:
|
li = FindLevelInfo(a->LevelName.GetChars());
|
||||||
if (state == StatCount || a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
if (li == NULL || (li->flags & LEVEL_VISITED)) continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ANIM_IFNOTENTERING:
|
// StatCount means 'leaving' - everything else means 'entering'!
|
||||||
if (state != StatCount && !a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
case ANIM_IFENTERING:
|
||||||
break;
|
if (state == StatCount || a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
||||||
|
break;
|
||||||
|
|
||||||
case ANIM_IFLEAVING:
|
case ANIM_IFNOTENTERING:
|
||||||
if (state != StatCount || a->LevelName.CompareNoCase(wbs->current, 8)) continue;
|
if (state != StatCount && !a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ANIM_IFNOTLEAVING:
|
case ANIM_IFLEAVING:
|
||||||
if (state == StatCount && !a->LevelName.CompareNoCase(wbs->current, 8)) continue;
|
if (state != StatCount || a->LevelName.CompareNoCase(wbs->current, 8)) continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ANIM_IFTRAVELLING:
|
case ANIM_IFNOTLEAVING:
|
||||||
if (a->LevelName2.CompareNoCase(wbs->current, 8) || a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
if (state == StatCount && !a->LevelName.CompareNoCase(wbs->current, 8)) continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ANIM_IFNOTTRAVELLING:
|
case ANIM_IFTRAVELLING:
|
||||||
if (!a->LevelName2.CompareNoCase(wbs->current, 8) && !a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
if (a->LevelName2.CompareNoCase(wbs->current, 8) || a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ANIM_IFNOTTRAVELLING:
|
||||||
|
if (!a->LevelName2.CompareNoCase(wbs->current, 8) && !a->LevelName.CompareNoCase(wbs->next, 8)) continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (a->ctr >= 0 && ConditionsMet(state, a->conditions))
|
||||||
|
DrawTexture(twod, a->frames[a->ctr].image, false, a->loc.x, a->loc.y,
|
||||||
|
DTA_VirtualWidthF, animwidth, DTA_VirtualHeightF, animheight, DTA_FullscreenScale, FSMode_ScaleToFit43, TAG_DONE);
|
||||||
}
|
}
|
||||||
if (a->ctr >= 0)
|
|
||||||
DrawTexture(twod, a->frames[a->ctr], false, a->loc.x, a->loc.y,
|
|
||||||
DTA_VirtualWidthF, animwidth, DTA_VirtualHeightF, animheight, DTA_FullscreenScale, FSMode_ScaleToFit43, TAG_DONE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawsplat)
|
if (drawsplat)
|
||||||
|
@ -731,6 +1138,23 @@ DEFINE_ACTION_FUNCTION(DInterBackground, drawBackground)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//====================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//====================================================================
|
||||||
|
|
||||||
|
bool DInterBackground::IsUsingMusic()
|
||||||
|
{
|
||||||
|
return muslump.IsNotEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(DInterBackground, IsUsingMusic)
|
||||||
|
{
|
||||||
|
PARAM_SELF_PROLOGUE(DInterBackground);
|
||||||
|
ACTION_RETURN_BOOL(self->IsUsingMusic());
|
||||||
|
}
|
||||||
|
|
||||||
IMPLEMENT_CLASS(DInterBackground, true, false)
|
IMPLEMENT_CLASS(DInterBackground, true, false)
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
|
@ -6,6 +6,7 @@ class InterBackground native ui version("2.5")
|
||||||
native virtual bool LoadBackground(bool isenterpic);
|
native virtual bool LoadBackground(bool isenterpic);
|
||||||
native virtual void updateAnimatedBack();
|
native virtual void updateAnimatedBack();
|
||||||
native virtual void drawBackground(int CurState, bool drawsplat, bool snl_pointeron);
|
native virtual void drawBackground(int CurState, bool drawsplat, bool snl_pointeron);
|
||||||
|
native virtual bool IsUsingMusic();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is obsolete. Hopefully this was never used...
|
// This is obsolete. Hopefully this was never used...
|
||||||
|
@ -825,7 +826,8 @@ class StatusScreen : ScreenJob abstract version("2.5")
|
||||||
|
|
||||||
virtual void StartMusic()
|
virtual void StartMusic()
|
||||||
{
|
{
|
||||||
Level.SetInterMusic(wbs.next);
|
if (!bg.IsUsingMusic())
|
||||||
|
Level.SetInterMusic(wbs.next);
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================================================================
|
//====================================================================
|
||||||
|
|
Loading…
Reference in a new issue