Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,202 @@
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

View File

@@ -0,0 +1,397 @@
--note nuvie direction values aren't the same as the original it uses the following scheme
--701
--6 2
--543
DIR_NORTH = 0
DIR_EAST = 1
DIR_SOUTH = 2
DIR_WEST = 3
DIR_NORTHEAST = 4
DIR_SOUTHEAST = 5
DIR_SOUTHWEST = 6
DIR_NORTHWEST = 7
DIR_NONE = 8
UI_STYLE_ORIG = 0
UI_STYLE_NEW = 1
UI_STYLE_ORIG_PLUS_CUTOFF_MAP = 2
UI_STYLE_ORIG_PLUS_FULL_MAP = 3
STACK_OBJECT_QTY = true
movement_offset_x_tbl = {0, 1, 1, 1, 0, -1, -1, -1}
movement_offset_y_tbl = {-1, -1, 0, 1, 1, 1, 0, -1 }
if not setfenv then -- Lua 5.2
-- based on http://lua-users.org/lists/lua-l/2010-06/msg00314.html
-- this assumes f is a function
local function findenv(f)
local level = 1
repeat
local name, value = debug.getupvalue(f, level)
if name == '_ENV' then return level, value end
level = level + 1
until name == nil
return nil
end
getfenv = function (f) return(select(2, findenv(f)) or _G) end
setfenv = function (f, t)
local level = findenv(f)
if level then debug.setupvalue(f, level, t) end
return f
end
end
function get_target()
local loc = coroutine.yield("target")
return loc
end
function get_direction(prompt)
if prompt ~= nil then
print(prompt)
end
local dir = coroutine.yield("dir")
return dir
end
function really_get_direction(prompt)
if prompt ~= nil then
print(prompt)
end
local dir = coroutine.yield("need_dir")
return dir
end
function direction_string(dir)
if dir ~= nil then
if dir == DIR_NORTH then return "north" end
if dir == DIR_NORTHEAST then return "northeast" end
if dir == DIR_EAST then return "east" end
if dir == DIR_SOUTHEAST then return "southeast" end
if dir == DIR_SOUTH then return "south" end
if dir == DIR_SOUTHWEST then return "southwest" end
if dir == DIR_WEST then return "west" end
if dir == DIR_NORTHWEST then return "northwest" end
end
return "unknown"
end
local dir_rev_tbl =
{
[DIR_NORTH] = DIR_SOUTH,
[DIR_NORTHEAST] = DIR_SOUTHWEST,
[DIR_EAST] = DIR_WEST,
[DIR_SOUTHEAST] = DIR_NORTHWEST,
[DIR_SOUTH] = DIR_NORTH,
[DIR_SOUTHWEST] = DIR_NORTHEAST,
[DIR_WEST] = DIR_EAST,
[DIR_NORTHWEST] = DIR_SOUTHEAST
}
function direction_reverse(dir) return dir_rev_tbl[dir] end
local g_dir_offset_tbl =
{
[DIR_NORTH] = {["x"]=0, ["y"]=-1},
[DIR_NORTHEAST] = {["x"]=1, ["y"]=-1},
[DIR_EAST] = {["x"]=1, ["y"]=0},
[DIR_SOUTHEAST] = {["x"]=1, ["y"]=1},
[DIR_SOUTH] = {["x"]=0, ["y"]=1},
[DIR_SOUTHWEST] = {["x"]=-1, ["y"]=1},
[DIR_WEST] = {["x"]=-1, ["y"]=0},
[DIR_NORTHWEST] = {["x"]=-1, ["y"]=-1},
[DIR_NONE] = {["x"]=0, ["y"]=0}
}
function direction_get_loc(dir, from_x, from_y)
return g_dir_offset_tbl[dir].x + from_x, g_dir_offset_tbl[dir].y + from_y
end
function abs(val)
if val < 0 then
return -val
end
return val
end
--collect Yes/No input from user and return true if Yes selected. false otherwise.
function input_should_proceed()
local input = input_select("yn", true)
print("\n")
if input == nil or input == "N" or input == "n" then
return false
end
return true
end
function play_midgame_sequence(seq_num)
local ui_style = game_get_ui_style()
canvas_show()
canvas_hide_all_sprites()
canvas_set_opacity(0xff);
canvas_set_update_interval(25)
canvas_rotate_game_palette(true)
local bg = sprite_new(nil, 8, 16, true)
local avatar = sprite_new(nil, 8, 16, false)
local text_sprite
--local text_sprite_bg
if ui_style == UI_STYLE_ORIG then
canvas_set_solid_bg(false)
else
--[[
text_sprite_bg = sprite_new(nil, 8, 160, true)
text_sprite_bg.text_align = 2
text_sprite_bg.text_color = 14
--]]
text_sprite = sprite_new(nil, 8, 160, true)
text_sprite.text_align = 2
text_sprite.text_color = 15
bg.x = 80
bg.y = 12
avatar.x = 80
avatar.y = 12
end
local midgame_data = midgame_load("midgame"..string.format("%x", seq_num)..".lzc")
local i = 0
local data = midgame_data[i]
while data ~= nil do
bg.image = data.images[0]
if data.images[1] ~= nil then
local gender = player_get_gender()
avatar.image = data.images[1+gender]
avatar.visible = true
else
avatar.visible = false
end
local j = 0
local text = data.text[j]
while text ~= nil do
if text ~= "*END*" then
if ui_style == UI_STYLE_ORIG then
clear_scroll()
print(text)
else
text_sprite.text = text
--text_sprite_bg.text = text
end
local input = nil
while input == nil do
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
end
j = j + 1
text = data.text[j]
end
i = i + 1
data = midgame_data[i]
end
if ui_style == UI_STYLE_ORIG then
clear_scroll()
end
canvas_set_solid_bg(true)
canvas_rotate_game_palette(false)
canvas_hide()
end
function get_wrapped_dist(pt1, pt2)
local diff
if pt2 >= pt1 then
diff = pt2 - pt1
else
diff = pt1 - pt2
end
if diff > 512 then
diff = 1024 - diff
end
return diff
end
function get_anim_index_for_tile(tile_number)
local total_anims = anim_get_number_of_entries()
for i=0,total_anims-1 do
if anim_get_tile(i) == tile_number then
return i
end
end
return nil
end
function altcode_242_set_actor_talk_flag()
print("NPC: ")
local input = input_select(nil, true)
local actor_num = tonumber(input, 16)
local actor = Actor.get(actor_num)
print("\n"..actor.name.."\n")
print("flags: \n") --FIXME print talk flags
print("\nBit: ")
local bit = input_select_integer(nil, true)
local value = Actor.get_talk_flag(actor, bit)
local value_str = "off"
if value == true then
value_str = "on"
end
print(" is "..value_str..".\n")
print("New value? ")
value = input_select_integer(nil, true)
value_str = "off"
if value == 1 or value == "o" then
value_str = "on"
Actor.set_talk_flag(actor, bit)
else
Actor.clear_talk_flag(actor, bit)
end
print("\n"..value_str.."\n")
end
function altcode_250_create_object()
print("Create Item:\nType:0x")
local input = input_select(nil, true)
local obj_n = tonumber(input, 16)
local obj = Obj.new(obj_n)
local tmp_obj = Obj.new(obj_n+1)
if tmp_obj ~= nil and tmp_obj.tile_num - obj.tile_num > 1 then
print("\nFrame:0x")
input = input_select(nil, true)
obj.frame_n = tonumber(input, 16)
end
print("\nQual:0x")
input = input_select(nil, true)
obj.quality = tonumber(input, 16)
if obj.stackable or create_object_needs_quan(obj_n) then
print("\nQuan:0x")
input = input_select(nil, true)
obj.qty = tonumber(input, 16)
end
Obj.moveToInv(obj, Actor.get(1).actor_num)
print("\n")
end
function altcode_913_export_tmx_map_files()
print("\nExport maps to savedir? ")
if not input_should_proceed() then
return
end
print("saving.\n")
script_wait(1)
if map_export_tmx_files() == true then
print("done.\n\n")
else
print("error!!\n\n")
end
end
function altcode_914_export_tileset()
print("Exporting tileset to \"data/images/tiles/"..config_get_game_type().."/custom_tiles.bmp\" in the savegame directory.\n")
if not tileset_export() then
print("file already exists. Overwrite? ")
if not input_should_proceed() then
return
end
tileset_export(true)
end
print("done.\n\n")
end
function altcode_999_find_objs_on_map()
print("Find Object\nObj_n: ")
local input = input_select(nil, true)
local obj_n = tonumber(input, 10)
if obj_n == nil then
print("Nothing.\n")
return
end
print("\nFrame: ")
input = input_select(nil, true)
local frame_n = tonumber(input, 10)
print("\nQuality: ")
input = input_select(nil, true)
local quality = tonumber(input, 10)
print("\nz: ")
input = input_select(nil, true)
local z = tonumber(input, 10)
if z == nil then
z = 0
end
print("\n")
for obj in find_obj(z, obj_n, frame_n, quality) do
print(string.format("OBJ: (%x,%x,%x)\n", obj.x, obj.y, obj.z))
party_move(obj.x, obj.y, obj.z)
print("continue? ")
input = input_select("yn", false)
print("\n")
if input == "N" or input == "n" then
return
end
end
end
local altcode_tbl = {
[242]=altcode_242_set_actor_talk_flag,
[250]=altcode_250_create_object,
[913]=altcode_913_export_tmx_map_files,
[914]=altcode_914_export_tileset,
[999]=altcode_999_find_objs_on_map,
}
function handle_alt_code(altcode)
local func = altcode_tbl[altcode]
if func ~= nil then
func()
end
end
function get_actor_or_obj_from_loc(location)
local target = map_get_actor(location)
if target == nil then
target = map_get_obj(location)
end
return target
end
--load other common functions
local lua_file = nil
lua_file = nuvie_load("common/lang.lua");
lua_file();
lang_init("game")
lua_file = nuvie_load("common/actor.lua"); lua_file();

View File

@@ -0,0 +1,348 @@
-- input value constants
MOUSE_CLICK = 0
MOUSE_MOTION = 1
SDLK_BACKSPACE = 8
SDLK_RETURN = 13
SDLK_ESCAPE = 27
SDLK_SPACE = 32
SDLK_a = 97
SDLK_b = 98
SDLK_c = 99
SDLK_g = 103
SDLK_i = 105
SDLK_j = 106
SDLK_q = 113
SDLK_r = 114
SDLK_s = 115
SDLK_t = 116
SDLK_KP2 = 258
SDLK_KP4 = 260
SDLK_KP6 = 262
SDLK_KP8 = 264
SDLK_KP_ENTER = 271
SDLK_UP = 82 + 1073741824
SDLK_DOWN = 81 + 1073741824
SDLK_RIGHT = 79 + 1073741824
SDLK_LEFT = 80 + 1073741824
function trim_string(s)
return s:match'^%s*(.*%S)' or ''
end
function wait_for_input()
local input = nil
while input == nil do
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
return input
end
local g_should_exit = false
function clear_should_exit_flag()
g_should_exit = false
end
function should_exit()
return g_should_exit
end
function poll_for_input()
input = input_poll()
if input ~= nil then
if input == SDLK_ESCAPE then
g_should_exit = true
end
end
if engine_should_quit() == 1 then
g_should_exit = true
end
return input
end
function poll_for_key_or_button(cycles)
local input
if engine_should_quit() == 1 then
g_should_exit = true
return true
end
if cycles == nil then
input = input_poll()
if input ~= nil then
if input == SDLK_ESCAPE then
g_should_exit = true
end
return true
end
else
local i
for i=0,cycles,1 do
local input = input_poll()
if input ~= nil then
if input == SDLK_ESCAPE then
g_should_exit = true
end
return true
end
if engine_should_quit() == 1 then
g_should_exit = true
return true
end
canvas_update()
end
end
return false
end
function poll_for_esc(cycles)
local input
if cycles == nil then
input = input_poll()
if input ~= nil and input == SDLK_ESCAPE then
return true
end
if engine_should_quit() == 1 then
return true
end
else
local i
for i=0,cycles,1 do
local input = input_poll()
if input ~= nil and input == SDLK_ESCAPE then
return true
end
if engine_should_quit() == 1 then
return true
end
canvas_update()
end
end
return false
end
function fade_in(speed)
if speed == nil then
speed = 3
end
local i
for i=0x0,0xff,speed do
canvas_set_opacity(i)
canvas_update()
if engine_should_quit() == 1 then
return false
end
end
return false
end
function fade_out(speed)
if speed == nil then
speed = 3
end
local i
for i=0xff,0,-speed do
canvas_set_opacity(i)
canvas_update()
if engine_should_quit() == 1 then
return false
end
end
return false
end
function update_players(players, img_tbl)
local rand = math.random
players[1].image = img_tbl[1][rand(0,12)]
players[2].image = img_tbl[2][rand(0,8)]
players[3].image = img_tbl[3][rand(0,2)]
players[4].image = img_tbl[4][rand(0,6)]
players[5].image = img_tbl[5][rand(0,4)]
players[6].image = img_tbl[6][rand(0,2)]
players[7].image = img_tbl[7][rand(0,4)]
players[8].image = img_tbl[8][rand(0,4)]
players[9].image = img_tbl[9][rand(0,3)]
end
function create_player_sprite(image, x, y)
local sprite = sprite_new(image, x, y, true)
sprite.clip_x = 0
sprite.clip_y = 0
sprite.clip_w = 320
sprite.clip_h = 152
return sprite
end
function create_sprite(image, x, y)
local sprite = sprite_new(image, x, y, true)
sprite.clip_x = 0
sprite.clip_y = 24
sprite.clip_w = 320
sprite.clip_h = 128
return sprite
end
function create_firework(img_tbl)
local rand = math.random
local colour = rand(0,2)
local exp = {create_sprite(img_tbl[11][8*colour], rand(0,319), rand(0,127)), colour, 0}
return exp
end
function fireworks_update(exp_tbl, img_tbl)
local exp_finished = 0
local k,v
for k,v in pairs(exp_tbl) do
if v[3] == 7 then
v[1].visible = false
table.remove(exp_tbl, k)
exp_finished = exp_finished + 1
else
v[3] = v[3] + 1
v[1].image = img_tbl[11][8*v[2]+v[3]]
end
end
return exp_finished
end
function fireworks(img_tbl, logo)
local rand = math.random
local exp_tbl = {}
local exp_count = 0
local i
for i=0,125 do
if exp_count < 5 then
if rand(0,5) == 0 then
local exp = create_firework(img_tbl)
table.insert(exp_tbl, exp)
exp_count = exp_count + 1
sprite_move_to_front(logo)
play_sfx(12, false)
end
end
local num_finished = fireworks_update(exp_tbl, img_tbl)
exp_count = exp_count - num_finished
poll_for_esc(1)
end
--wait for remaining explosions to finish
while exp_count > 0 do
local num_finished = fireworks_update(exp_tbl, img_tbl)
exp_count = exp_count - num_finished
poll_for_esc(1)
end
poll_for_esc(10)
-- create final 30 explosions.
for i=1,30 do
local exp = create_firework(img_tbl)
table.insert(exp_tbl, exp)
exp_count = exp_count + 1
end
while exp_count > 0 do
local num_finished = fireworks_update(exp_tbl, img_tbl)
exp_count = exp_count - num_finished
poll_for_esc(1)
end
end
function display_image_table(img_tbl, x, y)
if x == nil then
x = 160
end
if y == nil then
y = 100
end
local sprite = sprite_new(nil, x, y, true)
local text_sprite = sprite_new(nil, 100, 180, true)
local i = 0
for k,v in pairs(img_tbl) do
if type(v) == "table" then
local j = 0
for l,m in pairs(v) do
local img = image_new(50,20)
text_sprite.image = img
image_print(img, "("..k..","..l..")", 0, 50, 0, 8, 0x6)
sprite.image = m
wait_for_input()
j = j + 1
end
else
local img = image_new(50,20)
text_sprite.image = img
image_print(img, "("..k..",x)", 0, 50, 0, 8, 0x6)
sprite.image = v
wait_for_input()
end
i = i + 1
end
end
function about_martian_dreams()
canvas_hide_all_sprites()
local bg = sprite_new(image_load("mars.lzc", 0), 0, 24, true)
local text_tbl = text_load("scenetxt.lzc", 4)
music_play("mdd_mus.lzc", 8)
local sprites = {}
local i
for i=0,81 do
local s = sprite_new(nil, 11, 153 + i * 14, true)
s.text_color = 6
s.text = text_tbl[i]
table.insert(sprites, s)
s = sprite_new(nil, 12, 152 + i * 14, true)
s.text_color = 14
s.text = text_tbl[i]
table.insert(sprites, s)
end
--black bars for the top and bottom of the screen.
--These hide the text as it is scrolling in and out.
sprite_new(image_new(220, 24, 0), 0, 0, true)
sprite_new(image_new(220, 48, 0), 0, 152, true)
--scroll the text up the screen
for i=0,90*14 do
local j
for j=1,82*2 do
sprites[j].y = sprites[j].y - 1
end
poll_for_key_or_button(2)
if should_exit() then
fade_out()
return
end
end
music_stop()
fade_out()
end

View File

@@ -0,0 +1,58 @@
local lang
local lang_en
local game_type = config_get_game_type()
local lang_selected = config_get_language()
function lang_init(lang_type)
if lang_type ~= "intro" then
lang_type = "game"
end
lang_en = nuvie_load(string.lower(game_type).."/lang/en/"..lang_type..".lua")
if lang_en == nil then
lang_en = {}
else
lang_en = lang_en()
end
if lang_selected ~= "en" then
lang = nuvie_load(string.lower(game_type).."/lang/"..lang_selected.."/"..lang_type..".lua")
if lang == nil then
lang = lang_en
else
lang = lang()
end
else
lang = lang_en
end
end
function i18n(code)
local str = lang[code]
if str == nil then
str = lang_en[code]
end
if str == nil then
str = code
end
return str;
end
function i18nf(code, ...)
return string.format(i18n(code), ...)
end
function printnl(code)
print("\n"..i18n(code))
end
function printl(code)
print(i18n(code))
end
function printfl(code, ...)
print(i18nf(code, ...))
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,529 @@
-- [objectnum] = range
local range_weapon_tbl = {
[41] = 4,
[42] = 5,
[43] = 4,
[44] = 9,
[45] = 9,
[46] = 9,
[47] = 4,
[48] = 5,
[240] = 6,
[241] = 6,
[129] = 2,
[261] = 2,
[313] = 9,
[40] = 6,
[366] = 3,
[386] = 4,
[364] = 3,
[384] = 2,
}
function get_weapon_range(weapon)
local range = range_weapon_tbl[weapon.obj_n]
if range == nil then
range = 1
end
return range
end
local weapon_dmg_tbl = {
[16] = 30, --bloody saber
[40] = 1, --Cupid's bow and arrows (charms)
[41] = 15, --derringer
[42] = 18, --revolver
[43] = 20, --shotgun
[44] = 30, --rifle
[45] = 30, --Belgian combine
[46] = 45, --elephant gun
[47] = 8, --sling
[48] = 12, --bow
[49] = 15, --hatchet
[50] = 20, --axe
[51] = 10, --ball-peen hammer
[52] = 25, --sledge hammer
[54] = 10, --knife
[55] = 20, --machete
[56] = 25, --saber
[65] = 15, --pick
[66] = 8, --shovel
[67] = 10, --hoe
[68] = 10, --rake
[69] = 15, --pitchfork
[70] = 12, --cultivator
[71] = 20, --scythe
[72] = 10, --saw
[102] = 12, --pry bar
--[109] = 1, --torch
--[110] = 1, --lit torch
--[111] = 1, --candlestick
--[112] = 1, --lit candle
--[113] = 1, --candelabra
--[114] = 1, --lit andelabra
--[115] = 1, --oil lamp
--[116] = 1, --lit oil lamp
--[117] = 1, --lantern
--[118] = 1, --lit lantern
[129] = 60, --weed sprayer -- FIXME: no damage normally. Only effects plants?
--[136] = 1, --tongs
[241] = 20, --heat ray gun
[242] = 10, --freeze ray gun
--[243] = 1, --martian ritual pod knife
[261] = 60, --spray gun -- FIXME: no damage normally. Only effects plants?
[263] = 10, --martian hoe (couldn't be equipped in original)
[264] = 20, --martian scythe (couldn't be equipped in original)
[265] = 15, --martian pitchfork (couldn't be equipped in original)
[266] = 10, --martian rake (couldn't be equipped in original)
[267] = 8, --martian shovel (couldn't be equipped in original)
[313] = 254, --M60 machine gun (scripted to only attack and kill the big bad)
[327] = 15, --martian pick (couldn't be equipped in original)
[401] = 12, --pool cue
}
function get_weapon_damage(weapon)
local dmg
if weapon.luatype == "actor" then
dmg = actor_get_damage(weapon)
else
dmg = weapon_dmg_tbl[weapon.obj_n]
end
if dmg == nil then
dmg = -1
end
return dmg
end
function sub_1B432(attacker, target)
end
function actor_get_weapon(attacker, target)
local int_test = false
local selected_weapon = attacker
if not actor_has_bad_alignment(attacker) then
if math.random(1, 0x1e) <= actor_int_adj(attacker) then
int_test = true
end
end
local range = actor_get_combat_range(attacker, target.x, target.y)
for obj in actor_inventory(actor) do
if get_weapon_damage(obj) > 0 and get_weapon_range(obj) >= range then
if (obj.obj_n ~= 129 and obj.obj_n ~= 261) --OBJ_WEED_SPRAYER, OBJ_SPRAY_GUN
or (obj.quality ~= 0 and obj.invisible)
or (obj.quality == 0 and (is_plant_obj(target) or (target.luatype=="actor" and (is_actor_stat_bit_set(target.obj_n, 7) and not is_actor_stat_bit_set(target.obj_n, 14))))) then
local weapon_requires_int = false
if obj.obj_n == 240 --OBJ_HEAT_RAY_GUN
or obj.obj_n == 241 --OBJ_FREEZE_RAY_GUN
or obj.obj_n == 45 then
weapon_requires_int = true
end
--if int_test == true and weapon_requires_int == true or obj.obj_n == 43 and not sub_1B432(attacker, target) then --OBJ_SHOTGUN
end
end
end
end
function attack_dex_saving_throw(attacker, defender, weapon)
if defender == nil or defender.luatype == "obj" then
return true
end
local attacker_value
if weapon.luatype == "actor" and is_actor_stat_bit_set(weapon.obj_n, 5) then
attacker_value = actor_str_adj(attacker)
else
attacker_value = actor_dex_adj(attacker)
end
local defender_value = actor_dex_adj(defender)
if math.random(1, 30) >= math.floor((defender_value + 30 - attacker_value) / 2) then
return true
end
return false
end
function out_of_ammo(attacker, weapon, print_message) -- untested function
local weapon_obj_n = weapon.obj_n
if ((weapon_obj_n == 41 or weapon_obj_n == 42) and Actor.inv_has_obj_n(attacker, 57) == false) --derringer, revolver, pistol rounds
or (weapon_obj_n == 43 and Actor.inv_has_obj_n(attacker, 58) == false) --shotgun, shotgun shell
or (weapon_obj_n == 44 and Actor.inv_has_obj_n(attacker, 59) == false) --rifle, rifle round
or (weapon_obj_n == 45 and weapon.quality == 0 and (Actor.inv_has_obj_n(attacker, 58) == false or Actor.inv_has_obj_n(attacker, 59) == false)) --belgian combine (combine), shotgun shell, rifle round
or (weapon_obj_n == 45 and weapon.quality == 1 and Actor.inv_has_obj_n(attacker, 59) == false) --belgian combine (rifle), rifle round
or (weapon_obj_n == 45 and weapon.quality == 2 and Actor.inv_has_obj_n(attacker, 58) == false) --belgian combine (shotgun), shotgun shell
or (weapon_obj_n == 46 and Actor.inv_has_obj_n(attacker, 60) == false) --elephant gun, elephant gun round
or (weapon_obj_n == 47 and Actor.inv_has_obj_n(attacker, 63) == false) --sling, sling stone
or ((weapon_obj_n == 240 or weapon_obj_n == 241 or weapon_obj_n == 129 or weapon_obj_n == 261) and weapon.qty == 0) then --heat ray gun, freeze ray gun, weed sprayer, spray gun
if(print_message) then
printl("OUT_OF_AMMUNITION")
play_md_sfx(5)
end
return true
end
if weapon_obj_n == 48 and Actor.inv_has_obj_n(attacker, 64) == false then --bow, arrows
if(print_message) then
printl("OUT_OF_ARROWS")
play_md_sfx(5)
end
return true
end
return false
end
function attack_with_freezeray(actor, target_actor, damage)
if actor_tbl[target_actor.obj_n] ~= nil
and (is_actor_stat_bit_set(target_actor.obj_n, 14) or is_actor_stat_bit_set(target_actor.obj_n, 7)) then
target_actor.paralyzed = true
printfl("ACTOR_PARALYZED", target_actor.name)
if not is_actor_stat_bit_set(target_actor.obj_n, 7)
or is_actor_stat_bit_set(target_actor.obj_n, 14) then
hit_target(target_actor, BLUE_HIT_TILE)
else
actor_take_hit(actor, target_actor, damage, 1)
end
else
printl("IT_HAS_NO_EFFECT")
end
end
function check_ammo(actor, weapon)
local obj_n = weapon.obj_n
if obj_n == 47 and not Actor.inv_has_obj_n(actor, 63) then --OBJ_SLING, OBJ_SLING_STONE
return 1
end
if (obj_n == 41 or obj_n == 42) and not Actor.inv_has_obj_n(actor, 57) then --OBJ_DERRINGER, OBJ_REVOLVER, OBJ_PISTOL_ROUND
return 1
end
if obj_n == 46 and not Actor.inv_has_obj_n(actor, 60) then --OBJ_ELEPHANT_GUN, OBJ_ELEPHANT_GUN_ROUND
return 1
end
if obj_n == 44 and not Actor.inv_has_obj_n(actor, 59) then --OBJ_RIFLE, OBJ_RIFLE_ROUND
return 1
end
if obj_n == 43 and not Actor.inv_has_obj_n(actor, 58) then --OBJ_SHOTGUN, OBJ_SHOTGUN_SHELL
return 1
end
if (obj_n == 129 or obj_n == 261) and weapon.qty ~= 0 then --OBJ_WEED_SPRAYER, OBJ_SPRAY_GUN
return 1
end
return 0
end
function attack_target_with_weapon(actor, target_x, target_y, weapon)
local target_range = actor_get_combat_range(actor, target_x, target_y)
local weapon_range = get_weapon_range(weapon)
if target_range > weapon_range then
return 2 --out of range
end
local ret = check_ammo(actor, weapon)
if ret ~= 0 then
return ret
end
local obj_n = weapon.obj_n
local var_10 = 0
local var_12 = 0
--OBJ_HEAT_RAY_GUN
--OBJ_FREEZE_RAY_GUN
--OBJ_BELGIAN_COMBINE
if obj_n == 240 or obj_n == 241 or obj_n == 45 then
if weapon.quality < 2 then
var_10= 1
end
if weapon.quality ~= 1 then
var_12 = 1
end
if obj_n == 45 then --OBJ_BELGIAN_COMBINE
if var_10 ~= 0 then
if not Actor.inv_has_obj_n(actor, 59) then --OBJ_RIFLE_ROUND
var_10 = 0
end
end
if var_12 ~= 0 then
if not Actor.inv_has_obj_n(actor, 58) then --OBJ_SHOTGUN_SHELL
var_12 = 0
end
end
else
if weapon.qty == 0 then
return 1
end
if weapon.qty < (var_12 * 4) + var_10 then
var_12 = 0
end
end
if var_10 == 0 and var_12 == 0 then
return 1
end
else
if obj_n == 43 then --OBJ_SHOTGUN
var_10 = 0
var_12 = 1
else
var_10 = 1
var_12 = 0
end
end
local damage_mode = 0
if obj_n == 240 then --OBJ_HEAT_RAY_GUN
damage_mode = 3
end
if obj_n == 241 then --OBJ_FREEZE_RAY_GUN
damage_mode = 1
end
g_attack_target = g_selected_obj
if var_10 == 0 then
spread_weapon_damage(actor, target_x, target_y, weapon)
return 0
end
local is_ranged_attack = false
if target_range > 1 then
is_ranged_attack = true
end
if (obj_n >= 40 and obj_n <= 48) --OBJ_CUPIDS_BOW_AND_ARROWS, OBJ_BOW
or obj_n == 129 --OBJ_WEED_SPRAYER
or obj_n == 261 --OBJ_SPRAY_GUN
or obj_n == 240 --OBJ_HEAT_RAY_GUN
or obj_n == 241 --OBJ_FREEZE_RAY_GUN
then
is_ranged_attack = true
end
local damage
if weapon.luatype == "actor" then
damage = actor_get_damage(actor)
if damage == nil then
damage = 1
end
else
damage = get_weapon_damage(weapon)
if damage < 0 then
damage = 1
end
end
local does_damage
local target = find_rockworm_actor(g_attack_target)
if target ~= nil
and target.luatype == "actor"
and obj_n ~= 129 --OBJ_WEED_SPRAYER
and obj_n ~= 261 then --OBJ_SPRAY_GUN
does_damage = attack_dex_saving_throw(actor, target, weapon)
end
if is_ranged_attack then
fire_range_based_weapon(actor, target_x, target_y, weapon)
end
target = find_rockworm_actor(g_attack_target)
if not is_ranged_attack and map_is_on_screen(actor.xyz) then
play_md_sfx(0)
end
if does_damage == nil then
does_damage = true
if target ~= nil
and target.luatype == "actor"
and obj_n ~= 129 --OBJ_WEED_SPRAYER
and obj_n ~= 261 then --OBJ_SPRAY_GUN
does_damage = attack_dex_saving_throw(actor, target, weapon)
end
end
if not does_damage then
play_md_sfx(3)
end
if does_damage
and target ~= nil
and (target.luatype == "obj" or target.actor_num ~= actor.actor_num) then
if obj_n == 241 then --OBJ_FREEZE_RAY_GUN
if target.obj_n == 160 and target.frame_n == 1 then
printl("THE_WATER_FREEZES")
target.frame_n = 2
else
if target.luatype == "actor" then
attack_with_freezeray(actor, target, damage)
end
end
elseif obj_n == 129 or obj_n == 261 then --OBJ_WEED_SPRAYER, OBJ_SPRAY_GUN
if weapon.quality ~= 0 then
if target.luatype == "actor" and target.obj_n == 145 then --OBJ_MONSTER_FOOTPRINTS
target.obj_n = 364 --OBJ_PROTO_MARTIAN
printfl("BECOMES_VISIBLE", target.name)
elseif target.luatype == "obj" and target.invisible then
target.invisible = false
printfl("BECOMES_VISIBLE", target.name)
else
printl("IT_HAS_NO_EFFECT")
end
else
if actor_tbl[target.obj_n] ~= nil
and not is_actor_stat_bit_set(target.obj_n, 14)
and is_actor_stat_bit_set(target.obj_n, 7) then
actor_take_hit(actor, target, damage, 2)
else
printl("IT_HAS_NO_EFFECT")
end
end
elseif obj_n == 40 then --OBJ_CUPIDS_BOW_AND_ARROWS
if target.luatype == "actor" and target.align ~= ALIGNMENT_GOOD then
target.old_align = target.align
target.align = ALIGNMENT_GOOD
target.charmed = true
printfl("ACTOR_CHARMED", target.name)
end
else
actor_take_hit(actor, target, damage, damage_mode)
end
end
if var_12 ~= 0 then
spread_weapon_damage(actor, target_x, target_y, weapon)
end
return 0
end
local spread_weapon_sfx_tbl = {
[0x2b]=8,
[0x2d]=8,
[0xf0]=0xa,
[0xf1]=0xa,
}
local spread_weapon_tile_num_tbl = {
[0x2b]=0x106,
[0x2d]=0x106,
[0xf0]=0x14e,
[0xf1]=0x14f,
}
local spread_weapon_damage_tbl = {
[0x2b]=0x14,
[0x2d]=0x14,
[0xf0]=0x19,
[0xf1]=0xa,
}
function spread_weapon_damage(actor, target_x, target_y, weapon)
if spread_weapon_sfx_tbl[weapon.obj_n] ~= nil then
play_md_sfx(spread_weapon_sfx_tbl[weapon.obj_n])
end
--FIXME spread weapon anim here.
local hit_items = projectile_anim_multi (spread_weapon_tile_num_tbl[weapon.obj_n], actor.x, actor.y, {{x=target_x, y=target_y, z=actor.z}, {x=target_x+1, y=target_y-1, z=actor.z}}, 2, 1, 0)
local k, v
for k,v in pairs(hit_items) do
if weapon.obj_n == 241 then --OBJ_FREEZE_RAY_GUN
if v.obj_n == 160 and v.frame_n == 1 then --OBJ_EMPTY_BUCKET
printl("THE_WATER_FREEZES")
v.frame_n = 2
elseif v.luatype == "actor" then
if math.random(1, 0x2d) > actor_dex_adj(v) then
attack_with_freezeray(actor, v, 10)
else
printfl("ACTOR_DODGES", v.name)
play_md_sfx(3)
end
end
elseif v.luatype == "obj" or math.random(1, 0x2d) > actor_dex_adj(v) then
local dmg_mode = 0
if weapon.obj_n == 240 then --OBJ_HEAT_RAY_GUN
dmg_mode = 3
end
actor_take_hit(actor, v, spread_weapon_damage_tbl[weapon.obj_n], dmg_mode)
else
printfl("ACTOR_DODGES", v.name)
play_md_sfx(3)
end
end
if weapon.obj_n == 43 or weapon.obj_n == 45 then --OBJ_SHOTGUN, OBJ_BELGIAN_COMBINE
Actor.inv_remove_obj_qty(actor, 58, 1) --OBJ_SHOTGUN_SHELL
else
weapon.qty = weapon.qty - 4
if weapon.qty < 0 then
weapon.qty = 0
end
end
end
local projectile_tbl = {
[41]={tile_num=0x103, sfx_id=7, ammo_obj_n=57},
[42]={tile_num=0x103, sfx_id=7, ammo_obj_n=57},
[44]={tile_num=0x103, sfx_id=8, ammo_obj_n=59},
[45]={tile_num=0x103, sfx_id=8, ammo_obj_n=59},
[46]={tile_num=0x103, sfx_id=8, ammo_obj_n=60},
[47]={tile_num=0x23E, sfx_id=6, ammo_obj_n=63},
[48]={tile_num=0x23F, sfx_id=6, ammo_obj_n=64},
[40]={tile_num=0x23F, sfx_id=6, ammo_obj_n=-3},
[240]={tile_num=0x16B, sfx_id=10, ammo_obj_n=-2},
[241]={tile_num=0x16A, sfx_id=10, ammo_obj_n=-2},
[129]={tile_num=0x10A, sfx_id=6, ammo_obj_n=-2},
[261]={tile_num=0x10A, sfx_id=6, ammo_obj_n=-2},
[313]={tile_num=0x10B, sfx_id=50, ammo_obj_n=-3},
[366]={tile_num=0x16F, sfx_id=34, ammo_obj_n=-3},
[386]={tile_num=0x16C, sfx_id=34, ammo_obj_n=-3},
[364]={tile_num=0x16D, sfx_id=6, ammo_obj_n=-3},
[384]={tile_num=0x16E, sfx_id=6, ammo_obj_n=-3},
}
function fire_range_based_weapon(attacker, target_x, target_y, weapon)
local projectile_info = projectile_tbl[weapon.obj_n]
if projectile_info == nil then
projectile_info = {tile_num=weapon.tile_num, sfx_id=0, ammo_obj_n=-1 }
end
play_md_sfx(projectile_info.sfx_id)
projectile_anim(projectile_info.tile_num, attacker.x, attacker.y, target_x, target_y, 4, false, 0)
if projectile_info.ammo_obj_n > 0 then
Actor.inv_remove_obj_qty(attacker, projectile_info.ammo_obj_n, 1)
elseif projectile_info.ammo_obj_n == -2 then
weapon.qty = weapon.qty - 1
elseif projectile_info.ammo_obj_n == -1 and actor_get_combat_range(attacker, target_x, target_y) > 1 then
if is_open_water_at_loc(target_x, target_y, attacker.z) then
Obj.removeFromEngine(weapon)
else
Obj.moveToMap(weapon, target_x, target_y, attacker.z)
end
--FIXME original updated readied weapons here. We might also need to do that.
end
end

View File

@@ -0,0 +1,292 @@
function finish_dream_quest(actor)
local schedule = Actor.get_schedule(actor, 0)
Actor.move(actor, schedule.x, schedule.y, schedule.z)
local obj = map_get_obj(schedule.x, schedule.y, schedule.z, 461) --OBJ_DREAM_TELEPORTER
Obj.removeFromEngine(obj)
obj = map_get_obj(schedule.x, schedule.y-1, schedule.z, 292) --OBJ_OBELISK
Obj.removeFromEngine(obj)
Actor.set_talk_flag(actor, 7)
if Actor.get_talk_flag(0x56, 7)
and Actor.get_talk_flag(0x54, 7)
and Actor.get_talk_flag(0x52, 7)
and Actor.get_talk_flag(0x55, 7) then
Actor.set_talk_flag(0x60, 4)
end
if Actor.get_talk_flag(0x50, 7)
and Actor.get_talk_flag(0x51, 7)
and Actor.get_talk_flag(0x52, 7)
and Actor.get_talk_flag(0x53, 7)
and Actor.get_talk_flag(0x54, 7)
and Actor.get_talk_flag(0x55, 7)
and Actor.get_talk_flag(0x56, 7)
and Actor.get_talk_flag(0x57, 7) then
Actor.set_talk_flag(0x20, 4)
end
end
function wake_from_dream()
--FIXME dreamworld_cleanup_state() The original calls this with actor zero as an argument.
g_objlist_1d22_unk = 0
local minutes = 60 - clock_get_minute()
local current_hour = clock_get_hour()
current_hour = current_hour + 1
if current_hour >= 8 then
minutes = minutes + (24 - current_hour + 8) * 60
else
minutes = minutes + (8 - current_hour) * 60
end
clock_inc(minutes)
--FIXME reset walk_direction_modifier
for actor in party_members() do
actor_clear_berry_counters(actor.actor_num)
if actor.poisoned then
if actor.hp <= 30 then
if actor.hp <= 10 then
actor.hp = 1
else
actor.hp = math.random(1, 10)
end
else
actor.hp = math.random(24, 30)
end
end
end
local dream_actor = Actor.get(0)
party_set_in_vehicle(false)
dream_actor.visible = false
party_show_all()
party_update_leader()
party_set_combat_mode(false)
g_in_dream_mode = false
map_enable_temp_actor_cleaning(true)
printl("YOU_WAKE_UP")
unlock_inventory_view()
--remove dream actor's inventory
for obj in actor_inventory(dream_actor, true) do
Obj.removeFromEngine(obj)
end
local avatar = Actor.get(1)
avatar.mpts = avatar.dex
avatar.wt = WT_PLAYER
end
function actor_use_dream_machine(actor, dream_quality)
if actor.actor_num ~= 1 then
--FIXME advance time till dawn.
printfl("ACTOR_DREAMS_UNTIL_DAWN_WHILE_THE_PARTY_WAITS", actor.name)
actor.asleep = true
g_party_is_warm = true
advance_time(60 - clock_get_minute())
while clock_get_hour() ~= 8 do
advance_time(20)
script_wait(100)
end
g_party_is_warm = false
else
play_midgame_sequence(4)
party_set_party_mode()
local dream_actor = Actor.get(0)
local dream_x, dream_y
if dream_quality == 1 then
dream_x, dream_y = 0x64, 0x3b
else
dream_x, dream_y = 0x93, 0x34
end
--FIXME need to copy over more data from avatar actor.
dream_actor.obj_n = actor.obj_n
dream_actor.frame_n = actor.frame_n
dream_actor.base_obj_n = actor.base_obj_n
dream_actor.wt = WT_PLAYER
dream_actor.visible = true
dream_actor.hp = actor.max_hp
Actor.move(dream_actor, dream_x, dream_y, 2)
player_set_actor(dream_actor)
party_set_in_vehicle(true)
party_hide_all()
g_in_dream_mode = true
map_enable_temp_actor_cleaning(false)
g_prev_player_x = 0
g_prev_player_y = 0
g_current_dream_stage = 0
lock_inventory_view(Actor.get(0))
end
end
function cleanup_cliff_fall()
local dream_actor = Actor.get(0)
local avatar = Actor.get(1)
dream_actor.obj_n = avatar.base_obj_n
dream_actor.frame_n = 9
end
local dreamworld_cleanup_tbl = {
[5]=function() end,
[0x20]=function() end,
[0x40]=cleanup_cliff_fall,
[0x44]=function() end,
[0xa0]=function() end,
}
function fall_from_cliff()
printl("YOU_FALL_OFF_THE_CLIFF")
local dream_actor = Actor.get(0)
if player_get_gender() == 0 then
dream_actor.obj_n = 0x126
else
dream_actor.obj_n = 0x127
end
dream_actor.frame_n = 0
for y=dream_actor.y-8,dream_actor.y do
local actor = map_get_actor(dream_actor.x, y, dream_actor.z)
if actor ~= nil and actor.obj_n == 391 then --OBJ_YOUR_MOTHER
Actor.kill(actor, false)
end
end
end
local dreamworld_unk_tbl = {
[0x4]=function() end,
[0x40]=fall_from_cliff,
[0x85]=function() end,
[0xA1]=function() end,
[0xA4]=function() end,
[0xC0]=function() end,
[0xC1]=function() end,
[0xC4]=function() end,
[0xC5]=function() end,
[0xE0]=function() end,
}
function spawn_your_mother()
local player_loc = player_get_location()
local mother = Actor.new(391, player_loc.x, player_loc.y-1,player_loc.z)
actor_init(mother)
mother.wt = 0x15
mother.combat_mode = 0x15
mother.visible = true
Actor.move(mother, player_loc.x, player_loc.y-1,player_loc.z)
end
function create_pitcher(x, y, z)
local obj = Obj.new(217, math.floor(math.random(0, 5) / 2))
obj.qty = 3
Obj.moveToMap(obj, x, y, z)
end
function setup_tiffany_stage()
local tiffany = Actor.get(0x54)
Actor.clear_talk_flag(tiffany, 0)
Actor.clear_talk_flag(tiffany, 6)
local player_loc = player_get_location()
local z = player_loc.z
for obj in find_obj_from_area(0x21, 0x33, z, 0x1c, 0x10) do
local obj_n = obj.obj_n
--OBJ_RED_THROW_RUG, OBJ_RED_CAPE, OBJ_GLASS_PITCHER, OBJ_BROKEN_CRYSTAL, OBJ_MINOTAUR
if obj_n == 161 or obj_n == 162 or obj_n == 217 or obj_n == 218 or obj_n == 398 then
Obj.removeFromEngine(obj)
end
end
local rug = Obj.new(161) --OBJ_RED_THROW_RUG
Obj.moveToMap(rug, 0x24, 0x36, z)
for i=57,65 do
if i ~= 0x3e then
create_pitcher(0x37, i, z)
end
if i > 0x3a and i ~= 0x40 then
create_pitcher(0x39, i, z)
end
create_pitcher(0x3b, i, z)
end
create_pitcher(0x38, 0x39, z)
create_pitcher(0x38, 0x41, z)
create_pitcher(0x3a, 0x39, z)
create_pitcher(0x3a, 0x41, z)
local minotaur = Actor.new(398, 0x3b, 0x41, z)
actor_init(minotaur)
Actor.move(minotaur, 0x3b, 0x41, z)
minotaur.wt = 0x16
end
function complete_tiffany_stage()
local tiffany = Actor.get(0x54)
finish_dream_quest(tiffany)
Actor.set_talk_flag(tiffany, 1)
Actor.talk(tiffany)
wake_from_dream()
end
local dreamworld_init_tbl = {
[0x5]=function() end,
[0x20]=function() end,
[0x25]=spawn_your_mother,
[0x44]=setup_tiffany_stage,
[0x60]=function() end,
[0xA5]=function() end,
[0xC0]=function() end,
[0xC4]=function() end,
[0xC5]=function() end,
}
function dreamworld_cleanup_state(obj)
local dream_actor = Actor.get(0)
local new_stage = bit32.band(obj.status, 0xe5)
if g_current_dream_stage ~= 0 and new_stage ~= 0xa5 and new_stage ~= 0xe5 then
if dreamworld_cleanup_tbl[g_current_dream_stage] ~= nil then
dreamworld_cleanup_tbl[g_current_dream_stage]()
end
end
-- print("new stage="..new_stage.."\n")
if new_stage == 1 then
g_current_dream_stage = 0
return
elseif new_stage == 0x24 then
wake_from_dream()
return
elseif g_current_dream_stage ~= 0 and dreamworld_unk_tbl[new_stage] ~= nil then
dreamworld_unk_tbl[new_stage]()
end
if new_stage ~= 0xa5 then
--FIXME clean up temp objects
g_objlist_1d22_unk = 0
end
actor_clear_berry_counters(dream_actor.actor_num)
local player_loc = player_get_location()
player_move(obj.quality, obj.qty, player_loc.z)
if new_stage == 0xe5 then
if not Actor.get_talk_flag(0x66, 3) then
g_objlist_1d22_unk = 6
end
else
if dreamworld_init_tbl[new_stage] ~= nil then
dreamworld_init_tbl[new_stage]()
end
g_current_dream_stage = new_stage
end
end

View File

@@ -0,0 +1,220 @@
local lua_file = nil
--load common functions
lua_file = nuvie_load("common/intro_common.lua"); lua_file();
function play()
local gender = player_get_gender()
local g_img_tbl = image_load_all("endgame.lzc")
local text_tbl = text_load("scenetxt.lzc", 3)
local text = sprite_new(nil, 0, 160, true)
text.text_color = 4
text.text = text_tbl[0]
text.text_align = 2
local bg = sprite_new(g_img_tbl[0][0], 0, 24, true)
local jack = sprite_new(g_img_tbl[0][gender+1], 155, 151, true)
canvas_set_palette("md_title.pal", 0)
canvas_set_opacity(0xff);
mouse_cursor_visible(false)
canvas_set_update_interval(25)
music_play("mdd_mus.lzc", 11)
fade_in()
poll_for_key_or_button(150)
if should_exit() then return end
text.text = text_tbl[1]
poll_for_key_or_button(150)
if should_exit() then return end
--space capsule rockets away from mars
jack.visible = false
text.text = text_tbl[2]
bg.image = g_img_tbl[1][0]
local capsule = create_sprite(g_img_tbl[1][1], 105, 112)
capsule.visible = false
local smoke = sprite_new(g_img_tbl[1][2], 105, 112, false)
local i
for i=-1,39 do
bg.y = 23 + ((i + 3) % 4)
bg.x = ((i + 2) % 5) - 2
if i > -1 and i < 13 then
capsule.visible = true
capsule.x = 105 + (i * i * 2) / 3
capsule.y = 112 - i * i
capsule.image.scale = (i * i) + 16
smoke.image = g_img_tbl[1][2 + math.floor(i/2)]
smoke.visible = true
else
capsule.visible = false
smoke.visible = false
end
poll_for_key_or_button(3)
if should_exit() then return end
end
--capsule lands in the ocean.
bg.image = g_img_tbl[2][0]
bg.x = 0
bg.y = 24
capsule.visible = true
capsule.x = 170
capsule.y = 150
text.text = text_tbl[3]
for i=0,9 do
local j
for j=0,3 do
capsule.image = g_img_tbl[2][math.abs(2 - j) + 1]
if i == 5 then
text.text = text_tbl[4]
end
poll_for_key_or_button(8)
if should_exit() then return end
end
end
--ticket tape parade
canvas_set_opacity(0);
capsule.visible = false
bg.image = g_img_tbl[3][0]
local spector = sprite_new(g_img_tbl[3][gender+1], 190, 151, true)
text.text = text_tbl[5]
fade_in(6)
poll_for_key_or_button(150)
if should_exit() then return end
--group photo.
canvas_set_opacity(0);
spector.visible = false
bg.image = g_img_tbl[4][0]
local moongate_tbl = image_load_all("moongate.lzc")
local moongate = sprite_new(moongate_tbl[1][0], 35, 135, true)
local group = sprite_new(g_img_tbl[4][gender+1], 195, 151, true)
local photographer = sprite_new(g_img_tbl[4][3], 75, 151, true)
text.text = text_tbl[6]
fade_in(6)
for i=0,79 do
if i == 40 then
moongate.visible = false
group.visible = false
photographer.visible = false
bg.image = g_img_tbl[4][5]
poll_for_key_or_button(2)
fade_out(6)
bg.image = g_img_tbl[4][0]
moongate.visible = true
group.visible = true
photographer.visible = true
canvas_set_opacity(0xff);
else
moongate.image = moongate_tbl[1][i % 8]
if i >= 38 and i <= 42 then
photographer.image = g_img_tbl[4][4]
else
photographer.image = g_img_tbl[4][3]
end
if i == 41 then
text.text = text_tbl[7]
end
poll_for_key_or_button(3)
if should_exit() then return end
end
end
--mars dust storm
moongate.visible = false
group.visible = false
photographer.visible = false
bg.image = g_img_tbl[5]
local sand = sprite_new(nil, 240, 140, true)
local tree = sprite_new(nil, 0, 140, true)
local dust = create_sprite(g_img_tbl[6], 0, 24)
local dust1 = create_sprite(g_img_tbl[6], 0, 24)
local dust2 = create_sprite(g_img_tbl[6], 0, 24)
local dust3 = create_sprite(g_img_tbl[6], 0, 24)
local dust4 = create_sprite(g_img_tbl[6], 0, 24)
dust.visible = true
dust1.visible = true
dust2.visible = true
dust3.visible = true
dust4.visible = true
text.text = text_tbl[8]
for i=0,63 do
if math.floor(i / 8) > 4 then
sand.image = g_img_tbl[7][4]
else
sand.image = g_img_tbl[7][math.floor(i / 8)]
end
if i < 56 then
if i - 50 < 0 then
tree.image = g_img_tbl[8][0]
else
tree.image = g_img_tbl[8][i - 50]
end
else
tree.visible = false
end
dust.x = 340 - (i * 10) - math.random(0, 19)
dust.y = 24 - math.random(0, 9)
dust1.x = 420 - (i * 20) - math.random(0, 19)
dust1.y = 24 - math.random(0, 9)
dust2.x = 500 - (i * 30) - math.random(0, 19)
dust2.y = 24 - math.random(0, 9)
dust3.x = 580 - (i * 30) - math.random(0, 19)
dust3.y = 24 - math.random(0, 9)
dust4.x = 660 - (i * 20) - math.random(0, 19)
dust4.y = 24 - math.random(0, 9)
if i == 62 then
text.text = text_tbl[9]
end
poll_for_key_or_button(2)
if should_exit() then return end
end
poll_for_key_or_button(150)
if should_exit() then return end
about_martian_dreams()
end
play()

View File

@@ -0,0 +1,440 @@
local lua_file = nil
--load common functions
lua_file = nuvie_load("common/common.lua"); lua_file();
OBJLIST_OFFSET_HOURS_TILL_NEXT_HEALING = 0x1cf2
OBJLIST_OFFSET_PREV_PLAYER_X = 0x1d03
OBJLIST_OFFSET_PREV_PLAYER_Y = 0x1d04
OBJLIST_OFFSET_1D22_UNK = 0x1d22
OBJLIST_OFFSET_DREAM_MODE_FLAG = 0x1d29
OBJLIST_OFFSET_BERRY_COUNTERS = 0x1d2f
OBJLIST_OFFSET_DREAM_STAGE = 0x1d53
function dbg(msg_string)
--io.stderr:write(msg_string)
end
g_hours_till_next_healing = 0
g_in_dream_mode = false
local g_selected_obj
local g_attack_target
function update_watch_tile()
local anim_index = get_anim_index_for_tile(616) --616 = watch tile
if anim_index ~= nil then
local new_watch_tile = 416 + clock_get_hour() % 12
anim_set_first_frame(anim_index, new_watch_tile)
end
end
function load_game()
g_selected_obj = nil
g_attack_target = nil
objlist_seek(OBJLIST_OFFSET_HOURS_TILL_NEXT_HEALING)
g_hours_till_next_healing = objlist_read1()
objlist_seek(OBJLIST_OFFSET_DREAM_MODE_FLAG)
g_in_dream_mode = bit32.btest(objlist_read2(), 0x10)
map_enable_temp_actor_cleaning(not g_in_dream_mode)
if g_in_dream_mode then
lock_inventory_view(Actor.get(0))
end
objlist_seek(OBJLIST_OFFSET_DREAM_STAGE)
g_current_dream_stage = objlist_read2()
objlist_seek(OBJLIST_OFFSET_PREV_PLAYER_X)
g_prev_player_x = objlist_read1()
objlist_seek(OBJLIST_OFFSET_PREV_PLAYER_Y)
g_prev_player_y = objlist_read1()
objlist_seek(OBJLIST_OFFSET_1D22_UNK)
g_objlist_1d22_unk = objlist_read1()
update_watch_tile()
end
function save_game()
objlist_seek(OBJLIST_OFFSET_HOURS_TILL_NEXT_HEALING)
objlist_write1(g_hours_till_next_healing)
objlist_seek(OBJLIST_OFFSET_DREAM_MODE_FLAG)
local bytes = objlist_read2()
if g_in_dream_mode then
bytes = bit32.bor(bytes, 0x10)
else
bytes = bit32.band(bytes, 0xFFEF)
end
objlist_seek(OBJLIST_OFFSET_DREAM_MODE_FLAG)
objlist_write2(bytes)
objlist_seek(OBJLIST_OFFSET_DREAM_STAGE)
objlist_write2(g_current_dream_stage)
objlist_seek(OBJLIST_OFFSET_PREV_PLAYER_X)
objlist_write1(g_prev_player_x)
objlist_seek(OBJLIST_OFFSET_PREV_PLAYER_Y)
objlist_write1(g_prev_player_y)
objlist_seek(OBJLIST_OFFSET_1D22_UNK)
objlist_write1(g_objlist_1d22_unk)
end
local g_container_obj_tbl = {
[80]=1, [81]=1, [82]=1,
[83]=1, [85]=1, [86]=1,
[87]=1, [89]=1,[304]=1,
[139]=1,[341]=1,[257]=1,
[104]=1,[284]=1,[285]=1
}
function is_blood(obj_num)
if obj_num == 334 or obj_num == 335 or obj_num == 336 then --OBJ_BLOOD, OBJ_ICHOR, OBJ_SAP
return true
end
return false
end
function is_container_obj(obj_num)
if g_container_obj_tbl[obj_num] ~= nil then
return true
end
return false
end
--OBJ_CLOSED_DOOR, OBJ_GLOW_WORM, OBJ_DEVIL_POD, OBJ_DEVIL_PLANT, OBJ_GLASS_PITCHER
local attackable_obj_tbl = {
[0xB3]=1,
[0x184]=1,
[0x133]=1,
[0x12C]=1,
[0xD9]=1,
}
function is_obj_attackable(obj)
return attackable_obj_tbl[obj.obj_n] ~= nil
end
--OBJ_VINE, OBJ_TREE, OBJ_PORCUPOD, OBJ_FLOWER, OBJ_HARD_SHELLED_PLANT
--OBJ_DEVIL_PLANT, OBJ_DEVIL_POD, OBJ_HEDGE
local plant_obj_tbl = {
[0xCD]=1,
[0x198]=1,
[0xA8]=1,
[0xAA]=1,
[0xAB]=1,
[0x12C]=1,
[0x133]=1,
[0x12B]=1,
}
function is_plant_obj(obj)
return plant_obj_tbl[obj.obj_n] ~= nil
end
--OBJ_DOLLAR, OBJ_RUBLE, OBJ_PHOTOGRAPH, OBJ_THREAD, OBJ_BOX_OF_CIGARS
--OBJ_MATCH, OBJ_BOOK, OBJ_MAP, OBJ_NOTE, OBJ_WORMSBANE_SEED
--OBJ_SCROLL, OBJ_LIVE_MARTIAN_SEED, OBJ_PILE_OF_COAL
--OBJ_HUGE_LUMP_OF_COAL, OBJ_CHUNK_OF_ICE
local burnable_obj_tbl = {
[0x18]=1,
[0x84]=1,
[0x0B9]=1,
[0x3E]=1,
[0x65]=1,
[0x6B]=1,
[0x94]=1,
[0x96]=1,
[0x97]=1,
[0x9E]=1,
[0x0F3]=1,
[0x0FC]=1,
[0x1BC]=1,
[0x1BF]=1,
[0x100]=1,
}
function is_obj_burnable(obj)
return burnable_obj_tbl[obj.obj_n] ~= nil
end
function is_open_water_at_loc(x, y, z)
local tile_num = map_get_tile_num(x, y, z)
local is_water = tile_get_flag(tile_num, 1, 0)
if not is_water then
return false
end
if not tile_get_flag(tile_num, 1, 1) then -- not blocked
return false
end
for obj in objs_at_loc(location) do
tile_num = obj.tile_num
--FIXME original does this too
-- sub ax, word_40FA2
if tile_get_flag(tile_num, 3, 1) or tile_get_flag(tile_num, 3, 2) then --SUPPORT_OBJECT or FORCE_PASSABLE
return false
end
end
return true
end
function search(obj)
if obj.on_map == false then
return
end
local found_obj = false
local child
local first_loop = true
local prev_obj = nil
for child in container_objs(obj) do
if prev_obj ~= nil then
printfl("SEARCH_NEXT_OBJ", prev_obj.look_string)
Obj.moveToMap(prev_obj, obj.x, obj.y, obj.z)
end
if first_loop == true then
found_obj = true
printfl("SEARCHING_HERE_YOU_FIND", child.look_string)
Obj.moveToMap(child, obj.x, obj.y, obj.z)
else
prev_obj = child
end
script_wait(50)
first_loop = false
end
if prev_obj ~= nil then
printfl("SEARCH_LAST_OBJ", prev_obj.look_string)
Obj.moveToMap(prev_obj, obj.x, obj.y, obj.z)
end
if found_obj == false then
printl("SEARCHING_HERE_YOU_FIND_NOTHING")
else
print(".\n")
end
end
--tile_num, readied location
local g_readiable_objs_tbl = {
-- 0 = head
[512] = 0, --cap
[513] = 0, --cowboy hat
[514] = 0, --pith hat
[515] = 0, --military hat
[516] = 0, --derby
-- 1 = neck
[517] = 1, --kerchief
[518] = 1, --silk scarf
[519] = 1, --muffler
[1048] = 1, --martian jewelry
[1049] = 1, --martian jewelry
[1050] = 1, --martian jewelry
[1051] = 1, --martian jewelry
[1052] = 1, --martian jewelry
[1053] = 1, --martian jewelry
[1054] = 1, --martian jewelry
[1055] = 1, --martian jewelry
-- 3 = 1 handed
[527] = 3, --bloody saber
[552] = 3, --derringer
[553] = 3, --revolver
[560] = 3, --hatchet
[561] = 3, --axe
[562] = 3, --ball-peen hammer
[565] = 3, --knife
[566] = 3, --machete
[567] = 3, --saber
[622] = 3, --pry bar
[650] = 3, --weed sprayer
[667] = 3, --tongs
[1068] = 3, --martian ritual pod knife
-- 2 = torso
[528] = 2, --cloth jacket
[529] = 2, --wool sweater
[530] = 2, --cape
[531] = 2, --duster
[532] = 2, --wool overcoat
[533] = 2, --sheepskin jacket
[534] = 2, --arctic parka
[608] = 2, --electric belt
-- 3 = shield hand
[630] = 3, --torch
[631] = 3, --lit torch
[632] = 3, --candlestick
[633] = 3, --lit candlestick
[634] = 3, --candelabra
[635] = 3, --lit candelabra
[636] = 3, --oil lamp
[637] = 3, --lit oil lamp
[638] = 3, --lantern
[639] = 3, --lit lantern
-- 6 = UNK pants or dress FIXME: putting this here for now
[536] = 6, --cotton pants
[537] = 6, --cotton dress
[538] = 6, --denim jeans
[539] = 6, --wool pants
[540] = 6, --wool dress
[541] = 6, --chaps and jeans
-- 7 = feet
[520] = 7, --man's shoes
[521] = 7, --woman's shoes
[522] = 7, --riding boots
[523] = 7, --ruby slippers
[524] = 7, --thigh boots
[525] = 7, --hip boots
[526] = 7, --winged shoes
[542] = 7, --man's shoes
-- 4 = two handed
[551] = 4, --Cupid's bow and arrows
[554] = 4, --shotgun
[555] = 4, --rifle
[556] = 4, --Belgian combine
[557] = 4, --elephant gun
[558] = 4, --sling
[559] = 4, --bow
[563] = 4, --sledge hammer
[576] = 4, --pick
[577] = 4, --shovel
[578] = 4, --hoe
[579] = 4, --rake
[580] = 4, --pitchfork
[581] = 4, --cultivator
[582] = 4, --scythe
[583] = 4, --saw
[717] = 4, --throw rug
[718] = 4, --red cape
[1066] = 4, --heat ray gun
[1067] = 4, --freeze ray gun
[1093] = 4, --spray gun
[1095] = 4, --martian hoe (couldn't be equipped in original)
[1096] = 4, --martian scythe (couldn't be equipped in original)
[1097] = 4, --martian pitchfork (couldn't be equipped in original)
[1098] = 4, --martian rake (couldn't be equipped in original)
[1099] = 4, --martian shovel (couldn't be equipped in original)
[1188] = 4, --M60 machine gun
[1206] = 4, --martian pick (couldn't be equipped in original)
[1897] = 4, --pool cue
-- 5 = finger gloves and bracelets FIXME: putting this here for now
[544] = 5, --lady's silk gloves
[545] = 5, --driving gloves
[546] = 5, --cotton work gloves
[547] = 5, --work gloves
[548] = 5, --wool mittens
[549] = 5, --rubber gloves
[550] = 5 --welding gloves
}
function wrap_coord(coord, level)
local map_stride = 1024
if level ~= 0 then
map_stride = 256
end
if coord < 0 then
return map_stride + coord
end
return coord % map_stride
end
function can_move_obj(obj, rel_x, rel_y)
local z = obj.z
return map_can_put_obj(wrap_coord(obj.x+rel_x,z), wrap_coord(obj.y+rel_y,z), z)
end
function obj_get_readiable_location(obj)
if g_readiable_objs_tbl[obj.tile_num] ~= nil then
return g_readiable_objs_tbl[obj.tile_num]
end
return -1
end
function update_lamp_posts()
--Turn lamps on/off if we have power and it is dark.
local frame_n = 3
local hour = clock_get_hour()
if Actor.get_talk_flag(0x73, 4) and (hour < 6 or hour > 17) then
frame_n = 7
end
local loc = player_get_location()
for obj in find_obj(loc.z, 228) do --OBJ_LAMP_POST
if obj ~= nil then
obj.frame_n = frame_n
end
end
end
local PLAY_ASYNC = true
function play_md_sfx(sfx_id, play_async)
--FIXME
end
function play_door_sfx()
--FIXME
end
function create_object_needs_quan(obj_n)
-- obj.stackable is already checked
if obj_n == 196 or obj_n == 311 or obj_n == 312 then --OBJ_LEVER, OBJ_SWITCH, OBJ_SWITCH1
return true
else
return false
end
end
function input_select_obj_qty(obj)
if not obj.stackable then
return 1
end
printl("HOW_MANY")
local qty = input_select_integer("0123456789", true)
if qty > obj.qty then
return obj.qty
end
return qty
end
--load actor functions
local actor_load = nuvie_load("md/actor.lua");
if type(actor_load) == "function" then
actor_load()
else
if type(actor_load) == "string" then
--io.stderr:write(actor_load);
end
end
look_init = nuvie_load("md/look.lua"); look_init();
combat_init = nuvie_load("md/combat.lua"); combat_init();
-- init usecode
usecode_init = nuvie_load("md/usecode.lua"); usecode_init();
talk_init = nuvie_load("md/talk.lua"); talk_init();
player_init = nuvie_load("md/player.lua"); player_init();
worktype_init = nuvie_load("md/worktype.lua"); worktype_init();
dreamworld_init = nuvie_load("md/dreamworld.lua"); dreamworld_init();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,264 @@
return {
PASS="Pass!\n",
YOU_SEE="you see %s",
ON="On - ",
TO="To - ",
NOTHING="nothing!\n",
NO_EFFECT="\nNo effect\n",
AARGH="Aargh!\n",
BLOCKED="Blocked!\n",
HOW_MANY="How many? ",
YOU_ARE_CARRYING_TOO_MUCH_ALREADY="You are carrying too much already.\n",
YOU_PRIED_THE_NAILS_OUT_OF_THE_CRATE="You pried the nails out of the crate.\n",
YOU_NAIL_THE_CRATE_SHUT="You nail the crate shut.\n",
IT_HAS_NO_EFFECT="It has no effect.\n",
IT_IS_NAILED_SHUT="It is nailed shut.\n",
IT_IS_LOCKED="It is locked.\n",
IS_NOT_STRONG_ENOUGH="%s is not strong enough.\n",
NOT_WHILE_UNDERGROUND="Not while underground.\n",
YOU_ARE_SOMEWHERE_NEAR="You are somewhere near",
YOU_CANT_DIG_ANY_DEEPER="You can't dig any deeper.\n",
IT_IS_STUCK="It is stuck.\n",
THE_CONTROL_PANEL_OPERATES_THE_DREAM_MACHINE="The control panel operates the dream machine.\n",
YOU_NEED_TO_USE_PLIERS_TO_ATTACH_THE_CABLE="You need to use pliers to attach the cable.",
YOU_WILL_CHEW_IT_INSTINCTIVELY="You will chew it instinctively.\n",
THE_PLATE_IN_THE_CAMERA_HAS_ALREADY_BEEN_EXPOSED="The plate in the camera has already been exposed.\n",
YOU_MUST_USE_A_SHOVEL_TO_MOVE_THAT="You must use a shovel to move that.\n",
YOU_CANT_DETERMINE_HOW_TO_READ_THE_TIME="You can't determine how to read the time.\n",
THE_BERRIES_ARE_NOT_EDIBLE="The berries are not edible.\n",
YOU_DONT_KNOW_HOW_IT_WORKS="You don't know how it works.\n",
THE_GROUND_IS_NOT_CLEAR_FOR_DIGGING="The ground is not clear for digging.\n",
YOU_CANT_DIG_HERE="You can't dig here.\n",
YOU_FILLED_IN_THE_HOLE="You filled in the hole.\n",
YOU_MAY_USE_THE_RUBY_SLIPPERS_TO_GO_HOME="You may use the ruby slippers to go home. If you choose to, you may now view the Grand Finale.\n\n*Afterwards, you will exit to DOS. You will be able to resume play from your last saved game.\n\n*Would you like to see the Grand Finale now? If so, press Y. To resume play now, hit N: (Y N)\n",
CLICK="Click.\n",
NOT_WHILE_IN_SOLO_MODE="Not while in solo mode!\n",
SOMETHING="something",
SEARCHING_HERE_YOU_FIND="Searching here, you find %s",
SEARCHING_HERE_YOU_FIND_NOTHING="Searching here, you find nothing.\n",
SEARCH_NEXT_OBJ=", %s",
SEARCH_LAST_OBJ=" and %s",
YOU_CANT_SLEEP_IN_A_DREAM="You can't sleep in a dream.\n",
TENT_OBJ_IN_THE_WAY="The %s is in the way.\n",
THE_GROUND_IS_NOT_FLAT_ENOUGH="The ground is not flat enough.\n",
REST="Rest",
NOT_WHILE_IN_COMBAT_MODE="Not while in combat mode!\n",
NOT_WHILE_FOES_ARE_NEAR=" - Not while foes are near!\n",
IS_TOO_NEAR_TO_SETUP_CAMP=" - %s is too near to set up camp.\n",
IS_POISONED="\n%s is poisoned!",
DO_YOU_REALLY_WANT_TO_SLEEP="\nDo you really want to sleep anyway? ",
REST_UNTIL="\nRest until %s?",
SUNRISE="sunrise",
SUNSET="sunset",
HOW_MANY_HOURS="\nHow many hours? ",
HAS_A_DREAM="\n%s has a dream...\n\n",
SEES_THREE_STONE_OBELISKS="%s sees three stone obelisks, one inscribed with a book, one a heart, and one a sword.\n\n*",
FEELS_DRAWN_TO_ONE_OF_THE_OBELISKS="%s feels drawn to one of the obelisks.\n\n",
DOES_TOUCH_THE_OBELISK="Does %s touch the obelisk with the @book, the @heart, or the @sword?\n",
WHICH_BHS="Which (B H S):\n",
FEELS_BETTER="%s feels better.\n",
THE_TONGS_WILL_NOW_PROTECT_YOUR_HANDS="The tongs will now protect your hands.\n",
THEY_WONT_COME_OFF="They won't come off!\n",
OUCH_IT_IS_VERY_HOT="OUCH. It is very hot.\n",
COMPLAINS_OF_TOO_MUCH_LIGHT_AND_INANIMATE="\n%s complains of too much light and inanimate things keep talking.*\n",
COMPLAINS_OF_INANIMATE_THINGS_TALKING="\n%s complains of inanimate things talking.*\n",
COMPLAINS_OF_TOO_MUCH_LIGHT="\n%s complains of too much light.*\n",
YOU_CANT_SLEEP="\nYou can't sleep.\n",
NOBODY_CAN_SLEEP="\nNobody can sleep.\n",
A_MECHANICAL_PERSON_CANT_EAT_BERRIES="A mechanical person can't eat berries!\n",
YOU_EAT_A_MARTIAN_BERRY_YOU_FEEL_AN_INCREASE_IN_THE_STRANGE="You eat a Martian berry. You feel an increase in the strange ",
YOU_EAT_A_MARTIAN_BERRY_YOU_FEEL_A_STRANGE="You eat a Martian berry. You feel a strange ",
RELATIONSHIP_WITH_THINGS_AROUND_YOU="relationship with things around you.\n",
SENSITIVITY_TO_THE_FEELINGS_OF_OBJECTS_AROUND_YOU="sensitivity to the feelings of objects around you.\n",
SENSE_OF_YOUR_SPATIAL_LOCATION="sense of your spatial location.\n",
SUDDEN_FLUSH_DIZZINESS_AND_NAUSEA="sudden flush, dizziness, and nausea.\n",
BREATHES_EASIER="%s breathes easier!\n",
GASPS_FOR_AIR="%s gasps for air!\n",
THE_IS_OUT_OF_FUEL="The %s is out of fuel.\n",
WENT_OUT="%s went out.\n",
FEELS_WARMER="%s feels warmer!\n",
IS_FREEZING="%s is freezing!\n",
A_PSYCHIC_POWER_FADES="A psychic power fades...\n",
SOME_ICE_HAS_MELTED="Some ice has melted.\n",
THE_ICE_IS_MELTING="The ice is melting.\n",
THAT_WOULD_BE_A_WASTE_OUTSIDE_OF_COMBAT="That would be a waste outside of combat.\n",
ENTERS_A_BATTLE_FRENZY="%s enters a battle frenzy!\n",
YOU_SPIT_INTO_THE_SPITTOON="You spit into the spittoon.\n",
YOUR_MOUTH_IS_TOO_DRY="Your mouth is too dry.\n",
CHING="Ching!\n",
SHING="Shing!\n",
WHEEEEZE="Wheeeeze\n",
THUMP_THUMP="Thump! Thump!\n",
GONG="GONG!!!!\n",
YOU_PLAY_THE="You play the %s.\n",
THE_TIME_IS="\n\nThe time is ",
TIME_AM="%d:%02d A.M.\n",
TIME_PM="%d:%02d P.M.\n",
THE_CANNON_WILL_FIRE_STEEL_CANNON_BALLS="The cannon will fire steel cannon balls.\n",
IT_IS_EMPTY="It is empty.\n",
DIRT="dirt",
ROCK="rock",
IRON_ORE="iron ore",
COAL="coal",
IT_HAS_1_LOAD_OF="It has 1 load of %s.\n",
IT_HAS_N_LOADS_OF="It has %d loads of %s.\n",
IT_HAS_A_HEARTSTONE="It has a heartstone.\n",
IT_IS_GROWING="It is growing.\n",
IT_IS_RIPE="It is ripe.\n",
IT_IS_NOT_GROWING="It is not growing.\n",
IT_IS_READY_TO_USE="It is ready to use.\n",
THE_RUBBER_IN_THE_SPRAYER_SYSTEM_IS_NOT_FLESH_COLORED="The rubber in the sprayer system is not flesh-colored.\n",
THERE_IS_NO_RUBBER_IN_THE_SPRAYER_SYSTEM="There is no rubber in the sprayer system.\n",
IT_IS_ALSO_NOT_FLESH_COLORED="It is also not flesh-colored.\n",
CABINET_1="It appears to control a mechanical system.\n",
CABINET_2="It appears to control a valve system.\n",
CABINET_3="It appears to control an electrical system.\n",
CABINET_4="It appears to control this dream machine.\n",
CABINET_5="It appears to control this spray system.\n",
CABINET_6="It appears to control the ruby lens system.\n",
CABINET_7="It appears to control the cistern valves.\n",
YOU_CANNOT_DECIPHER_WHAT_IT_CONTROLS="You cannot decipher what it controls.\n",
IT_APPEARS_TO_BE_LOOSE="It appears to be loose.\n",
IT_APPEARS_TO_BE_BROKEN="It appears to be broken.\n",
THESE_APPEAR_TO_BE_MECHANICAL_CONTROLS="These appear to be mechanical controls.\n",
THESE_APPEAR_TO_BE_VALVE_CONTROLS="These appear to be valve controls.\n",
THESE_APPEAR_TO_BE_ELECTRICAL_CONTROLS="These appear to be electrical controls.\n",
IT_APPEARS_TO_CONTROL_A_DREAM_MACHINE="It appears to control a dream machine.\n",
IT_APPEARS_TO_CONTROL_A_SPRAY_SYSTEM="It appears to control a spray system.\n",
IT_APPEARS_TO_CONTROL_THE_RUBY_LENS_SYSTEM="It appears to control the ruby lens system.\n",
IT_APPEARS_TO_CONTROL_THE_CISTERN_VALVES="It appears to control the cistern valves.\n",
YOU_CANNOT_DECIPHER_ITS_PURPOSE="You cannot decipher its purpose.\n",
THE_PANEL_IS_LOOSE="The panel is loose.\n",
THE_PANEL_IS_BROKEN="The panel is broken.\n",
THE_PANEL_IS_NOT_INSTALLED="The panel is not installed.\n",
IT_IS_LOADED_WITH="It's loaded with %s",
AND_HAS_1_CHARGE_LEFT=", and has 1 charge left.\n",
AND_HAS_N_CHARGES_LEFT=", and has %d charges left.\n",
COMBINATION="Combination",
RIFLE="Rifle",
SHOTGUN="Shotgun",
IT_IS_SET_TO="It is set to '%s'",
IT_SEEMS_TO_BE_LOOSE="\nIt seems to be loose.\n",
IT_IS_NOT_INSTALLED="\nIt is not installed.\n",
PLENTY_OF="\nPlenty of ",
IT_HAS_N_MORE_MINUTES_OF="\nIt has %d more minutes of ",
ITS_ALMOST_OUT_OF="\nIt's almost out of \n",
NO="\nNo ",
FUEL="fuel.\n",
WICK="wick.\n",
IT_IS_APPARENTLY_RUSTED_SHUT="It is apparently rusted shut.\n",
IT_IS_APPARENTLY_LOCKED="It is apparently locked.\n",
THE_SWITCH_IS_FASTENED="The switch is fastened.\n",
THIS_SWITCH_CANNOT_BE_FIXED="This switch cannot be fixed.\n",
THE_SWITCH_IS_LOOSE="The switch is loose.\n",
THE_DRILL_MUST_BE_INSTALLED_ONTO_A_DRILL_CART="The drill must be installed onto a drill cart.\n",
THE_DRILLS_POWER_IS_CONNECTED="The drill's power is connected.\n",
IT_MUST_BE_REPAIRED_FIRST="It must be repaired first.\n",
PANELS_ARE_ONLY_INSTALLED_ONTO_CABINETS="Panels are only installed onto cabinets.\n",
THIS_CABINET_REQUIRES_A_DIFFERENT_TYPE_OF_PANEL="This cabinet requires a different type of panel.\n",
THE_PANEL_IS_FASTENED="The panel is fastened.\n",
YOU_GET_TWO_HANDFULS_OF_OXIUM_FROM_THE_BIN="You get two handfuls of oxium from the bin.\n",
WHICH_SECTION_OF_RAIL_NEEDS_FIXING="Which section of rail needs fixing -\n",
THE_WORK_IS_TO_PRECISE_TO_PERFORM_TELEKINETICALLY="The work is too precise to perform telekinetically.\n",
THE_CABLE_DOES_NOT_NEED_REPLACEMENT="The cable does not need replacement.\n",
OUT_OF_AMMUNITION="Out of ammunition!\n",
OUT_OF_ARROWS="Out of arrows!\n",
OVERCOME_BY_YOUR_WOUNDS_YOU_FALL_UNCONSCIOUS="\nOvercome by your wounds, you fall unconscious..... \n",
YOU_AWAKEN_BACK_AT_FEELING_RESTORED="\n....You awaken back at %s, feeling restored.\n",
THE_SPACE_CAPSULE="the space capsule",
THE_OLYMPUS_MINE="the Olympus mine",
IT_WONT_GO_IN_THAT_DIRECTION="It won't go in that direction!\n",
IT_TURNS_LOOSELY="It turns loosely.\n",
THERE_IS_NOTHING_TO_DRILL_INTO="There is nothing to drill into.\n",
THERE_IS_NO_ROOM_LEFT_FOR_THE_ORE="There is no room left for the ore.\n",
YOU_PUT_THE_ORE_INTO_THE_WHEELBARROW="You put the %s into the wheelbarrow.\n",
YOU_PUT_THE_ORE_INTO_THE_RAIL_CAR="You put the %s into the rail car.\n",
THERE_IS_NO_MORE_ROOM="There is no more room.\n",
YOU_CANT_MIX_DIFFERENT_THINGS_IN_THE_SAME_LOAD="You can't mix different things in the same load!\n",
THERE_IS_NOTHING_TO_UNLOAD="There is nothing to unload.\n",
THE_COAL_BEGINS_MOVING_DOWN_THE_BELT="The coal begins moving down the belt.\n",
OOOPS_THESE_ROLLERS_CAN_NEVER_BE_FIXED="Ooops. These rollers can never be fixed!\n",
STOKERS_PATH_IS_BLOCKED="Stoker's path is blocked!\n",
THE_CONVEYOR_BELT_STOPS="The conveyor belt stops.\n",
ACTOR_DIVIDES="%s divides!\n",
ACTOR_CRITICAL="`%s critical!\n",
ACTOR_HEAVILY_WOUNDED="`%s heavily wounded.\n",
MAN="man",
WOMAN="woman",
HOW_DARE_YOU_YOUNG_PERSON="How dare you, young %s!\n",
ACTOR_GRAZED="`%s grazed.\n",
ACTOR_ATTACKS="`%s attacks!\n",
ACTOR_PARALYZED="`%s paralyzed!\n",
ACTOR_CHARMED="%s charmed!\n",
ACTOR_DODGES="%s dodges!\n",
BECOMES_VISIBLE="`%s becomes visible!\n",
HEAVILY="heavily",
LIGHTLY="lightly",
BARELY="barely",
DAMAGED="damaged",
WOUNDED="wounded",
ACTOR_HIT_MESSAGE="`%s %s %s.\n",
OUT_OF_RANGE="Out of range!\n",
YOUR_HANDS_ARE_FULL="\nYour hands are full.\n",
WONT_BUDGE="Won't budge !\n",
THE_TOTAL_IS_TOO_HEAVY="\nThe total is too heavy.\n",
THAT_IS_NOT_POSSIBLE="That is not possible.\n",
AFFIDAVIT="--Affidavit--\n\nThe undersigned do hereby vouch for the trust-\nworthiness of %s, who bears this chit, commending same to the members of the Olympus Mons outpost.\n\n*Signed:\n%s\n*",
YOU_CANT_READ_IT="You can't read it.\n",
YOU_NEED_A_POOL_CUE="You need a cue stick in your hands.\n",
GOOD_SHOT_OLD_BEAN="Good shot, old bean!\n",
THE_ROBOT_ALREADY_HAS_A_HEARTSTONE="The robot already has a heartstone.\n",
THE_HEARTSTONE_IS_INSTALLED="The heartstone is installed.\n",
THE_ALIEN_DEVICE_DOESNT_SEEM_TO_BE_FUNCTIONING="The alien device doesn't seem to be functioning.\n",
NOTHING_APPEARS_TO_HAPPEN="Nothing appears to happen.\n",
YOU_MUST_BE_IN_PARTY_MODE_TO_ENTER="You must be in party mode to enter.\n",
YOU_MUST_BE_IN_PARTY_MODE_TO_LEAVE="You must be in party mode to leave.\n",
THIS_DOOR_IS_NOT_RUSTED="This door is not rusted.\n",
THE_DOOR_IS_UNSTUCK="The door is unstuck.\n",
YOU_SEE_YOURSELF="You see yourself.\n",
YOU_RECEIVE_A_MOMENTARY_IMPRESSION="You receive a momentary impression of a house falling on you.\n",
THIS_WAS_WORN_LAST_BY_A_DYING_MAN="This was worn last by a dying man.\n",
THIS_WAS_USED_BY_A_MARTIAN_MEASURING_TIME="This was used by a Martian whose entire life focussed on measuring time.\n",
THIS_JEWELRY_WAS_WORN_BY="This jewelry was worn by a distinguished Martian, a mayor or \"Agrarian&.\n",
THESE_FOOTBAGS_WERE_WORN_BY="These footbags were worn by an elderly, distinguished Martian whose job, \"Gatherer&, has no human analog - a combination of undertaker, dustman, and treasurer.\n",
THIS_SAW_WAS_USED_BY="This saw was used by a Martian doctor, or \"Arborist&, for surgery.\n",
THIS_DEVICE_WAS_USED_BY="This device was used by a Martian doctor, or \"Arborist&, on patients.\n",
THIS_SCULPTURE_HAD_GREAT_RITUAL_OR_RELIGIOUS_SIGNIFICANCE="This sculpture had great ritual or religious significance to a city, or \"Grove&, of Martians. The image is of \"very proud soil&.",
YOU_RECIEVE_NO_PSYCHIC_IMPRESSIONS="You receive no psychic impressions.\n",
THE_RADIUM_HAS_BEEN_INSTALLED="The radium has been installed.\n",
RADIUM_HAS_ALREADY_BEEN_INSTALLED="Radium has already been installed.\n",
THE_OBJ_IS_FULLY_CHARGED="The %s is fully charged.\n",
THE_OBJ_ONLY_NEEDED_N_RADIUM_BLOCKS="The %s only needed %d radium blocks.\n",
THE_HEADGEAR_IS_INSTALLED="The headgear is installed.\n",
YOU_ARE_COMPLETELY_UNSURE_WHAT_YOU_JUST_DID="You are completely unsure what you just did.\n",
LIGHTS_FLASH_AND_CHANGE_COLOR_BUT_NOTHING_ELSE_HAPPENS="Lights flash and change color but nothing else happens.\n",
STATUS_LIGHTS_CHANGE_BUT_YOU_SEE_NO_OTHER_EFFECT="Status lights change but you see no other effect.\n",
YOU_ACTUATE_THE_MECHANISM_TO_NO_APPARENT_EFFECT="You actuate the mechanism to no apparent effect.\n",
THE_DREAM_MACHINES_SEEM_TO_HAVE_CEASED_FUNCTIONING="The dream machines seem to have ceased functioning.\n",
THE_MACHINE_DOES_NOT_WORK="The machine does not work.\n",
THERE_IS_NOBODY_SITTING_IN_THE_MACHINE="There is nobody sitting in the machine.\n",
ACTOR_DREAMS_UNTIL_DAWN_WHILE_THE_PARTY_WAITS="%s dreams until dawn while the party waits.\n",
YOU_TRY_TO_WAKE_YOURSELF_UP="You try to wake yourself up.\n",
YOU_WAKE_UP="You wake up.\n",
YOU_ARENT_YET_THAT_INSANE="You aren't yet that insane.\n",
NO_BACKTALK_FROM_YOU_YOUNG_MAN="No backtalk from you, young man!\n",
NO_BACKTALK_FROM_YOU_YOUNG_WOMAN="No backtalk from you, young man!\n",
YOU_FALL_OFF_THE_CLIFF="You fall off the cliff!\n",
YOU_SHAKE_YOURSELF_AWAKE_FROM_THE_NIGHTMARE="You shake yourself awake from the nightmare.\n",
YOU_FEEL_YOUR_DREAM_CONSCIOUSNESS_RETURNING="You feel your dream consciousness returning.\n",
WHAT_AN_ODD_LEVER="What an odd lever!\n",
STRANGELY_NOTHING_HAPPENS="Strangely, nothing happens.\n",
STRANGELY_IT_DOESNT_MOVE="Strangely, it doesn't move.\n",
THE_POD_SPLITS_OPEN="The pod splits open!\n",
THE_ICE_THAWS="The ice thaws.\n",
THE_WATER_FREEZES="The water freezes.\n",
ATTACK_WITH_BARE_HANDS="Attack with bare hands-",
ATTACK_WITH_WEAPON="Attack with %s-",
FASTER="...faster!\n",
YOU_IMAGINE="You imagine ",
SPRAY_GUN_GREEN_PAINT="The spray gun now contains 20 charges of green paint.\n",
SPRAY_GUN_WEED_KILLER="The spray gun now contains 10 charges of weed killer.\n",
SPRAY_GUN_10_MORE_CHARGES="The spray gun has 10 more charges.\n",
THERE_IS_NOTHING_IN_THE_GUN="There is nothing in the gun.\n",
YOU_KILLED_THE_PLANT="You killed the plant.\n",
}

View File

@@ -0,0 +1,8 @@
return {
YOU_SEE="guardare %s",
ON="Su - ",
TO="A - ",
NOTHING="nessuna cosa!\n",
NO_EFFECT="\nNessun effetto\n",
IT_IS_STUCK="Si e bloccato.\n"
}

View File

@@ -0,0 +1,405 @@
function look_pocketwatch(obj)
printl("THE_TIME_IS")
local am = true
local hour = clock_get_hour()
local minute = clock_get_minute()
if hour >= 12 then
am = false
end
if hour > 12 then
hour = hour - 12
end
local time = "TIME_AM"
if am == false then
time = "TIME_PM"
end
printfl(time, hour, minute)
end
function look_cannon(obj)
if obj.quality ~= 0 then
printl("THE_CANNON_WILL_FIRE_STEEL_CANNON_BALLS")
end
end
function look_barrow(obj)
if obj.qty == 0 then
printl("IT_IS_EMPTY")
return
end
local quality = obj.quality
local material
if quality == 1 then
material = i18n("DIRT")
elseif quality == 2 then
material = i18n("ROCK")
elseif quality == 3 then
material = i18n("IRON_ORE")
elseif quality == 4 then
material = i18n("COAL")
end
if obj.qty == 1 then
printfl("IT_HAS_1_LOAD_OF", material)
else
printfl("IT_HAS_N_LOADS_OF", obj.qty, material)
end
end
function get_lat_long_string(x, y)
local lat_str = "N"
local long_str = "W"
local lat = math.modf(((y - 512) * 240) / 1024)
local long = math.modf(((x - 512) * 360) / 1024)
if lat > 0 then
lat_str = "S"
else
if lat == 0 then
lat_str = " "
end
end
if long == 180 or long == -180 or long == 0 then
long_str = " "
else
if long < 0 then
long_str = "E"
end
end
lat = math.abs(lat)
long = 180 - math.abs(long)
return lat..lat_str.." "..long..long_str
end
function look_marker_flag(obj)
local names = {
[1]="Coprates Chasma",
[2]="Arsia Mons",
[3]="Pavonis Mons",
[4]="Ascraeus Mons",
[5]="Alber Tholus",
[6]="Elysium Mons",
[7]="Hecates Tholus",
[8]="Terra Sirenum",
[9]="Noctis Labyrinthus",
[10]="Deuteronicus Mensae",
[11]="Syrtis Major Planum",
[12]="Olympus Mons",
}
if obj.z == 0 then
if obj.quality <= 12 then
if obj.quality ~= 0 then
print(names[obj.quality])
print(" "..get_lat_long_string(obj.x,obj.y).."\n")
end
else
printl("AARGH")
end
end
end
function look_broken_strap(obj)
local spector = Actor.get(2)
Actor.set_talk_flag(spector, 6)
Actor.talk(spector)
end
function look_metal_woman(obj)
if obj.quality ~= 0 then
printl("IT_HAS_A_HEARTSTONE")
end
end
function look_covered_martian_seed(obj)
if obj.frame_n < 4 then
local quality = obj.quality
if quality == 15 then
printl("IT_IS_GROWING")
elseif quality == 16 then
printl("IT_IS_RIPE")
else
printl("IT_IS_NOT_GROWING")
end
end
end
function look_sprayer_system(obj)
local quality = obj.quality
if bit32.btest(quality, 1) then
local actor = Actor.get(0x3e)
if Actor.get_talk_flag(actor, 5) == true then
if bit32.btest(quality, 2) then
printl("IT_IS_READY_TO_USE")
else
printl("THE_RUBBER_IN_THE_SPRAYER_SYSTEM_IS_NOT_FLESH_COLORED")
end
else
printl("IT_IS_READY_TO_USE")
end
else
printl("THERE_IS_NO_RUBBER_IN_THE_SPRAYER_SYSTEM")
if Actor.get_talk_flag(actor, 5) == true and bit32.btest(quality, 2) == false then
printl("IT_IS_ALSO_NOT_FLESH_COLORED")
end
end
end
function look_cabinet(obj)
local quality = obj.quality
if quality == 0 or quality > 7 then
printl("YOU_CANNOT_DECIPHER_WHAT_IT_CONTROLS")
else
printl("CABINET_"..quality)
end
end
function look_tracking_motor(obj)
local quality = obj.quality
if bit32.btest(quality, 1) and obj.on_map == true then
printl("IT_APPEARS_TO_BE_LOOSE")
end
if bit32.btest(quality, 2) then
printl("IT_APPEARS_TO_BE_BROKEN")
end
end
function look_panel(obj)
local qty = obj.qty
if qty == 0 then
local frame_n = obj.frame_n
if frame_n == 0 then
printl("THESE_APPEAR_TO_BE_MECHANICAL_CONTROLS")
elseif frame_n == 1 then
printl("THESE_APPEAR_TO_BE_VALVE_CONTROLS")
elseif frame_n == 2 then
printl("THESE_APPEAR_TO_BE_ELECTRICAL_CONTROLS")
end
elseif qty == 4 then
printl("IT_APPEARS_TO_CONTROL_A_DREAM_MACHINE")
elseif qty == 5 then
printl("IT_APPEARS_TO_CONTROL_A_SPRAY_SYSTEM")
elseif qty == 6 then
printl("IT_APPEARS_TO_CONTROL_THE_RUBY_LENS_SYSTEM")
elseif qty == 7 then
printl("IT_APPEARS_TO_CONTROL_THE_CISTERN_VALVES")
else
printl("YOU_CANNOT_DECIPHER_ITS_PURPOSE")
end
local quality = obj.quality
if bit32.btest(quality, 1) and obj.on_map == true then
printl("THE_PANEL_IS_LOOSE")
end
if bit32.btest(quality, 2) then
printl("THE_PANEL_IS_BROKEN")
end
end
function print_number_of_charges(qty)
if qty == 1 then
printl("AND_HAS_1_CHARGE_LEFT")
else
printfl("AND_HAS_N_CHARGES_LEFT", qty)
end
end
function look_portable_sprayer(obj)
local contents
if obj.quality == 0 then
contents = tile_get_description(649)
else
contents = tile_get_description(640)
end
printfl("IT_IS_LOADED_WITH", contents)
print_number_of_charges(obj.qty)
end
function get_weapon_mode_string(obj)
local mode
local quality = obj.quality
if quality == 0 then
mode = i18n("COMBINATION")
elseif quality == 1 then
mode = i18n("RIFLE")
else
mode = i18n("SHOTGUN")
end
return mode
end
function look_ray_gun(obj)
printfl("IT_IS_SET_TO", get_weapon_mode_string(obj))
print_number_of_charges(obj.qty)
end
function look_belgian_combine(obj)
printfl("IT_IS_SET_TO", get_weapon_mode_string(obj))
print(".\n")
end
function look_switch_bar(obj)
local quality = obj.quality
if quality == 1 then
printl("IT_SEEMS_TO_BE_LOOSE")
elseif quality == 2 then
printl("IT_IS_NOT_INSTALLED")
end
end
function look_light_source(obj)
local obj_n = obj.obj_n
local qty = obj.qty
local quality = obj.quality
if (obj_n == 109 or obj_n == 110) and qty > 1 then
return
end
if quality > 30 then
printl("PLENTY_OF")
elseif quality > 6 and quality <= 30 then
printfl("IT_HAS_N_MORE_MINUTES_OF", quality)
elseif quality > 0 and quality <= 6 then
printl("ITS_ALMOST_OUT_OF")
elseif obj_n == 115 or obj_n == 117 or obj_n == 116 or obj_n == 118 then
printl("NO")
else
printl("PLENTY_OF")
end
if obj_n == 115 or obj_n == 117 or obj_n == 116 or obj_n == 118 then
printl("FUEL")
else
printl("WICK")
end
end
function look_door(obj)
local quality = obj.quality
if quality >= 128 then
quality = quality - 128
if quality >= 64 then
printl("IT_IS_APPARENTLY_RUSTED_SHUT")
else
printl("IT_IS_APPARENTLY_LOCKED")
end
end
end
function look_obelisk(obj)
if obj.quality == 0 then
return
end
local ui_style = game_get_ui_style()
canvas_show()
canvas_hide_all_sprites()
canvas_set_opacity(0xff);
canvas_set_update_interval(25)
canvas_rotate_game_palette(true)
local obelisk = sprite_new(nil, 184, 0, true)
local text_sprite
--local text_sprite_bg
if ui_style == UI_STYLE_ORIG then
canvas_set_solid_bg(false)
else
text_sprite = sprite_new(nil, 8, 164, true)
text_sprite.text_align = 2
text_sprite.text_color = 15
text_sprite.text = "Obelisk."
obelisk.x = 96
obelisk.y = 41
end
obelisk.image = image_load("mdream.lzc", obj.quality-1)
local input = nil
while input == nil do
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
canvas_set_solid_bg(true)
canvas_rotate_game_palette(false)
canvas_hide()
end
local look_usecode = {
[45]=look_belgian_combine,
[91]=look_pocketwatch,
[98]=look_pocketwatch,
[109]=look_light_source, -- OBJ_TORCH
[110]=look_light_source, -- OBJ_LIT_TORCH
[111]=look_light_source, -- OBJ_CANDLESTICK
[112]=look_light_source, -- OBJ_LIT_CANDLE
[113]=look_light_source, -- OBJ_CANDELABRA
[114]=look_light_source, -- OBJ_LIT_CANDELABRA
[115]=look_light_source, -- OBJ_OIL_LAMP
[116]=look_light_source, -- OBJ_LIT_OIL_LAMP
[117]=look_light_source, -- OBJ_LANTERN
[118]=look_light_source, -- OBJ_LIT_LANTERN
[129]=look_portable_sprayer, --OBJ_WEED_SPRAYER
[172]=look_marker_flag,
[179]=look_door, --OBJ_CLOSED_DOOR
[227]=look_door, --OBJ_DOOR3
[240]=look_ray_gun, --OBJ_HEAT_RAY_GUN
[241]=look_ray_gun, --OBJ_FREEZE_RAY_GUN
[251]=look_covered_martian_seed,
[261]=look_portable_sprayer, --OBJ_SPRAY_GUN
[268]=look_barrow, --OBJ_MARTIAN_WHEEL_BARROW
[276]=look_sprayer_system,
[287]=look_metal_woman,
[292]=look_obelisk,
[314]=look_tracking_motor,
[333]=look_cannon,
[410]=look_barrow, --OBJ_RAIL_CAR
[411]=look_switch_bar,
[457]=look_cabinet,
[458]=look_panel,
[460]=look_broken_strap,
}
function look_obj(obj)
printfl("YOU_SEE", obj.look_string);
--FIXME usecode look description should be lua code.
if usecode_look(obj) then
print("\n")
return false
end
print(".\n\n");
if look_usecode[obj.obj_n] ~= nil then
look_usecode[obj.obj_n](obj)
print("\n")
end
if is_container_obj(obj.obj_n) then
search(obj)
end
return false
end

View File

@@ -0,0 +1,349 @@
local PLAYER_CAN_MOVE = 0
local PLAYER_BLOCKED = 1
local PLAYER_FORCE_MOVE = 2
local map_entrance_tbl = {
{x=0x43, y=0x51, z=0x1},
{x=0x80, y=0x8D, z=0x0},
{x=0x76, y=0x0F2, z=0x3},
{x=0x7A, y=0x0C, z=0x3},
{x=0x9A, y=0x41, z=0x4},
{x=0x2B2, y=0x1CC, z=0x0},
{x=0x73, y=0x40, z=0x4},
{x=0x29D, y=0x1CE, z=0x0},
{x=0x0B3, y=0x0E1, z=0x4},
{x=0x27B, y=0x1F1, z=0x0},
{x=0x0C3, y=0x70, z=0x1},
{x=0x0CB, y=0x1D1, z=0x0},
{x=0x24, y=0x0F1, z=0x1},
{x=0x31A, y=0x232, z=0x0},
{x=0x5C, y=0x0F1, z=0x1},
{x=0x34C, y=0x25A, z=0x0},
{x=0x7C, y=0x28, z=0x4},
{x=0x13E, y=0x118, z=0x0},
{x=0x0A, y=0x61, z=0x5},
{x=0x3B7, y=0x1C4, z=0x0},
{x=0x5C, y=0x0B1, z=0x5},
{x=0x3DC, y=0x1DD, z=0x0},
{x=0x5E, y=0x29, z=0x4},
{x=0x227, y=0x1ab, z=0x0}
}
local pod_teleport_tbl = {
{x=0xCA, y=0x295},
{x=0x34D, y=0x295},
{x=0x13A, y=0x17A},
{x=0x2CD, y=0x1FA}
}
function player_pass()
printl("PASS")
update_conveyor_belt(true)
end
--returns true if the player can move to rel_x, rel_y
function player_before_move_action(rel_x, rel_y)
if rel_x ~= 0 and rel_y ~= 0 then
return PLAYER_CAN_MOVE
end
local player_loc = player_get_location()
if rel_x == 0 and rel_y == 1 then
local tile_num = map_get_tile_num(player_loc)
-- Fall off cliff logic
if tile_num >= 384 and tile_num <= 387 then
return PLAYER_FORCE_MOVE
end
end
local z = player_loc.z
local x = wrap_coord(player_loc.x+rel_x,z)
local y = wrap_coord(player_loc.y+rel_y,z)
for obj in objs_at_loc(x, y, z) do
local obj_n = obj.obj_n
if obj_n == 268 then --wheelbarrow
move_wheelbarrow(obj, rel_x, rel_y)
if can_move_obj(obj, rel_x, rel_y) then
obj.x = obj.x + rel_x
obj.y = obj.y + rel_y
end
elseif obj_n == 410 and can_move_obj(obj, rel_x, rel_y) then --railcar
move_rail_cart(obj, rel_x, rel_y)
elseif obj_n == 441 then --assembled drill
move_drill(obj, rel_x, rel_y) --update drill direction
if can_move_drill(obj, rel_x, rel_y) then
obj.x = obj.x + rel_x
obj.y = obj.y + rel_y
end
end
end
return PLAYER_CAN_MOVE
end
function update_objects_around_party()
local loc = player_get_location()
for obj in find_obj_from_area(wrap_coord(loc.x - 5, loc.z), wrap_coord(loc.y - 5, loc.z), loc.z, 11, 11) do
local obj_n = obj.obj_n
if (obj_n == 227 and Actor.get_talk_flag(0x73, 2)) or --OBJ_DOOR3
(obj_n == 179 and Actor.get_talk_flag(0x73, 4)) then --OBJ_CLOSED_DOOR
if bit32.band(obj.quality, 0x80) == 0 then -- check if the door is stuck
local base_frame = bit32.band(obj.frame_n, 2)
local actor = map_get_actor(obj.xyz)
if actor ~= nil then
if map_is_on_screen(obj.xyz) then
play_door_sfx()
end
obj.frame_n = base_frame + 9
else
actor = map_get_actor(obj.x + movement_offset_x_tbl[base_frame + 1], obj.y + movement_offset_y_tbl[base_frame + 1], obj.z)
if actor == nil then
actor = map_get_actor(obj.x + movement_offset_x_tbl[base_frame + 4 + 1], obj.y + movement_offset_y_tbl[base_frame + 4 + 1], obj.z)
end
if actor ~= nil and map_is_on_screen(obj.xyz) then
play_door_sfx()
if obj.frame_n < 4 then
obj.frame_n = (base_frame) + 5
elseif obj.frame_n < 8 then
obj.frame_n = (base_frame) + 1
else
obj.frame_n = (base_frame) + 5
end
else
if obj.frame_n == 5 then
obj.frame_n = 1
elseif obj.frame_n == 7 then
obj.frame_n = 3
end
end
end
end
elseif obj_n == 301 then --OBJ_REFLECTIVE_SURFACE
if obj.frame_n < 3 then
local actor = map_get_actor(obj.x, obj.y + 1, obj.z)
if actor ~= nil then
local actor_num = actor.actor_num
if actor_num >= 0x70 or actor_num == 0x5d or (actor_num >= 0x6a and actor_num <= 0x6c) then
obj.frame_n = 0
elseif (actor_num < 0x20 and actor_num ~= 6)
or (actor_num >= 0x2a and actor_num <= 0x5c)
or actor_num == 0x60 or actor_num == 0x69 or actor_num == 0x6d then
obj.frame_n = 1
else
obj.frame_n = 2
end
else
obj.frame_n = 0
end
end
end
end
end
function player_post_move_action(did_move)
local player_loc = player_get_location()
if did_move then
if map_get_tile_num(player_loc, true) == 0x6f then
printl("FASTER")
--FIXME update falling brick animation speed here.
end
update_conveyor_belt(true)
update_objects_around_party()
for obj in objs_at_loc(player_loc) do
local obj_n = obj.obj_n
if (obj_n == 175 or obj_n == 163 or obj_n == 180 or obj_n == 178 or (obj_n == 197 and obj.frame_n == 3) or obj_n == 210) then
if player_is_in_solo_mode() then
if obj_n == 163 or obj_n == 178 then
printl("YOU_MUST_BE_IN_PARTY_MODE_TO_LEAVE")
else
printl("YOU_MUST_BE_IN_PARTY_MODE_TO_ENTER")
end
return
end
if obj_n == 175 then --Mine entry
for transfer_obj in objs_at_loc(player_loc.x, player_loc.y-1, player_loc.z) do
transfer_obj.x = map_entrance_tbl[obj.quality].x
transfer_obj.y = map_entrance_tbl[obj.quality].y-1
transfer_obj.z = map_entrance_tbl[obj.quality].z
end
elseif obj_n == 163 then --Mine exit
for transfer_obj in objs_at_loc(player_loc.x, player_loc.y+1, player_loc.z) do
transfer_obj.x = map_entrance_tbl[obj.quality].x
transfer_obj.y = map_entrance_tbl[obj.quality].y+2
transfer_obj.z = map_entrance_tbl[obj.quality].z
end
elseif obj_n == 197 then
if Actor.get_talk_flag(0x73, 4) then
if obj.quality == 0 then
printl("NOTHING_APPEARS_TO_HAPPEN")
elseif obj.quality <= 4 then
local pod_exit = pod_teleport_tbl[obj.quality]
advance_time(0)
party_use_entrance(player_loc.x, player_loc.y, player_loc.z, pod_exit.x, pod_exit.y, 0)
end
else
printl("THE_ALIEN_DEVICE_DOESNT_SEEM_TO_BE_FUNCTIONING")
end
return
end
advance_time(0)
party_use_entrance(player_loc.x, player_loc.y, player_loc.z, map_entrance_tbl[obj.quality])
elseif obj_n == 461 then --OBJ_DREAM_TELEPORTER
--FIXME add logic here.
local obelisk = map_get_obj(player_loc.x, player_loc.y - 1, player_loc.z, 292, true)
if obelisk ~= nil then
--FIXME fade here.
end
local dream_actor = Actor.get(0)
if bit32.band(obj.status, 0xe5) ~= 0xa5 or dream_actor.hp > 4 then
if bit32.band(obj.status, 0xe5) == 0 then
player_move(obj.quality, obj.qty, player_loc.z)
advance_time(0)
else
dreamworld_cleanup_state(obj)
end
end
elseif obj_n == 462 then --OBJ_DREAM_TELEPORTER1 Walk on walls object
local dream_actor = Actor.get(0)
if obj.quality == 0 then
dream_actor.frame_n = dream_actor.old_frame_n
dream_actor.obj_n = dream_actor.base_obj_n
else
dream_actor.frame_n = 0
if player_get_gender() == 0 then
dream_actor.obj_n = 318
else
dream_actor.obj_n = 319
end
end
elseif obj_n == 465 then --direction control modifier
--FIXME
end
end
else
actor_map_dmg(Actor.get_player_actor(), player_loc.x, player_loc.y, player_loc.z)
play_md_sfx(0)
end
end
function can_move_drill(drill, rel_x, rel_y)
if can_move_obj(drill, rel_x, rel_y) then
return true
end
local z = drill.z
local x = wrap_coord(drill.x+rel_x,z)
local y = wrap_coord(drill.y+rel_y,z)
if map_get_obj(x, y, z, 175, true) == nil then --mine entrance
return false
end
for obj in objs_at_loc(x, y, z) do
if is_blood(obj.obj_n) == false then
return false
end
end
return true
end
local player_readied_weapons
function weapon_select()
player_readied_weapons = {}
local player = Actor.get_player_actor()
for obj in actor_inventory(player) do
if obj.readied and get_weapon_damage(obj) > 0 then
player_readied_weapons[#player_readied_weapons+1] = obj
end
end
if #player_readied_weapons == 0 then
printl("ATTACK_WITH_BARE_HANDS")
return player
else
local weapon = player_readied_weapons[1]
table.remove(player_readied_weapons, 1)
printfl("ATTACK_WITH_WEAPON", weapon.name)
return weapon
end
end
function select_next_weapon()
if #player_readied_weapons == 0 then
return nil
end
local weapon = player_readied_weapons[1]
table.remove(player_readied_weapons, 1)
if weapon ~= nil then
print("\n")
printfl("ATTACK_WITH_WEAPON", weapon.name)
end
return weapon
end
function select_attack_target()
local target_loc = get_target()
g_selected_obj = get_actor_or_obj_from_loc(target_loc)
local name
if g_selected_obj ~= nil then
name = g_selected_obj.name
else
name = tile_get_description(map_get_tile_num(target_loc))
end
print(name..".\n")
return target_loc
end
function player_attack()
local weapon = weapon_select()
repeat
local target_loc = select_attack_target()
if target_loc == nil then
printl("WHAT")
return
end
player_attack_with_weapon(weapon, target_loc)
weapon = select_next_weapon()
until weapon == nil
end
function player_attack_with_weapon(weapon, target_loc)
local player = Actor.get_player_actor()
local obj_n = weapon.obj_n
if out_of_ammo(player, weapon, true) then
return
end
if obj_n == 313 then --OBJ_M60_MACHINE_GUN
--FIXME MACHINE GUN LOGIC HERE
else
local result = attack_target_with_weapon(player, target_loc.x, target_loc.y, weapon)
if result == 2 then
printl("OUT_OF_RANGE")
play_md_sfx(5)
elseif result == 3 then
printl("THAT_IS_NOT_POSSIBLE")
play_md_sfx(5)
end
end
end

View File

@@ -0,0 +1,184 @@
function open_gates_at_olympus_mons()
local gate = map_get_obj(0x2c3, 0x1f3, 0, 181) -- OBJ_GATE
if gate ~= nil then
gate.x = 0x2c2
gate.frame_n = 3
else
printl("AARGH")
end
gate = map_get_obj(0x2c4, 0x1f3, 0, 181) -- OBJ_GATE
if gate ~= nil then
gate.frame_n = 7
else
printl("AARGH")
end
end
function open_dream_machine_door()
local door = map_get_obj(0x2c7, 0x1dc, 0, 152) --OBJ_DOOR
if door ~= nil then
door.frame_n = 7
end
end
function talk_script_fix_panels()
local numPanels = 0
for actor in party_members() do
for obj in actor_inventory(actor) do
if obj.obj_n == 458 then --OBJ_PANEL
numPanels = numPanels + 1
play_md_sfx(4)
obj.quality = bit32.band(obj.quality, 0xfd)
obj.qty = 4
end
end
end
if numPanels <= 1 then
Actor.clear_talk_flag(0x39, 3)
else
Actor.set_talk_flag(0x39, 3)
end
end
function talk_script_spawn_monster_footprints()
g_objlist_1d22_unk = 0
local player_loc = player_get_location()
for i=0,5 do
local monster = Actor.new(145, player_loc.x, player_loc.y, player_loc.z) --OBJ_MONSTER_FOOTPRINTS
actor_init(monster)
toss_actor(monster, player_loc.x, player_loc.y, player_loc.z, 0)
monster.wt = 0x8
g_objlist_1d22_unk = g_objlist_1d22_unk + 1
end
end
local talk_script_tbl = {
[1]=talk_script_fix_panels,
[6]=open_gates_at_olympus_mons,
[7]=open_dream_machine_door,
[9]=function() talk_script_status = 9 end,
[0xA]=function() talk_script_status = 0xA end,
[0x35]=talk_script_spawn_monster_footprints,
}
function talk_script(script_number)
if talk_script_tbl[script_number] ~= nil then
talk_script_tbl[script_number]()
else
print("Attempting to run talk script #"..script_number.."\n")
end
end
local talk_script_status = -1
local talk_script_post_action_tbl = {
[0x9]=function() play_end_sequence() end,
[0xA]=function() end,
[0x34]=wake_from_dream,
[0x36]=wake_from_dream,
[0x38]=function() end,
[0x65]=function() end,
[0x66]=function() end,
[0x67]=function() end,
[0x68]=function() end,
[0x69]=function() end,
}
function talk_to_actor(actor)
local actor_num = actor.actor_num
if actor_num < 2 then
if g_in_dream_mode then
printl("YOU_TRY_TO_WAKE_YOURSELF_UP")
local player_loc = player_get_location()
if player_loc.z ~= 3 then
wake_from_dream()
end
elseif player_is_in_solo_mode() then
printl("NOT_WHILE_IN_SOLO_MODE")
else
printl("YOU_ARENT_YET_THAT_INSANE")
end
return true
end
if actor.obj_n == 391 then --your mother
if player_get_gender() == 0 then
printl("NO_BACKTALK_FROM_YOU_YOUNG_MAN")
else
printl("NO_BACKTALK_FROM_YOU_YOUNG_WOMAN")
end
return true
end
print(actor.name.."\n")
Actor.talk(actor_num)
print("\n")
if talk_script_post_action_tbl[talk_script_status] ~= nil then
talk_script_post_action_tbl[talk_script_status]()
end
talk_script_status = -1
return true
end
function talk_conveyor()
talk_to_actor(Actor.get(0x72))
end
function talk_tower()
talk_to_actor(Actor.get(0x73))
end
function talk_dream_machine()
talk_to_actor(Actor.get(0x74))
end
local talk_obj_tbl = {
[0xC] = function() printl("YOU_RECEIVE_A_MOMENTARY_IMPRESSION") end,
[0x5C] = function() printl("THIS_WAS_WORN_LAST_BY_A_DYING_MAN") end,
[0x64] = talk_dream_machine,
[0xBC] = talk_conveyor,
[0xBF] = talk_conveyor,
[0xC0] = talk_conveyor,
[0xC8] = talk_tower,
[0xC9] = talk_tower,
[0xD6] = talk_tower,
[0xD7] = talk_tower,
[0xE7] = function() printl("THIS_WAS_USED_BY_A_MARTIAN_MEASURING_TIME") end,
[0xEA] = function() printl("THIS_JEWELRY_WAS_WORN_BY") end,
[0xF6] = function() printl("THESE_FOOTBAGS_WERE_WORN_BY") end,
[0xF7] = function() printl("THIS_SAW_WAS_USED_BY") end,
[0xF9] = function() printl("THIS_DEVICE_WAS_USED_BY") end,
[0x113] = function() printl("THIS_SCULPTURE_HAD_GREAT_RITUAL_OR_RELIGIOUS_SIGNIFICANCE") end,
[0x120] = talk_dream_machine,
[0x121] = talk_dream_machine,
[0x122] = talk_dream_machine,
}
function talk_to_obj(obj)
local player = Actor.get_player_actor()
if actor_is_affected_by_green_berries(player.actor_num) then
if bit32.band(obj.status, 1) == 1 then
local talk_function = talk_obj_tbl[obj.obj_n]
if talk_function ~= nil then
talk_function()
return true
end
else
printl("YOU_RECIEVE_NO_PSYCHIC_IMPRESSIONS")
end
else
printl("NOTHING")
end
return false
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,259 @@
function select_target_actor(src_actor)
local var_10 = 0x7fff
local target_actor
for i=0,0xff do
local actor = Actor.get(i)
local actor_align = actor.align
local actor_obj_n = actor.obj_n
local src_actor_align = src_actor.align
local src_actor_obj_n = src_actor.obj_n
if actor_obj_n ~= 0 and actor.alive and actor.visible and actor.actor_num ~= src_actor.actor_num and actor_obj_n ~= 381 then --OBJ_DUST_DEVIL
if src_actor_align ~= ALIGNMENT_NEUTRAL or actor_align ~= ALIGNMENT_NEUTRAL then
if src_actor_align ~= ALIGNMENT_CHAOTIC or (src_actor_obj_n ~= actor_obj_n
and (src_actor_obj_n ~= 372 or (actor_obj_n ~= 370 and actor_obj_n ~= 371))
and ((src_actor_obj_n ~= 362 and src_actor_obj_n ~= 373 and src_actor_obj_n ~= 254)
or (actor_obj_n ~= 362 and actor_obj_n ~= 373 and actor_obj_n ~= 254)))
and (src_actor_align ~= ALIGNMENT_GOOD or actor_align == ALIGNMENT_EVIL or actor_align == ALIGNMENT_CHAOTIC)
and (src_actor_align ~= ALIGNMENT_EVIL or actor_align == ALIGNMENT_GOOD or actor_align == ALIGNMENT_CHAOTIC)
and actor_find_max_wrapped_xy_distance(src_actor, actor.x, actor.y) <= 0xb
and (actor.wt ~= 7 or actor_find_max_wrapped_xy_distance(Actor.get_player_actor(), actor.x, actor.y) <= 5)
then
local var_C = get_wrapped_dist(actor.x, src_actor.x)^2 + get_wrapped_dist(actor.y, src_actor.y)^2
if var_C < var_10
or (var_C == var_10 and actor_get_damage(actor) > actor_get_damage(target_actor)) then
var_10 = var_C
target_actor = actor
end
end
end
end
end
return target_actor
end
function worktype_8_combat_attack(actor)
g_selected_obj = select_target_actor(actor)
end
function worktype_15_your_mother(actor)
if actor_move(actor, DIR_SOUTH) == false then
local target_actor = select_target_actor(actor)
if target_actor ~= nil then
--FIXME do combat range check. sub_1B305
actor_take_hit(actor, target_actor, 6, 0)
end
end
subtract_movement_pts(actor, 3)
end
function worktype_stomp_around(actor)
subtract_movement_pts(actor, 5)
if actor.obj_n == 398 and g_current_dream_stage == 0x44 then
if math.random(0, 1) == 0 then
play_md_sfx(0, true)
quake_start(1,50)
else
return
end
end
local direction = math.random(0, 3)
actor_move(actor, direction, 0)
for obj in objs_at_loc(actor.xyz) do
actor_hit(obj, math.random(0, 0xa) + math.random(0, 0xa), 0)
end
end
function worktype_16_minotaur(actor)
if g_current_dream_stage == 0x60 then
Actor.kill(actor)
return
end
local dream_actor = Actor.get(0)
local target
if Actor.inv_has_obj_n(dream_actor, 162) then --OBJ_RED_CAPE
target = dream_actor
g_selected_obj = target
else
for obj in find_obj_from_area(0x21, 0x33, 2, 0x1c, 0x10) do
if obj.obj_n == 162 then --OBJ_RED_CAPE
target = obj
end
end
end
if target == nil then
worktype_stomp_around(actor)
return
end
if actor_get_combat_range(actor, target.x, target.y) <= 1 then
if target.luatype == "actor" then
attack_target_with_weapon(actor, target.x, target.y, actor)
subtract_movement_pts(actor, 0xa)
return
end
hit_target(target, RED_HIT_TILE)
if not Actor.get_talk_flag(0x54, 6) and target.x >= 0x37 and target.y <= 0x37 then
complete_tiffany_stage()
return
end
end
actor_move_towards_loc(actor, target.x, target.y)
play_md_sfx(0, true)
quake_start(1,50)
for obj in objs_at_loc(actor.xyz) do
actor_hit(obj, math.random(1, 0xa) + math.random(1, 0xa), 0)
end
subtract_movement_pts(actor, 5)
end
function worktype_99_coker_move_to_coal_vein(actor)
if actor_move(actor, DIR_NORTH) == false then
local vein = map_get_obj(actor.x, actor.y-1, actor.z, 446) --OBJ_VEIN_OF_COAL FIXME should be -2 not -1 need to fix actor_move for coker.
if vein ~= nil then
if map_is_on_screen(actor.x, actor.y, actor.z) then
play_md_sfx(0x10)
end
actor.wt = 0x9A
end
end
end
function worktype_9A_coker_drop_coal(actor)
local obj = map_get_obj(actor.x, actor.y+1, actor.z, 188) --OBJ_CONVEYOR_BELT
if obj ~= nil then
local coal = Obj.new(447) --OBJ_HUGE_LUMP_OF_COAL
Obj.moveToMap(coal, actor.x, actor.y+1, actor.z)
else
obj = map_get_obj(actor.x, actor.y+1, actor.z, 192) --OBJ_BARE_ROLLERS
if obj == nil then
actor_move(actor, DIR_SOUTH)
return
end
end
actor.wt = 0x9B
end
function worktype_9B_coker_wait_for_coal_to_move_away(actor)
local obj = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL
if obj == nil then
obj = map_get_obj(actor.x, actor.y+1, actor.z, 192) --OBJ_BARE_ROLLERS
if obj == nil then
actor.wt = 0x99
end
end
end
function worktype_9D_stoker_wait_for_coal(actor)
local coal
coal = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL
if coal ~= nil then
while coal ~= nil do
Obj.removeFromEngine(coal)
coal = map_get_obj(actor.x, actor.y+1, actor.z, 447) --OBJ_HUGE_LUMP_OF_COAL
end
actor.wt = 0x9E
end
end
function worktype_9E_stoker_walk_to_furnace(actor)
if actor_move(actor, DIR_NORTH) == false then
local furnace = map_get_obj(actor.x, actor.y-1, actor.z, 233)
if furnace == nil then
furnace = map_get_obj(actor.x+1, actor.y-1, actor.z, 233)
end
if furnace ~= nil then
if Actor.get_talk_flag(0x72, 2) == false then
activate_power_system()
else
if Actor.get_talk_flag(0x73, 2) == false or Actor.get_talk_flag(0x71, 3) == true then
if Actor.get_talk_flag(0x71, 3) == true then
Actor.clear_talk_flag(0x73, 2)
Actor.clear_talk_flag(0x71, 3)
--FIXME sub_3F740
end
Actor.set_talk_flag(0x73, 2)
activate_power_update_tiles()
activate_tower_electricity()
midgame_cutscene_2()
end
end
actor.wt = 0x9C
else
stoker_blocked(actor)
end
end
end
function activate_tower_electricity()
for obj in find_obj(0, 201) do --OBJ_TOWER_TOP
if obj ~= nil then
if obj.x >= 0x3d0 and obj.x <= 0x3f0 and obj.y >= 0x1d0 and obj.y <= 0x1e7 then
local frame_n = obj.frame_n
obj.frame_n = bit32.bor(frame_n, 4)
end
end
end
for obj in find_obj(0, 214) do --OBJ_POWER_CABLE
if obj ~= nil then
if obj.x >= 0x3d0 and obj.x <= 0x3f0 and obj.y >= 0x1d0 and obj.y <= 0x1e7 then
obj.obj_n = 215 --OBJ_POWER_CABLE1
end
end
end
end
function stoker_blocked(stoker)
if map_is_on_screen(stoker.x, stoker.y, stoker.z) then
printl("STOKERS_PATH_IS_BLOCKED")
play_md_sfx(0)
end
end
function worktype_9C_stoker_return_to_conveyor_belt(actor)
if map_get_obj(actor.x, actor.y+2, actor.z, 191) == nil then --OBJ_CONVEYOR_BELT2
if actor_move(actor, DIR_SOUTH) == false then
stoker_blocked(actor)
end
else
actor.wt = 0x9D
end
end
local worktype_tbl = {
[0x15]=worktype_15_your_mother,
[0x16]=worktype_16_minotaur,
[0x99]=worktype_99_coker_move_to_coal_vein,
[0x9a]=worktype_9A_coker_drop_coal,
[0x9b]=worktype_9B_coker_wait_for_coal_to_move_away,
[0x9c]=worktype_9C_stoker_return_to_conveyor_belt,
[0x9d]=worktype_9D_stoker_wait_for_coal,
[0x9e]=worktype_9E_stoker_walk_to_furnace,
}
function perform_worktype(actor)
--print("wt="..actor.wt.."\n")
local mpts = actor.mpts
if worktype_tbl[actor.wt] ~= nil then
local func = worktype_tbl[actor.wt]
func(actor)
end
if mpts == actor.mpts then
subtract_movement_pts(actor, 10)
end
end

View File

@@ -0,0 +1,291 @@
--Actor stats table
--[objnum] = {str,dex,int,hp,dmg,alignment,can talk,drops blood,?,?,?,lives in water,flies-immune to tremor,repel undead (not used anymore),poisonous,strength_based,double dmg from fire,immune to magic (fire only),immune to poison,undead and immune to death spells,immune to sleep spell,{spell table},{weapon table},{armor table},{treasure table},exp_related see actor_hit()}
actor_tbl = {
--carnivorous orchid
[282] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--serpent woman
[283] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--baby apatosaurus
[284] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--baby apatosaurus
[285] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--apatosaurus
[286] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--apatosaurus
[287] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--pteranodon
[288] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--allosaurus
[289] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--allosaurus
[290] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--wisp
[291] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--carnivorous orchid
[292] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--tyrannosaurus
[293] = {30, 28, 255, 3, 255, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--tyrannosaurus
[294] = {30, 28, 255, 3, 255, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--tyrannosaurus
[295] = {30, 28, 255, 3, 255, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--gorilla
[296] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--robosaurus
[297] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--robosaurus
[298] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--baby pteranodon
[299] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--plesiosaur
[300] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--argent sergeant
[301] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--turtle
[302] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--stegosaurus
[303] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--stegosaurus
[304] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--triceratops
[305] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--triceratops
[306] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--party member on turtle
[307] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--snake
[308] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--alphadon
[309] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--modern man
[310] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--professor
[311] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--reporter
[312] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--woman
[313] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--shaman
[314] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--chieftain
[315] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--man
[316] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--parrot
[317] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--Sakkhra
[318] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--automaton
[319] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--man
[320] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--woman
[321] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--noble
[322] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--myrmidex drone
[323] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--woman
[324] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--neanderthal
[325] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--man
[326] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--ankylosaurus
[327] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--Myrmidex queen
[328] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--dancer
[329] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--deinonychus
[330] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--sabretooth tiger
[331] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--sloth
[332] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--jaguar
[333] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--dimetrodon
[334] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--bear
[335] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--giant spider
[336] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0},
--eohippus
[337] = {1, 28, 4, 3, 1, ALIGNMENT_NEUTRAL, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, {}, {}, 0}
}
function actor_map_dmg(actor, map_x, map_y, map_z)
--FIXME
end
function actor_update_all()
--FIXME
end
-- [objectnum] = range
g_range_weapon_tbl = {
[1] = 5, -- spear of shamap
[21] = 4, --black staff --FIXME: only ranged weapon when Myrmidex are near
[26] = 6, -- spear
[27] = 4, -- throwing axe
[31] = 5, -- bow
[32] = 4, -- blowgun
[37] = 7, -- atl atl better than spear (whole screen)
[3] = 4, -- boomerang
[44] = 4, -- knife
[40] = 7, --modern rifle (whole screen)
[50] = 7, --bamboo flintlock (whole screen)
[138] = 6, --grenade
[139] = 6, --lit grenade
[240] = 6, --device
[241] = 6 --activated device
}
local projectile_weapon_tbl =
{
--obj_n = {tile_num, initial_tile_rotation, speed, rotation_amount}
[1] = {512, 45, 3, 0}, -- spear of shamap
[21] = {266, 90,4, 0}, --black staff --FIXME: rot, speed, amount
[26] = {547, 45,3, 0}, -- spear
[27] = {548, 0, 2, 10}, -- throwing axe
[31] = {566, 90,4, 0}, -- bow
[32] = {557, 90,4, 0}, --blowgun --CHECKME: rot, speed, amount
[37] = {547, 45,3, 0}, --atl atl
[39] = {560, 0, 4, 10}, -- boomerang
[44] = {565, 0, 2, 10}, -- knife
[40] = {562, 90,4, 0}, --modern rifle --FIXME: tile_num, rot, speed, amount
[50] = {562, 90,4, 0}, --bamboo flintlock --FIXME: tile_num, rot, speed, amount
[137] = {701, 90,4, 0}, --grenade --FIXME: tile_num, rot, speed, amount
[138] = {701, 90,4, 0}, --grenade --FIXME: tile_num, rot, speed, amount
[240] = {1029, 90,4, 0}, --device --FIXME: tile_num, rot, speed, amount
[241] = {1029, 90,4, 0} --activated device --FIXME: tile_num, rot, speed, amount
}
weapon_dmg_tbl = { --FIXME: all damage is made up
[1] = 15, -- spear of shamap (causes sleep)
[21] = 8, --black staff (extra damage vs Myrmidex)
[24] = 10, --club
[25] = 6, --obsidian knife
[26] = 15, --spear
[27] = 10, --throwing axe
[28] = 15, --axe
[29] = 15, --rock hammer
[31] = 15, --bow
[32] = 2, --blowgun (poisons)
[33] = 25, --obsidian sword
[34] = 20, --two-handed hammer
[37] = 25, --atl atl
[39] = 8, --boomerang
[40] = 20, --modern rifle
[44] = 10, --knife
[50] = 12, --bamboo flintlock
--[52] = 1, --scissors (says bare handed)
[94] = 15, --fire extingisher
[118] = 30, --fire axe
[119] = 15, --metal hammer
[128] = 4, --bamboo pole
--[131] = 1, --digging stick (says bare handed)
[137] = 30, --grenade
[138] = 30, --lit grenade
--[208] = 1, --torch (says bare handed)
[209] = 15, --lit torch
--[212] = 1, --fishing pole (says bare handed)
[240] = 30, --device (FIXME: explosive gas only hurts Myrmidex)
[241] = 30 --activated device (FIXME: explosive gas only hurts Myrmidex)
}
armour_tbl = --FIXME: all armor value is made up
{
[2] = 7, --shield of Krukk
[7] = 1, --cloth armor
[8] = 5, --leather armour
[9] = 2, --bark armor
[13] = 1, --bark shield
[14] = 3, --leather shield
[15] = 5, --stegosaurus shield
[67] = 10, --kotl shield (better vs Myrmidex?)
--[84] = 0, --tooth necklace
--[85] = 0, --jade necklace
--[135] = 0, --lei
--[600] = 0, --ring
}
function out_of_ammo(attacker, weapon, print_message) -- untest function
local weapon_obj_n = weapon.obj_n
if weapon_obj_n == 32 and Actor.inv_has_obj_n(attacker, 36) == false then --blowgun, poisoned darts
if(print_message) then
print("Out of darts!\n")
end
return true
end
if weapon_obj_n == 31 and Actor.inv_has_obj_n(attacker, 45) == false then --bow, arrows
if(print_message) then
print("Out of arrows!\n")
end
return true
end
if weapon_obj_n == 37 and Actor.inv_has_obj_n(attacker, 26) == false then --atl atl, spear
if(print_message) then
print("Out of spears!\n")
end
return true
end
if weapon_obj_n == 40 and Actor.inv_has_obj_n(attacker, 41) == false then --modern rifle, rifle bullet
if(print_message) then
print("Out of ammunition!\n")
end
return true
end
if weapon_obj_n == 50 and weapon.frame_n == 0 then --unloaded bamboo flintlock (frame 1 is loaded)
if(print_message) then
print("Flintlock not loaded!\n")
end
return true
end
return false
end
function actor_update_all()
dbg("actor_update_all()\n")
end
function advance_time(num_turns)
--FIXME
local minute = clock_get_minute()
clock_inc(num_turns)
if minute + num_turns >= 60 then
update_actor_schedules()
end
end
function can_get_obj_override(obj)
return false
end
function actor_get_obj(actor, obj) -- FIXME need to limit inventory slots
if obj.getable == false then
print("\nNot possible.")
return false
end
if Actor.can_carry_obj_weight(actor, obj) == false then
print("\nThe total is too heavy.")
return false
end
-- print("\nYou are carrying too much already.");
Obj.moveToInv(obj, actor.actor_num)
subtract_movement_pts(actor, 3)
return true
end
function player_post_move_action(did_move)
end

View File

@@ -0,0 +1,68 @@
local lua_file = nil
lua_file = nuvie_load("common/intro_common.lua"); lua_file();
function play()
local g_img_tbl = image_load_all("endgame.lzc")
-- 0,0 Party
-- 0,1 Lord British
-- 0,2 Aiela
-- 0,3 Tristia
-- 0,4 Leaving Savage Empire
local bg = sprite_new(g_img_tbl[0][0], 0, 0, true)
canvas_set_palette("savage.pal", 1)
canvas_set_opacity(0xff);
mouse_cursor_visible(false)
canvas_set_update_interval(25)
local txt = sprite_new(nil, 28, 135, true)
txt.text_color = 0
txt.text = i18n("IMG1_TXT1_END")
txt.text_align = 1
fade_in()
wait_for_input()
txt.text = i18n("IMG1_TXT2_END")
wait_for_input()
txt.text = i18n("IMG1_TXT3_END")
wait_for_input()
bg.image = g_img_tbl[0][1]
txt.text = i18n("IMG2_TXT1_END")
wait_for_input()
txt.text = i18n("IMG2_TXT2_END")
wait_for_input()
-- TODO: Add Check for Love with Aiela
bg.image = g_img_tbl[0][2]
txt.text = i18n("IMG3_TXT1_END")
wait_for_input()
txt.text = i18n("IMG3_TXT2_END")
wait_for_input()
txt.text = i18n("IMG3_TXT3_END")
wait_for_input()
-- TODO: Add Check for Love with Tristia
bg.image = g_img_tbl[0][3]
txt.text = i18n("IMG4_TXT1_END")
wait_for_input()
txt.text = i18n("IMG4_TXT2_END")
wait_for_input()
bg.image = g_img_tbl[0][4]
txt.text = i18n("IMG5_TXT1_END")
wait_for_input()
txt.text = i18n("IMG5_TXT2_END")
wait_for_input()
txt.text = i18n("IMG5_TXT3_END")
wait_for_input()
txt.text = i18n("IMG5_TXT4_END")
wait_for_input()
bg.image = g_img_tbl[0][1]
txt.text = i18n("IMG2_TXT3_END")
-- TODO - Add Years, Months, Days to String
wait_for_input()
end
play()

View File

@@ -0,0 +1,193 @@
local lua_file = nil
--load common functions
lua_file = nuvie_load("common/common.lua"); lua_file();
function dbg(msg_string)
--io.stderr:write(msg_string)
end
function load_game()
end
function save_game()
end
local g_tile_to_object_map = {
-- Trees
[50] = 5000, [51] = 5000, [64] = 5000, [65] = 5000, [66] = 5000,
[67] = 5000, [68] = 5000, [69] = 5000, [70] = 5000, [71] = 5000,
[72] = 5000, [192] = 5000, [193] = 5000, [194] = 5000, [195] = 5000,
[198] = 5000, [179] = 5000, [180] = 5000, [130] = 5000,
-- Oven Fire
[16] = 5001, [17] = 5001, [18] = 5001, [19] = 5001, [20] = 5001,
[21] = 5001, [22] = 5001, [23] = 5001, [24] = 5001, [25] = 5001,
[26] = 5001, [27] = 5001, [170] = 5001, [171] = 5001,
-- Yucca Plant
[52] = 5002,
}
function get_tile_to_object_mapping(tile_num)
return g_tile_to_object_map[tile_num]
end
local g_is_object_a_tile = {
[5000] = true, [5001] = true, [5002] = true
}
function is_tile_object(obj_num)
if g_is_object_a_tile[obj_num] ~= nil then
return true
end
return false
end
local g_container_obj_tbl = {
[59] = 1, [60] = 1, [97] = 1,
[182] = 1, [183] = 1, [184] = 1
}
function is_container_obj(obj_num)
if g_container_obj_tbl[obj_num] ~= nil then
return true
end
return false
end
function search(obj)
if obj.on_map == false then
return
end
local found_obj = false
local child
local first_loop = true
local prev_obj = nil
for child in container_objs(obj) do
if prev_obj ~= nil then
printfl("SEARCH_NEXT_OBJ", prev_obj.look_string)
Obj.moveToMap(prev_obj, obj.x, obj.y, obj.z)
end
if first_loop == true then
found_obj = true
printfl("SEARCHING_HERE_YOU_FIND", child.look_string)
Obj.moveToMap(child, obj.x, obj.y, obj.z)
else
prev_obj = child
end
script_wait(50)
first_loop = false
end
if prev_obj ~= nil then
printfl("SEARCH_LAST_OBJ", prev_obj.look_string)
Obj.moveToMap(prev_obj, obj.x, obj.y, obj.z)
end
if found_obj == false then
printl("SEARCHING_HERE_YOU_FIND_NOTHING")
else
print(".\n")
end
end
--tile_num, readied location
local g_readiable_objs_tbl = {
-- 0 = head
-- 1 = neck
[630] = 1, --tooth necklace
[631] = 1, --jade necklace
[696] = 1, --lei
-- 3 = 1 handed
[512] = 3, --spear of shamap
[541] = 3, --black staff
[545] = 3, --club
[546] = 3, --obsidian knife
[547] = 3, --spear
[548] = 3, --throwing axe
[549] = 3, --axe
[550] = 3, --rock hammer
[554] = 3, --obsidian sword
[558] = 3, --atl atl
[560] = 3, --boomerang
[565] = 3, --knife
[574] = 3, --scissors
[677] = 3, --metal hammer
[700] = 3, --grenade
[701] = 3, --lit grenade
[900] = 3, --torch
[901] = 3, --lit torch
[1028] = 3, --device
[1029] = 3, --activated device
-- 2 = torso
[518] = 2, --cloth armor
[519] = 2, --leather armour
[520] = 2, --bark armor
-- 3 = shield hand
[513] = 3, --shield of krukk
[524] = 3, --bark shield
[525] = 3, --leather shield
[526] = 3, --stegosaurus shield
[606] = 3, --kotl shield
-- 7 = feet
-- 4 = two handed - FIXME: guns (561, 571, 572) can't be equipped by natives
[552] = 4, --bow
[553] = 4, --blowgun
[553] = 4, --two handed hammer
[561] = 4, --modern rifle
[571] = 4, --bamboo flintlock
[572] = 4, --loaded bamboo flintlock
[640] = 4, --fire extinguisher
[676] = 4, --fire axe
[689] = 4, --bamboo pole
[692] = 4, --digging stick
[904] = 4, --fishing pole
-- 9 = finger
[600] = 9, --ring (not equipable in original)
}
function obj_is_readiable(obj)
if g_readiable_objs_tbl[obj.tile_num] ~= nil then
return true
end
return false
end
function obj_get_readiable_location(obj)
if g_readiable_objs_tbl[obj.tile_num] ~= nil then
return g_readiable_objs_tbl[obj.tile_num]
end
return -1
end
function create_object_needs_quan(obj_n)
-- obj.stackable is already checked
return false
end
function talk_to_obj(obj)
printl("NOTHING")
return false
end
--load actor functions
local actor_load = nuvie_load("se/actor.lua");
if type(actor_load) == "function" then
actor_load()
else
if type(actor_load) == "string" then
--io.stderr:write(actor_load);
end
end
look_init = nuvie_load("se/look.lua"); look_init();
-- init usecode
usecode_init = nuvie_load("se/usecode.lua"); usecode_init();
player_init = nuvie_load("se/player.lua"); player_init();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,36 @@
return {
PASS="Pass!\n",
YOU_SEE="you see %s",
NOTHING="nothing!\n",
SEARCHING_HERE_YOU_FIND="Searching here, you find %s",
SEARCHING_HERE_YOU_FIND_NOTHING="Searching here, you find nothing.\n",
SEARCH_NEXT_OBJ=", %s",
SEARCH_LAST_OBJ=" and %s",
OUT_OF_RANGE="Out of Range!\n",
BLAH="Blah",
CARRY_TOO_MUCH="You are carrying too much already.\n",
GOT_CORN="You got some corn from the plant.\n",
USE_CLAY="You shaped a small, soft pot from the clay.\n",
USE_FISHING_POLE_NO_WATER="You need to stand next to deep water.\n",
USE_FISHING_POLE_FAIL="You didn't get a fish.\n",
USE_FISHING_POLE_SUCCESS="You caught a fish!\n",
USE_DIGGING_STICK_NO_WATER="There is nothing to dig!\n",
USE_DIGGING_STICK="You get some clay.\n",
USE_YUCCA_PLANT="You got some flax from the yucca plant.\n",
USE_TREE="You pulled a branch from the tree.\n",
IMG1_TXT1_END="Members of all the tribes come for the feast... the largest and most important feast ever held in the Valley of Eodon.",
IMG1_TXT2_END="Kurak sits beside Yolaru, Pindiro beside Barako, Haakur beside Sakkhra, and peace is sworn between the tribes.",
IMG1_TXT3_END="You know this peace isn't for you. Soon enough, you will hear the call to action again. But tonight, there is time for music and dance, friendship and love.",
IMG2_TXT1_END="At dawn, your past catches up with you... and your future beckons. A vision of Lord British appears before you.",
IMG2_TXT2_END="\"You have done well,\" he says. \"But now I must take you where you are needed. For the sake of the friends you leave behind, I am sorry. Prepare yourself.\"",
IMG3_TXT1_END="You say farewell to Aiela. \"Aiela does not know your world. Take her there,\" she pleads. \"Teach her of your world.",
IMG3_TXT2_END="You shake your head. \"My world would strangle you. You must stay. My heart remains with you. But my duty is elsewhere... with him.\"",
IMG3_TXT3_END="Tears roll down her cheeks. \"Abandon duty, and you will not be warrior Aiela loves. Choose duty, and you must leave. Either way, Aiela loses all... Farewell.\"",
IMG4_TXT1_END="You say farewell to Tristia. \"I must go with Lord British,\" you say. \"My duty lies with him, though it breaks my heart.\"",
IMG4_TXT2_END="Tristia laughs sweetly. \"Tristia does not mind,\" she says. \"Tristia has found another loves: handsome Botorok. Botorok is so much better than you. Go with your chief. Go.\"",
IMG5_TXT1_END="You are joined by Spector's former assistant, Fritz, who came out of hiding to fight the Myrmidex, and bears their scars.",
IMG5_TXT2_END="The moongate appears, summoned by the shade of Lord British. Jimmy, Spector and Fritz gather their belongs...",
IMG5_TXT3_END="But Rafkin does not. \"I'm staying, my friend,\" he says, \"Someone must. I will stay here... and hope other scientists come. Farewell.\"",
IMG5_TXT4_END="Saddened, you follow your friends and allies into the moongate, leaving the Valley of Eodon. Perhaps someday you will return to those you have left behind.",
IMG2_TXT3_END="CONGRATULATIONS. You have completed THE SAVAGE EMPIRE in XXTIMESTRXX. Communicate your success to Lord British at Origin!",
}

View File

@@ -0,0 +1,25 @@
local look_usecode = {
}
function look_obj(obj)
printfl("YOU_SEE", obj.look_string);
--FIXME usecode look description should be lua code.
if usecode_look(obj) then
print("\n")
return false
end
print(".\n\n");
if look_usecode[obj.obj_n] ~= nil then
look_usecode[obj.obj_n](obj)
print("\n")
end
if is_container_obj(obj.obj_n) then
search(obj)
end
return false
end

View File

@@ -0,0 +1,16 @@
function player_pass()
printl("PASS")
end
--returns true if the player can move to rel_x, rel_y
function player_before_move_action(rel_x, rel_y)
return true
end
function player_post_move_action(did_move)
end
function player_attack()
--FIXME
end

View File

@@ -0,0 +1,256 @@
local USE_EVENT_USE = 0x01
-- Returns true if the actor has the item or a container with the item
function actor_has_item(actor, obj)
local tobj = obj
while tobj.in_container do
tobj = tobj.parent
end
if tobj.on_map == false and
tobj.parent.luatype == "actor" and
tobj.parent.actor_num == actor.actor_num then
return true
end
return false
end
-- Check Reachable
-- A) Next to actor passed in
-- B) In inventory of any party member
-- Return actor that can reach object or nil
-- Optionally automatically print "Out of Range!" message
function check_can_reach(obj, actor, print_msg)
if math.abs(obj.x - actor.x) <= 1 and
math.abs(obj.y - actor.y) <= 1 and
obj.z == actor.z then
return actor
end
for party_member in party_members() do
if actor_has_item(party_member, obj) == true then
return party_member
end
end
if print_msg then
printl("OUT_OF_RANGE")
end
return nil
end
-- delete an object from inventory or remove it from the map
function delete_or_remove_object(actor, obj, qty)
-- FIXME: Remove the exact object from the Actor
if Actor.inv_has_obj_n(actor, obj.obj_n) then
if qty ~= nil then
Actor.inv_remove_obj_qty(actor, obj.obj_n, qty)
else
Actor.inv_remove_obj(actor, obj)
end
-- Remove the object from the map
else
if qty ~= nil then
map_remove_obj(obj, qty)
else
map_remove_obj(obj)
end
end
end
-- create and add item to actor, qty if stackable, drop if required to create the item,
-- obj_n: Item Code to Create
-- actor: actor to get the object
-- qty: how many (or nil)
-- drop_if_fail: if true, object gets put on the map on failure
-- print_msg: if true, prints the carry too much message on failure
function add_item_to_actor(obj_n, actor, qty, drop_if_fail, print_msg)
local new_obj = Obj.new(obj_n)
if qty ~= nil then
new_obj.qty = qty
else
new_obj.qty = 1
end
if Actor.can_carry_obj(actor, new_obj) then
if qty ~= nil then
Actor.inv_add_obj(actor, new_obj, STACK_OBJECT_QTY)
else
Actor.inv_add_obj(actor, new_obj, false)
end
else
if print_msg then
printl("CARRY_TOO_MUCH")
end
return false
end
return true
end
function use_corn_stalk(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
if add_item_to_actor(108, use_actor, 1, false, true) == true then
printl("GOT_CORN")
end
end
function use_tree(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
if add_item_to_actor(206, use_actor, 1, false, true) == true then
printl("USE_TREE")
end
end
function use_yucca_plant(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
if add_item_to_actor(210, use_actor, 1, false, true) == true then
printl("USE_YUCCA_PLANT")
end
end
function use_clay(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
-- delete clay
local location_code = delete_or_remove_object(use_actor, obj, nil)
if add_item_to_actor(132, use_actor, nil, false, false) == true then
printl("USE_CLAY")
end
-- TODO: IF ADD FAILED, PUT CLAY BACK WHERE IT WAS
end
function use_fishing_pole(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
-- Check Deep Water
-- if <<Standing Next to Deep Water>> then
printl("USE_FISHING_POLE_NO_WATER")
-- end
-- Check Success
-- if random() == SUCCESS then
if add_item_to_actor(192, use_actor, nil, false, false) == true then
-- add_item without print
-- if SUCCESS then
printl("USE_FISHING_POLE_SUCCESS")
end
-- end
printl("USE_FISHING_POLE_FAIL")
end
function use_digging_stick(obj, actor)
local use_actor = check_can_reach(obj, actor, true)
if use_actor == nil then
return
end
-- Check Water
-- if <<Standing Next to Water>> then
printl("USE_DIGGING_STICK_NO_WATER")
-- end
if add_item_to_actor(192, use_actor, 1, false, true) == true then
printl("USE_DIGGING_STICK")
end
end
local usecode_table = {
[61]=use_corn_stalk,
[131]=use_digging_stick,
[192]=use_clay,
[212]=use_fishing_pole,
[5000]=use_tree,
[108]=use_tree,
[5001]=use_oven_or_fire,
[5002]=use_yucca_plant,
--[[
[62]=use_bean_stalk,
--[127]=use_bamboo_plant, -- confirmed
[132]=use_soft_clay_pot, -- confirmed
[133]=use_fired_clay_pot, -- confirmed
[134]=use_cloth_strip, -- confirmed
[191]=use_tarred_cloth_strip, -- confirmed
[210]=use_flax, -- confirmed
]]--
--[[
[10]=use_magnesium_ribbon, -- confirmed
[12]=use_paddle, -- confirmed
[20]={["on"]=use_rope},
[25]={["on"]=use_cutting_tool}, -- confirmed (obsidian knife)
[29]=use_rock_hammer, -- confirmed (rock hammer)
[42]=use_vine, -- confirmed (vine)
[44]={["on"]=use_cutting_tool}, -- confirmed (knife)
[47]=use_turtle_bait,
[51]=use_camera,
[52]={["on"]=use_cutting_tool}, -- confirmed (scissors)
[54]={["on"]=use_chocolatl}, --Original required using totem on reagent
[55]={["on"]=use_pinde}, -- confirmed
[56]={["on"]=use_yopo}, -- confirmed
[59]=use_grinding_stone, -- confirmed (mortar)
[60]=use_grinding_stone, -- confirmed (grinding stone)
[63]=use_jug_of_platcha,
[64]=use_torch,
[75]=standing_torch, -- confirmed (almost certainly can't use)
[86]=use_heluzz, -- confirmed
[87]=use_motazz, -- confirmed
[88]=use_aphazz, -- confirmed
[93]=use_corn_meal,
[94]=use_fire_extinguisher, -- confirmed
[102]=use_tortilla, -- confirmed
[108]=use_corn, -- confirmed
[118]=use_fire_axe, -- confirmed
[119]=use_metal_hammer, -- confirmed
[128]=use_bamboo_pole, -- confirmed
[136]=use_metal_bucket, -- confirmed
[137]=use_grenade, -- confirmed
[153]=use_vine(corn_stalk)???, -- confirmed
[206]=use_tree_branch, -- confirmed
[208]=use_torch,
[240]=use_device, -- confirmed Explosive Device
[267]=use_device2 -- confirmed Compass Device? USE?
]]--
}
function has_usecode(obj, usecode_type)
if usecode_type == USE_EVENT_USE and usecode_table[obj.obj_n] ~= nil then
return true
end
return false
end
function use_obj(obj, actor)
if type(usecode_table[obj.obj_n]) == "function" then
local func = usecode_table[obj.obj_n]
if func ~= nil then
print("\n")
func(obj, actor)
end
else
use_obj_on(obj, actor, usecode_table[obj.obj_n])
end
end
function move_obj(obj, rel_x, rel_y)
return false
end
function is_ranged_select(operation)
return false
end

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,517 @@
local g_img_tbl = {}
local START_YEAR = 161
local START_MONTH = 7
local START_DAY = 4
local function wait_for_input()
local input = nil
while input == nil do
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
return input
end
local g_pal_counter = 0
local star_field = nil
local function stones_rotate_palette()
if g_pal_counter == 4 then
canvas_rotate_palette(16, 16)
g_pal_counter = 0
else
g_pal_counter = g_pal_counter + 1
end
end
local function rotate_and_wait()
local input = nil
while input == nil do
image_update_effect(star_field.image)
stones_rotate_palette()
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
end
local function update_star_field_and_wait()
local input = nil
while input == nil do
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
break
end
end
end
local function play()
canvas_set_opacity(0xff);
mouse_cursor_visible(false)
g_img_tbl = image_load_all("end.shp")
music_play("brit.m")
--[ [
canvas_set_palette("endpal.lbm", 0)
canvas_set_update_interval(25)
sprite_new(g_img_tbl[7], 0, 0, true)--bg
image_set_transparency_colour(g_img_tbl[0], 0)
star_field = sprite_new(image_new_starfield(114,94), 106, 0, false)
star_field.clip_x = 106
star_field.clip_y = 0
star_field.clip_w = 107
star_field.clip_h = 84
image_update_effect(star_field.image)
local codex = sprite_new(g_img_tbl[1], 0x97, 0x1d, false)
local codex_opened = sprite_new(g_img_tbl[2], 0x85, 0x17, false)
local wall_transparent = sprite_new(g_img_tbl[0], 106, 0, false)--wall
local wall = sprite_new(g_img_tbl[4], 106, 0, true)--wall
moongate = sprite_new(g_img_tbl[3], 9, 0x7d, true)--moongate
moongate.clip_x = 0
moongate.clip_y = 0
moongate.clip_w = 320
moongate.clip_h = 0x7e
local characters = sprite_new(g_img_tbl[8], 0, 0, false)
characters.clip_x = 0
characters.clip_y = 0
characters.clip_w = 160
characters.clip_h = 200
local characters1 = sprite_new(g_img_tbl[9], 0, 0, false)
characters1.clip_x = 0
characters1.clip_y = 0
characters1.clip_w = 160
characters1.clip_h = 200
local blue_lens = sprite_new(g_img_tbl[5], 0x49, 0x57, true)--lens
local red_lens = sprite_new(g_img_tbl[6], 0xda, 0x57, true)--lens
local scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "A glowing portal springs from the floor!", 7, 303, 34, 13, 0x3e)
local scroll = sprite_new(scroll_img, 1, 0xa0, true)
local input
local i
for i=0x7d,-0xc,-1 do
stones_rotate_palette()
moongate.y = i
canvas_update()
input = input_poll()
if input ~= nil then
moongate.y = -0xc
break
end
end
rotate_and_wait()
characters.visible = true
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "From its crimson depths Lord British emerges, trailed by the mage Nystul. Anguish and disbelief prevail on the royal seer's face, but Lord British directs his stony gaze at you and speaks as if to a wayward child.", 8, 303, 7, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
rotate_and_wait()
scroll_img = image_load("end.shp", 0xc)
image_print(scroll_img, "\"Thou didst have just cause to burgle our Codex, I trust\127 His Majesty says. \"But for Virtue's sake...", 8, 303, 7, 12, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x97
for i=-0xc,0x7d,1 do
stones_rotate_palette()
moongate.y = i
canvas_update()
input = input_poll()
if input ~= nil then
moongate.y = 0x7d
break
end
end
moongate.visible = false
wait_for_input()
scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "\"WHAT HAST THOU DONE WITH IT?\127", 8, 303, 63, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x0
scroll.y = 0xa0
wait_for_input()
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "You pick up the concave lens and pass it to the King. \"Was the book ever truly ours, Your Majesty? Was it written for Britannia alone? Thou dost no longer hold the Codex, but is its wisdom indeed lost? Look into the Vortex, and let the Codex answer for itself!\127", 8, 303, 7, 8, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
wait_for_input()
blue_lens.visible = false
characters.clip_x = 160
characters.clip_w = 160
characters.visible = false
characters1.visible = true
wait_for_input()
scroll_img = image_load("end.shp", 0xc)
image_print(scroll_img, "As Lord British holds the glass before the wall, the Codex of Ultimate Wisdom wavers into view against a myriad of swimming stars!", 8, 303, 7, 12, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x97
star_field.visible = true
wall_transparent.visible = true
for i=0xff,0,-3 do
wall.opacity = i
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
wall.opacity = 0
break
end
end
codex.opacity = 0
codex.visible = true
for i=0,0xff,3 do
codex.opacity = i
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
codex.opacity = 0xff
break
end
end
update_star_field_and_wait()
scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "Yet the book remains closed.", 8, 303, 70, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x0
scroll.y = 0xa0
update_star_field_and_wait()
music_play("gargoyle.m")
scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "And waves of heat shimmer in the air, heralding the birth of another red gate!", 8, 303, 7, 9, 0x3e)
scroll.image = scroll_img
scroll.x = 0x0
scroll.y = 0x98
moongate.x = 0xe6
moongate.y = 0x7d
moongate.visible = true
for i=0x7d,-0xc,-1 do
image_update_effect(star_field.image)
stones_rotate_palette()
moongate.y = i
canvas_update()
input = input_poll()
if input ~= nil then
moongate.y = -0xc
break
end
end
rotate_and_wait()
characters.visible = true
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "King Draxinusom of the Gargoyles strides forward, flanked by a small army of wingless attendants. Like Lord British, he seems to suppress his rage only through a heroic effort of will. His scaly hand grasps your shoulder, and your Amulet of Submission grows very warm.", 8, 303, 7, 8, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
rotate_and_wait()
scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "\"Thy time hath come, Thief,\127 he says.", 8, 303, 46, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x0
scroll.y = 0xa0
for i=-0xc,0x7d,1 do
image_update_effect(star_field.image)
stones_rotate_palette()
moongate.y = i
canvas_update()
input = input_poll()
if input ~= nil then
moongate.y = 0x7d
break
end
end
moongate.visible = false
update_star_field_and_wait()
scroll_img = image_load("end.shp", 0xb)
image_print(scroll_img, "Quickly you reach down to seize the convex lens...", 8, 310, 5, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x0
scroll.y = 0x98
update_star_field_and_wait()
scroll_img = image_load("end.shp", 0xc)
image_print(scroll_img, "...and you press it into the hand of the towering Gargoyle king, meeting his sunken eyes. \"Join my Lord in his search for peace, I beg thee.\127", 8, 303, 7, 12, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x97
update_star_field_and_wait()
characters.visible = false
characters1.clip_w = 320
red_lens.visible = false
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "At your urging, King Draxinusom reluctantly raises his lens to catch the light. As Lord British holds up his own lens, every eye in the room, human and Gargoyle alike, fixes upon the image of the Codex which shines upon the wall.", 8, 303, 7, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
update_star_field_and_wait()
music_play("end.m")
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "The ancient book opens. Both kings gaze upon its pages in spellbound silence, as the eloquence of Ultimate Wisdom is revealed in the tongues of each lord's domain. You, too, can read the answers the Codex gives...", 8, 303, 7, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
codex_opened.opacity = 0
codex_opened.visible = true
for i=0,0xff,3 do
codex_opened.opacity = i
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
codex_opened.opacity = 0xff
break
end
end
codex.visible = false
update_star_field_and_wait()
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "...and when its wisdom is gleaned, when Lord British and King Draxinusom turn to each other as friends, hating no longer, fearing no more, you know that your mission in Britannia has ended at last.", 8, 303, 7, 13, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x85
update_star_field_and_wait()
scroll.visible = false
for i=0xff,0,-3 do
codex_opened.opacity = i
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
codex_opened.opacity = 0
break
end
end
codex_opened.visible = false
wall.opacity = 0
wall.visible = true
for i=0,0xff,3 do
wall.opacity = i
image_update_effect(star_field.image)
canvas_update()
input = input_poll()
if input ~= nil then
wall.opacity = 0xff
break
end
end
star_field.visible=false
wait_for_input()
for i=0xff,0,-3 do
canvas_set_opacity(i)
canvas_update()
end
canvas_hide_all_sprites()
canvas_set_opacity(0xff)
local num_string = {"zero",
"one",
"two",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"eleven",
"twelve",
"thirteen",
"fourteen",
"fifteen",
"sixteen",
"seventeen",
"eighteen",
"nineteen",
"twenty",
"twenty-one",
"twenty-two",
"twenty-three",
"twenty-four",
"twenty-five",
"twenty-six",
"twenty-seven",
"twenty-eight",
"twenty-nine"
}
local year = clock_get_year()
if year == nil then year = 161 end
local month = clock_get_month()
if month == nil then month = 7 end
local day = clock_get_day()
if day == nil then day = 4 end
local current_days = year * 365 + month * 30 + day
local start_days = START_YEAR * 365 + START_MONTH * 30 + START_DAY
local time = current_days - start_days
local years = math.floor(time / 365)
local months = math.floor((time - years * 365) / 30)
local days = time - (years * 365 + months * 30)
local line1 = ""
if years > 0 then
if years > 29 then
line1 = line1..years.." year"
else
line1 = line1..num_string[years+1].." year"
end
if years > 1 then
line1 = line1.."s"
end
end
if months > 0 then
if line1 ~= "" then
line1 = line1..", "
end
line1 = line1..num_string[months+1].." month"
if months > 1 then
line1 = line1.."s"
end
end
local line2 = ""
if days > 0 or line1 == "" then
if line1 ~= "" then
line1 = line1..","
line2 = "and "
end
line2 = line2..num_string[days+1].." day"
if days ~= 1 then
line2 = line2.."s"
end
end
if line1 == "" then
line1 = "Prophet, in"
else
line1 = "Prophet, in "..line1
end
if string.len(line1.." "..line2) <= 38 and line2 ~= "" then
line1 = line1.." "..line2
line2 = ""
end
if line2 == "" then
line1 = line1.."."
else
line2 = line2.."."
end
local x, y
y=9
scroll_img = image_load("end.shp", 0xa)
image_print(scroll_img, "CONGRATULATIONS", 8, 303, 107, y, 0x3e)
y=y+8
image_print(scroll_img, "Thou hast completed Ultima VI: The False", 8, 303, 34, y, 0x3e)
y=y+8
image_print(scroll_img, line1, 8, 303, math.floor((318-canvas_string_length(line1)) / 2), y, 0x3e)
y=y+8
if line2 ~= "" then
image_print(scroll_img, line2, 8, 303, math.floor((318-canvas_string_length(line2)) / 2), y, 0x3e)
y=y+8
end
image_print(scroll_img, "Report thy feat unto Lord British at Origin", 8, 303, 23, y, 0x3e)
y=y+8
image_print(scroll_img, "Systems!", 8, 303, 132, y, 0x3e)
scroll.image = scroll_img
scroll.x = 0x1
scroll.y = 0x44
scroll.opacity = 0
scroll.visible = true
for i=0,0xff,3 do
scroll.opacity = i
canvas_update()
input = input_poll()
if input ~= nil then
scroll.opacity = 0xff
break
end
end
wait_for_input()
end
play()

View File

@@ -0,0 +1,574 @@
local lua_file = nil
--load common functions
lua_file = nuvie_load("common/common.lua"); lua_file();
SFX_BLOCKED = 0
SFX_HIT = 1
SFX_FOUNTAIN = 2
SFX_DEATH = 3
SFX_RUBBER_DUCK = 4
SFX_BROKEN_GLASS = 5
SFX_BELL = 6
SFX_FIRE = 7
SFX_CLOCK = 8
SFX_PROTECTION_FIELD = 9
SFX_WATER_WHEEL = 10
SFX_MISSLE = 11
SFX_EXPLOSION = 12
SFX_ATTACK_SWING = 13
SFX_SUCCESS = 14
SFX_FAILURE = 15
SFX_CORPSER_DRAGGED_UNDER = 16
SFX_CORPSER_REGURGITATE = 17
SFX_CASTING_MAGIC_P1 = 18
SFX_CASTING_MAGIC_P1_2 = 19
SFX_CASTING_MAGIC_P1_3 = 20
SFX_CASTING_MAGIC_P1_4 = 21
SFX_CASTING_MAGIC_P1_5 = 22
SFX_CASTING_MAGIC_P1_6 = 23
SFX_CASTING_MAGIC_P1_7 = 24
SFX_CASTING_MAGIC_P1_8 = 25
SFX_CASTING_MAGIC_P2 = 26
SFX_CASTING_MAGIC_P2_2 = 27
SFX_CASTING_MAGIC_P2_3 = 28
SFX_CASTING_MAGIC_P2_4 = 29
SFX_CASTING_MAGIC_P2_5 = 30
SFX_CASTING_MAGIC_P2_6 = 31
SFX_CASTING_MAGIC_P2_7 = 32
SFX_CASTING_MAGIC_P2_8 = 33
SFX_AVATAR_DEATH = 34
SFX_KAL_LOR = 35
SFX_SLUG_DISSOLVE = 36
SFX_HAIL_STONE = 37
SFX_EARTH_QUAKE = 39
FADE_COLOR_RED = 12
FADE_COLOR_BLUE = 9
TIMER_LIGHT = 0
TIMER_INFRAVISION = 1
TIMER_STORM = 13
TIMER_TIME_STOP = 14
TIMER_ECLIPSE = 15
OBJLIST_OFFSET_VANISH_OBJ = 0x1c13
OBJLIST_OFFSET_MOONSTONES = 0x1c1b
OBJLIST_OFFSET_KEG_TIMER = 0x1c4b
g_vanish_obj = {["obj_n"] = 0, ["frame_n"] = 0}
g_keg_timer = 0
g_armageddon = false
g_avatar_died = false -- used so we don't keep casting once Avatar is dead
function is_avatar_dead()
return g_avatar_died
end
--used with triple crossbow and magic wind spells.
g_projectile_offset_tbl =
{
{
4,5,5,5,5,6,6,6,6,6,6,
4,4,5,5,5,6,6,6,6,6,7,
4,4,4,5,5,6,6,6,6,7,7,
4,4,4,4,5,6,6,6,7,7,7,
4,4,4,4,4,6,6,7,7,7,7,
4,4,4,4,4,0,0,0,0,0,0,
3,3,3,3,2,2,0,0,0,0,0,
3,3,3,2,2,2,1,0,0,0,0,
3,3,2,2,2,2,1,1,0,0,0,
3,2,2,2,2,2,1,1,1,0,0,
2,2,2,2,2,2,1,1,1,1,0
},
{
2,2,2,2,2,2,3,3,3,3,4,
1,2,2,2,2,2,3,3,3,4,4,
1,1,2,2,2,2,3,3,4,4,4,
1,1,1,2,2,2,3,4,4,4,4,
1,1,1,1,2,2,4,4,4,4,4,
0,0,0,0,0,0,4,4,4,4,4,
0,0,0,0,0,6,6,5,5,5,5,
0,0,0,0,7,6,6,6,5,5,5,
0,0,0,7,7,6,6,6,6,5,5,
0,0,7,7,7,6,6,6,6,6,5,
0,7,7,7,7,6,6,6,6,6,6
}
}
--moonstone data is loaded from objlist in load_game()
g_moonstone_loc_tbl =
{
{x=0x3A7, y=0x106, z=0},
{x=0x1F7, y=0x166, z=0},
{x=0x9F, y=0x3AE, z=0},
{x=0x127, y=0x26, z=0},
{x=0x33F, y=0x0A6, z=0},
{x=0x147, y=0x336, z=0},
{x=0x17, y=0x16, z=1},
{x=0x397, y=0x3A6, z=0}
}
g_show_stealing = config_get_boolean_value("config/ultima6/show_stealing")
-- some common functions
function set_g_show_stealing(stealing)
g_show_stealing = stealing
end
function dbg(msg_string)
--io.stderr:write(msg_string)
end
function alignment_is_evil(align)
if align == ALIGNMENT_EVIL or align == ALIGNMENT_CHAOTIC then return true end
return false
end
function advance_game_time(nturns)
if nturns == 0 then return end
coroutine.yield("adv_game_time", nturns);
end
function get_obj_from_inventory(actor)
local obj = coroutine.yield("inv_obj", actor)
return obj
end
function get_obj()
local obj = coroutine.yield("obj")
return obj
end
function actor_talk(actor)
coroutine.yield("talk", actor)
return
end
function get_spell()
local spell_num = coroutine.yield("spell")
return spell_num
end
function obj_new(obj_n, frame_n, status, qty, quality, x, y, z)
local obj = {}
obj["obj_n"] = obj_n or 0
obj["frame_n"] = frame_n or 0
obj["status"] = status or 0
obj["qty"] = qty or 0
obj["quality"] = quality or 0
obj["x"] = x or 0
obj["y"] = y or 0
obj["z"] = z or 0
return obj
end
--FIXME need a better way of doing this. Remove need for deprecated setfenv() function.
function run_script(script)
local t = {};
setmetatable(t, {__index = _G});
local body = nuvie_load(script);
setfenv(body, t);
body();
end
function look_obj(obj)
print("Thou dost see " .. obj.look_string);
local weight = obj.weight; --FIXME this could be a problem if we want to change Lua_number type to int.
if weight ~= 0 then
if obj.qty > 1 and obj.stackable then
print(". They weigh");
else
print(". It weighs");
end
print(string.format(" %.1f", weight).." stones");
end
--FIXME usecode look description should be lua code.
if usecode_look(obj) then
print("\n")
return false
end
local dmg = weapon_dmg_tbl[obj.obj_n];
if dmg ~= nil then
if weight ~= 0 then
print(" and")
else
print(". It")
end
print(" can do "..dmg.." point")
if dmg > 1 then print("s") end
print(" of damage")
end
local ac = armour_tbl[obj.obj_n]
if ac ~= nil then
if weight ~= 0 or dmg ~= 0 then
print(" and")
else
print(". It")
end
print(" can absorb "..ac.." point")
if ac > 1 then print("s") end
print(" of damage")
end
print(".\n");
local player_loc = player_get_location();
if g_show_stealing == true and obj.getable == true and player_loc.z == 0 and obj.ok_to_take == false then
if math.abs(player_loc.x - obj.x) > 1 or math.abs(player_loc.y - obj.y) > 1 then
print("PRIVATE PROPERTY\n")
else
print("PRIVATE PROPERTY")
end
end
return true
end
function player_subtract_karma(k)
local karma = player_get_karma() - k
if karma < 0 then karma = 0 end
player_set_karma(karma)
end
function player_add_karma(k)
local karma = player_get_karma() + k
if karma >= 100 then karma = 99 end
player_set_karma(karma)
end
function party_heal()
for actor in party_members() do
actor.asleep = false
actor.poisoned = false
actor.paralyzed = false
actor_remove_charm(actor)
actor.hp = actor.max_hp
end
end
function explosion(tile_num, x, y)
play_sfx(SFX_EXPLOSION)
return explosion_start(tile_num, x, y)
end
function projectile(tile_num, start_x, start_y, end_x, end_y, speed, spin)
if spin == nil then spin = 0 end
local rotate_offset = 0
local src_tile_y_offset = 0
if tile_num == 547 then --spear
rotate_offset = 45
elseif tile_num == 566 then --bow
rotate_offset = 90
src_tile_y_offset = 4
elseif tile_num == 567 then --crossbow
rotate_offset = 90
src_tile_y_offset = 3
end
play_sfx(SFX_MISSLE)
projectile_anim(tile_num, start_x, start_y, end_x, end_y, speed, false, rotate_offset, spin, src_tile_y_offset)
end
function fade_obj_blue(obj)
fade_obj(obj, FADE_COLOR_BLUE, 20)
end
function fade_actor_blue(actor)
Actor.black_fade_effect(actor, FADE_COLOR_BLUE, 20)
end
function fade_obj_out(obj)
obj.invisible = true
fade_tile(obj.x, obj.y, obj.z, obj.tile_num)
obj.invisible = false
end
function fade_obj_in(obj)
obj.invisible = true
fade_tile(obj.x, obj.y, obj.z, nil, obj.tile_num)
obj.invisible = false
end
function fade_actor_in(actor)
local new_tile_num = actor.tile_num
actor.visible = false
fade_tile(actor.x, actor.y, actor.z, nil, new_tile_num)
actor.visible = true
end
--tile_num, readied location
local g_readiable_objs_tbl = {
[0x200] = 0, [0x201] = 0, [0x202] = 0, [0x203] = 0, [0x204] = 0, [0x205] = 0, [0x206] = 0, [0x207] = 0,
[0x219] = 1, [0x250] = 1, [0x251] = 1, [0x252] = 1, [0x217] = 1, [0x101] = 1,
[0x220] = 2, [0x221] = 2, [0x223] = 2, [0x224] = 2, [0x225] = 2, [0x226] = 2, [0x227] = 2, [0x22A] = 2,
[0x22F] = 2, [0x230] = 2, [0x238] = 2, [0x254] = 2, [0x256] = 2, [0x255] = 2, [0x259] = 2, [0x262] = 2,
[0x263] = 2, [0x264] = 2, [0x270] = 2, [0x271] = 2, [0x272] = 2, [0x273] = 2, [0x274] = 2, [0x275] = 2,
[0x279] = 2, [0x27D] = 2, [0x27E] = 2, [0x27F] = 2, [0x280] = 2, [0x281] = 2, [0x28C] = 2, [0x28E] = 2,
[0x29D] = 2, [0x2A2] = 2, [0x2A3] = 2, [0x2B9] = 2,
[0x210] = 4, [0x211] = 4, [0x212] = 4, [0x213] = 4, [0x214] = 4, [0x215] = 4, [0x216] = 4, [0x218] = 4,
[0x219] = 4, [0x28c] = 4, [0x28e] = 4, [0x29d] = 4, [0x257] = 4,
[0x208] = 5, [0x209] = 5, [0x20a] = 5, [0x20b] = 5, [0x20c] = 5, [0x20d] = 5, [0x20e] = 5, [0x20f] = 5,
[0x222] = 5,
[0x21a] = 7, [0x21b] = 7,
[0x228] = 8, [0x229] = 8, [0x231] = 8, [0x235] = 8, [0x22b] = 8, [0x22c] = 8, [0x22d] = 8, [0x22e] = 8,
[0x258] = 9, [0x37d] = 9, [0x37e] = 9, [0x37f] = 9
}
function actor_is_readiable_obj(actor)
if g_readiable_objs_tbl[actor.tile_num] ~= nil then
return true
end
return false
end
function obj_is_readiable(obj)
if g_readiable_objs_tbl[obj.tile_num] ~= nil then
return true
end
return false
end
function is_time_stopped()
if timer_get(TIMER_TIME_STOP) ~= 0 then return true end
return false
end
function load_game()
objlist_seek(OBJLIST_OFFSET_VANISH_OBJ)
local tmp_obj_dat = objlist_read2()
local obj_n = tmp_obj_dat
local frame_n = 0
if tmp_obj_dat > 1023 then
frame_n = tmp_obj_dat - 1023
obj_n = tmp_obj_dat - frame_n
end
g_vanish_obj.obj_n = obj_n
g_vanish_obj.frame_n = frame_n
--Load moonstone locations.
objlist_seek(OBJLIST_OFFSET_MOONSTONES)
for i=1,8 do
local x = objlist_read2()
local y = objlist_read2()
local z = objlist_read2()
dbg("moonstone["..i.."] at ("..x..","..y..","..z..")\n")
g_moonstone_loc_tbl[i] = {x=x, y=y, z=z}
end
objlist_seek(OBJLIST_OFFSET_KEG_TIMER)
g_keg_timer = objlist_read2()
set_g_armageddon(false)
g_avatar_died = false
end
function save_game()
objlist_seek(OBJLIST_OFFSET_VANISH_OBJ)
local tmp_obj_dat = g_vanish_obj.obj_n
local frame_n = g_vanish_obj.frame_n
if frame_n > 0 then
tmp_obj_dat = tmp_obj_dat + (frame_n + 1023)
end
objlist_write2(tmp_obj_dat)
--Save moonstone locations
objlist_seek(OBJLIST_OFFSET_MOONSTONES)
for i=1,8 do
local loc = g_moonstone_loc_tbl[i]
objlist_write2(loc.x)
objlist_write2(loc.y)
objlist_write2(loc.z)
end
objlist_seek(OBJLIST_OFFSET_KEG_TIMER)
objlist_write2(g_keg_timer)
end
function moonstone_set_loc(phase, x, y, z)
if phase < 1 or phase > 8 then return false end
g_moonstone_loc_tbl[phase] = {x=x, y=y, z=z}
return true
end
function moonstone_get_loc(phase)
if phase < 1 or phase > 8 then return nil end
return g_moonstone_loc_tbl[phase]
end
function update_moongates(show_moongates)
local i, loc
for i,loc in ipairs(g_moonstone_loc_tbl) do
local moongate = map_get_obj(loc.x, loc.y, loc.z, 0x55) --moongate
if show_moongates == true then
if moongate == nil and loc.x ~= 0 then
moongate = Obj.new(0x55, 1)
Obj.moveToMap(moongate, loc)
end
else --hide moongate
if moongate ~= nil then
map_remove_obj(moongate)
end
end
end
end
function use_keg(obj)
if obj.frame_n ~= 0 then
print("\nNo effect\n")
return
end
if g_keg_timer > 0 then
print("\nNot now\n")
else
obj.frame_n = 1
print("\nPowder lit!\n")
g_keg_timer = 3
end
end
function explode_keg()
--try to find lit keg on the current game map.
local loc = player_get_location()
for obj in find_obj(loc.z, 223, 1) do --keg obj, frame_n = 1
if obj ~= nil then
explode_obj(obj)
end
end
--try to explode lit kegs in the party's inventory
local party_actor
for party_actor in party_members() do
local obj = Actor.inv_get_obj_n(party_actor, 223, 1) --keg with frame_n = 1
if obj ~= nil then
explode_obj(obj, party_actor)
end
end
end
function explode_obj(obj, actor)
dbg("Exploding "..obj.name.."\n")
local x, y, z
if actor ~= nil then
x = actor.x
y = actor.y
z = actor.z
else
x = obj.x
y = obj.y
z = obj.z
end
Obj.removeFromEngine(obj)
local hit_items = explosion(0x189, x, y)
local random = math.random
local k, v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
actor_hit(v, random(1, 0x3c))
end
if g_avatar_died == true then
explode_surrounding_objects(x, y, z)
actor_avatar_death(Actor.get(1))
return -- don't keep exploding once Avatar is dead
end
end
explode_surrounding_objects(x, y, z)
end
function explode_surrounding_objects(x, y, z)
--blow up doors and other kegs
for x = x - 2,x + 2 do
for y = y - 2,y + 2 do
local map_obj = map_get_obj(x, y, z, 223)
if map_obj ~= nil then
explode_obj(map_obj)
end
map_obj = map_get_obj(x, y, z, 0x12c) --steel door
if map_obj == nil or map_obj.frame_n == 0xc then
map_obj = map_get_obj(x, y, z, 0x129) --oaken door
if map_obj == nil or map_obj.frame_n == 0xc then
map_obj = map_get_obj(x, y, z, 0x12a) --windowed door
if map_obj == nil or map_obj.frame_n == 0xc then
map_obj = map_get_obj(x, y, z, 0x12b) --cedar door
end
end
end
if map_obj ~= nil and map_obj.frame_n <= 0xc then
Obj.removeFromEngine(map_obj)
print("\nThe door is blown up!\n")
end
end
end
end
function set_g_armageddon(val)
g_armageddon = val
set_armageddon(val)
end
function create_object_needs_quan(obj_n)
-- obj.stackable is already checked
return false
end
--load actor functions
actor_load = nuvie_load("u6/actor.lua");
if type(actor_load) == "function" then
actor_load()
else
if type(actor_load) == "string" then
io.stderr:write(actor_load);
end
end
-- init magic
magic_init = nuvie_load("u6/magic.lua"); magic_init();
-- init usecode
usecode_init = nuvie_load("u6/usecode.lua"); usecode_init();
player_init = nuvie_load("u6/player.lua"); player_init();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
return {
PASS="Pass!\n",
}

View File

@@ -0,0 +1,558 @@
--io.stderr:write("Magic init\n");
magic_syllable_tbl = {a = "An", b = "Bet", c = "Corp", d = "Des", e = "Ex", f = "Flam", g = "Grav", h = "Hur",
i = "In", j = "Jux", k = "Kal", l = "Lor", m = "Mani", n = "Nox", o = "Ort", p = "Por",
q = "Quas", r = "Rel", s = "Sanct", t = "Tym", u = "Uus", v = "Vas", w = "Wis", x = "Xen",
y = "Ylem", z = "Zu"}
magic = {}
magic_invocations = {}
function magic_print_invocation_string(spell_num)
local i
local invocation = magic_spell_invocation(spell_num)
for i = 1,#invocation do
if i ~= 1 then
print(" ")
end
print(magic_syllable_tbl[string.sub(invocation, i, i)])
end
end
run_magic_script = function(invocation)
local spell_num = magic_invocations[invocation]
if spell_num == nil then
--io.stderr:write("No magic script found for invocation \"" .. invocation .. "\"\n");
return
end
--io.stderr:write("Running script \"" .. magic_invocations[invocation].script .."\"\n");
--run_script(magic_invocations[invocation].script)
magic_cast_spell(spell_num, nil, nil)
return
end
g_magic_target = nil
g_magic_caster = nil
g_magic_spell_num = nil
function magic_cast_spell(spell_num, caster, target)
g_magic_target = target
g_magic_caster = caster
g_magic_spell_num = spell_num
if magic[spell_num+1] ~= nil then
run_script(magic[spell_num+1].script)
end
g_magic_caster = nil
g_magic_target = nil
if g_avatar_died == true then
actor_avatar_death()
end
end
function magic_spell_name(spell_num)
if magic[spell_num+1] ~= nil then
return magic[spell_num+1].name
end
return "Unknown"
end
function magic_spell_invocation(spell_num)
if magic[spell_num+1] ~= nil then
return magic[spell_num+1].invocation
end
return ""
end
function magic_get_spell_list()
local list = {}
local insert = table.insert
local k,v
for k,v in pairs(magic) do
insert(list, v)
end
return list
end
magic_init = function(name, invocation, reagents, circle, num, script)
local spell_num = (circle-1) * 16 + (num-1);
local spell = {name=name,invocation=invocation,reagents=reagents,circle=circle,spell_num=spell_num,script=script}
magic[spell_num+1] = spell
magic_invocations[string.lower(invocation)] = spell_num
--io.stderr:write("Init Magic: " .. name .. " I: " .. invocation .. "\n")
end
function select_location_with_prompt(prompt)
if g_magic_target ~= nil then return g_magic_target end
print(prompt)
return get_target()
end
function select_location()
return select_location_with_prompt("Location: ")
end
select_actor = function()
if g_magic_target ~= nil then return map_get_actor(g_magic_target) end
print("On whom: ");
local loc = get_target()
local actor
if loc ~= nil then
actor = map_get_actor(loc)
end
if actor == nil then
print("nothing\n");
else
print(actor.name.."\n");
if out_of_spell_range(actor.x, actor.y) then return end
end
return actor
end
select_obj = function()
if g_magic_target ~= nil then return map_get_obj(g_magic_target) end
print("On what: ");
local obj = get_obj()
if obj == nil then
print("nothing\n");
else
print(obj.name .. "\n");
if obj.on_map and out_of_spell_range(obj.x, obj.y) then return end
end
return obj
end
function select_actor_or_obj()
if g_magic_target ~= nil then return map_get_obj(g_magic_target) end
local is_player = caster_is_player()
local loc = select_location_with_prompt("On Whom: ")
local actor = map_get_actor(loc)
local obj
if actor == nil then
obj = map_get_obj(loc)
actor = obj
if is_player == true then
if obj ~= nil then
print(obj.name.."\n")
else
print("nothing\n")
end
end
elseif is_player == true then
print(actor.name.."\n")
end
magic_casting_fade_effect(caster)
if loc == nil or actor == nil then magic_no_effect() return end
if (obj == nil or obj.on_map) and out_of_spell_range(loc.x, loc.y) then return end
return actor
end
function select_actor_with_projectile(projectile_tile, caster)
if caster == nil then caster = magic_get_caster() end
local is_player = caster_is_player()
local loc = select_location_with_prompt("On Whom: ")
local actor = map_get_actor(loc)
if actor == nil then
local obj = map_get_obj(loc)
if is_player == true then
if obj ~= nil then
print(obj.name.."\n")
else
print("nothing\n")
end
end
elseif is_player == true then
print(actor.name.."\n")
end
magic_casting_fade_effect(caster)
if loc == nil then magic_no_effect() return end
if out_of_spell_range(loc.x, loc.y) then return end
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
projectile(projectile_tile, caster.x, caster.y, hit_x, hit_y, 4)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
if actor == nil then magic_no_effect() return end
return actor
end
function select_actor_or_obj_with_projectile(projectile_tile, caster)
if caster == nil then caster = magic_get_caster() end
local loc = select_location_with_prompt("On what: ")
local item = map_get_actor(loc)
if item == nil then
item = map_get_obj(loc)
end
if item ~= nil then
print(item.name)
else
print("nothing")
end
print("\n")
magic_casting_fade_effect(caster)
if loc == nil then magic_no_effect() return end
if out_of_spell_range(loc.x, loc.y) then return end
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
projectile(projectile_tile, caster.x, caster.y, hit_x, hit_y, 4)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
if item == nil then magic_no_effect() return end
return item
end
function select_obj_with_projectile(projectile_tile, caster)
if caster == nil then caster = magic_get_caster() end
local loc = select_location_with_prompt("On What: ")
local obj = map_get_obj(loc)
if obj == nil then
print("nothing\n");
else
print(obj.name.."\n");
end
magic_casting_fade_effect(caster)
if loc == nil then magic_no_effect() return end
if out_of_spell_range(loc.x, loc.y) then return end
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
projectile(projectile_tile, caster.x, caster.y, hit_x, hit_y, 4)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
if obj == nil then magic_no_effect() return end
return obj
end
function select_location_with_projectile(projectile_tile, caster)
if caster == nil then caster = magic_get_caster() end
local loc = select_location_with_prompt("Location: ")
magic_casting_fade_effect(caster)
if loc == nil then magic_no_effect() return end
if out_of_spell_range(loc.x, loc.y) then return end
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
projectile(projectile_tile, caster.x, caster.y, hit_x, hit_y, 4)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
return loc
end
function select_spell()
return get_spell()
end
function out_of_spell_range(target_x, target_y)
if Actor.get_range(magic_get_caster(), target_x, target_y) > 7 then
print("\nout of range\n")
return true
else
return false
end
end
function caster_get_location()
if g_magic_caster ~= nil then
return {x = g_magic_caster.x, y = g_magic_caster.y, z = g_magic_caster.z}
end
return player_get_location()
end
function magic_get_caster()
if g_magic_caster ~= nil then return g_magic_caster end
return Actor.get_player_actor()
end
function caster_is_player()
if g_magic_caster == nil then return true end
return false
end
function magic_casting_effect()
local magic_level = math.floor(g_magic_spell_num / 0x10);
play_sfx(SFX_CASTING_MAGIC_P1 + magic_level, true)
play_sfx(SFX_CASTING_MAGIC_P2 + magic_level)
xor_effect(1700)
end
function magic_casting_fade_effect(caster)
if caster == nil then caster = magic_get_caster() end
Actor.black_fade_effect(caster, 12, 20) -- 12 = colour red. 20 = fade_speed
end
function magic_remove_actor_enchantments(actor)
local success = false
fade_actor_blue(actor)
if actor.asleep == true then
actor.asleep = false
success = true
end
if actor.poisoned == true then
actor.poisoned = false
success = true
end
if actor.paralysed == true then
actor.paralyzed = false
success = true
end
if actor_remove_charm(actor) == true then
success = true
end
return success
end
function magic_wind(tile_num, caster, target_x, target_y)
local target_z = caster.z
local index = ((caster.y - target_y + 5) * 11) + (caster.x - target_x + 5) + 1
local offset_x_low = movement_offset_x_tbl[g_projectile_offset_tbl[1][index]+1]
local offset_x_high = movement_offset_x_tbl[g_projectile_offset_tbl[2][index]+1]
local offset_y_low = movement_offset_y_tbl[g_projectile_offset_tbl[1][index]+1]
local offset_y_high = movement_offset_y_tbl[g_projectile_offset_tbl[2][index]+1]
local targets = {
{x=target_x,
y=target_y,
z=target_z},
{x=target_x + offset_x_low,
y=target_y + offset_y_low,
z=target_z},
{x=target_x + offset_x_low + offset_x_low,
y=target_y + offset_y_low + offset_y_low,
z=target_z},
{x=target_x + offset_x_high,
y=target_y + offset_y_high,
z=target_z},
{x=target_x + offset_x_high + offset_x_high,
y=target_y + offset_y_high + offset_y_high,
z=target_z}
}
return projectile_anim_multi(tile_num, caster.x, caster.y, targets, 3, 1, 0)
end
function magic_wind_spell(spell_num, tile_num)
local caster = magic_get_caster()
local loc = select_location()
if loc == nil then return end
print("\n")
if loc.x == caster.x and loc.y == caster.y then return magic_no_effect() end
local hit_items = magic_wind(tile_num, caster, loc.x, loc.y)
local k, v
for k,v in pairs(hit_items) do
if v.luatype == "actor" and v.actor_num ~= caster.actor_num then
if spell_num == 83 then --flame wind
spell_take_fire_dmg(caster, v)
elseif spell_num == 87 then --poison wind
spell_poison_actor(caster, v)
elseif spell_num == 98 then --energy wind
local exp = actor_hit(v, math.random(1, 0x1e))
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_yell_for_help(caster, v, 1)
actor_hit_msg(v)
elseif spell_num == 113 then --death wind
spell_kill_actor(caster, v)
end
if g_avatar_died == true then
break -- don't keep casting once Avatar is dead
end
end
end
end
function magic_success()
if caster_is_player() then
print("\nSuccess\n")
play_sfx(SFX_SUCCESS)
end
end
function magic_no_effect()
if caster_is_player() then
print("\nNo effect\n")
play_sfx(SFX_FAILURE)
end
end
function magic_blocked()
if caster_is_player() then
print("\nBlocked!\n")
play_sfx(SFX_FAILURE)
end
end
function magic_failed()
if caster_is_player() then
print("\nFailed\n")
play_sfx(SFX_FAILURE)
end
end
function magic_not_possible()
if caster_is_player() then
print("\nNot possible\n")
play_sfx(SFX_FAILURE)
end
end
do
local init
--name, cast directly keys, reagents, level, level index, spell file
--MANDRAKE_ROOT 0x01, NIGHTSHADE 0x02, BLACK_PEARL 0x04, BLOOD_MOSS 0x08, SPIDER_SILK 0x10, GARLIC 0x20, GINSENG 0x40, SULFUROUS_ASH 0x80
--add reagent numbers together for reagents argument
magic_init("Create Food", "imy", 0x61, 1, 1, "u6/magic/circle_01/create_food.lua");
magic_init("Detect Magic", "wo", 0x82, 1, 2, "u6/magic/circle_01/detect_magic.lua");
magic_init("Detect Trap", "wj", 0x82, 1, 3, "u6/magic/circle_01/detect_trap.lua");
magic_init("Dispel Magic", "ajo", 0x60, 1, 4, "u6/magic/circle_01/dispel_magic.lua");
magic_init("Douse", "af", 0x24, 1, 5, "u6/magic/circle_01/douse.lua");
magic_init("Harm", "am", 0x12, 1, 6, "u6/magic/circle_01/harm.lua");
magic_init("Heal", "im", 0x50, 1, 7, "u6/magic/circle_01/heal.lua");
magic_init("Help", "kl", 0x00, 1, 8, "u6/magic/circle_01/help.lua");
magic_init("Ignite", "if", 0x84, 1, 9, "u6/magic/circle_01/ignite.lua");
magic_init("Light", "il", 0x80, 1, 10, "u6/magic/circle_01/light.lua");
magic_init("Infravision", "ql", 0x82, 2, 1, "u6/magic/circle_02/infravision.lua");
magic_init("Magic Arrow", "oj", 0x84, 2, 2, "u6/magic/circle_02/magic_arrow.lua");
magic_init("Poison", "inp", 0x0e, 2, 3, "u6/magic/circle_02/poison.lua");
magic_init("Reappear", "iy", 0x1c, 2, 4, "u6/magic/circle_02/reappear.lua");
magic_init("Sleep", "iz", 0x16, 2, 5, "u6/magic/circle_02/sleep.lua");
magic_init("Telekinesis", "opy", 0x0d, 2, 6, "u6/magic/circle_02/telekinesis.lua");
magic_init("Trap", "ij", 0x12, 2, 7, "u6/magic/circle_02/trap.lua");
magic_init("Unlock Magic", "ep", 0x88, 2, 8, "u6/magic/circle_02/unlock_magic.lua");
magic_init("Untrap", "aj", 0x88, 2, 9, "u6/magic/circle_02/untrap.lua");
magic_init("Vanish", "ay", 0x2c, 2, 10, "u6/magic/circle_02/vanish.lua");
magic_init("Curse", "as", 0xa2, 3, 1, "u6/magic/circle_03/curse.lua");
magic_init("Dispel Field", "ag", 0x84, 3, 2, "u6/magic/circle_03/dispel_field.lua");
magic_init("Fireball", "pf", 0x84, 3, 3, "u6/magic/circle_03/fireball.lua");
magic_init("Great Light", "vl", 0x81, 3, 4, "u6/magic/circle_03/great_light.lua");
magic_init("Lock", "ap", 0xa8, 3, 5, "u6/magic/circle_03/magic_lock.lua");
magic_init("Mass Awaken", "avz", 0x60, 3, 6, "u6/magic/circle_03/mass_awaken.lua");
magic_init("Mass Sleep", "vz", 0x52, 3, 7, "u6/magic/circle_03/mass_sleep.lua");
magic_init("Peer", "vwy", 0x03, 3, 8, "u6/magic/circle_03/peer.lua");
magic_init("Protection", "is", 0xe0, 3, 9, "u6/magic/circle_03/protection.lua");
magic_init("Repel Undead", "axc", 0xa0, 3, 10, "u6/magic/circle_03/repel_undead.lua");
magic_init("Animate", "oy", 0x89, 4, 1, "u6/magic/circle_04/animate.lua");
magic_init("Conjure", "kx", 0x11, 4, 2, "u6/magic/circle_04/conjure.lua");
magic_init("Disable", "avm", 0x13, 4, 3, "u6/magic/circle_04/disable.lua");
magic_init("Fire Field", "ifg", 0x94, 4, 4, "u6/magic/circle_04/fire_field.lua");
magic_init("Great Heal", "vm", 0x51, 4, 5, "u6/magic/circle_04/great_heal.lua");
magic_init("Locate", "iw", 0x02, 4, 6, "u6/magic/circle_04/locate.lua");
magic_init("Mass Dispel", "vajo", 0x60, 4, 7, "u6/magic/circle_04/mass_dispel.lua"); -- The original engine uses 0x16
magic_init("Poison Field", "ing", 0x16, 4, 8, "u6/magic/circle_04/poison_field.lua"); -- The original engine uses 0x54
magic_init("Sleep Field", "izg", 0x54, 4, 9, "u6/magic/circle_04/sleep_field.lua"); -- The original engine uses 0x60
magic_init("Wind Change", "rh", 0x88, 4, 10, "u6/magic/circle_04/wind_change.lua");
magic_init("Energy Field", "isg", 0x15, 5, 1, "u6/magic/circle_05/energy_field.lua");
magic_init("Explosion", "vpf", 0x8d, 5, 2, "u6/magic/circle_05/explosion.lua");
magic_init("Insect Swarm", "kbx", 0x98, 5, 3, "u6/magic/circle_05/insect_swarm.lua");
magic_init("Invisibility", "sl", 0x0a, 5, 4, "u6/magic/circle_05/invisibility.lua");
magic_init("Lightning", "og", 0x85, 5, 5, "u6/magic/circle_05/lightning.lua");
magic_init("Paralyze", "axp", 0x96, 5, 6, "u6/magic/circle_05/paralyze.lua");
magic_init("Pickpocket", "py", 0x1a, 5, 7, "u6/magic/circle_05/pickpocket.lua");
magic_init("Reveal", "asl", 0x13, 5, 8, "u6/magic/circle_05/reveal.lua");
magic_init("Seance", "kmc", 0x9b, 5, 9, "u6/magic/circle_05/seance.lua");
magic_init("X-ray", "wy", 0x81, 5, 10, "u6/magic/circle_05/xray.lua");
magic_init("Charm", "axe", 0x16, 6, 1, "u6/magic/circle_06/charm.lua");
magic_init("Clone", "iqx", 0xdb, 6, 2, "u6/magic/circle_06/clone.lua");
magic_init("Confuse", "vq", 0x03, 6, 3, "u6/magic/circle_06/confuse.lua");
magic_init("Flame Wind", "fh", 0x89, 6, 4, "u6/magic/circle_06/flame_wind.lua");
magic_init("Hail Storm", "kdy", 0x0d, 6, 5, "u6/magic/circle_06/hail_storm.lua");
magic_init("Mass Protect", "vis", 0xe1, 6, 6, "u6/magic/circle_06/mass_protect.lua");
magic_init("Negate Magic", "ao", 0xa1, 6, 7, "u6/magic/circle_06/negate_magic.lua");
magic_init("Poison Wind", "nh", 0x8a, 6, 8, "u6/magic/circle_06/poison_wind.lua");
magic_init("Replicate", "iqy", 0xda, 6, 9, "u6/magic/circle_06/replicate.lua");
magic_init("Web", "idp", 0x10, 6, 10, "u6/magic/circle_06/web.lua");
magic_init("Chain Bolt", "vog", 0x8d, 7, 1, "u6/magic/circle_07/chain_bolt.lua");
magic_init("Enchant", "ioy", 0x91, 7, 2, "u6/magic/circle_07/enchant.lua");
magic_init("Energy Wind", "gh", 0x8b, 7, 3, "u6/magic/circle_07/energy_wind.lua");
magic_init("Fear", "qc", 0x23, 7, 4, "u6/magic/circle_07/fear.lua");
magic_init("Gate Travel", "vrp", 0x85, 7, 5, "u6/magic/circle_07/gate_travel.lua");
magic_init("Kill", "ic", 0x86, 7, 6, "u6/magic/circle_07/kill.lua");
magic_init("Mass Curse", "vas", 0xa3, 7, 7, "u6/magic/circle_07/mass_curse.lua");
magic_init("Mass Invis", "vsl", 0x0f, 7, 8, "u6/magic/circle_07/mass_invisibility.lua");
magic_init("Wing Strike", "kox", 0x99, 7, 9, "u6/magic/circle_07/wing_strike.lua");
magic_init("Wizard Eye", "pow", 0x9f, 7, 10, "u6/magic/circle_07/wizard_eye.lua");
magic_init("Armageddon", "vcbm", 0x00, 8, 1, "u6/magic/circle_08/armageddon.lua");
magic_init("Death Wind", "ch", 0x8b, 8, 2, "u6/magic/circle_08/death_wind.lua");
magic_init("Eclipse", "val", 0xab, 8, 3, "u6/magic/circle_08/eclipse.lua");
magic_init("Mass Charm", "vaxe", 0x17, 8, 4, "u6/magic/circle_08/mass_charm.lua");
magic_init("Mass Kill", "vc", 0x87, 8, 5, "u6/magic/circle_08/mass_kill.lua");
magic_init("Resurrect", "imc", 0xf9, 8, 6, "u6/magic/circle_08/resurrect.lua");
magic_init("Slime", "vrx", 0xb, 8, 7, "u6/magic/circle_08/slime.lua");
magic_init("Summon", "kxc", 0x39, 8, 8, "u6/magic/circle_08/summon.lua");
magic_init("Time Stop", "at", 0x29, 8, 9, "u6/magic/circle_08/time_stop.lua");
magic_init("Tremor", "vpy", 0x89, 8, 10, "u6/magic/circle_08/tremor.lua");
magic_init("Monster Invisible", "", 0x00, 8, 17, "u6/magic/circle_08/monster_invisible.lua");
end
magic_load = nil

View File

@@ -0,0 +1,10 @@
magic_casting_effect()
magic_casting_fade_effect()
local qty = math.random(1,10)
local obj = Obj.new(129,0,0,qty)
Obj.moveToInv(obj, magic_get_caster())
print("\nCreate " .. obj.qty .. " food.\n")

View File

@@ -0,0 +1,58 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj == nil then magic_no_effect() return end
local magical_tiles = {
[0x207] = 1,[0x20F] = 1,[0x216] = 1,[0x22F] = 1,[0x232] = 1,[0x235] = 1,[0x238] = 1,[0x239] = 1,[0x23D] = 1,
[0x248] = 1,[0x249] = 1,[0x24A] = 1,[0x24B] = 1,[0x24C] = 1,[0x24D] = 1,[0x24E] = 1,[0x24F] = 1,[0x251] = 1,
[0x252] = 1,[0x253] = 1,[0x255] = 1,[0x256] = 1,[0x257] = 1,[0x25A] = 1,[0x25B] = 1,[0x25C] = 1,[0x25D] = 1,
[0x25F] = 1,[0x26E] = 1,[0x2B6] = 1,[0x31E] = 1,[0x31F] = 1,[0x326] = 1,[0x368] = 1,[0x369] = 1,[0x36A] = 1,
[0x36B] = 1,[0x36C] = 1,[0x36D] = 1,[0x36E] = 1,[0x36F] = 1,[0x37D] = 1,[0x37E] = 1,[0x37F] = 1,[0x3A8] = 1,
[0x3A9] = 1,[0x3AA] = 1,[0x3AB] = 1,[0x3AC] = 1,[0x3AD] = 1,[0x3AE] = 1,[0x3AF] = 1,[0x3FD] = 1,[0x3FE] = 1,
[0x40C] = 1,[0x40D] = 1,[0x40E] = 1,[0x40F] = 1,[0x41C] = 1,[0x41D] = 1,[0x41E] = 1,[0x41F] = 1,[0x42C] = 1,
[0x42D] = 1,[0x42E] = 1,[0x42F] = 1,[0x43C] = 1,[0x43D] = 1,[0x43E] = 1,[0x43F] = 1,[0x484] = 1,[0x485] = 1,
[0x48E] = 1,[0x48F] = 1,[0x6D0] = 1,[0x6D1] = 1,[0x6D2] = 1,[0x6D3] = 1}
local potion_name = {
[0] = "an awaken",
[1] = "a cure",
[2] = "a heal",
[3] = "a poison",
[4] = "a sleep",
[5] = "a protection",
[6] = "an invisibility",
[7] = "an xray vision",
[8] = "an unknown"
}
fade_obj_blue(obj)
if magical_tiles[obj.tile_num] ~= nil then
--magical object.
if obj.obj_n == 0x113 then
local frame_n = obj.frame_n
if frame_n > 8 then
frame_n = 8
end
print("\nIt's " .. potion_name[frame_n] .. " potion.\n")
else
print("\nIt's magical.\n")
end
else
--not magical
local has_charge = false
local child
for child in container_objs(obj) do -- look through container for effect object.
if child.obj_n == 0x150 then --charge
has_charge = true
print("\nIt shows a charge of " .. magic_spell_name(child.quality) .. ".\n")
break
end
end
if has_charge == false then
print("\nIt's not magical.\n")
end
end

View File

@@ -0,0 +1,30 @@
local caster = magic_get_caster()
local obj = select_obj()
magic_casting_fade_effect(caster)
if obj == nil then magic_no_effect() return end
fade_obj_blue(obj)
local found = false
local dice_roll = math.random(1, 0x1e)
local actor_int = actor_int_adj(caster)
if actor_int >= dice_roll then
local child
for child in container_objs(obj) do -- look through container for effect object.
if child.obj_n == 337 then --effect
found = true
print("\nIt's trapped.\n");
break
end
end
child = nil
end
if found == false then
print("\nNo trap.\n");
end
obj = nil

View File

@@ -0,0 +1,9 @@
local actor = select_actor_with_projectile(0x17f)
if actor == nil then return end
if magic_remove_actor_enchantments(actor) == true then
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,21 @@
local obj = select_obj_with_projectile(0x18b)
if obj == nil then return end
if obj.obj_n == 122 or --candle
obj.obj_n == 145 or --candelabra
obj.obj_n == 164 or --fireplace
obj.obj_n == 90 or --torch
(obj.obj_n == 206 and obj.frame_n == 1) then --flaming brazier
fade_obj_blue(obj)
if obj.frame_n == 1 or obj.frame_n == 3 then
if obj.obj_n == 90 then
Obj.use(obj) -- we want to use usecode to remove the torch
else
obj.frame_n = obj.frame_n - 1;
end
return magic_success()
end
end
return magic_no_effect()

View File

@@ -0,0 +1,8 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
if spell_hit_actor(caster, actor, 5) == false then --5 = harm spell number
magic_failed()
end

View File

@@ -0,0 +1,22 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
fade_actor_blue(actor)
if actor.alive == true then
local hp = actor.hp
local max_hp = actor.max_hp
hp = hp + math.random(1, 0x1e)
if hp > max_hp then
hp = max_hp
end
actor.hp = hp
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,10 @@
magic_casting_effect()
play_sfx(SFX_KAL_LOR, true)
if g_armageddon == false then
party_resurrect_dead_members()
end
party_heal()
player_move(0x133, 0x160, 0, true)
get_LB_to_throne()
fade_in() --FIXME the original fades from current location. We fade from black.

View File

@@ -0,0 +1,25 @@
local obj = select_obj_with_projectile(0x18d)
if obj == nil then return end
if obj.obj_n == 122 or --candle
obj.obj_n == 145 or --candelabra
obj.obj_n == 164 or --fireplace
obj.obj_n == 90 or --torch
(obj.obj_n == 206 and obj.frame_n == 0) then --flaming brazier
fade_obj_blue(obj)
if obj.frame_n == 0 or obj.frame_n == 2 then
if obj.obj_n == 90 then
Obj.use(obj) -- we want to use usecode to remove the torch
else
obj.frame_n = obj.frame_n + 1;
end
return magic_success()
end
elseif obj.obj_n == 0xdf and obj.frame_n == 0 then --unlit keg
use_keg(obj)
return magic_success()
end
return magic_no_effect()

View File

@@ -0,0 +1,3 @@
magic_casting_fade_effect()
magic_casting_effect()
timer_set(TIMER_LIGHT, 0x64)

View File

@@ -0,0 +1,3 @@
magic_casting_fade_effect()
magic_casting_effect()
timer_set(TIMER_INFRAVISION, 0x14)

View File

@@ -0,0 +1,24 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x236, caster)
if actor == nil then return end
local random = math.random
if (((actor_dex_adj(actor) / 2) + 0x1e) - actor_int_adj(caster)) / 2 <= random(1, 0x1e) then
print("\n")
local dmg = random(1, 0xa)
local exp = actor_hit(actor, dmg)
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_hit_msg(actor)
actor_yell_for_help(caster, actor, 1)
else
magic_failed()
end

View File

@@ -0,0 +1,12 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17c, caster)
if actor == nil then return end
local return_val = spell_poison_actor(caster, actor)
if return_val == 2 then
magic_no_effect()
elseif return_val == 1 then
magic_failed()
end

View File

@@ -0,0 +1,25 @@
local caster = magic_get_caster()
local loc = select_location_with_prompt("Location: ")
magic_casting_fade_effect(caster)
if loc == nil or g_vanish_obj.obj_n == 0 then magic_no_effect() return end
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
projectile(0x17f, caster.x, caster.y, hit_x, hit_y, 2)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
local obj = Obj.new(g_vanish_obj.obj_n, g_vanish_obj.frame_n)
obj.qty = 1
obj.status = 0x21 --OK, TEMP
if map_can_put_obj(loc) == false then
magic_no_effect()
else
Obj.moveToMap(obj, loc)
fade_obj_in(obj)
g_vanish_obj.obj_n = 0
g_vanish_obj.frame_n = 0
magic_success()
end

View File

@@ -0,0 +1,12 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17d, caster)
if actor == nil then return end
local ret = spell_put_actor_to_sleep(caster,actor)
if ret == 1 then
magic_failed()
elseif ret == 2 then
magic_no_effect()
end

View File

@@ -0,0 +1,24 @@
local caster = magic_get_caster()
item = select_actor_or_obj_with_projectile(0x17f)
if item == nil then return end
if item.luatype == "obj" then
fade_obj_blue(item)
if item.obj_n == 0x120 or item.obj_n == 0x10c then --crank, lever
Obj.use(item)
elseif item.weight >= 0.01 then
local dir = get_direction("Direction-")
print("`"..direction_string(dir).."\n")
local new_x, new_y = direction_get_loc(dir, item.x, item.y)
if map_can_put_obj(new_x, new_y, item.z) == true then
Obj.moveToMap(item, new_x, new_y, item.z)
else
print("\nBlocked\n")
end
else
print("\nNot Possible\n")
end
else
magic_no_effect() --do nothing with actors.
end

View File

@@ -0,0 +1,34 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj == nil then magic_no_effect() return end
fade_obj_blue(obj)
if (obj.obj_n >= 297 and obj.obj_n <= 300) or obj.obj_n == 98 then -- if door or chest
-- find existing effect in obj container.
local found_effect = false
local child
for child in container_objs(obj) do
if child ~= nil and child.obj_n == 337 then
found_effect = true
end
end
child = nil
--add effect if no existing effect found in container.
if found_effect == false then
local effect = Obj.new(337)
Obj.moveToCont(effect, obj)
effect = nil
obj = nil
return magic_success()
end
end
magic_no_effect()
obj = nil

View File

@@ -0,0 +1,15 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj == nil then magic_no_effect() return end
if obj.obj_n >= 297 and obj.obj_n <= 300 and obj.frame_n >= 13 then --magically locked door
obj.frame_n = obj.frame_n - 8
return print("\nunlocked!\n");
elseif obj.obj_n == 0x62 and obj.frame_n == 3 then --magically locked chest
obj.frame_n = 1
return print("\nunlocked!\n");
end
magic_no_effect()

View File

@@ -0,0 +1,26 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj == nil then magic_no_effect() return end
local found = false
fade_obj_blue(obj)
if (obj.obj_n >= 297 and obj.obj_n <= 300) or obj.obj_n == 98 then -- if door or chest
local child
for child in container_objs(obj) do -- look through container for effect object.
if child.obj_n == 337 then --effect
found = true
Obj.removeFromCont(child)
break
end
end
end
if found == true then
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,16 @@
local caster = magic_get_caster()
local obj = select_obj_with_projectile(0x17f, caster)
if obj == nil then return end
if tile_get_flag(obj.tile_num, 3, 3) == true then
g_vanish_obj.obj_n = obj.obj_n
g_vanish_obj.frame_n = obj.frame_n
fade_obj_out(obj)
map_remove_obj(obj)
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,9 @@
local actor = select_actor_with_projectile(0x17f)
if actor == nil then return end
if is_god_mode_enabled() and actor.in_party then
return
end
actor.cursed = true
magic_success()

View File

@@ -0,0 +1,22 @@
-- Dispel Field, An Grav
-- 317 Fire Field
-- 318 Poison Field
-- 319 Protection Field
-- 320 Sleep Field
local obj = select_obj_with_projectile(0x17f)
if obj == nil then return end
if obj.obj_n >= 317 and obj.obj_n <= 320 then
hit_anim(obj.x, obj.y)
map_remove_obj(obj)
obj = nil
return magic_success()
end
obj = nil
magic_no_effect()

View File

@@ -0,0 +1,6 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17e, caster)
if actor == nil then return end
spell_take_fire_dmg(caster, actor)

View File

@@ -0,0 +1,3 @@
magic_casting_fade_effect()
magic_casting_effect()
timer_set(TIMER_LIGHT, 0xff)

View File

@@ -0,0 +1,25 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj == nil then magic_no_effect() return end
if obj.obj_n >= 297 and obj.obj_n <= 300 then
if obj.frame_n <= 7 then
if obj.frame_n <= 3 then
print("\nCan't (Un)lock an opened door\n")
else
--FIXME need to handle a door which is already magically locked.
if obj.frame_n >= 5 and obj.frame_n <= 7 then
obj.frame_n = obj.frame_n + 8
print("\nmagically locked!\n")
end
end
magic_success()
end
elseif obj.obj_n == 0x62 and (obj.frame_n == 1 or obj.frame_n == 2) then
obj.frame_n = 3
print("\nmagically locked!\n")
else
magic_no_effect()
end

View File

@@ -0,0 +1,15 @@
local loc = select_location_with_projectile(0x18b)
if loc == nil then return end
local hit_items = explosion(0x17f,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
v.asleep = false
end
end
magic_success()

View File

@@ -0,0 +1,16 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x18b, caster)
if loc == nil then return end
local hit_items = explosion(0x17d,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
spell_put_actor_to_sleep(caster, v)
end
end
magic_success()

View File

@@ -0,0 +1,2 @@
magic_casting_effect()
peer_effect()

View File

@@ -0,0 +1,6 @@
local actor = select_actor_with_projectile(0x17f)
if actor == nil then return end
actor.protected = true
magic_success()

View File

@@ -0,0 +1,25 @@
local caster = magic_get_caster()
local x = caster.x
local y = caster.y
local z = caster.z
local loc_x = x
local loc_y = y
magic_casting_fade_effect(caster)
for x = x - 5,loc_x + 5 do
for y = y - 5,loc_y + 5 do
local actor = map_get_actor(x, y, z)
if actor ~= nil then
local actor_type = actor_tbl[actor.obj_n]
if actor_type ~= nil and actor_type[14] == 1 and actor_int_check(actor, caster) == false then --14 repel undead flag
actor.wt = WT_UNK_13
dbg("setting actor["..actor.actor_num.."] to timid worktype.\n")
end
end
end
end
magic_success()

View File

@@ -0,0 +1,11 @@
local obj = select_obj_with_projectile(0x17f)
if obj == nil then return end
if obj_is_readiable(obj) then
actor = Actor.new(obj.obj_n, obj.x, obj.y, obj.z, ALIGNMENT_GOOD, 8)
map_remove_obj(obj)
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,42 @@
local caster = magic_get_caster()
magic_casting_effect()
magic_casting_fade_effect(caster)
local random = math.random
local i = random(0, 0xf)
local obj_n = 0
if i <= 3 then
obj_n = 0x173 --troll
elseif i <= 6 then
obj_n = 0x156 --giant rat
elseif i <= 9 then
obj_n = 0x169 --giant spider
elseif i <= 0xc then
obj_n = 0x158 --giant bat
else
obj_n = 0x166 --snake
end
local from_x = caster.x
local from_y = caster.y
local from_z = caster.z
for i=1,8 do
local new_x = random(0, 10) + from_x - 5
local new_y = random(0, 10) + from_y - 5
if map_can_put(new_x, new_y, from_z) then
local actor = Actor.new(obj_n, new_x, new_y, from_z)
if actor ~= nil then
actor.align = caster.align
actor.wt = WT_ASSAULT
magic_success()
return
end
break
end
end
magic_failed()

View File

@@ -0,0 +1,10 @@
local caster = magic_get_caster()
local actor = select_actor()
magic_casting_fade_effect()
if actor == nil then magic_no_effect() return end
if spell_hit_actor(caster, actor, 50) == false then -- 50 = disable spell number
magic_failed()
end

View File

@@ -0,0 +1,14 @@
loc = select_location_with_projectile(0x17e)
if loc == nil then return end
if map_can_put_obj(loc) and map_is_water(loc.x,loc.y,loc.z) == false then
obj = Obj.new(317); --fire field
obj.temporary = true
obj.x,obj.y,obj.z = loc.x,loc.y,loc.z
Obj.moveToMap(obj)
fade_obj_in(obj)
magic_success()
else
magic_not_possible()
end

View File

@@ -0,0 +1,13 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
fade_actor_blue(actor)
if actor.alive == true then
actor.hp = actor.max_hp
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,9 @@
local caster = magic_get_caster()
magic_casting_fade_effect(caster)
magic_casting_effect()
local x,y,z = caster.x,caster.y,caster.z
x,y = math.floor(x / 8), math.floor(y / 8)
local lat,lon
if x > 38 then x, lon = x - 38, "E" else x, lon = 38 - x, "W" end
if y > 45 then y, lat = y - 45, "S" else y, lat = 45 - y, "N" end
print("\n"..y.."{"..lat..", "..x.."{"..lon.."\n");

View File

@@ -0,0 +1,16 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x18b, caster)
if loc == nil then return end
local hit_items = explosion(0x17f,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
magic_remove_actor_enchantments(v)
end
end
magic_success()

View File

@@ -0,0 +1,14 @@
loc = select_location_with_projectile(0x17c)
if loc == nil then return end
if map_can_put_obj(loc) and map_is_water(loc.x,loc.y,loc.z) == false then
obj = Obj.new(318); --poison field
obj.temporary = true
obj.x,obj.y,obj.z = loc.x,loc.y,loc.z
Obj.moveToMap(obj)
fade_obj_in(obj)
magic_success()
else
magic_not_possible()
end

View File

@@ -0,0 +1,14 @@
loc = select_location_with_projectile(0x17d)
if loc == nil then return end
if map_can_put_obj(loc) and map_is_water(loc.x,loc.y,loc.z) == false then
obj = Obj.new(320); --sleep field
obj.temporary = true
obj.x,obj.y,obj.z = loc.x,loc.y,loc.z
Obj.moveToMap(obj)
fade_obj_in(obj)
magic_success()
else
magic_not_possible()
end

View File

@@ -0,0 +1,4 @@
local dir = get_direction("Direction-")
print("`"..direction_string(dir).."\n")
wind_set_dir(dir)

View File

@@ -0,0 +1,14 @@
loc = select_location_with_projectile(0x17f)
if loc == nil then return end
if map_can_put_obj(loc) and map_is_water(loc.x,loc.y,loc.z) == false then
obj = Obj.new(319); --protection field
obj.temporary = true
obj.x,obj.y,obj.z = loc.x,loc.y,loc.z
Obj.moveToMap(obj)
fade_obj_in(obj)
magic_success()
else
magic_not_possible()
end

View File

@@ -0,0 +1,17 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x189, caster)
if loc == nil then return end
local hit_items = explosion(0x17e, loc.x,loc.y)
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
spell_take_fire_dmg(caster, v)
end
if g_avatar_died == true then
break -- don't keep casting once Avatar is dead
end
end
explode_surrounding_objects(loc.x, loc.y, loc.z)

View File

@@ -0,0 +1,26 @@
magic_casting_effect()
local random = math.random
local loc = caster_get_location()
local caster = magic_get_caster()
local from_z = loc.z
local i, j
magic_casting_fade_effect(caster)
for i=1,8 do
for j=1,8 do
local new_x = random(0, 10) + loc.x - 5
local new_y = random(0, 10) + loc.y - 5
if map_can_put(new_x, new_y, from_z) then
actor = Actor.new(0x157, new_x, new_y, from_z) --insect
if actor ~= nil then
actor.align = caster.align
actor.wt = WT_ASSAULT
end
break
end
end
end
magic_success()

View File

@@ -0,0 +1,12 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x18b, caster)
if actor == nil then return end
if actor.visible == true and actor_can_turn_invisible(actor.obj_n) == true then
fade_actor_blue(actor) --FIXME we should fade out at the same time as fading blue.
actor.visible = false
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,17 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x188, caster)
if actor == nil then return end
if caster_is_player() then
print("\n")
end
local exp = actor_hit(actor, math.random(1, 30))
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_hit_msg(actor)
actor_yell_for_help(caster, actor, 1)

View File

@@ -0,0 +1,16 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
if is_god_mode_enabled() and actor.in_party then
return
end
print("\n")
hit_anim(actor.x, actor.y)
actor.paralyzed = true
print(actor.name.." is paralyzed.\n")
if actor.in_party == true then
party_update_leader()
end

View File

@@ -0,0 +1,24 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x18b, caster)
if actor == nil then return end
print("Which object:")
local obj = get_obj_from_inventory(actor)
if obj ~= nil then
print(obj.name.."\n")
if Actor.can_carry_obj(actor, obj) == false then
print("\ncan't carry!\n")
return
end
projectile(obj.tile_num, actor.x, actor.y, caster.x, caster.y, 2)
Actor.inv_add_obj(caster, obj)
player_subtract_karma(5)
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,23 @@
local caster = magic_get_caster()
local x = caster.x
local y = caster.y
local z = caster.z
local loc_x = x
local loc_y = y
magic_casting_fade_effect(caster)
for x = x - 5,loc_x + 5 do
for y = y - 5,loc_y + 5 do
local actor = map_get_actor(x, y, z)
if actor ~= nil then
if actor.visible == false then
actor.visible = true
end
end
end
end
magic_success()

View File

@@ -0,0 +1,12 @@
local obj = select_actor_or_obj()
local obj_n = obj.obj_n
-- dead body ghost dead gargoyle dead cyclops
if obj_n == 0x153 or obj_n == 0x160 or obj_n == 0x155 or obj_n == 0x154 then
if obj.luatype == "actor" and obj.actor_num == 91 then
Actor.set_talk_flag(obj, 7)
actor_talk(obj)
else
Actor.talk(Actor.get(obj.quality))
end
end

View File

@@ -0,0 +1,4 @@
magic_casting_effect()
magic_casting_fade_effect()
xray_effect(6000)
print("\nDone\n")

View File

@@ -0,0 +1,8 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
if spell_charm_actor(caster, actor) == false then
magic_failed()
end

View File

@@ -0,0 +1,33 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x17f, caster)
if actor == nil then return end
local from_x = caster.x
local from_y = caster.y
local from_z = caster.z
local random = math.random
for i=1,8 do
local new_x = random(0, 10) + from_x - 5
local new_y = random(0, 10) + from_y - 5
if map_can_put(new_x, new_y, from_z) then
local clone_actor = Actor.new(actor.obj_n, new_x, new_y, from_z)
if clone_actor ~= nil then
clone_actor.frame_n = actor.frame_n
clone_actor.align = actor.align
if actor.wt > WT_PLAYER then
clone_actor.wt = actor.wt
else
clone_actor.wt = WT_ASSAULT
end
fade_actor_in(clone_actor)
magic_success()
return
end
break
end
end
magic_no_effect()

View File

@@ -0,0 +1,26 @@
local caster = magic_get_caster()
local x = caster.x
local y = caster.y
local z = caster.z
local loc_x = x
local loc_y = y
magic_casting_fade_effect(caster)
for x = x - 5,loc_x + 5 do
for y = y - 5,loc_y + 5 do
local actor = map_get_actor(x, y, z)
if actor ~= nil then
if actor.align == ALIGNMENT_EVIL then
if actor_int_check(actor, caster) == false then
actor.align = ALIGNMENT_GOOD
actor.wt = WT_ASSAULT
end
end
end
end
end
magic_success()

View File

@@ -0,0 +1 @@
magic_wind_spell(83, 0x18d)

View File

@@ -0,0 +1,11 @@
local loc = select_location_with_prompt("Location: ")
magic_casting_fade_effect()
if loc == nil then magic_no_effect() return end
print("\n")
hail_storm_effect(loc)
print("\nSuccess\n")

View File

@@ -0,0 +1,16 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x18b, caster)
if loc == nil then return end
local hit_items = explosion(0x17f,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
v.protected = true
end
end
magic_success()

View File

@@ -0,0 +1,3 @@
magic_casting_fade_effect()
magic_casting_effect()
timer_set(TIMER_STORM, 0x14)

View File

@@ -0,0 +1 @@
magic_wind_spell(87, 0x17c)

View File

@@ -0,0 +1,35 @@
local caster = magic_get_caster()
local obj = select_obj_with_projectile(0x17f, caster)
if obj == nil then return end
if tile_get_flag(obj.tile_num, 3, 3) == true then
local replicated_obj = Obj.new(obj.obj_n, obj.frame_n)
replicated_obj.qty = 1
replicated_obj.status = 0x21 --OK, TEMP
local loc = {}, i
local random = math.random
local caster_x = caster.x
local caster_y = caster.y
loc.z = caster.z
for i=1,8 do
loc.x = caster_x + random(0, 10) - 5
loc.y = caster_y + random(0, 10) - 5
if map_can_put_obj(loc) == true then
Obj.moveToMap(replicated_obj, loc)
fade_obj_in(replicated_obj)
return magic_success()
end
end
magic_failed()
else
magic_no_effect()
end

View File

@@ -0,0 +1,38 @@
local caster = magic_get_caster()
local loc = select_location_with_prompt("Location: ")
print("\n")
magic_casting_fade_effect(caster)
if loc == nil then magic_no_effect() return end
local target_x = loc.x
local target_y = loc.y
local target_z = caster.z
local targets = {}
local i,j
for i=target_x-1,target_x+1 do
for j = target_y-1,target_y+1 do
table.insert(targets,{x=i,y=j,z=target_z})
end
end
projectile_anim_multi(564, caster.x, caster.y, targets, 2, 0, 0) --564 = web tile num
local hit_x, hit_y = map_line_hit_check(caster.x, caster.y, loc.x, loc.y, loc.z)
if hit_x ~= loc.x or hit_y ~= loc.y then magic_blocked() return end
local k, v
for k,v in ipairs(targets) do
if map_can_put_obj(v) then
local obj = Obj.new(0x35, 0) --web obj
Obj.moveToMap(obj, v)
end
end
magic_success()

View File

@@ -0,0 +1,66 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x188, caster)
if actor == nil then return end
local random = math.random
local exp = actor_hit(actor, random(1, 0x1e))
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_yell_for_help(caster, actor, 1)
actor_hit_msg(actor)
local i,j
for i=0,6 do
if g_avatar_died == true then
break -- don't keep casting once Avatar is dead
end
local var_c = 32769
local new_target = nil
for j=1,0xff do
local tmp_actor = Actor.get(j)
if tmp_actor.obj_n ~= 0 and tmp_actor.alive == true and tmp_actor.actor_num ~= actor.actor_num and actor_ok_to_attack(actor, tmp_actor) == true then
local target_x = tmp_actor.x
local target_y = tmp_actor.y
if tmp_actor.z == caster.z and target_x > caster.x - 5 and target_x < caster.x + 5 and target_y > caster.y - 5 and target_y < caster.y + 5 then
local val = (target_x - actor.x) * (target_x - actor.x) + (target_y - actor.y) * (target_y - actor.y)
dbg("and here val = "..val.."\n")
if val > 0 then
if val <= var_c then
if val == var_c then
if random(0, 1) == 0 then
new_target = tmp_actor
end
else
var_c = val
new_target = tmp_actor
end
end
end
end
end
end
if new_target == nil then
break
end
projectile(0x188, actor.x, actor.y, new_target.x, new_target.y, 2, 0)
actor = new_target
local exp = actor_hit(actor, random(1, 0x1e))
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_yell_for_help(caster, actor, 1)
actor_hit_msg(actor)
end

View File

@@ -0,0 +1,35 @@
local caster = magic_get_caster()
local obj = select_obj()
if obj == nil then return end
if obj.obj_n ~= 0x4e then --staff
magic_no_effect()
return
end
print("with: ")
local spell_num = select_spell()
if spell_num ~= nil then
if spell_num ~= 0x61 then --0x61 = enchant. Don't allow recursion on enchant spell. ;-)
magic_print_invocation_string(spell_num)
print("\n")
local i = 0
for child in container_objs(obj) do
i = i + 1
end
if i >= 10 then
print("\nIt's full\n")
play_sfx(SFX_FAILURE)
return
end
magic_casting_fade_effect(caster)
local charge = Obj.new(336,0, spell_num)
charge.invisible = true
Obj.moveToCont(charge, obj)
end
else
print("none\n\n")
end

View File

@@ -0,0 +1 @@
magic_wind_spell(98, 0x188)

View File

@@ -0,0 +1,28 @@
local caster = magic_get_caster()
local x = caster.x
local y = caster.y
local z = caster.z
local loc_x = x
local loc_y = y
magic_casting_fade_effect(caster)
for x = x - 5,loc_x + 5 do
for y = y - 5,loc_y + 5 do
local actor = map_get_actor(x, y, z)
if actor ~= nil then
if actor.align ~= ALIGNMENT_GOOD then
if actor_int_check(actor, caster) == false then
local actor_base = actor_tbl[actor.obj_n]
if actor_base == nil or actor_base[20] == 0 then -- if not undead
actor.wt = WT_UNK_13
end
end
end
end
end
end
magic_success()

View File

@@ -0,0 +1,15 @@
print("To phase ")
local phase = input_select_integer(nil,true)
print("\n")
magic_casting_fade_effect()
if phase > 0 and phase < 9 and g_moonstone_loc_tbl[phase].x ~= 0 then
--FIXME the original walks the party into an invisible gate to teleport.
player_move(g_moonstone_loc_tbl[phase].x, g_moonstone_loc_tbl[phase].y, g_moonstone_loc_tbl[phase].z, true)
fade_in()
else
play_sfx(SFX_FAILURE)
end

View File

@@ -0,0 +1,12 @@
local caster = magic_get_caster()
local actor = select_actor_with_projectile(0x18c, caster)
if actor == nil then return end
local ret = spell_kill_actor(caster, actor)
if ret == 2 then
magic_no_effect()
elseif ret == 1 then
magic_failed()
end

View File

@@ -0,0 +1,18 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x18b, caster)
if loc == nil then return end
local hit_items = explosion(0x17f,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
if is_god_mode_enabled() == false or v.in_party == false then
v.cursed = true
end
end
end
magic_success()

View File

@@ -0,0 +1,19 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x188, caster)
if loc == nil then return end
local hit_items = explosion(0x18a,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
if v.visible == true and actor_can_turn_invisible(v.obj_n) == true then
fade_actor_blue(v) --FIXME we should fade out at the same time as fading blue.
v.visible = false
end
end
end
magic_success()

View File

@@ -0,0 +1,33 @@
magic_casting_fade_effect()
local player_loc = player_get_location()
local player_x = player_loc.x
local player_y = player_loc.y
local player_z = player_loc.z
local foes_present = false
local i
for i=1,0xff do
local actor = Actor.get(i)
if actor.obj_n ~= 0 and actor.alive == true and actor.visible == true and alignment_is_evil(actor.align) then
local target_x = actor.x
local target_y = actor.y
if actor.z == player_z and target_x > player_x - 5 and target_x < player_x + 5 and target_y > player_y - 5 and target_y < player_y + 5 then
wing_strike_effect(actor)
foes_present = true
end
if g_avatar_died == true then
break -- don't keep casting once Avatar is dead
end
end
end
if foes_present == false then
print("\nNo foes.\n")
play_sfx(SFX_FAILURE)
end

Some files were not shown because too many files have changed in this diff Show More