Just checked and there are no hearbeat scripts in this area, either on the area or the NPCs.
Here’s Lance’s script that’s on the OnEnter of the area:
#include "ginc_math"
#include "ginc_cutscene"
///////////////////////////////////////////////////////////////////////////////////////////////////
// SET "TRYSIT" VARIABLE TO 1 ON NPC AT BUILD TIME OR VIA SCRIPT TO MAKE THEM KEEP ATTEMPTING TO SIT
// THIS FUNCTION CAUSES PROBLEMS WHEN ADDED TO ALB_FUNCTIONS
// NB: NPCS MAY STRUGGLE TO SIT WHEN NOT CLOSE TO A CHAIR DUE TO WALKMESH ISSUES !!!!!!!!!!!!!!!!!!!
///////////////////////////////////////////////////////////////////////////////////////////////////
void ForceNPCReseat(object oTarget)
{
if(GetLocalInt(oTarget, "TRYSIT") == 0){return;} // SITTING HAS BEEN CANCELLED
object oCurrentChair = GetLocalObject(oTarget, "Seated");
// SendMessageToPC(GetFirstPC(TRUE), GetName(oTarget) + " IS TRYING TO SIT"); // DEBUG
// FIND THE NEAREST AVAILABLE CHAIR (USE THE FIRST 8 CHARACTERS E.g. pat_mid_chair5)
int iCount = 1; object oChair = GetNearestObject(OBJECT_TYPE_PLACEABLE, oTarget, iCount);
while(oChair != OBJECT_INVALID)
{
// FIND A CHAIR WITHOUT A CURRENT USER
if(GetStringLeft(GetTag(oChair), 8) == "pat_mid_")
{
object oCurrentSeater = GetLocalObject(oChair, "LastSeated");
// TRY IGNORING THE FACT THAT THE LAST SEATED CHAIR HAD AN OCCUPANT (IT WAS PROBABLY THEM ANYWAY PRIOR EXIT)
if(oCurrentSeater == OBJECT_INVALID || oCurrentSeater == oTarget)
{
//SendMessageToPC(GetFirstPC(TRUE), GetName(oTarget) + " FOUND A CHAIR"); // DEBUG
break;
}
}
iCount = iCount + 1; oChair = GetNearestObject(OBJECT_TYPE_PLACEABLE, oTarget, iCount);
}
// MAKE TARGET USE THIS CHAIR
SetLocalObject(oChair, "LastSeated", oTarget);
SetLocalObject(oTarget, "Seated", oChair);
AssignCommand(oTarget, ClearAllActions(TRUE));
AssignCommand(oTarget, ActionInteractObject(oChair));
}
void fadetoblack(float fSpeed, float fFailsafe, int nColor)
{
object oPCh = GetEnteringObject();
if (IsFloatNearInt(fFailsafe, 0))
fFailsafe = 15.0f;
FadeToBlackParty(oPCh, 1, fSpeed, fFailsafe, nColor);
}
void main()
{
object oCreature = GetEnteringObject();
// ONLY RUN WHEN PLAYER ENTERS
if(!GetIsPC(oCreature)){return;}
fadetoblack(3.2,3.2,0);
object oArea = GetArea(oCreature);
object oNPC = GetFirstObjectInArea(oArea);
while(oNPC != OBJECT_INVALID)
{
// RESEAT NPCS
if(GetObjectType(oNPC) == OBJECT_TYPE_CREATURE && GetLocalInt(oNPC, "TRYSIT") == 1)
{
DelayCommand(0.5, ForceNPCReseat(oNPC));
}
oNPC = GetNextObjectInArea(oArea);
}
}
And here’s Lance’s script that’s on the OnUsed of the chairs:
void ActionPlayCustomAnimation(object oObject, string sAnimationName, int nLooping, float fSpeed = 1.0f)
{
PlayCustomAnimation(oObject, sAnimationName, nLooping, fSpeed);
}
// float GetNormalizedDirection(float fDirection):
// * This script returns a direction normalized to the range 0.0 - 360.0
// * Copyright (c) 2002 Floodgate Entertainment
// * Created By: Naomi Novik
// * Created On: 11/08/2002
float GetNormalizedDirection(float fDirection)
{
float fNewDir = fDirection;
while (fNewDir >= 360.0) {
fNewDir -= 360.0;
}
while (fNewDir <= 0.0) {
fNewDir += 360.0;
}
return fNewDir;
}
void SitDown(object oSitter, object oChair)
{
AssignCommand(oSitter, SetFacing(GetNormalizedDirection(GetFacing(oChair)+180.00+GetLocalFloat(oChair,"rotate")) ));
AssignCommand(oSitter, ActionPlayCustomAnimation(OBJECT_SELF, "sitidle", 1, 1.0));
// EXTRA CODE THANKS TO SHAUGHN & EGUINTIR
//SetOrientOnDialog(oSitter,FALSE);
SetBumpState(oSitter,BUMPSTATE_UNBUMPABLE);
}
void main()
{
object oChair = OBJECT_SELF;
object oSitter = GetLastUsedBy();
object oCheckSitter = GetLocalObject(oChair, "LastSeated");
//SendMessageToAllPCs("Chair used by " + GetName(oSitter));
// RETRIEVE VARS ATTACHED TO CHAIR
int iHeading = GetLocalInt(oChair, "degree");
string sName = GetFirstName(oChair);
//Assign the heading degrees
location lChair_o = GetLocation(oChair);
location lChair = Location(GetArea(oChair), GetPositionFromLocation(lChair_o), GetNormalizedDirection(GetFacingFromLocation(lChair_o) + iHeading));
// CHECK THE SEAT IS FREE
if(GetLocalObject(oChair, "LastSeated") != OBJECT_INVALID && oSitter != oCheckSitter)
{
FloatingTextStringOnCreature("<<< The seat is already being used by somebody. >>>", oSitter, FALSE);
return;
}
// SEAT THE USER & ASSOCIATE SEAT WITH NPC FOR RETURN SEAT
if(oSitter != OBJECT_INVALID)
{
SetLocalObject(oChair, "LastSeated", oSitter);
SetLocalObject(oSitter, "Seated", oChair);
}
// JUST USE THE STANDARD CHAIRS
AssignCommand(oSitter, ActionMoveToLocation(lChair));
DelayCommand(2.0, SitDown(oSitter, oChair));
}
I hope this can help you a bit @aeliop !
As you see in the description of the first script, you need the TRYSIT variable on the NPCs you want to sit down.
If you use these, then you can speak to the characters sitting down. No issues there. Just use the default script for conversation on the NPC.
I have not tested this on combat, but I believe they would quit sitting down if there was a fight.
I forgot to mention that the chairs you use need to have the tag “pat_mid” as the first part of the tag for the scripts to work. If you look at the code here you understand why:
// FIND A CHAIR WITHOUT A CURRENT USER
if(GetStringLeft(GetTag(oChair), 8) == "pat_mid_")