{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Airport Location and Terrain Analysis Demo\n", "\n", "This notebook demonstrates DCS APIs for finding airports and checking terrain types." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Setup" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nil" ] } ], "source": [ "_ = net.lua2json" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Airport Discovery\n", "\n", "Get all airbases on the map:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[{\"name\":\"Rota Intl\",\"callsign\":\"Rota Intl\",\"id\":1,\"category\":0,\"position\":{\"y\":173.38017272949,\"x\":75950.7734375,\"z\":47661.18359375}},{\"name\":\"Saipan Intl\",\"callsign\":\"Saipan Intl\",\"id\":2,\"category\":0,\"position\":{\"y\":65.000068664551,\"x\":179620.453125,\"z\":100743.234375}},{\"name\":\"Tinian Intl\",\"callsign\":\"Tinian Intl\",\"id\":3,\"category\":0,\"position\":{\"y\":73.154266357422,\"x\":166672,\"z\":88785.890625}},{\"name\":\"Antonio B. Won Pat Intl\",\"callsign\":\"Antonio B. Won Pat Intl\",\"id\":4,\"category\":0,\"position\":{\"y\":77.79207611084,\"x\":-588.52325439453,\"z\":-1388.0504150391}},{\"name\":\"Olf Orote\",\"callsign\":\"Olf Orote\",\"id\":5,\"category\":0,\"position\":{\"y\":28.506044387817,\"x\":-4847.6000976562,\"z\":-16372.65625}}]" ] } ], "source": [ "-- Get all airbases on the map\n", "local airbases = world.getAirbases()\n", "\n", "-- Extract basic info for first few airbases\n", "local airbase_info = {}\n", "for i = 1, math.min(5, #airbases) do\n", " local ab = airbases[i]\n", " airbase_info[i] = {\n", " name = ab:getName(),\n", " id = ab:getID(),\n", " callsign = ab:getCallsign(),\n", " position = ab:getPoint(),\n", " category = ab:getDesc().category -- 0=AIRDROME, 1=HELIPAD, 2=SHIP\n", " }\n", "end\n", "\n", "return _(airbase_info)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Terrain Type Analysis\n", "\n", "Check surface types at different coordinates:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[{\"coordinates\":{\"z\":500000,\"x\":-100000},\"name\":\"Test Point 1\",\"height\":0,\"surface_type\":3,\"surface_name\":\"WATER\"},{\"coordinates\":{\"z\":600000,\"x\":-200000},\"name\":\"Test Point 2\",\"height\":0,\"surface_type\":3,\"surface_name\":\"WATER\"},{\"coordinates\":{\"z\":0,\"x\":0},\"name\":\"Origin\",\"height\":77.79207611084,\"surface_type\":5,\"surface_name\":\"RUNWAY\"}]" ] } ], "source": [ "-- Function to convert surface type number to readable text\n", "function getSurfaceTypeName(surfaceType)\n", " local types = {\n", " [1] = \"LAND\",\n", " [2] = \"SHALLOW_WATER\", \n", " [3] = \"WATER\",\n", " [4] = \"ROAD\",\n", " [5] = \"RUNWAY\"\n", " }\n", " return types[surfaceType] or \"UNKNOWN\"\n", "end\n", "\n", "-- Test different coordinate types\n", "local test_coords = {\n", " {x = -100000, z = 500000, name = \"Test Point 1\"},\n", " {x = -200000, z = 600000, name = \"Test Point 2\"},\n", " {x = 0, z = 0, name = \"Origin\"}\n", "}\n", "\n", "-- Analyze each coordinate\n", "local results = {}\n", "for i, coord in ipairs(test_coords) do\n", " local surface_type = land.getSurfaceType({x = coord.x, y = coord.z})\n", " local height = land.getHeight({x = coord.x, y = coord.z})\n", " \n", " results[i] = {\n", " name = coord.name,\n", " coordinates = {x = coord.x, z = coord.z},\n", " surface_type = surface_type,\n", " surface_name = getSurfaceTypeName(surface_type),\n", " height = height\n", " }\n", "end\n", "\n", "return _(results)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Find Specific Airport\n", "\n", "Try to find a specific airport by name:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"coalition\":0,\"surface_name\":\"RUNWAY\",\"name\":\"Saipan Intl\",\"position\":{\"y\":65.000068664551,\"x\":179620.453125,\"z\":100743.234375},\"height\":65.000068664551,\"surface_type\":5,\"category\":0}" ] } ], "source": [ "-- Try to find a specific airport (change name as needed for your map)\n", "-- Common Marianas airports: \"Rota Intl\", \"Saipan Intl\", \"Tinian Intl\", \"Andersen AFB\"\n", "local airport_name = \"Saipan Intl\" -- Change this to an airport on your map\n", "local airport = Airbase.getByName(airport_name)\n", "\n", "if airport then\n", " local info = {\n", " name = airport:getName(),\n", " position = airport:getPoint(),\n", " category = airport:getDesc().category,\n", " coalition = airport:getCoalition()\n", " }\n", " \n", " -- Check terrain at airport location\n", " local ap_pos = airport:getPoint()\n", " local surface_type = land.getSurfaceType({x = ap_pos.x, y = ap_pos.z})\n", " info.surface_type = surface_type\n", " info.surface_name = getSurfaceTypeName(surface_type)\n", " info.height = land.getHeight({x = ap_pos.x, y = ap_pos.z})\n", " \n", " return _(info)\n", "else\n", " return \"Airport not found. Try changing the name to match your map.\"\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Smart Spawn Location Finding\n", "\n", "Find a safe land location near the airport:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\"x\":179420.453125,\"z\":100743.234375,\"surface_name\":\"LAND\",\"surface_type\":1,\"distance_from_center\":200}" ] } ], "source": [ "-- Function to find safe spawn location near airport\n", "function findSafeSpawnLocation(center_x, center_z, search_radius)\n", " local search_radius = search_radius or 1000\n", " local step_size = 100\n", " \n", " -- Search in a spiral pattern\n", " for radius = 0, search_radius, step_size do\n", " for angle = 0, 360, 45 do\n", " local rad = math.rad(angle)\n", " local test_x = center_x + radius * math.cos(rad)\n", " local test_z = center_z + radius * math.sin(rad)\n", " \n", " local surface_type = land.getSurfaceType({x = test_x, y = test_z})\n", " \n", " -- Check if it's land (not water or runway)\n", " if surface_type == 1 then -- LAND\n", " return {\n", " x = test_x,\n", " z = test_z,\n", " surface_type = surface_type,\n", " surface_name = getSurfaceTypeName(surface_type),\n", " distance_from_center = radius\n", " }\n", " end\n", " end\n", " end\n", " \n", " return nil -- No safe location found\n", "end\n", "\n", "-- Re-find the airport in case variable wasn't carried over\n", "local airport_name = \"Saipan Intl\" -- Change this to match your airport\n", "airport = Airbase.getByName(airport_name)\n", "\n", "-- Find a safe spawn location near the airport\n", "if airport then\n", " local ap_pos = airport:getPoint()\n", " safe_location = findSafeSpawnLocation(ap_pos.x, ap_pos.z, 2000)\n", " \n", " if safe_location then\n", " -- Add visual marker\n", " local marker_pos = {x = safe_location.x, y = land.getHeight({x = safe_location.x, y = safe_location.z}), z = safe_location.z}\n", " trigger.action.smoke(marker_pos, trigger.smokeColor.Green)\n", " \n", " trigger.action.outText(\"Safe spawn location found near \" .. airport:getName() .. \" (green smoke)\", 10)\n", " \n", " return _(safe_location)\n", " else\n", " return \"No safe spawn location found near airport\"\n", " end\n", "else\n", " return \"Airport '\" .. airport_name .. \"' not found. Try different airport names for Marianas map.\"\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Airport-based Vehicle Spawning\n", "\n", "Spawn a vehicle at the validated safe location:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tank spawned successfully at validated terrain location" ] } ], "source": [ "-- Re-find airport and safe location in case variables weren't carried over\n", "local airport_name = \"Saipan Intl\" -- Change this to match your airport\n", "airport = Airbase.getByName(airport_name)\n", "\n", "if airport then\n", " local ap_pos = airport:getPoint()\n", " safe_location = findSafeSpawnLocation(ap_pos.x, ap_pos.z, 2000)\n", "end\n", "\n", "-- Spawn a vehicle at the safe location we found\n", "if airport and safe_location then\n", " local tank_group = {\n", " name = \"Airport_Tank\",\n", " task = \"Ground Nothing\",\n", " units = {\n", " [1] = {\n", " name = \"Airport_Tank_Unit\",\n", " type = \"M-1 Abrams\",\n", " x = safe_location.x,\n", " y = safe_location.z,\n", " heading = 0,\n", " skill = \"Average\"\n", " }\n", " }\n", " }\n", " \n", " coalition.addGroup(country.id.USA, Group.Category.GROUND, tank_group)\n", " \n", " -- Add blue smoke at airport\n", " local ap_pos = airport:getPoint()\n", " trigger.action.smoke(ap_pos, trigger.smokeColor.Blue)\n", " \n", " trigger.action.outText(\"Tank spawned near \" .. airport:getName() .. \" (blue smoke at airport)\", 10)\n", " \n", " return \"Tank spawned successfully at validated terrain location\"\n", "else\n", " return \"Cannot spawn - no safe location or airport available\"\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cleanup\n", "\n", "Remove the spawned vehicle:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "nil" ] } ], "source": [ "-- Clean up spawned units\n", "local group = Group.getByName(\"Airport_Tank\")\n", "if group then\n", " group:destroy()\n", " trigger.action.outText(\"Tank removed\", 5)\n", "else\n", " return \"No tank to remove\"\n", "end" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "dcs-lua", "language": "", "name": "dcs-lua" }, "language_info": { "file_extension": ".lua", "mimetype": "text/plain", "name": "lua", "version": "5.1" } }, "nbformat": 4, "nbformat_minor": 4 }