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