S&box Wiki

Revision Difference

Hammer_API#547837

<cat>Code.Misc</cat>⤶ <title>Hammer API</title>⤶ ⤶ <note>This stuff isn't mature as our games API, so this stuff will end up changing a fair amount as we figure out the best way to do things.</note>⤶ ⤶ # Hammer API⤶ ⤶ Tool addons can extend the capabilities of Hammer by using these APIs, you can interact with selected [map nodes](https://asset.party/api/Tools.MapDoc.MapNode) or procedurally create new map nodes. These nodes can be a [MapMesh](https://asset.party/api/Tools.MapDoc.MapMesh) which can procedurally create a mesh, [MapEntity](https://asset.party/api/Tools.MapDoc.MapEntity) for placing map entities and setting key values, or more.⤶ ⤶ ## Map Nodes⤶ ⤶ Map nodes can be created in the current map simply by calling their constructors.⤶ ⤶ ```csharp⤶ // Create new map entity⤶ MapEntity entity = new();⤶ entity.ClassName = "info_player_start";⤶ entity.Position = Vector3.Up * 32.0f;⤶ ```⤶ ⤶ ## Selection⤶ ⤶ You can get all the selected map nodes, or set the selection with the [Selection](https://asset.party/api/Tools.MapEditor.Selection) static class.⤶ ⤶ ```csharp⤶ // Get the first selected map node⤶ MapNode node = Selection.All.FirstOrDefault();⤶ ⤶ // You can pattern match MapNodes⤶ if ( node is MapMesh mesh )⤶ {⤶ // ...⤶ }⤶ ⤶ // Create a new entity and add it to the selection⤶ Selection.Add( new MapEntity() );⤶ ```⤶ ⤶ ## Traces⤶ ⤶ The [Trace](https://asset.party/api/Tools.Trace) API lets you ray cast within map worlds, there's options to only hit meshes or skip tools materials. This primarily has usage for pickers, but could be used to snap things down or some crazy procedural stuff.⤶ ⤶ ```csharp⤶ view.BuildRay( out Vector3 rayStart, out Vector3 rayEnd );⤶ var tr = Trace.Ray( rayStart, rayEnd ).Run( view.MapDoc.World );⤶ ⤶ var entity = new MapEntity();⤶ entity.ClassName = classname;⤶ entity.Position = tr.HitPosition;⤶ ⤶ Selection.Set( entity );⤶ ```⤶ ⤶ ## Map View Context Menu⤶ ⤶ You can extend the context menu in Hammer with the `hammer.mapview.contextmenu` event.⤶ ⤶ ```csharp⤶ [Event( "hammer.mapview.contextmenu" )]⤶ static void OnMapViewContextMenu( Menu menu, MapView view )⤶ {⤶ menu.AddSeparator();⤶ var submenu = menu.AddMenu( "Create Point Entity" );⤶ ⤶ // ...⤶ }⤶ ```⤶ ⤶ <upload src="a5727/8daba681b65ea31.png" size="182702" name="image.png" />⤶ ⤶ ## Adding Menu Bar⤶ ⤶ Menus can be added to the menu bar in Hammer the same as other tools⤶ ⤶ ```csharp⤶ [Menu( "Hammer", "My Cool Stuff/Log Selected", "info" )]⤶ public static void LogSelected()⤶ {⤶ Log.Info( Selection.All.First() );⤶ }⤶ ```⤶ ⤶ ## Primitive Builders⤶ ⤶ You can add new primitives to the block tool.⤶ ⤶ ```csharp⤶ [Title( "Rect" ), Icon( "rectangle" )]⤶ class RectPrimitive : PrimitiveBuilder⤶ {⤶ [Browsable( false )]⤶ public BBox BBox { get; set; }⤶ ⤶ public override void SetFromBox( BBox box ) => BBox = box;⤶ ⤶ public override void Build( PolygonMesh mesh )⤶ {⤶ var mins = BBox.Mins;⤶ var maxs = BBox.Maxs;⤶ ⤶ mesh.AddFace(⤶ new Vector3( mins.x, mins.y, maxs.z ),⤶ new Vector3( maxs.x, mins.y, maxs.z ),⤶ new Vector3( maxs.x, maxs.y, maxs.z ),⤶ new Vector3( mins.x, maxs.y, maxs.z )⤶ );⤶ }⤶ }⤶ ```⤶ ⤶ ## Map Drop Targets⤶ ⤶ Map drop targets enable you to create handlers for your own asset types.⤶ ⤶ Here's how we enable you to drop soundscapes into maps:⤶ ⤶ ```csharp⤶ [CanDrop( "sndscape" )]⤶ class SoundscapeDropTarget : IMapViewDropTarget⤶ {⤶ MapEntity SoundEntity { get; set; }⤶ ⤶ public void DragEnter( Asset asset, MapView view )⤶ {⤶ SoundEntity = new MapEntity();⤶ SoundEntity.ClassName = "snd_soundscape";⤶ SoundEntity.SetKeyValue( "soundscape", asset.Path );⤶ }⤶ ⤶ public void DragMove( MapView view )⤶ {⤶ view.BuildRay( out Vector3 rayStart, out Vector3 rayEnd );⤶ var tr = Trace.Ray( rayStart, rayEnd ).Run( view.MapDoc.World );⤶ SoundEntity.Position = tr.HitPosition;⤶ }⤶ }⤶ ```⤶