Jump to content

[LE] Script help: disable and delete function do not work properly


Recommended Posts

Due to my poor knowledge of script, especially to write a function, I'm experiencing some difficulty to accomplish my last script for my spell.

This spell is basically used for NPC only. When their enemies equip the bow and cross bow, two StoneShelter will be placed in front and back of the caster. And also a Turret will be placed above caster to shot the enemy. When enemies change their equaltype to onehand weapon or twohanded weapon, the StoneShelter and turret will be removed.

 

The disable and delete function doesn't work properly in the function RemoveStoneShelter(), objects TurretRef and StoneWallRef seems already delete, but not exactly. And this cause a problem that "SpellRef.RemoteCast(TurretRef,Caster,EnemyTarget)" is still shooting even if the TurretRef is gone to my function TurretTrigger(). In addition, there is also problem in the function StoneShelter(). The function only place StoneWallRef but not placing StoneWallRef2 ???

 

(Also, through few tests, The FindRandomReferenceOfTypeFromRef work perfectly for a Turret with NPC or Player, the only disadvantage is the limited of distance (this require a searching radius). The GetCombatTarget function work perfectly fine only with NPC not player. I think this is because the NPC always point out their sight point cross to their target, but obviously player cannot do that.)

 

Below is script.

Import Game
Import Utility
Import Math

Static Property StoneWall auto
Static Property StoneWall2 auto
Activator Property Turret auto
Activator Property SummonFx auto
Float Property SearchRadius = 3000.0 auto
Float Property fBaseTime = 1.0 auto
Float Property fBaseTime2 = 3.0 auto
Spell Property SpellRef auto
Spell Property SpellRef2 auto

Actor Caster
Actor Target
ObjectReference StoneWallRef
ObjectReference StoneWallRef2
ObjectReference TurretRef

Event OnEffectStart(Actor akTarget, Actor akCaster)
	Caster = akCaster
	Target = akTarget
	RegisterForSingleUpdate(1.0)
EndEvent


Event OnUpdate()
	Actor EnemyTarget = Caster.GetCombatTarget()
	 
		if (EnemyTarget.GetEquippedItemType(0)==7)
			if (FindRandomReferenceOfTypeFromRef(StoneWall,Caster,SearchRadius) == none)
				StoneShelter()
			else
				TurretTrigger()
			EndIf
		elseif (EnemyTarget.GetEquippedItemType(0)==12)
			if (FindRandomReferenceOfTypeFromRef(StoneWall,Caster,SearchRadius) == none)
				StoneShelter()
			else
				TurretTrigger()
			EndIf
		elseif ((EnemyTarget.GetEquippedItemType(0)==9)||(EnemyTarget.GetEquippedItemType(1)==9))
			if (FindRandomReferenceOfTypeFromRef(StoneWall,Caster,SearchRadius) == none)
				SpellRef2.Cast(Caster)
			else
				TurretTrigger()
			EndIf
		else
			if  (StoneWallRef!= none || StoneWallRef2!= none || TurretRef!= none)
				RemoveStoneShelter()
			EndIf
		Endif
		RegisterForSingleUpdate(fBaseTime)
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster)
	RemoveStoneShelter()
EndEvent


Function StoneShelter()
	TurretRef = Caster.PlaceAtMe(Turret)
	TurretRef.SetPosition(Caster.GetPositionX(),Caster.GetPositionY(),Caster.GetPositionZ()+ 440)
	StoneWallRef = Caster.PlaceAtMe(StoneWall)
	StoneWallRef.SetPosition(Caster.GetPositionX(),Caster.GetPositionY(),Caster.GetPositionZ())
	StoneWallRef.PlaceAtMe(SummonFx)
	StoneWallRef2 = Caster.PlaceAtMe(StoneWall2)
	StoneWallRef2.MoveTo(Caster,-40*sin(Caster.GetAngleZ()),-40*cos(Caster.GetAngleZ()),Caster.GetPositionZ())
	StoneWallRef2.PlaceAtMe(SummonFx)
EndFunction


Function TurretTrigger()
	Actor EnemyTarget = Caster.GetCombatTarget()
	if TurretRef != none
		SpellRef.RemoteCast(TurretRef,Caster,EnemyTarget)
	else
		RegisterForSingleUpdate(fBaseTime)
	EndIf
EndFunction


