Allow fixed-destination teleport traps
Add a theme room with multiple visible teleportation traps which will always teleport to specific locations in the same level. Teleport trap change from xNetHack by copperwater <aosdict@gmail.com>.
This commit is contained in:
@@ -220,6 +220,19 @@ themeroom_fills = {
|
|||||||
end;
|
end;
|
||||||
locs:iterate(func);
|
locs:iterate(func);
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-- Teleportation hub
|
||||||
|
function(rm)
|
||||||
|
local locs = selection.room():filter_mapchar(".");
|
||||||
|
for i = 1, 2 + nh.rn2(3) do
|
||||||
|
local pos = locs:rndcoord(1);
|
||||||
|
if (pos.x > 0) then
|
||||||
|
pos.x = pos.x + rm.region.x1 - 1;
|
||||||
|
pos.y = pos.y + rm.region.y1;
|
||||||
|
table.insert(postprocess, { handler = make_a_trap, data = { type = "teleport", seen = true, coord = pos, teledest = 1 } });
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
};
|
};
|
||||||
|
|
||||||
themerooms = {
|
themerooms = {
|
||||||
@@ -871,6 +884,17 @@ function make_garden_walls(data)
|
|||||||
des.replace_terrain({ selection = sel, fromterrain="w", toterrain = "T" });
|
des.replace_terrain({ selection = sel, fromterrain="w", toterrain = "T" });
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- postprocess callback: make a trap
|
||||||
|
function make_a_trap(data)
|
||||||
|
if (data.teledest == 1 and data.type == "teleport") then
|
||||||
|
local locs = selection.negate():filter_mapchar(".");
|
||||||
|
repeat
|
||||||
|
data.teledest = locs:rndcoord(1);
|
||||||
|
until (data.teledest.x ~= data.coord.x and data.teledest.y ~= data.coord.y);
|
||||||
|
end
|
||||||
|
des.trap(data);
|
||||||
|
end
|
||||||
|
|
||||||
-- called once after the whole level has been generated
|
-- called once after the whole level has been generated
|
||||||
function post_level_generate()
|
function post_level_generate()
|
||||||
for i, v in ipairs(postprocess) do
|
for i, v in ipairs(postprocess) do
|
||||||
|
|||||||
@@ -1002,7 +1002,8 @@ Example:
|
|||||||
|
|
||||||
=== trap
|
=== trap
|
||||||
|
|
||||||
Create a trap. The `launchfrom` is relative to the rolling boulder trap coord.
|
Create a trap. The `launchfrom` is relative to the rolling boulder trap coord,
|
||||||
|
but `teledest` is absolute.
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@@ -1011,6 +1012,7 @@ Example:
|
|||||||
des.trap({ type = "web", coord = {2, 2}, spider_on_web = false, seen = true });
|
des.trap({ type = "web", coord = {2, 2}, spider_on_web = false, seen = true });
|
||||||
des.trap({ type = "falling rock", victim = false });
|
des.trap({ type = "falling rock", victim = false });
|
||||||
des.trap({ type = "rolling boulder", coord = {7, 5}, launchfrom = {-2, -2} });
|
des.trap({ type = "rolling boulder", coord = {7, 5}, launchfrom = {-2, -2} });
|
||||||
|
des.trap({ type = "teleport", coord = {7, 5}, teledest = {2, 2} });
|
||||||
des.trap("hole", 3, 4);
|
des.trap("hole", 3, 4);
|
||||||
des.trap("level teleport", {5, 8});
|
des.trap("level teleport", {5, 8});
|
||||||
des.trap("rust")
|
des.trap("rust")
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ struct trap {
|
|||||||
coordxy tx, ty;
|
coordxy tx, ty;
|
||||||
d_level dst; /* destination for portals/holes/trapdoors */
|
d_level dst; /* destination for portals/holes/trapdoors */
|
||||||
coord launch;
|
coord launch;
|
||||||
|
#define teledest launch /* x,y destination for teleport traps, if > 0 */
|
||||||
Bitfield(ttyp, 5);
|
Bitfield(ttyp, 5);
|
||||||
Bitfield(tseen, 1);
|
Bitfield(tseen, 1);
|
||||||
Bitfield(once, 1);
|
Bitfield(once, 1);
|
||||||
|
|||||||
14
src/sp_lev.c
14
src/sp_lev.c
@@ -4362,7 +4362,19 @@ lspo_trap(lua_State *L)
|
|||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
gl.launchplace.x = lx;
|
gl.launchplace.x = lx;
|
||||||
gl.launchplace.y = ly;
|
gl.launchplace.y = ly;
|
||||||
}
|
} else
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_getfield(L, -1, "teledest");
|
||||||
|
if (lua_type(L, -1) == LUA_TTABLE) {
|
||||||
|
lua_Integer lx = -1, ly = -1;
|
||||||
|
|
||||||
|
(void) get_coord(L, -1, &lx, &ly);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
gl.launchplace.x = lx;
|
||||||
|
gl.launchplace.y = ly;
|
||||||
|
} else
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmptrap.type == NO_TRAP)
|
if (tmptrap.type == NO_TRAP)
|
||||||
|
|||||||
@@ -1098,6 +1098,8 @@ dotele(
|
|||||||
if (next_to_u()) {
|
if (next_to_u()) {
|
||||||
if (trap && trap_once)
|
if (trap && trap_once)
|
||||||
vault_tele();
|
vault_tele();
|
||||||
|
else if (trap && isok(trap->teledest.x, trap->teledest.y))
|
||||||
|
teleds(trap->teledest.x, trap->teledest.y, TELEDS_TELEPORT);
|
||||||
else
|
else
|
||||||
tele();
|
tele();
|
||||||
(void) next_to_u();
|
(void) next_to_u();
|
||||||
@@ -1450,6 +1452,20 @@ tele_trap(struct trap *trap)
|
|||||||
deltrap(trap);
|
deltrap(trap);
|
||||||
newsym(u.ux, u.uy); /* get rid of trap symbol */
|
newsym(u.ux, u.uy); /* get rid of trap symbol */
|
||||||
vault_tele();
|
vault_tele();
|
||||||
|
} else if (isok(trap->teledest.x, trap->teledest.y)) {
|
||||||
|
coord cc;
|
||||||
|
struct monst *mtmp = m_at(trap->teledest.x, trap->teledest.y);
|
||||||
|
|
||||||
|
if (mtmp) {
|
||||||
|
if (!enexto(&cc, mtmp->mx, mtmp->my, mtmp->data)) {
|
||||||
|
/* could not find some other place to put mtmp; the level must
|
||||||
|
* be nearly or completely full */
|
||||||
|
You1(shudder_for_moment);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rloc_to(mtmp, cc.x, cc.y);
|
||||||
|
}
|
||||||
|
teleds(trap->teledest.x, trap->teledest.y, TELEDS_TELEPORT);
|
||||||
} else
|
} else
|
||||||
tele();
|
tele();
|
||||||
}
|
}
|
||||||
@@ -1882,7 +1898,16 @@ mtele_trap(struct monst *mtmp, struct trap *trap, int in_sight)
|
|||||||
*/
|
*/
|
||||||
if (trap->once)
|
if (trap->once)
|
||||||
mvault_tele(mtmp);
|
mvault_tele(mtmp);
|
||||||
else
|
else if (isok(trap->teledest.x, trap->teledest.y)) {
|
||||||
|
/* monster teleporting onto hero's or another monster's spot does
|
||||||
|
* not work the same as hero teleporting onto monster's spot where
|
||||||
|
* the incoming monster displaces the resident to the nearest
|
||||||
|
* possible space - instead it just doesn't work. */
|
||||||
|
if (!(m_at(trap->teledest.x, trap->teledest.y)
|
||||||
|
|| u_at(trap->teledest.x, trap->teledest.y))) {
|
||||||
|
rloc_to_core(mtmp, trap->teledest.x, trap->teledest.y, RLOC_MSG);
|
||||||
|
}
|
||||||
|
} else
|
||||||
(void) rloc(mtmp, RLOC_NONE);
|
(void) rloc(mtmp, RLOC_NONE);
|
||||||
|
|
||||||
if (in_sight) {
|
if (in_sight) {
|
||||||
|
|||||||
@@ -541,6 +541,15 @@ maketrap(coordxy x, coordxy y, int typ)
|
|||||||
|
|
||||||
unearth_objs(x, y);
|
unearth_objs(x, y);
|
||||||
break;
|
break;
|
||||||
|
case TELEP_TRAP:
|
||||||
|
if (isok(gl.launchplace.x, gl.launchplace.y)) {
|
||||||
|
ttmp->teledest.x = gx.xstart + gl.launchplace.x;
|
||||||
|
ttmp->teledest.y = gy.ystart + gl.launchplace.y;
|
||||||
|
if (ttmp->teledest.x == x && ttmp->teledest.y == y) {
|
||||||
|
impossible("making fixed-dest tele trap pointing to itself");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oldplace) {
|
if (!oldplace) {
|
||||||
|
|||||||
Reference in New Issue
Block a user