Jump to content

[LE] Small Script Issue. i need fresh eyes or a different angle.


maxarturo

Recommended Posts

This is a script so simple that i didn't even tested it by itself, but it was tested as a whole, when i finished the scene on that particular cell along side with the new "Race Actors" and the "Heavy Script" that needed verification, and although everything works flawlessly !!.


This script has the issue that when the "SetPosition" is called, the "Explosion" has already started playing, so the "SetPosition" doesn't work on an FX that is already playing.

I tryed using math in the same line so that SetPosition is called before and in the same execution line, but the "PlaceAtMe" does not allows it or, i'm doing it wrongly.


As you may have already figured it out by now, if you have read some of my previous posts, some things i try doing them without using unnecessary functions (as simple as possible), so that i can have as much of the PC's resources available for the really Heavy and Important stuffs.


* That implies calling first an xMarker to SetPosition on it and then call the Explosion on the xMarker.

If this can not be done in the same line then it doesn't matter, i will simplify the script even further and create a new particle explosion system from scratch that will cover the mass i need it to cover.


Everytime i come across an issue is from a simple script as this one:



Scriptname aXMDnpcPlaceExplosionOnDying extends Actor
{Places 2 explosions at the actor's position when he starts dying}

Explosion Property DeathExplo01 Auto
{First explosion at torso height, ZaxeExpl01}

Explosion Property DeathExplo02 Auto
{Second explosion at torso bottom, ZaxeExpl02}

Float Property ZaxeExpl01 = 100.0 Auto
{First explosion at the Z axe, Default = 100}

Float Property ZaxeExpl02 = 75.0 Auto
{Second explosion at the Z axe, Default = 70}


Event OnDying(Actor akKiller)
ObjectReference DeathExplo01REF = Self.PlaceAtMe(DeathExplo01, 1)
DeathExplo01REF.SetPosition(0, 0, ZaxeExpl01)
ObjectReference DeathExplo02REF = Self.PlaceAtMe(DeathExplo02, 1)
DeathExplo02REF.SetPosition(0, 0, ZaxeExpl02)
EndEvent



Thank you very much for burning some of your brain cells in this one !...

Edited by maxarturo
Link to comment
Share on other sites

The easiest solution, as you mentioned, would be to create an XMarker and use that as the reference for the explosions. Just move it around before calling the explosion's PlaceAtMe. It's not going to slow down your script by any appreciable amount whatsoever.

Link to comment
Share on other sites

Hey Maxaturo,

 

As far as I know, like Reneer said, the only way to do this for sure would be to first place an xmarker, move it to the position, and then add your explosions.

 

It would be interesting to see what this does.

Event OnDying(Actor akKiller)
(Self.PlaceAtMe(DeathExplo01, 1)).SetPosition(0, 0, ZaxeExpl01)
(Self.PlaceAtMe(DeathExplo02, 1)).SetPosition(0, 0, ZaxeExpl02)
EndEvent

If that fails, Give this a shot. Don't forget to fill the xmarker property.

Scriptname aXMDnpcPlaceExplosionOnDying extends Actor 

{Places 2 explosions at the actor's position when he starts dying}

STATIC Property XMarker  Auto  

Explosion Property DeathExplo01 Auto
{First explosion at torso height, ZaxeExpl01}
 
Explosion Property DeathExplo02 Auto
{Second explosion at torso bottom, ZaxeExpl02}
 
Float Property ZaxeExpl01 = 100.0 Auto
{First explosion at the Z axe, Default = 100}
 
Float Property ZaxeExpl02 = 75.0 Auto
{Second explosion at the Z axe, Default = 70}
 
 
Event OnDying(Actor akKiller)
    ObjectReference XM = (Self.PlaceAtMe(XMarker, 1)).SetPosition(0, 0, ZaxeExpl01)
           XM.PlaceAtMe(DeathExplo01, 1)
           XM.SetPosition(0, 0, ZaxeExpl02)
           XM.PlaceAtMe(DeathExplo02, 1)
EndEvent


Link to comment
Share on other sites

Thanks Reneer & SurfsideNaturals for showing interest in this.


@ Reneer

I was hoping to not use too many functions on this, but as i'm explaining further down, this cannot be avoided if it's crucial for the explosions to be placed in the specific position.



"It's not going to slow down your script by any appreciable amount whatsoever."

I'm not so worried about this, but of other more crucial scripts not firing since i have found that sometimes if the PC is full/very busy it will miss/skip some scripts executions.




@ SurfsideNaturals

This compiles, but it will ignore completely the "SetPosition", the same effect as my first script.

* I did not tested it with an object instead of an FX, with an object it might work.



Event OnDying(Actor akKiller)
(Self.PlaceAtMe(DeathExplo01, 1)).SetPosition(0, 0, ZaxeExpl01)
(Self.PlaceAtMe(DeathExplo02, 1)).SetPosition(0, 0, ZaxeExpl02)
EndEvent



This compiles, but it will not call/place the xMarker as a result the Explosions never fire, or something else it's happening that won't fire the explosions.



STATIC Property XMarker Auto

Explosion Property DeathExplo01 Auto
{First explosion at torso height, ZaxeExpl01}

Explosion Property DeathExplo02 Auto
{Second explosion at torso bottom, ZaxeExpl02}

Float Property ZaxeExpl01 = 100.0 Auto
{First explosion at the Z axe, Default = 100}

Float Property ZaxeExpl02 = 75.0 Auto
{Second explosion at the Z axe, Default = 70}


Event OnDying(Actor akKiller)
ObjectReference XM = (Self.PlaceAtMe(XMarker, 1)).SetPosition(0, 0, ZaxeExpl01)
XM.PlaceAtMe(DeathExplo01, 1)
XM.SetPosition(0, 0, ZaxeExpl02)
XM.PlaceAtMe(DeathExplo02, 1)
EndEvent



Also, i found out that the "SetPosition" will set the position of the object according to the CELL'S X,Y,Z = 0 coordinates and NOT OF THE ACTOR.

So, it's actually useless for this occasion...


In order to make this work it needs to be done like this.

Final Working Script:



Scriptname aXMDnpcPlaceExplosionOnDying extends Actor
{Places 2 explosions at the actor's position when he starts dying}

Static Property XMDdeathExploMoveREF01 Auto
{The xMarker to Place & Move along the Actor's X,Y,Z axe}

Explosion Property DeathExplo01 Auto
{First explosion at torso height, ZaxeExpl01}

Explosion Property DeathExplo02 Auto
{Second explosion at torso bottom, ZaxeExpl02}

Float Property ZaxeExpl01 = 100.0 Auto
{First explosion at the Z axe, Default = 100}

Float Property ZaxeExpl02 = 70.0 Auto
{Second explosion at the Z axe, Default = 70}


Auto State WaitingKiller
Event OnDying(Actor akKiller)
ObjectReference XM = Self.PlaceAtMe(XMDdeathExploMoveREF01, 1)
XM.MoveTo(Self, 0.0, 0.0, ZaxeExpl01, abMatchRotation = true)
XM.PlaceAtMe(DeathExplo01, 1)
XM.MoveTo(Self, 0.0, 0.0, ZaxeExpl02, abMatchRotation = true)
XM.PlaceAtMe(DeathExplo02, 1)
XM.Delete()
Self.SetCriticalStage(CritStage_DisintegrateStart)
GoToState("RemoveActor")
EndEvent
EndState


State RemoveActor
Event OnCellDetach()
Self.SetCriticalStage(CritStage_DisintegrateEnd)
EndEvent
EndState



But i don't know if i will use it since this needs real time testing (fully load heavy cell - in game) on one specific Actor that already has 2 crucial scripts on it.

If one of them malfunction, the Player won't be able to proceed, since they are handling the "Allow to Enter Cell" of 2 cells and the corresponding activation of some Activators (like stairs, load doors... etc).

But this can wait until tomorrow...


* All testing of this script was done in the "PreFabsCells" which they don't exceed M#: 2.49% (3.90 MB / 157.00 MB ), the "PreFabsCells" are used mainly for testing "New Races" and by some in game scripts to obtain some "Reference Status" for their further functionality, so they are actually empty cells.


The only thing that makes me hope that it won't show any malfunction, is that the other 2 scripts fire "OnDeath", so after the "OnDying" finishes its functions, but you never know if you do not test it heavily...


* Now the Daedras explodes when they die (my daedras) and their dead invisible bodys don't stay around forever... or until they respawn...

This is one thing that i really hated in the game...


Anyway, i'm posting it just in case someone else might need it.


Thank you both very much for your assistance.

Edited by maxarturo
Link to comment
Share on other sites

Just for interest.. are the explosions of different type? If not one explosion property would be enough.

 

aXMDDisintegrateOnDyingScript

 

Scriptname aXMDDisintegrateOnDyingScript extends Actor  
{when this actor is dying let them explode twice}
; https://forums.nexusmods.com/index.php?/topic/8377573-small-script-issue-i-need-fresh-eyes-or-a-different-angle/
 
  Static PROPERTY XMDdeathExploMoveREF01 auto        ; {xMarker to place explosions along the Actors X,Y,Z axe}
 
  Explosion PROPERTY DeathExplo01 auto               ; explosion at torso height
  Explosion PROPERTY DeathExplo02 auto               ; explosion at torso bottom
 

; -- EVENTs --  

EVENT OnDying(Actor akKiller)
    myF_Explode(100.0, 70.0)
    gotoState("Waiting")            ; ### STATE ###
    self.SetCriticalStage(3)                        ; CritStage_DisintegrateStart
ENDEVENT


;=================================
state Waiting  ; Make sure to run OnCellDetach() once only !!!
;============
    EVENT OnCellDetach()
        gotoState("")                ; ### STATE ###
        Utility.Wait(0.5)
        self.SetCriticalStage(4)                    ; CritStage_DisintegrateEnd
    ENDEVENT
;=======
endState


; -- FUNCTION --

;---------------------------------------
FUNCTION myF_Explode(Float z1, Float z2)  ; explosion offset at z-axe
;---------------------------------------
; create an persistent and disabled X-Marker nearby the NPC
    objectReference oRef = self.PlaceAtMe(XMDdeathExploMoveREF01 as Form, 1, TRUE, TRUE)

; create an non-persistent and enabled X-Marker nearby the NPC
;;;    objectReference oRef = self.PlaceAtMe(XMDdeathExploMoveREF01, 1, False, False)        ; your version

IF ( oRef )
    oRef.MoveTo(self as ObjectReference, 0.0, 0.0, z1)
    oRef.PlaceAtMe(DeathExplo01, 1)                        ; first explosion

    Utility.Wait(0.1)        ; delay between explosions

    oRef.MoveTo(self as ObjectReference, 0.0, 0.0, z2)
    oRef.PlaceAtMe(DeathExplo02, 1)                        ; second explosion

    oRef.Delete()            ; remove the placed X-Marker, explosions should be cleaning up by the game engine
ENDIF
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Just for interest.. are the explosions of different type? If not one explosion property would be enough.

 

aXMDDisintegrateOnDyingScript

 

Scriptname aXMDDisintegrateOnDyingScript extends Actor  
{when this actor is dying let them explode twice}
; https://forums.nexusmods.com/index.php?/topic/8377573-small-script-issue-i-need-fresh-eyes-or-a-different-angle/
 
  Static PROPERTY XMDdeathExploMoveREF01 auto        ; {xMarker to place explosions along the Actors X,Y,Z axe}
 
  Explosion PROPERTY DeathExplo01 auto               ; explosion at torso height
  Explosion PROPERTY DeathExplo02 auto               ; explosion at torso bottom
 

; -- EVENTs --  

EVENT OnDying(Actor akKiller)
    myF_Explode(100.0, 70.0)
    gotoState("Waiting")            ; ### STATE ###
    self.SetCriticalStage(3)                        ; CritStage_DisintegrateStart
ENDEVENT


;=================================
state Waiting  ; Make sure to run OnCellDetach() once only !!!
;============
    EVENT OnCellDetach()
        gotoState("")                ; ### STATE ###
        Utility.Wait(0.5)
        self.SetCriticalStage(4)                    ; CritStage_DisintegrateEnd
    ENDEVENT
;=======
endState


; -- FUNCTION --

;---------------------------------------
FUNCTION myF_Explode(Float z1, Float z2)  ; explosion offset at z-axe
;---------------------------------------
; create an persistent and disabled X-Marker nearby the NPC
    objectReference oRef = self.PlaceAtMe(XMDdeathExploMoveREF01 as Form, 1, TRUE, TRUE)

; create an non-persistent and enabled X-Marker nearby the NPC
;;;    objectReference oRef = self.PlaceAtMe(XMDdeathExploMoveREF01, 1, False, False)        ; your version

IF ( oRef )
    oRef.MoveTo(self as ObjectReference, 0.0, 0.0, z1)
    oRef.PlaceAtMe(DeathExplo01, 1)                        ; first explosion

    Utility.Wait(0.1)        ; delay between explosions

    oRef.MoveTo(self as ObjectReference, 0.0, 0.0, z2)
    oRef.PlaceAtMe(DeathExplo02, 1)                        ; second explosion

    oRef.Delete()            ; remove the placed X-Marker, explosions should be cleaning up by the game engine
ENDIF
ENDFUNCTION

 

 

 

Hey ReDragon.

 

Yes, one is the actual death explosion and the second one is the Actor's "Debris Explosion", custom made havoc particles / meshes to simulate the breaking down of the daedra's body that they lay around for a few sec after the daedra's death.

 

* By the way, if you read all of the above, in the end i had to make 2 scripts, one for all Actors (the last posted script) and one for the specific actor i was having concerns, removing all previous scripts that it had and merging them into one.

Edited by maxarturo
Link to comment
Share on other sites

  • 1 month later...
I come across this old post of my and i wanted to add that (if anyone might be interested), there is a simpler solution to this, if you don't want to have unnecessary extra functions in your script, and eliminate completely any possible lag.


Just edit the "Explosion nif" file and move every node to the height you want, and then create a "New Explosion" in CK with that edited nif.


I hope this might help anyone interested...

Edited by maxarturo
Link to comment
Share on other sites

I remember a long time ago I had problems with SetPosition or possibly it was TranslateToRef. Either way I remember the only way i could get what I wanted to move smoothly in real time or instantly

was to use them together. I would set an object to a XMarkers x,y,z with SetPosition then use TranslateToRef at a speed or instantly. Was even able to use a loop and step through movement smoothly.

Used it for a water flooding effect. Not sure if that helps ... good luck

Link to comment
Share on other sites

  • Recently Browsing   0 members

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