mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-31 21:50:48 +00:00
Tidier conversion of string properties on linedefs to UDMF
Previously, many concatenated texture field strings were turned to text, then had that string run through get_number, then had it converted back into a string to become a stringarg. Now, the concatenated string is copied directly to the relevant stringarg, with no intermediary steps. This fixes an issue where a map with object or state properties would have "context drift" - breaking when the object or state list changed, due to differently ordered freeslots, or new hardcoded objects. Affected types: - doomednum 1110/Action 9 (Custom Mace/Chain) - doomednum 700 and those immediately following (Ambient Sound) - Action 4 and 414 (dash pad, play sound effect) - Action 14 (bustable block parameters) - Action 434 (Award Power) - doomednum 757/Action 15 (fan particle generator) - doomednum 1202 (bumpable hazard rock/apple spawner) - This one has undefined behaviour in the binary map format which was not previously forbidden. This undefined behaviour is EXTREMELY vulnerable to context drift, and so it's simply not worth creating a system to write numerical values into object types - we write an explicit name only for the intended range, and otherwise report the threat of context drift when converting. In addition, to reduce duplicated zone memory, (sidedef_t).text and (linedef_t).text have been removed from all but the Lua API. In Lua, in binary maps, they point to the host line's stringargs - the line's text and a frontside's text will return stringargs[0], while a backside's text will return stringargs[1]. I've done my best to match the previous API as closely possible, to the point of reporting false nils if the line didn't previously have text available. However, there are four linedef Actions for which the sidedef text will be different between builds containing and not containing this commit - 331, 332, 333 (the Character-specific linedef executors), and 443 (Call Lua Script), and only if the text is long enough to go over two lines. Given that both halves would be incomplete nonsense in this case, I'm willing to wager this minor point of discrepancy is not a breaking issue.
This commit is contained in:
parent
dee2489620
commit
66dd952fdd
3 changed files with 208 additions and 152 deletions
|
@ -1032,8 +1032,24 @@ static int line_get(lua_State *L)
|
|||
LUA_PushUserdata(L, line->polyobj, META_POLYOBJ);
|
||||
return 1;
|
||||
case line_text:
|
||||
lua_pushstring(L, line->text);
|
||||
{
|
||||
if (udmf)
|
||||
{
|
||||
LUA_Deprecated(L, "(linedef_t).text", "(linedef_t).stringargs");
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (line->special == 331 || line->special == 443)
|
||||
{
|
||||
// See P_ProcessLinedefsAfterSidedefs, P_ConvertBinaryLinedefTypes
|
||||
lua_pushstring(L, line->stringargs[0]);
|
||||
}
|
||||
else
|
||||
lua_pushnil(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
case line_callcount:
|
||||
lua_pushinteger(L, line->callcount);
|
||||
return 1;
|
||||
|
@ -1149,9 +1165,20 @@ static int side_get(lua_State *L)
|
|||
lua_pushinteger(L, side->repeatcnt);
|
||||
return 1;
|
||||
case side_text:
|
||||
lua_pushstring(L, side->text);
|
||||
{
|
||||
if (udmf)
|
||||
{
|
||||
LUA_Deprecated(L, "(sidedef_t).text", "(sidedef_t).line.stringargs");
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
boolean isfrontside = side->line->sidenum[0] == side-sides;
|
||||
|
||||
lua_pushstring(L, side->line->stringargs[isfrontside ? 0 : 1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
320
src/p_setup.c
320
src/p_setup.c
|
@ -1103,7 +1103,6 @@ static void P_InitializeLinedef(line_t *ld)
|
|||
ld->validcount = 0;
|
||||
ld->polyobj = NULL;
|
||||
|
||||
ld->text = NULL;
|
||||
ld->callcount = 0;
|
||||
|
||||
// cph 2006/09/30 - fix sidedef errors right away.
|
||||
|
@ -1207,10 +1206,108 @@ static void P_InitializeSidedef(side_t *sd)
|
|||
sd->special = sd->line->special;
|
||||
}
|
||||
|
||||
sd->text = NULL;
|
||||
sd->colormap_data = NULL;
|
||||
}
|
||||
|
||||
static boolean contextdrift = false;
|
||||
|
||||
// In Ring Racers, this is just the reference implementation.
|
||||
// But in SRB2, backwards compatibility is a design goal!?
|
||||
// So we let the map function on load, but report that there's
|
||||
// an issue which could prevent saving it as a UDMF map.
|
||||
//
|
||||
// ... "context drift" is a term I learned from the story "Lena",
|
||||
// styled after a wikipedia article on a man whose brain scan
|
||||
// spawns an industry of digital brain emulation. It is a term
|
||||
// to describe that the understanding of the world MMAcevedo has
|
||||
// is rooted in a specific moment and time and will lose relevance
|
||||
// as societal norms, languages, and events change and are changed.
|
||||
// It is on the real wikipedia, but under the name "concept drift".
|
||||
// I am connecting the idea of the rooted-in-time brainstate with
|
||||
// the numerical evaluation of get_number(), the ground truth
|
||||
// CONTEXT for all these silly integers, that will trip up future
|
||||
// builds of SRB2 that have modified states and object lists.
|
||||
// Golden statues rotating in place of carousel rides is perhaps
|
||||
// not quite what qntm meant, but is a TEXTMAP, a human-readable
|
||||
// document for imparting a sense of place made/read by machines,
|
||||
// not its own language providing a vulnerable context?
|
||||
// ~toast 200723, see https://qntm.org/mmacevedo
|
||||
//
|
||||
static void P_WriteConstant(INT32 constant, char **target, const char *desc, UINT32 id)
|
||||
{
|
||||
char buffer[12];
|
||||
size_t len;
|
||||
|
||||
CONS_Alert(
|
||||
CONS_WARNING, M_GetText(
|
||||
"P_WriteConstant has been called for %s %d, "
|
||||
"this level is vulnerable to context drift "
|
||||
"if -writetextmap is used.\n"),
|
||||
desc, id
|
||||
);
|
||||
|
||||
contextdrift = true;
|
||||
|
||||
sprintf(buffer, "%d", constant);
|
||||
len = strlen(buffer) + 1;
|
||||
*target = Z_Malloc(len, PU_LEVEL, NULL);
|
||||
M_Memcpy(*target, buffer, len);
|
||||
}
|
||||
|
||||
static void P_WriteDuplicateText(const char *text, char **target)
|
||||
{
|
||||
if (text == NULL || text[0] == '\0')
|
||||
return;
|
||||
|
||||
size_t len = strlen(text) + 1;
|
||||
*target = Z_Malloc(len, PU_LEVEL, NULL);
|
||||
M_Memcpy(*target, text, len);
|
||||
}
|
||||
|
||||
static void P_WriteSkincolor(INT32 constant, char **target)
|
||||
{
|
||||
if (constant <= SKINCOLOR_NONE
|
||||
|| constant >= (INT32)numskincolors)
|
||||
return;
|
||||
|
||||
P_WriteDuplicateText(
|
||||
va("SKINCOLOR_%s", skincolors[constant].name),
|
||||
target
|
||||
);
|
||||
}
|
||||
|
||||
static void P_WriteSfx(INT32 constant, char **target)
|
||||
{
|
||||
if (constant <= sfx_None
|
||||
|| constant >= (INT32)sfxfree)
|
||||
return;
|
||||
|
||||
P_WriteDuplicateText(
|
||||
va("sfx_%s", S_sfx[constant].name),
|
||||
target
|
||||
);
|
||||
}
|
||||
|
||||
static void P_WriteTics(INT32 tics, char **target)
|
||||
{
|
||||
if (!tics)
|
||||
return;
|
||||
|
||||
INT32 seconds = (tics / TICRATE);
|
||||
tics %= TICRATE;
|
||||
|
||||
const char *text;
|
||||
|
||||
if (tics && !seconds)
|
||||
text = va("%d", tics);
|
||||
else if (seconds && !tics)
|
||||
text = va("(%d*TICRATE)", seconds);
|
||||
else
|
||||
text = va("(%d*TICRATE)%s%d", seconds, (tics > 0) ? "+" : "", tics);
|
||||
|
||||
P_WriteDuplicateText(text, target);
|
||||
}
|
||||
|
||||
static void P_LoadSidedefs(UINT8 *data)
|
||||
{
|
||||
mapsidedef_t *msd = (mapsidedef_t*)data;
|
||||
|
@ -1259,9 +1356,13 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
|
||||
case 413: // Change music
|
||||
{
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
|
||||
if (!isfrontside)
|
||||
break;
|
||||
|
||||
char process[8+1];
|
||||
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
|
||||
{
|
||||
M_Memcpy(process,msd->bottomtexture,8);
|
||||
|
@ -1276,48 +1377,39 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
sd->midtexture = get_number(process);
|
||||
}
|
||||
|
||||
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
|
||||
if (isfrontside && !(msd->toptexture[0] == '-' && msd->toptexture[1] == '\0'))
|
||||
if (msd->toptexture[0] != '-' && msd->toptexture[1] != '\0')
|
||||
{
|
||||
sd->line->stringargs[0] = Z_Malloc(7, PU_LEVEL, NULL);
|
||||
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
process[8] = '\0';
|
||||
|
||||
// If they type in O_ or D_ and their music name, just shrug,
|
||||
// then copy the rest instead.
|
||||
if ((process[0] == 'O' || process[0] == 'D') && process[7])
|
||||
M_Memcpy(sd->text, process+2, 6);
|
||||
M_Memcpy(sd->line->stringargs[0], process+2, 6);
|
||||
else // Assume it's a proper music name.
|
||||
M_Memcpy(sd->text, process, 6);
|
||||
sd->text[6] = 0;
|
||||
M_Memcpy(sd->line->stringargs[0], process, 6);
|
||||
sd->line->stringargs[0][6] = '\0';
|
||||
}
|
||||
else
|
||||
sd->text[0] = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: // Speed pad parameters
|
||||
{
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
|
||||
{
|
||||
char process[8+1];
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
process[8] = '\0';
|
||||
sd->toptexture = get_number(process);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 414: // Play SFX
|
||||
{
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
|
||||
if (!isfrontside)
|
||||
break;
|
||||
|
||||
if (msd->toptexture[0] != '-' || msd->toptexture[1] != '\0')
|
||||
{
|
||||
char process[8 + 1];
|
||||
M_Memcpy(process, msd->toptexture, 8);
|
||||
process[8] = '\0';
|
||||
sd->text = Z_Malloc(strlen(process) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(sd->text, process, strlen(process) + 1);
|
||||
P_WriteDuplicateText(process, &sd->line->stringargs[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1326,21 +1418,13 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
case 14: // Bustable block parameters
|
||||
case 15: // Fan particle spawner parameters
|
||||
{
|
||||
char process[8*3+1];
|
||||
memset(process,0,8*3+1);
|
||||
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
|
||||
if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')
|
||||
break;
|
||||
else
|
||||
M_Memcpy(process,msd->toptexture,8);
|
||||
if (msd->midtexture[0] != '-' || msd->midtexture[1] != '\0')
|
||||
M_Memcpy(process+strlen(process), msd->midtexture, 8);
|
||||
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
|
||||
M_Memcpy(process+strlen(process), msd->bottomtexture, 8);
|
||||
sd->toptexture = get_number(process);
|
||||
if (msd->toptexture[7] == '\0' && strcasecmp(msd->toptexture, "MT_NULL") == 0)
|
||||
{
|
||||
// Don't bulk the conversion with irrelevant types
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// FALLTHRU
|
||||
case 331: // Trigger linedef executor: Skin - Continuous
|
||||
case 332: // Trigger linedef executor: Skin - Each time
|
||||
case 333: // Trigger linedef executor: Skin - Once
|
||||
|
@ -1366,8 +1450,11 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
M_Memcpy(process+strlen(process), msd->midtexture, 8);
|
||||
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
|
||||
M_Memcpy(process+strlen(process), msd->bottomtexture, 8);
|
||||
sd->text = Z_Malloc(strlen(process)+1, PU_LEVEL, NULL);
|
||||
M_Memcpy(sd->text, process, strlen(process)+1);
|
||||
|
||||
P_WriteDuplicateText(
|
||||
process,
|
||||
&sd->line->stringargs[(isfrontside) ? 0 : 1]
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -2716,6 +2803,15 @@ static void P_WriteTextmap(void)
|
|||
Z_Free(wlines);
|
||||
Z_Free(wsides);
|
||||
Z_Free(specialthings);
|
||||
|
||||
if (contextdrift)
|
||||
{
|
||||
CONS_Alert(
|
||||
CONS_WARNING, M_GetText(
|
||||
"Some elements of this level are vulnerable to context drift."
|
||||
"Please check the console log for more information.\n")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/** Loads the textmap data, after obtaining the elements count and allocating their respective space.
|
||||
|
@ -2909,15 +3005,20 @@ static void P_ProcessLinedefsAfterSidedefs(void)
|
|||
case 332: // Trigger linedef executor: Skin - Each time
|
||||
case 333: // Trigger linedef executor: Skin - Once
|
||||
case 443: // Calls a named Lua function
|
||||
if (sides[ld->sidenum[0]].text)
|
||||
if (ld->stringargs[0] && ld->stringargs[1])
|
||||
{
|
||||
size_t len = strlen(sides[ld->sidenum[0]].text) + 1;
|
||||
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
|
||||
len += strlen(sides[ld->sidenum[1]].text);
|
||||
ld->text = Z_Malloc(len, PU_LEVEL, NULL);
|
||||
M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text) + 1);
|
||||
if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text)
|
||||
M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1);
|
||||
size_t len[2];
|
||||
len[0] = strlen(ld->stringargs[0]);
|
||||
len[1] = strlen(ld->stringargs[1]);
|
||||
|
||||
if (len[1])
|
||||
{
|
||||
ld->stringargs[0] = Z_Realloc(ld->stringargs[0], len[0] + len[1] + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(ld->stringargs[0] + len[0] + 1, ld->stringargs[1], len[1] + 1);
|
||||
}
|
||||
|
||||
Z_Free(ld->stringargs[1]);
|
||||
ld->stringargs[1] = NULL;
|
||||
}
|
||||
break;
|
||||
case 447: // Change colormap
|
||||
|
@ -4033,14 +4134,6 @@ static void P_AddBinaryMapTags(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void P_WriteConstant(INT32 constant, char **target)
|
||||
{
|
||||
char buffer[12];
|
||||
sprintf(buffer, "%d", constant);
|
||||
*target = Z_Malloc(strlen(buffer) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(*target, buffer, strlen(buffer) + 1);
|
||||
}
|
||||
|
||||
static line_t *P_FindPointPushLine(taglist_t *list)
|
||||
{
|
||||
INT32 i, l;
|
||||
|
@ -4183,7 +4276,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[1] |= TMSP_NOTELEPORT;
|
||||
if (lines[i].flags & ML_WRAPMIDTEX)
|
||||
lines[i].args[1] |= TMSP_FORCESPIN;
|
||||
P_WriteConstant(sides[lines[i].sidenum[0]].toptexture ? sides[lines[i].sidenum[0]].toptexture : sfx_spdpad, &lines[i].stringargs[0]);
|
||||
break;
|
||||
case 7: //Sector flat alignment
|
||||
lines[i].args[0] = tag;
|
||||
|
@ -4269,8 +4361,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
|
||||
lines[i].args[2] = !!(lines[i].flags & ML_SKEWTD);
|
||||
if (sides[lines[i].sidenum[0]].toptexture)
|
||||
P_WriteConstant(sides[lines[i].sidenum[0]].toptexture, &lines[i].stringargs[0]);
|
||||
break;
|
||||
case 16: //Minecart parameters
|
||||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
|
@ -4733,7 +4823,7 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[2] = 16;
|
||||
}
|
||||
if (lines[i].flags & ML_MIDSOLID)
|
||||
P_WriteConstant(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]);
|
||||
P_WriteSfx(sides[lines[i].sidenum[0]].textureoffset >> FRACBITS, &lines[i].stringargs[0]);
|
||||
break;
|
||||
case 252: //FOF: Shatter block
|
||||
case 253: //FOF: Shatter block, translucent
|
||||
|
@ -5000,11 +5090,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
else
|
||||
lines[i].args[0] = TMT_CONTINUOUS;
|
||||
lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB);
|
||||
if (lines[i].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1);
|
||||
}
|
||||
lines[i].special = 331;
|
||||
break;
|
||||
case 334: // Object dye - continuous
|
||||
|
@ -5017,11 +5102,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
else
|
||||
lines[i].args[0] = TMT_CONTINUOUS;
|
||||
lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB);
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
lines[i].special = 334;
|
||||
break;
|
||||
case 337: //Emerald check - continuous
|
||||
|
@ -5168,11 +5248,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[4] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : 0;
|
||||
lines[i].args[5] = (lines[i].sidenum[1] != 0xffff) ? sides[lines[i].sidenum[1]].rowoffset >> FRACBITS : -1;
|
||||
lines[i].args[6] = sides[lines[i].sidenum[0]].bottomtexture;
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 414: //Play sound effect
|
||||
lines[i].args[2] = tag;
|
||||
|
@ -5212,11 +5287,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[1] = TMSL_EVERYONE;
|
||||
}
|
||||
}
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 415: //Run script
|
||||
{
|
||||
|
@ -5307,13 +5377,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
lines[i].args[1] = !!(lines[i].flags & ML_NOCLIMB);
|
||||
break;
|
||||
case 425: //Change object state
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 426: //Stop object
|
||||
lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB);
|
||||
break;
|
||||
|
@ -5353,18 +5416,18 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
lines[i].args[2] = !!(lines[i].flags & ML_BLOCKMONSTERS);
|
||||
break;
|
||||
case 434: //Award power-up
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
if ((lines[i].flags & ML_BLOCKMONSTERS) == 0)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
if (lines[i].sidenum[1] != 0xffff && lines[i].flags & ML_BLOCKMONSTERS) // read power from back sidedef
|
||||
// do NOT read power from back sidedef if this flag is not present
|
||||
if (lines[i].stringargs[1] != NULL)
|
||||
{
|
||||
lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1);
|
||||
Z_Free(lines[i].stringargs[1]);
|
||||
lines[i].stringargs[1] = NULL;
|
||||
}
|
||||
|
||||
// Instead... write the desired time!
|
||||
P_WriteTics((lines[i].flags & ML_NOCLIMB) ? -1 : (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS), &lines[i].stringargs[1]);
|
||||
}
|
||||
else
|
||||
P_WriteConstant((lines[i].flags & ML_NOCLIMB) ? -1 : (sides[lines[i].sidenum[0]].textureoffset >> FRACBITS), &lines[i].stringargs[1]);
|
||||
break;
|
||||
case 435: //Change plane scroller direction
|
||||
lines[i].args[0] = tag;
|
||||
|
@ -5392,30 +5455,10 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
break;
|
||||
case 442: //Change object type state
|
||||
lines[i].args[0] = tag;
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
if (lines[i].sidenum[1] == 0xffff)
|
||||
lines[i].args[1] = 1;
|
||||
else
|
||||
{
|
||||
lines[i].args[1] = 0;
|
||||
if (sides[lines[i].sidenum[1]].text)
|
||||
{
|
||||
lines[i].stringargs[1] = Z_Malloc(strlen(sides[lines[i].sidenum[1]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[1], sides[lines[i].sidenum[1]].text, strlen(sides[lines[i].sidenum[1]].text) + 1);
|
||||
}
|
||||
}
|
||||
lines[i].args[3] = (lines[i].sidenum[1] == 0xffff) ? 1 : 0;
|
||||
break;
|
||||
case 443: //Call Lua function
|
||||
if (lines[i].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(lines[i].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], lines[i].text, strlen(lines[i].text) + 1);
|
||||
}
|
||||
else
|
||||
if (lines[i].stringargs[0] == NULL)
|
||||
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(i));
|
||||
break;
|
||||
case 444: //Earthquake
|
||||
|
@ -5568,11 +5611,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
if (lines[i].flags & ML_MIDSOLID)
|
||||
lines[i].args[2] |= TMP_FREEZETHINKERS;*/
|
||||
lines[i].args[3] = (lines[i].sidenum[1] != 0xFFFF) ? sides[lines[i].sidenum[1]].textureoffset >> FRACBITS : tag;
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 460: //Award rings
|
||||
lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
|
||||
|
@ -5600,18 +5638,6 @@ static void P_ConvertBinaryLinedefTypes(void)
|
|||
}
|
||||
else
|
||||
lines[i].args[4] = 0;
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 463: //Dye object
|
||||
if (sides[lines[i].sidenum[0]].text)
|
||||
{
|
||||
lines[i].stringargs[0] = Z_Malloc(strlen(sides[lines[i].sidenum[0]].text) + 1, PU_LEVEL, NULL);
|
||||
M_Memcpy(lines[i].stringargs[0], sides[lines[i].sidenum[0]].text, strlen(sides[lines[i].sidenum[0]].text) + 1);
|
||||
}
|
||||
break;
|
||||
case 464: //Trigger egg capsule
|
||||
lines[i].args[0] = tag;
|
||||
|
@ -6440,7 +6466,7 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
break;
|
||||
case 543: //Balloon
|
||||
if (mapthings[i].angle > 0)
|
||||
P_WriteConstant(((mapthings[i].angle - 1) % (numskincolors - 1)) + 1, &mapthings[i].stringargs[0]);
|
||||
P_WriteSkincolor(((mapthings[i].angle - 1) % (numskincolors - 1)) + 1, &mapthings[i].stringargs[0]);
|
||||
mapthings[i].args[0] = !!(mapthings[i].options & MTF_AMBUSH);
|
||||
break;
|
||||
case 555: //Diagonal yellow spring
|
||||
|
@ -6465,22 +6491,22 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
case 706: //Water ambience G
|
||||
case 707: //Water ambience H
|
||||
mapthings[i].args[0] = 35;
|
||||
P_WriteConstant(sfx_amwtr1 + mapthings[i].type - 700, &mapthings[i].stringargs[0]);
|
||||
P_WriteSfx(sfx_amwtr1 + mapthings[i].type - 700, &mapthings[i].stringargs[0]);
|
||||
mapthings[i].type = 700;
|
||||
break;
|
||||
case 708: //Disco ambience
|
||||
mapthings[i].args[0] = 512;
|
||||
P_WriteConstant(sfx_ambint, &mapthings[i].stringargs[0]);
|
||||
P_WriteSfx(sfx_ambint, &mapthings[i].stringargs[0]);
|
||||
mapthings[i].type = 700;
|
||||
break;
|
||||
case 709: //Volcano ambience
|
||||
mapthings[i].args[0] = 220;
|
||||
P_WriteConstant(sfx_ambin2, &mapthings[i].stringargs[0]);
|
||||
P_WriteSfx(sfx_ambin2, &mapthings[i].stringargs[0]);
|
||||
mapthings[i].type = 700;
|
||||
break;
|
||||
case 710: //Machine ambience
|
||||
mapthings[i].args[0] = 24;
|
||||
P_WriteConstant(sfx_ambmac, &mapthings[i].stringargs[0]);
|
||||
P_WriteSfx(sfx_ambmac, &mapthings[i].stringargs[0]);
|
||||
mapthings[i].type = 700;
|
||||
break;
|
||||
case 750: //Slope vertex
|
||||
|
@ -6543,8 +6569,7 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
mapthings[i].args[3] = sides[lines[j].sidenum[0]].rowoffset >> FRACBITS;
|
||||
mapthings[i].args[4] = lines[j].backsector ? sides[lines[j].sidenum[1]].textureoffset >> FRACBITS : 0;
|
||||
mapthings[i].args[6] = mapthings[i].angle;
|
||||
if (sides[lines[j].sidenum[0]].toptexture)
|
||||
P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]);
|
||||
P_WriteDuplicateText(lines[j].stringargs[0], &mapthings[i].stringargs[0]);
|
||||
break;
|
||||
}
|
||||
case 762: //PolyObject spawn point (crush)
|
||||
|
@ -6633,8 +6658,8 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
mapthings[i].args[8] |= TMM_ALWAYSTHINK;
|
||||
if (mapthings[i].type == 1110)
|
||||
{
|
||||
P_WriteConstant(sides[lines[j].sidenum[0]].toptexture, &mapthings[i].stringargs[0]);
|
||||
P_WriteConstant(lines[j].backsector ? sides[lines[j].sidenum[1]].toptexture : MT_NULL, &mapthings[i].stringargs[1]);
|
||||
P_WriteDuplicateText(lines[j].stringargs[0], &mapthings[i].stringargs[0]);
|
||||
P_WriteDuplicateText(lines[j].stringargs[1], &mapthings[i].stringargs[1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -6675,7 +6700,13 @@ static void P_ConvertBinaryThingTypes(void)
|
|||
mapthings[i].args[0] = P_AproxDistance(lines[j].dx, lines[j].dy) >> FRACBITS;
|
||||
mapthings[i].args[1] = sides[lines[j].sidenum[0]].textureoffset >> FRACBITS;
|
||||
mapthings[i].args[2] = !!(lines[j].flags & ML_NOCLIMB);
|
||||
P_WriteConstant(MT_ROCKCRUMBLE1 + (sides[lines[j].sidenum[0]].rowoffset >> FRACBITS), &mapthings[i].stringargs[0]);
|
||||
INT32 id = (sides[lines[j].sidenum[0]].rowoffset >> FRACBITS);
|
||||
// Rather than introduce deh_tables.h as a dependency for literally one
|
||||
// conversion, we just... recreate the string expected to be produced.
|
||||
if (id > 0 && id < 16)
|
||||
P_WriteDuplicateText(va("MT_ROCKCRUMBLE%d", id+1), &mapthings[i].stringargs[0]);
|
||||
else
|
||||
P_WriteConstant(MT_ROCKCRUMBLE1 + id, &mapthings[i].stringargs[0], "Mapthing", i);
|
||||
break;
|
||||
}
|
||||
case 1221: //Minecart saloon door
|
||||
|
@ -6808,6 +6839,7 @@ static void P_ConvertBinaryLinedefFlags(void)
|
|||
//For maps in binary format, converts setup of specials to UDMF format.
|
||||
static void P_ConvertBinaryMap(void)
|
||||
{
|
||||
contextdrift = false;
|
||||
P_ConvertBinaryLinedefTypes();
|
||||
P_ConvertBinarySectorTypes();
|
||||
P_ConvertBinaryThingTypes();
|
||||
|
|
|
@ -547,7 +547,6 @@ typedef struct line_s
|
|||
size_t validcount; // if == validcount, already checked
|
||||
polyobj_t *polyobj; // Belongs to a polyobject?
|
||||
|
||||
char *text; // a concatenation of all front and back texture names, for linedef specials that require a string.
|
||||
INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0
|
||||
} line_t;
|
||||
|
||||
|
@ -576,8 +575,6 @@ typedef struct
|
|||
INT16 special; // the special of the linedef this side belongs to
|
||||
INT16 repeatcnt; // # of times to repeat midtexture
|
||||
|
||||
char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string.
|
||||
|
||||
extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors.
|
||||
} side_t;
|
||||
|
||||
|
|
Loading…
Reference in a new issue