Equipment Docs

This commit is contained in:
ckcz123 2018-09-17 18:19:34 +08:00
parent c00ae6e017
commit 2ab6661ab1
12 changed files with 172 additions and 50 deletions

View File

@ -40,7 +40,7 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
"equip": {
"_leaf": true,
"_type": "textarea",
"_data": "装备属性设置仅对cls为equips有效。\n如果此项不为null需要是一个对象里面可含\"type\"\"atk\"\"def\"\"mdef\"\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档和已有的几个装备的写法。"
"_data": "装备属性设置仅对cls为equips有效。\n如果此项不为null需要是一个对象里面可含\"type\"\"atk\"\"def\"\"mdef\"\"animate\"五项,分别对应装备部位、攻防魔防和动画。\n具体详见文档(元件说明-装备)和已有的几个装备的写法。"
},
}
},

View File

@ -72,8 +72,17 @@ core.setItem('pickaxe', 10)
将破墙镐个数设置为10个。这里可以写任何道具的ID。
core.addItem('pickaxe', 2)
将破墙镐的个数增加2个无任何特效。这里可以写任何道具的ID。
core.getItem('pickaxe', 4)
另勇士获得四个破墙镐。这里可以写任何道具的ID。
令勇士获得4个破墙镐。这里可以写任何道具的ID。
和addItem相比使用getItem会播放获得道具的音效也会在左上角绘制获得提示。
core.removeItem('pickaxe', 3)
删除3个破墙镐。第二项可忽略默认值为1。
core.itemCount('pickaxe')
@ -84,6 +93,15 @@ core.hasItem('pickaxe')
返回当前是否存在某个道具。等价于 core.itemCount('pickaxe')>0 。
core.getEquip(0)
获得0号装备类型武器的当前装备的itemId。如果不存在则返回null。
这里可以写任意装备类型从0开始和全塔属性中的equipName一一对应。
core.hasEquip('sword1')
获得当前某个具体的装备是否处于正在被装备状态。
core.setFlag('xyz', 2)
设置某个flag/变量的值为2。这里可以写任何的flag变量名。
@ -229,12 +247,12 @@ core.canUseItem(itemId)
返回当前能否使用某个道具。
core.addItem(itemId, number)
将某个道具增加number个
core.loadEquip(itemId, callback)
装备上某个装备。itemId为装备的IDcallback为成功或失败后的回调
core.removeItem(itemId)
将某个道具个数-1如果道具个数归0则从道具列表删除
core.unloadEquip(equipType, callback)
卸下某个部位的装备。equipType为装备类型从0开始callback为成功或失败后的回调
core.getNextItem()
@ -266,6 +284,11 @@ core.getLocalStorage(key, defaultValue)
从localStorage中获得某个数据已被parse如果对应的key不存在则返回defaultValue。
core.getLocalForage(key, defaultValue, successCallback, errorCallback)
从localForage中获得某个数据已被parse如果对应的key不存在则返回defaultValue。
如果成功则通过successCallback回调失败则通过errorCallback回调。
core.clone(data)
深拷贝某个对象。
@ -399,6 +422,10 @@ core.events.setHeroIcon(name)
items.js将处理和道具相关的内容比如道具的使用获取和删除等等。
core.items.compareEquipment(equipId1, equipId2)
比较两个装备的属性变化值
========== core.loader.XXX 和游戏加载相关的函数 ==========
loader.js将主要用来进行资源的加载比如加载音乐、图片、动画等等。

View File

