All files / js/levels astral.js

100% Statements 204/204
100% Branches 6/6
100% Functions 1/1
100% Lines 204/204

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 2051x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2x 2x 14x 14x 8x 8x 14x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x  
/**
 * astral - NetHack special level
 * Converted from: astral.lua
 */
 
import * as des from '../sp_lev.js';
import { selection, percent, shuffle } from '../sp_lev.js';
import { rn2 } from '../rng.js';
import { A_CHAOTIC, A_NEUTRAL, A_LAWFUL } from '../const.js';
 
export async function generate(_nhlib_align) {
    const align = _nhlib_align;
 
    // NetHack endgame astral.lua	$NHDT-Date: 1652196020 2022/5/10 15:20:20 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $
    // Copyright (c) 1989 by Jean-Christophe Collet
    // Copyright (c) 1992,1993 by Izchak Miller, David Cohrs,
    // and Timo Hakulinen
    // NetHack may be freely redistributed.  See license for details.
    // 
    des.level_init({ style: "solidfill", fg: " " });
 
    des.level_flags("mazelevel", "noteleport", "hardfloor", "nommap", "shortsighted", "solidify");
    des.message("You arrive on the Astral Plane!");
    des.message("Here the High Temple of %d is located.");
    des.message("You sense alarm, hostility, and excitement in the air!");
    await des.map(`\
                              ---------------                              
                              |.............|                              
                              |..---------..|                              
                              |..|.......|..|                              
---------------               |..|.......|..|               ---------------
|.............|               |..|.......|..|               |.............|
|..---------..-|   |-------|  |..|.......|..|  |-------|   |-..---------..|
|..|.......|...-| |-.......-| |..|.......|..| |-.......-| |-...|.......|..|
|..|.......|....-|-.........-||..----+----..||-.........-|-....|.......|..|
|..|.......+.....+...........||.............||...........+.....+.......|..|
|..|.......|....-|-.........-|--|.........|--|-.........-|-....|.......|..|
|..|.......|...-| |-.......-|   -|---+---|-   |-.......-| |-...|.......|..|
|..---------..-|   |---+---|    |-.......-|    |---+---|   |-..---------..|
|.............|      |...|-----|-.........-|-----|...|      |.............|
---------------      |.........|...........|.........|      ---------------
                     -------...|-.........-|...-------                     
                           |....|-.......-|....|                           
                           ---...|---+---|...---                           
                             |...............|                             
                             -----------------                             
`);
 
    // chance to alter above map and turn the wings of the bottom-center into
    // a pair of big (5x15) rooms
    for (let i = 1, __end_i = 2; i <= __end_i; i++) {
       // 3.6.[1]: 75% chance that both sides opened up, 25% that neither did;
       // 3.6.2: 60% twice == 36% chance that both sides open up, 24% left side
       // only, 24% right side only, 16% that neither side opens up
       let hall;
       if (percent(60)) {
         if (i == 1) {
            des.terrain(selection.area(17,14, 30,18),".");
            des.wallify();
            // temporarily close off the area to be filled so that it doesn't cover
            // the entire entry area
            des.terrain(33,18, "|");
            hall = selection.floodfill(30,16)
            // re-connect the opened wing with the rest of the map
            des.terrain(33,18, ".");
         } else {
            des.terrain(selection.area(44,14, 57,18),".");
            des.wallify();
            des.terrain(41,18, "|");
            hall = selection.floodfill(44,16)
            des.terrain(41,18, ".");
         }
         // extra monsters; was [6 + 3d4] when both wings were opened up at once
         for (let j = 1, __end_j = (rn2((9) - (4) + 1) + (4)); j <= __end_j; j++) {
            await des.monster({ id: "Angel", coord: hall.rndcoord(1), align: "noalign", peaceful: 0 });
            if (percent(50)) {
               await des.monster({ coord: hall.rndcoord(1), peaceful: 0 });
            }
         }
       }
    }
 
    // Rider locations
    let place = selection.new();
    place.set(23,9);
    place.set(37,14);
    place.set(51,9);
 
    // Where the player will land on arrival
    des.teleport_region({ region: [29,15,45,15], exclude: [30,15,44,15] });
    // Lit courts
    await des.region({ region: [1,5,16,14],lit: 1,type: "ordinary",irregular: 1 });
    await des.region({ region: [31,1,44,10],lit: 1,type: "ordinary",irregular: 1 });
    await des.region({ region: [61,5,74,14],lit: 1,type: "ordinary",irregular: 1 });
    // A Sanctum for each alignment
    // The shrines' alignments are shuffled for
    // each game
    await des.region({ region: [4,7,10,11],lit: 1,type: "temple",filled: 2 });
    await des.region({ region: [34,3,40,7],lit: 1,type: "temple",filled: 2 });
    await des.region({ region: [64,7,70,11],lit: 1,type: "temple",filled: 2 });
 
    await des.altar({ x: 7, y: 9, align: align[0],type: "sanctum" });
    await des.altar({ x: 37, y: 5, align: align[1],type: "sanctum" });
    await des.altar({ x: 67, y: 9, align: align[2],type: "sanctum" });
    // Doors
    des.door("closed",11,9);
    des.door("closed",17,9);
    des.door("locked",23,12);
    des.door("locked",37,8);
    des.door("closed",37,11);
    des.door("closed",37,17);
    des.door("locked",51,12);
    des.door("locked",57,9);
    des.door("closed",63,9);
    // Non diggable and phazeable everywhere
    des.non_diggable(selection.area(0,0,74,19));
    des.non_passwall(selection.area(0,0,74,19));
    // Moloch's horde
    // West round room
    await des.monster({ id: "aligned cleric",x: 18,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 19,y: 8,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 19,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 19,y: 10,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 20,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 20,y: 10,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Pestilence", coord: place.rndcoord(1), peaceful: 0 });
    // South-central round room
    await des.monster({ id: "aligned cleric",x: 36,y: 12,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 37,y: 12,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 38,y: 12,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 36,y: 13,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 38,y: 13,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 37,y: 13,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Death", coord: place.rndcoord(1), peaceful: 0 });
    // East round room
    await des.monster({ id: "aligned cleric",x: 56,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 55,y: 8,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 55,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 55,y: 10,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 54,y: 9,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Angel",x: 54,y: 10,align: "noalign", peaceful: 0 });
    await des.monster({ id: "Famine", coord: place.rndcoord(1), peaceful: 0 });
    // 
    // The aligned horde
    // 
    // We do not know in advance the alignment of the
    // player.  The mpeaceful bit will need resetting
    // when the level is created.  The setting here is
    // but a place holder.
    // 
    // West court
    await des.monster({ id: "aligned cleric",x: 12,y: 7,align: "chaos", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 13,y: 7,align: "chaos",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 14,y: 7,align: "law", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 12,y: 11,align: "law",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 13,y: 11,align: "neutral", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 14,y: 11,align: "neutral",peaceful: 1 });
    await des.monster({ id: "Angel",x: 11,y: 5,align: "chaos", peaceful: 0 });
    await des.monster({ id: "Angel",x: 12,y: 5,align: "chaos",peaceful: 1 });
    await des.monster({ id: "Angel",x: 13,y: 5,align: "law", peaceful: 0 });
    await des.monster({ id: "Angel",x: 11,y: 13,align: "law",peaceful: 1 });
    await des.monster({ id: "Angel",x: 12,y: 13,align: "neutral", peaceful: 0 });
    await des.monster({ id: "Angel",x: 13,y: 13,align: "neutral",peaceful: 1 });
    // Central court
    await des.monster({ id: "aligned cleric",x: 32,y: 9,align: "chaos", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 33,y: 9,align: "chaos",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 34,y: 9,align: "law", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 40,y: 9,align: "law",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 41,y: 9,align: "neutral", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 42,y: 9,align: "neutral",peaceful: 1 });
    await des.monster({ id: "Angel",x: 31,y: 8,align: "chaos", peaceful: 0 });
    await des.monster({ id: "Angel",x: 32,y: 8,align: "chaos",peaceful: 1 });
    await des.monster({ id: "Angel",x: 31,y: 9,align: "law", peaceful: 0 });
    await des.monster({ id: "Angel",x: 42,y: 8,align: "law",peaceful: 1 });
    await des.monster({ id: "Angel",x: 43,y: 8,align: "neutral", peaceful: 0 });
    await des.monster({ id: "Angel",x: 43,y: 9,align: "neutral",peaceful: 1 });
    // East court
    await des.monster({ id: "aligned cleric",x: 60,y: 7,align: "chaos", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 61,y: 7,align: "chaos",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 62,y: 7,align: "law", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 60,y: 11,align: "law",peaceful: 1 });
    await des.monster({ id: "aligned cleric",x: 61,y: 11,align: "neutral", peaceful: 0 });
    await des.monster({ id: "aligned cleric",x: 62,y: 11,align: "neutral",peaceful: 1 });
    await des.monster({ id: "Angel",x: 61,y: 5,align: "chaos", peaceful: 0 });
    await des.monster({ id: "Angel",x: 62,y: 5,align: "chaos",peaceful: 1 });
    await des.monster({ id: "Angel",x: 63,y: 5,align: "law", peaceful: 0 });
    await des.monster({ id: "Angel",x: 61,y: 13,align: "law",peaceful: 1 });
    await des.monster({ id: "Angel",x: 62,y: 13,align: "neutral", peaceful: 0 });
    await des.monster({ id: "Angel",x: 63,y: 13,align: "neutral",peaceful: 1 });
    // 
    // Assorted nasties
    await des.monster({ class: "L", peaceful: 0 });
    await des.monster({ class: "L", peaceful: 0 });
    await des.monster({ class: "L", peaceful: 0 });
    await des.monster({ class: "V", peaceful: 0 });
    await des.monster({ class: "V", peaceful: 0 });
    await des.monster({ class: "V", peaceful: 0 });
    await des.monster({ class: "D", peaceful: 0 });
    await des.monster({ class: "D", peaceful: 0 });
    await des.monster({ class: "D", peaceful: 0 });
 
 
    return des.finalize_level();
}