mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-15 17:01:51 +00:00
Lunatic: sinking in code.
git-svn-id: https://svn.eduke32.com/eduke32@3324 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
d7cfde9d3d
commit
cc090a2ea8
7 changed files with 228 additions and 27 deletions
|
@ -11,6 +11,7 @@ local setmetatable = setmetatable
|
|||
|
||||
local error = error
|
||||
local type = type
|
||||
local unpack = unpack
|
||||
|
||||
local player = assert(player)
|
||||
local defs_c = require("defs_common")
|
||||
|
@ -73,6 +74,8 @@ local function action_or_move(what, numargs, tab, name, ...)
|
|||
tab[name] = ffi.new("const con_"..what.."_t", lastid[what], args)
|
||||
end
|
||||
|
||||
---=== ACTION / MOVE / AI ===---
|
||||
|
||||
function action(name, ...)
|
||||
action_or_move("action", 5, def.action, name, ...)
|
||||
end
|
||||
|
@ -124,9 +127,116 @@ end
|
|||
|
||||
---=== RUNTIME CON FUNCTIONS ===---
|
||||
|
||||
-- TODO: also check whether sprite exists in the game world (statnum != MAXSTATUS)
|
||||
local function check_sprite_idx(i)
|
||||
if (i >= ffiC.MAXSPRITES+0ULL) then
|
||||
error("invalid argument: must be a valid sprite index", 3)
|
||||
end
|
||||
end
|
||||
|
||||
local function check_tile_idx(tilenum)
|
||||
if (tilenum >= ffiC.MAXTILES+0ULL) then
|
||||
error("invalid argument: must be a valid tile number", 3)
|
||||
end
|
||||
end
|
||||
|
||||
local function krandand(mask)
|
||||
return bit.band(ffiC.krand(), mask)
|
||||
end
|
||||
|
||||
-- Lunatic's "insertsprite" is a wrapper around the game "A_InsertSprite", not
|
||||
-- the engine "insertsprite".
|
||||
--
|
||||
-- Forms:
|
||||
-- 1. table-call: insertsprite{tilenum, pos, sectnum [, owner [, statnum]] [, key=val...]}
|
||||
-- valid keys are: owner, statnum, shade, xrepeat, yrepeat, xvel, zvel
|
||||
-- 2. position-call: insertsprite(tilenum, pos, sectnum [, owner [, statnum]])
|
||||
function insertsprite(tab_or_tilenum, ...)
|
||||
local tilenum, pos, sectnum -- mandatory
|
||||
-- optional with defaults:
|
||||
local owner, statnum
|
||||
local shade, xrepeat, yrepeat, xvel, zvel = 0, 48, 48, 0, 0
|
||||
|
||||
if (type(tab_or_sectnum)=="table") then
|
||||
local tab = tab_or_tilenum
|
||||
tilenum, pos, sectnum = unpack(tab, 1, 3)
|
||||
owner = tab[4] or tab.owner or -1
|
||||
statnum = tab[5] or tab.statnum or 0
|
||||
shade = shade and tab.shade
|
||||
xrepeat = xrepeat and tab.xrepeat
|
||||
yrepeat = yrepeat and tab.yrepeat
|
||||
xvel = xvel and tab.xvel
|
||||
zvel = zvel and tab.zvel
|
||||
else
|
||||
tilenum = table_or_tilenum
|
||||
local args = {...}
|
||||
pos, sectnum = unpack(args, 1, 2)
|
||||
owner = args[3] or -1
|
||||
statnum = args[4] or 0
|
||||
end
|
||||
|
||||
if (type(sectnum)~="number" or type(tilenum) ~= "number") then
|
||||
error("invalid insertsprite call: 'sectnum' and 'tilenum' must be numbers", 2)
|
||||
end
|
||||
check_tile_idx(tilenum)
|
||||
defs_c.check_sector_idx(sectnum)
|
||||
if (statnum >= ffiC.MAXSTATUS) then
|
||||
error("invalid 'statnum' argument to insertsprite: must be a status number (0 .. MAXSTATUS-1)", 2)
|
||||
end
|
||||
|
||||
return ffiC.A_InsertSprite(sectnum, pos.x, pos.y, pos.z, tilenum,
|
||||
shade, xrepeat, yrepeat, ang, xvel, zvel,
|
||||
owner, statnum)
|
||||
end
|
||||
|
||||
-- INTERNAL USE ONLY.
|
||||
function _addtodelqueue(spritenum)
|
||||
check_sprite_idx(spritenum)
|
||||
ffiC.A_AddToDeleteQueue(spritenum)
|
||||
end
|
||||
|
||||
-- This corresponds to the first (spawn from parent sprite) form of A_Spawn().
|
||||
function spawn(parentspritenum, tilenum, addtodelqueue)
|
||||
check_sprite_idx(parentspritenum)
|
||||
check_tile_idx(tilenum)
|
||||
|
||||
if (addtodelqueue and ffiC.g_spriteDeleteQueueSize == 0) then
|
||||
return -1
|
||||
end
|
||||
|
||||
local i = ffiC.A_Spawn(parentspritenum, tilenum)
|
||||
if (addtodelqueue) then
|
||||
ffiC.A_AddToDeleteQueue(i)
|
||||
end
|
||||
return i
|
||||
end
|
||||
|
||||
-- This is the second A_Spawn() form. INTERNAL USE ONLY.
|
||||
function _spawnexisting(spritenum)
|
||||
check_sprite_idx(spritenum)
|
||||
return ffiC.A_Spawn(-1, spritenum)
|
||||
end
|
||||
|
||||
-- A_SpawnMultiple clone
|
||||
-- ow: parent sprite number
|
||||
function _spawnmany(ow, tilenum, n)
|
||||
local spr = sprite[ow]
|
||||
|
||||
for i=n,1, -1 do
|
||||
local j = insertsprite{ tilenum, spr^(ffiC.krand()%(47*256)), spr.sectnum, ow, 5,
|
||||
shade=-32, xrepeat=8, yrepeat=8, ang=krandand(2047) }
|
||||
_spawnexisting(j)
|
||||
sprite[j].cstat = krandand(8+4)
|
||||
end
|
||||
end
|
||||
|
||||
function isenemytile(tilenum)
|
||||
return (bit.band(ffiC.g_tile[tilenum], ffiC.SFLAG_BADGUY)~=0)
|
||||
end
|
||||
|
||||
function rotatesprite(x, y, zoom, ang, tilenum, shade, pal, orientation,
|
||||
cx1, cy1, cx2, cy2)
|
||||
if (type(tilenum) ~= "number" or not (tilenum >= 0 and tilenum < ffiC.MAXTILES)) then
|
||||
if (type(tilenum) ~= "number" or tilenum >= ffiC.MAXTILES+0ULL) then
|
||||
error("bad argument #5 to rotatesprite: must be number in [0.."..ffiC.MAXTILES.."]", 2)
|
||||
end
|
||||
|
||||
|
@ -187,17 +297,68 @@ local D = {
|
|||
HEATSENSOR = 59,
|
||||
BOOTS = 61,
|
||||
HOLODUKE = 1348,
|
||||
|
||||
GLASSPIECES = 1031,
|
||||
COMMANDER = 1920,
|
||||
JIBS2 = 2250,
|
||||
SCRAP1 = 2400,
|
||||
BLIMP = 3400,
|
||||
}
|
||||
|
||||
local function check_sprite_idx(i)
|
||||
if (i >= ffiC.MAXSPRITES+0ULL) then
|
||||
error("invalid argument: must be a valid sprite index", 3)
|
||||
function _A_DoGuts(i, gutstile, n)
|
||||
check_tile_idx(gutstile)
|
||||
local spr = sprite[i]
|
||||
local smallguts = spr.xrepeat < 16 and spr:isenemy()
|
||||
local xsz = smallguts and 8 or 32
|
||||
local ysz = xsz
|
||||
local z = math.min(spr, sector[spr.sectnum]:floorzat(spr)) - 8*256
|
||||
|
||||
if (spr.picnum == D.COMMANDER) then
|
||||
z = z - (24*256)
|
||||
end
|
||||
|
||||
for i=n,1, -1 do
|
||||
local pos = geom.vec3(spr.x+krandand(255)-128, spr.y+krandand(255)-128, z-krandand(8191))
|
||||
local j = insertsprite{ gutstile, pos, spr.sectnum, i, 5, shade=-32, xrepeat=xsz, yrepeat=ysz,
|
||||
ang=krandand(2047), xvel=48+krandand(31), zvel=-512-krandand(2047) }
|
||||
local newspr = sprite[j]
|
||||
if (newspr.picnum==D.JIBS2) then
|
||||
-- This looks silly, but EVENT_EGS code could have changed the size
|
||||
-- between the insertion and here.
|
||||
newspr.xrepeat = newspr.xrepeat/4
|
||||
newspr.yrepeat = newspr.yrepeat/4
|
||||
end
|
||||
newspr.pal = spr.pal
|
||||
end
|
||||
end
|
||||
|
||||
local function check_tile_idx(tilenum)
|
||||
if (tilenum >= ffiC.MAXTILES+0ULL) then
|
||||
error("invalid argument: must be a valid tile number", 3)
|
||||
function _debris(i, dtile, n)
|
||||
local spr = sprite[i]
|
||||
if (spr.sectnum >= ffiC.numsectors+0ULL) then
|
||||
return
|
||||
end
|
||||
|
||||
for j=n-1,0, -1 do
|
||||
local isblimpscrap = (spr.picnum==D.BLIMP and dtile==D.SCRAP1)
|
||||
local picofs = isblimpscrap and 0 or krandand(3)
|
||||
local pos = spr + geom.vec3(krandand(255)-128, krandand(255)-128, -(8*256)-krandand(8191))
|
||||
local jj = insertsprite{ dtile+picofs, pos, spr.sectnum, i, 5,
|
||||
shade=spr.shade, xrepeat=32+krandand(15), yrepeat=32+krandand(15),
|
||||
ang=krandand(2047), xvel=32+krandand(127), zvel=-krandand(2047) }
|
||||
-- NOTE: BlimpSpawnSprites[14] (its array size if 15) will never be chosen
|
||||
sprite[jj].yvel = isblimpscrap and ffiC.BlimpSpawnSprites[math.mod(jj, 14)] or -1
|
||||
sprite[jj].pal = spr.pal
|
||||
end
|
||||
end
|
||||
|
||||
function _A_SpawnGlass(i, n)
|
||||
local spr = sprite[i]
|
||||
|
||||
for j=n,1, -1 do
|
||||
local k = insertsprite{ D.GLASSPIECES+n%3, spr^(256*krandand(16)), spr.sectnum, i, 5,
|
||||
shade=krandand(15), xrepeat=36, yrepeat=36, ang=krandand(2047),
|
||||
xvel=32+krandand(63), zvel=-512-krandand(2047) }
|
||||
sprite[k].pal = spr.pal
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -403,10 +564,6 @@ function _awayfromwall(spr, d)
|
|||
return true
|
||||
end
|
||||
|
||||
local function krandand(mask)
|
||||
return bit.band(ffiC.krand(), mask)
|
||||
end
|
||||
|
||||
local BANG2RAD = math.pi/1024
|
||||
|
||||
local function cossinb(bang)
|
||||
|
|
|
@ -454,6 +454,8 @@ playerdata_t g_player[MAXPLAYERS];
|
|||
|
||||
const int32_t playerswhenstarted;
|
||||
int32_t lastvisinc;
|
||||
int16_t g_spriteDeleteQueueSize;
|
||||
int16_t BlimpSpawnSprites[15];
|
||||
|
||||
int32_t A_IncurDamage(int32_t sn); // not bound-checked!
|
||||
void P_AddWeaponMaybeSwitch(DukePlayer_t *ps, int32_t weap);
|
||||
|
@ -465,6 +467,10 @@ int32_t VM_ResetPlayer2(int32_t snum);
|
|||
void A_RadiusDamage(int32_t i, int32_t r, int32_t, int32_t, int32_t, int32_t);
|
||||
void G_OperateSectors(int32_t sn, int32_t ii);
|
||||
int32_t A_Dodge(spritetype *s);
|
||||
int32_t A_InsertSprite(int32_t whatsect,int32_t s_x,int32_t s_y,int32_t s_z,int32_t s_pn,int32_t s_s,
|
||||
int32_t s_xr,int32_t s_yr,int32_t s_a,int32_t s_ve,int32_t s_zv,int32_t s_ow,int32_t s_ss);
|
||||
int32_t A_Spawn(int32_t j, int32_t pn);
|
||||
void A_AddToDeleteQueue(int32_t i);
|
||||
]]
|
||||
|
||||
-- functions
|
||||
|
|
|
@ -209,6 +209,11 @@ const int16_t headsectbunch[2][MAXBUNCHES], nextsectbunch[2][MAXSECTORS];
|
|||
|
||||
int16_t yax_getbunch(int16_t i, int16_t cf);
|
||||
|
||||
int32_t getceilzofslopeptr(const sectortype *sec, int32_t dax, int32_t day);
|
||||
int32_t getflorzofslopeptr(const sectortype *sec, int32_t dax, int32_t day);
|
||||
void getzsofslopeptr(const sectortype *sec, int32_t dax, int32_t day,
|
||||
int32_t *ceilz, int32_t *florz);
|
||||
|
||||
int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
|
||||
hitdata_t *hitinfo, uint32_t cliptype);
|
||||
int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1,
|
||||
|
@ -248,6 +253,19 @@ local ivec3_mt = {
|
|||
}
|
||||
ivec3_ = ffi.metatype("vec3_t", ivec3_mt)
|
||||
|
||||
local sectortype_mt = {
|
||||
__index = {
|
||||
ceilingzat = function(s, pos)
|
||||
return ffiC.getceilzofslope(s, pos.x, pos.y)
|
||||
end,
|
||||
|
||||
floorzat = function(s, pos)
|
||||
return ffiC.getflorzofslope(s, pos.x, pos.y)
|
||||
end,
|
||||
}
|
||||
}
|
||||
ffi.metatype("sectortype", sectortype_mt)
|
||||
|
||||
local walltype_mt = {
|
||||
__index = {
|
||||
isblocking = function(w)
|
||||
|
@ -356,7 +374,7 @@ nextspritestat = creategtab(ffiC.nextspritestat, ffiC.MAXSPRITES, 'nextspritesta
|
|||
prevspritesect = creategtab(ffiC.prevspritesect, ffiC.MAXSPRITES, 'prevspritesect[]')
|
||||
prevspritestat = creategtab(ffiC.prevspritestat, ffiC.MAXSPRITES, 'prevspritestat[]')
|
||||
|
||||
local function check_sector_idx(sectnum)
|
||||
function check_sector_idx(sectnum)
|
||||
if (sectnum >= ffiC.numsectors+0ULL) then
|
||||
error("passed out-of-bounds sector number "..sectnum, 3)
|
||||
end
|
||||
|
|
|
@ -17,6 +17,10 @@ ydim;
|
|||
|
||||
yax_getbunch;
|
||||
|
||||
getceilzofslopeptr;
|
||||
getflorzofslopeptr;
|
||||
getzsofslopeptr;
|
||||
|
||||
headspritesect;
|
||||
headspritestat;
|
||||
prevspritesect;
|
||||
|
@ -63,6 +67,8 @@ g_player;
|
|||
|
||||
playerswhenstarted;
|
||||
lastvisinc;
|
||||
g_spriteDeleteQueueSize;
|
||||
BlimpSpawnSprites;
|
||||
|
||||
luaJIT_BC_lunacon;
|
||||
luaJIT_BC_con_lang;
|
||||
|
@ -86,4 +92,7 @@ VM_ResetPlayer2;
|
|||
A_RadiusDamage;
|
||||
G_OperateSectors;
|
||||
A_Dodge;
|
||||
A_InsertSprite;
|
||||
A_Spawn;
|
||||
A_AddToDeleteQueue;
|
||||
};
|
||||
|
|
|
@ -17,6 +17,10 @@ ydim;
|
|||
|
||||
yax_getbunch;
|
||||
|
||||
getceilzofslopeptr;
|
||||
getflorzofslopeptr;
|
||||
getzsofslopeptr;
|
||||
|
||||
headspritesect;
|
||||
headspritestat;
|
||||
prevspritesect;
|
||||
|
|
|
@ -19,6 +19,7 @@ local print = print
|
|||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local type = type
|
||||
local unpack = unpack
|
||||
|
||||
if (string.dump) then
|
||||
require("strict")
|
||||
|
@ -119,10 +120,7 @@ local function on_actor_end(usertype, tsamm, codetab)
|
|||
str = str .. tostring(tsamm[i])..","
|
||||
end
|
||||
if (#tsamm==5) then
|
||||
local flags = 0
|
||||
for i=5,#tsamm do
|
||||
flags = bit.bor(flags, tsamm[i])
|
||||
end
|
||||
local flags = bit.bor(unpack(tsamm, 5))
|
||||
str = str .. flags..","
|
||||
end
|
||||
|
||||
|
@ -690,7 +688,7 @@ local varvarop = cmd(W,R)
|
|||
-- Allow nesting... stuff like
|
||||
-- ifvarl actorvar[sprite[THISACTOR].owner].burning 0
|
||||
-- is kinda breaking the classic "no array nesting" rules
|
||||
-- (if there ever were any) and making our life harder else.
|
||||
-- (if there ever were any) but making our life harder else.
|
||||
local arraypat = sp0 * "[" * sp0 * t_rvar * sp0 * "]"
|
||||
|
||||
-- Have to bite the bullet here and list actor/player members with second parameters,
|
||||
|
@ -887,11 +885,11 @@ local Ci = {
|
|||
addweapon = cmd(D,D) -- NLCF
|
||||
/ format("if (%s) then _con.longjmp() end", PLS":addweapon(%1,%2)"),
|
||||
debris = cmd(D,D)
|
||||
/ "", -- TODO
|
||||
/ "_con._debris(_aci, %1, %2)",
|
||||
addinventory = cmd(D,D)
|
||||
/ PLS":addinventory(%1,%2)",
|
||||
guts = cmd(D,D)
|
||||
/ "", -- TODO
|
||||
/ "_con._A_DoGuts(_aci,%1,%2)",
|
||||
|
||||
-- cont'd
|
||||
addkills = cmd(D)
|
||||
|
@ -908,14 +906,16 @@ local Ci = {
|
|||
espawn = cmd(D),
|
||||
globalsound = cmd(D)
|
||||
/ "",
|
||||
lotsofglass = cmd(D),
|
||||
lotsofglass = cmd(D)
|
||||
/ "_con._A_SpawnGlass(_aci,%1)",
|
||||
mail = cmd(D)
|
||||
/ "", -- TODO
|
||||
/ "_con._spawnmany(_aci,4410,%1)", -- TODO: dyntile
|
||||
money = cmd(D)
|
||||
/ "", -- TODO
|
||||
/ "_con._spawnmany(_aci,1233,%1)", -- TODO: dyntile
|
||||
paper = cmd(D)
|
||||
/ "", -- TODO
|
||||
qspawn = cmd(D),
|
||||
/ "_con._spawnmany(_aci,4460,%1)", -- TODO: dyntile
|
||||
qspawn = cmd(D)
|
||||
/ "_con.spawn(_aci,%1,true)",
|
||||
quote = cmd(D)
|
||||
/ "", -- TODO
|
||||
savenn = cmd(D),
|
||||
|
@ -925,7 +925,8 @@ local Ci = {
|
|||
soundonce = cmd(D),
|
||||
sound = cmd(D)
|
||||
/ "", -- TODO: all things audio...
|
||||
spawn = cmd(D),
|
||||
spawn = cmd(D)
|
||||
/ "_con.spawn(_aci, %1)",
|
||||
stopsound = cmd(D)
|
||||
/ "",
|
||||
|
||||
|
@ -943,7 +944,8 @@ local Ci = {
|
|||
/ format("_con._flash(%s,%s)", ACS"", SPS""),
|
||||
getlastpal = cmd()
|
||||
/ "_con._getlastpal(_aci)",
|
||||
insertspriteq = cmd(),
|
||||
insertspriteq = cmd()
|
||||
/ "_con._addtodelqueue(_aci)",
|
||||
killit = cmd() -- NLCF
|
||||
/ "_con.killit()",
|
||||
mikesnd = cmd()
|
||||
|
@ -1483,8 +1485,8 @@ local Grammar = Pat{
|
|||
|
||||
-- Some often-used terminals follow. These appear here because we're
|
||||
-- hitting a limit with LPeg else.
|
||||
|
||||
-- http://lua-users.org/lists/lua-l/2008-11/msg00462.html
|
||||
|
||||
-- NOTE: NW demo (NWSNOW.CON) contains a Ctrl-Z char (decimal 26)
|
||||
whitespace = Set(" \t\r\26") + newline + Set("(),;") + comment + linecomment,
|
||||
|
||||
|
|
|
@ -303,6 +303,11 @@ require("test/test_rotspr")
|
|||
|
||||
print('---=== END TEST SCRIPT ===---')
|
||||
|
||||
function check_sector_idx()
|
||||
error("bla")
|
||||
end
|
||||
spritesofsect(0)
|
||||
|
||||
-- This will complain about wrong usage of 'error'. In particular,
|
||||
-- the nil must not propagate to C!
|
||||
error(nil)
|
||||
|
|
Loading…
Reference in a new issue