mirror of
https://github.com/ZDoom/Raze.git
synced 2024-11-16 09:21:36 +00:00
Lunatic: implement a couple more 1.5 commands.
git-svn-id: https://svn.eduke32.com/eduke32@2869 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
8fa80701bb
commit
7f4eb4f5c3
4 changed files with 165 additions and 21 deletions
|
@ -946,6 +946,7 @@ skip_check:
|
|||
#ifdef LUNATIC
|
||||
set_action_members(vm.g_i);
|
||||
#endif
|
||||
// NOTE: "if (g_t[5])" added in r1155. It used to be a pointer though.
|
||||
if (vm.g_t[5])
|
||||
{
|
||||
vm.g_t[1] = *(script + vm.g_t[5] + 1); // move
|
||||
|
|
|
@ -12,26 +12,34 @@ local type = type
|
|||
module(...)
|
||||
|
||||
|
||||
local lastid = { action=0, move=0 }
|
||||
local lastid = { action=0, move=0, ai=0 }
|
||||
local def = { action={}, move={}, ai={} }
|
||||
|
||||
local function forbidden() error("newindex forbidden", 2) end
|
||||
local ac, mv = {}, {}
|
||||
|
||||
AC = setmetatable({}, { __index=ac, __newindex=forbidden })
|
||||
MV = setmetatable({}, { __index=mv, __newindex=forbidden })
|
||||
AC = setmetatable({}, { __index=def.action, __newindex=forbidden })
|
||||
MV = setmetatable({}, { __index=def.move, __newindex=forbidden })
|
||||
AI = setmetatable({}, { __index=def.ai, __newindex=forbidden })
|
||||
|
||||
local function check_name(name, what, errlev)
|
||||
if (type(name)~="string" or #name > 63) then
|
||||
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, ...)
|
||||
assert(lastid[what] > -(2^31))
|
||||
if (type(name)~="string" or #name > 63) then
|
||||
error("bad argument #1 to "..what..": must be a string of length <= 63", 3)
|
||||
end
|
||||
check_name(name, what, 3)
|
||||
|
||||
local args = {...}
|
||||
assert(#args <= numargs)
|
||||
|
||||
for i=1,#args do
|
||||
local n = args[i]
|
||||
assert(type(n)=="number" and (n >= -32768 and n <= 32767))
|
||||
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
|
||||
-- missing fields are initialized to 0 by ffi.new
|
||||
|
||||
|
@ -46,9 +54,47 @@ local function action_or_move(what, numargs, tab, name, ...)
|
|||
end
|
||||
|
||||
function action(name, ...)
|
||||
action_or_move("action", 5, ac, name, ...)
|
||||
action_or_move("action", 5, def.action, name, ...)
|
||||
end
|
||||
|
||||
function move(name, ...)
|
||||
action_or_move("move", 2, mv, name, ...)
|
||||
action_or_move("move", 2, def.move, name, ...)
|
||||
end
|
||||
|
||||
|
||||
local function get_action_or_move(what, val, argi)
|
||||
if (val == nil) then
|
||||
return {} -- will init the struct to all zeros
|
||||
elseif (type(val)=="string") 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
|
||||
end
|
||||
|
||||
-- TODO: literal number actions/moves?
|
||||
error("bad argument #"..argi.." to ai: must be string or "..what)
|
||||
end
|
||||
|
||||
function ai(name, action, move, flags)
|
||||
assert(lastid.ai > -(2^31))
|
||||
check_name(name, "ai", 2)
|
||||
|
||||
lastid.ai = lastid.ai-1
|
||||
|
||||
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
|
||||
|
||||
def.ai[name] = ffi.new("const con_ai_t", lastid.ai, act, mov, flags)
|
||||
end
|
||||
|
|
|
@ -67,7 +67,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
vec3_t pos;
|
||||
int16_t hitsprite, hitwall, hitsect;
|
||||
int16_t sprite, wall, sect;
|
||||
} hitdata_t;
|
||||
|
||||
typedef struct {
|
||||
|
@ -247,6 +247,13 @@ struct move {
|
|||
typedef struct { int32_t id; struct move mv; } con_move_t;
|
||||
typedef struct { int32_t id; struct action ac; } con_action_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t id;
|
||||
con_action_t act;
|
||||
con_move_t mov;
|
||||
int32_t movflags;
|
||||
} con_ai_t;
|
||||
|
||||
// TODO: still need to make some fields read-only
|
||||
// NOTE: must not expose arrays in structs!!!
|
||||
typedef struct
|
||||
|
@ -255,9 +262,9 @@ typedef struct
|
|||
..repeat_n_elts("int32_t", "_t", 10)..
|
||||
[[
|
||||
// const int32_t t_data[10]; // 56b sometimes used to hold offsets to con code
|
||||
struct move mv;
|
||||
struct action ac;
|
||||
const int16_t padding_;
|
||||
const struct move mv;
|
||||
const struct action ac;
|
||||
const int16_t _padding;
|
||||
|
||||
int16_t picnum,ang,extra,owner; //8b
|
||||
int16_t movflag,tempang,timetosleep; //6b
|
||||
|
@ -562,7 +569,7 @@ string.dump = nil
|
|||
|
||||
-- sanity-check struct type sizes
|
||||
for i=0,6 do
|
||||
assert(ffi.sizeof(ffi.typeof(ffi.string(ffiC.g_sizes_of_what[i])))
|
||||
assert(ffi.sizeof(ffi.string(ffiC.g_sizes_of_what[i]))
|
||||
== ffiC.g_sizes_of[i])
|
||||
end
|
||||
|
||||
|
@ -575,30 +582,117 @@ local con = require("con")
|
|||
-- All-zero action and move
|
||||
local nullac, nullmv = ffi.new("const struct action"), ffi.new("const struct move")
|
||||
|
||||
local function check_literal_am(am)
|
||||
if (type(am) ~= "number") then
|
||||
error("bad argument: expected number", 3)
|
||||
end
|
||||
|
||||
if (not (am >= 0 and am <= 32767)) then
|
||||
error("bad argument: expected number in [0 .. 32767]", 3)
|
||||
end
|
||||
end
|
||||
|
||||
local actor_mt = {
|
||||
__index = {
|
||||
-- action
|
||||
set_action = function(a, act)
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
if (ffi.istype("con_action_t", act)) then
|
||||
a.t_data[4] = act.id
|
||||
a.ac = act.ac
|
||||
else
|
||||
assert(type(act)=="number" and act >= 0 and act <= 32767)
|
||||
check_literal_am(act)
|
||||
a.t_data[4] = act
|
||||
a.ac = nullac
|
||||
end
|
||||
|
||||
a.t_data[2] = 0
|
||||
a.t_data[3] = 0
|
||||
end,
|
||||
|
||||
set_move = function(a, mv)
|
||||
has_action = function(a, act)
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
if (ffi.istype("con_action_t", act)) then
|
||||
return (a.t_data[4]==act.id)
|
||||
else
|
||||
check_literal_am(act)
|
||||
return (a.t_data[4]==act)
|
||||
end
|
||||
end,
|
||||
|
||||
-- count
|
||||
set_count = function(a)
|
||||
ffi.cast("actor_u_t *", a).t_data[0] = 0
|
||||
end,
|
||||
|
||||
get_count = function(a)
|
||||
return ffi.cast("actor_u_t *", a).t_data[0]
|
||||
end,
|
||||
|
||||
-- action count
|
||||
reset_acount = function(a)
|
||||
ffi.cast("actor_u_t *", a).t_data[2] = 0
|
||||
end,
|
||||
|
||||
get_acount = function(a)
|
||||
return ffi.cast("actor_u_t *", a).t_data[2]
|
||||
end,
|
||||
|
||||
-- move
|
||||
set_move = function(a, mov, movflags)
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
if (ffi.istype("con_move_t", mov)) then
|
||||
a.t_data[4] = mov.id
|
||||
a.t_data[1] = mov.id
|
||||
a.mv = mov.mv
|
||||
else
|
||||
assert(type(mov)=="number" and mov >= 0 and mov <= 32767)
|
||||
a.t_data[4] = mov
|
||||
check_literal_am(mov)
|
||||
a.t_data[1] = mov
|
||||
a.mv = nullmv
|
||||
end
|
||||
|
||||
a.t_data[0] = 0
|
||||
local i = a-ffi.cast("actor_u_t *", ffiC.actor[0])
|
||||
ffiC.sprite[i].hitag = movflags or 0
|
||||
|
||||
-- TODO: random angle moveflag
|
||||
end,
|
||||
|
||||
has_move = function(a, mov)
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
if (ffi.istype("con_move_t", mov)) then
|
||||
return (a.t_data[1]==mov.id)
|
||||
else
|
||||
check_literal_am(mov)
|
||||
return (a.t_data[1]==mov)
|
||||
end
|
||||
end,
|
||||
|
||||
-- ai
|
||||
set_ai = function(a, ai)
|
||||
local oa = a
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
|
||||
-- TODO: literal number AIs?
|
||||
assert(ffi.istype("con_ai_t", ai))
|
||||
|
||||
-- NOTE: compare with gameexec.c
|
||||
a.t_data[5] = ai.id
|
||||
|
||||
oa:set_action(ai.act)
|
||||
oa:set_move(ai.mov, ai.movflags)
|
||||
|
||||
a.t_data[0] = 0
|
||||
end,
|
||||
|
||||
has_ai = function(a, ai)
|
||||
a = ffi.cast("actor_u_t *", a)
|
||||
|
||||
if (ffi.istype("con_ai_t", ai)) then
|
||||
return (a.t_data[5]==ai.id)
|
||||
else
|
||||
check_literal_am(ai)
|
||||
return (a.t_data[5]==ai)
|
||||
end
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -233,8 +233,10 @@ local stat = require("stat")
|
|||
local hs = stat.new()
|
||||
|
||||
local con = require("con")
|
||||
local AC = con.AC
|
||||
local AC, MV = con.AC, con.MV
|
||||
con.action("TROOPFLINTCH", 50, 1, 1, 1, 6)
|
||||
con.move("SHRUNKVELS", 32)
|
||||
con.ai("AITEMP", "TROOPFLINTCH", MV.SHRUNKVELS, 0) -- TODO: test
|
||||
|
||||
gameactor(1680, -- LIZTROOP
|
||||
function(i, playeri, dist)
|
||||
|
@ -257,6 +259,7 @@ gameactor(1680, -- LIZTROOP
|
|||
if (dist < 4096) then
|
||||
-- Duke Vader / Anakin Nukewalker?
|
||||
actor[i]:set_action(AC.TROOPFLINTCH)
|
||||
actor[i]:set_move(MV.SHRUNKVELS)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue