Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarCollisionBlock.hpp
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2023-06-20 14:33:09 +1000
commit6352e8e3196f78388b6c771073f9e03eaa612673 (patch)
treee23772f79a7fbc41bc9108951e9e136857484bf4 /source/game/StarCollisionBlock.hpp
parent6741a057e5639280d85d0f88ba26f000baa58f61 (diff)
everything everywhere
all at once
Diffstat (limited to 'source/game/StarCollisionBlock.hpp')
-rw-r--r--source/game/StarCollisionBlock.hpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/source/game/StarCollisionBlock.hpp b/source/game/StarCollisionBlock.hpp
new file mode 100644
index 0000000..40234c9
--- /dev/null
+++ b/source/game/StarCollisionBlock.hpp
@@ -0,0 +1,115 @@
+#ifndef STAR_COLLISION_BLOCK_HPP
+#define STAR_COLLISION_BLOCK_HPP
+
+#include "StarPoly.hpp"
+#include "StarList.hpp"
+#include "StarBiMap.hpp"
+
+namespace Star {
+
+enum class CollisionKind : uint8_t {
+ // Special collision block that is used for unloaded / un-generated tiles.
+ // Collides the same as "Block", but does not tile with it.
+ Null,
+ None,
+ Platform,
+ Dynamic,
+ Slippery,
+ Block
+};
+
+class CollisionSet {
+public:
+ CollisionSet();
+ CollisionSet(initializer_list<CollisionKind> kinds);
+
+ void insert(CollisionKind kind);
+ void remove(CollisionKind kind);
+ bool contains(CollisionKind kind) const;
+
+private:
+ static uint8_t kindBit(CollisionKind kind);
+
+ uint8_t m_kinds;
+};
+
+// The default CollisionSet consists of Null, Slippery, Dynamic and Block
+CollisionSet const DefaultCollisionSet({CollisionKind::Null, CollisionKind::Slippery, CollisionKind::Dynamic, CollisionKind::Block});
+
+// Defines what can be "blocks" e.g. for tile rendering: Block and Slippery
+CollisionSet const BlockCollisionSet({CollisionKind::Block, CollisionKind::Slippery});
+
+extern EnumMap<CollisionKind> const CollisionKindNames;
+
+bool isColliding(CollisionKind kind, CollisionSet const& collisionSet);
+bool isSolidColliding(CollisionKind kind);
+
+// Returns the highest priority collision kind, where Block > Slippery >
+// Dynamic > Platform > None > Null
+CollisionKind maxCollision(CollisionKind first, CollisionKind second);
+
+struct CollisionBlock {
+ // Make a null collision block for the given space.
+ static CollisionBlock nullBlock(Vec2I const& space);
+
+ CollisionKind kind;
+ Vec2I space;
+ PolyF poly;
+ RectF polyBounds;
+};
+
+inline CollisionSet::CollisionSet()
+ : m_kinds(0) {}
+
+inline CollisionSet::CollisionSet(initializer_list<CollisionKind> kinds)
+ : CollisionSet() {
+ for (auto kind : kinds) {
+ insert(kind);
+ }
+}
+
+inline void CollisionSet::insert(CollisionKind kind) {
+ m_kinds = m_kinds | kindBit(kind);
+}
+
+inline void CollisionSet::remove(CollisionKind kind) {
+ m_kinds = m_kinds & ~kindBit(kind);
+}
+
+inline bool CollisionSet::contains(CollisionKind kind) const {
+ return m_kinds & kindBit(kind);
+}
+
+inline uint8_t CollisionSet::kindBit(CollisionKind kind) {
+ return 1 << ((uint8_t)kind + 1);
+}
+
+inline bool isColliding(CollisionKind kind, CollisionSet const& collisionSet) {
+ return collisionSet.contains(kind);
+}
+
+inline bool isSolidColliding(CollisionKind kind) {
+ return isColliding(kind, DefaultCollisionSet);
+}
+
+inline CollisionKind maxCollision(CollisionKind first, CollisionKind second) {
+ return max(first, second);
+}
+
+inline CollisionBlock CollisionBlock::nullBlock(Vec2I const& space) {
+ CollisionBlock block;
+ block.kind = CollisionKind::Null;
+ block.space = space;
+ block.poly = {
+ Vec2F(space) + Vec2F(0, 0),
+ Vec2F(space) + Vec2F(1, 0),
+ Vec2F(space) + Vec2F(1, 1),
+ Vec2F(space) + Vec2F(0, 1)
+ };
+ block.polyBounds = RectF::withSize(Vec2F(space), Vec2F(1, 1));
+ return block;
+}
+
+}
+
+#endif