//============================================================================= // rpg_managers.js v1.6.2 //============================================================================= //----------------------------------------------------------------------------- // DataManager // // The static class that manages the database and game objects. function DataManager() { throw new Error("This is a static class"); } var $dataActors = null; var $dataClasses = null; var $dataSkills = null; var $dataItems = null; var $dataWeapons = null; var $dataArmors = null; var $dataEnemies = null; var $dataTroops = null; var $dataStates = null; var $dataAnimations = null; var $dataTilesets = null; var $dataCommonEvents = null; var $dataSystem = null; var $dataMapInfos = null; var $dataMap = null; var $gameTemp = null; var $gameSystem = null; var $gameScreen = null; var $gameTimer = null; var $gameMessage = null; var $gameSwitches = null; var $gameVariables = null; var $gameSelfSwitches = null; var $gameActors = null; var $gameParty = null; var $gameTroop = null; var $gameMap = null; var $gamePlayer = null; var $testEvent = null; DataManager._globalId = "RPGMV"; DataManager._lastAccessedId = 1; DataManager._errorUrl = null; DataManager._databaseFiles = [ { name: "$dataActors", src: "Actors.json" }, { name: "$dataClasses", src: "Classes.json" }, { name: "$dataSkills", src: "Skills.json" }, { name: "$dataItems", src: "Items.json" }, { name: "$dataWeapons", src: "Weapons.json" }, { name: "$dataArmors", src: "Armors.json" }, { name: "$dataEnemies", src: "Enemies.json" }, { name: "$dataTroops", src: "Troops.json" }, { name: "$dataStates", src: "States.json" }, { name: "$dataAnimations", src: "Animations.json" }, { name: "$dataTilesets", src: "Tilesets.json" }, { name: "$dataCommonEvents", src: "CommonEvents.json" }, { name: "$dataSystem", src: "System.json" }, { name: "$dataMapInfos", src: "MapInfos.json" }, ]; DataManager.loadDatabase = function () { var test = this.isBattleTest() || this.isEventTest(); var prefix = test ? "Test_" : ""; for (var i = 0; i < this._databaseFiles.length; i++) { var name = this._databaseFiles[i].name; var src = this._databaseFiles[i].src; this.loadDataFile(name, prefix + src); } if (this.isEventTest()) { this.loadDataFile("$testEvent", prefix + "Event.json"); } }; DataManager.loadDataFile = function (name, src) { var xhr = new XMLHttpRequest(); var url = "data/" + src; xhr.open("GET", url); xhr.overrideMimeType("application/json"); xhr.onload = function () { if (xhr.status < 400) { window[name] = JSON.parse(xhr.responseText); DataManager.onLoad(window[name]); } }; xhr.onerror = this._mapLoader || function () { DataManager._errorUrl = DataManager._errorUrl || url; }; window[name] = null; xhr.send(); }; DataManager.isDatabaseLoaded = function () { this.checkError(); for (var i = 0; i < this._databaseFiles.length; i++) { if (!window[this._databaseFiles[i].name]) { return false; } } return true; }; DataManager.loadMapData = function (mapId) { if (mapId > 0) { var filename = "Map%1.json".format(mapId.padZero(3)); this._mapLoader = ResourceHandler.createLoader( "data/" + filename, this.loadDataFile.bind(this, "$dataMap", filename) ); this.loadDataFile("$dataMap", filename); } else { this.makeEmptyMap(); } }; DataManager.makeEmptyMap = function () { $dataMap = {}; $dataMap.data = []; $dataMap.events = []; $dataMap.width = 100; $dataMap.height = 100; $dataMap.scrollType = 3; }; DataManager.isMapLoaded = function () { this.checkError(); return !!$dataMap; }; DataManager.onLoad = function (object) { var array; if (object === $dataMap) { this.extractMetadata(object); array = object.events; } else { array = object; } if (Array.isArray(array)) { for (var i = 0; i < array.length; i++) { var data = array[i]; if (data && data.note !== undefined) { this.extractMetadata(data); } } } if (object === $dataSystem) { Decrypter.hasEncryptedImages = !!object.hasEncryptedImages; Decrypter.hasEncryptedAudio = !!object.hasEncryptedAudio; Scene_Boot.loadSystemImages(); } }; DataManager.extractMetadata = function (data) { var re = /<([^<>:]+)(:?)([^>]*)>/g; data.meta = {}; for (;;) { var match = re.exec(data.note); if (match) { if (match[2] === ":") { data.meta[match[1]] = match[3]; } else { data.meta[match[1]] = true; } } else { break; } } }; DataManager.checkError = function () { if (DataManager._errorUrl) { throw new Error("Failed to load: " + DataManager._errorUrl); } }; DataManager.isBattleTest = function () { return Utils.isOptionValid("btest"); }; DataManager.isEventTest = function () { return Utils.isOptionValid("etest"); }; DataManager.isSkill = function (item) { return item && $dataSkills.contains(item); }; DataManager.isItem = function (item) { return item && $dataItems.contains(item); }; DataManager.isWeapon = function (item) { return item && $dataWeapons.contains(item); }; DataManager.isArmor = function (item) { return item && $dataArmors.contains(item); }; DataManager.createGameObjects = function () { $gameTemp = new Game_Temp(); $gameSystem = new Game_System(); $gameScreen = new Game_Screen(); $gameTimer = new Game_Timer(); $gameMessage = new Game_Message(); $gameSwitches = new Game_Switches(); $gameVariables = new Game_Variables(); $gameSelfSwitches = new Game_SelfSwitches(); $gameActors = new Game_Actors(); $gameParty = new Game_Party(); $gameTroop = new Game_Troop(); $gameMap = new Game_Map(); $gamePlayer = new Game_Player(); }; DataManager.setupNewGame = function () { this.createGameObjects(); this.selectSavefileForNewGame(); $gameParty.setupStartingMembers(); $gamePlayer.reserveTransfer($dataSystem.startMapId, $dataSystem.startX, $dataSystem.startY); Graphics.frameCount = 0; }; DataManager.setupBattleTest = function () { this.createGameObjects(); $gameParty.setupBattleTest(); BattleManager.setup($dataSystem.testTroopId, true, false); BattleManager.setBattleTest(true); BattleManager.playBattleBgm(); }; DataManager.setupEventTest = function () { this.createGameObjects(); this.selectSavefileForNewGame(); $gameParty.setupStartingMembers(); $gamePlayer.reserveTransfer(-1, 8, 6); $gamePlayer.setTransparent(false); }; DataManager.loadGlobalInfo = function () { var json; try { json = StorageManager.load(0); } catch (e) { console.error(e); return []; } if (json) { var globalInfo = JSON.parse(json); for (var i = 1; i <= this.maxSavefiles(); i++) { if (!StorageManager.exists(i)) { delete globalInfo[i]; } } return globalInfo; } else { return []; } }; DataManager.saveGlobalInfo = function (info) { StorageManager.save(0, JSON.stringify(info)); }; DataManager.isThisGameFile = function (savefileId) { var globalInfo = this.loadGlobalInfo(); if (globalInfo && globalInfo[savefileId]) { if (StorageManager.isLocalMode()) { return true; } else { var savefile = globalInfo[savefileId]; return savefile.globalId === this._globalId && savefile.title === $dataSystem.gameTitle; } } else { return false; } }; DataManager.isAnySavefileExists = function () { var globalInfo = this.loadGlobalInfo(); if (globalInfo) { for (var i = 1; i < globalInfo.length; i++) { if (this.isThisGameFile(i)) { return true; } } } return false; }; DataManager.latestSavefileId = function () { var globalInfo = this.loadGlobalInfo(); var savefileId = 1; var timestamp = 0; if (globalInfo) { for (var i = 1; i < globalInfo.length; i++) { if (this.isThisGameFile(i) && globalInfo[i].timestamp > timestamp) { timestamp = globalInfo[i].timestamp; savefileId = i; } } } return savefileId; }; DataManager.loadAllSavefileImages = function () { var globalInfo = this.loadGlobalInfo(); if (globalInfo) { for (var i = 1; i < globalInfo.length; i++) { if (this.isThisGameFile(i)) { var info = globalInfo[i]; this.loadSavefileImages(info); } } } }; DataManager.loadSavefileImages = function (info) { if (info.characters) { for (var i = 0; i < info.characters.length; i++) { ImageManager.reserveCharacter(info.characters[i][0]); } } if (info.faces) { for (var j = 0; j < info.faces.length; j++) { ImageManager.reserveFace(info.faces[j][0]); } } }; DataManager.maxSavefiles = function () { return 20; }; DataManager.saveGame = function (savefileId) { try { StorageManager.backup(savefileId); return this.saveGameWithoutRescue(savefileId); } catch (e) { console.error(e); try { StorageManager.remove(savefileId); StorageManager.restoreBackup(savefileId); } catch (e2) {} return false; } }; DataManager.loadGame = function (savefileId) { try { return this.loadGameWithoutRescue(savefileId); } catch (e) { console.error(e); return false; } }; DataManager.loadSavefileInfo = function (savefileId) { var globalInfo = this.loadGlobalInfo(); return globalInfo && globalInfo[savefileId] ? globalInfo[savefileId] : null; }; DataManager.lastAccessedSavefileId = function () { return this._lastAccessedId; }; DataManager.saveGameWithoutRescue = function (savefileId) { var json = JsonEx.stringify(this.makeSaveContents()); if (json.length >= 200000) { console.warn("Save data too big!"); } StorageManager.save(savefileId, json); this._lastAccessedId = savefileId; var globalInfo = this.loadGlobalInfo() || []; globalInfo[savefileId] = this.makeSavefileInfo(); this.saveGlobalInfo(globalInfo); return true; }; DataManager.loadGameWithoutRescue = function (savefileId) { var globalInfo = this.loadGlobalInfo(); if (this.isThisGameFile(savefileId)) { var json = StorageManager.load(savefileId); this.createGameObjects(); this.extractSaveContents(JsonEx.parse(json)); this._lastAccessedId = savefileId; return true; } else { return false; } }; DataManager.selectSavefileForNewGame = function () { var globalInfo = this.loadGlobalInfo(); this._lastAccessedId = 1; if (globalInfo) { var numSavefiles = Math.max(0, globalInfo.length - 1); if (numSavefiles < this.maxSavefiles()) { this._lastAccessedId = numSavefiles + 1; } else { var timestamp = Number.MAX_VALUE; for (var i = 1; i < globalInfo.length; i++) { if (!globalInfo[i]) { this._lastAccessedId = i; break; } if (globalInfo[i].timestamp < timestamp) { timestamp = globalInfo[i].timestamp; this._lastAccessedId = i; } } } } }; DataManager.makeSavefileInfo = function () { var info = {}; info.globalId = this._globalId; info.title = $dataSystem.gameTitle; info.characters = $gameParty.charactersForSavefile(); info.faces = $gameParty.facesForSavefile(); info.playtime = $gameSystem.playtimeText(); info.timestamp = Date.now(); return info; }; DataManager.makeSaveContents = function () { // A save data does not contain $gameTemp, $gameMessage, and $gameTroop. var contents = {}; contents.system = $gameSystem; contents.screen = $gameScreen; contents.timer = $gameTimer; contents.switches = $gameSwitches; contents.variables = $gameVariables; contents.selfSwitches = $gameSelfSwitches; contents.actors = $gameActors; contents.party = $gameParty; contents.map = $gameMap; contents.player = $gamePlayer; return contents; }; DataManager.extractSaveContents = function (contents) { $gameSystem = contents.system; $gameScreen = contents.screen; $gameTimer = contents.timer; $gameSwitches = contents.switches; $gameVariables = contents.variables; $gameSelfSwitches = contents.selfSwitches; $gameActors = contents.actors; $gameParty = contents.party; $gameMap = contents.map; $gamePlayer = contents.player; }; //----------------------------------------------------------------------------- // ConfigManager // // The static class that manages the configuration data. function ConfigManager() { throw new Error("This is a static class"); } ConfigManager.alwaysDash = false; ConfigManager.commandRemember = false; Object.defineProperty(ConfigManager, "bgmVolume", { get: function () { return AudioManager._bgmVolume; }, set: function (value) { AudioManager.bgmVolume = value; }, configurable: true, }); Object.defineProperty(ConfigManager, "bgsVolume", { get: function () { return AudioManager.bgsVolume; }, set: function (value) { AudioManager.bgsVolume = value; }, configurable: true, }); Object.defineProperty(ConfigManager, "meVolume", { get: function () { return AudioManager.meVolume; }, set: function (value) { AudioManager.meVolume = value; }, configurable: true, }); Object.defineProperty(ConfigManager, "seVolume", { get: function () { return AudioManager.seVolume; }, set: function (value) { AudioManager.seVolume = value; }, configurable: true, }); ConfigManager.load = function () { var json; var config = {}; try { json = StorageManager.load(-1); } catch (e) { console.error(e); } if (json) { config = JSON.parse(json); } this.applyData(config); }; ConfigManager.save = function () { StorageManager.save(-1, JSON.stringify(this.makeData())); }; ConfigManager.makeData = function () { var config = {}; config.alwaysDash = this.alwaysDash; config.commandRemember = this.commandRemember; config.bgmVolume = this.bgmVolume; config.bgsVolume = this.bgsVolume; config.meVolume = this.meVolume; config.seVolume = this.seVolume; return config; }; ConfigManager.applyData = function (config) { this.alwaysDash = this.readFlag(config, "alwaysDash"); this.commandRemember = this.readFlag(config, "commandRemember"); this.bgmVolume = this.readVolume(config, "bgmVolume"); this.bgsVolume = this.readVolume(config, "bgsVolume"); this.meVolume = this.readVolume(config, "meVolume"); this.seVolume = this.readVolume(config, "seVolume"); }; ConfigManager.readFlag = function (config, name) { return !!config[name]; }; ConfigManager.readVolume = function (config, name) { var value = config[name]; if (value !== undefined) { return Number(value).clamp(0, 100); } else { return 100; } }; //----------------------------------------------------------------------------- // StorageManager // // The static class that manages storage for saving game data. function StorageManager() { throw new Error("This is a static class"); } StorageManager.save = function (savefileId, json) { if (this.isLocalMode()) { this.saveToLocalFile(savefileId, json); } else { this.saveToWebStorage(savefileId, json); } }; StorageManager.load = function (savefileId) { if (this.isLocalMode()) { return this.loadFromLocalFile(savefileId); } else { return this.loadFromWebStorage(savefileId); } }; StorageManager.exists = function (savefileId) { if (this.isLocalMode()) { return this.localFileExists(savefileId); } else { return this.webStorageExists(savefileId); } }; StorageManager.remove = function (savefileId) { if (this.isLocalMode()) { this.removeLocalFile(savefileId); } else { this.removeWebStorage(savefileId); } }; StorageManager.backup = function (savefileId) { if (this.exists(savefileId)) { if (this.isLocalMode()) { var data = this.loadFromLocalFile(savefileId); var compressed = LZString.compressToBase64(data); var fs = require("fs"); var dirPath = this.localFileDirectoryPath(); var filePath = this.localFilePath(savefileId) + ".bak"; if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath); } fs.writeFileSync(filePath, compressed); } else { var data = this.loadFromWebStorage(savefileId); var compressed = LZString.compressToBase64(data); var key = this.webStorageKey(savefileId) + "bak"; localStorage.setItem(key, compressed); } } }; StorageManager.backupExists = function (savefileId) { if (this.isLocalMode()) { return this.localFileBackupExists(savefileId); } else { return this.webStorageBackupExists(savefileId); } }; StorageManager.cleanBackup = function (savefileId) { if (this.backupExists(savefileId)) { if (this.isLocalMode()) { var fs = require("fs"); var dirPath = this.localFileDirectoryPath(); var filePath = this.localFilePath(savefileId); fs.unlinkSync(filePath + ".bak"); } else { var key = this.webStorageKey(savefileId); localStorage.removeItem(key + "bak"); } } }; StorageManager.restoreBackup = function (savefileId) { if (this.backupExists(savefileId)) { if (this.isLocalMode()) { var data = this.loadFromLocalBackupFile(savefileId); var compressed = LZString.compressToBase64(data); var fs = require("fs"); var dirPath = this.localFileDirectoryPath(); var filePath = this.localFilePath(savefileId); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath); } fs.writeFileSync(filePath, compressed); fs.unlinkSync(filePath + ".bak"); } else { var data = this.loadFromWebStorageBackup(savefileId); var compressed = LZString.compressToBase64(data); var key = this.webStorageKey(savefileId); localStorage.setItem(key, compressed); localStorage.removeItem(key + "bak"); } } }; StorageManager.isLocalMode = function () { return Utils.isNwjs(); }; StorageManager.saveToLocalFile = function (savefileId, json) { var data = LZString.compressToBase64(json); var fs = require("fs"); var dirPath = this.localFileDirectoryPath(); var filePath = this.localFilePath(savefileId); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath); } fs.writeFileSync(filePath, data); }; StorageManager.loadFromLocalFile = function (savefileId) { var data = null; var fs = require("fs"); var filePath = this.localFilePath(savefileId); if (fs.existsSync(filePath)) { data = fs.readFileSync(filePath, { encoding: "utf8" }); } return LZString.decompressFromBase64(data); }; StorageManager.loadFromLocalBackupFile = function (savefileId) { var data = null; var fs = require("fs"); var filePath = this.localFilePath(savefileId) + ".bak"; if (fs.existsSync(filePath)) { data = fs.readFileSync(filePath, { encoding: "utf8" }); } return LZString.decompressFromBase64(data); }; StorageManager.localFileBackupExists = function (savefileId) { var fs = require("fs"); return fs.existsSync(this.localFilePath(savefileId) + ".bak"); }; StorageManager.localFileExists = function (savefileId) { var fs = require("fs"); return fs.existsSync(this.localFilePath(savefileId)); }; StorageManager.removeLocalFile = function (savefileId) { var fs = require("fs"); var filePath = this.localFilePath(savefileId); if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); } }; StorageManager.saveToWebStorage = function (savefileId, json) { var key = this.webStorageKey(savefileId); var data = LZString.compressToBase64(json); localStorage.setItem(key, data); }; StorageManager.loadFromWebStorage = function (savefileId) { var key = this.webStorageKey(savefileId); var data = localStorage.getItem(key); return LZString.decompressFromBase64(data); }; StorageManager.loadFromWebStorageBackup = function (savefileId) { var key = this.webStorageKey(savefileId) + "bak"; var data = localStorage.getItem(key); return LZString.decompressFromBase64(data); }; StorageManager.webStorageBackupExists = function (savefileId) { var key = this.webStorageKey(savefileId) + "bak"; return !!localStorage.getItem(key); }; StorageManager.webStorageExists = function (savefileId) { var key = this.webStorageKey(savefileId); return !!localStorage.getItem(key); }; StorageManager.removeWebStorage = function (savefileId) { var key = this.webStorageKey(savefileId); localStorage.removeItem(key); }; StorageManager.localFileDirectoryPath = function () { var path = require("path"); var base = path.dirname(process.mainModule.filename); return path.join(base, "save/"); }; StorageManager.localFilePath = function (savefileId) { var name; if (savefileId < 0) { name = "config.rpgsave"; } else if (savefileId === 0) { name = "global.rpgsave"; } else { name = "file%1.rpgsave".format(savefileId); } return this.localFileDirectoryPath() + name; }; StorageManager.webStorageKey = function (savefileId) { if (savefileId < 0) { return "RPG Config"; } else if (savefileId === 0) { return "RPG Global"; } else { return "RPG File%1".format(savefileId); } }; //----------------------------------------------------------------------------- // ImageManager // // The static class that loads images, creates bitmap objects and retains them. function ImageManager() { throw new Error("This is a static class"); } ImageManager.cache = new CacheMap(ImageManager); ImageManager._imageCache = new ImageCache(); ImageManager._requestQueue = new RequestQueue(); ImageManager._systemReservationId = Utils.generateRuntimeId(); ImageManager._generateCacheKey = function (path, hue) { return path + ":" + hue; }; ImageManager.loadAnimation = function (filename, hue) { return this.loadBitmap("img/animations/", filename, hue, true); }; ImageManager.loadBattleback1 = function (filename, hue) { return this.loadBitmap("img/battlebacks1/", filename, hue, true); }; ImageManager.loadBattleback2 = function (filename, hue) { return this.loadBitmap("img/battlebacks2/", filename, hue, true); }; ImageManager.loadEnemy = function (filename, hue) { return this.loadBitmap("img/enemies/", filename, hue, true); }; ImageManager.loadCharacter = function (filename, hue) { return this.loadBitmap("img/characters/", filename, hue, false); }; ImageManager.loadFace = function (filename, hue) { return this.loadBitmap("img/faces/", filename, hue, true); }; ImageManager.loadParallax = function (filename, hue) { return this.loadBitmap("img/parallaxes/", filename, hue, true); }; ImageManager.loadPicture = function (filename, hue) { return this.loadBitmap("img/pictures/", filename, hue, true); }; ImageManager.loadSvActor = function (filename, hue) { return this.loadBitmap("img/sv_actors/", filename, hue, false); }; ImageManager.loadSvEnemy = function (filename, hue) { return this.loadBitmap("img/sv_enemies/", filename, hue, true); }; ImageManager.loadSystem = function (filename, hue) { return this.loadBitmap("img/system/", filename, hue, false); }; ImageManager.loadTileset = function (filename, hue) { return this.loadBitmap("img/tilesets/", filename, hue, false); }; ImageManager.loadTitle1 = function (filename, hue) { return this.loadBitmap("img/titles1/", filename, hue, true); }; ImageManager.loadTitle2 = function (filename, hue) { return this.loadBitmap("img/titles2/", filename, hue, true); }; ImageManager.loadBitmap = function (folder, filename, hue, smooth) { if (filename) { var path = folder + encodeURIComponent(filename) + ".png"; var bitmap = this.loadNormalBitmap(path, hue || 0); bitmap.smooth = smooth; return bitmap; } else { return this.loadEmptyBitmap(); } }; ImageManager.loadEmptyBitmap = function () { var empty = this._imageCache.get("empty"); if (!empty) { empty = new Bitmap(); this._imageCache.add("empty", empty); this._imageCache.reserve("empty", empty, this._systemReservationId); } return empty; }; ImageManager.loadNormalBitmap = function (path, hue) { var key = this._generateCacheKey(path, hue); var bitmap = this._imageCache.get(key); if (!bitmap) { bitmap = Bitmap.load(decodeURIComponent(path)); bitmap.addLoadListener(function () { bitmap.rotateHue(hue); }); this._imageCache.add(key, bitmap); } else if (!bitmap.isReady()) { bitmap.decode(); } return bitmap; }; ImageManager.clear = function () { this._imageCache = new ImageCache(); }; ImageManager.isReady = function () { return this._imageCache.isReady(); }; ImageManager.isObjectCharacter = function (filename) { var sign = filename.match(/^[\!\$]+/); return sign && sign[0].contains("!"); }; ImageManager.isBigCharacter = function (filename) { var sign = filename.match(/^[\!\$]+/); return sign && sign[0].contains("$"); }; ImageManager.isZeroParallax = function (filename) { return filename.charAt(0) === "!"; }; ImageManager.reserveAnimation = function (filename, hue, reservationId) { return this.reserveBitmap("img/animations/", filename, hue, true, reservationId); }; ImageManager.reserveBattleback1 = function (filename, hue, reservationId) { return this.reserveBitmap("img/battlebacks1/", filename, hue, true, reservationId); }; ImageManager.reserveBattleback2 = function (filename, hue, reservationId) { return this.reserveBitmap("img/battlebacks2/", filename, hue, true, reservationId); }; ImageManager.reserveEnemy = function (filename, hue, reservationId) { return this.reserveBitmap("img/enemies/", filename, hue, true, reservationId); }; ImageManager.reserveCharacter = function (filename, hue, reservationId) { return this.reserveBitmap("img/characters/", filename, hue, false, reservationId); }; ImageManager.reserveFace = function (filename, hue, reservationId) { return this.reserveBitmap("img/faces/", filename, hue, true, reservationId); }; ImageManager.reserveParallax = function (filename, hue, reservationId) { return this.reserveBitmap("img/parallaxes/", filename, hue, true, reservationId); }; ImageManager.reservePicture = function (filename, hue, reservationId) { return this.reserveBitmap("img/pictures/", filename, hue, true, reservationId); }; ImageManager.reserveSvActor = function (filename, hue, reservationId) { return this.reserveBitmap("img/sv_actors/", filename, hue, false, reservationId); }; ImageManager.reserveSvEnemy = function (filename, hue, reservationId) { return this.reserveBitmap("img/sv_enemies/", filename, hue, true, reservationId); }; ImageManager.reserveSystem = function (filename, hue, reservationId) { return this.reserveBitmap("img/system/", filename, hue, false, reservationId || this._systemReservationId); }; ImageManager.reserveTileset = function (filename, hue, reservationId) { return this.reserveBitmap("img/tilesets/", filename, hue, false, reservationId); }; ImageManager.reserveTitle1 = function (filename, hue, reservationId) { return this.reserveBitmap("img/titles1/", filename, hue, true, reservationId); }; ImageManager.reserveTitle2 = function (filename, hue, reservationId) { return this.reserveBitmap("img/titles2/", filename, hue, true, reservationId); }; ImageManager.reserveBitmap = function (folder, filename, hue, smooth, reservationId) { if (filename) { var path = folder + encodeURIComponent(filename) + ".png"; var bitmap = this.reserveNormalBitmap(path, hue || 0, reservationId || this._defaultReservationId); bitmap.smooth = smooth; return bitmap; } else { return this.loadEmptyBitmap(); } }; ImageManager.reserveNormalBitmap = function (path, hue, reservationId) { var bitmap = this.loadNormalBitmap(path, hue); this._imageCache.reserve(this._generateCacheKey(path, hue), bitmap, reservationId); return bitmap; }; ImageManager.releaseReservation = function (reservationId) { this._imageCache.releaseReservation(reservationId); }; ImageManager.setDefaultReservationId = function (reservationId) { this._defaultReservationId = reservationId; }; ImageManager.requestAnimation = function (filename, hue) { return this.requestBitmap("img/animations/", filename, hue, true); }; ImageManager.requestBattleback1 = function (filename, hue) { return this.requestBitmap("img/battlebacks1/", filename, hue, true); }; ImageManager.requestBattleback2 = function (filename, hue) { return this.requestBitmap("img/battlebacks2/", filename, hue, true); }; ImageManager.requestEnemy = function (filename, hue) { return this.requestBitmap("img/enemies/", filename, hue, true); }; ImageManager.requestCharacter = function (filename, hue) { return this.requestBitmap("img/characters/", filename, hue, false); }; ImageManager.requestFace = function (filename, hue) { return this.requestBitmap("img/faces/", filename, hue, true); }; ImageManager.requestParallax = function (filename, hue) { return this.requestBitmap("img/parallaxes/", filename, hue, true); }; ImageManager.requestPicture = function (filename, hue) { return this.requestBitmap("img/pictures/", filename, hue, true); }; ImageManager.requestSvActor = function (filename, hue) { return this.requestBitmap("img/sv_actors/", filename, hue, false); }; ImageManager.requestSvEnemy = function (filename, hue) { return this.requestBitmap("img/sv_enemies/", filename, hue, true); }; ImageManager.requestSystem = function (filename, hue) { return this.requestBitmap("img/system/", filename, hue, false); }; ImageManager.requestTileset = function (filename, hue) { return this.requestBitmap("img/tilesets/", filename, hue, false); }; ImageManager.requestTitle1 = function (filename, hue) { return this.requestBitmap("img/titles1/", filename, hue, true); }; ImageManager.requestTitle2 = function (filename, hue) { return this.requestBitmap("img/titles2/", filename, hue, true); }; ImageManager.requestBitmap = function (folder, filename, hue, smooth) { if (filename) { var path = folder + encodeURIComponent(filename) + ".png"; var bitmap = this.requestNormalBitmap(path, hue || 0); bitmap.smooth = smooth; return bitmap; } else { return this.loadEmptyBitmap(); } }; ImageManager.requestNormalBitmap = function (path, hue) { var key = this._generateCacheKey(path, hue); var bitmap = this._imageCache.get(key); if (!bitmap) { bitmap = Bitmap.request(path); bitmap.addLoadListener(function () { bitmap.rotateHue(hue); }); this._imageCache.add(key, bitmap); this._requestQueue.enqueue(key, bitmap); } else { this._requestQueue.raisePriority(key); } return bitmap; }; ImageManager.update = function () { this._requestQueue.update(); }; ImageManager.clearRequest = function () { this._requestQueue.clear(); }; //----------------------------------------------------------------------------- // AudioManager // // The static class that handles BGM, BGS, ME and SE. function AudioManager() { throw new Error("This is a static class"); } AudioManager._masterVolume = 1; // (min: 0, max: 1) AudioManager._bgmVolume = 100; AudioManager._bgsVolume = 100; AudioManager._meVolume = 100; AudioManager._seVolume = 100; AudioManager._currentBgm = null; AudioManager._currentBgs = null; AudioManager._bgmBuffer = null; AudioManager._bgsBuffer = null; AudioManager._meBuffer = null; AudioManager._seBuffers = []; AudioManager._staticBuffers = []; AudioManager._replayFadeTime = 0.5; AudioManager._path = "audio/"; AudioManager._blobUrl = null; Object.defineProperty(AudioManager, "masterVolume", { get: function () { return this._masterVolume; }, set: function (value) { this._masterVolume = value; WebAudio.setMasterVolume(this._masterVolume); Graphics.setVideoVolume(this._masterVolume); }, configurable: true, }); Object.defineProperty(AudioManager, "bgmVolume", { get: function () { return this._bgmVolume; }, set: function (value) { this._bgmVolume = value; this.updateBgmParameters(this._currentBgm); }, configurable: true, }); Object.defineProperty(AudioManager, "bgsVolume", { get: function () { return this._bgsVolume; }, set: function (value) { this._bgsVolume = value; this.updateBgsParameters(this._currentBgs); }, configurable: true, }); Object.defineProperty(AudioManager, "meVolume", { get: function () { return this._meVolume; }, set: function (value) { this._meVolume = value; this.updateMeParameters(this._currentMe); }, configurable: true, }); Object.defineProperty(AudioManager, "seVolume", { get: function () { return this._seVolume; }, set: function (value) { this._seVolume = value; }, configurable: true, }); AudioManager.playBgm = function (bgm, pos) { if (this.isCurrentBgm(bgm)) { this.updateBgmParameters(bgm); } else { this.stopBgm(); if (bgm.name) { if (Decrypter.hasEncryptedAudio && this.shouldUseHtml5Audio()) { this.playEncryptedBgm(bgm, pos); } else { this._bgmBuffer = this.createBuffer("bgm", bgm.name); this.updateBgmParameters(bgm); if (!this._meBuffer) { this._bgmBuffer.play(true, pos || 0); } } } } this.updateCurrentBgm(bgm, pos); }; AudioManager.playEncryptedBgm = function (bgm, pos) { var ext = this.audioFileExt(); var url = this._path + "bgm/" + encodeURIComponent(bgm.name) + ext; url = Decrypter.extToEncryptExt(url); Decrypter.decryptHTML5Audio(url, bgm, pos); }; AudioManager.createDecryptBuffer = function (url, bgm, pos) { this._blobUrl = url; this._bgmBuffer = this.createBuffer("bgm", bgm.name); this.updateBgmParameters(bgm); if (!this._meBuffer) { this._bgmBuffer.play(true, pos || 0); } this.updateCurrentBgm(bgm, pos); }; AudioManager.replayBgm = function (bgm) { if (this.isCurrentBgm(bgm)) { this.updateBgmParameters(bgm); } else { this.playBgm(bgm, bgm.pos); if (this._bgmBuffer) { this._bgmBuffer.fadeIn(this._replayFadeTime); } } }; AudioManager.isCurrentBgm = function (bgm) { return this._currentBgm && this._bgmBuffer && this._currentBgm.name === bgm.name; }; AudioManager.updateBgmParameters = function (bgm) { this.updateBufferParameters(this._bgmBuffer, this._bgmVolume, bgm); }; AudioManager.updateCurrentBgm = function (bgm, pos) { this._currentBgm = { name: bgm.name, volume: bgm.volume, pitch: bgm.pitch, pan: bgm.pan, pos: pos, }; }; AudioManager.stopBgm = function () { if (this._bgmBuffer) { this._bgmBuffer.stop(); this._bgmBuffer = null; this._currentBgm = null; } }; AudioManager.fadeOutBgm = function (duration) { if (this._bgmBuffer && this._currentBgm) { this._bgmBuffer.fadeOut(duration); this._currentBgm = null; } }; AudioManager.fadeInBgm = function (duration) { if (this._bgmBuffer && this._currentBgm) { this._bgmBuffer.fadeIn(duration); } }; AudioManager.playBgs = function (bgs, pos) { if (this.isCurrentBgs(bgs)) { this.updateBgsParameters(bgs); } else { this.stopBgs(); if (bgs.name) { this._bgsBuffer = this.createBuffer("bgs", bgs.name); this.updateBgsParameters(bgs); this._bgsBuffer.play(true, pos || 0); } } this.updateCurrentBgs(bgs, pos); }; AudioManager.replayBgs = function (bgs) { if (this.isCurrentBgs(bgs)) { this.updateBgsParameters(bgs); } else { this.playBgs(bgs, bgs.pos); if (this._bgsBuffer) { this._bgsBuffer.fadeIn(this._replayFadeTime); } } }; AudioManager.isCurrentBgs = function (bgs) { return this._currentBgs && this._bgsBuffer && this._currentBgs.name === bgs.name; }; AudioManager.updateBgsParameters = function (bgs) { this.updateBufferParameters(this._bgsBuffer, this._bgsVolume, bgs); }; AudioManager.updateCurrentBgs = function (bgs, pos) { this._currentBgs = { name: bgs.name, volume: bgs.volume, pitch: bgs.pitch, pan: bgs.pan, pos: pos, }; }; AudioManager.stopBgs = function () { if (this._bgsBuffer) { this._bgsBuffer.stop(); this._bgsBuffer = null; this._currentBgs = null; } }; AudioManager.fadeOutBgs = function (duration) { if (this._bgsBuffer && this._currentBgs) { this._bgsBuffer.fadeOut(duration); this._currentBgs = null; } }; AudioManager.fadeInBgs = function (duration) { if (this._bgsBuffer && this._currentBgs) { this._bgsBuffer.fadeIn(duration); } }; AudioManager.playMe = function (me) { this.stopMe(); if (me.name) { if (this._bgmBuffer && this._currentBgm) { this._currentBgm.pos = this._bgmBuffer.seek(); this._bgmBuffer.stop(); } this._meBuffer = this.createBuffer("me", me.name); this.updateMeParameters(me); this._meBuffer.play(false); this._meBuffer.addStopListener(this.stopMe.bind(this)); } }; AudioManager.updateMeParameters = function (me) { this.updateBufferParameters(this._meBuffer, this._meVolume, me); }; AudioManager.fadeOutMe = function (duration) { if (this._meBuffer) { this._meBuffer.fadeOut(duration); } }; AudioManager.stopMe = function () { if (this._meBuffer) { this._meBuffer.stop(); this._meBuffer = null; if (this._bgmBuffer && this._currentBgm && !this._bgmBuffer.isPlaying()) { this._bgmBuffer.play(true, this._currentBgm.pos); this._bgmBuffer.fadeIn(this._replayFadeTime); } } }; AudioManager.playSe = function (se) { if (se.name) { this._seBuffers = this._seBuffers.filter(function (audio) { return audio.isPlaying(); }); var buffer = this.createBuffer("se", se.name); this.updateSeParameters(buffer, se); buffer.play(false); this._seBuffers.push(buffer); } }; AudioManager.updateSeParameters = function (buffer, se) { this.updateBufferParameters(buffer, this._seVolume, se); }; AudioManager.stopSe = function () { this._seBuffers.forEach(function (buffer) { buffer.stop(); }); this._seBuffers = []; }; AudioManager.playStaticSe = function (se) { if (se.name) { this.loadStaticSe(se); for (var i = 0; i < this._staticBuffers.length; i++) { var buffer = this._staticBuffers[i]; if (buffer._reservedSeName === se.name) { buffer.stop(); this.updateSeParameters(buffer, se); buffer.play(false); break; } } } }; AudioManager.loadStaticSe = function (se) { if (se.name && !this.isStaticSe(se)) { var buffer = this.createBuffer("se", se.name); buffer._reservedSeName = se.name; this._staticBuffers.push(buffer); if (this.shouldUseHtml5Audio()) { Html5Audio.setStaticSe(buffer._url); } } }; AudioManager.isStaticSe = function (se) { for (var i = 0; i < this._staticBuffers.length; i++) { var buffer = this._staticBuffers[i]; if (buffer._reservedSeName === se.name) { return true; } } return false; }; AudioManager.stopAll = function () { this.stopMe(); this.stopBgm(); this.stopBgs(); this.stopSe(); }; AudioManager.saveBgm = function () { if (this._currentBgm) { var bgm = this._currentBgm; return { name: bgm.name, volume: bgm.volume, pitch: bgm.pitch, pan: bgm.pan, pos: this._bgmBuffer ? this._bgmBuffer.seek() : 0, }; } else { return this.makeEmptyAudioObject(); } }; AudioManager.saveBgs = function () { if (this._currentBgs) { var bgs = this._currentBgs; return { name: bgs.name, volume: bgs.volume, pitch: bgs.pitch, pan: bgs.pan, pos: this._bgsBuffer ? this._bgsBuffer.seek() : 0, }; } else { return this.makeEmptyAudioObject(); } }; AudioManager.makeEmptyAudioObject = function () { return { name: "", volume: 0, pitch: 0 }; }; AudioManager.createBuffer = function (folder, name) { var ext = this.audioFileExt(); var url = this._path + folder + "/" + encodeURIComponent(name) + ext; if (this.shouldUseHtml5Audio() && folder === "bgm") { if (this._blobUrl) Html5Audio.setup(this._blobUrl); else Html5Audio.setup(url); return Html5Audio; } else { return new WebAudio(url); } }; AudioManager.updateBufferParameters = function (buffer, configVolume, audio) { if (buffer && audio) { buffer.volume = (configVolume * (audio.volume || 0)) / 10000; buffer.pitch = (audio.pitch || 0) / 100; buffer.pan = (audio.pan || 0) / 100; } }; AudioManager.audioFileExt = function () { if (WebAudio.canPlayOgg() && !Utils.isMobileDevice()) { return ".ogg"; } else { return ".m4a"; } }; AudioManager.shouldUseHtml5Audio = function () { // The only case where we wanted html5audio was android/ no encrypt // Atsuma-ru asked to force webaudio there too, so just return false for ALL // return Utils.isAndroidChrome() && !Decrypter.hasEncryptedAudio; return false; }; AudioManager.checkErrors = function () { this.checkWebAudioError(this._bgmBuffer); this.checkWebAudioError(this._bgsBuffer); this.checkWebAudioError(this._meBuffer); this._seBuffers.forEach( function (buffer) { this.checkWebAudioError(buffer); }.bind(this) ); this._staticBuffers.forEach( function (buffer) { this.checkWebAudioError(buffer); }.bind(this) ); }; AudioManager.checkWebAudioError = function (webAudio) { if (webAudio && webAudio.isError()) { throw new Error("Failed to load: " + webAudio.url); } }; //----------------------------------------------------------------------------- // SoundManager // // The static class that plays sound effects defined in the database. function SoundManager() { throw new Error("This is a static class"); } SoundManager.preloadImportantSounds = function () { this.loadSystemSound(0); this.loadSystemSound(1); this.loadSystemSound(2); this.loadSystemSound(3); }; SoundManager.loadSystemSound = function (n) { if ($dataSystem) { AudioManager.loadStaticSe($dataSystem.sounds[n]); } }; SoundManager.playSystemSound = function (n) { if ($dataSystem) { AudioManager.playStaticSe($dataSystem.sounds[n]); } }; SoundManager.playCursor = function () { this.playSystemSound(0); }; SoundManager.playOk = function () { this.playSystemSound(1); }; SoundManager.playCancel = function () { this.playSystemSound(2); }; SoundManager.playBuzzer = function () { this.playSystemSound(3); }; SoundManager.playEquip = function () { this.playSystemSound(4); }; SoundManager.playSave = function () { this.playSystemSound(5); }; SoundManager.playLoad = function () { this.playSystemSound(6); }; SoundManager.playBattleStart = function () { this.playSystemSound(7); }; SoundManager.playEscape = function () { this.playSystemSound(8); }; SoundManager.playEnemyAttack = function () { this.playSystemSound(9); }; SoundManager.playEnemyDamage = function () { this.playSystemSound(10); }; SoundManager.playEnemyCollapse = function () { this.playSystemSound(11); }; SoundManager.playBossCollapse1 = function () { this.playSystemSound(12); }; SoundManager.playBossCollapse2 = function () { this.playSystemSound(13); }; SoundManager.playActorDamage = function () { this.playSystemSound(14); }; SoundManager.playActorCollapse = function () { this.playSystemSound(15); }; SoundManager.playRecovery = function () { this.playSystemSound(16); }; SoundManager.playMiss = function () { this.playSystemSound(17); }; SoundManager.playEvasion = function () { this.playSystemSound(18); }; SoundManager.playMagicEvasion = function () { this.playSystemSound(19); }; SoundManager.playReflection = function () { this.playSystemSound(20); }; SoundManager.playShop = function () { this.playSystemSound(21); }; SoundManager.playUseItem = function () { this.playSystemSound(22); }; SoundManager.playUseSkill = function () { this.playSystemSound(23); }; //----------------------------------------------------------------------------- // TextManager // // The static class that handles terms and messages. function TextManager() { throw new Error("This is a static class"); } TextManager.basic = function (basicId) { return $dataSystem.terms.basic[basicId] || ""; }; TextManager.param = function (paramId) { return $dataSystem.terms.params[paramId] || ""; }; TextManager.command = function (commandId) { return $dataSystem.terms.commands[commandId] || ""; }; TextManager.message = function (messageId) { return $dataSystem.terms.messages[messageId] || ""; }; TextManager.getter = function (method, param) { return { get: function () { return this[method](param); }, configurable: true, }; }; Object.defineProperty(TextManager, "currencyUnit", { get: function () { return $dataSystem.currencyUnit; }, configurable: true, }); Object.defineProperties(TextManager, { level: TextManager.getter("basic", 0), levelA: TextManager.getter("basic", 1), hp: TextManager.getter("basic", 2), hpA: TextManager.getter("basic", 3), mp: TextManager.getter("basic", 4), mpA: TextManager.getter("basic", 5), tp: TextManager.getter("basic", 6), tpA: TextManager.getter("basic", 7), exp: TextManager.getter("basic", 8), expA: TextManager.getter("basic", 9), fight: TextManager.getter("command", 0), escape: TextManager.getter("command", 1), attack: TextManager.getter("command", 2), guard: TextManager.getter("command", 3), item: TextManager.getter("command", 4), skill: TextManager.getter("command", 5), equip: TextManager.getter("command", 6), status: TextManager.getter("command", 7), formation: TextManager.getter("command", 8), save: TextManager.getter("command", 9), gameEnd: TextManager.getter("command", 10), options: TextManager.getter("command", 11), weapon: TextManager.getter("command", 12), armor: TextManager.getter("command", 13), keyItem: TextManager.getter("command", 14), equip2: TextManager.getter("command", 15), optimize: TextManager.getter("command", 16), clear: TextManager.getter("command", 17), newGame: TextManager.getter("command", 18), continue_: TextManager.getter("command", 19), toTitle: TextManager.getter("command", 21), cancel: TextManager.getter("command", 22), buy: TextManager.getter("command", 24), sell: TextManager.getter("command", 25), alwaysDash: TextManager.getter("message", "alwaysDash"), commandRemember: TextManager.getter("message", "commandRemember"), bgmVolume: TextManager.getter("message", "bgmVolume"), bgsVolume: TextManager.getter("message", "bgsVolume"), meVolume: TextManager.getter("message", "meVolume"), seVolume: TextManager.getter("message", "seVolume"), possession: TextManager.getter("message", "possession"), expTotal: TextManager.getter("message", "expTotal"), expNext: TextManager.getter("message", "expNext"), saveMessage: TextManager.getter("message", "saveMessage"), loadMessage: TextManager.getter("message", "loadMessage"), file: TextManager.getter("message", "file"), partyName: TextManager.getter("message", "partyName"), emerge: TextManager.getter("message", "emerge"), preemptive: TextManager.getter("message", "preemptive"), surprise: TextManager.getter("message", "surprise"), escapeStart: TextManager.getter("message", "escapeStart"), escapeFailure: TextManager.getter("message", "escapeFailure"), victory: TextManager.getter("message", "victory"), defeat: TextManager.getter("message", "defeat"), obtainExp: TextManager.getter("message", "obtainExp"), obtainGold: TextManager.getter("message", "obtainGold"), obtainItem: TextManager.getter("message", "obtainItem"), levelUp: TextManager.getter("message", "levelUp"), obtainSkill: TextManager.getter("message", "obtainSkill"), useItem: TextManager.getter("message", "useItem"), criticalToEnemy: TextManager.getter("message", "criticalToEnemy"), criticalToActor: TextManager.getter("message", "criticalToActor"), actorDamage: TextManager.getter("message", "actorDamage"), actorRecovery: TextManager.getter("message", "actorRecovery"), actorGain: TextManager.getter("message", "actorGain"), actorLoss: TextManager.getter("message", "actorLoss"), actorDrain: TextManager.getter("message", "actorDrain"), actorNoDamage: TextManager.getter("message", "actorNoDamage"), actorNoHit: TextManager.getter("message", "actorNoHit"), enemyDamage: TextManager.getter("message", "enemyDamage"), enemyRecovery: TextManager.getter("message", "enemyRecovery"), enemyGain: TextManager.getter("message", "enemyGain"), enemyLoss: TextManager.getter("message", "enemyLoss"), enemyDrain: TextManager.getter("message", "enemyDrain"), enemyNoDamage: TextManager.getter("message", "enemyNoDamage"), enemyNoHit: TextManager.getter("message", "enemyNoHit"), evasion: TextManager.getter("message", "evasion"), magicEvasion: TextManager.getter("message", "magicEvasion"), magicReflection: TextManager.getter("message", "magicReflection"), counterAttack: TextManager.getter("message", "counterAttack"), substitute: TextManager.getter("message", "substitute"), buffAdd: TextManager.getter("message", "buffAdd"), debuffAdd: TextManager.getter("message", "debuffAdd"), buffRemove: TextManager.getter("message", "buffRemove"), actionFailure: TextManager.getter("message", "actionFailure"), }); //----------------------------------------------------------------------------- // SceneManager // // The static class that manages scene transitions. function SceneManager() { throw new Error("This is a static class"); } /* * Gets the current time in ms without on iOS Safari. * @private */ SceneManager._getTimeInMsWithoutMobileSafari = function () { return performance.now(); }; SceneManager._scene = null; SceneManager._nextScene = null; SceneManager._stack = []; SceneManager._stopped = false; SceneManager._sceneStarted = false; SceneManager._exiting = false; SceneManager._previousClass = null; SceneManager._backgroundBitmap = null; SceneManager._screenWidth = 816; SceneManager._screenHeight = 624; SceneManager._boxWidth = 816; SceneManager._boxHeight = 624; SceneManager._deltaTime = 1.0 / 60.0; if (!Utils.isMobileSafari()) SceneManager._currentTime = SceneManager._getTimeInMsWithoutMobileSafari(); SceneManager._accumulator = 0.0; SceneManager.run = function (sceneClass) { try { this.initialize(); this.goto(sceneClass); this.requestUpdate(); } catch (e) { this.catchException(e); } }; SceneManager.initialize = function () { this.initGraphics(); this.checkFileAccess(); this.initAudio(); this.initInput(); this.initNwjs(); this.checkPluginErrors(); this.setupErrorHandlers(); }; SceneManager.initGraphics = function () { var type = this.preferableRendererType(); Graphics.initialize(this._screenWidth, this._screenHeight, type); Graphics.boxWidth = this._boxWidth; Graphics.boxHeight = this._boxHeight; Graphics.setLoadingImage("img/system/Loading.png"); if (Utils.isOptionValid("showfps")) { Graphics.showFps(); } if (type === "webgl") { this.checkWebGL(); } }; SceneManager.preferableRendererType = function () { if (Utils.isOptionValid("canvas")) { return "canvas"; } else if (Utils.isOptionValid("webgl")) { return "webgl"; } else { return "auto"; } }; SceneManager.shouldUseCanvasRenderer = function () { return Utils.isMobileDevice(); }; SceneManager.checkWebGL = function () { if (!Graphics.hasWebGL()) { throw new Error("Your browser does not support WebGL."); } }; SceneManager.checkFileAccess = function () { if (!Utils.canReadGameFiles()) { throw new Error("Your browser does not allow to read local files."); } }; SceneManager.initAudio = function () { var noAudio = Utils.isOptionValid("noaudio"); if (!WebAudio.initialize(noAudio) && !noAudio) { throw new Error("Your browser does not support Web Audio API."); } }; SceneManager.initInput = function () { Input.initialize(); TouchInput.initialize(); }; SceneManager.initNwjs = function () { if (Utils.isNwjs()) { var gui = require("nw.gui"); var win = gui.Window.get(); if (process.platform === "darwin" && !win.menu) { var menubar = new gui.Menu({ type: "menubar" }); var option = { hideEdit: true, hideWindow: true }; menubar.createMacBuiltin("Game", option); win.menu = menubar; } } }; SceneManager.checkPluginErrors = function () { PluginManager.checkErrors(); }; SceneManager.setupErrorHandlers = function () { window.addEventListener("error", this.onError.bind(this)); document.addEventListener("keydown", this.onKeyDown.bind(this)); }; SceneManager.requestUpdate = function () { if (!this._stopped) { requestAnimationFrame(this.update.bind(this)); } }; SceneManager.update = function () { try { this.tickStart(); if (Utils.isMobileSafari()) { this.updateInputData(); } this.updateManagers(); this.updateMain(); this.tickEnd(); } catch (e) { this.catchException(e); } }; SceneManager.terminate = function () { window.close(); }; SceneManager.onError = function (e) { console.error(e.message); console.error(e.filename, e.lineno); try { this.stop(); Graphics.printError("Error", e.message); AudioManager.stopAll(); } catch (e2) {} }; SceneManager.onKeyDown = function (event) { if (!event.ctrlKey && !event.altKey) { switch (event.keyCode) { case 116: // F5 if (Utils.isNwjs()) { location.reload(); } break; case 119: // F8 if (Utils.isNwjs() && Utils.isOptionValid("test")) { require("nw.gui").Window.get().showDevTools(); } break; } } }; SceneManager.catchException = function (e) { if (e instanceof Error) { Graphics.printError(e.name, e.message); console.error(e.stack); } else { Graphics.printError("UnknownError", e); } AudioManager.stopAll(); this.stop(); }; SceneManager.tickStart = function () { Graphics.tickStart(); }; SceneManager.tickEnd = function () { Graphics.tickEnd(); }; SceneManager.updateInputData = function () { Input.update(); TouchInput.update(); }; SceneManager.updateMain = function () { if (Utils.isMobileSafari()) { this.changeScene(); this.updateScene(); } else { var newTime = this._getTimeInMsWithoutMobileSafari(); var fTime = (newTime - this._currentTime) / 1000; if (fTime > 0.25) fTime = 0.25; this._currentTime = newTime; this._accumulator += fTime; while (this._accumulator >= this._deltaTime) { this.updateInputData(); this.changeScene(); this.updateScene(); this._accumulator -= this._deltaTime; } } this.renderScene(); this.requestUpdate(); }; SceneManager.updateManagers = function () { ImageManager.update(); }; SceneManager.changeScene = function () { if (this.isSceneChanging() && !this.isCurrentSceneBusy()) { if (this._scene) { this._scene.terminate(); this._scene.detachReservation(); this._previousClass = this._scene.constructor; } this._scene = this._nextScene; if (this._scene) { this._scene.attachReservation(); this._scene.create(); this._nextScene = null; this._sceneStarted = false; this.onSceneCreate(); } if (this._exiting) { this.terminate(); } } }; SceneManager.updateScene = function () { if (this._scene) { if (!this._sceneStarted && this._scene.isReady()) { this._scene.start(); this._sceneStarted = true; this.onSceneStart(); } if (this.isCurrentSceneStarted()) { this._scene.update(); } } }; SceneManager.renderScene = function () { if (this.isCurrentSceneStarted()) { Graphics.render(this._scene); } else if (this._scene) { this.onSceneLoading(); } }; SceneManager.onSceneCreate = function () { Graphics.startLoading(); }; SceneManager.onSceneStart = function () { Graphics.endLoading(); }; SceneManager.onSceneLoading = function () { Graphics.updateLoading(); }; SceneManager.isSceneChanging = function () { return this._exiting || !!this._nextScene; }; SceneManager.isCurrentSceneBusy = function () { return this._scene && this._scene.isBusy(); }; SceneManager.isCurrentSceneStarted = function () { return this._scene && this._sceneStarted; }; SceneManager.isNextScene = function (sceneClass) { return this._nextScene && this._nextScene.constructor === sceneClass; }; SceneManager.isPreviousScene = function (sceneClass) { return this._previousClass === sceneClass; }; SceneManager.goto = function (sceneClass) { if (sceneClass) { this._nextScene = new sceneClass(); } if (this._scene) { this._scene.stop(); } }; SceneManager.push = function (sceneClass) { this._stack.push(this._scene.constructor); this.goto(sceneClass); }; SceneManager.pop = function () { if (this._stack.length > 0) { this.goto(this._stack.pop()); } else { this.exit(); } }; SceneManager.exit = function () { this.goto(null); this._exiting = true; }; SceneManager.clearStack = function () { this._stack = []; }; SceneManager.stop = function () { this._stopped = true; }; SceneManager.prepareNextScene = function () { this._nextScene.prepare.apply(this._nextScene, arguments); }; SceneManager.snap = function () { return Bitmap.snap(this._scene); }; SceneManager.snapForBackground = function () { this._backgroundBitmap = this.snap(); this._backgroundBitmap.blur(); }; SceneManager.backgroundBitmap = function () { return this._backgroundBitmap; }; SceneManager.resume = function () { this._stopped = false; this.requestUpdate(); if (!Utils.isMobileSafari()) { this._currentTime = this._getTimeInMsWithoutMobileSafari(); this._accumulator = 0; } }; //----------------------------------------------------------------------------- // BattleManager // // The static class that manages battle progress. function BattleManager() { throw new Error("This is a static class"); } BattleManager.setup = function (troopId, canEscape, canLose) { this.initMembers(); this._canEscape = canEscape; this._canLose = canLose; $gameTroop.setup(troopId); $gameScreen.onBattleStart(); this.makeEscapeRatio(); }; BattleManager.initMembers = function () { this._phase = "init"; this._canEscape = false; this._canLose = false; this._battleTest = false; this._eventCallback = null; this._preemptive = false; this._surprise = false; this._actorIndex = -1; this._actionForcedBattler = null; this._mapBgm = null; this._mapBgs = null; this._actionBattlers = []; this._subject = null; this._action = null; this._targets = []; this._logWindow = null; this._statusWindow = null; this._spriteset = null; this._escapeRatio = 0; this._escaped = false; this._rewards = {}; this._turnForced = false; }; BattleManager.isBattleTest = function () { return this._battleTest; }; BattleManager.setBattleTest = function (battleTest) { this._battleTest = battleTest; }; BattleManager.setEventCallback = function (callback) { this._eventCallback = callback; }; BattleManager.setLogWindow = function (logWindow) { this._logWindow = logWindow; }; BattleManager.setStatusWindow = function (statusWindow) { this._statusWindow = statusWindow; }; BattleManager.setSpriteset = function (spriteset) { this._spriteset = spriteset; }; BattleManager.onEncounter = function () { this._preemptive = Math.random() < this.ratePreemptive(); this._surprise = Math.random() < this.rateSurprise() && !this._preemptive; }; BattleManager.ratePreemptive = function () { return $gameParty.ratePreemptive($gameTroop.agility()); }; BattleManager.rateSurprise = function () { return $gameParty.rateSurprise($gameTroop.agility()); }; BattleManager.saveBgmAndBgs = function () { this._mapBgm = AudioManager.saveBgm(); this._mapBgs = AudioManager.saveBgs(); }; BattleManager.playBattleBgm = function () { AudioManager.playBgm($gameSystem.battleBgm()); AudioManager.stopBgs(); }; BattleManager.playVictoryMe = function () { AudioManager.playMe($gameSystem.victoryMe()); }; BattleManager.playDefeatMe = function () { AudioManager.playMe($gameSystem.defeatMe()); }; BattleManager.replayBgmAndBgs = function () { if (this._mapBgm) { AudioManager.replayBgm(this._mapBgm); } else { AudioManager.stopBgm(); } if (this._mapBgs) { AudioManager.replayBgs(this._mapBgs); } }; BattleManager.makeEscapeRatio = function () { this._escapeRatio = (0.5 * $gameParty.agility()) / $gameTroop.agility(); }; BattleManager.update = function () { if (!this.isBusy() && !this.updateEvent()) { switch (this._phase) { case "start": this.startInput(); break; case "turn": this.updateTurn(); break; case "action": this.updateAction(); break; case "turnEnd": this.updateTurnEnd(); break; case "battleEnd": this.updateBattleEnd(); break; } } }; BattleManager.updateEvent = function () { switch (this._phase) { case "start": case "turn": case "turnEnd": if (this.isActionForced()) { this.processForcedAction(); return true; } else { return this.updateEventMain(); } } return this.checkAbort(); }; BattleManager.updateEventMain = function () { $gameTroop.updateInterpreter(); $gameParty.requestMotionRefresh(); if ($gameTroop.isEventRunning() || this.checkBattleEnd()) { return true; } $gameTroop.setupBattleEvent(); if ($gameTroop.isEventRunning() || SceneManager.isSceneChanging()) { return true; } return false; }; BattleManager.isBusy = function () { return $gameMessage.isBusy() || this._spriteset.isBusy() || this._logWindow.isBusy(); }; BattleManager.isInputting = function () { return this._phase === "input"; }; BattleManager.isInTurn = function () { return this._phase === "turn"; }; BattleManager.isTurnEnd = function () { return this._phase === "turnEnd"; }; BattleManager.isAborting = function () { return this._phase === "aborting"; }; BattleManager.isBattleEnd = function () { return this._phase === "battleEnd"; }; BattleManager.canEscape = function () { return this._canEscape; }; BattleManager.canLose = function () { return this._canLose; }; BattleManager.isEscaped = function () { return this._escaped; }; BattleManager.actor = function () { return this._actorIndex >= 0 ? $gameParty.members()[this._actorIndex] : null; }; BattleManager.clearActor = function () { this.changeActor(-1, ""); }; BattleManager.changeActor = function (newActorIndex, lastActorActionState) { var lastActor = this.actor(); this._actorIndex = newActorIndex; var newActor = this.actor(); if (lastActor) { lastActor.setActionState(lastActorActionState); } if (newActor) { newActor.setActionState("inputting"); } }; BattleManager.startBattle = function () { this._phase = "start"; $gameSystem.onBattleStart(); $gameParty.onBattleStart(); $gameTroop.onBattleStart(); this.displayStartMessages(); }; BattleManager.displayStartMessages = function () { $gameTroop.enemyNames().forEach(function (name) { $gameMessage.add(TextManager.emerge.format(name)); }); if (this._preemptive) { $gameMessage.add(TextManager.preemptive.format($gameParty.name())); } else if (this._surprise) { $gameMessage.add(TextManager.surprise.format($gameParty.name())); } }; BattleManager.startInput = function () { this._phase = "input"; $gameParty.makeActions(); $gameTroop.makeActions(); this.clearActor(); if (this._surprise || !$gameParty.canInput()) { this.startTurn(); } }; BattleManager.inputtingAction = function () { return this.actor() ? this.actor().inputtingAction() : null; }; BattleManager.selectNextCommand = function () { do { if (!this.actor() || !this.actor().selectNextCommand()) { this.changeActor(this._actorIndex + 1, "waiting"); if (this._actorIndex >= $gameParty.size()) { this.startTurn(); break; } } } while (!this.actor().canInput()); }; BattleManager.selectPreviousCommand = function () { do { if (!this.actor() || !this.actor().selectPreviousCommand()) { this.changeActor(this._actorIndex - 1, "undecided"); if (this._actorIndex < 0) { return; } } } while (!this.actor().canInput()); }; BattleManager.refreshStatus = function () { this._statusWindow.refresh(); }; BattleManager.startTurn = function () { this._phase = "turn"; this.clearActor(); $gameTroop.increaseTurn(); this.makeActionOrders(); $gameParty.requestMotionRefresh(); this._logWindow.startTurn(); }; BattleManager.updateTurn = function () { $gameParty.requestMotionRefresh(); if (!this._subject) { this._subject = this.getNextSubject(); } if (this._subject) { this.processTurn(); } else { this.endTurn(); } }; BattleManager.processTurn = function () { var subject = this._subject; var action = subject.currentAction(); if (action) { action.prepare(); if (action.isValid()) { this.startAction(); } subject.removeCurrentAction(); } else { subject.onAllActionsEnd(); this.refreshStatus(); this._logWindow.displayAutoAffectedStatus(subject); this._logWindow.displayCurrentState(subject); this._logWindow.displayRegeneration(subject); this._subject = this.getNextSubject(); } }; BattleManager.endTurn = function () { this._phase = "turnEnd"; this._preemptive = false; this._surprise = false; this.allBattleMembers().forEach(function (battler) { battler.onTurnEnd(); this.refreshStatus(); this._logWindow.displayAutoAffectedStatus(battler); this._logWindow.displayRegeneration(battler); }, this); if (this.isForcedTurn()) { this._turnForced = false; } }; BattleManager.isForcedTurn = function () { return this._turnForced; }; BattleManager.updateTurnEnd = function () { this.startInput(); }; BattleManager.getNextSubject = function () { for (;;) { var battler = this._actionBattlers.shift(); if (!battler) { return null; } if (battler.isBattleMember() && battler.isAlive()) { return battler; } } }; BattleManager.allBattleMembers = function () { return $gameParty.members().concat($gameTroop.members()); }; BattleManager.makeActionOrders = function () { var battlers = []; if (!this._surprise) { battlers = battlers.concat($gameParty.members()); } if (!this._preemptive) { battlers = battlers.concat($gameTroop.members()); } battlers.forEach(function (battler) { battler.makeSpeed(); }); battlers.sort(function (a, b) { return b.speed() - a.speed(); }); this._actionBattlers = battlers; }; BattleManager.startAction = function () { var subject = this._subject; var action = subject.currentAction(); var targets = action.makeTargets(); this._phase = "action"; this._action = action; this._targets = targets; subject.useItem(action.item()); this._action.applyGlobal(); this.refreshStatus(); this._logWindow.startAction(subject, action, targets); }; BattleManager.updateAction = function () { var target = this._targets.shift(); if (target) { this.invokeAction(this._subject, target); } else { this.endAction(); } }; BattleManager.endAction = function () { this._logWindow.endAction(this._subject); this._phase = "turn"; }; BattleManager.invokeAction = function (subject, target) { this._logWindow.push("pushBaseLine"); if (Math.random() < this._action.itemCnt(target)) { this.invokeCounterAttack(subject, target); } else if (Math.random() < this._action.itemMrf(target)) { this.invokeMagicReflection(subject, target); } else { this.invokeNormalAction(subject, target); } subject.setLastTarget(target); this._logWindow.push("popBaseLine"); this.refreshStatus(); }; BattleManager.invokeNormalAction = function (subject, target) { var realTarget = this.applySubstitute(target); this._action.apply(realTarget); this._logWindow.displayActionResults(subject, realTarget); }; BattleManager.invokeCounterAttack = function (subject, target) { var action = new Game_Action(target); action.setAttack(); action.apply(subject); this._logWindow.displayCounter(target); this._logWindow.displayActionResults(target, subject); }; BattleManager.invokeMagicReflection = function (subject, target) { this._action._reflectionTarget = target; this._logWindow.displayReflection(target); this._action.apply(subject); this._logWindow.displayActionResults(target, subject); }; BattleManager.applySubstitute = function (target) { if (this.checkSubstitute(target)) { var substitute = target.friendsUnit().substituteBattler(); if (substitute && target !== substitute) { this._logWindow.displaySubstitute(substitute, target); return substitute; } } return target; }; BattleManager.checkSubstitute = function (target) { return target.isDying() && !this._action.isCertainHit(); }; BattleManager.isActionForced = function () { return !!this._actionForcedBattler; }; BattleManager.forceAction = function (battler) { this._actionForcedBattler = battler; var index = this._actionBattlers.indexOf(battler); if (index >= 0) { this._actionBattlers.splice(index, 1); } }; BattleManager.processForcedAction = function () { if (this._actionForcedBattler) { this._turnForced = true; this._subject = this._actionForcedBattler; this._actionForcedBattler = null; this.startAction(); this._subject.removeCurrentAction(); } }; BattleManager.abort = function () { this._phase = "aborting"; }; BattleManager.checkBattleEnd = function () { if (this._phase) { if (this.checkAbort()) { return true; } else if ($gameParty.isAllDead()) { this.processDefeat(); return true; } else if ($gameTroop.isAllDead()) { this.processVictory(); return true; } } return false; }; BattleManager.checkAbort = function () { if ($gameParty.isEmpty() || this.isAborting()) { SoundManager.playEscape(); this._escaped = true; this.processAbort(); } return false; }; BattleManager.processVictory = function () { $gameParty.removeBattleStates(); $gameParty.performVictory(); this.playVictoryMe(); this.replayBgmAndBgs(); this.makeRewards(); this.displayVictoryMessage(); this.displayRewards(); this.gainRewards(); this.endBattle(0); }; BattleManager.processEscape = function () { $gameParty.performEscape(); SoundManager.playEscape(); var success = this._preemptive ? true : Math.random() < this._escapeRatio; if (success) { this.displayEscapeSuccessMessage(); this._escaped = true; this.processAbort(); } else { this.displayEscapeFailureMessage(); this._escapeRatio += 0.1; $gameParty.clearActions(); this.startTurn(); } return success; }; BattleManager.processAbort = function () { $gameParty.removeBattleStates(); this.replayBgmAndBgs(); this.endBattle(1); }; BattleManager.processDefeat = function () { this.displayDefeatMessage(); this.playDefeatMe(); if (this._canLose) { this.replayBgmAndBgs(); } else { AudioManager.stopBgm(); } this.endBattle(2); }; BattleManager.endBattle = function (result) { this._phase = "battleEnd"; if (this._eventCallback) { this._eventCallback(result); } if (result === 0) { $gameSystem.onBattleWin(); } else if (this._escaped) { $gameSystem.onBattleEscape(); } }; BattleManager.updateBattleEnd = function () { if (this.isBattleTest()) { AudioManager.stopBgm(); SceneManager.exit(); } else if (!this._escaped && $gameParty.isAllDead()) { if (this._canLose) { $gameParty.reviveBattleMembers(); SceneManager.pop(); } else { SceneManager.goto(Scene_Gameover); } } else { SceneManager.pop(); } this._phase = null; }; BattleManager.makeRewards = function () { this._rewards = {}; this._rewards.gold = $gameTroop.goldTotal(); this._rewards.exp = $gameTroop.expTotal(); this._rewards.items = $gameTroop.makeDropItems(); }; BattleManager.displayVictoryMessage = function () { $gameMessage.add(TextManager.victory.format($gameParty.name())); }; BattleManager.displayDefeatMessage = function () { $gameMessage.add(TextManager.defeat.format($gameParty.name())); }; BattleManager.displayEscapeSuccessMessage = function () { $gameMessage.add(TextManager.escapeStart.format($gameParty.name())); }; BattleManager.displayEscapeFailureMessage = function () { $gameMessage.add(TextManager.escapeStart.format($gameParty.name())); $gameMessage.add("\\." + TextManager.escapeFailure); }; BattleManager.displayRewards = function () { this.displayExp(); this.displayGold(); this.displayDropItems(); }; BattleManager.displayExp = function () { var exp = this._rewards.exp; if (exp > 0) { var text = TextManager.obtainExp.format(exp, TextManager.exp); $gameMessage.add("\\." + text); } }; BattleManager.displayGold = function () { var gold = this._rewards.gold; if (gold > 0) { $gameMessage.add("\\." + TextManager.obtainGold.format(gold)); } }; BattleManager.displayDropItems = function () { var items = this._rewards.items; if (items.length > 0) { $gameMessage.newPage(); items.forEach(function (item) { $gameMessage.add(TextManager.obtainItem.format(item.name)); }); } }; BattleManager.gainRewards = function () { this.gainExp(); this.gainGold(); this.gainDropItems(); }; BattleManager.gainExp = function () { var exp = this._rewards.exp; $gameParty.allMembers().forEach(function (actor) { actor.gainExp(exp); }); }; BattleManager.gainGold = function () { $gameParty.gainGold(this._rewards.gold); }; BattleManager.gainDropItems = function () { var items = this._rewards.items; items.forEach(function (item) { $gameParty.gainItem(item, 1); }); }; //----------------------------------------------------------------------------- // PluginManager // // The static class that manages the plugins. function PluginManager() { throw new Error("This is a static class"); } PluginManager._path = "js/plugins/"; PluginManager._scripts = []; PluginManager._errorUrls = []; PluginManager._parameters = {}; PluginManager.setup = function (plugins) { plugins.forEach(function (plugin) { if (plugin.status && !this._scripts.contains(plugin.name)) { this.setParameters(plugin.name, plugin.parameters); this.loadScript(plugin.name + ".js"); this._scripts.push(plugin.name); } }, this); }; PluginManager.checkErrors = function () { var url = this._errorUrls.shift(); if (url) { throw new Error("Failed to load: " + url); } }; PluginManager.parameters = function (name) { return this._parameters[name.toLowerCase()] || {}; }; PluginManager.setParameters = function (name, parameters) { this._parameters[name.toLowerCase()] = parameters; }; PluginManager.loadScript = function (name) { var url = this._path + name; var script = document.createElement("script"); script.type = "text/javascript"; script.src = url; script.async = false; script.onerror = this.onError.bind(this); script._url = url; document.body.appendChild(script); }; PluginManager.onError = function (e) { this._errorUrls.push(e.target._url); };