Jump to content

Recommended Posts

Posted

Hey,

now that bs2 got the mission editor of the warthog, I'm eager to get my horses running with all that possibilities. I'm aware that I'm able to use lua-scripts for unit behavior (for example at the special task-conditions), but I'm unable to find any reference, which lua-libs and function()s are available. I'm thinking of the possibility to use a script in the following way:

 

 

tank2InsideZone()

if distance(tank2,zone1) < 200)

return true;

 

while(tank2InsideZone() && tank2.alive())

tank1.setTarget(tank2)

 

I'm aware that this task is also achievable by usage of triggers, but it's only an not-so-complex example, and I'm way faster at lua scripting then trigger-building ;)

There's no "Overkill". There's only "open fire!" and "time to reload".

Specs: i7-980@4,2Ghz, 12GB RAM, 2x GTX480, 1x 8800GTS, X-Fi HD, Cougar, Warthog, dcs-F16-pedals

Posted (edited)

I will attempt a _G dump of the mission scripting environment tomorrow and get back to you (I also need to get back to tyrspawn on a similar question). Before I tell you more, I want to see if there are any changes post 1110. I can tell you now, the main objects available in the mission scripting environment are Unit, Group, and Controller. Unit and Group are pretty self-explanatory. Controller is the object that allows you to assign tasks and AI actions. Every group has one.

Edited by Speed

Intelligent discourse can only begin with the honest admission of your own fallibility.

Member of the Virtual Tactical Air Group: http://vtacticalairgroup.com/

Lua scripts and mods:

MIssion Scripting Tools (Mist): http://forums.eagle.ru/showthread.php?t=98616

Slmod version 7.0 for DCS: World: http://forums.eagle.ru/showthread.php?t=80979

Now includes remote server administration tools for kicking, banning, loading missions, etc.

Posted

So group and unit are probably extending the controller? Yeah, I'ld be real greatful. It's nice to use complex trigger solutions, but a script is often way cleaner in my experience.

There's no "Overkill". There's only "open fire!" and "time to reload".

Specs: i7-980@4,2Ghz, 12GB RAM, 2x GTX480, 1x 8800GTS, X-Fi HD, Cougar, Warthog, dcs-F16-pedals

Posted

Sorry for the late reply. I have not yet gotten a chance to do a _G dump of the mission scripting environment. However, I can give you a quick guide on the Unit, Group, and Controller objects:

 

NOTE: I WROTE THIS SEVERAL MONTHS AGO. SOME OF THIS INFO MAY BE OUT OF DATE. I have also vastly improved (with much more improvement possible still) my Lua programming skills in the interim. Furthermore, I have not vetted this for typos or programming errors.

 


Unit functions:
Units are ground units, air units, and naval units.  I do not believe that static objects are units, though this may have changed.

In Lua, all a Unit consists of is:
[unit] = { id_ = <large integer number> }

You can run most of the following functions on this Lua table to get a Unit’s actual properties.

Unit.getByName

Usage:
[unit] = Unit.getByName( [string]<name> )

Description:
Returns the Unit with name <name>.   Returns nil if the unit with name <name> does not exist.

Example:
--If there is a live unit named "playeraircraft" in the mission, then
--its Unit will be returned to playerunit
playerunit =  Unit.getByName("playeraircraft")


Unit.isExist

Usage:

[boolean] = Unit.isExist( [unit] <unit> )
or
[boolean] =  [unit]<unit>:isExist() 

Description:
Returns true if the Unit <unit> exists, returns false if the Unit <unit> doesn’t (alive or not yet activated units count as “existing”, dead units or deactivated units count as non-existing).  Input parameter is a Unit.  

Example:
--set playerunitalive true if playerunit is alive
playerunit =  Unit.getByName('playeraircraft')
playerunitalive = Unit.isExist(playerunit)

Another example:
--same thing
playerunit =  Unit.getByName('playeraircraft')
playerunitdead = playerunit:isExist()

Unit.getVelocity

Usage:
[velocity table] = Unit.getVelocity([unit]<unit>)
or
[velocity table] = [unit]<unit>:getVelocity()

