- move conversation ID definition to MAPINFO as well. Uses the newly added filter feature to handle the teaser differences.

This commit is contained in:
Christoph Oelckers 2015-04-05 00:31:15 +02:00
commit b6a4511dd1
46 changed files with 709 additions and 374 deletions

View file

@ -328,6 +328,7 @@ PClass *PClass::CreateDerivedClass (FName name, unsigned int size)
info->Class = type;
info->GameFilter = GAME_Any;
info->SpawnID = 0;
info->ConversationID = 0;
info->DoomEdNum = -1;
info->OwnedStates = NULL;
info->NumOwnedStates = 0;
@ -423,6 +424,7 @@ void PClass::InitializeActorInfo ()
info->Class = this;
info->GameFilter = GAME_Any;
info->SpawnID = 0;
info->ConversationID = 0;
info->DoomEdNum = -1;
info->OwnedStates = NULL;
info->NumOwnedStates = 0;

View file

@ -46,6 +46,9 @@
#include "zstring.h"
#include "vectors.h"
struct PClass;
typedef TMap<int, const PClass *> FClassMap;
// Since this file is included by everything, it seems an appropriate place
// to check the NOASM/USEASM macros.

View file

@ -106,6 +106,7 @@ struct FMapInfoParser
void ParseIntermission();
void ParseDoomEdNums();
void ParseSpawnNums();
void ParseConversationIDs();
void ParseAMColors(bool);
FName CheckEndSequence();
FName ParseEndGame();

View file

@ -1900,6 +1900,18 @@ void FMapInfoParser::ParseMapInfo (int lump, level_info_t &gamedefaults, level_i
sc.ScriptError("spawnnums definitions not supported with old MAPINFO syntax");
}
}
else if (sc.Compare("conversationids"))
{
if (format_type != FMT_Old)
{
format_type = FMT_New;
ParseConversationIDs();
}
else
{
sc.ScriptError("conversationids definitions not supported with old MAPINFO syntax");
}
}
else if (sc.Compare("automap") || sc.Compare("automap_overlay"))
{
if (format_type != FMT_Old)

View file

@ -156,6 +156,15 @@ void FActorInfo::RegisterIDs ()
{
const PClass *cls = PClass::FindClass(Class->TypeName);
// Conversation IDs have never been filtered by game so we cannot start doing that.
if (ConversationID > 0)
{
StrifeTypes[ConversationID] = cls;
if (cls != Class)
{
Printf(TEXTCOLOR_RED"Conversation ID %d refers to hidden class type '%s'\n", SpawnID, cls->TypeName.GetChars());
}
}
if (GameFilter == GAME_Any || (GameFilter & gameinfo.gametype))
{
if (SpawnID > 0)
@ -184,7 +193,6 @@ void FActorInfo::RegisterIDs ()
}
}
}
// Fill out the list for Chex Quest with Doom's actors
}
//==========================================================================

View file

@ -266,7 +266,8 @@ struct FActorInfo
FActorInfo *Replacee;
int NumOwnedStates;
BYTE GameFilter;
BYTE SpawnID;
WORD SpawnID;
WORD ConversationID;
SWORD DoomEdNum;
FStateLabels *StateList;
DmgFactors *DamageFactors;

View file

@ -60,6 +60,7 @@
#include "farchive.h"
#include "p_lnspec.h"
#include "r_utility.h"
#include "p_local.h"
#include "menu/menu.h"
// The conversations as they exist inside a SCRIPTxx lump.
@ -105,11 +106,10 @@ void GiveSpawner (player_t *player, const PClass *type);
TArray<FStrifeDialogueNode *> StrifeDialogues;
typedef TMap<int, const PClass *> FStrifeTypeMap; // maps conversation IDs to actor classes
typedef TMap<int, int> FDialogueIDMap; // maps dialogue IDs to dialogue array index (for ACS)
typedef TMap<FName, int> FDialogueMap; // maps actor class names to dialogue array index
static FStrifeTypeMap StrifeTypes;
FClassMap StrifeTypes;
static FDialogueIDMap DialogueRoots;
static FDialogueMap ClassRoots;
static int ConversationMenuY;

View file

