Jump to content

Mod NPC Villain questions


ericp07

Recommended Posts

Hello,

 

My current mod project will include a master villain, his sidekick, and a small group of their close "friends" :hm: I'm narrowing down where the showdown with my joinable NPC should occur (one of the outdoor, non-city areas) while setting up the needed files, and I'd greatly appreciate some feedback, please.

 

The master villain, an evil male Human cleric, and his sidekick, an evil male Elf fallen ranger, each have a .cre file. If I can sort out the custom item of "Claws of Malar," a pair of claw bracers meant to be used as a weapon for main- and off-hand, then the cleric with have these. Otherwise, neither villain will have any custom gear. They'll spawn in the appropriate area (via an area-spawning script) after all Beast of Malar hunting pack attacks have occurred (a limited number of randomish encounters that function as they should), plus two or three days. Each villain has a DV, no dialogue file, no override script yet, and their default script is set to WTASIGHT for each. A friend suggested DRUID10A for the cleric's default script, if memory serves, but I have yet to explore that.

 

Each villain will have a bit of dialogue with the party, then fight. I might want the fallen ranger to appear earlier, perhaps with one of the random hunting packs. I thought this might fool the party into believing he's the master villain, then have them surprised to find that he serves another. I'll need him to survive, if he engages the party in combat, so he can flee and appear with his "master" for the battle. The villains will be accompanied by some werewolves and a pair of Beasts of Malar for the fight, but the beasts are scripted to attack on sight, and I don't want any enemies to attack the party till the "villain speech" is finished.

 

Here's the area-spawning script for the encouter as I have it so far:

 

// Malarite spawning scripts

// Mehmen Jassan, Talon of Malar
IF
Global("EP#MehmeExists","AR1700",0)
THEN
RESPONSE #100
CreateCreature("EP#Mehme",[x.y],7)
SetGlobal("EP#MehmeExists","AR1700",1)
END

// Taeghan Moondown, fallen ranger, with a pair of Beasts of Malar
IF
Global("EP#TaeghExists","AR1700",0)
THEN
RESPONSE #100
CreateCreature("EP#Taegh",[x.y],7)
SetGlobal("EP#TaeghExists","AR1700",1)

CreateCreatureObjectOffScreen("EP#Taegh","EP#MABHL",0,0,0)
CreateCreatureObjectOffset("EP#MABHP","EP#MABHL",[100.100])
END

 

I'm sure this will need some adjusting. I may change the area, and I'll choose coordinates for the villains. I figured a beast could spawn off the fallen ranger, then the second one could spawn off the first. What, if anything, needs changing here?

 

I'll add the werewolf spawns later, as i want to get this much taken care of first. I don't need dialogue files for the villains, do I? Also, could I write an override script for each villain's spoken text? What else should I include in the override script? I'm hoping for efficient coding and minimal use of files wherever possible. Should I use different default scripts as well, for each villain, or perhaps the same default script for both? The fallen ranger should probably begin combat using a bow, then switch to melee weapons and engage the enemy at a strategic point (like after the werewolves and beasts are slain).

 

That's about all I have for this right now. Please share your insights and experience with me to bring this together, and feel free to critique the concept and offer any suggestions for improvement ???

 

Thanks,

Eric

Link to comment

Unless somebody talks, they don't need a dialogue (and if they're enemy, they can't be talked to manually). If they're supposed to talk, though, then they do need dialogues, yeah. But you could give them all the same dialogue and use variables to progress through the encounters if it's all just generic "Come get me!" villainly drawl (if it's really concise, you may want to consider DisplayStringHead() instead to keep the player in the fight).

 

The last two CreateCreatureObject() calls are pretty lame. If you know where your referenced object is, then pick some appropriate coordinates. You have no control over spot the engine is going to generate for "Offscreen." And using "Offset" here instead of doing your own math is just shameful. :p

 

Have separate scripts for the combat behaviors. There's no reason to do otherwise. Unless you have some need to script up the dialogues, you could probably get away with a single NumTimesTalkedTo(0) override script to fire dialogue (you may not even have to come up with one; the game has a variety of InitDlg and ShoutDlg scripts that you can assign to the chars).

 

