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, November 16, 2005

Work in Progress

Today we have a script, its long and repetitive but it will do something rather joyous: it will very easily allow us to add chatter from (or even between) NPC followers, a la BG and such other games as have it. It is a work in progress due to a snag I hit, then shoved it on the back burner to work on the Pishella thing, but that is dealing with associated voice issues so its still slowly getting there. This will all be finished when the Starter Pack is re-released.

The way we are going to fire our chatter is from san_new_map. If a script is attached to this, it will fire each time the NPC changes maps (funnily enough). Usually this is done to check if the NPC is to do something specific at that map - for instance, leaving the party (Thrommel, Morgan etc) or betraying them (if you’ve never had this happen in ToEE, it only occurs in very specific circumstances, I won’t spoil it by saying when). What we are going to do is, on specific maps (the Keep itself, the wilderness map outside the Caves of Chaos and a few others - maps where the player will first off be moving for a period rather than fighting or talking to someone) a random number will be generated. If it is in the range we want (we don't need this to happen all the time, it would get very old quickly), then the nearest party member to the NPC will be examined, and the NPC will then make an appropriate comment.

Sound confusing? Well, I have done one up for a character called 'Two Swords', one of Cujo's PCs that he has graciously allowed me to use in KotB as an NPC follower. Two Swords is everything we want in a lass - skilful, voluptuous (in a toned way, of course), rough and tough etc. She likes jewelry and the furry animals that follow rangers (a bit of projection from His Dogginess perhaps?), she dislikes goody-goody Paladins and Druids babbling about balance.

IMPORTANT NOTE: The san_new_map column in ProtoEd is MISLABELLED, it is actually 2 cols to the right, labeled san_join or something.

Anyway: lets look at the script, as I said it was long and repetitive but people who like it can just copy it easily enough.

def san_new_map( attachee, triggerer ):
________randy1 = game.random_range(1,12)
________if (attachee.leader_get() != OBJ_HANDLE_NULL):
________________if (attachee.map == 5129) and randy1 >= 10:
________________________attachee.float_line(975,triggerer)
________________elif (((attachee.map == 5121) or (attachee.map == 5137)) and randy1 >=9):
________________________for obj in game.obj_list_vicinity(attachee.location,OLC_PC):
________________________________if (obj.distance_to(attachee) <= 30 and critter_is_unconscious(obj) != 1):
________________________________________if (obj.stat_level_get(stat_race) == race_halfling):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(900,triggerer)
________________________________________elif ((obj.stat_level_get(stat_race) == race_halforc) and (pc.stat_level_get( stat_gender ) == gender_male )):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(965,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_paladin) >= 1):
________________________________________________attachee.float_line(990,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_sorcerer) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(930,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_bard) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(945,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_cleric) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(925,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_barbarian) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(950,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_monk) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(935,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_ranger) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(970,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_druid) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(920,triggerer)
________________________________________elif (obj.stat_level_get(stat_level_rogue) >= 1):
________________________________________________attachee.turn_towards(obj)
________________________________________________attachee.float_line(955,triggerer)
________return RUN_DEFAULT

Crikey, thats hard to read like that! O well, lets hack our way through it anyways.

First off, we generate a random number between 1 and 12. We call it 'randy1'.

Next we make a quick check to see if we are entering the pub (map 5129). If we are, and randy1 is more than 10, then Two Swords makes a quip about how its good to be back at the pub.

If we are at map 5121 (the main Keep) or 5137 (the front gate) and Randy1 is more than 9, then we have the room and opportunity to make a comment.

So, now we check the nearest party member. If it is (in no particular order):

a druid
a paladin
a barbarian
a fighter
a thief
a halfling
a male half-orc
a ranger
a monk
a sorcerer

then she makes a comment (these will later be expanded to include animal companions and wizards carrying more than 3 scrolls). If not, or if none of these are nearby (she is surrounded by wizards with no scrolls and female half-orcs) then she may make another comment, again randomly determined:

on the party alignment
on her jewelry situation.

Haven't done that bit yet. The alignment one is obvious enough, and will later be expanded to include reputations: she will respond to what they party are actually doing, not just the alignment. The jewellery one will depend on what she has in certain slots (the worn necklace and worn rings slots). If she has some expensive jewellery (established by using the get command to find the value of the item) or magical items (established by using get to find the magical flag), she will purr about it. If she has some cheap crap, she will complain about it, and if she has nothing, she will make it clear to nearby male party members they are falling down on the job.

Simple, eh?

Ok it is long and annoying but it can be copied easily enough and the arguments can be changed. So by all means use it for a new NPC! Of course, for NPCs who join in pairs (like Turuko and Kobort), or who run into other NPCs they know of or would react to in some way (like Taki and Ashrem, or Otis and Elmo), some of these lines can trigger butt-ins and exchanges (again, a la some of the stuff in BG). The hardest part will be getting voice actors: without voices to accompany the floatlines, it really doesn't work at all.

Now, other than the expansions for other comments, what does this work in progress still have to do? I have to come up with a way to delay all this til the NPC is a few seconds into the map. This will allow the party to break up a bit (otherwise the NPC will ALWAYS comment to the same character, unless u change the party order - that gets old quickly). Of course, it will only be if the NPCs are free to chat and not in combat ;-). The time interval will differ for each NPC: by changing the amount of time each, erm, time something fires, even if more than one NPC gets lucky with randy1, their comments will fire at different times, rather than talking over the top of each other. I have tried to implement this using the add_time thing but have had no luck getting event the simplest script to fire from it (despite having used this successfully in the past in DH for Gwenno's reward - well, sorta successfully ;-)) Back to the drawing board!

Now, what exactly are Two Swords comments? You'll have to wait and see 8^P

Subsequent update: I fixed the timed chatter thing, the problem was I added a san chatter() thing but didn't realise I needed to define it with args (attachee, triggerer) because I am a n00b. More info HERE and HERE.

Also, to go straight to the next tutorial, click HERE.

4 Comments:

At 1:02 pm, Anonymous Anonymous said...

uh homie,
amatur voc actein sux, dun even tink bout it, voc onli gud if pro qalitay!
no voc is bettar dan nub voc!
u can paly soem niec muzak instaed.

 
At 1:17 pm, Anonymous Anonymous said...

oh n 1 mo tip (cuz i feel real smarsty 2dae)
bout dat delay stuff. delay tiem 2 rerange partay ordar 2 talk 2 diffriant soundz not gud. u dun need 2 delay i tink. wut u need 2 do is not delay by randem but pick teh dielog victim frum partay ordar list by randem! dis way da chick is gunna talk to differiant playa eech tiem! n also if u gunna haev mo dan 1 talkin chix, u can pick which is gunna do talkin by randem 2!

 
At 12:01 pm, Blogger ShiningTed said...

Yeah, actually I may well be able to do that... worth looking into.

And I agree no voice is better than n00b voices: luckily I have some acting friends if I can ever track them down.

 
At 4:16 pm, Anonymous Anonymous said...

debt consolidation

 

Post a Comment

<< Home