Showing posts with label Scripting. Show all posts
Showing posts with label Scripting. Show all posts

Monday, 5 May 2008

Last try

I asked about it a several of months ago, without any luck. Now I try again one last time before giving up.

Has anyone got the SetAreaTransitionBMP Function working in NWN2?
I want to control which load screen my OnAreaTransitionClick script throws (different load screens in different situations.

This should work but doesn't. Any clue?

Code
// Name:     z_tr_area_transition_ls

#include "ginc_transition"
void main()
{
object oEnter = GetEnteringObject();
object oTarget = GetTransitionTarget(OBJECT_SELF);
SetAreaTransitionBMP(AREA_TRANSITION_CRYPT);
AttemptAreaTransition(oEnter, oTarget);
}


/A

Saturday, 8 March 2008

I did it!

Fell asleep while working with the toolset, I mean... I must have been really exhausted. Luckily my head was beside the keyboard and not on any important short-key. :)

After a two hour super-power-nap I was like the D-Cell Bunnie and gave the first part of the Maze entrance a work over. I've understood theres a few screen shot-fetishists out there so heres several shots from different angles. Tell me what you thing, because I've been troubled with what I'll do with this area for so long now. The are pretty dark, mainly because the Gamma setting in the game differs from the one in the capture software. I have lighten them a bit so you can see what's going on. And yes, I do apply some blur to remove the boring pixel-effect Things that may worth looking close at is the wooden beams and support that make the passage more fragile and under construction looking That wooden construction kit is so usefull. The wall mine lamps with electrical light (may feel unusual for Dnd:ers, but this it Zork). Notice the almost 4 meters height difference thanks to the guys of RWS.

I did one more simple little script that I thought I'd share with you. As usal nothing fancy but I think it works well. It the old autoclosing door but the delay is controlled from a variable and theres a random component to it. And theres this sound of foot steps walking up to the door, closing it and walking away. Mysteroius! :)

// Name:     z_on_open_autoclose
// Date: 2008-mars-8
// Author: Amraphael
// Backlog: Variable for Random Amount. Unlikely

void main()
{
// Put the on the Door's ON_OPEN-script
// Create a Variable FLOAT called "CloseAfter"
and give it a value in Seconds.

// This is the offset Delay before the door auto-closes.

float fDelay = GetLocalFloat(OBJECT_SELF,"CloseAfter");
// If no Variable Set, set it to 60.0 seconds
if (fDelay == 0.0) fDelay = 60.0;

// Randomize the offset by +/- 50%
int iRandom = FloatToInt(fDelay/2)+Random(FloatToInt(fDelay));
fDelay = IntToFloat(iRandom);

// Play the footsteps walking up to the dour
DelayCommand(fDelay-2.0, PlaySound("fs_stone_hard1"));
DelayCommand(fDelay-1.5, PlaySound("fs_stone_hard2"));
DelayCommand(fDelay-1.0, PlaySound("fs_stone_hard3"));
//Close the door
DelayCommand(fDelay, ActionCloseDoor(OBJECT_SELF));
// Play the footsteps walking away
DelayCommand(fDelay+1.0, PlaySound("fs_stone_hard1"));
DelayCommand(fDelay+1.5, PlaySound("fs_stone_hard2"));
DelayCommand(fDelay+2.0, PlaySound("fs_stone_hard3"));
DelayCommand(fDelay+2.3, PlaySound("fs_stone_hard2"));
DelayCommand(fDelay+2.5, PlaySound("fs_stone_hard1"));
DelayCommand(fDelay+2.9, PlaySound("fs_stone_hard3"));
}


Okay over to what you came for, the screenies!

Have a nice weekend!
/A

Monday, 14 January 2008

Boohoo, I want to sleep on the ground too!

Been a while. Lots of work at my job....

Okay, you have seen my resting on ground screen shots. Here's a little information that can help out if you want to do your own laydown sleeping animation. The resting and healing part is so Zork specific that I don't believe it's usefull for anyone else, so I skip that part. Besides, it's the easy part ;)

