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