Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Tales of MajEyal
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
K'van
Tales of MajEyal
Commits
c4214930
Commit
c4214930
authored
10 years ago
by
Grayswandir
Browse files
Options
Downloads
Patches
Plain Diff
Added hooks and such for extending the targeting system.
parent
3899074a
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
game/engines/default/engine/Target.lua
+227
-171
227 additions, 171 deletions
game/engines/default/engine/Target.lua
game/engines/default/engine/interface/ActorProject.lua
+15
-6
15 additions, 6 deletions
game/engines/default/engine/interface/ActorProject.lua
with
242 additions
and
177 deletions
game/engines/default/engine/Target.lua
+
227
−
171
View file @
c4214930
...
...
@@ -24,6 +24,8 @@ local Shader = require "engine.Shader"
--- handles targetting
module
(
...
,
package
.
seeall
,
class
.
make
)
_M
.
defaults
=
{}
function
_M
:
init
(
map
,
source_actor
)
self
.
display_x
,
self
.
display_y
=
map
.
display_x
,
map
.
display_y
self
.
w
,
self
.
h
=
map
.
viewport
.
width
,
map
.
viewport
.
height
...
...
@@ -69,7 +71,7 @@ function _M:createTextures()
end
function
_M
:
enableFBORenderer
(
texture
,
shader
)
if
not
shader
or
not
core
.
display
.
fboSupportsTransparency
then
if
not
shader
or
not
core
.
display
.
fboSupportsTransparency
then
self
.
fbo
=
nil
self
:
createTextures
()
return
...
...
@@ -112,7 +114,7 @@ function _M:display(dispx, dispy, prevfbo, rotate_keyframes)
sx
=
sx
+
game
.
level
.
map
.
display_x
sy
=
sy
+
game
.
level
.
map
.
display_y
self
.
display_x
,
self
.
display_y
=
dispx
or
sx
or
self
.
display_x
,
dispy
or
sy
or
self
.
display_y
if
self
.
active
then
if
not
self
.
fbo
then
self
:
realDisplay
(
self
.
display_x
,
self
.
display_y
)
...
...
@@ -149,11 +151,95 @@ function _M:display(dispx, dispy, prevfbo, rotate_keyframes)
self
.
display_x
,
self
.
display_y
=
ox
,
oy
end
-- Being completely blocked by the corner of an adjacent tile is annoying, so let's make it a special case and hit it instead.
_M
.
defaults
.
display_blocked_by_adjacent
=
function
(
self
,
d
)
if
d
.
blocked_corner_x
then
d
.
block
=
true
d
.
hit
=
true
d
.
hit_radius
=
false
stopped
=
true
if
self
.
target_type
.
min_range
and
core
.
fov
.
distance
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
d
.
lx
,
d
.
ly
)
<
self
.
target_type
.
min_range
then
d
.
s
=
self
.
sr
end
if
game
.
level
.
map
:
isBound
(
d
.
blocked_corner_x
,
d
.
blocked_corner_y
)
then
d
.
display_highlight
(
d
.
s
,
d
.
blocked_corner_x
,
d
.
blocked_corner_y
)
end
d
.
s
=
self
.
sr
end
end
_M
.
defaults
.
display_check_block_path
=
function
(
self
,
d
)
d
.
block
,
d
.
hit
,
d
.
hit_radius
=
false
,
true
,
true
d
.
block
,
d
.
hit
,
d
.
hit_radius
=
self
.
target_type
:
block_path
(
d
.
lx
,
d
.
ly
,
true
)
end
-- Update coordinates and set color
_M
.
defaults
.
display_update_hit
=
function
(
self
,
d
)
if
d
.
hit
then
d
.
stop_x
,
d
.
stop_y
=
d
.
lx
,
d
.
ly
if
not
d
.
block
and
d
.
hit
==
"unknown"
then
d
.
s
=
self
.
sy
end
else
d
.
s
=
self
.
sr
end
end
_M
.
defaults
.
display_update_radius
=
function
(
self
,
d
)
if
d
.
hit_radius
then
d
.
stop_radius_x
,
d
.
stop_radius_y
=
d
.
lx
,
d
.
ly
end
end
_M
.
defaults
.
display_update_min_range
=
function
(
self
,
d
)
if
self
.
target_type
.
min_range
then
-- Check if we should be "red"
if
core
.
fov
.
distance
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
d
.
lx
,
d
.
ly
)
<
self
.
target_type
.
min_range
then
d
.
s
=
self
.
sr
-- Check if we were only "red" because of minimum distance
elseif
d
.
s
==
self
.
sr
then
d
.
s
=
self
.
sb
end
end
end
_M
.
defaults
.
display_line_step
=
function
(
self
,
d
)
d
.
display_highlight
(
d
.
s
,
d
.
lx
,
d
.
ly
)
end
_M
.
defaults
.
display_on_block
=
function
(
self
,
d
)
d
.
s
=
self
.
sr
d
.
stopped
=
true
end
_M
.
defaults
.
display_on_block_corner
=
function
(
self
,
d
)
d
.
block
=
true
d
.
stopped
=
true
d
.
hit_radius
=
false
d
.
s
=
self
.
sr
-- double the fun :-P
if
game
.
level
.
map
:
isBound
(
d
.
blocked_corner_x
,
d
.
blocked_corner_y
)
then
if
self
.
target_type
.
display_corner_block
then
self
.
target_type
.
display_corner_block
(
self
,
d
)
else
d
.
display_highlight
(
d
.
s
,
d
.
blocked_corner_x
,
d
.
blocked_corner_y
,
2
)
end
end
end
_M
.
defaults
.
display_default_target
=
function
(
self
,
d
)
-- Entity tracking, if possible and if visible
if
self
.
target
.
entity
and
self
.
target
.
entity
.
x
and
self
.
target
.
entity
.
y
and
game
.
level
.
map
.
seens
(
self
.
target
.
entity
.
x
,
self
.
target
.
entity
.
y
)
then
self
.
target
.
x
,
self
.
target
.
y
=
self
.
target
.
entity
.
x
,
self
.
target
.
entity
.
y
end
self
.
target
.
x
=
self
.
target
.
x
or
self
.
source_actor
.
x
self
.
target
.
y
=
self
.
target
.
y
or
self
.
source_actor
.
y
end
function
_M
:
realDisplay
(
dispx
,
dispy
,
display_highlight
)
if
not
display_highlight
then
if
util
.
isHex
()
then
display_highlight
=
function
(
texture
,
tx
,
ty
,
count
)
count
=
count
or
1
if
self
.
target_type
.
filter
and
not
self
.
target_type
.
no_filter_highlight
and
self
.
target_type
.
filter
(
tx
,
ty
)
then
count
=
count
+
1
end
for
i
=
1
,
count
do
texture
:
toScreenHighlightHex
(
dispx
+
(
tx
-
game
.
level
.
map
.
mx
)
*
self
.
tile_w
*
Map
.
zoom
,
...
...
@@ -165,6 +251,7 @@ function _M:realDisplay(dispx, dispy, display_highlight)
else
display_highlight
=
function
(
texture
,
tx
,
ty
,
count
)
count
=
count
or
1
if
self
.
target_type
.
filter
and
not
self
.
target_type
.
no_filter_highlight
and
self
.
target_type
.
filter
(
tx
,
ty
)
then
count
=
count
+
1
end
for
i
=
1
,
count
do
texture
:
toScreen
(
dispx
+
(
tx
-
game
.
level
.
map
.
mx
)
*
self
.
tile_w
*
Map
.
zoom
,
...
...
@@ -206,113 +293,70 @@ function _M:realDisplay(dispx, dispy, display_highlight)
return
end
local
d
=
{}
d
.
display_highlight
=
display_highlight
-- Make sure we have a source
if
not
self
.
target_type
.
source_actor
then
self
.
target_type
.
source_actor
=
self
.
source_actor
end
-- Entity tracking, if possible and if visible
if
self
.
target
.
entity
and
self
.
target
.
entity
.
x
and
self
.
target
.
entity
.
y
and
game
.
level
.
map
.
seens
(
self
.
target
.
entity
.
x
,
self
.
target
.
entity
.
y
)
then
self
.
target
.
x
,
self
.
target
.
y
=
self
.
target
.
entity
.
x
,
self
.
target
.
entity
.
y
end
self
.
target
.
x
=
self
.
target
.
x
or
self
.
source_actor
.
x
self
.
target
.
y
=
self
.
target
.
y
or
self
.
source_actor
.
y
-- Pick default target
self
.
target_type
.
display_default_target
(
self
,
d
)
self
.
target_type
.
start_x
=
self
.
target_type
.
start_x
or
self
.
target_type
.
x
or
self
.
target_type
.
source_actor
and
self
.
target_type
.
source_actor
.
x
or
self
.
x
self
.
target_type
.
start_y
=
self
.
target_type
.
start_y
or
self
.
target_type
.
y
or
self
.
target_type
.
source_actor
and
self
.
target_type
.
source_actor
.
y
or
self
.
y
-- self.cursor:toScreen(dispx + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, dispy + (self.target.y - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-- Do not display if not requested
if
not
self
.
active
then
return
end
local
s
=
self
.
sb
local
l
d
.
s
=
self
.
sb
if
self
.
target_type
.
source_actor
.
lineFOV
then
l
=
self
.
target_type
.
source_actor
:
lineFOV
(
self
.
target
.
x
,
self
.
target
.
y
,
nil
,
nil
,
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
)
d
.
l
=
self
.
target_type
.
source_actor
:
lineFOV
(
self
.
target
.
x
,
self
.
target
.
y
,
nil
,
nil
,
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
)
else
l
=
core
.
fov
.
line
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
self
.
target
.
x
,
self
.
target
.
y
)
d
.
l
=
core
.
fov
.
line
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
self
.
target
.
x
,
self
.
target
.
y
)
end
local
block_corner
=
self
.
target_type
.
block_path
and
function
(
_
,
bx
,
by
)
local
b
,
h
,
hr
=
self
.
target_type
:
block_path
(
bx
,
by
,
true
)
;
return
b
and
h
and
not
hr
end
or
function
(
_
,
bx
,
by
)
return
false
end
l
:
set_corner_block
(
block_corner
)
local
lx
,
ly
,
blocked_corner_x
,
blocked_corner_y
=
l
:
step
()
d
.
l
:
set_corner_block
(
block_corner
)
d
.
lx
,
d
.
ly
,
d
.
blocked_corner_x
,
d
.
blocked_corner_y
=
d
.
l
:
step
()
local
stop_x
,
stop_y
=
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
local
stop_radius_x
,
stop_radius_y
=
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
local
stopped
=
false
local
block
,
hit
,
hit_radius
d
.
stop_x
,
d
.
stop_y
=
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
d
.
stop_radius_x
,
d
.
stop_radius_y
=
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
d
.
stopped
=
false
local
firstx
,
firsty
=
lx
,
ly
d
.
firstx
,
d
.
firsty
=
d
.
lx
,
d
.
ly
-- Being completely blocked by the corner of an adjacent tile is annoying, so let's make it a special case and hit it instead
if
blocked_corner_x
then
block
=
true
hit
=
true
hit_radius
=
false
stopped
=
true
if
self
.
target_type
.
min_range
and
core
.
fov
.
distance
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
lx
,
ly
)
<
self
.
target_type
.
min_range
then
s
=
self
.
sr
end
if
game
.
level
.
map
:
isBound
(
blocked_corner_x
,
blocked_corner_y
)
then
display_highlight
(
s
,
blocked_corner_x
,
blocked_corner_y
)
end
s
=
self
.
sr
end
while
lx
and
ly
do
if
not
stopped
then
block
,
hit
,
hit_radius
=
false
,
true
,
true
if
self
.
target_type
.
block_path
then
block
,
hit
,
hit_radius
=
self
.
target_type
:
block_path
(
lx
,
ly
,
true
)
end
self
.
target_type
.
display_blocked_by_adjacent
(
self
,
d
)
while
d
.
lx
and
d
.
ly
do
if
not
d
.
stopped
then
self
.
target_type
.
display_check_block_path
(
self
,
d
)
-- Update coordinates and set color
if
hit
then
stop_x
,
stop_y
=
lx
,
ly
if
not
block
and
hit
==
"unknown"
then
s
=
self
.
sy
end
else
s
=
self
.
sr
end
if
hit_radius
then
stop_radius_x
,
stop_radius_y
=
lx
,
ly
end
if
self
.
target_type
.
min_range
then
-- Check if we should be "red"
if
core
.
fov
.
distance
(
self
.
target_type
.
start_x
,
self
.
target_type
.
start_y
,
lx
,
ly
)
<
self
.
target_type
.
min_range
then
s
=
self
.
sr
-- Check if we were only "red" because of minimum distance
elseif
s
==
self
.
sr
then
s
=
self
.
sb
end
end
end
display_highlight
(
s
,
lx
,
ly
)
if
block
then
s
=
self
.
sr
stopped
=
true
self
.
target_type
.
display_update_hit
(
self
,
d
)
self
.
target_type
.
display_update_radius
(
self
,
d
)
self
.
target_type
.
display_update_min_range
(
self
,
d
)
end
lx
,
ly
,
blocked_corner_x
,
blocked_corner_y
=
l
:
step
(
)
self
.
target_type
.
display_line_step
(
self
,
d
)
if
blocked_corner_x
and
not
stopped
then
block
=
true
stopped
=
true
hit_radius
=
false
s
=
self
.
sr
-- double the fun :-P
if
game
.
level
.
map
:
isBound
(
blocked_corner_x
,
blocked_corner_y
)
then
display_highlight
(
s
,
blocked_corner_x
,
blocked_corner_y
,
2
)
end
end
if
d
.
block
then
self
.
target_type
.
display_on_block
(
self
,
d
)
end
d
.
lx
,
d
.
ly
,
d
.
blocked_corner_x
,
d
.
blocked_corner_y
=
d
.
l
:
step
()
if
d
.
blocked_corner_x
and
not
d
.
stopped
then
self
.
target_type
.
display_on_block_corner
(
self
,
d
)
end
end
if
self
.
target_type
.
ball
and
self
.
target_type
.
ball
>
0
then
core
.
fov
.
calc_circle
(
stop_radius_x
,
stop_radius_y
,
d
.
stop_radius_x
,
d
.
stop_radius_y
,
game
.
level
.
map
.
w
,
game
.
level
.
map
.
h
,
self
.
target_type
.
ball
,
...
...
@@ -321,17 +365,19 @@ function _M:realDisplay(dispx, dispy, display_highlight)
end
,
function
(
_
,
px
,
py
)
if
not
self
.
target_type
.
no_restrict
and
not
game
.
level
.
map
.
remembers
(
px
,
py
)
and
not
game
.
level
.
map
.
seens
(
px
,
py
)
then
display_highlight
(
self
.
syg
,
px
,
py
)
d
.
display_highlight
(
self
.
syg
,
px
,
py
)
else
display_highlight
(
self
.
sg
,
px
,
py
)
d
.
display_highlight
(
self
.
sg
,
px
,
py
)
end
end
,
nil
)
elseif
self
.
target_type
.
cone
and
self
.
target_type
.
cone
>
0
then
nil
)
end
if
self
.
target_type
.
cone
and
self
.
target_type
.
cone
>
0
then
--local dir_angle = math.deg(math.atan2(self.target.y - self.source_actor.y, self.target.x - self.source_actor.x))
core
.
fov
.
calc_beam_any_angle
(
stop_radius_x
,
stop_radius_y
,
d
.
stop_radius_x
,
d
.
stop_radius_y
,
game
.
level
.
map
.
w
,
game
.
level
.
map
.
h
,
self
.
target_type
.
cone
,
...
...
@@ -345,16 +391,18 @@ function _M:realDisplay(dispx, dispy, display_highlight)
end
,
function
(
_
,
px
,
py
)
if
not
self
.
target_type
.
no_restrict
and
not
game
.
level
.
map
.
remembers
(
px
,
py
)
and
not
game
.
level
.
map
.
seens
(
px
,
py
)
then
display_highlight
(
self
.
syg
,
px
,
py
)
d
.
display_highlight
(
self
.
syg
,
px
,
py
)
else
display_highlight
(
self
.
sg
,
px
,
py
)
d
.
display_highlight
(
self
.
sg
,
px
,
py
)
end
end
,
nil
)
elseif
self
.
target_type
.
wall
and
self
.
target_type
.
wall
>
0
then
end
if
self
.
target_type
.
wall
and
self
.
target_type
.
wall
>
0
then
core
.
fov
.
calc_wall
(
stop_radius_x
,
stop_radius_y
,
d
.
stop_radius_x
,
d
.
stop_radius_y
,
game
.
level
.
map
.
w
,
game
.
level
.
map
.
h
,
self
.
target_type
.
wall
,
...
...
@@ -368,15 +416,100 @@ function _M:realDisplay(dispx, dispy, display_highlight)
end
,
function
(
_
,
px
,
py
)
if
not
self
.
target_type
.
no_restrict
and
not
game
.
level
.
map
.
remembers
(
px
,
py
)
and
not
game
.
level
.
map
.
seens
(
px
,
py
)
then
display_highlight
(
self
.
syg
,
px
,
py
)
d
.
display_highlight
(
self
.
syg
,
px
,
py
)
else
display_highlight
(
self
.
sg
,
px
,
py
)
d
.
display_highlight
(
self
.
sg
,
px
,
py
)
end
end
,
nil
)
end
d
[
1
]
=
"Target:realDisplay"
self
:
triggerHook
(
d
)
end
_M
.
defaults
.
block_path
=
function
(
typ
,
lx
,
ly
,
for_highlights
)
if
not
game
.
level
.
map
:
isBound
(
lx
,
ly
)
then
return
true
,
false
,
false
elseif
not
typ
.
no_restrict
then
if
typ
.
range
and
typ
.
start_x
then
local
dist
=
core
.
fov
.
distance
(
typ
.
start_x
,
typ
.
start_y
,
lx
,
ly
)
if
dist
>
typ
.
range
then
return
true
,
false
,
false
end
elseif
typ
.
range
and
typ
.
source_actor
and
typ
.
source_actor
.
x
then
local
dist
=
core
.
fov
.
distance
(
typ
.
source_actor
.
x
,
typ
.
source_actor
.
y
,
lx
,
ly
)
if
dist
>
typ
.
range
then
return
true
,
false
,
false
end
end
local
is_known
=
game
.
level
.
map
.
remembers
(
lx
,
ly
)
or
game
.
level
.
map
.
seens
(
lx
,
ly
)
if
typ
.
requires_knowledge
and
not
is_known
then
return
true
,
false
,
false
end
if
not
typ
.
pass_terrain
and
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
not
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
)
then
if
for_highlights
and
not
is_known
then
return
false
,
"unknown"
,
true
else
return
true
,
true
,
false
end
-- If we explode due to something other than terrain, then we should explode ON the tile, not before it
elseif
typ
.
stop_block
then
local
nb
=
game
.
level
.
map
:
checkAllEntitiesCount
(
lx
,
ly
,
"block_move"
)
-- Reduce for pass_projectile or pass_terrain, which was handled above
if
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
(
typ
.
pass_terrain
or
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
))
then
nb
=
nb
-
1
end
-- Reduce the nb blocking for friendlies
if
not
typ
.
friendlyblock
and
typ
.
source_actor
and
typ
.
source_actor
.
reactionToward
then
local
a
=
game
.
level
.
map
(
lx
,
ly
,
engine
.
Map
.
ACTOR
)
if
a
and
typ
.
source_actor
:
reactionToward
(
a
)
>
0
then
nb
=
nb
-
1
end
end
if
nb
>
0
then
if
for_highlights
then
-- Targeting highlight should be yellow if we don't know what we're firing through
if
not
is_known
then
return
false
,
"unknown"
,
true
-- Don't show the path as blocked if it's blocked by an actor we can't see
elseif
nb
==
1
and
typ
.
source_actor
and
typ
.
source_actor
.
canSee
and
not
typ
.
source_actor
:
canSee
(
game
.
level
.
map
(
lx
,
ly
,
engine
.
Map
.
ACTOR
))
then
return
false
,
true
,
true
end
end
return
true
,
true
,
true
end
end
if
for_highlights
and
not
is_known
then
return
false
,
"unknown"
,
true
end
end
-- If we don't block the path, then the explode point should be here
return
false
,
true
,
true
end
_M
.
defaults
.
block_radius
=
function
(
typ
,
lx
,
ly
,
for_highlights
)
return
not
typ
.
no_restrict
and
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
not
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
)
and
not
(
for_highlights
and
not
(
game
.
level
.
map
.
remembers
(
lx
,
ly
)
or
game
.
level
.
map
.
seens
(
lx
,
ly
)))
end
--- targeting type strings -> modification function.
_M
.
types_def
=
{
ball
=
function
(
dest
,
src
)
dest
.
ball
=
src
.
radius
end
,
cone
=
function
(
dest
,
src
)
dest
.
cone
=
src
.
radius
dest
.
cone_angle
=
src
.
cone_angle
or
55
dest
.
selffire
=
false
end
,
wall
=
function
(
dest
,
src
)
if
util
.
isHex
()
then
--with a hex grid, a wall should only be defined by the number of spots
src
.
halfmax_spots
=
src
.
halflength
src
.
halflength
=
2
*
src
.
halflength
end
dest
.
wall
=
src
.
halflength
end
,
bolt
=
function
(
dest
,
src
)
dest
.
stop_block
=
true
end
,
beam
=
function
(
dest
,
scr
)
dest
.
line
=
true
end
,}
-- @return t The target table used by ActorProject, Projectile, GameTargeting, etc.
-- @param t Target table used to generate the
-- @param t.type The engine-defined type, populates other more complex variables (see below)
...
...
@@ -416,92 +549,16 @@ function _M:getType(t)
selffire
=
true
,
friendlyfire
=
true
,
friendlyblock
=
true
,
--- Determines how a path is blocked for a target type
--@param typ The target type table
block_path
=
function
(
typ
,
lx
,
ly
,
for_highlights
)
if
not
game
.
level
.
map
:
isBound
(
lx
,
ly
)
then
return
true
,
false
,
false
elseif
not
typ
.
no_restrict
then
if
typ
.
range
and
typ
.
start_x
then
local
dist
=
core
.
fov
.
distance
(
typ
.
start_x
,
typ
.
start_y
,
lx
,
ly
)
if
dist
>
typ
.
range
then
return
true
,
false
,
false
end
elseif
typ
.
range
and
typ
.
source_actor
and
typ
.
source_actor
.
x
then
local
dist
=
core
.
fov
.
distance
(
typ
.
source_actor
.
x
,
typ
.
source_actor
.
y
,
lx
,
ly
)
if
dist
>
typ
.
range
then
return
true
,
false
,
false
end
end
local
is_known
=
game
.
level
.
map
.
remembers
(
lx
,
ly
)
or
game
.
level
.
map
.
seens
(
lx
,
ly
)
if
typ
.
requires_knowledge
and
not
is_known
then
return
true
,
false
,
false
end
if
not
typ
.
pass_terrain
and
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
not
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
)
then
if
for_highlights
and
not
is_known
then
return
false
,
"unknown"
,
true
else
return
true
,
true
,
false
end
-- If we explode due to something other than terrain, then we should explode ON the tile, not before it
elseif
typ
.
stop_block
then
local
nb
=
game
.
level
.
map
:
checkAllEntitiesCount
(
lx
,
ly
,
"block_move"
)
-- Reduce for pass_projectile or pass_terrain, which was handled above
if
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
(
typ
.
pass_terrain
or
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
))
then
nb
=
nb
-
1
end
-- Reduce the nb blocking for friendlies
if
not
typ
.
friendlyblock
and
typ
.
source_actor
and
typ
.
source_actor
.
reactionToward
then
local
a
=
game
.
level
.
map
(
lx
,
ly
,
engine
.
Map
.
ACTOR
)
if
a
and
typ
.
source_actor
:
reactionToward
(
a
)
>
0
then
nb
=
nb
-
1
end
end
if
nb
>
0
then
if
for_highlights
then
-- Targeting highlight should be yellow if we don't know what we're firing through
if
not
is_known
then
return
false
,
"unknown"
,
true
-- Don't show the path as blocked if it's blocked by an actor we can't see
elseif
nb
==
1
and
typ
.
source_actor
and
typ
.
source_actor
.
canSee
and
not
typ
.
source_actor
:
canSee
(
game
.
level
.
map
(
lx
,
ly
,
engine
.
Map
.
ACTOR
))
then
return
false
,
true
,
true
end
end
return
true
,
true
,
true
end
end
if
for_highlights
and
not
is_known
then
return
false
,
"unknown"
,
true
end
end
-- If we don't block the path, then the explode point should be here
return
false
,
true
,
true
end
,
block_radius
=
function
(
typ
,
lx
,
ly
,
for_highlights
)
return
not
typ
.
no_restrict
and
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"block_move"
)
and
not
game
.
level
.
map
:
checkEntity
(
lx
,
ly
,
engine
.
Map
.
TERRAIN
,
"pass_projectile"
)
and
not
(
for_highlights
and
not
(
game
.
level
.
map
.
remembers
(
lx
,
ly
)
or
game
.
level
.
map
.
seens
(
lx
,
ly
)))
end
}
for
k
,
v
in
pairs
(
self
.
defaults
)
do
target_type
[
k
]
=
v
end
-- And now modify for the default types
if
t
.
type
then
if
t
.
type
:
find
(
"ball"
)
then
target_type
.
ball
=
t
.
radius
end
if
t
.
type
:
find
(
"cone"
)
then
target_type
.
cone
=
t
.
radius
target_type
.
cone_angle
=
t
.
cone_angle
or
55
target_type
.
selffire
=
false
end
if
t
.
type
:
find
(
"wall"
)
then
if
util
.
isHex
()
then
--with a hex grid, a wall should only be defined by the number of spots
t
.
halfmax_spots
=
t
.
halflength
t
.
halflength
=
2
*
t
.
halflength
end
target_type
.
wall
=
t
.
halflength
end
if
t
.
type
:
find
(
"bolt"
)
then
target_type
.
stop_block
=
true
elseif
t
.
type
:
find
(
"beam"
)
then
target_type
.
line
=
true
for
type_name
,
fun
in
pairs
(
self
.
types_def
)
do
if
t
.
type
:
find
(
type_name
)
then
fun
(
target_type
,
t
)
end
end
end
table
.
update
(
t
,
target_type
)
return
t
end
...
...
@@ -551,7 +608,7 @@ function _M:scan(dir, radius, sx, sy, filter, kind)
sx
=
sx
or
self
.
target
.
x
sy
=
sy
or
self
.
target
.
y
if
not
sx
or
not
sy
then
return
end
kind
=
kind
or
engine
.
Map
.
ACTOR
radius
=
radius
or
20
local
actors
=
{}
...
...
@@ -602,4 +659,3 @@ function _M:pointAtRange(srcx, srcy, destx, desty, dist)
return
lx
,
ly
end
end
This diff is collapsed.
Click to expand it.
game/engines/default/engine/interface/ActorProject.lua
+
15
−
6
View file @
c4214930
...
...
@@ -56,6 +56,7 @@ function _M:project(t, x, y, damtype, dam, particles)
local
grids
=
{}
local
function
addGrid
(
x
,
y
)
if
typ
.
filter
and
not
typ
.
filter
(
x
,
y
)
then
return
end
if
not
grids
[
x
]
then
grids
[
x
]
=
{}
end
grids
[
x
][
y
]
=
true
end
...
...
@@ -112,7 +113,9 @@ function _M:project(t, x, y, damtype, dam, particles)
end
end
local
single_target
=
true
if
typ
.
ball
and
typ
.
ball
>
0
then
single_target
=
false
core
.
fov
.
calc_circle
(
stop_radius_x
,
stop_radius_y
,
...
...
@@ -128,7 +131,10 @@ function _M:project(t, x, y, damtype, dam, particles)
end
,
nil
)
addGrid
(
stop_x
,
stop_y
)
elseif
typ
.
cone
and
typ
.
cone
>
0
then
end
if
typ
.
cone
and
typ
.
cone
>
0
then
single_target
=
false
--local dir_angle = math.deg(math.atan2(y - self.y, x - self.x))
core
.
fov
.
calc_beam_any_angle
(
stop_radius_x
,
...
...
@@ -149,7 +155,10 @@ function _M:project(t, x, y, damtype, dam, particles)
end
,
nil
)
addGrid
(
stop_x
,
stop_y
)
elseif
typ
.
wall
and
typ
.
wall
>
0
then
end
if
typ
.
wall
and
typ
.
wall
>
0
then
single_target
=
false
core
.
fov
.
calc_wall
(
stop_radius_x
,
stop_radius_y
,
...
...
@@ -168,11 +177,11 @@ function _M:project(t, x, y, damtype, dam, particles)
addGrid
(
px
,
py
)
end
,
nil
)
else
-- Deal damage: single
addGrid
(
stop_x
,
stop_y
)
end
-- Deal damage: single
if
single_target
then
addGrid
(
stop_x
,
stop_y
)
end
-- Check for minimum range
if
typ
.
min_range
and
core
.
fov
.
distance
(
typ
.
start_x
,
typ
.
start_y
,
stop_x
,
stop_y
)
<
typ
.
min_range
then
return
...
...
@@ -188,7 +197,7 @@ function _M:project(t, x, y, damtype, dam, particles)
end
end
end
self
:
check
(
"on_project_grids"
,
grids
)
-- Now project on each grid, one type
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment