Vanilla uses a tortured system of nested libraries to manage the mission system. A large part of said said system boils down to an unweighted do_any.
We did not wish to copy that format.
Here is a small example of a multi-step mission:
Code: Select all
<cue name="MissionSignaller">
<actions>
<find_station name="$Station" space="player.sector" multiple="false" />
<signal_cue_instantly cue="DockMissionOfferCue" param="$Station" />
</actions>
</cue>
<cue name="DockMissionOfferCue" instantiate="true" namespace="this">
<conditions>
<event_cue_signalled />
</conditions>
<actions>
<set_value name="$BaseCue" exact="this" />
<create_cue_actor cue="this" actor="event.param.controlentity.{controlpost.manager}" />
<create_offer cue="DockMissionOfferCue" name="'Dock Mission (Test)'" difficulty="level.trivial" reward="500Cr" actor="event.param.controlentity.{controlpost.manager}" associated="event.param" description="'foo'" faction="faction.argon">
<briefing>
<objective step="1" action="objective.flyto" object="event.param" />
<objective step="2" action="objective.talkto" object="event.param.controlentity.{controlpost.manager}" />
</briefing>
</create_offer>
</actions>
<cues>
<cue name="DockMissionCue">
<conditions>
<event_object_signalled object="this.parent.actor" param="'accept'" />
</conditions>
<actions>
<create_mission cue="this" offercue="DockMissionOfferCue"></create_mission>
<set_objective cue="this" step="1" action="objective.flyto" object="this.parent.actor.assignedcontrolled" />
<remove_offer cue="this.parent" />
</actions>
<cues>
<cue name="DockEventListener">
<conditions>
<event_object_docked_at container="$BaseCue.actor.assignedcontrolled" />
<check_value value="event.param == player.ship" />
</conditions>
<actions>
<set_objective cue="this.parent" step="2" action="objective.talkto" object="$BaseCue.actor" />
</actions>
</cue>
<cue name="TalkEventListener">
<conditions>
<check_any>
<event_conversation_started conversation="default" actor="$BaseCue.actor" />
</check_any>
</conditions>
<actions>
<remove_mission cue="this.parent" type="completed" />
<transfer_money from="faction.argon" to="faction.player" amount="500Cr" />
</actions>
</cue>
<cue name="AbortListener">
<conditions>
<event_mission_aborted cue="this.parent" />
</conditions>
<actions>
<remove_mission cue="this.parent" type="aborted" />
<cancel_cue cue="$BaseCue" />
</actions>
</cue>
</cues>
</cue>
</cues>
</cue>
There are a few poorly expressed, but very essential patterns here.
Keeping Offers and Missions Alive:
- offer and mission cues require child cues to maintain the offer or mission, or it will just disappear when the cue completes its actions.
- we overcome this in the example by creating the mission as a child of the offer cue, and the event listeners act as children of the mission.
- each mission offer requires an actor to interact with the UI. This can be a generic cue actor, or (as in our case) an NPC involved in the mission itself; it doesn't really matter who it is. We set the NPC as the cue actor for ease of reference through the rest of the code, but this may not be required.
- event_object_signalled object="this.parent.actor" param="'accept'" comes all the way from lua. It is the signal created when you click the "Accept" button on a mission offer.
- remove_offer and remove_mission are the only way to get them out of your UI without cancelling the cues.
Some additional points to keep in mind:
Creating a Mission Group:
- add an entry to missiongroups.xml, then include group="missiongroup.GROUPIDHERE" in your create_offer
- using location on the mission offer will override the mission group
- use both the location (station, or supposedly ship?) and distance attributes on your create_offer
- the space attribute will also limit the area in which you can see an offer, but it does not create an icon on the map or at a specific station
- the offer will not automatically disappear if you fly away, and there isn't a natural timeout either; you'll have to insert additional code to make that happen
- you must transfer money to the player upon completion of the mission
- the rewardtext attribute on create_offer allows you to insert your own reward text string. Just replace the transfer_money line with add_inventory or whatever you want to do instead.
- like the mentor mission series, you can use the mission_thread stuff to make missions that pop up one after each other, but we have not explored that too deeply yet.
- create_mission can reference an offercue like we did in the example above to steal its attributes, or you can include many of the same attributes from create_offer on create_mission instead, and just give the player a mission without making them click on anything.
- remember to cancel the $BaseCue when aborting a mission, or else it doesn't actually stop listening for you to complete the objectives.