diff --git a/polymer/eduke32/source/lunatic/con_lang.lua b/polymer/eduke32/source/lunatic/con_lang.lua index 28aadf297..67c9d3fb4 100644 --- a/polymer/eduke32/source/lunatic/con_lang.lua +++ b/polymer/eduke32/source/lunatic/con_lang.lua @@ -349,12 +349,22 @@ local function S2U(label) return { s2u(label), label } end +-- Some literal checker functions (LITERAL_CHECKING). +-- KEEPINSYNC with the actual setter code. +local function litok_gem1(lit) + return (lit >= -1) +end + +local function litok_ge0(lit) + return (lit >= 0) +end + local ActorLabels = { x = SP".x", y = SP".y", z = SP".z", cstat = SP".cstat", - picnum = { SP".picnum", SP":set_picnum(%%s)" }, + picnum = { SP".picnum", SP":set_picnum(%%s)", litok_ge0 }, shade = SP".shade", pal = SP".pal", clipdist = SP".clipdist", @@ -364,10 +374,10 @@ local ActorLabels = { yrepeat = SP".yrepeat", xoffset = SP".xoffset", yoffset = SP".yoffset", - sectnum = { SP".sectnum", SP":changesect(%%s)" }, -- set: for tsprite + sectnum = { SP".sectnum", SP":changesect(%%s)", litok_ge0 }, -- set: for tsprite statnum = { SP".statnum" }, ang = SP".ang", - owner = { SP".owner", SP":_set_owner(%%s)" }, + owner = { SP".owner", SP":_set_owner(%%s)", litok_ge0 }, xvel = SP".xvel", yvel = { SP".yvel", SP":_set_yvel(%%s)" }, -- XXX zvel = SP".zvel", @@ -380,10 +390,11 @@ local ActorLabels = { -- ActorExtra labels... htcgg = AC".cgg", + -- XXX: why <0 allowed? htpicnum = { AC".picnum", AC":set_picnum(%%s)" }, htang = AC".ang", htextra = AC".extra", - htowner = { AC".owner", AC":set_owner(%%s)" }, + htowner = { AC".owner", AC":set_owner(%%s)", litok_ge0 }, htmovflag = AC"._movflag", httempang = AC".tempang", htactorstayput = AC".stayputsect", -- NAME @@ -674,7 +685,7 @@ local SectorLabels = { floorstat = SEC".floorstat", -- CEILING - ceilingpicnum = { SEC".ceilingpicnum", SEC":set_ceilingpicnum(%%s)" }, + ceilingpicnum = { SEC".ceilingpicnum", SEC":set_ceilingpicnum(%%s)", litok_ge0 }, ceilingslope = SEC".ceilingheinum", -- NAME ceilingshade = SEC".ceilingshade", @@ -684,7 +695,7 @@ local SectorLabels = { ceilingypanning = SEC".ceilingypanning", -- FLOOR - floorpicnum = { SEC".floorpicnum", SEC":set_floorpicnum(%%s)" }, + floorpicnum = { SEC".floorpicnum", SEC":set_floorpicnum(%%s)", litok_ge0 }, floorslope = SEC".floorheinum", -- NAME floorshade = SEC".floorshade", @@ -718,8 +729,8 @@ local WallLabels = { nextwall = { WAL".nextwall", WAL":_set_nextwall(%%s)" }, nextsector = { WAL".nextsector", WAL":_set_nextsector(%%s)" }, cstat = WAL".cstat", - picnum = { WAL".picnum", WAL":set_picnum(%%s)" }, - overpicnum = { WAL".overpicnum", WAL":set_overpicnum(%%s)" }, + picnum = { WAL".picnum", WAL":set_picnum(%%s)", litok_ge0 }, + overpicnum = { WAL".overpicnum", WAL":set_overpicnum(%%s)", litok_ge0 }, shade = WAL".shade", pal = WAL".pal", xrepeat = WAL".xrepeat", @@ -751,17 +762,17 @@ local ProjectileLabels = { hitradius = PROJ".hitradius", range = PROJ".range", flashcolor = PROJ".flashcolor", - spawns = { PROJ".spawns", PROJ":set_spawns(%%s)" }, - sound = { PROJ".sound", PROJ":set_sound(%%s)" }, - isound = { PROJ".isound", PROJ":set_isound(%%s)" }, + spawns = { PROJ".spawns", PROJ":set_spawns(%%s)", litok_gem1 }, + sound = { PROJ".sound", PROJ":set_sound(%%s)", litok_gem1 }, + isound = { PROJ".isound", PROJ":set_isound(%%s)", litok_gem1 }, vel = PROJ".vel", - decal = { PROJ".decal", PROJ":set_decal(%%s)" }, - trail = { PROJ".trail", PROJ":set_trail(%%s)" }, + decal = { PROJ".decal", PROJ":set_decal(%%s)", litok_gem1 }, + trail = { PROJ".trail", PROJ":set_trail(%%s)", litok_gem1 }, tnum = PROJ".tnum", drop = PROJ".drop", offset = PROJ".offset", bounces = PROJ".bounces", - bsound = { PROJ".bsound", PROJ":set_bsound(%%s)" }, + bsound = { PROJ".bsound", PROJ":set_bsound(%%s)", litok_gem1 }, toffset = PROJ".toffset", extra = PROJ".extra", extra_rand = PROJ".extra_rand", @@ -817,7 +828,7 @@ local UserdefLabels = { fta_on = UD".fta_on", god = UDRO".god", idplayers = UDRO".idplayers", - level_number = { UD".level_number", UD":set_level_number(%%s)" }, + level_number = { UD".level_number", UD":set_level_number(%%s)", {0, MAXLEVELS-1} }, levelstats = UD".levelstats", lockout = UDRO".lockout", m_player_skill = UDRO".m_player_skill", @@ -835,7 +846,7 @@ local UserdefLabels = { showallmap = UD".showallmap", showweapons = UDRO".showweapons", statusbarscale = UDRO".statusbarscale", - volume_number = { UD".volume_number", UD":set_volume_number(%%s)" }, + volume_number = { UD".volume_number", UD":set_volume_number(%%s)", {0, MAXVOLUMES} }, weaponscale = UDRO".weaponscale", weaponswitch = UD".weaponswitch", } diff --git a/polymer/eduke32/source/lunatic/doc/lunatic.txt b/polymer/eduke32/source/lunatic/doc/lunatic.txt index 08e3baa11..11c2f657d 100644 --- a/polymer/eduke32/source/lunatic/doc/lunatic.txt +++ b/polymer/eduke32/source/lunatic/doc/lunatic.txt @@ -655,10 +655,10 @@ from `0` to `255`. ===== `sector` methods -`sec:set_ceilingpicnum(tilenum)`, `sec:set_floorpicnum(tilenum)`:: +`sec:set_ceilingpicnum(tilenum)`, {nbsp} `sec:set_floorpicnum(tilenum)`:: Set the tile number of the ceiling or floor. -[[sec_cfz_at]] `sec:ceilingzat(pos)`, `sec:floorzat(pos)`:: +[[sec_cfz_at]] `sec:ceilingzat(pos)`, {nbsp} `sec:floorzat(pos)`:: Return the z coordinate of sector `sec`'s ceiling or floor at position `pos`, which can be anything indexable with the strings `x` and `y`. diff --git a/polymer/eduke32/source/lunatic/lunacon.lua b/polymer/eduke32/source/lunatic/lunacon.lua index 13e1eba66..19fccf203 100644 --- a/polymer/eduke32/source/lunatic/lunacon.lua +++ b/polymer/eduke32/source/lunatic/lunacon.lua @@ -1894,8 +1894,15 @@ local function StructAccess(Structname, writep, index, membertab) return "_MEMBINVALID" end + -- Function checking a literal number for being OK for assignment to this + -- member. Can also be a table {min, max}. See con_lang.lua, LITERAL_CHECKING. + local lit_ok_func_or_table + if (type(armembcode)=="table") then -- Read and write accesses differ. + if (writep) then + lit_ok_func_or_table = armembcode[3] + end armembcode = armembcode[writep and 2 or 1] if (armembcode==nil) then errprintf("%s access to %s[].%s is not available", @@ -1947,7 +1954,7 @@ local function StructAccess(Structname, writep, index, membertab) end end - return code, ismethod + return code, ismethod, lit_ok_func_or_table end function lookup.array_expr(writep, structname, index, membertab) @@ -2020,13 +2027,20 @@ end local function SetStructCmd(accessfunc, pattern) local function capfunc(idx, memb, var) - local membercode, ismethod = accessfunc(true, idx, memb) ---[[ - local member = memb[1]:lower() - if (type(var)=="number" and var<0 and member:match("picnum")) then - warnprintf("member '.%s' is set to a negative value", member) + -- litok: function or table + local membercode, ismethod, litok = accessfunc(true, idx, memb) + + -- Light static checking for literal values being OK for member + -- assignment. LITERAL_CHECKING. + if (type(var)=="number" and litok) then + if (type(litok)=="table" and not (var>=litok[1] and var<=litok[2]) or + type(litok)=="function" and not litok(var)) then + local member = memb[1]:lower() + warnprintf("setting member '.%s' to %d will fail at game time", + member, var) + end end ---]] + if (ismethod) then -- METHOD_MEMBER syntax