Initial Commit
Initial Commit
This commit is contained in:
291
_module/nss/pacifico_trash.nss
Normal file
291
_module/nss/pacifico_trash.nss
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
|
||||
pacifico_trash - Garbage Collector and Lost & Found script
|
||||
By: Mike Knowles aka pacifico
|
||||
Email: mknowles@ilovescience.com
|
||||
|
||||
Garbage collector NPC who will wander around and pick up dropped
|
||||
objects, either disposing of them, or putting the objects in a
|
||||
"lost and found" chest.
|
||||
|
||||
|
||||
Feel free to use/modify/whatever. I'd love credit if you change it,
|
||||
but would love more an email if you use it and your thoughts (good and bad)
|
||||
about it.
|
||||
|
||||
Version 1.2
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
The first few tags are easy ways to customize
|
||||
the garbage collector. Hopefully most are obvious.
|
||||
|
||||
To use, just place him in your module and he'll start
|
||||
cleaning up. He can be lazy sometimes, so don't expect
|
||||
him to pick things up immediately. He'll get to it
|
||||
eventually, though.
|
||||
|
||||
Also, if you create a placeable obect that's a container
|
||||
(a chest is a good choice) with a tag of "pac_lost_found"
|
||||
then the collector will put anything he finds into that chest
|
||||
instead of getting rid of it.
|
||||
|
||||
ISSUES AND SUCH:
|
||||
He's not terribly tolerant of full lost and founds, and of
|
||||
non-destroyable things if there's no lost and found. Also,
|
||||
he's even takes gold to the lost and found, which will be changed,
|
||||
soon (as well as emptying out the lost and found periodically).
|
||||
|
||||
*/
|
||||
|
||||
string P_TAG_LOSTFOUND = "pac_lost_found"; // tag of the lost & found container. If this box exists, the collector
|
||||
// will put the trash here, instead of destroying it (assuming there's room
|
||||
// in the box).
|
||||
|
||||
float P_TRASH_DISTANCE = 15.0; // number of meters that the garbage collector will look for local trash.
|
||||
|
||||
int P_FLAG_EFFICIENT = 0; // if 1, then the NPC picks up things as soon as they're dropped and doesn't take breaks.
|
||||
// this flag is good for small areas where a roving collector isn't as appropriate.
|
||||
// For instance, this script could be applied to a barmaid who is a normal maid, but
|
||||
// also has floor sweeping duties when people drop things.
|
||||
|
||||
int P_FLAG_WHINER = 1; // if 1, then the collector says what he's about to collect. 0 turns this off.
|
||||
int P_FLAG_WHISTLE = 1; // Sometimes whistles while on break.
|
||||
|
||||
int P_VALUE_LAZY = 4; // Indicates how lazy the garbage collector is. P_FLAG_EFFICIENT overides this value.
|
||||
// Values between 1-9 work. 9 = super lazy, 1 = hardly any breaks.
|
||||
|
||||
int P_VALUE_MAXBREAKLEN = 15; // The max number of rounds a break will last.
|
||||
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
/********* END FLAGS AND STUFF**************************/
|
||||
|
||||
|
||||
int P_STATUS_NOTHING = 0;
|
||||
int P_STATUS_WALKING = 1;
|
||||
int P_STATUS_REMOVEITEM = 3;
|
||||
int P_STATUS_LOSTFOUND = 4;
|
||||
|
||||
int P_STATUS_ONBREAK = -1;
|
||||
int P_STATUS_WORKING = -2;
|
||||
|
||||
int DoCollection();
|
||||
int DecideWhatToDo();
|
||||
int WalkSomewhere();
|
||||
int LostAndFound();
|
||||
int StillOnBreak();
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
switch(GetLocalInt(OBJECT_SELF, "iStatus"))
|
||||
{
|
||||
case -1: //P_STATUS_ONBREAK:
|
||||
SetLocalInt(OBJECT_SELF, "iStatus", StillOnBreak());
|
||||
break;
|
||||
case 3: //P_STATUS_REMOVEITEM:
|
||||
SetLocalInt(OBJECT_SELF, "iStatus", DoCollection());
|
||||
break;
|
||||
case 4: //P_STATUS_LOSTFOUND:
|
||||
SetLocalInt(OBJECT_SELF, "iStatus", LostAndFound());
|
||||
break;
|
||||
case 1: //P_STATUS_WALKING:
|
||||
SetLocalInt(OBJECT_SELF, "iStatus", WalkSomewhere());
|
||||
break;
|
||||
case 0: //P_STATUS_NOTHING:
|
||||
SetLocalInt(OBJECT_SELF, "iStatus", DecideWhatToDo());
|
||||
break;
|
||||
case -2: //P_STATUS_WORKING:
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int DecideWhatToDo()
|
||||
{
|
||||
|
||||
// reset our internal data.
|
||||
SetLocalInt(OBJECT_SELF, "iBreakTime", 0);
|
||||
SetLocalObject(OBJECT_SELF,"oThing", OBJECT_INVALID);
|
||||
|
||||
ClearAllActions();
|
||||
|
||||
|
||||
// if we have something in our hands, we should deal with it before getting more garbage
|
||||
if (GetIsObjectValid(GetFirstItemInInventory()))
|
||||
{
|
||||
// there's something in our inventory, so we should do something with it.
|
||||
// Someday, we should support picking up more than one item at a time...
|
||||
|
||||
ClearAllActions();
|
||||
return P_STATUS_LOSTFOUND;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// see if there is garbage nearby. If not, decide to move to another area or take a break.
|
||||
object oThing = GetNearestObject(OBJECT_TYPE_ITEM);
|
||||
|
||||
if (GetIsObjectValid(oThing))
|
||||
{
|
||||
float fDist = GetDistanceToObject(oThing);
|
||||
|
||||
if (fDist<P_TRASH_DISTANCE)
|
||||
{
|
||||
// object is close - should go get it.
|
||||
return P_STATUS_REMOVEITEM;
|
||||
}
|
||||
|
||||
// there's something out there, so a break is less likely
|
||||
if (Random(10)<P_VALUE_LAZY) { return P_STATUS_ONBREAK; }
|
||||
return P_STATUS_WALKING;
|
||||
}
|
||||
|
||||
// nothing around, anyway. Better time for a break.
|
||||
if (Random(5)<(P_VALUE_LAZY)) { return P_STATUS_ONBREAK; }
|
||||
|
||||
return P_STATUS_WALKING;
|
||||
}
|
||||
|
||||
int WalkSomewhere()
|
||||
{
|
||||
|
||||
// right now, the garbage collector doesn't do any rounds, and just walks towards the next
|
||||
// item. I want him to do rounds, instead, until he comes across items. Will take longer to
|
||||
// pick things up, but would seem more 'real'.
|
||||
|
||||
object oThing = GetNearestObject(OBJECT_TYPE_ITEM);
|
||||
|
||||
if (GetIsObjectValid(oThing))
|
||||
{
|
||||
ActionMoveToObject(oThing,FALSE, IntToFloat(Random(15)+1));
|
||||
} else {
|
||||
ActionRandomWalk();
|
||||
}
|
||||
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
int StillOnBreak()
|
||||
{
|
||||
if (P_FLAG_EFFICIENT)
|
||||
{
|
||||
ActionRandomWalk();
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
int iBreakTime = GetLocalInt(OBJECT_SELF,"iBreakTime");
|
||||
|
||||
if (iBreakTime==0 && P_FLAG_WHINER) { ActionSpeakString("What a tough job. Time for a break."); }
|
||||
|
||||
iBreakTime++;
|
||||
|
||||
SetLocalInt(OBJECT_SELF, "iBreakTime", iBreakTime);
|
||||
|
||||
int iBreak = P_VALUE_MAXBREAKLEN - iBreakTime;
|
||||
|
||||
if ((Random(P_VALUE_MAXBREAKLEN)-iBreakTime)<0) { ClearAllActions(); return P_STATUS_NOTHING; }
|
||||
|
||||
if (Random(3)==0 && P_FLAG_WHISTLE) { ActionSpeakString("*whistles*"); }
|
||||
|
||||
ActionRandomWalk();
|
||||
return P_STATUS_ONBREAK;
|
||||
|
||||
}
|
||||
|
||||
int LostAndFound()
|
||||
{
|
||||
object oThing = GetFirstItemInInventory();
|
||||
|
||||
if (!GetIsObjectValid(oThing))
|
||||
{
|
||||
|
||||
ClearAllActions();
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
object oBox = GetNearestObjectByTag(P_TAG_LOSTFOUND);
|
||||
|
||||
if (!GetIsObjectValid(oBox) && (GetObjectType(oBox)==OBJECT_TYPE_PLACEABLE))
|
||||
{ //No lost and found found. Just destroy the object.
|
||||
DestroyObject(oThing);
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
|
||||
if (GetDistanceToObject(oBox)>2.0)
|
||||
{
|
||||
ActionMoveToObject(oBox,FALSE,1.0);
|
||||
return P_STATUS_LOSTFOUND;
|
||||
}
|
||||
|
||||
|
||||
ClearAllActions();
|
||||
ActionGiveItem(oThing,oBox);
|
||||
|
||||
ActionSpeakString("Well, that's done. Off to find more trash");
|
||||
return P_STATUS_LOSTFOUND;
|
||||
|
||||
}
|
||||
|
||||
int DoCollection()
|
||||
{
|
||||
|
||||
|
||||
object oSavedThing = GetLocalObject(OBJECT_SELF,"oThing");
|
||||
|
||||
|
||||
if (GetIsObjectValid(oSavedThing)) // we have trash targeted already
|
||||
{
|
||||
|
||||
object oThing = GetNearestObject(OBJECT_TYPE_ITEM);
|
||||
if (!GetIsObjectValid(oThing))
|
||||
{
|
||||
// someone beat us to the item.
|
||||
ClearAllActions();
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
if (oThing != oSavedThing)
|
||||
{ // Something happened... either someone picked up the item,
|
||||
// or someone dropped something closer to us.
|
||||
|
||||
|
||||
// Note: originally this did a separate check for another item, but
|
||||
// it seemed better to have the DecideWhatToDo() function should
|
||||
// handle that. Now, this could be combined with the IsValid check,
|
||||
// above.
|
||||
ClearAllActions();
|
||||
return P_STATUS_NOTHING;
|
||||
}
|
||||
|
||||
// Still moving to oThing [ActionPickUpItem(oThing);] from below
|
||||
|
||||
return P_STATUS_REMOVEITEM;
|
||||
|
||||
} else {
|
||||
// find new trash
|
||||
|
||||
object oThing = GetNearestObject(OBJECT_TYPE_ITEM);
|
||||
SetLocalObject(OBJECT_SELF, "oThing", oThing);
|
||||
|
||||
if (!GetIsObjectValid(oThing)) { ClearAllActions(); return P_STATUS_NOTHING; }
|
||||
|
||||
|
||||
if (P_FLAG_WHINER)
|
||||
{
|
||||
string sMessage = "When will someone enforce those litter laws?";
|
||||
ActionSpeakString(sMessage);
|
||||
}
|
||||
|
||||
ActionMoveToObject(oThing,FALSE,1.0); // I want to walk there instead of run. Looks more natural to me for this job.
|
||||
ActionPickUpItem(oThing);
|
||||
}
|
||||
|
||||
return P_STATUS_REMOVEITEM; // want to return here
|
||||
}
|
||||
|
Reference in New Issue
Block a user