using System; using Photon.Deterministic; using Quantum.Task; namespace Quantum { public unsafe class ChainSystem : SystemThreadedFilter, ISignalOnTrigger3D, ISignalOnCollision3D, ISignalOnComponentAdded { 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(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(info.Other, out var pickup) && frame.Unsafe.TryGetPointer(info.Entity, out var chain)) { EntityRef entity = frame.Create(pickup->ItemPrototype); if (frame.Unsafe.TryGetPointer(entity, out var item)) { int index = chain->Count++; item->Chain = info.Entity; item->Index = index; } if (frame.Unsafe.TryGetPointerSingleton(out var spawner)) { spawner->Count--; } frame.Destroy(info.Other); } } public void OnCollision3D(Frame frame, CollisionInfo3D info) { if (frame.Unsafe.TryGetPointer(info.Entity, out var drivable) && frame.Unsafe.TryGetPointer(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(info.Other, out var item) && frame.Unsafe.TryGetPointer(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); } } }