Skip to main content
Glama

calculate_aoe

Calculate area of effect for D&D 5e spells and abilities, supporting sphere, cone, line, cube, and cylinder shapes to determine combat impact.

Instructions

Calculate area of effect for D&D 5e spells/abilities (sphere, cone, line, cube, cylinder)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
encounterIdNo
shapeYes
originYes
lengthNo
widthNo
radiusNo
sideLengthNo
heightNo
directionNo
includeOriginNo
excludeIdsNo

Implementation Reference

  • Core handler function implementing calculate_aoe tool logic: computes affected grid tiles for D&D 5e AoE shapes (sphere, cone, line, cube, cylinder) and generates formatted ASCII output with parameters, tile count, and sample positions.
    export function calculateAoe(input: CalculateAoeInput): string { const content: string[] = []; const { encounterId, shape, origin, length, width = 5, radius, sideLength, height, direction, includeOrigin = false, excludeIds = [], } = input; // Calculate affected tiles based on shape let tiles: Position[] = []; switch (shape) { case 'sphere': tiles = calculateSphereTiles(origin, radius!, includeOrigin); break; case 'cone': tiles = calculateConeTiles(origin, length!, direction || { x: 1, y: 0 }, includeOrigin); break; case 'line': tiles = calculateLineTiles(origin, length!, width, direction || { x: 1, y: 0 }); break; case 'cube': tiles = calculateCubeTiles(origin, sideLength!, direction, includeOrigin); break; case 'cylinder': tiles = calculateCylinderTiles(origin, radius!, height!, includeOrigin); break; } // Build header content.push(centerText(`${shape.toUpperCase()} AoE`, AOE_DISPLAY_WIDTH)); content.push(''); content.push(`Origin: (${origin.x}, ${origin.y}, ${origin.z ?? 0})`); content.push(''); content.push(BOX.LIGHT.H.repeat(AOE_DISPLAY_WIDTH)); content.push(''); // Show shape parameters content.push(centerText('PARAMETERS', AOE_DISPLAY_WIDTH)); content.push(''); content.push(`Shape: ${shape}`); switch (shape) { case 'sphere': content.push(`Radius: ${radius} ft`); break; case 'cone': content.push(`Length: ${length} ft`); content.push(`Width at base: ${length} ft`); if (direction) { content.push(`Direction: (${direction.x}, ${direction.y})`); } break; case 'line': content.push(`Length: ${length} ft`); content.push(`Width: ${width} ft`); if (direction) { content.push(`Direction: (${direction.x}, ${direction.y})`); } break; case 'cube': content.push(`Side: ${sideLength} ft`); break; case 'cylinder': content.push(`Radius: ${radius} ft`); content.push(`Height: ${height} ft`); break; } content.push(''); content.push(BOX.LIGHT.H.repeat(AOE_DISPLAY_WIDTH)); content.push(''); // Show tile count content.push(centerText('AFFECTED AREA', AOE_DISPLAY_WIDTH)); content.push(''); content.push(`Tiles affected: ${tiles.length} squares`); content.push(`Origin included: ${includeOrigin ? 'Yes' : 'No'}`); // If includeOrigin, show the origin position if (includeOrigin) { content.push(`Origin tile: (${origin.x}, ${origin.y}, ${origin.z ?? 0})`); } // Show sample tiles (first few) if (tiles.length > 0) { content.push(''); const sampleSize = Math.min(5, tiles.length); content.push(`Sample tiles (first ${sampleSize}):`); for (let i = 0; i < sampleSize; i++) { const t = tiles[i]; content.push(` (${t.x}, ${t.y}, ${t.z ?? 0})`); } if (tiles.length > sampleSize) { content.push(` ... and ${tiles.length - sampleSize} more`); } } // Find creatures in AoE if encounterId provided if (encounterId) { content.push(''); content.push(BOX.LIGHT.H.repeat(AOE_DISPLAY_WIDTH)); content.push(''); content.push(centerText('CREATURES IN AoE', AOE_DISPLAY_WIDTH)); content.push(''); // This would check encounter participants // For now, show placeholder content.push('(Encounter integration pending)'); } // Show excluded IDs if any if (excludeIds.length > 0) { content.push(''); content.push(`Excluded: ${excludeIds.join(', ')}`); } return createBox('AREA OF EFFECT', content); }
  • Zod schema for validating calculate_aoe input parameters, including shape-specific refinements.
    export const calculateAoeSchema = z.object({ encounterId: z.string().optional(), shape: AoeShapeSchema, origin: PositionSchema, // Shape-specific parameters length: z.number().optional(), // Line, Cone width: z.number().default(5).optional(), // Line radius: z.number().optional(), // Sphere, Cylinder sideLength: z.number().optional(), // Cube height: z.number().optional(), // Cylinder direction: DirectionSchema.optional(), // Options includeOrigin: z.boolean().default(false), excludeIds: z.array(z.string()).optional(), }).refine((data) => { // Validate required parameters based on shape switch (data.shape) { case 'sphere': return data.radius !== undefined; case 'cone': return data.length !== undefined; case 'line': return data.length !== undefined; case 'cube': return data.sideLength !== undefined; case 'cylinder': return data.radius !== undefined && data.height !== undefined; default: return true; } }, { message: 'Missing required parameters for shape', });
  • Tool registration in the central registry, including name, description, schema conversion, and wrapper handler with validation and error handling.
    calculate_aoe: { name: 'calculate_aoe', description: 'Calculate area of effect for D&D 5e spells/abilities (sphere, cone, line, cube, cylinder)', inputSchema: toJsonSchema(calculateAoeSchema), handler: async (args) => { try { const validated = calculateAoeSchema.parse(args); const result = calculateAoe(validated); return success(result); } catch (err) { if (err instanceof z.ZodError) { const messages = err.errors.map(e => `${e.path.join('.')}: ${e.message}`).join(', '); return error(`Validation failed: ${messages}`); } const message = err instanceof Error ? err.message : String(err); return error(message); } }, },

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/ChatRPG'

If you have feedback or need assistance with the MCP directory API, please join our Discord server