LeahTheUnknown Posted April 12, 2020 Share Posted April 12, 2020 I'm working on a new mod called "LAGO - Linearly Aligning Geometric Objects." Basically, I'm making Lego blocks. They are supposed to snap together like their real-world counterparts. The script I'm writing for them is, to put it mildly, driving me insane. The script is supposed to do, in essence, four things: 1. Orient itself to upright when released from the player's grip, 2. Request nearby blocks position data, 3. Orient itself to the nearest block, and 4. Send position data when a released block nearby requests it. I can't seem to get past the first part. When I release a block, it tries to translate to x0, y0, whether there is a close block or not. The script is in the spoiler, and I've linked a 7z of the mod so far, if you want to see what it does. As for the texturing, I've downloaded a bunch of badass textures from a guy's blog (he allows any use, and of course I will credit/link/Ko-Fi him on the mod page). They include spec and normal maps, but they are... off (have weird shadows/lighting) in game and the Creation Kit (the textures look fine in NifSkope). GKX Lago.7z Google Drive Link Scriptname _gkx_lagoblocks extends ObjectReference Struct PositionData Float XPos Float YPos Float ZPos Float ZAngle Float XSize Float YSize Float ZSize EndStruct Float Property XLength Auto Float Property YDepth Auto Float Property ZHeight Auto Float Property SearchRadius Auto _gkx_lagoblocks[] BlockScript _gkx_lagoblocks MyScript CustomEvent SendMyLocation CustomEvent RequestLocations PositionData MyData PositionData Nearest PositionData[] CloseBlocks Int DataIndex = 0 Int NearIndex = 0 Bool Busy1 = FALSE Bool Busy2 = FALSE Bool Busy3 = FALSE Bool Busy4 = FALSE Bool BeenMoved = FALSE Bool TranslateMe = FALSE Float Radius Float NewRadius Float SameRadius Event OnInit() MyScript = Self RegisterForHitEvent(Self) SetMotionType(1) SameRadius = ((Math.Min(XLength, YDepth)) / 4.0) RegisterForCustomEvent(BlockScript, "RequestLocations") RegisterForCustomEvent(BlockScript, "SendMyLocation") EndEvent Event OnHit(ObjectReference Target, ObjectReference Aggressor, Form Source, Projectile Proj, bool PAttack, bool SAttack, bool BAttack, bool Blocked, string Material) If ((Proj) || (PAttack) || (SAttack) || (BAttack)) Disable() Delete() Else SetMotionType(1) EndIf EndEvent Event _gkx_lagoblocks.RequestLocations(_gkx_lagoblocks Sender, Var[] SourceData) If (CalcDistance(ArrayToStruct(SourceData)) < SearchRadius) && BeenMoved Var[] SendMe = new Var[8] SendMe = (StructToArray(MyData)) SendCustomEvent("SendMyLocation", SendMe) EndIf EndEvent Event _gkx_lagoblocks.SendMyLocation(_gkx_lagoblocks Sender, Var[] RecData) CloseBlocks[DataIndex] = ArrayToStruct(RecData) DataIndex += 1 EndEvent Event OnGrab() CloseBlocks.Clear() DataIndex = 0 EndEvent Event OnRelease() SetMotionType(2) FillCurrentPosition() While Busy4 Utility.Wait(0.1) EndWhile TranslateTo(MyData.XPos, MyData.YPos, MyData.ZPos, 0.0, 0.0, MyData.ZAngle, 10.0, 1440.0) SendCustomEvent("RequestLocations") Bool Receiving = TRUE Utility.Wait(0.1) Int OldLength = CloseBlocks.Length While Receiving Utility.Wait(0.1) If CloseBlocks.Length == OldLength Receiving = FALSE EndIf OldLength = CloseBlocks.Length EndWhile If CloseBlocks.Length > 0 FindNearest() While Busy1 Utility.Wait(0.1) EndWhile MyData = FixMyData(CloseBlocks[NearIndex]) While Busy2 Utility.Wait(0.1) EndWhile CloseBlocks.Clear() DataIndex = 0 Else FillCurrentPosition() While Busy4 Utility.Wait(0.1) EndWhile TranslateMe = TRUE EndIf If TranslateMe TranslateTo(MyData.XPos, MyData.YPos, MyData.ZPos, 0.0, 0.0, MyData.ZAngle, 10.0, 1440.0) BeenMoved = TRUE Else SetMotionType(1) EndIf EndEvent Function FindNearest() Busy1 = TRUE Int Count1 = 0 Float Smallest = SearchRadius Float Latest = 0.0 While (Count1 < CloseBlocks.Length) Latest = CalcDistance(CloseBlocks[Count1]) If Latest < Smallest Smallest = Latest NearIndex = Count1 EndIf Count1 += 1 EndWhile Busy1 = FALSE EndFunction PositionData Function ArrayToStruct(Var[] InputArray) PositionData TempPos TempPos.Xpos = InputArray[0] as Float TempPos.Ypos = InputArray[1] as Float TempPos.Zpos = InputArray[2] as Float TempPos.ZAngle = InputArray[3] as Float TempPos.XSize = InputArray[4] as Float TempPos.YSize = InputArray[5] as Float TempPos.ZSize = InputArray[6] as Float Return TempPos EndFunction Var[] Function StructToArray(PositionData InputPos) Var[] TempArray = New Var[8] TempArray[0] = InputPos.Xpos TempArray[1] = InputPos.Ypos TempArray[2] = InputPos.Zpos TempArray[3] = InputPos.ZAngle TempArray[4] = InputPos.XSize TempArray[5] = InputPos.YSize TempArray[6] = InputPos.ZSize TempArray[7] = MyScript Return TempArray EndFunction Float Function CalcDistance(PositionData CalcData) Float XSquared = Math.Pow((MyData.XPos - CalcData.XPos), 2.0) Float YSquared = Math.Pow((MyData.YPos - CalcData.YPos), 2.0) Float ZSquared = Math.Pow((MyData.ZPos - CalcData.ZPos), 2.0) Float Distance = Math.Sqrt(XSquared + YSquared + ZSquared) Return Distance EndFunction PositionData Function FixMyData(PositionData UseThis) Busy2 = TRUE PositionData TempData Float XYDistance Float ZAngleDiff = Math.Abs(UseThis.ZAngle - MyData.ZAngle) Float XPosDiff = Math.Abs(UseThis.XPos - MyData.XPos) Float YPosDiff = Math.Abs(UseThis.YPos - MyData.YPos) Float ZPosDiff = Math.Abs(UseThis.ZPos - MyData.ZPos) If (ZAngleDiff <=90.0) TempData.ZAngle = UseThis.ZAngle ElseIf (ZAngleDiff <= 180.0) TempData.ZAngle = (UseThis.ZAngle + 90.0) ElseIf (ZAngleDiff <= 270.0) If (UseThis.ZAngle > 0) TempData.ZAngle = (UseThis.ZAngle - 180.0) Else TempData.ZAngle = (UseThis.ZAngle + 180.0) EndIf Else TempData.ZAngle = (UseThis.ZAngle - 90.0) EndIf If (IsSame(MyData.ZPos, UseThis.ZPos, SameRadius)) TempData.ZPos = UseThis.ZPos EndIf XYDistance = Hypot(XPosDiff, YPosDiff) If (XYDistance <= SameRadius) TempData.XPos = UseThis.XPos TempData.YPos = UseThis.YPos If (MyData.ZPos > UseThis.ZPos) TempData.ZPos = (UseThis.ZSize + MyData.ZPos) Else TempData.ZPos = (UseThis.ZPos - MyData.ZSize) EndIf Else NewRadius = FixRadius(UseThis, MyData, XYDistance) While Busy3 Utility.Wait(0.1) EndWhile If !TranslateMe TempData.XPos = Self.GetPositionX() TempData.YPos = Self.GetPositionY() TempData.ZPos = Self.GetPositionZ() TempData.ZAngle = Self.GetAngleZ() Else TempData.XPos = (Math.Cos(TempData.ZAngle) * NewRadius) TempData.YPos = (Math.Sin(TempData.ZAngle) * NewRadius) EndIf EndIf Busy2 = FALSE Return TempData EndFunction Float Function FixRadius(PositionData Source, PositionData Me, Float OldRadius) Busy3 = TRUE Float SXHalf = (Source.XSize * 0.5) Float SYHalf = (Source.YSize * 0.5) Float MXHalf = (Me.XSize * 0.5) Float MYHalf = (Me.YSize * 0.5) Float[] PossRadii = New Float[11] PossRadii[0] = SXHalf PossRadii[1] = SYHalf PossRadii[2] = (SXHalf + MXHalf) PossRadii[3] = (SXHalf + MXHalf) PossRadii[4] = (SYHalf + MXHalf) PossRadii[5] = (SYHalf + MYHalf) PossRadii[6] = (Hypot(SXHalf, SYHalf)) PossRadii[7] = (Hypot(SXHalf, (SXHalf + MXHalf))) PossRadii[8] = (Hypot(SXHalf, (SXHalf + MYHalf))) PossRadii[9] = (Hypot(SYHalf, (SYHalf + MXHalf))) PossRadii[10] = (Hypot(SYHalf, (SYHalf + MYHalf))) Int Count1 = 0 Bool FoundIt = FALSE Float Result Float TempRadius = (Math.Max(Source.XSize, Source.YSize) / 2.0) While (Count1 < 11) && !FoundIt FoundIt = IsSame(PossRadii[Count1], OldRadius, TempRadius) If FoundIt Result = PossRadii[Count1] EndIf Count1 += 1 EndWhile Busy3 = FALSE If !FoundIt || (Count1 >= 11) TranslateMe = FALSE Return 1000.0 Else TranslateMe = TRUE Return Result EndIf EndFunction Function NewPosition() DataIndex = 0 FillCurrentPosition() EndFunction Bool Function IsSame(Float Num1, Float Num2, Float NumRadius) Float DiffNum = (Math.Abs(Num1 - Num2)) If DiffNum < NumRadius Return TRUE Else Return FALSE EndIf EndFunction Float Function Hypot(Float Num1, Float Num2) Float Result = (Math.Sqrt((Num1 * Num1) + (Num2 * Num2))) Return Result EndFunction Function FillCurrentPosition() Busy4 = TRUE MyData.XPos = Self.GetPositionX() MyData.YPos = Self.GetPositionY() MyData.ZPos = Self.GetPositionZ() MyData.ZAngle = Self.GetAngleZ() MyData.XSize = XLength MyData.YSize = YDepth MyData.ZSize = ZHeight Busy4 = FALSE EndFunction Link to comment Share on other sites More sharing options...
Reneer Posted April 12, 2020 Share Posted April 12, 2020 My suggestion would be to start adding debug.trace calls in your code to see exactly what is going on. There are simply too many variables and too much complexity to figure out at a glance what exactly is causing the problem (and unfortunately I don't have the time to try and run the mod). Cool idea, though. As an aside, I would suggest you look into changing how you are interacting with your DataIndex / ClosedBlock code, especially your RequestLocations / SendMyLocation events, because it is going to send that to every single instance of your _gkx_lagoblocks, all at once. I can pretty much guarantee you that once you hit a certain number of blocks you will crash the game due to a Papyrus stack overflow. I know this from my own experience in creating a lighting mod for Fallout 4 (and the crashes will likely occur on consoles / older PCs even if you can't reproduce it on your own machine). I would suggest that you change the code to send data to specific blocks in the given radius rather than to every block (which would just be a call to a new function on a specific Objectreference). Link to comment Share on other sites More sharing options...
Oynlen Posted April 12, 2020 Share Posted April 12, 2020 for textures, you have only included one of a white brick wall. it looks quite bad as in, it looks like it was much smaller originally and is now pixelated and low resolution at the size of 1024x1024. Tthe Spec and normal are not right for fallout. Spec looks far to bright and normal.. I have never seen that format. Any image can be converted to work in fallout, but its a lot to type. you seem smart, I have never understood scripting, so If you jus check some tutorial vids on how to convert textures to work in Fallout 4 or Skyrim, I'm sure you will figure it out. Get Gimp photo editor for free and the DDs plugin for it found on github Link to comment Share on other sites More sharing options...
YouDoNotKnowMyName Posted April 12, 2020 Share Posted April 12, 2020 Why don't you just use snap points, like the settlement building pieces? Link to comment Share on other sites More sharing options...
DocMoebius Posted April 12, 2020 Share Posted April 12, 2020 As for the texturing, I've downloaded a bunch of badass textures from a guy's blog (he allows any use, and of course I will credit/link/Ko-Fi him on the mod page). They include spec and normal maps, but they are... off (have weird shadows/lighting) in game and the Creation Kit (the textures look fine in NifSkope).Textures need to be in the right format. I'm using BC3 for dif, BC5 for normals and specular. For further information, I would recommend to watch this vid https://www.youtube.com/watch?v=3cDJ0Rk7hC0Secondly, as you may have noticed, you have a material file, which can greatly influence how the texture looks in game through different things such as specular multiplier, greyscaling, environment mapping, the used cube etc, so you might want to take a look into that as well/experiment with it. Link to comment Share on other sites More sharing options...
YouDoNotKnowMyName Posted April 12, 2020 Share Posted April 12, 2020 Texture problems?Don't forget to run the final nif file through Elric befoe putting it in the game ...(I think I said that for like the third time this weekend ... ) Link to comment Share on other sites More sharing options...
LeahTheUnknown Posted April 12, 2020 Author Share Posted April 12, 2020 I realized after I downloaded them, the textures are 1k 72dpi jpegs. When I get my stimulus money, I'll toss the guy some patreon money for the 4k textures. I did save the normal and speculars as BC5 and the diffuse as BC3, and I used a brick wall BGSM from the game files and just replaced the textures. I don't know, Elric messed up my model. It stripped out the collision data completely... As for the script, I'll do what Reneer suggested Thanks everyone~GKX Link to comment Share on other sites More sharing options...
DocMoebius Posted April 12, 2020 Share Posted April 12, 2020 (edited) I realized after I downloaded them, the textures are 1k 72dpi jpegs. When I get my stimulus money, I'll toss the guy some patreon money for the 4k textures. I did save the normal and speculars as BC5 and the diffuse as BC3, and I used a brick wall BGSM from the game files and just replaced the textures. I don't know, Elric messed up my model. It stripped out the collision data completely... As for the script, I'll do what Reneer suggested Thanks everyone~GKXIf it's the normal brickwall bgsm then it greyscales to a pallet, if I remember it correctly. Try to get rid of the greyscaling and see if this helps. Edited April 12, 2020 by DocMoebius Link to comment Share on other sites More sharing options...
Reneer Posted April 12, 2020 Share Posted April 12, 2020 As for the script, I'll do what Reneer suggestedIf you have any further trouble figuring out what the problem is, feel free to PM me or post again here and I'll be happy to help as best I can. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted April 15, 2020 Share Posted April 15, 2020 GenghisKhanX wrote: "I cannot seem to get past the first part. When I release a block, it tries to translate to x0, y0, whether there is a close block or not." 1. What is a threadlock? WHILE (Busy1) Utility.Wait(0.1) ; Threadlock 1 active ENDWHILE Busy1 = TRUE ; *T* ; ------------ ; code inside that manipulates script data (variables and/or porperties) and may not interrupted ; ------------ Busy1 = False ; ***2. How to init an array or a struct variable (user defined record of given types)? CloseBlocks = new PositionData[0] ; create new array (with userdefined struct) of ZERO length PositionData PD = new PositionData ; create new struct3. Make sure you do not have to many "wait()" inside your code. Its horrible to debug, because of event calling by threads. 4. _gkx_lagoblocks Scriptname _gkx_lagoblocks extends ObjectReference ; https://forums.nexusmods.com/index.php?/topic/8587993-any-advanced-scripters-out-there-want-to-give-this-long-script-a-look-also-need-some-texturing-help/ ; GenghisKhanX wrote:" ; 1. Orient itself to upright when released from the player's grip ; 2. Request nearby blocks position data ; 3. Orient itself to the nearest block ; 4. Send position data when a released block nearby requests it." ; Issue: "I cannot seem to get past the first part. ; When I release a block, it tries to translate to x0, y0, whether there is a close block or not." ;-------------------------------------------------------------------------------------------------------- ;_gkx_lagoblocks MyScript ; UnUSED now ;_gkx_lagoblocks[] BlockScript ; !!?? Struct PositionData ; record structure Float XPos Float YPos Float ZPos Float ZAngle Float XSize Float YSize Float ZSize endStruct ;PositionData Nearest ; UnUSED by default! PositionData MyData PositionData[] CloseBlocks ; array of record *** Keep in mind: max array length is 128 *** ; start values Float PROPERTY XLength auto ; [default=0.0] Float PROPERTY YDepth auto Float PROPERTY ZHeight auto Float PROPERTY SearchRadius auto ; default = 0.0 Float Radius Float SameRadius ; preset by OnInit() ;Float NewRadius ; default = 0 Int DataIndex ;Int NearIndex ; UnUSED ; default = False Bool BeenMoved Bool TranslateMe Bool Busy1 ;Bool Busy2 ; UnUSED ;Bool Busy3 ; UnUSED Bool Busy4 ; user events CustomEvent Request ; RequestLocations ;CustomEvent SendMyLocation ; UnUSED by now ; -- EVENTs -- 4 + 1 ; Destroys the whole array, no Zero length array keeps left ;;; PositionData[] b ;;; CloseBlocks = b EVENT OnInit() SameRadius = Math.Min(XLength, YDepth) SameRadius = SameRadius * 0.25 CloseBlocks = new PositionData[0] ; create new array (with userdefined struct) of ZERO length RegisterForHitEvent(self) ; akSender: The ScriptObject that receives the event we want to also receive. RegisterForCustomEvent(self, "Request") ; register A ;;; RegisterForCustomEvent(self, "SendMyLocation") ; register B ; https://www.creationkit.com/fallout4/index.php?title=SetMotionType_-_ObjectReference ; int Property Motion_Fixed = 0 AutoReadOnly ; int Property Motion_Dynamic = 1 AutoReadOnly ; int Property Motion_Keyframed = 2 AutoReadOnly ; ******************************************* ; *** ARE YOUR SURE THIS IS WORKING HERE? *** ; ******************************************* self.SetMotionType(1) ; Motion_Dynamic ENDEVENT ; ;EVENT OnLoad() ; self.SetMotionType(1) ; Motion_Dynamic ;ENDEVENT ; EVENT OnGrab() ; called when SELF has been grabbed by the player (z-keyed). myF_Grab() ENDEVENT EVENT OnRelease() ; called when SELF has been released by the player (un-z-keyed). WHILE (Busy4) Utility.Wait(0.1) ; Threadlock 4 active ENDWHILE Busy4 = TRUE ; *T* ;-------------------------------- self.SetMotionType(2) ; Motion_KeyFramed FillCurrentPosition() myF_Translate() myF_Wait() IF (CloseBlocks.Length > 0) WHILE (Busy1) Utility.Wait(0.1) ; Threadlock 1 active ENDWHILE Busy1 = TRUE ; *T* ; ------------ FixMyData() myF_Grab() ; ------------ Busy1 = False ; *** ELSE FillCurrentPosition() TranslateMe = TRUE ENDIF IF ( TranslateMe ) myF_Translate() BeenMoved = TRUE ELSE self.SetMotionType(1) ; Motion_Dynamic ENDIF ;-------------------------------- Busy4 = False ; *** ENDEVENT EVENT OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4, String asMaterialName) ;Event OnHit(ObjectReference akTarget, ObjectReference akAggressor, Form akSource, Projectile akProjectile, \ ; bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked, string asMaterialName) IF (akProj) ELSEIF ( b1 ) ELSEIF ( b2 ) ELSEIF ( b3 ) self.SetMotionType(1) ;;; RegisterForHitEvent(self) ; RE-REGISTER ??? RETURN ; - STOP - not hit by projectile OR powerAttack OR sneakAttack OR bashAttack ENDIF ;--------------------- self.DisableNoWait() UnRegisterForCustomEvent(self, "Request") ; unregister (A) ;;; UnRegisterForCustomEvent(self, "SendMyLocation") ; unregister (B) self.Delete() ; mark this objectRef for delete, this script as well ENDEVENT ; (A) EVENT _gkx_lagoblocks.Request(_gkx_lagoblocks akSender, Var[] akArgs) ; akArgs = SourceData myF_ADD( ArrayToStruct(akArgs) ) ENDEVENT ; (B) °°°obsolete°°° ;EVENT _gkx_lagoblocks.SendMyLocation(_gkx_lagoblocks akSender, Var[] akArgs) ; akArgs = RecData ; CloseBlocks.Add( ArrayToStruct(akArgs) ) ; DataIndex += 1 ;ENDEVENT ; -- FUNCTIONs -- 13 ;------------------ FUNCTION myF_Grab() ; internal helper ;------------------ ; Removes all entries from the array, reducing it to a 0-length array. IF ( Busy1 ) ; hanging inside release event ELSE CloseBlocks.Clear() DataIndex = 0 ENDIF ENDFUNCTION ;-------------------------------- FUNCTION myF_ADD(PositionData PD) ; internal helper ;-------------------------------- IF (BeenMoved) && (CalcDistance(PD) < SearchRadius) ; Instead of second custom event we add new position data to the array directly! ;;; SendCustomEvent("SendMyLocation", StructToArray(MyData)) ; call event (B) ;--- CloseBlocks.Add(PD) DataIndex += 1 ;--- ENDIF ENDFUNCTION ;------------------ FUNCTION myF_Wait() ; ??? ;------------------ ; https://www.creationkit.com/fallout4/index.php?title=SendCustomEvent_-_ScriptObject SendCustomEvent("Request", MyData) ; call for event A Utility.Wait(0.1) int OldLength = CloseBlocks.Length WHILE (CloseBlocks) Utility.Wait(0.1) IF (CloseBlocks.Length == OldLength) RETURN ; - STOP - leave the loop and finish function ENDIF OldLength = CloseBlocks.Length ENDWHILE ENDFUNCTION ;;-------------------------------------------- ;Var[] FUNCTION StructToArray(PositionData PD) ; PD = InputPos ;;-------------------------------------------- ;Var[] a = new Var[8] ; ; a[0] = PD.Xpos ; a[1] = PD.Ypos ; a[2] = PD.Zpos ; a[3] = PD.ZAngle ; a[4] = PD.XSize ; a[5] = PD.YSize ; a[6] = PD.ZSize ; a[7] = self ; ; RETURN a ; ARRAY ;ENDFUNCTION ;------------------------------------------- PositionData FUNCTION ArrayToStruct(Var[] a) ; a = InputArray ;------------------------------------------- ; https://www.creationkit.com/fallout4/index.php?title=Struct_Reference PositionData PD = new PositionData PD.Xpos = a[0] as Float PD.Ypos = a[1] as Float PD.Zpos = a[2] as Float PD.ZAngle = a[3] as Float PD.XSize = a[4] as Float PD.YSize = a[5] as Float PD.ZSize = a[6] as Float RETURN PD ; STRUCT ENDFUNCTION ;------------------------------------------- Float FUNCTION CalcDistance(PositionData PD) ; PD = CalcData ;------------------------------------------- float fx = MyData.XPos float fy = MyData.YPos float fz = MyData.ZPos fx = fx - PD.XPos fx = fx * fx ; XSquared fy = fy - PD.YPos fy = fy * fy ; YSquared fz = fz - PD.ZPos fz = fz * fz ; ZSquared RETURN Math.Sqrt(fx + fy + fz) ; Distance ENDFUNCTION ;------------------------ Int FUNCTION FindNearBy() ;------------------------ float R = SearchRadius ; R = Smallest int n = 0 int i = 0 ; i = Count1 WHILE (CloseBlocks) && (i < CloseBlocks.Length) float f = CalcDistance( CloseBlocks[i] ) ; f = Latest IF (f < R) R = f ; decrease search radius n = i ; update return value ENDIF i = i + 1 ENDWHILE RETURN n ; NearIndex ENDFUNCTION ;-------------------------------------------------- Bool FUNCTION IsInside(Float R, Float f1, Float f2) ; f = NumRadius ;-------------------------------------------------- float f = Math.ABS(f1 - f2) RETURN (f < R) ; < TRUE, >= False ENDFUNCTION ;------------------- FUNCTION FixMyData() ;------------------- int n = FindNearBy() ;;; Busy2 = TRUE ; *T* IF ( CloseBlocks ) ELSE RETURN ; - STOP - failsafe ENDIF ;--------------------- ; get a pointer to existing struct as part of array "CloseBlocks" PositionData SDF = CloseBlocks[n] ; SDF = UseThis, n = NearIndex ; create new struct temporarily PositionData PD = new PositionData ; PD = TempData ; z-Angle preset ;~~~~~~~~~~~~~~~ float aZ= SDF.ZAngle float f = Math.ABS(aZ - MyData.ZAngle) ; f = ZAngleDiff IF (f <= 90.0) ; 0 .. 90 PD.ZAngle = aZ ELSEIF (f <= 180.0) ; >90 .. 180 PD.ZAngle = aZ + 90.0 ELSEIF (f > 270.0) ; >270 .. 360 PD.ZAngle = aZ - 90.0 ELSE ; >180 .. 270 IF (fz > 0.0) PD.ZAngle = aZ - 180.0 Else PD.ZAngle = aZ + 180.0 EndIf ENDIF ; z-Pos pre-check ;~~~~~~~~~~~~~~~~ f = SDF.ZPos IF IsInside(SameRadius, MyData.ZPos, f) PD.ZPos = f ENDIF ; distance check ;~~~~~~~~~~~~~~~ ;;; Float ZPosDiff = Math.ABS(SDF.ZPos - MyData.ZPos) float fx = SDF.XPos fx = Math.ABS(fx - MyData.XPos) ; fx = XPosDiff float fy = SDF.YPos fy = Math.ABS(fy - MyData.YPos) ; fy = YPosDiff ;;; f = Hypo(fx, fy) f = Math.Sqrt((fx*fx) + (fy*fy)) ; f = XYDistance IF (f <= SameRadius) fx = SDF.XPos PD.XPos = fx fy = SDF.YPos PD.YPos = fy IF (MyData.ZPos > SDF.ZPos) PD.ZPos = MyData.ZPos + SDF.ZSize ELSE PD.ZPos = SDF.ZPos - MyData.ZSize ENDIF ELSE ;;; WHILE (Busy3) ;;; Utility.Wait(0.1) ; Threadlock 3 active ;;; ENDWHILE ;;; Busy3 = TRUE ; *T* f = FixRadius(SDF, f) ; NewRadius = FixRadius(UseThis, MyData, XYDistance) ;;; Busy3 = False ; *** IF ( TranslateMe ) PD.XPos = Math.Cos(PD.ZAngle) * f PD.YPos = Math.Sin(PD.ZAngle) * f ELSE PD.XPos = self.GetPositionX() PD.YPos = self.GetPositionY() PD.ZPos = self.GetPositionZ() PD.ZAngle = self.GetAngleZ() ENDIF ENDIF ; do not forget these, if you need size !!! PD.XSize = SDF.XSize ; = MyData.XSize PD.YSize = SDF.YSize ; = MyData.YSize PD.ZSize = SDF.ZSize ; = MyData.ZSize MyData = PD ; update the whole script struct variable ;;; Busy2 = False ; *** ENDFUNCTION ;-------------------------------------- Float FUNCTION Hypo(Float fx, Float fy) ;-------------------------------------- RETURN Math.Sqrt((fx*fx) + (fy*fy)) ; distance XY ENDFUNCTION ;-------------------------------------------------- Float FUNCTION FixRadius(PositionData SDF, Float f) ;-------------------------------------------------- ;;; Float SXHalf = (Source.XSize * 0.5) ;;; Float SYHalf = (Source.YSize * 0.5) ;;; Float MXHalf = (Me.XSize * 0.5) ;;; Float MYHalf = (Me.YSize * 0.5) float fx float fy float[] a = new Float[11] ; a = PossRadii fx = SDF.XSize fy = SDF.YSize a[0] = fx * 0.5 ; SXHalf a[1] = fy * 0.5 ; SYHalf float R = Math.Max(fx,fy) * 0.5 ; TempRadius = Math.Max(Source.XSize, Source.YSize) / 2.0 fx = MyData.XSize * 0.5 ; MXHalf fy = MyData.YSize * 0.5 ; MYHalf a[2] = a[0] + fx a[3] = a[0] + fy ; TYPO --> PossRadii[3] = (SXHalf + MXHalf) a[4] = a[1] + fx a[5] = a[1] + fy a[6] = Hypo(a[0], a[1]) a[7] = Hypo(a[0], a[2]) ; (SXHalf + MXHalf) a[8] = Hypo(a[0], a[3]) a[9] = Hypo(a[1], a[4]) a[10]= Hypo(a[1], a[5]) int i = 0 ; i = Count1 WHILE (i < 11) IF IsInside(R, a[i], f) ; f = OldRadius TranslateMe = TRUE RETURN a[i] ; /1 result ENDIF ; ---------- i = i + 1 ENDWHILE TranslateMe = False RETURN 1000.0 ; /2 result ENDFUNCTION ;----------------------------- FUNCTION FillCurrentPosition() ;----------------------------- ;;; IF ( CloseBlocks ) ;;; ; array already created ;;; ELSE ; create new array (with userdefined struct) of ZERO length ;;; CloseBlocks = new PositionData[0] ; see OnInit() event ;;; ENDIF IF ( MyData ) ; struct already created ELSE MyData = new PositionData ; create a userdefined struct ENDIF MyData.XPos = self.GetPositionX() MyData.YPos = self.GetPositionY() MyData.ZPos = self.GetPositionZ() MyData.ZAngle = self.GetAngleZ() MyData.XSize = XLength MyData.YSize = YDepth MyData.ZSize = ZHeight ENDFUNCTION ;----------------------- FUNCTION myF_Translate() ; helper to shrink stack size ;----------------------- IF ( MyData ) float fx = MyData.XPos float fy = MyData.YPos float fz = MyData.ZPos float aZ = MyData.ZAngle self.TranslateTo(fx,fy,fz, 0.0, 0.0, aZ, 10.0, 1440.0) ENDIF ENDFUNCTION ;--------------------- FUNCTION NewPosition() ; ??? ;--------------------- DataIndex = 0 FillCurrentPosition() ENDFUNCTION Link to comment Share on other sites More sharing options...
Recommended Posts