diff --git a/src/dehacked.c b/src/dehacked.c index 7107c3a1e..9a19833a9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -808,9 +808,11 @@ static void readskincolor(MYFILE *f, INT32 num) { size_t namesize = sizeof(skincolors[num].name); char truncword[namesize]; + UINT16 dupecheck; deh_strlcpy(truncword, word2, namesize, va("Skincolor %d: name", num)); // truncate here to check for dupes - if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || R_GetColorByName(truncword))) + dupecheck = R_GetColorByName(truncword); + if (truncword[0] != '\0' && (!stricmp(truncword, skincolors[SKINCOLOR_NONE].name) || dupecheck && dupecheck != num)) { size_t lastchar = strlen(truncword); char oldword[lastchar+1]; @@ -4726,11 +4728,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { if (i == 0 && word2[0] != '0') // If word2 isn't a number i = get_skincolor(word2); // find a skincolor by name - if (i < numskincolors && i >= (INT32)SKINCOLOR_FIRSTFREESLOT) + if (i && i < numskincolors) readskincolor(f, i); else { - deh_warning("Skincolor %d out of range (%d - %d)", i, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + deh_warning("Skincolor %d out of range (1 - %d)", i, numskincolors-1); ignorelines(f); } } diff --git a/src/lua_infolib.c b/src/lua_infolib.c index b3e92f833..830d97625 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -1491,7 +1491,7 @@ static void setRamp(lua_State *L, skincolor_t* c) { UINT32 i; lua_pushnil(L); for (i=0; i= numskincolors) - return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + if (!cnum || cnum >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1); info = &skincolors[cnum]; // get the skincolor to assign to. } luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table. @@ -1563,14 +1563,19 @@ static int lib_setSkinColor(lua_State *L) } else if (i == 3 || (str && fastcmp(str,"invcolor"))) { UINT16 v = (UINT16)luaL_checkinteger(L, 3); if (v >= numskincolors) - return luaL_error(L, "attempt to set skincolors[%d].invcolor to out of range value %d.", cnum, v); + return luaL_error(L, "skincolor_t field 'invcolor' out of range (1 - %d)", numskincolors-1); info->invcolor = v; } else if (i == 4 || (str && fastcmp(str,"invshade"))) info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE; else if (i == 5 || (str && fastcmp(str,"chatcolor"))) info->chatcolor = (UINT16)luaL_checkinteger(L, 3); - else if (i == 6 || (str && fastcmp(str,"accessible"))) - info->accessible = lua_toboolean(L, 3); + else if (i == 6 || (str && fastcmp(str,"accessible"))) { + boolean v = lua_toboolean(L, 3); + if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) + return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + else + info->accessible = v; + } lua_pop(L, 1); } return 0; @@ -1615,12 +1620,13 @@ static int skincolor_set(lua_State *L) UINT32 i; skincolor_t *info = *((skincolor_t **)luaL_checkudata(L, 1, META_SKINCOLOR)); const char *field = luaL_checkstring(L, 2); + UINT16 cnum = (UINT16)(info-skincolors); I_Assert(info != NULL); I_Assert(info >= skincolors); - if (info-skincolors < SKINCOLOR_FIRSTFREESLOT || info-skincolors >= numskincolors) - return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", info-skincolors, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + if (!cnum || cnum >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1); if (fastcmp(field,"name")) { const char* n = luaL_checkstring(L, 3); @@ -1633,7 +1639,7 @@ static int skincolor_set(lua_State *L) if (info->name[0] != '\0') // don't check empty string for dupe { UINT16 dupecheck = R_GetColorByName(info->name); - if (!stricmp(info->name, skincolors[SKINCOLOR_NONE].name) || (dupecheck && (dupecheck != info-skincolors))) + if (!stricmp(info->name, skincolors[SKINCOLOR_NONE].name) || (dupecheck && (dupecheck != cnum))) CONS_Alert(CONS_WARNING, "skincolor_t field 'name' ('%s') is a duplicate of another skincolor's name.\n", info->name); } } else if (fastcmp(field,"ramp")) { @@ -1644,19 +1650,23 @@ static int skincolor_set(lua_State *L) else for (i=0; iramp[i] = (*((UINT8 **)luaL_checkudata(L, 3, META_COLORRAMP)))[i]; - skincolor_modified[info-skincolors] = true; + skincolor_modified[cnum] = true; } else if (fastcmp(field,"invcolor")) { UINT16 v = (UINT16)luaL_checkinteger(L, 3); if (v >= numskincolors) - return luaL_error(L, "attempt to set skincolor_t field 'invcolor' to out of range value %d.", v); + return luaL_error(L, "skincolor_t field 'invcolor' out of range (1 - %d)", numskincolors-1); info->invcolor = v; } else if (fastcmp(field,"invshade")) info->invshade = (UINT8)luaL_checkinteger(L, 3)%COLORRAMPSIZE; else if (fastcmp(field,"chatcolor")) info->chatcolor = (UINT16)luaL_checkinteger(L, 3); - else if (fastcmp(field,"accessible")) - info->accessible = lua_toboolean(L, 3); - else + else if (fastcmp(field,"accessible")) { + boolean v = lua_toboolean(L, 3); + if (cnum < FIRSTSUPERCOLOR && v != skincolors[cnum].accessible) + return luaL_error(L, "skincolors[] index %d is a standard color; accessibility changes are prohibited.", cnum); + else + info->accessible = v; + } else CONS_Debug(DBG_LUA, M_GetText("'%s' has no field named '%s'; returning nil.\n"), "skincolor_t", field); return 1; } @@ -1688,11 +1698,11 @@ static int colorramp_get(lua_State *L) static int colorramp_set(lua_State *L) { UINT8 *colorramp = *((UINT8 **)luaL_checkudata(L, 1, META_COLORRAMP)); - UINT16 cnum = (UINT16)(((uint8_t*)colorramp - (uint8_t*)(skincolors[0].ramp))/sizeof(skincolor_t)); + UINT16 cnum = (UINT16)(((UINT8*)colorramp - (UINT8*)(skincolors[0].ramp))/sizeof(skincolor_t)); UINT32 n = luaL_checkinteger(L, 2); UINT8 i = (UINT8)luaL_checkinteger(L, 3); - if (cnum < SKINCOLOR_FIRSTFREESLOT || cnum >= numskincolors) - return luaL_error(L, "skincolors[] index %d out of range (%d - %d)", cnum, SKINCOLOR_FIRSTFREESLOT, numskincolors-1); + if (!cnum || cnum >= numskincolors) + return luaL_error(L, "skincolors[] index %d out of range (1 - %d)", cnum, numskincolors-1); if (n >= COLORRAMPSIZE) return luaL_error(L, LUA_QL("skincolor_t") " field 'ramp' index %d out of range (0 - %d)", n, COLORRAMPSIZE-1); if (hud_running)