_[v1.20] Tutorial 2 - Areas, Enhancing our Simple Mission.
Welcome to Tutorial No.2.The following tutorial will enhance some of the aspects done on the first tutorial, while introducing alternatives approaches to some of the topics we discussed on tutorial one.
The tutorial will cover the following topics:
The tutorial will cover the following topics:
- Areas element - Introduction
- Area types and rules - which one to choose
- Gathering info regarding the area.
- Defining an area in the mission data file
- Basic Events in Area
- Implementing area in our "Simple Mission" from tutorial one.
- Test + Exercise
- Area as Target
- Implement the feature in our Simple Mission
- Test again
- Finishing Words
Areas
Areas can be seen as Triggering events on a certain location. The location can be defined as radius or polygonal area.
Using area basically give you a more versatile way to handle the mission events. The areas are part of an Objective and not defined globally.
One of the key advantages to use Areas, is the inclusion of events. To each area there are basic events that are pre-defined like: "onEnter", "onLeave", "onSuccess", "onFail". These are not the only things you can do in areas, you can link between a target and an area, so rules defined in area, are the rules of the target itself, you can define your own event names and then call then from <Logic> events (not in this scope). These characteristics allow a lot of flexibility when designing a mission and its targets.
Using area basically give you a more versatile way to handle the mission events. The areas are part of an Objective and not defined globally.
One of the key advantages to use Areas, is the inclusion of events. To each area there are basic events that are pre-defined like: "onEnter", "onLeave", "onSuccess", "onFail". These are not the only things you can do in areas, you can link between a target and an area, so rules defined in area, are the rules of the target itself, you can define your own event names and then call then from <Logic> events (not in this scope). These characteristics allow a lot of flexibility when designing a mission and its targets.
What are the types of areas and which one to choose
As of v1.20 we have three types of areas. Area based on Radius, areas based on polygonal boundaries and slope. The area based on radius, is similar to a <Feedback> or <StaticTarget> elements, their boundaries are circular, you define the radius and the plugin test when the plane enter that area.
In our tutorial we will use the polygonal area type, in order to practice it and not because it is better or more adequate to our mission.
Next, we need to decide which event to use. In this tutorial we will replace the <Feedback> that we implemented, just after crossing LOIK airport.
That means, we need an area that will trigger an event that sends message to the simmer when he/she enters that area.
Now that we know which action we want to trigger, we can now define which event will handle the triggering action (rule). In this case, we need an "onEnter" event ( we can also use "onSuccess" but it can be confusing )
To sum it up:
We will create an Area with type="poly" its action rule="enter" and the <Event> handler will be of type: "onEnter".
Our next goal will be to prepare the area data, and handle the event using the Mission Data syntax.
In our tutorial we will use the polygonal area type, in order to practice it and not because it is better or more adequate to our mission.
Next, we need to decide which event to use. In this tutorial we will replace the <Feedback> that we implemented, just after crossing LOIK airport.
That means, we need an area that will trigger an event that sends message to the simmer when he/she enters that area.
Now that we know which action we want to trigger, we can now define which event will handle the triggering action (rule). In this case, we need an "onEnter" event ( we can also use "onSuccess" but it can be confusing )
To sum it up:
We will create an Area with type="poly" its action rule="enter" and the <Event> handler will be of type: "onEnter".
Our next goal will be to prepare the area data, and handle the event using the Mission Data syntax.
Gathering info regarding the area
Since we are using a polygonal area, we need to define at list three coordinates that will define the area. We can do it quite easily using the Flight Gauge in conjunction with the mission-x designer build ( should be under the designer directory of the plugin ).
Here is my 50 cents on how to use it:
Here is a simple visual example:
Here is my 50 cents on how to use it:
- Load X-Plane.
- Move plane to LOIK airport.
- Click the "Flight Gauge" under "mission-x v1.20.xx designer"
- Enter "Local Map" screen.
- Move plane on map to the location you need to fetch coordinate.
- Exit Local Map view, and write down the coordinate.
- Repeat this process for all locations.
Here is a simple visual example:
From the image, you can see that I have defined four locations that represent the area. We need to extract the coordination and write them down in clockwise order:
- 47.673611 / 12.223461
- 47.621880 / 12.256681
- 47.597233 / 12.203191
- 47.619671 / 12.134592
Defining an area in the mission data file
Before modifying any mission file, we should back it up first.
Now we can do the following:
Here is a snippet of the Areas element
Now we can do the following:
- Edit Tutorial01_mission.xml file ( or any name you gave it )
- Add a new <Areas> element and a new <AreaZone> that will hold the triggering rules.
- Remove the old feedback and the optional objective we created in Tutorial 1.
Here is a snippet of the Areas element
<Areas>
<AreaZone type="poly" rule="enter" failCanCont="1" elevMin="0" elevMax="0" radius="0.0" timer="0.0" restrictElev="0" groupId="" stopOnReach="0">
<Point lat="47.673611" long="12.223461" />
<Point lat="47.621880" long="12.256681" />
<Point lat="47.597233" long="12.203191" />
<Point lat="47.619671" long="12.134592" />
<Event....>
</AreaZone>
</Areas>
<AreaZone type="poly" rule="enter" failCanCont="1" elevMin="0" elevMax="0" radius="0.0" timer="0.0" restrictElev="0" groupId="" stopOnReach="0">
<Point lat="47.673611" long="12.223461" />
<Point lat="47.621880" long="12.256681" />
<Point lat="47.597233" long="12.203191" />
<Point lat="47.619671" long="12.134592" />
<Event....>
</AreaZone>
</Areas>
From the <Areas> structure, you can see that you have the option to define one or more AreaZones in each objective.
We define the triggering rules in the AreaZone. The must have definitions of the AreaZone are the "type" and "rule" attributes.
Since we define "poly" area, we need to add at least three <Point> elements that define the area boundaries. Each Point represent one [ lat | lon ] coordinate, gathered in previous step.
Our Area definition is almost complete, we still need to define the <Event> ( action ) to take place once the plane has entered the AreaZone.
For that lets do a short refresh about Events.
We define the triggering rules in the AreaZone. The must have definitions of the AreaZone are the "type" and "rule" attributes.
Since we define "poly" area, we need to add at least three <Point> elements that define the area boundaries. Each Point represent one [ lat | lon ] coordinate, gathered in previous step.
Our Area definition is almost complete, we still need to define the <Event> ( action ) to take place once the plane has entered the AreaZone.
For that lets do a short refresh about Events.
Events
Event element represent the Action the plugin should conduct once a waiting trigger has been triggered. In our case when the plane enters an AreaZone. The event is a complimentary element meaning, it need to be encapsulated under other elements.
In this tutorial, our event type will be "onEnter".
In the <Event> we can define few actions but none of them is mandatory.
The actions are:
- Send feedback to the simmer
- Trigger ActiveFeedback ( see designer guide for more explanation )
- Apply logic (not discussed on this tutorial)
- Apply Inventory Actions (not discussed on this tutorial)
Since we want to send a message to our simmer, we will just define the <Msg> element under our Event.
It should be something as follow:
<Event id="1" type="onEnter" >
<Msg><![CDATA[Remember to follow the river north]]></Msg>
</Event>
<Msg><![CDATA[Remember to follow the river north]]></Msg>
</Event>
We need to copy and paste what we have done into the second objective and then clean the old Feedback and the Optional target we created just for it.Here is an example:
<!-- Second Objective: Land at EDNV airport -->
<Objective id="2" >
<Targets>
<StaticTarget id="1" lat="47.945999" long="12.204670" elev="1539" needToLand="1" tolerateDistance="0.8" tolerateElev="0" />
<!-- end of valley -->
<StaticTarget id="3" lat="47.564991" long="12.127969" elev="3000" needToLand="0" tolerateDistance="1" tolerateElev="5000" optional="1" />
</Targets>
<Desc>
<![CDATA[Continue eastwards from LOIK airport, and follow the river north until you reach the end of the valley.;Once there, head to EDNV airport and land there to complete the flight plan.;;Good Luck;]]>
</Desc>
<Feedbacks>
<Broadcast id="2" subTarget="3" distanceToBroadcast="3" ><![CDATA[You are nearing the end of the valley. Remember to head ~4 degrees to reach EDNV airfield.;You can use the local map too.;]]></Broadcast>
<Broadcast id="3" subTarget="1" distanceToBroadcast="8" ><![CDATA[You are nearing EDNV airfield;]]></Broadcast>
</Feedbacks>
<Areas>
<AreaZone type="poly" rule="enter" failCanCont="1" elevMin="0" elevMax="0" radius="0.0" timer="0.0" restrictElev="0" groupId="" stopOnReach="0">
<Point lat="47.673611" long="12.223461" />
<Point lat="47.621880" long="12.256681" />
<Point lat="47.597233" long="12.203191" />
<Point lat="47.619671" long="12.134592" />
<Event id="1" type="onEnter" >
<Msg><![CDATA[Remember to follow the river north]]></Msg>
</Event>
</AreaZone>
</Areas>
</Objective>
<Objective id="2" >
<Targets>
<StaticTarget id="1" lat="47.945999" long="12.204670" elev="1539" needToLand="1" tolerateDistance="0.8" tolerateElev="0" />
<!-- end of valley -->
<StaticTarget id="3" lat="47.564991" long="12.127969" elev="3000" needToLand="0" tolerateDistance="1" tolerateElev="5000" optional="1" />
</Targets>
<Desc>
<![CDATA[Continue eastwards from LOIK airport, and follow the river north until you reach the end of the valley.;Once there, head to EDNV airport and land there to complete the flight plan.;;Good Luck;]]>
</Desc>
<Feedbacks>
<Broadcast id="2" subTarget="3" distanceToBroadcast="3" ><![CDATA[You are nearing the end of the valley. Remember to head ~4 degrees to reach EDNV airfield.;You can use the local map too.;]]></Broadcast>
<Broadcast id="3" subTarget="1" distanceToBroadcast="8" ><![CDATA[You are nearing EDNV airfield;]]></Broadcast>
</Feedbacks>
<Areas>
<AreaZone type="poly" rule="enter" failCanCont="1" elevMin="0" elevMax="0" radius="0.0" timer="0.0" restrictElev="0" groupId="" stopOnReach="0">
<Point lat="47.673611" long="12.223461" />
<Point lat="47.621880" long="12.256681" />
<Point lat="47.597233" long="12.203191" />
<Point lat="47.619671" long="12.134592" />
<Event id="1" type="onEnter" >
<Msg><![CDATA[Remember to follow the river north]]></Msg>
</Event>
</AreaZone>
</Areas>
</Objective>
Our second Objective has now the <Areas> definition, and you can see I removed <StaticTarget id="2".../> and <Broadcast id="1" subTarget="2" ../> since they are needed no more.
The AreaZone is self-contained; it is like a target with inner rules and actions management.
Another thing we can see is that Adding more features can make objective code more complex.
Try to keep your mission data file as clean and indent as possible, that way it will be easier to spot what you look for. This is why I try to use good editors that help me distinguish between relevant and irrelevant info.
The AreaZone is self-contained; it is like a target with inner rules and actions management.
Another thing we can see is that Adding more features can make objective code more complex.
Try to keep your mission data file as clean and indent as possible, that way it will be easier to spot what you look for. This is why I try to use good editors that help me distinguish between relevant and irrelevant info.
Our First mission enhancement is complete.
Load X-Plane, and test the modified objective.
Load X-Plane, and test the modified objective.
Click on the link to download complete example for Areas and Messeging | |
File Size: | 1 kb |
File Type: | zip |
Short Exercise:
After testing our first "enhancement" with AreaZone and Event elements, lets try to create a rule that will be govern by an area.
On the first tutorial, we asked the simmer to fly over the valley and cruise at level no more then 6000 feet until he/she reaches LOIK airport. We did not restricted or inform the simmer that he is not in the correct area/level and now is a good opportunity to implement this.
I'll just add that there might be more then one way to achieve these tasks but on the suggested implementation I'll use only one solution.
Task One: Inform the simmer that he/she is not flying in the correct route. It's enough that the feedback will be sent only once.
Task Two: Modify the Area, so it will send the restriction message when the plane in not correct elevation too. We can describe this as: "if plane not in area coordination or plane in area but not in defined elevation then send message: Not in area or cruising level"
Start by implementing Task One, and then add Task Two.
In order to accomplish this, use the Designer Guide (Appendix A), and read the Area topic.
I'll publish my suggested solution at the end of this tutorial
On the first tutorial, we asked the simmer to fly over the valley and cruise at level no more then 6000 feet until he/she reaches LOIK airport. We did not restricted or inform the simmer that he is not in the correct area/level and now is a good opportunity to implement this.
I'll just add that there might be more then one way to achieve these tasks but on the suggested implementation I'll use only one solution.
Task One: Inform the simmer that he/she is not flying in the correct route. It's enough that the feedback will be sent only once.
Task Two: Modify the Area, so it will send the restriction message when the plane in not correct elevation too. We can describe this as: "if plane not in area coordination or plane in area but not in defined elevation then send message: Not in area or cruising level"
Start by implementing Task One, and then add Task Two.
In order to accomplish this, use the Designer Guide (Appendix A), and read the Area topic.
I'll publish my suggested solution at the end of this tutorial
Area as Target
In some cases, you will want that an area will be the Objective, hence it will represent as a target.
In order to reach this goal, we need to link between a target and an area. The link is done by attribute "groupId".
Here are the steps to define area as target:
In our case, we will convert Objective two StaticTarget to an AreaTarget. This is for the sake of practice.
We will use an Area type "rad" (radius) same as the static target, and copy relevant info from it.
Here is an example of how it should look:
In order to reach this goal, we need to link between a target and an area. The link is done by attribute "groupId".
Here are the steps to define area as target:
- Define <AreaZone> element if not defined yet.
- Give it a unique groupId number.
- Define <AreaTarget> element under <Targets>. Its groupId should be the same as the AreaZone GroupId.
In our case, we will convert Objective two StaticTarget to an AreaTarget. This is for the sake of practice.
We will use an Area type "rad" (radius) same as the static target, and copy relevant info from it.
Here is an example of how it should look:
<!-- Second Objective: Land at EDNV airport -->
<Objective id="2" >
<Targets>
<AreaTarget id="1" groupId="100" lat="0" long="0" elev="0.0" needToLand="1" />
<!-- end of valley -->
<StaticTarget id="3" lat="47.758482" long="12.130899" elev="3000" needToLand="0" tolerateDistance="1" tolerateElev="5000" optional="1" />
</Targets>
<Desc>
<![CDATA[Continue eastwards from LOIK airport, and follow the river north until you reach the end of the valley.;Once there, head to EDNV airport and land there to complete the flight plan.;;Good Luck;]]>
</Desc>
<Feedbacks>
<Broadcast id="2" subTarget="3" distanceToBroadcast="3" ><![CDATA[You are nearing the end of the valley. Remember to head ~4 degrees to reach EDNV airfield.;You can use the local map too.;]]></Broadcast>
<Broadcast id="3" subTarget="1" distanceToBroadcast="8" ><![CDATA[You are nearing EDNV airfield;]]></Broadcast>
</Feedbacks>
<Areas>
<AreaZone rule="enter" failCanCont="1" elevMin="0" elevMax="0" radius="0.0" timer="0.0" restrictElev="0" groupId="" stopOnReach="0">
<Point lat="47.673611" long="12.223461" />
<Point lat="47.621880" long="12.256681" />
<Point lat="47.597233" long="12.203191" />
<Point lat="47.619671" long="12.134592" />
<Event id="1" type="onEnter" >
<Msg><![CDATA[Remember to follow the river north]]></Msg>
</Event>
</AreaZone>
<AreaZone type="rad" rule="enter" failCanCont="1" radius="0.8" timer="0.0" restrictElev="0" groupId="100" stopOnReach="0">
<Point lat="47.945999" long="12.204670" />
<Event id="1" type="onSuccess" >
<Msg><![CDATA[Congratulations, You made it to EDNV in one piece.]]></Msg>
</Event>
</AreaZone>
</Areas>
</Objective>
Read carefully the suggested code above. Pay attention to the "red" highlighted text.
I'll do a quick explanation of what was done.
In this example, I kept the new AreaZone definitions same as the original StaticTarget to simulate exact behavior.
Test the solution in X-Plane.
I'll do a quick explanation of what was done.
- First: I have modified the StaticTarget to AreaTarget. The lat/long/elev are not relevant in it, since it will inherit the location from AreaZone.
The attributes that passes from AreaTarget to AreaZone are: "id", "needToLand", "tolerateDistance, "TolerateElev" and "name". - Second: I defined a groupId. The groupId, will link between the AreaTarget and the AreaZone.
- Third: I added a new AreaZone (under Areas) with: type="rad, rule="enter" and groupId={same as AreaTarget groupId}.
- Fourth: [important] You should define an onSuccess event that will notify the simmer that target was achieved. Without the Event message the simmer might not notice he/she accomplished the objective or reached the target.
In this example, I kept the new AreaZone definitions same as the original StaticTarget to simulate exact behavior.
Test the solution in X-Plane.
Click on the link below to download the second example, that shows how to define an AreaTarget and link it to an AreaZone | |
File Size: | 1 kb |
File Type: | zip |
Proposed Solutions for Exercise:
Finishing Words:
The <Areas> element is one of the more important and flexible components that you should be aware of. The area helps simulate a trigger/respond mechanism in the plugin, and in future it will probably have more options embedded into it.
Hope this tutorial helped and makes it easier to understand how <Areas> element can enhance your mission. In upcoming tutorials we will return to the <Areas> and use it.
( If you find mistakes, any kind, please e-mail it to my mailbox )
Snagar