v1.0 - 20th May 2002 - Dalai

You can give your map objectives by placing down a special objectives actor which describes the tasks the player has to do.

You will need one objectives actor for the thieves, one for the guards and one for Thiefmatch.

A team will win if all their objectives are marked as complete, or if all members of the opposing team are killed.

If the timelimit is hit, the guards are deemed to have successfully prevented the thieves from achieving their goals and so therefore win the game.

Generic Objectives

The objectives system contains a few prescripted common objectives. These objectives include:

  • Find X amount of loot
  • Find X items
  • Escape with the above to zone X
These objectives cover most of the Thievery release maps. However, if you wish for more complicated objectives, you can script them yourself. See the section below on custom objectives.

How to set up your objectives:

  • Make sure the following .u files are loaded:
    • ThieveryLowLevel.u
    • ThieveryObjectives.u
    • ThieveryMod.u
    • ThieveryAI.u

  • Place a TObjectiveHelper somewhere on your map. This can be found under Actor->Info->TInfo->TObjectiveInfo->TObjectiveBase.

  • To make sure you don't lose this actor, you might want to bring up its properties and go to Display->DrawScale and set it to 5 or so, to make the icon larger and easily spotted.

  • Set the TeamNo for this set of objectives. Bring up the TObjectiveHelper's properties, go to TObjectiveBase and set the TeamNo. 0 for thieves, 1 for guards.

  • Fill in your objective descriptions. In the properties, under TObjectiveBase, there is an array called Objectives. This array holds the descriptions for your objectives. For each objective fill out the following:

    • ObjectiveName - a small word to identify this objective, e.g. FindLoot
    • FullDescription - the text shown to the player at the start of the game and when he brings up his objectives, e.g. Sneak into the manor house and steal 500 loot.
    • ShortDescription - a shorter version of the description (used to notify players when the objective is complete), e.g. Steal 500 loot.

  • You now need to set the conditions under which the above objectives will be marked off as complete:

    • Find X amount of loot - go to the TObjectiveHelper's properties, in the TObjective_FindLoot category. Here you will set the amount of loot required and the ObjectiveName of the objective to be ticked off when the loot is found, e.g. FindLoot. In Thieves vs Guards, this objective will add up the whole team's loot when deciding if it is complete or not.

    • Find X items - go to the TObjectiveHelper's properties, in the TObjective_FindItems category. You can have up to 16 FindItems objectives. For each you need to set the class or Tag of the items that need to be found, the number of items to find, and the ObjectiveName of the objective that will be ticked off when the items are found. If you want to make a custom pickup (e.g. the evidence on Aquatone, the relics on Theatre, the gems on Folly and Korman) check the Custom Objective Items tutorial.

    • Escape with the above to zone X - go to the TObjectiveHelper's properties, in the TObjective_Escape category. Here you will set the Tag of the escape zone, and the ObjectiveName of the objective that will be ticked off when the player escapes. The escape will only be triggered if all the required items and loot (if any) are also in the escape zone.

Guard Objectives

Typically, the listed guard objectives are just description to add flavour and advice to the map, they win by killing all the thieves or guarding up to the timelimit, not by objectives logic. Therefore, for the guards:

  • Put down a TObjectiveHelper.
  • Set its Team to 1.
  • Fill in the Full/Short Descriptions and ObjectiveName with text to help the guards, e.g. You must protect the Holy Cross of Bob, it is in the guard tower at the north.
Note, there is nothing to stop you giving guards more complex objectives, if you think it will play out well. Guards do not collect loot, however the Find Items objectives would work, as would any custom objectives (see below).

ThiefMatch Objectives

To set up the objectives for the ThiefMatch gametype, the procedure is almost identical to above, except instead of placing a TObjectiveHelper, you should place a TObjectiveHelperThiefmatch. This can be found under Actor->Info->TInfo->TObjectiveInfo->TObjectiveBase->TObjectiveBaseThiefMatch.

In ThiefMatch, each player has a copy of the objectives. The generic objectives logic will not count up the whole team's loot or items, but rather look at the individual players.

Custom Objectives: Using triggers

A handy way to make your own objectives is to use triggers. UT has a very good system of triggers, linking things up with Event and Tag, using Counters, Dispatchers, etc. You could, for example, make an objective that requires hitting a number of switches, such as in Th-Spider.

The all important actor for this is the TObjectiveChanger. This can be found under Actor->Info->TInfo->TObjectiveInfo.

  • Place a TObjectiveChanger on the map.
  • Set the TObjectiveChanger's Event to match the Tag of the target TObjectiveHelper.
  • In the TObjectiveChanger's properties, set the target ObjectiveName and new status.
When the TObjectiveChanger is triggered, it will make the above change to the target objective.

For example, you may have set up an objective with the description "Pull the bright red lever" and given it an ObjectiveName of RedLever. You would set a TObjectiveChanger with an ObjectiveName of RedLever and NewStatus of ETOS_Complete, linking the red lever to the TObjectiveChanger and the TObjectiveChanger to the TObjectiveHelper. Pulling the lever would then mark the objective off as complete.

Custom Objectives: Scripting

It is possible to script your own custom objectives, giving you freedom to think up any task you like. UScript knowledge is recommended before attempting this.

  • Find TObjectiveHelper in the actor class browser, right click on it and choose New. This makes your own TObjectiveHelper class, give it a name (such as MyHelper) and place it in package MyLevel (thus storing it in the .unr).

  • Place a MyHelper on the map.

  • Set its TeamNo, fill in the objectives descriptions, etc all as above. Use any generic objectives logic you wish to use, as normal.

  • Right click on the MyHelper on the map and choose "Edit Script".

  • Here in the script, you need to define "function ProcessObjectives()". This is called every 3 seconds and should contain the new custom logic to process your special objectives.

  • Your code should check whatever conditions you like and then call SetObjectiveComplete(ObjectiveName) to tick the objective off.

  • Remember to use team logic and counting where necessary in normal objectives, and individual player logic in ThiefMatch objectives. The TObjectiveHelperThiefMatch holds a reference to the individual player in the ThePlayer variable to help with this.

  • The TObjectiveHelpers are also passed these events ingame:
    • function Killed(pawn Killer, pawn Other, name damageType) - called whenever someone is killed.
    • function ObjectiveTakeDamage(int Damage, Pawn Victim, Pawn InstigatedBy, out Vector HitLocation, out Vector Momentum, name DamageType) - called whenever someone takes damage.

  • You can also make a team win by calling function MissionSuccess(byte TeamNo), or PlayerMissionSuccess() for ThiefMatch objectives.

  • There are many helper functions written to aid you in coding your own objectives. Take a look at the script for TObjectiveInfo, TObjectiveBase and TObjectiveHelper. Function include:

    • function final SetObjectiveIncomplete(String objname)
    • function final SetObjectiveComplete(String objname)
    • function final SetObjectiveFailed(String objname)
    • function final SetObjectiveCancelled(String objname)
    • function final bool IsObjectiveComplete(String objname)
    • function float CountTeamLootInZone(Name ZoneTag)
    • function float CountTeamItemsWithTag(name n, optional name ZoneTag)
    • function float CountTeamItemsOfClass(class C, optional name ZoneTag)
    • function float CountLootForTeam(byte TeamNo);
    • and many more...

The objectives can be pretty complicated, so if you have any questions feel free to post on our mapping forum or e-mail myself or Joel.