Jump to content

Scripting Woes


greyday01

Recommended Posts

As well as the basic troubles of covering every possible scenario and figuring out syntax for things like casting and trying to get the values of properties from scripts on other objects which is hard enough for someone with no programming training, the peculiarities of Papyrus can be exasperating.

 

I had a custom ghost (no defaultghostscript) with 2 states alive and dead. A triggerbox with 2 states ready and haunted.

After I entered and wacked the ghost that appeared until it fell down dead. The script on the triggerbox had an if ghost.IsDead() with the property pointing to my ghost but it kept insisting that the dead ghost at my feet was still alive. The Event OnDeath on the ghost itself fired just fine. I fought with that for ages then gave up and used If ghost.GetState() = "Dead" instead. But I still don't know why IsDead did not work. SettingCriticalStages on the ghost after killing it made no difference so that's not the problem.

 

Oh well, it's working now with the revision. The Wiki was less than useful.

Link to comment
Share on other sites

What event did you use on the trigger box script?

OnTrigger

OnTriggerEnter

OnTriggerLeave

 

If it was OnTrigger and the ghost remained inside the trigger box IsDead should have worked provided the property pointed to the pre-placed instance of the ghost. That said, it might not work instantaneously. OnTrigger is triggered often while the object remains inside but there is a delay between each run.

 

Using OnTriggerLeave and checking when the player leaves the kill zone (i.e. trigger box) should have worked too with IsDead.

 

But as long as you got something working, that is all that matters. Once you get more comfortable with Papyrus, you can always go back and try things differently.

Link to comment
Share on other sites

I used OnTriggerEnter. After I entered the first time and killed it I moved the corpse to a holding cell. Then I left the box and came back. At that point since the ghost was dead it should not have moved a ghost back into the kill zone. Each time the ghost appeared it had the same ref ID. Does MoveTo automatically resurrect NPCs?

Link to comment
Share on other sites

Bethesda employees were coding against a deadline so its best to avoid using their syntax and such, and focus more on the task they are aiming to accomplish

 

States arent even required to be declared in a script. Just useful depending on your situation. And when they name states similar to actual conditions actors can be, like dead, yeah, it will confuse a passerby very quickly

 

Moving does not resurrect, no. Maybe there is a reset() routine somewhere? That could cause some things to look un-done

Link to comment
Share on other sites

No i walked into the kill area, wacked the ghost, moved about a farmhouse distance away and came back, killed the ghost again and repeated this a few times. Just wouldn't stay dead. I'm thinking it must be something about move to resurrecting it. It wasn't scripted to resurrect until daylight so something else must have resurrected it since it wasn't a dead ghost that was moved back to the graveyard.

Link to comment
Share on other sites

Not knowing the whole setup I'm assuming that it's the logic of your set up.

Here you have a scripts set up example for a similar to one of mine mod's situation:

Script on actor:



ObjectReference Property MyTriggerBox01 Auto

Event OnDeath(Actor akKiller)
MyTriggerBox01.Activate(Self)
ENDEVENT



Script on the trigger box:



GlobalVariable Property MyGL Auto
Actor Property MyGhost Auto

EVENT OnActivate(ObjectReference akActionRef)
If ( akActionRef == MyGhost )
MyGL.SetValue( 1 )
EndIf
ENDEVENT

EVENT OnTriggerEnter(ObjectReference akActionRef)
If ( MyGL.GetValue() == 1 )
;;;;;Do My s***
EndIf
ENDEVENT



If you can't go forwards, then go around....

Edited by maxarturo
Link to comment
Share on other sites

That's a bit odd. My set up as I have it working is that the ghost is in a holding cell. If you enter the trigger at night the ghost is moved into the trigger. After you wack it, the ghost's state goes from "alive" to "dead" using Event OnDeath on the ghost and is moved back to the holding cell. After a few hours it is resurrected, and its state goes back to "alive".

 

That may be why IsDead on a script on the trigger did not fire. No CriticalStage was set so possibly the game did not view it as really quite dead and it could be moved. I'm certain it was moved because after wacking I've COC'd to the holding cell and the ghost was there. The Wiki says Flora can't be moved but it says nothing about dead NPCs. Nothing new there. The Wiki misses a lot.

 

I've a question about criticalstage and npcs. Every npc doesn't have a script on it setting criticalstage when it is killed. As far as I can see it is only in the defaultGhostScript that is added only on ghosts. So, when DO you need to add this script to a NPC you create? Is it only for things like ghosts and skeletons that fall apart or are replaced by ectoplasm after being wacked? Regular killed NPCs just lay there dead until the cell resets and gets rid of them.

Link to comment
Share on other sites

'criticalstage' is used ONLY when you need to delete an actor.


I'm guessing that you are still trying to do your 'spawn ghost in cemetery' idea without the use of the Story Manager.

Ok, here you have a simplified execution in simple steps:

1) Place wherever you like an 'xMarker', give it a unique name and be sure that's above the ground.

2) Place this script in the 'BASE' actor, do not add an actor in you render window / in your worldspace / cell, and the script goes in the actor's 'create npc' window/tab:



GlobalVariable Property GhostDeadGL Auto

EVENT OnDying(Actor akKiller)
Slef.SetCriticalStage(3)
ENDEVENT

EVENT OnDeath(Actor killer)
GhostDeadGL.SetValue( 1 )
Slef.SetCriticalStage(4)
ENDEVENT



3) Create a trigger box and cover the entire place you want this to happen, and place this script:



Actor Property PlayerREF Auto
ActorBase Property MyBaseGhost Auto
ObjectReference Property xMarkerPlaceGhost Auto
GlobalVariable Property GhostDeadGL Auto

AUTO STATE WaitingPlayer
EVENT OnTriggerEnter(ObjectReference akActionRef)
If ( akActionRef == PlayerREF ) && ( GhostDeadGL.GetValue() == 0 )
GoToState("Inactive")
float fTime = Utility.GetCurrentGameTime()
If ( fTime >= 20 ) && ( fTime <= 8 )
xMarkerPlaceGhost.PlaceActorAtMe(MyBaseGhost).StartCombat(PlayerREF)
RegisterForSingleUpdateGameTime(12.0)
Else
GoToState("WaitingPlayer")
EndIf
EndIf
ENDEVENT
ENDSTATE

STATE Inactive
ENDSTATE

EVENT OnUpdateGameTime()
GhostDeadGL.SetValue( 0 )
GoToState("WaitingPlayer")
ENDEVENT



4) Create a 'GlobalVariable' and set it to ' 0 '


5) Fill in all the properties in both scripts.


6) Save and go in game to test.

Have fun....


NOTE:

- You will need to set the time to your likings, I've set it to after or 20.00 at the evening to before or 8.00 in the morning.

- This will happen ONLY once per day.

- I did not double checked it for 'Typos', I just wrote it and hit the post button, not enough free time for much.

- Do not make your actor 'Unique'.

Edited by maxarturo
Link to comment
Share on other sites

  • Recently Browsing   0 members

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