Thursday, March 8, 2007

Riddle Door!

The next stage of the adventure requires the PC's to attempt to pass a riddle door. I'm sure everyone who has any experience in the fantasy world understands the concept - a door is locked, you have to answer X number of riddles to unlock it. In the original campaign, on which this module is based, I allowed the players to figure out the riddles on their own. They varied in success, but in all honesty kicked my (carefully-chosen) riddles' ass. Maybe I had smart friends, maybe I picked riddles that were too easy...either way, I figured to make it a little more difficult in the module.

And how, you might ask? Well, I set the riddles' difficulties according to the players' Wisdom attributes. The first riddle has a threshold of 14, the second 16, and the third 18. If the player's Wisdom meets these thresholds, then they have the answer available to them in the conversation. If not, then they cannot solve the riddles. Okay, so maybe that's a bit harsh (understandably), so I created an item called a "Riddle Book" that will be available to purchase in town that allows PCs to bypass the wisdom checks in order to move forward (I'm nothing if not a forgiving DM...sometimes).

I had a little bit of trouble translating the exact desctiption of the door from the campaign as I designed it into a NWN2 module. The exact description, as I originally wrote it was:

"The keyhole is located in what appears to be the mouth of a demon, and the eyes glow a dim, eerie red. Upon inserting the key, the door animates, the eyes glowing more intently as it swallows the key. It then begins speaking..."

So there's no door that fits that description (and as I said before, I'm no 3D modeler)...so I used the closest thing I could find - the Illefarn door, with some lighting added for effect. And after playing with some of the effects, red just didn't look "right", so I settled on blue for the "glow" effect...



Overall, I'm very happy with the visual effect - it pulses from a white light to a blue light, which is placed behind the door, but leaks out around it. A very cool effect that (unfortunately) you can't really grasp just from the screenshot.

So how does the riddle door work? Well, first of all it's locked, so if the PC's encounter the door without the proper key, they just get a quick cutscene saying "The strange door glows an eerie blue"...

Once they have the correct key, the real fun begins. The door has a custom script on it (assigned to the OnFailToOpen event -- door set to Locked, Plot, no required Key, but Open Lock DC of 99) that I created, called "mod_talking_door" which simply triggers the conversation "mod_goblincave_strangedoor" set in the "conversation" property. This conversation checks to see whether the PC has the key, and has additional conditionals to determine whether the PC has interacted with the door before, whether there are any remaining riddles to be answered, and whether the door should be open:


As you can tell, there are a lot of conditionals and actions involved in this conversation. The general idea is that each of the three riddles have their own "state" in the local int "iRiddles". If the PC hasn't answered any, and hasn't interacted with the door previously, this value is zero. If the PC has interacted but not answered any riddles, the value is 1. If the PC has interacted, and answered 1, 2, or 3 of the riddles correctly, the values are 2, 3, or 4, respectively. If the value is 4, then the door simply opens (assuming it somehow gets closed).

As commented on before, the riddle nodes are in reverse order (remember that conversation nodes trigger on the first node that has a TRUE conditional, and ignores the rest). So we start with the end state, iRiddle = 4, where the door simply opens. We then check whether iRiddle > 0, and if so fire off the second-interaction node, which also then checks whether none, 1, or 2 of the riddles are already answered. Next we check to see if the PC has the "Strange Key", and if so we initiate the riddle dialogue. Finally, we have the generic, no key and no prior interaction "teaser" node.

Also, you'll notice that there's an action called "mod_004_riddle_effects()" with the optional parameter of "1", "2", or "3". This is where the fun begins...each of the riddles has an effect that hints at the answer to that riddle. The first has a blindness effect associated with it, the second has a Stinking Cloud effect (downgraded from the CloudKill effect in the original campaign), and the last riddle has a Summon Skeletons effect associated with it.


// Function wrapper for the Stinking Cloud effect.
// Requires a creature in an inaccessible area to issue AssignCommand to.
// Usage: AssignCommand(oPlaceHolder,CreateCloudAOE(oPC));
void CreateCloudAOE(object oTarget) {
float fDuration = IntToFloat(d6()*6);
effect eAOE = EffectAreaOfEffect(AOE_PER_FOGSTINK);
location lLocation = GetLocation(oTarget);
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY, eAOE, lLocation, fDuration);
}
void main (int iAction=2) {
// This script defines the actions taken during the "Riddle Door" interaction.
// 1 = Blindness cast on PC Speaker.
// 2 = Cloudkill cast on location of PC Speaker.
// 3 = 1d4 skeletons summoned on waypoint "mod_001_wp_skspawn".

if (iAction <> 3) return;
object oPC = GetPCSpeaker();
if (GetIsPC(oPC) == FALSE) {
return;
}
if (iAction == 1) {
// FloatingTextStringOnCreature("Blindness Effect",oPC,FALSE,10.0);
effect eBlindVFX = EffectVisualEffect(VFX_DUR_SPELL_BLIND_DEAF,FALSE);
effect eBlind = EffectBlindness();
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBlindVFX,oPC);
ApplyEffectToObject(DURATION_TYPE_TEMPORARY,eBlind,oPC,120.0);
}
else if (iAction == 2) {
// FloatingTextStringOnCreature("Stinking Cloud Effect",oPC,FALSE,10.0);
object oPlaceHolder = GetObjectByTag("mod_004_c_StinkCloud");
AssignCommand(oPlaceHolder,CreateCloudAOE(oPC));
}
else if (iAction == 3) {
// FloatingTextStringOnCreature("Skeleton Summoning",oPC,FALSE,10.0);
effect eSkeletonSpawn = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD,FALSE);
location lSpawn = GetLocation(GetObjectByTag("mod_001_wp_skspawn"));
int iSpawn =0;
ApplyEffectAtLocation(DURATION_TYPE_TEMPORARY,eSkeletonSpawn,lSpawn,1.5);
for (iSpawn; iSpawn <= Random(4); iSpawn++) {
CreateObject(OBJECT_TYPE_CREATURE,"mod_c_skeleton",lSpawn,FALSE);
}
}
}


The easiest of these are the effects flagged by 1 and 3. Effect #1 simply applies a blindness effect and animation on the PC attempting to open the door. Effect #3 summons 1-4 skeletons behind the PC(s), at the mod_001_wp_skspawn waypoint. Effect #2, the Stinking Cloud, required a little more work. It appears that doors can't have actions associated with them (as long as they have zero hit points), so I had to create a placeholder creature, in a room waaaay off from the PC's location, to which I could assign the action ApplyEffectAtLocation. I recently read a post that suggested you could get around this by setting the door's Hit Point value > 0, but I haven't actually tested this out.

The fun part about this part is that if the user gets an answer wrong, they suffer some form of punishment - the first answer blinds them if incorrect, the second casts a Stinking Cloud effect on the PC's location, and the third answer summons skeletons to attack if incorrect. The boring part is, if the PC's wisdom is high enough, or they have the Riddle Book, they just pass through and open the door.

No comments: