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

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

View File

@@ -0,0 +1,8 @@
magic_casting_effect()
magic_casting_fade_effect()
local loc = caster_get_location()
wizard_eye_effect(0x28, loc)
print("\nDone\n")

View File

@@ -0,0 +1,9 @@
set_g_armageddon(true)
magic_casting_effect()
local i
for i=1,0xff do
local actor = Actor.get(i)
if i ~= 1 and i ~= 5 and actor ~= nil and actor.alive then --don't kill the Avatar or Lord British.
Actor.kill(actor, false) --false = don't create body
end
end

View File

@@ -0,0 +1 @@
magic_wind_spell(113, 0x18c)

View File

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

View File

@@ -0,0 +1,16 @@
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
spell_charm_actor(caster, v)
end
end
magic_success()

View File

@@ -0,0 +1,20 @@
local caster = magic_get_caster()
local loc = select_location_with_projectile(0x188, caster)
if loc == nil then return end
local hit_items = explosion(0x18c,loc.x,loc.y)
local k,v
for k,v in pairs(hit_items) do
if v.luatype == "actor" then
spell_kill_actor(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)
magic_success()

View File

@@ -0,0 +1,8 @@
local caster = magic_get_caster()
if caster.visible == true then
fade_actor_blue(caster)
caster.visible = false
magic_success()
else
magic_no_effect()
end

View File

@@ -0,0 +1,25 @@
local obj = select_obj()
magic_casting_fade_effect()
if obj ~= nil and g_armageddon == false then
fade_obj_blue(obj)
-- if statement is redundant with ObjManager::is_corpse(Obj *obj) but not really worth adding to the scripting language
--dead body, mouse, dead gargoyle, dead cyclops;
if (obj.obj_n == 339 or obj.obj_n == 0x162 or obj.obj_n == 0x155 or obj.obj_n == 0x154 or
obj.obj_n == 349 or obj.obj_n == 134) then --dog, horse carcass
if obj.quality < 203 then --greater than 202 temp actors
if obj.quality ~= 0 then
local actor = Actor.get(obj.quality)
Actor.resurrect(actor, obj.x, obj.y, obj.z, obj)
magic_success()
else
print("\nThe corpse is too old!\n")
end
end
else
magic_no_effect()
end
else
magic_no_effect()
end

View File

@@ -0,0 +1,38 @@
local loc = player_get_location()
local caster = magic_get_caster()
local x = loc.x - 5
local y = loc.y - 5
local z = loc.z
magic_casting_fade_effect(caster)
for x = loc.x - 5,loc.x + 5 do
for y = loc.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.align == ALIGNMENT_EVIL and (actor_type == nil or actor_type[12] == 0) then
if actor_int_check(actor, caster) == false then
local old_tile_num = actor.tile_num
actor.base_obj_n = 0x177 --convert actor into slime
local new_tile_num = actor.tile_num
actor.visible = false
--FIXME need to fade all at once.
fade_tile(x, y, z, old_tile_num, new_tile_num)
actor.visible = true
if actor.temp == true then
--remove inventory
local obj
for obj in actor_inventory(actor) do
Actor.inv_remove_obj(actor, obj)
end
end
end
end
end
end
end
slime_update_frames()

View File

@@ -0,0 +1,3 @@
local caster = magic_get_caster()
loc = player_get_location()
actor = Actor.new(367, loc.x, loc.y-1, loc.z, caster.align, 8)

View File

@@ -0,0 +1,3 @@
magic_casting_fade_effect()
magic_casting_effect()
timer_set(TIMER_TIME_STOP, 0xa)

View File

@@ -0,0 +1,39 @@
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)
play_sfx(SFX_EARTH_QUAKE, false)
quake_start(1,1024)
local random = math.random
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
local actor_base = actor_tbl[actor.obj_n]
if actor_base == nil or actor_base[13] == 0 then -- 13 is immune to tremor
local exp = actor_hit(actor, random(1, 0x1e))
if exp ~= 0 then
caster.exp = caster.exp + exp
end
actor_hit_msg(actor)
if g_avatar_died == true then
break -- don't keep casting once Avatar is dead
end
end
end
end
end
end
print("\nSuccess\n")

View File

@@ -0,0 +1,3 @@
function player_pass()
printl("PASS")
end

View File

@@ -0,0 +1,94 @@
local USE_EVENT_USE = 0x01
function use_telescope(obj, actor)
if obj.on_map == true then
mapwindow_center_at_location(obj.x, obj.y, obj.z)
else -- FIXME - should probably work in the inventory (can't be done without cheating though)
print("Not usable\n")
return
end
local dir = really_get_direction("Direction-")
if dir == nil or dir == DIR_NONE then
mapwindow_center_at_location(actor.x, actor.y, actor.z)
print("nowhere.\n")
return
end
local dir_string = direction_string(dir)
dir_string = dir_string:gsub("^%l", string.upper)
print(dir_string..".\n")
local loc = mapwindow_get_location()
--FIXME need to fade out blacking.
mapwindow_set_enable_blacking(false)
for i=0,40 do
loc.x,loc.y = direction_get_loc(dir,loc.x, loc.y)
mapwindow_set_location(loc.x, loc.y, loc.z)
script_wait(50)
end
script_wait(600)
mapwindow_set_enable_blacking(true)
mapwindow_center_at_location(actor.x, actor.y, actor.z)
print("\nDone\n")
end
function use_silver_horn(obj, actor)
local i
for i=0,0xff do
local tmp_actor = Actor.get(i)
if tmp_actor.obj_n == 413 and tmp_actor.alive == true and actor_find_max_xy_distance(tmp_actor, actor.x, actor.y) <= 8 then
print("Not now!\n")
return
end
end
local random = math.random
for i=1,3 do
local new_x = random(1, 7) + random(1, 7) + actor.x - 8
local new_y = random(1, 7) + random(1, 7) + actor.y - 8
local snake = Actor.new(413, new_x, new_y, actor.z, ALIGNMENT_CHAOTIC)
end
print("Silver snakes are generated!\n")
end
local usecode_table = {
[154]=use_telescope,
[313]=use_silver_horn
}
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