-- Game control module for Lunatic. local require = require local ffi = require("ffi") local ffiC = ffi.C local jit = require("jit") -- Lua C API functions, this comes from El_PushCFunctions() in lunatic_game.c. local CF = CF local bit = require("bit") local io = require("io") local math = require("math") local table = require("table") local bcheck = require("bcheck") local con_lang = require("con_lang") local byte = require("string").byte local setmetatable = setmetatable local assert = assert local error = error local ipairs = ipairs local pairs = pairs local print = print local rawget = rawget local rawset = rawset local select = select local tostring = tostring local type = type local unpack = unpack local format = require("string").format local actor, player = assert(actor), assert(player) local dc = require("defs_common") local cansee, hitscan, neartag = dc.cansee, dc.hitscan, dc.neartag local inside = dc.inside local sector, wall, sprite = dc.sector, dc.wall, dc.sprite local wallsofsect = dc.wallsofsect local spritesofsect, spritesofstat = dc.spritesofsect, dc.spritesofstat local OUR_REQUIRE_STRING = [[ local _con=require'con' local _ga,_av,_pv=_con._gamearray,_con.actorvar,_con.playervar ]] local function our_get_require() return OUR_REQUIRE_STRING end module(...) ---=== ACTION/MOVE/AI HELPERS ===--- local lastid = { action=0, move=0, ai=0 } 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") -- 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 literal_am = { action=literal_act, move=literal_mov } local am_ctype = { action=con_action_ct, move=con_move_ct } local function def_action_or_move(what, tab) if (lastid[what] <= -(2^31)) then error("Too many "..what.."s defined", 3); end bcheck.top_level(what, 4) if (type(tab) ~= "table") then error("invalid argument to con."..what..": must be a table", 3) end -- Named actions or moves have negative ids so that non-negative ones -- can be used as (different) placeholders for all-zero ones. lastid[what] = lastid[what]-1 -- Pass args table to ffi.new, which can take either: a table with numeric -- indices, or a table with key-value pairs, *but not in combination*. -- See http://luajit.org/ext_ffi_semantics.html#init_table return am_ctype[what](lastid[what], tab) end ---=== ACTION/MOVE/AI FUNCTIONS ===--- function action(tab) return def_action_or_move("action", tab) end function move(tab) return def_action_or_move("move", tab) end -- Get action or move for an 'ai' definition. local function get_action_or_move(what, val, argi) if (val == nil) then return literal_am[what][0] elseif (ffi.istype(am_ctype[what], val)) then return val elseif (type(val)=="number") then if (val==0 or val==1) then return literal_am[what][val] end end error("bad argument #"..argi.." to ai: must be nil/nothing, 0, 1, or "..what, 3) end function ai(action, move, flags) bcheck.top_level("ai") if (lastid.ai <= -(2^31)) then error("Too many AIs defined", 2); end local act = get_action_or_move("action", action, 2) local mov = get_action_or_move("move", move, 3) if (flags~=nil) then if (type(flags)~="number" or not (flags>=0 and flags<=32767)) then error("bad argument #4 to ai: must be a number in [0..32767]", 2) end else flags = 0 end lastid.ai = lastid.ai-1 return con_ai_ct(lastid.ai, act, mov, flags) end ---=== RUNTIME CON FUNCTIONS ===--- local check_sector_idx = bcheck.sector_idx local check_tile_idx = bcheck.tile_idx local check_sprite_idx = bcheck.sprite_idx local check_player_idx = bcheck.player_idx local check_sound_idx = bcheck.sound_idx local check_type = bcheck.type -- Will contain [