ughfhhyg4555786 Posted August 2, 2020 Share Posted August 2, 2020 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 More sharing options...
maxarturo Posted August 2, 2020 Share Posted August 2, 2020 "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 More sharing options...
ughfhhyg4555786 Posted August 3, 2020 Author Share Posted August 3, 2020 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 More sharing options...
maxarturo Posted August 3, 2020 Share Posted August 3, 2020 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 More sharing options...
ughfhhyg4555786 Posted August 3, 2020 Author Share Posted August 3, 2020 Thank you very much for reply, I will try this and I also have some idea about that. Once I have done the test, I will let you know. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted August 5, 2020 Share Posted August 5, 2020 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 ENDIFI 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 More sharing options...
ughfhhyg4555786 Posted August 6, 2020 Author Share Posted August 6, 2020 That's amazing. I will need some times to read this Link to comment Share on other sites More sharing options...
Recommended Posts