Description:
Returns a table containing the x (east), y (altitude), and z (north) velocity in meters per second.  NOTE THAT THIS TABLE DIFFERS FROM THE MISSION EDITOR’S POSITION TABLE IN WHICH x AND y ARE THE NORTH AND EAST COORDINATES!
Such as:
{ x = <number>, y = <number>, z =  <number> } 

Example: 
if playerunit:isExist() then
   velocity = playerunit:getVelocity()
   Northvel = velocity.x
   AltVel = velocity.y
   EastVel = velocity.z
end


Unit.getController

Usage:
[Controller] = Unit.getController( [unit]<unit>)
or
[Controller] = [unit]<unit>:getController()

Description:
Returns that Controller class object for that unit.  The Controller object is what you need if you want to assign that unit’s group a task, such as fire at point or bombing at point.  See the Controller section for more on the controller object.

Unit.getPosition

Usage:
[position table] = Object.getPosition( [Object]<object>)
or
[position table] = [Object]<object>:getPosition()

Description:
Returns a table of FOUR tables concerning an object’s position.  These tables are x, y, z, and p.  The “p” table is the x,y,z map coordinates of the target, in Lock On (LO) format.  The x, y, and z tables deal with things such as unit heading.

Example:
if unit1 ~= nil then
   if unit1:isExist() then
       unit1posit = unit1:getPosition().p
       unit1Ncoord = unit1posit.x
       unit1Ecoord = unit1posit.z
       unit1Alt = unit1posit.y
   end
end


Unit.setPosition

Usage:
Unknown

Description:
This function sure sounds promising, but I’m not sure if it even does anything.  It sounds like you could use it to teleport units to certain locations, but every time I’ve tried to make this function do anything it has had no effect.  Experimentation is welcome!


Unit.getWsType

Usage:
Unknown, likely usage is described in description

Description:
This function obviously should return the “WsType” of the unit. Experimentation with using it, however, suggested that the function MAY not work correctly- but I am not sure of it.

The usage is:
[WsType] = Unit.getWsType ( [unit]<unit> )
or
[WsType] = [unit]<unit>:getWsType()




Unit.inAir

Usage:
Unknown, likely usage is described in description

Description:
Probably, you input a Unit object and this returns a boolean value (true or false) if the unit is airborne:
[boolean] = Unit.inAir( [unit]<unit> )
or
[boolean] = [unit]<unit>:inAir()


Unit.getCommunicator

Usage:
[Communicator] = Unit.getCommunicator( [unit]<unit> )
or
[Communicator] = [unit]<unit>:getCommunicator()

Description:
Returns the Communicator object of <unit>.  The Communicator object is used to make that object send radio messages.  Radio messages tend to be limited to pre-defined lines, but a way to send a custom one may be possible.  Any generated radio message is only likely to be only heard by the single player/host, but I have not done the experiment to test this.

Unit. getLife0

Usage:
Unknown, likely usage is described in description

Description
Function likely returns the starting life of the unit, and likely usage is as follows:
[number?] = Unit.getLife0( [unit]<unit> )
or
[number?] = [unit]<unit>:getLife0()

Unit. getLife

Usage:
Unknown, likely usage is described in description

Description
Function likely returns the current life of the unit, and likely usage is as follows:
[number?] = Unit.getLife( [unit]<unit> )
or
[number?] = [unit]<unit>:getLife()


Unit.getName

Usage:
Unknown, likely usage is described in description

Description
Function likely returns the name of the unit, and likely usage is as follows:
[string] = Unit.getName( [unit]<unit> )
or
[string] = [unit]<unit>:getName()

Unit.getNumber

Usage:
Unknown

Description:
Returns a unit’s number within its group?


Unit.getGroup

Usage:
Unknown, but likely usage is described in description

Description
There is a Group type object, and this function undoubtedly returns the unit’s Group object.  A group object, if I remember correctly looks exactly like a Unit object in that it is a table with a single entry in it ( [Group] = { id = <number> }  ), but I could be wrong about this.  This function could come in useful if you wanted to only specify a single unit of a group and use it to find out information about other units within the same group.
So likely usage would be:
[Group] = Unit.getGroup( [unit]<unit> )
or
[Group] = [unit]<unit>:getGroup()



