1023 lines
27 KiB
JavaScript
1023 lines
27 KiB
JavaScript
//=============================================================================
|
|
// KMS_ShopInventory.js
|
|
// Last update: 2017/02/03
|
|
//=============================================================================
|
|
|
|
/*:
|
|
* @plugindesc
|
|
* [v0.1.0] Add the inventory control function for shops.
|
|
*
|
|
* @author TOMY (Kamesoft)
|
|
*
|
|
* @param Sold out text
|
|
* @default SOLD OUT
|
|
* @desc "Sold out" text which is displayed instead of item's price.
|
|
*
|
|
* @param Caption for stock
|
|
* @default Stock
|
|
* @desc The caption for stocks of items.
|
|
*
|
|
* @param Stock display
|
|
* @default 1
|
|
* @desc
|
|
* Specify the window for displaying stock numbers.
|
|
* 0: ShopNumber 1: ShopStatus
|
|
*
|
|
* @help
|
|
*
|
|
* ## Plugin commands
|
|
* ShopInventory apply shop1 # Use an inventory info specified as ID:shop1 when the event command "Shop" is called in the next
|
|
* ShopInventory supplySpeed shop1 3 # All items are supplied to ID:shop1 by 3x
|
|
* ShopInventory supplySpeed shop2 0 # Do not supply any item to ID:shop2
|
|
* ShopInventory restockAll shop1 # Stock of ID:shop1 is replenished fully
|
|
* ShopInventory resetAll # Initialize all inventory info
|
|
*/
|
|
|
|
/*:ja
|
|
* @plugindesc
|
|
* [v0.1.0] アイテムの在庫管理機能を追加します。
|
|
*
|
|
* @author TOMY (Kamesoft)
|
|
*
|
|
* @param Sold out text
|
|
* @default SOLD OUT
|
|
* @desc 在庫がない場合、アイテムの価格の代わりに表示するテキストです。
|
|
*
|
|
* @param Caption for stock
|
|
* @default 在庫
|
|
* @desc 在庫表示の名称です。
|
|
*
|
|
* @param Stock display
|
|
* @default 1
|
|
* @desc
|
|
* 在庫数を表示するウィンドウを指定します。
|
|
* 0: 購入数選択 1: ステータス
|
|
*
|
|
* @help
|
|
*
|
|
* ■ プラグインコマンド
|
|
* ShopInventory apply shop1 # 次の「ショップの処理」で ID:shop1 の在庫情報を使用
|
|
* ShopInventory supplySpeed shop1 3 # ID:shop1 の在庫を 3 倍速で補充
|
|
* ShopInventory supplySpeed shop2 0 # ID:shop2 の在庫は補充しない
|
|
* ShopInventory restockAll shop1 # ID:shop1 の在庫を最大まで補充
|
|
* ShopInventory resetAll # 在庫情報を初期化
|
|
*/
|
|
|
|
var KMS = KMS || {};
|
|
|
|
// セーブデータからの復元を可能にするため、セーブデータに入るクラスをグローバルスコープに置く
|
|
function Game_ShopInventory() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
function Game_ShopSupplySchedule() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
function Game_ShopInventorySupplier() {
|
|
this.initialize.apply(this, arguments);
|
|
}
|
|
|
|
(function () {
|
|
"use strict";
|
|
|
|
var PluginName = "KMS_ShopInventory";
|
|
|
|
KMS.imported = KMS.imported || {};
|
|
KMS.imported["ShopInventory"] = true;
|
|
|
|
var pluginParams = PluginManager.parameters(PluginName);
|
|
var Params = {};
|
|
Params.soldOutText = pluginParams["Sold out text"] || "SOLD OUT";
|
|
Params.stockCaption = pluginParams["Caption for stock"] || "Stock";
|
|
Params.showStockInStatus = Number(pluginParams["Show stock in status"] || 1);
|
|
|
|
// 商品の補充モード
|
|
var SupplyMode = {
|
|
playtime: 0, // プレイ時間
|
|
battleCount: 1, // 戦闘回数
|
|
|
|
max: 1,
|
|
};
|
|
|
|
// 商品の補充モードシンボル
|
|
var SupplyModeSymbol = {
|
|
T: SupplyMode.playtime,
|
|
B: SupplyMode.battleCount,
|
|
};
|
|
|
|
// 定数
|
|
var Const = {
|
|
debug: false, // デバッグモード
|
|
pluginCommandCode: "ShopInventory", // プラグインコマンドコード
|
|
};
|
|
|
|
// デバッグログ
|
|
var debuglog;
|
|
if (Const.debug) {
|
|
debuglog = function () {
|
|
console.log(arguments);
|
|
};
|
|
} else {
|
|
debuglog = function () {};
|
|
}
|
|
|
|
// トルコロケールで i の小文字変換が期待と異なる件に対する W/A
|
|
var toUpper = function (s) {
|
|
return s.toUpperCase();
|
|
};
|
|
|
|
if ("I" !== "i".toUpperCase()) {
|
|
// トルコ用
|
|
toUpper = function (s) {
|
|
return s.replace(/[A-Z]/g, function (ch) {
|
|
return String.fromCharCode(ch.charCodeAt(0) & ~32);
|
|
});
|
|
};
|
|
}
|
|
|
|
var _Game_Interpreter_pluginCommand =
|
|
Game_Interpreter.prototype.pluginCommand;
|
|
Game_Interpreter.prototype.pluginCommand = function (command, args) {
|
|
_Game_Interpreter_pluginCommand.call(this, command, args);
|
|
|
|
if (command !== Const.pluginCommandCode) {
|
|
return;
|
|
}
|
|
|
|
// TODO: 商品の個別補充
|
|
|
|
switch (args[0]) {
|
|
case "apply": // 在庫情報の呼び出し (inventoryId)
|
|
if (args[1] == null) {
|
|
console.error(
|
|
"[%1 %2] Inventory ID is not specified.".format(
|
|
Const.pluginCommandCode,
|
|
args[0]
|
|
)
|
|
);
|
|
} else {
|
|
$gameTemp.nextInventoryId = args[1];
|
|
}
|
|
break;
|
|
|
|
case "supplySpeed": // 補充速度の変更 (inventoryId speed)
|
|
if (isNaN(args[2])) {
|
|
console.error(
|
|
"[%1 %2] Invalid speed (%3).".format(
|
|
Const.pluginCommandCode,
|
|
args[0],
|
|
args[2]
|
|
)
|
|
);
|
|
} else {
|
|
// インベントリ未作成の場合は自動的に作成される
|
|
var speed = Number(args[2]);
|
|
$gameSystem.getInventoryById(args[1]).setSupplySpeed();
|
|
}
|
|
break;
|
|
|
|
case "restockAll": // 在庫の完全補充 (inventoryId)
|
|
if ($gameSystem.existsInventory(args[1])) {
|
|
$gameSystem.getInventoryById(args[1]).initializeStock();
|
|
} else {
|
|
console.log(
|
|
'[%1 %2] Inventory "%3" is not exist.'.format(
|
|
Const.pluginCommandCode,
|
|
args[0],
|
|
args[1]
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
|
|
case "resetAll": // 全ショップの在庫情報初期化
|
|
$gameSystem.clearInventories();
|
|
break;
|
|
|
|
default:
|
|
// 不明なコマンド
|
|
console.error(
|
|
"[%1 %2] Unknown command.".format(Const.pluginCommandCode, args[0])
|
|
);
|
|
break;
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Item
|
|
|
|
/**
|
|
* 同一のアイテムであるか
|
|
*/
|
|
function isSameItem(item1, item2) {
|
|
if (item1.id !== item2.id) {
|
|
return false;
|
|
}
|
|
|
|
var result =
|
|
(DataManager.isItem(item1) && DataManager.isItem(item2)) ||
|
|
(DataManager.isWeapon(item1) && DataManager.isWeapon(item2)) ||
|
|
(DataManager.isArmor(item1) && DataManager.isArmor(item2));
|
|
|
|
if (KMS.imported["AbilityOrb"]) {
|
|
result |=
|
|
DataManager.isAbilityOrb(item1) && DataManager.isAbilityOrb(item2);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 在庫メモの解析
|
|
*/
|
|
function parseNotesForStock(item) {
|
|
var note = item.meta["kms_shop_stock"];
|
|
if (note == null) {
|
|
return;
|
|
}
|
|
|
|
var opts = note.replace(/\s+/g, "").split(/,/);
|
|
if (!opts || opts.length < 2) {
|
|
return;
|
|
}
|
|
|
|
if (isNaN(opts[0])) {
|
|
console.error("%1: Invalid stock count".format(item.name));
|
|
return;
|
|
}
|
|
|
|
if (isNaN(opts[1])) {
|
|
console.error("%1: Invalid supply interval".format(item.name));
|
|
return;
|
|
}
|
|
|
|
item.shopStockCountMax = parseInt(opts[0]);
|
|
item.shopStockSupplyInterval = parseInt(opts[1]);
|
|
|
|
if (opts.length >= 3) {
|
|
// 補充モードの判定 (不正なモードの場合はプレイ時間にフォールバック)
|
|
var modeSymbol = toUpper(opts[2] || "T");
|
|
if (SupplyModeSymbol[modeSymbol] != null) {
|
|
item.shopStockSupplyMode = SupplyModeSymbol[modeSymbol];
|
|
} else {
|
|
console.error("%1: Invalid supply mode".format(item.name));
|
|
item.shopStockSupplyMode = SupplyMode.playtime;
|
|
}
|
|
} else {
|
|
// モード省略時はプレイ時間扱い
|
|
item.shopStockSupplyMode = SupplyMode.playtime;
|
|
}
|
|
|
|
debuglog(
|
|
"%1: Max=%2, Interval=%3, Mode=%4".format(
|
|
item.name,
|
|
item.shopStockCountMax,
|
|
item.shopStockSupplyInterval,
|
|
item.shopStockSupplyMode
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 在庫上限の取得
|
|
*/
|
|
function getStockMax(item) {
|
|
return item.shopStockCountMax;
|
|
}
|
|
|
|
/**
|
|
* 補充間隔の取得
|
|
*/
|
|
function getSupplyInterval(item) {
|
|
return item.shopStockSupplyInterval;
|
|
}
|
|
|
|
/**
|
|
* 補充モードの取得
|
|
*/
|
|
function getSupplyMode(item) {
|
|
return item.shopStockSupplyMode;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// DataManager
|
|
|
|
var _DataManager_onLoad = DataManager.onLoad;
|
|
DataManager.onLoad = function (object) {
|
|
_DataManager_onLoad.call(this, object);
|
|
|
|
// 在庫設定の解析
|
|
if (
|
|
object === $dataItems ||
|
|
object === $dataWeapons ||
|
|
object === $dataArmors ||
|
|
(KMS.imported["AbilityOrb"] && object === $dataKmsAbilityOrbs)
|
|
) {
|
|
for (var i = 0; i < object.length; i++) {
|
|
var obj = object[i];
|
|
if (obj != null) {
|
|
parseNotesForStock(obj);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_Temp
|
|
|
|
/**
|
|
* 次回呼び出す在庫管理情報の ID
|
|
*
|
|
* @property nextInventoryId
|
|
* @type String
|
|
*/
|
|
Object.defineProperty(Game_Temp.prototype, "nextInventoryId", {
|
|
get: function () {
|
|
return this._nextInventoryId;
|
|
},
|
|
set: function (value) {
|
|
this._nextInventoryId = value;
|
|
},
|
|
configurable: true,
|
|
});
|
|
|
|
var _Game_Temp_initialize = Game_Temp.prototype.initialize;
|
|
Game_Temp.prototype.initialize = function () {
|
|
_Game_Temp_initialize.call(this);
|
|
|
|
this._nextInventoryId = null;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_System
|
|
|
|
var _Game_System_initialize = Game_System.prototype.initialize;
|
|
Game_System.prototype.initialize = function () {
|
|
_Game_System_initialize.call(this);
|
|
|
|
this.clearInventories();
|
|
};
|
|
|
|
/**
|
|
* 指定 ID に対応する店舗在庫が存在するか
|
|
*/
|
|
Game_System.prototype.existsInventory = function (id) {
|
|
this._inventories = this._inventories || {};
|
|
return this._inventories[id] != null;
|
|
};
|
|
|
|
/**
|
|
* 指定 ID に対応する店舗在庫を取得
|
|
*/
|
|
Game_System.prototype.getInventoryById = function (id) {
|
|
if (!this.existsInventory(id)) {
|
|
this._inventories[id] = new Game_ShopInventory(id);
|
|
}
|
|
|
|
return this._inventories[id];
|
|
};
|
|
|
|
/**
|
|
* 店舗在庫の全クリア
|
|
*/
|
|
Game_System.prototype.clearInventories = function () {
|
|
this._inventories = {};
|
|
this._inventorySupplier = new Game_ShopInventorySupplier();
|
|
};
|
|
|
|
/**
|
|
* 在庫補充スケジュールの登録
|
|
*/
|
|
Game_System.prototype.registerInventorySupplySchedule = function (
|
|
inventoryId,
|
|
item
|
|
) {
|
|
if (!this._inventorySupplier) {
|
|
this._inventorySupplier = new Game_ShopInventorySupplier();
|
|
}
|
|
|
|
var schedule = new Game_ShopSupplySchedule(inventoryId, item);
|
|
this._inventorySupplier.register(schedule);
|
|
};
|
|
|
|
/**
|
|
* 在庫補充スケジュールの更新
|
|
*/
|
|
Game_System.prototype.updateInventorySupplier = function () {
|
|
if (!this._inventorySupplier) {
|
|
this._inventorySupplier = new Game_ShopInventorySupplier();
|
|
}
|
|
|
|
this._inventorySupplier.update();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_ShopInventory
|
|
//
|
|
// 店舗の在庫を管理するクラス
|
|
|
|
Object.defineProperties(Game_ShopInventory.prototype, {
|
|
id: {
|
|
get: function () {
|
|
return this._id;
|
|
},
|
|
configurable: true,
|
|
},
|
|
supplySpeed: {
|
|
get: function () {
|
|
return this._supplySpeed;
|
|
},
|
|
configurable: true,
|
|
},
|
|
});
|
|
|
|
Game_ShopInventory.prototype.initialize = function (id) {
|
|
this._id = id;
|
|
this._supplySpeed = 1;
|
|
|
|
this.initializeStock();
|
|
};
|
|
|
|
/**
|
|
* コンテナの初期化
|
|
*/
|
|
Game_ShopInventory.prototype.initializeStock = function (item) {
|
|
this._itemStock = {};
|
|
this._weaponStock = {};
|
|
this._armorStock = {};
|
|
|
|
this._abilityOrbStock = {};
|
|
};
|
|
|
|
/**
|
|
* 商品のコンテナを取得
|
|
*/
|
|
Game_ShopInventory.prototype.itemContainer = function (item) {
|
|
if (!item) {
|
|
return null;
|
|
} else if (DataManager.isItem(item)) {
|
|
return this._itemStock;
|
|
} else if (DataManager.isWeapon(item)) {
|
|
return this._weaponStock;
|
|
} else if (DataManager.isArmor(item)) {
|
|
return this._armorStock;
|
|
} else if (KMS.imported["AbilityOrb"] && DataManager.isAbilityOrb(item)) {
|
|
return this._abilityOrbStock;
|
|
} else {
|
|
console.error("Game_ShopInventory: Invalid item type");
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 商品の補充速度を設定
|
|
*/
|
|
Game_ShopInventory.prototype.setSupplySpeed = function (speed) {
|
|
this._supplySpeed = Math.max(speed, 0);
|
|
};
|
|
|
|
/**
|
|
* 商品の補充間隔を取得
|
|
*/
|
|
Game_ShopInventory.prototype.getSupplyInterval = function (item) {
|
|
return Math.max(Math.floor(getSupplyInterval(item) * this._supplySpeed), 0);
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数を取得
|
|
*/
|
|
Game_ShopInventory.prototype.getStock = function (item) {
|
|
if (!this.isStockManaged(item)) {
|
|
// 在庫管理外なら常に MAX 扱い
|
|
return $gameParty.maxItems(item);
|
|
}
|
|
|
|
var stock = this.itemContainer(item);
|
|
if (stock[item.id] == null) {
|
|
// 初回参照時は在庫をフルにする
|
|
stock[item.id] = this.getStockMax(item);
|
|
}
|
|
|
|
return stock[item.id];
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数を設定
|
|
*/
|
|
Game_ShopInventory.prototype.setStock = function (item, number) {
|
|
if (!this.isStockManaged(item)) {
|
|
return;
|
|
}
|
|
|
|
var stock = this.itemContainer(item);
|
|
if (stock != null) {
|
|
stock[item.id] = number.clamp(0, this.getStockMax(item));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 商品が在庫管理対象か
|
|
*/
|
|
Game_ShopInventory.prototype.isStockManaged = function (item) {
|
|
return getStockMax(item) != null;
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数上限を取得
|
|
*/
|
|
Game_ShopInventory.prototype.getStockMax = function (item) {
|
|
// TODO: 店ごとに上限を指定できるようにしたい
|
|
return this.isStockManaged(item)
|
|
? getStockMax(item)
|
|
: $gameParty.maxItems(item);
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数が上限か
|
|
*/
|
|
Game_ShopInventory.prototype.isStockFull = function (item) {
|
|
return this.getStock(item) >= this.getStockMax(item);
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数があるか
|
|
*/
|
|
Game_ShopInventory.prototype.isStockAvailable = function (item) {
|
|
return this.getStock(item) > 0;
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数を増やす
|
|
*/
|
|
Game_ShopInventory.prototype.gainStock = function (item, amount) {
|
|
var prevStock = this.getStock(item);
|
|
this.setStock(item, prevStock + amount);
|
|
return this.getStock(item) - prevStock;
|
|
};
|
|
|
|
/**
|
|
* 商品の在庫数を減らす
|
|
*/
|
|
Game_ShopInventory.prototype.loseStock = function (item, amount) {
|
|
return -this.gainStock(item, -amount);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_ShopSupplySchedule
|
|
//
|
|
// 店舗の在庫補充タイミングを制御するクラス
|
|
|
|
Object.defineProperties(Game_ShopSupplySchedule.prototype, {
|
|
inventoryId: {
|
|
get: function () {
|
|
return this._inventoryId;
|
|
},
|
|
configurable: true,
|
|
},
|
|
item: {
|
|
get: function () {
|
|
return this._item.object();
|
|
},
|
|
configurable: true,
|
|
},
|
|
});
|
|
|
|
Game_ShopSupplySchedule.prototype.initialize = function (inventoryId, item) {
|
|
this._inventoryId = inventoryId;
|
|
this._item = new Game_Item(item);
|
|
this._startCount = -1;
|
|
};
|
|
|
|
/**
|
|
* 補充間隔の取得
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.getSupplyInterval = function () {
|
|
var inventory = $gameSystem.getInventoryById(this.inventoryId);
|
|
return inventory.getSupplyInterval(this.item);
|
|
};
|
|
|
|
/**
|
|
* 有効なスケジュールであるか
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.isValid = function () {
|
|
return this._startCount >= 0;
|
|
};
|
|
|
|
/**
|
|
* 補充を行うか
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.canSupply = function () {
|
|
return this.getSupplyInterval() > 0;
|
|
};
|
|
|
|
/**
|
|
* 同一と見なせるスケジュールであるか
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.logicallyEqual = function (rhs) {
|
|
return (
|
|
rhs != null &&
|
|
this.isValid() &&
|
|
this.inventoryId === rhs.inventoryId &&
|
|
isSameItem(this.item, rhs.item)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 補充判定用カウントの現在値を取得
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.getCurrentCountForSupply = function () {
|
|
switch (getSupplyMode(this.item)) {
|
|
case SupplyMode.playtime:
|
|
return $gameSystem.playtime();
|
|
case SupplyMode.battleCount:
|
|
return $gameSystem.battleCount();
|
|
|
|
default:
|
|
console.error("Invalid supply mode");
|
|
return -1;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 補充可能な個数を取得
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.getSuppliableCount = function () {
|
|
if (!this.isValid() || !this.canSupply()) {
|
|
return 0;
|
|
}
|
|
|
|
var currentCount = this.getCurrentCountForSupply();
|
|
if (currentCount < 0) {
|
|
// 異常なモード設定
|
|
this.stop();
|
|
return;
|
|
}
|
|
|
|
// 現在のカウントが開始時のカウントより減っている場合、
|
|
// 値が変更されたと見なしてカウントを初期化
|
|
if (currentCount < this._startCount) {
|
|
this._startCount = currentCount;
|
|
}
|
|
|
|
return Math.floor(
|
|
(currentCount - this._startCount) / this.getSupplyInterval()
|
|
);
|
|
};
|
|
|
|
/**
|
|
* スケジュールの開始
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.start = function () {
|
|
if (!this.canSupply()) {
|
|
debuglog("%1 is not necessary to supply.".format(this.item.name));
|
|
return;
|
|
}
|
|
|
|
var currentCount = this.getCurrentCountForSupply();
|
|
if (currentCount >= 0) {
|
|
this._startCount = currentCount;
|
|
} else {
|
|
// 無効なスケジュール
|
|
this.stop();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* スケジュールの停止
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.stop = function () {
|
|
this._startCount = -1;
|
|
debuglog(
|
|
"Schedule [%1:%2] stopped".format(this.inventoryId, this.item.name)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 在庫補充処理
|
|
*/
|
|
Game_ShopSupplySchedule.prototype.supply = function () {
|
|
if (!this.canSupply()) {
|
|
this.stop();
|
|
return;
|
|
}
|
|
|
|
var count = this.getSuppliableCount();
|
|
if (count <= 0) {
|
|
return;
|
|
}
|
|
|
|
var item = this.item;
|
|
var inventory = $gameSystem.getInventoryById(this.inventoryId);
|
|
inventory.gainStock(item, count);
|
|
|
|
debuglog("%1: Supplied %2".format(item.name, count));
|
|
|
|
if (inventory.isStockFull(item)) {
|
|
this.stop();
|
|
} else {
|
|
// 補充した分カウンタを進める
|
|
this._startCount += count * this.getSupplyInterval();
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Game_ShopInventorySupplier
|
|
//
|
|
// 店舗の在庫補充を制御するクラス
|
|
|
|
Game_ShopInventorySupplier.prototype.initialize = function () {
|
|
this._schedules = [];
|
|
};
|
|
|
|
/**
|
|
* 既に同一アイテムのスケジュールが登録済みか
|
|
*/
|
|
Game_ShopInventorySupplier.prototype.isRegistered = function (schedule) {
|
|
return this._schedules.some(function (s) {
|
|
return s.logicallyEqual(schedule);
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* スケジュール登録
|
|
*/
|
|
Game_ShopInventorySupplier.prototype.register = function (schedule) {
|
|
if (this.isRegistered(schedule)) {
|
|
return;
|
|
}
|
|
|
|
schedule.start();
|
|
if (schedule.isValid()) {
|
|
this._schedules.push(schedule);
|
|
debuglog("Schedule for %1 is registered".format(schedule.item.name));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 指定したスケジュールを削除
|
|
*/
|
|
Game_ShopInventorySupplier.prototype.remove = function (schedule) {
|
|
this._schedules = this._schedules.filter(function (s) {
|
|
return !s.logicallyEqual(schedule);
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* 停止済みのスケジュールを削除
|
|
*/
|
|
Game_ShopInventorySupplier.prototype.removeStopped = function () {
|
|
this._schedules = this._schedules.filter(function (s) {
|
|
return s.isValid();
|
|
}, this);
|
|
};
|
|
|
|
/**
|
|
* 在庫の更新
|
|
*/
|
|
Game_ShopInventorySupplier.prototype.update = function () {
|
|
this._schedules.forEach(function (s) {
|
|
s.supply();
|
|
}, this);
|
|
|
|
this.removeStopped();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_Base
|
|
|
|
/**
|
|
* 店舗在庫数の描画
|
|
*/
|
|
Window_Base.prototype.drawShopStockNumber = function (
|
|
item,
|
|
inventory,
|
|
x,
|
|
y,
|
|
width
|
|
) {
|
|
if (!inventory.isStockManaged(item)) {
|
|
return;
|
|
}
|
|
|
|
var valueWidth = this.textWidth("000");
|
|
var slashWidth = this.textWidth("/");
|
|
var captionWidth = this.textWidth(Params.stockCaption) + 8;
|
|
|
|
this.changeTextColor(this.systemColor());
|
|
this.drawText(Params.stockCaption, x, y, captionWidth);
|
|
|
|
var numX = x + width - (valueWidth * 2 + slashWidth);
|
|
var stock = inventory.getStock(item);
|
|
var stockMax = inventory.getStockMax(item);
|
|
this.resetTextColor();
|
|
this.drawText(stock, numX, y, valueWidth, "right");
|
|
this.drawText("/", numX + valueWidth, y, slashWidth, "right");
|
|
this.drawText(
|
|
stockMax,
|
|
numX + valueWidth + slashWidth,
|
|
y,
|
|
valueWidth,
|
|
"right"
|
|
);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_ShopBuy
|
|
|
|
var _Window_ShopBuy_isEnabled = Window_ShopBuy.prototype.isEnabled;
|
|
Window_ShopBuy.prototype.isEnabled = function (item) {
|
|
var enabled = _Window_ShopBuy_isEnabled.call(this, item);
|
|
|
|
if (this._inventory) {
|
|
return enabled && this._inventory.isStockAvailable(item);
|
|
} else {
|
|
return enabled;
|
|
}
|
|
};
|
|
|
|
var _Window_ShopBuy_drawItem = Window_ShopBuy.prototype.drawItem;
|
|
Window_ShopBuy.prototype.drawItem = function (index) {
|
|
var item = this._data[index];
|
|
if (this._inventory && !this._inventory.isStockAvailable(item)) {
|
|
// 売り切れ表示
|
|
var rect = this.itemRect(index);
|
|
var priceWidth = 96;
|
|
rect.width -= this.textPadding();
|
|
this.changePaintOpacity(this.isEnabled(item));
|
|
this.drawItemName(item, rect.x, rect.y, rect.width - priceWidth);
|
|
this.drawText(
|
|
Params.soldOutText,
|
|
rect.x + rect.width - priceWidth,
|
|
rect.y,
|
|
priceWidth,
|
|
"right"
|
|
);
|
|
this.changePaintOpacity(true);
|
|
} else {
|
|
_Window_ShopBuy_drawItem.call(this, index);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 在庫管理オブジェクトの設定
|
|
*/
|
|
Window_ShopBuy.prototype.setInventory = function (inventory) {
|
|
this._inventory = inventory;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_ShopNumber
|
|
|
|
var _Window_ShopNumber_refresh = Window_ShopNumber.prototype.refresh;
|
|
Window_ShopNumber.prototype.refresh = function () {
|
|
_Window_ShopNumber_refresh.call(this);
|
|
|
|
if (!Params.showStockInStatus) {
|
|
this.drawStockNumber();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 在庫数の描画
|
|
*/
|
|
Window_ShopNumber.prototype.drawStockNumber = function () {
|
|
if (!this._item || !this._inventory) {
|
|
return;
|
|
}
|
|
|
|
var valueWidth = this.textWidth("000");
|
|
var slashWidth = this.textWidth("/");
|
|
var captionWidth =
|
|
this.textWidth(Params.stockCaption) + this.textPadding() * 2 + 8;
|
|
var width = captionWidth + valueWidth * 2 + slashWidth;
|
|
var x = this.contents.width - width - this.textPadding() * 2;
|
|
var y = this.stockY();
|
|
this.drawShopStockNumber(this._item, this._inventory, x, y, width);
|
|
};
|
|
|
|
/**
|
|
* 在庫数 Y 座標
|
|
*/
|
|
Window_ShopNumber.prototype.stockY = function () {
|
|
return this.itemY() - this.lineHeight() * 2;
|
|
};
|
|
|
|
/**
|
|
* 在庫管理オブジェクトの設定
|
|
*/
|
|
Window_ShopNumber.prototype.setInventory = function (inventory) {
|
|
this._inventory = inventory;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Window_ShopStatus
|
|
|
|
var _Windowe_ShopStatus_refresh = Window_ShopStatus.prototype.refresh;
|
|
Window_ShopStatus.prototype.refresh = function () {
|
|
_Windowe_ShopStatus_refresh.call(this);
|
|
|
|
if (Params.showStockInStatus) {
|
|
var x = this.textPadding();
|
|
this.drawStockNumber(x, this.lineHeight());
|
|
}
|
|
};
|
|
|
|
/**
|
|
* 在庫数の描画
|
|
*/
|
|
Window_ShopStatus.prototype.drawStockNumber = function (x, y) {
|
|
if (!this._item || !this._inventory) {
|
|
return;
|
|
}
|
|
|
|
var width = this.contents.width - this.textPadding() * 2;
|
|
this.drawShopStockNumber(this._item, this._inventory, x, y, width);
|
|
};
|
|
|
|
/**
|
|
* 在庫管理オブジェクトの設定
|
|
*/
|
|
Window_ShopStatus.prototype.setInventory = function (inventory) {
|
|
this._inventory = inventory;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Scene_Shop
|
|
|
|
var _Scene_Shop_prepare = Scene_Shop.prototype.prepare;
|
|
Scene_Shop.prototype.prepare = function (goods, purchaseOnly) {
|
|
_Scene_Shop_prepare.call(this, goods, purchaseOnly);
|
|
|
|
// 在庫補充
|
|
$gameSystem.updateInventorySupplier();
|
|
|
|
// 予約されている在庫管理情報を呼び出す
|
|
var id = $gameTemp.nextInventoryId;
|
|
if (id != null) {
|
|
this._inventory = $gameSystem.getInventoryById(id);
|
|
$gameTemp.nextInventoryId = null;
|
|
} else {
|
|
this._inventory = null;
|
|
}
|
|
};
|
|
|
|
var _Scene_Shop_createBuyWindow = Scene_Shop.prototype.createBuyWindow;
|
|
Scene_Shop.prototype.createBuyWindow = function () {
|
|
_Scene_Shop_createBuyWindow.call(this);
|
|
|
|
this._buyWindow.setInventory(this._inventory);
|
|
};
|
|
|
|
var _Scene_Shop_createNumberWindow = Scene_Shop.prototype.createNumberWindow;
|
|
Scene_Shop.prototype.createNumberWindow = function () {
|
|
_Scene_Shop_createNumberWindow.call(this);
|
|
|
|
this._numberWindow.setInventory(this._inventory);
|
|
};
|
|
|
|
var _Scene_Shop_createStatusWindow = Scene_Shop.prototype.createStatusWindow;
|
|
Scene_Shop.prototype.createStatusWindow = function () {
|
|
_Scene_Shop_createStatusWindow.call(this);
|
|
|
|
this._statusWindow.setInventory(this._inventory);
|
|
};
|
|
|
|
var _Scene_Shop_maxBuy = Scene_Shop.prototype.maxBuy;
|
|
Scene_Shop.prototype.maxBuy = function () {
|
|
var count = _Scene_Shop_maxBuy.call(this);
|
|
|
|
if (this._inventory) {
|
|
// 既に所持金に応じた cap がかかっているので、在庫数と比較して少ない方を採用
|
|
count = Math.min(count, this._inventory.getStock(this._item));
|
|
}
|
|
|
|
return count;
|
|
};
|
|
|
|
var _Scene_Shop_doBuy = Scene_Shop.prototype.doBuy;
|
|
Scene_Shop.prototype.doBuy = function (number) {
|
|
_Scene_Shop_doBuy.call(this, number);
|
|
|
|
// 在庫を減らす
|
|
if (this._inventory) {
|
|
this._inventory.loseStock(this._item, number);
|
|
|
|
// 在庫補充を開始
|
|
$gameSystem.registerInventorySupplySchedule(
|
|
this._inventory.id,
|
|
this._item
|
|
);
|
|
}
|
|
};
|
|
|
|
var _Scene_Shop_doSell = Scene_Shop.prototype.doSell;
|
|
Scene_Shop.prototype.doSell = function (number) {
|
|
_Scene_Shop_doSell.call(this, number);
|
|
|
|
// 買戻し用に在庫を増やす
|
|
if (this._inventory) {
|
|
this._inventory.gainStock(this._item, number);
|
|
}
|
|
};
|
|
})();
|