Message Spam

Revision as of 00:31, 25 February 2007 by imported>Mmmpld (link to alternate solution)

See Preventing messages for an alternate solution.




AVOIDING MESSAGE SPAM WITH INVENTORY OBJECTS by Guidobot


If like me, you think it is a pain seeing messages like "xxx Added" or "xxx Removed" then check this out.

Here's the basic idea for adding a single item:

set itemRef to PlaceAtMe MyModdedItemType 1 0 0
itemRef.Activate player

Notes:

1) This method should only be used to add non-persistant objects.

2) The issue about requiring separate calls to retain scripts on your objects is particularly pertinent here!

Here's a more specific version that allows N standard items to be added to your inventory (without message spam) using an in-game function script:

scn MyAddItemScript

; item type/number
short numItems
short itemType

; private
short runAdd
ref itemRef

Begin OnActivate

if numItems > 0
  set runAdd to 1
endif

End

Begin GameMode

if runAdd == 0
  Return
endif

if itemType == 0
  set itemRef to player.PlaceAtMe Gold001 1 0 0
elseif itemType == 1
  set itemRef to player.PlaceAtMe Lockpick 1 0 0
elseif itemType == 2
  set itemRef to player.PlaceAtMe RepairHammer 1 0 0
elseif itemType == 3
  set itemRef to player.PlaceAtMe Torch02 1 0 0
else
  set itemRef to 0
endif
if itemRef
  itemRef.Activate player
endif
set numItems to (numItems)-1
set runAdd to numItems

End

Then to use:

; some script - example
set MyAddItemFunc.numItems to 1+0.1*GetRandomPercent; 1-10 for number
set MyAddItemFunc.itemType to 0.04*GetRandomPercent; 0-3  for type
MyAddItemFunc.Activate player 1

Note: Because the actual adding of multiple objects happens in GameMode, nothing will happen until this current script ends. You could easily make it add one of these in the activate block and then N-1 others, or add more than one at a time in your GameMode, etc. Additionally, the GameMode block will only fire every ~30 seconds unless the IGF item is in the same cell as the player. This is just a quick example and as with all the code here you should experiment for yourself to see what works best for your needs.


To drop items from your inventory without message spam, you can use the Drop method since this does not create message spam as the RemoveItem method does. Note that the Drop method also does not fire the OnDrop method.

To remove an item that is in your inventory you will need your own copy of the object in-game, or more likely your own scripted object. This is best done with a global variable in case you have multiple copies. In this case the global variable is in the script attached to MyQuest and the item concerned is MyItem.

Begin GameMode
...
if MyQuest.RemoveMyItem > 0 && player.GetItemCount MyItem > 0
  set MyQuest.RemoveMyItem to (MyQuest.RemoveMyItem)-1
  RemoveMe
endif
...
End

This code will not do anything for an object (MyItem) not on a player. Since it may leave the MyQuest.RemoveMyItem set if not called appropriately you should make the object be removed silently thus:

set MyQuest.RemoveMyItem to player.GetItemCount MyItem

More general notes as FYI:

1) The particular objects used in the MyAddItemScript here are special and cannot be copied to objects that have the same game-play properties. They may be scripted but this is a very bad idea because of MOD conflicts and other possible issues. However, with some extra you can save a list of the object IDs (as an array or link-list) and call RemoveMe on the saved reference IDs.

2) True stacks of items, e.g. when created as a bunch with a single PlaceAtMe or AddItem call, can only be removed using RemoveItem since the base object script is not transferred. (Drop also works if you dont mind them at your feet.)

3) I'm still working on trying to find a way to avoid EquipItem spam for stacked objects. Individually created items will retain their unique script variables, including their own reference. Hence, you can remove a specific item from an inventory stack. Unfortunately this can mess with what OB thinks is the currently equipped item if an item of a stack is equipped, whether the actual equipped instance is the one removed or not. OBSE may have methods that can help out here.