1108 lines
27 KiB
JavaScript
1108 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);
|
|
}
|
|
};
|
|
|
|
})();
|