饰品
饰品也是很简单滴。
它除了需要一个基本物品的属性之外,也就多那么点东西。以下都在 SetDefaults
中:
Item.accessory = true; // 将物品标记为饰品,会让这个物品可以装备在饰品栏,同时物品的介绍上也会显示“可装备”字样 Item.defense = 10; // 装备了可以增加10点防御力,这一般是盾牌类型的才写 // Item.expert = true; 物品是专家模式及以上独有的,会改变物品的稀有度变成专家稀有度(彩虹渐变色) // Item.expertOnly = true; 饰品在专家难度以下不会生效,这不影响使用只影响装备效果,你在经典模式装备该饰品就会有一个红叉号并且属性无效 // Item.master = true; 大师独有,改变稀有度为大师(金红渐变色) // Item.masterOnly = true; 仅大师难度以上生效
好的饰品写完了!本篇结束了!
咳,如果只是如此,那这个饰品也太单调了。
再来加些东西吧。
UpdateAccessory
饰品的核心函数,在装备时触发,它提供玩家实例和一个叫 hideVisual
的 bool
参数,是说你是否关掉了饰品可见性。你可以用这个重写函数来给玩家写加成,或者是减益?
public override void UpdateAccessory(Player player, bool hideVisual) { player.lifeRegen += 10; // 玩家生命回复增加 10 / 2 = 5点每秒 player.GetDamage(DamageClass.Generic) += 0.1f; // 玩家全伤害增加10% player.GetAttackSpeed(DamageClass.Melee) -= 0.1f; // 玩家近战攻速减少10% if (hideVisual) player.GetCritChance(DamageClass.Magic) += 20f; // 玩家魔法暴击率增加20%,当关掉饰品可见性时 }
Wow,你应该注意到这些Get的方法了,它们的参数是伤害类型。
玩家部分属性
玩家的属性有很多,教程中无法一一列举出来,这里就放出一些常用的属性。你们应该熟练运用vs的自动补全并且靠着英文意思和实际测试去探索更多的属性。
字段名 | 值类型 | 描述 |
---|---|---|
statLife | int | 玩家当前生命值 |
statLifeMax | int | 生命上限的基准,生命水晶和生命果加的是这个 |
statLifeMax2 | int | 临时的生命上限,生命力药水和饰品效果用这个 |
lifeRegen | int | 每两秒的生命回复量 |
lifeRegenTime | int | 开始生命回复的速率,加的越多就越快开始生命回复 |
statDefense | int | 玩家防御力 |
endurance | float | 玩家伤害减免,蠕虫围巾是 += 0.17f,增加17% |
statMana | int | 玩家当前魔力 |
statManaMax | int | 魔力上限基准,@魔力水晶 |
statManaMax2 | int | 魔力临时上限 |
manaRegen | int | 每两秒的魔力回复量 |
manaCost | float | 魔力消耗率, += 0.05f 就是增加5%魔力消耗 |
noKnockback | bool | 为true则玩家不会被击退 @钴蓝盾 |
noFallDmg | bool | 为true则玩家不会受到摔落伤害 @马蹄铁 |
moveSpeed | float | 玩家水平移速 |
maxRunSpeed | float | 玩家水平移速上限 |
runAcceleration | float | 玩家水平移动加速度 |
runSlowdown | float | 玩家不控制水平移动的减速度 |
maxMinions | int | 玩家的最大召唤栏 |
numMinions | int | 玩家召唤了多少个召唤物 |
slotsMinions | float | 玩家使用了多少召唤栏(双子魔眼2个占1栏) |
翅膀
翅膀是比较特殊的饰品,参数也多,贴图要两份,还得给它打标()
先按着之前学过的知识来创建一个翅膀饰品的文件吧。
你应该注意到不一样的东西了—— [AutoloadEquip(EquipType.Wings)]
Attribute
这个其实是一个C#里面叫做 Attribute
的东西,我们可以理解为给这个类打上一个标记,这样TML读到这个类的时候就会知道这是个翅膀。注意到我们之前的那个帧图贴图了吗,为什么它要有一个后缀_Wings
,就是因为打了Wings标记的类需要一个Wings帧图,而且这个帧图名字必须匹配且必须有正好4帧。
有关翅膀,在 SetDefaults
中跟其他饰品没有区别,但是 UpdateAcc
中要多写一个属性:
public override void UpdateAccessory(Player player, bool hideVisual) { player.wingTimeMax = 180; // 玩家的最大飞行时间,3s // player.wingTime = player.wingTimeMax; 这样写会导致每帧你的剩余飞行时间都被重置为最大值,然后你就无限飞行了 }
写了就能飞,不过这个最大飞行时间不等于实际飞行时间,因为飞行时间的消耗速率在某些情况下不一样。
嗯,其实就是悬停消耗减半啦,然后喷气背包按住上升时是双倍消耗率。反正跟咱们没关系。
飞行参数
// 控制垂直飞行的函数 public override void VerticalWingSpeeds(Player player, ref float ascentWhenFalling, ref float ascentWhenRising, ref float maxCanAscendMultiplier, ref float maxAscentMultiplier, ref float constantAscend) { } // 控制水平飞行的函数 public override void HorizontalWingSpeeds(Player player, ref float speed, ref float acceleration) { }
这两个重写函数的参数比较多,它们是玩家在飞时每帧更新的。
先看 VerticalWingSpeeds
这个函数,Player就不说了,
ascentWhenFalling
这个属性是控制玩家在下落的时候开启翅膀的下落减速度(下落时爬升率),如果设为0那么下落的时候就需要比较长的时间才能上去;
ascentWhenRising
是玩家切换到上升状态时的爬升率;
maxCanAscendMultiplier
是,当 玩家上升速度 比 玩家跳跃速度*这个值 小 的时候,使用那个上升爬升率;
maxAscentMultiplier
是玩家可以到达的最大爬升率;
constantAscend
是正常飞行时翅膀的爬升率;
然后就是 HorizontalWingSpeeds
这个函数,speed
就是你一直按着方向键能到多快,acceleration
就是加速度啦。
不过水平速度上的控制还有另一种写法,同时这种写法也可以选择让翅膀是否能悬停。
WingStats
噢,IDSet要来力!注意,因为是写在SSD,所以这个玩意是不会像上面两个函数一样每帧更新的。
public override void SetStaticDefaults() { ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats( /*键入参数*/ ); }
WingStats
,这是一个结构体,来看看它的构造方法。
前三个参数分别是,飞行时间,水平最大速度,水平加速度。
后面三个是重点,它们分别是:可否悬停,平飞最大速度,平飞加速度。想想星盘,它用平飞那真不是一般的快。
// eg. // ArmorIDs.Wing.Sets.Stats[Item.wingSlot] = new WingStats(180, 8, 4.5f, true, 16, 16); // 这样这个翅膀的水平机动力就和天界星盘的水平机动力一致了
名称 | 平飞最大速度 | 平飞加速度 |
---|---|---|
悬浮板 | 10 | 10 |
双足翼龙之翼 | 12 | 12 |
星云斗篷 | 12 | 12 |
星旋强化翼 | 12 | 12 |
天界星盘 | 16 | 16 |
这里是原版翅膀的数据,拿去参考吧,这里边就没有悬停的数据了。
关于悬停等一些飞行属性:,本篇教程中不完整,这里感谢裙友威瑟(@nether_wither)的补充:
盔甲
盔甲是更复杂的可装备物。嗯,我说的是噩梦一般的帧图
它分为头身腿三个部位,记得打标。这次的就不是 Wings
了:头盔 Head
,胸铠 Body
,腿甲 Legs
。
写上以上 Attribute
,TML会自动识别它们的类型,并让它们可装备。
还要记得要 在SetDefaults
中写上防御力嗷~
在套装/装备效果里面,我们要用UpdateEquip
这个重写函数来施加效果,而不是UpdateAccessory
,因为装备不具备饰品的一些特性。
UpdateEquip
public override void UpdateEquip(Player player) { // 免疫灼伤debuff player.buffImmune[BuffID.OnFire] = true; // 增加生命上限50 player.statLifeMax2 += 50; // 增加2点生命恢复,虽然看起来不多,其实在游戏里还挺可观的 player.lifeRegen += 2; }
套装效果
套装效果是盔甲的一大特色,这里涉及到两个重写函数,一个用于判定,一个用于生效效果。
想想原版的神圣套,它使用头盔的类型来区分职业类型。所以,我们把套装判定写在头盔中。你应该不会想准备很多种胸铠的贴图吧?画师会掐死你的
IsArmorSet
在头盔中写上这个重写函数,用以判定玩家是否穿了套装,你们只要把判定里的物品类型改成自己的就好。
// 让头盔,胸甲,护腿全部都是模板装备的才能算是套装 public override bool IsArmorSet(Item head, Item body, Item legs) { // 这里没有判定头盔类型,因为玩家要穿着这个头盔才会执行这里的判定 return body.type == ModContent.ItemType<ExampleBreastplate>() && legs.type == ModContent.ItemType<ExampleLeggings>(); }
UpdateArmorSet
这是当上面那个 IsArmorSet
的返回值是 true
的时候才会执行的函数。
public override void UpdateArmorSet(Player player) { // 套装奖励描述,就是鼠标移上去最底下显示的套装效果 player.setBonus = "进一步增加回血速度,吸取红心范围增大\n" + "增加10%伤害减免"; player.endurance += 0.1f; player.lifeRegen += 2; player.lifeMagnet = true; // 加点特技,你们可以试试效果 //player.armorEffectDrawShadow = true; }
不过这个套装效果在头盔里写一次就够了,在三个盔甲里都写会发生什么呢?三倍Ice cream!!!
练习
基础
- 写一个看起来很nb但实际毫无作用的套装描述来逗逗玩家吧?答案
player.setBonus = "可装备" + "\n材料" + "\n100 防御力" + "\n“无论凡人或不朽,都承认你的神性”" + "\n暴击率设为50%" + "\n每次暴击提升10%" + "\n达到100%时所有攻击附带10%的生命偷取,增加5%伤害,增加5防御力" + "\n可叠加950次直到被攻击" + "\n额外获得:增加250%的伤害" + "\n增加100%的射击速度" + "\n增加25%的暴击率" + "\n暴击造成10倍伤害" + "\n所有武器击退翻倍并可自动连发" + "\n最大小黄人数量增加30" + "\n最大哨兵数量增加20" + "\n最大魔力值增加到999" + "\n最大生命恢复提升50%,增加40%伤害免疫,增加15生命回复" + "\n获得回击免疫和大部分减益" + "\n你会反弹所有射弹"; // 放进UpdateArmorSet重写函数就行
进阶
- 如何实现在装备某套装后,某个武器受到影响?
- 试着实现一下多头盔配一套盔甲和护腿吧!
- 试着实现一下上面所说的(基础问题1)盔甲效果吧!(别打我)
劝退
- 试着写一个套装,该套装的头盔为原版全头盔的效果之和,盔甲和护腿也是如此。而套装奖励则是每分钟随机挑选十个原版的套装奖励作为套装奖励。
坐等有人做出劝退(bushi
有没有方法让某个装备部位失效或者让套装效果失效(
翅膀那里设置成true了,但是不能悬停时什么原因
还有,帧图怎么画呀,照着抄的头盔移动时会从下朝上移动,看起来特别怪
现在装备特效的player.armorEffectDrawShadow = true;这玩意要写在public override void ArmorSetShadows(Player player){}里,写public override void UpdateArmorSet(Player player) {}里不起效(目移)
请问要怎么检测脱下饰品呢,
有没有类似于removeAccesory的钩子