From af623931441d03a129ca7652ccf852405abb8100 Mon Sep 17 00:00:00 2001 From: Deon Moolman Date: Mon, 17 Dec 2012 20:55:17 +0200 Subject: [PATCH] Implement entity searching function Drop item function Couple of world effect helper functions An initial repl.clj as a scratchpatch --- README.md | 6 ++ src/cljminecraft/blocks.clj | 120 ++++++++++++++++++++++++++++++++++++ src/cljminecraft/entity.clj | 26 +++++--- src/cljminecraft/items.clj | 7 ++- src/cljminecraft/repl.clj | 47 ++++++++++++++ src/cljminecraft/world.clj | 54 +++++++++++++++- 6 files changed, 248 insertions(+), 12 deletions(-) create mode 100644 src/cljminecraft/blocks.clj create mode 100644 src/cljminecraft/repl.clj diff --git a/README.md b/README.md index fc78d16..cb8a613 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,12 @@ understand what changes are made and adjust your plugins accordingly. Changelog: +17 December 2012: + - Implement entity searching function + - Drop item function + - Couple of world effect helper functions + - An initial repl.clj as a scratchpatch + 14 December 2012: - API Breaking Change: ev/event needs to now reference eventname as "player.player-interact" string instead of symbol. - Implement material handling types properly diff --git a/src/cljminecraft/blocks.clj b/src/cljminecraft/blocks.clj new file mode 100644 index 0000000..0694af2 --- /dev/null +++ b/src/cljminecraft/blocks.clj @@ -0,0 +1,120 @@ +(ns cljminecraft.blocks + (:require [cljminecraft.items :as i])) + +(defn turn-direction + "Set the current facing direction, relative to the current direction (imagine current direction as north)" + [blockface-direction]) + +(defn move-direction + "Move relative to the origin and current facing direction" + [[x y z]] + ) + +(defn up [& [x]] + (move-direction [0 (- 0 (or x 1)) 0])) + +(defn down [& [x]] + (move-direction [0 (or x 1) 0])) + +(defn left [x] + (move-direction [(- 0 (or x 1)) 0 0])) + +(defn right [x] + (move-direction [(or x 1) 0 0])) + +(defn forward [x] + (move-direction [0 0 (or x 1)])) + +(defn back [x] + (move-direction [0 0 (- 0 (or x 1))])) + +(defn turn-left [] + (turn-direction :east)) + +(defn turn-right [] + (turn-direction :west)) + +(defn turn-up [] + (turn-direction :up)) + +(defn turn-down [] + (turn-direction :down)) + +(defn turn-around [] + (turn-direction :south)) + +(defn material + "Set the current 'painted' material :none, or nil for 'pen up', ie - no effect." + []) + +(defn penup []) + +(defn pendown []) + +(defn fork + "Run the given actions seperate to the main context. This could run parallel to your main process, but it generally means that your position is left unchanged" + [& actions]) + +(defn extend-actions + "For the to-action, do the extended action after every movement in the to-action.." + [extended-actions & to-actions] + (for [to-action to-actions] + [to-action + (fork extended-action)])) + +(defn test-fn + "Test an expression, given the current context - executing actions in the true of false block as required" + [fn true-block & [false-block]]) + +(defn if-material + "Decision branch depending on material" + [material-key true-block & [false-block]]) + +(defn run-actions + [origin direction]) + + +(comment + "To define a house:" + (defn wall [length height] + [(fork + (extend-actions + [(forward length)] + (for [_ (range heigth)] (up)))) + (penup) + (forward length) + ]) + + (defn house-walls [width length height] + [(wall width height) + (turn-right) + (wall length height) + (turn-right) + (wall width height) + (turn-right)]) + + (extend-actions + [(forward width) + (right length) + (back width) + (left length)] + (up height)) + + (let [marker (generate-marker)] + (mark marker) + (foward width) + (right length) + (up height) + (fill-to-mark marker :air) + (extend-actions + [(forward width) + (right length) + (back width) + (left length)] + (up height)))) + + + +(let [shuffled (shuffle players)] + (dosomething) + (doelsfklds)) \ No newline at end of file diff --git a/src/cljminecraft/entity.clj b/src/cljminecraft/entity.clj index 5909857..1a6d2ae 100644 --- a/src/cljminecraft/entity.clj +++ b/src/cljminecraft/entity.clj @@ -3,6 +3,21 @@ (def entitytypes (util/map-enums org.bukkit.entity.EntityType)) +(defn get-entities [world & {:keys [type-keys living?]}] + (cond + type-keys + (let [entclasses + (filter #(not (nil? %)) + (map #(if-let [t (get entitytypes %)] (.getEntityClass type)) + (if (coll? type-keys) type-keys [type-keys])))] + (if (not-empty entclasses) + (.getEntitiesByClasses world (into-array Class entclasses)) + [])) + living? + (.getLivingEntities world) + :else + (.getEntities world))) + (defn find-entity [nm] (let [names (map #(name (first %)) entitytypes)] (filter #(.contains % (.toLowerCase nm)) names))) @@ -10,14 +25,5 @@ (defn spawn-entity [location entityname] (let [type (get entitytypes (keyword entityname))] (when (and type (.isSpawnable type)) - (.spawn (.getWorld location) location type)))) - - - - - - - - - + (.spawnEntity (.getWorld location) location type)))) diff --git a/src/cljminecraft/items.clj b/src/cljminecraft/items.clj index 632baae..f508d85 100644 --- a/src/cljminecraft/items.clj +++ b/src/cljminecraft/items.clj @@ -219,4 +219,9 @@ (let [material (get-material material-key)] (if (instance? MaterialData material) (.toItemStack (or qty 1)) - (ItemStack. material (or qty 1))))) \ No newline at end of file + (ItemStack. material (or qty 1))))) + +(defn drop-item [location itemstack & [naturally?]] + (if naturally? + (.dropItemNaturally (.getWorld location) itemstack) + (.dropItem (.getWorld location) itemstack))) \ No newline at end of file diff --git a/src/cljminecraft/repl.clj b/src/cljminecraft/repl.clj new file mode 100644 index 0000000..c6961ab --- /dev/null +++ b/src/cljminecraft/repl.clj @@ -0,0 +1,47 @@ +(ns cljminecraft.repl + (:require [cljminecraft.bukkit :as bk] + [cljminecraft.events :as ev] + [cljminecraft.entity :as ent] + [cljminecraft.player :as plr] + [cljminecraft.util :as util] + [cljminecraft.logging :as log] + [cljminecraft.config :as cfg] + [cljminecraft.commands :as cmd] + [cljminecraft.recipes :as r] + [cljminecraft.items :as i] + [cljminecraft.files :as f] + [cljminecraft.core :as core] + )) + +;; This is a REPL scratchpatch file. It simply includes everything so +;; that you can play around a build stuff + +;; Handy reference to plugin +(def plugin core/clj-plugin) + +(def bombs (atom [])) + +(defn drop-dirt [ev] + (when (= (.. ev getItemDrop getItemStack getType) (i/get-material :dirt)) + (swap! bombs conj (.getItemDrop ev)) + (plr/send-msg ev "You just dropped a bomb! wooh"))) + +(defn interact [ev] + (log/info "Explosion!") + (doseq [bomb @bombs] + (let [l (.getLocation bomb)] + (.createExplosion (.getWorld l) l 10.0))) + (reset! bombs [])) + +(defn ondie [ev] + (.setDeathMessage ev "You fool!")) + +(ev/register-event @plugin "player.player-drop-item" #'drop-dirt) +(ev/register-event @plugin "player.player-interact" #'interact) +(ev/register-event @plugin "entity.player-death" #'ondie) + + + + + + diff --git a/src/cljminecraft/world.clj b/src/cljminecraft/world.clj index 72e3a9b..47ae75d 100644 --- a/src/cljminecraft/world.clj +++ b/src/cljminecraft/world.clj @@ -1,7 +1,14 @@ (ns cljminecraft.world (:require [cljminecraft.bukkit :as bk]) (:require [cljminecraft.player :as plr]) - (:import [org.bukkit.material Directional])) + (:require [cljminecraft.util :as util]) + (:import [org.bukkit.material Directional] + [org.bukkit Location] + [org.bukkit.util Vector])) + +(def effects (util/map-enums org.bukkit.Effect)) +(def sounds (util/map-enums org.bukkit.Sound)) +(def treetypes (util/map-enums org.bukkit.TreeType)) (defn facing-block "If this is a directional block, will return the block it's facing, otherwise it will return the block itself" @@ -11,3 +18,48 @@ (.getFace block (.getFacing data)) block))) +(defn explode + "Creates an explosion at a given location" + [location power & [fire?]] + (.createExplosion (.getWorld location) location power (or fire? false))) + +(defn coerce-vector + "Coerces a [x y z] vec a org.bukkit.util.Vector" + [vec] + ;; TODO: Look into making this an open type - ie, either protocol or defmulti + (cond + (instance? Vector vec) vec + (coll? vec) + (let [[x y z] vec] (Vector. x y z)) + :else + (Vector.))) + +(defn arrow + "Pew! direction is either a org.bukkit.util.Vector or a [x y z] vec" + [location direction & [speed spread]] + (let [vector (coerce-vector direction)] + (.spawnArrow (.getWorld location) vector (or speed 0.6) (or spread 12)))) + +(defn lightning + [location & [effectonly?]] + (if effectonly? + (.strikeLightningEffect (.getWorld location) location) + (.strikeLightning (.getWorld location) location))) + +(defn effect [location effect-key data & [radius]] + (if radius + (.playEffect (.getWorld location) location effect data radius) + (.playEffect (.getWorld location) location effect data))) + +(defn sound [location sound-key volume pitch] + (if-let [sound (get sounds sound-key)] + (.playSound (.getWorld location) location sound volume pitch))) + +(defn generate-tree [location treetype-key & [change-delegate]] + (let [world (.getWorld location) + treetype (get treetypes treetype-key)] + (if change-delegate + (.generateTree location treetype change-delegate) + (.generateTree location treetype)))) + +