slave-princess-charlotte/data/Script/singleton/singleton-skillcontrol.js
2025-10-12 13:17:46 -05:00

543 lines
16 KiB
JavaScript

// スキルの発動を管理する
var SkillRandomizer = {
isSkillInvoked: function(active, passive, skill) {
var skilltype;
var result = false;
if (skill === null) {
return false;
}
skilltype = skill.getSkillType();
if (skilltype === SkillType.FASTATTACK) {
result = this._isFastAttack(active, passive, skill);
}
else if (skilltype === SkillType.CONTINUOUSATTACK) {
result = this._isContinuousAttack(active, passive, skill);
}
else if (skilltype === SkillType.COUNTERATTACKCRITICAL) {
result = this._isCounterattackCritical(active, passive, skill);
}
else if (skilltype === SkillType.DAMAGEABSORPTION) {
result = this._isDamageAbsorption(active, passive, skill);
}
else if (skilltype === SkillType.TRUEHIT) {
result = this._isTrueHit(active, passive, skill);
}
else if (skilltype === SkillType.STATEATTACK) {
result = this._isStateAttack(active, passive, skill);
}
else if (skilltype === SkillType.DAMAGEGUARD) {
result = this._isDamageGuard(active, passive, skill);
}
else if (skilltype === SkillType.SURVIVAL) {
result = this._isSurvival(active, passive, skill);
}
return result;
},
isCustomSkillInvoked: function(active, passive, skill, keyword) {
if (skill === null || skill.getCustomKeyword() !== keyword) {
return false;
}
return this.isCustomSkillInvokedInternal(active, passive, skill, keyword);
},
isCustomSkillInvokedInternal: function(active, passive, skill, keyword) {
return false;
},
_isFastAttack: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isContinuousAttack: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isCounterattackCritical: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isDamageAbsorption: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isTrueHit: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isStateAttack: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isDamageGuard: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isSurvival: function(active, passive, skill) {
return this._isSkillInvokedInternal(active, passive, skill);
},
_isSkillInvokedInternal: function(active, passive, skill) {
var type = skill.getInvocationType();
var value = skill.getInvocationValue();
if (!skill.getTargetAggregation().isCondition(passive)) {
return false;
}
// 相手がスキルを無効化できる場合は、スキルを発動しない
if (SkillControl.getBattleSkillFromFlag(passive, active, SkillType.INVALID, InvalidFlag.SKILL) !== null) {
return false;
}
// valueを「発動率」として計算する
return Probability.getInvocationProbability(active, type, value);
}
};
var ObjectFlag = {
UNIT: 0x01,
CLASS: 0x02,
WEAPON: 0x04,
ITEM: 0x08,
SKILL: 0x10,
STATE: 0x20,
FUSION: 0x40
};
// スキルの所持確認などを行う
var SkillControl = {
checkAndPushSkill: function(active, passive, attackEntry, isActive, skilltype) {
var skill = this.getPossessionSkill(active, skilltype);
if (SkillRandomizer.isSkillInvoked(active, passive, skill)) {
// スキルに「発動時に表示する」が設定されているか調べる
if (skill.isSkillDisplayable()) {
// 表示する場合は、描画時にスキルを参照できるように保存する
if (isActive) {
attackEntry.skillArrayActive.push(skill);
}
else {
attackEntry.skillArrayPassive.push(skill);
}
}
return skill;
}
return null;
},
checkAndPushCustomSkill: function(active, passive, attackEntry, isActive, keyword) {
var skill = this.getPossessionCustomSkill(active, keyword);
if (SkillRandomizer.isCustomSkillInvoked(active, passive, skill, keyword)) {
if (skill.isSkillDisplayable()) {
if (isActive) {
attackEntry.skillArrayActive.push(skill);
}
else {
attackEntry.skillArrayPassive.push(skill);
}
}
return skill;
}
return null;
},
getBattleSkill: function(active, passive, skilltype) {
var arr = this.getDirectSkillArray(active, skilltype, '');
var skill = this._returnSkill(skilltype, arr);
return this._getBattleSkillInternal(active, passive, skill);
},
getBattleSkillFromFlag: function(active, passive, skilltype, flag) {
var i, count;
var arr = this.getDirectSkillArray(active, skilltype, '');
count = arr.length;
for (i = 0; i < count; i++) {
if (arr[i].skill.getSkillType() === skilltype && arr[i].skill.getSkillValue() & flag) {
return this._getBattleSkillInternal(active, passive, arr[i].skill);
}
}
return null;
},
getBattleSkillFromValue: function(active, passive, skilltype, value) {
var i, count;
var arr = this.getDirectSkillArray(active, skilltype, '');
count = arr.length;
for (i = 0; i < count; i++) {
if (arr[i].skill.getSkillType() === skilltype && arr[i].skill.getSkillValue() === value) {
return this._getBattleSkillInternal(active, passive, arr[i].skill);
}
}
return null;
},
// unitがskilltypeのスキルを所持しているか調べる。
// 戻り値は、所持しているスキル。
getPossessionSkill: function(unit, skilltype) {
var arr = this.getDirectSkillArray(unit, skilltype, '');
return this._returnSkill(skilltype, arr);
},
// 最も数値が大きいスキルを返す
getBestPossessionSkill: function(unit, skilltype) {
var i, count;
var arr = this.getDirectSkillArray(unit, skilltype, '');
var max = -1000;
var index = -1;
count = arr.length;
for (i = 0; i < count; i++) {
if (arr[i].skill.getSkillType() === skilltype && arr[i].skill.getSkillValue() > max) {
max = arr[i].skill.getSkillValue();
index = i;
}
}
if (index === -1) {
return null;
}
return arr[index].skill;
},
// 後のバージョンで削除
getFlagPossessionSkill: function(unit, skilltype, flag) {
return this.getBattleSkillFromFlag(unit, null, skilltype, flag);
},
getPossessionCustomSkill: function(unit, keyword) {
var arr = this.getDirectSkillArray(unit, SkillType.CUSTOM, keyword);
return this._returnSkill(SkillType.CUSTOM, arr);
},
getDirectSkillArray: function(unit, skilltype, keyword) {
var weapon = ItemControl.getEquippedWeapon(unit);
return this.getSkillMixArray(unit, weapon, skilltype, keyword);
},
// skilltypeが-1の場合は、unitに関連する全てのスキルが対象になる
getSkillMixArray: function(unit, weapon, skilltype, keyword) {
var objectFlag = ObjectFlag.UNIT | ObjectFlag.CLASS | ObjectFlag.WEAPON | ObjectFlag.ITEM | ObjectFlag.STATE | ObjectFlag.FUSION;
return this.getSkillObjectArray(unit, weapon, skilltype, keyword, objectFlag);
},
getSkillObjectArray: function(unit, weapon, skilltype, keyword, objectFlag) {
var arr = [];
this._pushObjectSkill(unit, weapon, arr, skilltype, keyword, objectFlag);
return this._getValidSkillArray(arr);
},
_getBattleSkillInternal: function(active, passive, skill) {
if (skill === null) {
return null;
}
// 有効相手として許可されない
if (passive !== null && !skill.getTargetAggregation().isCondition(passive)) {
return null;
}
return skill;
},
_pushObjectSkill: function(unit, weapon, arr, skilltype, keyword, objectFlag) {
var i, item, list, count, child;
var cls = unit.getClass();
if (objectFlag & ObjectFlag.UNIT) {
// ユニットのスキルを追加する
this._pushSkillValue(unit, ObjectType.UNIT, arr, skilltype, keyword);
}
if (objectFlag & ObjectFlag.CLASS) {
// ユニットが属するクラスのスキルを追加する
this._pushSkillValue(cls, ObjectType.CLASS, arr, skilltype, keyword);
}
if (objectFlag & ObjectFlag.WEAPON) {
if (weapon !== null) {
// 武器のスキルを追加する
this._pushSkillValue(weapon, ObjectType.WEAPON, arr, skilltype, keyword);
}
}
if (objectFlag & ObjectFlag.ITEM) {
count = UnitItemControl.getPossessionItemCount(unit);
for (i = 0; i < count; i++) {
item = UnitItemControl.getItem(unit, i);
if (item !== null && ItemControl.isItemUsable(unit, item)) {
// アイテムを使用できる場合は、スキルを追加する
this._pushSkillValue(item, ObjectType.ITEM, arr, skilltype, keyword);
}
}
}
if (objectFlag & ObjectFlag.STATE) {
// ユニットにかかっているステートのスキルを追加する
list = unit.getTurnStateList();
count = list.getCount();
for (i = 0; i < count; i++) {
this._pushSkillValue(list.getData(i).getState(), ObjectType.STATE, arr, skilltype, keyword);
}
}
if (objectFlag & ObjectFlag.FUSION) {
child = FusionControl.getFusionChild(unit);
if (child !== null) {
objectFlag = FusionControl.getFusionData(unit).getSkillIncludedObjectFlag();
this._pushObjectSkillFromFusion(child, ItemControl.getEquippedWeapon(child), arr, skilltype, keyword, objectFlag);
}
}
},
_pushObjectSkillFromFusion: function(unit, weapon, arr, skilltype, keyword, objectFlag) {
var i, item, list, count;
var cls = unit.getClass();
if (objectFlag & ObjectFlag.UNIT) {
// ユニットのスキルを追加する
this._pushSkillValue(unit, ObjectType.FUSION, arr, skilltype, keyword);
}
if (objectFlag & ObjectFlag.CLASS) {
// ユニットが属するクラスのスキルを追加する
this._pushSkillValue(cls, ObjectType.FUSION, arr, skilltype, keyword);
}
if (objectFlag & ObjectFlag.WEAPON) {
if (weapon !== null) {
// 武器のスキルを追加する
this._pushSkillValue(weapon, ObjectType.FUSION, arr, skilltype, keyword);
}
}
if (objectFlag & ObjectFlag.ITEM) {
count = UnitItemControl.getPossessionItemCount(unit);
for (i = 0; i < count; i++) {
item = UnitItemControl.getItem(unit, i);
if (item !== null && ItemControl.isItemUsable(unit, item)) {
// アイテムを使用できる場合は、スキルを追加する
this._pushSkillValue(item, ObjectType.FUSION, arr, skilltype, keyword);
}
}
}
if (objectFlag & ObjectFlag.STATE) {
// ユニットにかかっているステートのスキルを追加する
list = unit.getTurnStateList();
count = list.getCount();
for (i = 0; i < count; i++) {
this._pushSkillValue(list.getData(i).getState(), ObjectType.FUSION, arr, skilltype, keyword);
}
}
},
_pushSkillValue: function(data, objecttype, arr, skilltype, keyword) {
var i, skill, skillEntry, isBuild;
var list = data.getSkillReferenceList();
var count = list.getTypeCount();
// スキルリストからtypeで識別されるスキルを探す。
// 見つかった場合は、そのスキルの値をarrに保存する。
for (i = 0; i < count; i++) {
skill = list.getTypeData(i);
isBuild = false;
if (skilltype === -1) {
isBuild = true;
}
else if (skill.getSkillType() === skilltype) {
if (skilltype === SkillType.CUSTOM) {
if (skill.getCustomKeyword() === keyword) {
isBuild = true;
}
}
else {
isBuild = true;
}
}
if (isBuild) {
skillEntry = StructureBuilder.buildMixSkillEntry();
skillEntry.objecttype = objecttype;
skillEntry.skill = skill;
arr.push(skillEntry);
}
}
},
_returnSkill: function(skilltype, arr) {
var i;
var count = arr.length;
var max = -1000;
var index = -1;
// arrの中からskilltypeと一致スキルを探す。
// 同種スキルが複数存在する場合は、発動率が高いスキルを優先する
for (i = 0; i < count; i++) {
if (arr[i].skill.getSkillType() === skilltype && arr[i].skill.getInvocationValue() > max) {
max = arr[i].skill.getInvocationValue();
index = i;
}
}
if (index === -1) {
return null;
}
return arr[index].skill;
},
_getValidSkillArray: function(arr) {
var i;
var count = arr.length;
var usedAry = [];
for (i = 0; i < count; i++) {
// 既に追加されているスキルは、再び追加してはならない
if (this._isUsed(usedAry, arr[i])) {
continue;
}
usedAry.push(arr[i]);
}
return usedAry;
},
_isUsed: function(arr, obj) {
var i;
var count = arr.length;
for (i = 0; i < count; i++) {
if (arr[i].skill.getId() === obj.skill.getId()) {
return true;
}
}
return false;
}
};
// スキルの追加や削除を行う
var SkillChecker = {
arrangeSkill: function(unit, skill, increaseType) {
var list = unit.getSkillReferenceList();
var count = list.getTypeCount();
var editor = root.getDataEditor();
if (increaseType === IncreaseType.INCREASE) {
// コンフィグの「スキル所持数」を超えてないか調べる
if (count < DataConfig.getMaxSkillCount()) {
editor.addSkillData(list, skill);
}
}
else if (increaseType === IncreaseType.DECREASE) {
editor.deleteSkillData(list, skill);
}
else if (increaseType === IncreaseType.ALLRELEASE) {
editor.deleteAllSkillData(list);
}
},
addAllNewSkill: function(unit) {
var i, count, newSkill;
if (unit === null) {
return;
}
count = unit.getNewSkillCount();
for (i = 0; i < count; i++) {
newSkill = unit.getNewSkill(i);
this.addNewSkill(unit, newSkill);
}
},
addNewSkill: function(unit, newSkill) {
// スキルを習得できるレベルに達してないか調べる
if (unit.getLv() < newSkill.getLv()) {
return false;
}
// スキルを既に所持しているか調べる
if (this._isSkillLearned(unit, newSkill.getSkill())) {
return false;
}
if (newSkill.getNewSkillType() === NewSkillType.NEW) {
// スキルの新規習得の場合は、既にそのスキルが置き換わったことがあるかどうか調べる
if (!this._isSkillReplaced(unit, newSkill.getSkill())) {
this.arrangeSkill(unit, newSkill.getSkill(), IncreaseType.INCREASE);
return true;
}
}
else {
// スキルの置き換えの場合は、置き換え元スキルを習得しているかどうか調べる
if (this._isSkillLearned(unit, newSkill.getOldSkill())) {
this._powerupSkill(unit, newSkill);
return true;
}
}
return false;
},
_powerupSkill: function(unit, newSkill) {
var list = unit.getSkillReferenceList();
root.getDataEditor().changeSkillData(list, newSkill.getSkill(), newSkill.getOldSkill());
},
_isSkillLearned: function(unit, skill) {
var i;
var list = unit.getSkillReferenceList();
var count = list.getTypeCount();
for (i = 0; i < count; i++) {
if (skill === list.getTypeData(i)) {
return true;
}
}
return false;
},
// 置き換え後スキルを所持している場合は、置き換え元スキルは再取得できない
_isSkillReplaced: function(unit, skill) {
var i, newSkill;
var count = unit.getNewSkillCount();
for (i = 0; i < count; i++) {
newSkill = unit.getNewSkill(i);
if (newSkill.getNewSkillType() === NewSkillType.POWERUP && newSkill.getOldSkill() === skill) {
if (this._isSkillLearned(unit, newSkill.getSkill())) {
return true;
}
}
}
return false;
}
};