summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBardur Arantsson <bardur@scientician.net>2012-04-16 20:20:43 +0200
committerBardur Arantsson <bardur@scientician.net>2012-04-17 20:33:00 +0200
commitca30fc5a6f92d75ee1c7eec2dd863776fe7afb5f (patch)
tree8c784ba04736f5ee845ae42cba66d80194efa951
parentcf9afa2063fa9123f8653e76d17404775a34313d (diff)
Lua: Move "Geomancy" spell functions to C
-rw-r--r--lib/mods/theme/scpt/s_geom.lua235
-rw-r--r--lib/scpt/s_geom.lua235
-rw-r--r--src/cmd1.c11
-rw-r--r--src/externs.h26
-rw-r--r--src/loadsave.c3
-rw-r--r--src/spells.pkg29
-rw-r--r--src/spells3.c400
-rw-r--r--src/types.h3
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",
diff --git a/src/cmd1.c b/src/cmd1.c
index 49c0d38f..1184df0c 100644
--- a/src/cmd1.c
+++ b/src/cmd1.c
@@ -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;