計算式

Ver1.120時点でのsingleton-calculatorの内容。
この辺り、公式でも解説はしているのですがいかんせんざっくりしすぎているので……
書き換え方はこちらを参照。
随時更新中。



AbilityCalculator

ユニットの戦闘に関わる数値の計算を行う。

getPower

ユニットの攻撃力を計算する。
ユニットの力か魔力に武器攻撃力を追加するという内容。

  • 変更例
AbilityCalculator.getPower = function(unit, weapon) {
	var pow;

	if (weapon.custom.waza) {
		if (Miscellaneous.isPhysicsBattle(weapon)) {
			// 物理攻撃または投射攻撃
			pow = RealBonus.getStr(unit);
		}
		else {
			// 魔法攻撃
			pow = RealBonus.getMag(unit);
		}
	} else {
			// 技の武器
		pow = RealBonus.getSki(unit);
	}
	// 武器の威力 + (力 or 魔力 or 技)
	return pow + weapon.getPow();
};

カスパラ「waza」がtrueの武器を装備中の場合は(力or魔力)の代わりに技を加算する。

getHit

ユニットの命中率を計算する。
武器の命中率 + (ユニットの技 * 3)。
return(そこで処理を終了させて呼び出し元の処理に数値を返す)の中で計算している。
これをどうするか。

  • 変更例1
AbilityCalculator.getHit = function(unit, weapon) {
	// 武器の命中率 + (技 * 3) + 幸運
	return weapon.getHit() + (RealBonus.getSki(unit) * 3) + RealBonus.getLuk(unit);
};

デフォルトの計算式にユニットの幸運の加算させたもの。

  • 変更例2
AbilityCalculator.getHit = function(unit, weapon) {
	var hit;
	
	// 武器の命中率
	hit += weapon.getHit();
	
	// ユニットの技*3
	hit += RealBonus.getSki(unit) * 3;
	
	// ユニットの幸運
	hit += RealBonus.getLuk(unit);
	
	return hit;
};

例1の計算式を変数hitを宣言(var)した上でhitに計算した値をまとめていく方法。
returnの中で計算を済ませることもできるが、複雑な計算の場合は見た目が非常に散らかってしまい、
後から確認する時に大変な思いをすることになるだろう。

getAvoid

ユニットの回避率を計算する。
引数(functionの中のパラメータ)にユニットのクラスが存在しないため、
この処理の中でクラスを呼び出しているのがポイント。

  • 変更例1
AbilityCalculator.getAvoid = function(unit) {
	var avoid, terrain;
	var cls = unit.getClass();
	
	// 回避は、(速さ * 2)
	avoid = RealBonus.getSpd(unit) * 2;
	
	// クラスの回避率
	if (typeof cls.custom.kaihi === 'number')
		avoid += cls.custom.kaihi;
	}
	
	// クラスタイプが地形ボーナスを考慮する場合は、「地形効果」の回避率を加算する
	if (cls.getClassType().isTerrainBonusEnabled()) {
		terrain = PosChecker.getTerrainFromPos(unit.getMapX(), unit.getMapY());
		if (terrain !== null) {
			avoid += terrain.getAvoid();
		}
	}
	
	return avoid;
};


クラス(cls)のカスパラ「kaihi」に数値が設定されている場合はkaihiの数値分回避率が上昇する。

  • 変更例2
AbilityCalculator.getAvoid = function(unit) {
	var avoid, terrain;
	var cls = unit.getClass();
	var weapon = ItemControl.getEquippedWeapon(unit);
	
	if (weapon === null) {
		// 武器を装備していない場合の回避は、(速さ * 2)
		avoid = RealBonus.getSpd(unit) * 2;
	} else {
		// 武器を装備している場合の回避は、(敏捷 * 2)
		avoid = AbilityCalculator.getAgility(unit, weapon) * 2;
	}
			
	// クラスタイプが地形ボーナスを考慮する場合は、「地形効果」の回避率を加算する
	if (cls.getClassType().isTerrainBonusEnabled()) {
		terrain = PosChecker.getTerrainFromPos(unit.getMapX(), unit.getMapY());
		if (terrain !== null) {
			avoid += terrain.getAvoid();
		}
	}
	
	return avoid;
};


