mirror of
https://github.com/DrBeef/Raze.git
synced 2024-11-16 09:21:12 +00:00
9a7bdfa76c
git-svn-id: https://svn.eduke32.com/eduke32@2227 1a8010ca-5511-0410-912e-c29ae57300e0
1350 lines
35 KiB
Text
1350 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
|
|
|
|
////////// 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
|
|
*/
|