Move enemy functions to proect

This commit is contained in:
oc 2018-07-19 02:08:04 +08:00
parent 236c6408b5
commit 1d70bcd131
15 changed files with 353 additions and 234 deletions

View File

@ -193,6 +193,7 @@ action
| setBlock_s | setBlock_s
| setHeroIcon_s | setHeroIcon_s
| update_s | update_s
| updateEnemys_s
| sleep_s | sleep_s
| wait_s | wait_s
| battle_s | battle_s
@ -496,6 +497,18 @@ var code = '{"type": "update"},\n';
return code; return code;
*/; */;
updateEnemys_s
: '更新怪物数据' Newline
/* updateEnemys_s
tooltip : updateEnemys: 立刻更新怪物数据
helpUrl : https://ckcz123.github.io/mota-js/#/event?id=updateEnemys%ef%bc%9a%e6%9b%b4%e6%96%b0%e6%80%aa%e7%89%a9%e6%95%b0%e6%8d%ae
colour : this.dataColor
var code = '{"type": "updateEnemys"},\n';
return code;
*/;
sleep_s sleep_s
: '等待' Int '毫秒' Newline : '等待' Int '毫秒' Newline
@ -1702,6 +1715,10 @@ ActionParser.prototype.parseAction = function() {
this.next = MotaActionBlocks['update_s'].xmlText([ this.next = MotaActionBlocks['update_s'].xmlText([
this.next]); this.next]);
break; break;
case "updateEnemys":
this.next = MotaActionBlocks['updateEnemys_s'].xmlText([
this.next]);
break;
case "sleep": // 等待多少毫秒 case "sleep": // 等待多少毫秒
this.next = MotaActionBlocks['sleep_s'].xmlText([ this.next = MotaActionBlocks['sleep_s'].xmlText([
data.time,this.next]); data.time,this.next]);

View File

@ -495,6 +495,12 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"_bool": "bool", "_bool": "bool",
"_data": "夹击方式是向上取整还是向下取整。如果此项为true则为向上取整为false则为向下取整" "_data": "夹击方式是向上取整还是向下取整。如果此项为true则为向上取整为false则为向下取整"
}, },
"useLoop": {
"_leaf": true,
"_type": "checkbox",
"_bool": "bool",
"_data": "是否循环计算临界如果此项为true则使用循环法而不是回合数计算法来算临界"
},
"startDirectly": { "startDirectly": {
"_leaf": true, "_leaf": true,
"_type": "checkbox", "_type": "checkbox",

View File

@ -87,6 +87,7 @@ editor_blockly = function () {
MotaActionBlocks['setValue_s'].xmlText(), MotaActionBlocks['setValue_s'].xmlText(),
MotaActionBlocks['input_s'].xmlText(), MotaActionBlocks['input_s'].xmlText(),
MotaActionBlocks['update_s'].xmlText(), MotaActionBlocks['update_s'].xmlText(),
MotaActionBlocks['updateEnemys_s'].xmlText(),
MotaActionBlocks['moveHero_s'].xmlText(), MotaActionBlocks['moveHero_s'].xmlText(),
MotaActionBlocks['jumpHero_s'].xmlText(), MotaActionBlocks['jumpHero_s'].xmlText(),
MotaActionBlocks['changeFloor_s'].xmlText(), MotaActionBlocks['changeFloor_s'].xmlText(),

View File

@ -99,6 +99,30 @@ functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
} }
} }
}, },
"enemy": {
"_leaf": false,
"_type": "object",
"_data": {
"getSpecials": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "怪物特殊属性的定义(获得怪物的特殊属性)"
},
"getDamageInfo": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "获得战斗伤害信息(实际伤害计算函数)"
},
"updateEnemys": {
"_leaf": true,
"_type": "textarea",
"_lint": true,
"_data": "更新怪物数据,可以在这里对怪物属性和数据进行动态更新"
}
}
},
"plugins": { "plugins": {
"_leaf": false, "_leaf": false,
"_type": "object", "_type": "object",

View File

@ -338,7 +338,7 @@ core.enemys.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef)
core.enemys.calDamage(enemy, hero_hp, hero_atk, hero_def, hero_mdef) core.enemys.calDamage(enemy, hero_hp, hero_atk, hero_def, hero_mdef)
计算战斗伤害实际返回的是上面getDamageInfo中伤害的数值。 获得在某个勇士属性下怪物伤害实际返回的是上面getDamageInfo中伤害的数值。
core.enemys.getCurrentEnemys(floorId) core.enemys.getCurrentEnemys(floorId)

View File

@ -509,6 +509,12 @@ name是可选的代表目标行走图的文件名。
如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。 如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。
### updateEnemys更新怪物数据
使用 `{"type": "updateEnemys"}` 可以动态修改怪物数据。
详见[怪物数据的动态修改](#怪物数据的动态修改)。
### sleep等待多少毫秒 ### sleep等待多少毫秒
等价于RMXP中的"等待x帧",不过是以毫秒来计算。 等价于RMXP中的"等待x帧",不过是以毫秒来计算。
@ -1591,25 +1597,33 @@ core.insertAction([
而在我们的存档中是不会对怪物数据进行存储的只会存各个变量和Flag因此我们需要在读档后根据变量或Flag来调整怪物数据。 而在我们的存档中是不会对怪物数据进行存储的只会存各个变量和Flag因此我们需要在读档后根据变量或Flag来调整怪物数据。
我们可以在脚本编辑中的`afterLoadData`进行处理。 我们可以在脚本编辑中的`updateEnemys`进行处理。
``` js ``` js
////// 读档事件后,载入事件前,可以执行的操作 ////// ////// 读档事件后,载入事件前,可以执行的操作 //////
"afterLoadData" : function(data) { "updateEnemys" : function () {
// 读档事件后,载入事件前,可以执行的操作 // 更新怪物数据,可以在这里对怪物属性和数据进行动态更新,详见文档——事件——怪物数据的动态修改
if (core.hasFlag("fengyin")) { // 如果存在封印flag为真 // 比如下面这个例子如果flag:xxx为真则将绿头怪的攻击设为100红头怪的金币设为20
core.material.enemys.blackKing.hp/=10; // 将怪物的血量变成原来的十分之一 // 推荐写变化后的具体数值,以免多次变化导致冲突
// ... /*
// 如果flag:xxx为真你也可以写其他判断语句比如core.hasItem(...)等等
if (core.hasFlag('xxx')) {
core.material.enemys.greenSlime.atk = 100;
core.material.enemys.redSlime.money = 20;
} }
// 同样难度分歧可以类似写 if (core.getFlag('hard', 0)==3) {... */
// 别忘了在事件中调用“更新怪物数据”事件!
} }
```
// 在封印时可以调用setValue将该flag置为真然后调用自定义脚本 core.afterLoadData() 即可。 当我们获得一个道具(或者触发某个事件等)后,需要在事件中调用“更新怪物数据”事件。
``` js
// 调用`updateEnemys`(更新怪物数据)事件就可以触发了
"x,y": [ "x,y": [
{"type": "setValue", "name": "flag:fengyin", "value": "true"}, // 封印 "将flag:xxx置为真就可以让怪物数据发生改变",
{"type": "function", "function": function() { // 手动调用自定义JS脚本 core.afterLoadData() {"type": "setValue", "name": "flag:xxx", "value": "true"}, // 将flag:xxx置为真
core.afterLoadData(); {"type": "updateEnemys"} // 更新怪物数据此时绿头怪攻击就会变成100了
}}
] ]
``` ```

View File

@ -244,6 +244,7 @@
<input type="button" value="数据区"/> <input type="button" value="数据区"/>
<input type="button" value="地图区"/> <input type="button" value="地图区"/>
<input type="button" value="素材库"/> <input type="button" value="素材库"/>
<input type="button" value="前往游戏" onclick="window.location='./index.html'"/>
</span> </span>
<div id="menuDiv"> <div id="menuDiv">
<div id="midMenu" style="display:none"> <div id="midMenu" style="display:none">
@ -268,10 +269,9 @@
<input type="button" value="保存地图" id='saveFloor'/> <input type="button" value="保存地图" id='saveFloor'/>
<span id='mobileeditdata' style="display:none"> <span id='mobileeditdata' style="display:none">
<input type="button" value="编辑"/> <input type="button" value="编辑"/>
<input type="button" value="显示完整名称"/> <input type="button" value="显示完整名称" style="display: none;"/>
<input type="button" value="显示完整注释"/> <input type="button" value="显示完整注释"/>
</span> </span>
<input type="button" value="前往游戏" onclick="window.location='./index.html'"/>
<!-- --> <!-- -->
<div id="bgSelect" v-cloak style="display:none"> <div id="bgSelect" v-cloak style="display:none">
<span>当前地板: </span> <span>当前地板: </span>

View File

@ -292,10 +292,7 @@ control.prototype.resetStatus = function(hero, hard, floorId, route, maps, value
core.values = core.clone(values); core.values = core.clone(values);
else core.values = core.clone(core.data.values); else core.values = core.clone(core.data.values);
core.flags = core.clone(core.data.flags);
core.events.initGame(); core.events.initGame();
} }
////// 开始游戏 ////// ////// 开始游戏 //////
@ -1663,14 +1660,14 @@ control.prototype.startReplay = function (list) {
////// 更改播放状态 ////// ////// 更改播放状态 //////
control.prototype.triggerReplay = function () { control.prototype.triggerReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (core.status.replay.pausing) this.resumeReplay(); if (core.status.replay.pausing) this.resumeReplay();
else this.pauseReplay(); else this.pauseReplay();
} }
////// 暂停播放 ////// ////// 暂停播放 //////
control.prototype.pauseReplay = function () { control.prototype.pauseReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
core.status.replay.pausing = true; core.status.replay.pausing = true;
core.updateStatusBar(); core.updateStatusBar();
@ -1679,7 +1676,7 @@ control.prototype.pauseReplay = function () {
////// 恢复播放 ////// ////// 恢复播放 //////
control.prototype.resumeReplay = function () { control.prototype.resumeReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
core.status.replay.pausing = false; core.status.replay.pausing = false;
core.updateStatusBar(); core.updateStatusBar();
@ -1689,7 +1686,7 @@ control.prototype.resumeReplay = function () {
////// 加速播放 ////// ////// 加速播放 //////
control.prototype.speedUpReplay = function () { control.prototype.speedUpReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
var toAdd = core.status.replay.speed>=3?3:core.status.replay.speed>=2?2:1; var toAdd = core.status.replay.speed>=3?3:core.status.replay.speed>=2?2:1;
core.status.replay.speed = parseInt(10*core.status.replay.speed + toAdd)/10; core.status.replay.speed = parseInt(10*core.status.replay.speed + toAdd)/10;
@ -1699,7 +1696,7 @@ control.prototype.speedUpReplay = function () {
////// 减速播放 ////// ////// 减速播放 //////
control.prototype.speedDownReplay = function () { control.prototype.speedDownReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
var toAdd = core.status.replay.speed>3?3:core.status.replay.speed>2?2:1; var toAdd = core.status.replay.speed>3?3:core.status.replay.speed>2?2:1;
core.status.replay.speed = parseInt(10*core.status.replay.speed - toAdd)/10; core.status.replay.speed = parseInt(10*core.status.replay.speed - toAdd)/10;
@ -1709,7 +1706,7 @@ control.prototype.speedDownReplay = function () {
////// 停止播放 ////// ////// 停止播放 //////
control.prototype.stopReplay = function () { control.prototype.stopReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
core.status.replay.toReplay = []; core.status.replay.toReplay = [];
core.status.replay.totalList = []; core.status.replay.totalList = [];
@ -1724,7 +1721,7 @@ control.prototype.stopReplay = function () {
////// 回退 ////// ////// 回退 //////
control.prototype.rewindReplay = function () { control.prototype.rewindReplay = function () {
if (core.status.event.id=='save') return; if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
if (!core.status.replay.pausing) { if (!core.status.replay.pausing) {
core.drawTip("请先暂停录像"); core.drawTip("请先暂停录像");
@ -1759,6 +1756,7 @@ control.prototype.rewindReplay = function () {
////// 回放时存档 ////// ////// 回放时存档 //////
control.prototype.saveReplay = function () { control.prototype.saveReplay = function () {
if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
if (!core.status.replay.pausing) { if (!core.status.replay.pausing) {
core.drawTip("请先暂停录像"); core.drawTip("请先暂停录像");
@ -1779,6 +1777,7 @@ control.prototype.saveReplay = function () {
////// 回放时查看怪物手册 ////// ////// 回放时查看怪物手册 //////
control.prototype.bookReplay = function () { control.prototype.bookReplay = function () {
if (core.status.event.id=='save' || core.status.event.id=='book') return;
if (!core.status.replay.replaying) return; if (!core.status.replay.replaying) return;
if (!core.status.replay.pausing) { if (!core.status.replay.pausing) {
core.drawTip("请先暂停录像"); core.drawTip("请先暂停录像");
@ -2331,7 +2330,8 @@ control.prototype.getStatus = function (statusName) {
////// 获得某个等级的名称 ////// ////// 获得某个等级的名称 //////
control.prototype.getLvName = function () { control.prototype.getLvName = function () {
if (core.status.hero.lv>core.firstData.levelUp.length) return core.status.hero.lv; if (!core.isset(core.firstData.levelUp) || core.status.hero.lv<=0
|| core.status.hero.lv>core.firstData.levelUp.length) return core.status.hero.lv;
return core.firstData.levelUp[core.status.hero.lv-1].name || core.status.hero.lv; return core.firstData.levelUp[core.status.hero.lv-1].name || core.status.hero.lv;
} }

View File

@ -171,10 +171,11 @@ core.prototype.init = function (coreData, callback) {
core.setLocalStorage('battleAnimate', false); core.setLocalStorage('battleAnimate', false);
} }
// core.initStatus.shops = core.firstData.shops; if (core.isset(core.firstData.shops)) {
core.firstData.shops.forEach(function (t) { core.firstData.shops.forEach(function (t) {
core.initStatus.shops[t.id] = t; core.initStatus.shops[t.id] = t;
}) })
}
core.dom.versionLabel.innerHTML = core.firstData.version; core.dom.versionLabel.innerHTML = core.firstData.version;
core.dom.logoLabel.innerHTML = core.firstData.title; core.dom.logoLabel.innerHTML = core.firstData.title;

View File

@ -4,9 +4,9 @@ function enemys() {
////// 初始化 ////// ////// 初始化 //////
enemys.prototype.init = function () { enemys.prototype.init = function () {
// 怪物属性初始化定义:
this.enemys = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80; this.enemys = enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80;
//delete(enemys_fcae963b_31c9_42b4_b48c_bb48d09f3f80); this.enemydata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.enemy;
this.enemydata.hasSpecial = function (a, b) {return core.enemys.hasSpecial(a, b)};
} }
////// 获得一个或所有怪物数据 ////// ////// 获得一个或所有怪物数据 //////
@ -41,129 +41,112 @@ enemys.prototype.hasSpecial = function (special, test) {
return false; 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 (enemyId) { enemys.prototype.getSpecialText = function (enemy) {
var enemy = core.material.enemys[enemyId]; // 移动到了脚本编辑 - getSpecials中
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
if (!core.isset(enemy)) return []; if (!core.isset(enemy)) return [];
var special = enemy.special; var special = enemy.special;
var text = []; var text = [];
if (this.hasSpecial(special, 1)) text.push("先攻");
if (this.hasSpecial(special, 2)) text.push("魔攻"); var specials=this.getSpecials();
if (this.hasSpecial(special, 3)) text.push("坚固"); if (core.isset(specials)) {
if (this.hasSpecial(special, 4)) text.push("2连击"); for (var i=0;i<specials.length;i++) {
if (this.hasSpecial(special, 5)) text.push("3连击"); if (this.hasSpecial(special, specials[i][0]))
if (this.hasSpecial(special, 6)) text.push((enemy.n||4)+"连击"); text.push(this.calContent(enemy, specials[i][1]));
if (this.hasSpecial(special, 7)) text.push("破甲"); }
if (this.hasSpecial(special, 8)) text.push("反击"); }
if (this.hasSpecial(special, 9)) text.push("净化");
if (this.hasSpecial(special, 10)) text.push("模仿");
if (this.hasSpecial(special, 11)) text.push("吸血");
if (this.hasSpecial(special, 12)) text.push("中毒");
if (this.hasSpecial(special, 13)) text.push("衰弱");
if (this.hasSpecial(special, 14)) text.push("诅咒");
if (this.hasSpecial(special, 15)) text.push("领域");
if (this.hasSpecial(special, 16)) text.push("夹击");
if (this.hasSpecial(special, 17)) text.push("仇恨");
if (this.hasSpecial(special, 18)) text.push("阻击");
if (this.hasSpecial(special, 19)) text.push("自爆");
if (this.hasSpecial(special, 20)) text.push("无敌");
if (this.hasSpecial(special, 21)) text.push("退化");
if (this.hasSpecial(special, 22)) text.push("固伤");
if (this.hasSpecial(special, 23)) text.push("重生");
return text; return text;
} }
////// 获得每个特殊属性的说明 ////// ////// 获得每个特殊属性的说明 //////
enemys.prototype.getSpecialHint = function (enemy, special) { 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(special)) {
if (!core.isset(specials)) return [];
var hints = []; var hints = [];
for (var i=1;i<100;i++) { for (var i=0;i<specials.length;i++) {
if (this.hasSpecial(enemy.special, i)) { if (this.hasSpecial(enemy, specials[i][0]))
var hint=this.getSpecialHint(enemy, i); hints.push(this.calContent(enemy, specials[i][1])+""+this.calContent(enemy, specials[i][2]));
if (hint!='')
hints.push(hint);
}
} }
return hints; return hints;
} }
switch (special) { if (!core.isset(specials)) return "";
case 1: return "先攻:怪物首先攻击"; for (var i=0;i<specials.length;i++) {
case 2: return "魔攻:怪物无视勇士的防御"; if (special == specials[i][0])
case 3: return "坚固勇士每回合最多只能对怪物造成1点伤害"; return this.calContent(enemy, specials[i][1])+""+this.calContent(enemy, specials[i][2]);
case 4: return "2连击怪物每回合攻击2次";
case 5: return "3连击怪物每回合攻击3次";
case 6: return (enemy.n||4)+"连击: 怪物每回合攻击"+(enemy.n||4)+"次";
case 7: return "破甲:战斗前,怪物附加角色防御的"+Math.floor(100*core.values.breakArmor||0)+"%作为伤害";
case 8: return "反击:战斗时,怪物每回合附加角色攻击的"+Math.floor(100*core.values.counterAttack||0)+"%作为伤害,无视角色防御";
case 9: return "净化:战斗前,怪物附加勇士魔防的"+core.values.purify+"倍作为伤害";
case 10: return "模仿:怪物的攻防和勇士攻防相等";
case 11: return "吸血:战斗前,怪物首先吸取角色的"+Math.floor(100*enemy.value||0)+"%生命作为伤害"+(enemy.add?",并把伤害数值加到自身生命上":"");
case 12: return "中毒:战斗后,勇士陷入中毒状态,每一步损失生命"+core.values.poisonDamage+"点";
case 13: return "衰弱:战斗后,勇士陷入衰弱状态,攻防暂时下降"+(core.values.weakValue>=1?core.values.weakValue+"点":parseInt(core.values.weakValue*100)+"%");
case 14: return "诅咒:战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验";
case 15: return "领域:经过怪物周围"+(enemy.range||1)+"格时自动减生命"+(enemy.value||0)+"点";
case 16: return "夹击:经过两只相同的怪物中间,勇士生命值变成一半";
case 17: return "仇恨:战斗前,怪物附加之前积累的仇恨值作为伤害"+(core.flags.hatredDecrease?";战斗后,释放一半的仇恨值":"")+"。(每杀死一个怪物获得"+(core.values.hatred||0)+"点仇恨值)";
case 18: return "阻击:经过怪物的十字领域时自动减生命"+(enemy.value||0)+"点,同时怪物后退一格";
case 19: return "自爆战斗后勇士的生命值变成1";
case 20: return "无敌:勇士无法打败怪物,除非拥有十字架";
case 21: return "退化:战斗后勇士永久下降"+(enemy.atkValue||0)+"点攻击和"+(enemy.defValue||0)+"点防御";
case 22: return "固伤:战斗前,怪物对勇士造成"+(enemy.damage||0)+"点固定伤害,无视勇士魔防。";
case 23: return "重生:怪物被击败后,角色转换楼层则怪物将再次出现";
default: break;
} }
return ""; return "";
} }
////// 能否获胜 ////// ////// 能否获胜 //////
enemys.prototype.canBattle = function (monsterId) { enemys.prototype.canBattle = function (enemyId) {
var damage = this.getDamage(monsterId); var damage = this.getDamage(enemyId);
return damage != null && damage < core.status.hero.hp; return damage != null && damage < core.status.hero.hp;
} }
////// 获得某个怪物的伤害 ////// ////// 获得某个怪物的伤害 //////
enemys.prototype.getDamage = function (monsterId) { enemys.prototype.getDamage = function (enemy) {
var monster = core.material.enemys[monsterId]; if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var damage = this.calDamage(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); var damage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef);
if (damage == null) return null; if (damage == null) return null;
return damage + this.getExtraDamage(monster); return damage + this.getExtraDamage(enemy);
} }
////// 获得某个怪物的额外伤害 ////// ////// 获得某个怪物的额外伤害 //////
enemys.prototype.getExtraDamage = function (monster) { enemys.prototype.getExtraDamage = function (enemy) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var extra_damage = 0; var extra_damage = 0;
if (this.hasSpecial(monster.special, 17)) { // 仇恨 if (this.hasSpecial(enemy.special, 17)) { // 仇恨
extra_damage += core.getFlag('hatred', 0); extra_damage += core.getFlag('hatred', 0);
} }
if (this.hasSpecial(monster.special, 22)) { // 固伤 if (this.hasSpecial(enemy.special, 22)) { // 固伤
extra_damage += monster.damage||0; extra_damage += enemy.damage||0;
} }
return extra_damage; return extra_damage;
} }
////// 接下来N个临界值和临界减伤计算 ////// ////// 接下来N个临界值和临界减伤计算 //////
enemys.prototype.nextCriticals = function (monsterId, number) { enemys.prototype.nextCriticals = function (enemy, number) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
var useTurn = true; // 是否使用回合法计算临界值如果要用循环法则直接改为false。 var useTurn = !core.flags.useLoop; // 是否使用回合法计算临界值如果要用循环法则直接改为false。
number = number||1; number = number||1;
var monster = core.material.enemys[monsterId];
if (this.hasSpecial(monster.special, 3)) { if (this.hasSpecial(enemy.special, 3)) {
if (core.status.hero.atk<=monster.def) { if (core.status.hero.atk<=enemy.def) {
return [[monster.def+1-core.status.hero.atk,'?']]; return [[enemy.def+1-core.status.hero.atk,'?']];
} }
return []; return [];
} }
// 坚固、模仿怪物没有临界! // 坚固、模仿怪物没有临界!
if (this.hasSpecial(monster.special, 10)) return []; if (this.hasSpecial(enemy.special, 10)) return [];
var info = this.getDamageInfo(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); var info = this.getDamageInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef);
if (info == null) { if (info == null) {
if (core.status.hero.atk<=monster.def) { if (core.status.hero.atk<=enemy.def) {
return [[monster.def+1-core.status.hero.atk,'?']]; return [[enemy.def+1-core.status.hero.atk,'?']];
} }
return []; return [];
} }
@ -173,14 +156,14 @@ enemys.prototype.nextCriticals = function (monsterId, number) {
} }
var list = [], pre = null; var list = [], pre = null;
var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = monster.def, turn = info.turn; var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = enemy.def, turn = info.turn;
if (useTurn) { // 回合数计算法 if (useTurn) { // 回合数计算法
for (var t = turn-1;t>=1;t--) { for (var t = turn-1;t>=1;t--) {
var nextAtk = Math.ceil(mon_hp/t) + mon_def; var nextAtk = Math.ceil(mon_hp/t) + mon_def;
if (nextAtk<=hero_atk) break; if (nextAtk<=hero_atk) break;
if (nextAtk!=pre) { if (nextAtk!=pre) {
var nextInfo = this.getDamageInfo(monster, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef); var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef);
if (nextInfo==null) break; if (nextInfo==null) break;
list.push([nextAtk-hero_atk,info.damage-nextInfo.damage]); list.push([nextAtk-hero_atk,info.damage-nextInfo.damage]);
if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break; if (nextInfo.damage<=0 && !core.flags.enableNegativeDamage) break;
@ -193,7 +176,7 @@ enemys.prototype.nextCriticals = function (monsterId, number) {
else { // 暴力for循环法 else { // 暴力for循环法
pre = info.damage; pre = info.damage;
for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) { for (var atk=hero_atk+1;atk<=mon_hp+mon_def;atk++) {
var nextInfo = this.getDamageInfo(monster, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef); var nextInfo = this.getDamageInfo(enemy, core.status.hero.hp, atk, core.status.hero.def, core.status.hero.mdef);
if (nextInfo==null) break; if (nextInfo==null) break;
if (pre>nextInfo.damage) { if (pre>nextInfo.damage) {
pre = nextInfo.damage; pre = nextInfo.damage;
@ -208,115 +191,34 @@ enemys.prototype.nextCriticals = function (monsterId, number) {
} }
////// N防减伤计算 ////// ////// N防减伤计算 //////
enemys.prototype.getDefDamage = function (monsterId, k) { enemys.prototype.getDefDamage = function (enemy, k) {
if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
k = k || 1; k = k || 1;
var monster = core.material.enemys[monsterId]; var nowDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef);
var nowDamage = this.calDamage(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); var nextDamage = this.calDamage(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def + k, core.status.hero.mdef);
var nextDamage = this.calDamage(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def + k, core.status.hero.mdef);
if (nowDamage == null || nextDamage ==null) return "???"; if (nowDamage == null || nextDamage ==null) return "???";
return nowDamage - nextDamage; return nowDamage - nextDamage;
} }
////// 获得战斗伤害信息 ////// ////// 获得战斗伤害信息(实际伤害计算函数) //////
enemys.prototype.getDamageInfo = function(monster, hero_hp, hero_atk, hero_def, hero_mdef) { enemys.prototype.getDamageInfo = function(enemy, hero_hp, hero_atk, hero_def, hero_mdef) {
// 移动到了脚本编辑 - getDamageInfo中
if (typeof monster == 'string') { if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
monster = core.material.enemys[monster]; return this.enemydata.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef);
} }
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def, mon_special = monster.special; ////// 获得在某个勇士属性下怪物伤害 //////
hero_hp=Math.max(0, hero_hp); enemys.prototype.calDamage = function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) {
hero_atk=Math.max(0, hero_atk); if (typeof enemy == 'string') enemy = core.material.enemys[enemy];
hero_def=Math.max(0, hero_def);
hero_mdef=Math.max(0, hero_mdef);
if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross")) // 如果是无敌属性,且勇士未持有十字架 var info = this.getDamageInfo(enemy, hero_hp, hero_atk, hero_def, hero_mdef);
return null; // 返回不可战斗
var initDamage = 0; // 战前伤害
// 吸血
if (this.hasSpecial(mon_special, 11)) {
var vampireDamage = hero_hp * monster.value;
// 如果有神圣盾免疫吸血等可以在这里写
vampireDamage = Math.floor(vampireDamage) || 0;
// 加到自身
if (monster.add) // 如果加到自身
mon_hp += vampireDamage;
initDamage += vampireDamage;
}
// 模仿
if (this.hasSpecial(mon_special,10)) {
mon_atk = hero_atk;
mon_def = hero_def;
}
// 坚固
if (this.hasSpecial(mon_special,3) && mon_def < hero_atk - 1) mon_def = hero_atk - 1;
if (hero_atk <= mon_def) return null; // 不可战斗时请直接返回null
var per_damage = mon_atk - hero_def;
// 魔攻
if (this.hasSpecial(mon_special,2)) per_damage = mon_atk;
if (per_damage < 0) per_damage = 0;
// 2连击 & 3连击 & N连击
if (this.hasSpecial(mon_special, 4)) per_damage *= 2;
if (this.hasSpecial(mon_special, 5)) per_damage *= 3;
if (this.hasSpecial(mon_special, 6)) per_damage *= (monster.n||4);
var counterDamage = 0;
// 反击
if (this.hasSpecial(mon_special, 8)) counterDamage += Math.floor(core.values.counterAttack * hero_atk);
// 先攻
if (this.hasSpecial(mon_special, 1))
initDamage += per_damage;
// 破甲
if (this.hasSpecial(mon_special, 7))
initDamage += Math.floor(core.values.breakArmor * hero_def);
// 净化
if (this.hasSpecial(mon_special, 9))
initDamage += Math.floor(core.values.purify * hero_mdef);
// turn: 勇士攻击回合数
var turn = Math.ceil(mon_hp / (hero_atk - mon_def));
var ans = initDamage + (turn - 1) * per_damage + turn * counterDamage;
ans -= hero_mdef;
if (!core.flags.enableNegativeDamage)
ans=Math.max(0, ans);
return {
"hero_atk": hero_atk,
"hero_def": hero_def,
"hero_mdef": hero_mdef,
"mon_hp": mon_hp,
"mon_atk": mon_atk,
"mon_def": mon_def,
"per_damage": per_damage,
"initDamage": initDamage,
"turn": turn,
"damage": ans
};
}
////// 具体的伤害计算公式 //////
enemys.prototype.calDamage = function (monster, hero_hp, hero_atk, hero_def, hero_mdef) {
if (typeof monster == 'string') {
monster = core.material.enemys[monster];
}
var info = this.getDamageInfo(monster, hero_hp, hero_atk, hero_def, hero_mdef);
if (info == null) return null; if (info == null) return null;
return info.damage; return info.damage;
}
////// 更新怪物数据 //////
enemys.prototype.updateEnemys = function () {
return this.enemydata.updateEnemys();
} }
////// 获得当前楼层的怪物列表 ////// ////// 获得当前楼层的怪物列表 //////
@ -328,42 +230,42 @@ enemys.prototype.getCurrentEnemys = function (floorId) {
for (var b = 0; b < mapBlocks.length; b++) { for (var b = 0; b < mapBlocks.length; b++) {
if (core.isset(mapBlocks[b].event) && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable) if (core.isset(mapBlocks[b].event) && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)
&& mapBlocks[b].event.cls.indexOf('enemy')==0) { && mapBlocks[b].event.cls.indexOf('enemy')==0) {
var monsterId = mapBlocks[b].event.id; var enemyId = mapBlocks[b].event.id;
if (core.isset(used[monsterId])) continue; if (core.isset(used[enemyId])) continue;
var monster = core.material.enemys[monsterId]; var enemy = core.material.enemys[enemyId];
var mon_hp = monster.hp, mon_atk = monster.atk, mon_def = monster.def; var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def;
if (this.hasSpecial(monster.special, 10)) { if (this.hasSpecial(enemy.special, 10)) {
mon_atk=core.status.hero.atk; mon_atk=core.status.hero.atk;
mon_def=core.status.hero.def; mon_def=core.status.hero.def;
} }
if (this.hasSpecial(monster.special, 3) && mon_def < core.status.hero.atk - 1) if (this.hasSpecial(enemy.special, 3) && mon_def < core.status.hero.atk - 1)
mon_def = core.status.hero.atk - 1; mon_def = core.status.hero.atk - 1;
var specialText = core.enemys.getSpecialText(monsterId); var specialText = core.enemys.getSpecialText(enemyId);
if (specialText.length>=3) specialText = "多属性..."; if (specialText.length>=3) specialText = "多属性...";
else specialText = specialText.join(" "); else specialText = specialText.join(" ");
var critical = this.nextCriticals(monsterId); var critical = this.nextCriticals(enemyId);
if (critical.length>0) critical=critical[0]; if (critical.length>0) critical=critical[0];
enemys.push({ enemys.push({
'id': monsterId, 'id': enemyId,
'name': monster.name, 'name': enemy.name,
'hp': mon_hp, 'hp': mon_hp,
'atk': mon_atk, 'atk': mon_atk,
'def': mon_def, 'def': mon_def,
'money': monster.money, 'money': enemy.money,
'experience': monster.experience, 'experience': enemy.experience,
'point': monster.point||0, // 加点 'point': enemy.point||0, // 加点
'special': specialText, 'special': specialText,
'damage': this.getDamage(monsterId), 'damage': this.getDamage(enemyId),
'critical': critical[0], 'critical': critical[0],
'criticalDamage': critical[1], 'criticalDamage': critical[1],
'defDamage': this.getDefDamage(monsterId) 'defDamage': this.getDefDamage(enemyId)
}); });
used[monsterId] = true; used[enemyId] = true;
} }
} }

View File

@ -802,6 +802,11 @@ events.prototype.doAction = function() {
core.updateStatusBar(); core.updateStatusBar();
this.doAction(); this.doAction();
break; break;
case "updateEnemys":
core.enemys.updateEnemys();
core.updateStatusBar();
this.doAction();
break;
case "sleep": // 等待多少毫秒 case "sleep": // 等待多少毫秒
if (core.status.replay.replaying) if (core.status.replay.replaying)
core.events.doAction(); core.events.doAction();
@ -1376,7 +1381,8 @@ events.prototype.setHeroIcon = function (name) {
////// 检查升级事件 ////// ////// 检查升级事件 //////
events.prototype.checkLvUp = function () { events.prototype.checkLvUp = function () {
if (!core.flags.enableLevelUp || core.status.hero.lv>=core.firstData.levelUp.length) return; if (!core.flags.enableLevelUp || !core.isset(core.firstData.levelUp)
|| core.status.hero.lv>=core.firstData.levelUp.length) return;
// 计算下一个所需要的数值 // 计算下一个所需要的数值
var need=core.firstData.levelUp[core.status.hero.lv].need; var need=core.firstData.levelUp[core.status.hero.lv].need;
if (!core.isset(need)) return; if (!core.isset(need)) return;

View File

@ -1307,10 +1307,10 @@ ui.prototype.drawBook = function (index) {
damage = core.formatBigNumber(damage); damage = core.formatBigNumber(damage);
if (core.enemys.hasSpecial(core.material.enemys[enemy.id], 19)) if (core.enemys.hasSpecial(core.material.enemys[enemy.id], 19))
damage += "+"; damage += "+";
}
if (core.material.enemys[enemy.id].notBomb) if (core.material.enemys[enemy.id].notBomb)
damage += "[b]"; damage += "[b]";
}
core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px Verdana'); core.fillText('ui', damage, damageOffset, 62 * i + 50, color, 'bold 13px Verdana');
core.canvas.ui.textAlign = "left"; core.canvas.ui.textAlign = "left";

View File

@ -152,9 +152,10 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
"enableNegativeDamage": false, "enableNegativeDamage": false,
"hatredDecrease": true, "hatredDecrease": true,
"betweenAttackCeil": false, "betweenAttackCeil": false,
"useLoop": false,
"startDirectly": false, "startDirectly": false,
"canOpenBattleAnimate": true, "canOpenBattleAnimate": true,
"showBattleAnimateConfirm": true, "showBattleAnimateConfirm": false,
"battleAnimate": false, "battleAnimate": false,
"displayEnemyDamage": true, "displayEnemyDamage": true,
"displayCritical": true, "displayCritical": true,

View File

@ -301,9 +301,145 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
////// 读档事件后,载入事件前,可以执行的操作 ////// ////// 读档事件后,载入事件前,可以执行的操作 //////
"afterLoadData" : function(data) { "afterLoadData" : function(data) {
// 读档事件后,载入事件前,可以执行的操作 // 读档事件后,载入事件前,可以执行的操作
// 可以在这里对怪物数据进行动态修改,详见文档——事件——怪物数据的动态修改 // 怪物数据的动态修改迁移到了“脚本编辑 - updateEnemys”中详见文档说明
core.enemys.updateEnemys();
}
},
"enemy": {
"getSpecials" : function() {
// 获得怪物的特殊属性,每一行定义一个特殊属性。
// 分为三项,第一项为该特殊属性的数字,第二项为特殊属性的名字,第三项为特殊属性的描述
// 可以直接写字符串也可以写个function将怪物传进去
return [
[1, "先攻", "怪物首先攻击"],
[2, "魔攻", "怪物无视勇士的防御"],
[3, "坚固", "勇士每回合最多只能对怪物造成1点伤害"],
[4, "2连击", "怪物每回合攻击2次"],
[5, "3连击", "怪物每回合攻击3次"],
[6, function(enemy) {return (enemy.n||4)+"连击";}, function(enemy) {return "怪物每回合攻击"+(enemy.n||4)+"次";}],
[7, "破甲", "战斗前,怪物附加角色防御的"+Math.floor(100*core.values.breakArmor||0)+"%作为伤害"],
[8, "反击", "战斗时,怪物每回合附加角色攻击的"+Math.floor(100*core.values.counterAttack||0)+"%作为伤害,无视角色防御"],
[9, "净化", "战斗前,怪物附加勇士魔防的"+core.values.purify+"倍作为伤害"],
[10, "模仿", "怪物的攻防和勇士攻防相等"],
[11, "吸血", function (enemy) {return "吸血:战斗前,怪物首先吸取角色的"+Math.floor(100*enemy.value||0)+"%生命作为伤害"+(enemy.add?",并把伤害数值加到自身生命上":"");}],
[12, "中毒", "战斗后,勇士陷入中毒状态,每一步损失生命"+core.values.poisonDamage+"点"],
[13, "衰弱", "战斗后,勇士陷入衰弱状态,攻防暂时下降"+(core.values.weakValue>=1?core.values.weakValue+"点":parseInt(core.values.weakValue*100)+"%")],
[14, "诅咒", "战斗后,勇士陷入诅咒状态,战斗无法获得金币和经验"],
[15, "领域", function (enemy) {return "经过怪物周围"+(enemy.range||1)+"格时自动减生命"+(enemy.value||0)+"点";}],
[16, "夹击", "经过两只相同的怪物中间,勇士生命值变成一半"],
[17, "仇恨", "战斗前,怪物附加之前积累的仇恨值作为伤害"+(core.flags.hatredDecrease?";战斗后,释放一半的仇恨值":"")+"。(每杀死一个怪物获得"+(core.values.hatred||0)+"点仇恨值)"],
[18, "阻击", function (enemy) {return "经过怪物的十字领域时自动减生命"+(enemy.value||0)+"点,同时怪物后退一格";}],
[19, "自爆", "战斗后勇士的生命值变成1"],
[20, "无敌", "勇士无法打败怪物,除非拥有十字架"],
[21, "退化", function (enemy) {return "战斗后勇士永久下降"+(enemy.atkValue||0)+"点攻击和"+(enemy.defValue||0)+"点防御";}],
[22, "固伤", function (enemy) {return "战斗前,怪物对勇士造成"+(enemy.damage||0)+"点固定伤害,无视勇士魔防。";}],
[23, "重生", "怪物被击败后,角色转换楼层则怪物将再次出现"]
];
},
"getDamageInfo" : function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) {
// 获得战斗伤害信息(实际伤害计算函数)
// 怪物生命,怪物攻击、防御、特殊属性
var mon_hp = enemy.hp, mon_atk = enemy.atk, mon_def = enemy.def, mon_special = enemy.special;
// 勇士的负属性都按0计算
hero_hp=Math.max(0, hero_hp); hero_atk=Math.max(0, hero_atk); hero_def=Math.max(0, hero_def); hero_mdef=Math.max(0, hero_mdef);
// 如果是无敌属性,且勇士未持有十字架
if (this.hasSpecial(mon_special, 20) && !core.hasItem("cross"))
return null; // 不可战斗
// 战前造成的额外伤害(可被魔防抵消)
var init_damage = 0;
// 吸血
if (this.hasSpecial(mon_special, 11)) {
var vampire_damage = hero_hp * enemy.value;
// 如果有神圣盾免疫吸血等可以在这里写
// if (core.hasFlag('shield5')) vampire_damage = 0;
vampire_damage = Math.floor(vampire_damage) || 0;
// 加到自身
if (enemy.add) // 如果加到自身
mon_hp += vampire_damage;
init_damage += vampire_damage;
}
// 模仿
if (this.hasSpecial(mon_special, 10)) {
mon_atk = hero_atk;
mon_def = hero_def;
}
// 坚固
if (this.hasSpecial(mon_special, 3) && mon_def < hero_atk - 1)
mon_def = hero_atk - 1;
// 检查是否破防;否则直接返回不可战斗
if (hero_atk <= mon_def) return null;
// 每回合怪物对勇士造成的战斗伤害
var per_damage = mon_atk - hero_def;
// 魔攻:战斗伤害就是怪物攻击力
if (this.hasSpecial(mon_special, 2)) per_damage = mon_atk;
// 战斗伤害不能为负值
if (per_damage < 0) per_damage = 0;
// 2连击 & 3连击 & N连击
if (this.hasSpecial(mon_special, 4)) per_damage *= 2;
if (this.hasSpecial(mon_special, 5)) per_damage *= 3;
if (this.hasSpecial(mon_special, 6)) per_damage *= (enemy.n||4);
// 每回合的反击伤害;反击是按照勇士的攻击次数来计算回合
var counterDamage = 0;
if (this.hasSpecial(mon_special, 8)) counterDamage += Math.floor(core.values.counterAttack * hero_atk);
// 先攻
if (this.hasSpecial(mon_special, 1)) init_damage += per_damage;
// 破甲
if (this.hasSpecial(mon_special, 7))
init_damage += Math.floor(core.values.breakArmor * hero_def);
// 净化
if (this.hasSpecial(mon_special, 9))
init_damage += Math.floor(core.values.purify * hero_mdef);
// 勇士每回合对怪物造成的伤害
var hero_per_damage = hero_atk - mon_def;
// 勇士的攻击回合数;为怪物生命除以每回合伤害向上取整
var turn = Math.ceil(mon_hp / hero_per_damage);
// 最终伤害:初始伤害 + 怪物对勇士造成的伤害 + 反击伤害
var damage = init_damage + (turn - 1) * per_damage + turn * counterDamage;
// 再扣去魔防
damage -= hero_mdef;
// 检查是否允许负伤
if (!core.flags.enableNegativeDamage)
damage=Math.max(0, damage);
return {
"mon_hp": mon_hp,
"mon_atk": mon_atk,
"mon_def": mon_def,
"init_damage": init_damage,
"per_damage": per_damage,
"hero_per_damage": hero_per_damage,
"turn": turn,
"damage": damage
};
},
"updateEnemys" : function () {
// 更新怪物数据,可以在这里对怪物属性和数据进行动态更新,详见文档——事件——怪物数据的动态修改
// 比如下面这个例子如果flag:xxx为真则将绿头怪的攻击设为100金币设为20
/*
if (core.hasFlag('xxx')) {
core.material.enemys.greenSlime.atk = 100;
core.material.enemys.greenSlime.money = 20;
}
*/
// 别忘了在事件中调用“更新怪物数据”事件!
} }
}, },
"ui":{ "ui":{

View File

@ -1,4 +1,15 @@
HTML5魔塔样板V2.3.2 HTML5魔塔样板V2.3.3
将怪物特殊属性定义和伤害计算函数移动到脚本编辑中 √
事件:画面震动
事件:更新怪物数据
移动事件和跳跃事件增加“不消失”选项 √
修复读档开启战斗动画等Bug √
大量细节优化 √
-----------------------------------------------------------------------
HTML5魔塔样板V2.3.2
适配手机端的造塔页面 适配手机端的造塔页面
启动服务的多开版本 启动服务的多开版本