武器を所持している場合は敏捷(つまり武器の重さによる減算が発生した後の数値)を回避率の計算に使う。
ここで気をつけたいのが「攻撃力」「命中率」「必殺率」は
武器を所持していない状態(つまり攻撃できない状態)ならそれらの計算に入ることはないが、
回避率」と「必殺回避率」と「敏捷」の計算は武器を持っていなくても行われるということ。
つまりこれらの計算時に武器を参照する場合は武器を所持しているかどうかをチェックする必要がある。
敏捷はデフォルトで武器を所持していない場合の分岐を用意しているが、
回避率と必殺回避率の処理で武器を扱う際にこのチェックを怠ると、
僧侶などの武器を持たない非戦闘ユニットのステータスを開いただけでエラーを起こすようになるので注意。

getCritical

ユニットの必殺率を計算する。

  • 変更例
AbilityCalculator.getCritical = function(unit, weapon) {
	var crt;
	var cls = unit.getClass();
	
	// 技
	crt += RealBonus.getSki(unit);
	
	// 武器のクリティカル率
	crt += weapon.getCritical();
	
	// クラスのクリティカル率
	crt += cls.custom.hissatu;

	return crt;
};

クラス(cls)のカスパラ「hissatu」に数値が設定されている場合はhissatuの数値分必殺率が上昇する。

getCriticalAvoid

ユニットの必殺回避率を計算する。

  • 変更例
AbilityCalculator.getCriticalAvoid = function(unit) {
	// (幸運/2)がクリティカル回避率
	return Math.floor( RealBonus.getLuk(unit) / 2 );
};

幸運の半分の値が必殺回避率になる。
Javascriptで除算を行う場合はMath.○○を用いて小数点以下を丸めて整数にする作業が必須。
うっかり小数点のまま処理を進めたりすると数字が表示されなくなったりフリーズを引き起こす要因になる。
SRPG Studioでは基本的にMath.floorを使う。
Math.round(丸めたい数値) 四捨五入
Math.ceil(丸めたい数値) 切り上げ
Math.floor(丸めたい数値) 切り捨て

getAgility

ユニットの敏捷(戦闘時の素早さ)を計算する。
これまでと比べると複雑な分岐を行っている。

  • 変更例
AbilityCalculator.getAgility = function(unit, weapon) {
	var agi, value, param;
	var spd = RealBonus.getSpd(unit);
	
	// 通常、敏捷は速さと同一
	agi = spd;
	
	// 武器が指定されてない場合、または重さを考慮しない場合は、敏捷は変わらない
	if (weapon === null || !DataConfig.isItemWeightDisplayable()) {
		return agi;
	}
	
	// 体格が有効な場合は体格で判定し、そうでない場合は力(魔力)で判定する
	if (DataConfig.isBuildDisplayable()) {
		param = ParamBonus.getBld(unit);
		param += Math.floor(ParamBonus.getStr(unit)/2);
	}
	else {
		param = ParamBonus.getStr(unit);
	}
	
	// 重さ - パラメータ
	value = weapon.getWeight() - param;
	if (value > 0) {
		// パラメータが重さより低い場合は、その差分だけ敏捷を下げる
		agi -= value;
	}
	
	return agi;
};

魔法武器なら魔力で武器の重さを相殺するところを魔法武器でも力で相殺するように固定化している。
体格が有効になっている場合は(体格+力の半分)で相殺を行う。

DamageCalculator

実際の戦闘におけるダメージ計算。

calculateDamage

クリティカル時の処理を行う部分。
  • 変更例1
