Author Topic: Area Cleaner / Not a Trash Bin  (Read 527 times)

Legacy_L0BSTER

  • Newbie
  • *
  • Posts: 32
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« on: March 29, 2011, 10:03:36 pm »


               Dear script's ....

I am doing alterations in one of the PW World's module with lots of maps and Monsters and i would like to ask
does anyone have a working Area Cleaner in one of there Module's'Image 

If so could i have some help understanding how it works.
what i want is ( To kill monster's and get there Items and money) after you have left the map, The map makes an Encounter monster that has the loot that was drop from the monsters



'Image 
Thank you for Reading!!

L0BSTER
               
               

               
            

Legacy_OXELUE

  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #1 on: March 29, 2011, 10:12:01 pm »


               Sounds like your after a cleaner that collects items into a pile and not destroy.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #2 on: March 30, 2011, 01:45:20 am »


               This is the one we were using. It was provided by Axe Murderer if I remember right(It does have some commenting too):


// Area OnExit script.
//:://///////////////////////

const float CLEANER_TIMER_DELAY = 10.0f; // 10 seconds after last PC leaves the area is cleaned.


// Function to determine if any PCs are in an area.
int GetIsPCInArea( object oArea = OBJECT_SELF)
{ if( !GetIsObjectValid( oArea) || (GetArea( oArea) != oArea)) return FALSE;

  object oInArea = GetFirstObjectInArea( oArea);
  if( !GetIsObjectValid( oInArea)) return FALSE;
  if( GetIsPC( oInArea)) return TRUE;
  return GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oInArea));
}


// Function to Clear the area of bodybags, loose items laying on the ground, and creatures spawned by encounters.
void CleanArea( object oArea)
{ if( !GetIsObjectValid( oArea) || (GetArea( oArea) != oArea)) return;

  // Don't do anything if there is a player in the area. Need to check again in case a player entered during the delay.
  if( GetIsPCInArea()) return;

  // Clean up the area.
  object oObject = GetFirstObjectInArea( oArea);
  while(GetIsObjectValid( oObject))
  {
  if((GetTag(oObject) == "BodyBag")
    || ((GetObjectType(oObject) == OBJECT_TYPE_CREATURE)
    && GetIsEncounterCreature(oObject))
    || ((GetObjectType(oObject) == OBJECT_TYPE_ITEM)))
    {
    if(GetHasInventory(oObject))
      {
      object oItem = GetFirstItemInInventory(oObject);
      while(GetIsObjectValid(oItem))
        {
        DestroyObject(oItem);
        oItem = GetNextItemInInventory( oObject);
        }
       }
     DestroyObject( oObject, 0.1f);
     }
   oObject = GetNextObjectInArea( oArea);
  }
}


// OnExit main function.
void main()
{ // Don't do anything if there is a player in the area.
  if( GetIsPCInArea()) return;

  // No players in the area do the area clean-up after a 10 second delay.
  DelayCommand( CLEANER_TIMER_DELAY, CleanArea( OBJECT_SELF));
}


Hope that helps. Good luck.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #3 on: March 30, 2011, 02:10:12 am »


               GoG: your GetIsPCInArea function is not correct. It was but patch 1.69 (probably) changed GetNearestCreature behavior. So your function will return true even if there is any dead PC.

Im using this:

int GetNumPCsInArea(object oArea)
{
 if(!GetIsObjectValid(oArea) || GetArea(oArea) != oArea)
 {
 return 0;
 }
object oPC = GetFirstPC();
int nCount;
 while(GetIsObjectValid(oPC))
 {
  if(GetArea(oPC) == oArea)
  {
  nCount++;
  }
 oPC = GetNextPC();
 }
return nCount;
}

and then if(GetNumPCsInArea(OBJECT_SELF) < 1)
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #4 on: March 30, 2011, 02:17:25 am »


               

ShaDoOoW wrote...

GoG: your GetIsPCInArea function is not correct. It was but patch 1.69 (probably) changed GetNearestCreature behavior. So your function will return true even if there is any dead PC.


Interesting since it worked in our PW with 1.69....

Edit: Oh yes..if there is a dead player in the area the items should NOT be cleaned up. This was the desired behavior for us but that is a matter of prefference. Not correctness. And doesn't your function also count dead players?':blink:'
               
               

               


                     Modifié par GhostOfGod, 30 mars 2011 - 02:06 .
                     
                  


            

Legacy_OXELUE

  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #5 on: March 30, 2011, 02:36:06 am »


               I thought Lobster wanted a cleaner to collect the items for the player.