Unless you really want to get into it, you can just use some of the generic AI scripts too (the most basic WTASIGHT (melee) and WTARSGT (ranged), or some of ToBs Cclass scripts, like CARCH20* or CFIGH30). Ranged AI probably won't be all that hot in the game anyway (you can't control what the player will do; it would be stupid to stick with bow shots if the player casts Pro from Magic Weapons and just runs past your werewolves to whack on the archer). DRUID10A won't be much of a boss battle, though. There aren't a ton of PRIES* cleric scripts, but you may find one that kicks enough to at least be somewhat challenging (the ToB caster scripts can get pretty stupid, so see if an SoA one works first, and stay far away from the GP* scripts).

Link to comment
Unless somebody talks, they don't need a dialogue (and if they're enemy, they can't be talked to manually). If they're supposed to talk, though, then they do need dialogues, yeah. But you could give them all the same dialogue and use variables to progress through the encounters if it's all just generic "Come get me!" villainly drawl (if it's really concise, you may want to consider DisplayStringHead() instead to keep the player in the fight).

 

The last two CreateCreatureObject() calls are pretty lame. If you know where your referenced object is, then pick some appropriate coordinates. You have no control over spot the engine is going to generate for "Offscreen." And using "Offset" here instead of doing your own math is just shameful. :hm:

 

Have separate scripts for the combat behaviors. There's no reason to do otherwise. Unless you have some need to script up the dialogues, you could probably get away with a single NumTimesTalkedTo(0) override script to fire dialogue (you may not even have to come up with one; the game has a variety of InitDlg and ShoutDlg scripts that you can assign to the chars).

 

Unless you really want to get into it, you can just use some of the generic AI scripts too (the most basic WTASIGHT (melee) and WTARSGT (ranged), or some of ToBs Cclass scripts, like CARCH20* or CFIGH30). Ranged AI probably won't be all that hot in the game anyway (you can't control what the player will do; it would be stupid to stick with bow shots if the player casts Pro from Magic Weapons and just runs past your werewolves to whack on the archer). DRUID10A won't be much of a boss battle, though. There aren't a ton of PRIES* cleric scripts, but you may find one that kicks enough to at least be somewhat challenging (the ToB caster scripts can get pretty stupid, so see if an SoA one works first, and stay far away from the GP* scripts).

 

All right...some great stuff here! I've made some notes, so I can research and play with these ideas.

 

Thanks! Hope to see some more feedback, especially as things progress ???

- E

Link to comment

Here's the progress so far:

 

AR2600, Tethir Wood, is the tentative area for the showdown.

 

I've set up each villain's override script to include a first meeting with the party and a second, final meeting. I'll have them make their evil, arrogant comments upon meeting up with the party in the override scripts new .d files for each (particularly directed at Hinaeariel, as she displays Mielikki's holy symbol, announcing direct opposition to Malar and his followers).

 

The Cleric's default script will tentatively be PRIES18B, while the fallen Ranger's will be WTARSGT.

 

Edit: The ranger should be able to use ranged attacks first, then switch to melee.

 

I've outfitted the fallen Ranger with gear, but haven't decided yet on how the Cleric should be geared up.

 

If these details appear reasonable, I'll carry on, and see about putting it all together, then install and test.

 

Edit: Still struggling with this, but I know it will all be fine soon enough :)

 

Happy modding,

Eric

Link to comment

Just a little note, your Ranger need not be Fallen. In my opinion, it actually makes more sense if he started out as a Ranger serving Mielikki and/or some of the Seldarine, then Fell, then entered the service of Malar, who restored his full Ranger abilities. It's only PC Rangers & Paladins that have to always be on Good behavior; non-Good NPC Paladins & Rangers work just fine.

Link to comment
Just a little note, your Ranger need not be Fallen. In my opinion, it actually makes more sense if he started out as a Ranger serving Mielikki and/or some of the Seldarine, then Fell, then entered the service of Malar, who restored his full Ranger abilities. It's only PC Rangers & Paladins that have to always be on Good behavior; non-Good NPC Paladins & Rangers work just fine.

 

