Author Topic: Raising/Catching an "open bag" event  (Read 312 times)

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Raising/Catching an "open bag" event
« on: March 12, 2015, 09:44:53 pm »


               

Hey, I'm wondering if it's feasible? For example, if and when PC opens/closes his magic bag, catch the event and react accordingly in handler. Any idea?


 


 


Thanks


 


Kato



               
               

               
            

Legacy_Proleric

  • Hero Member
  • *****
  • Posts: 1750
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #1 on: March 12, 2015, 10:49:29 pm »


               I don't think you can do that in vanilla NWN, with regular bags, as there are no suitable UI events. IIRC bags don't even fire an event when their content is disturbed.
               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #2 on: March 12, 2015, 11:05:01 pm »


               

Ah, too bad then, thank you Proleric.



               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #3 on: March 13, 2015, 07:55:00 pm »


               

No OnOpen OnClose, but OnDisturbed is easily determined via OnAcquire



               
               

               
            

Legacy_meaglyn

  • Hero Member
  • *****
  • Posts: 1451
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #4 on: March 13, 2015, 08:07:51 pm »


               

How so? I don't think OnAcquire fires if the PC takes something out of a magic bag already in her inventory does it? Nor does on unacquire fire if something is moved from base inventory into a container in inventory. At least I don't remember seeing those events fire in these cases...



               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #5 on: March 13, 2015, 09:54:04 pm »


               


How so? I don't think OnAcquire fires if the PC takes something out of a magic bag already in her inventory does it? Nor does on unacquire fire if something is moved from base inventory into a container in inventory. At least I don't remember seeing those events fire in these cases...




doh! sorry I misread what is talked about...


               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #6 on: March 15, 2015, 08:41:48 pm »


               


Hey, I'm wondering if it's feasible? For example, if and when PC opens/closes his magic bag, catch the event and react accordingly in handler. Any idea?


 


 


Thanks


 


Kato




Depends. There is a way to do this, but it's pretty cpu-intensive, so I wouldn't recommend this for a PW. Proleric is correct about there being no custom-fit event for this - with or without nwnx, so far as I have seen. You can, however, always resort to the fallback, the heartbeat event. If you want to go more than every 6 seconds to more closely align the event with the addition/removal from the container, you could use a psuedo, but then you would really be slamming your module with extra load.


 


So, how to do this? Well, you can detect if a given item is in a container, using these two functions (which include CEP container item types, as well):


int GetItemIsContainer (object oItem) {
    switch (GetBaseItemType(oItem)) {
        case 23:
        case 67:
        case BASE_ITEM_CEP_THINBOX:
        case BASE_ITEM_CEP_SMALLBOX:
        case BASE_ITEM_LARGEBOX:
        return TRUE;
    }
    return FALSE;
}
 
object GetContainerOfItem (object oItem) {
    object oPossessor = GetItemPossessor(oItem);
    if (!GetIsObjectValid(oPossessor))
        return OBJECT_INVALID;

    object oContents, oCheck;
    object oContainer = GetFirstItemInInventory(oPossessor);
    while (GetIsObjectValid(oContainer)) {
        if (GetItemIsContainer(oContainer)) {
            oCheck = GetFirstItemInInventory(oContainer);
            while (GetIsObjectValid(oCheck)) {
                if (oCheck == oItem)
                    return oContainer;
                oCheck = GetNextItemInInventory(oContainer);
            }
        }
        oContainer = GetNextItemInInventory(oPossessor);
    }
    return OBJECT_INVALID;
}

 


From there, it's just a question of tracking object ids of the pcs items' containers (if any), storing them (I would probably recommend a hash with nwnx, if you have it), and checking to see if they have changed each heartbeat. If so, if the item's container has changed (to a new container, or none), you can fire the appropriate 'event' code.


 


We don't use these functions for this purpose on HG, but they still come in handy for people who try to exploit 'binding items' that attach to a pc, becoming undroppable, by 'binding them' while they are in a container, like so: 


    if (GetIsObjectValid(GetContainerOfItem(oItem))) {
        FloatingTextStringOnCreature("<cþ  >Your unlimited ammunition container cannot be used in a container.</c>", oPC, FALSE);
        return;
    }

 


Funky


               
               

               
            

Legacy_Kato -

  • Hero Member
  • *****
  • Posts: 747
  • Karma: +0/-0
Raising/Catching an "open bag" event
« Reply #7 on: March 15, 2015, 09:21:10 pm »


               

Hey Funky, that's clever and interesting indeed. I can see why you don't advise using the concept in a PW but the code snippets(and the infos) are giving me a few new ideas, thanks! '<img'>


 


 


Kato