Some of you may be aware that I and PeterBitt are working on a huge overhaul for Morrowind sound and music system: Morrowind Acoustic Overhaul (MAO). A huge part of this projject is sound randomization for Player, NPCs, and creatures. Recently we discovered a huge problem with attaching scripts into NPCs via MWSE xFirstNPC, xNextRef functions. There's got to be some kind of bug with MWSE NPC lists. In some cases when you change the cell xFirstNPC and xNextRef functions will skip NPCs (and creatures) within the cell player currently is. When you change cell the global script will be once again able to add script into that NPCs.
Please prove me worng and show me the error in scripts
MAO scripts contains hundreds lines of code so for testing purpose I stripped down all unnecessarry junk, optimization etc. and left only basic MWSE NPC list loop, so anyone could test it in game.
Global script, which loop through NPC MWSE list and start directed AO_MWSE_NPC script when neccesarry:
Spoiler
Begin AO_MWSE_GetRef long lAIRef long lTemp float fDelay set fDelay to ( fDelay + GetSecondsPassed ) if ( fDelay < 0.05 ) ; max 20 times per second (0.033 = 30) return endif set fDelay to 0 if ( MenuMode == 1 ) return elseif ( CellChanged == 1 ) ; set lAIRef to 0 ; resetting reference doesn't fix problem MessageBox "CellChanged" return endif ifx ( lAIRef ) setx lAIRef to xNextRef lAIRef else setx lAIRef to xFirstNPC endif if ( lAIRef == 0 ) ; MessageBox "xNextRef loop done. xFirstNPC will be triggered in the next frame." return endif setx lTemp to lAIRef->xRefType if ( lTemp != 1598246990 ) ; not NPC return endif XSetRef lAIRef if ( GetItemCount "AO_DummyTemp" > 0 ) ; script already attached return endif XSetRef lAIRef if ( GetDistance Player > 2048 ) ; NPC is not close enough return endif XSetRef lAIRef StartScript "AO_MWSE_NPC" ; this directed script attaches script to NPCEnd
This directed script attaches one of AO_MWSE_NPC_XX scripts into NPC:
Spoiler
Begin AO_MWSE_NPC StopScript "AO_MWSE_NPC" ; this only needs to run for one frame if ( ScriptRunning "AO_MWSE_NPC_01" == 0 ) StartScript "AO_MWSE_NPC_01" elseif ( ScriptRunning "AO_MWSE_NPC_02" == 0 ) StartScript "AO_MWSE_NPC_02" elseif ( ScriptRunning "AO_MWSE_NPC_03" == 0 ) StartScript "AO_MWSE_NPC_03" elseif ( ScriptRunning "AO_MWSE_NPC_04" == 0 ) StartScript "AO_MWSE_NPC_04" elseif ( ScriptRunning "AO_MWSE_NPC_05" == 0 ) StartScript "AO_MWSE_NPC_05" else return endif set AO_NPC_Count to ( AO_NPC_Count + 1 ) ; MessageBox "DEBUG: Scrip attached. AO_NPC_Count = %0.f" AO_NPC_CountEnd
And this is the script that is attached to NPC. It adds AO_DummyTemp item into NPC inventory to let the AO_MWSE_GetRef script know that NPC has script already attached. For testing purpose it just shows MessageBox "Script is attached" when you activate NPC. In test esp that I've uploaded below there are 5 such scripts (01-05).
Spoiler
Begin AO_MWSE_NPC_01 short sDisable short doOnce if ( sDisable == 1 ) set sDisable to 0 set doOnce to 0 if ( GetItemCount "AO_DummyTemp" > 0 ) RemoveItem "AO_DummyTemp" 1 endif set AO_NPC_Count to ( AO_NPC_Count - 1 ) ; MessageBox "DEBUG: Script disabled. AO_NPC_Count = %0.f" AO_NPC_Count StopScript "AO_MWSE_NPC_01" return endif if ( doOnce == 0 ) if ( GetItemCount "AO_DummyTemp" == 0 ) AddItem "AO_DummyTemp" 1 endif set doOnce to 1 endif if ( OnActivate ) MessageBox "Script is attached" Activate endif if ( GetDistance Player > 2048 ) set sDisable to 1 return endif if ( GetHealth <= 1 ) set sDisable to 1 return endifEnd
If you can find an error within the scripts that would explain why excatly AO_MWSE_GetRef script can't see some NPCs, please let me know.
---------------------------------
Here is the plugin with the above scripts if anyone would be kind enough to test it in game: http://www.sendspace.com/file/osmz9w
Here is how you can recreate the problem:
1. open console and type "coc Balmora" (coc usage doesn't change anything - if you travel to Balmora by Slit Strited other part of the city will have silent NPCs due to different cell you start in).
2. go to the roof of Council Club in Balmora without leaving the town (you should see only one cellchanged messagege when you travel there in a direct line). Council Club is located near slit strider port but be sure to not change the cell, which ends nearby. Talk to Tedryn Brenur or Dranas Dradas who are standing there - none of them will have script attached (you won't see MessageBox when you talk to them). They don't have AO_DummyTemp item in thier inventory so they can't be skipped by the script this way (you can check it in console with GetItemCount). Unless you are using MCA there are free script slots too (type "show AO_NPC_Count" in console to be sure).
3. Leave the Balmora using the nearest gate (CellChanged) and come back - both Tedryn Brenur and Dranas Dradas will have now script attached.
It looks like MWSE is sometimes using wrong NPC lists or... dunno