Author Topic: Trash Can problem?  (Read 361 times)

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Trash Can problem?
« on: September 27, 2011, 11:02:55 pm »


               Hi all,

I'm using Axe's Killer Death System and it's a good thing I re-read the readme because he recommends that trash cans be scripted so that the dead body item can't be trashed. Problem is, I haven't the faintest idea how to script that, so I'm posting the trash can script here and maybe someone would be a sweetheart and fix that for me? '<img'>

void main()
{
    object oTrashCan = OBJECT_SELF;
    object oPlayer = GetPCSpeaker();
    string sFlag="";

    object oItemInTrash = GetFirstItemInInventory(oTrashCan);
    while(GetIsObjectValid(oItemInTrash) == TRUE)
    {
        //addition by MIAS
        if (GetPlotFlag(oItemInTrash)==TRUE)       sFlag=sFlag+"<PLOT>";
        if (GetItemCursedFlag(oItemInTrash)==TRUE) sFlag=sFlag+"<CURSED>";
        if (GetStolenFlag(oItemInTrash)==TRUE)     sFlag=sFlag+"<STOLEN>";
        if (sFlag!="") SendMessageToAllDMs("Player " + GetName(oPlayer) + " trashed an item in area " +GetName(GetArea(oPlayer)) + " flagged as: " +sFlag);
        //End addition

        DestroyObject(oItemInTrash);
        oItemInTrash = GetNextItemInInventory(oTrashCan);
    }
}





Thank you in advance. '<img'>
               
               

               
            

Legacy_Axe_Murderer

  • Full Member
  • ***
  • Posts: 199
  • Karma: +0/-0
Trash Can problem?
« Reply #1 on: September 28, 2011, 03:03:12 pm »


               This modification will ensure that no KDS1 dead body item or death token item will be destroyed by that script. It simply checks the item's resref and only when it does not match one of the blueprints reserved for use by KDS1 items will it allow your cleanup code to run and get rid of the item.
[nwscript]
#include "_kds1_inc"
 
void main()
{
    object oTrashCan = OBJECT_SELF;
    object oPlayer = GetPCSpeaker();

    object oItemInTrash = GetFirstItemInInventory( oTrashCan );
    while( GetIsObjectValid( oItemInTrash ) )
    {
        if( (GetResRef( oItemInTrash ) != DEAD_PC_ITEM_RESREF ) &&
            (GetResRef( oItemInTrash ) != DEATH_TOKEN_RESREF)  )
        {
           //addition by MIAS
           string sFlag = "";
           if( GetPlotFlag( oItemInTrash ) )              sFlag += "<PLOT>";
           if( GetItemCursedFlag( oItemInTrash ) ) sFlag += "<CURSED>";
           if( GetStolenFlag( oItemInTrash ) )          sFlag += "<STOLEN>";
           if( sFlag != "" ) SendMessageToAllDMs( "Player " +GetName( oPlayer ) +" trashed an item in area " +GetName( GetArea( oPlayer ) ) +" flagged as: " +sFlag );
           //End addition

           DestroyObject( oItemInTrash );
        }
       
        oItemInTrash = GetNextItemInInventory( oTrashCan );
    }
}[/nwscript]

The check for the death token tag is probably unnecessary because, as I recall, I programmed the tag-based script for those such that they get destroyed automatically when you lose them from your inventory, but it doesn't hurt to check I suppose. Actually the proper thing to do should a death token ever show up in a trash can would be to destroy it since it should never be there to begin with, so maybe that death token check should be removed to be positive they get wasted too. But as I said, it should not matter because that situation is never expected to happen.

