source: scenarios/GerminationX/oak/src/oak/plant.clj @ 1026

Revision 1026, 5.4 KB checked in by dave, 10 years ago (diff)

changes for camp pixelache

Line 
1;; Copyright (C) 2010 FoAM vzw
2;; This program is free software: you can redistribute it and/or modify
3;; it under the terms of the GNU Affero General Public License as
4;; published by the Free Software Foundation, either version 3 of the
5;; License, or (at your option) any later version.
6;;
7;; This program is distributed in the hope that it will be useful,
8;; but WITHOUT ANY WARRANTY; without even the implied warranty of
9;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10;; GNU Affero General Public License for more details.
11;;
12;; You should have received a copy of the GNU Affero General Public License
13;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
14
15(ns oak.plant
16  (:use
17   oak.vec2
18   oak.forms)
19  (:require
20   clojure.contrib.math))
21
22(def season-length (* 60 10))
23(def min-health 10)
24(def max-health 90)
25(def start-health 20)
26(def min-neighbours 2)
27(def max-neighbours 5)
28
29(defrecord plant
30  [id
31   pos
32   type
33   layer
34   state
35   picked-by
36   owner
37   size
38   timer
39   tick
40   health
41   fruit])
42 
43(defn plant-pos [plant] (:pos plant))
44(defn plant-type [plant] (:type plant))
45(defn plant-layer [plant] (:layer plant))
46(defn plant-state [plant] (:state plant))
47(defn plant-picked-by [plant] (:picked-by plant))
48(defn plant-owner [plant] (:owner plant))
49(defn plant-size [plant] (:size plant))
50
51(defn plant-type->layer [type]
52  (cond
53   (= type "dandelion") "cover"
54   (= type "clover") "cover"
55   (= type "aronia") "shrub"
56   (= type "apple") "tree"
57   (= type "cherry") "tree"))
58
59(defn plant-type->id [type]
60  (cond
61   (= type "cherry") 0
62   (= type "apple") 1
63   (= type "plant-002") 1 ; temp apple tree
64   (= type "aronia") 2
65   (= type "plant-003") 2 ; temp aronia
66   (= type "dandelion") 3
67   (= type "plant-001") 3 ; temp dandelion
68   (= type "clover") 4))
69
70(defn layer->spirit-name [layer]
71  (cond
72   (= layer "canopy") "CanopySpirit"
73   (= layer "vertical") "VerticalSpirit"
74   (= layer "cover") "CoverSpirit"
75   (= layer "tree") "TreeSpirit"
76   (= layer "shrub") "ShrubSpirit"
77   :else "UnknownSpirit"))
78
79(defn make-plant [pos type owner size]
80  (plant. (generate-id) pos type (plant-type->layer type)
81          'grow-a '() owner size 0 (+ (/ season-length 50) (Math/floor (rand 10))) start-health false))
82
83(defn make-random-plant []
84  (let [type (rand-nth (list "aronia" "dandelion" "apple" "cherry" "clover"))]
85    (make-plant
86     (make-vec2 (Math/floor (rand 15)) (Math/floor (rand 15)))
87     type
88     (layer->spirit-name (plant-type->layer type))
89     (Math/round (+ 1 (rand 10))))))
90
91; the plant state machine, advance state, based on health
92(defn adv-state [state health season annual]
93  (cond
94   (= state 'grow-a) (cond (> health min-health) 'grow-b :else (rand-nth (list 'grow-a 'grow-b)))
95   (= state 'grow-b) (cond (> health min-health) 'grow-c :else (rand-nth (list 'grow-b 'grow-c)))
96   (= state 'grow-c) (cond (> health min-health) 'grown :else (rand-nth (list 'grow-c 'grown)))
97   (= state 'grown) (cond
98                     (and (> health max-health)
99                          (or (= season 'spring)
100                              (= season 'summer)))
101                     'fruit-a
102                     (or (= season 'autumn) (= season 'winter)
103                         (< health min-health))
104                     'decay-a
105                     :else 'grown)
106   (= state 'fruit-a) (if (< health min-health) 'decay-a 'fruit-b)
107   (= state 'fruit-b) (if (< health min-health) 'decay-a'fruit-c)
108   (= state 'fruit-c) (if (or (= season 'autumn) (= season 'winter)
109                              (< health min-health))
110                        'decay-a 'grown)
111   (= state 'decay-a) 'decay-b
112   (= state 'decay-b) 'decay-c
113   (= state 'decay-c) (cond (and (or (= season 'spring) (= season 'summer))
114                                 (> health min-health))
115                            (if annual 'grow-a 'grown)
116                            :else
117                            (if (< health min-health) 'ill-c 'decay-c))
118   (= state 'ill-c) (cond (< health min-health) 'decayed
119                (> health max-health) 'grown
120                :else 'ill-c)
121   (= state 'decayed) 'decayed))
122
123(defn load-companion-rules [filename]
124  (read-string (slurp filename)))
125
126(defn get-relationship [from to rules]
127  (nth (nth rules (plant-type->id from))
128       (plant-type->id to)))
129       
130(defn plant-update [plant time delta neighbours rules season]
131;  (println (str season " " (:state plant) " " (:health plant) " " (:timer plant) " " (:tick plant)))
132  (modify
133   :health
134   (fn [health]
135     health (max 0 (min 100
136                        (+ health
137                           (reduce
138                            (fn [r n]
139                              (+ r (get-relationship
140                                    (:type plant) (:type n) rules)))
141                            (if (empty? neighbours) -1 1)
142                            neighbours)))))
143   (modify
144    :fruit
145    (fn [f]
146      (if (and (not f) (= (:state plant) 'fruit-c))
147        true f))
148    (modify
149     :timer
150     (fn [timer]
151       (+ timer delta))
152     (if (> (:timer plant) (:tick plant))
153       (modify
154        :state
155        (fn [state] (adv-state state
156                               (:health plant)
157                               season
158                               ; for the moment assume cover plants
159                               ; are annuals
160                               (= (:layer plant) "cover")))
161        (modify
162         :timer (fn [t] 0) plant))
163       plant)))))
164
Note: See TracBrowser for help on using the repository browser.