-
Posts
1080 -
Joined
-
Last visited
Content Type
Profiles
Forums
Events
Everything posted by Hardcard
-
Script to Make Flag Value Increase by 1
Hardcard replied to Sedlo's topic in Scripting Tips, Tricks & Issues
@Sedlo The key is to build the audio file table according to fox type and unit. Script + demo mission below local Foxcall_Table = { Fox_1 = { ['UZI 11'] = { "Fox1_big_1.ogg" , "Fox1_big_2.ogg" , "Fox1_big_3.ogg" } , [color="Blue"]-- 3 different fox1 calls for pilot 1[/color] ['UZI 12'] = { "Fox1_normal_1.ogg" , "Fox1_normal_2.ogg" , "Fox1_normal_3.ogg" } , [color="blue"]-- 3 different fox1 calls for pilot 2[/color] ['UZI 13'] = { "Fox1_tiny_1.ogg" , "Fox1_tiny_2.ogg" , "Fox1_tiny_3.ogg" } , [color="blue"]-- 3 different fox1 calls for pilot 3[/color] }, Fox_2 = { ['UZI 11'] = { "Fox2_big_1.ogg" , "Fox2_big_2.ogg" , "Fox2_big_3.ogg" } , [color="blue"]-- 3 different fox2 calls for pilot 1[/color] ['UZI 12'] = { "Fox2_normal_1.ogg" , "Fox2_normal_2.ogg" , "Fox2_normal_3.ogg" } , [color="blue"]-- 3 different fox2 calls for pilot 2[/color] ['UZI 13'] = { "Fox2_tiny_1.ogg" , "Fox2_tiny_2.ogg" , "Fox2_tiny_3.ogg" } , [color="blue"]-- 3 different fox2 calls for pilot 3[/color] }, Fox_3 = { ['UZI 11'] = { "Fox3_big_1.ogg" , "Fox3_big_2.ogg" , "Fox3_big_3.ogg" } , [color="blue"]-- 3 different fox3 calls for pilot 1[/color] ['UZI 12'] = { "Fox3_normal_1.ogg" , "Fox3_normal_2.ogg" , "Fox3_normal_3.ogg" } , [color="blue"]-- 3 different fox3 calls for pilot 2[/color] ['UZI 13'] = { "Fox3_tiny_1.ogg" , "Fox3_tiny_2.ogg" , "Fox3_tiny_3.ogg" } , [color="blue"]-- 3 different fox3 calls for pilot 3[/color] } } local Handler = {} function Handler:onEvent(event) if event.id == world.event.S_EVENT_SHOT and Foxcall_Table.Fox_1[event.initiator:getName()] then if event.weapon and event.weapon:getTypeName() and event.weapon:getDesc() and event.weapon:getDesc().guidance then local Initiator_Name = event.initiator:getName() local Initiator_Coalition = event.initiator:getCoalition() local _weapon = event.weapon:getDesc() local _weapon_guidance = _weapon.guidance local _weapon_type = event.weapon:getTypeName() if _weapon_guidance == 4 then [color="Blue"]-- Guidance type 4 is fox 1[/color] trigger.action.outSoundForCoalition( Initiator_Coalition , Foxcall_Table.Fox_1[initiator_Name][math.random(1,3)] ) elseif _weapon_guidance == 3 then [color="Blue"]-- Guidance type 3 is fox 3[/color] trigger.action.outSoundForCoalition( Initiator_Coalition , Foxcall_Table.Fox_3[initiator_Name][math.random(1,3)] ) elseif _weapon_guidance == 2 then [color="Blue"]-- Guidance type 2 is fox 2[/color] trigger.action.outSoundForCoalition( Initiator_Coalition , Foxcall_Table.Fox_2[initiator_Name][math.random(1,3)] ) end trigger.action.outText(event.initiator:getName().." launched ".._weapon_type, 10) end end end world.addEventHandler(Handler) Fox Detection Test.miz -
Yup, I kind of expected that. It might still be doable with dynamic WPs, but not with this method.
-
@Birdman81 If you don't find the cockpit argument, you can script it instead (required fields marked in red): local Plane = "[color="Red"]Unit name in ME[/color]" local Tanker = "[color="red"]Tanker name in ME[/color]" Six_K_trigger = 0 local function Scheduler() if Unit.getByName(Plane) and Unit.getByName(Tanker) then local DCS_Unit = Unit.getByName(Plane) local DCS_Tanker = Unit.getByName(Tanker) local Unit_Vec3 = DCS_Unit:getPoint() local Tanker_Vec3 = DCS_Tanker:getPoint() local Distance2D = math.floor( ( ( Unit_Vec3.x - Tanker_Vec3.x ) ^ 2 + ( Unit_Vec3.z - Tanker_Vec3.z ) ^ 2 ) ^ 0.5, 0 ) local Aircraft_Max_Internal_Fuel = DCS_Unit:getDesc().fuelMassMax local Fuel_Multiplier = DCS_Unit:getFuel() local Fuel_Kg = math.floor( Aircraft_Max_Internal_Fuel * Fuel_Multiplier, 0 ) local Fuel_Lbs = math.floor( Fuel_Kg * 2.2046 , 0 ) if Distance2D < 300 and Fuel_Lbs >= 6000 and Six_K_trigger ~= 1 then [color="Blue"]-- Do stuff when fuel quantity reaches 6000 or higher[/color] Six_K_trigger = 1 end end if Six_K_trigger ~= 1 then return timer.getTime() + 3 end end timer.scheduleFunction(Scheduler, nil , timer.getTime() + 1) Might need some tweaking, but this is the idea.
-
Script to Make Flag Value Increase by 1
Hardcard replied to Sedlo's topic in Scripting Tips, Tricks & Issues
So you have 4 pilots with different voices, is that it? If that's the case, then I'd use the initiator group/unit names rather than flags to assign individual sound files. You could also add an extra layer of variation by recording several fox calls for each pilot. If that's not the case, then I guess you have a "common pool" of fox calls and you simply want to randomize things a bit. Either way, I'd work with tables, for loops and randomizers instead of flags. I can provide script examples later, if you're interested. -
...or you could use a standard DCS scheduler and stop it with a flag activation, as shown in #5 :D local blueunits = mist.makeUnitTable({'[blue][plane]'}) local zone_name = trigger.misc.getZone('Staging Zone') local inZone = {} local function check() count = 0 for i = 1, #blueunits do if Unit.getByName(blueunits[i]) then local u = Unit.getByName(blueunits[i]) if mist.utils.get2DDist(u:getPosition().p, zone_name.point) < zone_name.radius then count = count + 1 if not inZone[u:getName()] then inZone[u:getName()] = true end else if inZone[u:getName()] then inZone[u:getName()] = nil end end end end trigger.action.setUserFlag('200', count) trigger.action.outText( 'Flag 200: ' .. trigger.misc.getUserFlag ( '200' ), 10 ) if trigger.misc.getUserFlag('5000') ~= 1 then return timer.getTime() + 300 [color="Blue"]-- As long as flag 5000 either doesn't exist or isn't true (doesn't have a value of 1), the scheduler will keep running every 5 minutes[/color] end end timer.scheduleFunction(check, nil, timer.getTime() + 6)
-
Dodged a bullet there ;) Here's a way of doing it, although I'm not sure it'll work with dynamic waypoints (required fields marked in red, at the bottom): local function Get_WP_Vec2(Grp_Name , WP) if type(Grp_Name) == "string" and type(WP) == "number" and _DATABASE:GetGroupTemplate(Grp_Name) then local Group_Template = _DATABASE:GetGroupTemplate(Grp_Name) if Group_Template.route.points[WP] and Group_Template.route.points[WP].x and Group_Template.route.points[WP].y then local WP_Coord = { x = Group_Template.route.points[WP].x , y = Group_Template.route.points[WP].y } return WP_Coord end end end Get_WP_Vec2( "[color="red"]Name of the group in ME[/color]" , [color="Red"]waypoint number[/color] ) You can also create a custom WP table and fill it with the WP coordinates extracted from the group template (required fields marked in red):
-
You can call the project any name you want, doesn't have to be Moose_Framework (same for the rest). Try setting it all up in the same workspace, with different names and sources. Alternatively, LDT allows you to create and switch between different workspaces. To create a new workspace, add a new folder in the LDT installdir and name it as you like. Then open LDT and go to File > Switch Workspace > Other..., browse for that new folder and hit Launch. LDT will restart in the new workspace, then you can set it up the same way you did the other one... but using the develop source files instead.
-
No idea of how removeFunction() works, like I said, I've never used MIST. However, the correct syntax would be: if trigger.[color="Green"]misc[/color].getUserFlag([color="Green"]'[/color]5000[color="green"]'[/color]) [color="Green"]==[/color] [color="Green"]1[/color] then mist.removeFunction(check) end Also, here's a way of stopping a standard DCS scheduler with a flag activation: local function Scheduler() [color="Blue"]-- Do stuff[/color] if trigger.misc.getUserFlag('5000') ~= 1 then return timer.getTime() + 10 [color="blue"]-- As long as flag 5000 either doesn't exist or isn't true (doesn't have a value of 1), the scheduler will keep running[/color] end end timer.scheduleFunction(Scheduler, nil, timer.getTime() + 1)
-
@CougarFFW04 MOOSE. It's a tracing function for debugging, can be used to dump tables in dcs.log Alternatively, I think that BASE:I can be used as well, no tracing required for that one.
-
Script to Make Flag Value Increase by 1
Hardcard replied to Sedlo's topic in Scripting Tips, Tricks & Issues
I think there's still a problem with your if statement. if event.id == world.event.S_EVENT_SHOT and event.initiator == Unit.getByName('UZI 11')[color="Red"] or Unit.getByName('UZI 12') or Unit.getByName('UZI 13') or Unit.getByName('UZI 14') [/color]then As it's written, your statement will check for the following: - Whether it's a SHOT event and - Whether the initiator is UZI 11 or - Whether UZI 12 is found in database or - Whether UZI 13 is found in database or - Whether UZI 14 is found in database If you want to check whether the initiator is UZI 11,12,13 or 14, you must write the relational condition each time: if event.initiator == Unit.getByName('UZI 11') or event.initiator == Unit.getByName('UZI 12') or event.initiator == Unit.getByName('UZI 13') or event.initiator == Unit.getByName('UZI 14') then Sure, having to write the same thing over and over is kind of annoying and dumb, but that's how Lua works. Alternatively, you can simply create a table of initiators (or unit names) and then check if the initiator of the SHOT event is in it. Also, why don't you make the script play a different sound file depending on missile type? Like Fox 1/ Fox 2 / Fox 3! That would be cooler ;) (Btw, you know that the "fox number" doesn't represent the quantity of missiles fired, but the missile type, right?) Fox 1 = Semi-active missile Fox 2 = Heat seeker missile Fox 3 = Active missile It's actually quite easy to do, you just need to know the missile type enumerators (which can be gathered from a simple test mission), then classify them according to fox type. -
Those module errors are normal, the error you reported isn't. The Moose.lua include that you need to run in your missions is definitely there. It's the third asset/link --> https://github.com/FlightControl-Master/MOOSE/releases/tag/v2.5.0pre1 Previous MOOSE versions are missing AIRBOSS module, new methods and a host of bug fixes.
-
Then you've probably set up My_Missions wrong. Delete the project and create it again. - No execution environment - No default template - Delete the src folder - Make sure Moose_Framework is referenced - Make sure Moose_Framework is properly set up (Moose Development/Moose should be selected as source folder)
-
Delete that src folder under My_Missions. Then right-click My_Missions > Build Path > Configure Build Path... > Add Moose_Framework under Projects tab (if it isn't already there) Intellisense should work fine, assuming that Moose_Framework project is correctly set up. Also, you should be able to create folders and put scripts in them.
-
Not many people around these parts use MIST, see if Grimes can come to the rescue (as usual :D). If you're new to scripting, though, I wouldn't recommend starting with MIST, since it requires advanced Lua knowledge and documentation is rather scarce. I think it's easier to start with standard DCS code, then maybe toy around with MOOSE, since they're better documented. In any case, here are my two cents (I've never used MIST, mind you): local blueunits = mist.makeUnitTable({'[blue][plane]'})[color="blue"] -- If this set doesn't include all blue planes / doesn't get updated over time, it'll be problematic[/color] local zone_name = trigger.misc.getZone('Staging Zone') local inZone = {} local function check() count = 0 [color="Blue"]-- Make this variable global and put it inside the check function, so it'll be reset every time the scheduler runs[/color] for i = 1, #blueunits do if Unit.getByName(blueunits[i]) then local u = Unit.getByName(blueunits[i]) if mist.utils.get2DDist(u:getPosition().p, zone_name.point) < zone_name.radius then [color="blue"]-- I modified the statement to include Staging Zone's coords and radius[/color] count = count + 1 [color="blue"]-- count will increase by 1 for every blue plane found in zone... assuming I'm interpreting the code correctly[/color] if not inZone[u:getName()] then inZone[u:getName()] = true end else if inZone[u:getName()] then inZone[u:getName()] = nil end end end end trigger.action.setUserFlag('200', count) [color="blue"]-- With this line, flag 200 should be given a numerical value equal to the number of blue planes found within the zone[/color] trigger.action.outText( 'Flag 200: ' .. trigger.misc.getUserFlag ( '200' ), 10 ) end mist.scheduleFunction(check, {}, timer.getTime()+6, 6, timer.getTime()+ 300) [color="blue"]-- I'm assuming this scheduler will run every 5 minutes? [/color]
-
@Ahmed You're preaching to the choir, man ;)
-
@Ahmed Make sure that you only have a single client in each group, this way you'll always know which unit triggered the menu command. Then... Option #1 - Link that F10 menu to an event, then pass the initiator unit as argument: local function Command_Function(Initiator) [color="Blue"]-- Do stuff using initiator unit object[/color] end local Handler = {} function Handler:onEvent(event) if event.id == world.event.S_EVENT_BIRTH and event.initiator:getCategory() == Object.Category.UNIT then if event.initiator:getPlayerName() then local Grp = event.initiator:getGroup() local Grp_ID = Grp:getID() local Initiator = event.initiator Main = missionCommands.addSubMenuForGroup(Grp_ID, "Group Menu") Command = missionCommands.addCommandForGroup(Grp_ID, "Group Command", Main, Command_Function, Initiator)[color="blue"] -- Pass Initiator as argument[/color] end end end world.addEventHandler(Handler) Option #2 - Include all relevant clients in a set, then iterate the set, creating a group menu for each one of them, passing the client unit and/or player name as argument (MOOSE example): local function Command_Function(Client , Player_Name) [color="Blue"]-- Do stuff using the client object (unit) and/or the player name[/color] end local Client_SET = SET_CLIENT:New():FilterActive(Active):FilterPrefixes("[color="Red"]common client prefix/suffix[/color]"):FilterStart() Client_SET:ForEachClient( function(Client) local Grp = Client:GetGroup() local Player_Name = Client:GetPlayerName() Main = MENU_GROUP:New(Grp , "Group Menu") Command = MENU_GROUP_COMMAND:New(Grp , "Group Command" , Main , Command_Function , Client , Player_Name) [color="Blue"]-- Pass client object (unit) and player name as arguments[/color] end end )
-
Other than by trial and error, I don't know. AttackGroup and AttackUnit tasks can also be pushed to individual units. The main difference between them and AttackMapObject is that they won't work on static and scenery targets.
-
The problem with your script is that you're providing vec3 instead of vec2 coordinates (AttackMapObject task only accepts vec2 coordinates). Here, this will make the strike eagles engage the soldiers: local pil01 = Unit.getByName('Pilot01'):getController() local sol01 = StaticObject.getByName('cible01') local sol01_vec2 = { x = sol01:getPoint().x , y = sol01:getPoint().z } [color="Blue"]-- Conversion to Vec2 coordinate format[/color] local Strike_Task01 = { id = 'AttackMapObject', params = { point = sol01_vec2, groupAttack = false, expend = "ALL" } } pil01:pushTask(Strike_Task01) local pil02 = Unit.getByName('Pilot02'):getController() local sol02 = StaticObject.getByName('cible02') local sol02_vec2 = { x = sol02:getPoint().x , y = sol02:getPoint().z } [color="Blue"]-- Conversion to Vec2 coordinate format[/color] local Strike_Task02 = { id = 'AttackMapObject', params = { point = sol02_vec2, groupAttack = false, expend = "ALL" } } pil02:pushTask(Strike_Task02) local pil03 = Unit.getByName('Pilot03'):getController() local sol03 = StaticObject.getByName('cible03') local sol03_vec2 = { x = sol03:getPoint().x , y = sol03:getPoint().z } [color="Blue"]-- Conversion to Vec2 coordinate format[/color] local Strike_Task03 = { id = 'AttackMapObject', params = { point = sol03_vec2, groupAttack = false, expend = "ALL" } } pil03:pushTask(Strike_Task03)
-
Post the mission file here.
-
Right, that's because I forgot to prepare the script properly for actual testing... also, I made a silly mistake in the scheduled function :doh: Remember that the script will only work with flag 1 (as it's written) and that the flag checker (scheduled function) runs once a minute. If you need the flag checker to run more often, change the value from 60 to a lower one. As long as flag 1 is set to 1, spawning will be active, if flag 1 doesn't exist or isn't set to 1, no copies of NATO E-3A Sentry group should spawn the next time the flag checker runs. Load this script using a ONCE trigger, no conditions (I've removed :InitRepeatOnEngineShutDown(), in case it's interfering. Also, that behaviour can be scripted in another way... but we'll get to that later): Spawn_E3A = SPAWN:New("NATO E-3A Sentry") Spawn_E3A:InitLimit( 1, 0 ) local function FlagChecker() if trigger.misc.getUserFlag("1") and trigger.misc.getUserFlag("1") == 1 then Spawn_E3A:Spawn() end return timer.getTime() + 60 [color="Blue"]-- Number of seconds before the flag checker runs again[/color] end timer.scheduleFunction(FlagChecker, nil, timer.getTime() + 1)
-
Sure, some tasks can be pushed to individual units, but I seem to remember that some other tasks only work at group level. Lucky for you, AttackMapObject task works at unit level ;) Regarding the script I provided, it includes an automatic finder of closest enemy airbase + scenery object scan... I'd say it's pretty useful stuff for any mission creator :D
-
@fargo007 Because I hate ME zones with a passion :D Seriously now, they have their uses, but I prefer working with coordinates for several reasons. @A101Wayz The problem is that creating a Mission task table with the correct waypoints and format is a PITA.
-
According to your snippet, you're spawning a custom static object, not a unit object, that's an important difference. IIRC, event handlers and spawned custom statics don't mix well, but it has been a while since I last messed with this stuff. I do remember that some static types simply aren't accessible (like infantry, for instance) What are you trying to accomplish, specifically? What do you need the ids for? See if you can get a description table from the initiator, with any luck you'll find the displayName in there. But, as I said, that might be tricky if the object is dead, so try using a HIT event instead (use the target, not the initiator in that case).
-
One way of doing it is by accessing the group template's route subtable in the mission database. Here's an example (required field marked in red): BASE:TraceOnOff(true) BASE:TraceAll(true) BASE:TraceLevel(2) BASE:T(_DATABASE:GetGroupTemplate("[color="Red"]name of the group in ME[/color]").route) [color="Blue"]-- This will dump the group's [i][b]route[/b][/i] subtable to dcs.log[/color] BASE:TraceOnOff(false) Keep in mind that the route subtable is a bit tricky to navigate, but you should be able to access x and y values like this: route.points[[color="Red"]waypoint number[/color]].y route.points[[color="red"]waypoint number[/color]].x I've attached an output example from a group template with 6 waypoints Route output.lua
-
Learning the basics of Lua is easier than it seems, plus it'll unlock a whole new world of possibilities for you. In this case, you need to write an if...else statement/check + the DCS method to get flag values. Put it all together: Spawn_E3A = SPAWN:New("NATO E-3A Sentry") Spawn_E3A:InitLimit( 1, 0 ) if trigger.misc.getUserFlag("1") == 1 then [color="Blue"]-- [i][b]if[/b][/i] statement/check using [i][b]getUserFlag()[/b]. If flag 1 is true (meaning it's set to 1), the three lines below it will execute[/i][/color] Spawn_E3A:InitRepeatOnEngineShutDown() Spawn_E3A:SpawnScheduled( 60, 0 ) [color="blue"]-- This defines and starts the spawning scheduler[/color] Spawn_E3A:SpawnScheduleStart() [color="blue"]-- This should restart the spawning scheduler, in case it has been stopped[/color] else [color="Blue"]-- This is an [i][b]else[/b][/i] statement/check, which will execute the line below if the first statement/check isn't true (flag 1 isn't true)[/color] Spawn_E3A:SpawnScheduleStop() [color="blue"]-- This should stop the spawning scheduler[/color] end [color="Blue"]-- Note that this [i][b]if...else[/b][/i] statement/check should be placed inside a scheduler (in order to periodically check the state of flag 1) -- But putting schedulers inside other schedulers will create unnecessary complications, I'd rather simplify the script by getting rid of the spawning scheduler and writing a custom one[/color] [color="Blue"]-- Like this:[/color] Spawn_E3A = SPAWN:New("NATO E-3A Sentry") Spawn_E3A:InitLimit( 1, 0 ) local function FlagChecker() if trigger.misc.getUserFlag("1") == 1 then Spawn_E3A:InitRepeatOnEngineShutDown() Spawn_E3A:Spawn() return timer.getTime() + 60 end end timer.scheduleFunction(FlagChecker, nil, timer.getTime() + 1) Lua tutorial for newbies --> https://www.tutorialspoint.com/lua/index.htm Standard DCS scripting documentation --> https://wiki.hoggitworld.com/view/Simulator_Scripting_Engine_Documentation MOOSE documentation --> https://flightcontrol-master.github.io/MOOSE_DOCS/Documentation/index.html