/* 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 (fDist2.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 }