Difference between revisions of "Talk:SetPos"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>GuidoBot
(fyi notes to script example)
imported>8asrun6aer
 
(14 intermediate revisions by 6 users not shown)
Line 4: Line 4:


'''This does not work:'''
'''This does not work:'''
<pre>SetPos X (GetPos X   40)</pre>
<pre>SetPos X (GetPos X + 40)</pre>


'''This works:'''
'''This works:'''
<pre>short xPos
<pre>short xPos
Set xPos to (GetPos X   40)
Set xPos to (GetPos X + 40)
SetPos X xPos</pre>
SetPos X xPos</pre>


Line 44: Line 44:


:I think only the Disable/Enable is necessary in combo with the MoveTo as it may be needed to reset their collison meshes(?) I have had CTD's [for some objects] when I used Enable/Disable in the same frame. If you have such trouble then spilt them so they are called on successive frames. [[User:GuidoBot|GuidoBot]] 22:58, 11 April 2007 (EDT)
:I think only the Disable/Enable is necessary in combo with the MoveTo as it may be needed to reset their collison meshes(?) I have had CTD's [for some objects] when I used Enable/Disable in the same frame. If you have such trouble then spilt them so they are called on successive frames. [[User:GuidoBot|GuidoBot]] 22:58, 11 April 2007 (EDT)
::Just tried the above code and it did work! Thanks. I have a moving light that stops shining on new objects as it moves. Additional tweaking showed that just adding the two lines below, before my original SetPos, did the trick. In my case, it worked fine without the disable/enable. [[User:QQuix|QQuix]] 12:21, 7 September 2008 (EDT)
<dl><dl>
<pre>LightRef.positioncell 0 0 0 0 AbandonedMine
LightRef.moveto player</pre></dl></dl>
=Havok, setPos, and MoveTo=
I've been doing some experiments and one thing to keep in mind is setPos is ignored by havok... so any velocity the object had before calling setPos will be retained, and havok will apply it's gravity and collision rules at the new position to update that velocity. This means if you do a "levitate" spell that uses setPos to hold the actor up in the air, the actor will accumulate velocity from gravity, so when your spell wears off he will slingshot into the ground. [[User:ABO|ABO]] 22:35, 21 May 2008 (EDT)
:I'm not sure if I heard this about '''SetPos''' or '''MoveTo''' (I believe it was SetPos), but it did stop the velocity of arrows. That is, if you use '''SetPos''' to offset an arrow to the side, it will stop right there and drop to the ground.--[[User:Haama|Haama]] 11:54, 26 June 2008 (EDT)
=setPos, getPos, and swimming=
Something very strange happens when swimming. If you do ''setPos X'' or ''setPos Y'' when swimming, the Z position will also be "reset" to a value that I think is supposed to put you at the surface of the water (-5 in my particular tests). If you do ''setPos Z'', it will move you vertically, but when you do ''getPos Z'' it will report a value about +90 above what you specified. This behaviour seems to change when you are under water vs swimming at the surface. The following piece of code will result in the player floating above the surface of the water [[User:ABO|ABO]];
set zp to player.getPos Z
player.setPos Z zp
=How to avoid Wall/Ceiling Collisions=
Basically: how to avoid setting an object/actor's position to inside or beyond a wall or ceiling?  For ground, there's the [[Determining_Ground_Position]] discussion page going on.  But as for walls and ceilings, any hints?
:There isn't really a good way. You could maybe try firing an invisible projectile in the desired direction, find it using [[GetFirstRef]], and then following it until it hits a wall? I've thought about doing things like that in theory quite a few times, but I've avoided actually having to try it to see if it would work.
:[[User:DragoonWraith|<span style="font-family: Oblivion; size=2;">D</span>ragoon <span style="font-family: Oblivion; size=2;">W</span>raith]] [[User_talk:DragoonWraith|<span style="font-family: Oblivion; size=2;">TALK</span>]] 11:06, 22 December 2011 (EST)
:: For Player flying at least, I tested jumping (or triggering a jump), and while in the air, holding and adjusting only the Z position.  Though somewhat glitchy, with flight speed dependent on how fast you were running when jumping, it works for flying as collisions with walls still register while allowing you to move forward/back/strafe in-air.  Combined with hints from [[Determining_Ground_Position]], it effectively prevents moving through the ground and through walls... just not the ceiling.  Still, hopefully there's a better, more simple way. --[[User:8asrun6aer|8asrun6aer]] 2011-12-22
:::If the player were put on some invisible platform, and the ''platform'' were moved under them (such that the difference in height from frame to frame was rather small), they might stay on it without calling SetPos on the player at all, thereby maintaining collision. Maybe. Be a tricky script to set up. I'd probably store the player's XY position in two float variables, setting the new Z by looking at the XY distance traveled, doing some trig using [[GetAngle]], and then using Disable, MoveTo, Enable on the platform to maintain collision. Probably with some maximum angle above and below the horizontal so that the player doesn't clip through the platform.
:::In-game, this will look a lot like the player is running through the air — which is exactly what Levitate used to look like.
:::[[User:DragoonWraith|<span style="font-family: Oblivion; size=2;">D</span>ragoon <span style="font-family: Oblivion; size=2;">W</span>raith]] [[User_talk:DragoonWraith|<span style="font-family: Oblivion; size=2;">TALK</span>]] 10:53, 23 December 2011 (EST)
::::I believed I found a solution.  In OBSE 20, they added a [[SetVelocity]]/[[GetVelocity]] pair of functions.  Accounting for gravity and using a basic trig for flight-paths and flight-speed, it avoids wall/ceiling/obstacle/ground clipping altogether.  For moving platforms, I imagine it would take making sure [[resetFallDamageTimer]] is always called each frame, and increasing player's downward Z velocity depending on the drop-speed of the lift.
::::[[User:8asrun6aer|8asrun6aer]] 19:32, 23 December 2011 (EST);
::::In fact, with this, I think my flying script is complete.  I started a new [[Flying]] page to document it all.
::::[[User:8asrun6aer|8asrun6aer]] 19:32, 23 December 2011 (EST);

Latest revision as of 21:46, 23 December 2011

I added some additional information that helped me in the process of scripting my mods.--Omzy 11:50, 13 June 2006 (EDT)

Setting this value via computations does not work. Instead, use GetPos with computations and use the result as a variable for SetPos.

This does not work:

SetPos X (GetPos X + 40)

This works:

short xPos
Set xPos to (GetPos X + 40)
SetPos X xPos


What's the point of this info? No Function accepts expressions as parameters.--JOG 12:11, 13 June 2006 (EDT)
Dragoon Wraith TALK 14:36, 13 June 2006 (EDT): Is that fact anywhere on the Wiki? Because I didn't realize that for a while...
Well, it's implicit that only those things work that are specified as working, when we find out something that wasn't mentioned before we add it, but there is no point in adding info to random functions that things from other programming languages don't work here. There are no arrays, no sub-procedures, no default values on variable definition, no control structures besides if, and so on...--JOG 15:33, 13 June 2006 (EDT)


If you're having a problem getting light to shed properly after updating its position using SetPos, here is a solution using a combination of MoveTo, SetPos, a persistent Light Form, and a Dummy Cell:

Begin GameMode

  PersistentLightReference.PositionCell 0 0 0 0 DummyCell
   ; Using PositionCell because SetAtStart did not work,
   ; though using a Marker in conjunction with MoveTo might- didn't test

  PersistentLightReference.Disable
  PersistentLightReference.MoveTo Player
  Set PlayerPosX to Player.GetPos X
  Set PlayerPosY to Player.GetPos Y
  Set PlayerPosZ to Player.GetPos Z
  PersistentLightReference.SetPos X PlayerPosX
  PersistentLightReference.SetPos Y PlayerPosY
  PersistentLightReference.SetPos Z PlayerPosZ
  PersistentLightReference.Enable

End

You could conceivably use another MoveTo in conjunction with a Marker instead of PositionCell, but this method is simpler.

This is just the core of the solution, of course. You'll have to declare the Floats PlayerPosX/Y/Z, place a persistent Light, make a Dummy Cell to move to and from, and replace any references or set up any conditionals in the GameMode block that you need for your particular application. For those of you who are still confused, the exact implementation is included in my Wieldable Torches mod.--The Munchkin Lord 23:06, 25 February 2007 (EST)

I think only the Disable/Enable is necessary in combo with the MoveTo as it may be needed to reset their collison meshes(?) I have had CTD's [for some objects] when I used Enable/Disable in the same frame. If you have such trouble then spilt them so they are called on successive frames. GuidoBot 22:58, 11 April 2007 (EDT)
Just tried the above code and it did work! Thanks. I have a moving light that stops shining on new objects as it moves. Additional tweaking showed that just adding the two lines below, before my original SetPos, did the trick. In my case, it worked fine without the disable/enable. QQuix 12:21, 7 September 2008 (EDT)
LightRef.positioncell 0 0 0 0 AbandonedMine 
LightRef.moveto player

Havok, setPos, and MoveTo[edit source]

I've been doing some experiments and one thing to keep in mind is setPos is ignored by havok... so any velocity the object had before calling setPos will be retained, and havok will apply it's gravity and collision rules at the new position to update that velocity. This means if you do a "levitate" spell that uses setPos to hold the actor up in the air, the actor will accumulate velocity from gravity, so when your spell wears off he will slingshot into the ground. ABO 22:35, 21 May 2008 (EDT)

I'm not sure if I heard this about SetPos or MoveTo (I believe it was SetPos), but it did stop the velocity of arrows. That is, if you use SetPos to offset an arrow to the side, it will stop right there and drop to the ground.--Haama 11:54, 26 June 2008 (EDT)

setPos, getPos, and swimming[edit source]

Something very strange happens when swimming. If you do setPos X or setPos Y when swimming, the Z position will also be "reset" to a value that I think is supposed to put you at the surface of the water (-5 in my particular tests). If you do setPos Z, it will move you vertically, but when you do getPos Z it will report a value about +90 above what you specified. This behaviour seems to change when you are under water vs swimming at the surface. The following piece of code will result in the player floating above the surface of the water ABO;

set zp to player.getPos Z
player.setPos Z zp


How to avoid Wall/Ceiling Collisions[edit source]

Basically: how to avoid setting an object/actor's position to inside or beyond a wall or ceiling? For ground, there's the Determining_Ground_Position discussion page going on. But as for walls and ceilings, any hints?

There isn't really a good way. You could maybe try firing an invisible projectile in the desired direction, find it using GetFirstRef, and then following it until it hits a wall? I've thought about doing things like that in theory quite a few times, but I've avoided actually having to try it to see if it would work.
Dragoon Wraith TALK 11:06, 22 December 2011 (EST)
For Player flying at least, I tested jumping (or triggering a jump), and while in the air, holding and adjusting only the Z position. Though somewhat glitchy, with flight speed dependent on how fast you were running when jumping, it works for flying as collisions with walls still register while allowing you to move forward/back/strafe in-air. Combined with hints from Determining_Ground_Position, it effectively prevents moving through the ground and through walls... just not the ceiling. Still, hopefully there's a better, more simple way. --8asrun6aer 2011-12-22
If the player were put on some invisible platform, and the platform were moved under them (such that the difference in height from frame to frame was rather small), they might stay on it without calling SetPos on the player at all, thereby maintaining collision. Maybe. Be a tricky script to set up. I'd probably store the player's XY position in two float variables, setting the new Z by looking at the XY distance traveled, doing some trig using GetAngle, and then using Disable, MoveTo, Enable on the platform to maintain collision. Probably with some maximum angle above and below the horizontal so that the player doesn't clip through the platform.
In-game, this will look a lot like the player is running through the air — which is exactly what Levitate used to look like.
Dragoon Wraith TALK 10:53, 23 December 2011 (EST)
I believed I found a solution. In OBSE 20, they added a SetVelocity/GetVelocity pair of functions. Accounting for gravity and using a basic trig for flight-paths and flight-speed, it avoids wall/ceiling/obstacle/ground clipping altogether. For moving platforms, I imagine it would take making sure resetFallDamageTimer is always called each frame, and increasing player's downward Z velocity depending on the drop-speed of the lift.
8asrun6aer 19:32, 23 December 2011 (EST);
In fact, with this, I think my flying script is complete. I started a new Flying page to document it all.
8asrun6aer 19:32, 23 December 2011 (EST);