Files
scummvm/devtools/create_ultima/files/ultima6/scripts/common/actor.lua
T

203 lines
5.1 KiB
Lua

ALIGNMENT_DEFAULT = 0
ALIGNMENT_NEUTRAL = 1
ALIGNMENT_EVIL = 2
ALIGNMENT_GOOD = 3
ALIGNMENT_CHAOTIC = 4
HEAD = 0
NECK = 1
BODY = 2
ARM = 3
ARM_2 = 4
HAND = 5
HAND_2 = 6
FOOT = 7
g_combat_range_tbl = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 1, 2, 3, 4, 5, 6, 7,
2, 2, 2, 3, 4, 5, 6, 7,
3, 3, 3, 4, 5, 6, 7, 7,
4, 4, 4, 5, 6, 7, 7, 8,
5, 5, 5, 6, 7, 7, 8, 8,
6, 6, 6, 7, 7, 8, 8, 8,
7, 7, 7, 7, 8, 8, 8, 8}
function get_combat_range(absx, absy)
if absx < 8 and absy < 8 then
return g_combat_range_tbl[absx * 8 + absy + 1]
end
return 9
end
function get_weapon_range(obj_n)
local range = g_range_weapon_tbl[obj_n]
if range == nil then
return 1
end
return range
end
function actor_randomise_stat(base_stat)
local tmp = math.floor(base_stat/2)
if tmp == 0 then
return base_stat
end
return math.random(0, tmp) + math.random(0, tmp) + base_stat - tmp
end
function actor_is_holding_obj(actor, obj_n)
local hand
hand = Actor.inv_get_readied_obj_n(actor, HAND)
if hand == obj_n then
return true
end
hand = Actor.inv_get_readied_obj_n(actor, HAND_2)
if hand == obj_n then
return true
end
return false
end
function actor_has_free_arm(actor)
if Actor.inv_get_readied_obj_n(actor, ARM) == -1
or Actor.inv_get_readied_obj_n(actor, ARM_2) == -1 then
return true
end
return false
end
function actor_find_max_xy_distance(actor, x, y)
x, y = abs(actor.x - x), abs(actor.y - y)
return (x > y) and x or y
end
function actor_find_max_wrapped_xy_distance(actor, x, y)
x, y = get_wrapped_dist(actor.x, x), get_wrapped_dist(actor.y, y)
return (x > y) and x or y
end
function actor_get_combat_range(actor, target_x, target_y)
--FIXME might need to adjust the src position for multi-tile actors.
x, y = get_wrapped_dist(actor.x, target_x), get_wrapped_dist(actor.y, target_y)
return get_combat_range(x, y)
end
function subtract_map_movement_pts(actor)
local points = map_get_impedence(actor.x, actor.y, actor.z, false) + 5
subtract_movement_pts(actor, points)
end
function actor_move_towards_loc(actor, map_x, map_y)
--dgb("move actor "..actor.name.." from ("..actor.x..","..actor.y..") towards ("..map_x..","..map_y..") ")
local var_2 = (word_30A6B == 1) and 0 or 1
local var_6 = 1
local diff_x = map_x - actor.x
local diff_y = map_y - actor.y
if (diff_x == 0 and diff_y == 0) or actor.wt == WT_STATIONARY then subtract_movement_pts(actor, 5) return 0 end
local x_direction, y_direction
if diff_x ~= 0 then
x_direction = (diff_x >= 0) and DIR_EAST or DIR_WEST
else
x_direction = (math.random(0, 1) == 0) and DIR_WEST or DIR_EAST
end
if diff_y ~= 0 then
y_direction = (diff_y >= 0) and DIR_SOUTH or DIR_NORTH
else
y_direction = (math.random(0, 1) == 0) and DIR_SOUTH or DIR_NORTH
end
unk_30A72 = 0
local var_4
if abs(diff_x) >= 4 or abs(diff_y) >= 4 then
var_4 = (math.random(1, abs(diff_x) + abs(diff_y)) <= abs(diff_x)) and 1 or 0
else
if abs(diff_x) > abs(diff_y) then
var_4 = 0
else
if abs(diff_x) < abs(diff_y) then
var_4 = 1
else
var_4 = math.random(0, 1)
end
end
--var_4 = (abs(diff_x) >= abs(diff_y) or abs(diff_x) ~= abs(diff_y) or math.random(0, 1) == 0) and 0 or 1
end
----dgb("var_4 = "..var_4.."\n")
if var_4 == 0 then
if actor_move(actor, x_direction, var_2) == 0 then
if actor_move_diagonal(actor, x_direction, y_direction) == 0 then
if actor_move(actor, y_direction, var_2) == 0 then
if math.random(0, 1) ~= 0 or actor_move(actor, (y_direction == DIR_NORTH) and DIR_SOUTH or DIR_NORTH, 1) == 0 then
subtract_map_movement_pts(actor)
var_6 = 0 --didn't move anywhere
end
end
end
end
else
if actor_move(actor, y_direction, var_2) == 0 then
if actor_move_diagonal(actor, x_direction, y_direction) == 0 then
if actor_move(actor, x_direction, var_2) == 0 then
if math.random(0, 1) ~= 0 or actor_move(actor, (x_direction == DIR_EAST) and DIR_WEST or DIR_EAST, 1) == 0 then
subtract_map_movement_pts(actor)
var_6 = 0 --didn't move anywhere
end
end
end
end
end
unk_30A72 = 1
----dgb("var_6 = "..var_6)
--dgb(" now at ("..actor.x..","..actor.y..") dir="..actor.direction.."\n")
return var_6
end
function toss_actor(actor, from_x, from_y, from_z, arg_0)
local random = math.random
local player_loc = player_get_location()
for i=1,8 do
local new_x = random(1, 4) + random(1, 4) + from_x - 5
local new_y = random(1, 4) + random(1, 4) + from_y - 5
if arg_0 == 0
or player_loc.x - 5 > new_x or player_loc.x + 5 < new_x or player_loc.y - 5 > new_y or player_loc.y + 5 < new_y then
if Actor.move(actor, new_x, new_y, from_z) == true then return true end
end
end
return false
end
function actor_has_bad_alignment(actor)
return actor.wt == ALIGNMENT_EVIL or actor.wt == ALIGNMENT_CHAOTIC
end