Noble Ape
The Central Directories of the Noble Ape Simulation.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
food.c
Go to the documentation of this file.
1 /****************************************************************
2 
3  food.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 
46 #define GENE_ENERGY_FROM_VEGETABLES(gene) GENE_VAL_REG(gene, 3, 13, 15, 3)
47 
50 #define GENE_ENERGY_FROM_FRUITS(gene) GENE_VAL_REG(gene, 14, 7, 6, 4)
51 
54 #define GENE_ENERGY_FROM_SHELLFISH(gene) GENE_VAL_REG(gene, 10, 12, 12, 2)
55 
58 #define GENE_ENERGY_FROM_SEAWEED(gene) GENE_VAL_REG(gene, 0, 9, 11, 12)
59 
62 #define GENE_ENERGY_FROM_BIRD_EGGS(gene) GENE_VAL_REG(gene, 7, 1, 9, 5)
63 
66 #define GENE_ENERGY_FROM_LIZARD_EGGS(gene) GENE_VAL_REG(gene, 15, 3, 12, 8)
67 
68 
75 n_int food_absorption(noble_being * local, n_int max_energy, n_byte food_type)
76 {
77  n_genetics * genetics = being_genetics(local);
78 
79  n_int vegetable = GENE_ENERGY_FROM_VEGETABLES(genetics);
80  n_int fruit = GENE_ENERGY_FROM_FRUITS(genetics);
81  n_int shellfish = GENE_ENERGY_FROM_SHELLFISH(genetics);
82  n_int seawood = GENE_ENERGY_FROM_SEAWEED(genetics);
83 
84  n_int bird_eggs = GENE_ENERGY_FROM_BIRD_EGGS(genetics);
85  n_int lizard_eggs = GENE_ENERGY_FROM_LIZARD_EGGS(genetics);
86 
87  n_int return_value = 0;
89  n_int absorb_denom = 1 + vegetable + fruit + seawood + bird_eggs + lizard_eggs;
90 
92  being_ingest_pathogen(local, food_type);
93 
94  switch (food_type)
95  {
96  case FOOD_VEGETABLE:
97  return_value = (vegetable << 4) / absorb_denom;
98  break;
99  case FOOD_FRUIT:
100  return_value = (fruit << 4) / absorb_denom;
101  break;
102  case FOOD_SHELLFISH:
103  return_value = (shellfish << 4) / absorb_denom;
104  break;
105  case FOOD_SEAWEED:
106  return_value = (seawood << 4) / absorb_denom;
107  break;
108  case FOOD_BIRD_EGGS:
109  return_value = (seawood << 4) / absorb_denom;
110  break;
111  case FOOD_LIZARD_EGGS:
112  return_value = (seawood << 4) / absorb_denom;
113  break;
114  default:
115  return 0;
116  }
117 
118  return_value = (max_energy * (1 + return_value) >> 3);
119 
120  if (return_value > 320)
121  {
122  return_value = 320;
123  }
124  return return_value;
125 }
126 
136 static n_int food_location(n_land * local_land,
137  n_int loc_x,
138  n_int loc_y,
139  n_int kind)
140 {
141  return land_operator_interpolated(local_land, loc_x, loc_y,
142  (n_byte*)&operators[kind - VARIABLE_BIOLOGY_AREA]);
143 }
144 
155 void food_values(n_land * local_land,
156  n_int loc_x,
157  n_int loc_y,
158  n_int *grass, n_int *trees, n_int *bush)
159 {
160  /* TODO include bird and lizard eggs */
161 
163  *grass =
164  food_location(local_land, loc_x, loc_y, VARIABLE_BIOLOGY_GRASS)+OFFSET_GRASS;
165 
167  *trees =
168  food_location(local_land, loc_x, loc_y, VARIABLE_BIOLOGY_TREE);
169 
171  *bush =
172  food_location(local_land, loc_x, loc_y, VARIABLE_BIOLOGY_BUSH)+OFFSET_BUSH;
173 
174  *grass += LAND_DITHER(*grass, *trees, *bush);
175 }
176 
185 static n_byte food_eat_land(
186  n_land * local_land,
187  n_int loc_x,
188  n_int loc_y,
189  n_int * energy)
190 {
191  n_byte food_type = FOOD_VEGETABLE;
192  n_int grass, trees, bush;
193 
194  /* TODO Handle this logic centrally - including the int values in the function not outside */
195 
196  food_values(local_land, loc_x,loc_y,&grass, &trees, &bush);
197 
199  if ((grass > bush) && (grass > trees))
200  {
201  *energy = ENERGY_GRASS;
202  }
203  else
204  {
205  if (bush > trees)
206  {
207  *energy = ENERGY_BUSH;
208  }
209  else
210  {
211  *energy = ENERGY_FRUIT;
212  food_type = FOOD_FRUIT;
213  }
214  }
215  return food_type;
216 }
217 
226 static n_byte food_intertidal(
227  n_land * local_land,
228  n_int loc_x,
229  n_int loc_y,
230  n_int * energy)
231 {
232  n_byte food_type = FOOD_VEGETABLE;
233  n_int seaweed, rockpool, beach;
234 
236  seaweed =
237  food_location(
238  local_land, loc_x, loc_y, VARIABLE_BIOLOGY_SEAWEED);
239 
241  rockpool =
242  food_location(
243  local_land, loc_x, loc_y, VARIABLE_BIOLOGY_ROCKPOOL);
244 
246  beach =
247  food_location(
248  local_land, loc_x, loc_y, VARIABLE_BIOLOGY_BEACH);
249 
250  beach += LAND_DITHER(seaweed, rockpool, beach);
251 
253  if ((seaweed > rockpool) && (seaweed > beach))
254  {
255  *energy = ENERGY_SEAWEED;
256  food_type = FOOD_SEAWEED;
257  }
258  else
259  {
260  if (rockpool > beach)
261  {
262  *energy = ENERGY_SHELLFISH;
263  food_type = FOOD_SHELLFISH;
264  }
265  }
266  return food_type;
267 }
268 
279  n_land * local_land,
280  n_int loc_x,
281  n_int loc_y,
282  n_int az,
283  n_byte * food_type,
284  noble_being * local_being)
285 {
286  n_int max_energy = BEING_DEAD;
287 
288  *food_type = FOOD_VEGETABLE;
289 
290  if (az > TIDE_MAX)
291  {
293  *food_type = food_eat_land(local_land, loc_x, loc_y, &max_energy);
294  }
295  else
296  {
298  *food_type = food_intertidal(local_land, loc_x, loc_y, &max_energy);
299  }
300 
301  return food_absorption(local_being, max_energy, *food_type);
302 }