Untitled

 avatar
unknown
lua
25 days ago
2.9 kB
7
Indexable
if BackupTarget and BackupDistance and BackupSpeed then
				local currentPos = self.Movement.Position
				local visualPos = self.Movement.VisualPosition

				local diff = BackupTarget - currentPos
				local dist = vector.magnitude(diff)

				if dist > 0 and dist < BackupDistance then
					local horDiff = diff * vector.create(1, 0, 1)
					local moveDir = if horDiff == vector.zero then vector.create(1, 0, 0) else -vector.normalize(horDiff)

					local move = moveDir * (1 - dist / BackupDistance)^0.1 * BackupSpeed * dt

					local position = currentPos
					local tri = self.Movement.CurrentTriangle

					for i = 1, 4 do
						local moveDist = vector.magnitude(move)
						if moveDist <= 0.001 then break end

						local hitPos, hitT, hitTri, hitEdge = Global.CustomPathfindingService:Navcast(position, move, nil, tri)

						position = hitPos
						move *= 1 - hitT
						tri = hitTri

						if hitEdge then
							local normal = vector.cross(hitEdge[2] - hitEdge[1], vector.create(0, 1, 0))
							if normal == vector.zero then break end

							normal = vector.normalize(normal)

							position -= normal * 0.01
							move -= normal * vector.dot(normal, move)
						else
							break
						end
					end

					-- this is probably slow, but eh
					local adjust = vector.zero
					local radius = 1

					local yoted = {}

					local n = 0
					local function yeet(tri)
						if yoted[tri] then return end
						yoted[tri] = true

						n += 1

						for i = 1, 3 do
							local a, b = tri[i], tri[i % 3 + 1]

							local ab = b - a
							local ap = position - a

							local c = a + ab * math.clamp(ab:Dot(ap) / ab.Magnitude^2, 0, 1)

							local diff = (c - position) * vector.create(1, 0, 1)
							local dist = vector.magnitude(diff)

							if dist < radius then
								local link = tri[3 + i]
								local tri2 = if link[4] then link[4][3] else nil

								local cross

								if tri2 then
									yeet(tri2)
								elseif dist > 0 then
									local cross = ab.X * ap.Z - ab.Z * ap.X

									if cross <= 0 then
										local dir = vector.normalize(diff)
										adjust += dir * (-radius + dist - vector.dot(dir, adjust))
									end
								end
							end
						end
					end

					yeet(tri)

					if adjust ~= vector.zero then
						local hitPos, hitT, hitTri, hitEdge = Global.CustomPathfindingService:Navcast(position, adjust, nil, tri)

						position = hitPos
						tri = hitTri
					end
					--

					if vector.magnitude(position - currentPos) > 0.01 then
						self.Movement.Position = position
						self.Movement.VisualPosition = Global.ServerNPCs:SnapToGround(position)
						self.Movement.CurrentTriangle = tri

						self.ReplicatedMoveSpeed = vector.magnitude(position - currentPos) / dt
					end
				end
			end
Editor is loading...
Leave a Comment