451 lines
No EOL
14 KiB
JavaScript
451 lines
No EOL
14 KiB
JavaScript
//=============================================================================
|
|
// RPG Maker MZ - KN_Util.js
|
|
//=============================================================================
|
|
|
|
/*:ja
|
|
* @target MZ
|
|
* @author kurogoma knights
|
|
* @base PluginCommonBase
|
|
* @plugindesc 便利機能を提供
|
|
*
|
|
* @help
|
|
* ・宝箱カウントアップ
|
|
* ・踏破率カウントアップ
|
|
* ・立ち絵名取得
|
|
* ・アイテム付与
|
|
*
|
|
* @command TEST
|
|
* @text [デバッグ] テスト機能
|
|
* @desc テスト機能です。デバッグ用です。
|
|
*
|
|
* @command ADD_ITEM_ALL
|
|
* @text [デバッグ] 全アイテム付与
|
|
* @desc 全アイテムを付与します。デバッグ用です。
|
|
*
|
|
* @command ADD_ITEM_SKILL_ALL
|
|
* @text [デバッグ] 全スキル付与
|
|
*
|
|
* @command ADD_ITEM_ARTIFACT_ALL
|
|
* @text [デバッグ] 全遺物付与
|
|
*
|
|
* @command FORCE_ITEM_GOLD_RESET
|
|
* @text [デバッグ] 全所持品&お金リセット
|
|
*
|
|
* @command GET_ITEM_NAME
|
|
* @text アイテム名の取得
|
|
* @arg itemID
|
|
* @type item
|
|
* @arg variableID
|
|
* @type variable
|
|
*
|
|
*/
|
|
|
|
// プラグイン "ExtraWindow" の設定で変数使ってるので注意
|
|
(() => {
|
|
'use strict';
|
|
const script = document.currentScript;
|
|
const param = PluginManagerEx.createParameter(script);
|
|
|
|
// 服耐久度
|
|
const ARMOR_MUKIZU = 0;
|
|
const ARMOR_CHUUHA = 50;
|
|
const ARMOR_TAIHA = 100;
|
|
// ムラムラ
|
|
const MURAMURA = 50;
|
|
const TOROTORO = 200;
|
|
const HATUJO = 999;
|
|
// 淫乱レベル
|
|
const LV_1 = 30;
|
|
const LV_2 = 100;
|
|
const LV_3 = 300;
|
|
|
|
// 発情ステートID
|
|
const EROS_STATE_ID = 33;
|
|
|
|
|
|
//
|
|
// プラグインコマンド
|
|
//
|
|
|
|
// test
|
|
PluginManagerEx.registerCommand(script, "TEST", args => {
|
|
});
|
|
Game_Map.prototype.knUtilTest = function() {
|
|
};
|
|
|
|
// [DEBUG] アイテム全付与 x9
|
|
PluginManagerEx.registerCommand(script, "ADD_ITEM_ALL", args => {
|
|
$dataItems.forEach(item => {
|
|
if (item && item.name !== "" && item.name.charAt(0) !== "-")
|
|
$gameParty.gainItem(item, 9);
|
|
});
|
|
});
|
|
|
|
// [DEBUG] スキル付与
|
|
PluginManagerEx.registerCommand(script, "ADD_ITEM_SKILL_ALL", args => {
|
|
$dataItems.forEach(item => {
|
|
if (item && item.name && item.meta['SGカテゴリ'] === "スキル") {
|
|
$gameParty.gainItem(item, 9);
|
|
}
|
|
})
|
|
});
|
|
|
|
// [DEBUG] 遺物付与
|
|
PluginManagerEx.registerCommand(script, "ADD_ITEM_ARTIFACT_ALL", args => {
|
|
$dataItems.forEach(item => {
|
|
if (item && item.name && item.meta['SGカテゴリ'] === "遺物") {
|
|
$gameParty.gainItem(item, 1);
|
|
}
|
|
});
|
|
});
|
|
|
|
// [DEBUG] アイテムお金全消し
|
|
PluginManagerEx.registerCommand(script, "FORCE_ITEM_GOLD_RESET", function(args) {
|
|
// 全消し
|
|
$gameParty.initAllItems();
|
|
$gameParty.gainGold(-99999999)
|
|
});
|
|
|
|
|
|
// アイテム名取得
|
|
PluginManagerEx.registerCommand(script, "GET_ITEM_NAME", args => {
|
|
const item = $dataItems[args.itemID];
|
|
$gameVariables.setValue(args.variableID, item.name);
|
|
});
|
|
|
|
//
|
|
// Game_Player
|
|
//
|
|
|
|
// 服の損傷度
|
|
Game_Player.prototype.getCostumeKey = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.CostumeKey); // 衣装key
|
|
}
|
|
|
|
// 服の損傷度
|
|
Game_Player.prototype.getArmorValue = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.ArmorDamage); // シロ服損傷度(0-100)
|
|
}
|
|
|
|
// 発情中?
|
|
Game_Player.prototype.isEros = function() {
|
|
const actor = $gameParty.leader();
|
|
return actor.isStateAffected(EROS_STATE_ID);
|
|
}
|
|
|
|
// とにかくピンチ?
|
|
Game_Player.prototype.isPinch = function() {
|
|
const actor = $gameParty.leader();
|
|
return this.isArmorTaiha() || actor.isDying();
|
|
}
|
|
|
|
// シロちゃんの服、大破してる?
|
|
Game_Player.prototype.isArmorTaiha = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.ArmorDamage) >= ARMOR_TAIHA;
|
|
}
|
|
|
|
// シロちゃんの服、中破してる?
|
|
Game_Player.prototype.isArmorChuuha = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.ArmorDamage) >= ARMOR_CHUUHA;
|
|
}
|
|
|
|
// シロちゃんの服、やぶれてない?
|
|
Game_Player.prototype.isArmorMukizu = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.ArmorDamage) >= ARMOR_MUKIZU;
|
|
}
|
|
|
|
// 猫? 条件分岐スクリプトで使う想定
|
|
Game_Player.prototype.isNeko = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.CostumeKey) === "neko";
|
|
};
|
|
|
|
// ムラムラ
|
|
Game_Player.prototype.getMuramuraText = function() {
|
|
const value = $gameVariables.value(Kurogoma.VariableConst.Muramura);
|
|
if (this.isHatujo())
|
|
return "発情";
|
|
if (this.isTorotoro())
|
|
return "とろとろ";
|
|
if (this.isMuramura())
|
|
return "むらむら";
|
|
return "ふつう";
|
|
}
|
|
Game_Player.prototype.isHatujo = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.Muramura) >= HATUJO;
|
|
}
|
|
Game_Player.prototype.isTorotoro = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.Muramura) >= TOROTORO;
|
|
}
|
|
Game_Player.prototype.isMuramura = function() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.Muramura) >= MURAMURA;
|
|
}
|
|
|
|
// 淫乱度
|
|
Game_Player.prototype.getEcchiLevel = function() {
|
|
const value = $gameVariables.value(Kurogoma.VariableConst.Inran); // 淫乱度
|
|
if (value >= LV_3)
|
|
return 3;
|
|
if (value >= LV_2)
|
|
return 2;
|
|
if (value >= LV_1)
|
|
return 1;
|
|
return 0;
|
|
};
|
|
Game_Player.prototype.getEcchiText = function() {
|
|
const value = $gameVariables.value(Kurogoma.VariableConst.Inran); // 淫乱度
|
|
if (value >= LV_3)
|
|
return "★3";
|
|
if (value >= LV_2)
|
|
return "★2";
|
|
if (value >= LV_1)
|
|
return "★1";
|
|
return "★0";
|
|
}
|
|
|
|
// デバフもち? DBステート参照
|
|
Game_Player.prototype.hasDebuff = function() {
|
|
const debuffStateIds = [
|
|
4, // 毒
|
|
5, // 暗闇
|
|
6, // 沈黙
|
|
7, // 激昂
|
|
8, // 混乱
|
|
9, // 魅了
|
|
10, // 睡眠
|
|
11, // 瘴気
|
|
12, // 麻痺
|
|
13, // スタン
|
|
];
|
|
const actor = $gameParty.leader();
|
|
let hasDebuff = false;
|
|
debuffStateIds.forEach(id => hasDebuff = hasDebuff || actor.isStateAffected(id));
|
|
return hasDebuff;
|
|
}
|
|
|
|
|
|
//
|
|
// Game_Interpreter
|
|
//
|
|
|
|
// 選択肢Index取得
|
|
Game_Interpreter.prototype.getBranchIndex = function() {
|
|
return this._branch[this._indent];
|
|
};
|
|
|
|
// 親インタプリタを参照できるように
|
|
const _Game_Interpreter_setupChild = Game_Interpreter.prototype.setupChild;
|
|
Game_Interpreter.prototype.setupChild = function(list, eventId) {
|
|
this._childInterpreter = new Game_Interpreter(this._depth + 1);
|
|
this._childInterpreter._parentInterpreter = this; // 親を保存
|
|
this._childInterpreter.setup(list, eventId);
|
|
};
|
|
|
|
// 親
|
|
Game_Interpreter.prototype.parent = function() {
|
|
return this._parentInterpreter;
|
|
};
|
|
|
|
// スクリプトをコモンイベントみたいに実行
|
|
Game_Interpreter.prototype.runScripts = function(scripts) {
|
|
if (!Array.isArray(scripts))
|
|
return; // 安全策: 配列でなければ処理しない
|
|
|
|
// スクリプトをイベントコマンドに変換
|
|
const list = convertScriptToEventCommand(scripts);
|
|
|
|
// setupChildで実行
|
|
this.setupChild(list, this.eventId());
|
|
};
|
|
|
|
|
|
// スクリプトをイベントコマンドデータに変換
|
|
// scriptsは1行 () => hoge.fuga() みたいな形で書くとパースできないから注意
|
|
function convertScriptToEventCommand(scripts) {
|
|
const list = [];
|
|
|
|
scripts.forEach(script => {
|
|
if (typeof script === "function") {
|
|
const scriptString = script.toString()
|
|
.replace(/^.*?{/, '') // 関数の `{` を削除
|
|
.replace(/}$/, '') // 関数の `}` を削除
|
|
.trim(); // 前後の空白を削除
|
|
|
|
const lines = scriptString.split("\n")
|
|
.map(line => line.trim())
|
|
.filter(line => line.length > 0);
|
|
|
|
if (lines.length === 0) return;
|
|
|
|
// 最初の行は `355`(スクリプト実行)
|
|
list.push({
|
|
code: 355,
|
|
indent: 0, // indnet:0固定なのでループ中断とかで困りそうではある
|
|
parameters: [lines[0]]
|
|
});
|
|
|
|
// 2行目以降は `655`(スクリプト継続)
|
|
for (let i = 1; i < lines.length; i++) {
|
|
list.push({
|
|
code: 655,
|
|
indent: 0,
|
|
parameters: [lines[i]]
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
// リストの最後に { code: 0 } を追加(イベントの終了)
|
|
list.push({
|
|
code: 0,
|
|
indent: 0,
|
|
parameters: []
|
|
});
|
|
|
|
return list;
|
|
}
|
|
|
|
|
|
//
|
|
// Window_Base
|
|
//
|
|
|
|
// アイコンとテキストを出すやつ
|
|
Window_Base.prototype.drawIconText = function(iconId, text, x, y, width, align = "left", spacing = 4) {
|
|
const iconW = ImageManager.iconWidth;
|
|
const iconH = ImageManager.iconHeight;
|
|
|
|
// アイコンを垂直センタリング
|
|
const iconY = y + (this.lineHeight() - iconH) / 2;
|
|
this.drawIcon(iconId, x, iconY);
|
|
|
|
// テキスト描画位置
|
|
const textX = x + iconW + spacing;
|
|
const textWidth = width - iconW - spacing;
|
|
this.drawText(text, textX, y, textWidth, align);
|
|
};
|
|
|
|
|
|
//
|
|
// Game_Map
|
|
//
|
|
|
|
// 実行中の一番深いインタプリタを取得
|
|
Game_Map.prototype.getInterpreter = function() {
|
|
let interpreter = this._interpreter;
|
|
while (interpreter._childInterpreter) {
|
|
interpreter = interpreter._childInterpreter;
|
|
}
|
|
return interpreter;
|
|
};
|
|
|
|
|
|
//
|
|
// 独自関数
|
|
//
|
|
|
|
window.Kurogoma = window.Kurogoma || {};
|
|
|
|
|
|
// デバッグ用
|
|
class Debug {
|
|
static console = {
|
|
log(value, options = {}) {
|
|
const { label = "[Debug]", trace = false } = options;
|
|
console.log(label, JsonEx.makeDeepCopy(value));
|
|
if (trace) console.trace();
|
|
}
|
|
};
|
|
}
|
|
window.Kurogoma.Debug = Debug;
|
|
|
|
|
|
// 環境情報
|
|
class Environment {
|
|
// 現在のバージョン情報
|
|
static getBuildVersion() {
|
|
return $dataUniques?.BuildInfo.version;
|
|
}
|
|
|
|
// 現在のビルドタイプ trial / release
|
|
static getBuildType() {
|
|
return $dataUniques?.BuildInfo.type;
|
|
}
|
|
|
|
// 体験版かどうか
|
|
static isTrialBuild() {
|
|
return $dataUniques?.BuildInfo.type === "trial";
|
|
}
|
|
|
|
// 製品版かどうか
|
|
static isReleaseBuild() {
|
|
return $dataUniques?.BuildInfo.type === "release";
|
|
}
|
|
}
|
|
window.Kurogoma.Environment = Environment;
|
|
|
|
|
|
// 便利関数
|
|
class Util {
|
|
// 入力値を整数に変換(ここでは四捨五入していますが、必要に応じて Math.floor や Math.ceil に変更可能)
|
|
static clampInt(value, min, max) {
|
|
const intValue = Math.round(value);
|
|
return Math.min(Math.max(intValue, min), max);
|
|
}
|
|
}
|
|
window.Kurogoma.Util = Util;
|
|
|
|
|
|
// オプション情報
|
|
class Option {
|
|
// 通常バトル
|
|
static isBattleNormalMode() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.BattleSetting) == 0;
|
|
}
|
|
// セーフティ
|
|
static isBattleSafeMode() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.BattleSetting) == 1;
|
|
}
|
|
// スキップ
|
|
static isBattleSkipMode() {
|
|
return $gameVariables.value(Kurogoma.VariableConst.BattleSetting) == 2;
|
|
}
|
|
}
|
|
window.Kurogoma.Option = Option;
|
|
|
|
|
|
// レイアウト
|
|
class Layout {
|
|
// rmmz_scenes.js
|
|
static calcWindowHeight = function(numLines, selectable) {
|
|
if (selectable) {
|
|
return Window_Selectable.prototype.fittingHeight(numLines);
|
|
} else {
|
|
return Window_Base.prototype.fittingHeight(numLines);
|
|
}
|
|
};
|
|
}
|
|
window.Kurogoma.Layout = Layout;
|
|
|
|
|
|
// 乱数
|
|
class Random {
|
|
// 整数範囲の乱数を取得
|
|
static range(min, max) {
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
}
|
|
// 指定した確率で1か0を返す
|
|
static chance(rate) {
|
|
return Math.random() < (rate / 100) ? 1 : 0;
|
|
}
|
|
// 指定した確率で複数回抽選し、当選した回数を返す
|
|
static chanceMultiple(rate, times) {
|
|
let successCount = 0;
|
|
for (let i = 0; i < times; i++) {
|
|
successCount += this.chance(rate);
|
|
}
|
|
return successCount;
|
|
}
|
|
}
|
|
window.Kurogoma.Random = Random;
|
|
|
|
})(); |