×
Меню
Индекс

MSFD Deleting a reference completely

 
[no fix?] SetDelete flag_enum
 
     SetDelete 1
 
The SetDelete function can be used in combination with Disable to remove an object more completely. SetDelete 1 marks a reference for deletion and SetDelete 0 clears that flag. This can be useful in optimization. Certain objects have scripts on them which simulate picking them up by disabling the activated reference and adding a new object to your inventory. This leaves an ever-present, but disabled, reference at that location (which eats up memory and processor time since the script on the disabled reference is still run every frame). If the reference is marked for deletion then it is essentially gone. If the reference came from the master file, it is still there but knows it shouldn’t be so has no art and no scripting. If was created in game, it will actually be deleted.
 
Notes and cautions:
SetDelete will crash Morrowind if there is any other function operating on the object in the same frame. It will also crash if the object emits sounds (or plays animations with linked sounds) and is disabled and deleted in the same frame (forum info / JOG).
 
This Script will crash:
 
Begin _spell_effect
float timer
rotate y 120 ; crash caused by this
if ( timer < 3 )    
     set timer to ( timer + GetSecondsPassed )
else    
     disable    
     setdelete 1
endIf
 
A solution is to use first disabling the object and then using GetDisabled and Return to safely delete the object:
Begin _spell_effect
 
DontSaveObject
 
float timer
    
if ( GetDisabled == 1 )
     setdelete 1
     return
endIf    
 
rotate y 120
 
if ( timer < 3 )
     set timer to ( timer + GetSecondsPassed )
else
     disable
endIf
 
Another solution was proposed by Soralis, using a local variable "deletobj" as a flag:
 
if ( deleteobj = 1 ) ;Local variable, set when you want to delete
    if ( deletetimer == 0 )
        Disable
    endif
    if ( deletetimer < 10 )
        set deletetimer to ( deletetimer + 1 )
    endif
    if ( deletetimer == 10 )
        SetDelete, 1
    endif
    Return
endif
 
Always call SetDelete from a local script assigned to the object you want to remove. Never use Object->SetDelete 1 as this usually causes crashes when Morrowind is running. However, starting a targeted script on the object and then using SetDelete in that script works fine.
 
Don't delete items in inventory: this results in incorrect encumbrance. If necessary, Drop can be used to remove the item from inventory before deletion.
 
It has been reported that magic effects can cause problems with SetDelete (forum info / Dan_Wheeler). I (melian) am not sure exactly what this refers to, but I do know that if an NPC is deleted too quickly after another NPC casts a spell on it (scripted cast), the game will crash. If this causes you problems, use a timer to wait before deleting the object (you may need to wait a few seconds).