WillieSea

General Script Questions #2

160 posts in this topic

Here is one idea, a bit late, though, and from someone not too experienced in magic effect thingies. But something relatively easy to accomplish might be using an activator, placed in a separate cell, that is moved to the target, made cast a spell and then moved back to the holding cell. Like:

  • Create a new cell, place an xmarker and an activator (create a new one, for example) in there
  • Set the Editor ID of the activator to something unique you will remember, like NefariousAlienMashmellows
  • Set the xmarker as the activator's enable parent

And you will have an activator ready for use. The xmarker is just something to move the activator back to when spell has been cast. Now onto the script in your Katana! I think. To make things relatively simple, you could make a new magic effect, with a Script Effect, and use the code in the effect. This way, it will work universally without the need to use OBSE event handlers or anything. In your script, you will want to

  • pick a random spell (you have these ready, right)
  • move the activator to the target
  • have the activator cast the chosen spell on the target
  • move the activator away

So it could look a bit like this (not sure exactly, been a few months since I did any Oblivion scripting, but something to give the idea of what it might look like):

ScriptName MyMagicEffectScript

ref       rMe     ; the target this effect script runs on
ref       rSpell  ; the spell picked for use
float     fTemp   ; temporary integer
Array_var aSpells ; array of spells you have selected

Begin ScriptEffectStart

    let aSpells := ar_Construct Array ; initiliase the array
    ar_Append aSpells SpellNumberOne  ; add a spell to the array
    ar_Append aSpells SpellNumberTwo  ; add another spell, etc.
    let fTemp  := ar_Size aSpells     ; get array size
    let fTemp  -= 1                   ; size = indexes + 1
    let fTemp  := rand 0 fTemp        ; get random index... maybe?
    let fTemp  := floor fTemp         ; to round it down?
    let rSpell := aSpells[fTemp]      ; get spell at index
    let rMe    := GetSelf             ; get the actor this runs on
    NefariousAlienCucumber.MoveTo rMe
    NefariousAlienCucumber.Cast rSpell rMe
    MessageEX "Activator cast %q%n%q on %q%n%q!", rSpell rMe
    let rMe := NefariousAlienCucumber.GetParentRef
    NefariousAlienCucumber.MoveTo rMe ; move to the parent xmarker
    
End

Hopefully that helps you a little. I have no idea how floating point numbers work as list indices. Feel free to ask if you run into issues, I can see if I could help you somehow. And hope I do not end up needing help myself, as well. :P

Also, if someone has a better idea, I would love to hear it. Adding effects to NPCs is not my expertise. Just adding spells tagged as "ability" might be a better option if it works. That way, you would not need to have the activator thingy. If it works, that is. Just an idea.

Edited by PhilippePetain
fixed a typo, also a few errors
0

Share this post


Link to post
Share on other sites

I'm trying to modify the script for those spell-casting stones in Ayleid ruins so they target all actors in range instead of just the Player.

 

The original script is:

 

	scn ARTrapEvilStoneAUTOFIRE01SCRIPT
	; come within range and this thing will shoot a fireball at you (range is 700)
	float timer
short ready
short disabled
short SpellRank
	begin onActivate
	    if isActionRef player == 0
        if disabled == 0
            set disabled to 1
            set timer to 0
        else
            set disabled to 0
        endif
    endif
	end
	begin gameMode
	    if SpellRank == 0 && disabled == 0
	        if getDistance player < 700 && timer <= 0
            playgroup forward 0
            set ready to 1
            set timer to 8
        
            ;This section will choose the trap spell based on the PC's level... hopefully
            if player.GetLevel <= 5
                set SpellRank to 1
            elseif ( player.GetLevel >= 6 ) && ( player.GetLevel <= 10 )
                set SpellRank to 2
            elseif ( player.GetLevel >= 11 ) && ( player.GetLevel <= 15 )
                set SpellRank to 3
            elseif ( player.GetLevel >= 16 ) && (player.GetLevel <= 20)
                set SpellRank to 4
            elseif ( player.GetLevel >= 21 )
                set SpellRank to 5
            endif
        endif
    endif
	    if timer <= 4 && ready == 1 && SpellRank > 0
        ; check to make sure player is still in range
        if getDistance player < 700
            ;Debug message
            ;message "Rank %.0f Freezy Spell", SpellRank, 10
            if SpellRank == 1
                cast StandardFrostDamageTarget1Novice player
            elseif SpellRank == 2
                cast StandardFrostDamageTarget2Apprentice player
            elseif SpellRank == 3
                cast StandardFrostDamageTarget3Journeyman player
            elseif SpellRank == 4
                cast StandardFrostDamageTarget4Expert player
            elseif SpellRank == 5
                cast StandardFrostDamageTarget5Master player
            endif
            set ready to 0
            set spellrank to 0
	        endif
    
    endif
	    if timer > 0
        set timer to timer - getSecondsPassed
    endif
    
end
	begin onReset
	    reset3DState
    set SpellRank to 0
end

 

My modified script is:

 

	scn AATestTrapStoneActor01SCRIPT
	; come within range and this thing will shoot a fireball at you (range is 1400)
	float timer
short ready
short disabled
short SpellRank
Ref Actor
	begin onActivate
     
     Set Actor to GetActionRef
	        if disabled == 0
            set disabled to 1
            set timer to 0
        else
            set disabled to 0
        endif
    
	end
	begin gameMode
	    if SpellRank == 0 && disabled == 0
	        if getDistance Actor < 1400 && timer <= 0
            playgroup forward 0
            set ready to 1
            set timer to 8
        
            ;This section will choose the trap spell based on the PC's level... hopefully
            if player.GetLevel <= 5
                set SpellRank to 1
            elseif ( player.GetLevel >= 6 ) && ( player.GetLevel <= 10 )
                set SpellRank to 2
            elseif ( player.GetLevel >= 11 ) && ( player.GetLevel <= 15 )
                set SpellRank to 3
            elseif ( player.GetLevel >= 16 ) && (player.GetLevel <= 20)
                set SpellRank to 4
            elseif ( player.GetLevel >= 21 )
                set SpellRank to 5
            endif
        endif
    endif
	    if timer <= 4 && ready == 1 && SpellRank > 0
        ; check to make sure player is still in range
        if getDistance Actor < 1400
            ;Debug message
            ;message "Rank %.0f Freezy Spell", SpellRank, 10
            if SpellRank == 1
                cast StandardFrostDamageTarget1Novice Actor
            elseif SpellRank == 2
                cast StandardFrostDamageTarget2Apprentice Actor
            elseif SpellRank == 3
                cast StandardFrostDamageTarget3Journeyman Actor
            elseif SpellRank == 4
                cast StandardFrostDamageTarget4Expert Actor
            elseif SpellRank == 5
                cast StandardFrostDamageTarget5Master Actor
            endif
            set ready to 0
            set spellrank to 0
	        endif
    
    endif
	    if timer > 0
        set timer to timer - getSecondsPassed
    endif
    
end
	begin onReset
	    reset3DState
    set SpellRank to 0
	end
	

This does absolutely nothing; it doesn't fire at anyone or anything, or even play any animations. What do I need to do to get this thing to fire at every creature and/or NPC in range?

0

Share this post


Link to post
Share on other sites
57 minutes ago, The Vyper said:

I'm trying to modify the script for those spell-casting stones in Ayleid ruins so they target all actors in range instead of just the Player.

The original script is:

It would be faster if you modified the spell itself so that it has a radius range, wouldn't it?

0

Share this post


Link to post
Share on other sites
3 hours ago, ladyonthemoon said:

It would be faster if you modified the spell itself so that it has a radius range, wouldn't it?

Modifying the spells won't have any effect. The activator itself is what fires the spells at the Player once the Player gets in range. There are multiple versions of the vanilla script in question (at least one of which fires area effect spells at the Player), but all of them target the Player exclusively. I'm trying to find a way to script the activator to fire at any and all Actors in range. It never made sense to me that the vanilla activators only fired at the Player.

0

Share this post


Link to post
Share on other sites

Couldn't you just remove the check for if the actionref is the player?

0

Share this post


Link to post
Share on other sites
13 hours ago, HeyYou said:

Couldn't you just remove the check for if the actionref is the player?

I could, but then it would try to fire at the Player whenever any actor walked within range. I need some way to set other actors as the reference targets. Is there a way to set up a TriggerZone to have a non-unique linked reference fire at the triggering actor?

0

Share this post


Link to post
Share on other sites

on that, I don't know. Been too long since I played with Oblivion scripting. :D

0

Share this post


Link to post
Share on other sites
12 hours ago, HeyYou said:

on that, I don't know. Been too long since I played with Oblivion scripting. :D

Same here. :D Oh well, it was worth a try.

0

Share this post


Link to post
Share on other sites

Is there a difference between setting an object reference name within the view window versus setting the name within a script?

0

Share this post


Link to post
Share on other sites

I'm running into an odd problem. I've set up a trigger zone to cause a non-unique linked reference to cast a spell at any actor who triggers it. The problem is that the reference will fire at the triggering actor once, and then fire straight north from that point on until the actor exits the trigger zone. If the actor then re-enters the trigger zone, the reference will again fire at them once and then start shooting north. The script I'm using is:

 

	scn TestTrigZoneDingus01Script
	Short Triggered
	Ref Victim
	Ref Dingus
	Float Timer
	Begin OnTriggerActor
	 If Triggered == 0
   Set Triggered to 1
   Set Dingus to GetParentRef
   Set Victim to GetActionRef 
   Set Timer to 1
 EndIf
	End
	Begin GameMode
	  If Triggered == 1
    If Timer <= 0
      Dingus.Cast MajesticDmgHealth10 Victim
      Set Triggered to 0
    Else
      Set Timer to Timer - GetSecondsPassed
    EndIf
  EndIf
	End
	

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now