Jump to content

Tricky Scripting Questions


Recommended Posts

Hello, people!

I have really tricky (at least for me) questions. Wil be happy for any clue in these ones.

 

Q.1. How to teleport actor right behind the player by script?

Context: After the dialogue player receives two followers who have to be teleported by varibale (in dialogue result script). But they can appear right behind my eyes which is distorbing for game experience. 

So I've found a script by Wrye from his Summon Bed mod (link from here). I've shaped it as a function but still can't figure out how to change it porperly according to my idea. That's it:

  

Spoiler

scn teleport

; Done from Summon Bed mod as an example by Wrye

float pos
float ang ;(the measure of the angle, first deg, then radians)
float ang2 ;(ang^2) Just for convenience. Could use ang*ang directly.
float ang4 ;(ang^4) Just for convenience. Could use ang*ang*ang*ang directly.
float sign ;sign correction
float sin ;(sine of the angle)
float cos ;(cosine of the angle)

ref rMovable


begin function {rMovable}

  ; Now, want to summon bed and place it in front of player at 150 units.
    ; So, need to get player heading (north == 0, increasing clockwise, 
    ; (east == 90), going up to 360.) Then use fourth/fifth order polynomial
    ; approximations for sin and cos.
    ;--sin, cos
    set sign to 1
    set ang to player.getAngle z
    if ang > 270
        set ang to ang - 360
    elseif ang > 90
        set ang to ang - 180
        set sign to -1
    endif
    set ang to 0.017453*ang 
    set ang2 to ang * ang
    set ang4 to ang2 * ang2
    set sin to sign*ang*(1 - 0.16605*ang2 + 0.00761*ang4)
    set cos to sign*(1 - 0.4967*ang2 + 0.03705*ang4)

    ;--Move it
    rMovable.moveTo player 

    set pos to player.getPos x + 150*sin
   rMovable.setPos x pos
    
    set pos to player.getPos y + 150*cos
   rMovable.setPos y pos

    set pos to player.getPos z + 55 ;--Tweak offset to put object on ground.
  rMovable.setPos z pos

    ;--Set angle of bed relative to PC heading
    set ang to player.getAngle z + 90
  rMovable.setAngle x 0
 rMovable.setAngle y 0
  rMovable.setAngle z ang

    ;--Done
   rMovable.enable


    end


Q.2. How to create a reference via script from base object in the cell?

Context: I've tried to create a varla's holder activator so you can put a varla stone here ('ve already created special static nif for it) but I don't want to just enable\disable it and tried to make something more dynamical. And I've found out that you cannot actually create a ref by script! Or I just don't understand how to do it? Here is my attempt:

Spoiler

float x1
float x2

float y1
float y2

float z1
float z2

float scaleHolder
float ScaleStone

short activated

ref rMe

ref rStone

;float placeAngle

begin onactivate

    let rMe := getself

    let rStone := BBVarlaStaticREF.getbaseobject
    
    let x1 := rme.getangle x

let y1 := rme.getangle y

    let z1 := rme.getangle z

    let scaleHolder := rme.getscale
    let ScaleStone := scaleHolder + 0.2

let x2 := x1 + (0.0955)
        let y2 := y1 + (-0.0936)
        let z2 := z1 + (5.0167)
    
    if activated == 0
        if player.GetItemCount VarlaStone > 0
        if (isformvalid rStone)
        

                rStone.moveto rMe     x2, y2, z2

                

                let activated := 1

            else 
                message "form is invalid"
                return
            endif
        else
            message "You don't have a varla stone"
            return
        endif
    else
        player.additem varlastone 1
        rStone.DeleteReference

         
endif


Q.3. The most tricky one. How to make  a scripted movement for an actor to a dynamic point?
Context:  It'll be easier if I put it more clear. I created an activator which should make a player "jump" to the point above the activator wherever he is. 

This activator is a hook which is used to "jump" the player to the roof of the building. A way around for players who haven't a high acrobatics skill. But it seems to be a really tough scripting.

It should analyze an actual player's position, then a position of hook ref, then create a step by which it would move the player to the hook position via the parabola (with "jumping" animation loop) and after player has grounded to the roof the script should be stopped. Maybe somebody has seen something similar in mods? I have some code but it doesn't have any considerable shape now.

Thank to all who'd try to help!
 

Edited by ArtemSHikoff
Link to comment
Share on other sites

Here's a code snippet from one of our follower scripts. This script would be placed on the NPC. This allows a follower to catch up if they lag behind. They will wind up just behind the player.

ModControlQuest is a quest that you would create to hold global variables, like follower and OrderStay. Both are shorts (short integers). Also note that this script uses OBSE syntax since my mods usually require OBSE. You'll have to change all the let... to set if you aren't using OBSE.

short doOnce
float distancePlayer
short lagging
float angle
Begin gameMode
	let distancePlayer := GetDistance Player
	
	if (ModControlQuest.follower == 1) && (ModControlQuest.OrderStay == 0) && (Player.IsInInterior == 0)
		if lagging == 0
			if distancePlayer > 2000
				let lagging := 1
			endif
		else
			let lagging := 0
			Disable
			let angle := player.GetAngle Z
			if angle < 45 || angle > 315
				MoveTo Player 0 -50 0	; south
			elseif angle < 135
				MoveTo Player -50 0 0	; west
			elseif angle < 225
				MoveTo Player 0 50 0	; north
			else
				MoveTo Player 50 0 0	; east
			endif
			Enable
		endif
	endif
End

PlaceAtMe should be avoided as it causes saved game bloat. I have to use it in Imperial Furniture Renovated, but I destroy the reference once I'm done with it to avoid bloat. You might want to check it out as you might find the placement scripts useful for what you're trying to do.

  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

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