It sounds like after the encounters are all dead the player leaves the area, the cleaner is summoned and collects the items into a pile to be picked up player.
I did see some thing like this in a mod were the cleaner was a chest which the player could kill.
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #6 on: March 30, 2011, 02:57:12 am »


               Ah yes. Looks like you are right OXELUE. I misread the post. I will see about coming up with something unless someone else beats me to it. Don't have time just now.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #7 on: March 30, 2011, 03:39:21 am »


               

GhostOfGod wrote...

Interesting
since it worked in our PW with 1.69....

Edit: Oh yes..if there
is a dead player in the area the items should NOT be cleaned up. This
was the desired behavior for us but that is a matter of prefference. Not
correctness. And doesn't your function also count dead players?[smilie]../../../images/forum/emoticons/andy.png[/smilie]

Well maybe I explained it wrong, so I make a example with the code:

Prior to some patch, very probably 1.69 the line:

GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oInArea)

returned any player no matter if he was alive or dead, but since 1.69 this works  as you would wrote:

GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, oInArea, CREATURE_TYPE_IS_ALIVE, TRUE)

So if there is any dead player, your function will not take him in consideration. The reason why it works for you is that you got there GetIsEncounterCreature condition, but if you wouldn't checked fot encounter creature, then dead players could lost all their items which is what happened to me with area cleaner I made for one guy here.
               
               

               


                     Modifié par ShaDoOoW, 30 mars 2011 - 02:41 .
                     
                  


            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #8 on: March 30, 2011, 03:50:07 am »


               OOooh....so by default the function only sees living PCs now unless you check for the other parameters. Gotcha.

Ok and sorry for taking over your thread LOBSTER.

Back to LOBSTERS original question.....
               
               

               


                     Modifié par GhostOfGod, 30 mars 2011 - 02:51 .
                     
                  


            

Legacy_OXELUE

  • Newbie
  • *
  • Posts: 6
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #9 on: April 05, 2011, 04:57:05 am »


               bump
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #10 on: April 05, 2011, 05:15:09 am »


               Well..from a scripting perspective there are all kinds of things that need to be figured out before something like this can be done.

-When people leave the area, all the encounter monsters/bodybags are destroyed but their items are moved to a new encounter monster...but if all the players left the area..what's the point in making the encounter monster there? Or is this monster supposed to be created somewhere else?
-What happens when a player leaves the area and the new encounter monster with all the items is still there? Then all of the items from him will go to a second new encounter monster creating a sort of loop that keeps passing on the items?
-Is the new monster with all the items supposed to be created when a player re-enters the area?
-If the new monster with all the items is in the area..do the other regular encounter monsters still spawn too?

Probably some other stuff I didn't think about yet but you can see how there are a lot of factors that can make the scripting go in all kinds of different directions.

Most likely this would use a cleanup script like ones posted above, that copy each item before it is destroyed to a chest somewhere. Then in the OnSpawn script of the new encounter moster you would loop through the items in the chest and copy then to the monster and destroy from the chest.
               
               

               


                     Modifié par GhostOfGod, 05 avril 2011 - 04:22 .
                     
                  


            

Legacy_Ryuhi2000

  • Full Member
  • ***
  • Posts: 159
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #11 on: April 05, 2011, 06:03:38 am »


               GoG from my understanding of it most of that is answered by lobster.

"what i want is To kill monster's and get there Items and money after you have left the map,
The map makes an Encounter monster that has the loot that was drop from the monsters"

so the easiest answer to lobsters question would be below this i think:

to have a encounter crature grabbing the loot and gold in the area on the creatures hearbeat, then moving the contents of the encounter monsters inventory to the players invetory on area exit, the encounter monster would be created on area enter, making a new encounter monster for each player entering the area, and then destroyed when the player leaves the area after its inventory has been moved to the player?
               
               

               


                     Modifié par Ryuhi2000, 05 avril 2011 - 05:05 .
                     
                  


            

Legacy_L0BSTER

  • Newbie
  • *
  • Posts: 32
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #12 on: April 10, 2011, 04:25:25 pm »


               I have readed all the post so far and it sound's like i't not possable to make a Area cleaner that picks all the loot up on the floor after you have left the map and not destroy it

i was hopeing to make a monster that appers after you have left the map and picks everything off the floor even Bodybags and the Player find's it kills it!

Thank you for reading

L0BSTER  XxX
               
               

               
            

Legacy_GhostOfGod

  • Hero Member
  • *****
  • Posts: 1490
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #13 on: April 10, 2011, 05:02:54 pm »


               No this is possible...but once again it's how you want to go about it.
