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