Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
being.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  being.c
4 
5  =============================================================
6 
7  Copyright 1996-2014 Tom Barbalet. All rights reserved.
8 
9  Permission is hereby granted, free of charge, to any person
10  obtaining a copy of this software and associated documentation
11  files (the "Software"), to deal in the Software without
12  restriction, including without limitation the rights to use,
13  copy, modify, merge, publish, distribute, sublicense, and/or
14  sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following
16  conditions:
17 
18  The above copyright notice and this permission notice shall be
19  included in all copies or substantial portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28  OTHER DEALINGS IN THE SOFTWARE.
29 
30  This software and Noble Ape are a continuing work of Tom Barbalet,
31  begun on 13 June 1996. No apes or cats were harmed in the writing
32  of this software.
33 
34  ****************************************************************/
35 
43 #include "entity.h"
44 #include "entity_internal.h"
45 
46 #include <stdio.h>
47 #include <stdlib.h>
48 
49 /* worst case 1500 + 180 per step */
50 
51 #define VISIBILITY_MAXIMUM (2000)
52 
53 #define VISIBILITY_SPAN (VISIBILITY_MAXIMUM / ((15+16) >> 1))
54 
55 #define WALK_ON_WATER(pz,w) (((pz)<w) ? w : (pz))
56 
59 #define GENE_SWIM(gene) GENE_VAL_REG(gene, 9, 11, 13, 7)
60 
63 #define GENE_SPEED(gene) GENE_VAL_REG(gene, 14, 5, 12, 10)
64 
67 #define GENE_STAGGER(gene) GENE_VAL_REG(gene, 12, 14, 3, 11)
68 
71 #define GENE_HILL_CLIMB(gene) GENE_VAL_REG(gene, 4, 6, 5, 2)
72 
81 typedef struct
82 {
89 }
91 
92 #ifdef BRAINCODE_ON
93 
95 {
96  noble_social * social_value = being_social(value);
97  return social_value[0].braincode;
98 }
99 
101 {
102  noble_social * social_value = being_social(value);
103  return social_value[value->attention[ATTENTION_ACTOR]].braincode;
104 }
105 
106 #endif
107 
109 {
110  value->macro_state = state;
111 }
112 
114 {
115  value->macro_state |= state;
116 
117 }
119 {
120  return value->macro_state;
121 }
122 
123 static void being_random3(noble_being * value)
124 {
125  math_random3(value->seed);
126 }
127 
129 {
130  return math_random(value->seed);
131 }
132 
133 static void being_set_random(noble_being * value, n_byte2 * seed)
134 {
135  value->seed[0] = seed[0];
136  value->seed[1] = seed[1];
137 }
138 
139 static void being_set_random1(noble_being * value, n_byte2 seed1)
140 {
141  value->seed[1] = seed1;
142 }
143 
144 static n_byte2 * being_get_random(noble_being * value)
145 {
146  return value->seed;
147 }
148 
149 n_int being_memory(noble_simulation * local, n_byte * buffer, n_uint * location, n_int memory_available)
150 {
151  n_uint lpx = 0;
152  n_uint number_apes = 0;
153 
154  if (memory_available < 1)
155  {
156  return SHOW_ERROR("Memory not available");
157  }
158 
159  number_apes = (memory_available / sizeof(noble_being)) - 1;
160 
161  if (number_apes < 1)
162  {
163  return SHOW_ERROR("Not enough memory for an ape");
164  }
165 
166 #ifdef LARGE_SIM
167  local->max = LARGE_SIM;
168 #else
169  local->max = (memory_available / sizeof(noble_being)) - 1;
170 #endif
171  local->beings = (noble_being *) & buffer[ * location ];
172  * location += sizeof(noble_being) * local->max ;
173 
174  while (lpx < local->max)
175  {
176  noble_being * local_being = &(local->beings[ lpx ]);
177 #ifdef BRAIN_ON
178  io_erase(local_being->brain, DOUBLE_BRAIN);
179 #endif
180  io_erase((n_byte *)local_being->social, (SOCIAL_SIZE * sizeof(noble_social)));
181  io_erase((n_byte *)local_being->episodic, (EPISODIC_SIZE * sizeof(noble_episodic)));
182  lpx ++;
183  }
184  return 0;
185 }
186 
187 static void being_set_brainatates(noble_being * value, n_int asleep, n_byte2 val1, n_byte2 val2, n_byte2 val3)
188 {
189  n_int three_offset = (asleep ? 0 : 3);
190 
191  value->brain_state[three_offset + 0] = val1;
192  value->brain_state[three_offset + 1] = val2;
193  value->brain_state[three_offset + 2] = val3;
194 }
195 
196 n_int being_brainstates(noble_being * value, n_int asleep, n_byte2 * states)
197 {
198  n_int three_offset = (asleep ? 0 : 3);
199 
200  states[0] = value->brain_state[three_offset + 0];
201  states[1] = value->brain_state[three_offset + 1];
202  states[2] = value->brain_state[three_offset + 2];
203 
204  return ((states[0] != 0) || (states[1] != 1024) || (states[2] != 0));
205 }
206 
208 {
209  io_erase((n_byte*)value, sizeof(noble_being));
210 }
211 
213 {
214  return value->honor;
215 }
216 
218 {
219  if (inc->honor < 255) inc->honor++;
220  if (dec->honor > 0) dec->honor--;
221 }
222 
223 void being_honor_swap(noble_being * victor, noble_being * vanquished)
224 {
225  if (victor->honor < vanquished->honor)
226  {
228  n_byte temp_hon = victor->honor;
229  victor->honor = vanquished->honor;
230  vanquished->honor = temp_hon;
231  }
232 }
233 
235 {
236  if (first->honor > second->honor)
237  {
238  return 1;
239  }
240 
241  if (first->honor < second->honor)
242  {
243  return -1;
244  }
245 
246  return 0;
247 }
248 
249 static n_byte being_honor_immune(noble_being * value)
250 {
251  n_int local_honor = being_honor(value);
252  if (local_honor < 250) /* ALPHA_RANK */
253  {
254  return (n_byte)(1 + (local_honor>>6));
255  }
256  return 2; /* IMMUNE_STRENGTH_ALPHA */
257 }
258 
260 {
261  return value->posture;
262 }
263 
265 {
266  value->posture = post;
267 }
268 
270 {
271  return (value->posture < post);
272 }
273 
274 #ifdef BRAIN_ON
276 {
277  return value->brain;
278 }
279 #endif
280 
282 {
283  return value->episodic;
284 
285 }
286 
288 {
289  return value->social;
290 }
291 
293 {
294  return (n_int)value->location[0];
295 }
296 
298 {
299  return (n_int)value->location[1];
300 }
301 
303 {
304  return value->location;
305 }
306 
308 {
309  value->location[0] = from[0];
310  value->location[1] = from[1];
311 }
312 
314 {
315  return value->velocity;
316 }
317 
319 {
320  value->velocity = sp;
321 }
322 
323 void being_delta(noble_being * primary, noble_being * secondary, n_vect2 * delta)
324 {
325  delta->x = primary->location[0] - secondary->location[0];
326  delta->y = primary->location[1] - secondary->location[1];
327 }
328 
330 {
331  return value->date_of_birth;
332 }
333 
334 void being_facing_towards(noble_being * value, n_vect2 * vector)
335 {
336  value->direction_facing = math_turn_towards(vector, value->direction_facing, 0);
337 }
338 
339 void being_wander(noble_being * value, n_int wander)
340 {
341  value->direction_facing = (n_byte)((value->direction_facing + 256 + wander) & 255);
342 }
343 
344 static void being_facing_init(noble_being * value)
345 {
346  value->direction_facing = (n_byte)(being_random(value) & 255);
347 }
348 
349 void being_facing_vector(noble_being * value, n_vect2 * vect, n_int divisor)
350 {
351  vect2_direction(vect, value->direction_facing, divisor * 32);
352 }
353 
355 {
356  return value->direction_facing;
357 }
358 
360 {
361  return value->genetics;
362 }
363 
365 {
366  return value->date_of_conception;
367 }
368 
370 {
371  return value->fetal_genetics;
372 }
373 
374 /* TODO: Remove this kind of access eventually */
376 {
377  return value->stored_energy;
378 }
379 
381 {
382  return being_energy(value) < less_than;
383 }
384 
385 void being_dead(noble_being * value)
386 {
387  value->stored_energy = BEING_DEAD;
388 }
389 
391 {
392  value->stored_energy = BEING_FULL;
393 }
394 
396 {
397  n_int total = value->stored_energy + delta;
398 
399  if (total < BEING_DEAD)
400  {
401  total = BEING_DEAD;
402  }
403 
404  value->stored_energy = (n_byte2) total;
405 }
406 
408 {
409  return value->drives[drive];
410 }
411 
413 {
414  if (value->drives[drive] < DRIVES_MAX)
415  {
416  value->drives[drive]++;
417  }
418 }
419 
421 {
422  if (value->drives[drive] > 0)
423  {
424  value->drives[drive]--;
425  }
426 }
427 
429 {
430  value->drives[drive] = 0;
431 }
432 
434 {
435  return value->height;
436 }
437 
439 {
440  return value->mass;
441 }
442 
443 static void being_turn_away_from_water(noble_being * value, n_land * land)
444 {
445  n_int it_water_turn = 0;
446  n_vect2 location_vector;
447 
448  vect2_byte2(&location_vector, being_location(value));
449 
450  while (it_water_turn < 7)
451  {
452  /* find higher land first */
453  n_int iturn = 8 - it_water_turn;
454  n_int loc_f = being_facing(value);
455  n_int iturn_plus = loc_f + iturn;
456  n_int iturn_minus = loc_f + (256-iturn);
457 
458  n_byte turn_plus = (n_byte)((iturn_plus) & 255);
459  n_byte turn_minus = (n_byte)((iturn_minus) & 255);
460  n_vect2 temp_vector;
461 
462  n_int z_plus;
463  n_int z_minus;
464 
465  vect2_direction(&temp_vector, turn_plus, 128);
466  vect2_add(&temp_vector, &temp_vector, &location_vector);
467 
469 
470  vect2_direction(&temp_vector, turn_minus, 128);
471  vect2_add(&temp_vector, &temp_vector, &location_vector);
472 
474 
475  if (z_minus > z_plus)
476  {
477  being_wander(value, -iturn);
478  }
479  else if (z_minus < z_plus)
480  {
481  being_wander(value, iturn);
482  }
483  it_water_turn++;
484  }
485 }
486 
488 {
489  return ((value)->inventory[location]>>3)<<3;
490 }
491 
492 void being_drop(noble_being * value, enum BODY_INVENTORY_TYPES location)
493 {
494  (value)->inventory[location] &= 7;
495  GET_A(value,ATTENTION_BODY) = location;
496 }
497 
498 void being_take(noble_being * value, enum BODY_INVENTORY_TYPES location, enum inventory_type object)
499 {
500  (value)->inventory[location] |= object;
501  GET_A(value,ATTENTION_BODY) = location;
502 }
503 
504 void being_loop_no_thread(noble_simulation * sim, noble_being * being_not, being_loop_fn bf_func, void * data)
505 {
506  n_uint loop = 0;
507  while (loop < sim->num)
508  {
509  noble_being * output = &(sim->beings[loop]);
510  if (output != being_not)
511  {
512  bf_func(sim, output, data);
513  }
514  loop++;
515  }
516 }
517 /*
518 static void being_loop_generic(noble_simulation * sim, noble_being * being_not, being_loop_fn bf_func, void * data)
519 {
520 #ifdef EXECUTE_THREADED
521  n_uint loop = 0;
522  while (loop < sim->num)
523  {
524  noble_being * output = &(sim->beings[loop]);
525  if (output != being_not)
526  {
527  execute_add(((execute_function*)bf_func), (void*)sim, (void*)output, data);
528  }
529  loop++;
530  }
531 #else
532  being_loop_no_thread(sim, being_not, bf_func, data);
533 #endif
534 }
535  */
536 
537 void being_loop(noble_simulation * sim, being_loop_fn bf_func, n_int beings_per_thread)
538 {
539 #if 1
540  n_uint loop = 0;
541  n_int count = beings_per_thread;
542  while (loop < sim->num)
543  {
544  noble_being * output = &(sim->beings[loop]);
545 
546  if ((beings_per_thread + loop) >= sim->num)
547  {
548  count = sim->num - loop;
549  }
550 
551  execute_group(((execute_function*)bf_func), (void*)sim, (void*)output, count, sizeof(noble_being));
552 
553  if (count != beings_per_thread)
554  {
555  break;
556  }
557  else
558  {
559  loop += count;
560  }
561  }
562 #else
563  being_loop_generic(sim, 0L, bf_func, 0L);
564 #endif
565 }
566 
574 static n_byte being_ground(n_int px, n_int py, n_int dx, n_int dy, void * params)
575 {
576  n_int abs_sum = ABS(dx) + ABS(dy);
577  being_draw * being_pixel = (being_draw *) params;
578  n_int d_vis = being_pixel->visibility_delta;
579  n_int local_z = ((px*(being_pixel->offset_x)) + (py*(being_pixel->offset_y))) >> 9;
580 
581  if (abs_sum)
582  {
584  n_int span10 = ((abs_sum - 1) ? 1448 : 1024);
585 
586  switch (seven_values)
587  {
590  being_pixel->visibility_total += (span10 * (d_vis + 16)) >> 11;
591  break;
594  being_pixel->visibility_total += (span10 * ((2 * d_vis) + 25)) >> 11;
595  break;
597  being_pixel->visibility_total += (span10 * ((5 * d_vis) + 65)) >> 11;
599  being_pixel->visibility_total += (span10 * ((8 * d_vis) + 93)) >> 11;
601  being_pixel->visibility_total += (span10 * ((12 * d_vis) + 145)) >> 11;
602  break;
603 
604  case WEATHER_SEVEN_ERROR:
605  default:
606  return 1;
607  }
608  if (being_pixel->visibility_total > VISIBILITY_MAXIMUM)
609  return 1;
610 
611  local_z += being_pixel->start_z;
612 
613  if (local_z < WALK_ON_WATER(land_location(being_pixel->land, px, py),being_pixel->land->tide_level))
614  {
615  return 1;
616  }
617  }
618  return 0;
619 }
620 
621 static n_byte being_los_projection(n_land * land, noble_being * local, n_int lx, n_int ly)
622 {
623  n_vect2 start, delta, vector_facing;
624 
625  /* TODO: Check for being awake - need a land and being based awake check */
626 
627  vect2_byte2(&start, being_location(local));
628 
629  delta.x = lx;
630  delta.y = ly;
631 
632  vect2_subtract(&delta, &delta, &start);
633 
634  {
635  n_int distance_squared = vect2_dot(&delta, &delta, 1, 1);
636  if (distance_squared > (VISIBILITY_SPAN * VISIBILITY_SPAN))
637  return 0;
638  }
641  if ((delta.x == 0) && (delta.y == 0))
642  {
643  return 1;
644  }
645  being_facing_vector(local, &vector_facing, 16);
646 
647  /* if it is behind, it can't be in the line of sight */
648  if (vect2_dot(&vector_facing, &delta, 1, 64) < 0)
649  {
650  return 0;
651  }
652 
654  start.x = APESPACE_TO_MAPSPACE(start.x);
655  start.y = APESPACE_TO_MAPSPACE(start.y);
656  delta.x = APESPACE_TO_MAPSPACE(delta.x);
657  delta.y = APESPACE_TO_MAPSPACE(delta.y);
658 
659  /* check trivial case first - self aware (after co-ord translation) */
660  if ((delta.x == 0) && (delta.y == 0))
661  {
662  return 1;
663  }
664 
665  {
666  n_int start_z = (n_int)WALK_ON_WATER(land_location(land, start.x, start.y),land->tide_level) + 3; /* the nominal height of the Noble Ape */
667  n_int delta_z = ((n_int)WALK_ON_WATER(land_location(land, (start.x + delta.x), (start.y + delta.y)),land->tide_level)) - start_z + 3; /* the nominal height of the Noble Ape */
668  n_int common_divisor = vect2_dot(&delta, &delta, 1, 1);
669  being_draw translate;
670 
671  if(common_divisor == 0)
672  {
673  common_divisor = 1;
674  }
675 
676  {
677  n_vect2 offset = {0};
678 
679  vect2_d(&offset, &delta, 512 * delta_z, common_divisor);
680 
681  start_z -= vect2_dot(&start, &offset, 1, 512);
682 
683  translate.start_z = start_z;
684  translate.offset_x = offset.x;
685  translate.offset_y = offset.y;
686 
687  translate.visibility_total = 100 * GENE_VISION_INITIAL(being_genetics(local));
688 
690  }
691 
692  translate.land = land;
693  {
694  n_join being_point;
695  being_point.information = (void *) &translate;
696  being_point.pixel_draw = &being_ground;
697 
698  if(math_join_vect2(start.x, start.y, &delta, &being_point))
699  {
700  return 0;
701  }
702  }
703  }
704  return 1;
705 }
706 
707 typedef struct{
711 
712 static void being_from_name_loop(noble_simulation * sim, noble_being * local, void * data)
713 {
715  n_string_block str;
716 
717  if (bfns->being_from_name)
718  {
719  return;
720  }
721 
722  being_name_simple(local, str);
723 
725 
726  if (io_find(str,0,io_length(str,STRING_BLOCK_SIZE),bfns->name,io_length(bfns->name,STRING_BLOCK_SIZE))>-1)
727  {
728  bfns->being_from_name = local;
729  }
730 }
731 
739 {
741  bfns.being_from_name = 0L;
742  io_lower(name, io_length(name,STRING_BLOCK_SIZE));
743  bfns.name = name;
744  being_loop_no_thread(sim, 0L, being_from_name_loop, &bfns);
745  return bfns.being_from_name;
746 }
747 
749 {
750  noble_being * response = being_from_name(sim, name);
751  if (response == 0L)
752  {
753  (void)SHOW_ERROR("Ape not found");
754  return;
755  }
756  sim->select = response;
757 }
758 
760 {
761  static n_string_block name;
762  n_int position = 0;
763  if (sim->select == 0L)
764  {
765  io_string_write(name,"*** ALL APES DEAD ***", &position);
766  }
767  else
768  {
769  being_name_simple(sim->select, name);
770  }
771  return (n_string)name;
772 }
773 
774 
784 {
785  /* There is probably a logical simplification of this
786  as I can't think of it here is the brute force method.
787 
788  The Noble Ape Simulation universe wraps around in all
789  directions you need to calculate the line of site off the map too. */
790  n_int local_facing = ((being_facing(local))>>5);
791 
792  /*
793  6
794  5 7
795  4 0
796  3 1
797  2
798  */
799 
800  if (being_los_projection(land, local,lx,ly) == 1)
801  return 1;
802 
803  if ((local_facing == 6) || (local_facing == 7) || (local_facing == 0) || (local_facing == 1) || (local_facing == 2))
804  {
805  if (being_los_projection(land, local,lx+MAP_APE_RESOLUTION_SIZE,ly) == 1)
806  return 1;
807  }
808 
809  if ((local_facing == 7) || (local_facing == 0) || (local_facing == 1) || (local_facing == 2) || (local_facing == 3))
810  {
811  if (being_los_projection(land, local,lx+MAP_APE_RESOLUTION_SIZE,ly+MAP_APE_RESOLUTION_SIZE) == 1)
812  return 1;
813  }
814  if ((local_facing == 0) || (local_facing == 1) || (local_facing == 2) || (local_facing == 3) || (local_facing == 4))
815  {
816  if (being_los_projection(land, local,lx,ly+MAP_APE_RESOLUTION_SIZE) == 1)
817  return 1;
818  }
819  if ((local_facing == 1) || (local_facing == 2) || (local_facing == 3) || (local_facing == 4) || (local_facing == 5))
820  {
821  if (being_los_projection(land, local,lx-MAP_APE_RESOLUTION_SIZE,ly+MAP_APE_RESOLUTION_SIZE) == 1)
822  return 1;
823  }
824  if ((local_facing == 2) || (local_facing == 3) || (local_facing == 4) || (local_facing == 5) || (local_facing == 6))
825  {
826  if (being_los_projection(land, local,lx-MAP_APE_RESOLUTION_SIZE,ly) == 1)
827  return 1;
828  }
829  if ((local_facing == 3) || (local_facing == 4) || (local_facing == 5) || (local_facing == 6) || (local_facing == 7))
830  {
831  if (being_los_projection(land, local,lx-MAP_APE_RESOLUTION_SIZE,ly-MAP_APE_RESOLUTION_SIZE) == 1)
832  return 1;
833  }
834  if ((local_facing == 4) || (local_facing == 5) || (local_facing == 6) || (local_facing == 7) || (local_facing == 0))
835  {
836  if (being_los_projection(land, local,lx,ly-MAP_APE_RESOLUTION_SIZE) == 1)
837  return 1;
838  }
839  if ((local_facing == 5) || (local_facing == 6) || (local_facing == 7) || (local_facing == 0) || (local_facing == 1))
840  {
841  if (being_los_projection(land, local,lx+MAP_APE_RESOLUTION_SIZE,ly-MAP_APE_RESOLUTION_SIZE) == 1)
842  return 1;
843  }
844  return 0;
845 }
846 
847 static void being_immune_init(noble_being * local)
848 {
849 #ifdef IMMUNE_ON
850  n_byte i;
851  n_byte2 * local_random = being_get_random(local);
852  noble_immune_system * immune = &(local->immune_system);
853 
854  for (i = 0; i < IMMUNE_ANTIGENS; i += 2)
855  {
856  immune->antigens[i]=0;
857  immune->antigens[i+1]=0;
858  math_random3(local_random);
859  immune->shape_antigen[i] = (n_byte)(local_random[0]&255);
860  immune->shape_antigen[i+1] = (n_byte)(local_random[1]&255);
861  }
862  for (i = 0; i < IMMUNE_POPULATION; i += 2)
863  {
864  immune->antibodies[i]=0;
865  immune->antibodies[i+1]=0;
866  math_random3(local_random);
867  immune->shape_antibody[i] = (n_byte)(local_random[0]&255);
868  immune->shape_antibody[i+1] = (n_byte)(local_random[1]&255);
869  }
870 #endif
871 }
872 
873 static void being_immune_seed(noble_being * mother, noble_being * child)
874 {
875 #ifdef IMMUNE_ON
876  n_byte i;
877  noble_immune_system * immune_mother = &(mother->immune_system);
878  noble_immune_system * immune_child = &(child->immune_system);
879 
881  for (i=0; i<IMMUNE_POPULATION; i++)
882  {
883  immune_child->shape_antibody[i]=immune_mother->shape_antibody[i];
884  immune_child->antibodies[i]=immune_mother->antibodies[i];
885  }
886 #endif
887 }
888 
889 static void being_acquire_pathogen(noble_being * local, n_byte transmission_type)
890 {
891 #ifdef IMMUNE_ON
892  n_byte i;
893  noble_immune_system * immune = &(local->immune_system);
894  n_byte2 * local_random = being_get_random(local);
895 
896  math_random3(local_random);
897  if (local_random[0] < PATHOGEN_ENVIRONMENT_PROB)
898  {
899  i = local_random[1]%IMMUNE_ANTIGENS;
900  if (immune->antigens[i]==0)
901  {
902  math_random3(local_random);
903  immune->antigens[i]=(n_byte)(local_random[0]&7);
904  immune->shape_antigen[i] = (n_byte)RANDOM_PATHOGEN(local_random[1], transmission_type);
905  }
906  }
907 #endif
908 }
909 
910 void being_ingest_pathogen(noble_being * local, n_byte food_type)
911 {
912  n_byte transmission_type=food_type+PATHOGEN_TRANSMISSION_FOOD_VEGETABLE;
913  being_acquire_pathogen(local,transmission_type);
914 }
915 
916 void being_immune_transmit(noble_being * meeter_being, noble_being * met_being, n_byte transmission_type)
917 {
918 #ifdef IMMUNE_ON
919  n_byte i,j;
920  n_byte2 * local_random = being_get_random(meeter_being);
921  noble_immune_system * immune0 = &(meeter_being->immune_system);
922  noble_immune_system * immune1 = &(met_being->immune_system);
923 
925  being_acquire_pathogen(meeter_being, transmission_type);
926 
928  math_random3(local_random);
929  if (local_random[0] < PATHOGEN_TRANSMISSION_PROB)
930  {
931  math_random3(local_random);
932  i = local_random[0]%IMMUNE_ANTIGENS;
933  if ((immune0->antigens[i]>0) &&
934  (PATHOGEN_TRANSMISSION(immune0->shape_antigen[i])==transmission_type))
935  {
937  for (j = 0; j < IMMUNE_ANTIGENS; j++)
938  {
939  if (immune0->shape_antigen[i]==immune1->shape_antigen[j])
940  {
941  if (immune1->antigens[j]<255) immune1->antigens[j]++;
942  break;
943  }
944  }
945  if (j == IMMUNE_ANTIGENS)
946  {
947  j = local_random[1]%IMMUNE_ANTIGENS;
948  if (immune1->antigens[j]<=MIN_ANTIGENS)
949  {
951  immune1->shape_antigen[j]=immune0->shape_antigen[i];
952  }
953  }
954  }
955  }
956 #endif
957 }
958 
959 static void being_immune_response(noble_being * local)
960 {
961 #ifdef IMMUNE_ON
962  n_int min_antibodies;
963  n_int max_bits_matched;
964  n_byte2 total_antigens,max_severity;
965  n_byte i,j,k,match,best_match,bits_matched,bit;
966  n_byte2 * local_random = being_get_random(local);
967  noble_immune_system * immune = &(local->immune_system);
968 
970  math_random3(local_random);
971  if (local_random[0]<ANTIBODY_DEPLETION_PROB)
972  {
973  i = local_random[1]%IMMUNE_POPULATION;
974  if (immune->antibodies[i]>0)
975  {
976  immune->antibodies[i]--;
977  }
978  }
979 
981  math_random3(local_random);
982  i = local_random[0]%IMMUNE_ANTIGENS;
983  if (immune->antigens[i] != 0)
984  {
986  if (local_random[1]<PATHOGEN_MUTATION_PROB)
987  {
988  math_random3(local_random);
989  if ((immune->shape_antigen[i] & (1<<(local_random[0]&7))) != 0)
990  {
991  immune->shape_antigen[i] ^= (local_random[0]&7);
992  }
993  else
994  {
995  immune->shape_antigen[i] |= (local_random[0]&7);
996  }
997  }
998 
1000  max_bits_matched=0;
1001  best_match=0;
1002  for (j = 0; j < IMMUNE_POPULATION; j++)
1003  {
1004  match = (immune->shape_antibody[j] & immune->shape_antigen[i]) |
1005  ((~immune->shape_antibody[j]) & (~immune->shape_antigen[i]));
1006  if (match!=0)
1007  {
1009  bits_matched=0;
1010  for (bit=0; bit<8; bit++)
1011  {
1012  if ((match & (1<<bit)) != 0)
1013  {
1014  bits_matched++;
1015  }
1016  }
1018  if (bits_matched>max_bits_matched)
1019  {
1020  max_bits_matched=bits_matched;
1021  best_match = j;
1022  }
1023  }
1024  }
1025 
1027  min_antibodies=immune->antibodies[0];
1028  j=0;
1029  for (k=1; k<IMMUNE_POPULATION; k++)
1030  {
1031  if (immune->antibodies[k]<min_antibodies)
1032  {
1033  min_antibodies = immune->antibodies[k];
1034  j = k;
1035  }
1036  }
1037 
1039  if (max_bits_matched>IMMUNE_FIT)
1040  {
1043  if (immune->antibodies[best_match]<255-max_bits_matched)
1044  {
1045  immune->antibodies[best_match]+=(n_byte)max_bits_matched;
1048  if (immune->antibodies[best_match]<MIN_ANTIBODIES)
1049  {
1050  immune->antibodies[best_match]=MIN_ANTIBODIES;
1051  }
1052  }
1054  if (immune->antigens[i]>being_honor_immune(local))
1055  {
1056  immune->antigens[i]-=being_honor_immune(local);
1057  }
1058  else
1059  {
1060  immune->antigens[i]=0;
1061  }
1063  if (j!=best_match)
1064  {
1065  immune->antibodies[j]=1;
1066  match = immune->shape_antibody[best_match];
1067  math_random3(local_random);
1068  if ((match & (1<<(local_random[0]&7))) != 0)
1069  {
1070  match ^= (local_random[0]&7);
1071  }
1072  else
1073  {
1074  match |= (local_random[0]&7);
1075  }
1076  immune->shape_antibody[j] = match;
1077  }
1078  }
1079  else
1080  {
1082  if (immune->antigens[i]<255)
1083  {
1084  immune->antigens[i]++;
1085  }
1086 
1088  math_random3(local_random);
1089  if (local_random[0]<ANTIBODY_GENERATION_PROB(local))
1090  {
1091  math_random3(local_random);
1092  immune->shape_antibody[j]=(n_byte)(local_random[0]&255);
1093  immune->antibodies[j]=(n_byte)(local_random[1]&7);
1094  }
1095  }
1096  }
1097 
1100  total_antigens=0;
1101  max_severity=0;
1102  for (i=0; i<IMMUNE_ANTIGENS; i++)
1103  {
1104  /* total quantity of pathogen */
1105  total_antigens+=immune->antigens[i];
1106  /* record the maximum pathogen severity */
1107  if (immune->shape_antigen[i]>max_severity)
1108  {
1109  max_severity=immune->shape_antigen[i];
1110  }
1111  }
1112  math_random3(local_random);
1113  if ((local_random[0] < (total_antigens>>2)) && (being_energy_less_than(local, BEING_DEAD + 1) == 0))
1114  {
1115  being_energy_delta(local, 0-PATHOGEN_SEVERITY(max_severity));
1116  }
1117 #endif
1118 }
1119 
1120 static n_uint being_genetic_count_zeros(n_genetics count)
1121 {
1122  n_uint loop = 0;
1123  n_uint addition = 0;
1124  while (loop < sizeof(n_genetics)*8)
1125  {
1126  if (((count>>loop) & 1) == 0)
1127  {
1128  addition++;
1129  }
1130  loop++;
1131  }
1132  return addition;
1133 }
1134 
1135 n_uint being_genetic_comparison(n_genetics * primary, n_genetics * secondary, n_int parse_requirements)
1136 {
1137  n_int loop = 0;
1138  n_uint addition = 0;
1139 
1140  if (FIND_SEX(secondary[CHROMOSOME_Y]) != SEX_FEMALE)
1141  {
1142  if (parse_requirements == 1) return 0;
1143  }
1144  else
1145  {
1146  if (parse_requirements == 0) return 0;
1147  }
1148 
1149  while (loop < CHROMOSOMES)
1150  {
1151  n_genetics comparison = primary[loop] ^ secondary[loop];
1152  addition += being_genetic_count_zeros(comparison);
1153  loop++;
1154  }
1155  return addition;
1156 }
1157 
1158 typedef struct
1159 {
1167 
1168 static void being_find_closest_loop(noble_simulation * sim, noble_being * local, void * data)
1169 {
1171 
1172  n_byte success = 0;
1173  n_int local_dob = being_dob(local);
1174 
1175  if (bfcs->older == 0) success = 1;
1176 
1177  if ((bfcs->older == 1) && ((local_dob - AGE_OF_MATURITY) > bfcs->actual_age))
1178  {
1179  success = 1;
1180  }
1181 
1182  if ((bfcs->older == -1) && ((bfcs->actual_age - AGE_OF_MATURITY) > local_dob))
1183  {
1184  success = 1;
1185  }
1186 
1187  if (success)
1188  {
1189  n_uint comparison = being_genetic_comparison(bfcs->genetics, being_genetics(local), bfcs->parse_requirements);
1190  if (comparison > bfcs->comparison_best)
1191  {
1192  bfcs->comparison_best = comparison;
1193  bfcs->return_value = local;
1194  }
1195  }
1196 
1197 }
1198 
1199 static noble_being * being_find_closest(noble_simulation * sim, noble_being * actual, n_int parse_requirements, n_int older)
1200 {
1202  bfcs.parse_requirements = parse_requirements;
1203  bfcs.older = older;
1205  bfcs.comparison_best = 3 * sizeof(n_genetics) * CHROMOSOMES;
1206  bfcs.return_value = 0L;
1207  bfcs.genetics = being_genetics(actual);
1208  bfcs.actual_age = being_dob(actual);
1209 
1210  being_loop_no_thread(sim, actual, being_find_closest_loop, &bfcs);
1211 
1212  return bfcs.return_value;
1213 }
1214 
1215 typedef struct
1216 {
1223 
1224 static void being_find_child_loop(noble_simulation * sim, noble_being * local, void * data)
1225 {
1227  n_uint comparison = being_genetic_comparison(bfcs->genetics, being_genetics(local), -1);
1228  if ((comparison > bfcs->comparison_best) && ((bfcs->today - being_dob(local)) < bfcs->max_age))
1229  {
1230  bfcs->comparison_best = comparison;
1231  bfcs->return_value = local;
1232  }
1233 }
1234 
1235 static noble_being * being_find_child(noble_simulation * sim, n_genetics * genetics, n_int max_age)
1236 {
1238 
1239  bfcs.today = sim->land->date;
1240  bfcs.comparison_best = 0;
1241  bfcs.max_age = max_age;
1242  bfcs.genetics = genetics;
1243  bfcs.return_value = 0L;
1244  being_loop_no_thread(sim, 0L, being_find_child_loop, &bfcs);
1245  return bfcs.return_value;
1246 }
1247 
1248 typedef struct
1249 {
1254 
1255 static void being_find_name_loop(noble_simulation * sim, noble_being * local, void * data)
1256 {
1258  if (bfns->local == 0L)
1259  {
1260  if (being_name_comparison(local, bfns->first_gender, bfns->family))
1261  {
1262  bfns->local = local;
1263  }
1264  }
1265 }
1266 
1268 {
1270  bfns.first_gender = first_gender;
1271  bfns.family = family;
1272  bfns.local = 0L;
1273  being_loop_no_thread(sim, 0L, being_find_name_loop, &bfns);
1274  return bfns.local;
1275 }
1276 
1278 n_uint being_affect(noble_simulation * local_sim, noble_being * local, n_byte is_positive)
1279 {
1280  n_uint affect = 0;
1281 #ifdef EPISODIC_ON
1282  n_uint i;
1283  noble_episodic * local_episodic = being_episodic(local);
1284  if (!local_episodic) return affect;
1285 
1286  for (i=0; i<EPISODIC_SIZE; i++)
1287  {
1288  if (is_positive!=0)
1289  {
1290  if (local_episodic[i].affect>EPISODIC_AFFECT_ZERO)
1291  {
1292  affect += (n_uint)(local_episodic[i].affect) - EPISODIC_AFFECT_ZERO;
1293  }
1294  }
1295  else
1296  {
1297  if (local_episodic[i].affect<EPISODIC_AFFECT_ZERO)
1298  {
1299  affect += EPISODIC_AFFECT_ZERO - (n_uint)(local_episodic[i].affect);
1300  }
1301  }
1302  }
1303 #endif
1304  return affect;
1305 }
1306 
1308 {
1309  "Head","Teeth","Back","Front","Left hand","Right hand","Left foot","Right foot"
1310 };
1311 
1313 {
1314  return body_inventory_description[index];
1315 }
1316 
1318 {
1319  "Associate","Self","Mother","Father","Daughter",
1320  "Son","Granddaughter","Grandson","Sister","Brother",
1321  "Maternal Grandmother","Maternal Grandfather","Paternal Grandmother","Paternal Grandson", "Mother",
1322  "Father","Daughter","Son","Granddaughter","Grandson",
1323  "Sister","Brother","Maternal Grandmother","Maternal Grandfather","Paternal Grandmother",
1324  "Paternal Grandson"
1325 };
1326 
1328 {
1329  n_int position = 0;
1330  if (index >= RELATIONSHIPS)
1331  {
1332  sprintf(description,"ERROR: relationship out of range %d\n",(int)index);
1333  return;
1334  }
1335  io_string_write(description, relationship_description[index], &position);
1336 }
1337 
1338 static void being_inventory_string(n_string string, n_int * location, n_int item)
1339 {
1340  switch (item)
1341  {
1342  case INVENTORY_BRANCH:
1343  io_string_write(string,"branch",location);
1344  break;
1345  case INVENTORY_ROCK:
1346  io_string_write(string,"rock",location);
1347  break;
1348  case INVENTORY_SHELL:
1349  io_string_write(string,"shell",location);
1350  break;
1351  case INVENTORY_TWIG:
1352  io_string_write(string,"twig",location);
1353  break;
1354  case INVENTORY_NUT_CRACKED:
1355  io_string_write(string,"cracked nut",location);
1356  break;
1357  case INVENTORY_GRASS:
1358  io_string_write(string,"piece of grass",location);
1359  break;
1360  case INVENTORY_SCRAPER:
1361  io_string_write(string,"scraper",location);
1362  break;
1363  case INVENTORY_SPEAR:
1364  io_string_write(string,"spear",location);
1365  break;
1366  case INVENTORY_FISH:
1367  io_string_write(string,"fish",location);
1368  break;
1369  case INVENTORY_BIRD_EGGS:
1370  io_string_write(string,"bird eggs",location);
1371  break;
1372  case INVENTORY_LIZARD_EGGS:
1373  io_string_write(string,"lizard eggs",location);
1374  break;
1375  case INVENTORY_CHILD:
1376  case INVENTORY_WOUND:
1377  case INVENTORY_GROOMED:
1378  default:
1379  io_string_write(string,"thing being carried",location);
1380  break;
1381  }
1382 }
1383 
1384 static void being_social_event_string(n_string string, n_int * location, n_int event_type, n_string name_str)
1385 {
1386  switch (event_type)
1387  {
1388  case EVENT_MATE:
1389  io_string_write(string,"Mated with ",location);
1390  break;
1391  case EVENT_SEEK_MATE:
1392  io_string_write(string,"Searched for mate ",location);
1393  break;
1394  case EVENT_GROOM:
1395  io_string_write(string,"Groomed ",location);
1396  break;
1397  case EVENT_GROOMED:
1398  io_string_write(string,"Groomed by ",location);
1399  break;
1400  case EVENT_CHAT:
1401  io_string_write(string,"Chatted with ",location);
1402  break;
1403  case EVENT_BIRTH:
1404  io_string_write(string,"Gave birth to ",location);
1405  break;
1406  case EVENT_HURLED:
1407  io_string_write(string,"Hurled a rock at ",location);
1408  break;
1409  case EVENT_HURLED_BY:
1410  io_string_write(string,"Was hit by a rock hurled by ",location);
1411  break;
1412 
1413  case EVENT_HIT:
1414  io_string_write(string,"Hit ",location);
1415  break;
1416  case EVENT_HIT_BY:
1417  io_string_write(string,"Hit by ",location);
1418  break;
1419  case EVENT_CARRIED:
1420  io_string_write(string,"Carried ",location);
1421  break;
1422  case EVENT_CARRIED_BY:
1423  io_string_write(string,"Carried by ",location);
1424  break;
1425  case EVENT_SUCKLED:
1426  io_string_write(string,"Suckled ",location);
1427  break;
1428  case EVENT_SUCKLED_BY:
1429  io_string_write(string,"Suckled by ",location);
1430  break;
1431  case EVENT_WHACKED:
1432  io_string_write(string,"Whacked ",location);
1433  break;
1434  case EVENT_WHACKED_BY:
1435  io_string_write(string,"Whacked by ",location);
1436  break;
1437  case EVENT_HUGGED:
1438  io_string_write(string,"Hugged ",location);
1439  break;
1440  case EVENT_HUGGED_BY:
1441  io_string_write(string,"Hugged by ",location);
1442  break;
1443  case EVENT_PRODDED:
1444  io_string_write(string,"Prodded ",location);
1445  break;
1446  case EVENT_PRODDED_BY:
1447  io_string_write(string,"Prodded by ",location);
1448  break;
1449  case EVENT_GIVEN:
1450  io_string_write(string,"Given ",location);
1451  break;
1452  case EVENT_GIVEN_BY:
1453  io_string_write(string,"Given by ",location);
1454  break;
1455  case EVENT_POINT:
1456  io_string_write(string,"Pointed to ",location);
1457  break;
1458  case EVENT_POINTED:
1459  io_string_write(string,"Pointed to by ",location);
1460  break;
1461  case EVENT_SMILED:
1462  io_string_write(string,"Smiled at ",location);
1463  break;
1464  case EVENT_SMILED_BY:
1465  io_string_write(string,"Smiled at by ",location);
1466  break;
1467  case EVENT_TICKLED:
1468  io_string_write(string,"Tickled ",location);
1469  break;
1470  case EVENT_TICKLED_BY:
1471  io_string_write(string,"Tickled by ",location);
1472  break;
1473  case EVENT_GLOWERED:
1474  io_string_write(string,"Glowered at ",location);
1475  break;
1476  case EVENT_GLOWERED_BY:
1477  io_string_write(string,"Glowered at by ",location);
1478  break;
1479  case EVENT_PATTED:
1480  io_string_write(string,"Patted ",location);
1481  break;
1482  case EVENT_PATTED_BY:
1483  io_string_write(string,"Patted by ",location);
1484  break;
1485  default:
1486  {
1487  n_string_block number_str;
1488  sprintf(number_str,"%ld", event_type);
1489  io_string_write(string,"Some erroneous action (",location);
1490  io_string_write(string,number_str,location);
1491  io_string_write(string,") with ",location);
1492  break;
1493  }
1494  }
1495  io_string_write(string,name_str,location);
1496 }
1497 
1499 {
1500  noble_remains * remains = sim->remains;
1501 
1502  remains->count = 0;
1503  remains->location = 0;
1504 }
1505 
1507 {
1508  noble_remains * remains = sim->remains;
1509  n_byte2 location = remains->location;
1510 
1511  remains->bodies[location].location[0] = dead->location[0];
1512  remains->bodies[location].location[1] = dead->location[1];
1513  remains->location = (remains->location + 1) % NUMBER_OF_BODIES;
1514 
1515  if (remains->count < NUMBER_OF_BODIES)
1516  {
1517  remains->count++;
1518  }
1519 }
1520 
1522  noble_simulation * sim,
1523  noble_being * local_being,
1524  n_int index,
1525  n_string description)
1526 {
1527  n_string_block str;
1528  n_int string_index = 0;
1529  n_int social = 0;
1530 #ifdef EPISODIC_ON
1531  n_string_block str2, name_str;
1532  noble_episodic * local_episodic;
1533  n_uint days_elapsed,time_elapsed;
1534  n_uint current_date;
1535 
1536  current_date = sim->land->date;
1537  local_episodic = being_episodic(local_being);
1538 
1539  if(local_episodic == 0L)
1540  {
1541  return SHOW_ERROR("No episodic description");
1542  }
1543 
1544  if ((local_episodic[index].event>0) &&
1545  being_name_comparison(local_being, local_episodic[index].first_name[0], local_episodic[index].family_name[0]))
1546  {
1547  being_name_byte2(local_episodic[index].first_name[BEING_MET], local_episodic[index].family_name[BEING_MET], name_str);
1548 
1549  switch(local_episodic[index].event)
1550  {
1551  case EVENT_EAT:
1552  {
1553  io_string_write(str,"Was eating ",&string_index);
1554  switch(local_episodic[index].food)
1555  {
1556  case FOOD_VEGETABLE:
1557  {
1558  io_string_write(str,"vegetation",&string_index);
1559  break;
1560  }
1561  case FOOD_FRUIT:
1562  {
1563  io_string_write(str,"fruit",&string_index);
1564  break;
1565  }
1566  case FOOD_SHELLFISH:
1567  {
1568  io_string_write(str,"shellfish",&string_index);
1569  break;
1570  }
1571  case FOOD_SEAWEED:
1572  {
1573  io_string_write(str,"seaweed",&string_index);
1574  break;
1575  }
1576  case FOOD_BIRD_EGGS:
1577  {
1578  io_string_write(str,"bird eggs",&string_index);
1579  break;
1580  }
1581  case FOOD_LIZARD_EGGS:
1582  {
1583  io_string_write(str,"lizard eggs",&string_index);
1584  break;
1585  }
1586  }
1587  break;
1588  }
1589  case EVENT_SWIM:
1590  {
1591  io_string_write(str,"Went swimming",&string_index);
1592  break;
1593  }
1594  case EVENT_GROOM:
1595  {
1596  io_string_write(str,"Groomed ",&string_index);
1597  io_string_write(str,name_str,&string_index);
1598  io_string_write(str,"'s ",&string_index);
1599  io_string_write(str,being_body_inventory_description(local_episodic[index].arg),&string_index);
1600 
1601  social = 1;
1602  break;
1603  }
1604  case EVENT_SHOUT:
1605  {
1606  io_string_write(str,"Shouted ",&string_index);
1607  break;
1608  }
1609  case EVENT_FISH:
1610  {
1611  io_string_write(str,"Caught a fish ",&string_index);
1612  break;
1613  }
1614  case EVENT_CHEW:
1615  {
1616  io_string_write(str,"Chewing ",&string_index);
1617  if (local_episodic[index].arg & INVENTORY_GRASS)
1618  {
1619  io_string_write(str,"grass ",&string_index);
1620  }
1621  else
1622  {
1623  if (local_episodic[index].arg & INVENTORY_TWIG)
1624  {
1625  io_string_write(str,"twig ",&string_index);
1626  }
1627  else
1628  {
1629  if (local_episodic[index].arg & INVENTORY_FISH)
1630  {
1631  io_string_write(str,"fish ",&string_index);
1632  }
1633  else
1634  {
1635  if (local_episodic[index].arg & INVENTORY_NUT_CRACKED)
1636  {
1637  io_string_write(str,"a cracked nut ",&string_index);
1638  }
1639  else
1640  {
1641  {
1642  if (local_episodic[index].arg & INVENTORY_BIRD_EGGS)
1643  {
1644  io_string_write(str,"birds eggs ",&string_index);
1645  }
1646  else
1647  {
1648  if (local_episodic[index].arg & INVENTORY_LIZARD_EGGS)
1649  {
1650  io_string_write(str,"lizard eggs ",&string_index);
1651  }
1652  }
1653  }
1654  }
1655  }
1656  }
1657  }
1658  if (local_episodic[index].arg & 1)
1659  {
1660  io_string_write(str,"held in right hand ",&string_index);
1661  }
1662  else
1663  {
1664  io_string_write(str,"held in left hand ",&string_index);
1665  }
1666  break;
1667  }
1668  case EVENT_DRAG:
1669  io_string_write(str,"Dragged a ",&string_index);
1670  being_inventory_string(str, &string_index, local_episodic[index].arg);
1671  break;
1672  case EVENT_BRANDISH:
1673  io_string_write(str,"Waved a ",&string_index);
1674  being_inventory_string(str, &string_index, local_episodic[index].arg);
1675  break;
1676  case EVENT_DROP:
1677  io_string_write(str,"Dropped a ",&string_index);
1678  being_inventory_string(str, &string_index, local_episodic[index].arg);
1679  break;
1680  case EVENT_PICKUP:
1681  io_string_write(str,"Picked up a ",&string_index);
1682  being_inventory_string(str, &string_index, local_episodic[index].arg);
1683  break;
1684  default:
1685  being_social_event_string(str, &string_index, local_episodic[index].event, name_str);
1686  social = 1;
1687  break;
1688  }
1689 
1690  if (string_index == 0)
1691  {
1692  return SHOW_ERROR("No string in episodic description");
1693  }
1694 
1695  days_elapsed = current_date - local_episodic[index].space_time.date;
1696  if (days_elapsed == 0)
1697  {
1698  time_elapsed = sim->land->time - local_episodic[index].space_time.time;
1699 
1700  if (time_elapsed < 60)
1701  {
1702  if (time_elapsed == 0)
1703  {
1704  io_string_write(str," now",&string_index);
1705  }
1706  else if (time_elapsed == 1)
1707  {
1708  io_string_write(str," a minute ago",&string_index);
1709  }
1710  else if (time_elapsed<5)
1711  {
1712  io_string_write(str," a few minutes ago",&string_index);
1713  }
1714  else
1715  {
1716  sprintf((char*)str2," %d minutes ago", (int)time_elapsed);
1717  io_string_write(str,str2, &string_index);
1718  }
1719  }
1720  else
1721  {
1722  if (time_elapsed<120)
1723  {
1724  io_string_write(str," an hour ago",&string_index);
1725  }
1726  else
1727  {
1728  sprintf((char*)str2," %d hours ago", (int)time_elapsed/60);
1729  io_string_write(str,str2,&string_index);
1730  }
1731  }
1732  }
1733  else
1734  {
1735  if (days_elapsed==1)
1736  {
1737  io_string_write(str, " yesterday",&string_index);
1738  }
1739  else
1740  {
1741  sprintf((char*)str2," %d days ago", (int)days_elapsed);
1742  io_string_write(str, str2,&string_index);
1743  }
1744  }
1745  }
1746 #endif
1747  str[string_index] = 0;
1748 
1749  string_index = 0;
1750 
1751  io_string_write(description, str, &string_index);
1752 
1753  return social;
1754 }
1755 
1756 #ifdef SHORT_NAMES
1757 
1758 /* ape names */
1759 #define NAMES_SURNAMES 16
1760 #define NAMES_FIRST 64
1761 
1763 const n_string EnglishNames[144] =
1764 {
1765  "Adams","Baker","Brown","Davis","Evans","Green","Jones","Mason",
1766  "Moore","Myers","Perry","Price","Quinn","Smith","White","Young",
1767 
1768  "Agnes","Aimee","Alice","Amber","Anita","April","Becky","Beryl",
1769  "Carla","Chloe","Donna","Doris","Edith","Elena","Elise","Ellen",
1770  "Emily","Erika","Ethel","Faith","Fiona","Flora","Gilda","Grace",
1771  "Hazel","Helen","Hilda","Holly","Irene","Janet","Jewel","Kacey",
1772 
1773  "Kerri","Lacey","Linda","Mabel","Madge","Mandy","Maude","Mavis",
1774  "Megan","Mercy","Misty","Molly","Nancy","Naomi","Norma","Nydia",
1775  "Pansy","Patty","Pearl","Polly","Rhoda","Robin","Sadie","Sally",
1776  "Sarah","Tammy","Tanya","Tilda","Tracy","Vania","Wanda","Wilda",
1777 
1778  "Aaron","Angus","Barry","Basil","Blair","Blake","Boris","Brent",
1779  "Brian","Brock","Bruce","Bruno","Byron","Casey","Cecil","Clive",
1780  "Clyde","Colin","Craig","Cyril","Damon","Darcy","David","Derek",
1781  "Edgar","Edwin","Elmer","Elroy","Elton","Errol","Felix","Floyd",
1782 
1783  "Frank","Garth","Gavin","Giles","Glenn","Grant","Henry","Homer",
1784  "Isaac","Jacob","Jason","Jesse","Keith","Kevin","Leroy","Lloyd",
1785  "Logan","Miles","Nigel","Oscar","Peter","Quinn","Ralph","Roger",
1786  "Scott","Shawn","Simon","Trent","Tyler","Unwin","Vance","Wayne"
1787 };
1788 
1789 #else
1790 
1791 /* ape names */
1792 #define NAMES_SURNAMES 64
1793 #define NAMES_FIRST 256
1794 
1796 const n_string EnglishNames[576] =
1797 {
1798  "Adams","Allen","Bailey","Baker","Barnes","Bell","Brooks","Brown","Butler","Clark","Cook","Cooper","Davies","Davis","Evans",
1799  "Fisher","Foster","Graham","Gray","Green","Hall","Harris","Hill","Howard","Hughes","James","Jones","Kelly","King","Lewis",
1800  "Long","Mason","Matine","Miller","Moore","Morgan","Munroe","Murphy","Mutz","Myers","Nelson","Owen","Parker","Perry",
1801  "Powell","Price","Quinn","Reed","Reid","Rogers","Rose","Reis","Scrim","Smith","Taylor","Thiel","Turner","Walker","Ward",
1802  "Watson","White","Wilson","Wood","Young",
1803 
1804  "Ada","Agatha","Agnes","Aileen","Aimee","Alanna","Alda","Alice","Alina","Alison","Alma","Amanda","Amber","Andrea","Angela",
1805  "Anita","Anthea","April","Ariana","Arleen","Astrid","Audrey","Beata","Becky","Beryl","Bess","Bianca","Blair","Blythe",
1806  "Bonnie","Brenda","Briana","Brooke","Carla","Carly","Carmen","Cheryl","Chloe","Coral","Daphne","Davida","Dawn","Denise",
1807  "Donna","Dora","Doris","Echo","Eda","Edana","Edith","Edlyn","Edna","Edwina","Effie","Eileen","Elaine","Elena","Elga",
1808  "Elise","Eliza","Ella","Ellen","Eloise","Elsie","Elvira","Emily","Emma","Erika","Erin","Estra","Ethel","Eudora","Eunice",
1809  "Faith","Fannie","Fawn","Faye","Fedora","Fern","Fiona","Flora","Gale","Gaye","Geneva","Gilda","Gladys","Gloria","Grace",
1810  "Gwynne","Harley","Hattie","Hazel","Hetty","Hilda","Holly","Honey","Hope","Ingrid","Irene","Iris","Ivory","Ivy","Jade",
1811  "Jane","Janet","Janice","Jeanne","Jemima","Jewel","Joan","Joanna","Joy","June","Kacey","Kara","Kate","Kay","Keely","Kelsey",
1812  "Kendra","Kerri","Kyla","Lacey","Lane","Lara","Larina","Leanne","Leslie","Linda","Livia","Lizzie","Lois","Lorena","Lulu",
1813  "Luna","Lynn","Mabel","Madge","Maggie","Maia","Maisie","Mandy","Marcia","Margot","Marnia","Mary","Maude","Maura","Mavis",
1814  "Maxine","Megan","Melody","Mercy","Meris","Merle","Miriam","Misty","Moira","Molly","Mona","Monica","Mora","Morgan","Muriel",
1815  "Myra","Myrtle","Nancy","Naomi","Nell","Nerita","Nina","Noelle","Nola","Norma","Nydia","Odette","Olga","Opal","Oprah","Orva",
1816  "Page","Pamela","Pansy","Patty","Pearl","Phoebe","Polly","Quenna","Questa","Rachel","Ramona","Regina","Rhea","Rhoda","Rita",
1817  "Robin","Rosa","Rowena","Ruby","Ruth","Sacha","Sadie","Salena","Sally","Salome","Sandra","Sarah","Serena","Shana","Sharon",
1818  "Sheila","Sibley","Silver","Sirena","Talia","Tamara","Tammy","Tanya","Tara","Tasha","Tatum","Tess","Thalia","Thea","Thelma",
1819  "Thora","Tilda","Tina","Tracy","Trina","Trista","Tyne","Udele","Ula","Ulrica","Ulva","Una","Unity","Ursa","Ursula","Valda",
1820  "Vania","Veleda","Vera","Verda","Violet","Vita","Wanda","Wilda","Willa","Willow","Wynne","Zea","Zelda","Zera","Zoe",
1821 
1822  "Aaron","Abbott","Abel","Adam","Albern","Albert","Alfie","Alfred","Alvin","Amery","Amos","Andrew","Angus","Ansel","Arlen",
1823  "Arnold","Arvel","Austin","Axel","Baird","Barry","Basil","Bert","Blair","Blake","Boris","Brent","Brian","Brice","Brock",
1824  "Bruce","Bruno","Bryant","Buck","Bud","Burton","Byron","Calvin","Carl","Carter","Carver","Cary","Casey","Casper","Cecil",
1825  "Cedric","Claude","Clive","Clyde","Colin","Conan","Connor","Conrad","Conroy","Conway","Corwin","Craig","Crosby","Culver",
1826  "Curt","Curtis","Cyril","Damon","Daniel","Darcy","David","Dean","Declan","Dennis","Derek","Dermot","Derwin","Dexter",
1827  "Dillon","Dion","Dirk","Donald","Dorian","Drew","Dudley","Duncan","Dwayne","Dwight","Dylan","Earl","Edgar","Edwin","Efrain",
1828  "Egbert","Elbert","Elmer","Elroy","Elton","Elvis","Emmett","Emrick","Ernest","Errol","Esmond","Eugene","Evan","Ezra","Fabian",
1829  "Farley","Felix","Fenton","Ferris","Finbar","Floyd","Foster","Fox","Frank","Gale","Galvin","Garret","Garth","Gavin","George",
1830  "Gideon","Giles","Gilroy","Glenn","Godwin","Graham","Grant","Guy","Hadden","Hadley","Hadwin","Hale","Hall","Hamlin","Hardy",
1831  "Harley","Hector","Henry","Herman","Homer","Howard","Hubert","Hunter","Ian","Isaac","Isaiah","Ivan","Ives","Jack","Jacob",
1832  "Jarvis","Jason","Jasper","Jed","Jerome","Jesse","John","Joshua","Justin","Keaton","Keith","Kelsey","Kelvin","Kent","Kerry",
1833  "Kevin","Kirby","Kirk","Kit","Kody","Konrad","Kurt","Kyle","Lamont","Landon","Lane","Lars","Lee","Leroy","Leslie","Lester",
1834  "Lionel","Lloyd","Logan","Lowell","Lyndon","Marcus","Marlon","Martin","Marvin","Medwin","Melvin","Merlin","Miles","Morgan",
1835  "Morris","Morton","Murray","Neal","Nigel","Noel","Norman","Olaf","Olin","Oliver","Oscar","Oswald","Otis","Owen","Paul",
1836  "Perry","Peter","Philip","Pierce","Quincy","Quinn","Ralph","Rex","Riley","Rodney","Roger","Roland","Rolf","Ronald","Rory",
1837  "Ross","Roy","Rufus","Rupert","Ryan","Samson","Samuel","Scott","Sean","Seth","Shawn","Sidney","Simon","Sloane","Stacy",
1838  "Thomas","Toby","Todd","Tony","Trent","Trevor","Troy","Tyler","Unwin","Vance","Victor","Walter","Warren","Wayne","Wilbur",
1839  "Willis","Wyatt","Wylie"
1840 };
1841 
1842 #endif
1843 
1844 #define FAMILY_NAME_AND_MOD (NAMES_SURNAMES - 1)
1845 #define FIRST_NAME_AND_MOD (NAMES_FIRST - 1)
1846 
1847 #define UNPACK_FAMILY_FIRST_NAME(packed_family_name) (packed_family_name & FAMILY_NAME_AND_MOD)
1848 #define UNPACK_FAMILY_SECOND_NAME(packed_family_name) ((packed_family_name / NAMES_SURNAMES)&FAMILY_NAME_AND_MOD)
1849 #define GET_NAME_FAMILY(f0,f1) ((n_byte2)((f0&FAMILY_NAME_AND_MOD)|((f1&FAMILY_NAME_AND_MOD)*NAMES_SURNAMES)))
1850 
1851 
1852 void being_unpack_family(n_byte2 name, n_byte * values)
1853 {
1854  values[0] = UNPACK_FAMILY_FIRST_NAME(name);
1855  values[1] = UNPACK_FAMILY_SECOND_NAME(name);
1856 }
1857 
1859 {
1860  if (value == 0L)
1861  {
1862  return 0;
1863  }
1864  {
1865  noble_social * local_social = being_social(value);
1866  return local_social->first_name[BEING_MET] & FIRST_NAME_AND_MOD;
1867  }
1868 }
1869 
1870 static void being_set_first_name(noble_being * value, n_byte2 name)
1871 {
1872  noble_social * local_social = being_social(value);
1873  local_social->first_name[BEING_MET] = name & FIRST_NAME_AND_MOD;
1874 }
1875 
1877 {
1878  noble_social * local_social = being_social(value);
1879  local_social->family_name[BEING_MET] = GET_NAME_FAMILY(first,last);
1880 }
1881 
1883 {
1884  if (value == 0L)
1885  {
1886  return 0;
1887  }
1888  return (n_byte2)((being_first_name(value) | (FIND_SEX(GET_I(value))<<8)));
1889 }
1890 
1892 {
1893  if (value == 0L)
1894  {
1895  return 0;
1896  }
1898 }
1899 
1900 n_int being_name_comparison(noble_being * value, n_byte2 gender_name, n_byte2 family_name)
1901 {
1902  return ((being_gender_name(value) == gender_name) && (being_family_name(value) == family_name));
1903 }
1904 
1906 {
1907  if (value == 0L)
1908  {
1909  return 0;
1910  }
1911  {
1912  noble_social * local_social = being_social(value);
1913  return UNPACK_FAMILY_FIRST_NAME(local_social->family_name[BEING_MET]);
1914  }
1915 }
1916 
1918 {
1919  if (value == 0L)
1920  {
1921  return 0;
1922  }
1923  {
1924  noble_social * local_social = being_social(value);
1925  return UNPACK_FAMILY_SECOND_NAME(local_social->family_name[BEING_MET]);
1926  }
1927 }
1928 
1929 static void being_name(n_byte female, n_int first, n_byte family0, n_byte family1, n_string name)
1930 {
1931  n_int position = 0;
1932  if (first != -1)
1933  {
1934  if (female)
1935  {
1936  io_string_write(name, EnglishNames[ NAMES_SURNAMES + first ], &position);
1937  }
1938  else
1939  {
1940  io_string_write(name, EnglishNames[ NAMES_SURNAMES + NAMES_FIRST + first ], &position);
1941  }
1942  io_string_write(name, " ", &position);
1943  io_string_write(name, EnglishNames[ family0 ], &position);
1944  io_string_write(name, "-", &position);
1945  io_string_write(name, EnglishNames[ family1 ], &position);
1946  }
1947  else
1948  {
1949  io_string_write(name, "Unknown", &position);
1950  }
1951 }
1952 
1954 {
1955  being_name((FIND_SEX(GET_I(value)) == SEX_FEMALE), being_first_name(value), being_family_first_name(value), being_family_second_name(value), str);
1956 }
1957 
1958 void being_name_byte2(n_byte2 first, n_byte2 family, n_string name)
1959 {
1960  being_name((n_byte)((first>>8)==SEX_FEMALE),
1961  (n_int)(first&255),
1964  name);
1965 }
1966 
1968 {
1969  /* if you change this you need to change the corresponding definitions in entity.h */
1970  const n_string state_description[] =
1971  {
1972  "Sleeping", "Awake", "Hungry", "Swimming", "Eating", "Moving",
1973  "Speaking", "Shouting", "Grooming", "Suckling",
1974  "Showing Force", "Attacking"
1975  };
1976  n_int string_length=0;
1977  n_int n=2;
1978 
1979  if (state == BEING_STATE_ASLEEP)
1980  {
1981  io_string_write(result, state_description[0], &string_length);
1982  return;
1983  }
1984 
1985  while (n < BEING_STATES)
1986  {
1987  if (state & (1<<(n-1)))
1988  {
1989  if (string_length > 0)
1990  {
1991  io_string_write(result, ", ", &string_length);
1992  }
1993  io_string_write(result, state_description[n], &string_length);
1994  }
1995  n++;
1996  }
1997 }
1998 
2010 void being_move(noble_being * local, n_int rel_vel, n_byte kind)
2011 {
2012  if (kind > 0)
2013  {
2014  n_vect2 location_vector;
2015  n_byte2 loc[2];
2016  vect2_byte2(&location_vector, being_location(local));
2017  if (kind == 1)
2018  {
2019  n_vect2 facing_vector;
2020  being_facing_vector(local, &facing_vector, 1);
2021  vect2_d(&location_vector, &facing_vector, rel_vel, 512);
2022  }
2023  else
2024  {
2025  if (rel_vel < 2)
2026  location_vector.y -= (rel_vel * 200)-100;
2027  else
2028  location_vector.x += 500-(rel_vel * 200);
2029  }
2030  loc[0] = APESPACE_WRAP(location_vector.x);
2031  loc[1] = APESPACE_WRAP(location_vector.y);
2032  being_set_location(local, loc);
2033  }
2034  else
2035  {
2036  being_wander(local, -rel_vel);
2037  }
2038 }
2039 
2041 {
2042  noble_being * local_select = sim->select;
2043  noble_being * first = sim->beings;
2044  noble_being * last = &(sim->beings[sim->num - 1]);
2045  if (forwards)
2046  {
2047  if (sim->select != last)
2048  {
2049  local_select++;
2050  }
2051  else
2052  {
2053  local_select = first;
2054  }
2055  }
2056  else
2057  {
2058  if (sim->select != first)
2059  {
2060  local_select--;
2061  }
2062  else
2063  {
2064  local_select = last;
2065  }
2066  }
2067  sim_set_select(local_select);
2068 }
2069 
2077 {
2078  n_land * land = sim->land;
2079 
2080  if (being_energy_less_than(local, BEING_DEAD + 1))
2081  {
2082  return FULLY_ASLEEP;
2083  }
2084 
2086  if(IS_NIGHT(land->time) == 0)
2087  {
2088  return FULLY_AWAKE;
2089  }
2090 
2096  {
2097  return FULLY_AWAKE;
2098  }
2099 
2102  if (being_energy_less_than(local, BEING_HUNGRY + 1))
2103  {
2104  return SLIGHTLY_AWAKE;
2105  }
2106 
2109  if(being_speed(local) > 0)
2110  {
2111  return SLIGHTLY_AWAKE;
2112  }
2113 
2116  return FULLY_ASLEEP;
2117 }
2118 
2119 /*
2120 
2121  Rough sketch on brain compression method
2122 
2123  Hypthesis:
2124 
2125  From a zeroed brain,
2126 
2127  After n OUTPUT_ACTUATOR firings into the brain, and,
2128 
2129  After m brain_cycle occurrences with the states recorded,
2130 
2131  There should be a near identical brain to a standard run brain.
2132 
2133  n and m are independent but an acceptable level needs to be recorded.
2134 
2135  Data set:
2136 
2137  Type (either output actuator or brain cycle)
2138 
2139  For output actuator, record position in brain (n_byte2) and set value (n_byte)
2140 
2141  For brain cycle, record awake or asleep.
2142 
2143  Position in brain is on the 32k boundry, the delimiting could be:
2144 
2145  Position in brain - if 32k-1 then actuator set. If 64k-1, then brain cycle
2146 
2147  Set value is set value if actuator set, 0 is asleep, 1 is awake if brain cycle
2148 
2149  */
2150 
2151 
2152 #ifdef BRAINCODE_ON
2153 #ifdef BRAIN_ON
2154 
2155 static void being_brain_probe(noble_being * local)
2156 {
2157  n_byte * local_brain = being_brain(local);
2158  n_int i = 0;
2159  n_int count[NUMBER_BRAINPROBE_TYPES] = {0};
2160 
2161  if (local_brain == 0L) return;
2162 
2163  while (i < BRAINCODE_PROBES)
2164  {
2165  count[local->brainprobe[i++].type]++;
2166  }
2167 
2169  if (count[INPUT_SENSOR] < (BRAINCODE_PROBES>>2))
2170  {
2171  local->brainprobe[0].type = INPUT_SENSOR;
2172  }
2173  else if (count[OUTPUT_ACTUATOR] < (BRAINCODE_PROBES>>2))
2174  {
2175  local->brainprobe[0].type = OUTPUT_ACTUATOR;
2176  }
2177 
2179  i = 0;
2180 
2181  while (i < BRAINCODE_PROBES)
2182  {
2183  local->brainprobe[i].state++;
2184  if (local->brainprobe[i].state >= local->brainprobe[i].frequency)
2185  {
2186  n_byte * local_braincode = being_braincode_internal(local);
2188  n_int position_in_brain = ((local->brainprobe[i].position * (SINGLE_BRAIN>>8))) & (SINGLE_BRAIN-1);
2189  n_int position_in_braincode = local->brainprobe[i].address % BRAINCODE_SIZE;
2190 
2191  local->brainprobe[i].state = 0;
2192 
2193  if (local->brainprobe[i].type == INPUT_SENSOR)
2194  {
2196  n_int set_value = (local_brain[position_in_brain] + local->brainprobe[i].offset)&255;
2198  local_braincode[position_in_braincode] = (n_byte)set_value;
2199  }
2200  else
2201  {
2203  n_int set_value = (local_braincode[position_in_braincode] + local->brainprobe[i].offset)&255;
2205  local_brain[position_in_brain] = (n_byte)set_value;
2206  }
2207  }
2208  i++;
2209  }
2210 }
2211 #endif
2212 #endif
2213 
2216 {
2217  being_immune_response(local);
2218 
2219 #ifdef BRAINCODE_ON
2220 #ifdef BRAIN_ON
2221 
2223  being_brain_probe(local);
2224 #endif
2225 #endif
2226 
2227  if ((awake == 0) && local)
2228  {
2230 
2232  }
2233 }
2234 
2235 /* For a new child this populates the social graph with family relationships */
2236 static void being_create_family_links(noble_being * mother,
2237  noble_being * child,
2238  noble_simulation * sim)
2239 {
2240  n_int i,j,index;
2241  noble_being * parent[6]= {0L};
2242  noble_being * sibling;
2243  n_byte parent_relation[6];
2244  n_byte child_relation[6];
2245  n_byte sibling_relation;
2246  noble_social * parent_social_graph;
2247 
2248  if (mother==0L) return;
2249 
2252  parent[0] = mother;
2253  parent[1] = being_find_name(sim, mother->father_name[0], mother->father_name[1]);
2254 
2255  parent_relation[0] = RELATIONSHIP_DAUGHTER;
2256  parent_relation[1] = RELATIONSHIP_DAUGHTER;
2257  parent_relation[2] = RELATIONSHIP_GRANDDAUGHTER;
2258  parent_relation[3] = RELATIONSHIP_GRANDDAUGHTER;
2259  parent_relation[4] = RELATIONSHIP_GRANDDAUGHTER;
2260  parent_relation[5] = RELATIONSHIP_GRANDDAUGHTER;
2261 
2262  child_relation[0] = RELATIONSHIP_MOTHER;
2263  child_relation[1] = RELATIONSHIP_MOTHER;
2264  child_relation[2] = RELATIONSHIP_MATERNAL_GRANDMOTHER;
2265  child_relation[3] = RELATIONSHIP_MATERNAL_GRANDMOTHER;
2266  child_relation[4] = RELATIONSHIP_PATERNAL_GRANDMOTHER;
2267  child_relation[5] = RELATIONSHIP_PATERNAL_GRANDMOTHER;
2268 
2270  for (j = 0; j < 2; j++)
2271  {
2272  if (parent[j])
2273  {
2275  parent_social_graph = being_social(parent[j]);
2276  if (parent_social_graph)
2277  {
2278  for (i = 0; i < 2; i++)
2279  {
2280  parent[2+(j*2)+i] = 0L;
2282  index = social_get_relationship(parent[j], (n_byte)(RELATIONSHIP_MOTHER+i),sim);
2283  if ((index > -1) && (parent_social_graph != 0L))
2284  {
2286  parent[2+(j*2)+i] =
2287  being_find_name(sim,
2288  parent_social_graph[index].first_name[BEING_MET],
2289  parent_social_graph[index].family_name[BEING_MET]);
2290  }
2291  }
2292  }
2293  }
2294  }
2295 
2297  sibling_relation = RELATIONSHIP_BROTHER;
2298  if (FIND_SEX(GET_I(child)) == SEX_FEMALE)
2299  {
2300  sibling_relation = RELATIONSHIP_SISTER;
2301  }
2302 
2303  for (j = 0; j < 2; j++)
2304  {
2306  if (parent[j])
2307  {
2308  parent_social_graph = being_social(parent[j]);
2309  if (parent_social_graph)
2310  {
2311  for (i=1; i<SOCIAL_SIZE_BEINGS; i++)
2312  {
2313  if ((parent_social_graph[i].relationship==RELATIONSHIP_SON) ||
2314  (parent_social_graph[i].relationship==RELATIONSHIP_DAUGHTER))
2315  {
2316  sibling = being_find_name(sim, parent_social_graph[i].first_name[BEING_MET], parent_social_graph[i].family_name[BEING_MET]);
2317  if (sibling!=0L)
2318  {
2319  if (parent_social_graph[i].relationship==RELATIONSHIP_SON)
2320  {
2321  social_set_relationship(child, RELATIONSHIP_BROTHER, sibling, sim);
2322  }
2323  else
2324  {
2325  social_set_relationship(child, RELATIONSHIP_SISTER, sibling, sim);
2326  }
2327  social_set_relationship(sibling, sibling_relation, child, sim);
2328  }
2329  }
2330  }
2331  }
2332  }
2333  }
2334 
2336  for (i = 0; i < 6; i++)
2337  {
2338  if (parent[i]==0L) continue;
2339 
2341  if (FIND_SEX(GET_I(child)) == SEX_FEMALE)
2342  {
2343  social_set_relationship(parent[i], parent_relation[i], child, sim);
2344  }
2345  else
2346  {
2347  social_set_relationship(parent[i], parent_relation[i]+1, child, sim);
2348  }
2349 
2350  if (i%2==0)
2351  {
2352  social_set_relationship(child, child_relation[i], parent[i], sim);
2353  }
2354  else
2355  {
2356  social_set_relationship(child, child_relation[i]+1, parent[i], sim);
2357  }
2358  }
2359 
2360 }
2361 
2362 static void being_follow_loop1(noble_simulation * sim, noble_being * other, void * data)
2363 {
2364  being_nearest * nearest = (being_nearest *)data;
2365  n_vect2 difference_vector;
2366 
2368  if ((FIND_SEX(GET_I(other))!=FIND_SEX(GET_I(nearest->local))) &&
2369  being_name_comparison(other, nearest->local->goal[1], nearest->local->goal[2]))
2370  {
2371  being_delta(nearest->local, other, &difference_vector);
2372  if (being_los(sim->land, nearest->local, (n_byte2)difference_vector.x, (n_byte2)difference_vector.y))
2373  {
2374  n_uint compare_distance = vect2_dot(&difference_vector, &difference_vector, 1, 1);
2375  if (compare_distance < nearest->opposite_sex_distance)
2376  {
2377  nearest->opposite_sex = other;
2378  nearest->opposite_sex_distance = compare_distance;
2379  }
2380  }
2381  }
2382 }
2383 
2384 static void being_follow_loop2(noble_simulation * sim, noble_being * other, void * data)
2385 {
2386  being_nearest * nearest = (being_nearest *)data;
2387  n_vect2 difference_vector;
2388 
2390  if (being_name_comparison(other,
2391  nearest->local_social->first_name[BEING_MET],
2392  nearest->local_social->family_name[BEING_MET]))
2393  {
2395  being_delta(nearest->local, other, &difference_vector);
2396  if (being_los(sim->land, nearest->local, (n_byte2)difference_vector.x, (n_byte2)difference_vector.y))
2397  {
2398  n_uint compare_distance = vect2_dot(&difference_vector, &difference_vector, 1, 1);
2399  if (FIND_SEX(GET_I(other))!=FIND_SEX(GET_I(nearest->local)))
2400  {
2401  if (compare_distance < nearest->opposite_sex_distance)
2402  {
2403  nearest->opposite_sex = other;
2404  nearest->opposite_sex_distance = compare_distance;
2405  }
2406  }
2407  else
2408  {
2409  if (compare_distance < nearest->same_sex_distance)
2410  {
2411  nearest->same_sex = other;
2412  nearest->same_sex_distance = compare_distance;
2413  }
2414  }
2415  }
2416  }
2417 
2418 }
2419 
2429 static void being_follow(noble_simulation * sim,
2430  noble_being * local,
2431  being_nearest * nearest)
2432 {
2433  noble_social * local_social_graph;
2434  n_int social_graph_index;
2435 
2436  nearest->local = local;
2437  nearest->opposite_sex_distance = 0xffffffff;
2438  nearest->same_sex_distance = 0xffffffff;
2439  nearest->opposite_sex = 0L;
2440  nearest->same_sex = 0L;
2441 
2443  if (local->goal[0]==GOAL_MATE)
2444  {
2445  being_loop_no_thread(sim, local, being_follow_loop1, nearest);
2446  if (nearest->opposite_sex != 0L)
2447  {
2448  return;
2449  }
2450  }
2451 
2452  local_social_graph = being_social(local);
2453  if (local_social_graph == 0L) return;
2454 
2456  social_graph_index = GET_A(local,ATTENTION_ACTOR);
2457 
2458  nearest->local_social = &local_social_graph[social_graph_index];
2459 
2461  if ((social_graph_index>0) &&
2462  (local_social_graph[social_graph_index].entity_type == ENTITY_BEING) &&
2463  (!SOCIAL_GRAPH_ENTRY_EMPTY(local_social_graph, social_graph_index)))
2464  {
2465  being_loop_no_thread(sim, local, being_follow_loop2, nearest);
2466  }
2467 }
2468 
2469 typedef struct
2470 {
2474 
2475 static void being_listen_loop(noble_simulation * sim, noble_being * other, void * data)
2476 {
2477  being_listen_struct * bls = (being_listen_struct *)data;
2478  n_vect2 difference_vector;
2479  n_uint compare_distance;
2480 
2481  being_delta(bls->local, other, &difference_vector);
2482  compare_distance = vect2_dot(&difference_vector, &difference_vector, 1, 1);
2484  if ((being_state(other)&BEING_STATE_SHOUTING) &&
2485  (compare_distance < SHOUT_RANGE) &&
2486  (other->shout[SHOUT_VOLUME] > bls->max_shout_volume))
2487  {
2488  bls->max_shout_volume = other->shout[SHOUT_VOLUME];
2489  bls->local->shout[SHOUT_HEARD] = other->shout[SHOUT_CONTENT];
2492  }
2493 }
2494 
2500 void being_listen(noble_simulation * local_sim, noble_being * local_being, void * data)
2501 {
2502  being_listen_struct bls;
2503 
2504  if (being_awake(local_sim, local_being) == 0) return;
2505 
2506  bls.max_shout_volume = 127;
2507  bls.local = local_being;
2509  if (local_being->shout[SHOUT_CTR] > 0)
2510  {
2511  local_being->shout[SHOUT_CTR]--;
2512  }
2513  being_loop_no_thread(local_sim, local_being, being_listen_loop, &bls);
2514 }
2515 
2516 static void being_closest_loop(noble_simulation * sim, noble_being * test_being, void * data)
2517 {
2518  being_nearest * nearest = (being_nearest *)data;
2519  n_vect2 difference_vector;
2520  n_uint compare_distance;
2521  being_delta(nearest->local, test_being, &difference_vector);
2522  compare_distance = vect2_dot(&difference_vector, &difference_vector, 1, 1);
2523  if (FIND_SEX(GET_I(test_being)) != FIND_SEX(GET_I(nearest->local)))
2524  {
2525  if (compare_distance < nearest->opposite_sex_distance)
2526  {
2527  /* 'function' : conversion from 'n_int' to 'n_byte2', possible loss of data x 2 */
2528  if (being_los(sim->land, nearest->local, (n_byte2)difference_vector.x, (n_byte2)difference_vector.y))
2529  {
2530  nearest->opposite_sex_distance = compare_distance;
2531  nearest->opposite_sex = test_being;
2532  }
2533  }
2534  }
2535  else
2536  {
2537  if ( compare_distance < nearest->same_sex_distance )
2538  {
2539  if (FIND_SEX(GET_I(test_being)) == FIND_SEX(GET_I(nearest->local)))
2540  {
2541  if (being_los(sim->land, nearest->local, (n_byte2)difference_vector.x, (n_byte2)difference_vector.y))
2542  {
2543  nearest->same_sex_distance = compare_distance;
2544  nearest->same_sex = test_being;
2545  }
2546  }
2547  }
2548  }
2549 }
2550 
2561 static void being_closest(noble_simulation * sim,
2562  noble_being * local,
2563  being_nearest * nearest)
2564 {
2565  nearest->local = local;
2566  nearest->opposite_sex_distance = 0xffffffff;
2567  nearest->same_sex_distance = 0xffffffff;
2568  nearest->opposite_sex = 0L;
2569  nearest->same_sex = 0L;
2570  being_loop_no_thread(sim, local, being_closest_loop, nearest);
2571 }
2572 
2585 static void being_interact(noble_simulation * sim,
2586  noble_being * local,
2587  noble_being * other_being,
2588  n_uint other_being_distance,
2589  n_int * awake,
2590  n_byte * state,
2591  n_int * speed,
2592  n_byte opposite_sex)
2593 {
2594  if (other_being != 0L)
2595  {
2596  n_land * land = sim->land;
2597  n_int today_days = land->date;
2598  n_int birth_days = being_dob(local);
2599  n_uint local_is_female = FIND_SEX(GET_I(local));
2600 
2601  n_vect2 delta_vector;
2602 
2604  n_byte2 familiarity=0;
2605  n_int being_index = social_network(local, other_being, other_being_distance, sim);
2606 
2607  being_delta(local, other_being, &delta_vector);
2608 
2609  if (being_index > -1)
2610  {
2611  noble_social * local_social_graph = being_social(local);
2612  if (local_social_graph)
2613  {
2614  familiarity = local_social_graph[being_index].familiarity;
2615  }
2616  }
2617 
2618  being_facing_towards(local, &delta_vector);
2619 
2620  if ((birth_days+AGE_OF_MATURITY)<today_days)
2621  {
2622  if (social_groom(local, other_being, other_being_distance, *awake, familiarity, sim))
2623  {
2624  *state |= BEING_STATE_GROOMING;
2625 
2626  /* both beings stop */
2627  *speed = 0;
2628  being_set_speed(other_being, 0);
2629  }
2630  else
2631  {
2632  /* squabbling between adults */
2633  if ((other_being_distance < SQUABBLE_RANGE) && ((being_dob(other_being)+AGE_OF_MATURITY) < today_days))
2634  {
2635  n_byte2 squabble_val;
2636  being_set_speed(local, (n_byte)*speed);
2637  squabble_val = social_squabble(local, other_being, other_being_distance, local_is_female, sim);
2638  if (squabble_val != 0)
2639  {
2640  *state |= squabble_val;
2641  *speed = being_speed(local);
2642  }
2643  }
2644  }
2645 
2646  }
2647  if ((other_being_distance < SOCIAL_RANGE) && (being_index>-1))
2648  {
2649  /* attraction and mating */
2650  if (opposite_sex != 0)
2651  {
2652  *state |= social_mate(local, other_being, being_index, other_being_distance, sim);
2653  }
2654 
2655  /* chat */
2656  *state |= social_chat(local, other_being, being_index, sim);
2657  }
2658  }
2659 }
2660 
2661 typedef struct{
2666 
2667 void being_index_loop(noble_simulation * local_sim, noble_being * local_being, void * data)
2668 {
2670 
2671  if (bils->return_value != -1)
2672  {
2673  return;
2674  }
2675 
2676  if (local_being == bils->being)
2677  {
2678  bils->return_value = bils->counter;
2679  }
2680  else
2681  {
2682  bils->counter++;
2683  }
2684 }
2685 
2687 {
2689 
2690  value.return_value = -1;
2691  value.being = local;
2692  value.counter = 0;
2693 
2694  being_loop_no_thread(sim, 0L, being_index_loop, &value);
2695  return value.return_value;
2696 }
2697 
2699 {
2700  n_land * land = sim->land;
2701  n_uint local_is_female = FIND_SEX(GET_I(local));
2702  n_int today_days = land->date;
2703  n_int birth_days = being_dob(local);
2704 
2705  n_int loc_s = being_speed(local);
2706  n_int loc_h = GET_H(local);
2707 
2708  n_byte loc_state = BEING_STATE_ASLEEP;
2709  n_int fat_mass, child_mass = 0;
2710  n_int awake = being_awake(sim, local);
2711 
2712  n_int carrying_child = 0;
2713 
2714  n_genetics * genetics = being_genetics(local);
2715 
2717  n_int tmp_speed;
2719  n_int az;
2720 
2721 #ifdef TERRITORY_ON
2722  n_uint territory_index;
2723 #endif
2724  being_nearest nearest;
2725  n_int test_land = 1;
2726 
2727  nearest.opposite_sex = 0L;
2728  nearest.same_sex = 0L;
2729 
2730  {
2731  n_vect2 location_vector;
2732  n_vect2 facing_vector;
2733  n_vect2 slope_vector;
2734  n_vect2 looking_vector;
2735 
2736  vect2_byte2(&location_vector, being_location(local));
2737 
2738  being_facing_vector(local, &facing_vector, 4);
2739 
2740  land_vect2(&slope_vector, &az, land, &location_vector);
2741 
2742  vect2_add(&looking_vector, &location_vector, &facing_vector);
2743 
2744 
2745 
2746  test_land = (WATER_TEST(land_location(land,(APESPACE_TO_MAPSPACE(looking_vector.x)),
2747  (APESPACE_TO_MAPSPACE(looking_vector.y))),land->tide_level)!= 0);
2748 
2749  {
2750  n_int delta_z = vect2_dot(&slope_vector,&facing_vector,1,24);
2751 
2752  tmp_speed = ((delta_z + 280) >> 4);
2753  }
2754  }
2755 #ifdef LAND_ON
2756  /* TODO why not test_land here? */
2757 
2758  if (WATER_TEST(az,land->tide_level) != 0)
2759  {
2760  loc_state |= BEING_STATE_SWIMMING;
2761  }
2762 #endif
2763 
2764  if (awake != FULLY_ASLEEP)
2765  {
2766  loc_state |= BEING_STATE_AWAKE;
2767  }
2768 
2769  if (loc_s != 0)
2770  {
2771  loc_state |= BEING_STATE_MOVING;
2772  }
2773 
2774  {
2775  n_int hungry = being_energy_less_than(local, BEING_HUNGRY);
2776 
2778  {
2779  hungry = being_energy_less_than(local, BEING_FULL);
2780  }
2781 
2782  if (hungry != 0)
2783  {
2784  loc_state |= BEING_STATE_HUNGRY;
2785  }
2786  }
2787 
2789  fat_mass = GET_BODY_FAT(local);
2790  if (fat_mass > BEING_MAX_MASS_FAT_G)
2791  {
2792  fat_mass = BEING_MAX_MASS_FAT_G;
2793  }
2794 
2796  if (((loc_state & BEING_STATE_SWIMMING) != 0) || test_land)
2797  {
2798  n_uint loop;
2799 
2800  being_turn_away_from_water(local, land);
2801 
2803  being_set_posture(local, 0);
2804 
2808  for (loop=0; loop<INVENTORY_SIZE; loop++)
2809  {
2810  if (!((loop==BODY_HEAD) || (loop==BODY_BACK)))
2811  {
2812  local->inventory[loop] = 0;
2813  }
2814  }
2816  tmp_speed = (tmp_speed * (GENE_SWIM(genetics)+8)) >> 4;
2817 
2818  episodic_self(sim, local, EVENT_SWIM, being_energy(local), 0);
2819 
2821  if (local->parasites > 0) local->parasites--;
2822  }
2823  else
2824  {
2826  tmp_speed = (tmp_speed * (GENE_SPEED(genetics)+8)) >> 3;
2827 
2829  being_follow(sim, local, &nearest);
2830  if (nearest.opposite_sex == 0L)
2831  {
2833  being_closest(sim, local, &nearest);
2834  }
2835 
2836  /* TODO: SOCIAL_THRESHOLD should not be a macro, it should be a function returning n_int */
2837 
2838  if (being_drive(local, DRIVE_SOCIAL) > SOCIAL_THRESHOLD(local))
2839  {
2840  being_interact(sim,
2841  local,
2842  nearest.same_sex, nearest.same_sex_distance,
2843  &awake, &loc_state,
2844  &loc_s, 0);
2845 
2846  being_interact(sim,
2847  local,
2848  nearest.opposite_sex, nearest.opposite_sex_distance,
2849  &awake, &loc_state,
2850  &loc_s, 1);
2851  }
2852  }
2853 
2854  if ((loc_state & (BEING_STATE_SWIMMING | BEING_STATE_GROOMING | BEING_STATE_ATTACK | BEING_STATE_SHOWFORCE)) == 0)
2855  {
2856  if ((loc_state & BEING_STATE_HUNGRY) != 0)
2857  {
2858  if (loc_s == 0)
2859  {
2861  n_byte food_type;
2862  n_int energy = food_eat(sim->land, being_location_x(local), being_location_y(local), az, &food_type, local);
2863 
2865  episodic_food(sim, local, energy, food_type);
2866 
2867  being_energy_delta(local, energy);
2868 
2870 
2871  loc_state |= BEING_STATE_EATING;
2873  if (loc_h < BEING_MAX_HEIGHT)
2874  {
2875  if ((birth_days+AGE_OF_MATURITY) > today_days)
2876  {
2877  loc_h += ENERGY_TO_GROWTH(local,energy);
2878  }
2879  }
2880  }
2881  }
2882  else
2883  {
2885  social_goals(local);
2886  if (loc_s==0)
2887  {
2888  loc_s = 10;
2889  }
2890  }
2891  }
2892 
2893  if (tmp_speed > 39) tmp_speed = 39;
2894  if (tmp_speed < 0) tmp_speed = 0;
2895 
2896  if ((awake != FULLY_AWAKE) || (loc_state & BEING_STATE_HUNGRY))
2897  {
2898  if ((loc_state & BEING_STATE_SWIMMING) != 0)
2899  {
2900  tmp_speed = (being_energy(local) >> 7);
2901  }
2902  else
2903  {
2904  tmp_speed = 0;
2905  }
2906  }
2907 
2908  if (tmp_speed > loc_s) loc_s++;
2909  if (tmp_speed < loc_s) loc_s--;
2910  if (tmp_speed < loc_s) loc_s--;
2911  if (tmp_speed < loc_s) loc_s--;
2912 
2913  if ((local->goal[0]==GOAL_NONE) &&
2914  (nearest.opposite_sex == 0L) &&
2915  (nearest.same_sex == 0L) &&
2916  (being_random(local) < 1000 + 3600*GENE_STAGGER(genetics)))
2917  {
2918  n_int wander = math_spread_byte(being_random(local) & 7);
2919  being_wander(local, wander);
2920  }
2921 
2923  if ((being_pregnant(local) != 0) &&
2924  ((being_pregnant(local) + GESTATION_DAYS + CONCEPTION_INHIBITION_DAYS) < today_days))
2925  {
2927  local->date_of_conception = 0;
2928  }
2929 
2930  if ((loc_state & (BEING_STATE_AWAKE | BEING_STATE_SWIMMING)) == BEING_STATE_AWAKE)
2931  {
2932  n_uint conception_days = being_pregnant(local) ;
2933  if (conception_days > 0)
2934  {
2935  n_int gestation_days = conception_days + GESTATION_DAYS;
2936  if (today_days > gestation_days)
2937  {
2939  noble_being * being_child = being_find_child(sim, genetics, CARRYING_DAYS);
2940 
2942  if (being_child == 0L)
2943  {
2944  if((sim->num + 1) < sim->max)
2945  {
2946  being_child = &(sim->beings[sim->num]);
2947 
2948  if (being_init(sim->land, sim->beings, sim->num, being_child, local, 0L) == 0)
2949  {
2950  episodic_close(sim, local, being_child, EVENT_BIRTH, AFFECT_BIRTH, 0);
2951  being_create_family_links(local,being_child,sim);
2952  if (sim->ext_birth != 0)
2953  {
2954  sim->ext_birth(being_child,local,sim);
2955  }
2956  sim->num++;
2957  }
2958  }
2959  }
2960  else
2961  {
2963  n_int carrying_days = conception_days + GESTATION_DAYS + CARRYING_DAYS;
2964  if (today_days < carrying_days)
2965  {
2966  if (!((local->inventory[BODY_FRONT] & INVENTORY_CHILD) ||
2967  (local->inventory[BODY_BACK] & INVENTORY_CHILD)))
2968  {
2969  local->inventory[BODY_BACK] |= INVENTORY_CHILD;
2970  GET_A(local,ATTENTION_BODY) = BODY_BACK;
2971  }
2972  carrying_child = 1;
2973 
2974  being_set_location(being_child, being_location(local));
2975 
2976  child_mass = GET_M(being_child);
2977  episodic_close(sim, local, being_child, EVENT_CARRIED, AFFECT_CARRYING, 0);
2978  episodic_close(sim, being_child, local, EVENT_CARRIED_BY, AFFECT_CARRIED, 0);
2979  }
2980  }
2981  }
2982  else
2983  {
2986  child_mass = (today_days - conception_days) * BIRTH_MASS / GESTATION_DAYS;
2987  }
2988  }
2989 
2991  if ((birth_days + WEANING_DAYS) > today_days)
2992  {
2993  noble_being * mother = being_find_closest(sim, local, 1, 1);
2994  if (mother != 0L)
2995  {
2997  n_vect2 mother_vector;
2998 
2999  being_delta(mother, local, &mother_vector);
3000 
3001  being_facing_towards(local, &mother_vector);
3002 
3004  if ((loc_state & BEING_STATE_HUNGRY) != 0)
3005  {
3006  n_int distance = vect2_dot(&mother_vector, &mother_vector, 1, 1);
3007  if (distance < SUCKLING_MAX_SEPARATION)
3008  {
3010  if (mother->inventory[BODY_BACK] & INVENTORY_CHILD)
3011  {
3012  mother->inventory[BODY_BACK] -= INVENTORY_CHILD;
3013  }
3014  mother->inventory[BODY_FRONT] |= INVENTORY_CHILD;
3015  GET_A(mother,ATTENTION_BODY) = BODY_FRONT;
3017  if (mother->inventory[BODY_FRONT] & INVENTORY_GROOMED)
3018  {
3020  }
3022  if (being_energy_less_than(mother, BEING_HUNGRY) == 0)
3023  {
3025  being_energy_delta(mother, 0 - SUCKLING_ENERGY);
3029 
3031  loc_state |= BEING_STATE_SUCKLING;
3033  being_immune_seed(mother, local);
3034 
3035  episodic_close(sim, mother, local, EVENT_SUCKLED, AFFECT_SUCKLING, 0);
3036  episodic_close(sim, local, mother, EVENT_SUCKLED_BY, AFFECT_SUCKLING, 0);
3037  }
3038  }
3039  }
3040  }
3041  }
3042  }
3043 
3045  if ((carrying_child==0) && (local_is_female == SEX_FEMALE))
3046  {
3047  if (local->inventory[BODY_FRONT] & INVENTORY_CHILD)
3048  {
3050  }
3051  if (local->inventory[BODY_BACK] & INVENTORY_CHILD)
3052  {
3053  local->inventory[BODY_BACK] -= INVENTORY_CHILD;
3054  }
3055  }
3056 
3057 #ifdef TERRITORY_ON
3058  territory_index =
3061 
3062  if (local->territory[territory_index].familiarity<65534)
3063  {
3064  local->territory[territory_index].familiarity++;
3065  }
3066  else
3067  {
3069  for (territory_index=0; territory_index<TERRITORY_AREA; territory_index++)
3070  {
3071  local->territory[territory_index].familiarity>>=2;
3072  }
3073  }
3074 #endif
3075 
3076  being_set_speed(local, (n_byte)loc_s);
3077  GET_H(local) = (n_byte2) loc_h;
3078  GET_M(local) = (n_byte2)((BEING_MAX_MASS_G*loc_h/BEING_MAX_HEIGHT)+fat_mass+child_mass);
3079  being_set_state(local, loc_state);
3080 }
3081 
3082 #ifdef BRAINCODE_ON
3083 
3085  noble_being * other,
3086  n_byte friend_foe,
3087  n_byte internal)
3088 {
3089  n_byte2 * local_random = being_get_random(local);
3090  n_uint ch,i,most_similar_index,diff,min,actor_index;
3091  noble_social * graph;
3092  if (other==0L)
3093  {
3095  for (ch = 0; ch < BRAINCODE_SIZE; ch+=3)
3096  {
3097  math_random3(local_random);
3098  if (internal != 0)
3099  {
3100 #ifdef RANDOM_INITIAL_BRAINCODE
3101  being_braincode_internal(local)[ch] = math_random(local_random) & 255;
3102 #else
3103  being_random3(local);
3104  being_braincode_internal(local)[ch] = (math_random(local_random) & 192) | get_braincode_instruction(local);
3105 #endif
3106  being_braincode_internal(local)[ch+1] = math_random(local_random) & 255;
3107  being_braincode_internal(local)[ch+2] = math_random(local_random) & 255;
3108  }
3109  else
3110  {
3111 #ifdef RANDOM_INITIAL_BRAINCODE
3112  being_braincode_external(local)[ch] = math_random(local_random) & 255;
3113 #else
3114  being_random3(local);
3115  being_braincode_external(local)[ch] = (math_random(local_random) & 192) | get_braincode_instruction(local);
3116 #endif
3117  being_braincode_external(local)[ch+1] = math_random(local_random) & 255;
3118  being_braincode_external(local)[ch+2] = math_random(local_random) & 255;
3119  }
3120  }
3121  }
3122  else
3123  {
3125  graph = being_social(local);
3126 
3127  if (graph == 0L)
3128  {
3129  return;
3130  }
3131 
3132  most_similar_index=0;
3133  min=99999;
3134  actor_index = GET_A(local,ATTENTION_ACTOR);
3135 
3140  for (i=0; i<SOCIAL_SIZE; i++)
3141  {
3142  if ((i!=actor_index) && (!SOCIAL_GRAPH_ENTRY_EMPTY(graph,i)))
3143  {
3144  n_int signed_diff = (n_int)graph[i].friend_foe - (n_int)friend_foe;
3145  if (signed_diff < 0)
3146  {
3147  diff = -signed_diff;
3148  }
3149  else
3150  {
3151  diff = signed_diff;
3152  }
3153  if (diff < min)
3154  {
3155  min = diff;
3156  most_similar_index = i;
3157  }
3158  }
3159  }
3161  io_copy(graph[most_similar_index].braincode, graph[actor_index].braincode, BRAINCODE_SIZE);
3162  }
3163 }
3164 #endif
3165 
3167 static n_int being_set_unique_name(noble_being * beings,
3168  n_int number,
3169  noble_being * local_being,
3170  n_byte2 mother_family_name,
3171  n_byte2 father_family_name)
3172 {
3173  n_int i;
3174  n_int samples=0,found=0;
3175  n_byte2 possible_family_name;
3176  n_byte2 possible_first_name;
3177  n_byte2 * random_factor = being_get_random(local_being);
3178  n_byte2 local_random[2];
3179 
3180  local_random[0] = random_factor[0];
3181  local_random[1] = random_factor[1];
3182 
3184  math_random3(local_random);
3185  math_random3(local_random);
3186 
3188  if ((mother_family_name==0) && (father_family_name==0))
3189  {
3190  mother_family_name =
3192  (math_random(local_random) & FAMILY_NAME_AND_MOD));
3193  father_family_name =
3194  GET_NAME_FAMILY((math_random(local_random) & FAMILY_NAME_AND_MOD),
3195  (math_random(local_random) & FAMILY_NAME_AND_MOD));
3196  }
3197 
3199  possible_family_name =
3200  GET_NAME_FAMILY(UNPACK_FAMILY_FIRST_NAME(mother_family_name),
3201  UNPACK_FAMILY_SECOND_NAME(father_family_name));
3202 
3203  while ((found == 0) && (samples < 2048))
3204  {
3206  possible_first_name = (n_byte2)((math_random(local_random) & 255) | (FIND_SEX(GET_I(local_being))<<8));
3207 
3209  if (UNPACK_FAMILY_FIRST_NAME(mother_family_name) ==
3210  UNPACK_FAMILY_SECOND_NAME(father_family_name))
3211  {
3212  possible_family_name =
3213  GET_NAME_FAMILY(UNPACK_FAMILY_FIRST_NAME(mother_family_name),
3214  (math_random(local_random) & FAMILY_NAME_AND_MOD));
3215  }
3216 
3217  if (samples == 1024)
3218  {
3220  possible_family_name =
3221  GET_NAME_FAMILY(UNPACK_FAMILY_SECOND_NAME(mother_family_name),
3222  UNPACK_FAMILY_FIRST_NAME(father_family_name));
3223  }
3224 
3226  if (UNPACK_FAMILY_SECOND_NAME(mother_family_name) ==
3227  UNPACK_FAMILY_FIRST_NAME(father_family_name))
3228  {
3229  possible_family_name =
3230  GET_NAME_FAMILY(UNPACK_FAMILY_SECOND_NAME(mother_family_name),
3231  (math_random(local_random) & FAMILY_NAME_AND_MOD));
3232  }
3233 
3234  being_set_first_name(local_being,possible_first_name);
3235  being_set_family_name(local_being,
3236  UNPACK_FAMILY_FIRST_NAME(possible_family_name),
3237  UNPACK_FAMILY_SECOND_NAME(possible_family_name));
3238 
3240  found = 1;
3241  for (i = 0; i < number; i++)
3242  {
3243  noble_being * other_being = &beings[i];
3244  if (being_name_comparison(local_being, being_gender_name(other_being), being_family_name(other_being)))
3245  {
3246  found = 0;
3247  break;
3248  }
3249  }
3250  samples++;
3251  }
3252 
3253  return found;
3254 }
3255 
3256 static void being_random_genetics(n_genetics * value, n_byte2 * random, n_int male)
3257 {
3258  n_int loop = 0;
3259  math_random3(random);
3260  while (loop < CHROMOSOMES)
3261  {
3262  n_uint loop2 = 0;
3263 
3264  value[loop] = 0;
3265 
3266  while (loop2 < (sizeof(n_genetics)*8))
3267  {
3268  if (math_random(random)&1)
3269  {
3270  value[loop] |= 1 << loop2;
3271  }
3272  loop2++;
3273  }
3274  loop++;
3275  }
3276  value[CHROMOSOME_Y] &= ~1;
3277  value[CHROMOSOME_Y] |= (male ? 2 : 3);
3278 }
3279 
3287 n_int being_init(n_land * land, noble_being * beings, n_int number,
3288  noble_being * local, noble_being * mother,
3289  n_byte2* random_factor)
3290 {
3292  n_byte ch;
3293 #ifdef EPISODIC_ON
3294  noble_social * local_social_graph = being_social(local);
3295  noble_episodic * local_episodic = being_episodic(local);
3296 #endif
3297  if (local_social_graph == 0L)
3298  {
3299  return SHOW_ERROR("Social memory not available");
3300  }
3301  if (local_episodic == 0L)
3302  {
3303  return SHOW_ERROR("Episodic memory not available");
3304  }
3305 
3306  being_erase(local);
3307 
3308 #ifdef BRAIN_ON
3309  {
3310  n_byte * brain_memory = being_brain(local);
3311  if (brain_memory != 0L)
3312  {
3313  io_erase(brain_memory, DOUBLE_BRAIN);
3314  }
3315  else
3316  {
3317  return SHOW_ERROR("Brain memory not available");
3318  }
3319  }
3320 #endif
3321 
3322  local->goal[0]=GOAL_NONE;
3323 
3326  for (ch = 0; ch < PREFERENCES; ch++)
3327  {
3328  local->learned_preference[ch]=127;
3329  }
3330 
3331  being_immune_init(local);
3332 
3333  for (ch = 0; ch < ATTENTION_SIZE; ch++)
3334  {
3335  local->attention[ch]=0;
3336  }
3337 
3339  if (mother)
3340  {
3341  local->generation_max = mother->child_generation_max + 1;
3342  local->generation_min = mother->child_generation_min + 1;
3343  }
3344  else
3345  {
3346  local->generation_max = 0;
3347  local->generation_min = 0;
3348  }
3349  local->child_generation_max = 0;
3350  local->child_generation_min = 0;
3351 
3356  if (random_factor)
3357  {
3358  being_set_random(local, random_factor);
3359  being_random3(local);
3360  being_random3(local);
3361 
3362  }
3363  else if (mother)
3364  {
3365  (void)being_random(mother);
3366 
3367  being_set_random(local, being_get_random(mother));
3368 
3369  being_random3(local);
3370 
3371  being_set_random1(local, being_get_random(mother)[0]);
3372 
3373  being_random3(local);
3374 
3375  being_set_random1(local, land->time);
3376 
3377  being_random3(local);
3378  }
3379  else
3380  {
3381  NA_ASSERT(random_factor, "Random factor not set");
3382  NA_ASSERT(mother, "Mother not set");
3383  return SHOW_ERROR("No correct being interface provided");
3384  }
3385 #ifdef BRAINCODE_ON
3386 
3387  being_random3(local);
3388 
3389 #ifdef EPISODIC_ON
3390 
3391  io_erase((n_byte*)local_social_graph,sizeof(noble_social)*SOCIAL_SIZE);
3392 
3393  for (ch=0; ch<EPISODIC_SIZE; ch++)
3394  {
3395  local_episodic[ch].affect=EPISODIC_AFFECT_ZERO;
3396  }
3397 
3398  local_social_graph[0].relationship=RELATIONSHIP_SELF;
3399  for (ch=0; ch<SOCIAL_SIZE; ch++)
3400  {
3402  local_social_graph[ch].entity_type = ENTITY_BEING;
3405  local_social_graph[ch].friend_foe = SOCIAL_RESPECT_NORMAL;
3406  }
3407 #endif
3408 
3409  being_init_braincode(local,0L,0,
3411  being_init_braincode(local,0L,0,
3413 
3415  for (ch = 0; ch < BRAINCODE_PSPACE_REGISTERS; ch++)
3416  {
3417  being_random3(local);
3418  local->braincode_register[ch] = (n_byte)being_random(local)&255;
3419  }
3420 
3422  for (ch = 0; ch < BRAINCODE_PROBES; ch++)
3423  {
3424  being_random3(local);
3425  if (being_random(local)&1)
3426  {
3427  local->brainprobe[ch].type = INPUT_SENSOR;
3428  }
3429  else
3430  {
3431  local->brainprobe[ch].type = OUTPUT_ACTUATOR;
3432  }
3433  local->brainprobe[ch].frequency = (n_byte)1 + (being_random(local)%BRAINCODE_MAX_FREQUENCY);
3434  being_random3(local);
3435  local->brainprobe[ch].address = (n_byte)being_random(local)&255;
3436  local->brainprobe[ch].position = (n_byte)being_random(local)&255;
3437  being_random3(local);
3438  local->brainprobe[ch].offset = (n_byte)being_random(local)&255;
3439  }
3440 #endif
3441 
3442  being_facing_init(local);
3443 
3444  if (random_factor)
3445  {
3446  n_byte2 location[2];
3447 
3448  n_int loop = 0;
3449 
3450  being_random3(local);
3451 
3452  do
3453  {
3454  location[0] = (n_byte2)(being_random(local) & APESPACE_BOUNDS);
3455  location[1] = (n_byte2)(being_random(local) & APESPACE_BOUNDS);
3456  loop ++;
3457  }
3458  while ((loop < 20) && (WATER_TEST(land_location(land, APESPACE_TO_MAPSPACE(location[0]), APESPACE_TO_MAPSPACE(location[1])),land->tide_level)));
3459 
3460 
3461 
3462 
3463  being_set_location(local, location);
3464 
3465  {
3466  n_genetics mother_genetics[CHROMOSOMES];
3467  n_genetics father_genetics[CHROMOSOMES];
3468  n_byte2 gene_random[2];
3469 
3470  being_random3(local);
3471 
3472  gene_random[0] = being_random(local);
3473  being_random3(local);
3474  being_random3(local);
3475 
3476  gene_random[1] = being_random(local);
3477 
3478  being_random_genetics(mother_genetics, gene_random, 0);
3479 
3480  being_random3(local);
3481 
3482  gene_random[0] = being_random(local);
3483  being_random3(local);
3484  being_random3(local);
3485  being_random3(local);
3486 
3487  gene_random[1] = being_random(local);
3488 
3489  being_random_genetics(father_genetics, gene_random, 1);
3490  being_random3(local);
3491 
3492  body_genetics(beings, number, being_genetics(local), mother_genetics, father_genetics, gene_random);
3493 
3494  being_set_unique_name(beings, number, local, 0L, 0L);
3495  }
3496  local->social_x = local->social_nx =
3497  (math_random(local->seed) & 32767)+16384;
3498  local->social_y = local->social_ny =
3499  (math_random(local->seed) & 32767)+16384;
3500 
3501  local->date_of_birth = 0;
3502  }
3503  else
3504  {
3505  being_set_location(local, being_location(mother));
3506 
3508  being_wander(local, being_facing(mother) - being_facing(local));
3509 
3510  (void) being_random(local);
3511  local->social_x = local->social_nx = mother->social_x;
3512  local->social_y = local->social_ny = mother->social_y;
3513 
3515 
3517  local->honor = (n_byte)being_honor(mother);
3518 
3519  being_set_unique_name(beings, number, local,
3520  being_family_name(mother),
3521  mother->father_name[1]);
3522 
3523  local->date_of_birth = land->date;
3524  }
3525 
3526  being_living(local);
3527 
3528  if (random_factor)
3529  {
3530  GET_H(local) = BIRTH_HEIGHT;
3531  GET_M(local) = BIRTH_MASS;
3532  }
3533  else
3534  {
3536  being_random3(local);
3537  GET_H(local) = BIRTH_HEIGHT +
3538  (local->seed[0]%(BEING_MAX_HEIGHT-BIRTH_HEIGHT));
3539  GET_M(local) = BIRTH_MASS +
3540  (local->seed[1]%(BEING_MAX_MASS_G-BIRTH_MASS));
3541  }
3542 
3543  local->crowding = MIN_CROWDING;
3544 #ifdef BRAIN_ON
3545  if (being_brain(local))
3546  {
3549  being_set_brainatates(local, 0, 171, 0, 146);
3550  being_set_brainatates(local, 1, 86, 501, 73);
3551 
3552  }
3553 #endif
3554  return 0;
3555 }
3556 
3557 void being_tidy_loop(noble_simulation * local_sim, noble_being * local_being, void * data)
3558 {
3559  n_genetics *genetics = being_genetics(local_being);
3560  n_int local_honor = being_honor(local_being);
3561  n_land *land = local_sim->land;
3562  n_int delta_e = 0;
3563  n_int conductance = 5;
3564  n_int *max_honor = data;
3565  if (local_honor >= 254)
3566  {
3567  max_honor[0] = 1;
3568  }
3569  if(being_awake(local_sim, local_being))
3570  {
3571  n_int local_s = being_speed(local_being);
3572 
3573  n_vect2 location_vector;
3574  n_vect2 facing_vector;
3575 
3576  vect2_byte2(&location_vector, being_location(local_being));
3577 
3578  being_facing_vector(local_being, &facing_vector, 1);
3579 
3580  if (local_s > 0)
3581  {
3582  n_byte2 location[2];
3583  vect2_d(&location_vector, &facing_vector, local_s, 512);
3584 
3585  /* vector to n_byte2 may do incorrect wrap around MUST be improved */
3586  location[0] = (n_byte2)APESPACE_WRAP(location_vector.x);
3587  location[1] = (n_byte2)APESPACE_WRAP(location_vector.y);
3588 
3589  being_set_location(local_being, location);
3590  }
3591 
3592  {
3593  n_int delta_z;
3594  n_int delta_energy;
3595  n_int local_z;
3596  n_vect2 slope_vector;
3597 
3598  land_vect2(&slope_vector, &local_z,land, &location_vector);
3599 
3600  delta_z = vect2_dot(&slope_vector,&facing_vector,1,96);
3601  delta_energy = ((512 - delta_z) * local_s)/80;
3602 
3603  if (WATER_TEST(local_z,land->tide_level))
3604  {
3605  n_int insulation=0;
3607  n_int fat_mass = GET_BODY_FAT(local_being);
3608  delta_energy = ((delta_energy * delta_energy) >> 9);
3609  if (fat_mass > BEING_MAX_MASS_FAT_G)
3610  {
3611  fat_mass = BEING_MAX_MASS_FAT_G;
3612  }
3613  insulation = fat_mass * 5 / BEING_MAX_MASS_FAT_G;
3614  delta_e += (delta_energy + 10 - insulation) >> 3;
3615  conductance = 4;
3616  }
3617  else
3618  {
3619  if (delta_z > 0)
3620  {
3622  delta_energy += GENE_HILL_CLIMB(genetics);
3623  }
3624 
3625  delta_energy = ((delta_energy * delta_energy) >> 9);
3626 
3627  /* the more massive the more energy consumed when moving */
3628  delta_e += (delta_energy + 4 + (GET_M(local_being)*5/BEING_MAX_MASS_G)) >> 2;
3629  }
3630  }
3631  }
3632  else
3633  {
3634  being_set_speed(local_being, 0);
3635  delta_e += (7) >> 2;
3636  }
3637 
3638  if (delta_e > 0)
3639  {
3641  delta_e -= ((GENE_HAIR(genetics)*delta_e)>>conductance);
3642  if (delta_e < 1) delta_e = 1;
3643  }
3644 
3645  being_energy_delta(local_being, 0 - delta_e);
3646 
3647 
3648  if (land->time == 0)
3649  {
3650  n_int age_in_years = AGE_IN_YEARS(local_sim,local_being);
3652  if (age_in_years > 29)
3653  {
3654  if(being_random(local_being) < (age_in_years - 29))
3655  {
3656  being_energy_delta(local_being, 0 - BEING_HUNGRY);
3657  }
3658  }
3659  }
3660 }
3661 
3662 void being_recalibrate_honor_loop(noble_simulation * local, noble_being * value, void * data)
3663 {
3664  value->honor = (n_byte)(((n_int)value->honor*220)/255);
3665 }
3666 
3667 static n_int being_remove_internal_value = 0;
3668 static n_int being_remove_external_value = 0;
3669 
3671 {
3672  return being_remove_internal_value;
3673 }
3674 
3676 {
3677  being_remove_external_value = value;
3678 }
3679 
3680 void being_remove_loop1(noble_simulation * local_sim, noble_being * local_being, void * data)
3681 {
3682  if (being_energy_less_than(local_being, BEING_DEAD + 1))
3683  {
3684  local_sim->ext_death(local_being,local_sim);
3685  }
3686 }
3687 
3688 void being_remove_loop2(noble_simulation * local_sim, noble_being * local, void * data)
3689 {
3691 
3692  if (being_energy_less_than(local, BEING_DEAD + 1) == 0)
3693  {
3694  if ( local != brls->being_count )
3695  {
3696  io_copy((n_byte *)local, (n_byte *)brls->being_count, sizeof(noble_being));
3697  }
3698  brls->being_count++;
3699  brls->count++;
3700  }
3701  else
3702  {
3703  being_remains(local_sim, local);
3704  if (local == brls->reference)
3705  {
3706  brls->selected_died = 1;
3707  }
3708  }
3709 }
3710 
3712 {
3714 
3715  brls->reference = local_sim->select;
3716  brls->being_count = local_sim->beings;
3717  brls->selected_died = 0;
3718  brls->count = 0;
3719 
3720  if (being_remove_external_value)
3721  {
3722  do {}
3723  while(being_remove_external_value);
3724  }
3725 
3726  being_remove_internal_value = 1;
3727  return brls;
3728 }
3729 
3731 {
3732  local_sim->num = (*brls)->count;
3733  if ((*brls)->selected_died)
3734  {
3735  if ((*brls)->count)
3736  {
3737  sim_set_select(local_sim->beings);
3738  }
3739  else
3740  {
3741  sim_set_select(0L);
3742  }
3743  }
3744 
3745  if ((*brls)->count == 0)
3746  {
3747  (void)SHOW_ERROR("No Apes remain start new run");
3748  }
3749 
3750  being_remove_internal_value = 0;
3751  io_free((void **)brls);
3752 }
3753 
3754