Advertisement
Guest User

NF T2 1.1 Polarity Script + Dependencies

a guest
Mar 21st, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VBScript 13.36 KB | None | 0 0
  1.  
  2. 'NF start
  3.  
  4.  
  5.  
  6. 'Other necessary Script modifications:
  7. 'Next to LeftFlipper.RotateToEnd add LF.ProcessBalls (or comment it out and use LF.Fire)
  8. 'Next to RightFlipper.RotateToEnd add RF.ProcessBalls (or comment it out and use RF.Fire)
  9.  
  10. 'Object dependencies:
  11. LeftFlipper & Rightflipper (Specifically from T2 1.1~)
  12. TriggerLF and TriggerRF (Triggers)
  13. EndPointLp and EndPointRp (Helper primitives)
  14.  
  15. For Debug:
  16. StickR primitive
  17. Textboxes named 'TB' and 'TBPL'
  18.  
  19.  
  20. 'FlipperPolarity 0.10
  21.  
  22. 'No longer includes overall speedhack because it was redundant with the velocity correction stuff.
  23. 'If you are experiencing flipper lag please rig up solenoids on a 1-interval timer, or use a flipper solenoid if possible!!
  24.  
  25.  
  26. 'Setup -                                                            
  27. 'Triggers tight to the flippers TriggerLF and TriggerRF. Timers as low as possible
  28. 'Debug box TBpl (for .debug = True)
  29.  
  30.  
  31. dim LF : Set LF = New FlipperPolarity
  32. dim RF : Set RF = New FlipperPolarity
  33. InitPolarity
  34. Sub InitPolarity()
  35.     dim x, a : a = Array(LF, RF)
  36.     for each x in a
  37.         'safety coefficient (diminishes polarity correction only)
  38.         'x.AddPoint "Ycoef", 0, RightFlipper.Y-65, 0    'don't mess with these
  39.         x.AddPoint "Ycoef", 0, RightFlipper.Y-65, 1 'disabled
  40.         x.AddPoint "Ycoef", 1, RightFlipper.Y-11, 1
  41.  
  42.         x.enabled = True
  43.         'x.DebugOn = True : stickL.visible = True : tbpl.visible = True ': vpmflips.DebugOn = True
  44.         x.TimeDelay = 44
  45.     Next
  46.         'T2 1.11
  47.         rf.report "Velocity"
  48.         addpt "Velocity", 0, 0,     1
  49.         addpt "Velocity", 1, 0.2,   1.07
  50.         addpt "Velocity", 2, 0.41, 1.05
  51.         addpt "Velocity", 3, 0.44, 1
  52.         addpt "Velocity", 4, 0.65,  1.0'0.982
  53.         addpt "Velocity", 5, 0.702, 0.968
  54.         addpt "Velocity", 6, 0.95,  0.968
  55.         addpt "Velocity", 7, 1.03,  0.945
  56.  
  57.  
  58.         rf.report "Polarity"
  59.         AddPt "Polarity", 0, 0, 0
  60.         AddPt "Polarity", 1, 0.16, -4.7
  61.         AddPt "Polarity", 2, 0.33, -5
  62.         AddPt "Polarity", 3, 0.37, -4.7 '4.2
  63.         AddPt "Polarity", 4, 0.41, -5.3
  64.         AddPt "Polarity", 5, 0.45, -5 '4.2
  65.         AddPt "Polarity", 6, 0.576,-4.7
  66.         AddPt "Polarity", 7, 0.66, -2.8'-2.1896
  67.         AddPt "Polarity", 8, 0.743, -1.5
  68.         AddPt "Polarity", 9, 0.81, -1.5
  69.         AddPt "Polarity", 10, 0.88, 0
  70.  
  71.     LF.Object = LeftFlipper
  72.     LF.EndPoint = EndPointLp    'you can use just a coordinate, or an object with a .x property. Using a couple of simple primitive objects
  73.     RF.Object = RightFlipper
  74.     RF.EndPoint = EndPointRp
  75. End Sub
  76.  
  77. Sub AddPt(aStr, idx, aX, aY)    'debugger wrapper for adjusting flipper script in-game
  78.     dim a : a = Array(LF, RF)
  79.     dim x : for each x in a
  80.         x.addpoint aStr, idx, aX, aY
  81.     Next
  82. End Sub
  83.  
  84.  
  85. Sub TriggerLF_Hit() : LF.Addball activeball : End Sub
  86. Sub TriggerLF_UnHit() : LF.PolarityCorrect activeball : End Sub
  87. Sub TriggerRF_Hit() : RF.Addball activeball : End Sub
  88. Sub TriggerRF_UnHit() : RF.PolarityCorrect activeball : End Sub
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95. 'Methods:
  96. '.TimeDelay - Delay before trigger shuts off automatically. Default = 80 (ms)
  97. '.AddPoint - "Polarity", "Velocity", "Ycoef" coordinate points. Use one of these 3 strings, keep coordinates sequential. x = %position on the flipper, y = output
  98. '.Object - set to flipper reference. Optional.
  99. '.StartPoint - set start point coord. Unnecessary, if .object is used.
  100.  
  101. 'Called with flipper -
  102. 'ProcessBalls - catches ball data.
  103. ' - OR -
  104. '.Fire - fires flipper.rotatetoend automatically + processballs. Requires .Object to be set to the flipper.
  105.  
  106.  
  107. 'Trigger Hit - .AddBall activeball
  108. 'Trigger UnHit - .PolarityCorrect activeball
  109.  
  110. Class FlipperPolarity
  111.     Public DebugOn, Enabled
  112.     Private FlipAt  'Timer variable (IE 'flip at 723,530ms...)
  113.     Public TimeDelay    'delay before trigger turns off and polarity is disabled TODO set time!
  114.     private Flipper, FlipperStart, FlipperEnd, LR, PartialFlipCoef
  115.     Private Balls(20), balldata(20)
  116.    
  117.     dim PolarityIn, PolarityOut
  118.     dim VelocityIn, VelocityOut
  119.     dim YcoefIn, YcoefOut
  120.     Public Sub Class_Initialize
  121.         redim PolarityIn(0) : redim PolarityOut(0) : redim VelocityIn(0) : redim VelocityOut(0) : redim YcoefIn(0) : redim YcoefOut(0)
  122.         Enabled = True : TimeDelay = 50 : LR = 1:  dim x : for x = 0 to uBound(balls) : balls(x) = Empty : set Balldata(x) = new SpoofBall : next
  123.     End Sub
  124.    
  125.     Public Property let Object(aInput) : Set Flipper = aInput : StartPoint = Flipper.x : End Property
  126.     Public Property Let StartPoint(aInput) : if IsObject(aInput) then FlipperStart = aInput.x else FlipperStart = aInput : end if : End Property
  127.     Public Property Get StartPoint : StartPoint = FlipperStart : End Property
  128.     Public Property Let EndPoint(aInput) : if IsObject(aInput) then FlipperEnd = aInput.x else FlipperEnd = aInput : end if : End Property
  129.     Public Property Get EndPoint : EndPoint = FlipperEnd : End Property
  130.    
  131.     Public Sub AddPoint(aChooseArray, aIDX, aX, aY) 'Index #, X position, (in) y Position (out)
  132.         Select Case aChooseArray
  133.             case "Polarity" : ShuffleArrays PolarityIn, PolarityOut, 1 : PolarityIn(aIDX) = aX : PolarityOut(aIDX) = aY : ShuffleArrays PolarityIn, PolarityOut, 0
  134.             Case "Velocity" : ShuffleArrays VelocityIn, VelocityOut, 1 :VelocityIn(aIDX) = aX : VelocityOut(aIDX) = aY : ShuffleArrays VelocityIn, VelocityOut, 0
  135.             Case "Ycoef" : ShuffleArrays YcoefIn, YcoefOut, 1 :YcoefIn(aIDX) = aX : YcoefOut(aIDX) = aY : ShuffleArrays YcoefIn, YcoefOut, 0
  136.         End Select
  137.         if gametime > 100 then Report aChooseArray
  138.     End Sub
  139.  
  140.     Public Sub Report(aChooseArray)     'debug, reports all coords in tbPL.text
  141.         if not DebugOn then exit sub
  142.         dim a1, a2 : Select Case aChooseArray
  143.             case "Polarity" : a1 = PolarityIn : a2 = PolarityOut
  144.             Case "Velocity" : a1 = VelocityIn : a2 = VelocityOut
  145.             Case "Ycoef" : a1 = YcoefIn : a2 = YcoefOut
  146.             case else :tbpl.text = "wrong string" : exit sub
  147.         End Select
  148.         dim str, x : for x = 0 to uBound(a1) : str = str & aChooseArray & " x: " & round(a1(x),4) & ", " & round(a2(x),4) & vbnewline : next
  149.         tbpl.text = str
  150.     End Sub
  151.    
  152.     Public Sub AddBall(aBall) : dim x : for x = 0 to uBound(balls) : if IsEmpty(balls(x)) then set balls(x) = aBall : exit sub :end if : Next  : End Sub
  153.  
  154.     Private Sub RemoveBall(aBall)
  155.         dim x : for x = 0 to uBound(balls)
  156.             if TypeName(balls(x) ) = "IBall" then
  157.                 if aBall.ID = Balls(x).ID Then
  158.                     balls(x) = Empty
  159.                     Balldata(x).Reset
  160.                 End If
  161.             End If
  162.         Next
  163.     End Sub
  164.    
  165.     Public Sub Fire()
  166.         Flipper.RotateToEnd
  167.         processballs
  168.     End Sub
  169.  
  170.     Public Property Get Pos 'returns % position a ball. For debug stuff.
  171.         dim x : for x = 0 to uBound(balls)
  172.             if not IsEmpty(balls(x) ) then
  173.                 pos = pSlope(Balls(x).x, FlipperStart, 0, FlipperEnd, 1)
  174.             End If
  175.         Next       
  176.     End Property
  177.  
  178.     Public Sub ProcessBalls() 'save data of balls in flipper range
  179.         FlipAt = GameTime
  180.         dim x : for x = 0 to uBound(balls)
  181.             if not IsEmpty(balls(x) ) then
  182.                 balldata(x).Data = balls(x)
  183.                 if DebugOn then StickL.visible = True : StickL.x = balldata(x).x        'debug TODO
  184.             End If
  185.         Next
  186.         PartialFlipCoef = ((Flipper.StartAngle - Flipper.CurrentAngle) / (Flipper.StartAngle - Flipper.EndAngle))
  187.         PartialFlipCoef = abs(PartialFlipCoef-1)
  188.     End Sub
  189.     Private Function FlipperOn() : if gameTime < FlipAt+TimeDelay then FlipperOn = True : End If : End Function 'Timer shutoff for polaritycorrect
  190.    
  191.     Public Sub PolarityCorrect(aBall)
  192.         if FlipperOn() then
  193.             dim tmp, BallPos, x, IDX, Ycoef : Ycoef = 1
  194.             dim teststr : teststr = "Cutoff"
  195.             tmp = PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1)
  196.             if tmp < 0.1 then 'if real ball position is behind flipper, exit Sub to prevent stucks  'Disabled 1.03, I think it's the Mesh that's causing stucks, not this
  197.                 if DebugOn then TestStr = "real pos < 0.1 ( " & round(tmp,2) & ")" : tbpl.text = Teststr
  198.                 'RemoveBall aBall
  199.                 'Exit Sub
  200.             end if
  201.  
  202.             'y safety Exit
  203.             if aBall.VelY > -8 then 'ball going down
  204.                 if DebugOn then teststr = "y velocity: " & round(aBall.vely, 3) & "exit sub" : tbpl.text = teststr
  205.                 RemoveBall aBall
  206.                 exit Sub
  207.             end if
  208.             'Find balldata. BallPos = % on Flipper
  209.             for x = 0 to uBound(Balls)
  210.                 if aBall.id = BallData(x).id AND not isempty(BallData(x).id) then
  211.                     idx = x
  212.                     BallPos = PSlope(BallData(x).x, FlipperStart, 0, FlipperEnd, 1)
  213.                     'TB.TEXT = balldata(x).id & " " & BALLDATA(X).X & VBNEWLINE & FLIPPERSTART & " " & FLIPPEREND
  214.                     if ballpos > 0.65 then  Ycoef = LinearEnvelope(BallData(x).Y, YcoefIn, YcoefOut)                'find safety coefficient 'ycoef' data
  215.                 end if
  216.             Next
  217.  
  218.             'Velocity correction
  219.             if not IsEmpty(VelocityIn(0) ) then
  220.                 Dim VelCoef
  221.                 if DebugOn then set tmp = new spoofball : tmp.data = aBall : End If
  222.                 if IsEmpty(BallData(idx).id) and aBall.VelY < -12 then 'if tip hit with no collected data, do vel correction anyway
  223.                     if PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1) > 1.1 then 'adjust plz
  224.                         VelCoef = LinearEnvelope(5, VelocityIn, VelocityOut)
  225.                         if partialflipcoef < 1 then VelCoef = PSlope(partialflipcoef, 0, 1, 1, VelCoef)
  226.                         if Enabled then aBall.Velx = aBall.Velx*VelCoef'VelCoef
  227.                         if Enabled then aBall.Vely = aBall.Vely*VelCoef'VelCoef
  228.                         if DebugOn then teststr = "tip protection" & vbnewline & "velcoef: " & round(velcoef,3) & vbnewline & round(PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1),3) & vbnewline
  229.                         'debug.print teststr
  230.                     end if
  231.                 Else
  232.          :          VelCoef = LinearEnvelope(BallPos, VelocityIn, VelocityOut)
  233.                     if Enabled then aBall.Velx = aBall.Velx*VelCoef
  234.                     if Enabled then aBall.Vely = aBall.Vely*VelCoef
  235.                 end if
  236.             End If
  237.  
  238.             'Polarity Correction (optional now)
  239.             if not IsEmpty(PolarityIn(0) ) then
  240.                 If StartPoint > EndPoint then LR = -1   'Reverse polarity if left flipper
  241.                 dim AddX : AddX = LinearEnvelope(BallPos, PolarityIn, PolarityOut) * LR
  242.                 if Enabled then aBall.VelX = aBall.VelX + 1 * (AddX*ycoef*PartialFlipcoef)
  243.             End If
  244.             'debug
  245.             if DebugOn then
  246.                 TestStr = teststr & "%pos:" & round(BallPos,2)
  247.                 if IsEmpty(PolarityOut(0) ) then
  248.                     teststr = teststr & vbnewline & "(Polarity Disabled)" & vbnewline
  249.                 else
  250.                     teststr = teststr & "+" & round(1 *(AddX*ycoef*PartialFlipcoef),3)
  251.                     if BallPos >= PolarityOut(uBound(PolarityOut) ) then teststr = teststr & "(MAX)" & vbnewline else teststr = teststr & vbnewline end if 
  252.                     if Ycoef < 1 then teststr = teststr &  "ycoef: " & ycoef & vbnewline
  253.                     if PartialFlipcoef < 1 then teststr = teststr & "PartialFlipcoef: " & round(PartialFlipcoef,4) & vbnewline             
  254.                 end if
  255.  
  256.                 teststr = teststr & vbnewline & "Vel: " & round(BallSpeed(tmp),2) & " -> " & round(ballspeed(aBall),2) & vbnewline
  257.                 teststr = teststr & "%" & round(ballspeed(aBall) / BallSpeed(tmp),2)
  258.                 tbpl.text = TestSTR
  259.             end if
  260.         Else
  261.             'if DebugOn then tbpl.text = "td" & timedelay
  262.         End If
  263.         RemoveBall aBall
  264.     End Sub
  265. End Class
  266.  
  267.  
  268. '================================
  269.  
  270.  
  271.  
  272. 'Helper Functions
  273.  
  274.  
  275. Sub ShuffleArray(ByRef aArray, byVal offset) 'shuffle 1d array
  276.     dim x, aCount : aCount = 0
  277.     redim a(uBound(aArray) )
  278.     for x = 0 to uBound(aArray) 'Shuffle objects in a temp array
  279.         if not IsEmpty(aArray(x) ) Then
  280.             if IsObject(aArray(x)) then
  281.                 Set a(aCount) = aArray(x)
  282.             Else
  283.                 a(aCount) = aArray(x)
  284.             End If
  285.             aCount = aCount + 1
  286.         End If
  287.     Next
  288.     if offset < 0 then offset = 0
  289.     redim aArray(aCount-1+offset)   'Resize original array
  290.     for x = 0 to aCount-1       'set objects back into original array
  291.         if IsObject(a(x)) then
  292.             Set aArray(x) = a(x)
  293.         Else
  294.             aArray(x) = a(x)
  295.         End If
  296.     Next
  297. End Sub
  298.  
  299. Sub ShuffleArrays(aArray1, aArray2, offset)
  300.     ShuffleArray aArray1, offset
  301.     ShuffleArray aArray2, offset
  302. End Sub
  303.  
  304.  
  305. Function BallSpeed(ball) 'Calculates the ball speed
  306.    BallSpeed = SQR(ball.VelX^2 + ball.VelY^2 + ball.VelZ^2)
  307. End Function
  308.  
  309. Function PSlope(Input, X1, Y1, X2, Y2)  'Set up line via two points, no clamping. Input X, output Y
  310.     dim x, y, b, m : x = input : m = (Y2 - Y1) / (X2 - X1) : b = Y2 - m*X2
  311.     Y = M*x+b
  312.     PSlope = Y
  313. End Function
  314.  
  315.  
  316.  
  317.  
  318. 'Variable Envelope. Infinite amount of points!
  319. 'Keep keyframes in order, bounds equal, and all that.
  320. '   L1          L2        L3        L4      L5... etc...      L(uBound(xKeyFrame)
  321. '          .
  322. '        /  \
  323. '      /      \                .
  324. '    /          \           _/  \__
  325. '  /              \       _/       \__
  326. '/                  \ . /             \__
  327. '0.........1..........2........3.........4..........etc........uBound(xKeyFrame)
  328.  
  329.  
  330. 'in animation's case, xInput = MS
  331. Function LinearEnvelope(xInput, xKeyFrame, yLvl)
  332.     dim y 'Y output
  333.     dim L 'Line
  334.     dim ii : for ii = 1 to uBound(xKeyFrame)    'find active line
  335.         if xInput <= xKeyFrame(ii) then L = ii : exit for : end if
  336.     Next
  337.     if xInput > xKeyFrame(uBound(xKeyFrame) ) then L = uBound(xKeyFrame)    'catch line overrun
  338.     Y = pSlope(xInput, xKeyFrame(L-1), yLvl(L-1), xKeyFrame(L), yLvl(L) )
  339.  
  340.     'Clamp if on the boundry lines
  341.     'if L=1 and Y < yLvl(LBound(yLvl) ) then Y = yLvl(lBound(yLvl) )
  342.     'if L=uBound(xKeyFrame) and Y > yLvl(uBound(yLvl) ) then Y = yLvl(uBound(yLvl) )
  343.     'clamp 2.0
  344.     if xInput <= xKeyFrame(lBound(xKeyFrame) ) then Y = yLvl(lBound(xKeyFrame) )    'Clamp lower
  345.     if xInput >= xKeyFrame(uBound(xKeyFrame) ) then Y = yLvl(uBound(xKeyFrame) )    'Clamp upper
  346.  
  347.     LinearEnvelope = Y
  348. End Function
  349.  
  350.  
  351.  
  352. Class spoofball
  353.     Public X, Y, Z, VelX, VelY, VelZ, ID, Mass, Radius
  354.     Public Property Let Data(aBall)
  355.         With aBall
  356.             x = .x : y = .y : z = .z : velx = .velx : vely = .vely : velz = .velz
  357.             id = .ID : mass = .mass : radius = .radius
  358.         end with
  359.     End Property
  360.     Public Sub Reset()
  361.         x = Empty : y = Empty : z = Empty  : velx = Empty : vely = Empty : velz = Empty
  362.         id = Empty : mass = Empty : radius = Empty
  363.     End Sub
  364. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement