Ted's RPG Rant

A place to rant about RPG games, particularly the Temple of Elemental Evil. Co8 members get a free cookie for stopping by. Thats ONE cookie each, no seconds.

Wednesday, October 05, 2005

Adding NPC followers

This blog is being written at work on my lappie! Amazing the things u can achieve once the li'l buggers are in bed :-)

Today, persuant to something I said at Co8, I am going to explain how to add an NPC as a follower. Its ridiculously simple: you just add the following command:

pc.follower_add(npc)

But what sort of tutor would I be if I just told you that? So lets set the scene: first of all, go to HERE and download the zip file. It includes new .dlg and .py files for Pishella to make her an NPC follower. Note that the .py file is just to fiddle her dialogue so that when you talk to her in the party she reacts differently than when you just chat to her in Burne's tower, but otherwise you don't need any additional script to get that follower_add command to work - it really is that easy. You don't have to install this btw, I won't be offended ;-) But stick it somewhere you can look at the files.

Ok, where does it all begin? Well, go to line 30. This is where she would normally say, "Nice to see you again, I am busy" and that would be that. But, I have added lines 34 and 35 asking her if she would like to join. Then, it jumps off to line 200: she normally ends in the 170's (and some of that is added for the Burne's puzzles quest) so going to line 200 gives us plenty of room to add whatever we like.

200 is her agreeing to sign up: we then have to address the issue of the party being full. Hey, look at that! I put the first conditional command, in line 201, in the wrong place! It should be in the middle, not at the end (in the usual place for conidiotnal arguments we have discussed before). The last brackets are for executing commands: the game will ignore not pc.follower_atmax() here because it doesn't execute. But the game may NOT ignore the subsequent atempt to add a follower, and if you follow this line with a full party, you will probably get a crash! (Based on what happens when NPCs such as Fruella push their way into the party when it is at max and the player is using PC Count Fiddler so the game doesn't realise it is at max). So if you do want to use this script, change that ;-)

The conditionals that fire if the party is at max or isn't are of course there to prevent such a disaster. That is really the only essential thing you need: that and a subsequent script to remove the character. We'll look at that in a minute. But first...

Just to add a bit of variety and spice (and because Cujo asked me to when I wrote this thing for him) I have added a thing whereby Burne charges you 50gp to hire her. I also added some dialogue such that Pishella explains this as Burne being a greedy sod - I think this is consistent with the image of him in the game, what with the amount of treasure he demands (I mean yes the guy is high level but he has a dragon hoard dagnabit! Well, he reputedly has a dragon hoard... never believed a word of that. Hey, why doesn't Burne have a beard like in the module? Never understand meaningless changes like that... like at the Argonath when they have one of the figures carrying a sword instead of an axe, the book CLEARLY says they have axes, why change it? Ok ok we are slightly off topic...

So, another new command to learn. In fact a couple, since we have to get the players to pay, AND we have to make sure they have the money! So...

pc.money_get() < 5000
pc.money_get() >= 5000


Simple, isn't it? You've probably noticed the get command is often used to find out the values of this or that, stats or flags or whatever. It just gets the value without changing it or anything.

So, if the party has the money, they have to hand it over. To do that we use:

pc.money_adj(-5000)

the excessively bright among you will have figured out that this command will also ADD money to the party - just leave out the minus sign! In fact it adds either way, just here it is 'adding' negative 5000.

SO what is the currency? Well, all currency transactions in the game, be they getting money or adjusting as here or the value of items recorded in the protos.tab, its always in COPPER pieces. So here, 5000 copper is 500 silver is the 50gp Burne wants. Its that simple. NOte we are not transferring the money to Burne, we are just knocking it off... we could give it to him, but transfering items is the topic for next time :-) And this way is easier ;-).

Speaking of easier, I couldn't be bothered doing a Burne butt-in where he himself asks for the money. If you really want to enhance the experience, though, you can do that yourself because we discussed this last time. And, you can even voice it, becuase he mentions 50gp somewhere! Its the amount he pays you for exposing Jayfie for memory. Add that - Burne butting in to ask for 50gp to let you hire Pishella, in the actors actual voice - and you would have an experience that you would swear blind came straight out of original game :-). Meh, thats what I'm here for.