@ -24,7 +24,58 @@
如果需要让剑盾等变成装备,可以直接在`data.js`中设置`'equipment': true`即可。
有关装备更为详细的资料可参见[自定义装备](personalization#自定义装备)的说明。
从V2.4.1开始HTML5魔塔样板终于拥有了属于自己的装备页面。
### 装备栏的设置,装备类型
在全塔属性中,有一个`equipName`项,其定义了本塔的所有可装备的装备栏。
其需要是一个不小于1且不大于6的数组其中每一项为装备栏的名称**建议是两个汉字**。
例如下面这种写法就是定义了四个装备孔,名称分别为武器、防御、首饰和魔杖。
``` js
"equipName": ["武器","防具","首饰","魔杖"]
```
这么定义好后装备类型即为每个装备孔的索引从0开始
武器的装备类型是0防御的装备类型是1首饰的装备类型是2魔杖的装备类型是3。
### 设置每个装备的属性
如果要将一个道具设置为装备,首先需要将其`cls`设为`equips`。
然后在图块属性的`equip`一项中设置装备的具体属性。该项写法如下:
``` js
{"type": 0, "atk": 0, "def": 0, "mdef"0, "animate": "hand"}
```
type为该装备的类型必填和上面装备栏一一对应。例如0就是武器2就是首饰等等。
atk/def/mdef为该装备分别增加的攻防魔防数值支持负数如果不加也可省略不写。
animate为该装备的攻击动画仅对type为0时有效。具体可参见[动画和天气系统](#动画和天气系统)。
下面是几个写法例子。
``` js
{"type": 0, "atk": 10} // 装备类型是武器,效果是攻击+10使用默认的攻击动画
{"type": 0, "atk": 40, "animate": "sword"} // 装备类型为武器,效果是攻击+10攻击动画是sword
{"type": 1, "def": 40} // 装备类型是防具,效果是防御+40
{"type": 1, "def": 100, "mdef": 100} // 装备类型是防具,效果是防御和魔防各+100
{"type": 3, "atk": -20, "def": 50, "mdef": 50} // 装备类型是魔杖,效果是攻击-20防御和魔防各+50
```
### 检测是否存在装备
可以使用`core.hasEquip(itemId)`来检测是否装上某个装备。
使用`core.hasItem(itemId)`来检测是否存在一个未装上的装备。
使用`core.getEquip(equipType)`来获得某个装备类型的当前装备。
更多相关API详见[附录API列表](api)。
## 门
@ -32,6 +83,8 @@
开门后可触发该层的`afterOpenDoor`事件,有关事件的详细介绍请参见第四章。
如果要新增自己的门,请参见[新增门和对应的钥匙](personalization#新增门和对应的钥匙)。
## 暗墙
本塔支持暗墙。
@ -139,16 +192,26 @@ N连击怪物的special是6且我们可以为它定义n代表实际连击数
领域怪还可以设置`range`选项代表该领域怪的范围不写则默认为1。
**将`flag:no_zone`设置为true可以取消领域效果。**
阻击怪同样需要设置value代表阻击伤害的数值。如果勇士生命值扣减到0则直接死亡触发lose事件。
**将`flag:no_snipe`设置为true可以取消阻击效果。**
!> 阻击怪后退的地点不能有任何事件存在,即使是已经被禁用的自定义事件!
激光怪同样需要设置value代表激光伤害的数值。
请注意如果吸血、领域、阻击中任何两个同时存在则value会冲突。**因此请勿将吸血、领域、阻击或激光放置在同一个怪物身上。**
**将`flag:no_laser`设置为true可以免疫激光效果。**
退化怪需要设置'atkValue'和'defValue'表示退化的数值也可以不设置默认为0。
夹击可以通过全塔属性中的`betweenAttackCeil`设为true可以将伤害向上取整。
**将`flag:no_betweenAttack`设置为true可以免疫夹击效果。**
固伤怪则需要设置`damage`选项,代表战前扣血数值。
如有额外需求,可参见[自定义怪物属性](personalization#自定义自定义怪物属性),里面讲了如何设置一个新的怪物属性。

View File

@ -308,25 +308,13 @@ function (enemy, hero_hp, hero_atk, hero_def, hero_mdef) {
}
// ... 下略
```
3. 免疫领域、夹击、阻击效果:在`control.js`中找到checkBlock函数并编辑成如果有神圣盾标记则将伤害变成0
3. 免疫领域、夹击、阻击效果:在2.4.1之后可以直接将flag:no_zone设为true来免疫领域效果其他几个同理
``` js
// 检查领域、夹击、阻击事件
control.prototype.checkBlock = function () {
var x=core.getHeroLoc('x'), y=core.getHeroLoc('y');
var damage = core.status.checkBlock.damage[x+core.bigmap.width*y];
if (damage>0) {
if (core.hasFlag("shield5")) damage = 0; // 如果存在神圣盾则将伤害变成0
core.status.hero.hp -= damage;
// 检查阻击事件
var snipe = [];
var scan = {
'up': {'x': 0, 'y': -1},
'left': {'x': -1, 'y': 0},
'down': {'x': 0, 'y': 1},
'right': {'x': 1, 'y': 0}
}
// ... 下略
// 同样写在道具的itemEffect中
core.setFlag("no_zone", true); // 免疫领域
core.setFlag("no_snipe", true); // 免疫阻击
core.setFlag("no_laser", true); // 免疫激光
core.setFlag("no_betweenAttack", true); // 免疫夹击
```
4. 如果有更高的需求,例如想让吸血效果变成一半,则还是在上面这些地方进行对应的修改即可。
@ -375,6 +363,7 @@ control.prototype.useFly = function (need) {
```
修改时,请先把`null`改成空字符串`""`,然后再双击进行编辑。
<!--
## 自定义装备
@ -449,6 +438,8 @@ this.useEquipment = function (itemId) { // 使用装备
!> 必须对于每一个装备部位定义唯一一个不同的ID脱掉装备空装备必须是该ID加数字0的形式其他有效装备必须是
该ID+正整数的形式,不然会出错!
-->
## 自定义怪物属性
如果你对现有的怪物不满意,想自行添加怪物属性也是可以的。具体参见脚本编辑-getSpecials。

View File

@ -201,6 +201,8 @@ HTML5的塔都是可以进行控制台调试的。
- `core.getItem('pickaxe', 2)` 令勇士获得两个破墙镐。
- `core.itemCount('pickaxe')` 返回勇士某个道具的个数。
- `core.hasItem('pickaxe')` 返回勇士是否拥有某个道具。等价于`core.itemCount('pickaxe')!=0`。
- `core.getEquip(0)` 返回0号装备类型武器的当前装备的itemId不存在则返回null
- `core.hasEquip('sword1')` 返回某个装备当前是否处于被装备状态
- `core.setFlag('xxx', 1)` 设置某个flag/自定义变量的值。
- `core.getFlag('xxx', 10)` 获得某个flag/自定义变量的值;如果该项不存在(未被定义),则返回第二个参数的值。
- `core.hasFlag('xxx')` 返回是否存在某个变量且不为0。等价于`core.getFlag('xxx', 0)!=0`。
@ -210,7 +212,6 @@ HTML5的塔都是可以进行控制台调试的。
- `core.getBlock(3, 5, 'MT1')` 获得当前地图上某一个块的信息。第三个参数为floorId可省略表示当前楼层。
- `core.getBlockId(3, 5, 'MT1')` 获得当前地图上某一个点的图块ID。第三个参数为floorId可省略表示当前楼层。
- `core.resetMap()` 重置当前层地图。**当修改地图后再读档修改的地图不会立刻生效此时可以使用resetMap来重置当前楼层的地图。**
- `localStorage` 获得所有的存档数据。可以用 `core.getLocalStorage('save1')` 来具体获得某个存档。
- ……
更多API和详细参数介绍可参见[API列表](api)。

View File

@ -1480,6 +1480,7 @@ actions.prototype.clickEquipboxIndex = function(index) {
if (index>=(main.equipName||[]).length) return;
if (index==core.status.event.selection && core.isset(core.status.hero.equipment[index])) {
core.unloadEquip(index);
core.status.route.push("unEquip:"+index);
}
}
else if (index>=12) {
@ -1487,6 +1488,7 @@ actions.prototype.clickEquipboxIndex = function(index) {
if (index==core.status.event.selection) {
var equipId = equips[index-12 + (core.status.event.data.page-1)*12];
core.loadEquip(equipId);
core.status.route.push("equip:"+equipId);
}
}
core.ui.drawEquipbox(index);

View File

@ -1860,6 +1860,7 @@ control.prototype.replay = function () {
var equipType = parseInt(action.substring(8));
if (core.isset(equipType)) {
core.ui.drawEquipbox(equipType);
core.status.route.push(action);
setTimeout(function () {
core.ui.closePanel();
core.unloadEquip(equipType, function () {
@ -1874,6 +1875,7 @@ control.prototype.replay = function () {
var ownEquipment = Object.keys(core.status.hero.items.equips).sort();
var index = ownEquipment.indexOf(equipId);
if (index>=0) {
core.status.route.push(action);
core.status.event.data = {"page":Math.floor(index/12)+1, "selectId":null};
index = index%12+12;
core.ui.drawEquipbox(index);
@ -2639,8 +2641,6 @@ control.prototype.updateStatusBar = function () {
core.statusBar.image.settings.src = core.statusBar.icons.settings.src;
}
core.updateDamage();
}
////// 屏幕分辨率改变后重新自适应 //////

View File

@ -834,8 +834,13 @@ core.prototype.hasItem = function (itemId) {
}
////// 是否装备某件装备 //////
core.prototype.hasEquip = function (equipId) {
return core.items.hasEquip(equipId);
core.prototype.hasEquip = function (itemId) {
return core.items.hasEquip(itemId);
}
////// 获得某个装备类型的当前装备 /////
core.prototype.getEquip = function (equipType) {
return core.items.getEquip(equipType);
}
////// 设置某个物品的个数 //////
@ -844,8 +849,8 @@ core.prototype.setItem = function (itemId, itemNum) {
}
////// 删除某个物品 //////
core.prototype.removeItem = function (itemId) {
return core.items.removeItem(itemId);
core.prototype.removeItem = function (itemId, itemNum) {
return core.items.removeItem(itemId, itemNum);
}
////// 使用某个物品 //////

View File

@ -97,17 +97,22 @@ items.prototype.hasItem = function (itemId) {
}
////// 是否装备某件装备 //////
items.prototype.hasEquip = function (equipId) {
items.prototype.hasEquip = function (itemId) {
if (!core.isset(equipId)) return null;
if (!core.isset((core.material.items[equipId]||{}).equip)) return null;
if (!core.isset(itemId)) return null;
if (!core.isset((core.material.items[itemId]||{}).equip)) return null;
var equiptype = core.material.items[equipId].equip.type;
return equipId == (core.status.hero.equipment||[])[equiptype];
return itemId == this.getEquip(core.material.items[itemId].equip.type);
}
////// 获得某个装备类型的当前装备 //////
items.prototype.getEquip = function (equipType) {
return (core.status.hero.equipment||[])[equipType]||null;
}
////// 设置某个物品的个数 //////
items.prototype.setItem = function (itemId, itemNum) {
itemNum = itemNum || 1;
var itemCls = core.material.items[itemId].cls;
if (itemCls == 'items') return;
if (!core.isset(core.status.hero.items[itemCls])) {
@ -120,11 +125,12 @@ items.prototype.setItem = function (itemId, itemNum) {
}
////// 删除某个物品 //////
items.prototype.removeItem = function (itemId) {
items.prototype.removeItem = function (itemId, itemNum) {
itemNum = itemNum || 1;
if (!core.hasItem(itemId)) return false;
var itemCls = core.material.items[itemId].cls;
core.status.hero.items[itemCls][itemId]--;
if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]==0) {
core.status.hero.items[itemCls][itemId]-=itemNum;
if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]<=0) {
delete core.status.hero.items[itemCls][itemId];
}
core.updateStatusBar();
@ -178,7 +184,7 @@ items.prototype.loadEquip = function (equipId, callback) {
core.updateStatusBar();
// 记录路线
core.status.route.push("equip:"+equipId);
// core.status.route.push("equip:"+equipId);
// 装备更换完毕:删除换上的装备
core.removeItem(equipId);
@ -217,7 +223,7 @@ items.prototype.unloadEquip = function (equipType, callback) {
core.updateStatusBar();
// 记录路线
core.status.route.push("unEquip:"+equipType);
// core.status.route.push("unEquip:"+equipType);
// 装备更换完毕:增加卸下的装备
core.addItem(unloadEquipId, 1);

View File

@ -1804,7 +1804,8 @@ ui.prototype.drawEquipbox = function(index) {
// 描述
if (core.isset(selectId)) {
var equip=core.material.items[selectId];
var equipType = (equip.equip||{}).type || 0;
if (!core.isset(equip.equip)) equip.equip = {"type": 0};
var equipType = equip.equip.type;
core.fillText('ui', equip.name + "" + (allEquips[equipType]||"未知部位") + "", 10, 32, '#FFD700', "bold 20px Verdana")
var text = equip.text||"该装备暂无描述。";

View File

@ -32,9 +32,8 @@ main.floors.sample0=
],
"events": {
"10,9": [
"\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为三类items, constants, tools。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\n\n后两类道具在工具栏中可以看到并使用。",
"\t[老人,man]这些是本样板支持的所有的道具。\n\n道具分为四类items, constants, toolsequips。\nitems 为即捡即用类道具,例如宝石、血瓶、剑盾等。\nconstants 为永久道具,例如怪物手册、楼层传送器、幸运金币等。\ntools 为消耗类道具,例如破墙镐、炸弹、中心对称飞行器等。\nequips 为装备,例如剑盾等。",
"\t[老人,man]\b[up]有关道具效果定义在items.js中。\n目前大多数道具已有默认行为如有自定义的需求则需在items.js中修改代码。",
"\t[老人,man]constants 和 tools 各最多只允许12种多了会导致图标溢出。",
"\t[老人,man]\b[up]拾取道具结束后可触发 afterGetItem 事件。\n\n有关事件的各种信息在下一层会有更为详细的说明。",
{
"type": "hide",

View File

@ -477,44 +477,60 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
core.setStatus('hp', Math.min(core.getStatus('hpmax'), core.getStatus('hp')));
}
// 更新领域、阻击、显伤
core.updateCheckBlock();
// 设置等级奴名称
var lvName = core.getLvName();
core.statusBar.lv.innerHTML = lvName;
// 检测是不是纯数字;如果带中文等需要取消斜体(不然很难看的!)
if (/^[+-]?\d+$/.test(lvName))
core.statusBar.lv.style.fontStyle = 'italic';
else core.statusBar.lv.style.fontStyle = 'normal';
// 设置生命上限、生命值、攻防魔防金币和经验值
var statusList = ['hpmax', 'hp', 'atk', 'def', 'mdef', 'money', 'experience'];
statusList.forEach(function (item) {
// 向下取整
if (core.isset(core.status.hero[item]))
core.status.hero[item] = Math.floor(core.status.hero[item]);
// 大数据格式化
core.statusBar[item].innerHTML = core.formatBigNumber(core.getStatus(item));
});
// 可以在这里添加自己额外的状态栏信息,比如想攻击显示 +0.5 可以这么写:
// if (core.hasFlag('halfAtk')) core.statusBar.atk.innerHTML += "+0.5";
// 如果是自定义添加的状态栏,也需要在这里进行设置显示的数值
// 进阶
if (core.flags.enableLevelUp && core.status.hero.lv<core.firstData.levelUp.length) {
core.statusBar.up.innerHTML = core.firstData.levelUp[core.status.hero.lv].need || " ";
}
else core.statusBar.up.innerHTML = " ";
// 钥匙
var keys = ['yellowKey', 'blueKey', 'redKey'];
keys.forEach(function (key) {
core.statusBar[key].innerHTML = core.setTwoDigits(core.status.hero.items.keys[key]);
})
});
// 毒衰咒
if(core.flags.enableDebuff){
core.statusBar.poison.innerHTML = core.hasFlag('poison')?"毒":"";
core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":"";
core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":"";
}
// 破炸飞
if (core.flags.enablePZF) {
core.statusBar.pickaxe.innerHTML = "破"+core.itemCount('pickaxe');
core.statusBar.bomb.innerHTML = "炸"+core.itemCount('bomb');
core.statusBar.fly.innerHTML = "飞"+core.itemCount('centerFly');
}
// 难度
core.statusBar.hard.innerHTML = core.status.hard;
// 更新阻激夹域的伤害值
core.updateCheckBlock();
// 更新全地图显伤
core.updateDamage();
},
"updateCheckBlock": function () {
// 领域、夹击、阻击等的伤害值计算
@ -549,6 +565,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
var id = core.status.checkBlock.map[x+core.bigmap.width*y];
if (core.isset(id)) {
// 如果是血网,直接加上伤害值
if (id=="lavaNet") {
core.status.checkBlock.damage[x+core.bigmap.width*y]+=core.values.lavaDamage||0;
continue;
@ -558,14 +575,18 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 存在领域
// 如果要防止领域伤害,可以直接简单的将 flag:no_zone 设为true
if (core.enemys.hasSpecial(enemy.special, 15) && !core.hasFlag("no_zone")) {
// 领域范围默认为1
var range = enemy.range || 1;
// 是否是九宫格领域
var zoneSquare = false;
if (core.isset(enemy.zoneSquare)) zoneSquare=enemy.zoneSquare;
// 在范围内进行搜索,增加领域伤害值
for (var dx=-range;dx<=range;dx++) {
for (var dy=-range;dy<=range;dy++) {
if (dx==0 && dy==0) continue;
var nx=x+dx, ny=y+dy;
if (nx<0 || nx>=core.bigmap.width || ny<0 || ny>=core.bigmap.height) continue;
// 如果是十字领域,则还需要满足 |dx|+|dy|<=range
if (!zoneSquare && Math.abs(dx)+Math.abs(dy)>range) continue;
core.status.checkBlock.damage[nx+ny*core.bigmap.width]+=enemy.value||0;
}
@ -574,6 +595,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 存在激光
// 如果要防止激光伤害,可以直接简单的将 flag:no_laser 设为true
if (core.enemys.hasSpecial(enemy.special, 24) && !core.hasFlag("no_laser")) {
// 检查同行和同列,增加激光伤害值
for (var nx=0;nx<core.bigmap.width;nx++) {
if (nx!=x) core.status.checkBlock.damage[nx+y*core.bigmap.width]+=enemy.value||0;
}
@ -603,7 +625,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
if (!core.hasFlag('no_betweenAttack')) {
for (var x=0;x<core.bigmap.width;x++) {
for (var y=0;y<core.bigmap.height;y++) {
// 该点是否存在夹击
var has=false;
// 检测左右是否存在相同的怪物,且拥有夹击属性
if (x>0 && x<core.bigmap.width-1) {
var id1=core.status.checkBlock.map[x-1+core.bigmap.width*y],
id2=core.status.checkBlock.map[x+1+core.bigmap.height*y];
@ -614,6 +638,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
}
}
}
// 检测上下是否存在相同的怪物,且拥有夹击属性
if (y>0 && y<core.bigmap.height-1) {
var id1=core.status.checkBlock.map[x+core.bigmap.width*(y-1)],
id2=core.status.checkBlock.map[x+core.bigmap.width*(y+1)];
@ -627,7 +652,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 计算夹击伤害
if (has) {
core.status.checkBlock.betweenAttack[x+core.bigmap.width*y]=true;
// 先扣除该点领域/阻击/激光造成的伤害,再算夹击
var leftHp = core.status.hero.hp - core.status.checkBlock.damage[x+core.bigmap.width*y];
// 1血不夹core.flags.betweenAttackCeil控制向上还是向下
if (leftHp>1)
core.status.checkBlock.damage[x+core.bigmap.width*y] += Math.floor((leftHp+(core.flags.betweenAttackCeil?0:1))/2);
}
@ -677,7 +704,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
// 在这里写所有需要自定义的函数
// 写法必须是 this.xxx = function (args) { ...
// 如果不写this的话函数将无法被外部所访问
this.test = function () {
this.test = function () {
console.log("插件函数执行测试");
}