希望你们是看过之前的教程再来看这边的,此时你应该有一个配置好环境的工程文件。
因为是一个物品,所以我们来到Items文件夹,创建一个新的类,并让它继承 ModItem
这个类。这样,TML就会知道这是一个模组物品。
设置物品的基础属性
SetStaticDefaults
一个基本的物品,它需要一个名字,一段描述,和一些属性。输入public override ssd,此时你应该会看到来自vs的代码补全:
按回车或tab或鼠标双击应用补全。
这个重写函数,用于设置无需变动的东西,比如旅途研究数量, ID.Set
的属性设定。
public override void SetStaticDefaults() { // 这是在旅途模式中物品需要研究多少个才能复制,不写的话默认为需要1个,设为0将禁用研究 Item.ResearchUnlockCount = 0; }
接着是按照格式写入本地化文件(注意语言):
Items: { SkirtSword:{ DisplayName: 裙裙的剑 Tooltip: 被击中会导致免死金牌归零,再次被击中进入24小时优质睡眠 } }
ID.Set
用到再讲,接下来我们要设置物品的属性。
SetDefaults
那么在继承了ModItem的类中,它会给我们提供一个这个类的实例,Item
,以及它的 Type
物品类型(这是一个int
类型的字段)。我们可以使用这两个玩意儿来设置这个物品的属性。
首先我们要确定物品的大小。一般来说,这个大小就设置为贴图的大小。
public override void SetDefaults() { Item.width = 贴图的宽度; Item.height = 贴图的高度; }
注意,这决定了物品的碰撞箱大小,假设这个物品的贴图有伤害。
然后是物品的稀有度和价值(其实都可以不写,默认就是0,但是你最好写,你也不想你的Mod物品全是白级无价值吧)。
有关原版的物品稀有度,请参考原版稀有度。
Item.rare = 1;
上面这种写法叫做使用魔法值。这是一种很坏的行为,vs会给你作出警告:
是的,为了你的代码可读性,请Alt+Enter应用vs的建议,将它写成:
Item.rare = ItemRarityID.Blue;
否则你有很大的可能在重新翻看你写的代码的时候不知道自己在写啥(乐)~
// Item.maxStack = 9999; // 对于9999堆叠,这种写法不太推荐 // 实际上如果想写9999堆叠最好使用下面这种写法 Item.maxStack = Item.CommonMaxStack;
这是设定物品的最大堆叠数量,可以不写,默认会是1。
Item.value = Item.sellPrice(0, 1, 60, 0);
这是设定物品的价值,Item.sellPrice()
这个方法,设定的是物品的卖出价值。
可以看到这个方法有四个参数,分别是铂金币,金币,银币和铜币,它的意思和作用应该很明确吧?
不过你也可以用其它写法:
推荐以卖出价为基准哦。
哦,差点忘了,当然你要记得给这个物品一个贴图。将文件名与物品类名
一致的PNG格式的贴图放在正确的文件夹里。
tml会自动根据命名空间和类名寻找贴图文件。但如果你不想将贴图和代码放在一块儿?
贴图问题
很简单,你可以重写贴图路径。Texture
就是物品的贴图路径。
public override string Texture => "path";
以模板剑为例,它的贴图路径就是 "TemplateMod2/Items/SkirtSword"
。改动这个的话,tml就会去你指定的位置寻找贴图文件了,不需要带文件后缀名。你可以用这个方式让你的物品使用原版的贴图,比如:
public override string Texture => "Terraria/Images/Extra_98";
这样就可以让它去找原版的这个叫Extra_98的贴图了。这是一个超级好用的万能贴图~
到此一个非常基础的物品就写完了,它不可以使用,但是你可以让它作为一个合成材料,或是让它从NPC身上掉落,又或是可以给它一个合成表,让它被合成出来。
关于给NPC添加掉落,会在之后的章节中讲到,这里就先介绍合成表相关内容。
给物品添加合成表
1.4的合成表具体写法可以查看该网址来详细看看,这里只是一个简单的示例。
使用重写函数 AddRecipes()
来给物品添加合成表:
public override void AddRecipes() { // 这个括号里有一个默认的参数1,你可以填任何大于0的整数。它代表了这个合成表会生成多少个物品 CreateRecipe() // 这样可以生成50个 // CreateRecipe(50); // 合成材料,需要10个泥土块 // 哦对了,如果你写俩种相同的材料的话,它们会分别显示而不是合并成一个(我家门前有两颗树,一颗是枣树,另一颗还是枣树) .AddIngredient(ItemID.DirtBlock, 10) // 使用ModContent.ItemType<xxx>()来获取你的物品的type,不过在这里,你可以使用Type .AddIngredient(/*ModContent.ItemType<SkirtSword>()*/Type, 1) // 以及在工作台旁边 .AddTile(TileID.WorkBenches) // 把这个合成表装进tr的系统里 .Register(); }
上面的写法看起来很离谱,其实是因为 CreateRecipe() 的返回类型是 Recipe,然后 AddIngredient() 和 AddTile() 的返回类型还是 Recipe,所以它可以连着写。
我们还可以用另一种写法:
效果是一样的,那么来看看这里面用到的方法。
AddIngredient
这个方法的作用,是给这个合成表添加材料。通过vs可以看到,这个方法有一个必填参数和一个选填参数,itemID,意思是你想要加入合成表的物品的ID,或者说是type(物品的类型)。stack,是需要的数量,可不填,不填即是一个。你可以写很多次这个方法来添加很多种材料。
你可以使用 ModContent.ItemType<你的物品类>()
来获取你自己的物品的id,这里的 你的物品类
必须是继承于 ModItem
的类。
注意:使用ModContent.XXXType<T>()这类函数通常会让T里面的东西被VS画上红线,此时要用小灯泡(vs的提示)进行修复。因为T的值通常需要引用其它命名空间的类。
你也可以使用ItemID.xxx来获取原版的物品id。有关原版的id,请参考Wiki。
AddTile
这个是给合成表加入制作环境,上图添加的是原版的工匠作坊。参数tileID,是物块的类型。TileID即是原版的物块ID。使用 ModContent.TileType<你的物块类>()
来获取你的物块id。同样的,既然是物块那就必须是继承自ModTile的类。你一样可以写很多次这个方法来添加多个合成站,虽然不太推荐。
AddCondition
来点儿没见过的~
这个方法的作用是给合成表添加条件。
利用自动补全,你可以用猜的方式把条件给写出来(
例如:靠近某种液体:
又如:在某种环境:
当然条件也是可以加一大堆的。今天玩家和作者必须要气死一个
AddRecipeGroup
再来点怪东西,这个是给合成表添加合成组,比如使用所有木头。
那么怎么写一个自己的合成组呢?
首先,你要创建一个类,让它继承ModSystem
接着在里面使用这个重写函数:
这里是一个是用金矿或铁矿的示例:
public override void AddRecipeGroups() { RecipeGroup recipeGroup = new RecipeGroup(() => "金或铁", //游戏中显示的合成组的名字 new int[] { ItemID.GoldOre, //金矿石 ItemID.IronOre //铁矿石 });//以上是要向合成组中添加的物品 //recipeGroup.IconicItemId = ItemID.xxx; 这是合成组显示的贴图是哪个物品,填物品的类型 RecipeGroup.RegisterGroup("GoldAndIron", recipeGroup);//向游戏注册这个合成组,这里的名字也是之后使用合成组的文字索引 }
然后你就可以向你的合成表添加这个合成组:
recipe.AddRecipeGroup("GoldAndIron", 10); //需要10个金矿或铁矿,可以是5个金矿和5个铁矿。
ReplaceResult
这个方法可以让你修改合成表的生成物和数量。之前的 CreateRecipe()
的生成物一定是你的这个物品,但用这个方法就可以把它给改了,虽然一般不用(
它的参数和前面的添加合成材料是一样的。
Register
最后,向游戏注册这个合成表,完成!
现在这个物品(不,是天顶剑)就可以用这个合成表来制作了!
Pingback: 物块制作第一节:单物块与平台 - 裙中世界
如果想向原版合成组中添加物品,只要确保RegisterGroup中的文字引索是目标的原版合成组的名字即可