mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-01-18 07:02:03 +00:00
- allow multiple line IDs as well using the same method as for sector tags.
This commit is contained in:
parent
b921157f57
commit
db61c1cb57
16 changed files with 159 additions and 90 deletions
|
@ -119,6 +119,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
||||||
blockhitscan = <bool>; // Line blocks hitscan attacks
|
blockhitscan = <bool>; // Line blocks hitscan attacks
|
||||||
locknumber = <int>; // Line special is locked
|
locknumber = <int>; // Line special is locked
|
||||||
arg0str = <string>; // Alternate string-based version of arg0
|
arg0str = <string>; // Alternate string-based version of arg0
|
||||||
|
moreids = <string>; // Additional line IDs, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||||
|
|
||||||
transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25)
|
transparent = <bool>; // true = line is a Strife transparent line (alpha 0.25)
|
||||||
|
|
||||||
|
@ -201,6 +202,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
|
||||||
// sound sequence thing in the sector will override this property.
|
// sound sequence thing in the sector will override this property.
|
||||||
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
hidden = <bool>; // if true this sector will not be drawn on the textured automap.
|
||||||
waterzone = <bool>; // Sector is under water and swimmable
|
waterzone = <bool>; // Sector is under water and swimmable
|
||||||
|
moreids = <string>; // Additional sector IDs/tags, specified as a space separated list of numbers (e.g. "2 666 1003 4505")
|
||||||
|
|
||||||
* Note about dropactors
|
* Note about dropactors
|
||||||
|
|
||||||
|
@ -370,6 +372,9 @@ Added transparent line property (to be folded back to core UDMF standard), and h
|
||||||
Added plane equations for sector slopes. (Please read carefully to ensure proper use!)
|
Added plane equations for sector slopes. (Please read carefully to ensure proper use!)
|
||||||
Changed language describing the DIALOGUE lump to mention USDF as an option.
|
Changed language describing the DIALOGUE lump to mention USDF as an option.
|
||||||
|
|
||||||
|
1.25 19.04.2015
|
||||||
|
Added 'moreids' for linedefs and sectors.
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
EOF
|
EOF
|
||||||
===============================================================================
|
===============================================================================
|
||||||
|
|
|
@ -2235,7 +2235,7 @@ void FParser::SF_LineTrigger()
|
||||||
maplinedef_t mld;
|
maplinedef_t mld;
|
||||||
mld.special=intvalue(t_argv[0]);
|
mld.special=intvalue(t_argv[0]);
|
||||||
mld.tag=t_argc > 1 ? intvalue(t_argv[1]) : 0;
|
mld.tag=t_argc > 1 ? intvalue(t_argv[1]) : 0;
|
||||||
P_TranslateLineDef(&line, &mld, false);
|
P_TranslateLineDef(&line, &mld);
|
||||||
P_ExecuteSpecial(line.special, NULL, Script->trigger, false,
|
P_ExecuteSpecial(line.special, NULL, Script->trigger, false,
|
||||||
line.args[0],line.args[1],line.args[2],line.args[3],line.args[4]);
|
line.args[0],line.args[1],line.args[2],line.args[3],line.args[4]);
|
||||||
}
|
}
|
||||||
|
@ -4385,7 +4385,7 @@ void FParser::SF_SetLineTrigger()
|
||||||
mld.tag = tag;
|
mld.tag = tag;
|
||||||
mld.flags = 0;
|
mld.flags = 0;
|
||||||
int f = lines[i].flags;
|
int f = lines[i].flags;
|
||||||
P_TranslateLineDef(&lines[i], &mld, false);
|
P_TranslateLineDef(&lines[i], &mld);
|
||||||
lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) |
|
lines[i].flags = (lines[i].flags & (ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY)) |
|
||||||
(f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY));
|
(f & ~(ML_MONSTERSCANACTIVATE | ML_REPEAT_SPECIAL | ML_SPAC_MASK | ML_FIRSTSIDEONLY));
|
||||||
|
|
||||||
|
|
|
@ -844,7 +844,7 @@ void P_Spawn3DFloors (void)
|
||||||
{
|
{
|
||||||
if (line->args[1]&8)
|
if (line->args[1]&8)
|
||||||
{
|
{
|
||||||
line->SetMainId(line->args[4]);
|
tagManager.AddLineID(i, line->args[4]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -167,7 +167,7 @@ void P_Attach3dMidtexLinesToSector(sector_t *sector, int lineid, int tag, bool c
|
||||||
{
|
{
|
||||||
line_t *ln = sectors[sec].lines[line];
|
line_t *ln = sectors[sec].lines[line];
|
||||||
|
|
||||||
if (lineid != 0 && !ln->HasId(lineid)) continue;
|
if (lineid != 0 && !tagManager.LineHasID(ln, lineid)) continue;
|
||||||
|
|
||||||
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
|
if (ln->frontsector == NULL || ln->backsector == NULL || !(ln->flags & ML_3DMIDTEX))
|
||||||
{
|
{
|
||||||
|
|
|
@ -2063,7 +2063,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int
|
||||||
{
|
{
|
||||||
int wallnum = scroller->GetWallNum ();
|
int wallnum = scroller->GetWallNum ();
|
||||||
|
|
||||||
if (wallnum >= 0 && sides[wallnum].linedef->HasId(id) &&
|
if (wallnum >= 0 && tagManager.LineHasID(sides[wallnum].linedef, id) &&
|
||||||
int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum &&
|
int(sides[wallnum].linedef->sidedef[sidechoice] - sides) == wallnum &&
|
||||||
Where == scroller->GetScrollParts())
|
Where == scroller->GetScrollParts())
|
||||||
{
|
{
|
||||||
|
@ -2082,7 +2082,7 @@ static void SetWallScroller (int id, int sidechoice, fixed_t dx, fixed_t dy, int
|
||||||
while ( (collect.Obj = iterator.Next ()) )
|
while ( (collect.Obj = iterator.Next ()) )
|
||||||
{
|
{
|
||||||
if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 &&
|
if ((collect.RefNum = ((DScroller *)collect.Obj)->GetWallNum ()) != -1 &&
|
||||||
sides[collect.RefNum].linedef->HasId(id) &&
|
tagManager.LineHasID(sides[collect.RefNum].linedef, id) &&
|
||||||
int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum &&
|
int(sides[collect.RefNum].linedef->sidedef[sidechoice] - sides) == collect.RefNum &&
|
||||||
Where == ((DScroller *)collect.Obj)->GetScrollParts())
|
Where == ((DScroller *)collect.Obj)->GetScrollParts())
|
||||||
{
|
{
|
||||||
|
|
|
@ -409,8 +409,13 @@ void P_SerializeWorld (FArchive &arc)
|
||||||
arc << li->flags
|
arc << li->flags
|
||||||
<< li->activation
|
<< li->activation
|
||||||
<< li->special
|
<< li->special
|
||||||
<< li->Alpha
|
<< li->Alpha;
|
||||||
<< li->id;
|
|
||||||
|
if (SaveVersion < 4523)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
arc << id;
|
||||||
|
}
|
||||||
if (P_IsACSSpecial(li->special))
|
if (P_IsACSSpecial(li->special))
|
||||||
{
|
{
|
||||||
P_SerializeACSScriptNumber(arc, li->args[0], false);
|
P_SerializeACSScriptNumber(arc, li->args[0], false);
|
||||||
|
|
|
@ -825,38 +825,6 @@ sector_t *sector_t::GetHeightSec() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void line_t::SetMainId(int newid)
|
|
||||||
{
|
|
||||||
id = newid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void line_t::ClearIds()
|
|
||||||
{
|
|
||||||
id = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool line_t::HasId(int checkid) const
|
|
||||||
{
|
|
||||||
return id == checkid;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void line_t::HashIds()
|
|
||||||
{
|
|
||||||
// killough 4/17/98: same thing, only for linedefs
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=numlines; --i>=0; ) // Initially make all slots empty.
|
|
||||||
lines[i].firstid = -1;
|
|
||||||
for (i=numlines; --i>=0; ) // Proceed from last to first linedef
|
|
||||||
{ // so that lower linedefs appear first
|
|
||||||
int j = (unsigned) lines[i].id % (unsigned) numlines; // Hash func
|
|
||||||
lines[i].nextid = lines[j].firstid; // Prepend linedef to chain
|
|
||||||
lines[j].firstid = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const
|
bool secplane_t::CopyPlaneIfValid (secplane_t *dest, const secplane_t *opp) const
|
||||||
{
|
{
|
||||||
bool copy = false;
|
bool copy = false;
|
||||||
|
|
|
@ -1907,54 +1907,59 @@ void P_AdjustLine (line_t *ld)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void P_SetLineID (line_t *ld)
|
void P_SetLineID (int i, line_t *ld)
|
||||||
{
|
{
|
||||||
// [RH] Set line id (as appropriate) here
|
// [RH] Set line id (as appropriate) here
|
||||||
// for Doom format maps this must be done in P_TranslateLineDef because
|
// for Doom format maps this must be done in P_TranslateLineDef because
|
||||||
// the tag doesn't always go into the first arg.
|
// the tag doesn't always go into the first arg.
|
||||||
if (level.maptype == MAPTYPE_HEXEN)
|
if (level.maptype == MAPTYPE_HEXEN)
|
||||||
{
|
{
|
||||||
|
int setid = -1;
|
||||||
switch (ld->special)
|
switch (ld->special)
|
||||||
{
|
{
|
||||||
case Line_SetIdentification:
|
case Line_SetIdentification:
|
||||||
if (!(level.flags2 & LEVEL2_HEXENHACK))
|
if (!(level.flags2 & LEVEL2_HEXENHACK))
|
||||||
{
|
{
|
||||||
ld->SetMainId(ld->args[0] + 256 * ld->args[4]);
|
setid = ld->args[0] + 256 * ld->args[4];
|
||||||
ld->flags |= ld->args[1]<<16;
|
ld->flags |= ld->args[1]<<16;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ld->SetMainId(ld->args[0]);
|
setid = ld->args[0];
|
||||||
}
|
}
|
||||||
ld->special = 0;
|
ld->special = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TranslucentLine:
|
case TranslucentLine:
|
||||||
ld->SetMainId(ld->args[0]);
|
setid = ld->args[0];
|
||||||
ld->flags |= ld->args[3]<<16;
|
ld->flags |= ld->args[3]<<16;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Teleport_Line:
|
case Teleport_Line:
|
||||||
case Scroll_Texture_Model:
|
case Scroll_Texture_Model:
|
||||||
ld->SetMainId(ld->args[0]);
|
setid = ld->args[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Polyobj_StartLine:
|
case Polyobj_StartLine:
|
||||||
ld->SetMainId(ld->args[3]);
|
setid = ld->args[3];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Polyobj_ExplicitLine:
|
case Polyobj_ExplicitLine:
|
||||||
ld->SetMainId(ld->args[4]);
|
setid = ld->args[4];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Plane_Align:
|
case Plane_Align:
|
||||||
ld->SetMainId(ld->args[2]);
|
setid = ld->args[2];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Static_Init:
|
case Static_Init:
|
||||||
if (ld->args[1] == Init_SectorLink) ld->SetMainId(ld->args[0]);
|
if (ld->args[1] == Init_SectorLink) setid = ld->args[0];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (setid != -1)
|
||||||
|
{
|
||||||
|
tagManager.AddLineID(i, setid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2037,7 +2042,7 @@ void P_FinishLoadingLineDef(line_t *ld, int alpha)
|
||||||
{
|
{
|
||||||
for (j = 0; j < numlines; j++)
|
for (j = 0; j < numlines; j++)
|
||||||
{
|
{
|
||||||
if (lines[j].HasId(ld->args[0]))
|
if (tagManager.LineHasID(j, ld->args[0]))
|
||||||
{
|
{
|
||||||
lines[j].Alpha = alpha;
|
lines[j].Alpha = alpha;
|
||||||
if (additive)
|
if (additive)
|
||||||
|
@ -2139,13 +2144,13 @@ void P_LoadLineDefs (MapData * map)
|
||||||
|
|
||||||
mld = (maplinedef_t *)mldf;
|
mld = (maplinedef_t *)mldf;
|
||||||
ld = lines;
|
ld = lines;
|
||||||
for (i = numlines; i > 0; i--, mld++, ld++)
|
for (i = 0; i < numlines; i++, mld++, ld++)
|
||||||
{
|
{
|
||||||
ld->Alpha = FRACUNIT; // [RH] Opaque by default
|
ld->Alpha = FRACUNIT; // [RH] Opaque by default
|
||||||
|
|
||||||
// [RH] Translate old linedef special and flags to be
|
// [RH] Translate old linedef special and flags to be
|
||||||
// compatible with the new format.
|
// compatible with the new format.
|
||||||
P_TranslateLineDef (ld, mld, true);
|
P_TranslateLineDef (ld, mld, i);
|
||||||
|
|
||||||
ld->v1 = &vertexes[LittleShort(mld->v1)];
|
ld->v1 = &vertexes[LittleShort(mld->v1)];
|
||||||
ld->v2 = &vertexes[LittleShort(mld->v2)];
|
ld->v2 = &vertexes[LittleShort(mld->v2)];
|
||||||
|
@ -2231,13 +2236,12 @@ void P_LoadLineDefs2 (MapData * map)
|
||||||
ld->v1 = &vertexes[LittleShort(mld->v1)];
|
ld->v1 = &vertexes[LittleShort(mld->v1)];
|
||||||
ld->v2 = &vertexes[LittleShort(mld->v2)];
|
ld->v2 = &vertexes[LittleShort(mld->v2)];
|
||||||
ld->Alpha = FRACUNIT; // [RH] Opaque by default
|
ld->Alpha = FRACUNIT; // [RH] Opaque by default
|
||||||
ld->ClearIds();
|
|
||||||
|
|
||||||
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0]));
|
P_SetSideNum (&ld->sidedef[0], LittleShort(mld->sidenum[0]));
|
||||||
P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1]));
|
P_SetSideNum (&ld->sidedef[1], LittleShort(mld->sidenum[1]));
|
||||||
|
|
||||||
P_AdjustLine (ld);
|
P_AdjustLine (ld);
|
||||||
P_SetLineID(ld);
|
P_SetLineID(i, ld);
|
||||||
P_SaveLineSpecial (ld);
|
P_SaveLineSpecial (ld);
|
||||||
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
|
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
|
||||||
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
|
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
|
||||||
|
@ -3209,7 +3213,6 @@ static void P_GroupLines (bool buildmap)
|
||||||
times[4].Clock();
|
times[4].Clock();
|
||||||
// killough 1/30/98: Create xref tables for tags
|
// killough 1/30/98: Create xref tables for tags
|
||||||
tagManager.HashTags();
|
tagManager.HashTags();
|
||||||
line_t::HashIds();
|
|
||||||
times[4].Unclock();
|
times[4].Unclock();
|
||||||
|
|
||||||
times[5].Clock();
|
times[5].Clock();
|
||||||
|
|
|
@ -115,7 +115,7 @@ struct line_t;
|
||||||
struct maplinedef_t;
|
struct maplinedef_t;
|
||||||
|
|
||||||
void P_LoadTranslator(const char *lumpname);
|
void P_LoadTranslator(const char *lumpname);
|
||||||
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setlineid);
|
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid = -1);
|
||||||
int P_TranslateSectorSpecial (int);
|
int P_TranslateSectorSpecial (int);
|
||||||
|
|
||||||
int GetUDMFInt(int type, int index, const char *key);
|
int GetUDMFInt(int type, int index, const char *key);
|
||||||
|
|
|
@ -232,7 +232,7 @@ bool P_ActivateLine (line_t *line, AActor *mo, int side, int activationType)
|
||||||
!repeat && // only non-repeatable triggers
|
!repeat && // only non-repeatable triggers
|
||||||
(special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs
|
(special<Generic_Floor || special>Generic_Crusher) && // not for Boom's generalized linedefs
|
||||||
special && // not for lines without a special
|
special && // not for lines without a special
|
||||||
line->HasId(line->args[0]) && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0]
|
tagManager.LineHasID(line, line->args[0]) && // Safety check: exclude edited UDMF linedefs or ones that don't map the tag to args[0]
|
||||||
line->args[0] && // only if there's a tag (which is stored in the first arg)
|
line->args[0] && // only if there's a tag (which is stored in the first arg)
|
||||||
P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef
|
P_FindFirstSectorFromTag (line->args[0]) == -1) // only if no sector is tagged to this linedef
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,11 @@ static inline int sectindex(const sector_t *sector)
|
||||||
return (int)(intptr_t)(sector - sectors);
|
return (int)(intptr_t)(sector - sectors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int lineindex(const line_t *line)
|
||||||
|
{
|
||||||
|
return (int)(intptr_t)(line - lines);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
@ -58,6 +63,8 @@ static inline int sectindex(const sector_t *sector)
|
||||||
|
|
||||||
void FTagManager::AddSectorTag(int sector, int tag)
|
void FTagManager::AddSectorTag(int sector, int tag)
|
||||||
{
|
{
|
||||||
|
if (tag == 0) return;
|
||||||
|
|
||||||
// This function assumes that all tags for a single sector get added sequentially.
|
// This function assumes that all tags for a single sector get added sequentially.
|
||||||
// Should there ever be some need for compatibility.txt to add tags to sectors which already have a tag this function needs to be changed to adjust the startForSector indices.
|
// Should there ever be some need for compatibility.txt to add tags to sectors which already have a tag this function needs to be changed to adjust the startForSector indices.
|
||||||
while (startForSector.Size() <= (unsigned int)sector)
|
while (startForSector.Size() <= (unsigned int)sector)
|
||||||
|
@ -108,14 +115,50 @@ void FTagManager::RemoveSectorTags(int sect)
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FTagManager::AddLineID(int line, int tag)
|
||||||
|
{
|
||||||
|
if (tag == -1) return; // For line IDs -1 means 'not set', unlike sectors.
|
||||||
|
|
||||||
|
// This function assumes that all ids for a single line get added sequentially.
|
||||||
|
while (startForLine.Size() <= (unsigned int)line)
|
||||||
|
{
|
||||||
|
startForLine.Push(-1);
|
||||||
|
}
|
||||||
|
if (startForLine[line] == -1)
|
||||||
|
{
|
||||||
|
startForLine[line] = allIDs.Size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check if the key was already defined
|
||||||
|
for (unsigned i = startForLine[line]; i < allIDs.Size(); i++)
|
||||||
|
{
|
||||||
|
if (allIDs[i].tag == tag)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FTagItem it = { line, tag, -1 };
|
||||||
|
allIDs.Push(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void FTagManager::HashTags()
|
void FTagManager::HashTags()
|
||||||
{
|
{
|
||||||
// add an end marker so we do not need to check for the array's size in the other functions.
|
// add an end marker so we do not need to check for the array's size in the other functions.
|
||||||
static FTagItem it = { -1, -1, -1 };
|
static FTagItem it = { -1, -1, -1 };
|
||||||
allTags.Push(it);
|
allTags.Push(it);
|
||||||
|
allIDs.Push(it);
|
||||||
|
|
||||||
// Initially make all slots empty.
|
// Initially make all slots empty.
|
||||||
memset(TagHashFirst, -1, sizeof(TagHashFirst));
|
memset(TagHashFirst, -1, sizeof(TagHashFirst));
|
||||||
|
memset(IDHashFirst, -1, sizeof(IDHashFirst));
|
||||||
|
|
||||||
// Proceed from last to first so that lower targets appear first
|
// Proceed from last to first so that lower targets appear first
|
||||||
for (int i = allTags.Size() - 1; i >= 0; i--)
|
for (int i = allTags.Size() - 1; i >= 0; i--)
|
||||||
|
@ -127,6 +170,17 @@ void FTagManager::HashTags()
|
||||||
TagHashFirst[hash] = i;
|
TagHashFirst[hash] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = allIDs.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (allIDs[i].target > 0) // only link valid entries
|
||||||
|
{
|
||||||
|
int hash = ((unsigned int)allIDs[i].tag) % FTagManager::TAG_HASH_SIZE;
|
||||||
|
allIDs[i].nexttag = IDHashFirst[hash];
|
||||||
|
IDHashFirst[hash] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -184,6 +238,37 @@ bool FTagManager::SectorHasTag(const sector_t *sector, int tag) const
|
||||||
return SectorHasTag(sectindex(sector), tag);
|
return SectorHasTag(sectindex(sector), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool FTagManager::LineHasID(int i, int tag) const
|
||||||
|
{
|
||||||
|
if (LineHasIDs(i))
|
||||||
|
{
|
||||||
|
int ndx = startForLine[i];
|
||||||
|
while (allIDs[ndx].target == i)
|
||||||
|
{
|
||||||
|
if (allIDs[ndx].tag == tag) return true;
|
||||||
|
ndx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool FTagManager::LineHasID(const line_t *line, int tag) const
|
||||||
|
{
|
||||||
|
return LineHasID(lineindex(line), tag);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// RETURN NEXT SECTOR # THAT LINE TAG REFERS TO
|
// RETURN NEXT SECTOR # THAT LINE TAG REFERS TO
|
||||||
|
@ -237,10 +322,10 @@ int FSectorTagIterator::NextCompat(bool compat, int start)
|
||||||
|
|
||||||
int FLineIdIterator::Next()
|
int FLineIdIterator::Next()
|
||||||
{
|
{
|
||||||
while (start != -1 && lines[start].id != searchtag) start = lines[start].nextid;
|
while (start >= 0 && tagManager.allIDs[start].tag != searchtag) start = tagManager.allIDs[start].nexttag;
|
||||||
if (start == -1) return -1;
|
if (start == -1) return -1;
|
||||||
int ret = start;
|
int ret = start;
|
||||||
start = lines[start].nextid;
|
start = start = tagManager.allIDs[start].nexttag;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/p_tags.h
10
src/p_tags.h
|
@ -12,6 +12,7 @@ struct FTagItem
|
||||||
};
|
};
|
||||||
|
|
||||||
class FSectorTagIterator;
|
class FSectorTagIterator;
|
||||||
|
class FLineIdIterator;
|
||||||
|
|
||||||
class FTagManager
|
class FTagManager
|
||||||
{
|
{
|
||||||
|
@ -21,12 +22,14 @@ class FTagManager
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class FSectorTagIterator;
|
friend class FSectorTagIterator;
|
||||||
|
friend class FLineIdIterator;
|
||||||
|
|
||||||
TArray<FTagItem> allTags;
|
TArray<FTagItem> allTags;
|
||||||
TArray<FTagItem> allIDs;
|
TArray<FTagItem> allIDs;
|
||||||
TArray<int> startForSector;
|
TArray<int> startForSector;
|
||||||
TArray<int> startForLine;
|
TArray<int> startForLine;
|
||||||
int TagHashFirst[TAG_HASH_SIZE];
|
int TagHashFirst[TAG_HASH_SIZE];
|
||||||
|
int IDHashFirst[TAG_HASH_SIZE];
|
||||||
|
|
||||||
bool SectorHasTags(int sect) const
|
bool SectorHasTags(int sect) const
|
||||||
{
|
{
|
||||||
|
@ -49,9 +52,12 @@ public:
|
||||||
bool SectorHasTag(int sector, int tag) const;
|
bool SectorHasTag(int sector, int tag) const;
|
||||||
bool SectorHasTag(const sector_t *sector, int tag) const;
|
bool SectorHasTag(const sector_t *sector, int tag) const;
|
||||||
|
|
||||||
bool LineHasID(int line, int id);
|
bool LineHasID(int line, int id) const;
|
||||||
|
bool LineHasID(const line_t *line, int id) const;
|
||||||
|
|
||||||
void HashTags();
|
void HashTags();
|
||||||
void AddSectorTag(int sector, int tag);
|
void AddSectorTag(int sector, int tag);
|
||||||
|
void AddLineID(int line, int tag);
|
||||||
void RemoveSectorTags(int sect);
|
void RemoveSectorTags(int sect);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +105,7 @@ public:
|
||||||
FLineIdIterator(int id)
|
FLineIdIterator(int id)
|
||||||
{
|
{
|
||||||
searchtag = id;
|
searchtag = id;
|
||||||
start = lines[(unsigned) id % (unsigned) numlines].firstid;
|
start = tagManager.IDHashFirst[((unsigned int)id) % FTagManager::TAG_HASH_SIZE];
|
||||||
}
|
}
|
||||||
|
|
||||||
int Next();
|
int Next();
|
||||||
|
|
|
@ -755,7 +755,7 @@ public:
|
||||||
mld.flags = 0;
|
mld.flags = 0;
|
||||||
mld.special = th->special;
|
mld.special = th->special;
|
||||||
mld.tag = th->args[0];
|
mld.tag = th->args[0];
|
||||||
P_TranslateLineDef(&ld, &mld, true);
|
P_TranslateLineDef(&ld, &mld);
|
||||||
th->special = ld.special;
|
th->special = ld.special;
|
||||||
memcpy(th->args, ld.args, sizeof (ld.args));
|
memcpy(th->args, ld.args, sizeof (ld.args));
|
||||||
}
|
}
|
||||||
|
@ -780,10 +780,10 @@ public:
|
||||||
bool strifetrans2 = false;
|
bool strifetrans2 = false;
|
||||||
FString arg0str, arg1str;
|
FString arg0str, arg1str;
|
||||||
int lineid; // forZDoomTranslated namespace
|
int lineid; // forZDoomTranslated namespace
|
||||||
|
FString tagstring;
|
||||||
|
|
||||||
memset(ld, 0, sizeof(*ld));
|
memset(ld, 0, sizeof(*ld));
|
||||||
ld->Alpha = FRACUNIT;
|
ld->Alpha = FRACUNIT;
|
||||||
ld->ClearIds();
|
|
||||||
ld->sidedef[0] = ld->sidedef[1] = NULL;
|
ld->sidedef[0] = ld->sidedef[1] = NULL;
|
||||||
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
|
if (level.flags2 & LEVEL2_CLIPMIDTEX) ld->flags |= ML_CLIP_MIDTEX;
|
||||||
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
|
if (level.flags2 & LEVEL2_WRAPMIDTEX) ld->flags |= ML_WRAP_MIDTEX;
|
||||||
|
@ -817,7 +817,7 @@ public:
|
||||||
|
|
||||||
case NAME_Id:
|
case NAME_Id:
|
||||||
lineid = CheckInt(key);
|
lineid = CheckInt(key);
|
||||||
ld->SetMainId(lineid);
|
tagManager.AddLineID(index, lineid);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case NAME_Sidefront:
|
case NAME_Sidefront:
|
||||||
|
@ -1040,22 +1040,17 @@ public:
|
||||||
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
|
Flag(ld->flags, ML_3DMIDTEX_IMPASS, key);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case NAME_MoreIds:
|
||||||
|
// delay parsing of the tag string until parsing of the sector is complete
|
||||||
|
// This ensures that the ID is always the first tag in the list.
|
||||||
|
tagstring = CheckString(key);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 // for later
|
|
||||||
if (namespace_bits & (Zd)) && !strnicmp(key.GetChars(), "Id", 2))
|
|
||||||
{
|
|
||||||
char *endp;
|
|
||||||
int num = strtol(key.GetChars(), &endp, 10);
|
|
||||||
if (num > 0 && *endp == NULL)
|
|
||||||
{
|
|
||||||
// only allow ID## with ## as a proper number
|
|
||||||
ld->SetId((short)CheckInt(key), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
|
if ((namespace_bits & (Zd | Zdt)) && !strnicmp("user_", key.GetChars(), 5))
|
||||||
{
|
{
|
||||||
|
@ -1063,6 +1058,17 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tagstring.IsNotEmpty())
|
||||||
|
{
|
||||||
|
FScanner sc;
|
||||||
|
sc.OpenMem("tagstring", tagstring.GetChars(), tagstring.Len());
|
||||||
|
// scan the string as long as valid numbers can be found
|
||||||
|
while (sc.CheckNumber())
|
||||||
|
{
|
||||||
|
if (sc.Number != 0) tagManager.AddLineID(index, sc.Number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isTranslated)
|
if (isTranslated)
|
||||||
{
|
{
|
||||||
int saved = ld->flags;
|
int saved = ld->flags;
|
||||||
|
@ -1071,7 +1077,7 @@ public:
|
||||||
memset(&mld, 0, sizeof(mld));
|
memset(&mld, 0, sizeof(mld));
|
||||||
mld.special = ld->special;
|
mld.special = ld->special;
|
||||||
mld.tag = lineid;
|
mld.tag = lineid;
|
||||||
P_TranslateLineDef(ld, &mld, false);
|
P_TranslateLineDef(ld, &mld);
|
||||||
ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY));
|
ld->flags = saved | (ld->flags&(ML_MONSTERSCANACTIVATE|ML_REPEAT_SPECIAL|ML_FIRSTSIDEONLY));
|
||||||
}
|
}
|
||||||
if (passuse && (ld->activation & SPAC_Use))
|
if (passuse && (ld->activation & SPAC_Use))
|
||||||
|
|
|
@ -60,7 +60,7 @@ typedef enum
|
||||||
PushMany,
|
PushMany,
|
||||||
} triggertype_e;
|
} triggertype_e;
|
||||||
|
|
||||||
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setid)
|
void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, int lineindexforid)
|
||||||
{
|
{
|
||||||
unsigned short special = (unsigned short) LittleShort(mld->special);
|
unsigned short special = (unsigned short) LittleShort(mld->special);
|
||||||
short tag = LittleShort(mld->tag);
|
short tag = LittleShort(mld->tag);
|
||||||
|
@ -100,13 +100,13 @@ void P_TranslateLineDef (line_t *ld, maplinedef_t *mld, bool setid)
|
||||||
}
|
}
|
||||||
flags = newflags;
|
flags = newflags;
|
||||||
|
|
||||||
if (setid)
|
if (lineindexforid >= 0)
|
||||||
{
|
{
|
||||||
// For purposes of maintaining BOOM compatibility, each
|
// For purposes of maintaining BOOM compatibility, each
|
||||||
// line also needs to have its ID set to the same as its tag.
|
// line also needs to have its ID set to the same as its tag.
|
||||||
// An external conversion program would need to do this more
|
// An external conversion program would need to do this more
|
||||||
// intelligently.
|
// intelligently.
|
||||||
ld->SetMainId(tag);
|
tagManager.AddLineID(lineindexforid, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0 specials are never translated.
|
// 0 specials are never translated.
|
||||||
|
|
|
@ -888,21 +888,12 @@ struct line_t
|
||||||
DWORD activation; // activation type
|
DWORD activation; // activation type
|
||||||
int special;
|
int special;
|
||||||
fixed_t Alpha; // <--- translucency (0=invisibile, FRACUNIT=opaque)
|
fixed_t Alpha; // <--- translucency (0=invisibile, FRACUNIT=opaque)
|
||||||
int id; // <--- same as tag or set with Line_SetIdentification
|
|
||||||
int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width)
|
int args[5]; // <--- hexen-style arguments (expanded to ZDoom's full width)
|
||||||
int firstid, nextid;
|
|
||||||
side_t *sidedef[2];
|
side_t *sidedef[2];
|
||||||
//DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided
|
|
||||||
fixed_t bbox[4]; // bounding box, for the extent of the LineDef.
|
fixed_t bbox[4]; // bounding box, for the extent of the LineDef.
|
||||||
sector_t *frontsector, *backsector;
|
sector_t *frontsector, *backsector;
|
||||||
int validcount; // if == validcount, already checked
|
int validcount; // if == validcount, already checked
|
||||||
int locknumber; // [Dusk] lock number for special
|
int locknumber; // [Dusk] lock number for special
|
||||||
|
|
||||||
|
|
||||||
void SetMainId(int newid);
|
|
||||||
void ClearIds();
|
|
||||||
bool HasId(int id) const;
|
|
||||||
static void HashIds();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// phares 3/14/98
|
// phares 3/14/98
|
||||||
|
|
|
@ -4520,7 +4520,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_LineEffect)
|
||||||
if ((oldjunk.special = special)) // Linedef type
|
if ((oldjunk.special = special)) // Linedef type
|
||||||
{
|
{
|
||||||
oldjunk.tag = tag; // Sector tag for linedef
|
oldjunk.tag = tag; // Sector tag for linedef
|
||||||
P_TranslateLineDef(&junk, &oldjunk, false); // Turn into native type
|
P_TranslateLineDef(&junk, &oldjunk); // Turn into native type
|
||||||
res = !!P_ExecuteSpecial(junk.special, NULL, self, false, junk.args[0],
|
res = !!P_ExecuteSpecial(junk.special, NULL, self, false, junk.args[0],
|
||||||
junk.args[1], junk.args[2], junk.args[3], junk.args[4]);
|
junk.args[1], junk.args[2], junk.args[3], junk.args[4]);
|
||||||
if (res && !(junk.flags & ML_REPEAT_SPECIAL)) // If only once,
|
if (res && !(junk.flags & ML_REPEAT_SPECIAL)) // If only once,
|
||||||
|
|
Loading…
Reference in a new issue