raze-gles/polymer/eduke32/samples/a.m32
helixhorned c01109c483 m32script: fix some commands breaking too early in case of a failed validation.
If one next instruction happened to be interpreted, madness would ensue,
because the pointer wouldn't be aligned on the "opcode" part anymore.
Also, with "seti", set current sprite index only after a successful validation.

git-svn-id: https://svn.eduke32.com/eduke32@2591 1a8010ca-5511-0410-912e-c29ae57300e0
2012-04-05 19:49:30 +00:00

1366 lines
35 KiB
Text

// m32 script editor extensions.
// to load, enter "include samples/a" (without quotes) in the console
// or into a file named m32_autoexec.cfg for automatic loading on startup.
// to enable all events, "enableevent all"
////////// USER SETTINGS //////////
// settings for the tweaking of Polymer pr_override*-variables with the keypad keys
define MINPARALLAXSCALE -10 // minimum pr_parallaxscale value
define MAXPARALLAXSCALE 10
define MINPARALLAXBIAS -10
define MAXPARALLAXBIAS 10
define PSCALESTEPS 1000 // 0..1 is mapped to 0..PSCALESTEPS
define PBIASSTEPS 1000
define MINSPECULARPOWER -10
define MAXSPECULARPOWER 1000
define MINSPECULARFACTOR -10
define MAXSPECULARFACTOR 1000
define SPOWERSTEPS 100
define SFACTORSTEPS 100
// color of various drawing enhancements
define PREVIEW_DRAW_COLOR 11
gamevar showpal 0 0
// whether to use overridden aspect/range values when entering 3d mode (software/Polymost).
// tweak with keys 7,8,9,0 on the top row
gamevar use_custom_aspect 0 0 // this is now the same as r_usenewaspect
gamevar davr 65536 0
gamevar dayx 65536 0
// whether to remap certain widely-available keys to rare ones
// (notebook/netbook convenience, see EVENT_KEYPRESS for details)
gamevar use_notebook_keys 0 0
// see end of file for more user settings and examples
////////// END USER SETTINGS //////////
include names.h
// flag 1: per-block (top-level, event, or state) variable
gamevar i 0 1
gamevar j 0 1
gamevar k 0 1
gamevar p 0 1
gamevar r 0 1
gamevar x 0 0
gamevar y 0 0
gamevar z 0 0
gamevar dx 0 0
gamevar dy 0 0
gamevar dz 0 0
gamevar dang 0 0
gamevar tmp 0 0
gamevar cnt 0 0
gamevar sec 0 0
gamevar wal 0 0
gamevar drawcol 9 0
define TQUOTE 0
definequote TQUOTE >>> write on me! <<<
//light
define LIGHTQUOTE 1
// x y z r g b mins maxs
definequote LIGHTQUOTE light %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d
// sec range radius fade ang horiz prio tile
define PRSCALE 1000
define MAXSPECULAR 100000
define TMPARLEN 128
gamearray ar TMPARLEN
gamearray xx TMPARLEN
gamearray yy TMPARLEN
gamearray parm 8
// prints out maphack light definitions based on SE lights in map
defstate printlights
"Print Polymer lights"
var flags
print "--PRLIGHTS--"
for i allsprites, ifactor SECTOREFFECTOR, ifge .lotag 49, ifle .lotag 50
{
ife .lotag 50
{
set j 128, sub j .shade, shiftl j 1
set k j, mul k 3, div k 4
}
else
{
set j 0, set k 0
}
set flags 0
ifand .cstat 2
{
ifand .cstat 512
set flags 4
else
set flags 2
}
// range r g b
qsprintf TQUOTE LIGHTQUOTE .sectnum .x .y .z .hitag .xvel .yvel .zvel
j k .ang .extra .xoffset .yoffset flags .owner
// radius fade horiz minshade maxshade prio tile
print TQUOTE
}
print "--ENDPRLIGHTS--"
ends
defstate insertlights
"Insert active SE lights"
var sectnum
set k 0
for i activelights
{
insertsprite light[i].sector
// I is the inserted sprites' index now
set .picnum 1
set .x light[i].x
set .y light[i].y
set .z light[i].z
set .hitag light[i].range
set .xvel light[i].r
set .yvel light[i].g
set .zvel light[i].b
set .extra light[i].horiz
set .xoffset light[i].minshade
set .yoffset light[i].maxshade
set .owner light[i].tilenum
set .xrepeat 48
set .yrepeat 48
// now those that are calculated
ifge light[i].priority 4 or .cstat 512
ifge light[i].priority 2 or .cstat 2
ife light[i].radius 0
{
set .lotag 49
}
else
{
set .lotag 50
set j light[i].radius, shiftr j 1, sub j 128, inv j
clamp j -128 127
set .shade j
}
add k 1
}
qsprintf TQUOTE "* Inserted %d SE sprites based on active lights." k
print TQUOTE
ends
// convenient polymer SE light manipulation with keypad keys
// when aiming at light SE (49 or 50):
// KP 4,5,6,8: angle/horiz
// KP 7,9: range
// KP+/-: radius
// KP 1,2,3: RGB color (Shift inverts)
//
// when aiming at wall or sector and the respective overrides are on:
// KP 5,8: parallaxscale
// KP 4,6: parallaxbias
// KP /,*: specularfactor
// KP 7,9: specularpower
//
// Also try Shift and/or Ctrl modifiers for different increments
defstate fiddlewithlights
var minval maxval
// if aiming at sector or wall
ifaimingsprite nullop
else ifn pr_overrideparallax 0
{
set j 0 set k 0
ifhitkey KEY_KP5 set j -1, ifhitkey KEY_KP8 set j 1
ifn j 0 set k 1
ifhitkey KEY_KP4 set j -1, ifhitkey KEY_KP6 set j 1
ife k 0 ifn j 0 set k 2
ifeitheralt mul j 10
ifeitherctrl mul j 10
switch k
case 0: break;
case 1:
{
set k pr_parallaxscale
ftoi k PSCALESTEPS // must convert to scaled integer, maps 0..1 to 0..PARALLAXSTEPS
set minval MINPARALLAXSCALE, mul minval PSCALESTEPS
set maxval MAXPARALLAXSCALE, mul maxval PSCALESTEPS
add k j, clamp k minval maxval
itof k PSCALESTEPS // convert back
qsprintf TQUOTE "PARALLAX SCALE: %f" k, quote TQUOTE
set pr_parallaxscale k
break;
}
case 2:
{
set k pr_parallaxbias
ftoi k PBIASSTEPS
set minval MINPARALLAXBIAS, mul minval PBIASSTEPS
set maxval MAXPARALLAXBIAS, mul maxval PBIASSTEPS
add k j, clamp k minval maxval
itof k PBIASSTEPS
qsprintf TQUOTE "PARALLAX BIAS: %f" k, quote TQUOTE
set pr_parallaxbias k
break;
}
endswitch
//quote "zxczxc"
}
//quote "asdasd"
// if aiming at sector or wall
ifaimingsprite nullop
else ifn pr_overridespecular 0
{
set j 0 set k 0
ifhitkey KEY_gSLASH set j -1, ifhitkey KEY_gSTAR set j 1
ifn j 0 set k 3
ifhitkey KEY_KP7 set j -1, ifhitkey KEY_KP9 set j 1
ife k 0 ifn j 0 set k 4
ifeitheralt mul j 10
ifeitherctrl mul j 10
switch k
case 0: break;
case 3:
{
set k pr_specularfactor
ftoi k SFACTORSTEPS
set minval MINSPECULARFACTOR, mul minval SFACTORSTEPS
set maxval MAXSPECULARFACTOR, mul maxval SFACTORSTEPS
add k j, clamp k minval maxval
itof k SFACTORSTEPS
qsprintf TQUOTE "SPECULAR FACTOR: %f" k, quote TQUOTE
set pr_specularfactor k
break;
}
case 4:
{
set k pr_specularpower
ftoi k SPOWERSTEPS
set minval MINSPECULARPOWER, mul minval SPOWERSTEPS
set maxval MAXSPECULARPOWER, mul maxval SPOWERSTEPS
add k j, clamp k minval maxval
itof k SPOWERSTEPS
qsprintf TQUOTE "SPECULAR POWER: %f" k, quote TQUOTE
set pr_specularpower k
break;
}
endswitch
}
//quote "qweqwe"
// if aiming at a sprite that's not a Polymer light
ifaimingsprite set k 1 else set k 0
ife k 1 ife sprite[searchwall].picnum SECTOREFFECTOR
ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50
set k 0
ife k 1
{
seti searchwall
// [xyz]vel / owner
ifeitheralt
{
ifhitkey KEY_KP1
{
getnumber256 .xvel "XVEL: " 0
getnumber256 .yvel "YVEL: " 0
getnumber256 .zvel "ZVEL: " 0
}
else ifeithershift ifhitkey KEY_KP2 // alt-kp2 collides with KP* replacement
{
getnumber256 .owner "OWNER: " 0
ifl .owner 0 set .owner -1
}
}
}
// if aiming at an SE with lotag 49 or 50 (Polymer light)
ifaimingsprite ife sprite[searchwall].picnum SECTOREFFECTOR
ifge sprite[searchwall].lotag 49 ifle sprite[searchwall].lotag 50
{
set i searchwall, seti i // set current sprite = targeted sprite
ife .lotag 50
{
// horiz
ifeithershift set j 1 else set j 10
ifhitkey KEY_gUP add .extra j
else ifhitkey KEY_gKP5 sub .extra j
clamp .extra -500 500
// angle
set j 128
ifeitherctrl set j 4
ifeithershift { ifeitherctrl set j 1 else set j 32 }
ifhitkey KEY_gLEFT sub .ang j
else ifhitkey KEY_gRIGHT add .ang j
// radius
ifeitherctrl
{
ifholdkey KEY_gMINUS add .shade 9
else ifholdkey KEY_gPLUS sub .shade 9
clamp .shade -118 117
}
}
// range
ifeithershift set j 10
else ifeitherctrl set j 1000
else set j 100
set k .hitag
ifhitkey KEY_KP9 add k j
else ifhitkey KEY_KP7 sub k j
clamp k 0 32767
set .hitag k
// min/max shade
ifeithershift set j -1 else set j 1
ifeitherctrl
{
ifhitkey KEY_gSLASH
{
set .xoffset 0
set .yoffset 0
quote "Reset X and Y OFFSET (min/max shade) to 0"
}
}
else
{
set k 0
ifhitkey KEY_gSLASH { add .xoffset j, set k 1 }
else ifhitkey KEY_gSTAR { add .yoffset j, set k 1 }
ife k 1
{
qsprintf TQUOTE "XY OFFSET (min/max shade): %d %d" .xoffset .yoffset
quote TQUOTE
}
}
// color/picnum
ifeitheralt
{
ifhitkey KEY_KP1
{
getnumber256 .xvel "XVEL (red): " 255
getnumber256 .yvel "YVEL (green): " 255
getnumber256 .zvel "ZVEL (blue): " 255
}
else ifhitkey KEY_KP2
{
getnumber256 .owner "OWNER (projection picnum): " -MAXTILES
ifl .owner 0 set .owner -1
}
}
else
{
ifeitherctrl set j 1 else set j 10
ifeithershift inv j
set k 0
ifhitkey KEY_B { add .xvel j, set k 1 }
ifhitkey KEY_N { add .yvel j, set k 1 }
ifhitkey KEY_M { add .zvel j, set k 1 }
ifhitkey KEY_KP1 { add .xvel j, set k 1 }
ifhitkey KEY_KP2 { add .yvel j, set k 1 }
ifhitkey KEY_KP3 { add .zvel j, set k 1 }
ife k 1
{
clamp .xvel 1 255
clamp .yvel 1 255
clamp .zvel 1 255
qsprintf TQUOTE "XYZ VEL (RGB color): %d %d %d" .xvel .yvel .zvel
quote TQUOTE
}
}
}
ends
// forward refs
defstate userkeys_3d ends
defstate userdrawlabel ends
onevent EVENT_PREKEYS3D
// state testkeyavail
state fiddlewithlights
state userkeys_3d
endevent
// rotate highlighted sprites around selected (closest to mouse) sprite
// global parameter: dang
defstate rotselspr
ifg highlightcnt 0
ifge pointhighlight 16384, ifl pointhighlight 32768
{
ife dang 0 return
set p pointhighlight, and p 16383
add sprite[p].ang dang
for i selsprites, ifn i p
{
rotatepoint sprite[p].x sprite[p].y .x .y dang (x y)
add .ang dang
bsetsprite I x y .z
}
}
ends
onevent EVENT_PREKEYS2D
// state testkeyavail
set j 0
ifeitherctrl
{
ifhitkey KEY_COMMA set j -1
ifhitkey KEY_PERIOD set j 1
}
ifn j 0
{
mul j 512
set dang j
state rotselspr
}
endevent
gamevar fyx 0 0
gamevar fvr 0 0
defstate setas
set fyx dayx
mul fyx 4 mul fyx 100 // the correction factor 100/107 has been found
div fyx 3 div fyx 107 // out experimentally. squares ftw!
set fvr davr
mul fvr xdim mul fvr 3
div fvr ydim div fvr 4
setaspect fvr fyx //davr dayx
ends
onevent EVENT_ENTER3DMODE
ifn use_custom_aspect 0
state setas
endevent
////// sector collecting stuff
gamevar ohlsecs 0 0
gamearray collectedsectors MAXSECTORS // shared with 'old-highlighted sectors'
defstate try_nextsector
var nexts
set nexts RETURN
set RETURN 0
for i spritesofsector nexts
{
ife .picnum SECTOREFFECTOR ife .lotag 7
{
set RETURN 1
break
}
}
ends
// save or restore highlighted sectors
defstate save_restore_hlsectors
"Save/restore hl. sectors"
ifge highlightsectorcnt 0
{
// save
for i range highlightsectorcnt
set collectedsectors[i] highlightsector[i]
set ohlsecs highlightsectorcnt
quote "Highlighted sectors saved"
}
else ifl highlightcnt 0
{
for i range ohlsecs
sethighlightsector collectedsectors[i] 1
quote "Highlighted sectors restored"
}
ends
defstate collect_teleporting_sectors // (sec)
"Collect telep. sectors"
var numsects
set numsects numsectors, sub numsects 1
ifinteractive
{
getnumberfromuser sec "starting sectnum: " numsects 8
ifl sec 0, return
}
set ohlsecs 0 // reset old hl'd sectors
collectsectors collectedsectors sec numsects try_nextsector
for i range numsects
sethighlightsector collectedsectors[i] 1
ends
////// show LOCATORS
defstate cmp_by_lotag // comparator subroutine for sorting
set RETURN sprite[SV2].lotag
sub RETURN sprite[SV1].lotag
ends
defstate connectlocators
// connect LOCATORS in a sector with lines
getarraysize ar tmp
set j 0
for i spritesofsector cursectnum
{
ifge j tmp nullop else
ifactor LOCATORS
{
set ar[j] i
add j 1
}
}
set tmp j
sort ar tmp cmp_by_lotag
sub tmp 1
for i range tmp
{
set j ar[i]
set k i, add k 1, set k ar[k]
drawline16z sprite[j].x sprite[j].y sprite[j].z sprite[k].x sprite[k].y sprite[k].z drawcol
}
ends
defstate draw_prlightprojections
////////// polymer light 2d projections //////////
var c d h r x2 y2 oldpat
array xx 2
array yy 2
set oldpat drawlinepat
set drawlinepat 0x11111111
for i spritesofsector cursectnum
{
ifactor SECTOREFFECTOR
{
ife .lotag 49 // point light
{
set d .hitag // light distance
mul d d, mul d 2, sqrt d d, div d 2
getclosestcol .xvel .yvel .zvel c // light color
inv c
set x .x, set x2 .x, set y .y, set y2 .y
add x d, add y d, sub x2 d, sub y2 d
drawline16z x y .z x2 y2 .z c
set x .x, set x2 .x, set y .y, set y2 .y
add x d, sub y d, sub x2 d, add y2 d
drawline16z x y .z x2 y2 .z c
drawcircle16z .x .y .z .hitag c
}
else ife .lotag 50 // spot light
{
set d .hitag // light distance
and d 65535
set r 128, sub r .shade, shiftl r 1 // light cone radius (BUILD angles)
getclosestcol .xvel .yvel .zvel c // light color
inv c
set x .x, set y .y, add x d
rotatepoint .x .y x y .ang x y
set h .extra // horiz
sub h 100
set tmp h, mul tmp tmp, add tmp 40000
sqrt tmp tmp
divscale h 200 tmp 15 // h: horizontal distance fraction
set dx .x, sub dx x
set dy .y, sub dy y
set tmp 32768, sub tmp h
mulscale dx dx tmp 15
mulscale dy dy tmp 15
set tmp 0, sub tmp r
rotatepoint .x .y x y tmp xx[0] yy[0]
set tmp 0, add tmp r
rotatepoint .x .y x y tmp xx[1] yy[1]
add xx[0] dx, add yy[0] dy
add xx[1] dx, add yy[1] dy
drawline16z .x .y .z xx[0] yy[0] .z c
drawline16z .x .y .z xx[1] yy[1] .z c
}
}
}
set drawlinepat oldpat
ends
defstate previewdoors2d
// preview swinging and sliding doors in 2d mode
var valid sect lo
var i j w numw ang trange dx dy
set valid 0
set sect searchsector
ifge sect 0 ifl sect numsectors
{
set lo sector[sect].lotag
ife lo 23 set valid 1
else ife lo 25 set valid 1
}
ife valid 1
{
set valid 0
for i spritesofsector sect
ifactor SECTOREFFECTOR
{
ife .lotag 11 ife lo 23 set valid 1 // swinging door
ife .lotag 15 ife lo 25 set valid 1 // slide door
ife valid 1 { set j i, break }
}
ife valid 1
seti j
else return
ife .lotag 15
{
set trange 256
for i spritesofsector sect
ifactor GPSPEED { set trange .lotag, break }
mul trange 2 // now equals distance of sliding door to travel
}
set i 0
for w loopofwall sector[sect].wallptr
{
ifge i TMPARLEN break
set xx[i] wall[w].x
set yy[i] wall[w].y
add i 1
}
ifl i TMPARLEN
{
set xx[i] xx[0]
set yy[i] yy[0]
add i 1
}
set numw i
ife .lotag 11
{
ifg .ang 1024 set ang -512 else set ang 512
for i range numw
rotatepoint .x .y xx[i] yy[i] ang xx[i] yy[i]
}
else // if .lotag 15
{
set ang .ang, add ang 1024
a2xy ang dx dy
mulscale dx trange dx 14
mulscale dy trange dy 14
for i range numw
{
add xx[i] dx
add yy[i] dy
}
}
set drawlinepat 0x33333333
sub numw 1
for i range numw
{
set j i, add j 1
drawline16z xx[i] yy[i] sector[sect].floorz xx[j] yy[j] sector[sect].floorz PREVIEW_DRAW_COLOR
}
set drawlinepat 0xffffffff
}
ends
// LOCATORS auto-incrementer
onevent EVENT_INSERTSPRITE2D
set k I
set j -1
for i spritesofsector .sectnum
{
ifn i k, ifactor LOCATORS, ifg .lotag j
set j .lotag
}
ifg j -1
{
add j 1
set .lotag j
}
endevent
defstate print_parallel_midpts // print the midpoints of parallel wall-lines
var p0 p1 p2 s1dx s1dy s2dx s2dy tmp nw
quote "----------------"
for p1 allwalls
{
lastwall p1 p0 // get the 'inverse point2'
set p2 wall[p1].point2 // ... and the forward one
set tmp 0
// both white: OK (may be false positive due to TROR)
ifl wall[p0].nextwall 0 ifl wall[p1].nextwall 0 set tmp 1
// both red and no wall originating from midpoint on the other side: OK
ifge wall[p0].nextwall 0 ifge wall[p1].nextwall 0
{
set nw wall[p1].nextwall
ifl p1 nw, ife wall[p0].nextwall wall[nw].point2, set tmp 1
}
ife tmp 1
{
set s1dx wall[p1].x, sub s1dx wall[p0].x
set s1dy wall[p1].y, sub s1dy wall[p0].y
set s2dx wall[p2].x, sub s2dx wall[p1].x
set s2dy wall[p2].y, sub s2dy wall[p1].y
// now have segment dx/dy's
mul s1dx -s2dy
mul s1dy s2dx
set tmp s1dx, add tmp s1dy // tmp = (s1dx, s1dy) . (-s2dy, s2dx)
ife tmp 0
{
qsprintf TQUOTE "%d" p1
quote TQUOTE
}
}
}
ends
//////////////////// SPRITE DUPLICATORS ////////////////////
defstate transcnt
ifle cnt 0 { inv cnt, add cnt 128 }
ends
define DUP_ROT_MAGIC 123
// duplicates and rotates selected sprites around
// pivot sprite with fields
// .extra=123 (magic)
// .ang: angle delta
// .yrepeat*32: z delta (positive if pal!=0, i.e. going down)
// .shade: count (-128 to 0 -> 255 to 128)
defstate duprot
ifaimingsprite nullop else return
ifn sprite[searchwall].extra DUP_ROT_MAGIC return
set p searchwall // pivot sprite
set cnt sprite[p].shade, state transcnt
set sprite[p].extra -1
for i range cnt
{
for j selsprites, ifn j p
{
dupsprite j // duplicate sprite j, I becomes index of newly created sprite
set dang i, add dang 1, mul dang sprite[p].ang
rotatepoint sprite[p].x sprite[p].y .x .y dang (x y)
add .ang dang
set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5
ife sprite[p].pal 0, inv z
add z .z
bsetsprite I x y z
}
}
ends
// same as above but with tsprite[], as a kind of preview
defstate tduprot
ifaimingsprite nullop else return
ifl searchwall 0 return
ifn sprite[searchwall].extra DUP_ROT_MAGIC return
set p searchwall // pivot sprite
set cnt sprite[p].shade, state transcnt
for i range cnt
{
for j selsprites, ifn j p
{
set k spritesortcnt
tdupsprite j
set dang i, add dang 1, mul dang sprite[p].ang
rotatepoint sprite[p].x sprite[p].y tsprite[k].x tsprite[k].y dang (x y)
add tsprite[k].ang dang
set z i, add z 1, mul z sprite[p].yrepeat, shiftl z 5
ife sprite[p].pal 0 inv z
add z tsprite[k].z
set tsprite[k].x x
set tsprite[k].y y
set tsprite[k].z z
or tsprite[k].cstat 514
}
}
ends
define DUP_LIN_MAGIC 234
define DUP_LIN_MAGIC2 345
// duplicates and translates selected sprites in the direction between two
// reference sprites with fields
// .extra=234 (1st sprite), =345 (2nd, aimed at sprite)
// .shade: count (-128 to 0 -> 255 to 128)
defstate duplin
ifaimingsprite nullop else return
ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return
set r searchwall // 2nd reference point
set cnt sprite[r].shade, state transcnt
set p -1 // 1st reference point
for i selsprites, ifn i r
{
ife .extra DUP_LIN_MAGIC { set p i, break }
}
ifl p 0 return
set sprite[p].extra -1
set sprite[r].extra -1
set dx sprite[r].x, sub dx sprite[p].x
set dy sprite[r].y, sub dy sprite[p].y
set dz sprite[r].z, sub dz sprite[p].z
for i range cnt
{
for j selsprites, ifn j r
{
dupsprite j
set x i, add x 1, mul x dx, add x .x
set y i, add y 1, mul y dy, add y .y
set z i, add z 1, mul z dz, add z .z
bsetsprite I x y z
}
}
ends
defstate tduplin
ifaimingsprite nullop else return
ifn sprite[searchwall].extra DUP_LIN_MAGIC2 return
set r searchwall // 2nd reference point
set cnt sprite[r].shade, state transcnt
set p -1 // 1st reference point
for i selsprites, ifn i r
{
ife .extra DUP_LIN_MAGIC { set p i, break }
}
ifl p 0 return
set dx sprite[r].x, sub dx sprite[p].x
set dy sprite[r].y, sub dy sprite[p].y
set dz sprite[r].z, sub dz sprite[p].z
for i range cnt
{
for j selsprites, ifn j r
{
set k spritesortcnt
tdupsprite j
set tmp i, add tmp 1, mul tmp dx
add tsprite[k].x tmp
set tmp i, add tmp 1, mul tmp dy
add tsprite[k].y tmp
set tmp i, add tmp 1, mul tmp dz
add tsprite[k].z tmp
or tsprite[k].cstat 514
// bsetsprite I x y z
}
}
ends
onevent EVENT_ANALYZESPRITES
state tduprot
state tduplin
endevent
onevent EVENT_KEYS3D
var l m
// door sound tester
ifeitherctrl ifeithershift ifaimingwall
ifholdkey KEY_SPACE
{
set k wall[searchwall].nextsector
ifl k 0 set k searchsector
ife sector[k].lotag 0 return
for i spritesofsector k
{
ifactor MUSICANDSFX
ifge .lotag 0 ifl .lotag MAXSOUNDS
{
getsoundflags .lotag m
ifand m 1 nullop else soundonce .lotag
resetkey KEY_SPACE
}
}
}
// swinging doors tester -- hit Ctrl-Shift-SPACE on a door wall
ifeitherctrl ifeithershift ifaimingwall
ifholdkey KEY_SPACE // SE11 ST23 up:ccw
{
set k wall[searchwall].nextsector
ifl k 0 return
ifn sector[k].lotag 23 return
resetkey KEY_SPACE
set tmp 0
for i loopofwall searchwall
{
ifl wall[i].nextsector 0 set tmp 1 else
ifn wall[i].nextsector k set tmp 1
}
// a weaker condition
// for i loopofwall wall[searchwall].nextwall
// {
// ifl wall[i].nextsector 0 set tmp 1 else
// ifn wall[i].nextsector searchsector set tmp 1
// }
ifn tmp 0
{
quote "door sector not an island sector!"
return
}
set l -1
for i spritesofsector k
{
ifactor SECTOREFFECTOR ife sprite[i].lotag 11
{
set l i
ifn sprite[i].ang 512 ifn sprite[i].ang 1024 ifn sprite[i].ang 1536 set l -1
}
}
ifl l 0
{
quote "door sector has no SE sprite!"
return
}
for tmp wallsofsector k
{
rotatepoint (sprite[l].x sprite[l].y) (wall[tmp].x wall[tmp].y) sprite[l].ang (i j)
dragpoint tmp i j
}
for tmp spritesofsector k
{
ifn tmp l
{
rotatepoint (sprite[l].x sprite[l].y) (sprite[tmp].x sprite[tmp].y) sprite[l].ang (i j)
bsetsprite tmp i j sprite[tmp].z
}
}
inv sprite[l].ang
}
// teleporter -- works on SE7 and SE17 (elevator)
ifeitheralt ifaimingsprite
ifholdkey KEY_SPACE
{
ife sprite[searchwall].picnum SECTOREFFECTOR
{
set tmp 0
ife sprite[searchwall].lotag 7 set tmp 1
ife sprite[searchwall].lotag 17 set tmp 1
ife tmp 0 return
resetkey KEY_SPACE
for i allsprites
{
ifn i searchwall, ifactor SECTOREFFECTOR, ife sprite[i].lotag sprite[searchwall].lotag
ife sprite[i].hitag sprite[searchwall].hitag
{
add posx sprite[i].x, sub posx sprite[searchwall].x
add posy sprite[i].y, sub posy sprite[searchwall].y
add posz sprite[i].z, sub posz sprite[searchwall].z
updatecursectnum
return
}
}
}
else ife sprite[searchwall].extra DUP_ROT_MAGIC
{
state duprot
resetkey KEY_SPACE
}
else ife sprite[searchwall].extra DUP_LIN_MAGIC2
{
state duplin
resetkey KEY_SPACE
}
}
set j 0
set k 0
ifholdkey KEY_7 set k -1
ifholdkey KEY_0 set k 1
ifn k 0
{
set j 1
ifeithershift nullop else mul k 256
add davr k
ifl davr 32768 set davr 32768
ifg davr 256000 set davr 256000
}
set k 0
ifholdkey KEY_8 set k -1
ifholdkey KEY_9 set k 1
ifn k 0
{
set j 1
ifeithershift nullop else mul k 256
add dayx k
ifl dayx 32768 set dayx 32768
ifg dayx 256000 set dayx 256000
}
ife j 1
{
// setaspect davr dayx
state setas
qsprintf TQUOTE "ASPECT: davr=%d, dayx=%d | FVR=%d, FYX=%d" davr dayx fvr fyx
quote TQUOTE
}
endevent
defstate replacestuff
for i spritesofsector searchsector
// ife sprite[i].picnum AMMO set sprite[i].picnum BATTERYAMMO
ifactor parm[0] cactor parm[1]
ends
defstate convlights // convert (0,0,0) lights to (255,255,255)-ones
for i allsprites ifactor 1 ifge .lotag 49 ifle .lotag 50 ife .xvel 0 ife .yvel 0 ife .zvel 0
{ set .xvel 255 set .yvel 255 set .zvel 255 }
ends
defstate resetallws // reset all sprites and walls to default repeat/panning
for i allsprites
{
set .xrepeat 64
set .yrepeat 64
}
for i allwalls
{
set wall[i].cstat 0
set wall[i].xpanning 0
set wall[i].ypanning 0
set wall[i].yrepeat 8
fixrepeats i
}
ends
defstate js // jump to current sprite
set posx .x
set posy .y
set posz .z
updatecursectnum
ends
defstate jumptowal // (wal)
ifge wal 0 ifl wal numwalls nullop else return
set posx wall[wal].x
set posy wall[wal].y
updatecursectnum
ends
defstate jumptosec // (sec)
ifge sec 0 ifl sec numsectors nullop else return
set wal sector[sec].wallptr
state jumptowal
ends
onevent EVENT_DRAW2DSCREEN
var tmp
var xx
state userdrawlabel
ifge cursectnum 0
{
state connectlocators
state draw_prlightprojections
}
state previewdoors2d
ifn showpal 0
{
set xx 100
for tmp range 256
{
drawline16 xx 100 xx 200 -tmp
add xx 1
drawline16 xx 100 xx 200 -tmp
add xx 1
ifge tmp 240
{
drawline16 xx 100 xx 200 -tmp
add xx 1
drawline16 xx 100 xx 200 -tmp
add xx 1
}
}
}
endevent
defstate mkterrain
var w2 w3 idx bit tmp sec
var warned
set warned 0
for i selwalls
{
sectorofwall j i
set tmp 0, ifand sector[j].floorstat 2, set tmp 1 // already handled
ife tmp 0 ife sector[j].wallnum 3
{
set w2 wall[i].point2
set idx w2, shiftr idx 3
set tmp w2, and tmp 7, set bit 1, shiftl bit tmp
ifand show2dwall[idx] bit
{
setfirstwall j i
set z 0x7ffffff
ifin3dmode
{
ife searchstat 2 // floor
set z sector[searchsector].floorz
}
else
{
for k allsectors
{
ifinside mousxplc mousyplc k
{
set z sector[k].floorz
break
}
}
}
ife z 0x7ffffff
{
ife warned 0
{
quote "Mouse pointer must be aiming at sector floor."
set warned 1
}
}
else
{
set w3 wall[w2].point2
set sec wall[i].nextsector
ifge sec 0
set sector[j].floorz sector[sec].floorz
alignflorslope j wall[w3].x wall[w3].y z
}
}
}
}
ends
defstate chselshade
for i selsectors
{
set sector[i].floorshade tempshade
set sector[i].ceilingshade tempshade
for j spritesofsector i
set .shade tempshade
for j wallsofsector i
set wall[j].shade tempshade
}
ends
defstate listusedtags
for i allsprites
{
getspritelinktype i k
ifn k 0
{
ife k 1
qsprintf TQUOTE "sprite %d lotag %d" i sprite[i].lotag
else ife k 2
qsprintf TQUOTE "sprite %d hitag %d" i sprite[i].hitag
quote TQUOTE
}
}
ends
////////// USER AREA //////////
// key settings
defstate userkeys_3d
ifholdkey KEY_SEMI ifhitkey KEY_C state chselshade
ends
// convenience rebindings for notebooks:
// Alt-F11 --> SCROLL LOCK (set first position)
// Alt-arrows --> KP arrows (change pan/repeat in 3D mode)
onevent EVENT_KEYPRESS
var thekey
set thekey RETURN
ifvare use_notebook_keys 0, return
/*
ifholdkey thekey
qsprintf TQUOTE "pressed %d" thekey
else
qsprintf TQUOTE "released %d" thekey
print TQUOTE
*/
ifholdkey thekey // if the callback key was pressed (and not released)
{
ifholdkey KEY_LALT
{
ifhitkey KEY_F11, setkey KEY_SCROLL
ifhitkey KEY_UP, setkey KEY_KP8
ifhitkey KEY_DOWN, setkey KEY_KP2
ifhitkey KEY_LEFT, setkey KEY_KP4
ifhitkey KEY_RIGHT, setkey KEY_KP6
// would be 'cleaner' (only checking cb key) but is too much code for my taste:
/*
switch (thekey)
{
case KEY_F11: setkey KEY_SCROLL; resetkey thekey; break;
// and so on with the rest...
}
endswitch
*/
}
}
else // cb key was released
{
switch (thekey)
{
case KEY_LALT:
{
resetkey KEY_KP8;
resetkey KEY_KP2;
resetkey KEY_KP4;
resetkey KEY_KP6;
break;
}
case KEY_UP: resetkey KEY_KP8; break;
case KEY_DOWN: resetkey KEY_KP2; break;
case KEY_LEFT: resetkey KEY_KP4; break;
case KEY_RIGHT: resetkey KEY_KP6; break;
}
endswitch
}
endevent
/*
// example for custom labels
defstate userdrawlabel
for i allsprites
{
ifactor 2978
{
qsprintf TQUOTE "MOVABLE EX:%d OW:%d", sprite[i].owner, sprite[i].extra
drawlabel TQUOTE .x .y .z 0 31
}
}
ends
*/