| Author: | ericksoa |
| Author Website: | n/a |
| Script Name: | Barmaid 3 |
| Description: | Makes a barmaid go to all the NPCs in a given range of metres and forces them to have a beer. This is a starting point, and a demonstration of state based processing for NPCs. You probably only need 1 or 2 of these in a room to really bog down processing, so be gentle with it. |
| Instructions on Use: | This goes in the OnUserDefined of any NPC called BARMAID. You need
waypoints labeled WP_BARMAID_BAR (for where the bar is) and WP_BARMAID_STA
(for where she goes between customers). She will visit only NPCs. Send a 2005 event at the end of any conversation (both aborted and not aborted) to make her activities survive interruption. Those are not included, but you can probably figure those out on your own. |
Script 1 (OnUserDefined):
void main()
{
// You need these outside the nEvent switch
// So you can use the varnames in other signal events
int STATUS_READY =10;
int STATUS_BUSY=20; // do nothing-she's busy with actions
int STATUS_FINISHED=30;
int STAGE_AQUIRE =10; //case doesn't use vars
int STAGE_GETORDER =20; //but put these here to
int STAGE_WALKBAR =30; //remind you which values
int STAGE_GETDRINK =40; //mean what
int STAGE_DELIVERDRINK =50;
int STAGE_GOSTATION =60;
float BARMAID_DISTANCE_THRESHOLD=1000.0; //set this to the range you want the barmaid to work
int nEvent=GetUserDefinedEventNumber();
switch (nEvent)
{
case 2005:
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
break;
case 1001: // heartbeats
int nStatus=GetLocalInt(OBJECT_SELF,"MAID_STATUS");
int nStage=GetLocalInt(OBJECT_SELF,"MAID_STAGE");
int iAquired = FALSE; //default, perhaps there is nobody to aquire
//object oTarget=GetLocalObject(OBJECT_SELF,"MAID_TARGET");
// int STAGE_AQUIRE =10; case doesn't use vars
// int STAGE_GETORDER =20; but put these here to
// int STAGE_WALKBAR =30; remind you which values
// int STAGE_GETDRINK =40; mean what
// int STAGE_DELIVERDRINK =50;
// int STAGE_GOSTATION =60;
if (nStatus==0) // Just started new module
{
nStatus=STATUS_READY;
SetLocalInt(OBJECT_SELF,"MAID_STAGE",nStatus);
nStage=STAGE_AQUIRE;
SetLocalInt(OBJECT_SELF,"MAID_STAGE",nStage);
}
switch(nStage)
{
case 10: // STAGE_AQUIRE
if (nStatus==STATUS_READY)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
int iNth = GetLocalInt(OBJECT_SELF, "NTH_PATRON");
iNth++;
//object oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, OBJECT_SELF, iNth);
object oTarget = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_NOT_PC, OBJECT_SELF, iNth);
SpeakString("I am looking for the " + IntToString(iNth) + " potential customer");
if (GetStringLeft(GetTag(oTarget), 7) == "BARMAID")
{
SpeakString("arrgh, cant serve to miself");
//do not take orders from other barmaids
iNth++;
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, OBJECT_SELF, iNth);
}
//other cases like this (e.g. dont serve to the inkeep, etc.) are possible...
//left out for simplicity the first time around
if (GetIsObjectValid(oTarget))
{
SpeakString("Master, object is valid");
}
else
{
SpeakString("Master, nearest object is not valid in my view");
}
if (GetIsObjectValid(oTarget) && (GetDistanceToObject(oTarget) <= BARMAID_DISTANCE_THRESHOLD))
{
SpeakString("Ahh, found a customer, the " + IntToString(iNth) + "th one");
iAquired = TRUE;
SetLocalObject(OBJECT_SELF,"MAID_TARGET",oTarget);
SetLocalInt(OBJECT_SELF, "NTH_PATRON", iNth);
ActionMoveToObject(oTarget);
}
else
{
//try setting iNth back to 1, cycling
SpeakString("Starting from the beginning");
iNth = 1;
oTarget = GetNearestCreature(CREATURE_TYPE_IS_ALIVE, TRUE, OBJECT_SELF, iNth);
if (GetIsObjectValid(oTarget) && (GetDistanceToObject(oTarget) <= BARMAID_DISTANCE_THRESHOLD))
{
//special case, we have cycled through all patrons
iAquired = TRUE;
SetLocalObject(OBJECT_SELF,"MAID_TARGET",oTarget);
SetLocalInt(OBJECT_SELF, "NTH_PATRON", iNth);
ActionMoveToObject(oTarget);
}
else
{
//Ok, so there is nobody here :)
SpeakString("Beer here... beer here...");
SetLocalInt(OBJECT_SELF, "NTH_PATRON", 0);
}
}
if (iAquired)
// we can move to finished and start serving someone only if there is
// someone to serve
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
else
//otherwise, reset to ready and try again in 6 seconds
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY));
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_GETORDER);
}
break;
case 20: // STAGE_GETORDER
if (nStatus==STATUS_READY)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
object oTarget = GetLocalObject(OBJECT_SELF, "MAID_TARGET");
//do your animations etc
ActionDoCommand(SpeakString("We only serve beer here... deal with it"));
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_WALKBAR);
}
break;
case 30: // STATE WALKBAR
if (nStatus==STATUS_READY)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
//Get a Waypoint for going to the bar, or if "object invalid", say that there is no bar, and that
// perhaps the owner of the place should buy one
//if you make your bar waypoint in the manner of WP_<your waitresstag>_BAR you are in good shape
object oBarWP = GetObjectByTag("WP_" + GetTag(OBJECT_SELF) + "_BAR");
if (GetIsObjectValid(oBarWP)==FALSE)
{
ActionDoCommand(SpeakString("Perhaps the owner should buy a bar for this inn... and tag it WP_" + GetTag(OBJECT_SELF) + "_BAR"));
}
else
{
ActionMoveToObject(oBarWP);
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
}
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_GETDRINK);
}
break;
case 40: //STAGE_GETDRINK
if (nStatus==STATUS_READY)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
object oTarget = GetLocalObject(OBJECT_SELF, "MAID_TARGET");
//do your animations etc
//at some point, this should do something like say "give me a <what they ordered>"
ActionDoCommand(SpeakString("Gimme a beer, bartender (or not)"));
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_DELIVERDRINK);
}
break;
case 50: //STAGE_DELIVER_DRINK
if (nStatus==STATUS_READY)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
object oTarget = GetLocalObject(OBJECT_SELF, "MAID_TARGET");
ActionMoveToObject(oTarget);
// update to actually base the selection on what was selected...
ActionDoCommand(SpeakString("Here's your beer."));
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_GOSTATION);
}
break;
case 60: //STAGE_GO_STATION
if (nStatus==STATUS_READY)
{
//Get a Waypoint for going to the station, or if "object invalid", say that there is no station, and that
// perhaps the owner of the place should set one
//if you make your station waypoint in the manner of WP_<your waitresstag>_STA you are in good shape
object oStaWP = GetObjectByTag("WP_" + GetTag(OBJECT_SELF) + "_STA");
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_BUSY);
if (GetIsObjectValid(oStaWP)==FALSE)
{
ActionDoCommand(SpeakString("Perhaps the owner should give me a station in this inn... and tag it WP_" + GetTag(OBJECT_SELF) + "_STA"));
}
else
{
ActionMoveToObject(oStaWP);
ActionDoCommand(SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_FINISHED));
}
}
if (nStatus==STATUS_FINISHED)
{
SetLocalInt(OBJECT_SELF,"MAID_STATUS",STATUS_READY);
SetLocalInt(OBJECT_SELF,"MAID_STAGE",STAGE_AQUIRE);
}
break;
}
break;
}
}
|
Script 2 (OnSpawn):
//::///////////////////////////////////////////////
//:: Default: On Spawn In
//:: NW_C2_DEFAULT9
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 25, 2001
//:://////////////////////////////////////////////
#include "NW_O2_CONINCLUDE"
#include "NW_I0_GENERIC"
void main()
{
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
//SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetSpawnInCondition(2005); // for "barmaid is ready" event after some *** bothers her.
// DEFAULT GENERIC BEHAVIOR (DO NOT TOUCH) *****************************************************************************************
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature
}
|