Difference between revisions of "Talk:Activation Functions"
Jump to navigation
Jump to search
imported>Haama (Notes on remote-to-local activators) |
imported>Wrye m (Talk:Ingame Functions moved to Talk:Activation Functions: "Ingame" is too vague. There are already "ingame" functions, and there are several alternate ways to do functions (e.g. Stage Functions).) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 11: | Line 11: | ||
::Also, I have found that you can [http://www.bethsoft.com/bgsforums/index.php?showtopic=752330 constantly load a remote activator] (make it run every frame as if it were moved to the player) by changing a variable on the activator. It hasn't been throughly tested, but maybe it should be included? | ::Also, I have found that you can [http://www.bethsoft.com/bgsforums/index.php?showtopic=752330 constantly load a remote activator] (make it run every frame as if it were moved to the player) by changing a variable on the activator. It hasn't been throughly tested, but maybe it should be included? | ||
::--[[User:Haama|Haama]] 18:34, 10 September 2007 (EDT) | ::--[[User:Haama|Haama]] 18:34, 10 September 2007 (EDT) | ||
:::Interesting, but becareful about what you assume about the generality of 'activators'. I am still suspect about expecting an activator to be callable 1000 times in the same frame, especially if the OnActivate script is of any length. If this is true then you should be able to generate visible lag very easily (even w/o inventory redraws, etc.). | |||
:::--[[User:Guidobot|Guidobot]] 12:27, 13 September 2007 (EDT) | |||
Not at all, I don't see any FPS drop until I run it 2000 times, and even then it's only 1 FPS. What seems to be important are the functions used, not the number of lines. Here's the script: | |||
<pre>scn ITNumCheckerScript | |||
ref pItem | |||
short ItemCount | |||
short TempItemCount | |||
short DiffNum | |||
short InvPos | |||
short LinkedListTotal | |||
short LinkedListPos | |||
begin onActivate | |||
set LinkedListPos to (LinkedListPos + 1) | |||
if pItem | |||
set TempItemCount to (player.GetItemCount pItem) | |||
if TempItemCount | |||
set InvPos to (InvPos + 1) | |||
endif | |||
if (TempItemCount == ItemCount) | |||
return ;Don't need to worry about changing ItemCount, it's the same as TempItemCount | |||
elseif (TempItemCount < ItemCount) ;Lost Quantity | |||
SetStage ITInvChangesDecreasedList 0 | |||
SetStage ITInvChangesRemovedList 0 | |||
ITInvChangesRemovedList.Changes | |||
else ;if (TempItemCount > ItemCount) ;Gained Quantity | |||
SetStage ITInvChangesIncreasedList 0 | |||
SetStage ITInvChangesAddedList 0 | |||
endif | |||
set ItemCount to TempItemCount | |||
;Setup new spot if needed | |||
elseif (LinkedListPos > LinkedListTotal) | |||
set pItem to (player.GetInventoryObject InvPos) | |||
if (pItem == 0) ;No more items | |||
set ITListManager.Counter to 254 ;Wraps everything up | |||
return | |||
elseif (ITLinkedListCont.GetItemCount pItem) ;If the player has picked up an item(s) that they've already picked up, then it won't be in the expected position above, and instead an item that's already in the linked list will be referenced, so check against a container full of linked list items | |||
ITInvScanner.Activate player, 1 | |||
if (pItem == 0) ;No more items - just in case | |||
set ITListManager.Counter to 254 | |||
return | |||
endif | |||
endif | |||
set LinkedListTotal to (LinkedListTotal + 1) | |||
ITLinkedListCont.AddItem pItem 1 | |||
set ITInvChangesNewList.Changes to (ITInvChangesNewList.Changes + 1) | |||
SetStage ITInvChangesNewList ITInvChangesNewList.Changes | |||
set TempItemCount to (player.GetItemCount pItem) | |||
if TempItemCount | |||
set InvPos to (InvPos + 1) | |||
endif | |||
if (TempItemCount == ItemCount) | |||
return ;Don't need to worry about changing ItemCount, it's the same as TempItemCount | |||
elseif (TempItemCount < ItemCount) ;Lost Quantity | |||
SetStage ITInvChangesDecreasedList 0 | |||
SetStage ITInvChangesRemovedList 0 | |||
else ;if (TempItemCount > ItemCount) ;Gained Quantity | |||
SetStage ITInvChangesIncreasedList 0 | |||
SetStage ITInvChangesAddedList 0 | |||
endif | |||
set ItemCount to TempItemCount ;this will leave pItem's that have been nullified with a random number, this might matter if the ref is actually remembered past a mod being uninstalled and reinstalled | |||
endif | |||
end</pre> | |||
--[[User:Haama|Haama]] 16:12, 13 September 2007 (EDT) |
Latest revision as of 22:28, 31 May 2008
"There appears to be some kind of recursion catch that stops calls working if the same script is called within the same frame more than ~4 times."
Guidobot, is this only true for recursion? I've not had any problems so far with 100s of activations (and yes, I need them), so long as it's another script calling the activator, and not the activator calling itself. Are there special circumstances?
--Haama 04:40, 12 July 2007 (EDT)
- I assume that the limit is put there as a recursion catch but it is active no matter how the object script is called within the same frame, e.g. having multiple Activate/PlaceAtMe lines in a single script or in multiple scripts running in the same frame. This also applies to scripts on objects placed in the game. For example, when you have 4 or more scripted skeletons some will appear to freeze/lag.
- --Guidobot 20:11, 9 September 2007 (EDT)
- I've done a bit more testing since then (see Activate), and as far as I can tell it's only true of recursion (not sure about the skeleton thing, though). One of my mods, Inventory Tracker, activates a single activator 1000 times a frame without any problems (reported, or in tests). The recursion limit also seems to be limited to the onActivate block, as I've run over 250 quest result scripts from within each other (again, see Inventory Tracker). I've also done some tests with mixes of result scripts and onActivate blocks, and 'SomeObject.Activate player, 1' won't run if and only if there are 3-4 other onActivate blocks running at the time (not, in the same frame). I'd have to dig those tests up, though.
- Also, I have found that you can constantly load a remote activator (make it run every frame as if it were moved to the player) by changing a variable on the activator. It hasn't been throughly tested, but maybe it should be included?
- --Haama 18:34, 10 September 2007 (EDT)
- Interesting, but becareful about what you assume about the generality of 'activators'. I am still suspect about expecting an activator to be callable 1000 times in the same frame, especially if the OnActivate script is of any length. If this is true then you should be able to generate visible lag very easily (even w/o inventory redraws, etc.).
- --Guidobot 12:27, 13 September 2007 (EDT)
Not at all, I don't see any FPS drop until I run it 2000 times, and even then it's only 1 FPS. What seems to be important are the functions used, not the number of lines. Here's the script:
scn ITNumCheckerScript ref pItem short ItemCount short TempItemCount short DiffNum short InvPos short LinkedListTotal short LinkedListPos begin onActivate set LinkedListPos to (LinkedListPos + 1) if pItem set TempItemCount to (player.GetItemCount pItem) if TempItemCount set InvPos to (InvPos + 1) endif if (TempItemCount == ItemCount) return ;Don't need to worry about changing ItemCount, it's the same as TempItemCount elseif (TempItemCount < ItemCount) ;Lost Quantity SetStage ITInvChangesDecreasedList 0 SetStage ITInvChangesRemovedList 0 ITInvChangesRemovedList.Changes else ;if (TempItemCount > ItemCount) ;Gained Quantity SetStage ITInvChangesIncreasedList 0 SetStage ITInvChangesAddedList 0 endif set ItemCount to TempItemCount ;Setup new spot if needed elseif (LinkedListPos > LinkedListTotal) set pItem to (player.GetInventoryObject InvPos) if (pItem == 0) ;No more items set ITListManager.Counter to 254 ;Wraps everything up return elseif (ITLinkedListCont.GetItemCount pItem) ;If the player has picked up an item(s) that they've already picked up, then it won't be in the expected position above, and instead an item that's already in the linked list will be referenced, so check against a container full of linked list items ITInvScanner.Activate player, 1 if (pItem == 0) ;No more items - just in case set ITListManager.Counter to 254 return endif endif set LinkedListTotal to (LinkedListTotal + 1) ITLinkedListCont.AddItem pItem 1 set ITInvChangesNewList.Changes to (ITInvChangesNewList.Changes + 1) SetStage ITInvChangesNewList ITInvChangesNewList.Changes set TempItemCount to (player.GetItemCount pItem) if TempItemCount set InvPos to (InvPos + 1) endif if (TempItemCount == ItemCount) return ;Don't need to worry about changing ItemCount, it's the same as TempItemCount elseif (TempItemCount < ItemCount) ;Lost Quantity SetStage ITInvChangesDecreasedList 0 SetStage ITInvChangesRemovedList 0 else ;if (TempItemCount > ItemCount) ;Gained Quantity SetStage ITInvChangesIncreasedList 0 SetStage ITInvChangesAddedList 0 endif set ItemCount to TempItemCount ;this will leave pItem's that have been nullified with a random number, this might matter if the ref is actually remembered past a mod being uninstalled and reinstalled endif end
--Haama 16:12, 13 September 2007 (EDT)