diff options
author | Bardur Arantsson <bardur@scientician.net> | 2012-04-16 20:20:43 +0200 |
---|---|---|
committer | Bardur Arantsson <bardur@scientician.net> | 2012-04-17 20:33:00 +0200 |
commit | ca30fc5a6f92d75ee1c7eec2dd863776fe7afb5f (patch) | |
tree | 8c784ba04736f5ee845ae42cba66d80194efa951 | |
parent | cf9afa2063fa9123f8653e76d17404775a34313d (diff) |
Lua: Move "Geomancy" spell functions to C
-rw-r--r-- | lib/mods/theme/scpt/s_geom.lua | 235 | ||||
-rw-r--r-- | lib/scpt/s_geom.lua | 235 | ||||
-rw-r--r-- | src/cmd1.c | 11 | ||||
-rw-r--r-- | src/externs.h | 26 | ||||
-rw-r--r-- | src/loadsave.c | 3 | ||||
-rw-r--r-- | src/spells.pkg | 29 | ||||
-rw-r--r-- | src/spells3.c | 400 | ||||
-rw-r--r-- | src/types.h | 3 |
8 files changed, 504 insertions, 438 deletions
diff --git a/lib/mods/theme/scpt/s_geom.lua b/lib/mods/theme/scpt/s_geom.lua index d152bc25..d4ce4437 100644 --- a/lib/mods/theme/scpt/s_geom.lua +++ b/lib/mods/theme/scpt/s_geom.lua @@ -11,20 +11,8 @@ CALL_THE_ELEMENTS = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - local ret, dir = 0, 0 - - if get_level(CALL_THE_ELEMENTS) >= 17 then - ret, dir = get_aim_dir() - if ret == FALSE then return end - end - - fire_ball(GF_ELEMENTAL_GROWTH, dir, 1, 1 + get_level(CALL_THE_ELEMENTS, 5, 0)) - return TRUE - end, - ["info"] = function() - return "rad "..(1 + get_level(CALL_THE_ELEMENTS, 5, 0)) - end, + ["spell"] = function() return geomancy_call_the_elements() end, + ["info"] = function() return geomancy_call_the_elements_info() end, ["desc"] = { "Randomly creates various elements around you", "Each type of element chance is controlled by your level", @@ -44,13 +32,8 @@ CHANNEL_ELEMENTS = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - channel_the_elements(player.py, player.px, get_level(CHANNEL_ELEMENTS)) - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_channel_elements() end, + ["info"] = function() return geomancy_channel_elements_info() end, ["desc"] = { "Draws on the caster's immediate environs to form an attack or other effect.", "Grass/Flower heals.", @@ -79,50 +62,8 @@ ELEMENTAL_WAVE = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - local ret, dir = get_rep_dir() - if ret == FALSE then return end - - local y, x = explode_dir(dir) - y = y + player.py - x = x + player.px - - local t = - { - -- Earth stuff - [FEAT_GRASS] = { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 200) }, - [FEAT_FLOWER] = { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 300) }, - -- cannot turn chasm into a wave - - -- Water stuff - [FEAT_SHAL_WATER] = { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 200) }, - [FEAT_DEEP_WATER] = { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 300) }, - [FEAT_ICE] = { GF_ICE, GF_ICE, 10 + get_skill_scale(SKILL_WATER, 200) }, - - -- Fire stuff - [FEAT_SAND] = { GF_LITE, GF_LITE, 10 + get_skill_scale(SKILL_FIRE, 400) }, - [FEAT_SHAL_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 200) }, - [FEAT_DEEP_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 300) }, - } - - - local effect = t[cave(y, x).feat] - if not effect then - msg_print("You cannot channel this area.") - else - local typ = effect[1] - if get_level(ELEMENTAL_WAVE) >= 20 then typ = effect[2] end - - cave_set_feat(y, x, FEAT_FLOOR) - - fire_wave(typ, 0, effect[3], 0, 6 + get_level(ELEMENTAL_WAVE, 20), EFF_WAVE + EFF_LAST + getglobal("EFF_DIR"..dir)) - end - - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_elemental_wave() end, + ["info"] = function() return geomancy_elemental_wave_info() end, ["desc"] = { "Draws on an adjacent special square to project a slow-moving", "wave of that element in that direction", @@ -145,42 +86,8 @@ VAPORIZE = add_spell ["depend"] = function() if get_skill(SKILL_AIR) >= 4 then return TRUE end end, - ["spell"] = function() - local t = - { - -- Earth stuff - [FEAT_GRASS] = { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 100) }, - [FEAT_FLOWER] = { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 150) }, - [FEAT_DARK_PIT] = { GF_DARK, GF_DARK, 5 + get_skill_scale(SKILL_EARTH, 200) }, - - -- Water stuff - [FEAT_SHAL_WATER] = { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 100) }, - [FEAT_DEEP_WATER] = { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 150) }, - [FEAT_ICE] = { GF_ICE, GF_ICE, 5 + get_skill_scale(SKILL_WATER, 100) }, - - -- Fire stuff - [FEAT_SAND] = { GF_LITE, GF_LITE, 5 + get_skill_scale(SKILL_FIRE, 200) }, - [FEAT_SHAL_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 100) }, - [FEAT_DEEP_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 150) }, - } - - local effect = t[cave(player.py, player.px).feat] - if not effect then - msg_print("You cannot channel this area.") - else - local typ = effect[1] - if get_level(VAPORIZE) >= 20 then typ = effect[2] end - - cave_set_feat(player.py, player.px, FEAT_FLOOR) - - fire_cloud(typ, 0, effect[3], 1 + get_level(VAPORIZE, 4), 10 + get_level(VAPORIZE, 20)) - end - - return TRUE - end, - ["info"] = function() - return "rad "..(1 + get_level(VAPORIZE, 4)).." dur "..(10 + get_level(VAPORIZE, 20)) - end, + ["spell"] = function() return geomancy_vaporize() end, + ["info"] = function() return geomancy_vaporize_info() end, ["desc"] = { "Draws upon your immediate environs to form a cloud of damaging vapors", } @@ -201,38 +108,14 @@ GEOLYSIS = add_spell ["depend"] = function() if get_skill(SKILL_EARTH) >= 7 then return TRUE end end, - ["spell"] = function() - local ret, dir = get_rep_dir() - if ret == FALSE then return end - - msg_print("Elements recombine before you, laying down an open path.") - geomancy_dig(player.py, player.px, dir, 5 + get_level(GEOLYSIS, 12)) - - return TRUE - end, - ["info"] = function() - return "length "..(5 + get_level(GEOLYSIS, 12)) - end, + ["spell"] = function() return geomancy_geolysis() end, + ["info"] = function() return geomancy_geolysis_info() end, ["desc"] = { "Burrows deeply and slightly at random into a wall,", "leaving behind tailings of various different sorts of walls in the passage.", } } -player.dripping_tread = 0 -add_loadsave("player.dripping_tread", 0) -add_hooks -{ - [HOOK_MOVED] = function(oy, ox) - if player.dripping_tread > 0 then - geomancy_random_floor(oy, ox, FALSE) - player.dripping_tread = player.dripping_tread - 1 - if player.dripping_tread == 0 then - msg_print("You stop dripping raw elemental energies.") - end - end - end -} DRIPPING_TREAD = add_spell { ["name"] = "Dripping Tread", @@ -248,19 +131,8 @@ DRIPPING_TREAD = add_spell ["depend"] = function() if get_skill(SKILL_WATER) >= 10 then return TRUE end end, - ["spell"] = function() - if player.dripping_tread == 0 then - player.dripping_tread = randint(15) + 10 + get_level(DRIPPING_TREAD) - msg_print("You start dripping raw elemental energies.") - else - player.dripping_tread = 0 - msg_print("You stop dripping raw elemental energies.") - end - return TRUE - end, - ["info"] = function() - return "dur "..(10 + get_level(DRIPPING_TREAD)).."+d15 movs" - end, + ["spell"] = function() return geomancy_dripping_tread() end, + ["info"] = function() return geomancy_dripping_tread_info() end, ["desc"] = { "Causes you to leave random elemental forms behind as you walk", } @@ -281,20 +153,8 @@ GROW_BARRIER = add_spell ["depend"] = function() if get_skill(SKILL_EARTH) >= 12 then return TRUE end end, - ["spell"] = function() - local ret, dir = 0, 0 - - if get_level(GROW_BARRIER) >= 20 then - ret, dir = get_aim_dir() - if ret == FALSE then return end - end - - fire_ball(GF_ELEMENTAL_WALL, dir, 1, 1) - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_grow_barrier() end, + ["info"] = function() return geomancy_grow_barrier_info() end, ["desc"] = { "Creates impassable terrain (walls, trees, etc.) around you.", "At level 20 it can be projected around another area.", @@ -312,71 +172,8 @@ ELEMENTAL_MINION = add_spell -- Unnafected by blindness ["random"] = 0, -- Must have at least 12 Earth - ["spell"] = function() - local ret, dir = 0, 0 - - ret, dir = get_rep_dir() - if ret == FALSE then return end - - local t = - { - [FEAT_WALL_EXTRA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_OUTER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_INNER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_SOLID] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - - [FEAT_DARK_PIT] = { SKILL_AIR, { "Air elemental", "Ancient blue dragon", "Great Storm Wyrm", "Sky Drake" } }, - - [FEAT_SANDWALL] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SANDWALL_H] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SANDWALL_K] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SHAL_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_DEEP_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - - [FEAT_ICE_WALL] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - [FEAT_SHAL_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - [FEAT_DEEP_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - } - - local y, x = explode_dir(dir) - y = y + player.py - x = x + player.px - - local effect = t[cave(y, x).feat] - if not effect then - msg_print("You cannot summon from this area.") - else - local skill = effect[1] - local types = effect[2] - - local max = get_skill_scale(skill, getn(types)) - if max == 0 then max = 1 end - - local r_idx = test_monster_name(types[rand_range(1, max)]) - - -- Summon it - local my, mx = find_position(y, x) - local m_idx = place_monster_one(my, mx, r_idx, 0, FALSE, MSTATUS_FRIEND) - - -- level it - if m_idx ~= 0 then - monster_set_level(m_idx, 10 + get_level(ELEMENTAL_MINION, 120)) - end - - cave_set_feat(y, x, FEAT_FLOOR) - end - - return TRUE - end, - ["info"] = function() - return "min level "..(10 + get_level(ELEMENTAL_MINION, 120)) - end, + ["spell"] = function() return geomancy_elemental_minion() end, + ["info"] = function() return geomancy_elemental_minion_info() end, ["desc"] = { "Summons a minion from a nearby element.", "Walls can summon Earth elmentals, Xorns and Xarens", diff --git a/lib/scpt/s_geom.lua b/lib/scpt/s_geom.lua index d152bc25..d4ce4437 100644 --- a/lib/scpt/s_geom.lua +++ b/lib/scpt/s_geom.lua @@ -11,20 +11,8 @@ CALL_THE_ELEMENTS = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - local ret, dir = 0, 0 - - if get_level(CALL_THE_ELEMENTS) >= 17 then - ret, dir = get_aim_dir() - if ret == FALSE then return end - end - - fire_ball(GF_ELEMENTAL_GROWTH, dir, 1, 1 + get_level(CALL_THE_ELEMENTS, 5, 0)) - return TRUE - end, - ["info"] = function() - return "rad "..(1 + get_level(CALL_THE_ELEMENTS, 5, 0)) - end, + ["spell"] = function() return geomancy_call_the_elements() end, + ["info"] = function() return geomancy_call_the_elements_info() end, ["desc"] = { "Randomly creates various elements around you", "Each type of element chance is controlled by your level", @@ -44,13 +32,8 @@ CHANNEL_ELEMENTS = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - channel_the_elements(player.py, player.px, get_level(CHANNEL_ELEMENTS)) - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_channel_elements() end, + ["info"] = function() return geomancy_channel_elements_info() end, ["desc"] = { "Draws on the caster's immediate environs to form an attack or other effect.", "Grass/Flower heals.", @@ -79,50 +62,8 @@ ELEMENTAL_WAVE = add_spell -- Unnafected by blindness ["blind"] = FALSE, ["random"] = 0, - ["spell"] = function() - local ret, dir = get_rep_dir() - if ret == FALSE then return end - - local y, x = explode_dir(dir) - y = y + player.py - x = x + player.px - - local t = - { - -- Earth stuff - [FEAT_GRASS] = { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 200) }, - [FEAT_FLOWER] = { GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 300) }, - -- cannot turn chasm into a wave - - -- Water stuff - [FEAT_SHAL_WATER] = { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 200) }, - [FEAT_DEEP_WATER] = { GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 300) }, - [FEAT_ICE] = { GF_ICE, GF_ICE, 10 + get_skill_scale(SKILL_WATER, 200) }, - - -- Fire stuff - [FEAT_SAND] = { GF_LITE, GF_LITE, 10 + get_skill_scale(SKILL_FIRE, 400) }, - [FEAT_SHAL_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 200) }, - [FEAT_DEEP_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 300) }, - } - - - local effect = t[cave(y, x).feat] - if not effect then - msg_print("You cannot channel this area.") - else - local typ = effect[1] - if get_level(ELEMENTAL_WAVE) >= 20 then typ = effect[2] end - - cave_set_feat(y, x, FEAT_FLOOR) - - fire_wave(typ, 0, effect[3], 0, 6 + get_level(ELEMENTAL_WAVE, 20), EFF_WAVE + EFF_LAST + getglobal("EFF_DIR"..dir)) - end - - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_elemental_wave() end, + ["info"] = function() return geomancy_elemental_wave_info() end, ["desc"] = { "Draws on an adjacent special square to project a slow-moving", "wave of that element in that direction", @@ -145,42 +86,8 @@ VAPORIZE = add_spell ["depend"] = function() if get_skill(SKILL_AIR) >= 4 then return TRUE end end, - ["spell"] = function() - local t = - { - -- Earth stuff - [FEAT_GRASS] = { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 100) }, - [FEAT_FLOWER] = { GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 150) }, - [FEAT_DARK_PIT] = { GF_DARK, GF_DARK, 5 + get_skill_scale(SKILL_EARTH, 200) }, - - -- Water stuff - [FEAT_SHAL_WATER] = { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 100) }, - [FEAT_DEEP_WATER] = { GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 150) }, - [FEAT_ICE] = { GF_ICE, GF_ICE, 5 + get_skill_scale(SKILL_WATER, 100) }, - - -- Fire stuff - [FEAT_SAND] = { GF_LITE, GF_LITE, 5 + get_skill_scale(SKILL_FIRE, 200) }, - [FEAT_SHAL_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 100) }, - [FEAT_DEEP_LAVA] = { GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 150) }, - } - - local effect = t[cave(player.py, player.px).feat] - if not effect then - msg_print("You cannot channel this area.") - else - local typ = effect[1] - if get_level(VAPORIZE) >= 20 then typ = effect[2] end - - cave_set_feat(player.py, player.px, FEAT_FLOOR) - - fire_cloud(typ, 0, effect[3], 1 + get_level(VAPORIZE, 4), 10 + get_level(VAPORIZE, 20)) - end - - return TRUE - end, - ["info"] = function() - return "rad "..(1 + get_level(VAPORIZE, 4)).." dur "..(10 + get_level(VAPORIZE, 20)) - end, + ["spell"] = function() return geomancy_vaporize() end, + ["info"] = function() return geomancy_vaporize_info() end, ["desc"] = { "Draws upon your immediate environs to form a cloud of damaging vapors", } @@ -201,38 +108,14 @@ GEOLYSIS = add_spell ["depend"] = function() if get_skill(SKILL_EARTH) >= 7 then return TRUE end end, - ["spell"] = function() - local ret, dir = get_rep_dir() - if ret == FALSE then return end - - msg_print("Elements recombine before you, laying down an open path.") - geomancy_dig(player.py, player.px, dir, 5 + get_level(GEOLYSIS, 12)) - - return TRUE - end, - ["info"] = function() - return "length "..(5 + get_level(GEOLYSIS, 12)) - end, + ["spell"] = function() return geomancy_geolysis() end, + ["info"] = function() return geomancy_geolysis_info() end, ["desc"] = { "Burrows deeply and slightly at random into a wall,", "leaving behind tailings of various different sorts of walls in the passage.", } } -player.dripping_tread = 0 -add_loadsave("player.dripping_tread", 0) -add_hooks -{ - [HOOK_MOVED] = function(oy, ox) - if player.dripping_tread > 0 then - geomancy_random_floor(oy, ox, FALSE) - player.dripping_tread = player.dripping_tread - 1 - if player.dripping_tread == 0 then - msg_print("You stop dripping raw elemental energies.") - end - end - end -} DRIPPING_TREAD = add_spell { ["name"] = "Dripping Tread", @@ -248,19 +131,8 @@ DRIPPING_TREAD = add_spell ["depend"] = function() if get_skill(SKILL_WATER) >= 10 then return TRUE end end, - ["spell"] = function() - if player.dripping_tread == 0 then - player.dripping_tread = randint(15) + 10 + get_level(DRIPPING_TREAD) - msg_print("You start dripping raw elemental energies.") - else - player.dripping_tread = 0 - msg_print("You stop dripping raw elemental energies.") - end - return TRUE - end, - ["info"] = function() - return "dur "..(10 + get_level(DRIPPING_TREAD)).."+d15 movs" - end, + ["spell"] = function() return geomancy_dripping_tread() end, + ["info"] = function() return geomancy_dripping_tread_info() end, ["desc"] = { "Causes you to leave random elemental forms behind as you walk", } @@ -281,20 +153,8 @@ GROW_BARRIER = add_spell ["depend"] = function() if get_skill(SKILL_EARTH) >= 12 then return TRUE end end, - ["spell"] = function() - local ret, dir = 0, 0 - - if get_level(GROW_BARRIER) >= 20 then - ret, dir = get_aim_dir() - if ret == FALSE then return end - end - - fire_ball(GF_ELEMENTAL_WALL, dir, 1, 1) - return TRUE - end, - ["info"] = function() - return "" - end, + ["spell"] = function() return geomancy_grow_barrier() end, + ["info"] = function() return geomancy_grow_barrier_info() end, ["desc"] = { "Creates impassable terrain (walls, trees, etc.) around you.", "At level 20 it can be projected around another area.", @@ -312,71 +172,8 @@ ELEMENTAL_MINION = add_spell -- Unnafected by blindness ["random"] = 0, -- Must have at least 12 Earth - ["spell"] = function() - local ret, dir = 0, 0 - - ret, dir = get_rep_dir() - if ret == FALSE then return end - - local t = - { - [FEAT_WALL_EXTRA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_OUTER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_INNER] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_WALL_SOLID] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ_H] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_MAGMA_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - [FEAT_QUARTZ_K] = { SKILL_EARTH, { "Earth elemental", "Xorn", "Xaren" } }, - - [FEAT_DARK_PIT] = { SKILL_AIR, { "Air elemental", "Ancient blue dragon", "Great Storm Wyrm", "Sky Drake" } }, - - [FEAT_SANDWALL] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SANDWALL_H] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SANDWALL_K] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_SHAL_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - [FEAT_DEEP_LAVA] = { SKILL_FIRE, { "Fire elemental", "Ancient red dragon" } }, - - [FEAT_ICE_WALL] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - [FEAT_SHAL_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - [FEAT_DEEP_WATER] = { SKILL_WATER, { "Water elemental", "Water troll", "Water demon" } }, - } - - local y, x = explode_dir(dir) - y = y + player.py - x = x + player.px - - local effect = t[cave(y, x).feat] - if not effect then - msg_print("You cannot summon from this area.") - else - local skill = effect[1] - local types = effect[2] - - local max = get_skill_scale(skill, getn(types)) - if max == 0 then max = 1 end - - local r_idx = test_monster_name(types[rand_range(1, max)]) - - -- Summon it - local my, mx = find_position(y, x) - local m_idx = place_monster_one(my, mx, r_idx, 0, FALSE, MSTATUS_FRIEND) - - -- level it - if m_idx ~= 0 then - monster_set_level(m_idx, 10 + get_level(ELEMENTAL_MINION, 120)) - end - - cave_set_feat(y, x, FEAT_FLOOR) - end - - return TRUE - end, - ["info"] = function() - return "min level "..(10 + get_level(ELEMENTAL_MINION, 120)) - end, + ["spell"] = function() return geomancy_elemental_minion() end, + ["info"] = function() return geomancy_elemental_minion_info() end, ["desc"] = { "Summons a minion from a nearby element.", "Walls can summon Earth elmentals, Xorns and Xarens", @@ -3098,6 +3098,17 @@ void move_player_aux(int dir, int do_pickup, int run, bool_ disarm) /* Some hooks */ if (process_hooks(HOOK_MOVE, "(d,d)", y, x)) return; + if (p_ptr->dripping_tread > 0) + { + geomancy_random_floor(y, x, FALSE); + p_ptr->dripping_tread -= 1; + if (p_ptr->dripping_tread == 0) + { + msg_print("You stop dripping raw elemental energies."); + } + } + + /* Get the monster */ m_ptr = &m_list[c_ptr->m_idx]; mr_ptr = race_inf(m_ptr); diff --git a/src/externs.h b/src/externs.h index fd156286..77d5613e 100644 --- a/src/externs.h +++ b/src/externs.h @@ -1538,6 +1538,32 @@ char *fire_firewall_info(); bool_ *fire_golem(); char *fire_golem_info(); +extern s32b CALL_THE_ELEMENTS; +extern s32b CHANNEL_ELEMENTS; +extern s32b ELEMENTAL_WAVE; +extern s32b VAPORIZE; +extern s32b GEOLYSIS; +extern s32b DRIPPING_TREAD; +extern s32b GROW_BARRIER; +extern s32b ELEMENTAL_MINION; + +bool_ *geomancy_call_the_elements(); +char *geomancy_call_the_elements_info(); +bool_ *geomancy_channel_elements(); +char *geomancy_channel_elements_info(); +bool_ *geomancy_elemental_wave(); +char *geomancy_elemental_wave_info(); +bool_ *geomancy_vaporize(); +char *geomancy_vaporize_info(); +bool_ *geomancy_geolysis(); +char *geomancy_geolysis_info(); +bool_ *geomancy_dripping_tread(); +char *geomancy_dripping_tread_info(); +bool_ *geomancy_grow_barrier(); +char *geomancy_grow_barrier_info(); +bool_ *geomancy_elemental_minion(); +char *geomancy_elemental_minion_info(); + /* randart.c */ extern int get_activation_power(void); extern void build_prob(cptr learn); diff --git a/src/loadsave.c b/src/loadsave.c index cb9156a9..5116acef 100644 --- a/src/loadsave.c +++ b/src/loadsave.c @@ -2874,6 +2874,9 @@ static bool_ do_savefile_aux(int flag) do_byte(&p_ptr->pet_open_doors, flag); do_byte(&p_ptr->pet_pickup_items, flag); + /* Dripping Tread */ + do_s16b(&p_ptr->dripping_tread, flag); + /* Read the inventory */ if (!do_inventory(flag) && (flag == LS_LOAD)) /* do NOT reverse this ordering */ { diff --git a/src/spells.pkg b/src/spells.pkg index 260cdf50..adfd6f1d 100644 --- a/src/spells.pkg +++ b/src/spells.pkg @@ -2579,3 +2579,32 @@ bool_ *fire_firewall(); char *fire_firewall_info(); bool_ *fire_golem(); char *fire_golem_info(); + +/* + * Geomancy + */ +extern s32b CALL_THE_ELEMENTS; +extern s32b CHANNEL_ELEMENTS; +extern s32b ELEMENTAL_WAVE; +extern s32b VAPORIZE; +extern s32b GEOLYSIS; +extern s32b DRIPPING_TREAD; +extern s32b GROW_BARRIER; +extern s32b ELEMENTAL_MINION; + +bool_ *geomancy_call_the_elements(); +char *geomancy_call_the_elements_info(); +bool_ *geomancy_channel_elements(); +char *geomancy_channel_elements_info(); +bool_ *geomancy_elemental_wave(); +char *geomancy_elemental_wave_info(); +bool_ *geomancy_vaporize(); +char *geomancy_vaporize_info(); +bool_ *geomancy_geolysis(); +char *geomancy_geolysis_info(); +bool_ *geomancy_dripping_tread(); +char *geomancy_dripping_tread_info(); +bool_ *geomancy_grow_barrier(); +char *geomancy_grow_barrier_info(); +bool_ *geomancy_elemental_minion(); +char *geomancy_elemental_minion_info(); diff --git a/src/spells3.c b/src/spells3.c index 7c8173ea..c3ca27bc 100644 --- a/src/spells3.c +++ b/src/spells3.c @@ -48,6 +48,15 @@ s32b FIERYAURA; s32b FIREWALL; s32b FIREGOLEM; +s32b CALL_THE_ELEMENTS; +s32b CHANNEL_ELEMENTS; +s32b ELEMENTAL_WAVE; +s32b VAPORIZE; +s32b GEOLYSIS; +s32b DRIPPING_TREAD; +s32b GROW_BARRIER; +s32b ELEMENTAL_MINION; + /* FIXME: Hackish workaround while we're still tied to Lua. This lets us return Lua's "nil" and a non-nil value (which is all the s_aux.lua cares about). */ @@ -1287,3 +1296,394 @@ char *fire_golem_info() (7 + get_level_s(FIREGOLEM, 70))); return buf; } + +bool_ *geomancy_call_the_elements() +{ + int dir = 0; + + if (get_level_s(CALL_THE_ELEMENTS, 50) >= 17) + { + if (!get_aim_dir(&dir)) + { + return FALSE; + } + } + + fire_ball(GF_ELEMENTAL_GROWTH, + dir, + 1, + 1 + get_level(CALL_THE_ELEMENTS, 5, 0)); + + return CAST; +} + +char *geomancy_call_the_elements_info() +{ + static char buf[128]; + sprintf(buf, + "rad %d", + (1 + get_level(CALL_THE_ELEMENTS, 5, 0))); + return buf; +} + +bool_ *geomancy_channel_elements() +{ + channel_the_elements(p_ptr->py, p_ptr->px, get_level_s(CHANNEL_ELEMENTS, 50)); + return CAST; +} + +char *geomancy_channel_elements_info() +{ + return ""; +} + +typedef struct eff_type eff_type; +struct eff_type { + s16b feat; + s16b low_effect; + s16b high_effect; + s16b damage; +}; + +static eff_type *geomancy_find_effect(eff_type effs[], int feat) +{ + int i; + for (i = 0; effs[i].feat >= 0; i++) + { + eff_type *p = &effs[i]; + if (p->feat == feat) + { + return p; + } + } + return NULL; +} + +bool_ *geomancy_elemental_wave() +{ + int dir = 0, y = 0, x = 0; + eff_type *eff_ptr = NULL; + eff_type t[] = + { + /* Earth */ + { FEAT_GRASS, GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 200) }, + { FEAT_FLOWER, GF_POIS, GF_POIS, 10 + get_skill_scale(SKILL_EARTH, 300) }, + + /* Water */ + { FEAT_SHAL_WATER, GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 200) }, + { FEAT_DEEP_WATER, GF_WATER, GF_WATER, 10 + get_skill_scale(SKILL_WATER, 300) }, + { FEAT_ICE, GF_ICE, GF_ICE, 10 + get_skill_scale(SKILL_WATER, 200) }, + + /* Fire */ + { FEAT_SAND, GF_LITE, GF_LITE, 10 + get_skill_scale(SKILL_FIRE, 400) }, + { FEAT_SHAL_LAVA, GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 200) }, + { FEAT_DEEP_LAVA, GF_FIRE, GF_HOLY_FIRE, 10 + get_skill_scale(SKILL_FIRE, 300) }, + { -1, -1, -1, -1 }, + }; + + if (!get_rep_dir(&dir)) + { + return FALSE; + } + + y = ddy[dir] + p_ptr->py; + x = ddx[dir] + p_ptr->px; + + eff_ptr = geomancy_find_effect(t, cave[y][x].feat); + + if (!eff_ptr) + { + msg_print("You cannot channel this area."); + return NO_CAST; + } + else + { + s16b typ = eff_ptr->low_effect; + char buf[16]; + s32b EFF_DIR; + + sprintf(buf, "EFF_DIR%d", dir); + EFF_DIR = get_lua_int(buf); + + if (get_level_s(ELEMENTAL_WAVE, 50) >= 20) + { + typ = eff_ptr->high_effect; + } + + cave_set_feat(y, x, FEAT_FLOOR); + + fire_wave(typ, + 0, + eff_ptr->damage, + 0, + 6 + get_level_s(ELEMENTAL_WAVE, 20), + EFF_WAVE + EFF_LAST + EFF_DIR); + + return CAST; + } +} + +char *geomancy_elemental_wave_info() +{ + return ""; +} + +bool_ *geomancy_vaporize() +{ + eff_type *eff_ptr = NULL; + eff_type t[] = { + /* Earth stuff */ + { FEAT_GRASS, GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 100) }, + { FEAT_FLOWER, GF_POIS, GF_POIS, 5 + get_skill_scale(SKILL_EARTH, 150) }, + { FEAT_DARK_PIT, GF_DARK, GF_DARK, 5 + get_skill_scale(SKILL_EARTH, 200) }, + /* Water stuff */ + { FEAT_SHAL_WATER, GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 100) }, + { FEAT_DEEP_WATER, GF_WATER, GF_WATER, 5 + get_skill_scale(SKILL_WATER, 150) }, + { FEAT_ICE, GF_ICE, GF_ICE, 5 + get_skill_scale(SKILL_WATER, 100) }, + /* Fire stuff */ + { FEAT_SAND, GF_LITE, GF_LITE, 5 + get_skill_scale(SKILL_FIRE, 200) }, + { FEAT_SHAL_LAVA, GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 100) }, + { FEAT_DEEP_LAVA, GF_FIRE, GF_HOLY_FIRE, 5 + get_skill_scale(SKILL_FIRE, 150) }, + { -1, -1, -1, -1 }, + }; + + eff_ptr = geomancy_find_effect(t, cave[p_ptr->py][p_ptr->px].feat); + + if (!eff_ptr) + { + msg_print("You cannot channel this area."); + return NO_CAST; + } + else + { + s16b typ = eff_ptr->low_effect; + if (get_level_s(VAPORIZE, 50) >= 20) + { + typ = eff_ptr->high_effect; + } + + cave_set_feat(p_ptr->py, p_ptr->px, FEAT_FLOOR); + + fire_cloud(typ, + 0, + eff_ptr->damage, + 1 + get_level_s(VAPORIZE, 4), + 10 + get_level_s(VAPORIZE, 20)); + + return CAST; + } +} + +char *geomancy_vaporize_info() +{ + static char buf[128]; + sprintf(buf, + "rad %d dur %d", + (1 + get_level_s(VAPORIZE, 4)), + (10 + get_level_s(VAPORIZE, 20))); + return buf; +} + +bool_ *geomancy_geolysis() +{ + int dir = 0; + + if (!get_rep_dir(&dir)) + { + return NO_CAST; + } + + msg_print("Elements recombine before you, laying down an open path."); + geomancy_dig(p_ptr->py, p_ptr->px, dir, 5 + get_level_s(GEOLYSIS, 12)); + + return CAST; +} + +char *geomancy_geolysis_info() +{ + static char buf[128]; + sprintf(buf, + "length %d", + (5 + get_level_s(GEOLYSIS, 12))); + return buf; +} + +bool_ *geomancy_dripping_tread() +{ + if (p_ptr->dripping_tread == 0) + { + p_ptr->dripping_tread = randint(15) + 10 + get_level_s(DRIPPING_TREAD, 50); + msg_print("You start dripping raw elemental energies."); + } + else + { + p_ptr->dripping_tread = 0; + msg_print("You stop dripping raw elemental energies."); + } + + return CAST; +} + +char *geomancy_dripping_tread_info() +{ + static char buf[128]; + sprintf(buf, + "dur %d+d15 movs", + (10 + get_level_s(DRIPPING_TREAD, 50))); + return buf; +} + +bool_ *geomancy_grow_barrier() +{ + int dir = 0; + + if (get_level_s(GROW_BARRIER, 50) >= 20) + { + if (!get_aim_dir(&dir)) + { + return FALSE; + } + } + + fire_ball(GF_ELEMENTAL_WALL, dir, 1, 1); + return CAST; +} + +char *geomancy_grow_barrier_info() +{ + return ""; +} + +typedef struct geo_summon geo_summon; +struct geo_summon { + s16b feat; + s16b skill_idx; + cptr *summon_names; +}; + +geo_summon *geomancy_find_summon(geo_summon summons[], int feat) +{ + int i; + for (i = 0; summons[i].feat >= 0; i++) + { + geo_summon *summon = &summons[i]; + if (summon->feat == feat) + { + return summon; + } + } + return NULL; +} + +int geomancy_count_elements(cptr *elements) +{ + int i; + for (i = 0; elements[i] != NULL; i++) + { + } + return i; +} + +bool_ *geomancy_elemental_minion() +{ + int dir = 0; + int x = 0, y = 0; + geo_summon *summon_ptr = NULL; + cptr earth_summons[] = { + "Earth elemental", + "Xorn", + "Xaren", + NULL + }; + cptr air_summons[] = { + "Air elemental", + "Ancient blue dragon", + "Great Storm Wyrm", + "Sky Drake", + NULL + }; + cptr fire_summons[] = { + "Fire elemental", + "Ancient red dragon", + NULL + }; + cptr water_summons[] = { + "Water elemental", + "Water troll", + "Water demon", + NULL + }; + geo_summon summons[] = { + { FEAT_WALL_EXTRA, SKILL_EARTH, earth_summons }, + { FEAT_WALL_OUTER, SKILL_EARTH, earth_summons }, + { FEAT_WALL_INNER, SKILL_EARTH, earth_summons }, + { FEAT_WALL_SOLID, SKILL_EARTH, earth_summons }, + { FEAT_MAGMA, SKILL_EARTH, earth_summons }, + { FEAT_QUARTZ, SKILL_EARTH, earth_summons }, + { FEAT_MAGMA_H, SKILL_EARTH, earth_summons }, + { FEAT_QUARTZ_H, SKILL_EARTH, earth_summons }, + { FEAT_MAGMA_K, SKILL_EARTH, earth_summons }, + { FEAT_QUARTZ_K, SKILL_EARTH, earth_summons }, + + { FEAT_DARK_PIT, SKILL_AIR, air_summons }, + + { FEAT_SANDWALL, SKILL_FIRE, fire_summons }, + { FEAT_SANDWALL_H, SKILL_FIRE, fire_summons }, + { FEAT_SANDWALL_K, SKILL_FIRE, fire_summons }, + { FEAT_SHAL_LAVA, SKILL_FIRE, fire_summons }, + { FEAT_DEEP_LAVA, SKILL_FIRE, fire_summons }, + + { FEAT_ICE_WALL, SKILL_WATER, water_summons }, + { FEAT_SHAL_WATER, SKILL_WATER, water_summons }, + { FEAT_DEEP_WATER, SKILL_WATER, water_summons }, + + { -1, -1, NULL }, + }; + + if (!get_rep_dir(&dir)) + { + return NO_CAST; + } + + y = ddy[dir] + p_ptr->py; + x = ddx[dir] + p_ptr->px; + + summon_ptr = geomancy_find_summon(summons, cave[y][x].feat); + + if (!summon_ptr) + { + msg_print("You cannot summon from this area."); + return NO_CAST; + } + else + { + cptr *names = summon_ptr->summon_names; + int max = get_skill_scale(summon_ptr->skill_idx, + geomancy_count_elements(names)); + int r_idx = test_monster_name(names[rand_int(max)]); + int mx, my, m_idx; + + /* Summon it */ + find_position(y, x, &my, &mx); + m_idx = place_monster_one(my, mx, r_idx, 0, FALSE, MSTATUS_FRIEND); + + /* Level it */ + if (m_idx) + { + monster_set_level(m_idx, 10 + get_level_s(ELEMENTAL_MINION, 120)); + } + + cave_set_feat(y, x, FEAT_FLOOR); + + return CAST; + } +} + +char *geomancy_elemental_minion_info() +{ + static char buf[128]; + sprintf(buf, + "min level %d", + (10 + get_level_s(ELEMENTAL_MINION, 120))); + return buf; +} diff --git a/src/types.h b/src/types.h index ea8213a3..ea66ff5f 100644 --- a/src/types.h +++ b/src/types.h @@ -1837,6 +1837,9 @@ struct player_type s16b melee_style; /* How are */ s16b use_piercing_shots; /* for archery */ + /* Dripping Tread spell timer */ + s16b dripping_tread; + /* Help */ help_info help; |