Modding:Advanced Items/ru: Difference between revisions
From Vintage Story Wiki
(Created page with "{{Navbox/modding|Vintage Story}}") |
(Updating to match new version of source page) |
||
Line 1: | Line 1: | ||
<languages/> | <languages/> | ||
<!--T:1--> | |||
__FORCETOC__ | __FORCETOC__ | ||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
{{GameVersion|1.19.3}} | {{GameVersion|1.19.3}} | ||
</div> | |||
<!--T:2--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This ''code mod'' tutorial requires a development environment. If you do not have one, please read and complete the [[Setting up your Development Environment]] page. It is also highly recommended to have read and completed the [[Basic Item]] tutorial. | |||
</div> | |||
= | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
= Creating a Tunnel Pickaxe = | |||
</div> <!--T:3--> | |||
<!--T:4--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
In this tutorial will we create a item with more advanced functionality: A pickaxe which allows you to dig a 3x3 tunnel by mining just one block. | |||
</div> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
== Item Assets == | |||
</div> <!--T:5--> | |||
<!--T:6--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Similar to the [[Basic Item]], we need to create our item's assets, including an itemtype, texture and a lang file. Those assets are pretty straight forward and you can download them [https://wiki.vintagestory.at/images/c/cd/Tunnler_-_No_CS_File.zip here]. Extract the file to your mods folder, and you are ready to start programming. | |||
</div> | |||
<!--T:7--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
There is only one new property in your itemtype json, <code>class</code>. This property tells our new item to be controlled by a certain C# class. | |||
</div> | |||
<syntaxhighlight lang="json"> | <syntaxhighlight lang="json"> | ||
class: "tunnler", | class: "tunnler", | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:8--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
We will create this class to give the item the desired functionality. | |||
</div> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
== The Item Class == | |||
</div> <!--T:9--> | |||
<!--T:10--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Creating our item requires a couple new <code>*.cs</code> files in our project. | |||
</div> | |||
<!--T:11--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
If you have read the [[Advanced Blocks]] Tutorial already, this should be familar to you. | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
=== The Mod System === | |||
</div> <!--T:12--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
In order to register your item class, we need to create a mod, which is a class extending ModSystem: | |||
</div> | |||
<!--T:13--> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public class TunnlerMod : ModSystem | public class TunnlerMod : ModSystem | ||
Line 37: | Line 71: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:14--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
By overriding the <code>Start(ICoreAPI)</code> method, we can register our class. The <code>RegisterItemClass</code> function has two parameters: the first is our item class ID, noteably this is how we link to this class in our itemtype json files. Ensure that this is identical to the class we specified in our earlier asset file. The second parameter is the type of our item class. | |||
</div> | |||
<!--T:15--> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public class TunnlerMod : ModSystem | public class TunnlerMod : ModSystem | ||
Line 52: | Line 88: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:16--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This should be marked as a syntax error because there is no <code>TunnlerItem</code> class yet. | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
=== The Item Class === | |||
</div> <!--T:17--> | |||
<!--T:18--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
When naming item scripts, it is recommended to name them in the format "{Name}Item". In the case of the tunnler pickaxe, we shall name our script <code>TunnlerItem.cs</code>. Any itemclass has to extend Item, giving it the functionality we need to access: | |||
</div> | |||
<!--T:19--> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public class TunnlerItem : Item | public class TunnlerItem : Item | ||
{ | { | ||
<!--T:20--> | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:21--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This should solve all syntax errors. | |||
</div> | |||
''' | <!--T:22--> | ||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
'''So what should our tool do?''' Once the player mines a block with this tool every block around it should be mined as well. | |||
</div> | |||
<!--T:23--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
As always, we can refer to the [https://apidocs.vintagestory.at/api/Vintagestory.API.Common.Item.html#methods item api docs] to find a function we can use. Although the item class itself does not contain an appropriate function, we can also check the [https://apidocs.vintagestory.at/api/Vintagestory.API.Common.CollectibleObject.html CollectibleObject api docs], which the item class extends from. | |||
</div> | |||
<!--T:24--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
In our specific case, we can override the method <code>bool OnBlockBrokenWith(IWorldAccessor world, Entity byEntity, ItemSlot itemslot, BlockSelection blockSel, float dropQuantityMultiplier = 1)</code>. | |||
</div> | |||
<!--T:25--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
We need to be aware of the facing (which side the player is focusing) and if the player is in creative or survival mode (whether items should be dropped or not). Before we are going to override <code>OnBlockBrokenWith</code> we should create a method which destroys all blocks between two block positions (min & max). It should also only drop items if the player is in survival mode: | |||
</div> | |||
<!--T:26--> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public void DestroyBlocks(IWorldAccessor world, BlockPos min, BlockPos max, IPlayer player) | public void DestroyBlocks(IWorldAccessor world, BlockPos min, BlockPos max, IPlayer player) | ||
Line 97: | Line 159: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:27--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Now we can implement <code>OnBlockBroken</code> rather easily, by taken care of every possible axis the player could face: | |||
</div> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
public override bool OnBlockBrokenWith(IWorldAccessor world, Entity byEntity, ItemSlot itemslot, BlockSelection blockSel, float dropQuantityMultiplier = 1) | public override bool OnBlockBrokenWith(IWorldAccessor world, Entity byEntity, ItemSlot itemslot, BlockSelection blockSel, float dropQuantityMultiplier = 1) | ||
Line 125: | Line 190: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:28--> | |||
---- | ---- | ||
<!--T:29--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
If you have done everything right, your file should look similar to this: | |||
</div> | |||
<syntaxhighlight lang="c#"> | <syntaxhighlight lang="c#"> | ||
using Vintagestory.API.Common; | using Vintagestory.API.Common; | ||
Line 133: | Line 202: | ||
using Vintagestory.API.MathTools; | using Vintagestory.API.MathTools; | ||
<!--T:30--> | |||
namespace ExampleMods | namespace ExampleMods | ||
{ | { | ||
Line 138: | Line 208: | ||
{ | { | ||
public override void Start(ICoreAPI api) | <!--T:31--> | ||
public override void Start(ICoreAPI api) | |||
{ | { | ||
base.Start(api); | base.Start(api); | ||
Line 144: | Line 215: | ||
} | } | ||
} | <!--T:32--> | ||
} | |||
public class TunnlerItem : Item | <!--T:33--> | ||
public class TunnlerItem : Item | |||
{ | { | ||
public void DestroyBlocks(IWorldAccessor world, BlockPos min, BlockPos max, IPlayer player) | <!--T:34--> | ||
public void DestroyBlocks(IWorldAccessor world, BlockPos min, BlockPos max, IPlayer player) | |||
{ | { | ||
BlockPos tempPos = new BlockPos(); | BlockPos tempPos = new BlockPos(); | ||
Line 168: | Line 242: | ||
} | } | ||
public override bool OnBlockBrokenWith(IWorldAccessor world, Entity byEntity, ItemSlot itemslot, BlockSelection blockSel, float dropQuantityMultiplier = 1) | <!--T:35--> | ||
public override bool OnBlockBrokenWith(IWorldAccessor world, Entity byEntity, ItemSlot itemslot, BlockSelection blockSel, float dropQuantityMultiplier = 1) | |||
{ | { | ||
if (base.OnBlockBrokenWith(world, byEntity, itemslot, blockSel)) | if (base.OnBlockBrokenWith(world, byEntity, itemslot, blockSel)) | ||
Line 193: | Line 268: | ||
} | } | ||
} | <!--T:36--> | ||
} | |||
} | } | ||
<!--T:37--> | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<!--T:38--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
You can also download the file directly: [https://wiki.vintagestory.at/images/a/ad/Tunnler.cs Tunnler.cs]. | |||
</div> | |||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
== Testing == | |||
</div> <!--T:39--> | |||
<!--T:40--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
This is how it looks ingame: | |||
</div> | |||
<!--T:41--> | |||
<youtube>2MRzYKguVFY</youtube> | <youtube>2MRzYKguVFY</youtube> | ||
== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
== Distribution == | |||
</div> <!--T:42--> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
=== Using the new Mod Template === | |||
</div> <!--T:43--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
If using the mod template setup, follow the instructions on [[Modding:Setting up your Development Environment#Packaging%20the%20Mod|Setting up your Development Environment]] to pack and distribute your mod. | |||
</div> | |||
=== | <div lang="en" dir="ltr" class="mw-content-ltr"> | ||
=== Using the (old) Modtools === | |||
= | </div> <!--T:44--> | ||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
If using the modtools program, open the modtools and type in <code>pack <your mod id></code>. Now you can take the zip file and share it with other people. It will work in the same way as ordinary mods, you can install it by copying it into the <code>mods</code> folder. | |||
</div> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
= Mod Download = | |||
</div> | |||
<!--T:45--> | |||
<div lang="en" dir="ltr" class="mw-content-ltr"> | |||
Here is my version: | |||
</div> | |||
* for VS v1.9: [https://wiki.vintagestory.at/images/7/7b/Tunnler_vs1.9_v1.0.0.zip Tunnler_vs1.9_v1.0.0.zip] | * for VS v1.9: [https://wiki.vintagestory.at/images/7/7b/Tunnler_vs1.9_v1.0.0.zip Tunnler_vs1.9_v1.0.0.zip] | ||
* for VS v1.8: [https://wiki.vintagestory.at/images/6/66/Tunnler.zip Tunnler.zip] | * for VS v1.8: [https://wiki.vintagestory.at/images/6/66/Tunnler.zip Tunnler.zip] | ||
<!--T:46--> | |||
{{Navbox/modding|Vintage Story}} | {{Navbox/modding|Vintage Story}} |