I was not aware of that! Thanks, this would be fine by me, and your bit of exposition lends added believability to the ranger himself ???

 

- E

Link to comment

It appears that my villainous ranger, and the evil cleric he serves (cleric must be controlling him somehow) need override scripts, default scripts, and .d files, so I can have each do a brief verbal exchange with the party before fighting. I'd like the player (charname) to be able to participate, as well as my joinable NPC. Not sure yet whether to use an existing script for this, or if I'll have to create new ones, but I'd like to use what already exists in BGII if possible.

 

So...SHOUTDLG.BCS looks like the most likely candidate for the default script...or does it? RAYIC.BCS looks like another possibility, but I'd have to create a script based on that one and change the name where appropriate. What would be most efficient for my purposes?

 

The ranger will appear twice: first, with one of the later Beast of Malar pack spawns, as a sort of "master of the hunt," and will have to escape the encounter alive; second, appearing with the evil cleric for the final showdown with the party. All of this is conditional on EP#Hin (the joinable NPC's DV) being in party. So, each time the ranger and party meet, they'll exchange a few words before fighting, and when the party first encounters the final showdown (with ranger, cleric, and some creatures spawned and waiting for them), the cleric will deliver some sort of dramatic villainous speech (again, with response options for both the mod NPC and charname) before fighting begins.

 

Trying to figure out which files to use, and what code blocks go where, is making me dizzy ??? So, I'd very much appreciate some advice/assistance in sorting these things out.

 

Thanks!

Eric

Link to comment

Upon further review...I wrote my own scripts to use as override scripts for the villains, but have yet to test them:

 

// Taeghan's script file

