//NPC_blacksmith
//Uncle FB
//06/2009
//Multiple location forge behavior
//Place a general waypoint at the forge tagged "WP_FORGE"
//Place a general waypoint at the anvil tagged "WP_ANVIL"
//Place a general waypoint at the bucket tagged "WP_QUENCH"
//Place an IPOINT placeable at the water level in the bucket tagged "WP_STEAM"
//Place a sound object "steamlongbursts" tagged "steamlongbursts" at the water level in your bucket
//be certain that the sound object is NOT active (SOUNDS ARE OPTIOINAL)
//Place a sound object "SmithyHammerings" taggeed "SmithyHammerings" near your anvil
//be certain that the sound object is NOT active (SOUNDS ARE OPTIONAL)
//Put this script "npc_blacksmith" in the on heartbeat slot of your blacksmith
//Make sure your blacksmith has the Martial Proficiency in feats
//
#include "ginc_item"
#include "ginc_combat"
#include "ginc_actions"
//This portion of the script controls the blacksmith one liners
//Change the int nRand to vary the frequency of speech. Currently this is
//set to 4 = 1 in 4 times speak.
//Change the test within "" in the case statements listed below the line "switch (nRand)"
//to change the one liners the blacksmith speaks
void NpcBlacksmithSpeak (int nSpeak)
{
int nRand = Random (4); //change the integer to vary the frequency of speech
{switch (nSpeak)
{
default:
break;
case 1:
{switch (nRand)
{
case 0:
{switch (Random(4))
{
case 0:
SpeakString ( "This forge isn't hot enough I need more coal");
break;
case 1:
SpeakString ( "Where did I put those tongs?");
break;
case 2:
SpeakString ( "OUCH!");
break;
case 3:
SpeakString ( "Jeez another clinker blocking the tuyere!");
break;
}
}
break;
default:
break;
}
}
}
}
}
//Action wrapper for PlayCustomAnimation to allow delay and assign
//no modification necessary
void ActionPlayCustomAnimation(object oNpc, string sAnimationName, int nLooping, float fSpeed = 1.0f)
{
PlayCustomAnimation(oNpc, sAnimationName, nLooping, fSpeed);
}
//Movement function for NPC blacksmith
//no modification necessary
void DelayJump (object oNpc, object oWp1)
{
float fDwp1 = GetDistanceToObject (oWp1);
float fDwp2 = GetFacing (oWp1);
float fFactor = GetMovementRateFactor(oNpc);
float fRateVS = (0.75 * fFactor); float fDVS = (fDwp1 / fRateVS);
float fRateS = (1.25 * fFactor); float fDS = (fDwp1 / fRateS);
float fRateN = (1.75 * fFactor); float fDN = (fDwp1 / fRateN);
float fRateF = (2.25 * fFactor); float fDF = (fDwp1 / fRateF);
float fRateVF = (2.75 * fFactor); float fDVF = (fDwp1 / fRateVF);
int nRate = GetMovementRate (oNpc);
int nLocation = GetLocalInt (oNpc, "atloc");
{switch (nLocation)
{
case 1:
break;
default:
{switch (nRate)
{
default:
break;
case 2:
ActionMoveToObject (oWp1,0,0.0);
DelayCommand (((fDVS)+0.2), ActionOrientToObject(oWp1,ORIENT_FACE_SAME_AS_TARGET));
SetLocalInt (oNpc, "ud",0);
SetLocalInt (oNpc,"atloc",1);
break;
case 3:
ActionMoveToObject (oWp1,0,0.0);
DelayCommand (((fDS)+0.2), ActionOrientToObject(oWp1,ORIENT_FACE_SAME_AS_TARGET));
SetLocalInt (oNpc, "ud",0);
SetLocalInt (oNpc,"atloc",1);
break;
case 4:
ActionMoveToObject (oWp1,0,0.0);
DelayCommand (((fDN)+0.2), ActionOrientToObject(oWp1,ORIENT_FACE_SAME_AS_TARGET));
SetLocalInt (oNpc, "ud",0);
SetLocalInt (oNpc,"atloc",1);
break;
case 5:
ActionMoveToObject (oWp1,0,0.0);
DelayCommand (((fDF)+0.2), ActionOrientToObject(oWp1,ORIENT_FACE_SAME_AS_TARGET));
SetLocalInt (oNpc, "ud",0);
SetLocalInt (oNpc,"atloc",1);
break;
case 6:
ActionMoveToObject (oWp1,0,0.0);
DelayCommand (((fDVF)+0.2), ActionOrientToObject(oWp1,ORIENT_FACE_SAME_AS_TARGET));
SetLocalInt (oNpc, "ud",0);
SetLocalInt (oNpc,"atloc",1);
break;
}
}
break;
}
}
}
//Main blacksmith function
void main ()
{
object oNpc = OBJECT_SELF;
if (IsInConversation (oNpc) == TRUE){return;}
object oWp1;
object oAnvil = GetWaypointByTag ("WP_ANVIL");
object oForge = GetWaypointByTag ("WP_FORGE");
object oQuench = GetWaypointByTag ("WP_QUENCH");
object oSoundObject = GetObjectByTag ("SteamLongBursts");
object oSoundHammer = GetObjectByTag ("SmithyHammerings");
object oEffectObject = GetObjectByTag ("WP_STEAM");
string sHammer = "nw_wblhl001";
string sSword = "nw_wswss001";
string sSword2 = "nw_wswss999";
int nSpeak = 1;
int nWPcontrol = GetLocalInt (oNpc, "control");
int nRand = Random (3)+1;
SetOrientOnDialog(oNpc, FALSE);
int nWptag = GetLocalInt (oNpc, "wptag");
if (nWptag == 0) {SetLocalInt (oNpc, "wptag", 1);}
//Select which waypoint we should be going to and assign it as oWp1 = current waypoint
if (nWPcontrol != 1)
{
ClearAllActions();
{switch (nWptag)
{
case 1: oWp1 = oAnvil; SetLocalInt (oNpc, "control", 1); break;
case 2: oWp1 = oForge; SetLocalInt (oNpc, "control", 1); break;
case 3: oWp1 = oQuench; SetLocalInt (oNpc, "control", 1); break;
}
}
}
//Get our new waypoint tag, check the distance and perform animations if within range ONLY
nWptag = GetLocalInt (oNpc,"wptag");
float fDwp1 = GetDistanceToObject (oWp1);
int nAction = GetLocalInt (oNpc, "actioncounter");
if (fDwp1 >= 0.3) {SetLocalInt (oNpc,"atloc",0);DelayJump(oNpc,oWp1);}
if (fDwp1 <= 0.5)
{switch (nWptag)
{
case 1:
//Location at WP_ANVIL
SetLocalInt (oNpc,"atloc",1);
{switch (nAction)
{
default:
//Anvil animation #1
//Equip sword and hammer if not already equipped
//Initialize hammering sound
EquipNewItem(oNpc, sHammer, 4);
DelayCommand (0.4, EquipNewItem(oNpc, sSword2, 5));
NpcBlacksmithSpeak (nSpeak);
DelayCommand (0.5, SoundObjectPlay(oSoundHammer));
ActionPlayCustomAnimation (oNpc, "craft01",1,5.9);
SetLocalInt (oNpc, "actioncounter",1);
break;
case 1:
//Anvil animation #2
NpcBlacksmithSpeak (nSpeak);
ActionPlayCustomAnimation (oNpc, "craft01",1,5.9);
SetLocalInt (oNpc, "actioncounter",2);
break;
case 2:
//Anvil animation #3
//disable hammering sound
//set wptag to 3 and go to location for quench
NpcBlacksmithSpeak (nSpeak);
DelayCommand (6.0, SoundObjectStop(oSoundHammer));
ActionPlayCustomAnimation (oNpc, "craft01",1,5.9);
SetLocalInt (oNpc, "actioncounter",0);
SetLocalInt (oNpc, "wptag" ,3);
SetLocalInt (oNpc, "control", 0);
break;
}
}
break;
case 2:
//Location at WP_FORGE
SetLocalInt (oNpc,"atloc",1);
{switch (nAction)
{
default:
//Forge animation #1
//remove sword from hand
NpcBlacksmithSpeak (nSpeak);
DelayCommand (1.1, DestroyItemInSlot (oNpc,5));
ActionPlayCustomAnimation(oNpc,"openlock",0,2.0);
SetLocalInt (oNpc, "actioncounter",1);
break;
case 1:
//Forge animation #2
NpcBlacksmithSpeak (nSpeak);
ActionPlayCustomAnimation (oNpc, "dustoff",0,5.9);
SetLocalInt (oNpc, "actioncounter",2);
break;
case 2:
//Forge animation #3
//Get red hot sword from forge
//set wptag to 1 and go to location for hammering
NpcBlacksmithSpeak (nSpeak);
DelayCommand (1.1, EquipNewItem(oNpc, sHammer, 4));
DelayCommand (1.3, EquipNewItem(oNpc, sSword2, 5));
ActionPlayCustomAnimation(oNpc,"openlock",0,2.0);
SetLocalInt (oNpc, "actioncounter",0);
SetLocalInt (oNpc, "wptag" ,1);
SetLocalInt (oNpc, "control", 0);
break;
}
}
break;
case 3:
//Location WP_QUENCH
SetLocalInt (oNpc,"atloc",1);
{switch (nAction)
{
default:
//Quench Animation #1
//Dip sword in water and drop it
//Initialize steam sound and fx
NpcBlacksmithSpeak (nSpeak);
DelayCommand (3.0, DestroyItemInSlot (OBJECT_SELF,5));
DelayCommand (1.0, SoundObjectPlay(oSoundObject));
DelayCommand (1.1, ApplyEffectToObject(DURATION_TYPE_PERMANENT, EffectNWN2SpecialEffectFile("fx_chimney"), oEffectObject));
ActionPlayCustomAnimation(OBJECT_SELF,"torchlightground",0,4.1);
SetLocalInt (oNpc, "actioncounter",1);
break;
case 1:
//Quench Animation #2
NpcBlacksmithSpeak (nSpeak);
ActionPlayCustomAnimation (oNpc, "yawn",0,5.9);
SetLocalInt (oNpc, "actioncounter",2);
break;
case 2:
//Quench Animation #3
//Disable steam sound and fx
//Reach down and grab the sword (no longer red hot)
//set wptag to 2 and go to location for forge
NpcBlacksmithSpeak (nSpeak);
SoundObjectStop(oSoundObject);
RemoveSEFFromObject(oEffectObject, ("fx_chimney"));
DelayCommand (2.8, EquipNewItem(oNpc, sHammer, 4));
DelayCommand (3.0, EquipNewItem(oNpc, sSword, 5));
ActionPlayCustomAnimation(OBJECT_SELF,"torchlightground",0,4.1);
SetLocalInt (oNpc, "actioncounter",0);
SetLocalInt (oNpc, "wptag" ,2);
SetLocalInt (oNpc, "control", 0);
break;
}
}
break;
}
}
}