COG Verbs - Player

Notes:

Player Index

All players in a game, whether SP or MP, have an index number. Player 0 will be the host, the first player to join will be Player 1, the second will be Player 2, and so on.

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 decision screen, the engine 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. When the player finishes the level, the engine calculates the player's alignment based on total peds and peds killed. The engine 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 engine looks at when the player reaches the decision 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 verbs that manipulate these goals are SetGoalFlags() and ClearGoalFlags(). Each goal can have Goal Flags assigned to it which tell the engine how to display the goal. 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. You would use the code from the next example to set the string offset for the first level.

 SetInv(player, 99, 1000);

The GoalFlags verbs have the player as a parameter because they are 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. 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 is the number of something and most objects in JK are numbered. In SP, it's simple to get a handle on the player. You would use GetLocalPlayerThing() or or GetPlayerThing(0). But in multiplayer, the problem becomes difficult with more than one player. 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:

1) Suppose that a player has fired a raildet. And you need to find who fired it in the created handler of the raildet's template cog (which is 00_smoketrail). GetLocalPlayerThing() will not work, and there's no sourceref for the created message. Because the player who fired the raildet will be its parent, you can use GetThingParent(raildet) to return the player who fired the raildet (the sender of created will be the raildet).

2) Say you need to get the thing number of the host. GetPlayerThing() is very handy for this purpose. Simply use GetPlayerThing(0) to return the thing number of the host.

3) If you need to find which player activated a hotkey in the activated handler of the hotkey's cog. Because the local player must have activated the hotkey (you can't activate other people's hotkeys over the network), you can use GetLocalPlayerThing() to return the player who pressed the hotkey. The soureref of activated is also the player who pressed the key.

One of the most common mistakes new editors make is to assume that GetSourceRef() always returns the value of a player. The sourceref is a property of a message. GetSourceRef() will return different things depending in which handler it is run. The Messages Section lists the source and sender of each message.

  • Create:
This page was last modified 23:48, 24 March 2006.   This page has been accessed 227 times.