/* This software is licensed under the new BSD license. Copyright (c) 2011, Seussnu Koromotani All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the H.AltProject nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ var THIEF = { conf : { id : 'Thief', // was used "HTML's id", and "System tag". fontFace : 'monospace, sans-serif', textColor : '#FFFFFF', emTextColor : '#FF0000', bgColor : '#000000', grayColor : '#7f7f7f', gridStyle : '0px none #888888', // css td border options mapWidth : 60, mapHeight : 20, mapDepth : 256, language : null, languagePriolity : ['en', 'ja'], statusPosition : 'bottom', // top or bottom statusLineFormat : [ '${THIEF.global.actDG.%get@name%}:${THIEF.global.actDG.nowLV}' + ' ${THIEF.global.adventurer.%get@name%}' + ' ♥:${THIEF.global.adventurer.%get@hp%}' + ' STR:${THIEF.global.adventurer.%get@str%}' + ' CON:${THIEF.global.adventurer.%get@con%}' + ' DEX:${THIEF.global.adventurer.%get@dex%}' + ' INT:${THIEF.global.adventurer.%get@int%}' + ' POW:${THIEF.global.adventurer.%get@pow%}' + ' EDU:${THIEF.global.adventurer.%get@edu%}' + ' APP:${THIEF.global.adventurer.%get@app%}' + ' SAN:${THIEF.global.adventurer.%get@san%}' + ' AC:${THIEF.global.adventurer.%get@armorPoint%}', 'Lang:${THIEF.conf.language}' + ' Turn:${THIEF.global.turn}' + ' CT:${THIEF.global.adventurer.%get@ct%}' ], messagePosition : 'top', // top or bottom messageLines : 3, messageHistorySize : 256, // infomationOverlap : true, mainWindowPosition : 'left', // css float option (left, right, none) msgOverflow : 'hidden', // css overflow option (visible, scroll, hidden, auto) itemSort : ['$', '"', ']', '[', '%', '!', '?', '+', '=', '/', '(', ')', '*' ], debugmode : false }, global : { actLV : null, actDG : null, turn : 0, keycode : NaN, hist : [], adventurer : null, // Player size : { Window : {width:Number.NaN, height:Number.NaN}, Main : {width:Number.NaN, height:Number.NaN}, // Input, Message, Map, Status Input : {width:Number.NaN, height:Number.NaN}, // 入力欄 Message : {width:Number.NaN, height:Number.NaN}, // メッセージ欄(入力上部) Map : {width:Number.NaN, height:Number.NaN}, // マップ Status : {width:Number.NaN, height:Number.NaN}, // ステータス Infomation : {width:Number.NaN, height:Number.NaN}, // 情報出力(インベントリの内容など) Debug : {width:Number.NaN, height:Number.NaN} // デバッグ情報 } }, KEY : { // charCodeAt の値 Backspace : 8, Enter : 13, Shift : 16, Ctrl : 17, Alt : 18, Esc : 27, Space : 32, PageUp : 33, // ! PageDown : 34, // " End : 10035, // # = 35 Home : 36, // $ Left : 37, // % Up : 38, // & Right : 39, // ' Down : 40, // Comma : ','.charCodeAt(0), Period : '.'.charCodeAt(0), Minus : '-'.charCodeAt(0), Sharp : '#'.charCodeAt(0), LT : '<'.charCodeAt(0), GT : '>'.charCodeAt(0), Asterisk : '*'.charCodeAt(0), A : 65, B : 66, C : 67, D : 68, E : 69, F : 70, G : 71, H : 72, I : 73, J : 74, K : 75, L : 76, M : 77, N : 78, O : 79, P : 80, Q : 81, R : 82, S : 83, T : 84, U : 85, V : 86, W : 87, X : 88, Y : 89, Z : 90, a : 97, b : 98, c : 99, d : 100, e : 101, f : 102, g : 103, h : 104, i : 105, j : 106, k : 107, l : 108, m : 109, n : 110, o : 111, p : 112, q : 113, r : 114, s : 115, t : 116, u : 117, v : 118, w : 119, x : 120, y : 121, z : 122, // [ = WinKey = 91 // \ = WinKey = 92 F1 : 112, // = p F2 : 113, // = q F3 : 114, // = r F4 : 115, // = s F5 : 116, // = t F6 : 117, // = u F7 : 118, // = v F8 : 119, // = w F9 : 120, // = x F10 : 121, // = y F11 : 122, // = z F12 : 123 // = { = "Shift + [" }, PROP : { siz : 'siz', shapeWidth : 'shapeWidth', shapeHeight : 'shapeHeight', //shapeDepth : 'shapeDepth', inventoryWidth : 'inventoryWidth', inventoryHeight : 'inventoryHeight', inventoryDepth : 'inventoryDepth', inventoryCellSize : 'inventoryCellSize', myOwner : 'myOwner', mergeable : 'mergeable', stackable : 'stackable', symbol : 'symbol', name : 'name', color : 'color', displayName : 'displayName', symbolName : 'symbolName', alphabet : 'alphabet', actObjectList : 'actObjectList', active : 'active', ct : 'ct', maxct : 'maxct', dex : 'dex', hp : 'hp', attack : 'attack', equipable : 'equipable', slot : 'slot', slotName : 'slotName', db : 'db', ac : 'ac', armorPoint : 'armorPoint', equiped : 'equiped' } }; // // Override // //noinspection JSUnusedGlobalSymbols window.onload = function(onload) { return function () { if (!!onload) { onload(); } THIEF.util.init(); }; }(window.onload); //noinspection JSUnusedGlobalSymbols window.onresize = function(onresize) { return function() { if (!!onresize) { onresize(); } if (window.innerWidth) { THIEF.global.size.Window.width = window.innerWidth; THIEF.global.size.Window.height = window.innerHeight; } else { THIEF.global.size.Window.width = document.documentElement.clientWidth || document.body.clientWidth || document.body.scrollWidth; THIEF.global.size.Window.height = document.documentElement.clientHeight || document.body.clientHeight || document.body.scrollHeight; } /* THIEF.global.size.Main.width = document.getElementById('Main').offsetWidth; THIEF.global.size.Main.height = document.getElementById('Main').offsetHeight; THIEF.global.size.Input = document.getElementById('Input').offsetWidth; THIEF.global.size.Input = document.getElementById('Input').offsetHeight; THIEF.global.size.Message = document.getElementById('Message').offsetWidth; THIEF.global.size.Message = document.getElementById('Message').offsetHeight; THIEF.global.size.Map = document.getElementById('Map').offsetWidth; THIEF.global.size.Map = document.getElementById('Map').offsetHeight; THIEF.global.size.Status = document.getElementById('Status').offsetWidth; THIEF.global.size.Status = document.getElementById('Status').offsetHeight; THIEF.global.size.Infomation = document.getElementById('Infomation').offsetWidth; THIEF.global.size.Infomation = document.getElementById('Infomation').offsetHeight; THIEF.global.size.Debug = document.getElementById('Debug').offsetWidth; THIEF.global.size.Debug = document.getElementById('Debug').offsetHeight; */ }; }(window.onresize); //noinspection JSUnusedGlobalSymbols document.onkeypress = function(onkeypress) { return function(event) { if (!!onkeypress) { onkeypress(event); } THIEF.global.keycode = THIEF.util.getKeyCode(event); THIEF.util.next(); THIEF.global.keycode = 0; }; }(document.onkeypress); if (!Object.create) { Object.create = function(o) { var func = function() { }; func.prototype = o; return new func(); }; } if (!Math.sign) { Math.sign = function(num) { if (num > 0) { return 1; } else { if (num < 0) { return -1; } else { return 0; } } }; } if (!Math.dice) { Math.dice = function(fre, sides) { var val = 0; for (var i = 0; i < fre; i++) { val += Math.round(Math.random() * sides + 0.5); } return val; } } if (!Array.prototype.remove) { Array.prototype.remove = function(o) { var len = this.length; var result = false; for (var i = 0; i < len; i++) { if (!result && this[i] === o) { result = true; delete this[i]; } if (result) { // shifting this[i] = this[i + 1]; } } if (result) { this.length = len - 1; } return result; }; } if (!Array.prototype.getLast) { Array.prototype.getLast = function() { return this[this.length - 1]; }; } if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(elt /*, from*/) { var len = this.length; var from = Number(arguments[1]) || 0; from = (from < 0) ? Math.ceil(from) : Math.floor(from); if (from < 0) { from += len; } for (; from < len; from++) { if (from in this && this[from] === elt) { return from; } } return -1; }; } // xxx : Manualable // $xxx : Common // _xxx : DebugModeOnly // THIEF.func = {}; THIEF.func.method = {}; THIEF.func.method.get = function (param) { var val; if (THIEF.global.debugmode) { if (typeof param === 'undefined') { alert('引数が指定されていません'); } } if (typeof this[param] === 'function') { val = this[param](); } else if (this[param]) { if (this[param][THIEF.conf.language]) { val = this[param][THIEF.conf.language]; } else { val = this[param]; for (var i = 0; i < THIEF.conf.languagePriolity.length; i++) { if (this[param][THIEF.conf.languagePriolity[i]]) { val = this[param][THIEF.conf.languagePriolity[i]]; break; } } } } return val; }; THIEF.func.method.isBasedOn = function (obj) { return this.uniqNumber === obj.uniqNumber; }; THIEF.func.method.removeFromInventory = function(obj) { var objX = obj.x; var objY = obj.y; THIEF.html.addDebugMessage(obj.get(THIEF.PROP.displayName) + 'を' + this.get(THIEF.PROP.displayName) + 'のインベントリ座標[' + obj.x + ', ' + obj.y + ']から除外...'); var shapeX = Math.ceil(obj.get(THIEF.PROP.shapeWidth) / this.get(THIEF.PROP.inventoryCellSize)) || 1; var shapeY = Math.ceil(obj.get(THIEF.PROP.shapeHeight) / this.get(THIEF.PROP.inventoryCellSize)) || 1; if (obj.myOwner === this) { obj.myOwner = null; obj.x = undefined; obj.y = undefined; for (var i = 0; i < shapeX; i++) { for (var j = 0; j < shapeY; j++) { THIEF.html.addDebugMessage('座標[' + (objX + i) + ', ' + (objY + j) + ']から除外'); this.inventory[objX + i][objY + j].remove(obj); THIEF.html.refreshXy(objX + i, objY + j); } } } THIEF.html.addDebugMessage('...' + obj.get(THIEF.PROP.displayName) + 'を' + this.get(THIEF.PROP.displayName) + 'のインベントリ座標[' + objX + ', ' + objY + ']から除外完了。'); return true; }; THIEF.func.method.addToInventory = function(obj, x, y) { var result = false; THIEF.html.addDebugMessage(obj.get(THIEF.PROP.displayName) + 'を' + this.get(THIEF.PROP.displayName) + 'のインベントリ座標[' + x + ', ' + y + ']に追加処理を開始...'); var target = this.getInventoryFreeSpace(obj, x, y); if (target.x >= 0 && target.y >= 0) { obj.x = target.x; obj.y = target.y; obj.myOwner = this; THIEF.html.addDebugMessage(target.x + ', ' + target.y + 'を基準に ' + target.width + 'x' + target.height + ' のサイズとして追加'); for (var i = target.x; i < target.x + target.width; i++) { for (var j = target.y; j < target.y + target.height; j++) { if (!this.inventory) { this.inventory = []; } if (!this.inventory[i]) { this.inventory[i] = []; } if (!this.inventory[i][j]) { this.inventory[i][j] = []; } // Item の場合のみアルファベットを設定 if (obj.isItem) { THIEF.html.addDebugMessage(obj.get(THIEF.PROP.displayName) + ' はアイテムなので、アルファベットの割り当てを行う...'); var alphabets = this.getInventoryAlphabets(); if (typeof obj.get(THIEF.PROP.alphabet) === 'string' && alphabets.indexOf(obj.get(THIEF.PROP.alphabet)) === -1) { // すでにアルファベットが登録済みで、かつ変更の必要は無い THIEF.html.addDebugMessage('すでに割りあたっているもの' + obj.get(THIEF.PROP.alphabet) + 'が再利用可能。'); } else { var alp = this.getInventoryNonExistAlphabet(); if (typeof alp === 'undefined') { alert('アルファベット関係の使用制限バグ'); } else { obj[THIEF.PROP.alphabet] = alp; } THIEF.html.addDebugMessage('新たに ' + alp + ' を割り当てた。') } THIEF.html.addDebugMessage('...アルファベットの割り当て処理完了。'); } this.inventory[i][j].push(obj); THIEF.html.addDebugMessage('[' + i + ', ' + j + ']に' + obj.get(THIEF.PROP.alphabet) + 'として追加'); result = true; } } } else { THIEF.html.addDebugMessage('追加可能なスペースがない。'); } THIEF.html.addDebugMessage('...' + obj.get(THIEF.PROP.displayName) + 'を' + this.get(THIEF.PROP.displayName) + 'のインベントリ座標[' + x + ', ' + y + ']に追加処理を完了。(return : ' + result + ')'); return result; }; THIEF.func.method.getInventoryRandomFreeSpace = function (obj) { var point; var challenge = this.get(THIEF.PROP.inventoryWidth) * this.get(THIEF.PROP.inventoryHeight); var counter = 0; while (counter < challenge) { counter++; var x = Math.round(Math.random() * this.get(THIEF.PROP.inventoryWidth)); var y = Math.round(Math.random() * this.get(THIEF.PROP.inventoryHeight)); point = this.getInventoryFreeSpace(obj, x, y); if (typeof point !== 'undefined' && this.inventory[x][y].getLast().type === THIEF.Data.Obj.$Floor.type) { //if (point.x === 'number' && typeof point.y === 'number') { break; } } // ランダムに見つからなければ、左上から順に検索 if (typeof point.x !== 'number' && typeof point.y !== 'number') { point = this.getInventoryFreeSpace(obj); } return point; }; THIEF.func.method.getInventoryFreeSpace = function(obj, _x, _y) { var invCellSize = this.get(THIEF.PROP.inventoryCellSize) || 10; var invWidth = this.get(THIEF.PROP.inventoryWidth) || 0; var invHeight = this.get(THIEF.PROP.inventoryHeight) || 0; var invDepth = this.get(THIEF.PROP.inventoryDepth) || 0; var objShapeWight = obj.get(THIEF.PROP.shapeWidth) || Math.ceil(obj.get(THIEF.PROP.siz) / 20) || 1; var objShapeHeight = obj.get(THIEF.PROP.shapeHeight) || Math.ceil(obj.get(THIEF.PROP.siz) / 20) || 1; var objInvShapeWight = Math.ceil(objShapeWight / invCellSize); var objInvShapeHeight = Math.ceil(objShapeHeight / invCellSize); var result; var startX = _x || 0; var startY = _y || 0; var once = (typeof _x === "number" || typeof _y === "number"); THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + 'のインベントリ(' + invHeight + ', ' + invWidth + ', ' + invDepth + ')の座標[' + _x + ', ' + _y + ']に' + obj.get(THIEF.PROP.displayName) + '(' + objInvShapeWight + ', ' + objInvShapeHeight + ')として格納できるか確認を開始...'); var free; outloop : for (var ancY = startY; ancY < invHeight; ancY++) { //alert(ancY + '行目を処理...'); for (var ancX = startX; ancX < invWidth; ancX++) { //alert(ancX + ', ' + ancY); free = true; //THIEF.html.addDebugMessage(ancX + ', ' + ancY + 'を確認...'); inloop : for (var targetY = ancY; targetY < ancY + objInvShapeHeight; targetY++) { for (var targetX = ancX + objInvShapeWight - 1; targetX >= ancX; targetX--) { if (this.inventory && this.inventory[targetX] && this.inventory[targetX][targetY]) { if (this.inventory[targetX][targetY].length <= invDepth) { var lastObj = this.inventory[targetX][targetY].getLast(); if (typeof lastObj === 'undefined' || lastObj.type !== THIEF.Data.Obj.$Wall.type && (obj.get(THIEF.PROP.stackable) || lastObj.get(THIEF.PROP.stackable)) /* || !lastObj.get(THIEF.PARAM.mergeable) */) { if (lastObj) { THIEF.html.addDebugMessage('[' + targetX + ', ' + targetY + ']にある' + lastObj.get(THIEF.PROP.displayName) + 'には重ねられる。'); } else { THIEF.html.addDebugMessage('[' + targetX + ', ' + targetY + ']には何も無いので重ねられる。'); } } else { free = false; ancX = targetX; //THIEF.html.addDebugMessage(targetX + ', ' + targetY + 'にある' + lastObj.get(THIEF.PARAM.name) + 'には重ねられない'); break inloop; } } else { free = false; ancX = targetX; //THIEF.html.addDebugMessage(targetX + ', ' + targetY + ' は高さが足りないからダメ'); break inloop; } } else { THIEF.html.addDebugMessage(targetX + ', ' + targetY + ' は空'); } } } if (free) { result = { x : ancX, y : ancY, width : objInvShapeWight, height : objInvShapeHeight }; break outloop; } if (once) { break outloop; } } } THIEF.html.addDebugMessage('...' + obj.get(THIEF.PROP.displayName) + '(' + objInvShapeWight + ', ' + objInvShapeHeight + ')として格納できるか確認を完了。'); return result; }; THIEF.func.method.attackedBy = function(obj) { THIEF.html.addDebugMessage(obj.get(THIEF.PROP.displayName) + ' による ' + this.get(THIEF.PROP.displayName) + ' への攻撃処理を開始...'); //my.slot[THIEF.PARAM.slot.hand] = selected[0]; var val; if (typeof obj.slot === 'undefined' || typeof obj.slot[THIEF.Data.Obj.$Item.slot] === 'undefined') { if (typeof obj.damage === 'undefined') { val = '1d2'; } else { val = obj.damage; } } else { val = obj.slot[THIEF.Data.Obj.$Item.slot].damage; } var revP = THIEF.util.infixToRevP(val); var damage = THIEF.util.execRevP(revP); THIEF.html.addDebugMessage('ベースダメージ : ' + damage); damage += obj.get(THIEF.PROP.db); THIEF.html.addDebugMessage('ダメージボーナス追加後 : ' + damage); var ac = this.get(THIEF.PROP.armorPoint); THIEF.html.addDebugMessage('AC適用後 : ' + (damage - ac)); damage -= ac; if (damage > 0) { THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + ' HP : ' + this.get(THIEF.PROP.hp) + ' -> ' + (this.get(THIEF.PROP.hp) - damage) + 'とする。'); this.hp -= damage; THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.attack, damage, this.get(THIEF.PROP.displayName), obj.get(THIEF.PROP.displayName))); } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.defence, this.get(THIEF.PROP.displayName), obj.get(THIEF.PROP.displayName))); } obj.ct -= 100; if (this.get(THIEF.PROP.hp) <= 0) { THIEF.html.addDebugMessage('死亡処理を開始...'); THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.killBy, this.get(THIEF.PROP.displayName), obj.get(THIEF.PROP.displayName))); THIEF.global.actLV.removeFromInventory(this); this.next = function() { return true }; THIEF.html.addDebugMessage('...死亡処理を完了。') } THIEF.html.addDebugMessage('...攻撃処理を完了。'); return true; }; THIEF.func.method.getInventoryXyObjects = function(x, y) { return this.inventory[x][y]; }; THIEF.func.method.getInventoryXyLastObject = function(x, y) { var obj; // 必ずしも inventory の配列を完全に持っているとは限らないので注意すること if (this.inventory && this.inventory[x] && this.inventory[x][y]) { obj = this.inventory[x][y].getLast(); } return obj; }; THIEF.func.method.delInventoryObject = function(o) { this.delInventoryXyObject(o.x, o.y, o); }; THIEF.func.method.delInventoryXyObject = function(x, y, o) { this.inventory[x][y].remove(o); /* if (this.mapRefreshPointList) { this.mapRefreshPointList.push({ x: x, y: y }); } */ }; // ループ処理を加えること THIEF.func.method.getInventoryAlphabets = function() { var alphabets = []; if (this.inventory) { for (var i = 0; i < this.get(THIEF.PROP.inventoryWidth); i++) { if (this.inventory[i]) { for (var j = 0; j < this.get(THIEF.PROP.inventoryHeight); j++) { if (this.inventory[i][j]) { for (var k = 0; k < this.inventory[i][j].length; k++) { var alphabet = this.inventory[i][j][k].get(THIEF.PROP.alphabet); if (alphabet) { alphabets.push(alphabet); } } } } } } } return alphabets; }; THIEF.func.method.getInventoryNonExistAlphabet = function() { // 常にアルファベットの先頭が利用されないようにしている var key = THIEF.KEY; var index = key.a; return function() { var alphabets = this.getInventoryAlphabets(); var counter = 0; while (alphabets.indexOf(String.fromCharCode(index)) !== -1 && counter < 52) { counter++; index++; if (index === (key.z + 1)) { index = key.A; } else { if (index === (key.Z + 1)) { index = key.a; } } } var alphabet; if (counter < 52) { alphabet = String.fromCharCode(index); index++; } return alphabet; }; }(); // 配列を渡してカリー化(?) THIEF.func.method.selecter = function(objs, exec, immediately, abc) { var key = THIEF.KEY; var selected = []; var targets = []; var i, j; THIEF.html.addDebugMessage('セレクターを生成'); // root_abc var alphabetIndex = key.a; // 一覧出力 for (i = 0; i < THIEF.conf.itemSort.length; i++) { //アイテムがあるか確認 var first = true; for (j = 0; j < objs.length; j++) { if (THIEF.conf.itemSort[i] === objs[j].symbol) { if (first) { first = false; THIEF.html.addInfomation('' + objs[j].get(THIEF.PROP.symbolName) + ''); } var alphabet; if (abc) { alphabet = String.fromCharCode(alphabetIndex); alphabetIndex++; } else { alphabet = objs[j].alphabet || this.getInventoryNonExistAlphabet(); if (alphabet === null) { // ページ切り替え break; } objs[j].alphabet = alphabet; } THIEF.html.addInfomation(alphabet + ' - ' + objs[j].get(THIEF.PROP.displayName)); targets[alphabet] = objs[j]; } } } // 選択用関数返却 return function() { var finish = false; switch (THIEF.global.keycode) { case 0: break; case key.Asterisk: break; case key.Esc: finish = true; selected.length = 0; break; case key.Space: break; case key.Enter: finish = true; this.action = THIEF.func.method.action; break; // すべてを選択しない case key.Minus: if (immediately) { selected.push(undefined); finish = true; } else { selected.length = 0; for (var i = 0; i < targets.length; i++) { // 表示を初期化すること } } break; default: var item = targets[String.fromCharCode(THIEF.global.keycode)]; var itemID = THIEF.conf.id + '_' + String.fromCharCode(THIEF.global.keycode); if (typeof item !== 'undefined') { if (document.getElementById(itemID).innerHTML === ' - ') { document.getElementById(itemID).innerHTML = ' + '; selected.push(item); } else { document.getElementById(itemID).innerHTML = ' - '; selected.remove(item); } } if (immediately) { finish = true; } break; } var result = false; if (finish) { // 画面クリア THIEF.html.clearInfomation(''); // アクションを元に戻す this.action = THIEF.func.method.action; // 選択後のアクションを実行 result = exec(selected); } return result; }; }; THIEF.func.method.cpu = function() { THIEF.html.addDebugMessage('CPU行動開始...'); var dx = 0; var dy = 0; var diffX = THIEF.global.adventurer.x - this.x; var diffY = THIEF.global.adventurer.y - this.y; if (diffX > 0) { dx = 1; } else if (diffX < 0) { dx = -1; } if (diffY > 0) { dy = 1; } else if (diffY < 0) { dy = -1; } this.move(dx, dy); THIEF.html.addDebugMessage('...CPU行動完了'); return true; }; THIEF.func.method.move = function(dx, dy) { var result; THIEF.html.addDebugMessage('移動処理 move(' + dx + ', ' + dy + ') を開始...'); THIEF.html.addDebugMessage(THIEF.global.actLV.get(THIEF.PROP.displayName) + 'のインベントリ座標[' + (this.x + dx) + ', ' + (this.y + dy) + ']を調査を行う。'); var target = THIEF.global.actLV.getInventoryXyLastObject(this.x + dx, this.y + dy); if (this.get(THIEF.PROP.stackable) || target.get(THIEF.PROP.stackable)) { var sX = this.x; var sY = this.y; THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + '[' + this.x + ', ' + this.y + ']は' + target.get(THIEF.PROP.displayName) + '[' + (this.x + dx) + ', ' + (this.y + dy) + ']の上に移動する。'); THIEF.global.actLV.removeFromInventory(this); THIEF.html.addDebugMessage('移動前の座標[' + sX + ', ' + sY + ']の描画を更新'); THIEF.html.refreshXy(sX, sY); this.x = sX + dx; this.y = sY + dy; THIEF.global.actLV.addToInventory(this, this.x, this.y); THIEF.html.addDebugMessage('移動後の座標[' + this.x + ', ' + this.y + ']の描画を更新'); THIEF.html.refreshXy(this.x, this.y); this.ct -= 60; result = true; } else { if (target.get(THIEF.PROP.active)) { THIEF.html.addDebugMessage('active なものが対象なので攻撃してみる。'); target.attackedBy(this); result = true; } else { THIEF.html.addDebugMessage('インベントリ座標[' + (this.x + dx) + ', ' + (this.y + dy) + '] には移動できない。'); result = false; } } THIEF.html.addDebugMessage('...移動処理を完了。'); return result; }; THIEF.func.method.inputWait = function () { this.next = THIEF.func.method.manual; THIEF.html.addDebugMessage('入力待ち'); THIEF.html.addMessage(); // 改行 return false; }; // 基本は AI 処理とする THIEF.func.method.next = function() { return this.cpu(); }; THIEF.func.method.notify = function() { if (typeof this.inventory !== "undefined") { var width = this.get(THIEF.PROP.inventoryWidth); for (var x = 0; x < width; x++) { if (typeof this.inventory[x] === "undefined") { break; } var length = this.get(THIEF.PROP.inventoryHeight); for (var y = 0; y < length; y++) { if (typeof this.inventory[x][y] === "undefined") { break; } var height = this.inventory[x][y].length; for (var h = 0; h < height; h++) { this.inventory[x][y][h].notify(); } } } } // CT を増加 if (this.get(THIEF.PROP.active)) { if (this.ct > 100) { this.ct = 100; } if (typeof this.get(THIEF.PROP.dex) === undefined) { this[THIEF.PROP.ct] += this.get(THIEF.PROP.dex); } else { this[THIEF.PROP.ct] += 33; // test } THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + ' の CT を ' + this[THIEF.PROP.ct] + ' に増加。'); } // ct が 100 を超えていたら行動対象に登録 if (this.get(THIEF.PROP.ct) >= 100) { if (typeof this[THIEF.PROP.myOwner][THIEF.PROP.actObjectList] === "undefined") { this[THIEF.PROP.myOwner][THIEF.PROP.actObjectList] = []; } THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + ' を、オーナ:' + this[THIEF.PROP.myOwner].get(THIEF.PROP.displayName) + ' に登録。'); this[THIEF.PROP.myOwner][THIEF.PROP.actObjectList].push(this); } }; THIEF.func.method.action = function() { THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + ' の行動を開始...'); if (typeof this[THIEF.PROP.actObjectList] !== 'undefined') { // ct の小さい順にソートする for (var i = 0; i < this[THIEF.PROP.actObjectList].length - 2; i++) { var isSorted = true; for (var j = this[THIEF.PROP.actObjectList].length - 1; j >= (1 + i); j--) { if (this[THIEF.PROP.actObjectList][j].get(THIEF.PROP.ct) < this[THIEF.PROP.actObjectList][j - 1].get(THIEF.PROP.ct)) { var swap = this[THIEF.PROP.actObjectList][j]; this[THIEF.PROP.actObjectList][j] = this[THIEF.PROP.actObjectList][j - 1]; this[THIEF.PROP.actObjectList][j - 1] = swap; isSorted = false; } } if (isSorted) { break; } } // ct の大きい順(配列の最後部)から実行 var obj = this[THIEF.PROP.actObjectList].pop(); for (; typeof obj !== 'undefined'; obj = this[THIEF.PROP.actObjectList].pop()) { THIEF.html.addDebugMessage(obj.get(THIEF.PROP.displayName) + ' の処理を開始...'); if (obj.action() === false) { // 行動が完了しない場合、現在のオブジェクトを再登録して一時停止(結果的に入力を待つ) THIEF.html.addDebugMessage('...' + obj.get(THIEF.PROP.displayName) + ' は処理が完了しなかった。'); this[THIEF.PROP.actObjectList].push(obj); break; } THIEF.html.addDebugMessage('...処理を完了'); } } var result = true; if (typeof this[THIEF.PROP.actObjectList] === 'undefined' || this[THIEF.PROP.actObjectList].length === 0) { if (this.active && this.turnEnd !== THIEF.global.turn) { if (this.get(THIEF.PROP.ct) >= 100) { if (this.next()) { this.turnEnd = THIEF.global.turn; //this[THIEF.PARAM.ct] -= 100; result = true; } else { result = false; } } } } else if (this[THIEF.PROP.actObjectList].length > 0) { result = false; } THIEF.html.addDebugMessage('... ' + this.get(THIEF.PROP.displayName) + ' の行動を完了。 (result = ' + result + ')'); return result; }; THIEF.func.method.decay = function() { if (this.decayable) { this.dp--; if (this.dp <= 0) { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.decay, this.name)); THIEF.global.actLV.delInventoryObject(this); } } return true; }; THIEF.func.method.manual = function() { var finish; var code = THIEF.global.keycode; if (code === 0) { finish = false; THIEF.html.addDebugMessage('無効なキー入力のため、何の処理もしない。') } else { THIEF.html.addDebugMessage(String.fromCharCode(code) + '(' + code + ')の入力に対する処理を開始...'); for (var name in THIEF.Data.Keymap) { if (THIEF.Data.Keymap[name].key !== 'undefined' && THIEF.Data.Keymap[name].key === code) { THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + ' の ' + name + ' コマンドを実行'); finish = THIEF.Data.Keymap[name].cmd.call(this); break; } } if (typeof finish === 'undefined') { if (code !== THIEF.KEY.Esc) { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.commandNotFound, String.fromCharCode(code))); } finish = false; } THIEF.html.addDebugMessage('...' + String.fromCharCode(code) + '(' + code + ')の入力に対する処理を完了。(return : ' + finish + ')'); if (finish) { this.next = THIEF.func.method.inputWait; } } return finish; }; THIEF.func.method.spawn = function (obj) { THIEF.html.addDebugMessage('湧き処理を開始...'); // 空きスペースの検索条件 var point = this.getInventoryRandomFreeSpace(obj); this.addToInventory(obj, point.x, point.y); THIEF.html.refreshXy(obj.x, obj.y); THIEF.html.addDebugMessage('...湧き処理を完了'); return obj; }; THIEF.func.method.goTheStairs = function(trueIsUpFalseIsDown) { var floor = THIEF.global.actLV.getInventoryXyObjects(this.x, this.y); var stairs; var flag = false; // 足元に、階段があるか確認 for (var i = 0; i < floor.length; i++) { if (trueIsUpFalseIsDown && floor[i].symbol === THIEF.Data.Obj.UpStairs.symbol || !trueIsUpFalseIsDown && floor[i].symbol === THIEF.Data.Obj.DownStairs.symbol) { flag = true; stairs = floor[i]; break; } } if (flag) { if (trueIsUpFalseIsDown) { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.goUpStairs, this.get(THIEF.PROP.displayName))); } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.goDownStairs, this.get(THIEF.PROP.displayName))); } THIEF.util.createLevel(stairs.nextDun, stairs.nextLv); THIEF.global.actLV.removeFromInventory(this); var oldDG = THIEF.global.actDG; var oldLV = THIEF.global.actDG.nowLV; // 新しい階層をセット THIEF.global.actDG = stairs.nextDun; THIEF.global.actDG.nowLV = stairs.nextLv; THIEF.global.actLV = stairs.nextDun[stairs.nextLv]; // 対になる階段が泣ければ作成する if (!stairs.partner) { // ブランチと、通常で場合分け if (stairs.isBranch) { // ブランチの場合は新規作成 var branchStairs; if (trueIsUpFalseIsDown) { branchStairs = THIEF.util.factory(THIEF.Data.Obj.DownStairs); } else { branchStairs = THIEF.util.factory(THIEF.Data.Obj.UpStairs); } branchStairs.point = THIEF.global.actLV.getInventoryRandomFreeSpace(branchStairs); branchStairs.nextDun = oldDG; branchStairs.nextLv = oldLV; branchStairs.color = 'red'; // 互いに登録 stairs.partner = branchStairs; branchStairs.partner = stairs; THIEF.global.actLV.addToInventory(branchStairs, branchStairs.point.x, branchStairs.point.y); } else { // 通常の場合は既設にくっつける // 互いに登録 if (trueIsUpFalseIsDown) { stairs.partner = THIEF.global.actLV.downStairs; THIEF.global.actLV.downStairs.partner = stairs; } else { stairs.partner = THIEF.global.actLV.upStairs; THIEF.global.actLV.upStairs.partner = stairs; } } } THIEF.global.actLV.addToInventory(this, stairs.partner.point.x, stairs.partner.point.y); THIEF.html.refresh(); THIEF.util.updateStatus(); } else { if (trueIsUpFalseIsDown) { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.doesNotGoUpStairs)); } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.doesNotGoDownStairs)); } } return flag; }; THIEF.func.command = {}; // マニュアルコマンドで実行して良いもの THIEF.func.command.goUp = function() { return this.move(0, -1); }; THIEF.func.command.goDown = function() { return this.move(0, 1); }; THIEF.func.command.goLeft = function() { return this.move(-1, 0); }; THIEF.func.command.goRight = function() { return this.move(1, 0); }; THIEF.func.command.goUpperLeft = function() { return this.move(-1, -1); }; THIEF.func.command.goUpperRight = function() { return this.move(1, -1); }; THIEF.func.command.goLowerLeft = function() { return this.move(-1, 1); }; THIEF.func.command.goLowerRight = function() { return this.move(1, 1); }; THIEF.func.command.refreshHTML = function() { THIEF.html.refresh(); return false; }; THIEF.func.command.rest = function() { return true; }; THIEF.func.command.pickup = function() { var tmp = THIEF.global.actLV.getInventoryXyObjects(this.x, this.y); var finish = true; var objs = []; for (var i = 0; i < tmp.length; i++) { if (tmp[i].portable) { objs.push(tmp[i]); } } if (objs.length > 0) { var from = THIEF.global.actLV; var to = this; var exec = function(selected) { var result = false; for (var i = 0; i < selected.length; i++) { result = true; to.ct -= 20; // 重量オーバなら拾えない様にすること if (from.removeFromInventory(selected[i])) { to.addToInventory(selected[i]); THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.pickup, selected[i].get(THIEF.PROP.displayName), to.get(THIEF.PROP.displayName))); } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.canNotPickup, selected[i].get(THIEF.PROP.displayName), to.get(THIEF.PROP.displayName))); } } return result; }; THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.pickupWhich)); this.action = THIEF.func.method.selecter(objs, exec, false, true); finish = false; } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.noItemHere)); } return finish; }; THIEF.func.command.drop = function() { // とりあえず一次元配列化 var list = []; if (typeof this.inventory !== 'undefined') { for (var x = 0; x < this.get(THIEF.PROP.inventoryWidth); x++) { if (typeof this.inventory[x] === 'undefined') { continue; } for (var y = 0; y < this.get(THIEF.PROP.inventoryHeight); y++) { if (typeof this.inventory[x][y] === 'undefined') { continue; } var cell = this.inventory[x][y]; for (var i = 0; i < cell.length; i++) { //THIEF.html.addDebugMessage('[' + x + ', ' + y + '] ' + cell[i].get(THIEF.PARAM.displayName) ); list.push(cell[i]); } } } } // メソッド書き換え if (list.length > 0) { var from = this; var to = THIEF.global.actLV; var exec = function(selected) { var act = false; if (selected.length > 0) { act = true; for (var i = 0; i < selected.length; i++) { // 呪われてたら捨てれない様にすること if (from.removeFromInventory(selected[i])) { // 装備済みなら外す if (typeof from.slot !== 'undefined' && typeof from.slot[selected[i].slot] !== 'undefined') { delete from.slot[selected[i].slot].equiped; delete from.slot[selected[i].slot]; THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.equipNone, from.get(THIEF.PROP.displayName), selected[i].get(THIEF.PROP.slotName))); from.ct -= 100; } to.addToInventory(selected[i], from.x, from.y); from.ct -= 20; THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.drop, selected[i].get(THIEF.PROP.displayName), from.get(THIEF.PROP.displayName), to.get(THIEF.PROP.displayName))); } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.canNotDrop, selected[i].get(THIEF.PROP.displayName), from.get(THIEF.PROP.displayName), to.get(THIEF.PROP.displayName))); } } // キャラクターは再配置して、一番上にする。 var adx = THIEF.global.adventurer.x; var ady = THIEF.global.adventurer.y; to.removeFromInventory(THIEF.global.adventurer); to.addToInventory(THIEF.global.adventurer, adx, ady); THIEF.html.refreshXy(adx, ady); } return act; }; this.action = THIEF.func.method.selecter(list, exec, false, false); //result = this.action(); //result = false; } else { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.inventoryIsEmpty)); } return false; }; THIEF.func.command.showInventory = function() { THIEF.html.addDebugMessage(this.get(THIEF.PROP.displayName) + 'のインベントリ表示を開始...'); var list = []; if (typeof this.inventory !== 'undefined') { for (var x = 0; x < this.get(THIEF.PROP.inventoryWidth); x++) { if (typeof this.inventory[x] === 'undefined') { continue; } for (var y = 0; y < this.get(THIEF.PROP.inventoryHeight); y++) { if (typeof this.inventory[x][y] === 'undefined') { continue; } var cell = this.inventory[x][y]; for (var i = 0; i < cell.length; i++) { THIEF.html.addDebugMessage('[' + x + ', ' + y + '] ' + cell[i].get(THIEF.PROP.displayName)); list.push(cell[i]); } } } } if (list.length === 0) { THIEF.html.addMessage(THIEF.util.getText(THIEF.Data.Text.inventoryIsEmpty)); } else { this.action = THIEF.func.method.selecter(list, THIEF.func.method.inputWait, true, false); } THIEF.html.addDebugMessage('...' + this.get(THIEF.PROP.displayName) + 'のインベントリ表示を完了。'); return false; }; THIEF.func.command.printHistory = function() { var key = THIEF.KEY; var index = THIEF.global.hist.length - 1; //for (var i = THIEF.conf.messageLines; i >= 0; i--) { for (var i = THIEF.conf.mapHeight; i >= 0; i--) { var hoge = THIEF.global.hist.length - i; if (typeof THIEF.global.hist[hoge] !== 'undefined') { THIEF.html.addInfomation(THIEF.global.hist[hoge].turn + ' : ' + THIEF.global.hist[hoge].text); } } THIEF.html.addInfomation('
' + text + '
\n'; }; //noinspection JSUnusedGlobalSymbols THIEF.html.addDebugMessage = function() { var indent = ''; var hist = []; return function(text) { if (THIEF.conf.debugmode) { if (typeof text === 'string') { // 文字列が ... から開始する場合にはインデントを減らす if (text.match(/^\.\.\./) && indent.length > 0) { indent = indent.slice(24); } hist.push(indent + text); // 文字列が ... で終わる場合にはインデントを増やす if (text.match(/\.\.\.$/)) { indent += ' '; } } else { var line = ''; for (var i = 0; i < hist.length; i++) { line += hist[i] + '| Command Help | ||
|---|---|---|
| ' + THIEF.util.getText(THIEF.Data.Keymap.$) + ' | ||
| ' + String.fromCharCode(THIEF.Data.Keymap[com[i]].key) + ' | ' + com[i] + ' | ' + THIEF.util.getText(THIEF.Data.Keymap[com[i]].text) + ' |
| # | '; } line += '
Debug Info
\n'; line += '\n'; } document.getElementById(THIEF.conf.id).innerHTML = line; THIEF.html.refresh(); }; /* Date オブジェクトのついて Data クラスはプリセットされたデータセットです。 配下には以下の三つの階層があります。 Data.Obj モンスターやアイテムの管理用 Data.Scenario イベントやシナリオの管理用 Data.Text ローカライズの管理用 Data.Prop 特殊変数の管理用 Data.Obj 配下の $ から始まるオブジェクトは、テンプレートとして扱われます。 ※ スポーンの対象にならない・一覧に表示されない、など Date.Obj 配下に格納されるオブジェクトは、 自動的に THIEF.func.command, THIEF.func.method 内のメソッドを継承し、その対象になります。 その為、すべてのオブジェクトが eat や wear メソッドの対象になります。 ※ 各コマンド名に -able をつけたプロパティ (eatable, wearable) の Boolean値 (true/false) に応じて動作します。 オブジェクト内に inheritance プロパティがあると、 そのオブジェクトも継承します。 inheritance は文字列で指定してください。 ※ inheritance : 'Human' 何もない場合は、Date.Obj.$を継承します。 プロパティは以下の順番で参照されます。 ※ Object -> THIEF.func.command -> THIEF.func.method -> Date.Obj.$ -> Date.Obj.Human -> this 現段階では、多段的な階層はサポートしていません。 今後もするつもりはありません。 ※ Date.Monster.Humanoid.Elf $ (テンプレート) 以外のオブジェクトも、実質的にはテンプレートとして扱われます。 オブジェクトの使用時にマスターオブジェクトが作成され、 以降はそれをクローニングしてスポーン処理などを行います。 そのため、起動後に Date 内のオブジェクトを修正した場合、 その結果が新しいインスタンスには反映されません。 Data.Obj 配下のオブジェクトのプロパティ値が _ から始まる場合、 数式として処理されます。 str : '_3d6' */ THIEF.Data = {}; THIEF.Data.Text = { attack : { // 1 : damage // 2 : subject // 3 : from ja : [ '${3} は ${2} に ${1} のダメージを与えた。', '${2} は ${1} のダメージを受けた。' ], //ja : '${3} は ${2} に ${1} のダメージを与えた。', en : '${2} Hit decreased by ${1}.' }, defence : { // 1 : subject // 2 : from ja : '${2} からの攻撃を防いだ。', en : '${1} avoided attacks from ${2}.' }, killBy : { // 1 : who // 2 : by ja : '${2} は ${1} を殺した。', en : '${1} are killed by ${2}.' }, pickup : { // 1 : item // 2 : subject // 3 : from ja : '${2} は ${1} を拾った。', en : '${2} pickup ${1}.' }, canNotPickup : { // 1 : item // 2 : subject // ja : '${1} を拾えない。', en : '${2} cannot pickup ${1}.' }, pickupWhich : { ja : 'どれを拾う?', en : 'Whitch item pickup?' }, noItemHere : { ja : 'ホコリくらいしか落ちていない...', en : 'You find any dusts...' }, drop : { // 1 : item // 2 : subject // 3 : to ja : '${1} を置いた。', en : '${2} drop ${1}' }, canNotDrop : { // 1 :item // 2 : subject // 3 : to ja : '${1} を置けない。', en : '${2} cannot drop ${1}' }, inventoryIsEmpty : { ja : '何も持っていません。', en : 'Your inventory is empty.' }, commandNotFound : { // 1 : command name ja : '"${1}" コマンド?', en : '"${1}" command?' }, decay : { // 1 : subject ja : '${1} は腐りきった。', en : '${1} is gone bad.' }, equipItem : { // 1 : item // 2 : subject // 3 : slot ja : '${2} は ${1} を ${3} に装備した。', en : '${2} equip ${1} on ${3}.' }, equipNone : { // 1 : subject // 2 : slot ja : '${1} は ${2} から装備を外した。', en : '${1} take off ${2}-item.' }, equipAlready : { // 1 : item // 2 : subject ja : '${1} は既に装備している。', en : 'Already, ${2} equiped ${1}.' }, goUpStairs : { // 1 : Subject ja : '${1}は階段を登った', en : '${1} go up the stairs.' }, doesNotGoUpStairs : { ja : '上り階段が見当たらない', en : 'You can not found the up stairs.' }, goDownStairs : { // 1 : Subject ja : '${1}は階段を降った', en : '${1} go down the stairs.' }, doesNotGoDownStairs : { ja : '下り階段が見当たらない', en : 'You can not found the sown stairs.' }, startGame : { ja : '冒険を開始します。', en : 'Start Game' }, cmdInventoryDesc : { ja : '持ち物を表示', en : 'show your inventory.' }, cmdEquipDesc : { ja : 'アイテムを装備', en : 'equip your item.' }, cmdPrintHistoryDesc : { ja : 'メッセージの履歴を表示', en : 'show messages history' }, cmdRefreshScreenDesc : { ja : '画面を再描画する', en : 'refresh screen' }, cmdPickupDesc : { ja : '足元のアイテムを拾う', en : 'pickup items from your step.' }, cmdDropDesc : { ja : 'アイテムを置く', en : 'drop your items.' }, cmdExecuteCommandDesc : { ja : '指定したコマンドを実行します', en : 'execute command' }, cmdGoUpStairs : { ja : '階段を登る', en : 'go up the stairs' }, cmdGoDownStairs : { ja : '階段を降りる', en : 'go down the stairs' }, objDefaultName : { ja : '無名', en : 'Nameless' }, objDefaultHumanName : { ja : '人間', en : 'Human' }, objDefaultSymbolName : { ja : '不明', en : 'Unknown' }, slotNameOfHand : { ja : '手', en : 'hand' }, slotNameOfChest : { ja : '胴', en : 'chest' }, symbolNameOfArmor : { ja : '防具', en : 'Armor' }, symbolNameOfFood : { ja : '食料', en : 'Food' }, symbolNameOfWeapn : { ja : '武器', en : 'Weapn' }, symbolNameOfMail : { ja : '鎧', en : 'Mail' }, objDebugDaemonName : { ja : 'デバッグ用モンスター', en : 'DebugMonster' }, objLitFloorName : { ja : '明るい床', en : 'Lit Floor' }, objDarkFloorName : { ja : '暗い床', en : 'Dark Floor' }, objRationName : { ja : '食料', en : 'Ration' }, objDebuggingDaggerName : { ja : 'テスト用ダガー', en : 'DebuggingDagger' }, objDebuggingHighDaggerName : { ja : 'テスト用上位ダガー', en : 'Debugging High Dagger' }, objDebuggingArmorName : { ja : 'テスト用鎧', en : 'Debugging Armor' }, objDebuggingHighArmorName : { ja : 'テスト用固鎧', en : 'Debugging High Armor' }, objDoorName : { ja : '扉', en : 'Door' }, objHiddenWallName : { ja : '壁の中', en : 'Hidden Wall' }, objUnbreakableWallName : { ja : '壊せない壁', en : 'Unbreakable Wall' }, objNormalWallName : { ja : '壁', en : 'Wall' }, objUpStairsName : { ja : '上り階段', en : 'Up Stairs' }, objDownStairsName : { ja : '下り階段', en : 'Down Stairs' }, sceTheDungeonName : { ja : '迷宮', en : 'The Dungeon' }, sceSideRoadName : { ja : '脇道', en : 'Side Road' } }; THIEF.Data.Prop = { // 特殊変数登録用 displayName : function() { var text = ''; if (this.equiped) { text += '[E] ' } text += this.get(THIEF.PROP.name) + '(' + this.get(THIEF.PROP.symbol) + ')'; return text; }, db : function () { var val = 0; // 体力に応じたダメージボーナス if (typeof this.con === 'undefined') { //val += 0; } else if (this.con >= 18) { val += (this.con / 6); } else if (this.con >= 17) { val += 2; } else if (this.con >= 15) { val += 1; } else if (this.con >= 7) { //val += 0; } else if (this.con >= 4) { val += -1; } else if (this.con >= 3) { val += -2; } else if (this.con < 3) { val += -3; } // 腕力、サイズに応じたダメージボーナス if (typeof this.str === 'undefined') { //val += 0; } else if (typeof this.siz === 'undefined') { // STR のみ定義されている場合 if (this.str >= 25) { val += (this.str / 2.27); } else if (this.str >= 18.99) { val += 4; } else if (this.str > 18) { val += 3; } else if (this.str >= 18) { val += 2; } else if (this.str >= 16) { val += 1; } else if (this.str >= 6) { //val += 0; } else if (this.str < 6) { val += -1; } } else { // STR と SIZ の両方が定義されている場合 var num = this.str + this.siz; if (num >= 57) { val += Math.dice(2 + Math.floor((num - 41) / 16), 6); } else if (num >= 41) { val += Math.dice(2, 6); } else if (num >= 33) { val += Math.dice(1, 6); } else if (num >= 25) { val += Math.dice(1, 4); } else if (num >= 17) { //val += 0; } else if (num >= 13) { val += -Math.dice(1, 4); } else if (num >= 0) { val += -Math.dice(1, 6); } } // アイテムに応じたダメージボーナス // 武器によるダメージは別で処理(二刀流対応のため) return val; }, armorPoint : function () { var val = 0; if (typeof this.slot !== 'undefined') { for (var slotName in this.slot) { if (typeof this.slot[slotName].ac === 'number') { val += this.slot[slotName].ac; } } } return val; } }; THIEF.Data.Obj = {}; // Monster & Item THIEF.Data.Obj.$ = { // Default name : THIEF.Data.Text.objDefaultName, symbol : '╳', // 未登録用印(X に近い) symbolName : THIEF.Data.Text.objDefaultSymbolName, type : 'unknown' }; THIEF.Data.Obj.$Monster = { active : true, ct : 0, maxct : 100, type : 'monster' }; THIEF.Data.Obj.$Item = { stackable : true, mergeable : true, portable : true, isItem : true, slot : 'Hand', // すべてのアイテムは手に持てる。 slotName : THIEF.Data.Text.slotNameOfHand, type : 'item' }; THIEF.Data.Obj.$Armor = { inheritance : '$Item', symbol : '[', symbolName : THIEF.Data.Text.symbolNameOfArmor, color : 'brown' }; THIEF.Data.Obj.$Level = { active : false, type : 'level' }; THIEF.Data.Obj.$Humanoid = { inheritance : '$Monster', symbol : '@' }; THIEF.Data.Obj.Human = { inheritance : '$Humanoid', color : 'red', name : THIEF.Data.Text.objDefaultHumanName, str : '_3d6', con : '_3d6', pow : '_3d6', dex : '_3d6', app : '_3d6', siz : '_2d6 + 6', 'int' : '_2d6 + 6', edu : '_3d6 + 3' }; THIEF.Data.Obj.$Daemon = { inheritance : '$Humanoid', symbol : '&' }; THIEF.Data.Obj.DebugDaemon = { inheritance : '$Daemon', color : '#00FF88', name : THIEF.Data.Text.objDebugDaemonName, str : '_3d6', con : '_3d6', pow : '_3d6', dex : '_3d6', app : '_3d6', siz : '_2d6 + 6', 'int' : '_2d6 + 6', edu : '_3d6 + 3' }; THIEF.Data.Obj.$Floor = { stackable : true, type : 'floor' // diggable : true }; THIEF.Data.Obj.LitFloor = { inheritance : '$Floor', symbol : '.', name : THIEF.Data.Text.objLitFloorName }; THIEF.Data.Obj.DarkFloor = { inheritance : '$Floor', symbol : '#', name : THIEF.Data.Text.objDarkFloorName }; THIEF.Data.Obj.UpStairs = { inheritance : '$Floor', symbol : '<', name : THIEF.Data.Text.objUpStairsName }; THIEF.Data.Obj.DownStairs = { inheritance : '$Floor', symbol : '>', name : THIEF.Data.Text.objDownStairsName }; THIEF.Data.Obj.$Wall = { symbol : '▓', // 濃いドット模様 type : 'wall' //diggable : true }; THIEF.Data.Obj.NonDiggableWall = { inheritance : '$Wall', symbol : '░', // 薄いドット模様 name : THIEF.Data.Text.objUnbreakableWallName }; THIEF.Data.Obj.NormalWall = { inheritance : '$Wall', symbol : '+', name : THIEF.Data.Text.objNormalWallName }; THIEF.Data.Obj.HiddenWall = { inheritance : '$Wall', symbol : ' ', name : THIEF.Data.Text.objHiddenWallName }; THIEF.Data.Obj.Door = { inheritance : '$Wall', symbol : '+', color : 'burlywood', name : THIEF.Data.Text.objDoorName }; THIEF.Data.Obj.$Food = { inheritance : '$Item', symbol : '%', symbolName : THIEF.Data.Text.symbolNameOfFood }; THIEF.Data.Obj.$Corpse = { inheritance : '$Food', decayable : true, next : THIEF.func.method.decay, dp : 20 }; THIEF.Data.Obj.Ration = { inheritance : '$Food', name : THIEF.Data.Text.objRationName, color : 'red' }; THIEF.Data.Obj.$Weapon = { inheritance : '$Item', symbol : ']', symbolName : THIEF.Data.Text.symbolNameOfWeapn }; THIEF.Data.Obj.DebugDagger = { inheritance : '$Weapon', name : THIEF.Data.Text.objDebuggingDaggerName, damage : '2d4', color : 'silver' }; THIEF.Data.Obj.DebugHighDagger = { inheritance : '$Weapon', name : THIEF.Data.Text.objDebuggingHighDaggerName, damage : '3d4', color : 'silver' }; THIEF.Data.Obj.$Mail = { inheritance : '$Armor', slot : 'Chest', slotName : THIEF.Data.Text.slotNameOfChest, symbolName : THIEF.Data.Text.symbolNameOfMail }; THIEF.Data.Obj.DebugArmor = { inheritance : '$Mail', ac : 2, name : THIEF.Data.Text.objDebuggingArmorName }; THIEF.Data.Obj.DebugHighArmor = { inheritance : '$Mail', ac : 4, name : THIEF.Data.Text.objDebuggingHighArmorName }; /* * Symbol Memo * * ■小文字アルファベットは基本的に 弱い or 普通の強さ……のものが多い * amphibia カエルなどの(小型)両生類 * blob * chiken, cockatrice, (basilisk) 小型の鳥? * dog * eyes, element 球形のもの * felid (cat) * gremlin, gargoyle, goblin, (kobold) 主に敵対的 * humanoid, hobbit, elf, (gnome) 主に友好的 * insect 昆虫。芋虫系は w * j * kop 無能な警官・警備員 * lacertilia, lizard トカゲっぽい小さな生き物。大型のは Reptilia へ。 * mimic * nymph * orc * piercer つらら状生物。 天井から落ちてくる。(それまでは見えない) * quadrupeds 小さい(草食的な)四足獣。大きくて強いのは Q * rat * slime * t * undead (zombi, mummy) * vortex 意思のないエネルギー体 * worm 昆虫は i * x * y * z * * ■大文字アルファベットは普通に強い * Angel * Bard, Bat 大型の飛行生物。猛禽類・ハーピーなど * Centaur -> T * Doragon * Element でかくて強いエレメント。精霊 * Fungus * Golem * HUMANOID (Giant) * Invisible monster * J * K * Lich * Minotaur -> T * Naga -> T * Ogre 鬼。小さい鬼は goblin * Predator 凄まじく猛獣。 * Quadrupeds 大きい(肉食的な)四足獣。小さくて弱いのは q * Reptilia 大型爬虫類。小型は l? * Sea Serpent 海上生物。クラーケンとかもここ。 * Therianthropy 半人半獣 * Unicorn, Uma(笑) * Vampire * Wight, Wraith * X * Y * Z * @ : human, Aventurier and sametype * & : Daemon * # : dark floor, unbreakable floor * . : lit floor * ~ : tail? -> ̰ ˷ * ^ : trap * ' : * ` : * { : fountain, lake (safe water place) * } : pool, lava (dangerous water place ) * : : Iron Bars (transparent wall) * ; : * - : wall, opened door * | : wall, opened door, tomb * \ : tree -> \ * < : staircase up * > : staircase down * _ : altar, throne, tomb? * 0(ZERO) : STONE * ? : scrool * ! : potion * " : amulet * + : wall, closed door, edge, book * $ : money * % : food * ( : tool * ) : unknown (oopart) * = : ring * [ : armor * ] : weapon * * : stone, jewel, gem * / : wand * */ //noinspection JSUnusedGlobalSymbols THIEF.Data.Keymap = { $ : { // help ja : '' + 'y k u' + ' ' + 'yuhjklbn: 指定方向に一歩歩く' + '