@ -160,7 +160,8 @@ void P_CheckFakeFloorTriggers (AActor *mo, fixed_t oldz, bool oldz_has_viewheigh
//
// [RH] P_THINGS
//
extern TMap<int, const PClass *> SpawnableThings;
extern FClassMap SpawnableThings;
extern FClassMap StrifeTypes;
bool P_Thing_Spawn (int tid, AActor *source, int type, angle_t angle, bool fog, int newtid);
bool P_Thing_Projectile (int tid, AActor *source, int type, const char * type_name, angle_t angle,

View file

@ -49,18 +49,7 @@
#include "i_system.h"
// Set of spawnable things for the Thing_Spawn and Thing_Projectile specials.
TMap<int, const PClass *> SpawnableThings;
struct MapinfoSpawnItem
{
FName classname; // DECORATE is read after MAPINFO so we do not have the actual classes available here yet.
// These are for error reporting. We must store the file information because it's no longer available when these items get resolved.
FString filename;
int linenum;
};
typedef TMap<int, MapinfoSpawnItem> SpawnMap;
static SpawnMap SpawnablesFromMapinfo;
FClassMap SpawnableThings;
static FRandom pr_leadtarget ("LeadTarget");
@ -543,22 +532,32 @@ const PClass *P_GetSpawnableType(int spawnnum)
return NULL;
}
typedef TMap<int, const PClass *>::Pair SpawnablePair;
struct MapinfoSpawnItem
{
FName classname; // DECORATE is read after MAPINFO so we do not have the actual classes available here yet.
// These are for error reporting. We must store the file information because it's no longer available when these items get resolved.
FString filename;
int linenum;
};
typedef TMap<int, MapinfoSpawnItem> SpawnMap;
static SpawnMap SpawnablesFromMapinfo;
static SpawnMap ConversationIDsFromMapinfo;
static int STACK_ARGS SpawnableSort(const void *a, const void *b)
{
return (*((SpawnablePair **)a))->Key - (*((SpawnablePair **)b))->Key;
return (*((FClassMap::Pair **)a))->Key - (*((FClassMap::Pair **)b))->Key;
}
CCMD (dumpspawnables)
static void DumpClassMap(FClassMap &themap)
{
TMapIterator<int, const PClass *> it(SpawnableThings);
SpawnablePair *pair, **allpairs;
FClassMap::Iterator it(themap);
FClassMap::Pair *pair, **allpairs;
int i = 0;
// Sort into numerical order, since their arrangement in the map can
// be in an unspecified order.
allpairs = new TMap<int, const PClass *>::Pair *[SpawnableThings.CountUsed()];
allpairs = new FClassMap::Pair *[themap.CountUsed()];
while (it.NextPair(pair))
{
allpairs[i++] = pair;
@ -572,7 +571,18 @@ CCMD (dumpspawnables)
delete[] allpairs;
}
void FMapInfoParser::ParseSpawnNums()
CCMD(dumpspawnables)
{
DumpClassMap(SpawnableThings);
}
CCMD (dumpconversationids)
{
DumpClassMap(StrifeTypes);
}
static void ParseSpawnMap(FScanner &sc, SpawnMap & themap, const char *descript)
{
TMap<int, bool> defined;
int error = 0;
@ -581,7 +591,6 @@ void FMapInfoParser::ParseSpawnNums()
editem.filename = sc.ScriptName;
ParseOpenBrace();
while (true)
{
if (sc.CheckString("}")) return;
@ -594,18 +603,18 @@ void FMapInfoParser::ParseSpawnNums()
bool *def = defined.CheckKey(ednum);
if (def != NULL)
{
sc.ScriptMessage("Spawn Number %d defined more than once", ednum);
sc.ScriptMessage("%s %d defined more than once", descript, ednum);
error++;
}
else if (ednum < 0)
{
sc.ScriptMessage("Spawn Number must be positive, got %d", ednum);
sc.ScriptMessage("%s must be positive, got %d", descript, ednum);
error++;
}
defined[ednum] = true;
editem.classname = sc.String;
SpawnablesFromMapinfo.Insert(ednum, editem);
themap.Insert(ednum, editem);
}
else
{
@ -614,14 +623,27 @@ void FMapInfoParser::ParseSpawnNums()
}
if (error > 0)
{
sc.ScriptError("%d errors encountered in SpawnNum definition");
sc.ScriptError("%d errors encountered in %s definition", error, descript);
}
}
void InitSpawnablesFromMapinfo()
void FMapInfoParser::ParseSpawnNums()
{
SpawnableThings.Clear();
SpawnMap::Iterator it(SpawnablesFromMapinfo);
ParseOpenBrace();
ParseSpawnMap(sc, SpawnablesFromMapinfo, "Spawn number");
}
void FMapInfoParser::ParseConversationIDs()
{
ParseOpenBrace();
ParseSpawnMap(sc, ConversationIDsFromMapinfo, "Conversation ID");
}
void InitClassMap(FClassMap &themap, SpawnMap &thedata)
{
themap.Clear();
SpawnMap::Iterator it(thedata);
SpawnMap::Pair *pair;
int error = 0;
@ -638,11 +660,17 @@ void InitSpawnablesFromMapinfo()
error++;
}
}
SpawnableThings.Insert(pair->Key, cls);
themap.Insert(pair->Key, cls);
}
if (error > 0)
{
I_Error("%d unknown actor classes found", error);
}
SpawnablesFromMapinfo.Clear(); // we do not need this any longer
thedata.Clear(); // we do not need this any longer
}
void InitSpawnablesFromMapinfo()
{
InitClassMap(SpawnableThings, SpawnablesFromMapinfo);
InitClassMap(StrifeTypes, ConversationIDsFromMapinfo);
}

View file

@ -404,11 +404,11 @@ DEFINE_INFO_PROPERTY(game, S, Actor)
DEFINE_INFO_PROPERTY(spawnid, I, Actor)
{
PROP_INT_PARM(id, 0);
if (id<0 || id>255)
if (id<0 || id>65535)
{
I_Error ("SpawnID must be in the range [0,255]");
I_Error ("SpawnID must be in the range [0,65535]");
}
else info->SpawnID=(BYTE)id;
else info->SpawnID=(WORD)id;
}
//==========================================================================
@ -420,20 +420,8 @@ DEFINE_INFO_PROPERTY(conversationid, IiI, Actor)
PROP_INT_PARM(id1, 1);
PROP_INT_PARM(id2, 2);
// Handling for Strife teaser IDs - only of meaning for the standard items
// as PWADs cannot be loaded with the teasers.
if (PROP_PARM_COUNT > 1)
{
if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE))
convid=id1;
if ((gameinfo.flags & (GI_SHAREWARE|GI_TEASER2)) == (GI_SHAREWARE|GI_TEASER2))
convid=id2;
}
if (convid <= 0) return; // 0 is not usable because the dialogue scripts use it as 'no object'.
SetStrifeType(convid, info->Class);
if (convid <= 0 || convid > 65535) return; // 0 is not usable because the dialogue scripts use it as 'no object'.
else info->ConversationID=(WORD)convid;
}
//==========================================================================