33048a7196b28a34b6e3403434c782dfe692ff93
[blender.git] / source / blender / makesrna / intern / rna_boid.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 by Janne Karhu.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/makesrna/intern/rna_boid.c
29  *  \ingroup RNA
30  */
31
32 #include <float.h>
33 #include <limits.h>
34 #include <stdlib.h>
35
36 #include "DNA_scene_types.h"
37 #include "DNA_boid_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_particle_types.h"
40
41 #include "BLI_utildefines.h"
42
43 #include "RNA_define.h"
44 #include "RNA_enum_types.h"
45
46 #include "rna_internal.h"
47
48 #include "WM_api.h"
49 #include "WM_types.h"
50
51 EnumPropertyItem boidrule_type_items[] = {
52         {eBoidRuleType_Goal, "GOAL", 0, "Goal", "Go to assigned object or loudest assigned signal source"},
53         {eBoidRuleType_Avoid, "AVOID", 0, "Avoid", "Get away from assigned object or loudest assigned signal source"},
54         {eBoidRuleType_AvoidCollision, "AVOID_COLLISION", 0, "Avoid Collision",
55                                        "Maneuver to avoid collisions with other boids and deflector objects in "
56                                        "near future"},
57         {eBoidRuleType_Separate, "SEPARATE", 0, "Separate", "Keep from going through other boids"},
58         {eBoidRuleType_Flock, "FLOCK", 0, "Flock", "Move to center of neighbors and match their velocity"},
59         {eBoidRuleType_FollowLeader, "FOLLOW_LEADER", 0, "Follow Leader", "Follow a boid or assigned object"},
60         {eBoidRuleType_AverageSpeed, "AVERAGE_SPEED", 0, "Average Speed", "Maintain speed, flight level or wander"},
61         {eBoidRuleType_Fight, "FIGHT", 0, "Fight", "Go to closest enemy and attack when in range"},
62 #if 0
63         {eBoidRuleType_Protect, "PROTECT", 0, "Protect", "Go to enemy closest to target and attack when in range"},
64         {eBoidRuleType_Hide, "HIDE", 0, "Hide", "Find a deflector move to it's other side from closest enemy"},
65         {eBoidRuleType_FollowPath, "FOLLOW_PATH", 0, "Follow Path",
66                                    "Move along a assigned curve or closest curve in a group"},
67         {eBoidRuleType_FollowWall, "FOLLOW_WALL", 0, "Follow Wall",
68                                    "Move next to a deflector object's in direction of it's tangent"},
69 #endif
70         {0, NULL, 0, NULL, NULL}
71 };
72
73 #ifndef RNA_RUNTIME
74 static EnumPropertyItem boidruleset_type_items[] = {
75         {eBoidRulesetType_Fuzzy, "FUZZY", 0, "Fuzzy",
76                                  "Rules are gone through top to bottom (only the first rule which effect is above "
77                                  "fuzziness threshold is evaluated)"},
78         {eBoidRulesetType_Random, "RANDOM", 0, "Random", "A random rule is selected for each boid"},
79         {eBoidRulesetType_Average, "AVERAGE", 0, "Average", "All rules are averaged"},
80         {0, NULL, 0, NULL, NULL}
81 };
82 #endif
83
84
85 #ifdef RNA_RUNTIME
86
87 #include "BLI_math_base.h"
88
89 #include "BKE_context.h"
90 #include "BKE_depsgraph.h"
91 #include "BKE_particle.h"
92
93 static void rna_Boids_reset(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
94 {
95         if (ptr->type == &RNA_ParticleSystem) {
96                 ParticleSystem *psys = (ParticleSystem *)ptr->data;
97                 
98                 psys->recalc = PSYS_RECALC_RESET;
99
100                 DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
101         }
102         else
103                 DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA | PSYS_RECALC_RESET);
104
105         WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
106 }
107 static void rna_Boids_reset_deps(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
108 {
109         if (ptr->type == &RNA_ParticleSystem) {
110                 ParticleSystem *psys = (ParticleSystem *)ptr->data;
111                 
112                 psys->recalc = PSYS_RECALC_RESET;
113
114                 DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
115         }
116         else
117                 DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA | PSYS_RECALC_RESET);
118
119         DAG_relations_tag_update(bmain);
120
121         WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
122 }
123
124 static StructRNA *rna_BoidRule_refine(struct PointerRNA *ptr)
125 {
126         BoidRule *rule = (BoidRule *)ptr->data;
127
128         switch (rule->type) {
129                 case eBoidRuleType_Goal:
130                         return &RNA_BoidRuleGoal;
131                 case eBoidRuleType_Avoid:
132                         return &RNA_BoidRuleAvoid;
133                 case eBoidRuleType_AvoidCollision:
134                         return &RNA_BoidRuleAvoidCollision;
135                 case eBoidRuleType_FollowLeader:
136                         return &RNA_BoidRuleFollowLeader;
137                 case eBoidRuleType_AverageSpeed:
138                         return &RNA_BoidRuleAverageSpeed;
139                 case eBoidRuleType_Fight:
140                         return &RNA_BoidRuleFight;
141                 default:
142                         return &RNA_BoidRule;
143         }
144 }
145
146 static char *rna_BoidRule_path(PointerRNA *ptr)
147 {
148         BoidRule *rule = (BoidRule *)ptr->data;
149         char name_esc[sizeof(rule->name) * 2];
150
151         BLI_strescape(name_esc, rule->name, sizeof(name_esc));
152
153         return BLI_sprintfN("rules[\"%s\"]", name_esc);  /* XXX not unique */
154 }
155
156 static PointerRNA rna_BoidState_active_boid_rule_get(PointerRNA *ptr)
157 {
158         BoidState *state = (BoidState *)ptr->data;
159         BoidRule *rule = (BoidRule *)state->rules.first;
160
161         for (; rule; rule = rule->next) {
162                 if (rule->flag & BOIDRULE_CURRENT)
163                         return rna_pointer_inherit_refine(ptr, &RNA_BoidRule, rule);
164         }
165         return rna_pointer_inherit_refine(ptr, &RNA_BoidRule, NULL);
166 }
167 static void rna_BoidState_active_boid_rule_index_range(PointerRNA *ptr, int *min, int *max,
168                                                        int *UNUSED(softmin), int *UNUSED(softmax))
169 {
170         BoidState *state = (BoidState *)ptr->data;
171         *min = 0;
172         *max = max_ii(0, BLI_listbase_count(&state->rules) - 1);
173 }
174
175 static int rna_BoidState_active_boid_rule_index_get(PointerRNA *ptr)
176 {
177         BoidState *state = (BoidState *)ptr->data;
178         BoidRule *rule = (BoidRule *)state->rules.first;
179         int i = 0;
180
181         for (; rule; rule = rule->next, i++) {
182                 if (rule->flag & BOIDRULE_CURRENT)
183                         return i;
184         }
185         return 0;
186 }
187
188 static void rna_BoidState_active_boid_rule_index_set(struct PointerRNA *ptr, int value)
189 {
190         BoidState *state = (BoidState *)ptr->data;
191         BoidRule *rule = (BoidRule *)state->rules.first;
192         int i = 0;
193
194         for (; rule; rule = rule->next, i++) {
195                 if (i == value)
196                         rule->flag |= BOIDRULE_CURRENT;
197                 else
198                         rule->flag &= ~BOIDRULE_CURRENT;
199         }
200 }
201
202 static int particle_id_check(PointerRNA *ptr)
203 {
204         ID *id = ptr->id.data;
205
206         return (GS(id->name) == ID_PA);
207 }
208
209 static char *rna_BoidSettings_path(PointerRNA *ptr)
210 {
211         BoidSettings *boids = (BoidSettings *)ptr->data;
212         
213         if (particle_id_check(ptr)) {
214                 ParticleSettings *part = (ParticleSettings *)ptr->id.data;
215                 
216                 if (part->boids == boids)
217                         return BLI_sprintfN("boids");
218         }
219         return NULL;
220 }
221
222 static PointerRNA rna_BoidSettings_active_boid_state_get(PointerRNA *ptr)
223 {
224         BoidSettings *boids = (BoidSettings *)ptr->data;
225         BoidState *state = (BoidState *)boids->states.first;
226
227         for (; state; state = state->next) {
228                 if (state->flag & BOIDSTATE_CURRENT)
229                         return rna_pointer_inherit_refine(ptr, &RNA_BoidState, state);
230         }
231         return rna_pointer_inherit_refine(ptr, &RNA_BoidState, NULL);
232 }
233 static void rna_BoidSettings_active_boid_state_index_range(PointerRNA *ptr, int *min, int *max,
234                                                            int *UNUSED(softmin), int *UNUSED(softmax))
235 {
236         BoidSettings *boids = (BoidSettings *)ptr->data;
237         *min = 0;
238         *max = max_ii(0, BLI_listbase_count(&boids->states) - 1);
239 }
240
241 static int rna_BoidSettings_active_boid_state_index_get(PointerRNA *ptr)
242 {
243         BoidSettings *boids = (BoidSettings *)ptr->data;
244         BoidState *state = (BoidState *)boids->states.first;
245         int i = 0;
246
247         for (; state; state = state->next, i++) {
248                 if (state->flag & BOIDSTATE_CURRENT)
249                         return i;
250         }
251         return 0;
252 }
253
254 static void rna_BoidSettings_active_boid_state_index_set(struct PointerRNA *ptr, int value)
255 {
256         BoidSettings *boids = (BoidSettings *)ptr->data;
257         BoidState *state = (BoidState *)boids->states.first;
258         int i = 0;
259
260         for (; state; state = state->next, i++) {
261                 if (i == value)
262                         state->flag |= BOIDSTATE_CURRENT;
263                 else
264                         state->flag &= ~BOIDSTATE_CURRENT;
265         }
266 }
267
268 #else
269
270 static void rna_def_boidrule_goal(BlenderRNA *brna)
271 {
272         StructRNA *srna;
273         PropertyRNA *prop;
274
275         srna = RNA_def_struct(brna, "BoidRuleGoal", "BoidRule");
276         RNA_def_struct_ui_text(srna, "Goal", "");
277         RNA_def_struct_sdna(srna, "BoidRuleGoalAvoid");
278
279         prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
280         RNA_def_property_pointer_sdna(prop, NULL, "ob");
281         RNA_def_property_flag(prop, PROP_EDITABLE);
282         RNA_def_property_ui_text(prop, "Object", "Goal object");
283         RNA_def_property_update(prop, 0, "rna_Boids_reset_deps");
284
285         prop = RNA_def_property(srna, "use_predict", PROP_BOOLEAN, PROP_NONE);
286         RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_GOAL_AVOID_PREDICT);
287         RNA_def_property_ui_text(prop, "Predict", "Predict target movement");
288         RNA_def_property_update(prop, 0, "rna_Boids_reset");
289 }
290
291 static void rna_def_boidrule_avoid(BlenderRNA *brna)
292 {
293         StructRNA *srna;
294         PropertyRNA *prop;
295
296         srna = RNA_def_struct(brna, "BoidRuleAvoid", "BoidRule");
297         RNA_def_struct_ui_text(srna, "Avoid", "");
298         RNA_def_struct_sdna(srna, "BoidRuleGoalAvoid");
299
300         prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
301         RNA_def_property_pointer_sdna(prop, NULL, "ob");
302         RNA_def_property_flag(prop, PROP_EDITABLE);
303         RNA_def_property_ui_text(prop, "Object", "Object to avoid");
304         RNA_def_property_update(prop, 0, "rna_Boids_reset_deps");
305
306         prop = RNA_def_property(srna, "use_predict", PROP_BOOLEAN, PROP_NONE);
307         RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_GOAL_AVOID_PREDICT);
308         RNA_def_property_ui_text(prop, "Predict", "Predict target movement");
309         RNA_def_property_update(prop, 0, "rna_Boids_reset");
310
311         prop = RNA_def_property(srna, "fear_factor", PROP_FLOAT, PROP_NONE);
312         RNA_def_property_range(prop, 0.0f, 100.0f);
313         RNA_def_property_ui_text(prop, "Fear factor", "Avoid object if danger from it is above this threshold");
314         RNA_def_property_update(prop, 0, "rna_Boids_reset");
315 }
316
317 static void rna_def_boidrule_avoid_collision(BlenderRNA *brna)
318 {
319         StructRNA *srna;
320         PropertyRNA *prop;
321
322         srna = RNA_def_struct(brna, "BoidRuleAvoidCollision", "BoidRule");
323         RNA_def_struct_ui_text(srna, "Avoid Collision", "");
324
325         prop = RNA_def_property(srna, "use_avoid", PROP_BOOLEAN, PROP_NONE);
326         RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_ACOLL_WITH_BOIDS);
327         RNA_def_property_ui_text(prop, "Boids", "Avoid collision with other boids");
328         RNA_def_property_update(prop, 0, "rna_Boids_reset");
329
330         prop = RNA_def_property(srna, "use_avoid_collision", PROP_BOOLEAN, PROP_NONE);
331         RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_ACOLL_WITH_DEFLECTORS);
332         RNA_def_property_ui_text(prop, "Deflectors", "Avoid collision with deflector objects");
333         RNA_def_property_update(prop, 0, "rna_Boids_reset");
334
335         prop = RNA_def_property(srna, "look_ahead", PROP_FLOAT, PROP_NONE);
336         RNA_def_property_range(prop, 0.0f, 100.0f);
337         RNA_def_property_ui_text(prop, "Look ahead", "Time to look ahead in seconds");
338         RNA_def_property_update(prop, 0, "rna_Boids_reset");
339 }
340
341 static void rna_def_boidrule_follow_leader(BlenderRNA *brna)
342 {
343         StructRNA *srna;
344         PropertyRNA *prop;
345
346         srna = RNA_def_struct(brna, "BoidRuleFollowLeader", "BoidRule");
347         RNA_def_struct_ui_text(srna, "Follow Leader", "");
348
349         prop = RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
350         RNA_def_property_pointer_sdna(prop, NULL, "ob");
351         RNA_def_property_flag(prop, PROP_EDITABLE);
352         RNA_def_property_ui_text(prop, "Object", "Follow this object instead of a boid");
353         RNA_def_property_update(prop, 0, "rna_Boids_reset_deps");
354
355         prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
356         RNA_def_property_range(prop, 0.0f, 100.0f);
357         RNA_def_property_ui_text(prop, "Distance", "Distance behind leader to follow");
358         RNA_def_property_update(prop, 0, "rna_Boids_reset");
359
360         prop = RNA_def_property(srna, "queue_count", PROP_INT, PROP_NONE);
361         RNA_def_property_int_sdna(prop, NULL, "queue_size");
362         RNA_def_property_range(prop, 0.0f, 100.0f);
363         RNA_def_property_ui_text(prop, "Queue Size", "How many boids in a line");
364         RNA_def_property_update(prop, 0, "rna_Boids_reset");
365
366         prop = RNA_def_property(srna, "use_line", PROP_BOOLEAN, PROP_NONE);
367         RNA_def_property_boolean_sdna(prop, NULL, "options", BRULE_LEADER_IN_LINE);
368         RNA_def_property_ui_text(prop, "Line", "Follow leader in a line");
369         RNA_def_property_update(prop, 0, "rna_Boids_reset");
370 }
371
372 static void rna_def_boidrule_average_speed(BlenderRNA *brna)
373 {
374         StructRNA *srna;
375         PropertyRNA *prop;
376
377         srna = RNA_def_struct(brna, "BoidRuleAverageSpeed", "BoidRule");
378         RNA_def_struct_ui_text(srna, "Average Speed", "");
379
380         prop = RNA_def_property(srna, "wander", PROP_FLOAT, PROP_NONE);
381         RNA_def_property_range(prop, 0.0f, 1.0f);
382         RNA_def_property_ui_text(prop, "Wander", "How fast velocity's direction is randomized");
383         RNA_def_property_update(prop, 0, "rna_Boids_reset");
384
385         prop = RNA_def_property(srna, "level", PROP_FLOAT, PROP_NONE);
386         RNA_def_property_range(prop, 0.0f, 1.0f);
387         RNA_def_property_ui_text(prop, "Level", "How much velocity's z-component is kept constant");
388         RNA_def_property_update(prop, 0, "rna_Boids_reset");
389
390         prop = RNA_def_property(srna, "speed", PROP_FLOAT, PROP_NONE);
391         RNA_def_property_range(prop, 0.0f, 1.0f);
392         RNA_def_property_ui_text(prop, "Speed", "Percentage of maximum speed");
393         RNA_def_property_update(prop, 0, "rna_Boids_reset");
394 }
395
396 static void rna_def_boidrule_fight(BlenderRNA *brna)
397 {
398         StructRNA *srna;
399         PropertyRNA *prop;
400
401         srna = RNA_def_struct(brna, "BoidRuleFight", "BoidRule");
402         RNA_def_struct_ui_text(srna, "Fight", "");
403
404         prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE);
405         RNA_def_property_range(prop, 0.0f, 100.0f);
406         RNA_def_property_ui_text(prop, "Fight Distance", "Attack boids at max this distance");
407         RNA_def_property_update(prop, 0, "rna_Boids_reset");
408
409         prop = RNA_def_property(srna, "flee_distance", PROP_FLOAT, PROP_NONE);
410         RNA_def_property_range(prop, 0.0f, 100.0f);
411         RNA_def_property_ui_text(prop, "Flee Distance", "Flee to this distance");
412         RNA_def_property_update(prop, 0, "rna_Boids_reset");
413 }
414
415 static void rna_def_boidrule(BlenderRNA *brna)
416 {
417         StructRNA *srna;
418         PropertyRNA *prop;
419         
420         /* data */
421         srna = RNA_def_struct(brna, "BoidRule", NULL);
422         RNA_def_struct_ui_text(srna, "Boid Rule", "");
423         RNA_def_struct_refine_func(srna, "rna_BoidRule_refine");
424         RNA_def_struct_path_func(srna, "rna_BoidRule_path");
425         
426         /* strings */
427         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
428         RNA_def_property_ui_text(prop, "Name", "Boid rule name");
429         RNA_def_struct_name_property(srna, prop);
430         
431         /* enums */
432         prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
433         RNA_def_property_clear_flag(prop, PROP_EDITABLE);
434         RNA_def_property_enum_sdna(prop, NULL, "type");
435         RNA_def_property_enum_items(prop, boidrule_type_items);
436         RNA_def_property_ui_text(prop, "Type", "");
437         
438         /* flags */
439         prop = RNA_def_property(srna, "use_in_air", PROP_BOOLEAN, PROP_NONE);
440         RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_IN_AIR);
441         RNA_def_property_ui_text(prop, "In Air", "Use rule when boid is flying");
442         RNA_def_property_update(prop, 0, "rna_Boids_reset");
443         
444         prop = RNA_def_property(srna, "use_on_land", PROP_BOOLEAN, PROP_NONE);
445         RNA_def_property_boolean_sdna(prop, NULL, "flag", BOIDRULE_ON_LAND);
446         RNA_def_property_ui_text(prop, "On Land", "Use rule when boid is on land");
447         RNA_def_property_update(prop, 0, "rna_Boids_reset");
448         
449         /*prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); */
450         /*RNA_def_property_boolean_sdna(prop, NULL, "mode", eModifierMode_Expanded); */
451         /*RNA_def_property_ui_text(prop, "Expanded", "Set modifier expanded in the user interface"); */
452
453         /* types */
454         rna_def_boidrule_goal(brna);
455         rna_def_boidrule_avoid(brna);
456         rna_def_boidrule_avoid_collision(brna);
457         rna_def_boidrule_follow_leader(brna);
458         rna_def_boidrule_average_speed(brna);
459         rna_def_boidrule_fight(brna);
460 }
461
462 static void rna_def_boidstate(BlenderRNA *brna)
463 {
464         StructRNA *srna;
465         PropertyRNA *prop;
466
467         srna = RNA_def_struct(brna, "BoidState", NULL);
468         RNA_def_struct_ui_text(srna, "Boid State", "Boid state for boid physics");
469
470         prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
471         RNA_def_property_ui_text(prop, "Name", "Boid state name");
472         RNA_def_struct_name_property(srna, prop);
473
474         prop = RNA_def_property(srna, "ruleset_type", PROP_ENUM, PROP_NONE);
475         RNA_def_property_enum_items(prop, boidruleset_type_items);
476         RNA_def_property_ui_text(prop, "Rule Evaluation", "How the rules in the list are evaluated");
477
478         prop = RNA_def_property(srna, "rules", PROP_COLLECTION, PROP_NONE);
479         RNA_def_property_struct_type(prop, "BoidRule");
480         RNA_def_property_ui_text(prop, "Boid Rules", "");
481
482         prop = RNA_def_property(srna, "active_boid_rule", PROP_POINTER, PROP_NONE);
483         RNA_def_property_struct_type(prop, "BoidRule");
484         RNA_def_property_pointer_funcs(prop, "rna_BoidState_active_boid_rule_get", NULL, NULL, NULL);
485         RNA_def_property_ui_text(prop, "Active Boid Rule", "");
486
487         prop = RNA_def_property(srna, "active_boid_rule_index", PROP_INT, PROP_UNSIGNED);
488         RNA_def_property_int_funcs(prop, "rna_BoidState_active_boid_rule_index_get",
489                                    "rna_BoidState_active_boid_rule_index_set",
490                                    "rna_BoidState_active_boid_rule_index_range");
491         RNA_def_property_ui_text(prop, "Active Boid Rule Index", "");
492
493         prop = RNA_def_property(srna, "rule_fuzzy", PROP_FLOAT, PROP_NONE);
494         RNA_def_property_float_sdna(prop, NULL, "rule_fuzziness");
495         RNA_def_property_range(prop, 0.0, 1.0);
496         RNA_def_property_ui_text(prop, "Rule Fuzziness", "");
497         RNA_def_property_update(prop, 0, "rna_Boids_reset");
498
499         prop = RNA_def_property(srna, "volume", PROP_FLOAT, PROP_NONE);
500         RNA_def_property_range(prop, 0.0, 100.0);
501         RNA_def_property_ui_text(prop, "Volume", "");
502         RNA_def_property_update(prop, 0, "rna_Boids_reset");
503
504         prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
505         RNA_def_property_range(prop, 0.0, 10.0);
506         RNA_def_property_ui_text(prop, "Falloff", "");
507         RNA_def_property_update(prop, 0, "rna_Boids_reset");
508 }
509 static void rna_def_boid_settings(BlenderRNA *brna)
510 {
511         StructRNA *srna;
512         PropertyRNA *prop;
513
514         srna = RNA_def_struct(brna, "BoidSettings", NULL);
515         RNA_def_struct_path_func(srna, "rna_BoidSettings_path");
516         RNA_def_struct_ui_text(srna, "Boid Settings", "Settings for boid physics");
517
518         prop = RNA_def_property(srna, "land_smooth", PROP_FLOAT, PROP_NONE);
519         RNA_def_property_float_sdna(prop, NULL, "landing_smoothness");
520         RNA_def_property_range(prop, 0.0, 10.0);
521         RNA_def_property_ui_text(prop, "Landing Smoothness", "How smoothly the boids land");
522         RNA_def_property_update(prop, 0, "rna_Boids_reset");
523
524         prop = RNA_def_property(srna, "bank", PROP_FLOAT, PROP_NONE);
525         RNA_def_property_float_sdna(prop, NULL, "banking");
526         RNA_def_property_range(prop, 0.0, 2.0);
527         RNA_def_property_ui_text(prop, "Banking", "Amount of rotation around velocity vector on turns");
528         RNA_def_property_update(prop, 0, "rna_Boids_reset");
529
530         prop = RNA_def_property(srna, "pitch", PROP_FLOAT, PROP_NONE);
531         RNA_def_property_float_sdna(prop, NULL, "pitch");
532         RNA_def_property_range(prop, 0.0, 2.0);
533         RNA_def_property_ui_text(prop, "Pitch", "Amount of rotation around side vector");
534         RNA_def_property_update(prop, 0, "rna_Boids_reset");
535
536         prop = RNA_def_property(srna, "height", PROP_FLOAT, PROP_NONE);
537         RNA_def_property_range(prop, 0.0, 2.0);
538         RNA_def_property_ui_text(prop, "Height", "Boid height relative to particle size");
539         RNA_def_property_update(prop, 0, "rna_Boids_reset");
540
541         /* states */
542         prop = RNA_def_property(srna, "states", PROP_COLLECTION, PROP_NONE);
543         RNA_def_property_struct_type(prop, "BoidState");
544         RNA_def_property_ui_text(prop, "Boid States", "");
545
546         prop = RNA_def_property(srna, "active_boid_state", PROP_POINTER, PROP_NONE);
547         RNA_def_property_struct_type(prop, "BoidRule");
548         RNA_def_property_pointer_funcs(prop, "rna_BoidSettings_active_boid_state_get", NULL, NULL, NULL);
549         RNA_def_property_ui_text(prop, "Active Boid Rule", "");
550
551         prop = RNA_def_property(srna, "active_boid_state_index", PROP_INT, PROP_UNSIGNED);
552         RNA_def_property_int_funcs(prop, "rna_BoidSettings_active_boid_state_index_get",
553                                    "rna_BoidSettings_active_boid_state_index_set",
554                                    "rna_BoidSettings_active_boid_state_index_range");
555         RNA_def_property_ui_text(prop, "Active Boid State Index", "");
556
557         /* character properties */
558         prop = RNA_def_property(srna, "health", PROP_FLOAT, PROP_NONE);
559         RNA_def_property_range(prop, 0.0, 100.0);
560         RNA_def_property_ui_text(prop, "Health", "Initial boid health when born");
561         RNA_def_property_update(prop, 0, "rna_Boids_reset");
562
563         prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_NONE);
564         RNA_def_property_range(prop, 0.0, 100.0);
565         RNA_def_property_ui_text(prop, "Strength", "Maximum caused damage on attack per second");
566         RNA_def_property_update(prop, 0, "rna_Boids_reset");
567
568         prop = RNA_def_property(srna, "aggression", PROP_FLOAT, PROP_NONE);
569         RNA_def_property_range(prop, 0.0, 100.0);
570         RNA_def_property_ui_text(prop, "Aggression", "Boid will fight this times stronger enemy");
571         RNA_def_property_update(prop, 0, "rna_Boids_reset");
572
573         prop = RNA_def_property(srna, "accuracy", PROP_FLOAT, PROP_NONE);
574         RNA_def_property_range(prop, 0.0, 1.0);
575         RNA_def_property_ui_text(prop, "Accuracy", "Accuracy of attack");
576         RNA_def_property_update(prop, 0, "rna_Boids_reset");
577
578         prop = RNA_def_property(srna, "range", PROP_FLOAT, PROP_NONE);
579         RNA_def_property_range(prop, 0.0, 100.0);
580         RNA_def_property_ui_text(prop, "Range", "Maximum distance from which a boid can attack");
581         RNA_def_property_update(prop, 0, "rna_Boids_reset");
582
583         /* physical properties */
584         prop = RNA_def_property(srna, "air_speed_min", PROP_FLOAT, PROP_NONE);
585         RNA_def_property_float_sdna(prop, NULL, "air_min_speed");
586         RNA_def_property_range(prop, 0.0, 1.0);
587         RNA_def_property_ui_text(prop, "Min Air Speed", "Minimum speed in air (relative to maximum speed)");
588         RNA_def_property_update(prop, 0, "rna_Boids_reset");
589
590         prop = RNA_def_property(srna, "air_speed_max", PROP_FLOAT, PROP_NONE);
591         RNA_def_property_float_sdna(prop, NULL, "air_max_speed");
592         RNA_def_property_range(prop, 0.0, 100.0);
593         RNA_def_property_ui_text(prop, "Max Air Speed", "Maximum speed in air");
594         RNA_def_property_update(prop, 0, "rna_Boids_reset");
595
596         prop = RNA_def_property(srna, "air_acc_max", PROP_FLOAT, PROP_NONE);
597         RNA_def_property_float_sdna(prop, NULL, "air_max_acc");
598         RNA_def_property_range(prop, 0.0, 1.0);
599         RNA_def_property_ui_text(prop, "Max Air Acceleration", "Maximum acceleration in air (relative to maximum speed)");
600         RNA_def_property_update(prop, 0, "rna_Boids_reset");
601
602         prop = RNA_def_property(srna, "air_ave_max", PROP_FLOAT, PROP_NONE);
603         RNA_def_property_float_sdna(prop, NULL, "air_max_ave");
604         RNA_def_property_range(prop, 0.0, 1.0);
605         RNA_def_property_ui_text(prop, "Max Air Angular Velocity",
606                                  "Maximum angular velocity in air (relative to 180 degrees)");
607         RNA_def_property_update(prop, 0, "rna_Boids_reset");
608
609         prop = RNA_def_property(srna, "air_personal_space", PROP_FLOAT, PROP_NONE);
610         RNA_def_property_range(prop, 0.0, 10.0);
611         RNA_def_property_ui_text(prop, "Air Personal Space", "Radius of boids personal space in air (% of particle size)");
612         RNA_def_property_update(prop, 0, "rna_Boids_reset");
613
614         prop = RNA_def_property(srna, "land_jump_speed", PROP_FLOAT, PROP_NONE);
615         RNA_def_property_range(prop, 0.0, 100.0);
616         RNA_def_property_ui_text(prop, "Jump Speed", "Maximum speed for jumping");
617         RNA_def_property_update(prop, 0, "rna_Boids_reset");
618
619         prop = RNA_def_property(srna, "land_speed_max", PROP_FLOAT, PROP_NONE);
620         RNA_def_property_float_sdna(prop, NULL, "land_max_speed");
621         RNA_def_property_range(prop, 0.0, 100.0);
622         RNA_def_property_ui_text(prop, "Max Land Speed", "Maximum speed on land");
623         RNA_def_property_update(prop, 0, "rna_Boids_reset");
624
625         prop = RNA_def_property(srna, "land_acc_max", PROP_FLOAT, PROP_NONE);
626         RNA_def_property_float_sdna(prop, NULL, "land_max_acc");
627         RNA_def_property_range(prop, 0.0, 1.0);
628         RNA_def_property_ui_text(prop, "Max Land Acceleration",
629                                  "Maximum acceleration on land (relative to maximum speed)");
630         RNA_def_property_update(prop, 0, "rna_Boids_reset");
631
632         prop = RNA_def_property(srna, "land_ave_max", PROP_FLOAT, PROP_NONE);
633         RNA_def_property_float_sdna(prop, NULL, "land_max_ave");
634         RNA_def_property_range(prop, 0.0, 1.0);
635         RNA_def_property_ui_text(prop, "Max Land Angular Velocity",
636                                  "Maximum angular velocity on land (relative to 180 degrees)");
637         RNA_def_property_update(prop, 0, "rna_Boids_reset");
638
639         prop = RNA_def_property(srna, "land_personal_space", PROP_FLOAT, PROP_NONE);
640         RNA_def_property_range(prop, 0.0, 10.0);
641         RNA_def_property_ui_text(prop, "Land Personal Space",
642                                  "Radius of boids personal space on land (% of particle size)");
643         RNA_def_property_update(prop, 0, "rna_Boids_reset");
644
645         prop = RNA_def_property(srna, "land_stick_force", PROP_FLOAT, PROP_NONE);
646         RNA_def_property_range(prop, 0.0, 1000.0);
647         RNA_def_property_ui_text(prop, "Land Stick Force", "How strong a force must be to start effecting a boid on land");
648         RNA_def_property_update(prop, 0, "rna_Boids_reset");
649
650         /* options */
651         prop = RNA_def_property(srna, "use_flight", PROP_BOOLEAN, PROP_NONE);
652         RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_FLIGHT);
653         RNA_def_property_ui_text(prop, "Allow Flight", "Allow boids to move in air");
654         RNA_def_property_update(prop, 0, "rna_Boids_reset");
655
656         prop = RNA_def_property(srna, "use_land", PROP_BOOLEAN, PROP_NONE);
657         RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_LAND);
658         RNA_def_property_ui_text(prop, "Allow Land", "Allow boids to move on land");
659         RNA_def_property_update(prop, 0, "rna_Boids_reset");
660
661         prop = RNA_def_property(srna, "use_climb", PROP_BOOLEAN, PROP_NONE);
662         RNA_def_property_boolean_sdna(prop, NULL, "options", BOID_ALLOW_CLIMB);
663         RNA_def_property_ui_text(prop, "Allow Climbing", "Allow boids to climb goal objects");
664         RNA_def_property_update(prop, 0, "rna_Boids_reset");
665 }
666
667 void RNA_def_boid(BlenderRNA *brna)
668 {
669         rna_def_boidrule(brna);
670         rna_def_boidstate(brna);
671         rna_def_boid_settings(brna);
672 }
673
674 #endif