First thing: The animations in NWN2 is a bit more complicated than in NWN1 but in the same time more powerfull (and more easy to mess upp), but more pretty (and big trouble)... Yeah, you get it.

Second: All animations are of different lenght

Third: Animations are different depending on what gender your creature have. Female animations are slower, male are faster.

I presume that you have some experience of writing scripts for NWN1 or 2. If you don't I recommend that you start learning. It's really fun and rewarding. I have a few good links down to the left to get you started. You can also start here. I hope you get some ideas of how to use animations and can pick out a few goodies for your own module. I know that I would have jumped in joy over it when I fumbled in the dark.

First of all you need some functions to call from your script:

//This one you call to be able make a series of animation with DelayCommand
void PlayCAnim(object oObject, string sAnimation, int nLoop, float fSpeed = 1.0f)
{
PlayCustomAnimation(oObject, sAnimation, nLoop, fSpeed);
}
////////////////////////////////////////////////////////


//This one come in handy when you want to know how long a certain animation takes
float AnimationLength(object oPC, string sAnim)
{
if (GetGender(oTarget) == GENDER_FEMALE)
{
if (sAnim == "disableground") { return 5.0; }
if (sAnim == "standupb") { return 3.0; }
if (sAnim == "laydownb") { return 3.33; }
if (sAnim == "proneb") { return 2.66; }
}
else
{
if (sAnim == "disableground") { return 5.0; }
if (sAnim == "standupb") { return 2.66; }
if (sAnim == "laydownb") { return 2.33; }
if (sAnim == "proneb") { return 2.0; }
}
}
////////////////////////////////////////////////////////


//If you want to make a bedroll somewhere in the animation sequence you need to call
a function like this one*/
void CreateBedroll(object oPC)
{
string sResRef = "plc_mr_blanketwool1"; //The Blanked Placeable
object oRestbedroll = CreateObject (OBJECT_TYPE_PLACEABLE, sResRef, GetLocation(oPC));
SetLocalObject (oPC, "oBedroll", oRestbedroll); // Remember the Bedroll
}
////////////////////////////////////////////////////////


/*If you want you can use a function to call when laying down like this one and call it from within the Main() of your script You see that it uses several of the functions above to get the timing right.*/
void GetDown(object oPC)
{
SetCutsceneMode(oPC, TRUE);//Freeze the camera
float fTDg = AnimationLength(oPC, "disableground");
float fTSu = AnimationLength(oPC, "standupb") + fTDg;
float fTLd = AnimationLength(oPC, "laydownb") + fTSu;
string sSound;
if (GetGender(oPC) == GENDER_FEMALE){sSound = "as_pl_snoringf1";}
else {sSound = "as_pl_snoringm1";} //Female or Male Zzzz sound
DelayCommand(0.3, SetCommandable(FALSE, oPC)); //Imobilize the PC
PlayCustomAnimation(oPC, "disableground", 0, 1.0);
DelayCommand(fTDg/2.0, CreateBedroll(oPC));
DelayCommand(fTDg, PlayCAnim(oPC, "standup", 0, 1.0));
DelayCommand(fTSu,
PlayCAnim(oPC, "laydownb", 0, 1.0));
DelayCommand(fTLd,
PlayCAnim(oPC, "proneb", 1, 1.0));
DelayCommand(fTLd+1.0, AssignCommand(GetLocalObject (oPC, "oBedroll"),PlaySound(sSound)));
}////////////////////////////////////////////////////////


