Notes on Player Verbs


Player Index

All players in a game, whether SP or MP, have an index number. The following table shows how index numbers are assigned.

Index Number Assignment
NumberPlayer
0Host or SP player.
1First player to join.
2Second joiner
3Third joiner
etcetc

GetPlayerNum() takes the player's thing number and returns his index number. GetPlayerThing() takes the index number and returns the thing number of a player.

Player's Alignment

Until the SP player reaches a level of type DECIDE in an episode, he won't have made the choice between the light and dark sides. When the player reaches the desicion screen, the exe looks at the player's alignment bin (#75) to determine if the player has been good or bad in the levels.

If the player has been bad (killed a lot of civvies and chosen dark powers), he will be "seduced by the dark side" and go the the appropriate dark side levels (as defined in the episode.jk of the episode).

If the player has been good to civvies and chosen light powers, he'll go to the light side - and play the light side levels. jkGetChoice() returns 0 before the DECIDE level, and afterwards returns 1 if the player joins the light side, or 2 if he joins the dark side.

When a pedestrian is created in the game, bin 73 (peds_total) is upped one. And when one of these peds dies, bin 72 (peds_killed) is incremented. Now when the player finishes the level, the exe calculates the player's alignment based on total peds and peds killed. The exe then stores this alignment value in bin 75.

If the alignment is positive, the player favors the light side; if the alignment value is negative the player favors the dark side. This alignment value is what the exe looks at when the player reaches the desicion screen (the DECIDE level).

Goals and their Flags

Goals, also called objectives, serve no purpose in gameplay except to be displayed in the objectives window. The cog verbs that manipulate these goals are SetGoalFlags() and ClearGoalFlags(). Each goal can have Goal Flags assigned to it which tell the exe how to display the goal. Be sure to read the Goal Flags document for more information on Goal Flags. Goals numbers start at zero, so the first goal has a number of 0 and is called goal 0.

In the Episode's .gob file, there is a misc folder that contains cogstrings.uni. Among other things, cogstrings contains the text to be displayed for each level's goals. A typical goal description in cogstrings looks like this:

"GOAL_01000"  0  "Find 8t88 before he escapes with your father's data disc."   # Goal 0

Goals numbers must begin at the string offset of a level - it is 1000 in the example. By convention, the first level in an Episode has a string offset of 1000, the second level has 2000, the third 3000, etc. If there were another goal in the above example, it would have a number of 1001, and the next goal would have 1002, and so on. Remember to update the message count at the top of cogstrings when you add new goals.

The string offset of a level is stored in bin 99 of the items.dat. So you would use SetInv(player, 99, 1000); to set the string offset for the first level.

You may wonder why the GoalFlags verbs have the player as a parameter. At first, it seems that goals belong more to the level than the player. But the truth is that the GoalFlags verbs are only setting inventory bins. They need the player's number to access his inventory. Bins 100 to 115 contain the flags that the goals are to be displayed with. And yes, you can use regular inventory verbs (like SetInv()) with these bins. Just remember that you're working with hexadecimal numbers.

Note that there is no way to retrieve the Goal Flags of a goal with the GoalFlags verbs. But you can use GetInv() to retrieve these flags:

flags=GetInv(player, 100 + goal_num);

A Handle on the Player

A handle, in editing terms, is the number of something (just about everything is numbered). In SP, it's simple to get a handle on the player; use GetLocalPlayerThing() or or GetPlayerThing(0). But in multiplayer, when there's more than one player, the problem becomes more difficult. Remember that GetLocalPlayerThing(), when run on different machines, will return the different local players; this is often forgotten and is a common multiplayer bug.

To get the value of the player that you want, you'll have to decide how he relates to the situation. Here's a few examples:

One of the most common mistakes new editors make is to assume that GetSourceRef() returns the value of a player. The sourceref is a property of a message. GetSourceRef() will return different things depending in what message it was run. The message descriptions list the source and sender of each message.