Objectives and the Objectives browser

From WiCWiki

Revision as of 15:17, 10 December 2007 by kowalski (Talk | contribs)
(diff) ←Older revision | Current revision (diff) | Newer revision→ (diff)
Jump to: navigation, search
  • When you finished this lesson you will have your first objective.

Fancy, right!

You can read about secondary objectives and counters in the secondary objectives chapter.


Contents

About Objectives

An objective is built by different parts in almost every file. We use the juice file to add descriptions, the camera or an image. We use the mapvars.py file to create the objectives variable. We use the client file to make the camera and the server file for the rest.

We will cover parts of the objectives here. You can read more about in the chapter about the Objective Class.

Image:Objectives_and_ObjectiveBrowser_001.jpg

Image:Objectives_and_ObjectiveBrowser_002.jpg

1: In this window the camera or the picture will be shown.

2: The objective marker.

4: A more detailed description of the objective.

3, 5 and 7 is the same text from the same place in the juice file but shown in different places. Number 7 for example is the event string that, if you like, stays on the screen during the whole objective.

6: Text which will be shown if you hover the cursor over the objective marker.


Create an Objective

As in chapter 3 when we created message boxes, there are 2 ways of creating an objective…you can use the Juicemaker tool or a text editor. To create it in the Juicemaker works the same way as with the message boxes so I’ll show you the text editor-way to make it possible for you lazy bastards out there to just copy and paste the code, if you like.


It is the same juice file as in previous chapters but, if you’ve forgot it’s located here.

wic\maps\mapname\mapname_singleplayerdata.juice


-the text editor way

If you open the juice file in a text editor it will look like this.


myPrimaryObjectives
{
  Objective
  {
  }
  “More objectives will be added here”.
}

The “Objective” part is what will become an objective. All objectives will be listed between the “myPrimaryObjectives” curly brackets.

The first thing we will do is to give the objective a name. This name is what you will use to call it from the python code later. You write the name next to “Objective”, in this example we’ll use the name “Village”

myPrimaryObjectives
{
  Objective Village
  {
  }
}

There are 7 variables which values you can change when creating a message box. All of them are listed between the “Objective” curly brackets. If you don’t have a value for the variable for example, you don’t have a camera, you should write”<empty>” instead.

Objective Village
{
  myDescription
  myLongDescription 
  myOptionalImage
  myDontShowInPOLFlag 0
  myOnClickPythonClientFunction 
  myOnClickPythonServerFunction <empty>
  myVisualisationText 
}

If you open the juice file in the Juicemaker you will find the Objectives under mySinglePlayerData -> mySinglePlayerMissionStats -> myPrimaryObjectives

Objectives variables

myDescription. myLongDescription. myOptionalImage. myDontShowInPOLFlag. myOnClickPythonClientFunction. myOnClickPythonServerFunction myVisualisationText.

1- myDescription.

The variable myDescription contains the text that will be shown in 3 places (see picture above number 3, 5 and 7).

If you write the text in a text editor you must put the text within quotation marks, else you won’t see the text in the game.


myType "Take the commandpoint."


If you use more than 200 characters the game will crash.

Only 70 characters will be visible under the Primary Objectives (number 5 in the picture earlier).


2 – myLongDescription.

The variable myLongDescription contains text that will be shown beneath the short description in the objectives browser (number 4 in the picture earlier).

If you write the text in a text editor you must put the text within quotation marks, else you won’t see the text in the game.


myLongDescription "Take the commandpoint to complete the objective."


If you want to use new line in the long description you will have to use “\n”.


myLongDescription "Take the commandpoint\n\nto complete the objective."


3 – myOptionalImage.

The variable myOptionalImage contains a file path to an image file. The file must be an *.dds file. We usually use this when there is no reason or possibility to use a camera.

The image will be placed in the same frame as the camera (number 1 in the picture earlier).


myOptionalImage myPictures /LastStandObj.dds


In our example we will use a camera so the code should look like this.


myOptionalImage <empty>


If you use both a camera and an image the image will override the camera.


4 – myDontShowInPOLFlag.

The myDontShowInPOLFlag variable contains either a 0 or a 1. It is 0 by default. It affects the objectives eventstring and the default value makes the eventstring stay on the screen for as long as the objective is active. If you change it to a 1 the eventstring will be shown but won’t stay on the screen. (See number 7 in the previous picture).


myDontShowInPOLFlag 0


5 – myOnClickPythonClientFunction.

The variable myOnClickPythonClientFunction can call any client function. We use this variable to call the objectives camera. The cameras name must be the same as in the client file. Objective cameras will be covered in the chapter objective cams.

The camera will be shown in the frame under the “Objective details” (number 1 in the picture earlier). Every time you open the browser or click on another objective (that is still active) in the objectives list in the browser the marked objectives camera will start from the beginning.


