I tried to write a simple warp script that would let me pull a daedra towards me without using AiFollow (because I don't want them leaving the cell they're in), but the SetPos part of the script has been acting really flaky. Sometimes it works once or twice during my tests and then stops working forever. Other times I load the game (a fresh test save) and it doesn't work at all. SV shows me the co-ordinates are being set. The script executes everything, it's just the SetPos that doesn't happen. Here's the script:
Begin Uvi_DaeSc_Summon
; For daedra bound to crystal ball
Short OnPCHitMe
Short combatCheck
Short warp
Float timer
Float myX
Float myY
Float playerX
Float playerY
Float playerZ
If ( OnPCHitMe ) ;do nothing
Set OnPCHitMe to 0
Endif
If ( OnActivate ) ;do nothing
Endif
If ( OnDeath )
Set timer to 5
Endif
If ( MenuMode )
Return
Endif
If ( Player->GetSpellEffects uvi_daesc_call )
If ( GetDisabled )
Enable
Endif
If ( warp < 1 )
Set warp to 1
Endif
Elseif ( GetSpellEffects uvi_daesc_dismiss )
PlaySound3D "conjuration hit"
Disable
Elseif ( GetSpellEffects uvi_daesc_pull )
If ( warp < 1 )
Set warp to 1
Endif
Elseif ( Player->GetSpellEffects mel_tpp_XWait )
AiWander 0 0 0 0 50 50
Elseif ( Player->GetSpellEffects mel_tpp_XWander )
AiWander 1000 0 0 0 50 50
Elseif ( Player->GetSpellEffects mel_tpp_XStpCmbt )
StartCombat Player
StopCombat
Endif
If ( timer )
Set timer to ( timer - GetSecondsPassed )
If ( timer < 0 )
Set timer to 0
Endif
Return
Endif
If ( GetHealth < 1 )
PlaySound3D "conjuration cast"
Resurrect
Return
Endif
If ( combatCheck < 1 )
If ( GetSoundPlaying "Weapon Swish" )
Set combatCheck to 1
ElseIf ( GetSoundPlaying "crossbowShoot" )
Set combatCheck to 1
ElseIf ( GetSoundPlaying "bowShoot" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "Health Damage" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "destruction hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "frost_hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "shock hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "alteration hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "illusion hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "Hand To Hand Hit" )
Set combatCheck to 1
Elseif ( GetSoundPlaying "Hand To Hand Hit 2" )
Set combatCheck to 1
Elseif ( combatCheck == -1 )
AiWander 1000 0 0 0 50 50
Set warp to 0
Set combatCheck to 0
EndIf
Elseif ( combatCheck == 1 )
If ( warp == 0 )
Set warp to 1 ;warp to player
Else
Set timer to 5
Endif
Set combatCheck to -1
Endif
If ( warp < 1 )
Return
Elseif ( warp == 1 ) ; pull to player
Set myX to GetPos x
Set myY to GetPos y
Set playerX to ( Player->GetPos x )
Set playerY to ( Player->GetPos y )
Set playerZ to ( Player->GetPos z )
Set warp to 2
Elseif ( warp == 2 )
If ( playerX < myX )
Set myX to ( playerX + 128 )
Else
Set myX to ( playerX - 128 )
Endif
If ( playerY < myY )
Set myY to ( playerY + 128 )
Else
Set myY to ( playerY - 128 )
Endif
Set warp to 3
Elseif ( warp == 3 )
SetPos x myX ;doesn't work
SetPos y myY ;doesn't work
SetPos z playerZ ;doesn't work
Set warp to 4 ;does work
Elseif ( warp == 4 )
RemoveSpellEffects uvi_daesc_pull
If ( combatCheck )
AiEscort Player 0 0 0 0 0
Set warp to -1
Else
AiWander 0 0 0 0 50 50
Set warp to 0
Endif
Set timer to 5
Endif
End
I've been using the uvi_daesc_pull spell to test it, because all that does is the warp. I know the spell is triggering the script properly, because as I said, all the variables are being set properly. It just decides, "Nah, I'm not gonna actually do the SetPos part," and skips to warp 4. It isn't the timer interfering either, because I check that it's reset to 0 before casting again.