### Place Waystone, Sharestone, and Warp Plate Blocks Source: https://context7.com/twelveiterations/waystones/llms.txt Use these methods to place Waystone, Sharestone, or Warp Plate blocks at runtime. The returned Optional is empty if placement fails. Custom types can be registered externally. ```java import net.blay09.mods.waystones.api.*; ServerLevel level = server.overworld(); BlockPos pos = new BlockPos(0, 65, 0); // Place a regular waystone (any registered WaystoneType) WaystoneType sandstoneType = WaystoneType.get( Identifier.fromNamespaceAndPath("waystones", "sandstone_waystone") ); Optional placed = WaystonesAPI.placeWaystone(level, pos, sandstoneType); // Give it a custom name immediately after placement placed.ifPresent(w -> { if (w instanceof MutableWaystone mw) { mw.setName(Component.literal("Spawn Point")); mw.setVisibility(WaystoneVisibility.GLOBAL); // visible to everyone mw.setOwnerUid(player.getUUID()); } }); // Place a sharestone (colour-matched among a group) SharestoneType goldSharestone = SharestoneTypes.get( Identifier.fromNamespaceAndPath("waystones", "gold_sharestone") ); WaystonesAPI.placeSharestone(level, pos.above(3), goldSharestone); // Place a warp plate (pressure-plate style teleporter) WaystonesAPI.placeWarpPlate(level, pos.above(6)); // Enumerate all registered waystone types WaystoneType.values().forEach(type -> System.out.println(type.identifier() + " rune colour: #" + Integer.toHexString(type.runeColor())) ); ``` -------------------------------- ### Programmatic Teleportation Source: https://context7.com/twelveiterations/waystones/llms.txt This section covers the teleportation pipeline, which is divided into two steps: creating a `WaystoneTeleportContext` and then attempting the teleport. The context bundles entities, target waystone, pets, leashed mobs, flags, and warp requirements. `tryTeleport` respects requirements and fires cancellable events, while `forceTeleport` bypasses these. ```APIDOC ## `WaystonesAPI.createDefaultTeleportContext` / `tryTeleport` / `forceTeleport` — Programmatic Teleportation The teleport pipeline is split into two steps: (1) create a `WaystoneTeleportContext` that bundles the entity, target waystone, pets, leashed mobs, flags, and warp requirements; (2) attempt the teleport, receiving an `Either, WaystoneTeleportError>` result. `tryTeleport` checks requirements and fires cancellable events; `forceTeleport` bypasses both. ```java import com.mojang.datafixers.util.Either; import net.blay09.mods.waystones.api.*; import net.blay09.mods.waystones.api.error.WaystoneTeleportError; // Retrieve target waystone Waystone target = WaystonesAPI.getWaystoneAt(overworld, destinationPos).orElseThrow(); // --- Default context (includes pets, leashed animals, default requirements) --- Either ctxResult = WaystonesAPI.createDefaultTeleportContext(player, target, ctx -> { ctx.setPlaysSound(true); ctx.setPlaysEffect(true); ctx.setWarpItem(player.getMainHandItem()); // used for durability cost ctx.setFromWaystone(sourceWaystone); // optional, for "from" XP formula ctx.addFlag(TeleportFlags.ADMIN); // bypass some restrictions }); ctxResult.ifLeft(ctx -> { // --- Attempt teleport (respects rules / events) --- Either, WaystoneTeleportError> result = WaystonesAPI.tryTeleport(ctx); result.ifLeft(teleported -> { System.out.println("Teleported " + teleported.size() + " entities."); }); result.ifRight(error -> { // Inspect the concrete error type for UI feedback if (error instanceof WaystoneTeleportError.RequirementsNotMet) { player.sendSystemMessage(error.getComponent()); } else if (error instanceof WaystoneTeleportError.DimensionalWarpDenied) { player.sendSystemMessage(error.getComponent()); } else if (error instanceof WaystoneTeleportError.LeashedWarpDenied) { player.sendSystemMessage(error.getComponent()); } }); }); ctxResult.ifRight(error -> System.out.println("Cannot build context: " + error.getClass().getSimpleName())); // --- Force-teleport, ignoring requirements and events --- Either forceCtx = WaystonesAPI.createCustomTeleportContext(player, target); forceCtx.ifLeft(ctx -> WaystonesAPI.forceTeleport(ctx)); ``` ``` -------------------------------- ### Programmatic Block Placement Source: https://context7.com/twelveiterations/waystones/llms.txt These methods allow for the placement of waystone blocks, sharestones, and warp plates at runtime. They initialize the block entity and backing data, similar to player placement. The methods return an Optional which will be empty if placement fails. Custom types can be registered via WaystoneType and SharestoneType registries. ```APIDOC ## `WaystonesAPI.placeWaystone` / `placeSharestone` / `placeWarpPlate` — Programmatic Block Placement These methods place a fully-initialized waystone block (including its block entity and backing data) into the world at runtime, as if a player had placed it. The returned `Optional` is empty if the placement fails. `WaystoneType` and `SharestoneType` registries hold all known variants; custom types can be registered externally. ```java import net.blay09.mods.waystones.api.*; ServerLevel level = server.overworld(); BlockPos pos = new BlockPos(0, 65, 0); // Place a regular waystone (any registered WaystoneType) WaystoneType sandstoneType = WaystoneType.get( Identifier.fromNamespaceAndPath("waystones", "sandstone_waystone") ); Optional placed = WaystonesAPI.placeWaystone(level, pos, sandstoneType); // Give it a custom name immediately after placement placed.ifPresent(w -> { if (w instanceof MutableWaystone mw) { mw.setName(Component.literal("Spawn Point")); mw.setVisibility(WaystoneVisibility.GLOBAL); // visible to everyone mw.setOwnerUid(player.getUUID()); } }); // Place a sharestone (colour-matched among a group) SharestoneType goldSharestone = SharestoneTypes.get( Identifier.fromNamespaceAndPath("waystones", "gold_sharestone") ); WaystonesAPI.placeSharestone(level, pos.above(3), goldSharestone); // Place a warp plate (pressure-plate style teleporter) WaystonesAPI.placeWarpPlate(level, pos.above(6)); // Enumerate all registered waystone types WaystoneType.values().forEach(type -> System.out.println(type.identifier() + " rune colour: #" + Integer.toHexString(type.runeColor())) ); ``` ``` -------------------------------- ### WaystoneTeleportEvent.Before / .After Source: https://context7.com/twelveiterations/waystones/llms.txt These events fire around every `tryTeleport` call. `Before` is cancellable and allows additional entities to be injected. `After` provides the final list of teleported entities. Both use the Balm cross-platform event system. ```APIDOC ## `WaystoneTeleportEvent.Before` / `.After` — Teleport Events These events fire around every `tryTeleport` call. `Before` is cancellable and allows additional entities to be injected. `After` provides the final list of teleported entities. Both use the Balm cross-platform event system and work identically on Fabric and NeoForge. ```java import net.blay09.mods.waystones.api.event.WaystoneTeleportEvent; // Register in your mod initializer (Balm event bus) WaystoneTeleportEvent.Before.EVENT.register(event -> { WaystoneTeleportContext ctx = event.getContext(); Waystone target = ctx.getTargetWaystone(); // Example: block teleport into a specific named zone if (target.getName().getString().equalsIgnoreCase("Forbidden Zone")) { event.setCanceled(true); ctx.getEntity().sendSystemMessage( Component.literal("That waystone is sealed!") ); return; } // Example: add a companion entity to every teleport Entity companion = findCompanion(ctx.getEntity()); if (companion != null) { event.addAdditionalEntity(companion); } }); WaystoneTeleportEvent.After.EVENT.register(event -> { List teleported = event.getTeleportedEntities(); Waystone from = event.getContext().getFromWaystone().orElse(null); Waystone to = event.getContext().getTargetWaystone(); System.out.printf("Teleport complete: %d entities → %s%n", teleported.size(), to.getName().getString()); }); ``` ``` -------------------------------- ### In-Game Commands Source: https://context7.com/twelveiterations/waystones/llms.txt Server operators can use the `/waystones` command tree to manage waystones, including activation, forgetting, placement, counting, listing, and cooldown resets. ```APIDOC ## In-Game Commands Waystones registers a `/waystones` command tree for server operators (permission level `COMMANDS_GAMEMASTER` by default, overridable via Permissions API). ``` # Activate a waystone at for one or more players /waystones activate # Make a player forget a waystone at , or all waystones /waystones forget /waystones forget all # Place a waystone block of a given type with a name /waystones place # Example: /waystones place 100 64 200 sandstone_waystone "Desert Outpost" # Count a player's activated waystones /waystones count # List a player's owned or all activated waystones (clickable coordinates in chat) /waystones list /waystones list all # Open the waystone selection GUI for a player /waystones gui # Reset all cooldowns or a specific cooldown for players /waystones cooldown reset all /waystones cooldown reset # Example: /waystones cooldown @a reset waystones:inventory_button ``` ``` -------------------------------- ### Programmatic Teleportation with Waystones API Source: https://context7.com/twelveiterations/waystones/llms.txt Initiate teleports using the Waystones API, which involves creating a teleport context and then attempting the teleport. `tryTeleport` respects rules and events, while `forceTeleport` bypasses them. ```java import com.mojang.datafixers.util.Either; import net.blay09.mods.waystones.api.*; import net.blay09.mods.waystones.api.error.WaystoneTeleportError; // Retrieve target waystone Waystone target = WaystonesAPI.getWaystoneAt(overworld, destinationPos).orElseThrow(); // --- Default context (includes pets, leashed animals, default requirements) --- Either ctxResult = WaystonesAPI.createDefaultTeleportContext(player, target, ctx -> { ctx.setPlaysSound(true); ctx.setPlaysEffect(true); ctx.setWarpItem(player.getMainHandItem()); // used for durability cost ctx.setFromWaystone(sourceWaystone); // optional, for "from" XP formula ctx.addFlag(TeleportFlags.ADMIN); // bypass some restrictions }); ctxResult.ifLeft(ctx -> { // --- Attempt teleport (respects rules / events) --- Either, WaystoneTeleportError> result = WaystonesAPI.tryTeleport(ctx); result.ifLeft(teleported -> { System.out.println("Teleported " + teleported.size() + " entities."); }); result.ifRight(error -> { // Inspect the concrete error type for UI feedback if (error instanceof WaystoneTeleportError.RequirementsNotMet) { player.sendSystemMessage(error.getComponent()); } else if (error instanceof WaystoneTeleportError.DimensionalWarpDenied) { player.sendSystemMessage(error.getComponent()); } else if (error instanceof WaystoneTeleportError.LeashedWarpDenied) { player.sendSystemMessage(error.getComponent()); } }); }); ctxResult.ifRight(error -> System.out.println("Cannot build context: " + error.getClass().getSimpleName())); // --- Force-teleport, ignoring requirements and events --- Either forceCtx = WaystonesAPI.createCustomTeleportContext(player, target); forceCtx.ifLeft(ctx -> WaystonesAPI.forceTeleport(ctx)); ``` -------------------------------- ### Build Waystone Teleport Context Source: https://context7.com/twelveiterations/waystones/llms.txt Use WaystoneTeleportContext to configure and execute teleportation attempts. Obtain a context via createDefaultTeleportContext or createCustomTeleportContext. Configure effects, items, flags, and entities before initiating teleportation. ```java import net.blay09.mods.waystones.api.*; WaystoneTeleportContext ctx = /* obtained from createDefaultTeleportContext or createCustomTeleportContext */; // Add extra entities to teleport alongside the primary entity ctx.addAdditionalEntity(someNPC); // Configure sound/particle effects ctx.setPlaysSound(false).setPlaysEffect(false); // Override the warp item (affects item-based requirements like durability) ctx.setWarpItem(warpStoneStack); ctx.setWarpHand(InteractionHand.MAIN_HAND); // Attach a "from" waystone so the XP cost formula can compute distance ctx.setFromWaystone(sourceWaystone); // Teleport flags affect rule evaluation ctx.addFlag(TeleportFlags.INVENTORY_BUTTON); // waystones:inventory_button ctx.addFlag(TeleportFlags.PORTSTONE); // waystones:portstone ctx.removeFlag(TeleportFlags.ADMIN); // Read back state System.out.println("Is dimensional teleport: " + ctx.isDimensionalTeleport()); System.out.println("Target: " + ctx.getTargetWaystone().getName().getString()); System.out.println("Leashed mobs: " + ctx.getLeashedEntities().size()); System.out.println("Active flags: " + ctx.getFlags()); ``` -------------------------------- ### WaystonesAPI - Querying and Managing Waystones Source: https://context7.com/twelveiterations/waystones/llms.txt This snippet demonstrates how to use the `WaystonesAPI` to query waystone information by position or UUID, list all waystones, manage player activation states, and remove waystone data. ```APIDOC ## WaystonesAPI ### Description The static `WaystonesAPI` class is the primary entry point for all server-side interactions with the mod. It provides methods for querying waystone data, triggering or forcing teleports, activating/deactivating waystones for players, and placing new waystone blocks programmatically. ### Methods #### `getWaystoneAt(ServerLevel level, BlockPos pos)` - **Description**: Queries a waystone at a specific block position. - **Returns**: An `Optional` containing the waystone if found, otherwise empty. #### `getWaystone(MinecraftServer server, UUID uid)` - **Description**: Looks up a waystone by its unique identifier (UUID). - **Returns**: An `Optional` containing the waystone if found, otherwise empty. #### `getAllWaystones(MinecraftServer server)` - **Description**: Retrieves a collection of all waystones currently registered in the database. - **Returns**: A `Collection` of all waystones. #### `getWaystonesByType(MinecraftServer server, ResourceLocation type)` - **Description**: Lists all waystones of a specific kind (e.g., `waystones:waystone`). - **Returns**: A `Collection` matching the specified type. #### `isWaystoneActivated(Player player, Waystone waystone)` - **Description**: Checks if a specific waystone is activated for a given player. - **Returns**: `true` if activated, `false` otherwise. #### `getActivatedWaystones(Player player)` - **Description**: Retrieves all waystones activated by a specific player. - **Returns**: A `Collection` of activated waystones. #### `getNearestWaystone(Player player)` - **Description**: Finds the nearest activated waystone to the player. - **Returns**: An `Optional` of the nearest waystone. #### `activateWaystone(ServerPlayer player, Waystone waystone)` - **Description**: Activates a waystone for a specific player. #### `deactivateWaystone(ServerPlayer player, Waystone waystone)` - **Description**: Deactivates a waystone for a specific player. #### `removeWaystoneFromDatabase(MinecraftServer server, Waystone waystone)` - **Description**: Removes a waystone's data from the database. This does not break the physical block. ### Example Usage ```java import com.mojang.datafixers.util.Either; import net.blay09.mods.waystones.api.*; import net.blay09.mods.waystones.api.error.WaystoneTeleportError; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; // --- Query a waystone at a block position --- ServerLevel overworld = server.overworld(); BlockPos pos = new BlockPos(100, 64, 200); Optional maybeWaystone = WaystonesAPI.getWaystoneAt(overworld, pos); maybeWaystone.ifPresent(waystone -> { System.out.println("Name: " + waystone.getName().getString()); System.out.println("UUID: " + waystone.getWaystoneUid()); System.out.println("Dimension: " + waystone.getDimension().location()); System.out.println("Kind: " + waystone.getWaystoneKind()); // e.g. waystones:waystone System.out.println("Origin: " + waystone.getOrigin()); // VILLAGE / WILDERNESS / PLAYER … System.out.println("Visibility: " + waystone.getVisibility()); // ACTIVATION / GLOBAL / SHARD_ONLY / SHARESTONES System.out.println("Valid: " + waystone.isValid()); }); // --- Look up a waystone by UUID --- UUID uid = UUID.fromString("…"); Optional byUid = WaystonesAPI.getWaystone(server, uid); // --- List every waystone in the database --- Collection all = WaystonesAPI.getAllWaystones(server); // --- List all waystones of one kind --- Collection regularWaystones = WaystonesAPI.getWaystonesByType(server, WaystoneKinds.WAYSTONE); // --- Check / manage activation state for a player --- boolean activated = WaystonesAPI.isWaystoneActivated(player, waystone); Collection playerWaystones = WaystonesAPI.getActivatedWaystones(player); Optional nearest = WaystonesAPI.getNearestWaystone(player); // --- Activate / deactivate a waystone for a specific player --- WaystonesAPI.activateWaystone((ServerPlayer) player, waystone); WaystonesAPI.deactivateWaystone((ServerPlayer) player, waystone); // --- Remove a waystone's data from the database (does not break the block) --- WaystonesAPI.removeWaystoneFromDatabase(server, waystone); ``` ``` -------------------------------- ### Create Bound Waystone Items with WaystonesAPI Source: https://context7.com/twelveiterations/waystones/llms.txt Utilize WaystonesAPI methods to create item stacks pre-bound to specific waystones. These items can be given to players or added to loot tables. Supports attuned shards for warp plates and bound scrolls for regular waystones. ```java import net.blay09.mods.waystones.api.WaystonesAPI; import net.minecraft.world.item.ItemStack; // Give a player an attuned shard linked to a warp plate Waystone warpPlate = WaystonesAPI.getWaystoneAt(level, platPos).orElseThrow(); ItemStack shard = WaystonesAPI.createAttunedShard(warpPlate); player.getInventory().add(shard); // Give a player a bound scroll linked to any waystone Waystone home = WaystonesAPI.getWaystoneAt(level, homePos).orElseThrow(); ItemStack scroll = WaystonesAPI.createBoundScroll(home); player.getInventory().add(scroll); // Bind an existing item stack to a waystone ItemStack existingScroll = new ItemStack(ModItems.BOUND_SCROLL.get()); WaystonesAPI.setBoundWaystone(existingScroll, home); // Read the bound waystone back from an item stack Optional bound = WaystonesAPI.getBoundWaystone(player, existingScroll); bound.ifPresent(w -> System.out.println("Scroll is bound to: " + w.getName().getString())); ``` -------------------------------- ### Waystones In-Game Commands Source: https://context7.com/twelveiterations/waystones/llms.txt Utilize the /waystones command for server operators to manage waystones. Commands include activating, forgetting, placing, counting, listing, and managing cooldowns. ```bash # Activate a waystone at for one or more players /waystones activate # Make a player forget a waystone at , or all waystones /waystones forget /waystones forget all # Place a waystone block of a given type with a name /waystones place # Example: /waystones place 100 64 200 sandstone_waystone "Desert Outpost" # Count a player's activated waystones /waystones count # List a player's owned or all activated waystones (clickable coordinates in chat) /waystones list /waystones list all # Open the waystone selection GUI for a player /waystones gui # Reset all cooldowns or a specific cooldown for players /waystones cooldown reset all /waystones cooldown reset # Example: /waystones cooldown @a reset waystones:inventory_button ``` -------------------------------- ### Accessing Waystones Configuration Source: https://context7.com/twelveiterations/waystones/llms.txt Retrieve the active configuration for Waystones using WaystonesConfig.getActive(). Access rules, inventory button settings, and world generation parameters. ```java import net.blay09.mods.waystones.config.WaystonesConfig; WaystonesConfig cfg = WaystonesConfig.getActive(); // Rules sub-section System.out.println("XP costs enabled: " + cfg.rules.enableXpCosts); System.out.println("Cooldowns enabled: " + cfg.rules.enableCooldowns); System.out.println("Durability enabled: " + cfg.rules.enableDurability); System.out.println("Default visibility: " + cfg.rules.defaultVisibility); // ACTIVATION or GLOBAL System.out.println("Transport pets: " + cfg.rules.transportPets); // ENABLED / SAME_DIMENSION / DISABLED System.out.println("Transport leashed: " + cfg.rules.transportLeashed); System.out.println("Warp requirements:\n " + String.join("\n ", cfg.rules.warpRequirements)); // Inventory button sub-section System.out.println("Inventory button: " + cfg.inventoryButton.inventoryButton); // "" / "nearest" / "any" / "" System.out.println("Button X/Y: " + cfg.inventoryButton.inventoryButtonX + "/" + cfg.inventoryButton.inventoryButtonY); // World generation sub-section System.out.println("Waystone style: " + cfg.worldGen.wildWaystoneStyle); // BIOME / DEFAULT / MOSSY / SANDY System.out.println("Chunks between: " + cfg.worldGen.chunksBetweenWildWaystones); System.out.println("Village spawning: " + cfg.worldGen.spawnInVillages); // REGULAR / FREQUENT / DISABLED System.out.println("Name mode: " + cfg.worldGen.nameGenerationMode); // PRESET_FIRST / PRESET_ONLY / MIXED ``` -------------------------------- ### WaystonesAPI.createAttunedShard / createBoundScroll Source: https://context7.com/twelveiterations/waystones/llms.txt These methods create item stacks that are pre-bound to a specific waystone, ready to be inserted into player inventories or loot tables. `createAttunedShard` targets warp plates; `createBoundScroll` targets regular waystones. ```APIDOC ## `WaystonesAPI.createAttunedShard` / `createBoundScroll` — Item Creation These methods create item stacks that are pre-bound to a specific waystone, ready to be inserted into player inventories or loot tables. `createAttunedShard` targets warp plates; `createBoundScroll` targets regular waystones. ```java import net.blay09.mods.waystones.api.WaystonesAPI; import net.minecraft.world.item.ItemStack; // Give a player an attuned shard linked to a warp plate Waystone warpPlate = WaystonesAPI.getWaystoneAt(level, platPos).orElseThrow(); ItemStack shard = WaystonesAPI.createAttunedShard(warpPlate); player.getInventory().add(shard); // Give a player a bound scroll linked to any waystone Waystone home = WaystonesAPI.getWaystoneAt(level, homePos).orElseThrow(); ItemStack scroll = WaystonesAPI.createBoundScroll(home); player.getInventory().add(scroll); // Bind an existing item stack to a waystone ItemStack existingScroll = new ItemStack(ModItems.BOUND_SCROLL.get()); WaystonesAPI.setBoundWaystone(existingScroll, home); // Read the bound waystone back from an item stack Optional bound = WaystonesAPI.getBoundWaystone(player, existingScroll); bound.ifPresent(w -> System.out.println("Scroll is bound to: " + w.getName().getString())); ``` ``` -------------------------------- ### Registering Custom Requirement Renderers and Mergers Source: https://context7.com/twelveiterations/waystones/llms.txt Use WaystonesClientAPI to register custom renderers and mergers for warp requirements on the client side. This allows custom display logic in the waystone selection GUI. ```java import net.blay09.mods.waystones.api.client.WaystonesClientAPI; import net.blay09.mods.waystones.client.requirement.RequirementRenderer; import net.blay09.mods.waystones.client.requirement.RequirementMerger; // Register a renderer for a custom requirement type WaystonesClientAPI.registerRequirementRenderer(MyRequirement.class, (guiGraphics, x, y, requirement) -> { // Draw cost icon or text at (x, y) guiGraphics.drawString(font, requirement.getCostLabel(), x, y, 0xFFFFFF); } ); // Register a merger so identical requirements are combined into one display line WaystonesClientAPI.registerRequirementMerger(MyRequirement.class, (a, b) -> new MyRequirement(a.getCost() + b.getCost()) ); ``` -------------------------------- ### Handle Waystone Teleport Events Source: https://context7.com/twelveiterations/waystones/llms.txt Subscribe to WaystoneTeleportEvent.Before and WaystoneTeleportEvent.After to intercept or react to teleportation attempts. The 'Before' event is cancellable and allows modification of the teleport context, while 'After' provides the final teleported entities. ```java import net.blay09.mods.waystones.api.event.WaystoneTeleportEvent; // Register in your mod initializer (Balm event bus) WaystoneTeleportEvent.Before.EVENT.register(event -> { WaystoneTeleportContext ctx = event.getContext(); Waystone target = ctx.getTargetWaystone(); // Example: block teleport into a specific named zone if (target.getName().getString().equalsIgnoreCase("Forbidden Zone")) { event.setCanceled(true); ctx.getEntity().sendSystemMessage( Component.literal("That waystone is sealed!") ); return; } // Example: add a companion entity to every teleport Entity companion = findCompanion(ctx.getEntity()); if (companion != null) { event.addAdditionalEntity(companion); } }); WaystoneTeleportEvent.After.EVENT.register(event -> { List teleported = event.getTeleportedEntities(); Waystone from = event.getContext().getFromWaystone().orElse(null); Waystone to = event.getContext().getTargetWaystone(); System.out.printf("Teleport complete: %d entities → %s%n", teleported.size(), to.getName().getString()); }); ``` -------------------------------- ### WaystonesClientAPI Source: https://context7.com/twelveiterations/waystones/llms.txt Allows client-side mods to register custom renderers and mergers for warp requirement objects, ensuring they are displayed correctly in the waystone selection GUI. ```APIDOC ## `WaystonesClientAPI` — Client-Side Requirement Rendering `WaystonesClientAPI` lets client-side mods register custom renderers and mergers for warp requirement objects, so they appear correctly in the waystone selection GUI. ```java import net.blay09.mods.waystones.api.client.WaystonesClientAPI; import net.blay09.mods.waystones.client.requirement.RequirementRenderer; import net.blay09.mods.waystones.client.requirement.RequirementMerger; // Register a renderer for a custom requirement type WaystonesClientAPI.registerRequirementRenderer(MyRequirement.class, (guiGraphics, x, y, requirement) -> { // Draw cost icon or text at (x, y) guiGraphics.drawString(font, requirement.getCostLabel(), x, y, 0xFFFFFF); } ); // Register a merger so identical requirements are combined into one display line WaystonesClientAPI.registerRequirementMerger(MyRequirement.class, (a, b) -> new MyRequirement(a.getCost() + b.getCost()) ); ``` ``` -------------------------------- ### Query Waystone Data with WaystonesAPI Source: https://context7.com/twelveiterations/waystones/llms.txt Use WaystonesAPI to retrieve information about waystones at specific locations, by UUID, or from the entire database. This includes details like name, UUID, dimension, kind, origin, visibility, and validity. ```java import com.mojang.datafixers.util.Either; import net.blay09.mods.waystones.api.*; import net.blay09.mods.waystones.api.error.WaystoneTeleportError; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; // --- Query a waystone at a block position --- ServerLevel overworld = server.overworld(); BlockPos pos = new BlockPos(100, 64, 200); Optional maybeWaystone = WaystonesAPI.getWaystoneAt(overworld, pos); maybeWaystone.ifPresent(waystone -> { System.out.println("Name: " + waystone.getName().getString()); System.out.println("UUID: " + waystone.getWaystoneUid()); System.out.println("Dimension: " + waystone.getDimension().location()); System.out.println("Kind: " + waystone.getWaystoneKind()); // e.g. waystones:waystone System.out.println("Origin: " + waystone.getOrigin()); // VILLAGE / WILDERNESS / PLAYER … System.out.println("Visibility: " + waystone.getVisibility()); // ACTIVATION / GLOBAL / SHARD_ONLY / SHARESTONES System.out.println("Valid: " + waystone.isValid()); }); // --- Look up a waystone by UUID --- UUID uid = UUID.fromString("…"); Optional byUid = WaystonesAPI.getWaystone(server, uid); // --- List every waystone in the database --- Collection all = WaystonesAPI.getAllWaystones(server); // --- List all waystones of one kind --- Collection regularWaystones = WaystonesAPI.getWaystonesByType(server, WaystoneKinds.WAYSTONE); // --- Check / manage activation state for a player --- boolean activated = WaystonesAPI.isWaystoneActivated(player, waystone); Collection playerWaystones = WaystonesAPI.getActivatedWaystones(player); Optional nearest = WaystonesAPI.getNearestWaystone(player); // --- Activate / deactivate a waystone for a specific player --- WaystonesAPI.activateWaystone((ServerPlayer) player, waystone); WaystonesAPI.deactivateWaystone((ServerPlayer) player, waystone); // --- Remove a waystone's data from the database (does not break the block) --- WaystonesAPI.removeWaystoneFromDatabase(server, waystone); ``` -------------------------------- ### Register Custom Waystone Name Generation Event Source: https://context7.com/twelveiterations/waystones/llms.txt Register an event handler to customize waystone names during world generation or first activation. This allows for biome-aware or localized naming conventions. ```java import net.blay09.mods.waystones.api.event.GenerateWaystoneNameEvent; import net.minecraft.network.chat.Component; GenerateWaystoneNameEvent.EVENT.register(event -> { Waystone w = event.getWaystone(); // Use biome name as the waystone name for wilderness waystones if (w.wasGenerated()) { // event.getName() holds the default generated name at this point String currentName = event.getName().getString(); if (currentName.isEmpty()) { event.setName(Component.literal("Unnamed Shrine")); } } // Prefix player-placed waystones with a crown symbol if (w.getOrigin() == WaystoneOrigin.PLAYER) { event.setName(Component.literal("♔ " + event.getName().getString())); } }); ``` -------------------------------- ### WaystoneType Registration and Placement Source: https://context7.com/twelveiterations/waystones/llms.txt Third-party mods can add entirely new waystone visual variants by registering a `WaystoneType`. Each type maps to a block supplier and a rune colour. ```APIDOC ## `WaystoneType` — Custom Waystone Type Registration Third-party mods can add entirely new waystone visual variants by registering a `WaystoneType`. Each type maps to a block supplier and a rune colour used for the block's glowing overlay. ```java import net.blay09.mods.waystones.api.WaystoneType; import net.minecraft.resources.Identifier; // During mod initialisation (before blocks are used in-world) WaystoneType myType = new WaystoneType( Identifier.fromNamespaceAndPath("mymod", "obsidian_waystone"), 0x660066, // purple rune colour (ARGB hex) () -> MyModBlocks.OBSIDIAN_WAYSTONE.get() ); WaystoneType.register(myType); // Place one at runtime ServerLevel level = server.overworld(); WaystonesAPI.placeWaystone(level, new BlockPos(0, 64, 0), myType); ``` ``` -------------------------------- ### Waystones Configuration Source: https://context7.com/twelveiterations/waystones/llms.txt Access and modify Waystones configuration settings. Synced fields are automatically sent to clients. Retrieve the active configuration using `WaystonesConfig.getActive()`. ```APIDOC ## `WaystonesConfig` — Server / Client Configuration `WaystonesConfig` is a Balm-managed config class annotated with `@Config("waystones")`. `@Synced` fields are automatically sent to connecting clients. Retrieve the active config via `WaystonesConfig.getActive()`. ```java import net.blay09.mods.waystones.config.WaystonesConfig; WaystonesConfig cfg = WaystonesConfig.getActive(); // Rules sub-section System.out.println("XP costs enabled: " + cfg.rules.enableXpCosts); System.out.println("Cooldowns enabled: " + cfg.rules.enableCooldowns); System.out.println("Durability enabled: " + cfg.rules.enableDurability); System.out.println("Default visibility: " + cfg.rules.defaultVisibility); // ACTIVATION or GLOBAL System.out.println("Transport pets: " + cfg.rules.transportPets); // ENABLED / SAME_DIMENSION / DISABLED System.out.println("Transport leashed: " + cfg.rules.transportLeashed); System.out.println("Warp requirements:\n " + String.join("\n ", cfg.rules.warpRequirements)); // Inventory button sub-section System.out.println("Inventory button: " + cfg.inventoryButton.inventoryButton); // "" / "nearest" / "any" / "" System.out.println("Button X/Y: " + cfg.inventoryButton.inventoryButtonX + "/" + cfg.inventoryButton.inventoryButtonY); // World generation sub-section System.out.println("Waystone style: " + cfg.worldGen.wildWaystoneStyle); // BIOME / DEFAULT / MOSSY / SANDY System.out.println("Chunks between: " + cfg.worldGen.chunksBetweenWildWaystones); System.out.println("Village spawning: " + cfg.worldGen.spawnInVillages); // REGULAR / FREQUENT / DISABLED System.out.println("Name mode: " + cfg.worldGen.nameGenerationMode); // PRESET_FIRST / PRESET_ONLY / MIXED ``` ``` -------------------------------- ### Handle Waystone Activation Event Source: https://context7.com/twelveiterations/waystones/llms.txt Use WaystoneActivatedEvent to react when a player discovers a waystone for the first time. This is suitable for awarding achievements, logging statistics, or updating external map markers. ```java import net.blay09.mods.waystones.api.event.WaystoneActivatedEvent; WaystoneActivatedEvent.EVENT.register(event -> { Player player = event.player(); Waystone waystone = event.waystone(); System.out.printf("[Waystones] %s activated '%s' at %s in %s%n", player.getName().getString(), waystone.getName().getString(), waystone.getPos(), waystone.getDimension().location() ); // Example: award an advancement trigger if (player instanceof ServerPlayer sp) { ModTriggers.WAYSTONE_FOUND.trigger(sp, waystone); } }); ``` -------------------------------- ### Using Waystone Kind Identifiers Source: https://context7.com/twelveiterations/waystones/llms.txt Utilize WaystoneKinds constants for canonical Identifier values of built-in waystone kinds. Use these for filtering or routing logic by kind, and check if a kind is a sharestone. ```java import net.blay09.mods.waystones.api.WaystoneKinds; import net.minecraft.resources.Identifier; // Built-in kind constants Identifier waystoneKind = WaystoneKinds.WAYSTONE; // waystones:waystone Identifier warpPlateKind = WaystoneKinds.WARP_PLATE; // waystones:warp_plate Identifier invalidKind = WaystoneKinds.INVALID; // waystones:invalid // Test whether a kind is a sharestone WaystoneKinds.SHARESTONES.forEach(id -> System.out.println("Sharestone kind: " + id)); boolean isSharestone = WaystoneKinds.isSharestone(someWaystone.getWaystoneKind()); // Filter the global waystone list to only warp plates Collection warpPlates = WaystonesAPI.getAllWaystones(server) .stream() .filter(w -> w.getWaystoneKind().equals(WaystoneKinds.WARP_PLATE)) .toList(); ``` -------------------------------- ### WaystoneActivatedEvent Source: https://context7.com/twelveiterations/waystones/llms.txt Fires on the server whenever a player first activates (discovers) a waystone. Useful for awarding achievements, logging statistics, or syncing external map markers. ```APIDOC ## `WaystoneActivatedEvent` — Waystone Activation Event Fires on the server whenever a player first activates (discovers) a waystone. This is the right hook for awarding achievements, logging statistics, or syncing external map markers. ```java import net.blay09.mods.waystones.api.event.WaystoneActivatedEvent; WaystoneActivatedEvent.EVENT.register(event -> { Player player = event.player(); Waystone waystone = event.waystone(); System.out.printf("[Waystones] %s activated '%s' at %s in %s%n", player.getName().getString(), waystone.getName().getString(), waystone.getPos(), waystone.getDimension().location() ); // Example: award an advancement trigger if (player instanceof ServerPlayer sp) { ModTriggers.WAYSTONE_FOUND.trigger(sp, waystone); } }); ``` ``` -------------------------------- ### WaystoneTeleportContext Builder Source: https://context7.com/twelveiterations/waystones/llms.txt Use WaystoneTeleportContext to manage and modify parameters for a single teleportation attempt. It provides a fluent interface for setting various teleportation properties and flags. ```APIDOC ## `WaystoneTeleportContext` — Teleport Context Builder `WaystoneTeleportContext` carries all mutable parameters that influence a single teleportation attempt. It implements a fluent builder interface and also exposes the Shogi requirements pipeline so that other mods can add or inspect warp costs. ```java import net.blay09.mods.waystones.api.*; WaystoneTeleportContext ctx = /* obtained from createDefaultTeleportContext or createCustomTeleportContext */; // Add extra entities to teleport alongside the primary entity ctx.addAdditionalEntity(someNPC); // Configure sound/particle effects ctx.setPlaysSound(false).setPlaysEffect(false); // Override the warp item (affects item-based requirements like durability) ctx.setWarpItem(warpStoneStack); ctx.setWarpHand(InteractionHand.MAIN_HAND); // Attach a "from" waystone so the XP cost formula can compute distance ctx.setFromWaystone(sourceWaystone); // Teleport flags affect rule evaluation ctx.addFlag(TeleportFlags.INVENTORY_BUTTON); // waystones:inventory_button ctx.addFlag(TeleportFlags.PORTSTONE); // waystones:portstone ctx.removeFlag(TeleportFlags.ADMIN); // Read back state System.out.println("Is dimensional teleport: " + ctx.isDimensionalTeleport()); System.out.println("Target: " + ctx.getTargetWaystone().getName().getString()); System.out.println("Leashed mobs: " + ctx.getLeashedEntities().size()); System.out.println("Active flags: " + ctx.getFlags()); ``` ``` -------------------------------- ### Register Custom Waystone Types Source: https://context7.com/twelveiterations/waystones/llms.txt Register custom WaystoneTypes to introduce new visual variants of waystones in the game. This involves defining a unique identifier, a rune color, and a block supplier for the new waystone variant. ```java import net.blay09.mods.waystones.api.WaystoneType; import net.minecraft.resources.Identifier; // During mod initialisation (before blocks are used in-world) WaystoneType myType = new WaystoneType( Identifier.fromNamespaceAndPath("mymod", "obsidian_waystone"), 0x660066, // purple rune colour (ARGB hex) () -> MyModBlocks.OBSIDIAN_WAYSTONE.get() ); WaystoneType.register(myType); // Place one at runtime ServerLevel level = server.overworld(); WaystonesAPI.placeWaystone(level, new BlockPos(0, 64, 0), myType); ``` -------------------------------- ### WaystoneKinds Source: https://context7.com/twelveiterations/waystones/llms.txt Provides canonical `Identifier` constants for built-in waystone kinds and a thread-safe sharestone set. Use these for filtering or routing logic by kind. ```APIDOC ## `WaystoneKinds` — Kind Identifiers `WaystoneKinds` provides the canonical `Identifier` constants for all built-in waystone kinds and a thread-safe sharestone set. Use these instead of string literals when filtering or routing logic by kind. ```java import net.blay09.mods.waystones.api.WaystoneKinds; import net.minecraft.resources.Identifier; // Built-in kind constants Identifier waystoneKind = WaystoneKinds.WAYSTONE; // waystones:waystone Identifier warpPlateKind = WaystoneKinds.WARP_PLATE; // waystones:warp_plate Identifier invalidKind = WaystoneKinds.INVALID; // waystones:invalid // Test whether a kind is a sharestone WaystoneKinds.SHARESTONES.forEach(id -> System.out.println("Sharestone kind: " + id)); boolean isSharestone = WaystoneKinds.isSharestone(someWaystone.getWaystoneKind()); // Filter the global waystone list to only warp plates Collection warpPlates = WaystonesAPI.getAllWaystones(server) .stream() .filter(w -> w.getWaystoneKind().equals(WaystoneKinds.WARP_PLATE)) .toList(); ``` ``` -------------------------------- ### Handle Waystone Lifecycle Events Source: https://context7.com/twelveiterations/waystones/llms.txt Subscribe to WaystoneRemovedEvent and WaystoneUpdatedEvent to manage external integrations when a waystone is destroyed or its properties change. These events provide the affected Waystone instance. ```java import net.blay09.mods.waystones.api.event.WaystoneRemovedEvent; import net.blay09.mods.waystones.api.event.WaystoneUpdatedEvent; WaystoneRemovedEvent.EVENT.register(event -> { Waystone w = event.waystone(); System.out.println("Waystone removed: " + w.getName().getString() + " (uuid=" + w.getWaystoneUid() + ")"); // E.g. remove the corresponding JourneyMap waypoint or BlueMap marker ExternalMapSync.removeMarker(w.getWaystoneUid()); }); WaystoneUpdatedEvent.EVENT.register(event -> { Waystone w = event.waystone(); System.out.println("Waystone updated: " + w.getName().getString() + " visibility=" + w.getVisibility() + " pos=" + w.getPos()); // E.g. refresh the map marker label ExternalMapSync.updateMarker(w); }); ``` -------------------------------- ### GenerateWaystoneNameEvent Source: https://context7.com/twelveiterations/waystones/llms.txt Fires during world-generation or first activation when a nameless waystone needs a name. Handlers can override the generated component name. ```APIDOC ## `GenerateWaystoneNameEvent` — Custom Name Generation Fires during world-generation (or first activation) when a nameless waystone needs a name. Handlers can override the generated `Component` name, enabling integration with custom name lists, biome-aware naming, or localisation plugins. ```java import net.blay09.mods.waystones.api.event.GenerateWaystoneNameEvent; import net.minecraft.network.chat.Component; GenerateWaystoneNameEvent.EVENT.register(event -> { Waystone w = event.getWaystone(); // Use biome name as the waystone name for wilderness waystones if (w.wasGenerated()) { // event.getName() holds the default generated name at this point String currentName = event.getName().getString(); if (currentName.isEmpty()) { event.setName(Component.literal("Unnamed Shrine")); } } // Prefix player-placed waystones with a crown symbol if (w.getOrigin() == WaystoneOrigin.PLAYER) { event.setName(Component.literal("♔ " + event.getName().getString())); } }); ``` ``` -------------------------------- ### WaystoneRemovedEvent / WaystoneUpdatedEvent Source: https://context7.com/twelveiterations/waystones/llms.txt Lifecycle events for waystones. `WaystoneRemovedEvent` fires when a waystone is destroyed. `WaystoneUpdatedEvent` fires when a waystone's name, visibility, or owner changes. ```APIDOC ## `WaystoneRemovedEvent` / `WaystoneUpdatedEvent` — Lifecycle Events `WaystoneRemovedEvent` fires when a waystone block is destroyed and its data purged. `WaystoneUpdatedEvent` fires whenever a waystone's name, visibility, or owner changes. Both carry the affected `Waystone` instance. ```java import net.blay09.mods.waystones.api.event.WaystoneRemovedEvent; import net.blay09.mods.waystones.api.event.WaystoneUpdatedEvent; WaystoneRemovedEvent.EVENT.register(event -> { Waystone w = event.waystone(); System.out.println("Waystone removed: " + w.getName().getString() + " (uuid=" + w.getWaystoneUid() + ")"); // E.g. remove the corresponding JourneyMap waypoint or BlueMap marker ExternalMapSync.removeMarker(w.getWaystoneUid()); }); WaystoneUpdatedEvent.EVENT.register(event -> { Waystone w = event.waystone(); System.out.println("Waystone updated: " + w.getName().getString() + " visibility=" + w.getVisibility() + " pos=" + w.getPos()); // E.g. refresh the map marker label ExternalMapSync.updateMarker(w); }); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.