DamageCalculator.calculateDamage = function(active, passive, weapon, isCritical, activeTotalStatus, passiveTotalStatus, trueHitValue) {
	var pow, def, damage;
	var crtdamage = 0;
	
	if (this.isHpMinimum(active, passive, weapon, isCritical, trueHitValue)) {
		return -1;
	}
	
	pow = this.calculateAttackPower(active, passive, weapon, isCritical, activeTotalStatus, trueHitValue);
	def = this.calculateDefense(active, passive, weapon, isCritical, passiveTotalStatus, trueHitValue);
	
	damage = pow - def;
	if (this.isHalveAttack(active, passive, weapon, isCritical, trueHitValue)) {
		if (!this.isHalveAttackBreak(active, passive, weapon, isCritical, trueHitValue)) {
			damage = Math.floor(damage / 2);
		}
	}
	
	if (this.isCritical(active, passive, weapon, isCritical, trueHitValue)) {
		if (SkillControl.getBattleSkill(active, passive, SkillType.CRITICAL)) {
			crtdamage = 1;
		}
			damage = Math.floor(damage * (this.getCriticalFactor() + crtdamage));
	}
	
	return this.validValue(active, passive, weapon, damage);
};

「クリティカル可能」スキルを所持しているユニットはクリティカル時のダメージ倍率が+100%される。
DamageCalculator.getCriticalFactor()はツール側で設定されたクリティカル時のダメージ倍率を取得する関数。

  • 変更例2
DamageCalculator.calculateDamage = function(active, passive, weapon, isCritical, activeTotalStatus, passiveTotalStatus, trueHitValue) {
	var pow, def, damage;
	var crtdamage = Math.floor(Math.random() * 15) + 5;
	
	if (this.isHpMinimum(active, passive, weapon, isCritical, trueHitValue)) {
		return -1;
	}
	
	pow = this.calculateAttackPower(active, passive, weapon, isCritical, activeTotalStatus, trueHitValue);
	def = this.calculateDefense(active, passive, weapon, isCritical, passiveTotalStatus, trueHitValue);
	
	damage = pow - def;
	if (this.isHalveAttack(active, passive, weapon, isCritical, trueHitValue)) {
		if (!this.isHalveAttackBreak(active, passive, weapon, isCritical, trueHitValue)) {
			damage = Math.floor(damage / 2);
		}
	}
	
	if (this.isCritical(active, passive, weapon, isCritical, trueHitValue)) {
		if (SkillControl.getBattleSkill(active, passive, SkillType.CRITICAL)) {
			crtdamage = 5;
		}
			damage += crtdamage;
	}
	
	return this.validValue(active, passive, weapon, damage);
};

クリティカル時のダメージの計算が「ダメージ×3」から「ダメージ+5~20の乱数」に変わる。
「クリティカル可能」スキルを所持しているユニットはクリティカル時のダメージが更に+5される。
ツール側のクリティカル時のダメージ倍率の設定は使用されなくなる。

HitCalculator

実際の戦闘における攻撃命中判定処理。

CriticalCalculator

実際の戦闘におけるクリティカル判定処理。

Calculator

戦闘関係、アイテム関係などその他諸々の計算。

calculateRoundCount

再攻撃可能かどうか判定する。
  • 変更例