Function RemoveStoneShelter()
	if TurretRef!= none
		TurretRef.PlaceAtMe(SummonFx)
		TurretRef.disable()
		TurretRef.delete()
	EndIf
	
	if StoneWallRef!= none
		StoneWallRef.PlaceAtMe(SummonFx)
		StoneWallRef.disable()
		StoneWallRef.delete()
	EndIf
	
	if StoneWallRef2!= none
		StoneWallRef2.PlaceAtMe(SummonFx)
		StoneWallRef2.disable()
		StoneWallRef2.delete()
	EndIf
EndFunction
Link to comment
Share on other sites

"The disable and delete function doesn't work properly in the function RemoveStoneShelter(), objects TurretRef and StoneWallRef seems already delete, but not exactly. And this cause a problem that "SpellRef.RemoteCast(TurretRef,Caster,EnemyTarget)" is still shooting even if the TurretRef is gone to my function TurretTrigger()."


Objects that are "Disabled" they still occupied / have an existence in world / cell, so the function will / can still use the "Disabled Object" to run the "Cast" function.

You need to add and "InterruptCast" to the "RemoveStoneShelter()".

Example:

Function RemoveStoneShelter()

if TurretRef!= none

TurretRef.InterruptCast()

TurretRef.PlaceAtMe(SummonFx)

TurretRef.disable()

TurretRef.delete()

EndIf

EndFunction


"In addition, there is also problem in the function StoneShelter(). The function only place StoneWallRef but not placing StoneWallRef2 ???"

Be sure that you have assign the "StoneWallRef2" in the script's properties, also try to use a little more different 'Names', try adding a '02', like "StoneWallRef02" (the Skyrim game engine is not the most reliable).


The "Delete" function does NOT occur when the script call it on an object, the object is just "Marked For Deletion" and it's still in its position / location until the cell in which the player is, gets 'unloaded' > from where the "Deletion" was called > until the system memory is reset / clean, only after that the object will stop existing on the 'Next Save File'.


* Sorry if i wasn't more detailed, but i'm making this post from my stupid tablet.


Have a happy modding.

Link to comment
Share on other sites

Hi maxarturo,

Thank you for reply. I added the TurretRef.InterruptCast() to mu function, but it is still not working. Is because the delete function does not work well with OnUpdate event? I change StoneWallRef2 to StoneWallRef02, but the object is still not placing. :sad: Any idea?

Link to comment
Share on other sites

Your "Event OnUpdate()" is calling at the end a "RegisterForSingleUpdate(fBaseTime)", that's why is still "Casting", you need to "UnregisterForUpdate()" in the "RemoveStoneShelter()", sorry but i thought this was clear.


Function RemoveStoneShelter()

if TurretRef!= none

UnregisterForUpdate()

TurretRef.InterruptCast()

TurretRef.PlaceAtMe(SummonFx)

TurretRef.disable()

TurretRef.delete()

EndIf

EndFunction


I can't see any errors on your script, but in the other hand i'm looking at it with a small stupid tablet that i can barely see / read anything, plus i can not run any tests, i'm on vacations.


Maybe another expirienced modder with a PC available can take a look at it.


I'm so sorry....

Link to comment
Share on other sites

As maxarturo has already written: "The "Delete" function does NOT occur when the script call it on an object, the object is just "Marked For Deletion" and it's still in its position"

syntax as follow:

IF ( oRef )
    oRef.DisableNoWait()
    oRef.Delete()
    oRef = None
ENDIF

I do not merged TurretRef.InterruptCast() into the code. If you need that, try it out.

 

ughTurretEffectScript

 

Scriptname ughTurretEffectScript extend ActiveMagicEffect
; https://forums.nexusmods.com/index.php?/topic/8974388-script-help-disable-and-delete-function-do-not-work-properly/

  Spell PROPERTY SpellRef auto
  Spell PROPERTY SpellRef2 auto

  Static PROPERTY StoneWall auto
  Static PROPERTY StoneWall2 auto
 
  Activator PROPERTY Turret auto
  Activator PROPERTY SummonFx auto

  Float PROPERTY SearchRadius = 3000.0 auto
  Float PROPERTY fBaseTime    =    1.0 auto
 ;Float PROPERTY fBaseTime2   =    3.0 auto        ; UnUSED by default

  ObjectReference StoneWallRef
  ObjectReference StoneWallRef2
  ObjectReference TurretRef

  Actor caster
  Actor target


; -- EVENTs -- 3

EVENT OnEffectStart(Actor akTarget, Actor akCaster)
    caster = akCaster
    target = akTarget
    RegisterForSingleUpdate(1.0)
