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