Thus simply using:
[nwscript]
    ...
    {
        if( (GetResRef( oItemInTrash ) != DEAD_PC_ITEM_RESREF ) )
        { ...[/nwscript]

instead is the most correct way to go.
               
               

               


                     Modifié par Axe_Murderer, 28 septembre 2011 - 03:28 .
                     
                  


            

Legacy_Axe_Murderer

  • Full Member
  • ***
  • Posts: 199
  • Karma: +0/-0
Trash Can problem?
« Reply #2 on: September 28, 2011, 03:39:58 pm »


               After thinking about this some more I believe I coded the system so that you cannot put a dead PC's body into a placeable. You should test that to be sure...but if I'm remembering correctly then your script, like with the death token item, should also never encounter a dead body item when iterating thru items inside a trash can and so the check would be completely unnecessary.

There is the possibility however that you could potentially put the body into a sack in your inventory and then put the sack containing the body into a trash can, and that would get a body into a placeable. If you can do that then its really a bug with the system and I'm not sure what would happen. I know my code does not go searching thru all placeables and sacks on the ground throughout the module when looking for a dead body item. So should that ever occur, the system may not be able to find the item later on when it needs to turn the item back into a dead creature or restore the player where his body is located.

I seem to remember making the tag-based script for the dead body item put the item on the ground where you are standing whenever you lose one from your inventory. When (if) it does that then it should be destroying the one you're losing (even if it is inside a sack you're losing). and that would straighten everything out for you automagically. But I'm thinking that if you put a bag containing one into a placeable (or even on the ground) you might end up with one on the ground and a duplicate one inside the sack...in which case you would want the trash can to destroy it for you rather than preserve it (if the sack is put in the trash can). You'll have to test this out to see what actually happens. Just put a dead body into a sack and then put the sack into a placeable like an empty barrel or crate (one without any scripts at all on it... i.e. not a trashcan). Try also simply placing the sack on the ground too. If I did things right, then you should see the item show up on the ground where you are standing but not in the placeable or in the sack or in the sack inside the placeable. If the system lets you put one into a placeable or into a sack on the ground or into a sack inside a placeable, see what happens when you try to come back from purg in those scenarios.

Test this to see what the system does about it then I can give you better advice about what, if anything, you need to do elsewhere.
               
               

               


                     Modifié par Axe_Murderer, 28 septembre 2011 - 03:48 .
                     
                  


            

Legacy_archer4217

  • Full Member
  • ***
  • Posts: 206
  • Karma: +0/-0
Trash Can problem?
« Reply #3 on: September 29, 2011, 08:49:07 pm »


               Hiya Axe sweetie,
It's always a pleasure to hear from you. '<img'>

So, here's my problem now. I'm trying your suggestion to test the trash barrel with a body by killing off one of my characters and logging in another to get the body....however, when I log in the second character, there's no body. So, I'm wondering if my CleanArea script is destroying it? Here's the script I'm using. If it is the problem, how can it be fixed?

/*******************************************************************************
* lc_area_exit
*
* by LasCivious Sept 2004
* Called by area's OnExit event.  Clears area encounters, dropped items,
* stores & cleans placeable inventories if no PC is present for a length of time.
*******************************************************************************/

// Set this to FALSE if you do not want placeable inventories cleared
int nClearPlaceInv = TRUE;
// Set the amount of time to wait for cleaning here in seconds
float fDelayTime = 300.0;

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

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

   while(GetIsObjectValid(oTrash)) {
     string sTagPrefix = GetStringLeft(GetTag(oTrash), 15);
     // Clear remains, dropped items
     if(GetObjectType(oTrash)==OBJECT_TYPE_ITEM ||
        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);
          }
        }
      }
      // Clear encounters
      else if (GetIsEncounterCreature(oTrash) ||
               sTagPrefix == "PWFSE_SPAWNERID")
      {
        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);
  }
}

Many thanks for your help. '<img'>
               
               

               
            

Legacy_Axe_Murderer

  • Full Member
  • ***
  • Posts: 199
  • Karma: +0/-0
Trash Can problem?
« Reply #4 on: September 30, 2011, 08:45:20 am »


               Verify that your OnClientLeave script is calling KDS1OnClientLeave and your OnClientEnter is calling KDS1OnClientEnter.
Modify your script to look like so:
[nwscript]
#include "_kds1_inc"

/*******************************************************************************
* lc_area_exit
*
* by LasCivious Sept 2004
* Called by area's OnExit event.  Clears area encounters, dropped items,
* stores & cleans placeable inventories if no PC is present for a length of time.
*******************************************************************************/

// Set this to FALSE if you do not want placeable inventories cleared
int nClearPlaceInv = TRUE;
// Set the amount of time to wait for cleaning here in seconds
float fDelayTime = 300.0;

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

  object oTrash = GetFirstObjectInArea(oArea);
  object oInvItem;
   while(GetIsObjectValid(oTrash)) {
     string sTagPrefix = GetStringLeft(GetTag(oTrash), 15);

     // Clear remains, dropped items
     if( (GetObjectType(oTrash)==OBJECT_TYPE_ITEM ||
          GetStringLowerCase(GetName(oTrash)) == "remains") &&
          (GetResRef( oTrash ) != DEAD_PC_ITEM_RESREF) ) {
          AssignCommand(oTrash, SetIsDestroyable(TRUE));
          if (GetHasInventory(oTrash)) {
            oInvItem = GetFirstItemInInventory(oTrash);
            while(GetIsObjectValid(oInvItem)) {
              if( GetResRef( oInvItem ) != DEAD_PC_ITEM_RESREF) 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)) {
            if( GetResRef( oInvItem ) != DEAD_PC_ITEM_RESREF) DestroyObject(oInvItem,0.0);
            oInvItem = GetNextItemInInventory(oTrash);
          }
        }
      }

      // Clear encounters
      else if (GetIsEncounterCreature(oTrash) ||
               sTagPrefix == "PWFSE_SPAWNERID")
      {
        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);
  }
}[/nwscript]

I'm not sure testing by yourself like that (where you must log out to get another character) will be sufficient to test this properly. You really need two actual players online during the entire test because the system does special things with the dead bodies when a player who dies logs out before leaving purg or when a player who is carrying a dead PC logs out before that dead PC returns from purg.
               
               

               


                     Modifié par Axe_Murderer, 30 septembre 2011 - 08:06 .