Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
drives.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  drives.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 
40 #include "entity.h"
41 #include "entity_internal.h"
42 
45 #define GENE_MATE_SEEK(gene) GENE_VAL_REG(gene, 8, 9, 14, 2)
46 
51 static void drives_hunger(noble_being * local)
52 {
55  {
59  being_dec_drive(local, DRIVE_SEX);
60  }
61  else
62  {
65  }
66 }
67 
68 typedef struct
69 {
73 
74 static void drives_sociability_loop(noble_simulation * local_sim, noble_being * other, void * data)
75 {
77  n_int distance_squared;
78  n_vect2 difference_vector;
79  /* this needs to be checked against simulation near sight and sound values */
80  const n_int apespace_span = APESPACE_TO_MAPSPACE(10);
81  being_delta(dsd->being, other, &difference_vector);
82  /* los should not be used here, it's too expensive */
83  distance_squared = vect2_dot(&difference_vector, &difference_vector, 1, 1);
84  if (distance_squared < (apespace_span * apespace_span))
85  {
86  dsd->beings_in_vacinity++;
87  }
88 }
89 
96 static void drives_sociability(
97  noble_being * local,
98  noble_simulation * sim)
99 {
101  dsd.beings_in_vacinity = 0;
102  dsd.being = local;
103  being_loop_no_thread(sim, local, drives_sociability_loop, &dsd);
104 
106  if (dsd.beings_in_vacinity < local->crowding + SOCIAL_TOLLERANCE)
107  {
110  }
111  else
112  {
115  }
116 
118  if (dsd.beings_in_vacinity < local->crowding) local->crowding--;
119  if (dsd.beings_in_vacinity > local->crowding) local->crowding++;
120 
122  if (local->crowding < MIN_CROWDING) local->crowding = MIN_CROWDING;
123 
125  if (local->crowding > MAX_CROWDING) local->crowding = MAX_CROWDING;
126 }
127 
134 static void drives_sex(
135  noble_being * local,
136  n_int awake,
137  noble_simulation * local_sim)
138 {
139  n_int i,max;
140  noble_social * local_social_graph = being_social(local);
141  n_int age_in_days = AGE_IN_DAYS(local_sim,local);
142 
143 #ifdef EPISODIC_ON
144  noble_episodic * local_episodic = being_episodic(local);
145 #endif
146 
148  if (age_in_days > AGE_OF_MATURITY)
149  {
151  if (awake)
152  {
154  being_inc_drive(local, DRIVE_SEX);
155 
158  if ((being_drive(local, DRIVE_SEX) > THRESHOLD_SEEK_MATE) &&
159  (local->goal[0] == GOAL_NONE))
160  {
162  if (GENE_MATE_SEEK(being_genetics(local))&1)
163  {
165 #ifdef EPISODIC_ON
166  if (!local_episodic) return;
167 
169  for(i=0; i<EPISODIC_SIZE; i++)
170  {
171  if (local_episodic[i].event == EVENT_MATE)
172  {
175  if (being_name_comparison(local, local_episodic[i].first_name[BEING_MEETER], local_episodic[i].family_name[BEING_MEETER]))
176  {
178  local->goal[0]=GOAL_MATE;
179  local->goal[1]=local_episodic[i].first_name[BEING_MET];
180  local->goal[2]=local_episodic[i].family_name[BEING_MET];
181  local->goal[3]=GOAL_TIMEOUT;
185  local_sim,
186  being_gender_name(local), being_family_name(local),
187  local->goal[1], local->goal[2],0);
188  break;
189  }
190  }
191  }
192 #endif
193 
195  if (local->goal[0]!=GOAL_MATE)
196  {
197  max = 0;
198  if (!local_social_graph) return;
199 
200  for(i=1; i<SOCIAL_SIZE_BEINGS; i++)
201  {
202  if (!SOCIAL_GRAPH_ENTRY_EMPTY(local_social_graph,i))
203  {
204  if ((local_social_graph[i].attraction) > max)
205  {
207  max=local_social_graph[i].attraction;
208  local->goal[0]=GOAL_MATE;
209  local->goal[1]=
210  local_social_graph[i].first_name[BEING_MET];
211  local->goal[2]=
212  local_social_graph[i].family_name[BEING_MET];
213  local->goal[3]=GOAL_TIMEOUT;
214  }
215  }
216  }
218  if (local->goal[0]==GOAL_MATE)
219  {
222  local_sim,
223  being_gender_name(local), being_family_name(local),
224  local->goal[1], local->goal[2],0);
225  }
226  }
227  }
228  }
230  if (being_pregnant(local) != 0)
231  {
233  {
234  being_dec_drive(local, DRIVE_SEX);
235  }
236  }
237  }
238  else
239  {
241  being_dec_drive(local, DRIVE_SEX);
242  }
245  if ((being_drive(local, DRIVE_SEX) < THRESHOLD_SEEK_MATE) &&
246  (local->goal[0]==GOAL_MATE))
247  {
248  local->goal[0]=GOAL_NONE;
249  }
250  }
251 }
252 
258 static void drives_fatigue(
259  noble_being * local)
260 {
263  {
266  if (being_state(local) & BEING_STATE_SWIMMING)
267  {
269  }
271  being_dec_drive(local, DRIVE_SEX);
272  }
273  else
274  {
277  }
278 }
279 
287 void drives_cycle(noble_simulation * local_sim, noble_being * local_being, void * data)
288 {
289  drives_hunger(local_being);
290  drives_sociability(local_being, local_sim);
291  drives_sex(local_being, being_awake(local_sim,local_being), local_sim);
292  drives_fatigue(local_being);
293 }