USING: sequences math.statistics math math.functions kernel
assocs sorting arrays accessors math.vectors
juere-engine.utils
juere-engine.stage
juere-engine.physics ;
IN: juere-engine.shooting-gallery
:: hitscan-distance ( pxpz xz0 dxdz -- t distance )
pxpz xz0 dxdz [ t@q ] 3map mean :> t'n
t'n '{ _ } xz0 dxdz xz@ts first :> xz'n
pxpz xz'n [ - 2 ^ ] 2map sum sqrt :> d
t'n d ;
: hitscan-distance* ( pxpz xyz-from xyz-to -- t distance )
[ unclip*-2nd nip ] bi@ dupd [ swap - ] 2map
hitscan-distance ;
GENERIC#: hitme? 2 ( subject xyz-from xyz-to -- t/f )
CONSTANT: ent-width 0.25
M: object hitme? 3drop f ;
M: tangible hitme?
[ tangible-xyz ] 2dip hitscan-distance* ent-width <
! todo: height check
[ drop f ] unless ;
: entities-hit ( entities xyz-from xyz-to -- t-entities )
[ hitme? ] 2curry dupd map swap zip
[ first ] filter sort-keys ;
: entity-collision ( entities xyz-from xyz-to -- xyz )
2dup [ entities-hit ?first ] 2dip [
first 1array -rot xyz@ts first
] [ nip ] if* ;
TUPLE: shooter < physical
{ aiming-at initial: { 0/0. 0/0. 0/0. } } ;
TUPLE: crosshair < entity
height ;
GENERIC#: set-crosshair 1 ( shooter xyz -- )
M: object set-crosshair 2drop ;
M: shooter set-crosshair >>aiming-at drop ;
M: crosshair entity-action ( entity stage quots -- quots )
2over [ camera-xyz>> ] [ aiming-at>> ] [ tiles>> ]
tri next-position
! [ swap [ entities>> ] [ camera-xyz>> ] bi ] dip
! entity-collision
[ 50 0.008 * - >>height ] [ >>position ] bi*
drop call-next-method ;
TUPLE: fixed-crosshair < crosshair ;
: window-aimpoint ( stage -- xyz )
[ camera-xyz>> ] [ camera-pitch>> ] [ camera-yaw>> ] tri
[ neg deg>rad sin 10 * '{ 0 _ 0 } ]
[ -90 + [ 10 ] dip angle>xyz ] bi* v+ v+ ;
M: fixed-crosshair entity-action
over [ window-aimpoint ] keep aiming-at<< call-next-method ;
: shooter-test ( -- physical )
3 ramped-tiles V{ } V{ }
1 "liveangel.bmp" <rsrc>
0.015 { -0.5 -0.5 } entity boa suffix
2 "crosshair.bmp" <rsrc>
0.008 { -0.5 -0.5 } 0/0. crosshair boa suffix
phys-chicken suffix
V{ } V{ }
{ 0 5 1 } 0 0
0.02 { 1 5 1 } shooter boa ;