System description:
Many modules have guards whos responsibility is top unlock/open/lock/close gates, and use multiple scripts and conversations in order to do so. This system uses the same set of scripts for all NPC guards, whether they are on the inside or outside of the gate. They only need one conversation per gate. The same conversation will handle both the inside and outside gate NPCs.
System components:
000_sc_guard_in : SC to determine if NPC is inside the gate
000_sc_guard_out : SC to determine if NPC is outside the gate
000_guardduty : Main Action Taken script for NPC to perform Guard Duty
In addition a conversation is required
Example:
For the Zhentarim Lumber Camp I have a need to restrict who get access to it. I don't want players with low reputation in the Zhentarim faction to access it, and I want a different behaviour of the guards depending on the PC's reputation.
The gate area looks something like this:
Code: Select all
|
| W2-G2
|
G
|
W1-G1 |
|
They are located at two waypoints (W1 and W2), and are expected to return there after they have performed theyr duties.
The gate tag should be known. In my case it would be "stockage_east_gate".
The two waypoints should be named so we know if they are inside or outside the gate.
W1 : zlc_east_in
W2 : zlc_east_out
Variables on the guard NPC (G1 and G2):
We need the two guards, and depending on your spawn system, you can either have them NESS'ed in, which means you will have to have two different blueprints for guards, or you can place the guards static and change them after they are placed out.
Regardless of method, we need a set of variables on the NPCs. We need two different NPCs, one on each side.
Code: Select all
Variables:
MANDATORY VARIABLES:
guard_door : tag of door
guard_waypoint : waypoint to return to after close
OPTIONAL VARIABLES:
guard_doordelay : number of seconds the door should remain open. Default 10 seconds.
guard_closedelay : number of seconds before NPC returns to waypoint. From start of open action. Default 15 seconds
guard_nolock : if set to 1, the door will not be locked/unlocked. Only opened/closed. Default 0
guard_nokey : if set to 1, a key is not required to lock/unlock. Default 0
Code: Select all
G1 will have the following variables set:
guard_door string stockade_east_gate
guard_opendelay int 15
guard_closedelay int 20
guard_waypoint string zlc_east_in
G2 will have the following variables set:
guard_door string stockade_east_gate
guard_opendelay int 15
guard_closedelay int 20
guard_waypoint string zlc_east_out
Code: Select all
Root
Bugger off it ya'know whats good for ya. Ya have no business here (SC:rep_sc_rep_low)
[Eyes you suspiciously] What do you want ? (SC:rep_sc_rep_mid)
I'd like to enter the camp. (SC:guard_sc_out)
I guess... Don't make any trouble, or the sarge will have your head [gulps] ... and mine. (AT:guard_opengate)
I'd like to leave the camp. (SC:guard_sc_in)
Open gate, close gate, open gate and close gate... [rolls eyes] (AT:guard_opengate)
Never Mind, I'll stay here for now.
[salutes and springs to attention] Hail <FullName>. Let me get the gates for you <Sir/Madam>.(SC:rep_sc_rep_high)
And waste no time doing it ... (AT:guard_opengate)
Never Mind, I'll stay here for now.
reputation with the NPC's faction (Zhentarim). Depending on your reputation you get a different reaction.
- You don't get in if you have too low reputation.
- If you're barely known to them, you get in, but are dealt with rudely
- If you're very known to them, you'll get respect and can respond harsly without problems.
This shows two things.
1. In case 2, you have a different response for the inside and outside guard.
2. In case 3, you have the same response, but could have two if you wanted.
A simpler version without the reputation system would look like this:
Code: Select all
Root
[Eyes you suspiciously] What do you want ?
I'd like to enter the camp. (SC:guard_sc_out)
I guess... Don't make any trouble, or the sarge will have your head [gulps] ... and mine. (AT:guard_opengate)
I'd like to leave the camp. (SC:guard_sc_in)
Open gate, close gate, open gate and close gate... [rolls eyes] (AT:guard_opengate)
Never Mind, I'll stay here for now.
Code: Select all
////////////////////////////////////////////////////////////////////////////////
//
// System Name : Global ALFA script
// Filename : 000_sc_guard_in.nss
// $Revision:: $ 1.0
// $Date:: $ 09-OCT-2006
// Author : Petter Stene (Baalster)
//
// Var Prefix: unique name comprised of 3 letter system and feature acronyms
// Dependencies: OBJECT_SELF is an NPC with guard duty variables set. See GuardDuty.txt
//
// guard_waypoint :
// tag should end with "_in" for a guard inside the gate
// tag should end with "_out" for a guard outside the gate
//
// Description
// Script is a starting condition which determines whether the guard is placed
// on the inside or outside of the gate. The purpose is to use the same script
// and conversation file for both the inside and outside guards.
//
// This SC returns true if the "guard_waypoint" local variable string on the guard contain "_in".
// Used in Guard Duty NPC conversations.
//
// Revision History
// 09-OCT-2006 Baalster. Initial creation for NWN2
//
////////////////////////////////////////////////////////////////////////////////
int StartingConditional()
{
return (FindSubString(GetLocalString(OBJECT_SELF,"guard_waypoint"),"_in")>1);
}
Code: Select all
////////////////////////////////////////////////////////////////////////////////
//
// System Name : Global ALFA script
// Filename : 000_sc_guard_out.nss
// $Revision:: $ 1.0
// $Date:: $ 09-OCT-2006
// Author : Petter Stene (Baalster)
//
// Var Prefix: unique name comprised of 3 letter system and feature acronyms
// Dependencies: OBJECT_SELF is an NPC with guard duty variables set. See GuardDuty.txt
//
// guard_waypoint :
// tag should end with "_in" for a guard inside the gate
// tag should end with "_out" for a guard outside the gate
//
// Description
// Script is a starting condition which determines whether the guard is placed
// on the inside or outside of the gate. The purpose is to use the same script
// and conversation file for both the inside and outside guards.
//
// This SC returns true if the "guard_waypoint" local variable string on the guard contain "_out".
// Used in Guard Duty NPC conversations.
//
// Revision History
// 09-OCT-2006 Baalster. Initial creation for NWN2
//
////////////////////////////////////////////////////////////////////////////////
int StartingConditional()
{
return (FindSubString(GetLocalString(OBJECT_SELF,"guard_waypoint"),"_out")>1);
}
Code: Select all
////////////////////////////////////////////////////////////////////////////////
//
// System Name : Global ALFA script
// Filename : 000_guardduty.nss
// $Revision:: $ 1.0
// $Date:: $ 09-OCT-2006
// Author : Petter Stene (Baalster)
//
// Var Prefix: unique name comprised of 3 letter system and feature acronyms
// Dependencies: See GuardDuty.txt
// MANDATORY VARIABLES:
// guard_door : tag of door
// guard_waypoint : waypoint to return to after close
// OPTIONAL VARIABLES:
// guard_doordelay : number of seconds the door should remain open. Default 10 seconds.
// guard_closedelay : number of seconds before NPC returns to waypoint.
// From start of open action. Default 15 seconds
// guard_nolock : if set to 1, the door will not be locked/unlocked. Only opened/closed. Default 0
// guard_nokey : if set to 1, a key is not required to lock/unlock. Default 0
//
// Description
// Script relies heavily on variables set on the NPC from which the Action Taken is performed.
// Based on the variables, the gate and the waypoint it will move to the gate, unlock/open/close/lock
// and then move back to it's starting waypoint. Called from a Guard Duty NPC conversation.
//
// Revision History
// 09-OCT-2006 Baalster. Initial creation for NWN2
//
////////////////////////////////////////////////////////////////////////////////
void main()
{
// Get the variables off the NPC guard
// MANDATORY VARIABLES:
// guard_door : tag of door
// guard_waypoint : waypoint to return to after close
// OPTIONAL VARIABLES:
// guard_doordelay : number of seconds the door should remain open.
// guard_closedelay : number of seconds before NPC returns to waypoint. From start of open action.
// guard_nolock : if set to 1, the door will not be locked/unlocked. Only opened/closed.
// guard_nokey : if set to 1, a key is not required to lock/unlock.
object oDoor = GetObjectByTag(GetLocalString(OBJECT_SELF,"guard_door"));
object oWaypoint = GetObjectByTag(GetLocalString(OBJECT_SELF,"guard_waypoint"));
float fDoorDelay = GetLocalFloat(OBJECT_SELF,"guard_doordelay");
float fCloseDelay = GetLocalFloat(OBJECT_SELF,"guard_closedelay");
int nNolock = GetLocalInt(OBJECT_SELF,"guard_nolock");
int nNokey = GetLocalInt(OBJECT_SELF,"guard_nokey");
float fDirection = GetFacing(OBJECT_SELF);
// Make sure we have some reasonable default values. nNolock will default to 0.
if (fDoorDelay==0.0)
fDoorDelay=10.0;
if (fCloseDelay==0.0)
fCloseDelay=15.0;
// Unlock if needed, and open
if (!nNolock)
if (!nNokey)
AssignCommand(OBJECT_SELF, ActionUnlockObject(oDoor));
else
SetLocked(OBJECT_SELF, FALSE);
AssignCommand(OBJECT_SELF, ActionOpenDoor(oDoor));
// Close and lock if needed
AssignCommand(OBJECT_SELF, DelayCommand(fDoorDelay, ActionCloseDoor(oDoor)));
if (!nNolock)
if (!nNokey)
AssignCommand(OBJECT_SELF, DelayCommand((fDoorDelay + 1.0), ActionLockObject(oDoor)));
else
SetLocked(OBJECT_SELF, TRUE);
// Move back to post waypoint and face correctly
location lWaypoint = GetLocation(oWaypoint);
AssignCommand(OBJECT_SELF, DelayCommand(fCloseDelay, ActionMoveToLocation(lWaypoint)));
if (fDirection > 0.0)
AssignCommand(OBJECT_SELF, 2.0,SetFacing(fDirection);
}