If there is no one in the area to see a monster walking around picking up the loot that was left behind..then why waste system resources on scripting a monster to literally do this? What if the monster only picked up one item since a new player came into the area..etc? So once again the best way to do this would probably be to Clean the area once there are no players in the area, put all the contents into a inaccessible container, and then when a player enters the area, after it being empty, the cleaner monster spawns and all the items from that container are transferred over to the monster.
And again there are problems or issues that need to be figured out before you can script this.
-Can more than one of these cleaner monsters spawn?
-What if a player leaves the area and did not kill the cleaner monster? Do it's contents then get passed on to a new cleaner monster? Does the monster get destroyed?
-Do the other spawns in the area still spawn if the cleaner monster is there?
-Does the cleaner monster go around picking up stuff while the player is fighting in the area if the above is true?
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
Area Cleaner / Not a Trash Bin
« Reply #14 on: April 10, 2011, 06:58:37 pm »


               Don't forget left over living or dead horses. '<img'>

That is if you are using horses...

//Script Name: ag_area_clean (Horse Edition)
//////////////////////////////////////////
//Created by: Alan_Guile
//Modified By: Genisys (Guile) <<< Not Alan Guile
//Modified On: 9/17/08
/////////////////////////////////////////
/*
This script goes in the OnExit event
for all areas within your module, if
you want to clean inventories of placeable
objects, in some areas I suggest you save
this under a new name FIRST!

This script destroys all horses which are
not assigned to a PC left in the area
IF there are no more PCs in the area the
script will fire.

*/
////////////////////////////////////////
//Required Horse Include
#include "x3_inc_horse"

////////////////////////////////////////

//OPTIONS/////

//Note: This is a very important script, it should go on the exit event of
//all area you create.  (with some exceptions)  This reduces lagg too!

//IMPORTANT: If you change this option change the script name! (Save As)
// Set this to TRUE if you want placeable object's inventories cleared
int nClearPlaceInv = FALSE;

// Set the amount of time to wait for cleaning here in seconds
float fDelayTime = 5.0;

/////////////////WARNING: DON'T TOUCH ANYTHING BELOW!!!////////////

void CleanArea(object oArea)
{
  object oTrash = GetFirstObjectInArea(oArea);
  object oInvItem;

  //Check for PCs
  object oPC = GetFirstPC();
  while (GetIsObjectValid(oPC)) {
    if(!GetIsDM(oPC)||!GetIsDMPossessed(oPC))
    {
    if  (GetArea(oPC) == oArea) {
      DeleteLocalInt(oArea, "CleanArea");
      return;
    }
    }
    oPC = GetNextPC();
  }

   while(GetIsObjectValid(oTrash)) {
     string sTag = GetTag(oTrash);
     string sTagPrefix = GetStringLeft(GetTag(oTrash), 15);
     // Clear remains, dropped items
     if(GetObjectType(oTrash)==OBJECT_TYPE_ITEM ||
        sTag == "drow_ass" ||
        GetStringLowerCase(GetName(oTrash)) == "remains") {
          AssignCommand(oTrash, SetIsDestroyable(TRUE));
          if (GetHasInventory(oTrash)) {
            oInvItem = GetFirstItemInInventory(oTrash);
            while(GetIsObjectValid(oInvItem)) {
              DestroyObject(oInvItem,0.0);
              oInvItem = GetNextItemInInventory(oTrash);
            }
          }
          else DestroyObject(oTrash, 0.0);
      }
      // Clear placeable inventories
      if(GetObjectType(oTrash)==OBJECT_TYPE_PLACEABLE &&
         nClearPlaceInv == TRUE) {
        if (GetHasInventory(oTrash))
        {
          object oInvItem = GetFirstItemInInventory(oTrash);
          while(GetIsObjectValid(oInvItem)) {
            DestroyObject(oInvItem,0.0);
            oInvItem = GetNextItemInInventory(oTrash);
          }
        }
      }

      else if (GetIsEncounterCreature(oTrash) ||
               sTag == "drow_ass" ||
               sTagPrefix == "PWFSE_SPAWNERID")
      {
        AssignCommand(oTrash, SetIsDestroyable(TRUE));
        DestroyObject(oTrash, 0.0);
      }

      // If it's a mountable creature!
      else if (HorseGetIsAMount(oTrash))
      {
       //If the mount has no master!
       if(HorseGetOwner(oTrash)== OBJECT_INVALID)
       {
        AssignCommand(oTrash, SetIsDestroyable(TRUE));
        DestroyObject(oTrash, 0.0);
       }
      }



      oTrash = GetNextObjectInArea(oArea);
   }
   DeleteLocalInt(oArea, "CleanArea");
}

void main()
{
  object oArea = OBJECT_SELF;
  object oPC = GetExitingObject();
  if (!GetIsPC(oPC)) return;

  if (GetLocalInt(oArea, "CleanArea") != 1)
  {
    DelayCommand(fDelayTime, CleanArea(oArea));
    SetLocalInt(oArea, "CleanArea", 1);
  }

}
               
               

               


                     Modifié par _Guile, 10 avril 2011 - 06:01 .