Line 1,365: |
Line 1,365: |
| | | |
| ===Custom map actions=== | | ===Custom map actions=== |
− | {{/doc status|[[Modding:Maps]]|done=false}} | + | {{/doc status|[[Modding:Maps#Custom_Actions]]|done=true}} |
| | | |
| C# mods can now handle custom <samp>Action</samp> & <samp>TouchAction</samp> [[Modding:Maps|map properties]] by calling <samp>GameLocation.RegisterTileAction</samp> & <samp>RegisterTouchAction</samp>, and passing a callback which receives the location, map property arguments, player who activated it, and tile position. | | C# mods can now handle custom <samp>Action</samp> & <samp>TouchAction</samp> [[Modding:Maps|map properties]] by calling <samp>GameLocation.RegisterTileAction</samp> & <samp>RegisterTouchAction</samp>, and passing a callback which receives the location, map property arguments, player who activated it, and tile position. |
| | | |
− | For example, let's say you want a locked gate which needs a custom key item. You can add a regular <code>TouchAction Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod: | + | For example, let's say you want a locked gate which needs a custom key item. You can add a regular <code>TouchAction Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod. See the updated docs for an example. |
− | <syntaxhighlight lang="c#">
| |
− | internal class ModEntry : Mod
| |
− | {
| |
− | /// <inheritdoc />
| |
− | public override void Entry(IModHelper helper)
| |
− | {
| |
− | GameLocation.RegisterTouchAction("Example.ModId_UnlockGate", this.HandleUnlockGate);
| |
− | }
| |
| | | |
− | private void HandleUnlockGate(GameLocation location, string[] args, Farmer player, Vector2 tile)
| + | As another example, let's say you want the gate to unlock when the player presses the action key. You can add a regular <code>Action Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod. See the updated docs for an example. |
− | {
| |
− | const string mailFlag = "Example.ModId_GateUnlocked";
| |
− | const string keyId = "Example.ModId_GateKey";
| |
− | | |
− | // unlock gate if locked
| |
− | if (!player.mailReceived.Contains(mailFlag))
| |
− | {
| |
− | if (!Game1.player.Items.ContainsId(id, count))
| |
− | {
| |
− | Game1.activeClickableMenu = new DialogueBox("This gate is locked. I wonder where the key is?");
| |
− | return;
| |
− | }
| |
− | | |
− | player.removeFirstOfThisItemFromInventory(keyId);
| |
− | player.mailReceived.Add(mailFlag);
| |
− | }
| |
− | | |
− | // apply open-gate map edit
| |
− | // NOTE: this is a quick example which changes the location's current map. If another mod reloads the map
| |
− | // (e.g. a content pack editing it), the change will be lost. For persistent changes, you should use the
| |
− | // AssetRequested event to apply the change when the map is reloaded.
| |
− | IAssetDataForMap mapHelper = this.Helper.GameContent.GetPatchHelper(location.map).AsMap();
| |
− | mapHelper.PatchMap(
| |
− | this.Helper.Content.Load<Map>("assets/unlocked-gate.tmx"),
| |
− | targetArea: new Rectangle((int)tile.X - 1, (int)tile.Y - 1, 2, 2)
| |
− | );
| |
− | }
| |
− | }
| |
− | </syntaxhighlight>
| |
− | | |
− | As another example, let's say you want the gate to unlock when the player presses the action key. You can add a regular <code>Action Example.ModId_UnlockGate</code> map property (e.g. by adding it directly in the map file, or using [[Modding:Content Patcher|Content Patcher]]'s <samp>EditMap</samp>, or using the [[Modding:Modder Guide/APIs/Content|content API]]). Then you can just handle the logic from your C# mod: | |
− | <syntaxhighlight lang="c#">
| |
− | internal class ModEntry : Mod
| |
− | {
| |
− | /// <inheritdoc />
| |
− | public override void Entry(IModHelper helper)
| |
− | {
| |
− | GameLocation.RegisterTileAction("Example.ModId_UnlockGate", this.HandleUnlockGate);
| |
− | }
| |
− | | |
− | private bool HandleUnlockGate(GameLocation location, string[] args, Farmer player, Microsoft.Xna.Framework.Point point)
| |
− | {
| |
− | const string mailFlag = "Example.ModId_GateUnlocked";
| |
− | const string keyId = "Example.ModId_GateKey";
| |
− | | |
− | // unlock gate if locked
| |
− | if (!player.mailReceived.Contains(mailFlag))
| |
− | {
| |
− | if (!Game1.player.Items.ContainsId(id, count))
| |
− | {
| |
− | Game1.activeClickableMenu = new DialogueBox("This gate is locked. I wonder where the key is?");
| |
− | return false;
| |
− | }
| |
− | | |
− | player.removeFirstOfThisItemFromInventory(keyId);
| |
− | player.mailReceived.Add(mailFlag);
| |
− | }
| |
− | | |
− | // apply open-gate map edit
| |
− | // NOTE: this is a quick example which changes the location's current map. If another mod reloads the map
| |
− | // (e.g. a content pack editing it), the change will be lost. For persistent changes, you should use the
| |
− | // AssetRequested event to apply the change when the map is reloaded.
| |
− | IAssetDataForMap mapHelper = this.Helper.GameContent.GetPatchHelper(location.map).AsMap();
| |
− | mapHelper.PatchMap(
| |
− | this.Helper.Content.Load<Map>("assets/unlocked-gate.tmx"),
| |
− | targetArea: new Rectangle((int)point.X - 1, (int)point.Y - 1, 2, 2)
| |
− | );
| |
− | | |
− | return true;
| |
− | }
| |
− | }
| |
− | </syntaxhighlight>
| |
| | | |
| ===Custom map layers=== | | ===Custom map layers=== |