|
|
1번째 줄: |
1번째 줄: |
|
| |
|
|
| |
| /** 플러그인 uncydungeon***************************
| |
| * uncydungeon 실행
| |
| * 버전 => 0.1
| |
| * 작성자 : [[사용자:Jinhoftyu|Jinhoftyu]]
| |
| * JSON => uncydungeon = {"name":"uncydungeon","descript":"uncydungeon 실행","version":"0.1","local":true,"creat":"Jinhoftyu","state":"사용자:Jinhoftyu/Undungeon/플러그인","executable":true};
| |
| */
| |
| function plugin_uncydungeon() {
| |
| if($("[data-name='uncydungeon']").length >= 1){
| |
| // 이부분에 코드 입력 //
| |
| class Random {
| |
| nextInt(max) {
| |
| return Math.floor(Math.random() * max);
| |
| }
| |
| }
| |
|
| |
| class Item {
| |
| constructor(type, name, value) {
| |
| this.type = type;
| |
| this.name = name;
| |
| this.value = value;
| |
| }
| |
|
| |
| getType() {
| |
| return this.type;
| |
| }
| |
|
| |
| getName() {
| |
| return this.name;
| |
| }
| |
|
| |
| getValue() {
| |
| return this.value;
| |
| }
| |
|
| |
| setName(name) {
| |
| this.name = name;
| |
| }
| |
|
| |
| setValue(value) {
| |
| this.value = value;
| |
| }
| |
| }
| |
|
| |
| class Entity {
| |
| constructor(type, name, x, y, health) {
| |
| this.type = type;
| |
| this.name = name;
| |
| this.x = x;
| |
| this.y = y;
| |
| this.health = health;
| |
| }
| |
|
| |
| getType() {
| |
| return this.type;
| |
| }
| |
|
| |
| getName() {
| |
| return this.name;
| |
| }
| |
|
| |
| getHealth() {
| |
| return this.health;
| |
| }
| |
|
| |
| getAttack() {
| |
| return Main.getAttack(this.getName());
| |
| }
| |
|
| |
| setHealth(health) {
| |
| this.health = health;
| |
| }
| |
|
| |
| getX() {
| |
| return this.x;
| |
| }
| |
|
| |
| setX(x) {
| |
| this.x = x;
| |
| }
| |
|
| |
| getY() {
| |
| return this.y;
| |
| }
| |
|
| |
| setY(y) {
| |
| this.y = y;
| |
| }
| |
| }
| |
|
| |
| class StringBuilder {
| |
| constructor() {
| |
| this.data = [];
| |
| }
| |
|
| |
| append(text) {
| |
| this.data.push(text);
| |
| }
| |
|
| |
| delete(start, end) {
| |
| this.data.splice(start, end - start);
| |
| }
| |
|
| |
| length() {
| |
| return this.data.length;
| |
| }
| |
|
| |
| charAt(index) {
| |
| return this.data[index];
| |
| }
| |
|
| |
| toString() {
| |
| return this.data.join('');
| |
| }
| |
| }
| |
|
| |
| const rand = new Random();
| |
| let game = false;
| |
| const mapY = 20;
| |
| const mapX = 80;
| |
| const base = new Array(mapY);
| |
| const entity = new Array(mapY);
| |
| const entities = [];
| |
| const item = [];
| |
|
| |
| let dl;
| |
| let xl;
| |
| let hp;
| |
| let maxhp;
| |
| let pw;
| |
| let maxpw;
| |
| let time;
| |
|
| |
| let role;
| |
| let name = null;
| |
| let pl;
| |
| const inv = [];
| |
| const log = new StringBuilder();
| |
| let showInv = false;
| |
|
| |
| function refLog() {
| |
| let size = 0;
| |
| for (let i = 0; i < log.length(); i++) {
| |
| if (log.charAt(i) === '\n') {
| |
| size++;
| |
| }
| |
| }
| |
|
| |
| if (size > 3) {
| |
| let index = log.toString().indexOf("\n") + 1;
| |
| log.delete(0, index);
| |
| }
| |
| }
| |
|
| |
| function main() {
| |
| for (let i = 0; i < mapY; i++) {
| |
| const row = new Array(mapX);
| |
| base[i] = row;
| |
|
| |
| const entityRow = new Array(mapX);
| |
| entity[i] = entityRow;
| |
| }
| |
|
| |
| const readline = require('readline');
| |
| const rl = readline.createInterface({
| |
| input: process.stdin,
| |
| output: process.stdout
| |
| });
| |
|
| |
| const askName = () => {
| |
| rl.question("Your name? ", (answer) => {
| |
| name = answer;
| |
| while (!game) {
| |
| console.log(`
| |
| Your role?
| |
| a) Monk
| |
| b) Ranger
| |
| c) Valkryie
| |
| d) Wizard`);
| |
| rl.question("Choose your role: ", (roleChoice) => {
| |
| preset(roleChoice);
| |
| mapGen();
| |
| gameLoop();
| |
| });
| |
| }
| |
| });
| |
| };
| |
|
| |
| askName();
| |
| }
| |
|
| |
| function updateStack(x, y, items) {
| |
| const row = item[y];
| |
| row[x] = items;
| |
| item[y] = row;
| |
| }
| |
|
| |
| function pickup() {
| |
| const plx = pl.getX();
| |
| const ply = pl.getY();
| |
| const items = item[ply][plx];
| |
| if (items.length > 0) {
| |
| const item = items[0];
| |
| inv.push(item);
| |
| items.shift();
| |
| updateStack(plx, ply, items);
| |
| log.append("You picked up " + itemName(item) + ".\n");
| |
| turn();
| |
| } else {
| |
| log.append("There is nothing here.\n");
| |
| }
| |
| }
| |
|
| |
| function ascend() {
| |
| const plx = pl.getX();
| |
| const ply = pl.getY();
| |
| if (base[ply][plx] === '<') {
| |
| console.log("You escaped from the dungeon.");
| |
| process.exit(0);
| |
| } else {
| |
| log.append("You can't go up here.\n");
| |
| }
| |
| }
| |
|
| |
| function itemName(item) {
| |
| return item.getValue() + " " + item.getName() + (item.getValue() > 1 ? "s" : "");
| |
| }
| |
|
| |
| function move(en, dx, dy) {
| |
| const x = en.getX();
| |
| const y = en.getY();
| |
| if (base[y + dy][x + dx] !== '#' && entity[y + dy][x + dx] === null) {
| |
| entity[y][x] = null;
| |
| x += dx;
| |
| y += dy;
| |
| en.setX(x);
| |
| en.setY(y);
| |
| const floor = base[y][x];
| |
| entity[y][x] = en;
| |
| const items = item[y][x];
| |
|
| |
| // log output
| |
| if (en === pl) {
| |
| turn();
| |
| if (floor !== '.' && floor !== '\0') {
| |
| log.append("You are standing in " + floorDes(floor) + ".\n");
| |
| }
| |
| if (items.length > 1) {
| |
| log.append("You see here several items.\n");
| |
| } else if (items.length > 0) {
| |
| const item = items[0];
| |
| log.append("You see here " + itemName(item) + ".\n");
| |
| }
| |
| }
| |
| }
| |
| }
| |
|
| |
| function turn() {
| |
| for (let i = 0; i < entities.length; i++) {
| |
| const e = entities[i];
| |
| if (e !== pl) {
| |
| if (adjacent(e, pl)) {
| |
| attack(e, pl);
| |
| } else {
| |
| const randChoice = rand.nextInt(8);
| |
| switch (randChoice) {
| |
| case 0:
| |
| move(e, -1, 0);
| |
| break;
| |
| case 1:
| |
| move(e, 1, 0);
| |
| break;
| |
| case 2:
| |
| move(e, 0, -1);
| |
| break;
| |
| case 3:
| |
| move(e, 0, 1);
| |
| break;
| |
| case 4:
| |
| move(e, -1, -1);
| |
| break;
| |
| case 5:
| |
| move(e, 1, -1);
| |
| break;
| |
| case 6:
| |
| move(e, -1, 1);
| |
| break;
| |
| case 7:
| |
| move(e, 1, 1);
| |
| break;
| |
| }
| |
| }
| |
| }
| |
| }
| |
| time++;
| |
| }
| |
|
| |
| function mapGen() {
| |
| for (let y = 0; y < mapY; y++) {
| |
| for (let x = 0; x < mapX; x++) {
| |
|
| |
| // old mapgen
| |
| const xborder = (y === 1 || y === mapY - 2) && (x !== 0 && x !== mapX - 1);
| |
| const yborder = (x === 1 || x === mapX - 2) && (y !== 0 && y !== mapY - 1);
| |
| const floor = y > 1 && y < mapY - 2 && x > 1 && x < mapX - 2;
| |
| const up = x === 2 && y === 2;
| |
| const down = x === mapX - 3 && y === mapY - 3;
| |
| if (xborder || yborder) {
| |
| base[y][x] = '#';
| |
| } else if (up) {
| |
| base[y][x] = '<';
| |
| } else if (down) {
| |
| base[y][x] = '>';
| |
| } else if (floor) {
| |
| base[y][x] = '.';
| |
| }
| |
|
| |
| // item
| |
| if (base[y][x] === '.' && rand.nextInt(80) === 0) {
| |
| const items = [];
| |
| items.push((() => {
| |
| switch (rand.nextInt(6)) {
| |
| case 0:
| |
| return new Item('%', "food ration", 1);
| |
| case 1:
| |
| return new Item('$', "gold piece", 25);
| |
| case 2:
| |
| return new Item(')', "dagger", 1);
| |
| case 3:
| |
| return new Item('[', "leather armor", 1);
| |
| case 4:
| |
| return new Item('?', "scroll of upgrade", 1);
| |
| case 5:
| |
| return new Item('!', "potion of healing", 1);
| |
| }
| |
| })());
| |
| item[y][x] = items;
| |
| }
| |
|
| |
| // entity
| |
| if (base[y][x] === '.' && rand.nextInt(100) === 0) {
| |
| const e = (() => {
| |
| switch (rand.nextInt(5)) {
| |
| case 0:
| |
| return new Entity('B', "bat", x, y, getHP("bat"));
| |
| case 1:
| |
| return new Entity('r', "sewer rat", x, y, getHP("sewer rat"));
| |
| case 2:
| |
| return new Entity('k', "kobold", x, y, getHP("kobold"));
| |
| case 3:
| |
| return new Entity('o', "goblin", x, y, getHP("goblin"));
| |
| case 4:
| |
| return new Entity('&', "Demogorgon", x, y, getHP("Demogorgon"));
| |
| }
| |
| })();
| |
| entities.push(e);
| |
| entity[y][x] = e;
| |
| }
| |
| }
| |
| }
| |
| pl = new Entity('@', name, 2, 2, hp);
| |
| entity[2][2] = pl;
| |
| }
| |
|
| |
| function getHP(name) {
| |
| switch (name) {
| |
| case "bat":
| |
| return 2;
| |
| case "sewer rat":
| |
| return 4;
| |
| case "kobold":
| |
| return 5;
| |
| case "goblin":
| |
| return 8;
| |
| case "Demogorgon":
| |
| return 456;
| |
| default:
| |
| return 1;
| |
| }
| |
| }
| |
|
| |
| function getAttack(s) {
| |
| switch (s) {
| |
| case "bat":
| |
| case "goblin":
| |
| case "kobold":
| |
| return 4;
| |
| case "sewer rat":
| |
| return 3;
| |
| case "Demogorgon":
| |
| return 48;
| |
| default:
| |
| return 1;
| |
| }
| |
| }
| |
|
| |
| function adjacent(a, b) {
| |
| return Math.abs(a.getX() - b.getX()) <= 1 && Math.abs(a.getY() - b.getY()) <= 1;
| |
| }
| |
|
| |
| function attack(damager, damagee) {
| |
| const dam = damager.getAttack();
| |
| const health = damagee.getHealth();
| |
| if (damagee === pl) {
| |
| log.append("The " + damager.getName() + " hits!\n");
| |
| hp -= dam;
| |
| } else if (damager === pl) {
| |
| log.append("You hit the " + damagee.getName() + "\n");
| |
| }
| |
| if (dam >= health) {
| |
| death(damagee);
| |
| } else {
| |
| damagee.setHealth(damagee.getHealth() - dam);
| |
| }
| |
| }
| |
|
| |
| function death(e) {
| |
| if (e === pl) {
| |
| log.append("You were slain...");
| |
| refLog();
| |
| display();
| |
| process.exit(0);
| |
| } else {
| |
| entities.splice(entities.indexOf(e), 1);
| |
| entity[e.getY()][e.getX()] = null;
| |
| log.append(e.getName() + " died!\n");
| |
| }
| |
| }
| |
|
| |
| function display() {
| |
| const display = new StringBuilder();
| |
| for (let y = 0; y < mapY; y++) {
| |
| for (let x = 0; x < mapX; x++) {
| |
| const floor = base[y][x];
| |
| const it = item[y][x];
| |
| const en = entity[y][x];
| |
| let s = " ";
| |
| if (floor !== '\0') {
| |
| s = floor;
| |
| }
| |
| if (it.length > 0) {
| |
| s = it[0].getType();
| |
| }
| |
| if (en !== null) {
| |
| s = en.getType();
| |
| }
| |
| display.append(s);
| |
| }
| |
| display.append("\n");
| |
| }
| |
| refLog();
| |
| console.log(log.toString());
| |
| display.append(name + " the " + role + " t:" + time + "\nDlvl:" + dl + " Lv:" + xl + " HP:" + hp + "/" + maxhp + " Pw:" + pw + "/" + maxpw + "\n\n");
| |
| console.log(display.toString());
| |
| }
| |
|
| |
| function inventory() {
| |
| const display = new StringBuilder();
| |
| let c = 97;
| |
| display.append("Your inventory:\n");
| |
| if (inv.length === 0) {
| |
| display.append("It's empty.\n");
| |
| } else {
| |
| for (let i = 0; i < inv.length; i++) {
| |
| display.append(String.fromCharCode(c) + ") " + itemName(inv[i]) + "\n");
| |
| c++;
| |
| }
| |
| }
| |
| display.append("\nType any command...\n");
| |
| console.log(display.toString());
| |
| showInv = false;
| |
| }
| |
|
| |
| function preset(s) {
| |
| switch (s) {
| |
| case "a":
| |
| role = "Monk";
| |
| maxhp = 20;
| |
| maxpw = 10;
| |
| break;
| |
| case "b":
| |
| role = "Ranger";
| |
| maxhp = 15;
| |
| maxpw = 5;
| |
| break;
| |
| case "c":
| |
| role = "Valkriye";
| |
| maxhp = 20;
| |
| maxpw = 5;
| |
| break;
| |
| case "d":
| |
| role = "Wizard";
| |
| maxhp = 15;
| |
| maxpw = 15;
| |
| break;
| |
| default:
| |
| return;
| |
| }
| |
| xl = 1;
| |
| hp = maxhp;
| |
| pw = maxpw;
| |
| game = true;
| |
| }
| |
|
| |
| function floorDes(c) {
| |
| switch (c) {
| |
| case '<':
| |
| return "staircase leading upward";
| |
| case '>':
| |
| return "staircase leading downward";
| |
| default:
| |
| return "nothing";
| |
| }
| |
| }
| |
|
| |
| main();
| |
|
| |
| }
| |
| }
| |
| $( plugin_uncydungeon );
| |
| /* uncydungeon 끝 */
| |