Difference between revisions of "Message Spam"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>Ra5946
imported>QQuix
(Updated information on OBSE spamless functions)
 
(14 intermediate revisions by 7 users not shown)
Line 1: Line 1:
AVOIDING MESSAGE SPAM FOR INVENTORY OBJECTS By guidobot101
__NOTOC__[[Category: Useful Code]]
Tes4 displays messages to the player whenever: 1) spells are added to, 2) items are added to or removed from the player. For some scripts such messages are very undesirable (e.g. for an alchemical sorters which adds/removes many items). Hence, message "spam". There are several techniques for avoiding this spam.


If, like me, you think it is a pain seeing messages like "xxx Added" or "xxx Removed" try something like this.
===AddItem - aTemp Container===
When adding items to the player, spam can be avoided by first adding the item to a container, and then removing the contents from the container to the player. This works because unlike addItem, [[RemoveAllItems]] is silent.
<pre>
tempContainerRef.addItem deathDagger 1
tempContainerRef.removeAllItems player</pre>


Here's the basic idea for adding a single item:
If you're using [[Glossary#C|Cobl]], you can use '''cobGenXFerRef''' for the temporary container -- it's defined for just this sort of use.


'''Note:''' Do ''not'' wait a frame to remove the item to the player. If you do, you run the chance of running the item's script, which in rare circumstances can cause problems.


CODE
===Message Queue Overloading===
Simplest technique is to overload the message queue by sending the exact same message twice in a row <i>before</i> the offending add or remove line, <i>i.e.</i>
<pre>;--No messages.
message " "
message " "
addItem myItem, 1


;--OR... Covering message...
message "[You've been pickpocketed!]"
message "[You've been pickpocketed!]"
addItem myItem, 1</pre>


set itemRef to PlaceAtMe MyModdedItemType 1 0 0
There's no obvious reason why this does or should work, but it does. :shrug: The message that is sent (including a blank message) will still display for the usual time, but messages that would ordinarily appear after it seem to be discarded -- i.e. they never enter the queue.
itemRef.Activate player


'''Con:''' The downside of this approach is that it may block more messages than you want to block. It basically nukes the queue for a second or two -- any message sent by any script or action during that period will be lost.


Notes:
'''Con:''' Some UI mods add an Oblivion icon for all messages. This icon will still appear for the duration of the message - defeating the purpose of the blank message.
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!
===OBSE Commands===
OBSE provides the following spam free versions as alternatives for vanilla functions that generate spam messages and sound:


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:


CODE
These two functions do not span messages when adding and removing spells:
*[[AddSpellNS]]
*[[RemoveSpellNS]]




scn MyAddItemScript
These two functions do not span messages when equipping and unequipping:
*[[EquipItemNS]]
; item type/number
*[[UnequipItemNS]]
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:
These functions do not span messages and do not generate the corresponding sound:
*[[AddItemNS]]
*[[RemoveItemNS]]
*[[EquipItemSilent]]
*[[UnequipItemSilent]]


CODE




; 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


===Item Activate===
When adding items whose "activate" action results in being added to inventory (e.g. armor, but not books), you can use activate in a script.


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. 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.
<pre>someItemRef.activate player</pre>


-----------------------
'''Pro/Con:''' Requires that you have a ref for the item. On the plus side,this means that if you want the player to pick up a specific pre-existing, placed item, you can do that.
 
To drop items from your inventory without message spam, you can use the Drop method since this does not create message spam. Note that Drop does not fire the OnDrop method by default.
 
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.
 
CODE
 
 
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 (MyItem) object 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:
 
CODE
 
 
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 (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.
 
[[Category: Useful Code]]

Latest revision as of 08:17, 17 November 2012

Tes4 displays messages to the player whenever: 1) spells are added to, 2) items are added to or removed from the player. For some scripts such messages are very undesirable (e.g. for an alchemical sorters which adds/removes many items). Hence, message "spam". There are several techniques for avoiding this spam.

AddItem - aTemp Container[edit | edit source]

When adding items to the player, spam can be avoided by first adding the item to a container, and then removing the contents from the container to the player. This works because unlike addItem, RemoveAllItems is silent.

tempContainerRef.addItem deathDagger 1
tempContainerRef.removeAllItems player

If you're using Cobl, you can use cobGenXFerRef for the temporary container -- it's defined for just this sort of use.

Note: Do not wait a frame to remove the item to the player. If you do, you run the chance of running the item's script, which in rare circumstances can cause problems.

Message Queue Overloading[edit | edit source]

Simplest technique is to overload the message queue by sending the exact same message twice in a row before the offending add or remove line, i.e.

;--No messages.
message " "
message " "
addItem myItem, 1

;--OR... Covering message...
message "[You've been pickpocketed!]"
message "[You've been pickpocketed!]"
addItem myItem, 1

There's no obvious reason why this does or should work, but it does. :shrug: The message that is sent (including a blank message) will still display for the usual time, but messages that would ordinarily appear after it seem to be discarded -- i.e. they never enter the queue.

Con: The downside of this approach is that it may block more messages than you want to block. It basically nukes the queue for a second or two -- any message sent by any script or action during that period will be lost.

Con: Some UI mods add an Oblivion icon for all messages. This icon will still appear for the duration of the message - defeating the purpose of the blank message.

OBSE Commands[edit | edit source]

OBSE provides the following spam free versions as alternatives for vanilla functions that generate spam messages and sound:


These two functions do not span messages when adding and removing spells:


These two functions do not span messages when equipping and unequipping:


These functions do not span messages and do not generate the corresponding sound:



Item Activate[edit | edit source]

When adding items whose "activate" action results in being added to inventory (e.g. armor, but not books), you can use activate in a script.

someItemRef.activate player

Pro/Con: Requires that you have a ref for the item. On the plus side,this means that if you want the player to pick up a specific pre-existing, placed item, you can do that.