Robert Straughan - Capture Glory: Dwarf NPC
Snow White and... If you played the module, you will no doubt have seen Kilinar. He's a dwarf NPC that I've placed into the module to act as a henchman. He has a conversation with several scripts throughout them. Let's take a look. //Script "cave_hench1" int StartingConditional() { int iResult; iResult = GetLocalInt(OBJECT_SELF, "SPOKEN") == 0; return iResult; } This is actually the default one generated by the script editor when you press edit on the TextAppearsWhen handler in a conversation. It can also be written like this: //Example Script int StartingConditional() { if (GetLocalInt(OBJECT_SELF, "SPOKEN") == 0) return 1; return 0; } Essentially, iResult is a 1 or a 0, depending on whether the comparison statement is true or false. That value is then returned, since this is a StartingConditional script, not a void main(). Almost the only use for this kind of script is in conversations, and essentially, if a 1 is returned, then the node this is attached to will either be said by the NPC, or will be an option available to the PC. If a zero, then it won't show. What does the script do? If the local integer labelled SPOKEN is equal to one, then the script returns a one, and the line will be said. I'm using this to stop the line from being said twice. How? Read on: //Script "cave_hench4" void main() { SetLocalInt(OBJECT_SELF, "SPOKEN", 1); } By placing this script in the ActionsTaken handler of the very same conversation node, it means that the line will only show if the local integer hasn't been touched, and then immediately sets it to one to prevent the line from being said again. Later on, I do another script as follows: //Script "cave_hench2" int StartingConditional() { int iResult; iResult = GetLocalInt(OBJECT_SELF, "SPOKEN") == 1; return iResult; } This means that if I place this node above the one that checks for the same value to be set to zero, the line won't get spoken until the 'one-liner' node has been spoken. This is not necessary, but it can help when placing nodes into a specific order. At some point, Kilinar joins the player's party. This was done with the following script: //Script "cave_hench3" void main() { AddHenchman(GetPCSpeaker()); } Notice that I've made this just one line. What can we tell from this? GetPCSpeaker is an object returner like all the others that are based upon which handler you are using. It gets whatever PC is currently involved in the conversation. AddHenchman is the function which actually makes the NPC join the targetted object's party. There is actually a hidden parameter here, which if you look in the definitions, you'll find is already declared to OBJECT_SELF, which is fine given the caller of this script. //Script "cave_hench5" int StartingConditional() { int iResult; iResult = GetMaster() == GetPCSpeaker(); return iResult; } This script prevents a line being said unless the player talking to the NPC is their master. See how it does it? If you don't then you should look at the definition of the GetMaster function. Still don't understand it? GetMaster returns an object variable based on who is the master of a specified object. By default, the function uses OBJECT_SELF, so I don't need to add a parameter value to it. If the speaking NPCs master is the speaking PC, then the node shows. In case you're wondering, yes. Comparison operators can work with any kind of variable. The difference is that the operators == and != are equality tests, rather than mathematical, such as <= and >=. They are essentially EQUAL TO and NOT EQUAL TO. That does not require numeric values to be used. Really most of the dwarf's scripting is down to timing in the conversation file. I'm not even going to begin teaching you how to use conversations properly, or even that you should use it (a lot of DMs possess NPCs rather than use their own conversations). The scripting involved is simple.
Do we trust him? The dwarf's conversation leads the player to believe that he/she might not be able to trust Kilinar. As a little extra, in the OnExhausted handler of one of the encounters in the tunnel leading away from the cave, I placed the following: void main() { object oWP = GetObjectByTag("JOURNAL_POINTER"); object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oWP ); if (GetLocalInt(oPC, "NW_JOURNAL_ENTRYHenchKilinar") > 10) AddJournalQuestEntry ("HenchKilinar", 30, oPC); } Here's a useful function to know. AddJournalQuestEntry. Kilinar's conversation used the OtherActions tab to deal with the journal entries, but what if you wish to set a quest journal to a particular place without a conversation. The OnExhausted occurs when an encounter's spawned creatures have been killed off. However, because the encounter is not physically represented in the game, we need to use a waypoint as a reference to get the nearest player. So I've gotten the waypoint, and then the nearest creature to it which matches the criteria I specified (read the function definition if you're ever not sure of what values to use). Another useful piece of information about journal entries is that they are stored on a player as a local integer, labelled NW_JOURNAL_ENTRY and then with the quest tag given to it in the journal editor added onto the end. So the if statement compares the current state of the player's path in the HenchKilinar quest, and if it is greater than 10 (which I happen to know means that Kilinar has joined the player as a henchman) then this will change the player's journal entry accordingly. It is a matter of judgement as to whether you should use AddJournalQuestEntry, or SetLocalInt, in order to change a player's current position in a quest.
What have I just done? Well, you've learned how to use scripts in conjunction with a conversation, and the use of the StartingConditional scripts. You've also seen how to manipulate the journal through use of scripts. This was a pretty simple bunch of scripts, but you should be sure you've read the box before moving on. Try making an NPC of your own, and making a conversation to add or remove them from the player's party.
Tasks Create a conversation which presents options to the player that allow him/her to make an ability check against any ability to gain an NPC as a henchman. The check is made against the NPCs ability check. To make this more interesting, you could also remove any ability check from the conversation that the player would be unable to pass given their score and the target DC of the check. For something even more interesting, try making it so that the player can only make an attempt at each ability check once.
Hint
|
|
||
Screenshots |
|||
author: Robert Straughan, editors: Charles Feduke, Mistress, contributor: Ken Cotterill