mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 19:20:46 +00:00
Scripting: Add EVENT_DAMAGEHPLANE and document it in Lunatic doc Appendix B.
Also add test/damagehplane.lua with these demonstrations: - custom breakable ceilings - breakable TROR glass git-svn-id: https://svn.eduke32.com/eduke32@4206 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
f10e1b1a16
commit
0c69779b98
9 changed files with 187 additions and 9 deletions
|
@ -695,6 +695,7 @@ const char *EventNames[MAXEVENTS] =
|
||||||
"EVENT_SAVEGAME",
|
"EVENT_SAVEGAME",
|
||||||
"EVENT_PREGAME",
|
"EVENT_PREGAME",
|
||||||
"EVENT_CHANGEMENU",
|
"EVENT_CHANGEMENU",
|
||||||
|
"EVENT_DAMAGEHPLANE",
|
||||||
#ifdef LUNATIC
|
#ifdef LUNATIC
|
||||||
"EVENT_ANIMATEALLSPRITES",
|
"EVENT_ANIMATEALLSPRITES",
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -125,8 +125,9 @@ enum GameEvent_t {
|
||||||
EVENT_SAVEGAME,
|
EVENT_SAVEGAME,
|
||||||
EVENT_PREGAME,
|
EVENT_PREGAME,
|
||||||
EVENT_CHANGEMENU,
|
EVENT_CHANGEMENU,
|
||||||
|
EVENT_DAMAGEHPLANE, // 95
|
||||||
#ifdef LUNATIC
|
#ifdef LUNATIC
|
||||||
EVENT_ANIMATEALLSPRITES, // 95
|
EVENT_ANIMATEALLSPRITES,
|
||||||
#endif
|
#endif
|
||||||
MAXEVENTS
|
MAXEVENTS
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ MAXGAMETYPES = 16
|
||||||
|
|
||||||
MAXSKILLS = 7
|
MAXSKILLS = 7
|
||||||
|
|
||||||
MAXEVENTS = 95 -- KEEPINSYNC with EVENT_* list
|
MAXEVENTS = 96 -- KEEPINSYNC with EVENT_* list
|
||||||
MAXSOUNDS = 4096
|
MAXSOUNDS = 4096
|
||||||
|
|
||||||
MAXSESSIONVARS = 8 -- KEEPINSYNC lunatic_game.c
|
MAXSESSIONVARS = 8 -- KEEPINSYNC lunatic_game.c
|
||||||
|
@ -170,7 +170,8 @@ EVENT = {
|
||||||
EVENT_SAVEGAME = 92,
|
EVENT_SAVEGAME = 92,
|
||||||
EVENT_PREGAME = 93,
|
EVENT_PREGAME = 93,
|
||||||
EVENT_CHANGEMENU = 94,
|
EVENT_CHANGEMENU = 94,
|
||||||
-- EVENT_ANIMATEALLSPRITES = 95, -- internal
|
EVENT_DAMAGEHPLANE = 95,
|
||||||
|
-- EVENT_ANIMATEALLSPRITES = 96, -- internal
|
||||||
}
|
}
|
||||||
|
|
||||||
-- NOTE: negated values are not exported to the ffi.C namespace or CON.
|
-- NOTE: negated values are not exported to the ffi.C namespace or CON.
|
||||||
|
|
|
@ -272,6 +272,8 @@ end
|
||||||
function insertsprite(tab_or_tilenum, ...)
|
function insertsprite(tab_or_tilenum, ...)
|
||||||
local tilenum, pos, sectnum -- mandatory
|
local tilenum, pos, sectnum -- mandatory
|
||||||
-- optional with defaults:
|
-- optional with defaults:
|
||||||
|
-- TODO: swap order of owner and statnum?
|
||||||
|
-- XXX: owner -1 valid???
|
||||||
local owner, statnum
|
local owner, statnum
|
||||||
local shade, xrepeat, yrepeat, ang, xvel, zvel = 0, 48, 48, 0, 0, 0
|
local shade, xrepeat, yrepeat, ang, xvel, zvel = 0, 48, 48, 0, 0, 0
|
||||||
|
|
||||||
|
|
|
@ -2091,7 +2091,7 @@ local function our_gameactor(args)
|
||||||
|
|
||||||
-- Register our EVENT_ANIMATEALLSPRITES only now so that it is not
|
-- Register our EVENT_ANIMATEALLSPRITES only now so that it is not
|
||||||
-- called if there are no 'animate' definitions.
|
-- called if there are no 'animate' definitions.
|
||||||
gameevent_internal(95, animate_all_sprites) -- EVENT_ANIMATEALLSPRITES
|
gameevent_internal(96, animate_all_sprites) -- EVENT_ANIMATEALLSPRITES
|
||||||
end
|
end
|
||||||
|
|
||||||
-- All good, set the tile bits in initial run and register the actor!
|
-- All good, set the tile bits in initial run and register the actor!
|
||||||
|
|
|
@ -884,7 +884,7 @@ static_members.sector.STAT = conststruct
|
||||||
TRANS2 = 128,
|
TRANS2 = 128,
|
||||||
TRANS1 = 256,
|
TRANS1 = 256,
|
||||||
BLOCK = 512,
|
BLOCK = 512,
|
||||||
HITSCAN = 1024,
|
HITSCAN = 2048,
|
||||||
|
|
||||||
FLIP_BITMASK = 16+32,
|
FLIP_BITMASK = 16+32,
|
||||||
ORIENT_BITMASK = 4+16+32,
|
ORIENT_BITMASK = 4+16+32,
|
||||||
|
@ -936,6 +936,8 @@ static_members.sprite.CSTAT = conststruct
|
||||||
|
|
||||||
ALIGN_BITMASK = 16+32,
|
ALIGN_BITMASK = 16+32,
|
||||||
TRANS_BITMASK = 2+512,
|
TRANS_BITMASK = 2+512,
|
||||||
|
|
||||||
|
INVISIBLE = 32768,
|
||||||
}
|
}
|
||||||
|
|
||||||
local bitar = require("bitar")
|
local bitar = require("bitar")
|
||||||
|
@ -944,6 +946,19 @@ local bitar = require("bitar")
|
||||||
-- machines. This sucks.
|
-- machines. This sucks.
|
||||||
static_members.sector.showbitmap = bitar.new(ffiC.MAXSECTORS-1, ffi.cast("int32_t *", ffiC.show2dsector))
|
static_members.sector.showbitmap = bitar.new(ffiC.MAXSECTORS-1, ffi.cast("int32_t *", ffiC.show2dsector))
|
||||||
|
|
||||||
|
static_members.sector.DAMAGEHPLANE = conststruct
|
||||||
|
{
|
||||||
|
SUPPRESS = -1,
|
||||||
|
DEFAULT = 0,
|
||||||
|
GLASSBREAK = 2^20,
|
||||||
|
}
|
||||||
|
|
||||||
|
function static_members.sector.damagehplane_whatsect(RETURN)
|
||||||
|
local what = (band(RETURN, 65536)~=0) and "ceiling" or "floor"
|
||||||
|
local sectnum = band(RETURN, ffiC.MAXSECTORS-1)
|
||||||
|
return what, sectnum
|
||||||
|
end
|
||||||
|
|
||||||
local function iter_allsprites(_, curi)
|
local function iter_allsprites(_, curi)
|
||||||
for i=curi+1,ffiC.MAXSPRITES-1 do
|
for i=curi+1,ffiC.MAXSPRITES-1 do
|
||||||
if (ffiC.sprite[i].statnum ~= ffiC.MAXSTATUS) then
|
if (ffiC.sprite[i].statnum ~= ffiC.MAXSTATUS) then
|
||||||
|
|
|
@ -942,7 +942,7 @@ sprite by `zofs` units''.
|
||||||
Provides a mapping of symbolic names to values applicable to
|
Provides a mapping of symbolic names to values applicable to
|
||||||
<<sprite_cstat,`sprite[i].cstat`>>. These name single bits:
|
<<sprite_cstat,`sprite[i].cstat`>>. These name single bits:
|
||||||
`BLOCK`, `TRANS1`, `XFLIP`, `YFLIP`, `ALIGNWALL`, `ALIGNFLOOR`, `ONESIDE`,
|
`BLOCK`, `TRANS1`, `XFLIP`, `YFLIP`, `ALIGNWALL`, `ALIGNFLOOR`, `ONESIDE`,
|
||||||
`CENTER`, `HITSCAN`, `TRANS2`,
|
`CENTER`, `HITSCAN`, `TRANS2`, `INVISIBLE`,
|
||||||
while the following denote _bit masks_: `ALIGN_BITMASK`, `TRANS_BITMASK`.
|
while the following denote _bit masks_: `ALIGN_BITMASK`, `TRANS_BITMASK`.
|
||||||
|
|
||||||
===== `spriteext`
|
===== `spriteext`
|
||||||
|
@ -2232,6 +2232,45 @@ cheat give a different ``full'' amount. A negative value is ignored.
|
||||||
`CHEATGETSTEROIDS`, `CHEATGETHEAT`, `CHEATGETBOOT`, `CHEATGETSHIELD`,
|
`CHEATGETSTEROIDS`, `CHEATGETHEAT`, `CHEATGETBOOT`, `CHEATGETSHIELD`,
|
||||||
`CHEATGETSCUBA`, `CHEATGETHOLODUKE`, `CHEATGETJETPACK`, `CHEATGETFIRSTAID`.
|
`CHEATGETSCUBA`, `CHEATGETHOLODUKE`, `CHEATGETJETPACK`, `CHEATGETFIRSTAID`.
|
||||||
|
|
||||||
|
[float]
|
||||||
|
`EVENT_DAMAGEHPLANE`
|
||||||
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Triggered when a ceiling or a floor (collectively called ``hplane'') is
|
||||||
|
determined as being damaged. The event receives `RETURN` as a value that can be
|
||||||
|
decoded into two parts by passing it to `sector.damagehplane_whatsect`:
|
||||||
|
|
||||||
|
[source]
|
||||||
|
----------
|
||||||
|
local what, sectnum = sector.damagehplane_whatsect(gv.RETURN)
|
||||||
|
----------
|
||||||
|
Then,
|
||||||
|
|
||||||
|
* `what` is one of the strings `'ceiling'` or `'floor'` and
|
||||||
|
* `sectnum` is the sector whose hplane is considered to be damaged.
|
||||||
|
|
||||||
|
When `EVENT_DAMAGEHPLANE` is left, `RETURN` is examined to determine the
|
||||||
|
further action. It may be one of three values given by `sector.DAMAGEHPLANE`
|
||||||
|
(abbreviated `DHP` in the following):
|
||||||
|
|
||||||
|
* `DHP.SUPPRESS`: the hard-wired code that would subsequently be run is
|
||||||
|
suppressed entirely
|
||||||
|
|
||||||
|
* `DHP.DEFAULT`: The default code for hplane damaging is run. For floors, it
|
||||||
|
does nothing. For ceilings, it checks whether it has a tile number in a
|
||||||
|
hard-coded set of values depicting a breakable light. In that case, the tile
|
||||||
|
number is changed to the ``broken'' version and a ``glass breaking'' effect
|
||||||
|
consisting of playing a sound and spawning glass sprites is started. Also,
|
||||||
|
certain code related to SE3 and SE12 effects is run.
|
||||||
|
|
||||||
|
* `DHP.GLASSBREAK`: The light-breaking effect described above is run
|
||||||
|
unconditionally, but *without* changing the hplane's tile number, which is
|
||||||
|
assumed to have been done by the event.
|
||||||
|
|
||||||
|
If value last assigned to `RETURN` is not one in the above-mentioned set when
|
||||||
|
`EVENT_DAMAGEHPLANE` is left, the behavior is undefined.
|
||||||
|
|
||||||
|
|
||||||
[float]
|
[float]
|
||||||
TODO
|
TODO
|
||||||
~~~~
|
~~~~
|
||||||
|
|
105
polymer/eduke32/source/lunatic/test/damagehplane.lua
Normal file
105
polymer/eduke32/source/lunatic/test/damagehplane.lua
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
local bit = require("bit")
|
||||||
|
local band = bit.band
|
||||||
|
|
||||||
|
local tostring = tostring
|
||||||
|
|
||||||
|
local gv = gv
|
||||||
|
local actor = actor
|
||||||
|
local sector, wall, sprite = sector, wall, sprite
|
||||||
|
|
||||||
|
local printf = printf
|
||||||
|
local sectorsofbunch = sectorsofbunch
|
||||||
|
|
||||||
|
local con = require("con")
|
||||||
|
|
||||||
|
local D = require("CON.DEFS")
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
local TROR_GLASSBREAKER = 2959 -- red 'T'
|
||||||
|
-- Actor controlling the timing of a TROR hplane breaking.
|
||||||
|
gameactor
|
||||||
|
{
|
||||||
|
TROR_GLASSBREAKER,
|
||||||
|
|
||||||
|
function(aci, pli, dist)
|
||||||
|
local spr = sprite[aci]
|
||||||
|
if (not (spr.lotag == 712 and spr.hitag == 119)) then -- check BREAKER_MAGIC
|
||||||
|
sprite.changestat(aci, actor.STAT.DEFAULT)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local cnt = actor[aci]:get_count()
|
||||||
|
local finish = (cnt >= 6)
|
||||||
|
|
||||||
|
if (cnt == 0) then
|
||||||
|
-- NOTE: INTERNAL interface, DON'T USE!
|
||||||
|
con._sound(aci, D.GLASS_BREAKING)
|
||||||
|
end
|
||||||
|
|
||||||
|
local bunchnum = spr.extra
|
||||||
|
for sectnum, what in sectorsofbunch(bunchnum, gv.BOTH_CF) do
|
||||||
|
local cf = sector[sectnum][what]
|
||||||
|
|
||||||
|
-- TODO: provide cf:set_picnum()
|
||||||
|
if (what=="ceiling") then
|
||||||
|
sector[sectnum]:set_ceilingpicnum(D.GLASS2 + cnt)
|
||||||
|
else
|
||||||
|
sector[sectnum]:set_floorpicnum(D.GLASS2 + cnt)
|
||||||
|
end
|
||||||
|
|
||||||
|
cf.statbits:clear(sector.STAT.BLOCK + sector.STAT.HITSCAN)
|
||||||
|
if (finish) then
|
||||||
|
cf.statbits:clear(sector.STAT.TRANS_BITMASK)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (finish) then
|
||||||
|
con.killit()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local DHP = sector.DAMAGEHPLANE
|
||||||
|
|
||||||
|
gameevent
|
||||||
|
{
|
||||||
|
gv.EVENT_DAMAGEHPLANE,
|
||||||
|
|
||||||
|
function(aci, pli, dist)
|
||||||
|
local what, sectnum = sector.damagehplane_whatsect(gv.RETURN)
|
||||||
|
local sec = sector[sectnum]
|
||||||
|
|
||||||
|
-- Part I: make various screens breakable when it's a ceiling picnum.
|
||||||
|
if (what == "ceiling") then
|
||||||
|
-- hit ceiling
|
||||||
|
if (sec.ceilingpicnum >= 263 and sec.ceilingpicnum <= 275) then
|
||||||
|
sec:set_ceilingpicnum(D.W_SCREENBREAK + gv.krand()%3)
|
||||||
|
gv.RETURN = DHP.GLASSBREAK
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Part II: breakable TROR hplanes
|
||||||
|
local cf = sec[what]
|
||||||
|
-- printf("damage %s of sector %d (pic %d, bunch %d, hittable: %s)", what, sectnum,
|
||||||
|
-- cf.picnum, cf.bunch, tostring(cf.statbits:test(sector.STAT.HITSCAN)))
|
||||||
|
|
||||||
|
if (cf.bunch >= 0 and (cf.picnum==198 or cf.picnum==D.GLASS2) and
|
||||||
|
cf.statbits:test(sector.STAT.HITSCAN)) then
|
||||||
|
local bi = con.insertsprite(TROR_GLASSBREAKER, wall[sec.wallptr], sectnum, aci, actor.STAT.ACTOR)
|
||||||
|
local breaker = sprite[bi]
|
||||||
|
|
||||||
|
breaker.cstat = sprite.CSTAT.INVISIBLE
|
||||||
|
breaker.lotag, breaker.hitag = 712, 119 -- BREAKER_MAGIC
|
||||||
|
breaker.extra = cf.bunch
|
||||||
|
|
||||||
|
gv.RETURN = DHP.SUPPRESS
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
gv.RETURN = DHP.DEFAULT
|
||||||
|
end
|
||||||
|
}
|
|
@ -1874,13 +1874,27 @@ void A_DamageWall(int32_t spr,int32_t dawallnum,const vec3_t *pos,int32_t atwith
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: return value never examined in any of the callers.
|
||||||
int32_t Sect_DamageCeilingOrFloor(int32_t floorp, int32_t sn)
|
int32_t Sect_DamageCeilingOrFloor(int32_t floorp, int32_t sn)
|
||||||
{
|
{
|
||||||
int32_t i, j;
|
int32_t i, j;
|
||||||
|
|
||||||
|
const int32_t RETURN_in = floorp ? 131072+sn : 65536+sn;
|
||||||
|
int32_t ret = VM_OnEvent(EVENT_DAMAGEHPLANE, g_player[screenpeek].ps->i, screenpeek, -1, RETURN_in);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (floorp)
|
if (floorp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (ret == (1<<20))
|
||||||
|
{
|
||||||
|
// Execute the hard-coded stuff without changing picnum (expected to
|
||||||
|
// have been done by the event).
|
||||||
|
goto GLASSBREAK_CODE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (DYNAMICTILEMAP(sector[sn].ceilingpicnum))
|
switch (DYNAMICTILEMAP(sector[sn].ceilingpicnum))
|
||||||
{
|
{
|
||||||
case WALLLIGHT1__STATIC:
|
case WALLLIGHT1__STATIC:
|
||||||
|
@ -1890,9 +1904,6 @@ int32_t Sect_DamageCeilingOrFloor(int32_t floorp, int32_t sn)
|
||||||
case TECHLIGHT2__STATIC:
|
case TECHLIGHT2__STATIC:
|
||||||
case TECHLIGHT4__STATIC:
|
case TECHLIGHT4__STATIC:
|
||||||
|
|
||||||
A_SpawnCeilingGlass(g_player[myconnectindex].ps->i,sn,10);
|
|
||||||
A_PlaySound(GLASS_BREAKING,g_player[screenpeek].ps->i);
|
|
||||||
|
|
||||||
if (sector[sn].ceilingpicnum == WALLLIGHT1)
|
if (sector[sn].ceilingpicnum == WALLLIGHT1)
|
||||||
sector[sn].ceilingpicnum = WALLLIGHTBUST1;
|
sector[sn].ceilingpicnum = WALLLIGHTBUST1;
|
||||||
|
|
||||||
|
@ -1911,6 +1922,9 @@ int32_t Sect_DamageCeilingOrFloor(int32_t floorp, int32_t sn)
|
||||||
if (sector[sn].ceilingpicnum == TECHLIGHT4)
|
if (sector[sn].ceilingpicnum == TECHLIGHT4)
|
||||||
sector[sn].ceilingpicnum = TECHLIGHTBUST4;
|
sector[sn].ceilingpicnum = TECHLIGHTBUST4;
|
||||||
|
|
||||||
|
GLASSBREAK_CODE:
|
||||||
|
A_SpawnCeilingGlass(g_player[myconnectindex].ps->i,sn,10);
|
||||||
|
A_PlaySound(GLASS_BREAKING,g_player[screenpeek].ps->i);
|
||||||
|
|
||||||
if (sector[sn].hitag == 0)
|
if (sector[sn].hitag == 0)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue