More interesting Gehennom levels
Instead of just plain old boring mazes, spice up Gehennom by occasionally adding lava, iron bars, or even mines-style levels (with lava, of course). Of the fixed Gehennom levels, only Asmodeus' lair has been changed to add some random lava pools. Also some lua fixes and changes: - Fixed a selection negation bounding box being wrong. - Fixed a selection negated and ORed returning wrong results. - des.map now returns a selection of the map grids it touched. - When using des.map contents-function the commands following the map are not relative to it.
This commit is contained in:
118
dat/asmodeus.lua
118
dat/asmodeus.lua
@@ -6,8 +6,13 @@
|
||||
des.level_init({ style="mazegrid", bg ="-" });
|
||||
|
||||
des.level_flags("mazelevel")
|
||||
|
||||
local tmpbounds = selection.match("-");
|
||||
local bnds = tmpbounds:bounds();
|
||||
local bounds2 = selection.fillrect(bnds.lx, bnds.ly + 1, bnds.hx - 2, bnds.hy - 1);
|
||||
|
||||
-- First part
|
||||
des.map({ halign = "half-left", valign = "center", map = [[
|
||||
local asmo1 = des.map({ halign = "half-left", valign = "center", map = [[
|
||||
---------------------
|
||||
|.............|.....|
|
||||
|.............S.....|
|
||||
@@ -20,69 +25,72 @@ des.map({ halign = "half-left", valign = "center", map = [[
|
||||
|..|..-----------...|
|
||||
|..S..........|.....|
|
||||
---------------------
|
||||
]] });
|
||||
]], contents = function(rm)
|
||||
-- Doors
|
||||
des.door("closed",04,03)
|
||||
des.door("locked",18,04)
|
||||
des.door("closed",18,08)
|
||||
--
|
||||
des.stair("down", 13,07)
|
||||
-- Non diggable walls
|
||||
des.non_diggable(selection.area(00,00,20,11))
|
||||
-- Entire main area
|
||||
des.region(selection.area(01,01,20,10),"unlit")
|
||||
-- The fellow in residence
|
||||
des.monster("Asmodeus",12,07)
|
||||
-- Some random weapons and armor.
|
||||
des.object("[")
|
||||
des.object("[")
|
||||
des.object(")")
|
||||
des.object(")")
|
||||
des.object("*")
|
||||
des.object("!")
|
||||
des.object("!")
|
||||
des.object("?")
|
||||
des.object("?")
|
||||
des.object("?")
|
||||
-- Some traps.
|
||||
des.trap("spiked pit", 05,02)
|
||||
des.trap("fire", 08,06)
|
||||
des.trap("sleep gas")
|
||||
des.trap("anti magic")
|
||||
des.trap("fire")
|
||||
des.trap("magic")
|
||||
des.trap("magic")
|
||||
-- Random monsters.
|
||||
des.monster("ghost",11,07)
|
||||
des.monster("horned devil",10,05)
|
||||
des.monster("L")
|
||||
-- Some Vampires for good measure
|
||||
des.monster("V")
|
||||
des.monster("V")
|
||||
des.monster("V")
|
||||
end });
|
||||
|
||||
des.levregion({ region={01,00,6,20}, region_islev=1, exclude={6,1,70,16}, exclude_islev=1, type="stair-up" });
|
||||
-- des.stair(levregion(01,00,6,20),levregion(6,1,70,16),up)
|
||||
|
||||
des.levregion({ region={01,00,6,20}, region_islev=1, exclude={6,1,70,16}, exclude_islev=1, type="branch" });
|
||||
-- des.branch(levregion(01,00,6,20),levregion(6,1,70,16))
|
||||
des.teleport_region({ region = {01,00,6,20}, region_islev=1, exclude={6,1,70,16}, exclude_islev=1 })
|
||||
|
||||
-- Doors
|
||||
des.door("closed",04,03)
|
||||
des.door("locked",18,04)
|
||||
des.door("closed",18,08)
|
||||
--
|
||||
des.stair("down", 13,07)
|
||||
-- Non diggable walls
|
||||
des.non_diggable(selection.area(00,00,20,11))
|
||||
-- Entire main area
|
||||
des.region(selection.area(01,01,20,10),"unlit")
|
||||
-- The fellow in residence
|
||||
des.monster("Asmodeus",12,07)
|
||||
-- Some random weapons and armor.
|
||||
des.object("[")
|
||||
des.object("[")
|
||||
des.object(")")
|
||||
des.object(")")
|
||||
des.object("*")
|
||||
des.object("!")
|
||||
des.object("!")
|
||||
des.object("?")
|
||||
des.object("?")
|
||||
des.object("?")
|
||||
-- Some traps.
|
||||
des.trap("spiked pit", 05,02)
|
||||
des.trap("fire", 08,06)
|
||||
des.trap("sleep gas")
|
||||
des.trap("anti magic")
|
||||
des.trap("fire")
|
||||
des.trap("magic")
|
||||
des.trap("magic")
|
||||
-- Random monsters.
|
||||
des.monster("ghost",11,07)
|
||||
des.monster("horned devil",10,05)
|
||||
des.monster("L")
|
||||
-- Some Vampires for good measure
|
||||
des.monster("V")
|
||||
des.monster("V")
|
||||
des.monster("V")
|
||||
-- Second part
|
||||
des.map({ halign = "half-right", valign = "center", map = [[
|
||||
local asmo2 = des.map({ halign = "half-right", valign = "center", map = [[
|
||||
---------------------------------
|
||||
................................|
|
||||
................................+
|
||||
................................|
|
||||
---------------------------------
|
||||
]] });
|
||||
des.mazewalk(32,02,"east")
|
||||
-- Non diggable walls
|
||||
des.non_diggable(selection.area(00,00,32,04))
|
||||
des.door("closed",32,02)
|
||||
des.monster("&")
|
||||
des.monster("&")
|
||||
des.monster("&")
|
||||
des.trap("anti magic")
|
||||
des.trap("fire")
|
||||
des.trap("magic")
|
||||
]], contents = function(rm)
|
||||
des.mazewalk(32,02,"east")
|
||||
-- Non diggable walls
|
||||
des.non_diggable(selection.area(00,00,32,04))
|
||||
des.door("closed",32,02)
|
||||
des.monster("&")
|
||||
des.monster("&")
|
||||
des.monster("&")
|
||||
des.trap("anti magic")
|
||||
des.trap("fire")
|
||||
des.trap("magic")
|
||||
end });
|
||||
|
||||
local protected = bounds2:negate() | asmo1 | asmo2;
|
||||
hell_tweaks(protected);
|
||||
|
||||
@@ -91,6 +91,7 @@ dungeon = {
|
||||
base = 20,
|
||||
range = 5,
|
||||
flags = { "mazelike", "hellish" },
|
||||
lvlfill = "hellfill",
|
||||
alignment = "noalign",
|
||||
branches = {
|
||||
{
|
||||
|
||||
155
dat/hellfill.lua
Normal file
155
dat/hellfill.lua
Normal file
@@ -0,0 +1,155 @@
|
||||
-- NetHack 3.7 hellfill.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $
|
||||
-- Copyright (c) 2022 by Pasi Kallinen
|
||||
-- NetHack may be freely redistributed. See license for details.
|
||||
--
|
||||
--
|
||||
|
||||
-- The "fill" level for gehennom.
|
||||
--
|
||||
-- This level is used to fill out any levels not occupied by
|
||||
-- specific levels.
|
||||
--
|
||||
|
||||
function hellobjects()
|
||||
local objclass = { "(", "/", "=", "+", ")", "[", "?", "*", "%" };
|
||||
shuffle(objclass);
|
||||
|
||||
des.object(objclass[1]);
|
||||
des.object(objclass[1]);
|
||||
des.object(objclass[2]);
|
||||
des.object(objclass[3]);
|
||||
des.object(objclass[4]);
|
||||
des.object(objclass[5]);
|
||||
des.object()
|
||||
des.object()
|
||||
end
|
||||
|
||||
--
|
||||
|
||||
function hellmonsters()
|
||||
local monclass = { "V", "D", " ", "&", "Z" };
|
||||
shuffle(monclass);
|
||||
|
||||
des.monster({ class = monclass[1], peaceful = 0 });
|
||||
des.monster({ class = monclass[1], peaceful = 0 });
|
||||
des.monster({ class = monclass[2], peaceful = 0 });
|
||||
des.monster({ class = monclass[2], peaceful = 0 });
|
||||
des.monster({ class = monclass[3], peaceful = 0 });
|
||||
des.monster({ class = monclass[4], peaceful = 0 });
|
||||
des.monster({ peaceful = 0 });
|
||||
des.monster({ class = "H", peaceful = 0 });
|
||||
end
|
||||
|
||||
--
|
||||
|
||||
function helltraps()
|
||||
for i = 1, 12 do
|
||||
des.trap()
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
|
||||
function populatemaze()
|
||||
for i = 1, math.random(8) + 11 do
|
||||
if (percent(50)) then
|
||||
des.object("*");
|
||||
else
|
||||
des.object();
|
||||
end
|
||||
end
|
||||
|
||||
for i = 1, math.random(10) + 2 do
|
||||
des.object("`");
|
||||
end
|
||||
|
||||
for i = 1, math.random(3) do
|
||||
des.monster({ id = "minotaur", peaceful = 0 });
|
||||
end
|
||||
|
||||
for i = 1, math.random(5) + 7 do
|
||||
des.monster({ peaceful = 0 });
|
||||
end
|
||||
|
||||
for i = 1, math.random(6) + 7 do
|
||||
des.gold();
|
||||
end
|
||||
|
||||
for i = 1, math.random(6) + 7 do
|
||||
des.trap();
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
|
||||
-- TODO: cold hells? (ice & water instead of lava. sometimes floor = ice)
|
||||
-- TODO: more hell_tweaks:
|
||||
-- - replacing walls with iron bars
|
||||
-- - random prefab areas
|
||||
-- - replace all walls (in a full level width/height) in a small area
|
||||
|
||||
hells = {
|
||||
-- 1: "mines" style with lava
|
||||
function ()
|
||||
des.level_init({ style = "solidfill", fg = " " });
|
||||
des.level_flags("mazelevel", "noflip");
|
||||
des.level_init({ style="mines", fg=".", smoothed=true ,joined=true, lit=0, walled=true });
|
||||
des.replace_terrain({ fromterrain = " ", toterrain = "L" });
|
||||
des.replace_terrain({ fromterrain = ".", toterrain = "L", chance = 5 });
|
||||
des.replace_terrain({ mapfragment = [[w]], toterrain = "L", chance = 20 });
|
||||
des.replace_terrain({ mapfragment = [[w]], toterrain = ".", chance = 15 });
|
||||
end,
|
||||
|
||||
-- 2: mazes like original, with some hell_tweaks
|
||||
function ()
|
||||
des.level_flags("mazelevel", "noflip");
|
||||
des.level_init({ style = "mazegrid", bg = "-" });
|
||||
des.mazewalk(01,10,"east");
|
||||
local tmpbounds = selection.match("-");
|
||||
local bnds = tmpbounds:bounds();
|
||||
local protected_area = selection.fillrect(bnds.lx, bnds.ly + 1, bnds.hx - 2, bnds.hy - 1);
|
||||
hell_tweaks(protected_area:negate());
|
||||
end,
|
||||
|
||||
-- 3: mazes, style 1: wall thick = 1, random wid corr
|
||||
function ()
|
||||
des.level_init({ style = "solidfill", fg = " " });
|
||||
des.level_flags("mazelevel", "noflip");
|
||||
des.level_init({ style = "maze", wallthick = 1 });
|
||||
end,
|
||||
|
||||
-- 4: mazes, style 2: replace wall with iron bars of lava
|
||||
function ()
|
||||
des.level_init({ style = "solidfill", fg = " " });
|
||||
des.level_flags("mazelevel", "noflip");
|
||||
des.level_init({ style = "maze", wallthick = 1 });
|
||||
local outside_walls = selection.match(" ");
|
||||
local wallterrain = { "F", "L" };
|
||||
shuffle(wallterrain);
|
||||
des.replace_terrain({ mapfragment = "w", toterrain = wallterrain[1] });
|
||||
des.terrain(outside_walls, " "); -- return the outside back to solid wall
|
||||
end,
|
||||
|
||||
-- 5: mazes, thick walls, occasionally lava instead of walls
|
||||
function ()
|
||||
des.level_init({ style = "solidfill", fg = " " });
|
||||
des.level_flags("mazelevel", "noflip");
|
||||
des.level_init({ style = "maze", wallthick = 1 + math.random(2), corrwid = math.random(2) });
|
||||
if (percent(50)) then
|
||||
local outside_walls = selection.match(" ");
|
||||
des.replace_terrain({ mapfragment = "w", toterrain = "L" });
|
||||
des.terrain(outside_walls, " "); -- return the outside back to solid wall
|
||||
end
|
||||
end,
|
||||
};
|
||||
|
||||
local hellno = math.random(1, #hells);
|
||||
hells[hellno]();
|
||||
|
||||
--
|
||||
|
||||
des.stair("up")
|
||||
des.stair("down")
|
||||
|
||||
des.region(selection.area(00,00,77,21),"unlit");
|
||||
populatemaze();
|
||||
@@ -51,6 +51,58 @@ function monkfoodshop()
|
||||
return "food shop";
|
||||
end
|
||||
|
||||
-- tweaks to gehennom levels; might add random lava pools or
|
||||
-- a lava river.
|
||||
-- protected_area is a selection where no changes will be done.
|
||||
function hell_tweaks(protected_area)
|
||||
local liquid = "L";
|
||||
local ground = ".";
|
||||
local prot = protected_area:negate();
|
||||
|
||||
-- random pools
|
||||
if (percent(20 + u.depth)) then
|
||||
local pools = selection.new();
|
||||
local maxpools = 5 + math.random(u.depth);
|
||||
for i = 1, maxpools do
|
||||
pools:set();
|
||||
end
|
||||
pools = pools | selection.grow(selection.set(selection.new()), "west")
|
||||
pools = pools | selection.grow(selection.set(selection.new()), "north")
|
||||
pools = pools | selection.grow(selection.set(selection.new()), "random")
|
||||
|
||||
pools = pools & prot;
|
||||
|
||||
if (percent(80)) then
|
||||
local poolground = pools:clone():grow("all") & prot;
|
||||
local pval = math.random(1, 8) * 10;
|
||||
des.terrain(poolground:percentage(pval), ground)
|
||||
end
|
||||
des.terrain(pools, liquid)
|
||||
end
|
||||
|
||||
-- river
|
||||
if (percent(50)) then
|
||||
local floor = selection.match(ground);
|
||||
local a = selection.rndcoord(floor);
|
||||
local b = selection.rndcoord(floor);
|
||||
local lavariver = selection.randline(selection.new(), a.x, a.y, b.x, b.y, 10);
|
||||
|
||||
if (percent(50)) then
|
||||
lavariver = selection.grow(lavariver, "north");
|
||||
end
|
||||
if (percent(50)) then
|
||||
lavariver = selection.grow(lavariver, "west");
|
||||
end
|
||||
if (percent(25)) then
|
||||
local riverbanks = selection.grow(lavariver);
|
||||
riverbanks = riverbanks & prot;
|
||||
des.terrain(selection.percentage(riverbanks, 50), ground);
|
||||
end
|
||||
lavariver = lavariver & prot;
|
||||
des.terrain(lavariver, liquid);
|
||||
end
|
||||
end
|
||||
|
||||
-- pline with variable number of arguments
|
||||
function pline(fmt, ...)
|
||||
nh.pline(string.format(fmt, table.unpack({...})));
|
||||
|
||||
Reference in New Issue
Block a user