// First encounter with Hinaeariel
IF
See([PC])
Global("EP#TaeghTalks","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("EP#TaeghTalks","LOCALS",1)
StartDialogueNoSet([PC])
END

// Second encounter: the showdown
IF
See([PC])
Global("EP#TaeghTalks","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("EP#TaeghTalks","LOCALS",2)
StartDialogueNoSet([PC])
END

 

And for the "boss":

 

// Mehmen's script file
// Speech before the fight

IF
See([PC])
Global("EP#MehmenTalks","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("EP#MehmenTalks","LOCALS",1)
StartDialogueNoSet([PC])
END

 

Does this look reasonable? Ranger will say something to party at the first meeting, then run away. Ranger and Cleric will both appear for the showdown. Each will have something to say, then attack.

 

I've set up a dialogue file for each villain, so they can say something, then DO ~Enemy()~ EXIT. In the ranger's case, this line appears at the end of the second talk.

 

Any thoughts?

 

Still stumbling through these things, but progressing nonetheless ???

 

Thanks,

Eric

Link to comment

Local variables are set on that specific instance of the creature. So unless you preserve the instance of this Taeghan the second talk won't work (since a new instance wouldn't have the the local variable set to 1).

 

What's wrong with shoutdlg? You can use the same script for both your guys if you want them both to start talking. Then you have Taeghan EscapeArea (or something) when he's done in the first encounter and create a new one for the second encounter.

Link to comment
Local variables are set on that specific instance of the creature. So unless you preserve the instance of this Taeghan the second talk won't work (since a new instance wouldn't have the the local variable set to 1).

 

What's wrong with shoutdlg? You can use the same script for both your guys if you want them both to start talking. Then you have Taeghan EscapeArea (or something) when he's done in the first encounter and create a new one for the second encounter.

 

After checking out some scripts, I thought the Mayor of Zombie Town's behavior is close to what I want for the ranger, so I've modified the script that I hope will give the ranger the behavior I'm looking for, Taegh.baf...with spelling correction for first name ;) :

 

// Taeghen's script file

// First encounter with Meleryn
IF
See([PC])
Global("EP#TaeghTalks","LOCALS",0)
THEN
RESPONSE #100
SetGlobal("EP#TaeghTalks","LOCALS",1)
StartDialogueNoSet([PC])
END

// Keep alive; an eye for an eye
IF
AttackedBy([ANYONE],DEFAULT)
HPLT(Myself,30)
THEN
RESPONSE #100
	RunAwayFrom(LastAttackerOf(Myself),150)
	EscapeArea()
END

IF
AttackedBy([ANYONE],DEFAULT)
THEN
RESPONSE #100
	Attack(LastAttackerOf(Myself))
END

// Final encounter: the showdown
IF
See([PC])
Global("EP#TaeghTalks","LOCALS",1)
THEN
RESPONSE #100
SetGlobal("EP#TaeghTalks","LOCALS",2)
StartDialogueNoSet([PC])
END

 

Will this do the trick? Any changes needed?

 

Thanks!

Eric

Link to comment

Maybe I'm making things too complicated here. SHOUTDLG is probably better to use as the first script to fire for both the ranger and the cleric. In both instances of the ranger spawning, and with the cleric spawning, they speak to charname and to Meleryn on sight, then their combat scripts fire. If ranger's HP drop below 30, he runs away and escapes the area during the first fight only, but all enemies fight to the death in the final showdown encounter.

 

So, I'm still considering the most efficient way to accomplish this with scripts. The more existing files I can rely on, the better :) I welcome further guidance on this!

 

Thanks,

Eric

Link to comment

Local variables are not preserved when you use EscapeArea, CreateCreature et al. He'll start talking both times because of your first script block, but the second block to initiate dialogue will never trigger and if you use local variables inside the dialogue you will run into problems.

 

You probably also want to give him a minhp item, or he's likely to die before he can escape.

Link to comment
Local variables are not preserved when you use EscapeArea, CreateCreature et al. He'll start talking both times because of your first script block, but the second block to initiate dialogue will never trigger and if you use local variables inside the dialogue you will run into problems.

 

You probably also want to give him a minhp item, or he's likely to die before he can escape.

 

Hmmm...I do want him to begin each of the two encounters by saying something (different lines each time, of course), but don't want to duplicate or miss anything.

 

Others also recommend a minhp item, like the belt Imoen has in Irenicus' dungeon. That's a good idea, because I definitely don't want him getting killed in the first encounter ???

 

Thanks!

Eric

Link to comment

Yeah, give him MinHP1 and script him to DRYAD_TELEPORT when the time is right. EscapeArea() is crap in combat (you don't want to have the party chasing him around only to have him suddenly disappear).

 

Set an area or global variable inside your dialogue, and then have the dialogue states check that variable ("EP#TheFirstCopyOfMyEnemyHasTalked","GLOBAL",0) THEN BEGIN FirstTalk SetGlobal(=1) ("EP#TheFirstCopyOfMyEnemyHasTalked","GLOBAL",1) THEN BEGIN LastTalk SetGlobal(=2). The script to start dialogue truly doesn't matter unless you need special conditions.

Link to comment
Yeah, give him MinHP1 and script him to DRYAD_TELEPORT when the time is right. EscapeArea() is crap in combat (you don't want to have the party chasing him around only to have him suddenly disappear).

 

Set an area or global variable inside your dialogue, and then have the dialogue states check that variable ("EP#TheFirstCopyOfMyEnemyHasTalked","GLOBAL",0) THEN BEGIN FirstTalk SetGlobal(=1) ("EP#TheFirstCopyOfMyEnemyHasTalked","GLOBAL",1) THEN BEGIN LastTalk SetGlobal(=2). The script to start dialogue truly doesn't matter unless you need special conditions.

 

OK, yeah, the MinHP1 item is a better choice than Imoen's belt, so I've added that, and I think I've got all the ranger's gear sorted now.

 

I added a first talk and a second talk script block to my NPC's J.d file, with the variables above, but something tells me that either 1) that's not where it goes, or 2) I also need to put something in the ranger's .d file to correspond. I'll stare at it a while longer...

 

As for the DRYAD_TELEPORT, I suppose that should go into the ranger's .baf...which I just deleted *LOL* I should probably create a new one, but not sure what all I need to put in it. Currently, his .cre is set up with WTARSGT for override script, WEREWOLF for race script (there's a reason for it), and no other script slots currently assigned.

 

Getting closer now. Please keep the enlightenment and hints coming!

 

Thanks,

Eric

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...