Lunatic: allow indexing some weapon/inventory arrays with their names.

git-svn-id: https://svn.eduke32.com/eduke32@3564 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2013-03-15 16:56:19 +00:00
parent 9285a9054b
commit ef464f2a1d
3 changed files with 57 additions and 34 deletions

View file

@ -26,12 +26,20 @@ module(...)
-- For example, for 4 elements, -- For example, for 4 elements,
-- "const $ _r1, _f2, _u3, _n4;" -- "const $ _r1, _f2, _u3, _n4;"
function flatten_array(nelts, rng) function flatten_array(nelts, rng)
local strtab = { "const $ " } local strtab = { "$ " }
if (rng and rng.getu32==nil) then
assert(type(rng)=="table")
for i=1,#rng do
strtab[i+1] = rng[i]..((i<#rng) and "," or ";")
end
else
for i=1,nelts do for i=1,nelts do
local ch = 97 + (rng and (rng:getu32() % 25) or 0) -- 'a'..'z' local ch = 97 + (rng and (rng:getu32() % 25) or 0) -- 'a'..'z'
strtab[i+1] = string.format("_%c%x%s", ch, i, (i<nelts) and "," or ";") strtab[i+1] = string.format("_%c%x%s", ch, i, (i<nelts) and "," or ";")
end end
end
return table.concat(strtab) return table.concat(strtab)
end end
@ -44,6 +52,7 @@ end
-- <typename>: If non-nil, the name under which the derived type is typedef'd -- <typename>: If non-nil, the name under which the derived type is typedef'd
-- <rng>: Random generator state + method :getu32(). If nil, then members are -- <rng>: Random generator state + method :getu32(). If nil, then members are
-- named _a1, _a2, ... -- named _a1, _a2, ...
-- It also may be a table containing member names at numeric indices 1..#rng.
-- <mtadd>: A table containing functions __index and/or __newindex. They are -- <mtadd>: A table containing functions __index and/or __newindex. They are
-- called first and the bound-checking ones are tail-called then. -- called first and the bound-checking ones are tail-called then.
function new(basetype, numelts, showname, typename, rng, mtadd) function new(basetype, numelts, showname, typename, rng, mtadd)
@ -72,6 +81,7 @@ function new(basetype, numelts, showname, typename, rng, mtadd)
local addindexf, addnewindexf = mtadd.__index, mtadd.__newindex local addindexf, addnewindexf = mtadd.__index, mtadd.__newindex
if (addindexf) then if (addindexf) then
-- Additional __index metamethod given.
mt.__index = function(ar, idx) mt.__index = function(ar, idx)
addindexf(ar, idx) addindexf(ar, idx)
return curindexf(ar, idx) return curindexf(ar, idx)
@ -79,6 +89,7 @@ function new(basetype, numelts, showname, typename, rng, mtadd)
end end
if (addnewindexf) then if (addnewindexf) then
-- Additional __newindex metamethod given.
mt.__newindex = function(ar, idx, val) mt.__newindex = function(ar, idx, val)
addnewindexf(ar, idx, val) addnewindexf(ar, idx, val)
return curnewindexf(ar, idx, val) return curnewindexf(ar, idx, val)

View file

@ -63,43 +63,51 @@ local print = print
---=== EDuke32 game definitions ===--- ---=== EDuke32 game definitions ===---
local INV_NAMES = {
"STEROIDS",
"SHIELD",
"SCUBA",
"HOLODUKE",
"JETPACK",
"DUMMY1",
"ACCESS",
"HEATS",
"DUMMY2",
"FIRSTAID",
"BOOTS",
}
local WEAPON_NAMES = {
"KNEE",
"PISTOL",
"SHOTGUN",
"CHAINGUN",
"RPG",
"HANDBOMB",
"SHRINKER",
"DEVISTATOR",
"TRIPBOMB",
"FREEZE",
"HANDREMOTE",
"GROW",
}
---- game structs ---- ---- game structs ----
ffi.cdef[[ ffi.cdef([[
enum dukeinv_t { enum dukeinv_t {
GET_STEROIDS, ]].. "GET_"..table.concat(INV_NAMES, ",GET_") ..[[,
GET_SHIELD,
GET_SCUBA,
GET_HOLODUKE,
GET_JETPACK,
GET_DUMMY1,
GET_ACCESS,
GET_HEATS,
GET_DUMMY2,
GET_FIRSTAID,
GET_BOOTS,
GET_MAX GET_MAX
}; };
enum dukeweapon_t { enum dukeweapon_t {
KNEE_WEAPON, ]].. table.concat(WEAPON_NAMES, "_WEAPON,").."_WEAPON," ..[[
PISTOL_WEAPON,
SHOTGUN_WEAPON,
CHAINGUN_WEAPON,
RPG_WEAPON,
HANDBOMB_WEAPON,
SHRINKER_WEAPON,
DEVISTATOR_WEAPON,
TRIPBOMB_WEAPON,
FREEZE_WEAPON,
HANDREMOTE_WEAPON,
GROW_WEAPON,
MAX_WEAPONS MAX_WEAPONS
}; };
enum { enum {
MAXPLAYERS = 16, MAXPLAYERS = 16,
}; };
]] ]])
ffi.cdef[[ ffi.cdef[[
struct action { struct action {
@ -161,10 +169,9 @@ local check_sprite_idx = bcheck.sprite_idx
local check_weapon_idx, check_inventory_idx = bcheck.weapon_idx, bcheck.inventory_idx local check_weapon_idx, check_inventory_idx = bcheck.weapon_idx, bcheck.inventory_idx
local check_sound_idx = bcheck.sound_idx local check_sound_idx = bcheck.sound_idx
-- TODO: randomize member names bcarray.new("int16_t", 64, "loogie", "int16_x_64") -- TODO: randomize member names
bcarray.new("int16_t", 64, "loogie", "int16_x_64") bcarray.new("int16_t", ffiC.MAX_WEAPONS, "weapon", "int16_x_MAX_WEAPONS", WEAPON_NAMES)
bcarray.new("int16_t", ffiC.MAX_WEAPONS, "weapon", "int16_x_MAX_WEAPONS") bcarray.new("int16_t", ffiC.GET_MAX, "inventory", "int16_x_GET_MAX", INV_NAMES)
bcarray.new("int16_t", ffiC.GET_MAX, "inventory", "int16_x_GET_MAX")
-- NOTE: writing e.g. "ps.jetpack_on" in Lua when "ps.jetpack_on~=0" was meant -- NOTE: writing e.g. "ps.jetpack_on" in Lua when "ps.jetpack_on~=0" was meant
-- is probably one of the most commonly committed errors, so we make it a bool -- is probably one of the most commonly committed errors, so we make it a bool

View file

@ -141,7 +141,7 @@ checkfail('sprite._nextspritesect[4] = -666', "cannot write directly to nextspri
-- we're indexing a plain array! -- we're indexing a plain array!
checkfail('print(sprite._nextspritesect[4].whatfield)', "attempt to index a number value") checkfail('print(sprite._nextspritesect[4].whatfield)', "attempt to index a number value")
-- creating new keys forbidden... handled by LuaJit -- creating new keys forbidden... handled by LuaJIT
checkfail('wall[4].QWE = 123', "has no member named 'QWE'") checkfail('wall[4].QWE = 123', "has no member named 'QWE'")
-- our 'require' has only safe stuff -- our 'require' has only safe stuff
@ -278,10 +278,15 @@ gameevent(gv.EVENT_ENTERLEVEL,
gv.ksqrt(0xffffffff), math.sqrt(0xffffffff)) gv.ksqrt(0xffffffff), math.sqrt(0xffffffff))
local pl = player[0] local pl = player[0]
-- MAX < current is "allowed"
pl.max_ammo_amount[gv.RPG_WEAPON] = 17 pl.max_ammo_amount[gv.RPG_WEAPON] = 17
pl:give_weapon(gv.RPG_WEAPON) pl:give_weapon(gv.RPG_WEAPON)
pl.ammo_amount[gv.RPG_WEAPON] = 54 pl.ammo_amount[gv.RPG_WEAPON] = 54
pl:give_weapon(gv.SHRINKER_WEAPON)
-- This looks much prettier:
pl.ammo_amount.SHRINKER = 2
-- MORTER2 from test/weaponvars.con -- MORTER2 from test/weaponvars.con
player[0].weapon.SHOTGUN.shoots = 1653 player[0].weapon.SHOTGUN.shoots = 1653
local proj = projectile[1653] local proj = projectile[1653]