Jump to content

The_Vyper

Members
  • Posts

    726
  • Joined

  • Last visited

Posts posted by The_Vyper

  1. The problem you're running into actually has to do with the way ownership is processed by the game engine. If something that can be locked (such as a container or door) is owned by the Player or an NPC, the owner will be able to access it without a key regardless of lock level. That's something that can't be changed at the modder level. There is a possible workaround, but it requires a few steps:

     

    1. Place two unique chests in the cell; one owned by the NPC and the other without ownership of any kind.

    2. Make both chests persistent references with their own unique RefIDs and set the Player's chest to "Initially disabled" (I'll use PkNpcChestRef and PkPlayerChestRTef as examples, but you can choose whatever you want for a RefID as long as it's unique).

    3.Add a script to the key that will disable the NPC's chest, enable the Player's chest, and copy everything in the NPC's chest to the Player's chest once the Player is given the key. The script itself should look like this:

    scn PkStanTiKeyScript
     
    Short DoOnce
     
    Begin OnAdd Player ; this block will only run when the key is added to the Player's inventory
     
      If DoOnce == 0
     
        PkNpcChestRef.DuplicateAllItems PkPlayerChestRef
        PkNpcChestRef.Disable 
        PkPlayerChestRef.Enable
        Set DoOnce to 1
     
      EndIf
     
    End
    

    That should fix the "stealing" problem (as long as the cell isn't owned by anyone) while also requiring the player to have the key in order to open it.

  2. The problem with using OnTrigger instead of OnTriggerActor is that OnTrigger runs when any havoked object hits the trigger zone. I need this to run only when an actor triggers it, and I need the script to be as generic as possible so I can place multiple instances of this setup in game without needing to script each one individually.


    A full breakdown of what I'm trying to accomplish is:

    1. Actor enters trigger zone (creature, NPC, or Player)

    2.Timer starts counting down.

    3. Timer reaches 0, caster fires at the triggering actor.

    4. Repeat 2-3 for as long as the actor is within the trigger zone.

    5. Actor exits trigger zone, caster stops shooting.

    6. Actor re-enters trigger zone (or a new actor does).

    7. Repeat 2-5.


    What's actually happening:

    1. Actor enters trigger zone (creature, NPC, or Player)

    2.Timer starts counting down.

    3. Timer reaches 0, caster fires at the triggering actor.

    4. Timer starts counting down again.

    5. Timer reaches 0, caster fires north. (maybe it has a problem with Skyrim?)

    6. Repeat 4-5 for as long as the actor is within the trigger zone.

    7. Actor exits trigger zone, caster stops shooting.

    8. Actor re-enters trigger zone (or a new actor does).

    9. Repeat 2-7.


    I'm wondering if the Triggered short might be the part of the problem. Should I eliminate that and just go with the timer?


    This may be unrelated, but the "casting reference fires north" issue is one I've run into before when trying to script an activator to fire at multiple persistent references in sequence. If the target references are static objects (such as XMarkers), the shooting activator will only fire north, although it will fire at the appropriate intervals. If the target references are activators (enabled or disabled), the caster will fire in the correct directions at the correct intervals.

  3. I'm trying to script a trigger zone to cause a linked reference to fire at any actor who crosses its threshold, and continues to fire at them periodically while they remain withing the trigger zone's boundary. The script I'm using is:

    scn AAAATestTrigZoneDingus01Script
     
    Short Triggered
     
    Ref Monkey
     
    Ref Blastar
     
    Float Timer
     
    Begin OnTriggerActor
     
     If Triggered == 0
       Set Triggered to 1
       Set Blastar to GetParentRef
       Set Monkey to GetActionRef
       Set Timer to 1
     EndIf
     
    End
     
    Begin GameMode
     
      If Triggered == 1
        If Timer <= 0
          Blastar.Cast MajesticDmgHealth10 Monkey
          Set Triggered to 0
        Else
          Set Timer to Timer - GetSecondsPassed
        EndIf
      EndIf
     
    End
    
    The problem is that the reference only fires at the triggering actor once, then fires straight north until the actor leaves the trigger zone boundary. If the actor then re-enters the trigger zone, the reference fires on them once more then starts firing north again. Also, if I increase the Timer in the OnTriggerActor block, the reference refuses to fire at all.
    Any ideas on how to fix this so the reference consistently fires on the triggering actor (and does so once every 4 to 8 seconds instead of once per second)?
  4. 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 ARTrapEvilStone01SCRIPT
     
    ; when activated will shoot fireball at player after 3 sec
     
    float timer
    short ready
    ref mySelf
    ref myParent
    short next
    short SpellRank
     
    begin onActivate
     
    if isActionRef player == 0 && timer <= 0 && ready == 0
    playgroup forward 1
    set timer to 8
    set ready to 1
    set next to 1
    endif
     
    end
     
    begin gameMode
     
    ; daisy-chain
    if next == 1 && timer <= 5
    set mySelf to getSelf
    set myParent to getParentRef
    myParent.activate mySelf 1
    set next to 0
    endif
     
    ;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
     
    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
    endif
    set ready to 0
    endif
     
    if timer > 0
    set timer to timer - getSecondsPassed
    endif
     
    end

    My modified version 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

    For some reason, 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?
  5. I ban Pagafyr for misspelling TARDIS (Time And Relative Dimension In Space) and for assuming I borrowed it without the Doctor's knowledge or permission. You think I want to incur the Doctor's wrath? No way! I'd rather face an army of Daleks!

     

    I also ban PoorlyAged for having an avatar from Avatar.

  6. The method you're using for creating the icons different from the method I use, and I use the same tools. Here's what I do:

     

    1. Open the mesh in NifSkope and position the object the way I want it to look in the Icon.

     

    2. Press PrintScreen on the keyboard.

     

    3. Open GIMP and select New from the File menu.

     

    4. Select an image that's the size the same as my screen resolution. (In my case, it's 1440x900)

     

    5. Once the blank file opens, press Ctrl+V to paste your screenshot. (this is why you press PrintScreen in step 2)

     

    6. Click on the Rectangle Select Tool and click outside the highlighted image. (If I don't do this, GIMP will move my whole image instead of opening a selection box when I try the next step. Weird, but oh well.)

     

    7. Now select the part of your image you want to use as the icon. Make sure the selection box is perfectly square (you can do this by pressing & holding the Shift key while selecting the desired image portion. You can also manually set the selection box dimensions in the related section of the Toolbox.)

     

    8. Click on Image and select Crop To Selection.

     

    9. Go to Layer, Highlight Transparency, and select Add Alpha Channel.

     

    10. Click Select By Color and click on the background color you want to get rid of.

     

    11. Click on Edit and select Cut.

     

    12. Now scale the image to 64x64 and save the result in DTX3 with no mipmaps.

     

    That's the process I use and I haven't run into any problems (yet).

  7. If I'm understanding what you want, you're basically looking to create an announcement of sorts that can be posted on a wall and won't fly all over the place if somebody brushes against it. You don't need to remove the havoc settings in order to accomplish this, just change a few settings. Following these steps should get you what you want:

     

    1. Open the mesh in NifSkope.

     

    2. Find and expand the bhkCollisionObject node (5 on the Broadsheet01.nif)

     

    3. Select bhkRigidBody.

     

    4. In the Block Details list, change the following settings:

    Change OL_UNIDENTIFIED to OL_STATIC (Note: there are two instances of OL_UNIDENTIFIED and you need to change both)

    Change MO_SYS_BOX to MO_SYS_FIXED

    Change MO_QUAL_DEBRIS to MO_QUAL_FIXED

     

    5. Save the result as a new mesh and you're done.

     

    It's important to change all of those settings, otherwise you'll get weird results in game (speaking from experience here :laugh: ).

     

    Note: When you make the note object in the CS, make sure you select the "Can't be taken" flag so nobody can pick it up in game.

     

×
×
  • Create New...