feat(api): expand block/item hooks and debug tools

This commit is contained in:
Jacobwasbeast
2026-03-12 20:25:45 -05:00
parent 24dbf8b96b
commit faada7fbc4
12 changed files with 2883 additions and 31 deletions

View File

@@ -16,12 +16,14 @@ public class ExampleMod : IMod
public static RegisteredBlock? RubyWoodPlanks;
public static RegisteredBlock? RubyChair;
public static RegisteredBlock? RubySand;
public static RegisteredBlock? DebugHooksBlock;
public static RegisteredSlabBlock? RubyStoneSlab;
public static RegisteredSlabBlock? RubyWoodSlab;
public static RegisteredBlock? RubyLamp;
public static RegisteredBlock? RubyLampLit;
public static RegisteredBlock? Orichalcum;
public static RegisteredItem? Ruby;
public static RegisteredItem? DebugHooksItemEntry;
public static RegisteredItem? RubyPickaxeItem;
public static RegisteredItem? RubyShovelItem;
public static RegisteredItem? RubyHoeItem;
@@ -37,9 +39,6 @@ public class ExampleMod : IMod
public override UseItemResult OnUseItem(UseItemContext context)
{
if (context.IsTestUseOnly)
return UseItemResult.CancelVanilla;
long now = Environment.TickCount64;
ref long nextUseAtMs = ref context.IsClientSide ? ref _nextClientUseAtMs : ref _nextServerUseAtMs;
if (now < nextUseAtMs)
@@ -190,6 +189,153 @@ public class ExampleMod : IMod
}
}
private sealed class DebugHooks : WeaveLoader.API.Block.Block
{
private static void Log(string hook, BlockUpdateContext block, string? extra = null)
{
if (string.IsNullOrWhiteSpace(extra))
Logger.Info($"DebugHooks::{hook} at ({block.X}, {block.Y}, {block.Z}) blockId={block.BlockId} client={block.IsClientSide}");
else
Logger.Info($"DebugHooks::{hook} at ({block.X}, {block.Y}, {block.Z}) blockId={block.BlockId} client={block.IsClientSide} {extra}");
}
public override void OnPlace(BlockUpdateContext context)
{
Log("OnPlace", context);
}
public override void OnNeighborChanged(BlockNeighborChangedContext context)
{
Log("OnNeighborChanged", context.Block, $"neighborId={context.NeighborBlockId}");
}
public override void OnScheduledTick(BlockTickContext context)
{
Log("OnScheduledTick", context.Block);
}
public override BlockActionResult OnUse(BlockUseContext context)
{
Log("OnUse", context.Block,
$"face={context.Face} click=({context.ClickX:0.00},{context.ClickY:0.00},{context.ClickZ:0.00}) soundOnly={context.SoundOnly}");
return BlockActionResult.ContinueVanilla;
}
public override void OnStepOn(BlockEntityContext context)
{
Log("OnStepOn", context.Block, $"entityPtr=0x{context.NativeEntityPtr.ToString("X")}");
}
public override void OnEntityInsideTile(BlockEntityContext context)
{
Log("OnEntityInsideTile", context.Block, $"entityPtr=0x{context.NativeEntityPtr.ToString("X")}");
}
public override void OnFallOn(BlockFallContext context)
{
Log("OnFallOn", context.Block, $"entityPtr=0x{context.NativeEntityPtr.ToString("X")} fall={context.FallDistance:0.00}");
}
public override void OnRemoving(BlockRemovingContext context)
{
Log("OnRemoving", context.Block, $"blockData={context.BlockData}");
}
public override void OnRemoved(BlockRemoveContext context)
{
Log("OnRemoved", context.Block, $"removedId={context.RemovedBlockId} removedData={context.RemovedBlockData}");
}
public override void OnDestroyed(BlockDestroyContext context)
{
Log("OnDestroyed", context.Block, $"blockData={context.BlockData}");
}
public override void OnPlayerDestroy(BlockPlayerDestroyContext context)
{
Log("OnPlayerDestroy", context.Block,
$"playerPtr=0x{context.NativePlayerPtr.ToString("X")} blockData={context.BlockData}");
}
public override void OnPlayerWillDestroy(BlockPlayerWillDestroyContext context)
{
Log("OnPlayerWillDestroy", context.Block,
$"playerPtr=0x{context.NativePlayerPtr.ToString("X")} blockData={context.BlockData}");
}
public override void OnPlacedBy(BlockPlacedByContext context)
{
Log("OnPlacedBy", context.Block,
$"placerPtr=0x{context.NativePlacerPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
}
}
private sealed class DebugHooksItem : Item
{
private static void Log(string hook, string? extra = null)
{
if (string.IsNullOrWhiteSpace(extra))
Logger.Info($"DebugItem::{hook}");
else
Logger.Info($"DebugItem::{hook} {extra}");
}
public override MineBlockResult OnMineBlock(MineBlockContext context)
{
Log("OnMineBlock", $"itemId={context.ItemId} tileId={context.TileId} pos=({context.X},{context.Y},{context.Z})");
return MineBlockResult.ContinueVanilla;
}
public override UseItemResult OnUseItem(UseItemContext context)
{
Log("OnUseItem",
$"itemId={context.ItemId} client={context.IsClientSide} " +
$"itemPtr=0x{context.NativeItemInstancePtr.ToString("X")} playerPtr=0x{context.NativePlayerPtr.ToString("X")}");
return UseItemResult.ContinueVanilla;
}
public override ItemActionResult OnUseOn(UseOnItemContext context)
{
Log("OnUseOn",
$"itemId={context.ItemId} client={context.IsClientSide} " +
$"pos=({context.X},{context.Y},{context.Z}) face={context.Face} " +
$"click=({context.ClickX:0.00},{context.ClickY:0.00},{context.ClickZ:0.00}) " +
$"playerPtr=0x{context.NativePlayerPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
return ItemActionResult.ContinueVanilla;
}
public override ItemActionResult OnInteractEntity(ItemEntityInteractionContext context)
{
Log("OnInteractEntity",
$"itemId={context.ItemId} playerPtr=0x{context.NativePlayerPtr.ToString("X")} " +
$"targetPtr=0x{context.NativeTargetEntityPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
return ItemActionResult.ContinueVanilla;
}
public override ItemActionResult OnHurtEntity(ItemEntityInteractionContext context)
{
Log("OnHurtEntity",
$"itemId={context.ItemId} playerPtr=0x{context.NativePlayerPtr.ToString("X")} " +
$"targetPtr=0x{context.NativeTargetEntityPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
return ItemActionResult.ContinueVanilla;
}
public override void OnInventoryTick(ItemInventoryTickContext context)
{
Log("OnInventoryTick",
$"itemId={context.ItemId} slot={context.Slot} selected={context.IsSelected} client={context.IsClientSide} " +
$"ownerPtr=0x{context.NativeOwnerEntityPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
}
public override void OnCraftedBy(ItemCraftedByContext context)
{
Log("OnCraftedBy",
$"itemId={context.ItemId} amount={context.Amount} client={context.IsClientSide} " +
$"playerPtr=0x{context.NativePlayerPtr.ToString("X")} itemPtr=0x{context.NativeItemInstancePtr.ToString("X")}");
}
}
public void OnInitialize()
{
GameEvents.OnWorldLoaded += (_, e) =>
@@ -262,6 +408,17 @@ public class ExampleMod : IMod
.InCreativeTab(CreativeTab.BuildingBlocks)
.Prepend());
DebugHooksBlock = Registry.Block.Register("examplemod:debug_hooks",
new DebugHooks(),
new BlockProperties()
.Material(MaterialType.Stone)
.Hardness(1.0f)
.Resistance(5.0f)
.Sound(SoundType.Stone)
.Icon("examplemod:block/ruby_stone")
.Name(Text.Translatable("block.examplemod.debug_hooks"))
.InCreativeTab(CreativeTab.BuildingBlocks));
RubyStoneSlab = (RegisteredSlabBlock)Registry.Block.Register("examplemod:ruby_stone_slab",
new SlabBlock(),
new BlockProperties()
@@ -336,6 +493,14 @@ public class ExampleMod : IMod
.Name(Text.Translatable("item.examplemod.ruby"))
.InCreativeTab(CreativeTab.Materials));
DebugHooksItemEntry = Registry.Item.Register("examplemod:debug_item",
new DebugHooksItem(),
new ItemProperties()
.MaxStackSize(1)
.Icon("examplemod:item/ruby")
.Name(Text.Translatable("item.examplemod.debug_item"))
.InCreativeTab(CreativeTab.ToolsAndWeapons));
Registry.Item.RegisterToolMaterial("examplemod:ruby_material",
new ToolMaterialDefinition()
.BaseTier(ToolTier.Diamond)

View File

@@ -11,7 +11,9 @@ block.examplemod.ruby_wood_slab_double=Ruby Wood Slab
block.examplemod.ruby_lamp=Ruby Lamp
block.examplemod.ruby_lamp_lit=Ruby Lamp
block.examplemod.orichalcum_ore=Orichalcum Ore
block.examplemod.debug_hooks=Debug Hooks Block
item.examplemod.ruby=Ruby
item.examplemod.debug_item=Debug Hooks Item
item.examplemod.ruby_sword=Ruby Sword
item.examplemod.ruby_shovel=Ruby Shovel
item.examplemod.ruby_pickaxe=Ruby Pickaxe