/*Here's the a function to stand up quick. Maybe the sleeper has been attack or something. It also equips the items the PC held.*/
void GetUpQuick(object oTarget)
{
float fTSu = AnimationLength(oPC, "standupb");
SetCommandable(TRUE, oPC);
SetCommandable(TRUE, oPC);
SetCutsceneMode(oPC, FALSE);
PlayCAnim(oPC, "standupb", 0, 1.0);
DelayCommand(fTSu, PlayCAnim(oPC, "idle", 1, 1.0));
DelayCommand(fTSu + 0.1, AssignCommand(oPC, ActionEquipItem(GetLocalObject (oPC, "oLeftHand"), INVENTORY_SLOT_LEFTHAND)));
DelayCommand(fTSu + 0.1, AssignCommand(oPC, ActionEquipItem(GetLocalObject (oPC, "oRightHand"), INVENTORY_SLOT_RIGHTHAND)));
DelayCommand(fTSu + 0.1, DeleteLocalObject (oPC, "oBedroll"));
DelayCommand(fTSu + 0.1, DestroyObject (GetLocalObject (oPC, "oBedroll"))); //Remove the beddroll
}
////////////////////////////////////////////////////////


//This is a full wake up cycle with picking up the bedroll. By now you're familiar with how everything works.
void GetUp(object oPC)
{
float fTSu = AnimationLength(oPC, "standupb");
float fTId = AnimationLength(oPC, "idle") + fTSu;
fTId = 2.0 + fTSu;
float fTDg = AnimationLength(oPC, "disableground") + fTId;
string sSound;
if (GetGender(oPC) == GENDER_FEMALE){sSound = "as_pl_yawningf1";} //Male of female yawn
else {sSound = "as_pl_yawningm1";}
PlayCAnim(oPC, "standupb", 0, 1.0);
DelayCommand(fTSu, PlayCAnim(oPC, "idle", 1, 1.0));
DelayCommand(fTId, PlayCAnim(oPC, "disableground", 0, 1.0));
DelayCommand(fTDg-2.0, DeleteLocalObject (oPC, "oBedroll"));
DelayCommand(fTDg-2.1, DestroyObject (GetLocalObject (oPC, "oBedroll")));
DelayCommand(fTDg, SetCommandable(TRUE, oPC));
DelayCommand(fTDg+0.1, SetCommandable(TRUE, oPC));
DelayCommand(fTDg+0.3, SetCutsceneMode(oPC, FALSE));
DelayCommand(fTDg+0.3, AssignCommand(oPC, ActionEquipItem(GetLocalObject (oPC, "oLeftHand"), INVENTORY_SLOT_LEFTHAND)));
DelayCommand(fTDg+0.3, AssignCommand(oPC, ActionEquipItem(GetLocalObject (oPC, "oRightHand"), INVENTORY_SLOT_RIGHTHAND)));
DelayCommand(fTDg +0.5, PlayCAnim(oPC, "yawn", 0));
DelayCommand(fTDg +0.7, AssignCommand(oPC, PlaySound(sSound)));
}
////////////////////////////////////////////////////////


/*Okay, now we use all our fine functions to make the PC laydown and sleep and later
wake up and pick up the blanket. In this example the script is fired with from
an items on_activated_script*/
void main()
{
object oPC = GetItemActivator();
//Remember what things the PC had in left and right hand
SetLocalObject(oPC, "oLeftHand", GetItemInSlot(INVENTORY_SLOT_LEFTHAND , oPC));
SetLocalObject(oPC, "oRightHand", GetItemInSlot(INVENTORY_SLOT_RIGHTHAND , oPC));
//Unequip it before laying down
AssignCommand(oPC, ClearAllActions());
AssignCommand(oPC, ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_LEFTHAND , oPC)));
AssignCommand(oPC, ActionUnequipItem(GetItemInSlot(INVENTORY_SLOT_RIGHTHAND , oPC)));
//Call the lay down function
DelayCommand(1.0,GetDown(oPC));
//Wait some time and wake up
DelayCommand(20.0,GetUp(oPC));
}
////////////////////////////////////////////////////////

That's about it. Now you just have to add in some enimies nearby-check and a healing loop. But that's another story... I've written this code from my memory while sitting waiting for a customer to show up to our meeting so don't be afraid if there's a compile error. I just want to share the principles.