File size: 2,080 Bytes
ce81a16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
using System;
using Photon.Deterministic;
using Quantum.Task;

namespace Quantum
{
	public unsafe class ChainSystem : SystemThreadedFilter<ChainSystem.Filter>, ISignalOnTrigger3D, ISignalOnCollision3D, ISignalOnComponentAdded<Chain>
	{
		public struct Filter
		{
			public EntityRef Entity;
			public Transform3D* Transform;
			public PhysicsBody3D* Body;
			public Chain* Chain;
			public Drivable* Drivable;
		}

		public void OnAdded(Frame frame, EntityRef entity, Chain* chain)
		{
			Transform3D transform = frame.Get<Transform3D>(entity);
			chain->LastPosition = transform.Position;
			for (int i = 0; i < 5; i++)
			{
				chain->AddBreadCrumb(transform.Back);
			}
		}

		public void OnTrigger3D(Frame frame, TriggerInfo3D info)
		{
			if (frame.Unsafe.TryGetPointer<Pickup>(info.Other, out var pickup) && frame.Unsafe.TryGetPointer<Chain>(info.Entity, out var chain))
			{
				EntityRef entity = frame.Create(pickup->ItemPrototype);
				if (frame.Unsafe.TryGetPointer<ChainItem>(entity, out var item))
				{
					int index = chain->Count++;
					item->Chain = info.Entity;
					item->Index = index;
				}
				if (frame.Unsafe.TryGetPointerSingleton<PickupSpawner>(out var spawner))
				{
					spawner->Count--;
				}
				frame.Destroy(info.Other);
			}
		}

		public void OnCollision3D(Frame frame, CollisionInfo3D info)
		{
			if (frame.Unsafe.TryGetPointer<Drivable>(info.Entity, out var drivable) && frame.Unsafe.TryGetPointer<PhysicsBody3D>(info.Entity, out var body))
			{
				FP angle = FPVector3.Angle(info.ContactNormal, FPVector3.Up);
				if (angle < 45)
				{
					drivable->Grounded = true;
					drivable->SurfaceNormal = info.ContactNormal;
					body->GravityScale = FP._0;
				}
			}

			if (frame.Unsafe.TryGetPointer<ChainItem>(info.Other, out var item) && frame.Unsafe.TryGetPointer<Chain>(item->Chain, out var chain))
			{
				chain->Count = Math.Min(item->Index, chain->Count);
				info.IgnoreCollision = true;
			}
		}

		public override void Update(FrameThreadSafe frame, ref Filter filter)
		{
			filter.Chain->Update(frame, ref filter);
		}
	}
}