Godschildgaming Posted June 18, 2019 Share Posted June 18, 2019 (edited) So I've turned my eyes to the Khajiit race and noticed 2 spells that really make me upset 1) Eye of Fear and their night eye these upset me because they are cast like normal spells, So I have bound the eye of fear spell to a key but it still upsets me a lot that they still have to do the spell cast animation just to use their abilities. So what I want to do is either cut out the spell cast ability or find a way to shoot a scripted invisible projectile in the direction of the player looking. Down below is my current failure of a script it works in the fact is changes the spell to the racial ability to cast it then switch it to a spell of my choice.Things I have tried:Googling and forum searching for ways to get target ref from cursor/mouse positionSkipanim command - broke 1st person movement when I ran itPlaygroup command - seems to do nothing :/ scn keyscript;canusemagic is a global variablefloat fQuestDelayTimeint maxhint damageresultint waittillcastedint castkeyint nomagint keyheldref raceab01ref raceab02begin gamemodeset maxh to player.getmaxav healthif nomag == 1if player.iscasting != (player == player)set nomag to 0endifendifset castkey to getcontrol 7set fquestdelaytime to 0.01set raceab01 to PwRaceKhajiitDemoralizeif (iskeypressed2 45) != (player == player)set keyheld to 0endifif (iskeypressed2 45)if (Player.cancastpower raceab01)message "power used"selectplayerspell raceab01tapkey castkeyplayer.playgroup idle 1set nomag to 1elsemessage "that would hurt... but script has not been made yet... oh wait... now it is..."set damageresult to maxh*.25set damageresult to 0 - damageresultif keyheld == 0player.modav2 health damageresultset keyheld to 1endifendifendifif nomag == 0if canusemagic == 0selectplayerspell uselessspellendifendifend Edited June 18, 2019 by Godschildgaming Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted June 18, 2019 Share Posted June 18, 2019 Yeah, it's a bit more difficult than that. You can't just call "PlayGroup idle" to abort a playing animation. Rather it will "schedule" the next animation to play. Even with the second parameter being "1" there's still no guarantee for an immediate switch back to idle. Additionally, by using any other means to "disable" or prevent the casting animation from playing you'll only end up disabling your actor from "being able to" cast itself likewise. If the animation doesn't play, the actor will not cast. Now you "could" devise means to "switch" the casting animation temporarily to one without any motion, or a different, more befitting one even, perhaps, by using ToggleSpecialAnim right before and after the cast... But there's also different means. An invisible casting activator doing the casting for you comes to mind, because inanimate objects don't need to play no animations to cast. Just spawn it above yourself, or in front of you, then let "it" cast instead, and move it away (or leave it where it is until next cast, I've seen both solutions used). (https://cs.elderscrolls.com/index.php?title=Casting_Spells_From_An_Activator)You could use GetCrosshairRef to obtain the target you're looking at, but it only finds targets within activation range. A different approach to "aiming" targeted spells at targets outside of activation range would be to make one activator shoot a spell towards another but miss it (I think the key is the NIF file doesn't have collision to hit).Maybe you can make some use of my code in understanding this (however, there's some vector math magic by myself inside for easing my work. It definitely works without vector math and just simple geometric, too, though): DrakeDragonTransformCaster01.MoveTo player let fPosX := 0 let fPosY := 55 * GetScale let fPosZ := 60 * GetScale let vTemp := rSelf.Call DrakeDragonGetVectorGlobal fPosX fPosY fPosZ let fPosX := vTemp[0] + rSelf.GetPos X let fPosY := vTemp[1] + rSelf.GetPos Y let fPosZ := vTemp[2] + rSelf.GetPos Z DrakeDragonTransformCaster01.SetPos X fPosX DrakeDragonTransformCaster01.SetPos Y fPosY DrakeDragonTransformCaster01.SetPos Z fPosZ PrintToConsole "caster at %.02f %.02f %.02f" fPosX fPosY fPosZ DrakeDragonTransformCaster02.MoveTo player let fPosX := 0 let fPosY := 1000 let fPosZ := 60 * GetScale let vTemp := rSelf.Call DrakeDragonGetVectorGlobal fPosX fPosY fPosZ let fPosX := vTemp[0] + rSelf.GetPos X let fPosY := vTemp[1] + rSelf.GetPos Y let fPosZ := vTemp[2] + rSelf.GetPos Z DrakeDragonTransformCaster02.SetPos X fPosX DrakeDragonTransformCaster02.SetPos Y fPosY DrakeDragonTransformCaster02.SetPos Z fPosZ PrintToConsole "dummy target at %.02f %.02f %.02f" fPosX fPosY fPosZ Basically the caster is moved into my cell, gets positioned at a little offset to me relatively (60 above, 55 in front, to not hit myself accidentally, and relative to my scale, which you can neglect in your case),then I use my vector math function to get absolute world coordinates from the player-relative ones I defined (rSelf is the player in your case) and SetPos the caster into its place.The same goes for the target, it's just 1000 units forward away.Then have the caster cast a targeted spell at the target and the projectile will fly into the desired direction you're looking at. If you need it, here's my vector math magic for reference (I consider it common knowledge at this point): scn DrakeDragonGetVectorGlobal float fVecLocX float fVecLocY float fVecLocZ float fAngleX float fAngleY float fAngleZ array_var vVecLoc array_var vVec array_var mRotationX array_var mRotationY array_var mRotationZ array_var mRotationYXZ Begin Function {fVecLocX fVecLocY fVecLocZ} let vVecLoc := ar_Construct Array let vVecLoc[0] := fVecLocX let vVecLoc[1] := fVecLocY let vVecLoc[2] := fVecLocZ let vVecLoc := ForceColumnVector vVecLoc let fAngleX := -GetAngle X let fAngleY := GetAngle Y let fAngleZ := -GetAngle Z let mRotationX := GenerateRotationMatrix X fAngleX let mRotationY := GenerateRotationMatrix Y fAngleY let mRotationZ := GenerateRotationMatrix Z fAngleZ let mRotationYXZ := MatrixMultiply mRotationX mRotationY let mRotationYXZ := MatrixMultiply mRotationZ mRotationYXZ let vVecLoc := MatrixMultiply mRotationYXZ vVecLoc let vVec := ar_Construct Array let vVec[0] := vVecLoc[0][0] let vVec[1] := vVecLoc[1][0] let vVec[2] := vVecLoc[2][0] SetFunctionValue vVec End It's pretty much just basic vector math like we all learned it in school put into ObScript/OBSE terms... well, plus fixing some game engine oddities with their coordinate systems, so don't be surprised the resulting matrix isn't looking like what you expected. It works regardless, in this game. :sweat: Link to comment Share on other sites More sharing options...
Godschildgaming Posted June 19, 2019 Author Share Posted June 19, 2019 Yeah, it's a bit more difficult than that. You can't just call "PlayGroup idle" to abort a playing animation. Rather it will "schedule" the next animation to play. Even with the second parameter being "1" there's still no guarantee for an immediate switch back to idle. Additionally, by using any other means to "disable" or prevent the casting animation from playing you'll only end up disabling your actor from "being able to" cast itself likewise. If the animation doesn't play, the actor will not cast. Now you "could" devise means to "switch" the casting animation temporarily to one without any motion, or a different, more befitting one even, perhaps, by using ToggleSpecialAnim right before and after the cast... But there's also different means. An invisible casting activator doing the casting for you comes to mind, because inanimate objects don't need to play no animations to cast. Just spawn it above yourself, or in front of you, then let "it" cast instead, and move it away (or leave it where it is until next cast, I've seen both solutions used). (https://cs.elderscrolls.com/index.php?title=Casting_Spells_From_An_Activator)You could use GetCrosshairRef to obtain the target you're looking at, but it only finds targets within activation range. A different approach to "aiming" targeted spells at targets outside of activation range would be to make one activator shoot a spell towards another but miss it (I think the key is the NIF file doesn't have collision to hit).Maybe you can make some use of my code in understanding this (however, there's some vector math magic by myself inside for easing my work. It definitely works without vector math and just simple geometric, too, though): DrakeDragonTransformCaster01.MoveTo player let fPosX := 0 let fPosY := 55 * GetScale let fPosZ := 60 * GetScale let vTemp := rSelf.Call DrakeDragonGetVectorGlobal fPosX fPosY fPosZ let fPosX := vTemp[0] + rSelf.GetPos X let fPosY := vTemp[1] + rSelf.GetPos Y let fPosZ := vTemp[2] + rSelf.GetPos Z DrakeDragonTransformCaster01.SetPos X fPosX DrakeDragonTransformCaster01.SetPos Y fPosY DrakeDragonTransformCaster01.SetPos Z fPosZ PrintToConsole "caster at %.02f %.02f %.02f" fPosX fPosY fPosZ DrakeDragonTransformCaster02.MoveTo player let fPosX := 0 let fPosY := 1000 let fPosZ := 60 * GetScale let vTemp := rSelf.Call DrakeDragonGetVectorGlobal fPosX fPosY fPosZ let fPosX := vTemp[0] + rSelf.GetPos X let fPosY := vTemp[1] + rSelf.GetPos Y let fPosZ := vTemp[2] + rSelf.GetPos Z DrakeDragonTransformCaster02.SetPos X fPosX DrakeDragonTransformCaster02.SetPos Y fPosY DrakeDragonTransformCaster02.SetPos Z fPosZ PrintToConsole "dummy target at %.02f %.02f %.02f" fPosX fPosY fPosZ Basically the caster is moved into my cell, gets positioned at a little offset to me relatively (60 above, 55 in front, to not hit myself accidentally, and relative to my scale, which you can neglect in your case),then I use my vector math function to get absolute world coordinates from the player-relative ones I defined (rSelf is the player in your case) and SetPos the caster into its place.The same goes for the target, it's just 1000 units forward away.Then have the caster cast a targeted spell at the target and the projectile will fly into the desired direction you're looking at. If you need it, here's my vector math magic for reference (I consider it common knowledge at this point): scn DrakeDragonGetVectorGlobal float fVecLocX float fVecLocY float fVecLocZ float fAngleX float fAngleY float fAngleZ array_var vVecLoc array_var vVec array_var mRotationX array_var mRotationY array_var mRotationZ array_var mRotationYXZ Begin Function {fVecLocX fVecLocY fVecLocZ} let vVecLoc := ar_Construct Array let vVecLoc[0] := fVecLocX let vVecLoc[1] := fVecLocY let vVecLoc[2] := fVecLocZ let vVecLoc := ForceColumnVector vVecLoc let fAngleX := -GetAngle X let fAngleY := GetAngle Y let fAngleZ := -GetAngle Z let mRotationX := GenerateRotationMatrix X fAngleX let mRotationY := GenerateRotationMatrix Y fAngleY let mRotationZ := GenerateRotationMatrix Z fAngleZ let mRotationYXZ := MatrixMultiply mRotationX mRotationY let mRotationYXZ := MatrixMultiply mRotationZ mRotationYXZ let vVecLoc := MatrixMultiply mRotationYXZ vVecLoc let vVec := ar_Construct Array let vVec[0] := vVecLoc[0][0] let vVec[1] := vVecLoc[1][0] let vVec[2] := vVecLoc[2][0] SetFunctionValue vVec End It's pretty much just basic vector math like we all learned it in school put into ObScript/OBSE terms... well, plus fixing some game engine oddities with their coordinate systems, so don't be surprised the resulting matrix isn't looking like what you expected. It works regardless, in this game. :sweat:wow thats a lot of detail and sure it will come in handy, now I just gotta figure out how to dismantle the code and rescript it for my script Thanks for the help will reply with either a failed or successful attempt in like a few hours Link to comment Share on other sites More sharing options...
Godschildgaming Posted June 19, 2019 Author Share Posted June 19, 2019 Ok now I have a new problem.... I have a activator going to the target and it is right on the target and hits them perfectly with any spell... but I need it to use a demoralize spell... which it refuses to do... It'll shoot fireballs and lighting but gets shy when I try to have it fire a projectile demoralize Link to comment Share on other sites More sharing options...
Recommended Posts