Jump to content

PravusJSB

ED Closed Beta Testers Team
  • Posts

    324
  • Joined

  • Last visited

Everything posted by PravusJSB

  1. Hopefully you can glean from this the right struct to pass, its a constructor for all tasks so i dont remember the specifics of how i wrote... it wont be copy/pasteable but you should be able to just see the right struct, thats half of the problem with tasks and getting the desired results. EDIT: from the if obj.trg.pers is the rearm reful, but it looks like i add in the WPs for going back up again that might be what makes the magic happen. Yea im giving them an infinite patrol task after they get back up to give me time to pick them back up again and re-task them.... and work out the glide path for them so they go straight in with no extra delays. -- internal function -- air waypoint generate local function PointTask(pos,type,_speed,action,tasking,alt,spdlock,radio,wrap,push) local point = {['x'] = pos.x, ['y'] = pos.y or alt, ['z'] = pos.z} local speed = _speed if not action then action = "Turning Point" end if not type then type = "Turning Point" end local task = wrap or { ["id"] = "ComboTask", ["params"] = { ["tasks"] = tasking or {}, }, } return { ["properties"] = { ["addopt"] = { }, -- end of ["addopt"] }, -- end of ["properties"] ["type"] = type, ["name"] = new_point_name(), ["x"] = point.x, ["y"] = point.z, ["alt"] = alt or (point.y + Disposition.getPointHeight(pos)), ["alt_type"] = radio or "RADIO", ["speed"] = speed, ["action"] = action, ["task"] = task, ["ETA"] = push or 0, ["ETA_locked"] = push == true, ["speed_locked"] = spdlock or false, ["formation_template"] = "", } end; local function land_function(_group) local group = _group local obj = optDB.aiV4[group] -- our running thread, stopping when the object is dead or we flag it as dead while (obj.alive == true) do local start = os.clock() if not obj:isAlive() then obj.alive = false else local res,fun = pcall(function() if obj.flag == 0 then -- setup our objects tasking local vec = obj:vec3() local pnt if obj:inAir() and vec and vec.y and vec.y > 800 and obj.trg.perField then obj:clearTask() local base = Airbase.getByName(obj.trg.perField) local ret if not base then ret, base = pcall(function() _log("JSB V4 AI: Error in tasking land_func, had to find a base;\n%s",jsb.tbl2(obj)) return aiMed.fun.getJMR().getBaseClose(vec, 1) end) end if base then local rwObj = base:getRunways()[1] pnt = rwObj.position local rw = rwObj.course * -1 local dir = rw + (math.pi) local glide = { ['x'] = pnt.x + 2200 * math.cos( dir ), ['y'] = 0, ['z'] = pnt.z + 2200 * math.sin( dir ) } optDB.aiV4[group].task = { ['id'] = 'Mission', -- Mission ['params'] = { ['airborne'] = true, ['route'] = { ['points'] = { PointTask(vec, nil, mToKnots(0.75), 'Fly Over Point', nil, 10500/3.35), -- PointTask(shiftPoint(pnt,2000),nil,mToKnots(0.85),nil,nil,obj.trg.alt or (35000/3.3)), }, }, }, } if obj.trg.pers then -- TODO needs testing local patrol = { { ["number"] = 1, ["auto"] = false, ["id"] = "WrappedAction", ["enabled"] = true, ["params"] = { ["action"] = { ["id"] = "SwitchWaypoint", ["params"] = { ["goToWaypointIndex"] = #obj.task.params.route.points+1, ["fromWaypointIndex"] = #obj.task.params.route.points+2, }, }, }, }, } obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(glide,nil,mToKnots(0.45),nil,nil,450) -- landing phase obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(pnt,'LandingReFuAr',130,'LandingReFuAr',nil,100) obj.task.params.route.points[#obj.task.params.route.points]["airdromeId"] = base:getID() obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(pnt,nil,mToKnots(0.85),'Fly Over Point',nil,25500/3.35) obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(pnt,nil,mToKnots(0.85),'Fly Over Point',patrol,25500/3.35) -- obj:unitTask(true) -- optDB.aiV4[group].task = { -- ['id'] = 'EngageTargets', -- ['params'] = { -- ['maxDistEnabled'] = true, -- ['maxDist'] = 3000, -- ['targetTypes'] = { obj.trg.target_types or "All" }, -- ['priority'] = 1, -- ['noTargetTypes'] = obj.trg.trg_not, -- }, -- } obj:unitTask() elseif obj.trg.points and #obj.trg.points > 0 then -- new astar code for i = 1, #obj.trg.points do obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask({x = obj.trg.points[i][1], y = 0, z = obj.trg.points[i][2]}, nil, mToKnots(0.85), nil, nil, obj.trg.alt or obj.trg.points[i][3] or (42000/3.3)) -- specific route end obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(glide,nil,mToKnots(0.45),nil,nil,450) -- landing phase obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(pnt,'LandingReFuAr',130,'LandingReFuAr',nil,100) obj.task.params.route.points[#obj.task.params.route.points]["airdromeId"] = base:getID() obj.task.params.route.points[#obj.task.params.route.points - 2].alt = (10000/3.3) obj.task.params.route.points[#obj.task.params.route.points - 3].alt = (14000/3.3) -- obj.task.params.route.points[#obj.task.params.route.points - 4].alt = (17000/3.3) -- obj.task.params.route.points[#obj.task.params.route.points - 5].alt = (25000/3.3) -- obj.task.params.route.points[#obj.task.params.route.points - 6].alt = (30000/3.3) obj:unitTask() _log("Pushed new ASTAR route %s number points %d", _group, #obj.task.params.route.points) else obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(glide,nil,mToKnots(0.45),nil,nil,450) -- landing phase obj.task.params.route.points[#obj.task.params.route.points+1] = PointTask(pnt,'LandingReFuAr',130,'LandingReFuAr',nil,100) obj.task.params.route.points[#obj.task.params.route.points]["airdromeId"] = base:getID() obj:unitTask() end obj.flag = 1 -- _log("Has moved %s to flag 1",obj.name) else _log("JSB V4 AI: Error in tasking land_func, data;\n%s",jsb.tbl2(obj)) obj.flag = 2 end elseif not obj.trg.perField or not vec or not vec.y then obj.flag = 2 end elseif obj.flag == 1 then -- TDOO check for threats on way and route around them? obj.flag = 2 elseif obj.flag == 2 then -- TDOO check for threats on way and route around them? obj.alive = false end end) if not res then _log("ERROR in ai %s",tostring(fun)) obj.alive = false end end local fin = os.clock()-start if fin > 0.014 then _log("Land cor took %f",fin) end coroutine.yield() end end
  2. I think they all reside in <base_install>\CoreMods\aircraft\<frame>\Liveries
  3. Not sure if it exists in some form or another but certainly possible if not a little complex to code to capture all fringe cases of use, but nice idea. Also, can you get the AI to wing rock? New to me and for sure going to get used in a childish way is its a thing lol
  4. Usage example if pOpt.o.pflag and file_exists((dPath or jsbFM.dPath()) .. "persistent_flags.lua") then pflags:load() -- only one load per session needed mtm = pflags:get("smtm") elseif pOpt.o.pflag then _log('Error calling the pFlags file :: NO PERSISTENCE FILE FOUND !') pflags:add('fresh_start', 1) else _log("Persistence flags are disabled.") end
  5. This is my class for just the task, with push, pop, compare methods etc... You will have to replace some of the dependencies (a serializer and a ED SSE flag wrapper I think), let me know if you need help with how to use it. -- new 2022 pFlags P_FLAG = {} local pflags = {} local set_flag = jsb.set_flag_nl function pflags:pop(flag) if self[flag] then local tflag = self[flag] self[flag] = nil self:save() set_flag(flag, nil) return tflag end end function pflags:get(flag) return self[flag] end function pflags:cmp(flag, str) return self[flag] and self[flag] == str and true or false end function pflags:multi_add(flags) for flag, value in pairs (flags or {}) do self:add(flag, value) set_flag(flag, value) end self:save() end function pflags:add(flag, value) if not value and type(flag) == 'table' then self:multi_add(flag) return end self[flag] = value set_flag(flag, value) self:save() end function pflags:inc(flag, value) if self[flag] then if value then self[flag] = value else self[flag] = self[flag] + 1 end set_flag(flag, self[flag]) self:save() end end function pflags:reduce(flag, value) if self[flag] then if value then self[flag] = value else self[flag] = self[flag] - 1 end set_flag(flag, self[flag]) self:save() end end local jsb_tbl = jsb.tbl function pflags:save() if dont_save then return end local save_file = io.open((dPath or jsbFM.dPath()) .. "persistent_flags.lua", "w") if save_file then save_file:write(jsb_tbl(self, "pflags")) save_file:close() end end function pflags:load() local save_file = envLoad((dPath or jsbFM.dPath()) .. "persistent_flags.lua") if save_file and save_file.pflags then for flag, value in pairs (save_file.pflags) do self:add(flag, value) end end end P_FLAG.get = function() return pflags end --
  6. Yea for sure it works, but its a lengthy old process. I think the pilot goes cold and dark and exits the cockpit during the process too so it looks to not work but he will come back. If you need some tips on how to structure the task let me know I'll try put it together for you.
  7. I use the task action & type of 'LandingReFuAr' to achieve that. Takes them a while to fully refuel and re-arm and for good measure you should re-task them to be your wingman after they get airborne again.
  8. I have some data from a long while ago (below), it used to be a bit crash'y if you tried to get certain frames to barrel roll, your mileage may vary. There are 3 manoeuvres below taskMaster and I would choose one, update with real-time altitudes and speeds and start orders, then insert where the comment is and push it or set it to the unit as a combo_task and would get good results mostly. ['aeroTasks'] = { ['taskMaster'] = { [1] = { ["enabled"] = true, ["auto"] = false, ["id"] = "Aerobatics", ["number"] = 1, ["params"] = { ["maneuversSequency"] = { ---- this is where i insert... }, ["maneuversParams"] = { }, }, }, }, -- eof master ['rollLeft'] = { ["displayName"] = "Barrel roll", ["name"] = "BARREL_ROLL", ["params"] = { ["InitAltitude"] = { ["order"] = 2, ["value"] = 2500, -- needs group alt }, -- end of ["InitAltitude"] ["StartImmediatly"] = { ["order"] = 5, ["value"] = 1, }, -- end of ["StartImmediatly"] ["UseSmoke"] = { ["order"] = 4, ["value"] = 0, }, -- end of ["UseSmoke"] ["SIDE"] = { ["order"] = 6, ["value"] = 1, -- left side?? }, -- end of ["SIDE"] ["InitSpeed"] = { ["order"] = 3, ["value"] = 950, -- needs curr speed }, -- end of ["InitSpeed"] ["RollRate"] = { ["min_v"] = 15, ["max_v"] = 450, ["value"] = 90, ["step"] = 5, ["order"] = 7, }, -- end of ["RollRate"] ["SECTOR"] = { ["order"] = 8, ["value"] = 360, }, -- end of ["SECTOR"] ["RepeatQty"] = { ["min_v"] = 1, ["max_v"] = 10, ["value"] = 1, ["order"] = 1, }, -- end of ["RepeatQty"] }, }, -- eof roll ['breakRight'] = { ["displayName"] = "Military Turn", ["name"] = "MILITARY_TURN", ["params"] = { ["InitSpeed"] = { ["order"] = 3, ["value"] = 950, -- needs speed }, -- end of ["InitSpeed"] ["InitAltitude"] = { ["order"] = 2, ["value"] = 2200, -- needs alt }, -- end of ["InitAltitude"] ["StartImmediatly"] = { ["order"] = 5, ["value"] = 1, }, -- end of ["StartImmediatly"] ["UseSmoke"] = { ["order"] = 4, ["value"] = 0, }, -- end of ["UseSmoke"] ["RepeatQty"] = { ["min_v"] = 1, ["max_v"] = 10, ["value"] = 1, ["order"] = 1, }, -- end of ["RepeatQty"] ["SIDE"] = { ["order"] = 6, ["value"] = 1, }, -- end of ["SIDE"] }, -- end of ["params"] }, -- eof break right ['rollRight'] = { ["displayName"] = "Barrel roll", ["name"] = "BARREL_ROLL", ["params"] = { ["InitAltitude"] = { ["order"] = 2, ["value"] = 2500, -- needs group alt }, -- end of ["InitAltitude"] ["StartImmediatly"] = { ["order"] = 5, ["value"] = 1, }, -- end of ["StartImmediatly"] ["UseSmoke"] = { ["order"] = 4, ["value"] = 0, }, -- end of ["UseSmoke"] ["SIDE"] = { ["order"] = 6, ["value"] = 0, -- right side?? }, -- end of ["SIDE"] ["InitSpeed"] = { ["order"] = 3, ["value"] = 950, -- needs curr speed }, -- end of ["InitSpeed"] ["RollRate"] = { ["min_v"] = 15, ["max_v"] = 450, ["value"] = 90, ["step"] = 5, ["order"] = 7, }, -- end of ["RollRate"] ["SECTOR"] = { ["order"] = 8, ["value"] = 360, }, -- end of ["SECTOR"] ["RepeatQty"] = { ["min_v"] = 1, ["max_v"] = 10, ["value"] = 1, ["order"] = 1, }, -- end of ["RepeatQty"] }, }, -- eof roll },
  9. Uncontrolled should be no more of a CPU drain than a static object, as that's all it is. It has no brains.
  10. I like your thinking, I spawned a reaper, invisible, immortal, ground level for 0.001 and then silent destroy and get a large area opened, but I've yet to be around to see if it ever goes of it own accord.
  11. Hmm, yes its maybe possible, maybe, but would require heavy modding and knowledge of the ED Lua. If it were me I would write my own event listener and export to a website/discord or similar. That would be less of a job and you'd have more control. I figured out a cheaty way of pocking holes in the fog to 'reveal' map area's but its far from perfect and ive yet to figure out how to get rid of the hole lol.
  12. Open the .miz (donor) in something like 7zip or Winrar, open 'mission' in your editor of choice and copy the triggers, repeat with new mission (recipient).. important this time, paste. and Done.
  13. Happens to us all one day. Glad I could help!
  14. Simple Q but is the flag ExplodeMedivac at least the value of 61?
  15. This could be the issue; Lua::Config (Main): load error Config/main.cfg:[string "Config/terrain.lua"]:2: attempt to concatenate local 'visibRange' (a nil value). It seems like its having a trickle down effect on other scripts failing resulting in a black table which should hold graphics options. Delete that file and repair again, it might be skipping over it for whatever reason.
  16. I can help buddy, what is the specific error or output of the code?
  17. Did you setup a luaopen method for your binary? I also think the binary might need to be named with "lua-" prefix for calling in the mission environment (i think)
  18. It doesnt get it's Cpp bindings in the public release. There are some other ways to do this yourself from simple (F10 command that loads a script and returns result to log/screen) to real-time execution (witchcraft) or some other ways in between. What do you need it for?
  19. I'd have to to check but does mist read the mission file and cache all units for later 'search' use or does it dynamically build a set using world.searchObjects?
  20. I like the problem solving lol! The tasking system is a huge pita for this reason, clearly it doesnt like something you did but the unit will ignore it and keep quiet about the mistake. It's character building... If you want to post or DM me the code I can sanity check if you like.
  21. I should imagine if you look in the install dir/Mission Editor/modules you should be able to identify where you initiate the save and then trace the execution until (im guessing) there will be a setVisible or a close method method called and maybe set false but suggest you comment out for desired results but unintended consequences I am not sure, back everything up before you do anything.
  22. I'm not aware of a direct export variable but you could query certain systems to make an educated guess; LoGetMechInfo() -- mechanization info result_is = { gear = {status,value,main = {left = {rod},right = {rod},nose = {rod}}} flaps = {status,value} speedbrakes = {status,value} refuelingboom = {status,value} airintake = {status,value} noseflap = {status,value} parachute = {status,value} wheelbrakes = {status,value} hook = {status,value} wing = {status,value} canopy = {status,value} controlsurfaces = {elevator = {left,right},eleron = {left,right},rudder = {left,right}} -- relative vlues (-1,1) (min /max) (sorry:( } LoGetMCPState() -- (args - 0, results - 1 (table of key(string).value(boolean)) returned table keys for LoGetMCPState(): "LeftEngineFailure" "RightEngineFailure" "HydraulicsFailure" "ACSFailure" "AutopilotFailure" "AutopilotOn" "MasterWarning" "LeftTailPlaneFailure" "RightTailPlaneFailure" "LeftAileronFailure" "RightAileronFailure" "CanopyOpen" "CannonFailure" "StallSignalization" "LeftMainPumpFailure" "RightMainPumpFailure" "LeftWingPumpFailure" "RightWingPumpFailure" "RadarFailure" "EOSFailure" "MLWSFailure" "RWSFailure" "ECMFailure" "GearFailure" "MFDFailure" "HUDFailure" "HelmetFailure" "FuelTankDamage"
  23. I had a quick look, caveat I don't know the finer details of mist usage/syntax but all looks OK at first glance apart from that the check condition (tssZoneController.lua:92) only ever seems to run on script load and doesnt spin? You might try wrapping in a function and scheduling it to call each second.
×
×
  • Create New...