mota-js/libs/enemys.js
2019-01-21 22:19:24 +08:00

373 lines
14 KiB
JavaScript
Raw 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.

"use strict";
function enemys() {
this.init();
}
////// 初始化 //////
enemys.prototype.init = function () {
this.enemys = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80;
this.enemydata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.enemys;
if (main.mode=='play') {
this.enemydata.hasSpecial = function (a, b) {return core.enemys.hasSpecial(a, b)};
for (var enemyId in this.enemys) {
this.enemys[enemyId].id = enemyId;
}
}
}
////// 获得一个或所有怪物数据 //////
enemys.prototype.getEnemys = function (enemyId) {
if (!core.isset(enemyId)) {
return this.enemys;
}
return this.enemys[enemyId];
}
////// 判断是否含有某特殊属性 //////
enemys.prototype.hasSpecial = function (special, test) {
if (!core.isset(special)) return false;
if (special instanceof Array) {
return special.indexOf(test)>=0;
}
if (typeof special == 'number') {
return special!=0 && (special%100==test||this.hasSpecial(parseInt(special/100), test));
}
if (typeof special == 'string') {
return this.hasSpecial(core.material.enemys[special], test);
}
if (core.isset(special.special)) {
return this.hasSpecial(special.special, test);
}
return false;
}
enemys.prototype.getSpecials = function () {
return this.enemydata.getSpecials();
}
enemys.prototype.calContent = function (enemy, content) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
if (typeof content == 'string') return content;
if (content instanceof Function) {
return content(enemy);
}
return "";
}
////// 获得所有特殊属性的名称 //////
enemys.prototype.getSpecialText = function (enemy) {
// 移动到了脚本编辑 - getSpecials中
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
if (!core.isset(enemy)) return [];
var special = enemy.special;
var text = [];
var specials=this.getSpecials();
if (core.isset(specials)) {
for (var i=0;i<specials.length;i++) {
if (this.hasSpecial(special, specials[i][0]))
text.push(this.calContent(enemy, specials[i][1]));
}
}
return text;
}
////// 获得每个特殊属性的说明 //////
enemys.prototype.getSpecialHint = function (enemy, special) {
// 移动到了脚本编辑 - getSpecials中
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var specials=this.getSpecials();
if (!core.isset(special)) {
if (!core.isset(specials)) return [];
var hints = [];
for (var i=0;i<specials.length;i++) {
if (this.hasSpecial(enemy, specials[i][0]))
hints.push(this.calContent(enemy, specials[i][1])+""+this.calContent(enemy, specials[i][2]));
}
return hints;
}
if (!core.isset(specials)) return "";
for (var i=0;i<specials.length;i++) {
if (special == specials[i][0])
return this.calContent(enemy, specials[i][1])+""+this.calContent(enemy, specials[i][2]);
}
return "";
}
////// 能否获胜 //////
enemys.prototype.canBattle = function (enemyId, x, y, floorId) {
var damage = this.getDamage(enemyId, x, y, floorId);
return damage != null && damage < core.status.hero.hp;
}
////// 获得某个怪物的伤害 //////
enemys.prototype.getDamage = function (enemy, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var damage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (damage == null) return null;
return damage + this.getExtraDamage(enemy);
}
////// 获得某个怪物的额外伤害 //////
enemys.prototype.getExtraDamage = function (enemy) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var extra_damage = 0;
if (this.hasSpecial(enemy.special, 17)) { // 仇恨
extra_damage += core.getFlag('hatred', 0);
}
if (this.hasSpecial(enemy.special, 22)) { // 固伤
extra_damage += enemy.damage||0;
}
return extra_damage;
}
enemys.prototype.getDamageString = function (enemy, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var damage = core.enemys.getDamage(enemy, x, y, floorId);
var color = '#000000';
if (damage == null) {
damage = "???";
color = '#FF0000';
}
else {
if (damage <= 0) color = '#00FF00';
else if (damage < core.status.hero.hp / 3) color = '#FFFFFF';
else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00';
else if (damage < core.status.hero.hp) color = '#FF7F00';
else color = '#FF0000';
damage = core.formatBigNumber(damage, true);
if (core.enemys.hasSpecial(enemy, 19))
damage += "+";
if (core.enemys.hasSpecial(enemy, 21))
damage += "-";
if (core.enemys.hasSpecial(enemy, 11))
damage += "^";
}
return {
"damage": damage,
"color": color
};
}
////// 接下来N个临界值和临界减伤计算 //////
enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var useTurn = !core.flags.useLoop;
number = number||1;
if (this.hasSpecial(enemy.special, 3)) {
if (core.status.hero.atk<=enemy.def) {
return [[enemy.def+1-core.status.hero.atk,'?']];
}
return [];
}
// 坚固、模仿怪物没有临界!
if (this.hasSpecial(enemy.special, 10)) return [];
var info = this.getDamageInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (info == null) {
if (core.status.hero.atk<=enemy.def) {
return [[enemy.def+1-core.status.hero.atk,'?']];
}
return [];
}
// getDamageInfo直接返回数字
if (typeof info == 'number') {
return [[0,0]];
}
if (info.damage<=0 && !core.flags.enableNegativeDamage) {
return [[0,0]];
}
var list = [], pre = null;
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = enemy.def, turn = info.turn;
if (useTurn) { // 回合数计算法
for (var t = turn-1;t>=1;t--) {
var nextAtk = Math.ceil(mon_hp/t) + mon_def;
// 装备提升比例的计算临界
nextAtk = Math.ceil(nextAtk / core.getFlag('equip_atk_buff', 1));
if (nextAtk<=hero_atk) break;
if (nextAtk!=pre) {
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (nextInfo==null || (typeof nextInfo == 'number')) break;
list.push([nextAtk-hero_atk,Math.floor(info.damage-nextInfo.damage)]);
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
pre = nextAtk;
}
if (list.length>=number)
break;
}
}
else { // 暴力for循环法
// V2.5.3以后,大数据改为二分法进行计算
var LOOP_MAX_VALUE = 1;
pre = info.damage;
if (hero_atk <= LOOP_MAX_VALUE) { // 循环法
for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) {
var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (nextInfo==null || (typeof nextInfo == 'number')) break;
if (pre>nextInfo.damage) {
pre = nextInfo.damage;
list.push([atk-hero_atk, info.damage-nextInfo.damage]);
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
if (list.length>=number) break;
}
}
}
else { // 二分法算临界
var calNext = function (currAtk, maxAtk) {
var start = Math.floor(currAtk), end = Math.floor(maxAtk);
if (start>end) return null;
while (start<end) {
var mid = Math.floor((start+end)/2);
var nextInfo = core.enemys.getDamageInfo(enemy, core.status.hero.hp, mid, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
if (nextInfo == null || (typeof nextInfo == 'number')) return null;
if (pre>nextInfo.damage) end = mid;
else start = mid+1;
}
var nextInfo = core.enemys.getDamageInfo(enemy, core.status.hero.hp, start, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
return nextInfo==null||(typeof nextInfo == 'number')||nextInfo.damage>=pre?null:[start,nextInfo.damage];
}
var currAtk = hero_atk;
while (true) {
var next = calNext(currAtk+1, mon_hp+mon_def, pre);
if (next == null) break;
currAtk = next[0];
pre = next[1];
list.push([currAtk-hero_atk, info.damage-pre]);
if (pre<=0 && !core.flags.enableNegativeDamage) break;
if (list.length>=number) break;
}
}
}
if (list.length==0) list.push([0,0]);
return list;
}
////// N防减伤计算 //////
enemys.prototype.getDefDamage = function (enemy, k, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
k = k || 1;
var nowDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId);
var nextDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def + k, core.status.hero.mdef, x, y, floorId);
if (nowDamage == null || nextDamage ==null) return "???";
return nowDamage - nextDamage;
}
enemys.prototype.getEnemyInfo = function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
return this.enemydata.getEnemyInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId)
}
////// 获得战斗伤害信息(实际伤害计算函数) //////
enemys.prototype.getDamageInfo = function(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
// 移动到了脚本编辑 - getDamageInfo中
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
return this.enemydata.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
}
////// 获得在某个勇士属性下怪物伤害 //////
enemys.prototype.calDamage = function (enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var info = this.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef, x, y, floorId);
if (info == null) return null;
if (typeof info == 'number') return info;
return info.damage;
}
////// 更新怪物数据 //////
enemys.prototype.updateEnemys = function () {
return this.enemydata.updateEnemys();
}
////// 获得当前楼层的怪物列表 //////
enemys.prototype.getCurrentEnemys = function (floorId) {
floorId=floorId||core.status.floorId;
var enemys = [];
var used = {};
var mapBlocks = core.status.maps[floorId].blocks;
for (var b = 0; b < mapBlocks.length; b++) {
if (core.isset(mapBlocks[b].event) && !mapBlocks[b].disable
&& mapBlocks[b].event.cls.indexOf('enemy')==0) {
var enemyId = mapBlocks[b].event.id;
var enemy = core.material.enemys[enemyId];
if (!core.isset(enemy)) continue;
// 检查displayIdInBook
var tmpId = enemy.displayIdInBook;
if (core.isset(core.material.enemys[tmpId])) {
enemyId = tmpId;
enemy = core.material.enemys[tmpId];
}
if (core.isset(used[enemyId])) continue;
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def;
var hero_atk = core.status.hero.atk, hero_def = core.status.hero.def, hero_mdef = core.status.hero.mdef;
hero_atk = Math.floor(core.getFlag('equip_atk_buff',1)*hero_atk);
hero_def = Math.floor(core.getFlag('equip_def_buff',1)*hero_def);
hero_mdef = Math.floor(core.getFlag('equip_mdef_buff',1)*hero_mdef);
var enemyInfo = this.getEnemyInfo(enemy, core.status.hero.hp, hero_atk, hero_def, hero_mdef, null, null, floorId);
var specialText = core.enemys.getSpecialText(enemyId);
if (specialText.length>=3) specialText = "多属性...";
else specialText = specialText.join(" ");
var critical = this.nextCriticals(enemyId, 1, null, null, floorId);
if (critical.length>0) critical=critical[0];
var e = core.clone(enemy);
for (var x in enemyInfo) {
e[x] = enemyInfo[x];
}
e.id = enemyId;
e.specialText = specialText;
e.damage = this.getDamage(enemyId, null, null, floorId);
e.critical = critical[0];
e.criticalDamage = critical[1];
e.defDamage = this.getDefDamage(enemyId,1,null,null,floorId);
enemys.push(e);
used[enemyId] = true;
}
}
enemys.sort(function (a, b) {
if (a.damage == b.damage) {
return a.money - b.money;
}
if (a.damage == null) {
return 1;
}
if (b.damage == null) {
return -1;
}
return a.damage - b.damage;
});
return enemys;
}