SullyFUBAR Posted July 18, 2023 Posted July 18, 2023 I am trying to make a simple script that causes between 1-3 "crewmembers" to bailout out of a vehicle when it's destroyed. While I have that part working, I want to augment it by adding waypoints for the spawned units so they will run back to there lines, witch will just be a predetermined point in the AO. However, everything I've tired so far causes a crash and I don't know why. Any help would be appreciated. Script so far: do local armoredVehicleTypes = { "APC MTLB", "Scout BRDM-2", "IFV BMP-1", } local function generateInfantryGroup(spawnPoint) local numSoldiers = math.random(0, 3) local groupName = "InfantryGroup_" .. tostring(math.random(1, 10000)) local groupData = { ["units"] = {}, ["country"] = country.id.RUSSIA, ["category"] = "infantry", ["task"] = "Ground Nothing", ["taskSelected"] = true, ["name"] = groupName, } for i = 1, numSoldiers do table.insert(groupData.units, { ["type"] = "Infantry AK", ["transportable"] = { ["randomTransportable"] = false, }, ["skill"] = "Average", ["unitId"] = i, ["y"] = spawnPoint.z + 2 * i, ["x"] = spawnPoint.x + 2 * i, ["name"] = groupName .. "_Soldier_" .. i, ["heading"] = 0, ["playerCanDrive"] = false, }) end return groupData end local eventHandler = {} function eventHandler:onEvent(event) if event.id == world.event.S_EVENT_DEAD then if event.initiator then local unitDesc = event.initiator:getDesc() local unitPos = event.initiator:getPoint() if unitDesc and unitPos then for _, vehicleType in ipairs(armoredVehicleTypes) do if unitDesc.displayName == vehicleType then local newGroupData = generateInfantryGroup(unitPos) local newGroup = coalition.addGroup(country.id.RUSSIA, Group.Category.GROUND, newGroupData) trigger.action.outText("Armored unit destroyed: " .. unitDesc.displayName .. ", spawning infantry group at the destroyed unit's location", 10) return end end trigger.action.outText("Non-armored unit destroyed: " .. unitDesc.displayName, 10) else trigger.action.outText("Unit destroyed, but description or position could not be retrieved", 10) end end end end world.addEventHandler(eventHandler) end
Solution cfrag Posted July 19, 2023 Solution Posted July 19, 2023 There are multiple ways to achieve what you want. You can first spawn a group, and then access their controller and add a new path to the desired location. Be careful to allow DCS a second or so before accessing a newly spawned group's controller, so use 'scheduleFunction()' for the delayed setting of the path. OR, you can take a page from how missions spawns groups with the path added to the data that you are generating now. In this case, the route is part of the group's table, and is called, well, "route". Something like this: ["route"] = { ["points"] = { [1] = { ["alt"] = 13, ["type"] = "Turning Point", ["ETA"] = 0, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 646420.07565045, ["x"] = -281610.2890057, ["ETA_locked"] = true, ["speed"] = 0, ["action"] = "Off Road", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = { }, -- end of ["tasks"] }, -- end of ["params"] }, -- end of ["task"] ["speed_locked"] = true, } [2] = { ["alt"] = 13, ["type"] = "Turning Point", ["ETA"] = 198.65236602235, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 647014.85075951, ["x"] = -281083.36702851, ["ETA_locked"] = false, ["speed"] = 4, ["action"] = "Off Road", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = { }, -- end of ["tasks"] }, -- end of ["params"] }, -- end of ["task"] ["speed_locked"] = true, }, }, }, In your code you would then substitute for each point the "x" and "y" for the source (group's spawn point) and destination (where they should run back to) point's coordinates. Remember that the you must supply the "z" coordinate from those source/destination points for the route's "y" (in DCS internal data, they use x and y to represent x and z, harkening back to a simpler time) and then replace the "alt" for each point (source/dest) with that point's land.getHeight(). If you do that, you should be able to spawn your people with orders to move from source (the point they spawned) back to destination (the known location that they should run back to). Note: I'm on the road, typed largely from memory and notes, I did not verify above, use at your own risk. 1
SullyFUBAR Posted July 27, 2023 Author Posted July 27, 2023 (edited) On 7/19/2023 at 7:01 AM, cfrag said: There are multiple ways to achieve what you want. You can first spawn a group, and then access their controller and add a new path to the desired location. Be careful to allow DCS a second or so before accessing a newly spawned group's controller, so use 'scheduleFunction()' for the delayed setting of the path. OR, you can take a page from how missions spawns groups with the path added to the data that you are generating now. In this case, the route is part of the group's table, and is called, well, "route". Something like this: ["route"] = { ["points"] = { [1] = { ["alt"] = 13, ["type"] = "Turning Point", ["ETA"] = 0, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 646420.07565045, ["x"] = -281610.2890057, ["ETA_locked"] = true, ["speed"] = 0, ["action"] = "Off Road", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = { }, -- end of ["tasks"] }, -- end of ["params"] }, -- end of ["task"] ["speed_locked"] = true, } [2] = { ["alt"] = 13, ["type"] = "Turning Point", ["ETA"] = 198.65236602235, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 647014.85075951, ["x"] = -281083.36702851, ["ETA_locked"] = false, ["speed"] = 4, ["action"] = "Off Road", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = { }, -- end of ["tasks"] }, -- end of ["params"] }, -- end of ["task"] ["speed_locked"] = true, }, }, }, In your code you would then substitute for each point the "x" and "y" for the source (group's spawn point) and destination (where they should run back to) point's coordinates. Remember that the you must supply the "z" coordinate from those source/destination points for the route's "y" (in DCS internal data, they use x and y to represent x and z, harkening back to a simpler time) and then replace the "alt" for each point (source/dest) with that point's land.getHeight(). If you do that, you should be able to spawn your people with orders to move from source (the point they spawned) back to destination (the known location that they should run back to). Note: I'm on the road, typed largely from memory and notes, I did not verify above, use at your own risk. You're a champion, this was exactly what I needed. I added in a bit of a delay to make it all a little more realistic and will move to working on tying the spawned unit amount (0-3) to the length of time it takes to bailout (3-7 seconds). The longer it take to get out means less get out. Then I just need a tank crew model and it will be perfect. Thank you again, cheers! Script if you wanted it: do -- Define the types of armored vehicles that will trigger infantry spawning. local armoredVehicleTypes = { "APC MTLB", "IFV BMP-1", "IFV BMP-2", "IFV BMP-3", "MBT T-90", "Scout BRDM-2", } -- This function generates a group of infantry, with a random number of soldiers between 0-3. local function generateInfantryGroup(spawnPoint) local numSoldiers = math.random(0, 3) local groupName = "InfantryGroup_" .. tostring(math.random(1, 10000)) -- This is the basic data for the new group. local groupData = { ["units"] = {}, ["country"] = country.id.RUSSIA, ["category"] = "infantry", ["task"] = "Ground Nothing", ["taskSelected"] = true, ["name"] = groupName, ["route"] = { ["points"] = { [1] = { ["alt"] = 20, ["type"] = "Turning Point", ["ETA"] = 0, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 00203042, ["x"] = 00030998, ["ETA_locked"] = true, ["speed"] = 8, ["action"] = "line abreast", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = {}, }, }, ["speed_locked"] = true, }, [2] = { ["alt"] = 59, ["type"] = "Turning Point", ["ETA"] = 198.65236602235, ["alt_type"] = "BARO", ["formation_template"] = "", ["y"] = 00203042, ["x"] = 00030998, ["ETA_locked"] = false, ["speed"] = 8, ["action"] = "line abreast", ["task"] = { ["id"] = "ComboTask", ["params"] = { ["tasks"] = {}, }, }, ["speed_locked"] = true, }, }, }, } -- Add soldiers to the group. for i = 1, numSoldiers do table.insert(groupData.units, { ["type"] = "Infantry AK ver3", ["transportable"] = { ["randomTransportable"] = false, }, ["skill"] = "Average", ["unitId"] = i, ["y"] = spawnPoint.z + 2 * i, ["x"] = spawnPoint.x + 2 * i, ["name"] = groupName .. "_Soldier_" .. i, ["heading"] = 0, ["playerCanDrive"] = false, }) end -- Return the group data, ready to be added to the mission. return groupData end -- Define the event handler object. local eventHandler = {} -- Define the event handling function. function eventHandler:onEvent(event) -- We're only interested in the S_EVENT_DEAD event, which is triggered when a unit dies. if event.id == world.event.S_EVENT_DEAD then -- Check if the event has an initiator, which is the unit that caused the event. if event.initiator then -- Get the description and position of the unit. local unitDesc = event.initiator:getDesc() local unitPos = event.initiator:getPoint() -- Check if the unit description and position are available. if unitDesc and unitPos then -- Check if the unit is one of the armored vehicle types that we want crew to BailOut from. for _, vehicleType in ipairs(armoredVehicleTypes) do if unitDesc.displayName == vehicleType then -- Generate a new group of infantry at the unit's position. local newGroupData = generateInfantryGroup(unitPos) -- Define a function to spawn the new group. local spawnGroup = function() -- Add the group to the coalition local newGroup = coalition.addGroup(country.id.RUSSIA, Group.Category.GROUND, newGroupData) end -- Get the current time. local timeNow = timer.getTime() -- Generate a random delay between 3 and 7 seconds. This is how long it takes them to get out. local delay = math.random(3,7) -- Schedule the spawnGroup function to be called after the delay. timer.scheduleFunction(spawnGroup, nil, timeNow + delay) return end end end end end end -- Add the event handler to the world. world.addEventHandler(eventHandler) end Edited July 27, 2023 by SullyFUBAR
Recommended Posts