Calculator.calculateRoundCount = function(active, passive, weapon) {
	var activeAgi;
	var passiveAgi;
	var value;
	
	if (!this.isRoundAttackAllowed(active, passive)) {
		return 1;
	}
	
	activeAgi = AbilityCalculator.getAgility(active, weapon);
	passiveAgi = AbilityCalculator.getAgility(passive, ItemControl.getEquippedWeapon(passive));
	value = this.getDifference();
	
	//「再攻撃」を持っていれば再攻撃差分変更
	if (SkillControl.getBattleSkill(active, passive, SkillType.ROUNDATTACK){
		value = 1;
	}
	
	return (activeAgi - passiveAgi) >= value ? 2 : 1;
};

value = this.getDifference();」がツール側で設定した「再攻撃差分」の数値なので、
攻撃側が「再攻撃」のスキルを持っている場合は再攻撃差分が1に変更されるように。

calculateRecoveryItemPlus

回復アイテムの補正を計算する。
デフォルトでは回復アイテムが杖だった時に使用者の魔力を回復値に加算する処理のみ。
  • 変更例
Calculator.calculateRecoveryItemPlus = function(unit, targetUnit, item) {
	var plus = 0;
	var itemType = item.getItemType();
	
	if (itemType !== ItemType.RECOVERY && itemType !== ItemType.ENTIRERECOVERY) {
		return 0;
	}
	
	// アイテムが杖の場合は、使用者の魔防力を加算する
	if (item.isWand()) {
		plus = ParamBonus.getMdf(unit);
	}
	
	return plus;
};

魔力の代わりに魔防力を回復値に追加するようにする変更。
杖使いと魔法使いをより差別化したい時に。

calculateSellPrice

店でアイテムを売却する時の値段の計算。
  • 変更例
Calculator.calculateSellPrice = function(item) {
	var d;
	var gold = Math.floor(item.getGold() / 4);
	return gold;
};

耐久力で売却価格が変動する処理を廃し、売却価格を「買値の1/4の値段」で固定する。

SupportCalculator

支援効果の計算。

createTotalStatus

各種支援効果の配列を作成し、総合する部分。

  • 変更例
var alias1 = SupportCalculator.createTotalStatus;
SupportCalculator.createTotalStatus = function(unit) {
	var i, x, y, index, targetUnit, unitType, list, indexArray, count;
	var totalStatus = {};
	
	totalStatus.powerTotal = 0;
	totalStatus.defenseTotal = 0;
	totalStatus.hitTotal = 0;
	totalStatus.avoidTotal = 0;
	totalStatus.criticalTotal = 0;
	totalStatus.criticalAvoidTotal = 0;
		if (!SkillControl.getPossessionCustomSkill(unit,'noSupport')) {
			totalStatus = alias1.call(this, unit);
		}
	return totalStatus;
}

キーワード「noSupport」のカスタムスキルを所持しているユニットは一切の支援効果を受けられなくなる。
破壊できる壁などの障害物が支援スキルの影響を受けるのを無効化できる。

CompatibleCalculator

武器の有効相手(いわゆる三すくみ)の補正計算。

ExperienceCalculator

取得経験値の計算を行う。

_getExperienceFactor

取得経験値に対して補正をかける。
優先順位は「経験値上昇」スキルによる補正倍率>難易度設定による2倍効果となっており、
「経験値上昇」スキルを所持している場合は難易度設定による2倍効果は無効化される。

_getNoDamageExperience

ダメージを与えられなかった時の取得経験値。
baseExpの5を基礎値とする。
ここを0に変えればダメージを与えられなければ経験値が入らないことになる。
(ただしgetExperienceのレベル差補正も修正する必要あり)

_getVictoryExperience

敵を撃破できた時の取得経験値。
難易度設定による基礎経験値が使用される。

_getNormalValue

ダメージは与えたが敵を撃破できなかった時の取得経験値。
baseExpの8を基礎値とする。
ここを0に変えれば敵を撃破できないと経験値が入らないことになる。
(ただしgetExperienceのレベル差補正も修正する必要あり)

_getExperience

戦闘における最終的な取得経験値を割り出す。
味方ユニットと敵ユニットのレベル差、クラスランクによって修正が入る。

ExperienceControl

レベルアップ時の成長処理などを行う。

ParameterControl

レベルアップ時にステータスを上昇させる処理。

SymbolCalculator

クラスチェンジやフュージョンなどの許可判定、イベントなどのステータス条件判定の計算を行う部分。