Unit.hasAttribute

Usage:
Unknown

Description:
Unknown

Unit.getTypeName

Usage:
Unknown

Description:
Unknown

Unit.getClass

Usage:
Unknown

Description:
Unknown

Unit.getCoalition

Usage:
Unknown, but likely usage is described in description

Description:
Obviously this returns something corresponding to the unit’s coalition.  This could be useful, but you usually know this information already.
Likely usage:
[coalition something or another] = Unit.getCoalition( [unit]<unit> )
or
[coalition something or another] = [unit]<unit>:getCoalition()

Unit.getCountry

Usage:
Unknown, but likely usage is described in description

Description:
Obviously this returns something corresponding to the unit’s country.  This could be useful, but you usually know this information already.
Likely usage:
[country something or another] = Unit.getCountry( [unit]<unit> )
or
[country something or another] = [unit]<unit>:getCountry()

Group Functions
A group object, if I remember correctly looks exactly like a Unit object in that it is a table with a single entry in it ( [Group] = { id = <number> }  ), but I could be wrong about this.  Group functions would allow you to get information about a certain group.

Group.getSize

Usage:
Unknown, but likely usage is described in description

Description:
Probably returns the number of units in a group.  Likely usage:
[number?] = Group.getSize( [Group]<group> )
or
[number?] = [Group]<group>:getSize()


Group.getPoint

Usage:
Unknown

Description:
Unknown

Group.getUnits

Usage:
Unknown

Description:
Returns a table with all the group’s units in it?

Group.getClass

Usage:
Unknown

Description:
Unknown


Group.getName

Usage:
Unknown

Description:
Probably just returns the name of the group (as you named it in the mission editor).

Group.getUnit

Usage:
Unknown

Description:
Gonna take another guess, you probably specify an index value and it returns the unit that corresponds to that index value within the group.  Like, [unit] = [Group]<group>:getUnit(2) would return the second unit in that group.  Just a guess.

Controller functions
The Controller object is the object in lua code that translates tasks given to AI into actual AI actions.  Each group has a single controller, which can be gotten by using the Unit.getController function, used on any alive unit in that group.  I have not fully explored all uses of the Controller object.

Controller.setTask

Usage:
Controller.setTask( [Controller]<controller>, [Task]<task> )
or
<controller>:setTask( [Task]<task> )

Description:
Sets the task of the group with controller <controller> to the task <task>.  <task> is a table, and the format of <task> can be determined by this process:

1)	Create a simple mission with just the kind of unit you want to do a task.  Using the mission editor, give that unit the kind of task you want to assign in lua code later.  It can be either a waypoint action or triggered action; it usually won’t matter.
2)	Save the mission, close DCS, and unzip the mission.  Open the “mission” file (there is no extension) with Notepad++ and scroll down till you see the lines in the unzipped “mission” file that define the task you created in the mission editor.  The format of that you should use for <task> in the Controller.setTask function is exactly the same as this- other than perhaps having to make y mission editor coordinates z lua coordinates (see the description of Unit.getVelocity for more on this).

Example:
--The group that contains the unit named "M109_1" will set a target point on
--with a 50 meter radius on top of the position of the unit named "T-72_1".
if true then 
   
   local artyunit = Unit.getByName("M109_1")
   local targetunit = Unit.getByName("T-72_1")
   
   if (artyunit ~= nil) and (targetunit ~= nil) then
       local targetpoint = targetunit:getPosition().p
       local task1 = { id = "FireAtPoint", params = { y = targetpoint.z, x = targetpoint.x, zoneRadius =50}}
       --Note that in the fire at point task, you have to use mission editor x, y, and z coordinates, where --ME y coordinates equal lua z coordinates, and ME z coordinates equal lua y coordinates!
       local unitcontroller = Unit.getByName(unitname):getController()
       unitcontroller:setTask(task1)
   end
   
end
--In this example, I use the if true then to make all the local variables defined 
--inside the if statement local to that if statement only.  Thus, this script could 
--be run and re-used over and over again, for different units, at the global level, 
--and never make any global variables. 