myOnClickPythonClientFunction ObjCamVillage


If you will try to start the game and take a look at the objectives browser before you make a camera, simply write <empty> instead of ObjCamVillage.


6– myOnClickPythonServerFunction.

This variable works as the myOnClickPythonClientFunction variable but on the server side. We never use this variable because we only use cameras from the client side.


myOnClickPythonServerFunction <empty>


7 – myVisualisationText.

The variable myVisualisationText works as the myDescription variable but will be shown if you hover the cursor over the objective marker (number 6 in the picture earlier). We usually use the same text as in “myDescription” to avoid confusion.


myVisualisationText "Take the commandpoint."

The first, nice and good looking, cute little objective.

If you followed this example you should have a message box that looks like this in a text editor.

Objective Village
{
  myDescription "Take the commandpoint."
  myLongDescription "Take the commandpoint to complete the objective."
  myOptionalImage <empty>
  myDontShowInPOLFlag 0
  myOnClickPythonClientFunction ObjCamVillage
  myOnClickPythonServerFunction <empty>
  myVisualisationText "Take the commandpoint."
}

Objectives in Python

The first thing you have to do is to add a variable in the mapvars.py file. If you don’t save it in a global variable it won’t be remembered if you save and load the game.

We usually use the prefix “obj” but it’s not necessary. If you use this example it should look like this.

objVillage = None

When you have your variable you have to create an objective object. We do that in the server.py files often in the EventNameSetup(): functions (we covered them in the Before we star chapter and in the chapter about python files) but the only important thing is that the objective object is created before we use it else the game will crash.

In this case it will look like this.

mapvars.objVillage = Objective( 'Village', 'CP_Village', 'primary' )

If we saved the objectives variable in the mapvars.py file we have to write “mapvars.” before the variable name.


-The first parameter is the name you gave the objective in the juice file.

-The second parameter is where the objective marker will be placed. It can be set to ‘None’ if you don’t want or need an objectives marker or if you want to have multiple markers.

-The third parameter states the objectives level. It can be either a primary or a secondary objective. In the above case it is set to a primary objective.


We will return to objective variables later, it looks a bit different if it is a secondary objective and if you want a counter on it, but at the moment you won’t need more than this.


The next step is to add the objective to make it active and visible. If you use the action queue it will look like this.


queVillageStart.AddObjective( mapvars.objVillage )


If you don’t use the queue you add an objective like this.


mapvars.objVillage.AddObjective()


Now you can start the game and should see your first objective.


You can, as with message boxes trigger an objective on reactions such as closed message boxes, when the player enters an area, timers etc.

How to fail or complete objectives

Objectives you can’t fail or complete are pretty meaningless. So let’s add some fail and complete conditions.

As in the example in the action queue chapter it is handy to have one queue for if the objective fails and one if it is completed.

Objectives often fail or completes on reactions like if a command point is fortified or that all enemies in a group are dead.


Whether or not you want to use the action queue we will trigger the objectives on reactions. In this case we’ll use almost the same code as in the action queue-example.


queVillageStart = ActionQueue( 'queVillageStart' ) 
queVillageStart.AddObjective( mapvars.objVillage )
queVillageStart.Execute( )

queVillageComplete = ActionQueue( 'queVillageComplete' )
queVillageComplete.AddMessageBox( 'e1_2', 102 )
queVillageComplete.AddObjectiveCompleted( mapvars.objVillage )
RE_OnCommandPointTaken( 'CP_Village', TEAM_NATO, Action( queVillageComplete.Execute ) )

queVillageFail = ActionQueue( 'queVillageFail' )
queVillageFail.AddObjectiveFailed( mapvars.objVillage ) 
queVillageFail.AddFunction( wicg.EndGame, TEAM_USSR )
RE_OnEmptyPlatoon( mapvars.pltPlayer, Action( queVillageFail.Execute ) )


In this test map the player don’t have the reinforcements menu from the beginning so to fail on when all the players units are dead is a good thing, you won’t be able to proceed without units. (And you might not have enemy units yet and if you don’t you can try to fail the mission by disbanding your units instead. If you don’t know how check the WiC’s booklet).


This is the code if you still don’t want to use the queues.


RE_OnEmptyPlatoon( mapvars.pltPlayer, Action( mapvars.objVillage.Failed ) )

RE_OnCommandPointTaken( 'CP_Village', TEAM_NATO, Action( mapvars.objVillage.Completed ) )


Now you should have an objective that you can fail and complete, go ahead, start the game and try it out!

Update Objective

To update an objective is sometimes very neat for example if you first want the player to capture a command point and after that hold it during an attack or until the fortifications are done you can split the objective in two parts.


Update objectives in the juice file

First of all you must have two objectives in the mapname_singleplayerdata.juice. We can take a look at the event Mansion from the test map. There are two different objectives in the europeTest_singleplayerdata.juice regarding the mansion, the first is ‘TakeMansion’ and the second is ‘HoldMansion’

