Jump to content

Using Scripts to automate looting containers...


Recommended Posts

OK, after many hours of trying everything my tiny mortal brain can think of, I have reached the following conclusions:

 

1.A scripted item with an OnAdd block mandates that you use the AddItem/AddItemNS command to give it to the player, or its OnAdd block will not fire.

2. If you want stolen items to maintain their state, you have to do it manually if the item itself doesn't have the ownership set. The ownership data could be on the chest itself or the cell you are in. Using the IsOFFLimits command will tell you if you have to do this or not.

3. If a scripted item has any instance data, there is no way to copy it to the player and maintain that state and ensure the OnAdd block fires.

4. AddItemNS can be used only using the BaseID of an object, unless it is a Cloned-Form. If done on the RefID of a normal form it does nothing. It just ignores the command and goes to the next with no way for you to know. If done on a cloned form it magically duplicates that object (and all of its instance state.

5.Doing the IsOffLimits check on the items itself always fails. It works on the container.

6. There is no way to set the Required Rank when the owner is a faction. It is READ-ONLY?

7. There is no way to check if the items has an enchantment on it? I couldn't get GetEnchantment (or anything else) to work here.

 

Given all of that here is my current logic:

foreach rItem <- rContainer
   set rItemBase to rItem.GetBaseObject
   if bTakeIt == 1      ; If the above logic determines that this item is one the player wants to loot
    set rOwner to rItem.GetOwner
    if rContainer.IsOffLimits && rOwner == 0
        set rOwner to rContainer.GetOwner
        if rOwner
            rItem.SetOwnership rOwner
            PrintC"Item %n is OFF-LIMITS owner set to %n!" rItemBase, rOwner
        else
            set rOwner to player.getParentCellOwner
            if rOwner
                rItem.SetOwnership rOwner
                PrintC"Item %n is OFF-LIMITS owner set to %n!" rItemBase, rOwner
            else
                set bTakeit to 0  ; NO WAY TO take it if we can't figure out how the owner is
                PrintC"Item %n is OFF-LIMITS but no owner found!" rItemBase
                set bUserWarned to 1   ; Flag to warn the user after all items are processed
            endif
        endif
    endif     

    if bTakeIt == 1
        Set iNumRefs to rItem.GetRefCount
        ;set iNumItemsPlayerBefore to player.GetItemCount rItemBase
        if rItem.IsScripted == 0 || rItemBase == BoarMeat
            ;PrintC"Adding item %n (count %g) to player" rItemBase, iNumRefs   
            rItem.RemovemeIR player
        else
            PrintC"Adding SCRIPTED item %n (count %g) to player" rItemBase, iNumRefs
            if rItem.IsClonedForm
                player.AddItemNS rItem iNumRefs
                PrintC"   IsClonedForm YES"
                rItem.RemoveMeIR
            elseif iObjType == 20 || iObjType == 33  ; Armor or Weapon
                if iItemHealthDifference == 0   ; Difference between Base object health and the current health of the reference
                    PrintC"   Unused Scripted Weapon/Armor Added"
                    player.AddItemNS rItemBase iNumRefs
                    rItem.RemoveMeIR
             else
                 set bUserWarned to 1
             endif
      else
          PrintC"   Scripted OTHER Added"         
          player.AddItemNS rItemBase iNumRefs
          rItem.RemoveMeIR
      endif        
 endif
loop
Edited by GamerRick
Link to comment
Share on other sites

 

4. AddItemNS can be used only using the BaseID of an object, unless it is a Cloned-Form. If done on the RefID of a normal form it does nothing. It just ignores the command and goes to the next with no way for you to know. If done on a cloned form it magically duplicates that object (and all of its instance state.

The baseID/Form ID depends of the load order which varies from one player to another. You should always use the editor ID to add something since it doesn't chaneg with the load order.

Link to comment
Share on other sites

@Oblivionaddicted:

Unfortunately using EditorID is out of question - he evidently wants loot things also from another mods and even OBSE command GetEditorID can't retrieve editorID of an object (because they aren't loaded at run-time). Besides editorID will still point to base object or object placed somewhere, which is removed while placed in container/inventory. In inventory will be created as anew and so there's no even guarantee that it will have same FormID.

Link to comment
Share on other sites

Most of the OBSE commands wants the ID, not the ref. What is important to know about what a reference is, it is a form of box with properties, that the object are placed in.

Do use the Wiki when you use OBSE functions, as I have made this mistake many times: GetEnchantment

Ref Enchantment

Let Enchantment := Reference.GetEnchantment 

That never works, not if the object is in a container. I do not know when to use the syntax like this but the wiki says on references but when to use it in game? How do we find the object? With a spell? That does not work on misc items or weaons or armors. GetFisrstRef does and the crosshair, but I do not know if the crosshair will get a reference if you point at an object, besides actors. https://cs.elderscrolls.com/index.php?title=GetCrosshairRef . The last comment is interesting however. What will be registred with this function really besides actor? I use this to add targets to my companions. I add targets to them with this and GetFirstRef / GetNextRef, every 3rd s.

Ref Enchantment

Let Enchantment := GetEnchantment Object 

Works perfect if the Object is in a container.

 

almost all enchanted stuff in game has their own ID, but if it is a player made or script enchanted object, then it is best to move it to the container first and then check it with the syntax above. This is how most OBSE commands works.

 

We can target item references with Telekinesis but how that works is beyond me but I suspect it use something similar to GetCrosshairRef. I made some testes with adding scripts to a telekenesis spell, but I never managed the get the reference. Only GetFirstRef and GetCrosshairRef works for stuff outside a container, in the game world.

Edited by Pellape
Link to comment
Share on other sites

I edited the code to show where I am getting my two references:

 

rItem = Inventory Reference (IR) returned from the foreach command

rItemBase = Base Object Reference by doing rItem.GetBaseObject

 

So, I am just differentiating between those two. The IR enables you to do the commands that are specific to it. In this case it's RemoveMeIR. The problem is that RemoveMeIR and CopyIR work on everything but do not cause the scripted object to call its OnAdd block. The AddItemNS rItem command ONLY works on a cloned form (like my weapons and armor that were all enchanted by me). Otherwise you gotta do AddItemNS rItemBase.

 

I also just realized that I need to avoid doing the Ownership stuff when looting an NPC or Creature you kill in an interior that is owned by another NPC or Faction. How can I tell if the container I am searching is that of an NPC/Creature??

 

 

For the enchantment stuff, I will have to try again, but I thought I tried: GetEnchantment rItemBase. I tried it on clothing, weapons, armor, and misc items without success.

The documentation says it doesn't work on Arrows. Is there one that does? Or do I have to use the let command here?

 

i revert to using OOP terminology when I can't think of how else to say it. :confused:

 

Thanks!

Edited by GamerRick
Link to comment
Share on other sites

It is always best to use LET if it is an OBSE function or command you are using. Sometimes it only works with SET. I think I did a post about when it works or not a while ago in the CS forum. https://forums.nexusmods.com/index.php?/topic/11402098-set-and-let-observations-and-conclutions/

Link to comment
Share on other sites

It worked!

 

I was able to do this for a stack of arrows:

ref rEchantment

let rEnchantment := GetEnchantment rItemBase

I ran into another snag. If I allow the command to work when pickpocketing or stealing from a container right in front of the owner, taking the items with my routine doesn't cause any alarms to go off. So, I am going to disable my code for pickpocketing and stealing. I mainly wanted it so I could loot dead NPCs and Creatures quickly without taking the worthless stuff.

Link to comment
Share on other sites

Cool. I do have 2 different loot spells, well 3 in my mod and this spell, DL and load it in CS and see: https://www.nexusmods.com/oblivion/mods/19111 The Book Looting Spell, use 2 objects to detect the player.

  • A jewel that drops close to the player when your use the spell
  • An NPC that detects if the player are stealing

Take a peek how it implements the jewel and the NPC. I have forgotten exact how it works. I do know it works. The NPC is called BookShelf for some odd reason but it is that NPC that reports the player for stealing. It is a very good spell really. What I did, was to include all other object types in to that spell.

 

My own loot spells do not detect the players looting at all. I could include it I guess, but I have no need of it. The only reason to keep the stolen flag is if we need to get the fenced sum up, to be able to continue the TG quest line, otherwise it is rather pointless.

Edited by Pellape
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...