aboutsummaryrefslogtreecommitdiff
path: root/src/macroknight/systems.hy
diff options
context:
space:
mode:
Diffstat (limited to 'src/macroknight/systems.hy')
-rw-r--r--src/macroknight/systems.hy66
1 files changed, 47 insertions, 19 deletions
diff --git a/src/macroknight/systems.hy b/src/macroknight/systems.hy
index fccccd0..8c1bb9c 100644
--- a/src/macroknight/systems.hy
+++ b/src/macroknight/systems.hy
@@ -1,25 +1,53 @@
+(import utils [sub-points Direction])
+
;; Define systems here
(setv GRAVITY 5)
(defclass GoalHit [Exception])
-(defn apply-gravity [entity entities]
- (when (not entity.fixed)
- (.move entity #(0 GRAVITY))))
+(defn entities-by-type [entities types]
+ (gfor ent entities
+ :if (in ent.type types)
+ ent))
+
+(defmacro defsystem [name pred #* body]
+ `(defn ~name [entity entities]
+ (when ~pred
+ ~@body)))
+
+(defsystem apply-gravity
+ (not entity.fixed)
+ (.move entity #(0 GRAVITY)))
+
+(defsystem apply-collisions
+ (not entity.fixed)
+ (for [ent (gfor enti entities
+ :if (!= enti.id entity.id)
+ enti)]
+ (when (.colliderect entity.rect ent.rect)
+ (if (= ent.type "goal")
+ (raise (GoalHit))
+ (let [collision-rect (.clip entity.rect ent.rect)
+ move-x (get entity.total-move 0)
+ move-y (get entity.total-move 1)]
+ (when (!= move-x 0)
+ (.move entity #((* (if (> move-x 0) -1 1) collision-rect.width) 0)))
+ (when (!= move-y 0)
+ (.move entity #(0 (* (if (> move-y 0) -1 1) collision-rect.height))))))
+ (.ground entity))))
-(defn apply-collisions [entity entities]
- (when (not entity.fixed)
- (for [ent (gfor enti entities
- :if (!= enti.id entity.id)
- enti)]
- (when (.colliderect entity.rect ent.rect)
- (if (= ent.type "goal")
- (raise (GoalHit))
- (let [collision-rect (.clip entity.rect ent.rect)
- move-x (get entity.total-move 0)
- move-y (get entity.total-move 1)]
- (when (!= move-x 0)
- (.move entity #((* (if (> move-x 0) -1 1) collision-rect.width) 0)))
- (when (!= move-y 0)
- (.move entity #(0 (* (if (> move-y 0) -1 1) collision-rect.height))))))
- (.ground entity)))))
+(defsystem run-enemies
+ (= entity.type "enemy")
+ ;; If the player is on the tile next to the enemy, attack.
+ (let [player (next (entities-by-type entities ["player"]))
+ dist (sub-points entity.pos player.pos)
+ direction (.x-from-move Direction dist)]
+ ;; If facing the player and within reach, attack)
+ (when (and (= direction entity.facing)
+ (< (get dist 1) 1) ;; Same level
+ (< (abs (get dist 0)) 2)
+ (not entity.attacking))
+ (setv entity.attacking True)
+ (print "attack")
+ )
+ ))