-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGPTSpecialProjectile.lua
More file actions
148 lines (118 loc) · 5.52 KB
/
Copy pathGPTSpecialProjectile.lua
File metadata and controls
148 lines (118 loc) · 5.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
behaviour("GPTProjectile")
function GPTProjectile:Start()
self.projectile = self.targets.projectile.GetComponent(Projectile)
if self.projectile == nil then
self:DestroyScript()
return
end
self.startTime = Time.time
self.dataContainer = self.gameObject.GetComponent(DataContainer)
self.inheritVelocity = self.dataContainer.GetBool("InheritVelocity")
self.timeToReachMaxSpeed = self.dataContainer.GetFloat("TimeToReachMaxSpeed")
self.flareDuration = self.dataContainer.GetFloat("FlareDuration")
self.minAcceleration = self.dataContainer.GetFloat("MinAcceleration")
self.maxAcceleration = self.dataContainer.GetFloat("MaxAcceleration")
self.minAngle = self.dataContainer.GetFloat("MinAngle")
self.maxAngle = self.dataContainer.GetFloat("MaxAngle")
self.accelerationCurve = self.dataContainer.GetAnimationCurve("AccelerationCurve")
self.smoothingFactor = self.dataContainer.GetFloat("SmoothingFactor")
self.steeringCostFactor = self.dataContainer.GetFloat("SteeringCostFactor")
self.gravityFactor = self.dataContainer.GetFloat("GravityFactor")
self.climbFactor = self.dataContainer.GetFloat("ClimbFactor")
self.lastTarget = nil
self.isReady = true
self.hasLastTarget = false
self.onceLostTarget = false
self.lastDistanceTravelled = 0
self.cumulativeSpeedLoss = 0
end
function GPTProjectile:Update()
if self.projectile and self.lastDistanceTravelled ~= self.projectile.distanceTravelled then
self.lastDistanceTravelled = self.projectile.distanceTravelled
self:TraceProjectileUpdate()
else
if not self.onceDestroyScript then
self:DestroyScript()
end
end
-- Self-destruct after activeTime seconds
if Time.time - self.startTime > 25 then
self.projectile.Stop(false)
end
end
function GPTProjectile:StartFlareCoolDown()
self.isReady = false
coroutine.yield(WaitForSeconds(self.flareDuration))
if self:CheckAngleRange() then
self.projectile.SetTrackerTarget(self.lastTarget)
self.onceLostTarget = true
self.isReady = true
end
end
function GPTProjectile:TraceProjectileUpdate()
if not self.isReady then
return
end
if self.projectile.isTrackingTarget or self.onceLostTarget then
if not self.hasLastTarget then
self.hasLastTarget = true
self.lastTarget = self.projectile.currentTarget
end
local currentTime = Time.time - self.startTime
local baseSpeed = self:EvaluateAcceleration(currentTime)
local verticalSpeed = self.gravityFactor * Time.deltaTime
local target = self.projectile.currentTarget
local direction = target.transform.position - self.gameObject.transform.position
local currentDirection = self.projectile.velocity.normalized
local angle = Vector3.Angle(currentDirection, direction)
-- Adjust speed based on turning and accumulate
local speedLossFactor = angle * (baseSpeed / 400) * self.steeringCostFactor
self.cumulativeSpeedLoss = self.cumulativeSpeedLoss + speedLossFactor * Time.deltaTime
-- Apply upward force if target is far enough
local climbEffect = Vector3.zero
if currentTime <= 2.5 and currentTime >= 0.3 and direction.magnitude >= 1900 then
climbEffect = Vector3.up * self.climbFactor * Time.deltaTime
end
-- Gravity impact on speed only
local heightDifference = target.transform.position.y - self.gameObject.transform.position.y
if heightDifference > 0 then
self.cumulativeSpeedLoss = self.cumulativeSpeedLoss - verticalSpeed
else
self.cumulativeSpeedLoss = self.cumulativeSpeedLoss + verticalSpeed
end
-- Calculate final speed and apply minimum speed limit
local speed = math.max(baseSpeed - self.cumulativeSpeedLoss, 100)
-- Smooth transition for smoothingMultiplier
local smoothingMultiplier = Mathf.Clamp01((1200 - baseSpeed) / 1000) * 0.5 + 0.5
local smoothDirection = Vector3.Slerp(currentDirection, Vector3.Normalize(direction), Time.deltaTime * self.smoothingFactor * smoothingMultiplier)
-- Check if the angle exceeds the max angle
if angle > self.maxAngle and currentTime >= 1.5 then
self.projectile.Stop(false)
return
end
local velocity = smoothDirection * speed + climbEffect
self.projectile.velocity = velocity
else
if self.hasLastTarget then
self.hasLastTarget = false
self.script.StartCoroutine("StartFlareCoolDown")
end
end
end
function GPTProjectile:EvaluateAcceleration(currentTime)
local normalizedTime = Mathf.Clamp01(currentTime / self.timeToReachMaxSpeed)
local curveTime = normalizedTime * self.accelerationCurve.length
local speed = self.accelerationCurve.Evaluate(curveTime)
speed = Mathf.Lerp(self.minAcceleration, self.maxAcceleration, speed)
return speed
end
function GPTProjectile:CheckAngleRange()
local target = self.projectile.currentTarget
local direction = target.transform.position - self.gameObject.transform.position
local angle = Vector3.Angle(self.gameObject.transform.forward, direction)
return angle >= self.minAngle and angle <= self.maxAngle
end
function GPTProjectile:DestroyScript()
self.onceDestroyScript = true
GameObject.Destroy(self.script)
end