/**
* Статический класс, который управляет базой данных и игровыми объектами
* The static class that manages the database and game objects
*
* @class DataManager
*/
function DataManager() {
throw new Error('This is a static class');
}
/**
* База данных персонажей
*
* @type {Object[]}
*/
var $dataActors;
/**
* База данных классов
*
* @type {Object[]}
*/
var $dataClasses;
/**
* База данных навыков
*
* @type {Object[]}
*/
var $dataSkills;
/**
* База данных предметов
*
* @type {Object[]}
*/
var $dataItems;
/**
* База данных оружия
*
* @type {Object[]}
*/
var $dataWeapons;
/**
* База данных брони
*
* @type {Object[]}
*/
var $dataArmors;
/**
* База данных врагов
*
* @type {Object[]}
*/
var $dataEnemies;
/**
* База данных отрядов врагов
*
* @type {Object[]}
*/
var $dataTroops;
/**
* База данных состояний
*
* @type {Object[]}
*/
var $dataStates;
/**
* База данных анимаций
*
* @type {Object[]}
*/
var $dataAnimations;
/**
* База данных тайлсетов
*
* @type {Object[]}
*/
var $dataTilesets;
/**
* База данных общих событий
*
* @type {Object[]}
*/
var $dataCommonEvents;
/**
* База данных системных данных
*
* @type {Object[]}
*/
var $dataSystem;
/**
* База данных карт
*
* @type {Object[]}
*/
var $dataMapInfos;
/**
* База данных карты
*
* @type {Object}
*/
var $dataMap;
/**
* Глобальный объект временных данных
*
* @type Game_Temp
*/
var $gameTemp;
/**
* Глобальный объект системных данных
*
* @type Game_System
*/
var $gameSystem;
/**
* Глобальный объект экрана
*
* @type Game_Screen
*/
var $gameScreen;
/**
* Глобальный объект таймера
*
* @type Game_Timer
*/
var $gameTimer;
/**
* Глобальный объект сообщений
*
* @type Game_Message
*/
var $gameMessage;
/**
* Глобальный объект переключателей
*
* @type Game_Switches
*/
var $gameSwitches;
/**
* Глобальный объект переменных
*
* @type Game_Variables
*/
var $gameVariables;
/**
* Глобальный объект локальных переключателей
*
* @type Game_SelfSwitches
*/
var $gameSelfSwitches;
/**
* Глобальный объект персонажей
*
* @type Game_Actors
*/
var $gameActors;
/**
* Глобальный объект партии
*
* @type Game_Party
*/
var $gameParty;
/**
* Глобальный объект отряда врагов
*
* @type Game_Troop
*/
var $gameTroop;
/**
* Глобальный объект карты
*
* @type Game_Map
*/
var $gameMap;
/**
* Глобальный объект игрока
*
* @type Game_Player
*/
var $gamePlayer;
/**
* Загружает всю базу данных
*
* @static
* @static loadDatabase
*/
DataManager.loadDatabase;
/**
* Загружает файл в глобальную переменную
*
* @static
* loadDataFile
* @param {String} name - Название глобальной переменной
* @param {String} src - Название файла
*/
DataManager.loadDataFile;
/**
* Возвращает true, если база данных загружена
*
* @static
* isDatabaseLoaded
* @returns {Boolean} База данных загружена
*/
DataManager.isDatabaseLoaded;
/**
* Загружает информацию о карте
*
* @static
* loadMapData
* @param {Number} mapId - ID карты
*/
DataManager.loadMapData;
/**
* Создает пустой объект информации о карте
*
* @static
* makeEmptyMap
*/
DataManager.makeEmptyMap;
/**
* Возвращает true, если карта загружена
*
* @static
* isMapLoaded
* @returns {Boolean} Карта загружена
*/
DataManager.isMapLoaded;
/**
* Обрабатывает загрузку объекта базы данных
*
* @static
* onLoad
* @param {Array} object - Объект базы данных
*/
DataManager.onLoad;
/**
* Извлекает метаданные из объекта базы данных
*
* @static
* extractMetadata
* @param {Object} data - Объект базы данных
*/
DataManager.extractMetadata;
/**
* Проверяет DataManager на ошибки
*
* @static
* checkError
*/
DataManager.checkError;
/**
* Возвращает true, если запущен тест битвы
*
* @static @static isBattleTest
* @returns {Boolean} Запущен тест битвы
*/
DataManager.isBattleTest;
/**
* Возвращает true, если запущен тест события
*
* @static
* isEventTest
* @returns {Boolean} Запущен тест события
*/
DataManager.isEventTest;
/**
* Возвращает true, если item является навыком
*
* @static
* isSkill
* @param {Object} item - Навык
* @returns {Boolean} item является навыком
*/
DataManager.isSkill;
/**
* Возвращает true, если item является предметом
*
* @static
* isItem
* @param {Object} item - Предмет
* @returns {Boolean} item является предметом
*/
DataManager.isItem;
/**
* Возвращает true, если item является оружием
*
* @static
* isWeapon
* @param {Object} item - Предмет
* @returns {Boolean} item является оружием
*/
DataManager.isWeapon;
/**
* Возвращает true, если item является броней
*
* @static
* isArmor
* @param {Object} item - Предмет
* @returns {Boolean} item является броней
*/
DataManager.isArmor;
/**
* Создает объекты для новой игры
*
* @static
* createGameObjects
*/
DataManager.createGameObjects;
/**
* Устанавливает параметры для новой игры
*
* @static
* setupNewGame
*/
DataManager.setupNewGame;
/**
* Устанавливает параметры для теста битвы
*
* @static
* setupBattleTest
*/
DataManager.setupBattleTest;
/**
* Устанавливает параметры для теста события
*
* @static
* setupEventTest
*/
DataManager.setupEventTest;
/**
* Загружает информацию о сохранениях
*
* @static
* loadGlobalInfo
* @returns {Object[]} Информация о сохранениях
*/
DataManager.loadGlobalInfo;
/**
* Сохраняет информацию о сохранениях
*
* @static
* saveGlobalInfo
* @param {Object[]} info - Информация о сохранениях
*/
DataManager.saveGlobalInfo;
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;
}
};
/**
* Возвращает true, если хотя бы один файл сохранения существует
*
* @static
* isAnySavefileExists
* @returns {Boolean} Хотя бы один файл сохранения существует
*/
DataManager.isAnySavefileExists;
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.loadCharacter(info.characters[i][0]);
}
}
if (info.faces) {
for (var j = 0; j < info.faces.length; j++) {
ImageManager.loadFace(info.faces[j][0]);
}
}
};
/**
* Возвращает максимальное количество файлов сохранений
*
* @static
* maxSavefiles
* @returns {Number} Максимальное количество файлов сохранений
*/
DataManager.maxSavefiles;
/**
* Сохраняет игру в слот сохранения
* Возвращает true, если игра сохранена
*
* @static
* saveGame
* @param {Number} savefileId - Номер слота
* @returns {Boolean} Игра сохранена
*/
DataManager.saveGame;
/**
* Загружает игру из слота сохранения
* Возвращает true, если игра загружена
*
* @static
* loadGame
* @param {Number} savefileId - Номер слота
* @returns {Boolean} Игра загружена
*/
DataManager.loadGame;
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;
}
};
/**
* Выбирает слот сохранения для новой игры
*
* @static
* selectSavefileForNewGame
*/
DataManager.selectSavefileForNewGame;
/**
* Возвращает информацию о сохранении
*
* @static
* makeSavefileInfo
* @returns {Object} Информация о сохранении
*/
DataManager.makeSavefileInfo;
/**
* Создает объект для сохранения
*
* @static
* makeSaveContents
* @returns {Object} Объект для сохранения
*/
DataManager.makeSaveContents;
/**
* Извлекает сохраненные данные
*
* @static
* extractSaveContents
* @param {Object} contents - Сохраненные данные
*/
DataManager.extractSaveContents;
/**
* Статический класс, который управляет данными конфигурации
* The static class that manages the configuration data
*
* @class ConfigManager
*/
function ConfigManager() {
throw new Error('This is a static class');
}
/**
* Команда Всегда бежать
*
* @type {Boolean}
*/
ConfigManager.alwaysDash;
/**
* Команда Запомнить команду
*
* @type {Boolean}
*/
ConfigManager.commandRemember;
/**
* Громкость BGM
*
* @type {Number}
*/
Object.defineProperty(ConfigManager, 'bgmVolume', {
get: function() {
return AudioManager._bgmVolume;
},
set: function(value) {
AudioManager.bgmVolume = value;
},
configurable: true
});
/**
* Громкость BGS
*
* @type {Number}
*/
Object.defineProperty(ConfigManager, 'bgsVolume', {
get: function() {
return AudioManager.bgsVolume;
},
set: function(value) {
AudioManager.bgsVolume = value;
},
configurable: true
});
/**
* Громкость ME
*
* @type {Number}
*/
Object.defineProperty(ConfigManager, 'meVolume', {
get: function() {
return AudioManager.meVolume;
},
set: function(value) {
AudioManager.meVolume = value;
},
configurable: true
});
/**
* Громкость SE
*
* @type {Number}
*/
Object.defineProperty(ConfigManager, 'seVolume', {
get: function() {
return AudioManager.seVolume;
},
set: function(value) {
AudioManager.seVolume = value;
},
configurable: true
});
/**
* Загружает данные конфигурации
*
* @static
* load
*/
ConfigManager.load;
/**
* Сохраняет данные конфигурации
*
* @static
* save
*/
ConfigManager.save;
/**
* Создает объект для сохранения конфигурации
*
* @static
* makeData
* @returns {Object} Объект для сохранения
*/
ConfigManager.makeData;
/**
* Извлекает сохраненные данные
*
* @static
* applyData
* @param {Object} config - Сохраненные данные
*/
ConfigManager.applyData;
/**
* Возвращает true, если параметр включен
*
* @static
* readFlag
* @param {Object} config - Сохраненные данные
* @param {String} name - Название параметра
* @returns {Boolean} Активность параметра
*/
ConfigManager.readFlag;
/**
* Возвращает громкость звука
*
* @static
* readVolume
* @param {Object} config - Сохраненные данные
* @param {String} name - Название параметра
* @returns {Number} Громкость звука
*/
ConfigManager.readVolume;
/**
* Статический класс, который управляет хранилищем сохранений
* The static class that manages storage for saving game data
*
* @class StorageManager
*/
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);
}
};
/**
* Статический клаас, который загружает изображения, создает битмапы и сохраняет их
* The static class that loads images, creates bitmap objects and retains them
*
* @class ImageManager
*/
function ImageManager() {
throw new Error('This is a static class');
}
/**
* Кэш изображений
*
* @type {CacheMap}
*/
ImageManager.cache;
/**
* Загружает Bitmap из папки img/animations/
* Возвращает загруженный Bitmap
*
* @static
* loadAnimation
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadAnimation;
/**
* Загружает Bitmap из папки img/battlebacks1/
* Возвращает загруженный Bitmap
*
* @static
* loadBattleback1
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadBattleback1;
/**
* Загружает Bitmap из папки img/battlebacks2/
* Возвращает загруженный Bitmap
*
* @static
* loadBattleback2
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadBattleback2;
/**
* Загружает Bitmap из папки img/enemies/
* Возвращает загруженный Bitmap
*
* @static
* loadEnemy
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadEnemy;
/**
* Загружает Bitmap из папки img/characters/
* Возвращает загруженный Bitmap
*
* @static
* loadCharacter
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadCharacter;
/**
* Загружает Bitmap из папки img/faces/
* Возвращает загруженный Bitmap
*
* @static
* loadFace
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadFace;
/**
* Загружает Bitmap из папки img/parallaxes/
* Возвращает загруженный Bitmap
*
* @static
* loadParallax
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadParallax;
/**
* Загружает Bitmap из папки img/pictures/
* Возвращает загруженный Bitmap
*
* @static
* loadPicture
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadPicture;
/**
* Загружает Bitmap из папки img/sv_actors/
* Возвращает загруженный Bitmap
*
* @static
* loadSvActor
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadSvActor;
/**
* Загружает Bitmap из папки img/sv_enemies/
* Возвращает загруженный Bitmap
*
* @static
* loadSvEnemy
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadSvEnemy;
/**
* Загружает Bitmap из папки img/system/
* Возвращает загруженный Bitmap
*
* @static
* loadSystem
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadSystem;
/**
* Загружает Bitmap из папки img/tilesets/
* Возвращает загруженный Bitmap
*
* @static
* loadTileset
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadTileset;
/**
* Загружает Bitmap из папки img/titles1/
* Возвращает загруженный Bitmap
*
* @static
* loadTitle1
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadTitle1;
/**
* Загружает Bitmap из папки img/titles2/
* Возвращает загруженный Bitmap
*
* @static
* loadTitle2
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @returns {Boolean} Загруженный Bitmap
*/
ImageManager.loadTitle2;
/**
* Загружает Bitmap
* Возвращает загруженный или пустой Bitmap
*
* @static
* loadBitmap
* @param {String} folder - Путь к файлу
* @param {String} filename - Название файла
* @param {Number} hue - Оттенок
* @param {Boolean} smooth - Сглаживание
* @returns {Bitmap} Загруженный или пустой Bitmap
*/
ImageManager.loadBitmap;
/**
* Возвращает пустой Bitmap
*
* @static
* loadEmptyBitmap
* @returns {Bitmap} Пустой Bitmap
*/
ImageManager.loadEmptyBitmap;
/**
* Загружает Bitmap
* Возвращает загруженный Bitmap
*
* @static
* loadNormalBitmap
* @param {String} path - Путь файла
* @param {Number} hue - Оттенок
* @returns {Bitmap} Загруженный Bitmap
*/
ImageManager.loadNormalBitmap;
/**
* Очищает кэш изображений
*
* @static
* clear
*/
ImageManager.clear;
/**
* Возвращает true, если менеджер изображений готов
*
* @static
* isReady
* @returns {Boolean} Менеджер изображений готов
*/
ImageManager.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) === '!';
};
/**
* Статический класс, который обрабатывает BGM, BGS, ME, SE
* The static class that handles BGM, BGS, ME and SE
*
* @class AudioManager
*/
function AudioManager() {
throw new Error('This is a static class');
}
/**
* Громкость BGM
*
* @private
* @type {Number}
*/
AudioManager._bgmVolume;
/**
* Громкость BGS
*
* @private
* @type {Number}
*/
AudioManager._bgsVolume;
/**
* Громкость ME
*
* @private
* @type {Number}
*/
AudioManager._meVolume;
/**
* Громкость SE
*
* @private
* @type {Number}
*/
AudioManager._seVolume;
/**
* Текущий BGM
*
* @private
* @type {Object | null}
*/
AudioManager._currentBgm;
/**
* Текущий BGS
*
* @private
* @type {Object | null}
*/
AudioManager._currentBgs;
AudioManager._bgmBuffer = null;
AudioManager._bgsBuffer = null;
AudioManager._meBuffer = null;
AudioManager._seBuffers = [];
AudioManager._staticBuffers = [];
AudioManager._replayFadeTime = 0.5;
/**
* Путь к папке со звуками
*
* @private
* @type {String}
*/
AudioManager._path;
AudioManager._blobUrl = null;
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);
};
/**
* Обновляет текущий BGM
*
* @static
* updateCurrentBgm
* @param {Object} bgm - Объект BGM
* @param {String} bgm.name - Название файла
* @param {Number} bgm.volume - Громкость BGM
* @param {Number} bgm.pitch - Темп BGM
* @param {Number} bgm.pan - Панорама BGM
* @param {Number} pos - Позиция BGM
*/
AudioManager.updateCurrentBgm;
/**
* Останавливает BGM
*
* @static
* stopBgm
*/
AudioManager.stopBgm;
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;
};
/**
* Останавливает воспроизведение всех звуков
*
* @static
* stopAll
*/
AudioManager.stopAll;
/**
* Сохраняет BGM
* Возвращает текущий или пустой BGM
*
* @static
* saveBgm
* @returns {Object} Текущий или пустой BGM
*/
AudioManager.saveBgm;
/**
* Сохраняет BGS
* Возвращает текущий или пустой BGS
*
* @static
* saveBgs
* @returns {Object} Текущий или пустой BGS
*/
AudioManager.saveBgs;
/**
* Возвращает пустой звуковой объект
*
* @static
* makeEmptyAudioObject
* @returns {Object} Пустой звуковой объект
*/
AudioManager.makeEmptyAudioObject;
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;
}
};
/**
* Возвращает расширение звукового файла
*
* @static
* audioFileExt
* @returns {String} Расширение звукового файла
*/
AudioManager.audioFileExt;
AudioManager.shouldUseHtml5Audio = function() {
// We use HTML5 Audio to play BGM instead of Web Audio API
// because decodeAudioData() is very slow on Android Chrome.
return Utils.isAndroidChrome() && !Decrypter.hasEncryptedAudio;
};
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);
}
};
/**
* Статический класс, который воспроизводит звуки, определенные в базе данных
* The static class that plays sound effects defined in the database
*
* @class SoundManager
*/
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);
};
/**
* Статический класс, который управляет терминами и сообщениями
* The static class that handles terms and messages
*
* @class TextManager
*/
function TextManager() {
throw new Error('This is a static class');
}
/**
* Возвращает название характеристики
*
* @static
* basic
* @param {Number} basicId - ID характеристики
* @returns {String} Название характеристики
*/
TextManager.basic;
/**
* Возвращает название параметра
*
* @static
* param
* @param {Number} paramId - ID параметра
* @returns {String} Название параметра
*/
TextManager.param;
/**
* Возвращает название команды
*
* @static
* command
* @param {Number} commandId - ID команды
* @returns {String} Название команды
*/
TextManager.command;
/**
* Возвращает название сообщения
*
* @static
* message
* @param {Number} messageId - ID сообщения
* @returns {String} Название сообщения
*/
TextManager.message;
TextManager.getter = function(method, param) {
return {
get: function() {
return this[method](param);
},
configurable: true
};
};
/**
* Название валюты
*
* @type {String}
*/
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'),
});
/**
* Статический класс, который управляет переходами между сценами
* The static class that manages scene transitions
*
* @class SceneManager
*/
function SceneManager() {
throw new Error('This is a static class');
}
/*
* Gets the current time in ms.
* @private
*/
SceneManager._getTimeInMs = 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;
SceneManager._currentTime = SceneManager._getTimeInMs();
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 if (this.shouldUseCanvasRenderer()) {
return 'canvas';
} 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.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._getTimeInMs();
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(ticks, delta) {
ImageManager.cache.update(ticks, delta);
};
SceneManager.changeScene = function() {
if (this.isSceneChanging() && !this.isCurrentSceneBusy()) {
if (this._scene) {
this._scene.terminate();
this._previousClass = this._scene.constructor;
}
this._scene = this._nextScene;
if (this._scene) {
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;
};
/**
* Статический класс, который управляет битвой
* The static class that manages battle progress
*
* @class BattleManager
*/
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 = {};
};
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);
};
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(subject, subject);
};
BattleManager.invokeMagicReflection = function(subject, target) {
this._logWindow.displayReflection(target);
this._action.apply(subject);
this._logWindow.displayActionResults(subject, 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._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()) {
this.processAbort();
return true;
}
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 ($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);
});
};
/**
* Статический класс, который управляет плагинами
* The static class that manages the plugins
*
* @class PluginManager
*/
function PluginManager() {
throw new Error('This is a static class');
}
/**
* Путь к папке с плагинами
*
* @private
* @type {String}
*/
PluginManager._path;
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);
};