Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'NF start
- 'Other necessary Script modifications:
- 'Next to LeftFlipper.RotateToEnd add LF.ProcessBalls (or comment it out and use LF.Fire)
- 'Next to RightFlipper.RotateToEnd add RF.ProcessBalls (or comment it out and use RF.Fire)
- 'Object dependencies:
- LeftFlipper & Rightflipper (Specifically from T2 1.1~)
- TriggerLF and TriggerRF (Triggers)
- EndPointLp and EndPointRp (Helper primitives)
- For Debug:
- StickR primitive
- Textboxes named 'TB' and 'TBPL'
- 'FlipperPolarity 0.10
- 'No longer includes overall speedhack because it was redundant with the velocity correction stuff.
- 'If you are experiencing flipper lag please rig up solenoids on a 1-interval timer, or use a flipper solenoid if possible!!
- 'Setup -
- 'Triggers tight to the flippers TriggerLF and TriggerRF. Timers as low as possible
- 'Debug box TBpl (for .debug = True)
- dim LF : Set LF = New FlipperPolarity
- dim RF : Set RF = New FlipperPolarity
- InitPolarity
- Sub InitPolarity()
- dim x, a : a = Array(LF, RF)
- for each x in a
- 'safety coefficient (diminishes polarity correction only)
- 'x.AddPoint "Ycoef", 0, RightFlipper.Y-65, 0 'don't mess with these
- x.AddPoint "Ycoef", 0, RightFlipper.Y-65, 1 'disabled
- x.AddPoint "Ycoef", 1, RightFlipper.Y-11, 1
- x.enabled = True
- 'x.DebugOn = True : stickL.visible = True : tbpl.visible = True ': vpmflips.DebugOn = True
- x.TimeDelay = 44
- Next
- 'T2 1.11
- rf.report "Velocity"
- addpt "Velocity", 0, 0, 1
- addpt "Velocity", 1, 0.2, 1.07
- addpt "Velocity", 2, 0.41, 1.05
- addpt "Velocity", 3, 0.44, 1
- addpt "Velocity", 4, 0.65, 1.0'0.982
- addpt "Velocity", 5, 0.702, 0.968
- addpt "Velocity", 6, 0.95, 0.968
- addpt "Velocity", 7, 1.03, 0.945
- rf.report "Polarity"
- AddPt "Polarity", 0, 0, 0
- AddPt "Polarity", 1, 0.16, -4.7
- AddPt "Polarity", 2, 0.33, -5
- AddPt "Polarity", 3, 0.37, -4.7 '4.2
- AddPt "Polarity", 4, 0.41, -5.3
- AddPt "Polarity", 5, 0.45, -5 '4.2
- AddPt "Polarity", 6, 0.576,-4.7
- AddPt "Polarity", 7, 0.66, -2.8'-2.1896
- AddPt "Polarity", 8, 0.743, -1.5
- AddPt "Polarity", 9, 0.81, -1.5
- AddPt "Polarity", 10, 0.88, 0
- LF.Object = LeftFlipper
- LF.EndPoint = EndPointLp 'you can use just a coordinate, or an object with a .x property. Using a couple of simple primitive objects
- RF.Object = RightFlipper
- RF.EndPoint = EndPointRp
- End Sub
- Sub AddPt(aStr, idx, aX, aY) 'debugger wrapper for adjusting flipper script in-game
- dim a : a = Array(LF, RF)
- dim x : for each x in a
- x.addpoint aStr, idx, aX, aY
- Next
- End Sub
- Sub TriggerLF_Hit() : LF.Addball activeball : End Sub
- Sub TriggerLF_UnHit() : LF.PolarityCorrect activeball : End Sub
- Sub TriggerRF_Hit() : RF.Addball activeball : End Sub
- Sub TriggerRF_UnHit() : RF.PolarityCorrect activeball : End Sub
- 'Methods:
- '.TimeDelay - Delay before trigger shuts off automatically. Default = 80 (ms)
- '.AddPoint - "Polarity", "Velocity", "Ycoef" coordinate points. Use one of these 3 strings, keep coordinates sequential. x = %position on the flipper, y = output
- '.Object - set to flipper reference. Optional.
- '.StartPoint - set start point coord. Unnecessary, if .object is used.
- 'Called with flipper -
- 'ProcessBalls - catches ball data.
- ' - OR -
- '.Fire - fires flipper.rotatetoend automatically + processballs. Requires .Object to be set to the flipper.
- 'Trigger Hit - .AddBall activeball
- 'Trigger UnHit - .PolarityCorrect activeball
- Class FlipperPolarity
- Public DebugOn, Enabled
- Private FlipAt 'Timer variable (IE 'flip at 723,530ms...)
- Public TimeDelay 'delay before trigger turns off and polarity is disabled TODO set time!
- private Flipper, FlipperStart, FlipperEnd, LR, PartialFlipCoef
- Private Balls(20), balldata(20)
- dim PolarityIn, PolarityOut
- dim VelocityIn, VelocityOut
- dim YcoefIn, YcoefOut
- Public Sub Class_Initialize
- redim PolarityIn(0) : redim PolarityOut(0) : redim VelocityIn(0) : redim VelocityOut(0) : redim YcoefIn(0) : redim YcoefOut(0)
- Enabled = True : TimeDelay = 50 : LR = 1: dim x : for x = 0 to uBound(balls) : balls(x) = Empty : set Balldata(x) = new SpoofBall : next
- End Sub
- Public Property let Object(aInput) : Set Flipper = aInput : StartPoint = Flipper.x : End Property
- Public Property Let StartPoint(aInput) : if IsObject(aInput) then FlipperStart = aInput.x else FlipperStart = aInput : end if : End Property
- Public Property Get StartPoint : StartPoint = FlipperStart : End Property
- Public Property Let EndPoint(aInput) : if IsObject(aInput) then FlipperEnd = aInput.x else FlipperEnd = aInput : end if : End Property
- Public Property Get EndPoint : EndPoint = FlipperEnd : End Property
- Public Sub AddPoint(aChooseArray, aIDX, aX, aY) 'Index #, X position, (in) y Position (out)
- Select Case aChooseArray
- case "Polarity" : ShuffleArrays PolarityIn, PolarityOut, 1 : PolarityIn(aIDX) = aX : PolarityOut(aIDX) = aY : ShuffleArrays PolarityIn, PolarityOut, 0
- Case "Velocity" : ShuffleArrays VelocityIn, VelocityOut, 1 :VelocityIn(aIDX) = aX : VelocityOut(aIDX) = aY : ShuffleArrays VelocityIn, VelocityOut, 0
- Case "Ycoef" : ShuffleArrays YcoefIn, YcoefOut, 1 :YcoefIn(aIDX) = aX : YcoefOut(aIDX) = aY : ShuffleArrays YcoefIn, YcoefOut, 0
- End Select
- if gametime > 100 then Report aChooseArray
- End Sub
- Public Sub Report(aChooseArray) 'debug, reports all coords in tbPL.text
- if not DebugOn then exit sub
- dim a1, a2 : Select Case aChooseArray
- case "Polarity" : a1 = PolarityIn : a2 = PolarityOut
- Case "Velocity" : a1 = VelocityIn : a2 = VelocityOut
- Case "Ycoef" : a1 = YcoefIn : a2 = YcoefOut
- case else :tbpl.text = "wrong string" : exit sub
- End Select
- dim str, x : for x = 0 to uBound(a1) : str = str & aChooseArray & " x: " & round(a1(x),4) & ", " & round(a2(x),4) & vbnewline : next
- tbpl.text = str
- End Sub
- 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
- Private Sub RemoveBall(aBall)
- dim x : for x = 0 to uBound(balls)
- if TypeName(balls(x) ) = "IBall" then
- if aBall.ID = Balls(x).ID Then
- balls(x) = Empty
- Balldata(x).Reset
- End If
- End If
- Next
- End Sub
- Public Sub Fire()
- Flipper.RotateToEnd
- processballs
- End Sub
- Public Property Get Pos 'returns % position a ball. For debug stuff.
- dim x : for x = 0 to uBound(balls)
- if not IsEmpty(balls(x) ) then
- pos = pSlope(Balls(x).x, FlipperStart, 0, FlipperEnd, 1)
- End If
- Next
- End Property
- Public Sub ProcessBalls() 'save data of balls in flipper range
- FlipAt = GameTime
- dim x : for x = 0 to uBound(balls)
- if not IsEmpty(balls(x) ) then
- balldata(x).Data = balls(x)
- if DebugOn then StickL.visible = True : StickL.x = balldata(x).x 'debug TODO
- End If
- Next
- PartialFlipCoef = ((Flipper.StartAngle - Flipper.CurrentAngle) / (Flipper.StartAngle - Flipper.EndAngle))
- PartialFlipCoef = abs(PartialFlipCoef-1)
- End Sub
- Private Function FlipperOn() : if gameTime < FlipAt+TimeDelay then FlipperOn = True : End If : End Function 'Timer shutoff for polaritycorrect
- Public Sub PolarityCorrect(aBall)
- if FlipperOn() then
- dim tmp, BallPos, x, IDX, Ycoef : Ycoef = 1
- dim teststr : teststr = "Cutoff"
- tmp = PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1)
- 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
- if DebugOn then TestStr = "real pos < 0.1 ( " & round(tmp,2) & ")" : tbpl.text = Teststr
- 'RemoveBall aBall
- 'Exit Sub
- end if
- 'y safety Exit
- if aBall.VelY > -8 then 'ball going down
- if DebugOn then teststr = "y velocity: " & round(aBall.vely, 3) & "exit sub" : tbpl.text = teststr
- RemoveBall aBall
- exit Sub
- end if
- 'Find balldata. BallPos = % on Flipper
- for x = 0 to uBound(Balls)
- if aBall.id = BallData(x).id AND not isempty(BallData(x).id) then
- idx = x
- BallPos = PSlope(BallData(x).x, FlipperStart, 0, FlipperEnd, 1)
- 'TB.TEXT = balldata(x).id & " " & BALLDATA(X).X & VBNEWLINE & FLIPPERSTART & " " & FLIPPEREND
- if ballpos > 0.65 then Ycoef = LinearEnvelope(BallData(x).Y, YcoefIn, YcoefOut) 'find safety coefficient 'ycoef' data
- end if
- Next
- 'Velocity correction
- if not IsEmpty(VelocityIn(0) ) then
- Dim VelCoef
- if DebugOn then set tmp = new spoofball : tmp.data = aBall : End If
- if IsEmpty(BallData(idx).id) and aBall.VelY < -12 then 'if tip hit with no collected data, do vel correction anyway
- if PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1) > 1.1 then 'adjust plz
- VelCoef = LinearEnvelope(5, VelocityIn, VelocityOut)
- if partialflipcoef < 1 then VelCoef = PSlope(partialflipcoef, 0, 1, 1, VelCoef)
- if Enabled then aBall.Velx = aBall.Velx*VelCoef'VelCoef
- if Enabled then aBall.Vely = aBall.Vely*VelCoef'VelCoef
- if DebugOn then teststr = "tip protection" & vbnewline & "velcoef: " & round(velcoef,3) & vbnewline & round(PSlope(aBall.x, FlipperStart, 0, FlipperEnd, 1),3) & vbnewline
- 'debug.print teststr
- end if
- Else
- : VelCoef = LinearEnvelope(BallPos, VelocityIn, VelocityOut)
- if Enabled then aBall.Velx = aBall.Velx*VelCoef
- if Enabled then aBall.Vely = aBall.Vely*VelCoef
- end if
- End If
- 'Polarity Correction (optional now)
- if not IsEmpty(PolarityIn(0) ) then
- If StartPoint > EndPoint then LR = -1 'Reverse polarity if left flipper
- dim AddX : AddX = LinearEnvelope(BallPos, PolarityIn, PolarityOut) * LR
- if Enabled then aBall.VelX = aBall.VelX + 1 * (AddX*ycoef*PartialFlipcoef)
- End If
- 'debug
- if DebugOn then
- TestStr = teststr & "%pos:" & round(BallPos,2)
- if IsEmpty(PolarityOut(0) ) then
- teststr = teststr & vbnewline & "(Polarity Disabled)" & vbnewline
- else
- teststr = teststr & "+" & round(1 *(AddX*ycoef*PartialFlipcoef),3)
- if BallPos >= PolarityOut(uBound(PolarityOut) ) then teststr = teststr & "(MAX)" & vbnewline else teststr = teststr & vbnewline end if
- if Ycoef < 1 then teststr = teststr & "ycoef: " & ycoef & vbnewline
- if PartialFlipcoef < 1 then teststr = teststr & "PartialFlipcoef: " & round(PartialFlipcoef,4) & vbnewline
- end if
- teststr = teststr & vbnewline & "Vel: " & round(BallSpeed(tmp),2) & " -> " & round(ballspeed(aBall),2) & vbnewline
- teststr = teststr & "%" & round(ballspeed(aBall) / BallSpeed(tmp),2)
- tbpl.text = TestSTR
- end if
- Else
- 'if DebugOn then tbpl.text = "td" & timedelay
- End If
- RemoveBall aBall
- End Sub
- End Class
- '================================
- 'Helper Functions
- Sub ShuffleArray(ByRef aArray, byVal offset) 'shuffle 1d array
- dim x, aCount : aCount = 0
- redim a(uBound(aArray) )
- for x = 0 to uBound(aArray) 'Shuffle objects in a temp array
- if not IsEmpty(aArray(x) ) Then
- if IsObject(aArray(x)) then
- Set a(aCount) = aArray(x)
- Else
- a(aCount) = aArray(x)
- End If
- aCount = aCount + 1
- End If
- Next
- if offset < 0 then offset = 0
- redim aArray(aCount-1+offset) 'Resize original array
- for x = 0 to aCount-1 'set objects back into original array
- if IsObject(a(x)) then
- Set aArray(x) = a(x)
- Else
- aArray(x) = a(x)
- End If
- Next
- End Sub
- Sub ShuffleArrays(aArray1, aArray2, offset)
- ShuffleArray aArray1, offset
- ShuffleArray aArray2, offset
- End Sub
- Function BallSpeed(ball) 'Calculates the ball speed
- BallSpeed = SQR(ball.VelX^2 + ball.VelY^2 + ball.VelZ^2)
- End Function
- Function PSlope(Input, X1, Y1, X2, Y2) 'Set up line via two points, no clamping. Input X, output Y
- dim x, y, b, m : x = input : m = (Y2 - Y1) / (X2 - X1) : b = Y2 - m*X2
- Y = M*x+b
- PSlope = Y
- End Function
- 'Variable Envelope. Infinite amount of points!
- 'Keep keyframes in order, bounds equal, and all that.
- ' L1 L2 L3 L4 L5... etc... L(uBound(xKeyFrame)
- ' .
- ' / \
- ' / \ .
- ' / \ _/ \__
- ' / \ _/ \__
- '/ \ . / \__
- '0.........1..........2........3.........4..........etc........uBound(xKeyFrame)
- 'in animation's case, xInput = MS
- Function LinearEnvelope(xInput, xKeyFrame, yLvl)
- dim y 'Y output
- dim L 'Line
- dim ii : for ii = 1 to uBound(xKeyFrame) 'find active line
- if xInput <= xKeyFrame(ii) then L = ii : exit for : end if
- Next
- if xInput > xKeyFrame(uBound(xKeyFrame) ) then L = uBound(xKeyFrame) 'catch line overrun
- Y = pSlope(xInput, xKeyFrame(L-1), yLvl(L-1), xKeyFrame(L), yLvl(L) )
- 'Clamp if on the boundry lines
- 'if L=1 and Y < yLvl(LBound(yLvl) ) then Y = yLvl(lBound(yLvl) )
- 'if L=uBound(xKeyFrame) and Y > yLvl(uBound(yLvl) ) then Y = yLvl(uBound(yLvl) )
- 'clamp 2.0
- if xInput <= xKeyFrame(lBound(xKeyFrame) ) then Y = yLvl(lBound(xKeyFrame) ) 'Clamp lower
- if xInput >= xKeyFrame(uBound(xKeyFrame) ) then Y = yLvl(uBound(xKeyFrame) ) 'Clamp upper
- LinearEnvelope = Y
- End Function
- Class spoofball
- Public X, Y, Z, VelX, VelY, VelZ, ID, Mass, Radius
- Public Property Let Data(aBall)
- With aBall
- x = .x : y = .y : z = .z : velx = .velx : vely = .vely : velz = .velz
- id = .ID : mass = .mass : radius = .radius
- end with
- End Property
- Public Sub Reset()
- x = Empty : y = Empty : z = Empty : velx = Empty : vely = Empty : velz = Empty
- id = Empty : mass = Empty : radius = Empty
- End Sub
- End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement