mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 01:11:28 +00:00
Lunatic: don't register con.action/move/ai by name, make these return a cdata.
git-svn-id: https://svn.eduke32.com/eduke32@3916 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
16f2f4c475
commit
36f3a8e47c
6 changed files with 101 additions and 136 deletions
|
@ -77,11 +77,14 @@ enum uactortypes_t {
|
||||||
|
|
||||||
#ifdef LUNATIC
|
#ifdef LUNATIC
|
||||||
struct action {
|
struct action {
|
||||||
|
// These members MUST be in this exact order because FFI cdata of this type
|
||||||
|
// can be initialized by passing a table with numeric indices (con.action).
|
||||||
int16_t startframe, numframes;
|
int16_t startframe, numframes;
|
||||||
int16_t viewtype, incval, delay;
|
int16_t viewtype, incval, delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct move {
|
struct move {
|
||||||
|
// These members MUST be in this exact order.
|
||||||
int16_t hvel, vvel;
|
int16_t hvel, vvel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ end
|
||||||
|
|
||||||
function bcheck.top_level(funcname)
|
function bcheck.top_level(funcname)
|
||||||
if (ffiC.g_elCallDepth > 0) then
|
if (ffiC.g_elCallDepth > 0) then
|
||||||
error("Invalid use of "..funcname..": must be called from top level", 3)
|
error("Invalid use of "..funcname..": must be called from top level", errlev or 3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -104,9 +104,9 @@ function bcheck.number(val, errlev)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function bcheck.type(val, typestr)
|
function bcheck.type(val, typestr, errlev)
|
||||||
if (type(val)~=typestr) then
|
if (type(val)~=typestr) then
|
||||||
error("invalid argument: must be a "..typestr, 3)
|
error("invalid argument: must be a "..typestr, errlev or 3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ local pairs = pairs
|
||||||
local print = print
|
local print = print
|
||||||
local rawget = rawget
|
local rawget = rawget
|
||||||
local rawset = rawset
|
local rawset = rawset
|
||||||
|
local select = select
|
||||||
local tostring = tostring
|
local tostring = tostring
|
||||||
local type = type
|
local type = type
|
||||||
local unpack = unpack
|
local unpack = unpack
|
||||||
|
@ -53,99 +54,73 @@ end
|
||||||
module(...)
|
module(...)
|
||||||
|
|
||||||
|
|
||||||
|
---=== ACTION/MOVE/AI HELPERS ===---
|
||||||
|
|
||||||
local lastid = { action=0, move=0, ai=0 }
|
local lastid = { action=0, move=0, ai=0 }
|
||||||
local def = {
|
|
||||||
action = { NO=ffi.new("con_action_t") },
|
|
||||||
move = { NO=ffi.new("con_move_t") },
|
|
||||||
ai = { NO=ffi.new("con_ai_t") },
|
|
||||||
}
|
|
||||||
|
|
||||||
local function forbidden() error("newindex forbidden", 2) end
|
local con_action_ct = ffi.typeof("const con_action_t")
|
||||||
|
local con_move_ct = ffi.typeof("const con_move_t")
|
||||||
|
local con_ai_ct = ffi.typeof("const con_ai_t")
|
||||||
|
|
||||||
AC = setmetatable({}, { __index=def.action, __newindex=forbidden })
|
-- All-zero action and move with IDs. Mostly for CON support.
|
||||||
MV = setmetatable({}, { __index=def.move, __newindex=forbidden })
|
local literal_act = { [0]=con_action_ct(0), [1]=con_action_ct(1) }
|
||||||
AI = setmetatable({}, { __index=def.ai, __newindex=forbidden })
|
local literal_mov = { [0]=con_move_ct(0), [1]=con_move_ct(1) }
|
||||||
|
|
||||||
local function check_name(name, what, errlev)
|
local literal_am = { action=literal_act, move=literal_mov }
|
||||||
if (type(name)~="string" or #name > 63) then
|
local am_ctype = { action=con_action_ct, move=con_move_ct }
|
||||||
error("bad argument #1 to "..what..": must be a string of length <= 63", errlev+1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function action_or_move(what, numargs, tab, name, ...)
|
local function def_action_or_move(what, tab)
|
||||||
if (lastid[what] <= -(2^31)) then
|
if (lastid[what] <= -(2^31)) then
|
||||||
error("Too many "..what.."s defined", 3);
|
error("Too many "..what.."s defined", 3);
|
||||||
end
|
end
|
||||||
check_name(name, what, 3)
|
|
||||||
|
|
||||||
local args = {...}
|
bcheck.top_level(what, 4)
|
||||||
if (#args > numargs) then
|
|
||||||
error("Too many arguments passed to "..what, 3)
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1,#args do
|
if (type(tab) ~= "table") then
|
||||||
local n = args[i]
|
error("invalid argument to con."..what..": must be a table", 3)
|
||||||
if (type(n)~="number" or not (n >= -32768 and n <= 32767)) then
|
|
||||||
error("bad argument #".. i+1 .." to "..what..
|
|
||||||
": must be numbers in [-32768..32767]", 3)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
-- missing fields are initialized to 0 by ffi.new
|
|
||||||
|
|
||||||
-- Named actions or moves have negative ids so that non-negative ones
|
-- Named actions or moves have negative ids so that non-negative ones
|
||||||
-- can be used as (different) placeholders for all-zero ones.
|
-- can be used as (different) placeholders for all-zero ones.
|
||||||
lastid[what] = lastid[what]-1
|
lastid[what] = lastid[what]-1
|
||||||
|
|
||||||
-- ffi.new takes either for initialization: varargs, a table with numeric
|
-- Pass args table to ffi.new, which can take either: a table with numeric
|
||||||
-- indices, or a table with key-value pairs
|
-- indices, or a table with key-value pairs.
|
||||||
-- See http://luajit.org/ext_ffi_semantics.html#init_table
|
-- See http://luajit.org/ext_ffi_semantics.html#init_table
|
||||||
tab[name] = ffi.new("const con_"..what.."_t", lastid[what], args)
|
return am_ctype[what](lastid[what], tab)
|
||||||
end
|
end
|
||||||
|
|
||||||
---=== ACTION / MOVE / AI ===---
|
---=== ACTION/MOVE/AI FUNCTIONS ===---
|
||||||
|
|
||||||
function action(name, ...)
|
function action(tab)
|
||||||
bcheck.top_level("action")
|
return def_action_or_move("action", tab)
|
||||||
action_or_move("action", 5, def.action, name, ...)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function move(name, ...)
|
function move(tab)
|
||||||
bcheck.top_level("move")
|
return def_action_or_move("move", tab)
|
||||||
action_or_move("move", 2, def.move, name, ...)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Get action or move for an 'ai' definition.
|
-- Get action or move for an 'ai' definition.
|
||||||
local function get_action_or_move(what, val, argi)
|
local function get_action_or_move(what, val, argi)
|
||||||
if (val == nil) then
|
if (val == nil) then
|
||||||
return {} -- ffi.new will init the struct to all zeros
|
return literal_am[what][0]
|
||||||
elseif (type(val)=="string") then
|
elseif (ffi.istype(am_ctype[what], val)) then
|
||||||
local am = def[what][val]
|
|
||||||
if (am==nil) then
|
|
||||||
error("no "..what.." '"..val.."' defined", 3)
|
|
||||||
end
|
|
||||||
return am
|
|
||||||
elseif (ffi.istype("con_"..what.."_t", val)) then
|
|
||||||
return val
|
return val
|
||||||
elseif (type(val)=="number") then
|
elseif (type(val)=="number") then
|
||||||
if (val==0 or val==1) then
|
if (val==0 or val==1) then
|
||||||
-- Create an action or move with an ID of 0 or 1 but all other
|
return literal_am[what][val]
|
||||||
-- fields cleared.
|
|
||||||
return ffi.new("con_"..what.."_t", val)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
error("bad argument #"..argi.." to ai: must be string or (literal) "..what, 3)
|
error("bad argument #"..argi.." to ai: must be nil/nothing, 0, 1, or "..what, 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
function ai(name, action, move, flags)
|
function ai(action, move, flags)
|
||||||
bcheck.top_level("ai")
|
bcheck.top_level("ai")
|
||||||
|
|
||||||
if (lastid.ai <= -(2^31)) then
|
if (lastid.ai <= -(2^31)) then
|
||||||
error("Too many AIs defined", 2);
|
error("Too many AIs defined", 2);
|
||||||
end
|
end
|
||||||
check_name(name, "ai", 2)
|
|
||||||
|
|
||||||
lastid.ai = lastid.ai-1
|
|
||||||
|
|
||||||
local act = get_action_or_move("action", action, 2)
|
local act = get_action_or_move("action", action, 2)
|
||||||
local mov = get_action_or_move("move", move, 3)
|
local mov = get_action_or_move("move", move, 3)
|
||||||
|
@ -158,7 +133,8 @@ function ai(name, action, move, flags)
|
||||||
flags = 0
|
flags = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def.ai[name] = ffi.new("const con_ai_t", lastid.ai, act, mov, flags)
|
lastid.ai = lastid.ai-1
|
||||||
|
return con_ai_ct(lastid.ai, act, mov, flags)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -877,7 +877,6 @@ local g_tile = setmtonce({}, defs_c.GenStructMetatable("g_tile", "MAXTILES", til
|
||||||
-- ID-wrapped types con_action_t and con_move_t
|
-- ID-wrapped types con_action_t and con_move_t
|
||||||
local con = require("control")
|
local con = require("control")
|
||||||
local isenemytile = con.isenemytile
|
local isenemytile = con.isenemytile
|
||||||
local MV, AC, AI = con.MV, con.AC, con.AI
|
|
||||||
|
|
||||||
-- Add game-side metamethods to "spritetype" and register it with "metatype"
|
-- Add game-side metamethods to "spritetype" and register it with "metatype"
|
||||||
local spr_mt_index_add = {
|
local spr_mt_index_add = {
|
||||||
|
@ -887,14 +886,13 @@ local spr_mt_index_add = {
|
||||||
}
|
}
|
||||||
defs_c.finish_spritetype(spr_mt_index_add)
|
defs_c.finish_spritetype(spr_mt_index_add)
|
||||||
|
|
||||||
-- All-zero action and move
|
-- Check a literal numeric action or move value.
|
||||||
local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move")
|
|
||||||
|
|
||||||
local function check_literal_am(am, typename)
|
local function check_literal_am(am, typename)
|
||||||
if (type(am) ~= "number") then
|
if (type(am) ~= "number") then
|
||||||
error("bad argument: expected number or "..typename, 3)
|
error("bad argument: expected number or "..typename, 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Negative values are generated as con.action/con.move IDs.
|
||||||
if (not (am >= 0 and am <= 32767)) then
|
if (not (am >= 0 and am <= 32767)) then
|
||||||
error("bad argument: expected number in [0 .. 32767]", 3)
|
error("bad argument: expected number in [0 .. 32767]", 3)
|
||||||
end
|
end
|
||||||
|
@ -905,9 +903,16 @@ local actor_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(ACTOR_STRUCT)))
|
||||||
local player_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(DUKEPLAYER_STRUCT)))
|
local player_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(DUKEPLAYER_STRUCT)))
|
||||||
local projectile_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(PROJECTILE_STRUCT)))
|
local projectile_ptr_ct = ffi.typeof("$ *", ffi.typeof(strip_const(PROJECTILE_STRUCT)))
|
||||||
local weapondata_ptr_ct = ffi.typeof("$ *", ffi.typeof((strip_const(WEAPONDATA_STRUCT):gsub(" _"," "))))
|
local weapondata_ptr_ct = ffi.typeof("$ *", ffi.typeof((strip_const(WEAPONDATA_STRUCT):gsub(" _"," "))))
|
||||||
local con_action_ct = ffi.typeof("con_action_t")
|
|
||||||
local con_move_ct = ffi.typeof("con_move_t")
|
local con_action_ct = ffi.typeof("const con_action_t")
|
||||||
local con_ai_ct = ffi.typeof("con_ai_t")
|
local con_move_ct = ffi.typeof("const con_move_t")
|
||||||
|
local con_ai_ct = ffi.typeof("const con_ai_t")
|
||||||
|
|
||||||
|
-- All-zero bare action and move.
|
||||||
|
local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move")
|
||||||
|
-- All-zero action and move with IDs. Mostly for CON support.
|
||||||
|
local literal_act = { [0]=con_action_ct(0), [1]=con_action_ct(1) }
|
||||||
|
local literal_mov = { [0]=con_move_ct(0), [1]=con_move_ct(1) }
|
||||||
|
|
||||||
local function get_actor_idx(a)
|
local function get_actor_idx(a)
|
||||||
local i = ffi.cast(actor_ptr_ct, a)-ffi.cast(actor_ptr_ct, ffiC.actor)
|
local i = ffi.cast(actor_ptr_ct, a)-ffi.cast(actor_ptr_ct, ffiC.actor)
|
||||||
|
@ -920,11 +925,7 @@ local actor_mt = {
|
||||||
-- action
|
-- action
|
||||||
set_action = function(a, act)
|
set_action = function(a, act)
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
if (type(act)=="string") then
|
|
||||||
act = AC[act];
|
|
||||||
end
|
|
||||||
-- TODO: disallow passing the FFI types altogether, in favor of
|
|
||||||
-- strings (also move, ai)?
|
|
||||||
if (ffi.istype(con_action_ct, act)) then
|
if (ffi.istype(con_action_ct, act)) then
|
||||||
a.t_data[4] = act.id
|
a.t_data[4] = act.id
|
||||||
a.ac = act.ac
|
a.ac = act.ac
|
||||||
|
@ -940,9 +941,7 @@ local actor_mt = {
|
||||||
|
|
||||||
has_action = function(a, act)
|
has_action = function(a, act)
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
if (type(act)=="string") then
|
|
||||||
act = AC[act];
|
|
||||||
end
|
|
||||||
if (ffi.istype(con_action_ct, act)) then
|
if (ffi.istype(con_action_ct, act)) then
|
||||||
return (a.t_data[4]==act.id)
|
return (a.t_data[4]==act.id)
|
||||||
else
|
else
|
||||||
|
@ -972,9 +971,7 @@ local actor_mt = {
|
||||||
-- move
|
-- move
|
||||||
set_move = function(a, mov, movflags)
|
set_move = function(a, mov, movflags)
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
if (type(mov)=="string") then
|
|
||||||
mov = MV[mov];
|
|
||||||
end
|
|
||||||
if (ffi.istype(con_move_ct, mov)) then
|
if (ffi.istype(con_move_ct, mov)) then
|
||||||
a.t_data[1] = mov.id
|
a.t_data[1] = mov.id
|
||||||
a.mv = mov.mv
|
a.mv = mov.mv
|
||||||
|
@ -997,9 +994,7 @@ local actor_mt = {
|
||||||
|
|
||||||
has_move = function(a, mov)
|
has_move = function(a, mov)
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
if (type(mov)=="string") then
|
|
||||||
mov = MV[mov];
|
|
||||||
end
|
|
||||||
if (ffi.istype(con_move_ct, mov)) then
|
if (ffi.istype(con_move_ct, mov)) then
|
||||||
return (a.t_data[1]==mov.id)
|
return (a.t_data[1]==mov.id)
|
||||||
else
|
else
|
||||||
|
@ -1013,15 +1008,12 @@ local actor_mt = {
|
||||||
local oa = a
|
local oa = a
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
|
|
||||||
if (type(ai)=="string") then
|
|
||||||
ai = AI[ai];
|
|
||||||
end
|
|
||||||
-- TODO: literal number AIs?
|
-- TODO: literal number AIs?
|
||||||
if (not ffi.istype(con_ai_ct, ai)) then
|
if (not ffi.istype(con_ai_ct, ai)) then
|
||||||
error("bad argument: expected ai", 2)
|
error("bad argument: expected ai", 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- NOTE: compare with gameexec.c
|
-- NOTE: compare with gameexec.c, "CON_AI:"
|
||||||
a.t_data[5] = ai.id
|
a.t_data[5] = ai.id
|
||||||
|
|
||||||
oa:set_action(ai.act)
|
oa:set_action(ai.act)
|
||||||
|
@ -1033,9 +1025,6 @@ local actor_mt = {
|
||||||
has_ai = function(a, ai)
|
has_ai = function(a, ai)
|
||||||
a = ffi.cast(actor_ptr_ct, a)
|
a = ffi.cast(actor_ptr_ct, a)
|
||||||
|
|
||||||
if (type(ai)=="string") then
|
|
||||||
ai = AI[ai];
|
|
||||||
end
|
|
||||||
if (ffi.istype(con_ai_ct, ai)) then
|
if (ffi.istype(con_ai_ct, ai)) then
|
||||||
return (a.t_data[5]==ai.id)
|
return (a.t_data[5]==ai.id)
|
||||||
else
|
else
|
||||||
|
@ -1048,14 +1037,14 @@ local actor_mt = {
|
||||||
-- TODO: make a bcarray instead.
|
-- TODO: make a bcarray instead.
|
||||||
get_t_data = function(a, idx)
|
get_t_data = function(a, idx)
|
||||||
if (idx >= 10ULL) then
|
if (idx >= 10ULL) then
|
||||||
error("Invalid t_data index "..idx, 2)
|
error("invalid t_data index "..idx, 2)
|
||||||
end
|
end
|
||||||
return ffi.cast(actor_ptr_ct, a).t_data[idx]
|
return ffi.cast(actor_ptr_ct, a).t_data[idx]
|
||||||
end,
|
end,
|
||||||
|
|
||||||
_set_t_data = function(a, idx, val)
|
_set_t_data = function(a, idx, val)
|
||||||
if (idx >= 10ULL) then
|
if (idx >= 10ULL) then
|
||||||
error("Invalid t_data index "..idx, 2)
|
error("invalid t_data index "..idx, 2)
|
||||||
end
|
end
|
||||||
ffi.cast(actor_ptr_ct, a).t_data[idx] = val
|
ffi.cast(actor_ptr_ct, a).t_data[idx] = val
|
||||||
end,
|
end,
|
||||||
|
@ -1661,7 +1650,8 @@ local function our_require(modname, ...)
|
||||||
local ok, retval = coroutine.resume(modthread, omodname, ...)
|
local ok, retval = coroutine.resume(modthread, omodname, ...)
|
||||||
|
|
||||||
if (not ok) then
|
if (not ok) then
|
||||||
errorf(ERRLEV-1, "Failed running \"%s\": %s", modname, retval)
|
errorf(ERRLEV-1, "Failed running \"%s\": %s\n%s", modname,
|
||||||
|
retval, debug.traceback(modthread))
|
||||||
end
|
end
|
||||||
|
|
||||||
table.remove(modname_stack)
|
table.remove(modname_stack)
|
||||||
|
@ -1795,11 +1785,15 @@ local function chain_func3(func1, func2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Determines the last numeric index of a table using *ipairs*.
|
-- Determines the last numeric index of a table using *pairs*, so that in
|
||||||
|
-- arg-lists with "holes" (e.g. {1, 2, nil, function() end}) are handled
|
||||||
|
-- properly.
|
||||||
local function ourmaxn(tab)
|
local function ourmaxn(tab)
|
||||||
local maxi = 0
|
local maxi = 0
|
||||||
for i in ipairs(tab) do
|
for i in pairs(tab) do
|
||||||
maxi = math.max(i, maxi)
|
if (type(i)=="number") then
|
||||||
|
maxi = math.max(i, maxi)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return maxi
|
return maxi
|
||||||
end
|
end
|
||||||
|
@ -1836,7 +1830,7 @@ local function our_gameactor(args)
|
||||||
lastargi = 1/0
|
lastargi = 1/0
|
||||||
end
|
end
|
||||||
if (type(func) ~= "function") then
|
if (type(func) ~= "function") then
|
||||||
error("invalid gameactor call: must provide a function with last numeric arg or .func", 2)
|
error("invalid gameactor call: must provide a function with last numeric arg or .func".." "..type(func), 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
local flags = (lastargi > 2 and args[2]) or args.flags or 0
|
local flags = (lastargi > 2 and args[2]) or args.flags or 0
|
||||||
|
@ -1874,25 +1868,21 @@ local function our_gameactor(args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: literal number action other than 0?
|
local act = ((lastargi > 4 and args[4]) or args.action) or (replacep and literal_act[0] or nil)
|
||||||
local act = ((lastargi > 4 and args[4]) or args.action) or (replacep and "NO" or nil)
|
|
||||||
if (replacep or act ~= nil) then
|
if (replacep or act ~= nil) then
|
||||||
if (type(act)=="string") then
|
if (type(act)=="number" and (act==0 or act==1)) then
|
||||||
act = AC[act]
|
act = literal_act[act]
|
||||||
end
|
elseif (not ffi.istype(con_action_ct, act)) then
|
||||||
if (not ffi.istype(con_action_ct, act)) then
|
error("invalid 'action' argument (#4) to gameactor: must be an action", 2)
|
||||||
error("invalid 'action' argument (#4) to gameactor: must be a string or action", 2)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO: literal number move other than 0?
|
local mov = ((lastargi > 5 and args[5]) or args.move) or (replacep and literal_mov[0] or nil)
|
||||||
local mov = ((lastargi > 5 and args[5]) or args.move) or (replacep and "NO" or nil)
|
|
||||||
if (replacep or mov ~= nil) then
|
if (replacep or mov ~= nil) then
|
||||||
if (type(mov)=="string") then
|
if (type(mov)=="number" and (mov==0 or mov==1)) then
|
||||||
mov = MV[mov]
|
mov = literal_mov[mov]
|
||||||
end
|
elseif (not ffi.istype(con_move_ct, mov)) then
|
||||||
if (not ffi.istype(con_move_ct, mov)) then
|
error("invalid 'move' argument (#5) to gameactor: must be a move", 2)
|
||||||
error("invalid 'move' argument (#5) to gameactor: must be a string or move", 2)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -203,6 +203,7 @@ local function new_initial_codetab()
|
||||||
"-- NOTE to the reader: This require's result is Lunatic-private API! DO NOT USE!",
|
"-- NOTE to the reader: This require's result is Lunatic-private API! DO NOT USE!",
|
||||||
"local _dummy,_S=require'end_gamevars'",
|
"local _dummy,_S=require'end_gamevars'",
|
||||||
"local _V,_A=_V,_A",
|
"local _V,_A=_V,_A",
|
||||||
|
"local _C,_M,_I={},{},{}", -- actions, moves, ais
|
||||||
|
|
||||||
-- Static ivec3s so that no allocations need to be made.
|
-- Static ivec3s so that no allocations need to be made.
|
||||||
"local _IVEC = { _xmath.ivec3(), _xmath.ivec3() }",
|
"local _IVEC = { _xmath.ivec3(), _xmath.ivec3() }",
|
||||||
|
@ -414,11 +415,6 @@ function on.actor_end(pos, usertype, tsamm, codetab)
|
||||||
|
|
||||||
local str = flags..","
|
local str = flags..","
|
||||||
for i=2,math.min(#tsamm,4) do
|
for i=2,math.min(#tsamm,4) do
|
||||||
if ((i==3 or i==4) and tsamm[i]=="0") then
|
|
||||||
-- HACK, gameactor() currently doesn't support literals for actions
|
|
||||||
-- and moves.
|
|
||||||
tsamm[i] = "'NO'"
|
|
||||||
end
|
|
||||||
str = str .. tostring(tsamm[i])..","
|
str = str .. tostring(tsamm[i])..","
|
||||||
end
|
end
|
||||||
if (#tsamm >= 5) then
|
if (#tsamm >= 5) then
|
||||||
|
@ -605,8 +601,9 @@ end
|
||||||
local LABEL = { MOVE=2, AI=3, ACTION=5, [2]="move", [3]="ai", [5]="action",
|
local LABEL = { MOVE=2, AI=3, ACTION=5, [2]="move", [3]="ai", [5]="action",
|
||||||
NUMBER=1, [1]="number" }
|
NUMBER=1, [1]="number" }
|
||||||
|
|
||||||
-- Function names in the 'con' module
|
-- Function names in the 'con' module:
|
||||||
local LABEL_FUNCNAME = { [2]="move", [3]="ai", [5]="action" }
|
local LABEL_FUNCNAME = { [2]="move", [3]="ai", [5]="action" }
|
||||||
|
local LABEL_PREFIX = { [2]="M", [3]="I", [5]="C" } -- _C, _M, _I in the gen'd code
|
||||||
|
|
||||||
local g_labeldef = {} -- Lua numbers for numbers, strings for composites
|
local g_labeldef = {} -- Lua numbers for numbers, strings for composites
|
||||||
local g_labeltype = {}
|
local g_labeltype = {}
|
||||||
|
@ -705,7 +702,8 @@ local function check_sysvar_def_attempt(identifier)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function do_define_label(identifier, num)
|
local Define = {}
|
||||||
|
function Define.label(identifier, num)
|
||||||
if (check_sysvar_def_attempt(identifier)) then
|
if (check_sysvar_def_attempt(identifier)) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -774,9 +772,6 @@ function lookup.composite(labeltype, pos, identifier)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Generate a quoted identifier name.
|
|
||||||
val = format("%q", identifier)
|
|
||||||
|
|
||||||
return val
|
return val
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -788,7 +783,7 @@ local function check_reserved_bits(flags, allowedbits, suffix)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function do_define_composite(labeltype, identifier, ...)
|
function Define.composite(labeltype, identifier, ...)
|
||||||
local oldtype = g_labeltype[identifier]
|
local oldtype = g_labeltype[identifier]
|
||||||
local oldval = g_labeldef[identifier]
|
local oldval = g_labeldef[identifier]
|
||||||
|
|
||||||
|
@ -831,9 +826,11 @@ local function do_define_composite(labeltype, identifier, ...)
|
||||||
args[i] = format("%d", args[i])
|
args[i] = format("%d", args[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
addcodef("_con.%s(%q,%s)", LABEL_FUNCNAME[labeltype], identifier, table.concat(args, ","))
|
local refcode = mangle_name(identifier, LABEL_PREFIX[labeltype])
|
||||||
|
addcodef(isai and "%s=_con.%s(%s)" or "%s=_con.%s{%s}", -- ai has parens
|
||||||
|
refcode, LABEL_FUNCNAME[labeltype], table.concat(args, ","))
|
||||||
|
|
||||||
g_labeldef[identifier] = ""
|
g_labeldef[identifier] = refcode
|
||||||
g_labeltype[identifier] = labeltype
|
g_labeltype[identifier] = labeltype
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1488,7 +1485,7 @@ local Couter = {
|
||||||
includedefault = cmd()
|
includedefault = cmd()
|
||||||
/ Cmd.NYI("`includedefault'"),
|
/ Cmd.NYI("`includedefault'"),
|
||||||
define = cmd(I,D)
|
define = cmd(I,D)
|
||||||
/ do_define_label,
|
/ Define.label,
|
||||||
|
|
||||||
--- 2. Defines and Meta-Settings
|
--- 2. Defines and Meta-Settings
|
||||||
dynamicremap = cmd()
|
dynamicremap = cmd()
|
||||||
|
@ -1558,17 +1555,17 @@ local Couter = {
|
||||||
|
|
||||||
--- 5. Top level commands that are also run-time commands
|
--- 5. Top level commands that are also run-time commands
|
||||||
move = sp1 * tok.identifier * (sp1 * tok.define)^-2 -- hvel, vvel
|
move = sp1 * tok.identifier * (sp1 * tok.define)^-2 -- hvel, vvel
|
||||||
/ function(...) do_define_composite(LABEL.MOVE, ...) end,
|
/ function(...) Define.composite(LABEL.MOVE, ...) end,
|
||||||
|
|
||||||
-- startframe, numframes, viewtype, incval, delay:
|
-- startframe, numframes, viewtype, incval, delay:
|
||||||
action = sp1 * tok.identifier * (sp1 * tok.define)^-5
|
action = sp1 * tok.identifier * (sp1 * tok.define)^-5
|
||||||
/ function(...) do_define_composite(LABEL.ACTION, ...) end,
|
/ function(...) Define.composite(LABEL.ACTION, ...) end,
|
||||||
|
|
||||||
-- action, move, flags...:
|
-- action, move, flags...:
|
||||||
ai = sp1 * tok.identifier * (sp1 * tok.action *
|
ai = sp1 * tok.identifier * (sp1 * tok.action *
|
||||||
(sp1 * tok.move * (sp1 * tok.define)^0)^-1
|
(sp1 * tok.move * (sp1 * tok.define)^0)^-1
|
||||||
)^-1
|
)^-1
|
||||||
/ function(...) do_define_composite(LABEL.AI, ...) end,
|
/ function(...) Define.composite(LABEL.AI, ...) end,
|
||||||
|
|
||||||
--- 6. Deprecated TLCs
|
--- 6. Deprecated TLCs
|
||||||
betaname = newline_term_string,
|
betaname = newline_term_string,
|
||||||
|
@ -3220,6 +3217,7 @@ local Grammar = Pat{
|
||||||
* sp1 * Var("single_stmt") * (lpeg.Cc(nil) / on.while_end),
|
* sp1 * Var("single_stmt") * (lpeg.Cc(nil) / on.while_end),
|
||||||
|
|
||||||
stmt_common = Keyw("{") * sp1 * "}" / "" -- space separation of commands in CON is for a reason!
|
stmt_common = Keyw("{") * sp1 * "}" / "" -- space separation of commands in CON is for a reason!
|
||||||
|
-- XXX: this do...end can lead to exceeding Lua nesting limits, see nightstrike's tan.con
|
||||||
+ lpeg.Ct(Keyw("{")/"do" * sp1 * stmt_list * sp1 * (Keyw("}")/"end"))
|
+ lpeg.Ct(Keyw("{")/"do" * sp1 * stmt_list * sp1 * (Keyw("}")/"end"))
|
||||||
+ con_inner_command + Var("switch_stmt") + lpeg.Ct(Var("while_stmt")),
|
+ con_inner_command + Var("switch_stmt") + lpeg.Ct(Var("while_stmt")),
|
||||||
|
|
||||||
|
@ -3564,7 +3562,8 @@ if (string.dump) then
|
||||||
|
|
||||||
-- msgfile:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
-- msgfile:write(format("-- GENERATED CODE for \"%s\":\n", filename))
|
||||||
if (func == nil) then
|
if (func == nil) then
|
||||||
msgfile:write(format("-- INVALID Lua CODE: %s\n", errmsg))
|
msgfile:write(format("-- %s%s: INVALID Lua CODE: %s\n",
|
||||||
|
g_directory, filename, errmsg))
|
||||||
end
|
end
|
||||||
|
|
||||||
if (lineinfo) then
|
if (lineinfo) then
|
||||||
|
|
|
@ -395,15 +395,12 @@ local hs = stat.new()
|
||||||
local con = require("con")
|
local con = require("con")
|
||||||
local AC, MV = con.AC, con.MV
|
local AC, MV = con.AC, con.MV
|
||||||
|
|
||||||
con.action("TROOPSTAND",0,1,5,1,1)
|
local AC, MV = {}, {}
|
||||||
con.action("TROOPFLINTCH", 50, 1, 1, 1, 6)
|
|
||||||
con.move("SHRUNKVELS", 32)
|
AC.TROOPSTAND = con.action{0,1,5,1,1}
|
||||||
con.ai("AITEMP", AC.TROOPFLINTCH, MV.SHRUNKVELS, 0) -- TODO: test
|
AC.TROOPFLINTCH = con.action{50, 1, 1, 1, 6}
|
||||||
-- This should work as well. In fact, it's exactly the same, but I prefer the
|
MV.SHRUNKVELS = con.move{hvel=32}
|
||||||
-- above version for clarity. NOTE: we'll need to think whether it's OK to
|
con.ai(AC.TROOPFLINTCH, MV.SHRUNKVELS, 0) -- unused; TODO: test
|
||||||
-- redefine composites (moves/actions/ais) during gameplay (probably not).
|
|
||||||
-- Or will we allow only one definition per label ever?
|
|
||||||
con.ai("AITEMP", "TROOPFLINTCH", "SHRUNKVELS", 0)
|
|
||||||
|
|
||||||
local TROOPSTRENGTH = 30
|
local TROOPSTRENGTH = 30
|
||||||
|
|
||||||
|
@ -415,7 +412,7 @@ gameactor
|
||||||
{
|
{
|
||||||
D.LIZTROOP, AF.chain_end+AF.enemy, 2*TROOPSTRENGTH,
|
D.LIZTROOP, AF.chain_end+AF.enemy, 2*TROOPSTRENGTH,
|
||||||
|
|
||||||
action = "TROOPSTAND",
|
action = AC.TROOPSTAND,
|
||||||
|
|
||||||
func = function(i, playeri, dist)
|
func = function(i, playeri, dist)
|
||||||
spriteext[i]:make_animated()
|
spriteext[i]:make_animated()
|
||||||
|
@ -446,8 +443,8 @@ gameactor
|
||||||
|
|
||||||
if (dist < 4096) then
|
if (dist < 4096) then
|
||||||
-- Duke Vader / Anakin Nukewalker?
|
-- Duke Vader / Anakin Nukewalker?
|
||||||
actor[i]:set_action("TROOPFLINTCH")
|
actor[i]:set_action(AC.TROOPFLINTCH)
|
||||||
actor[i]:set_move("SHRUNKVELS")
|
actor[i]:set_move(MV.SHRUNKVELS)
|
||||||
|
|
||||||
if (dist < 1024) then
|
if (dist < 1024) then
|
||||||
con.killit()
|
con.killit()
|
||||||
|
|
Loading…
Reference in a new issue