What next? Well, there is the recruit line itself: we saw that at the beginning so I won't repeat myself (its right there in line 230) but will simply point out it fires from the NPC's command thing (does it work from the PC's? Does it matter? It works from the NPC's so use that!) Also, she joins the party without ending the conversation. She will leave that way too: thats how Liv did the 'equipment fix' thingy whereby she prevented NPCs selling stuff you gave them: in the middle of the conversation, unnoticed by the player (going on in the .py scripts) she would boot the NPC out then instantly rehire him or her. Thus, whatever they had at the time would become their 'starting equipment' that they refuse to give up. Ingenious solution! But it meant the NPC went to the end of the party (not a problem) and forget all their spells (a problem) so it was not perfect and some people have moved on to other solutions, such as Drifter's masterful .dll hack.

That everything? Well, what about the dialogue? We have fiddled the san_dialog bit of the .py script so that when you talk to her in the party, she will have different dialogue than when she is standing around in Burne's tower. Lets take a quick look at it:

def san_dialog( attachee, triggerer ):
________attachee.turn_towards(triggerer)
________if (attachee.has_met(triggerer)):
________________if (attachee.leader_get() == OBJ_HANDLE_NULL):
________________________triggerer.begin_dialog( attachee, 1 )
________________triggerer.begin_dialog( attachee, 250 )
________else:
________________triggerer.begin_dialog( attachee, 1 )
________return SKIP_DEFAULT

I just nicked this one from Elmo and copied it over the existing one. For one thing, it now turns her to face you :-)

Ok, the thing (attachee.leader_get() == OBJ_HANDLE_NULL) is something you will see regularly with NPC followers. What it does is it 'gets' the condition of whether the NPC is in the party, expressed as whether they acknowledge the party leader. Don't ask me why or what that means, just take my word for it, thats how you test if the NPC is in the party or not. It tests whether this condition returns NULL, that is, if the condition is NOT present: again with the negatives! So, if it is true, if 'getting' the condition of the NPC acknowledging the leader IS null, that is, returns false - ie the NPC is NOT in the party - then it will go to line 1 as usual, and the game can then use the existing 'npc_has_met' scripts to handle where to send the dialogue (since if they have not met they go to 1 also in this script). Its a pain working to get a logical NOT using '==' rather than '!=', but take a moment to understand this since some scripts will do it the oppsoite way and have '!=' to indicate that the NPC IS in the party.

If she doesn't return a null - if she IS in the party - then she goes to the appropriate dialogue I have written at line 250. Its just 'I want you to leave'. If you use this script, of course feel free to flesh all this out - in fact, I recommmend it :-)

Last thing: booting her out. Firstly, you are going to need her later so we can't just leave her down the bottom of the Temple or something. So we add a condition forcing you to be on the right map: this is

npc.area != 1
npc.area == 1


Area 1 is Hommlet: it refers to the area on the world map. So this makes sure you are somewhere in Hommlet before you can boot her. We COULD do it by specific map - see, for instance Zert's .py script where he may act in certain ways when entering certain maps. There's a san_entering_map or san_map_change or something thing that can be triggered, actually we will look at that next time becuase I am going to put that to an abstract use in KotB to improve the NPC experience, but for now it is enough to know it can be done. I don't have the whole damn game with me here at work so there is only so much i can do from memory ;-). Zert's thing will have the specific python script to check what map you are on, others will too (Mickey, for instance - he knows whether to act like he is in the brewery or in Nulb by checking the map number). Technically I guess we would have to allow Pishella to leave on a number of different maps - any level of the towr - so just saying 'area 1' is so much easier. Will she go back to the Tower on map change? I don't think she has a jumppoint to do it, so I see no reason whyb she should. So let her go IN the tower if you don't want problems later, and make sure she is standing near Burne so he can find her nearby if he needs to (though I think she does the 'destroy orb' thing all by herself).

And the actual script to boot her from the party?

pc.follower_remove(npc)

Again, it fires from the NPC's line, and doesn't terminate the conversation.

Ok, thats that. Now you know how to add Pishella, you can create some NPC followers for the Green Gryphon in the Keep! Get modding.

O and if you expected Pishella to be a wizard - not today. She is a fighter! LOL! Figure that out!

0 Comments:

Post a Comment

<< Home