Objective TakeMansion
{
    myDescription "Secure the Mansion."
    myLongDescription "Secure the Mansion.\n\nTo complete this objective you must capture the Mansion and build fortifications to level 2."
    myOptionalImage <empty>
    myDontShowInPOLFlag 0
    myOnClickPythonClientFunction ObjCamMansion
    myOnClickPythonServerFunction <empty>
    myVisualisationText "Secure the Mansion."
}
Objective HoldMansion
{
    myDescription "Defend the Mansion."
    myLongDescription "Defend the Mansion.\n\nTo complete this objective you must hold the Mansion until ordered to do otherwise.\n\nYou will fail the mission if the Russians manage to capture the position."
    myOptionalImage <empty>
    myDontShowInPOLFlag 0
    myOnClickPythonClientFunction ObjCamMansion
    myOnClickPythonServerFunction <empty>
    myVisualisationText "Defend the Mansion."
}

Both will be used but the first one you use will be the ‘main’ objective, the one you can complete or fail. The order in the juice file doesn’t matter.

Update objectives in python

The one you want as ‘main’ objective is the only one you need to have as an objective object. First create the variable in mapvars.py file as before.

objMansion = None

Then create the objective object in the server.py file like this. As before put it in a suitable function.

mapvars.objMansion = Objective( 'TakeMansion', 'CP_Mansion', 'primary' )

In this example we will update the objective when the player has build fortifications to level 2. The important and different piece of code is the line ‘queMansionUpdate.AddObjectiveUpdate( mapvars.objMansion, 'HoldMansion' )’.

In this line we will update the objective to the ‘HoldMansion’ objective from the europeTest_singleplayerdata.juice. We use the action queue method ‘AddObjectiveUpdate’.

- The first parameter is which objective we want to update.

- The second parameter is the new objective; the name is from the juice file.

# When the player has built lvl 2 fortifications on the mansion cp update the objective.
queMansionUpdate = ActionQueue( 'queMansionUpdate' )
queMansionUpdate.AddObjectiveUpdate( mapvars.objMansion, 'HoldMansion' )

# Run the update queue when Nato built lvl 2 fortification on the mansion.
RE_OnCommandPointFortifiedEx( [ 'PP_Mansion1', 'PP_Mansion2' ], TEAM_NATO, 2, Action( queMansionUpdate.Execute ), False, True )  


Everything else works the same as with ‘normal’ objectives. The only thing is that when you want to fail or complete the updated objective you’ll use the ‘main’ objective like this. But to execute the queue works the same way as with ‘normal’ objectives.

queMansionComplete = ActionQueue( 'queMansionComplete' )
queMansionComplete.AddObjectiveCompleted( mapvars.objMansion )

Appendix

Changed files in this chapter:

Server.py

Mapvars.py

europeTest_singleplayerdata.juice


Changes in the server.py file.

def VillageSetup( aKickStart = False ):    
    DebugMessage( "VillageSetup::" )

    # create the Village objective object.
    mapvars.objVillage = Objective( 'Village', 'CP_Village', 'primary' )

def VillageStart( ):
    [More code here.]

    queVillageStart = ActionQueue( 'queVillageStart' )
    queVillageStart.AddObjective( mapvars.objVillage )
    queVillageStart.AddFunction( PostEvent, 'RescueArtyStart' )

    [More code here.]          

    queVillageFail = ActionQueue( 'queVillageFail' )
    queVillageFail.AddObjectiveFailed( mapvars.objVillage ) 
    queVillageFail.AddFunction( wicg.EndGame, TEAM_USSR )

    [More code here.]          

    queVillageComplete.AddMessageBox( 'e1_2', 102 )
    queVillageComplete.AddObjectiveCompleted( mapvars.objVillage )
    queVillageComplete.AddFunction( VillageEnd )

Changes in the mapvars.py file.

##---------------------------------------------------------------

#---------------------------  Village ---------------------------

objVillage = None

[More variable here.]

Changes in the europeTest_singleplayerdata.juice file.

If you open europeTest.juice in the ‘JuiceMaker’ tool you will find myPrimaryObjectives under mySinglePlayerData -> mySinglePlayerMissionStats -> myPrimaryObjectives.

myPrimaryObjectives
{
    Objective Village
    {
        myDescription "Take the commandpoint."
        myLongDescription "Take the commandpoint to complete the objective."
        myOptionalImage <empty>
        myDontShowInPOLFlag 0
        myOnClickPythonClientFunction ObjCamVillage
        myOnClickPythonServerFunction <empty>
        myVisualisationText "Take the commandpoint."
     }
}


Chapter 7: Action Queue < > Chapter 9: Drop Zones and the Reinforcements Menu
Personal tools
User Created Content