这里是咕咕咕了好久的小天使,今天我来写转1.4的教程了。
首先我们需要看看1.4的tml改了什么。
点我去github上查看1.4tml的改变(有可能进不去,github就是这样神奇)
1.4的大致改变
那么我们首先就要知道1.4大概改了什么,这样才能避开因为1.4改了而找不到对应方法的坑。
命名规范
1.4tml的命名规范了,从原来的player这种全小写的属性变成了符合C#命名规范的写法:
mod
-> Mod
,
player
-> Player
(ModPlayer
里面的player),
npc
-> NPC
(ModNPC
里面的npc),
剩下的以此类推吧。
生成物品/弹幕/NPC等
1.4tml一个最直观的变化就是这个东西,因为生成物品/弹幕/NPC添加了一个新的参数,叫 source
,能填 source
的对应类很多,它们都继承自接口 IEntitySource
。
我这里大致的说出来在1.4如何去填写这些参数,让人能够好理解:
现在玩家/NPC/弹幕(只要是继承了 Entity
的)都可以通过对应方法,得到对应继承了 IEntitySource
的类,而获取这些类的方法的名字开头普遍为:GetSource_XXX
。
因为 IEntitySource
,物品的 Shoot
重写函数也要变个样子。
public override bool Shoot(Player player, EntitySource_ItemUse_WithAmmo source, Vector2 position, Vector2 velocity, int type, int damage, float knockback)
没有错,1.3tml的,带 ref
之类的没了,多了一行 EntitySource_ItemUse_WithAmmo source
,这个 source
是弹幕源自消耗子弹的,但是只要是写在 Shoot
里面的都是用 EntitySource_ItemUse_WithAmmo
的 source
,只不过这个 source
面的 AmmoID
为0。
虽然1.4tml的 Shoot
少了 ref
,但是1.4tml又多了一个新的重写函数:
public override void ModifyShootStats(Player player, ref Vector2 position, ref Vector2 velocity, ref int type, ref int damage, ref float knockback)
这一个调用在 Shoot
之前,可以修改伤害与发射位置等等(其实1.4就是把原本1.3tml写在一起的功能拆开来用了)。
对于 IEntitySource
与发射弹幕的详细,请自行移步去tml官方wiki处查看,这里就不再阐述。
伤害类型
1.4将我们习惯的伤害类型(也就是以前的melee,magic之类的)整合到了一起。变成了 DamageClass
之下的内容:
需要特别注意一点是 DamageClass.SummonMeleeSpeed
,这一个东西是给召唤师的鞭子用的,还有一个 DamageClass.MagicSummonHybrid
同时享有魔法和召唤加成。
于是给玩家增加某个类型的伤害的方式也变了个样子。
player.GetDamage(DamageClass.Melee) += 0.1f; player.GetDamage<MeleeDamageClass>() += 0.1f; //以上都是让玩家的近战伤害提高10%
当然,你也可以填入你自己的伤害类型,使用 ModContent.GetInstance<你的伤害类>()
来获取他。需要注意的是,1.3的 allDamage
在1.4变为了 DamageClass.Generic
。
类似于增加伤害,增加暴击和攻速也是同样的写法,分别是 player.GetCritChance
和 player.GetAttackSpeed
。
召唤物伤害
1.4给弹幕新加了一个参数,叫 originalDamage
,所有召唤物(minion
为true)都需要填这个,在生成的时候就需要填,不然会导致弹幕伤害一直为0。
然后我目前已知让生成的召唤物有 originalDamage
的方法有一个比较简单的,那就是重写 Shoot
,弹幕生成的时候就给予 originalDamage
与 damage
同样的值。
补充:1.4提供了一个生成召唤物的方法,同样是重写 Shoot
,但这个方法会自动给originDamage
赋值。
player.SpawnMinionOnCursor(IEntitySource projectileSource, int ownerIndex, int minionProjectileId, int originalDamageNotScaledByMinionDamage, float KnockBack, Vector2 offsetFromCursor = default, Vector2 velocityOnSpawn = default)
第一个参数就是生成源,直接用 Shoot
里提供的 source
,第二个参数 ownerIndex
即为弹幕主人的 WhoAmI
, 填 player.whoAmI
,第三个参数是召唤物的弹幕 Type
,第四个参数就是召唤物的基础 originDamage
,只要用 Shoot
里提供的 damage
即可,第五个 knockback
同理,第六个参数 offsetFromCursor
,这是生成位置相对于你点击的位置的偏移,第七个参数则是生成时弹幕初速度。因为召唤物一般都有自己的行动AI,所以6,7两个参数基本是可以不填的。
播放声音
(2022.6.1日稳定版更新,我不能保证其准确,所以发现错误请和我说,谢谢)
没错,该死的tml竟然对我们可爱的播放声音下手。
现在我们需要知道tml最新的PlaySound参数到底变成了什么。
等等,这个 SoundStyle
是什么玩意?这个返回值又是什么玩意?我PlaySound那么多重载去哪里了?
我摊牌不教了!
SoundStyle
这一个东西代替了我们以前的 LegacySoundStyle
。
现在 PlaySound
不支持使用数字ID,所以我们只能用 SoundID
了。
我们可以通过修改创建并修改 SoundStyle
的一个实例,来做到和以前 PlaySound
后面两个参数一样的效果:
ActiveSound
等等,这tm是啥。
除开使用创建并修改 SoundStyle
的实例,我们还可以选择用这个修改。
SoundEngine
提供了两种方法获取:
需要注意的是,下者应该有概率获取歪声音(就是获取到别的,目前不确定)。
而上者的返回值是bool,后面out出来的才是 ActiveSound
的实例。
TryGetActiveSound
和 FindActiveSound
的参数放这:
而 SlotID
就是给 TryGetActiveSound
用于获取播放的声音。
不要问我 in
是什么,看前面的教程去。
其他东西
获取贴图的方法
首先就是我们讨厌的删改环节,1.4tml把原来的 mod.GetTexture("XXX/XXX")
这种东西删掉了。
那么我们如何在1.4去代替1.3的写法呢?很简单:
只需要这样我们就能获取对应Mod文件夹下的贴图了。
Request
应该可以用来获取别的Mod的资源文件,Shader和Texture2D
获取弹幕之类的贴图的方法还有一种,就是通过 Terraria.GameContent
下的 TextureAssets
获取原版对应的贴图,具体用法不阐述,这里给一张图让大家自己理会:
获取其他mod的物品/弹幕等
之前我写的 Request
可以获取别的Mod的物品是有误的信息,那么我们如何获取别的Mod的物品与弹幕之类的东西呢?
使用 ModContent
的 Find<T>
。第一个参数是mod名字,第二个参数是对应的类名。
但是 Find<T>
在没有找到物品(比如那个模组把这玩意儿给删了)的时候就会直接抛出异常,所以我们也可以使用TryFind<T>
。他是一个 bool
方法,会在找到目标物品时返回true,并传出找到的物品,反之返回false。
ModLoader.TryGetMod("CalamityMod", out Mod CalamityMod); CalamityMod.TryFind<ModItem>("PlantyMush",out ModItem item);
在1.4写一个物品
SetStaticDefaults
GameCulture
的变化有一点大,把分开来的语言变成了枚举,于是现在你写一个7与 (int)GameCulture.CultureName.Cheinese
的区别不大(因为中文在 CultureName
里面的值就是7)(虽然1.3也能直接填7代替)。
那么最下面这一行是什么意思呢?
CreativeItemSacrificesCatalog.Instance.SacrificeCountNeededByItemId[Type] = num;
这一段的意思是为了旅途模式的研究而写的,如果你要这个物品可以被研究,那么就需要写这一行,上面所填的num是让它消耗num个物品研究成功。其实这一大串也可以直接写成 SacrificeTotal = num
。
SetDefaults
这一部分是没有什么好说的,能多填的也没有多少,唯一就是 Item.DamageType
的变化,上面有阐述就不再细说。
AddRecipes
这一部分的变化大了,让我们看看怎么写:
当然这是目前最推荐的方法,我们也可以用回1.3格式的写法,只不过就是内容不同了:
那么下面我就细说一下1.4的合成表的变化。
CreateRecipe 和 SetResult
CreateRecipe(num)
是同等于1.3时期的 SetResult(this,num)
(num代指生成的数量)。
CreateRecipe(num)
是ModItem自带的方法(1.4将 ModRecipe
移除了)。
AddIngredient 与 AddTile 等添加合成表内容的方法
在1.4里面,它们的返回值均从原来的 void
变成了 Recipe
,1.4又把原 ModRecipe
的内容给了 Recipe
,所以现在我们是可以连着写的(就是一开始的图)。
Register 与 AddRecipe
这两等效,只是名字不同。
太酷了