ENDEVENT


EVENT OnEffectFinish(Actor akTarget, Actor akCaster)
IF ( target )
    target = None
    RemoveStoneShelter()
ENDIF
ENDEVENT


EVENT OnUpdate()
    actor aRef

IF ( caster )
    aRef = caster.GetCombatTarget()
ELSE
    RETURN    ; - STOP -    caster is missing !!!
ENDIF
;---------------------
    IF ( aRef )
        myF_Action(aRef)
    ENDIF

    RegisterForSingleUpdate(fBaseTime)        ; 1.0 sec
ENDEVENT


; -- FUNCTIONs -- 5

;----------------------------
FUNCTION RemoveStoneShelter()
;----------------------------
    IF ( TurretRef )
        TurretRef.PlaceAtMe(SummonFx)       ; better to use an explosion here, instead activator !!!
        TurretRef.DisableNoWait()           ; 1
        TurretRef.Delete()                  ; 2
        TurretRef = None                    ; 3
    ENDIF
    
    IF ( StoneWallRef )
        StoneWallRef.PlaceAtMe(SummonFx)    ; better to use an explosion here, instead activator !!!
        StoneWallRef.DisableNoWait()
        StoneWallRef.Delete()
        StoneWallRef = None
    ENDIF
    
    IF ( StoneWallRef2 )
        StoneWallRef2.PlaceAtMe(SummonFx)    ; better to use an explosion here, instead activator !!!
        StoneWallRef2.DisableNoWait()
        StoneWallRef2.Delete()
        StoneWallRef2 = None
    ENDIF
ENDFUNCTION


;--------------------------------
FUNCTION TurretAction(Actor aRef)  ; aRef = EnemyTarget
;--------------------------------
    IF ( TurretRef )
        SpellRef.RemoteCast(TurretRef, caster, aRef)
    ENDIF
ENDFUNCTION


;------------------------------
FUNCTION myF_Action(Actor aRef)  ; aRef = EnemyTarget
;------------------------------
    int i = aRef.GetEquippedItemType(0)

IF (i == 7) || (i == 12)
    IF Game.FindRandomReferenceOfTypeFromRef(StoneWall, caster, SearchRadius)
        TurretAction(aRef)      ; found something
    ELSE
        StoneShelter(caster)    ; nothing here
    ENDIF
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (i == 9) || (aRef.GetEquippedItemType(1) == 9)
    IF Game.FindRandomReferenceOfTypeFromRef(StoneWall, caster, SearchRadius)
        TurretAction(aRef)
    ELSE
        SpellRef2.Cast(caster)
    ENDIF
    RETURN    ; - STOP -
ENDIF
;---------------------
    RemoveStoneShelter()
ENDFUNCTION


;--------------------------------------------------------------
ObjectReference FUNCTION myF_Summon(Form fm, Actor aRef, Int i)  ; aRef = caster
;--------------------------------------------------------------
    objectReference oRef = aRef.PlaceAtMe(fm)        ; place a new objRef (enabled and non-persistent) depends on baseobject parameter
    float fx = aRef.GetPositionX()
    float fy = aRef.GetPositionY()
    float fz = aRef.GetPositionZ()

IF (i == 1)
    fz = fz + 440.0
    oRef.SetPosition(fx,fy,fz)
    RETURN oRef                    ; TurretRef
ENDIF
;---------
IF (i == 2)
    oRef.SetPosition(fx,fy,fz)
    oRef.PlaceAtMe(SummonFx)
    RETURN oRef                    ; StoneWallRef
ENDIF
;---------
IF (i == 3)
    fy = aRef.GetAngleZ()
    fx = Math.SIN(fy) * -40.0      ; -40*sin(Caster.GetAngleZ())
    fy = Math.COS(fy) * -40.0      ; -40*cos(Caster.GetAngleZ())
    oRef.MoveTo(aRef, fx,fy,fz)
    oRef.PlaceAtMe(SummonFx)
    RETURN oRef                    ; StoneWallRef2
ENDIF
ENDFUNCTION


;--------------------------------
FUNCTION StoneShelter(Actor aRef)  ; aRef = caster
;--------------------------------
IF ( aRef )
    TurretRef     = myF_Summon(Turret     as Form, aRef, 1)
    StoneWallRef  = myF_Summon(StoneWall  as Form, aRef, 2)
    StoneWallRef2 = myF_Summon(StoneWall2 as Form, aRef, 3)
ENDIF
ENDFUNCTION

 


Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...