#pragma once #include "Runtime/RetroTypes.hpp" namespace metaforce { enum class EMaterialTypes { NoStepLogic = 0, Stone = 1, Metal = 2, Grass = 3, Ice = 4, Pillar = 5, MetalGrating = 6, Phazon = 7, Dirt = 8, Lava = 9, LavaStone = 10, Snow = 11, MudSlow = 12, HalfPipe = 13, Mud = 14, Glass = 15, Shield = 16, Sand = 17, ProjectilePassthrough = 18, Solid = 19, NoPlatformCollision = 20, CameraPassthrough = 21, Wood = 22, Organic = 23, NoEdgeCollision = 24, RedundantEdgeOrFlippedTri = 25, SeeThrough = 26, ScanPassthrough = 27, AIPassthrough = 28, Ceiling = 29, Wall = 30, Floor = 31, Player = 32, Character = 33, Trigger = 34, Projectile = 35, Bomb = 36, GroundCollider = 37, NoStaticCollision = 38, Scannable = 39, Target = 40, Orbit = 41, Occluder = 42, Immovable = 43, Debris = 44, PowerBomb = 45, Unknown46 = 46, CollisionActor = 47, AIBlock = 48, Platform = 49, NonSolidDamageable = 50, RadarObject = 51, PlatformSlave = 52, AIJoint = 53, Unknown54 = 54, SolidCharacter = 55, ExcludeFromLineOfSightTest = 56, ExcludeFromRadar = 57, NoPlayerCollision = 58, SixtyThree = 63 }; class CMaterialList { friend class CMaterialFilter; u64 x0_list = 0; public: constexpr CMaterialList() noexcept = default; constexpr CMaterialList(u64 flags) noexcept : x0_list(flags) {} constexpr CMaterialList(EMaterialTypes t1, EMaterialTypes t2, EMaterialTypes t3, EMaterialTypes t4, EMaterialTypes t5, EMaterialTypes t6) noexcept : CMaterialList(t1, t2, t3, t4, t5) { x0_list |= u64{1} << u64(t6); } constexpr CMaterialList(EMaterialTypes t1, EMaterialTypes t2, EMaterialTypes t3, EMaterialTypes t4, EMaterialTypes t5) noexcept : CMaterialList(t1, t2, t3, t4) { x0_list |= u64{1} << u64(t5); } constexpr CMaterialList(EMaterialTypes t1, EMaterialTypes t2, EMaterialTypes t3, EMaterialTypes t4) noexcept : CMaterialList(t1, t2, t3) { x0_list |= u64{1} << u64(t4); } constexpr CMaterialList(EMaterialTypes t1, EMaterialTypes t2, EMaterialTypes t3) noexcept : CMaterialList(t1, t2) { x0_list |= u64{1} << u64(t3); } constexpr CMaterialList(EMaterialTypes t1, EMaterialTypes t2) noexcept : CMaterialList(t1) { x0_list |= u64{1} << u64(t2); } constexpr CMaterialList(EMaterialTypes t1) noexcept : x0_list(u64{1} << u64(t1)) {} constexpr u64 GetValue() const noexcept { return x0_list; } static constexpr s32 BitPosition(u64 flag) noexcept { for (u32 i = 0; i < 64; ++i) { if ((flag & (u64{1} << i)) != 0) { return static_cast(i); } } return -1; } constexpr void Add(EMaterialTypes type) noexcept { x0_list |= (u64{1} << u64(type)); } constexpr void Add(const CMaterialList& l) noexcept { x0_list |= l.x0_list; } constexpr void Remove(EMaterialTypes type) noexcept { x0_list &= ~(u64{1} << u64(type)); } constexpr void Remove(const CMaterialList& other) noexcept { x0_list &= ~(other.x0_list); } constexpr bool HasMaterial(EMaterialTypes type) const noexcept { return (x0_list & (u64{1} << u64(type))) != 0; } constexpr bool SharesMaterials(const CMaterialList& other) const noexcept { for (u32 i = 0; i < 64; i++) { if ((x0_list & (u64{1} << i)) != 0 && (other.x0_list & (u64{1} << i)) != 0) { return true; } } return false; } constexpr u64 Intersection(const CMaterialList& other) const noexcept { return other.x0_list & x0_list; } constexpr u64 XOR(const CMaterialList& other) const noexcept { return x0_list ^ other.x0_list; } void Union(const CMaterialList& other) noexcept { x0_list |= other.x0_list; } }; } // namespace metaforce