diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 608fe508f..58f082201 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -2021,14 +2021,18 @@ linedeftypes { title = "Change Tagged Sector's Tag"; prefix = "(409)"; + flags2text = "[1] Remove tag"; flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Add tag"; } 410 { title = "Change Front Sector's Tag"; prefix = "(410)"; + flags2text = "[1] Remove tag"; flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Add tag"; } 416 diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index 45e22b8d6..70c416f70 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -2570,6 +2570,55 @@ udmf } } + 409 + { + title = "Change Tagged Sector's Tag"; + prefix = "(409)"; + arg0 + { + title = "Target sector tag"; + type = 13; + } + arg1 + { + title = "Tag"; + type = 13; + } + arg2 + { + title = "Behavior"; + type = 11; + enum + { + 0 = "Add tag"; + 1 = "Remove tag"; + 2 = "Replace first tag"; + } + } + } + + 410 + { + title = "Change Front Sector's Tag"; + prefix = "(410)"; + arg0 + { + title = "Tag"; + type = 13; + } + arg1 + { + title = "Behavior"; + type = 11; + enum + { + 0 = "Add tag"; + 1 = "Remove tag"; + 2 = "Replace first tag"; + } + } + } + 416 { title = "Start Adjustable Flickering Light"; diff --git a/src/p_setup.c b/src/p_setup.c index 71575abaf..d64aff1bf 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3706,6 +3706,25 @@ static void P_ConvertBinaryMap(void) else lines[i].args[1] = TMP_BOTH; break; + case 409: //Change tagged sector's tag + lines[i].args[0] = tag; + lines[i].args[1] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[2] = TMT_ADD; + else if (lines[i].flags & ML_BLOCKMONSTERS) + lines[i].args[2] = TMT_REMOVE; + else + lines[i].args[2] = TMT_REPLACEFIRST; + break; + case 410: //Change front sector's tag + lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS; + if (lines[i].flags & ML_NOCLIMB) + lines[i].args[1] = TMT_ADD; + else if (lines[i].flags & ML_BLOCKMONSTERS) + lines[i].args[1] = TMT_REMOVE; + else + lines[i].args[1] = TMT_REPLACEFIRST; + break; case 411: //Stop plane movement lines[i].args[0] = tag; break; diff --git a/src/p_spec.c b/src/p_spec.c index 256d6997e..589b31145 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2293,14 +2293,47 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 409: // Change tagged sectors' tag // (formerly "Change calling sectors' tag", but behavior was changed) { - TAG_ITER_SECTORS(tag, secnum) - Tag_SectorFSet(secnum,(INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); + mtag_t newtag = line->args[1]; + + TAG_ITER_SECTORS(line->args[0], secnum) + { + switch (line->args[2]) + { + case TMT_ADD: + Tag_SectorAdd(secnum, newtag); + break; + case TMT_REMOVE: + Tag_SectorRemove(secnum, newtag); + break; + case TMT_REPLACEFIRST: + default: + Tag_SectorFSet(secnum, newtag); + break; + } + } break; } case 410: // Change front sector's tag - Tag_SectorFSet((UINT32)(line->frontsector - sectors), (INT16)(sides[line->sidenum[0]].textureoffset>>FRACBITS)); + { + mtag_t newtag = line->args[1]; + secnum = (UINT32)(line->frontsector - sectors); + + switch (line->args[2]) + { + case TMT_ADD: + Tag_SectorAdd(secnum, newtag); + break; + case TMT_REMOVE: + Tag_SectorRemove(secnum, newtag); + break; + case TMT_REPLACEFIRST: + default: + Tag_SectorFSet(secnum, newtag); + break; + } break; + } case 411: // Stop floor/ceiling movement in tagged sector(s) TAG_ITER_SECTORS(line->args[0], secnum) diff --git a/src/p_spec.h b/src/p_spec.h index aeb557bf6..09a14d9a1 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -112,6 +112,13 @@ typedef enum TMP_BOTH = 2, } textmapplanes_t; +typedef enum +{ + TMT_ADD = 0, + TMT_REMOVE = 1, + TMT_REPLACEFIRST = 2, +} textmaptagoptions_t; + typedef enum { TMSS_TRIGGERMOBJ = 0, diff --git a/src/taglist.c b/src/taglist.c index ad1b9dc4b..f78f0c82b 100644 --- a/src/taglist.c +++ b/src/taglist.c @@ -37,6 +37,25 @@ void Tag_Add (taglist_t* list, const mtag_t tag) list->tags[list->count++] = tag; } +/// Removes a tag from a given element's taglist. +/// \warning This does not rebuild the global taggroups, which are used for iteration. +void Tag_Remove(taglist_t* list, const mtag_t tag) +{ + UINT16 i; + + for (i = 0; i < list->count; i++) + { + if (list->tags[i] != tag) + continue; + + for (; i+1 < list->count; i++) + list->tags[i] = list->tags[i+1]; + + list->tags = Z_Realloc(list->tags, (list->count - 1) * sizeof(mtag_t), PU_LEVEL, NULL); + return; + } +} + /// Sets the first tag entry in a taglist. /// Replicates the old way of accessing element->tag. void Tag_FSet (taglist_t* list, const mtag_t tag) @@ -376,6 +395,22 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start) // Ingame list manipulation. +/// Adds the tag to the given sector, and updates the global taggroups. +void Tag_SectorAdd (const size_t id, const mtag_t tag) +{ + sector_t* sec = §ors[id]; + Tag_Add(&sec->tags, tag); + Taggroup_Add(tags_sectors, tag, id); +} + +/// Removes the tag from the given sector, and updates the global taggroups. +void Tag_SectorRemove (const size_t id, const mtag_t tag) +{ + sector_t* sec = §ors[id]; + Tag_Remove(&sec->tags, tag); + Taggroup_Remove(tags_sectors, tag, id); +} + /// Changes the first tag for a given sector, and updates the global taggroups. void Tag_SectorFSet (const size_t id, const mtag_t tag) { diff --git a/src/taglist.h b/src/taglist.h index d045eb827..f15423d7a 100644 --- a/src/taglist.h +++ b/src/taglist.h @@ -28,12 +28,15 @@ typedef struct } taglist_t; void Tag_Add (taglist_t* list, const mtag_t tag); +void Tag_Remove (taglist_t* list, const mtag_t tag); void Tag_FSet (taglist_t* list, const mtag_t tag); mtag_t Tag_FGet (const taglist_t* list); boolean Tag_Find (const taglist_t* list, const mtag_t tag); boolean Tag_Share (const taglist_t* list1, const taglist_t* list2); boolean Tag_Compare (const taglist_t* list1, const taglist_t* list2); +void Tag_SectorAdd (const size_t id, const mtag_t tag); +void Tag_SectorRemove (const size_t id, const mtag_t tag); void Tag_SectorFSet (const size_t id, const mtag_t tag); /// Taggroup list. It is essentially just an element id list.