slave-princess-charlotte/data/Plugin/ExtraConfigSkill.js
2025-10-12 13:17:46 -05:00

884 lines
24 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*--------------------------------------------------------------------------
スキルの発動条件に関して詳細な設定が行えるようになります。
使用方法:
スキルのカスタムパラメータに{EC_NowHP:'0-50%'}のように設定します。
(詳しくは別紙参照)
※必ずTemporaryDataVirtualAttack.jsとセットで入れてください。
作成者:
o-to
更新履歴:
2015/05/30:新規作成
2015/06/15:発動条件の追加、このスクリプトに関する
カスタムパラメータが未設定なら公式の関数を呼ぶように修正
2015/11/09:公式の定義削除により、表示がundefinedになっていた箇所を修正
2015/12/06:コマンドスキル追加、スキル発動回数制限等の条件を作成
2016/01/11:
EC_SkillCheck.isCheckTriggerCountの戻り値を発動回数制限に引っかからなければtrue、
引っかかったらfalseにするように修正。
EPとFPの現在値判定と消費EPと消費FPを設定できるように追加。
コマンドスキルの表示条件にEPとFP、ターン数を追加。
公式1.048で動かない個所があるため対応。
熟練度と体格が公式に組み込まれたため、EC_OverStatusとEC_UnderStatusのアルゴリズム変更。
HP以外のパラメータの範囲条件を行うための設定、EC_NowStatusとEC_OpponentNowStatusを追加。
EC_NowHPはいずれ廃止されるため、今後はEC_NowStatusに設定をお願いします。
今後、パラメータが追加してもHPやMPのような最大値と現在値が別々に存在するもの以外なら
命名規則が違うなどの例外が無い限りは、
本スクリプトをいじらなくてもEC_NowStatusやEC_OpponentNowStatus、
EC_OverStatus、EC_UnderStatusで追加パラメータの指定が可能になるようアルゴリズム変更。
2016/04/24:
処理の大部分をExtraConfigBase.jsに移動
2016/08/29:
発動率と相手の見切りスキル無効化に関する設定を行うと
エディタの有効相手の設定を無視してしまう不具合を修正。
2017/02/05:
forループ用に使用している変数の宣言忘れしている箇所を修正
※同じように宣言忘れしている別スクリプトがあった場合、意図せぬ動作が起こるため
--------------------------------------------------------------------------*/
(function() {
// マップ型回数制限のタイプ
OT_SkillFusionType = {
NORMAL: 'NORMAL'
, ATTACK: 'ATTACK'
, ALL : 'ALL'
};
// スキル回数制限タイプ
OT_SkillTriggerCountType = {
BATTLE :'BATTLE'
, TURN :'TURN'
, MAP :'MAP'
, ALL :'ALL'
};
// コマンドスキルのタイプ
OT_SkillCommandType = {
ATTACK: 'ATTACK'
, WAIT : 'WAIT'
};
// マップ型回数制限のタイプ
OT_SkillTriggerMapType = {
MAP : 'MAP'
, COMMAND : 'COMMAND'
};
// コマンドスキル回数のセット
OT_CommandSkillSet = function() {
return {
BATTLE : 0
, TURN : 0
, MAP : 0
};
};
var alias1 = SkillRandomizer._isSkillInvokedInternal;
SkillRandomizer._isSkillInvokedInternal = function(active, passive, skill)
{
// 渡されたデータが公式関数内でエラーが起こらないか一旦チェック
var result = alias1.call(this, active, passive, skill);
var Percent = 0;
var type = skill.getInvocationType();
var value = skill.getInvocationValue();
var DefaultPercent = 0;
var Param = 0;
// スキル名の表示
EC_Putlog('スキル名:'+skill.getName(), skill);
// コマンド型スキルか確認
if( EC_SkillCheck.SkillCheckCommand(active, skill) == false )
{
return false;
}
// スキル発動条件を満たしているかチェック
if( EC_EnableManager.SkillCheckActivity(active, passive, skill) == false )
{
return false;
}
//---下記から発動率の補正---------------------------------------
//--- 発動率の補正と見切りに関する設定を行っていない時は
//--- 公式の関数を呼び出した結果をそのまま返す
if( skill.custom.EC_DefaultPercent == null
&& skill.custom.EC_Correction == null
&& skill.custom.EC_ScopePercent == null
&& skill.custom.EC_isAbandonIgnore == null
)
{
EC_Putlog('発動率の補正無し', skill);
//ログ用の確率を取得
if (type === InvocationType.ABSOLUTE) {
Percent = value;
}
else if (type === InvocationType.LV) {
Percent = active.getLv() * value;
}
else {
Percent = active.getParamValue(type) * value;
}
EC_Putlog('発動確率:' + Percent + '%', skill);
}
else
{
// 発動率周りの設定がされてる場合は補正する
// 有効相手のチェック
if (!skill.getTargetAggregation().isCondition(passive)) {
EC_Putlog('有効相手以外のため発動不可', skill);
return false;
}
//--- 見切り無効タイプのスキルか確認
if( skill.custom.EC_isAbandonIgnore == null || skill.custom.EC_isAbandonIgnore == false )
{
// 相手がスキルを無効化できる場合は、スキルを発動しない
if (SkillControl.getBattleSkillFromFlag(passive, active, SkillType.INVALID, InvalidFlag.SKILL) !== null) {
EC_Putlog('相手が見切りを持ってるため発動不可', skill);
return false;
}
}
else
{
EC_Putlog('相手の見切り無効のスキル', skill);
}
// デフォルト確率
if( skill.custom.EC_DefaultPercent != null )
{
DefaultPercent = skill.custom.EC_DefaultPercent;
EC_Putlog('デフォルト発動率:'+DefaultPercent, skill);
}
// 補正値
if( skill.custom.EC_Correction != null )
{
//実際のスキルの発動率は小数点以下は切捨てになります
value = value * skill.custom.EC_Correction;
EC_Putlog('補正値:'+skill.custom.EC_Correction, skill);
EC_Putlog('補正後係数:'+value, skill);
}
//パラメーターから確率を取得
if (type === InvocationType.HPDOWN) {
n = value / 100;
hp = ParamBonus.getMhp(unit) * n;
result = unit.getHp() <= hp;
}
else
{
if (type === InvocationType.ABSOLUTE) {
Percent = value + DefaultPercent;
}
else if (type === InvocationType.LV) {
Percent = active.getLv() * value + DefaultPercent;
}
else {
if (root.getUserExtension().isSkillInvocationBonusEnabled()) {
Percent = ParamBonus.getBonus(active, type) * value + DefaultPercent;
}
else {
Percent = active.getParamValue(type) * value + DefaultPercent;
}
}
// 確率範囲
if( skill.custom.EC_ScopePercent != null )
{
var str = skill.custom.EC_ScopePercent;
EC_Putlog('確率範囲:' + skill.custom.EC_ScopePercent, skill);
var regex = /^([0-9]+)\-([0-9]+)\%$/;
if (str.match(regex))
{
var min = parseInt(RegExp.$1);
var max = parseInt(RegExp.$2);
if(Percent < min)
{
Percent = min;
}
if(Percent > max)
{
Percent = max;
}
}
}
EC_Putlog('発動確率(小数点四捨五入):' + Math.round( Percent ) + '%', skill);
result = Probability.getProbability(Percent);
}
}
if( result == true )
{
EC_SkillCheck.TriggerCountUp(active, skill);
EC_SkillCheck.UseSkillExpendData(active, skill);
}
EC_Putlog('スキル発動:' + result, skill);
return result;
};
EC_SkillCheck = {
// スキル発動回数をカウント
TriggerCountUp: function(active, skill) {
var id = skill.getId();
if( skill.custom.EC_TriggerCountBattle == null && skill.custom.EC_TriggerCountTurn == null && skill.custom.EC_TriggerCountMap == null )
{
return false;
}
// 発動回数の初期化
if( active.custom.tmpSkillTriggerCount == null )
{
active.custom.tmpSkillTriggerCount = Array();
}
if( active.custom.tmpSkillTriggerCount[id] == null )
{
active.custom.tmpSkillTriggerCount[id] = OT_CommandSkillSet();
}
// 発動回数カウント
active.custom.tmpSkillTriggerCount[id].BATTLE++;
active.custom.tmpSkillTriggerCount[id].TURN++;
// マップ型回数制限がスキル発動時で回数が減るタイプの場合
if( skill.custom.EC_TriggerCountMap != null )
{
if( skill.custom.EC_TriggerCountMap[1] == OT_SkillTriggerMapType.MAP )
{
active.custom.tmpSkillTriggerCount[id].MAP++;
}
}
},
// スキル発動回数をカウント(コマンド用)
TriggerCountUpCommand: function(active, id) {
var list = DataVariable.Sdb.getList();
if( id == null )
{
return ;
}
var skill = list.getDataFromId(id);
if( skill.custom.EC_TriggerCountMap != null )
{
if( skill.custom.EC_TriggerCountMap[1] == OT_SkillTriggerMapType.COMMAND )
{
// 発動回数の初期化
if( active.custom.tmpSkillTriggerCount == null )
{
active.custom.tmpSkillTriggerCount = Array();
}
if( active.custom.tmpSkillTriggerCount[id] == null )
{
active.custom.tmpSkillTriggerCount[id] = OT_CommandSkillSet();
}
active.custom.tmpSkillTriggerCount[id].MAP++;
}
}
},
// スキル発動回数が発動可能回数を超えていない事をチェック
isCheckTriggerCount: function(active, skill) {
var id = skill.getId();
if( skill.custom.EC_TriggerCountBattle == null && skill.custom.EC_TriggerCountTurn == null && skill.custom.EC_TriggerCountMap == null )
{
return true;
}
// デバッグ用メッセージ作成
var msg = '発動可能回数';
// 戦闘
if( skill.custom.EC_TriggerCountBattle != null )
{
msg += ' 戦闘:' + skill.custom.EC_TriggerCountBattle;
}
// ターン
if( skill.custom.EC_TriggerCountTurn != null )
{
msg += ' TURN:' + skill.custom.EC_TriggerCountTurn;
}
// マップ
if( skill.custom.EC_TriggerCountMap != null )
{
msg += ' MAP:' + skill.custom.EC_TriggerCountMap[0];
}
// ここから発動条件チェック
if( active.custom.tmpSkillTriggerCount == null )
{
return true;
}
if( active.custom.tmpSkillTriggerCount[id] == null )
{
return true;
}
var tmp = active.custom.tmpSkillTriggerCount[id];
EC_Putlog(msg, skill);
EC_Putlog('発動回数 戦闘:' + tmp.BATTLE + ' TURN:' + tmp.TURN + ' MAP:' + tmp.MAP, skill);
// 戦闘
if( skill.custom.EC_TriggerCountBattle != null )
{
if( skill.custom.EC_TriggerCountBattle <= tmp.BATTLE )
{
return false;
}
}
// ターン
if( skill.custom.EC_TriggerCountTurn != null )
{
if( skill.custom.EC_TriggerCountTurn <= tmp.TURN )
{
return false;
}
}
// マップ
if( skill.custom.EC_TriggerCountMap != null )
{
if( skill.custom.EC_TriggerCountMap[0] <= tmp.MAP )
{
return false;
}
}
return true;
},
// スキル発動回数をリセット
ResetTriggerCount: function(unit, type) {
var length = 0;
var i = 0;
if( unit.custom.tmpSkillTriggerCount != null )
{
// マップ終了時に全ての回数をリセット
if( type == OT_SkillTriggerCountType.ALL )
{
delete unit.custom.tmpSkillTriggerCount;
//root.log(unit.getName() + 'のスキル発動回数をリセット');
return;
}
length = unit.custom.tmpSkillTriggerCount.length;
for( i=0 ; i<length ; i++ )
{
if( unit.custom.tmpSkillTriggerCount[i] != null )
{
switch(type)
{
case OT_SkillTriggerCountType.TURN :
unit.custom.tmpSkillTriggerCount[i].TURN = 0;
case OT_SkillTriggerCountType.BATTLE :
unit.custom.tmpSkillTriggerCount[i].BATTLE = 0;
break;
}
}
}
}
},
// コマンドからスキルを選択したのかを確認する
SkillCheckCommand: function(active, skill) {
// コマンド型ではない場合は素通り
if( OT_isCommandSkill(skill) == false )
{
return true;
}
EC_Putlog('コマンドから発動'+active.getName(), skill);
EC_Putlog(active.custom.tmpCommandSkillID, skill);
if( active.custom.tmpCommandSkillID == skill.getId() )
{
return true;
}
return false;
},
// コマンドスキル使用時に現在の状態から使用可を判定
isSkillCheckEnable: function(unit, skill, aryList) {
if( unit == null || skill == null )
{
return false;
}
// スキル名の表示
EC_Putlog('スキル名:'+skill.getName(), skill);
// コマンド回数が制限に引っかかっていない事を確認
if( !this.isCheckTriggerCount(unit, skill) ) return false;
// EPが使用前に一定値ある事を確認
if( !this.isUseEP(unit, skill, skill.custom.EC_UseEP)) return false;
// FPが使用前に一定値ある事を確認
if( !this.isUseFP(unit, skill, skill.custom.EC_UseFP)) return false;
// ターン数で発動できるかチェック
if( !EC_SituationCheck.isEnableTurn(skill) ) return false;
return true;
},
// 指定したステータスが範囲内である事を確認
isNowStatusInRange: function(active, passive, skill) {
var now = skill.custom.EC_NowStatus;
var opponentNow = skill.custom.EC_OpponentNowStatus;
if( now != null && active != null )
{
EC_Putlog('発動者のステータス範囲チェック', skill);
for( var key in now )
{
if( !this.isParamInRange(active, skill, key, now[key]) )
{
return false;
}
}
}
if( opponentNow != null && passive != null )
{
EC_Putlog('相手のステータス範囲チェック', skill);
for( var key in opponentNow )
{
if( !this.isParamInRange(passive, skill, key, opponentNow[key]) )
{
return false;
}
}
}
return true;
},
// パラメータが範囲内であるかチェック
isParamInRange: function(unit, skill, type, strRange) {
// パラメータが宣言されていない
if(UnitParameter[type] == 'undefined')
{
root.log(type + 'は未宣言のパラメータです。');
return 0;
}
var now = 0;
var max = 0;
var paramName = type;
switch(type)
{
// HPやEP、FPは現在値と最大値それぞれ取得する
case 'HP':
if(typeof unit.custom.tmpNowVirtualAttack == 'undefined')
{
now = unit.getHp();;
}
else
{
now = unit.custom.tmpNowVirtualAttack.hp;
}
max = ParamBonus.getMhp(unit);
break;
case 'EP':
now = OT_GetNowEP(unit) - unit.custom.tmpUseEP;
max = ParamBonus.getEp(unit);
break;
case 'FP':
now = OT_GetNowFP(unit) - unit.custom.tmpUseFP;
max = ParamBonus.getFp(unit);
break;
// HPやEP、FP以外のパラメータは最大値を成長限界値とする
case 'LV':
now = unit.getLv();
max = Miscellaneous.getMaxLv(unit);
break;
default:
now = ParamBonus.getBonus(unit, ParamType[type]);
max = UnitParameter[type].getMaxValue(unit);
paramName = UnitParameter[type].getParameterName();
break;
}
return this.isValueInRange(skill, now, max, strRange, paramName);
},
// 値が範囲内であるかチェック
isValueInRange: function(skill, nowValue, maxValue, str, paramName) {
if( str == null )
{
return true;
}
var regex = /^([0-9]+)\-([0-9]+)\%$/;
var regexNum = /^([0-9]+)\-([0-9]+)$/;
//EC_Putlog(paramName + ':' + nowValue, skill);
if (str.match(regex))
{
var min = parseInt(RegExp.$1);
var max = parseInt(RegExp.$2);
var MinPercent = Math.floor( maxValue * (min / 100) );
var MaxPercent = Math.floor( maxValue * (max / 100) );
EC_Putlog(paramName + ':' + nowValue +' 発動範囲:' + MinPercent + '' + MaxPercent + '(' + str + ')', skill);
if( nowValue < MinPercent || MaxPercent < nowValue )
{
return false;
}
}
else if(str.match(regexNum))
{
var min = parseInt(RegExp.$1);
var max = parseInt(RegExp.$2);
EC_Putlog(paramName + ':' + nowValue +' 発動範囲:' + min + '' + max, skill);
if( nowValue < min || max < nowValue )
{
return false;
}
}
return true;
},
// 消費EPが足りるかをチェック
isUseEP: function(unit, skill, value) {
if( unit == null || skill == null )
{
return false;
}
// 消費EPを確認
// 攻撃とスキルの発動どちらかしか行えないなら攻撃を優先させるようにする
if( value != null )
{
if(typeof OT_GetUseEP === 'undefined')
{
root.log('EP使用:EPシステムが未導入です');
}
else
{
var weapon = ItemControl.getEquippedWeapon(unit);
var nowEP = OT_GetNowEP(unit);
if(typeof unit.custom.tmpUseEP == 'number') {
nowEP -= unit.custom.tmpUseEP;
}
var useEP = OT_GetUseEP(unit, value);
if( OT_BeforeAttackSkill ) {
useEP += OT_GetItemUseEP(unit, weapon);
}
EC_Putlog('現EP:' + nowEP + ' 消費EP:' + useEP, skill)
if( nowEP < useEP )
{
return false;
}
}
}
return true;
},
// 消費FPが足りるかをチェック
isUseFP: function(unit, skill, value) {
if( unit == null || skill == null )
{
return false;
}
// 消費FPを確認
// 攻撃とスキルの発動どちらかしか行えないなら攻撃を優先させるようにする
if( value != null )
{
if(typeof OT_GetUseFP === 'undefined')
{
root.log('FP使用:FPシステムが未導入です');
}
else
{
var weapon = ItemControl.getEquippedWeapon(unit);
var nowFP = OT_GetNowFP(unit);
if(typeof unit.custom.tmpUseFP == 'number') {
nowFP -= unit.custom.tmpUseFP;
}
var useFP = OT_GetUseFP(unit, value);
if( OT_BeforeAttackSkill ) {
useFP += OT_GetItemUseFP(unit, weapon);
}
EC_Putlog('現FP:' + nowFP + ' 消費FP:' + useFP, skill)
if( nowFP < useFP )
{
return false;
}
}
}
return true;
},
// スキル使用時のEPとFPの消費
UseSkillExpendData: function(unit, skill) {
// EPを消費
if( skill.custom.EC_UseEP != null )
{
if(typeof OT_GetUseEP === 'undefined')
{
root.log('EP使用:EPシステムが未導入です');
}
else
{
unit.custom.tmpUseEP += OT_GetUseEP(unit, skill.custom.EC_UseEP);
}
}
// FPを消費
if( skill.custom.EC_UseFP != null )
{
if(typeof OT_GetUseFP === 'undefined')
{
root.log('FP使用:FPシステムが未導入です');
}
else
{
unit.custom.tmpUseFP += OT_GetUseFP(unit, skill.custom.EC_UseFP);
}
}
},
// フュージョン専用スキルの条件を満たしているかを確認
isFusionSkill: function(active, passive, skill) {
// 自分のフュージョンIDを確認する
if( !this.isSkillFusionID(active, skill, skill.custom.EC_FusionID) )
{
return false;
}
// 相手のフュージョンIDを確認する
if( !this.isSkillFusionID(passive, skill, skill.custom.EC_OpponentFusionID) )
{
return false;
}
return true;
},
// フュージョンタイプが指定のものかを確認する
isSkillFusionID: function(unit, skill, id) {
if(unit == null || id == null)
{
return true;
}
var data = FusionControl.getFusionData(unit);
var msg = unit.getName();
// フュージョンしてない場合flase
if( data == null )
{
EC_Putlog(msg + 'はフュージョンしていないため発動不可', skill);
return false;
}
var dataID = data.getId();
EC_Putlog(msg + 'のフュージョンID', skill);
EC_Putlog('いずれかを含めれば発動:' + id, skill);
for( var key in id )
{
if(typeof id[key] !== 'number') continue;
if(id[key] === dataID)
{
return true;
}
}
return false;
},
// 相手とのステータス差を確認
CheckStatusDiff: function(active, passive, type, value) {
var diffValue = 0;
var acValue = 0;
var psValue = 0;
// パラメータが宣言されていない
if(UnitParameter[type] == 'undefined')
{
return 0;
}
switch(type)
{
case 'LV':
acValue = active.getLv();
psValue = passive.getLv();
diffValue = acValue + value - psValue;
break;
case 'HP':
if(typeof active.custom.tmpNowVirtualAttack == 'undefined')
{
acValue = active.getHp();
psValue = passive.getHp();
}
else
{
acValue = active.custom.tmpNowVirtualAttack.hp;
psValue = passive.custom.tmpNowVirtualAttack.hp;
}
diffValue = acValue + value - psValue;
break;
case 'EP':
acValue = OT_GetNowEP(active) - active.custom.tmpUseEP;
psValue = OT_GetNowEP(passive) - passive.custom.tmpUseEP;
diffValue = acValue + value - psValue;
break;
case 'FP':
acValue = OT_GetNowFP(active) - active.custom.tmpUseFP;
psValue = OT_GetNowFP(passive) - passive.custom.tmpUseFP;
diffValue = acValue + value - psValue;
break;
default:
acValue = ParamBonus.getBonus(active, ParamType[type]);
psValue = ParamBonus.getBonus(passive, ParamType[type]);
diffValue = acValue + value - psValue;
break;
}
return diffValue;
}
};
// 発動回数制限タイプが戦闘なら、戦闘後に発動回数をリセットする
var alias2 = NormalAttackOrderBuilder._endVirtualAttack;
NormalAttackOrderBuilder._endVirtualAttack = function(virtualActive, virtualPassive)
{
alias2.call(this, virtualActive, virtualPassive);
var active = virtualActive.unitSelf;
var passive = virtualPassive.unitSelf;
EC_SkillCheck.ResetTriggerCount(active, OT_SkillTriggerCountType.BATTLE);
EC_SkillCheck.ResetTriggerCount(passive, OT_SkillTriggerCountType.BATTLE);
};
// 発動回数制限タイプがターンなら、自軍ターン開始時に発動回数をリセットする
var alias3 = TurnMarkFlowEntry.doMainAction;
TurnMarkFlowEntry.doMainAction = function(isMusic)
{
alias3.call(this, isMusic);
// 自軍ターンが開始される時にリセット
if (root.getCurrentSession().getTurnType() === TurnType.PLAYER) {
OT_ResetComandSkill(PlayerList.getMainList());
OT_ResetComandSkill(EnemyList.getMainList() );
OT_ResetComandSkill(AllyList.getMainList() );
OT_ResetTriggerCountList(PlayerList.getMainList(), OT_SkillTriggerCountType.TURN);
OT_ResetTriggerCountList(EnemyList.getMainList() , OT_SkillTriggerCountType.TURN);
OT_ResetTriggerCountList(AllyList.getMainList() , OT_SkillTriggerCountType.TURN);
}
};
// マップクリア時に全ユニットのスキル発動回数をリセットする
var alias4 = MapVictoryFlowEntry._completeMemberData;
MapVictoryFlowEntry._completeMemberData = function(battleResultScreen)
{
OT_ResetComandSkill(PlayerList.getMainList());
OT_ResetComandSkill(EnemyList.getMainList() );
OT_ResetComandSkill(AllyList.getMainList() );
OT_ResetTriggerCountList(PlayerList.getMainList(), OT_SkillTriggerCountType.ALL);
OT_ResetTriggerCountList(EnemyList.getMainList(), OT_SkillTriggerCountType.ALL);
OT_ResetTriggerCountList(AllyList.getMainList(), OT_SkillTriggerCountType.ALL);
return alias4.call(this, battleResultScreen);
};
// キャラの発動回数を纏めてリセット
OT_ResetTriggerCountList = function(list, type)
{
var count = list.getCount();
var unit;
for ( var i=0 ; i<count ; i++ )
{
unit = list.getData(i);
EC_SkillCheck.ResetTriggerCount(unit, type);
}
};
// コマンドスキルをリセット
OT_ResetComandSkill = function(list)
{
var count = list.getCount();
var unit;
for ( var i=0 ; i<count ; i++ )
{
unit = list.getData(i);
EC_SkillCheck.TriggerCountUpCommand(unit, unit.custom.tmpCommandSkillID);
delete unit.custom.tmpCommandSkillID;
}
//root.log('reset');
}
})();