Controller.resetTask

Usage:
Controller.resetTask( [Controller]<controller )
or
<controller>:resetTask()

Description:
Ends the current task that is assigned to <controller>

Controller.setCommand

Usage:
Controller.setCommand( [Controller]<controller>, [Command]<command> )
or
<controller>:setCommand( [Command]<command> )

Description:
Sets the “Command” <command> for <controller>. 

Example:
if true then
        --Modify the unit_name variable to match the aircraft you want to switch waypoints.  Put it in quote marks!
        local unit_name = 'airplane'

        --Modify the switch_to_waypoint variable to match the waypoint you want the aircraft to switch to.
        --The switch_to_waypoint number should match the number shown beside the waypoint on the ME.
        local switch_to_waypoint =  5

        --Modify nothing below this line
        ----------------------------------------------------------------------------------------------
        switch_to_waypoint = switch_to_waypoint + 1

        local switchtask = { id = "SwitchWaypoint", params = { goToWaypointIndex = switch_to_waypoint, fromWaypointIndex = switch_to_waypoint } }

        local air_unit = Unit.getByName(unit_name)
        if air_unit ~= nil then

                    local air_unit_controller = air_unit:getController()

                    air_unit_controller:setCommand(switchtask)
        end

end 

Intelligent discourse can only begin with the honest admission of your own fallibility.

Member of the Virtual Tactical Air Group: http://vtacticalairgroup.com/

Lua scripts and mods:

MIssion Scripting Tools (Mist): http://forums.eagle.ru/showthread.php?t=98616

Slmod version 7.0 for DCS: World: http://forums.eagle.ru/showthread.php?t=80979

Now includes remote server administration tools for kicking, banning, loading missions, etc.

Posted

Thanks! I'll def

There's no "Overkill". There's only "open fire!" and "time to reload".

Specs: i7-980@4,2Ghz, 12GB RAM, 2x GTX480, 1x 8800GTS, X-Fi HD, Cougar, Warthog, dcs-F16-pedals

Posted

Thanks! I'll definitivly experiment and report back.

There's no "Overkill". There's only "open fire!" and "time to reload".

Specs: i7-980@4,2Ghz, 12GB RAM, 2x GTX480, 1x 8800GTS, X-Fi HD, Cougar, Warthog, dcs-F16-pedals

Posted (edited)

Here's some simple Lua code that should make the group of units that includes the unit named "M109_1" set a fire at point task on the exact position of the unit named "T-72_1":

do 
local artyunit = Unit.getByName("M109_1")
local targetunit = Unit.getByName("T-72_1")

if artyunit and targetunit then
	local targetpoint = targetunit:getPosition().p
	local task1 = { id = "FireAtPoint", params = { y = targetpoint.z, x = targetpoint.x, zoneRadius =50}}
	--Note that in the fire at point task, you have to use mission editor x, y, and z coordinates where y and z are reversed.
	artyunit:getController():setTask(task1)
end
end

 

I noticed an error in the Lua script that was included in the guide- but after all, I never proof read the scripting guide before I abandoned work on it, so that's to be expected.

 

Anyway, this script SHOULD work if you run it on a group's triggered actions. Preferably, a third-party group (I use a group named "scriptman") that is placed far away from the action.

 

Anyway, if you expand upon this script, add in all the groups of units possible, add some randomization, add some logic to make artillery lead moving targets, then you get something very similar to the "autoarty" script I created in 1.1.0.7. Some form of this script should return in the future for my mod, especially considering that battle commander is going to make a comeback. Enemy artillery will need to intelligently react and respond to a human commander's movement across the battlefield, and an autoarty script will allow that.

Edited by Speed

Intelligent discourse can only begin with the honest admission of your own fallibility.

Member of the Virtual Tactical Air Group: http://vtacticalairgroup.com/

Lua scripts and mods:

MIssion Scripting Tools (Mist): http://forums.eagle.ru/showthread.php?t=98616

Slmod version 7.0 for DCS: World: http://forums.eagle.ru/showthread.php?t=80979

Now includes remote server administration tools for kicking, banning, loading missions, etc.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...