ALMaSS Partridge ODdox  1.1
The partridge model description following ODdox protocol
Partridge_Covey.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2011, Christopher John Topping, University of Aarhus
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
37 //
38 // Partridge_Covey.cpp
39 //
40 //---------------------------------------------------------------------------
41 
42 #include <cmath>
43 #include <assert.h>
44 #include <iostream>
45 #include <fstream>
46 #include "../Landscape/ls.h"
47 #include "../BatchALMaSS/PopulationManager.h"
48 #include "../Partridge/Partridge_Communication.h"
49 #include "../Partridge/Partridge_All.h"
50 #include "../Partridge/Partridge_Population_Manager.h"
51 #include "../Partridge/Partridge_Covey.h"
52 #include "../BatchALMaSS/BoostRandomGenerators.h"
53 
54 //---------------------------------------------------------------------------
55 
56 // *********
57 // * Covey *
58 // *********
59 
60 
62 extern double g_FoodNeed[ 200 ];
63 extern int g_MaxWalk[ 200 ];
64 //extern double g_move_veg_structure[ 4 ] [ 4 ];
66 
68 CfgFloat cfg_NOT1950sinsects("PAR_NOTFIFTIESINSECTSSCALER",CFG_CUSTOM,0.1);
70 CfgFloat cfg_parinsectScaler("PAR_INSECTSCALER",CFG_CUSTOM, 0.5);
72 CfgFloat cfg_terr_qual_good("PAR_TERR_QUAL_GOOD",CFG_CUSTOM,4.0);
74 CfgInt cfg_nest_field( "PAR_NEST_FIELD", CFG_CUSTOM, 1 );
76 CfgInt cfg_nest_roadside( "PAR_NEST_ROADSIDE", CFG_CUSTOM, 100 );
78 CfgInt cfg_nest_railway( "PAR_NEST_RAILWAY", CFG_CUSTOM, 100 );
80 CfgInt cfg_nest_fieldboundary( "PAR_NEST_FIELDBOUNDARY", CFG_CUSTOM, 200 );
82 CfgInt cfg_nest_permpastlowyield( "PAR_NEST_PERMPASTLOWYIELD", CFG_CUSTOM, 1 );
84 CfgInt cfg_nest_permpasttussocky( "PAR_NEST_PERMPASTTUSSOCKY", CFG_CUSTOM, 1 );
86 CfgInt cfg_nest_permsetaside( "PAR_NEST_PERMSETASIDE", CFG_CUSTOM, 100 );
88 CfgInt cfg_nest_naturalgrass( "PAR_NEST_NATURALGRASS", CFG_CUSTOM, 100 );
90 CfgInt cfg_nest_hedgebank0( "PAR_NEST_HEDGEBANKZERO", CFG_CUSTOM, 1 );
92 CfgInt cfg_nest_hedgebank1( "PAR_NEST_HEDGEBANKONE", CFG_CUSTOM, 100 );
94 CfgInt cfg_nest_hedgebank2( "PAR_NEST_HEDGEBANKTWO", CFG_CUSTOM, 200 );
95 
103 CfgInt g_par_terr_max_width( "PAR_TERR_MAX_WIDTH", CFG_CUSTOM, 500 );
105 CfgInt g_par_nest_min_dist_bad_areas( "PAR_NEST_MIN_DIST_BAD_AREAS", CFG_CUSTOM, 25 );
107 CfgInt g_par_nest_min_dist_other_nest( "PAR_NEST_MIN_DIST_OTHER_NEST", CFG_CUSTOM, 50 );
109 CfgInt cfg_par_parentdead_age1( "PAR_PARENTDEAD_AGEONE", CFG_CUSTOM, 35 );
111 CfgInt cfg_par_parentdead_age2( "PAR_PARENTDEAD_AGETWO", CFG_CUSTOM, 63 );
113 CfgInt cfg_par_parentdead_mort( "PAR_PARENTDEAD_MORT", CFG_CUSTOM, 100 );
114 //CfgInt cfg_par_lowqualthreshold( "PAR_LOWQUALTHRESHOLD", CFG_CUSTOM, 18 );
116 CfgInt cfg_par_highqualthreshold( "PAR_HIGHQUALTHRESHOLD", CFG_CUSTOM, 18 );
118 CfgInt cfg_par_chick_extra_mort( "PAR_CHICK_EXTRA_MORT", CFG_CUSTOM, 200 );
119 
121 CfgInt cfg_par_movequal_histlimit( "PAR_MOVEQUAL_HISTLIMIT", CFG_CUSTOM, 3 );
122 
127 CfgInt cfg_par_move_fuzzy_chance( "PAR_MOVE_FUZZY_CHANCE", CFG_CUSTOM, 50 );
128 
129 // Enter inverse values for speed!
130 /* \brief Used to calculate array indices */
131 CfgFloat cfg_par_bio_hindrance_inv( "PAR_BIO_HINDRANCE", CFG_CUSTOM, 0.00667 );
132 /* \brief Used to calculate array indices */
133 CfgFloat cfg_par_hei_hindrance_inv( "PAR_HEI_HINDRANCE", CFG_CUSTOM, 0.04 );
134 
135 
136 /* \brief Resolution of fly to testing */
146 CfgInt cfg_par_flyto_stepsize( "PAR_FLYTO_STEPSIZE", CFG_CUSTOM, 1 );
147 
148 
152 CfgBool cfg_par_force_enable( "PAR_COVEY_FORCE_ENABLE", CFG_CUSTOM, true );
153 
154 /* \brief Ignore limit */
159 CfgFloat cfg_par_force_ignore_dist_sq( "PAR_COVEY_FORCE_IGNORE_DIST_SQ", CFG_CUSTOM, 250000.0 );
160 
165 /* \brief The value below which covey force is ignored */
175 CfgFloat cfg_par_force_ignore_below( "PAR_COVEY_FORCE_IGNORE_BELOW", CFG_CUSTOM, 0.0 );
176 
177 /* \brief Covey peg pulling force */
179 CfgFloat cfg_par_force_speed( "PAR_COVEY_FORCE_SPEED", CFG_CUSTOM, 2.0 );
180 
181 /* \brief unused */
187 CfgFloat cfg_par_force_below( "PAR_COVEY_FORCE_BELOW", CFG_CUSTOM, 0.1 );
188 
189 /* \brief unused */
194 CfgFloat cfg_par_force_abs_limit( "PAR_COVEY_FORCE_ABS_LIMIT", CFG_CUSTOM, 100.0 );
195 
196 /* \brief Use peg drift? */
200 CfgBool cfg_par_covey_drift_enable( "PAR_COVEY_DRIFT_ENABLE", CFG_CUSTOM, true );
201 
206 CfgFloat cfg_par_covey_drift_speed( "PAR_COVEY_DRIFT_SPEED", CFG_CUSTOM, 2.0 );
207 
208 
209 // Stuff referenced elsewhere.
210 extern double m_move_veg_const[];
211 
212 //double m_move_veg_structure[4][4];
213 
215 CfgFloat cfg_min_merge_dist( "PAR_MIN_MERGE_DIST", CFG_CUSTOM, 50.0 );
217 CfgInt cfg_par_merging_chance( "PAR_MERGE_CHANCE", CFG_CUSTOM, 5 ); //0-100
219 CfgInt cfg_par_firstmerge( "PAR_FIRSTMERGE", CFG_CUSTOM, 150 ); //0-365
221 CfgInt cfg_par_lastmerge( "PAR_LASTMERGE", CFG_CUSTOM, 59 ); //0-365
222 
224 // Vegetation height, vegetation biomass.
225 //extern double m_move_veg_structure[4][4];
226 int m_move_list[ 8 ];
227 double m_move_dir_qual[ 8 ];
228 bool m_move_allowed[ 8 ];
229 static int m_move_select_list[ 8 ];
231 static unsigned int g_covey_id_counter = 0;
232 
233 #define TRIG_TABLE_LENGTH 8000
234 #define TRIG_TABLE_LENGTH_INV 0.00025
235 static double * g_trig_sin;
236 static double * g_trig_cos;
237 
238 #ifdef CONF_INLINES
239 inline
240 #endif
241 
245  if ( random( 10000 ) >= cfg_par_move_fuzzy_chance.value() )
246  return 0;
247 
248  if ( random( 100 ) < 50 )
249  return -1;
250 
251  return 1;
252 }
253 
254 
255 #ifdef CONF_INLINES
256 inline
257 #endif
258 
261 bool Partridge_Covey::MoveSelectLimit( int a_limit, int /* a_x */, int /* a_y */ ) {
262  bool l_found = false;
263  m_move_select_size = 0;
264 
265  int l_goto = NormInc( m_move_whence_we_came + 4, 8 );
266  int l_goto_sub = NormDec( l_goto - 1, 8 );
267  int l_goto_add = NormInc( l_goto + 1, 8 );
268 
269  if ( m_move_list[ l_goto ] == a_limit ) {
271  l_found = true;
272  }
273  if ( m_move_list[ l_goto_sub ] == a_limit ) {
274  m_move_select_list[ m_move_select_size++ ] = l_goto_sub;
275  l_found = true;
276  }
277  if ( m_move_list[ l_goto_add ] == a_limit ) {
278  m_move_select_list[ m_move_select_size++ ] = l_goto_add;
279  l_found = true;
280  }
281  if ( l_found ) {
282  return true;
283  }
284 
285  l_goto_sub = NormDec( l_goto_sub - 1, 8 );
286  l_goto_add = NormInc( l_goto_add + 1, 8 );
287  if ( m_move_list[ l_goto_sub ] == a_limit ) {
288  m_move_select_list[ m_move_select_size++ ] = l_goto_sub;
289  l_found = true;
290  }
291  if ( m_move_list[ l_goto_add ] == a_limit ) {
292  m_move_select_list[ m_move_select_size++ ] = l_goto_add;
293  l_found = true;
294  }
295  if ( l_found ) {
296  return true;
297  }
298 
299  l_goto_sub = NormDec( l_goto_sub - 1, 8 );
300  l_goto_add = NormInc( l_goto_add + 1, 8 );
301  if ( m_move_list[ l_goto_sub ] == a_limit ) {
302  m_move_select_list[ m_move_select_size++ ] = l_goto_sub;
303  l_found = true;
304  }
305  if ( m_move_list[ l_goto_add ] == a_limit ) {
306  m_move_select_list[ m_move_select_size++ ] = l_goto_add;
307  l_found = true;
308  }
309  if ( l_found ) {
310  return true;
311  }
312 
313  // None of the 7 previous directions matched our current quality
314  // limit. Consider backtracking if our previous quality history
315  // seems reasonable.
316  if ( m_move_list[ m_move_whence_we_came ] == a_limit
319  l_found = true;
320  }
321 
322  return l_found;
323 }
324 
325 
326 
327 #ifdef CONF_INLINES
328 inline
329 #endif
331  int l_rnd;
332  if ( m_move_select_size > 1 )
333  l_rnd = random( m_move_select_size ); else
334  l_rnd = 0;
335 
336 #ifdef PAR_DEBUG
337  printf( "l_rnd : %d\n", l_rnd );
338 #endif
339  return m_move_select_list[ l_rnd ];
340 }
341 
342 
343 
344 int Partridge_Covey::MoveWeighDirection( int a_x, int a_y ) {
345  int l_dir = -1;
346  bool loop=false; // This is only needed to stop compiler warnings
347  // The next section of code finds a direction with the best quality, medium then worst, then gives up if nothing
348  do { // This loop does not do anything except it prevents the MoveSelectLimit from being called unnecessarily
349  if ( MoveSelectLimit( 3, a_x, a_y ) ) {
350  l_dir = MoveSelect();
351  break;
352  }
353 
354  if ( MoveSelectLimit( 2, a_x, a_y ) ) {
355  l_dir = MoveSelect();
356  break;
357  }
358 
359  if ( MoveSelectLimit( 1, a_x, a_y ) ) {
360  l_dir = MoveSelect();
361  }
362  } while ( loop );
363 
364 #ifdef PAR_DEBUG
365  printf( "Select : %d %d %d %d %d %d %d %d :: %d\n", m_move_select_list[ 0 ], m_move_select_list[ 1 ],
368 
369 #endif
370 
371  // If we couldn't find an useful direction so far, then
372  // we just have to backtrack down the path from which we came.
373  // Do try to sidestep just a little in a random direction though.
374  if ( l_dir == -1 ) {
375  if ( random( 100 ) < 50 ) {
376  if ( m_move_list[ NormDec( m_move_whence_we_came - 1, 8 ) ] > 0 )
377  l_dir = NormDec( m_move_whence_we_came - 1, 8 ); else if ( m_move_list[ NormInc( m_move_whence_we_came + 1, 8 ) ] > 0 )
378  l_dir = NormInc( m_move_whence_we_came + 1, 8 ); else
379  l_dir = m_move_whence_we_came;
380  } else {
381  if ( m_move_list[ NormInc( m_move_whence_we_came + 1, 8 ) ] > 0 )
382  l_dir = NormInc( m_move_whence_we_came + 1, 8 ); else if ( m_move_list[ NormDec( m_move_whence_we_came - 1, 8 ) ] > 0 )
383  l_dir = NormDec( m_move_whence_we_came - 1, 8 ); else
384  l_dir = m_move_whence_we_came;
385  }
386  }
387  // Move fuzzy if allowed to do so.
388  int l_fuzzy = Norm( l_dir + MoveSelectFuzzy(), 8 );
389  if ( m_move_list[ l_fuzzy ] > 0 )
390  return l_fuzzy;
391 
392  return l_dir;
393 }
394 
395 
396 
397 void Partridge_Covey::MoveDirectionsAllowed( int a_x, int a_y ) {
398  // Finding the possible directions allowed by the location of the
399  // peg is slightly complicated, because the actual covey position
400  // may be on the other side of a map boundary.
401 
402  int l_dx = m_center_x - a_x;
403  int l_dy = m_center_y - a_y;
404 
405  if ( l_dx < 0 ) {
406  if ( -l_dx > ( m_width >> 1 ) ) {
407  l_dx += m_width;
408  }
409  } else {
410  if ( l_dx > ( m_width >> 1 ) ) {
411  l_dx -= m_width;
412  }
413  }
414 
415  if ( l_dy < 0 ) {
416  if ( -l_dy > ( m_height >> 1 ) ) {
417  l_dy += m_height;
418  }
419  } else {
420  if ( l_dy > ( m_height >> 1 ) ) {
421  l_dy -= m_height;
422  }
423  }
424 
425 #ifdef PAR_DEBUG
426  printf( "dX, dY : %d %d\n", l_dx, l_dy );
427 #endif
428 
429  // We now have l_dx and l_dy normalized wrt. to the map borders.
430  // Finding the true distance and direction to the peg is now trivial.
431  int l_dist_sq = l_dx * l_dx + l_dy * l_dy;
432 
433  if ( l_dx >= 0 ) {
434  // The peg is in 1st or 2nd quadrant as seen from the covey.
435  if ( l_dy < 0 ) {
436  // 1st quadrant. Check octant!
437  if ( -l_dy > l_dx ) {
438  // 1st octant.
439  m_move_allowed[ direction_n ] = true;
440  m_move_allowed[ direction_ne ] = true;
441  m_move_allowed[ direction_e ] = MoveTryExclude( l_dist_sq );
442  m_move_allowed[ direction_nw ] = MoveTryExclude( l_dist_sq );
447  } else {
448  // 2nd octant.
449  m_move_allowed[ direction_ne ] = true;
450  m_move_allowed[ direction_e ] = true;
451  m_move_allowed[ direction_n ] = MoveTryExclude( l_dist_sq );
452  m_move_allowed[ direction_se ] = MoveTryExclude( l_dist_sq );
457  }
458  } else {
459  // 2nd quadrant clockwise from north.
460  if ( l_dx > l_dy ) {
461  // 3rd octant.
462  m_move_allowed[ direction_e ] = true;
463  m_move_allowed[ direction_se ] = true;
464  m_move_allowed[ direction_ne ] = MoveTryExclude( l_dist_sq );
465  m_move_allowed[ direction_s ] = MoveTryExclude( l_dist_sq );
470  } else {
471  // 4th octant.
472  m_move_allowed[ direction_se ] = true;
473  m_move_allowed[ direction_s ] = true;
474  m_move_allowed[ direction_e ] = MoveTryExclude( l_dist_sq );
475  m_move_allowed[ direction_sw ] = MoveTryExclude( l_dist_sq );
480  }
481  }
482  } else {
483  // l_dx < 0
484  // The peg is in the 3rd or the 4th quadrant, clockwise from north.
485  if ( l_dy >= 0 ) {
486  // 3rd quadrant.
487  if ( l_dy > -l_dx ) {
488  // 5th octant.
489  m_move_allowed[ direction_s ] = true;
490  m_move_allowed[ direction_sw ] = true;
491  m_move_allowed[ direction_se ] = MoveTryExclude( l_dist_sq );
492  m_move_allowed[ direction_w ] = MoveTryExclude( l_dist_sq );
497  } else {
498  // 6th octant.
499  m_move_allowed[ direction_sw ] = true;
500  m_move_allowed[ direction_w ] = true;
501  m_move_allowed[ direction_s ] = MoveTryExclude( l_dist_sq );
502  m_move_allowed[ direction_nw ] = MoveTryExclude( l_dist_sq );
507  }
508  } else {
509  // l_dy < 0
510  // 4th quadrant.
511  if ( l_dx < l_dy ) {
512  // 7th octant.
513  m_move_allowed[ direction_w ] = true;
514  m_move_allowed[ direction_nw ] = true;
515  m_move_allowed[ direction_n ] = MoveTryExclude( l_dist_sq );
516  m_move_allowed[ direction_sw ] = MoveTryExclude( l_dist_sq );
521  } else {
522  // 8th octant.
523  m_move_allowed[ direction_nw ] = true;
524  m_move_allowed[ direction_n ] = true;
525  m_move_allowed[ direction_ne ] = MoveTryExclude( l_dist_sq );
526  m_move_allowed[ direction_w ] = MoveTryExclude( l_dist_sq );
531  }
532  }
533  }
534 }
535 
536 
537 
539  // Shift down the history array.
540  for ( int i = 0; i < MOVE_QUAL_HIST_SIZE - 1; i++ ) {
541  m_move_qual_hist[ 1 ] [ i ] = m_move_qual_hist[ 1 ] [ i + 1 ];
542  m_move_qual_hist[ 2 ] [ i ] = m_move_qual_hist[ 2 ] [ i + 1 ];
543  m_move_qual_hist[ 3 ] [ i ] = m_move_qual_hist[ 3 ] [ i + 1 ];
544  }
545 
546  // Zero top of history.
547  m_move_qual_hist[ 1 ] [ MOVE_QUAL_HIST_SIZE - 1 ] = 0;
548  m_move_qual_hist[ 2 ] [ MOVE_QUAL_HIST_SIZE - 1 ] = 0;
549  m_move_qual_hist[ 3 ] [ MOVE_QUAL_HIST_SIZE - 1 ] = 0;
550  m_move_qual_memory[ 1 ] = 0;
551  m_move_qual_memory[ 2 ] = 0;
552  m_move_qual_memory[ 3 ] = 0;
553 
554  // Set top of qurrent qual
555  m_move_qual_hist[ a_qual ] [ MOVE_QUAL_HIST_SIZE - 1 ] = 1;
556 
557  // Sum up the array.
558  for ( int i = 0; i < MOVE_QUAL_HIST_SIZE; i++ ) {
559  if ( m_move_qual_hist[ 1 ] [ i ] )
560  m_move_qual_memory[ 1 ] ++;
561  if ( m_move_qual_hist[ 2 ] [ i ] )
562  m_move_qual_memory[ 2 ] ++;
563  if ( m_move_qual_hist[ 3 ] [ i ] )
564  m_move_qual_memory[ 3 ] ++;
565  }
566 }
567 
568 
569 
570 void Partridge_Covey::MoveTo( int a_max_distance, int a_step_size ) {
571 
572  m_dist_moved = 0.0;
573  int l_x = m_covey_x;
574  int l_y = m_covey_y;
575 
576  if ( a_step_size != m_move_step_size ) {
577  m_move_step_size = a_step_size;
578  m_move_step_size_inv = 1.0 / ( double )a_step_size;
579  }
580 
581 /*
582  if ( m_move_get_enable ) {
583  m_move_get_index = 0;
584  m_move_get_size = 0;
585  }
586 */
587  while ( m_dist_moved < ( double )a_max_distance ) {
588 
589  // Build list of possible directions, given the location
590  // of the peg.
591  MoveDirectionsAllowed( l_x, l_y );
592 
593 #ifdef PAR_DEBUG
594  printf( "Allowed : %d %d %d %d %d %d %d %d\n", m_move_allowed[ 0 ], m_move_allowed[ 1 ], m_move_allowed[ 2 ],
596 #endif
597 
598  // Build list of movement evaluations in
599  // m_move_list[] from our present location.
600  if ( l_x - a_step_size >= 0 && l_x + a_step_size < m_width && l_y - a_step_size >= 0 && l_y + a_step_size < m_height ) {
601  MoveOptimalDirectionFast( l_x, l_y );
602  } else {
603  MoveOptimalDirectionSlow( l_x, l_y );
604  }
605 
606 #ifdef PAR_DEBUG
607  printf( "DirQual : %d %d %d %d %d %d %d %d\n", m_move_list[ 0 ], m_move_list[ 1 ], m_move_list[ 2 ], m_move_list[ 3 ],
608  m_move_list[ 4 ], m_move_list[ 5 ], m_move_list[ 6 ], m_move_list[ 7 ] );
609 #endif
610 
611  // Take peg location and possibly past history/memory into
612  // account.
613  int l_dir = MoveWeighDirection( l_x, l_y );
614  MoveQualMemory( m_move_list[ l_dir ] );
615 
616 #ifdef PAR_DEBUG
617  printf( "QualMemo: 1: %d 2: %d 3: %d\n", m_move_qual_memory[ 1 ], m_move_qual_memory[ 2 ], m_move_qual_memory[ 3 ] );
618  printf( "Selected: %d\n", l_dir );
619 #endif
620  m_move_whence_we_came = Norm( l_dir - 4, 8 );
621 
622  // We now have the direction that we want to move in l_dir.
623  m_food_today += m_move_dir_qual[ l_dir ];
624 
625  // This call also updates l_x and l_y. Nasty, nasty. ;-)
626  m_dist_moved += MoveDoIt( & l_x, & l_y, l_dir, a_step_size );
627 #ifdef PAR_DEBUG
628  //printf("Dist Sum: %f\n", m_dist_moved );
629  printf( "Coords : %d %d\n\n", l_x, l_y );
630 #endif
631 
632  // Collect movement reports.
633  /*
634  if ( m_move_get_enable ) {
635  m_move_get_size++;
636  m_move_get_x.resize( m_move_get_size );
637  m_move_get_y.resize( m_move_get_size );
638  m_move_get_x[ m_move_get_index ] = l_x;
639  m_move_get_y[ m_move_get_index ] = l_y;
640  m_move_get_index++;
641  }
642  */
643 }
644 
645  CoveyUpdateMemberPositions( l_x, l_y );
646  m_move_get_index = 0;
647  m_covey_x = l_x;
648  m_covey_y = l_y;
649  m_assess_done = false;
650 }
651 
652 void Partridge_Covey::MoveDistance( int a_max_distance, int a_step_size, double a_food_density_needed ) {
660  if ( m_move_done )
661  return;
662 
663  if ( !m_dist_done ) {
664  m_dist_done = true;
665  DistanceUpdate();
666  }
667 
668  if ( m_nest_on_nest ) {
669  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveDistance(): ", "Asked to move while on nest." );
670  exit( 1 );
671  }
672 
673  m_dist_moved = 0.0;
674  m_food_today = 0.0;
675  int l_x = m_covey_x;
676  int l_y = m_covey_y;
677 
678  if ( a_step_size != m_move_step_size ) {
679  m_move_step_size = a_step_size;
680  m_move_step_size_inv = 1.0 / ( double )a_step_size;
681  }
682 
683 /*
684  if ( m_move_get_enable ) {
685  m_move_get_index = 0;
686  m_move_get_size = 0;
687  }
688 */
689  while ( m_dist_moved < ( double )a_max_distance && m_food_today < a_food_density_needed ) {
690 
691  // Build list of possible directions, given the location
692  // of the peg.
693  MoveDirectionsAllowed( l_x, l_y );
694 
695 #ifdef PAR_DEBUG
696  printf( "Allowed : %d %d %d %d %d %d %d %d\n", m_move_allowed[ 0 ], m_move_allowed[ 1 ], m_move_allowed[ 2 ],
698 #endif
699 
700  // Build list of movement evaluations in
701  // m_move_list[] from our present location.
702  if ( l_x - a_step_size >= 0 && l_x + a_step_size < m_width && l_y - a_step_size >= 0 && l_y + a_step_size < m_height ) {
703  MoveOptimalDirectionFast( l_x, l_y );
704  } else {
705  MoveOptimalDirectionSlow( l_x, l_y );
706  }
707 
708 #ifdef PAR_DEBUG
709  printf( "DirQual : %d %d %d %d %d %d %d %d\n", m_move_list[ 0 ], m_move_list[ 1 ], m_move_list[ 2 ], m_move_list[ 3 ],
710  m_move_list[ 4 ], m_move_list[ 5 ], m_move_list[ 6 ], m_move_list[ 7 ] );
711 #endif
712 
713  // Take peg location and possibly past history/memory into
714  // account.
715  int l_dir = MoveWeighDirection( l_x, l_y );
716  MoveQualMemory( m_move_list[ l_dir ] );
717 
718 #ifdef PAR_DEBUG
719  printf( "QualMemo: 1: %d 2: %d 3: %d\n", m_move_qual_memory[ 1 ], m_move_qual_memory[ 2 ], m_move_qual_memory[ 3 ] );
720  printf( "Selected: %d\n", l_dir );
721 #endif
722  m_move_whence_we_came = Norm( l_dir - 4, 8 );
723 
724  // We now have the direction that we want to move in l_dir.
725  m_food_today += m_move_dir_qual[ l_dir ];
726 
727  // This call also updates l_x and l_y. Nasty, nasty. ;-)
728  m_dist_moved += MoveDoIt( & l_x, & l_y, l_dir, a_step_size );
729 #ifdef PAR_DEBUG
730  //printf("Dist Sum: %f\n", m_dist_moved );
731  printf( "Coords : %d %d\n\n", l_x, l_y );
732 #endif
733 
734  // Collect movement reports.
735 /*
736 if ( m_move_get_enable ) {
737  m_move_get_size++;
738  m_move_get_x.resize( m_move_get_size );
739  m_move_get_y.resize( m_move_get_size );
740  m_move_get_x[ m_move_get_index ] = l_x;
741  m_move_get_y[ m_move_get_index ] = l_y;
742  m_move_get_index++;
743  }
744 */
745  }
746 
747  CoveyUpdateMemberPositions( l_x, l_y );
748  m_move_get_index = 0;
749  m_covey_x = l_x;
750  m_covey_y = l_y;
751  m_assess_done = false;
752  m_move_done = true;
753 }
754 
755 /*
756 
757 #ifdef CONF_INLINES
758 inline
759 #endif
760 void Partridge_Covey::MoveGetEnable( bool a_state ) {
761  m_move_get_enable = a_state;
762 }
763 
764 
765 
766 int Partridge_Covey::MoveGetSteps( void ) {
767  if ( !m_move_get_enable ) {
768  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveGetSteps(): Movement data collection", " not enabled!" );
769  exit( 1 );
770  }
771 
772  return m_move_get_size;
773 }
774 
775 
776 
777 void Partridge_Covey::MoveGetPrepare( void ) {
778  if ( !m_move_get_enable ) {
779  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveGetPrepare(): Movement data collection", " not enabled!" );
780  exit( 1 );
781  }
782  m_move_get_index = 0;
783 }
784 
785 
786 
787 
788 bool Partridge_Covey::MoveGet( int * a_x, int * a_y ) {
789  if ( !m_move_get_enable ) {
790  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveGet(): Movement data collection", " not enabled!" );
791  exit( 1 );
792  }
793 
794  if ( ( unsigned int ) m_move_get_index == m_move_get_x.size() ) {
795  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveGet(): Loop length exceeded!", "" );
796  exit( 1 );
797  }
798 
799  * a_x = m_move_get_x[ m_move_get_index ];
800  * a_y = m_move_get_y[ m_move_get_index ];
801  m_move_get_index++;
802 
803  if ( ( unsigned int ) m_move_get_index == m_move_get_x.size() ) {
804  return false;
805  }
806  return true;
807 }
808 
809 */
810 
811 double Partridge_Covey::MoveDoIt( int * a_x, int * a_y, int a_dir, int a_step_size ) {
812  int l_diag_length = ( int )( ( double )a_step_size * 0.71 );
813  double l_length = ( double )a_step_size;
814 
815  switch ( a_dir ) {
816  case direction_n:
817  * a_y -= a_step_size;
818  break;
819 
820  case direction_ne:
821  * a_y -= l_diag_length;
822  * a_x += l_diag_length;
823  break;
824  case direction_e:
825  * a_x += a_step_size;
826  break;
827  case direction_se:
828  * a_y += l_diag_length;
829  * a_x += l_diag_length;
830  break;
831  case direction_s:
832  * a_y += a_step_size;
833  break;
834  case direction_sw:
835  * a_y += l_diag_length;
836  * a_x -= l_diag_length;
837  break;
838  case direction_w:
839  * a_x -= a_step_size;
840  break;
841  case direction_nw:
842  * a_y -= l_diag_length;
843  * a_x -= l_diag_length;
844  break;
845  }
846 
847  * a_x = Norm( * a_x, m_width );
848  * a_y = Norm( * a_y, m_height );
849  return l_length;
850 }
851 
852 
853 
854 #ifdef CONF_INLINES
855 inline
856 #endif
857 int Partridge_Covey::MoveCanMove( int a_x, int a_y ) {
858  return MoveCanMove( m_map->SupplyElementType( a_x, a_y ) );
859 }
860 
861 
862 
863 #ifdef CONF_INLINES
864 inline
865 #endif
866 int Partridge_Covey::Norm( int a_coord, int a_size ) {
870  while ( a_coord < 0 ) {
871  a_coord += a_size;
872  }
873  while ( a_coord >= a_size ) {
874  a_coord -= a_size;
875  }
876  return a_coord;
877 }
878 
879 #ifdef CONF_INLINES
880 inline
881 #endif
882 int Partridge_Covey::NormDec( int a_coord, int a_size ) {
886  if ( a_coord < 0 )
887  return a_coord + a_size;
888 
889  return a_coord;
890 }
891 
892 #ifdef CONF_INLINES
893 inline
894 #endif
895 int Partridge_Covey::NormInc( int a_coord, int a_size ) {
899  if ( a_coord >= a_size )
900  return a_coord - a_size;
901 
902  return a_coord;
903 }
904 
906  if ( !m_move_done ) {
907  g_msg->Warn( WARN_BUG, "Partridge_Covey::SupplyFoodToday: Move not done yet!", "" );
908  exit( 1 );
909  }
910  return m_food_today;
911 }
912 
913 
915  if ( !m_move_done ) {
916  g_msg->Warn( WARN_BUG, "Partridge_Covey::SupplyDistanceMoved: Move not done yet!", "" );
917  exit( 1 );
918  }
919  return m_dist_moved;
920 }
921 
922 
923 #ifdef CONF_INLINES
924 inline
925 #endif
926 double Partridge_Covey::HabitatEvaluateFast( int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl ) {
927  int l_poly_cache = -1;
928  double l_poly_value = 0.0;
929  double l_qual = 0.0;
930 
931  for ( int y = a_min_y_incl; y < a_max_y_excl; y++ ) {
932  for ( int x = a_min_x_incl; x < a_max_x_excl; x++ ) {
933  // l_current_element_type
935  int l_poly = m_map->SupplyPolyRef( x, y );
936  if ( l_poly != l_poly_cache ) {
937  // New polygon. Reevaluate the
938  // value of the current coordinate.
939  l_cet = m_map->SupplyElementType( x, y );
940  l_poly_value = HabitatEvalPoly( l_cet, l_poly );
941  l_poly_cache = l_poly;
942  }
943  l_qual += l_poly_value;
944  }
945  }
946  return l_qual;
947 }
948 
949 #ifdef CONF_INLINES
950 inline
951 #endif
952 double Partridge_Covey::HabitatEvaluateSlow( int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl ) {
953  int l_poly_cache = -1;
954  double l_poly_value = 0.0;
955  double l_qual = 0.0;
956 
957  ForIterator * l_fx = new ForIterator( a_min_x_incl, a_max_x_excl, 1, 0, m_width );
958  int * l_lx = l_fx->GetList();
959 
960  ForIterator * l_fy = new ForIterator( a_min_y_incl, a_max_y_excl, 1, 0, m_height );
961  int * l_ly = l_fy->GetList();
962 
963  for ( int iy = 0; iy < l_fy->GetLimit(); iy++ ) {
964  int y = l_ly[ iy ];
965  for ( int ix = 0; ix < l_fx->GetLimit(); ix++ ) {
966  int x = l_lx[ ix ];
967 
968  // l_current_element_type
970  int l_poly = m_map->SupplyPolyRef( x, y );
971  if ( l_poly != l_poly_cache ) {
972  // New polygon. Reevaluate the
973  // value of the current coordinate.
974  l_cet = m_map->SupplyElementType( x, y );
975  l_poly_value = HabitatEvalPoly( l_cet, l_poly );
976  l_poly_cache = l_poly;
977  }
978  l_qual += l_poly_value;
979  }
980  }
981  delete l_fy;
982  delete l_fx;
983  return l_qual;
984 }
985 
986 
991 double Partridge_Covey::HabitatEvaluate( int a_center_x, int a_center_y, int * a_size_used, bool a_rethink_size ) {
992  if ( !m_dist_done && a_rethink_size ) {
993  DistanceUpdate();
994  m_dist_done = true;
995  }
996  // l_width_height_half
997  int l_whh;
998  if ( a_rethink_size ) {
999  l_whh = ( ( int )m_nearest_covey_dist ) >> 1;
1000  if ( g_par_terr_max_width.value() < l_whh ) {
1001  l_whh = g_par_terr_max_width.value();
1002  } else if ( l_whh < 50 ) {
1003  l_whh = 50; // 100x100 = minimum possible size
1004  }
1005  * a_size_used = l_whh;
1006  } else {
1007  l_whh = * a_size_used;
1008  }
1009 
1010  int l_min_x_incl = a_center_x - l_whh;
1011  int l_max_x_excl = a_center_x + l_whh;
1012  int l_min_y_incl = a_center_y - l_whh;
1013  int l_max_y_excl = a_center_y + l_whh;
1014 
1015  if ( l_min_x_incl < 0 || l_max_x_excl > m_width || l_min_y_incl < 0 || l_max_y_excl > m_height ) {
1016  return HabitatEvaluateSlow( l_min_x_incl, l_max_x_excl, l_min_y_incl, l_max_y_excl );
1017  }
1018  return HabitatEvaluateFast( l_min_x_incl, l_max_x_excl, l_min_y_incl, l_max_y_excl );
1019 }
1020 
1021 
1027 double Partridge_Covey::HabitatEvaluateFaster( int a_center_x, int a_center_y ) {
1028  //This simply returns the territory value at a_center_x,a_center_y with a
1029  //radius of 50m.\n
1030  a_center_x = a_center_x / 10;
1031  a_center_y = a_center_y / 10;
1032  int l_min_x_incl = a_center_x - 5;
1033  int l_max_x_excl = a_center_x + 5;
1034  int l_min_y_incl = a_center_y - 5;
1035  int l_max_y_excl = a_center_y + 5;
1036 
1037  double qual = 0;
1038  if ((l_min_x_incl<0) || (l_min_y_incl<0) || (l_max_x_excl >= (m_width/10)) || (l_max_y_excl >= (m_height /10)) ) return 0; // ignore near the edge - speed fudge
1039  for ( int i = l_min_x_incl; i < l_min_x_incl + 5; i++ )
1040  {
1041  for ( int j = l_min_y_incl; j < l_min_y_incl + 5; j++ )
1042  {
1044  }
1045  }
1046  return qual;
1047 }
1048 
1049 
1051  if ( !m_terr_done ) {
1053  m_terr_done = true;
1054  }
1055  return m_terr_qual;
1056 }
1057 
1058 
1060  if ( !m_assess_done ) {
1062  m_assess_done = true;
1063  }
1064  a_sz = m_assess_size;
1065  return m_assess_qual;
1066 }
1067 
1070  m_assess_done = true;
1071  return m_assess_qual;
1072 }
1073 
1075  int sz = 0;
1076  if ( !m_assess_done ) {
1077  AssessHabitatQuality( sz );
1078  }
1081  m_center_x_float = ( double )m_covey_x;
1082  m_center_y_float = ( double )m_covey_y;
1083  m_terr_done = true;
1086  m_move_done = false;
1087 }
1088 
1089 
1094  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1095  m_members[ i ]->SetX( a_x );
1096  m_members[ i ]->SetY( a_y );
1097  }
1098  m_Location_x = a_x;
1099  m_Location_y = a_y;
1100 }
1101 
1102 
1103 
1108  // This algorithm can definitely be improved, time permitting!
1109  // FN, 16/6-2003.
1110 
1111  int l_whh = ( ( int )m_nearest_covey_dist ) >> 1;
1112  if ( g_par_terr_max_width.value() < l_whh ) {
1113  l_whh = g_par_terr_max_width.value();
1114  }
1115 
1116  int l_min_x_incl = m_center_x - l_whh;
1117  int l_max_x_excl = m_center_x + l_whh;
1118  int l_min_y_incl = m_center_y - l_whh;
1119  int l_max_y_excl = m_center_y + l_whh;
1120 
1121  if ( l_min_x_incl < 0 || l_max_x_excl > m_width || l_min_y_incl < 0 || l_max_y_excl > m_height ) {
1122  return NestFindSlow( l_min_x_incl, l_max_x_excl, l_min_y_incl, l_max_y_excl );
1123  }
1124 
1125  return NestFindFast( l_min_x_incl, l_max_x_excl, l_min_y_incl, l_max_y_excl );
1126 }
1127 
1128 #ifdef CONF_INLINES
1129 inline
1130 #endif
1131 bool Partridge_Covey::NestNearBadAreas( int a_x, int a_y ) {
1135  int l_min_x = a_x - g_par_nest_min_dist_bad_areas.value();
1136  int l_max_x = a_x + g_par_nest_min_dist_bad_areas.value() + 1;
1137  int l_min_y = a_y - g_par_nest_min_dist_bad_areas.value();
1138  int l_max_y = a_y + g_par_nest_min_dist_bad_areas.value() + 1;
1139 
1140  if ( l_min_x < 0 || l_max_x >= m_width || l_min_y < 0 || l_max_y >= m_height ) {
1141  return NestBadAreasScanSlow( l_min_x, l_min_y, l_max_x - l_min_x, a_x, a_y );
1142  }
1143 
1144  return NestBadAreasScanFast( l_min_x, l_min_y, l_max_x - l_min_x, a_x, a_y );
1145 }
1146 
1147 #ifdef CONF_INLINES
1148 inline
1149 #endif
1150 bool Partridge_Covey::NestBadAreasScanSlow( int a_min_x, int a_min_y, int a_length, int a_x, int a_y ) {
1151  int y_dec_base = NormInc( a_min_y + a_length, m_height );
1152 
1153  for ( int i = 0; i < a_length; i++ ) {
1154  int x_inc = Norm( a_min_x + i, m_width );
1155  int y_inc = Norm( a_min_y + i, m_height );
1156  int y_dec = Norm( y_dec_base - i, m_height );
1157  if ( NestBadArea( x_inc, y_inc ) || NestBadArea( x_inc, y_dec ) || NestBadArea( x_inc, a_y )
1158  || NestBadArea( a_x, y_inc ) ) {
1159  return true;
1160  }
1161  }
1162 
1163  return false;
1164 }
1165 
1166 
1167 #ifdef CONF_INLINES
1168 inline
1169 #endif
1170 bool Partridge_Covey::NestBadAreasScanFast( int a_min_x, int a_min_y, int a_length, int a_x, int a_y ) {
1171  for ( int i = 0; i < a_length; i++ ) {
1172  int x_inc = a_min_x + i;
1173  int y_inc = a_min_y + i;
1174  if ( NestBadArea( x_inc, y_inc ) || NestBadArea( x_inc, a_min_y + a_length - i ) || NestBadArea( x_inc, a_y )
1175  || NestBadArea( a_x, y_inc ) ) {
1176  return true;
1177  }
1178  }
1179 
1180  return false;
1181 }
1182 
1183 
1184 
1185 #ifdef CONF_INLINES
1186 inline
1187 #endif
1188 bool Partridge_Covey::NestNearNests( int a_x, int a_y, int a_min_dist_sq ) {
1189  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
1190  Partridge_Covey * l_covey = g_covey_list[ i ];
1191  // Skip coveys not on nest and ourselves.
1192  if ( !l_covey->NestOnNest() || l_covey->ID() == m_id ) {
1193  continue;
1194  }
1195  // Found covey on nest. See if this location is too close.
1196  int dx = l_covey->NestGetX() - a_x;
1197  int dy = l_covey->NestGetX() - a_y;
1198 
1199  if ( dx * dx + dy * dy < a_min_dist_sq ) {
1200  return true;
1201  }
1202  }
1203  return false;
1204 }
1205 
1206 
1207 bool Partridge_Covey::NestFindFast( int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl ) {
1208  int l_poly_cache = -1;
1210  for ( int loops = 0; loops < 10; loops++ ) {
1211  // Allows us 10 goes at finding a site
1212  for ( int x = a_min_x_incl; x < a_max_x_excl; x++ ) {
1213  for ( int y = a_min_y_incl; y < a_max_y_excl; y++ ) {
1214  int l_poly = m_map->SupplyPolyRef( x, y );
1215  if ( l_poly == l_poly_cache )
1216  continue;
1217 
1218  l_poly_cache = l_poly;
1219 
1220  if ( NestGoodSpot( x, y ) && !NestNearBadAreas( x, y ) && !NestNearNests( x, y, l_min_dist_sq ) ) {
1222  m_nest_on_nest = true;
1223  return true;
1224  }
1225  }
1226  }
1227  a_min_x_incl++;
1228  a_max_x_excl--;
1229  a_min_y_incl++;
1230  a_max_y_excl--;
1231  }
1232  return false;
1233 }
1234 
1235 
1236 bool Partridge_Covey::NestFindSlow( int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl ) {
1237  int l_poly_cache = -1;
1239 
1240  ForIterator * l_fx = new ForIterator( a_min_x_incl, a_max_x_excl, 1, 0, m_width );
1241  int * l_lx = l_fx->GetList();
1242 
1243  ForIterator * l_fy = new ForIterator( a_min_y_incl, a_max_y_excl, 1, 0, m_height );
1244  int * l_ly = l_fy->GetList();
1245  for ( int loop = 0; loop < 10; loop++ ) {
1246  for ( int iy = loop; iy < l_fy->GetLimit(); iy++ ) {
1247  int y = l_ly[ iy ];
1248  for ( int ix = loop; ix < l_fx->GetLimit(); ix++ ) {
1249  int x = l_lx[ ix ];
1250 
1251  int l_poly = m_map->SupplyPolyRef( x, y );
1252  if ( l_poly != l_poly_cache ) {
1253  l_poly_cache = l_poly;
1254 
1255  if ( NestGoodSpot( x, y ) && !NestNearBadAreas( x, y ) && !NestNearNests( x, y, l_min_dist_sq ) ) {
1257  m_nest_on_nest = true;
1258  delete l_fy;
1259  delete l_fx;
1260  return true;
1261  }
1262  }
1263  }
1264  }
1265  }
1266  delete l_fy;
1267  delete l_fx;
1268  return false;
1269 }
1270 
1272  // Returns true if the covey centre peg of any fixed covey is too close
1273  DistanceUpdate2();
1274  if ( m_nearest_covey_dist > 50 ) return false; // was 50 23/04/2008
1275  return true;
1276 }
1277 
1282  m_nearest_covey_dist = ( double )( m_width * m_height );
1283 
1284  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
1285  if ( m_id == g_covey_list[ i ]->ID() ) {
1286  continue;
1287  }
1288  if ( g_covey_list[ i ]->IsFixed() ) {
1289  double dist = DistanceToCovey( g_covey_list[ i ] );
1290  if ( dist < m_nearest_covey_dist ) {
1291  m_nearest_covey_dist = dist;
1292  }
1293  }
1294  }
1296 }
1297 
1302  m_nearest_covey_dist = ( double )( m_width * m_height );
1303 
1304  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
1305  if ( m_id == g_covey_list[ i ]->ID() ) {
1306  continue;
1307  }
1308  double dist = DistanceToCovey( g_covey_list[ i ] );
1309  if ( dist < m_nearest_covey_dist ) {
1310  m_nearest_covey_dist = dist;
1311  }
1312  }
1314 }
1315 
1316 #ifdef CONF_INLINES
1317 inline
1318 #endif
1320  double dx = m_center_x_float - a_covey->XCenterF();
1321  double dy = m_center_y_float - a_covey->YCenterF();
1322  // Divide by two becuase the maximum distance we can be away is half the world
1323  // in our wrap-around world
1324  double wf = ( double )( m_width >> 1 );
1325  double hf = ( double )( m_height >> 1 );
1326  // We need positive numbers
1327  if ( dx < 0 )
1328  dx = -dx;
1329  if ( dy < 0 )
1330  dy = -dy;
1331  // but we don't need numbers bigger than half the world
1332  if ( dx > wf )
1333  dx = m_width - dx;
1334  if ( dy > hf )
1335  dy = m_height - dy;
1336  // The next bit just makes sure that nothing goes out of whack by being too
1337  //small
1338  if ( dx < MIN_MATH_DIST_SQ ) {
1339  dx = MIN_MATH_DIST_SQ + ( double )( random( 100 ) ) / 100.0;
1340  }
1341  if ( dy < MIN_MATH_DIST_SQ ) {
1342  dy = MIN_MATH_DIST_SQ + ( double )( random( 100 ) ) / 100.0;
1343  }
1344  // Returns the squasre of the short sides or 0.0001, whichever is bigger
1345  return max( dx * dx + dy * dy, MIN_MATH_DIST_SQ );
1346 }
1347 
1348 
1349 bool Partridge_Covey::FlyToFast( int a_distance ) {
1350  // The distance we want to move as a double.
1351  double l_dist = ( double )a_distance;
1352 
1353  // Table Step size, as a double. Calculated so that
1354  // the difference in distance between points
1355  // around the perimeter of our scanning circle
1356  // are approximately 1 meter apart.
1357  // Eeewww... divisions... Avoid as far as possible.
1358  if ( a_distance != m_flyto_dist ) {
1359  m_flyto_dist = a_distance;
1360  m_flyto_steps = ( int )( floor( l_dist * TWO_PI ) );
1361  if ( cfg_par_flyto_stepsize.value() > 1 )
1363 
1364  m_flyto_ts = ( double )cfg_par_flyto_stepsize.value() * ( double )TRIG_TABLE_LENGTH / ( l_dist * TWO_PI );
1365  }
1366 
1367  // Table Step Sum. Set to random start value, corresponding
1368  // to a random angle around the circle.
1369  double l_tss = ( double )random( TRIG_TABLE_LENGTH );
1370 
1371  bool l_found = false;
1372  int l_new_x = -1;
1373  int l_new_y = -1;
1374  int l_poly_cache = -1;
1375  int l_dx_cache = -20000;
1376  int l_dy_cache = -20000;
1377 
1378  for ( int i = 0; i < m_flyto_steps; i++ ) {
1379  if ( l_tss > ( double )( TRIG_TABLE_LENGTH - 1 ) ) {
1380  l_tss = 0.000001;
1381  }
1382  int index = ( int )floor( l_tss );
1383  l_tss += m_flyto_ts;
1384 
1385  int dx = ( int )floor( l_dist * g_trig_cos[ index ] + 0.5 );
1386  int dy = ( int )floor( l_dist * g_trig_sin[ index ] + 0.5 );
1387 
1388  if ( dx == l_dx_cache && dy == l_dy_cache )
1389  continue;
1390  l_dx_cache = dx;
1391  l_dy_cache = dy;
1392  int x = m_covey_x + dx;
1393  int y = m_covey_y - dy;
1394 
1395  int l_poly = m_map->SupplyPolyRef( x, y );
1396  if ( l_poly != l_poly_cache ) {
1397  l_poly_cache = l_poly;
1398  int l_geo = MoveCanMove( m_map->SupplyElementType( l_poly ) );
1399  if ( l_geo == 1 ) {
1400  // Excellent terrain found. Stop immediately.
1401  m_center_x = x;
1402  m_center_y = y;
1403  return true;
1404  } else if ( l_geo == 0 && l_new_x == -1 ) {
1405  // Remember first acceptable location if we cannot do better.
1406  l_new_x = x;
1407  l_new_y = y;
1408  l_found = true;
1409  }
1410  }
1411  }
1412 
1413  // If we get this far, then we only might have found something
1414  // acceptable place to move, though not good.
1415  if ( l_found ) {
1416  m_center_x = l_new_x;
1417  m_center_y = l_new_y;
1418  }
1419  return l_found;
1420 }
1421 
1422 bool Partridge_Covey::FlyToSlow( int a_distance ) {
1423  double l_dist = ( double )a_distance;
1424 
1425  if ( a_distance != m_flyto_dist ) {
1426  m_flyto_dist = a_distance;
1427  m_flyto_steps = ( int )( floor( l_dist * TWO_PI ) );
1428  if ( cfg_par_flyto_stepsize.value() > 1 )
1430 
1431  m_flyto_ts = ( double )cfg_par_flyto_stepsize.value() * ( double )TRIG_TABLE_LENGTH / ( l_dist * TWO_PI );
1432  }
1433 
1434  double l_tss = ( double )random( TRIG_TABLE_LENGTH );
1435 
1436  bool l_found = false;
1437  int l_new_x = -1;
1438  int l_new_y = -1;
1439  int l_poly_cache = -1;
1440  int l_dx_cache = -20000;
1441  int l_dy_cache = -20000;
1442 
1443  for ( int i = 0; i < m_flyto_steps; i++ ) {
1444  if ( l_tss > ( double )( TRIG_TABLE_LENGTH - 1 ) ) {
1445  l_tss = 0.000001;
1446  }
1447  int index = ( int )floor( l_tss );
1448  l_tss += m_flyto_ts;
1449 
1450  int dx = ( int )floor( l_dist * g_trig_cos[ index ] + 0.5 );
1451  int dy = ( int )floor( l_dist * g_trig_sin[ index ] + 0.5 );
1452 
1453  if ( dx == l_dx_cache && dy == l_dy_cache )
1454  continue;
1455  l_dx_cache = dx;
1456  l_dy_cache = dy;
1457  int x = Norm( m_covey_x + dx, m_width );
1458  int y = Norm( m_covey_y - dy, m_height );
1459 
1460  int l_poly = m_map->SupplyPolyRef( x, y );
1461  if ( l_poly != l_poly_cache ) {
1462  l_poly_cache = l_poly;
1463  int l_geo = MoveCanMove( m_map->SupplyElementType( l_poly ) );
1464  if ( l_geo == 1 ) {
1465  m_center_x = x;
1466  m_center_y = y;
1467  return true;
1468  } else if ( l_geo == 0 && l_new_x == -1 ) {
1469  l_new_x = x;
1470  l_new_y = y;
1471  l_found = true;
1472  }
1473  }
1474  }
1475 
1476  if ( l_found ) {
1477  m_center_x = l_new_x;
1478  m_center_y = l_new_y;
1479  }
1480  return l_found;
1481 }
1482 
1483 
1484 bool Partridge_Covey::FlyTo( int a_distance ) {
1485  // New version, 4/8-2003.
1486 
1487  if ( a_distance <= 0 )
1488  return false;
1489 
1490  bool l_did_move = false;
1491 
1492  // The additional '2' is to ensure that rounding
1493  // in the calculations to follow will not cause
1494  // problems.
1495  if ( m_covey_x - a_distance - 2 >= 0 && m_covey_x + a_distance + 2 < m_width && m_covey_y - a_distance - 2 >= 0
1496  && m_covey_y + a_distance + 2 < m_height ) {
1497  l_did_move = FlyToFast( a_distance );
1498  } else {
1499  l_did_move = FlyToSlow( a_distance );
1500  }
1501 
1502  if ( l_did_move ) {
1505  m_terr_done = false;
1506  m_move_done = false;
1507  m_assess_done = false;
1508  m_dist_done = false;
1509  m_center_x_float = ( double )m_center_x;
1510  m_center_y_float = ( double )m_center_y;
1511 
1513  return true;
1514  }
1515  else return false;
1516 }
1517 
1519  Partridge_Female * l_female;
1520 #ifdef __PAR_DEBUG2
1521  if ( a_female->GetMate() ) {
1522  int rubbish = 0;
1523  }
1524 #endif
1525  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1526  if ( ( m_members[ i ]->GetFamily() != a_male->GetFamily() ) && ( m_members[ i ]->GetObjectType() == pob_Female ) ) {
1527  l_female = dynamic_cast < Partridge_Female * > ( m_members[ i ] );
1528  if ( !l_female->GetMate() ) return l_female;
1529  }
1530  }
1531  return NULL;
1532 }
1533 
1535  Partridge_Male * l_male;
1536 #ifdef __PAR_DEBUG2
1537  if ( a_male->GetMate() ) {
1538  int rubbish = 0;
1539  }
1540 #endif
1541  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1542  if ( (m_members[ i ]->GetFamily() != a_female->GetFamily()) && (m_members[ i ]->GetObjectType() == pob_Male )) {
1543  l_male = dynamic_cast < Partridge_Male * > ( m_members[ i ] );
1544  if ( !l_male->GetMate() ) return l_male;
1545  }
1546  }
1547  return NULL;
1548 }
1549 
1550 /*
1551 Partridge_Base * Partridge_Covey::GetUncle() {
1552  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1553  if ( m_members[ i ]->GetUncleStatus() ) {
1554  return m_members[ i ];
1555  }
1556  }
1557  return NULL;
1558 }
1559 */
1560 
1562  int l_dsq = a_max_distance * a_max_distance;
1563 
1564  TAnimal * l_candidate;
1565 
1567 
1568  l_candidate = m_manager->ObjectLoopFetch();
1569  while ( l_candidate ) {
1570  if ( dynamic_cast < Partridge_Base * > ( l_candidate )->GetState() == pars_FAttractingMate ) {
1571  int l_dx = m_covey_x - l_candidate->Supply_m_Location_x();
1572  int l_dy = m_covey_y - l_candidate->Supply_m_Location_y();
1573  if ( ( l_dx * l_dx + l_dy * l_dy ) < l_dsq ) {
1574  return dynamic_cast < Partridge_Female * > ( l_candidate );
1575  }
1576  }
1577  l_candidate = m_manager->ObjectLoopFetch();
1578  }
1579  return NULL;
1580 }
1581 
1582 
1584  if ( m_CurrentStateNo == -1 ) return;
1585  // Determine the movement distances and food requirements
1586  // Depends on the age of the chick
1587  //
1588  int age;
1589  // do we have any chicks?
1590  if ( GetOurChicks() > 0 ) {
1591  // if so then food requiremtns are dependent upon them
1592  age = m_ChickAge; // This set daily by the chicks
1593  }
1594  // otherwise then it is adult requirements
1596  m_maxFoodNeedToday = g_FoodNeed[ age ];
1597 
1598  if ( m_state == pars_CoveyDissolve ) {
1600  m_manager->DissolveCovey( this );
1602  m_CoveyDissolveDate = -1;
1603  }
1604  }
1605 }
1606 
1608  if ( m_StepDone ) {
1609  return;
1610  }
1611  m_StepDone = true;
1612 }
1613 
1614 
1615 
1617  if ( m_CurrentStateNo == -1 ) return;
1618  m_step_done = false;
1619  m_move_done = false;
1620  m_assess_done = false;
1621  m_terr_done = false;
1622 }
1623 
1626  SetCoveyDissolveDate( date );
1627 }
1628 
1629 
1630 /* Partridge_Male * Partridge_Covey::GetMember() { if ( m_members[ 0 ]->GetObjectType() != pob_Male ) {
1631 g_msg->Warn( WARN_BUG, "Partridge_Covey::GetMember(): ""Attempting to get a male when none are present!", "" ); exit( 1 ); }
1632 return dynamic_cast < Partridge_Male * > ( m_members[ 0 ] ); } */
1633 
1635  return m_members[ 0 ];
1636 }
1637 
1639  return m_members[ a_member ];
1640 }
1641 
1642 
1643 
1645  if ( m_CurrentStateNo == -1 ) {
1646  g_msg->Warn( WARN_BUG, "Partridge_Covey::AddMember(): ""Attempting to add a member to non-existent flock!", "" );
1647  exit( 1 );
1648  }
1649  if ( IsMember( a_new_member ) ) {
1650  g_msg->Warn( WARN_BUG, "Partridge_Covey::AddMember(): ""Attempting to add a member already belonging to the flock!", "" );
1651  exit( 1 );
1652  }
1653  if ( m_members_size>=99 ) {
1654  g_msg->Warn( WARN_BUG, "Partridge_Covey::AddMember(): ""Covey too big!", "" );
1655  exit( 1 );
1656  }
1657  //m_members.resize( m_members.size() + 1 );
1658  m_members_size++;
1659  m_members[ m_members_size - 1 ] = a_new_member;
1660 }
1661 
1662 
1663 
1665  if ( !IsMember( a_former_member ) ) {
1666  g_msg->Warn( WARN_BUG, "Partridge_Covey::RemoveMember(): "
1667  "Attempting to remove a member not belonging to the flock!", "" );
1668  exit( 1 );
1669  }
1670 
1671  if ( a_former_member == m_theDad ) {
1672  OntheDadDead();
1673  } else if ( a_former_member == m_theMum ) {
1674  OntheMumDead();
1675  }
1676 
1677  if ( m_members_size == 1 ) {
1678  g_covey_manager->DelCovey( this );
1679  // Tell the population manager to delete us.
1680  m_members_size=0;
1681  m_CurrentStateNo = -1;
1682  m_StepDone = true;
1683  return 0;
1684  }
1685 
1686  //vector<Partridge_Base*> l_members;
1687  Partridge_Base * l_members[ 100 ];
1688 
1689  unsigned int j = 0;
1690  //l_members.resize( m_members.size() - 1 );
1691 
1692  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1693  if ( m_members[ i ]->GetID() == a_former_member->GetID() ) {
1694  continue;
1695  }
1696  l_members[ j++ ] = m_members[ i ];
1697  }
1698 
1699  //m_members.resize( m_members.size() -1 );
1700  m_members_size--;
1701  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1702  m_members[ i ] = l_members[ i ];
1703  }
1704 
1705  return m_members_size;
1706 }
1707 
1708 
1709 bool Partridge_Covey::IsMember( Partridge_Base * a_possible_member ) {
1710  for ( unsigned int i = 0; i < m_members_size; i++ ) {
1711 
1712  // if ( a_possible_member->GetID() == m_members[ i ]->GetID() ) {
1713  if ( a_possible_member == m_members[ i ] ) {
1714  return true;
1715  }
1716  }
1717 
1718  return false;
1719 }
1720 
1721 #ifdef CONF_INLINES
1722 inline
1723 #endif
1724 double Partridge_Covey::Pressure( double a_distance ) {
1729  return 1.0 / max( a_distance, MIN_MATH_DIST_SQ );
1730 }
1731 
1732 
1733 
1734 #ifdef CONF_INLINES
1735 inline
1736 #endif
1737 bool Partridge_Covey::PressureLimitExceeded( double a_pressure ) {
1738  if ( a_pressure > cfg_par_force_abs_limit.value() )
1739  return true;
1740 
1741  return false;
1742 }
1743 
1744 
1747  return;
1748 
1749  double dx = ( double )m_covey_x - m_center_x_float;
1750  double dy = ( double )m_covey_y - m_center_y_float;
1751 
1752  double l_x_sign = 1.0;
1753  double l_y_sign = 1.0;
1754  double wf = ( double )( m_width >> 1 );
1755  double hf = ( double )( m_height >> 1 );
1756 
1757  if ( dx < 0.0 ) {
1758  dx = -dx;
1759  if ( dx > wf ) {
1760  dx = ( double )m_width - dx;
1761  } else {
1762  l_x_sign = -1.0;
1763  }
1764  } else {
1765  // dx > 0
1766  if ( dx > wf ) {
1767  dx = ( double )m_width - dx;
1768  l_x_sign = -1.0;
1769  }
1770  }
1771 
1772  if ( dy < 0.0 ) {
1773  dy = -dy;
1774  if ( dy > hf ) {
1775  dy = ( double )m_height - dy;
1776  } else {
1777  l_y_sign = -1.0;
1778  }
1779  } else {
1780  if ( dy > hf ) {
1781  dy = ( double )m_height - dy;
1782  l_y_sign = -1.0;
1783  }
1784  }
1785 
1786  double dsum = sqrt( dx * dx + dy * dy );
1787  if ( dsum > 0.0 ) {
1788  m_new_center_x_float += l_x_sign * cfg_par_covey_drift_speed.value() * dx / ( dsum );
1789  m_new_center_y_float += l_y_sign * cfg_par_covey_drift_speed.value() * dy / ( dsum );
1790  }
1791 }
1792 
1793 
1795  // This is called by the Tick function once a day between certain dates
1796  // for coveys that are not doing anything special and are only 1 or 2 birds
1797  // Test for merging
1798  if ( random( 100 ) >= cfg_par_merging_chance.value() ) return; // Only one chance per day
1799  unsigned int sz = unsigned(g_covey_list.size());
1800  for ( unsigned int i = 0; i < sz; i++ ) {
1801  Partridge_Covey* p_pc = g_covey_list[ i ];
1802  // Skip ourselves.
1803  if ( m_id == p_pc->ID() ) {
1804  continue;
1805  }
1806  if ( -1 == p_pc->m_CurrentStateNo ) {
1807  continue;
1808  }
1809  // Are we close to someone else?
1810  double dx = abs( m_center_x_float - p_pc->XCenterF() );
1811  double dy = abs( m_center_y_float - p_pc->YCenterF() );
1812  if ( ( dx < cfg_min_merge_dist.value() ) && ( dy < cfg_min_merge_dist.value() ) ) {
1813  // OK we feel like merging - will we be allowed to?
1814  // First find out if the target covey is full
1815  if ( p_pc->CanWeMerge( m_members_size ) ) {
1816  // Takes each member of a_covey and tells it to change covey
1817  Partridge_Base * pb;
1818  //unsigned int nu = g_covey_list[ i ]->GetCoveySize();
1819  unsigned int nu = GetCoveySize(); // are we one or two or three?
1820  for ( unsigned int k = 0; k < nu; k++ ) {
1821  pb = GetAMember();
1822  RemoveMember( pb ); //when the last is removed this covey will vanish
1823  pb->SetUncleStatus( true );
1824  pb->SetCovey( p_pc );
1825  p_pc->AddMember( pb );
1826  }
1827  return; // Done
1828  } // Not allowed to merge if we get here
1829  } // end of in-distance test
1830  } // loop each covey (this must be optimised!)
1831 }
1832 
1833 bool Partridge_Covey::CanWeMerge( int a_noOfUncles ) {
1834  // The rules are that if we have no chicks then we can have up to 8 'uncles'
1835  // Otherwise only 4 are allowed.
1836  // The answer is no if we are still busy
1837  if ( !AllFlocking() ) return false;
1838  // Otherwise it depends on the number of uncles etc.
1839  int UncleNumber = GetUncleNumber();
1840  if ( m_ourChicks > 0 ) {
1841  if ( (UncleNumber + a_noOfUncles) > 4 ) return false;
1842  }
1843  else
1844  if ( m_map->SupplyDayInYear() < June ) {
1845  if ( (UncleNumber + a_noOfUncles) > 4 ) {
1846  return false;
1847  }
1848  } else if ( (UncleNumber + a_noOfUncles) > 8 ) return false;
1849  // This code is not perfect - it would allow up to 8 Uncles after all chicks have
1850  // matured. To stop this merging to >4 is only allowed between June and Dec 31st
1851  return true;
1852 }
1853 
1854 
1856  m_force_low = false;
1859 
1861  return;
1862 
1863  double l_force_x = 0.0;
1864  double l_force_y = 0.0;
1865  double l_pressure_sum = 0.0;
1866  double wf = ( double )( m_width >> 1 );
1867  double hf = ( double )( m_height >> 1 );
1868  double l_x_sign = 1.0;
1869  double l_y_sign = 1.0;
1870 
1871  // Can anyone see this is a doubly nested for() loop?
1872  // Nah, nobody is looking... ;-)
1873  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
1874 
1875  // Skip ourselves.
1876  if ( m_id == g_covey_list[ i ]->ID() ) {
1877  continue;
1878  }
1879 
1880  double dx = m_center_x_float - g_covey_list[ i ]->XCenterF();
1881  double dy = m_center_y_float - g_covey_list[ i ]->YCenterF();
1882 
1883  if ( dx < 0.0 ) {
1884  dx = -dx;
1885  if ( dx > wf ) {
1886  dx = ( double )m_width - dx;
1887  l_x_sign = 1.0;
1888  } else {
1889  l_x_sign = -1.0;
1890  }
1891  } else {
1892  // dx > 0
1893  if ( dx > wf ) {
1894  dx = ( double )m_width - dx;
1895  l_x_sign = -1.0;
1896  } else {
1897  l_x_sign = 1.0;
1898  }
1899  }
1900 
1901  if ( dy < 0.0 ) {
1902  dy = -dy;
1903  if ( dy > hf ) {
1904  dy = ( double )m_height - dy;
1905  l_y_sign = 1.0;
1906  } else {
1907  l_y_sign = -1.0;
1908  }
1909  } else {
1910  if ( dy > hf ) {
1911  dy = ( double )m_height - dy;
1912  l_y_sign = -1.0;
1913  } else {
1914  l_y_sign = 1.0;
1915  }
1916  }
1917 
1918  if ( dx < MIN_MATH_DIST_SQ ) {
1919  dx = MIN_MATH_DIST_SQ;
1920  }
1921  if ( dy < MIN_MATH_DIST_SQ ) {
1922  dy = MIN_MATH_DIST_SQ;
1923  }
1924  double dist = max( dx * dx + dy * dy, MIN_MATH_DIST_SQ );
1925 
1926  if ( dist < cfg_par_force_ignore_dist_sq.value() ) {
1927  l_pressure_sum += Pressure( sqrt( dist ) ); // Eeewww....
1928  l_force_x += l_x_sign * dx / dist; // 'Hurt me plenty.'
1929  l_force_y += l_y_sign * dy / dist;
1930  }
1931  } // End of covey loop
1932 
1933  double l_vector_force = sqrt( l_force_x * l_force_x + l_force_y * l_force_y );
1934 
1935  if ( ( l_vector_force > g_covey_manager->Getpar_force_ignore_below() ) && ( !m_peg_is_fixed ) && ( !m_permanent_marker ) ) {
1938  }
1939 
1940  if ( l_vector_force < cfg_par_force_below.value() )
1941  m_force_low = true;
1942 
1943  m_essence_low = PressureLimitExceeded( l_pressure_sum );
1944 }
1945 
1946 
1947 
1950  return;
1951 
1952  if ( m_new_center_x_float < 0.0 )
1953  m_new_center_x_float += ( double )m_width; else if ( m_new_center_x_float > ( double )m_width - 1.0 )
1954  m_new_center_x_float -= ( double )m_width;
1955 
1956  if ( m_new_center_y_float < 0.0 )
1957  m_new_center_y_float += ( double )m_height; else if ( m_new_center_y_float > ( double )m_height - 1.0 )
1958  m_new_center_y_float -= ( double )m_height;
1959 
1962  m_center_x = ( int )m_center_x_float;
1963  m_center_y = ( int )m_center_y_float;
1964  m_terr_done = false;
1965  m_assess_done = false;
1966  m_dist_done = false;
1967 }
1968 
1969 
1970 
1972  g_covey_manager->DelCovey( this );
1973 }
1974 
1975 
1976 
1978  unsigned int a_center_x, unsigned int a_center_y, Landscape * a_map ) : TAnimal( a_center_x, a_center_y, a_map ) {
1980  m_map = a_map;
1981  m_width = a_map->SupplySimAreaWidth();
1982  m_height = a_map->SupplySimAreaHeight();
1983 
1984  m_maxAllowedMove = 1000; // default values
1985  m_maxFoodNeedToday = 10000; // default values
1986 
1987  m_manager = a_manager;
1988  m_center_x = a_center_x;
1989  m_center_y = a_center_y;
1990  m_center_x_float = ( double )m_center_x;
1991  m_center_y_float = ( double )m_center_y;
1992  m_covey_x = a_center_x;
1993  m_covey_y = a_center_y;
1994 
1995  m_nest_on_nest = false, m_nest_x = m_center_x; // Shouldn't matter.
1996  m_nest_y = m_center_y; // "
1997 
1998  m_step_done = false;
1999  m_permanent_marker = false;
2000  m_move_done = false;
2001  m_dist_moved = 0.0; // Shouldn't matter.
2002  m_food_today = 0.0; // "
2003  m_flyto_dist = -1;
2004 
2005  m_assess_done = false;
2006  //m_assess_qual = 0.0; // Shouldn't matter.
2007  m_assess_size = 0;
2008 
2009  m_terr_done = false;
2010  //m_terr_qual = 0.0; // Shouldn't matter.
2011  // Actually this matters if we start moving before
2012  // choosing a territory.
2014 
2015  m_dist_done = false;
2016  m_nearest_covey_dist = sqrt( ( double )m_width * m_height );
2017  m_peg_is_fixed = false;
2018  m_essence_low = false;
2019  m_force_low = true;
2020 
2021  //m_move_get_enable = false;
2022 
2023  /* m_members.resize( 1 ); */
2024  if ( a_first_member ) {
2025  m_members_size = 1;
2026  m_members[ 0 ] = a_first_member;
2027  } else {
2028  m_members_size = 0;
2029  }
2030 
2031  for ( int i = 0; i < MOVE_QUAL_HIST_SIZE; i++ ) {
2032  m_move_qual_hist[ 0 ] [ i ] = 0;
2033  m_move_qual_hist[ 1 ] [ i ] = 0;
2034  m_move_qual_hist[ 2 ] [ i ] = 0;
2035  m_move_qual_hist[ 3 ] [ i ] = 0;
2036  }
2037 
2038  m_move_qual_memory[ 0 ] = 0;
2039  m_move_qual_memory[ 1 ] = 0;
2040  m_move_qual_memory[ 2 ] = 0;
2041  m_move_qual_memory[ 3 ] = 0;
2042 
2043  MoveVegConstInit();
2044  CoveyUpdateMemberPositions( a_center_x, a_center_y );
2045 
2046  if ( g_covey_manager == NULL ) {
2048  }
2049  g_covey_manager->AddCovey( this );
2050 
2051  if ( a_manager )
2052  a_manager->AddObject( pob_Covey, this );
2053 
2055  m_move_whence_we_came = random( 8 );
2056  m_move_step_size = 1;
2057  m_move_step_size_inv = 1.0;
2058  m_CoveyDissolveDate = -1; // never do it
2059  m_ourChicks = 0; // don't start with chicks or parents
2060  m_theDad = NULL;
2061  m_theMum = NULL;
2062 }
2063 
2064 
2065 
2066 // ****************
2067 // * CoveyManager *
2068 // ****************
2069 
2071 
2072 CoveyManager::CoveyManager( unsigned int a_world_width, unsigned int a_world_height, Landscape * a_map ) {
2073  m_world_width = a_world_width;
2074  m_world_height = a_world_height;
2077  m_map = a_map;
2078 
2079  g_trig_sin = new double[ TRIG_TABLE_LENGTH ];
2080  g_trig_cos = new double[ TRIG_TABLE_LENGTH ];
2081 
2083 
2084 
2085  if ( !g_trig_sin || !g_trig_cos ) {
2086  g_msg->Warn( WARN_MSG, "CoveyManager::CoveyManager(): Out of memory.", "" );
2087  exit( 1 );
2088  }
2089 
2090  double l_val = 0.0;
2091  double l_step = TWO_PI / TRIG_TABLE_LENGTH;
2092  for ( int i = 0; i < TRIG_TABLE_LENGTH; i++ ) {
2093  g_trig_sin[ i ] = sin( l_val );
2094  g_trig_cos[ i ] = cos( l_val );
2095  l_val += l_step;
2096  }
2097 }
2098 
2100  delete g_trig_sin;
2101  delete g_trig_cos;
2102 }
2103 
2105  for ( PointerInt i = 0; i < (unsigned) g_covey_list.size(); i++ ) {
2106  if ( ( PointerInt )g_covey_list[ i ] < 1000 ) {
2107  g_msg->Warn( WARN_MSG, "CoveyManager::SanityCheck1(): NOT Sane", "" );
2108  exit( 0 );
2109  }
2110  }
2111 }
2112 
2115 }
2116 
2118  double product = 0;
2119  int NoBr = 0;
2120  int sz = (int)g_covey_list.size();
2121  if ( sz < 2000 ) {
2122  for ( int i = 0; i < sz; i++ ) {
2123  double chs = ( double )g_covey_list[ i ]->GetOurChicks();
2124  // only count those with chicks
2125  if ( chs > 0 ) {
2126  product += log10( chs );
2127  NoBr++;
2128  }
2129  }
2130  if ( NoBr > 0 ) {
2131  double power = 1.0 / NoBr;
2132  product *= power; // Mulitply log by the power
2133  // Antilog it
2134  double result = pow( 10, product );
2135  return result;
2136  }
2137  }
2138  return 0.0;
2139 }
2140 
2144 void CoveyManager::Tick( void ) {
2145  // Copies m_center_*_float into m_new_center_*_float.
2146  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
2147  g_covey_list[ i ]->ManagerRethinkPos();
2148  }
2149 
2150  // Adds any deltas to m_new_center_*_float.
2151  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
2152  g_covey_list[ i ]->ManagerDriftPos();
2153  }
2154 
2155  // Copies the m_new_center_*_float position back
2156  // into m_center_*_float, updating covey positions.
2157  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
2158  g_covey_list[ i ]->ManagerUpdatePos();
2159  }
2160 
2161  // This code removed to stop merging 011004 CJT (why?)
2162  // Only test for merging between certain dates
2163  //
2165  || ( m_map->SupplyDayInYear() <= cfg_par_lastmerge.value() ) ) {
2166  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
2167  if ( g_covey_list[ i ]->AllFlocking() ) {
2168  // Only singles and barren pairs are allowed to initiate merging
2169  if ( g_covey_list[ i ]->GetCoveySize() < 3 ) g_covey_list[ i ]->ManagerCheckMerge();
2170  }
2171  }
2172  }
2173 //*/
2174 }
2175 
2176 //---------------------------------------------------------------------------
2177 
2178 int CoveyManager::CoveyDensity( int x, int y, int radius ) {
2180  int tx, ty;
2181  int No = 0;
2182  int x1 = x - radius;
2183  int x2 = x + radius;
2184  int y1 = y - radius;
2185  int y2 = y + radius;
2186  // As usual this is complicated by the fact that x,y, might overlap boundries
2187  //
2188  if ( ( x - radius < 0 ) || ( x + radius >= m_world_width ) || ( y - radius < 0 ) || ( y + radius >= m_world_height ) ) {
2189  // Danger of running into the edge of the world
2190  // Also for speed and ease of calculation our radius is that of a square
2191  //
2192  for ( int i = 0; i < (int) g_covey_list.size(); i++ ) {
2193  tx = g_covey_list[ i ]->X();
2194  ty = g_covey_list[ i ]->Y();
2195  int dx = abs( x - tx );
2196  int dy = abs( y - ty );
2197  if ( dx > m_world_width_div2 ) dx = m_world_width - dx;
2198  if ( dy > m_world_height_div2 ) dy = m_world_height - dy;
2199  if ( ( tx < x2 ) && ( tx >= x1 ) && ( ty >= y1 ) && ( ty < y2 ) ) {
2200  // We have found one
2201  No++;
2202  }
2203  }
2204  } else {
2205  // Simple case, not near to the edge
2206  // Also for speed and ease of calculation our radius is that of a square
2207  //
2208  for ( int i = 0; i < (int) (g_covey_list.size()); i++ ) {
2209  tx = g_covey_list[ i ]->X();
2210  ty = g_covey_list[ i ]->Y();
2211  if ( ( tx <= x2 ) && ( tx >= x1 ) && ( ty >= y1 ) && ( ty <= y2 ) ) {
2212  // We have found one
2213  No++;
2214  }
2215  }
2216  }
2217  return No;
2218 }
2219 
2220 //---------------------------------------------------------------------------
2221 
2223  unsigned int l_newindex = (int)g_covey_list.size();
2224  g_covey_list.resize( l_newindex + 1 );
2225  g_covey_list[ l_newindex ] = a_covey;
2226 }
2227 
2228 //---------------------------------------------------------------------------
2229 
2231  unsigned int l_id = a_covey->ID();
2232 
2233  if ( a_covey->ManagerIsPermanant() ) {
2234  // Raise hell. Someone thought a permanent landscape marker
2235  // belonged to them.
2236  assert( false );
2237  }
2238 
2239  for ( unsigned int i = 0; i < g_covey_list.size(); i++ ) {
2240  if ( l_id == g_covey_list[ i ]->ID() ) {
2241  // Throw away our local pointer to the covey by
2242  // moving the rest of the elements down in the list.
2243  for ( unsigned int j = i + 1; j < g_covey_list.size(); j++ ) {
2244  g_covey_list[ j - 1 ] = g_covey_list[ j ];
2245  }
2246  g_covey_list.resize( g_covey_list.size() - 1 );
2247  return true;
2248  }
2249  }
2250 
2251  // Didn't find requested ID.
2252  return false;
2253 }
2254 //---------------------------------------------------------------------------
2255 
2256 ForIterator::ForIterator( int a_min_incl, int a_max_excl, int a_step_size, int a_norm_min_incl, int a_norm_max_excl ) {
2257  // a_min_incl or a_max_excl are goint to be <0 or > a_norm_max_excl
2258  if ( a_step_size > 1 )
2259  m_limit = ( a_max_excl - a_min_incl ) / a_step_size;
2260  else
2261  m_limit = a_max_excl - a_min_incl;
2262  m_list = new int[ m_limit ];
2263  if ( !m_list ) assert( false );
2264 
2265  int i, index = 0;
2266  // this only use if a_min_incl < a_norm_min_incl (0)
2267  for ( i = a_min_incl; i < a_norm_min_incl && index < m_limit; i += a_step_size ) {
2268  m_list[ index++ ] = i + a_norm_max_excl;
2269  }
2270  // a_norm_max_excl is typically the landscape width
2271  // a_norm_min_incl is typically 0
2272 
2273  // This loops is for the normal co-ords
2274  for ( ; i < a_norm_max_excl && index < m_limit; i += a_step_size ) {
2275  m_list[ index++ ] = i;
2276  }
2277  // if we have exceeded the upper bound then this is used
2278  for ( ; i < a_max_excl && index < m_limit; i += a_step_size ) {
2279  m_list[ index++ ] = i - a_norm_max_excl;
2280  }
2281 }
2282 //---------------------------------------------------------------------------
2283 
2285  delete m_list;
2286 }
2287 
2288 //---------------------------------------------------------------------------
2289 
2291  // If there are no neighbours then do nothing
2292  if ( m_neighbourlist_size < 1 ) return NULL;
2293  int neighbour = random( m_neighbourlist_size );
2294  /* DEBUG
2295  if ( m_neighbourlist[ neighbour ]->m_CurrentStateNo == -1 ) {
2296  int rubbish = 0;
2297  }
2298  // END DEBUG */
2299  return m_neighbourlist[ neighbour ];
2300 }
2301 
2302 //---------------------------------------------------------------------------
2303 
2305  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2306  if ( m_members[ i ]->GetObjectType() == pob_Female ) {
2307  Partridge_Female * pf = dynamic_cast < Partridge_Female * > ( m_members[ i ] );
2308  // Does she have an oldMate
2309  if ( pf->GetOldMate() ) {
2310  if ( IsMember( pf->GetOldMate() ) ) {
2311  return pf;
2312  } else {
2313  pf->RemoveOldMate(false);
2314  }
2315  }
2316  }
2317  }
2318  return NULL;
2319 }
2320 
2321 //---------------------------------------------------------------------------
2322 
2324  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2325  if ( m_members[ i ]->GetObjectType() == pob_Male ) {
2326  Partridge_Male * pm = dynamic_cast < Partridge_Male * > ( m_members[ i ] );
2327  return pm;
2328  }
2329  }
2330  return NULL;
2331 }
2332 //---------------------------------------------------------------------------
2333 
2335  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2336  if ( m_members[ i ]->GetObjectType() == pob_Female ) {
2337  Partridge_Female * pf = dynamic_cast < Partridge_Female * > ( m_members[ i ] );
2338  // Does she have an oldMate
2339  if ( pf->GetMate() == NULL ) {
2340  if ( pf->GetFamily() != a_family_counter )
2341  return pf;
2342  }
2343  }
2344  }
2345  return NULL;
2346 }
2347 
2348 //---------------------------------------------------------------------------
2349 
2351  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2352  if ( m_members[ i ]->GetObjectType() == pob_Female ) {
2353  Partridge_Female * pf = dynamic_cast < Partridge_Female * > ( m_members[ i ] );
2354  return pf;
2355  }
2356  }
2357  return NULL;
2358 }
2359 
2360 //---------------------------------------------------------------------------
2361 
2363  for ( unsigned i = 0; i < m_members_size; i++ ) {
2364  if ( ( m_members[ i ]->GetState() != pars_MFlocking ) && ( m_members[ i ]->GetState() != pars_FFlocking ) ) {
2365  return false;
2366  }
2367  }
2368  return true;
2369 }
2370 
2371 //---------------------------------------------------------------------------
2372 
2374  for ( unsigned i = 0; i < m_members_size; i++ ) {
2375  if ( ( m_members[ i ]->GetState() != pars_MFlocking ) && ( m_members[ i ]->GetState() != pars_FFlocking ) ) {
2376  return false;
2377  }
2378  }
2379  return true;
2380 }
2381 
2382 //---------------------------------------------------------------------------
2383 
2385  Partridge_Male * MP;
2386  Partridge_Female * FP;
2387  for ( unsigned i = 0; i < m_members_size; i++ ) {
2388  if ( m_members[ i ]->GetObjectType() == pob_Male ) {
2389  MP = dynamic_cast < Partridge_Male * > ( m_members[ i ] );
2390  if ( MP->GetMate() )
2391  return false;
2392  } else if ( m_members[ i ]->GetObjectType() == pob_Female ) {
2393  FP = dynamic_cast < Partridge_Female * > ( m_members[ i ] );
2394  if ( FP->GetMate() )
2395  return false;
2396  }
2397  }
2398  return true;
2399 }
2400 
2401 //---------------------------------------------------------------------------
2402 
2404  if (m_CurrentStateNo==-1) return;
2405  for ( unsigned i = 0; i < m_members_size; i++ ) {
2406  // Checks that all members have pointers to here
2407  if ( m_members[ i ]->GetCovey() != this ) {
2408  g_msg->Warn( WARN_BUG, "Partridge_Covey::SanityCheck(): ""Non-mutual pointers", "" );
2409  exit( 1 );
2410  }
2411  }
2412 }
2413 
2414 //---------------------------------------------------------------------------
2415 
2416 void Partridge_Covey::SanityCheck2( int no_chicks ) {
2417  // this one checks that the number of chicks in the covey
2418  // is the same as the number no_chicks
2419  int count = 0;
2420  for ( unsigned i = 0; i < m_members_size; i++ )
2421  if ( ( m_members[ i ]->GetObjectType() == pob_Chick ) || ( m_members[ i ]->GetObjectType() == pob_Chick2 ) ) count++;
2422  if ( count != no_chicks ) {
2423  g_msg->Warn( WARN_BUG, "Partridge_Covey::SanityCheck2(): ""wrong number of chicks", "" );
2424  exit( 1 );
2425  }
2426 }
2427 
2428 //---------------------------------------------------------------------------
2429 
2431  if ( m_move_list[ 0 ] > 7 ) {
2432  g_msg->Warn( WARN_BUG, "Partridge_Covey::SanityCheck3(): ""m_move_list illegal", "" );
2433  exit( 1 );
2434  }
2435 }
2436 
2437 //---------------------------------------------------------------------------
2438 
2440  for ( unsigned i = 0; i < m_members_size; i++ ) {
2441  // Checks that there are no clutches
2442  if ( m_members[ i ]->GetObjectType()==pob_Clutch ) {
2443  g_msg->Warn( WARN_BUG, "Partridge_Covey::SanityCheck(): ""Clutch present when it should not be!", "" );
2444  exit( 1 );
2445  }
2446  }
2447 }
2448 
2449 //---------------------------------------------------------------------------
2450 
2452  if ( ++m_ourChicks == 1 ) {
2453  m_theMum = a_pf;
2454  m_theDad = m_theMum->GetMate();
2455  }
2456 }
2457 
2458 //------------------------------------------------------------------------------
2459 
2461  if ( --m_ourChicks == 0 ) {
2462  //Tell Both Parents
2463  // The line below is really debug information, this identifies the caller
2464  m_manager->m_comms_data->m_covey = this;
2465  // Call the mother via the message centre
2469  m_theDad = NULL;
2470  m_theMum = NULL;
2471  SetFixed( false );
2472  }
2473 }
2474 
2475 //------------------------------------------------------------------------------
2476 
2478  if ( --m_ourChicks == 0 ) {
2479  //Tell Both Parents
2480  // The line below is really debug information, this identifies the caller
2481  m_manager->m_comms_data->m_covey = this;
2482  // Call the mother via the message centre
2486  m_theDad = NULL;
2487  m_theMum = NULL;
2488  SetFixed( false );
2489  }
2490 }
2491 
2492 //------------------------------------------------------------------------------
2493 
2495  //SanityCheck2(m_ourChicks );
2496  m_theMum = NULL;
2497  ActOnParentDeath();
2498 }
2499 
2500 //------------------------------------------------------------------------------
2501 
2503  //SanityCheck2(m_ourChicks );
2504  m_theDad = NULL;
2505  ActOnParentDeath();
2506 }
2507 
2508 //------------------------------------------------------------------------------
2517  int age = SupplyChickAge(); // depends on the fact that only one set of chicks
2518  if ( age >= cfg_par_parentdead_age2.value() ) return; // Old enough to cope
2519  if ( ( !m_theMum ) && ( !m_theDad ) ) {
2520  // Both parents dead - so need to look for uncles
2521  if ( GetUncleNumber() > 0 ) { // Can use an uncle or aunt
2522  SetUncle();
2523  } else
2524  KillChicks( 100 );
2525  return;
2526  }
2527  // depends on the fact that only one set of chicks
2528  // can be in the covey at any one time.
2529  if ( age < cfg_par_parentdead_age1.value() ) {
2530  KillExcessChicks( 8 ); // removes any chicks in excess of 8
2532  } else if ( age < cfg_par_parentdead_age2.value() )
2534 }
2535 
2536 //------------------------------------------------------------------------------
2541  for ( unsigned i = 0; i < m_members_size; i++ ) {
2542  if ( m_members[ i ]->GetUncleStatus() ) {
2543  if ( m_members[ i ]->GetObjectType() == pob_Male ) {
2544  m_theDad = dynamic_cast<Partridge_Male*>( m_members[ i ]);
2546  } else {
2547  m_theMum = dynamic_cast<Partridge_Female*>( m_members[ i ]);
2549  }
2550  m_members[ i ]->SetUncleStatus(false);
2551  return;
2552  }
2553  }
2554  // If we reach here there is an error
2555  g_msg->Warn( WARN_BUG, "Partridge_Covey::SetUncle(): ""Called but no uncles found", "" );
2556  exit( 1 );
2557 }
2558 //------------------------------------------------------------------------------
2559 
2561  int noUncs=0;
2562  for ( unsigned i = 0; i < m_members_size; i++ ) {
2563  if ( m_members[ i ]->GetUncleStatus() ) {
2564  noUncs++;
2565  }
2566  }
2567  return noUncs;
2568 }
2569 //------------------------------------------------------------------------------
2573 void Partridge_Covey::KillExcessChicks( int remaining ) {
2574  // Need to figure out if we need to kill any chicks
2575  if ( m_ourChicks < remaining ) return;
2576  Partridge_Chick * pc;
2577  int tokill = m_ourChicks - remaining;
2578  for ( int decimate = 0; decimate < tokill; decimate++ ) {
2579  for ( unsigned i = 0; i < m_members_size; i++ ) {
2580  if ( m_members[ i ]->GetObjectType() == pob_Chick ) {
2581  pc = dynamic_cast < Partridge_Chick * > ( m_members[ i ] );
2582  pc->OnYouAreDead();
2583  break;
2584  }
2585  }
2586  }
2587  //SanityCheck2(m_ourChicks );
2588 }
2589 
2590 //------------------------------------------------------------------------------
2591 
2595 void Partridge_Covey::KillChicks( int percent ) {
2596  //SanityCheck2(m_ourChicks );
2597  for ( int i = m_members_size - 1; i >= 0; i-- ) {
2598  if ( m_members[ i ]->GetObjectType() == pob_Chick ) {
2599  if ( random( 100 ) < percent )
2600  dynamic_cast < Partridge_Chick * > ( m_members[ i ] )->OnYouAreDead();
2601  }
2602  }
2603  //SanityCheck2(m_ourChicks );
2604 }
2605 
2606 //------------------------------------------------------------------------------
2607 
2609  // Relies on the fact that a covey can only have one set of chicks at a time
2610  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2611  if ( m_members[ i ]->GetObjectType() == pob_Chick ) {
2612  return m_members[ i ]->GetAge();
2613  }
2614  }
2615  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2616  if ( m_members[ i ]->GetObjectType() == pob_Chick2 ) {
2617  return m_members[ i ]->GetAge();
2618  }
2619  }
2620  g_msg->Warn( WARN_BUG, "Partridge_Covey::SupplyChickAge(): ""no chicks", "" );
2621  exit( 1 );
2622 }
2623 
2624 //------------------------------------------------------------------------------
2625 
2630  for ( unsigned int i = 0; i < m_members_size; i++ ) {
2631  if ( m_members[ i ]->GetObjectType() == pob_Chick ) {
2632  return true;
2633  }
2634  }
2635  return false;
2636 }
2637 //------------------------------------------------------------------------------
2638 
2643  for ( unsigned i = m_members_size; i >0; i-- ) {
2644  m_members[i-1]->Dying();
2645  }
2646  return true;
2647 }
2648 
2649 //------------------------------------------------------------------------------
2650 
2651 
2656  for ( unsigned i = m_members_size; i >0; i-- ) {
2657  if (!m_members[i-1]->ArePaired()) {
2658  if (random(10000)<cfg_IndividualEmigration.value()) {
2659  m_members[i-1]->Dying();
2660  }
2661  }
2662  }
2663 }
2664 
2665 //------------------------------------------------------------------------------
2666 
2667 
2668 
2669 
2670 
2672  for ( int i = m_members_size - 1; i >= 0; i-- ) {
2673  if ( m_members[ i ]->GetObjectType() == pob_Chick ) {
2674  if (random(10000) <cfg_par_chick_extra_mort.value()) {
2675  dynamic_cast < Partridge_Chick * > ( m_members[ i ] )->OnYouAreDead();
2676  }
2677  }
2678 }
2679 }
2680 
2681 #ifdef CONF_INLINES
2682 inline
2683 #endif
2684 int Partridge_Covey::MoveEvalEdgesAndQual( int a_edges, double a_qual ) {
2702 #ifdef MOVE_EVAL_KLUDGE
2703  if ( a_edges > 2 )
2704  return 3;
2705  if ( a_edges > 0 )
2706  return 2;
2707  return 1;
2708 
2709 #else
2710  int result = 2;
2711  double score = m_move_step_size_inv * a_qual;
2712  // if (score<cfg_par_lowqualthreshold.value())
2713  // result=1; //
2714  if ( score > cfg_par_highqualthreshold.value() )
2715  result = 3;
2716  // Result is 1 or 3 before edge evaluation
2717  // We have one special case, where food is 3 and edges are 2
2718  // correcting for this gives an even distributed result of 1,2,3
2719  if ( a_edges > 2 ) result += 3; else if ( a_edges > 0 ) {
2720  // The special case, where food is 3 and edges are 2
2721  if ( result == 3 ) result += 3; else result += 2;
2722  } else
2723  result += 1;
2724  // Result is now 2, 4 or 6
2725  result = result >> 1;
2726  return result;
2727 #endif
2728 }
2729 
2730 
2731 
2732 #ifdef CONF_INLINES
2733 inline
2734 #endif
2735 bool Partridge_Covey::MoveTryExclude( int a_dist_sq ) {
2736  // Half Radius Squared
2737  int l_hrs = ( int )m_nearest_covey_dist >> 1;
2738  l_hrs = l_hrs * l_hrs;
2739  if ( a_dist_sq < l_hrs || ( random( 100 ) < 50 ) )
2740  return true;
2741 
2742  return false;
2743 }
2744 
2745 
2746 
2747 #ifdef CONF_INLINES
2748 inline
2749 #endif
2751  // Half Radius Squared
2752  int l_hrs = ( int )m_nearest_covey_dist >> 1;
2753  l_hrs = l_hrs * l_hrs;
2754  if ( a_dist_sq < l_hrs )
2755  return true;
2756 
2757  if ( a_dist_sq < l_hrs * 1.6 && random( 100 ) < 10 )
2758  return true;
2759 
2760  return false;
2761 }
2762 
2763 
2764 
2765 
2766 #ifdef CONF_INLINES
2767 inline
2768 #endif
2770  int st;
2771  switch ( a_cet ) {
2772 
2773  // Terrible stuff
2774  case tole_IndividualTree:
2775  case tole_PlantNursery:
2776  case tole_WindTurbine:
2777  case tole_WoodyEnergyCrop:
2778  case tole_WoodlandMargin:
2779  case tole_Pylon:
2780  case tole_DeciduousForest:
2781  case tole_MixedForest:
2782  case tole_ConiferousForest:
2783  case tole_Building:
2784  case tole_UrbanNoVeg:
2785  case tole_AmenityGrass:
2786  return -2.0;
2787 
2788  // Bad stuff.
2789  case tole_MetalledPath:
2790  case tole_Carpark:
2791  case tole_Churchyard:
2792  case tole_Saltmarsh:
2793  case tole_Stream:
2794  case tole_HeritageSite:
2795  case tole_RiversidePlants:
2796  case tole_RiversideTrees:
2797  case tole_Garden:
2798  case tole_Track:
2799  case tole_SmallRoad:
2800  case tole_LargeRoad:
2801  case tole_ActivePit:
2802  case tole_Pond:
2803  case tole_Freshwater:
2804  case tole_River:
2805  case tole_Saltwater:
2806  case tole_Coast:
2807  case tole_BareRock:
2808  case tole_Parkland:
2809  case tole_UrbanPark:
2811  case tole_SandDune:
2812  case tole_Copse:
2813  return -1.0;
2814 
2815  // Questionable.
2816  case tole_NaturalGrassWet:
2817  case tole_StoneWall:
2818  case tole_Fence:
2819  case tole_Hedges:
2820  case tole_Marsh:
2821  case tole_PitDisused:
2822  case tole_OrchardBand:
2823  return 0.0;
2824 
2825  // OK stuff
2826  case tole_RoadsideSlope:
2827  case tole_PermPasture:
2829  return 2.0;
2830  // Good Stuff
2832  case tole_RoadsideVerge:
2833  case tole_Railway:
2834  case tole_FieldBoundary:
2836  case tole_NaturalGrassDry:
2837  case tole_YoungForest: // ?
2838  case tole_Heath:
2839  case tole_Orchard:
2840  case tole_MownGrass:
2841  case tole_Scrub:
2842  case tole_Vildtager:
2843  return cfg_terr_qual_good.value();
2844 
2845  // Really good stuff!
2846  case tole_BeetleBank:
2847  return (double) cfg_nest_hedgebank1.value();
2848  case tole_HedgeBank:
2849  st = m_OurLandscape->SupplyElementSubType( a_cet );
2850  switch ( st ) {
2851  case 0:
2852  return (double) cfg_nest_hedgebank0.value();
2853  case 1:
2854  return (double) cfg_nest_hedgebank1.value();
2855  case 2:
2856  return (double) cfg_nest_hedgebank2.value();
2857  default:
2858  return 100;
2859  }
2860  // Variable, depending on vegetation and condition of same.
2861  case tole_Field:
2863  return (double) HabitatEvalPolyField( a_poly );
2864 
2865  default:
2866  g_msg->Warn( WARN_BUG, "Partridge_Covey::TerrEvalPoly(): Unknown tole type", "" );
2867  exit( 1 );
2868  }
2869 }
2870 
2871 
2872 
2873 #ifdef CONF_INLINES
2874 inline
2875 #endif
2876 bool Partridge_Covey::NestGoodSpot( int a_x, int a_y ) {
2880  TTypesOfLandscapeElement l_cet = m_map->SupplyElementType( a_x, a_y );
2881  int score, st;
2882  switch ( l_cet ) {
2883  case tole_Field:
2884  score = cfg_nest_field.value();
2885  // Need to add something about patchy and tramlines
2886  // TO SIMULATE 1950s SITUATION WITH ALL ACCESS GRANTED
2887 #ifndef __P1950s
2888  if (m_map->SupplyVegPatchy( a_x, a_y )) score*=4; // doubled for patchy
2889  //else if (m_map->SupplyHasTramlines( a_x, a_y )) score*=2; // doubled for tramlines
2890 #else
2891  score *=4;
2892 #endif
2893  break;
2894  case tole_RoadsideVerge:
2895  score = cfg_nest_roadside.value();
2896  break;
2897  case tole_Railway:
2898  score = cfg_nest_railway.value();
2899  break;
2900  case tole_FieldBoundary:
2901  score = cfg_nest_fieldboundary.value();
2902  break;
2904  score = cfg_nest_permpastlowyield.value();
2905  break;
2907  score = cfg_nest_permpasttussocky.value();
2908  break;
2910  score = cfg_nest_permsetaside.value();
2911  break;
2912  case tole_Heath:
2913  case tole_NaturalGrassDry:
2914  score = cfg_nest_naturalgrass.value();
2915  break;
2916  case tole_BeetleBank:
2917  score = cfg_nest_hedgebank1.value();
2918  break;
2919  case tole_HedgeBank:
2920  st = m_OurLandscape->SupplyElementSubType( a_x, a_y );
2921  switch ( st ) {
2922  case 0:
2923  score = cfg_nest_hedgebank0.value();
2924  break;
2925  case 1:
2926  score = cfg_nest_hedgebank1.value();
2927  break;
2928  case 2:
2929  score = cfg_nest_hedgebank2.value();
2930  break;
2931  default:
2932  score = 100;
2933  }
2934  break;
2935  default:
2936  return false;
2937  }
2938  if ( score > random( 1000 ) ) return true;
2939  return false;
2940 }
2941 
2942 
2943 
2944 #ifdef CONF_INLINES
2945 inline
2946 #endif
2947 bool Partridge_Covey::NestBadArea( int a_x, int a_y ) {
2948  TTypesOfLandscapeElement l_cet = m_map->SupplyElementType( a_x, a_y );
2949 
2950  switch ( l_cet ) {
2951  case tole_PermPasture:
2952  case tole_Scrub:
2953  case tole_RiversidePlants:
2954  case tole_RiversideTrees:
2955  case tole_DeciduousForest:
2956  case tole_MixedForest:
2957  case tole_ConiferousForest:
2958  case tole_StoneWall:
2959  case tole_Fence:
2960  case tole_Track:
2961  case tole_SmallRoad:
2962  case tole_LargeRoad:
2963  case tole_ActivePit:
2964  case tole_Hedges:
2965  case tole_Marsh:
2966  case tole_PitDisused:
2967  case tole_RoadsideVerge:
2968  case tole_Railway:
2969  case tole_FieldBoundary:
2973  case tole_NaturalGrassDry:
2974  case tole_Heath:
2975  case tole_Orchard:
2976  case tole_YoungForest:
2977  case tole_HedgeBank:
2978  case tole_BeetleBank:
2980  case tole_Field:
2981  case tole_OrchardBand:
2982  case tole_MownGrass:
2983  case tole_NaturalGrassWet:
2984  case tole_RoadsideSlope:
2985  case tole_Vildtager:
2986  return false;
2987 
2988  case tole_MetalledPath:
2989  case tole_Carpark:
2990  case tole_Churchyard:
2991  case tole_Saltmarsh:
2992  case tole_Stream:
2993  case tole_HeritageSite:
2994  case tole_Garden:
2995  case tole_Building:
2996  case tole_Pond:
2997  case tole_Freshwater:
2998  case tole_River:
2999  case tole_Saltwater:
3000  case tole_Coast:
3001  case tole_BareRock:
3002  case tole_AmenityGrass:
3003  case tole_Parkland:
3004  case tole_UrbanNoVeg:
3005  case tole_UrbanPark:
3007  case tole_SandDune:
3008  case tole_Copse:
3009  case tole_IndividualTree:
3010  case tole_PlantNursery:
3011  case tole_WindTurbine:
3012  case tole_WoodyEnergyCrop:
3013  case tole_WoodlandMargin:
3014  case tole_Pylon:
3015  return true;
3016 
3017  default:
3018  g_msg->Warn( WARN_BUG, "Partridge_Covey::NestBadArea(): Unknown tole type", "" );
3019  exit( 1 );
3020  }
3021 }
3022 
3023 
3024 
3025 #ifdef CONF_INLINES
3026 inline
3027 #endif
3029 
3030  TTypesOfVegetation l_tov = m_map->SupplyVegType( a_field );
3031  int score;
3032  switch ( l_tov ) {
3033  case tov_OFirstYearDanger:
3034  case tov_OGrazingPigs:
3038  score = 0;
3039  break;
3040 
3041  case tov_Carrots:
3042  case tov_FieldPeas:
3043  case tov_FodderBeet:
3044  case tov_SugarBeet:
3045  case tov_OFodderBeet:
3046  case tov_Maize:
3047  case tov_MaizeSilage:
3048  case tov_OMaizeSilage:
3049  case tov_NoGrowth:
3050  case tov_None:
3051  case tov_OPotatoes:
3052  case tov_WinterRape:
3053  case tov_Potatoes:
3054  case tov_PotatoesIndustry:
3055  score = 1;
3056  break;
3057 
3059  case tov_PermanentSetaside:
3060  case tov_FodderGrass:
3063  case tov_Oats:
3064  case tov_OOats:
3065  case tov_OSeedGrass1:
3066  case tov_OSeedGrass2:
3067  case tov_OSpringBarley:
3068  case tov_OSpringBarleyExt:
3071  case tov_OSpringBarleyPigs:
3072  case tov_OTriticale:
3073  case tov_OWinterBarley:
3074  case tov_OWinterBarleyExt:
3075  case tov_OWinterRape:
3076  case tov_OWinterRye:
3078  case tov_OWinterWheat:
3079  case tov_SeedGrass1:
3080  case tov_SeedGrass2:
3081  case tov_SpringBarley:
3082  case tov_SpringBarleySpr:
3086  case tov_SpringBarleyGrass:
3087  case tov_SpringBarleySeed:
3089  case tov_SpringRape:
3090  case tov_SpringWheat:
3091  case tov_Triticale:
3092  case tov_WinterBarley:
3093  case tov_WinterRye:
3094  case tov_WinterWheat:
3095  case tov_WWheatPControl:
3097  case tov_WWheatPTreatment:
3099  case tov_WinterWheatShort:
3103  case tov_OSBarleySilage:
3104  case tov_OCarrots:
3106  case tov_OFieldPeas:
3107  case tov_OFieldPeasSilage:
3108  case tov_YoungForest:
3109  case tov_Heath:
3110  case tov_BroadBeans:
3111 
3112  score = 2;
3113  break;
3114 
3115  /* case tov_OGrassClover1: case tov_OGrassClover2: case tov_OBarleyPeaCloverGrass: case tov_OCarrots:
3116  case tov_OCloverGrassGrazed1: case tov_OCloverGrassGrazed2: case tov_OCloverGrassSilage1: case tov_OFieldPeas:
3117  case tov_OPermanentGrassGrazed: case tov_PermanentGrassGrazed: case tov_PermanentGrassTussocky: return 3.0; */
3118 
3119  case tov_Setaside:
3120  case tov_NaturalGrass:
3121  case tov_OSetaside:
3122  score = 4;
3123  break;
3124 
3125  case tov_Undefined:
3126  default:
3127  return 0;
3128  }
3129  return score;
3130 }
3131 
3132 
3133 
3134  // The next five lines were included in MoveMagicVegToFood when it was thought that the type of
3135  // habitat might need to influence food collection
3136  // TTypesOfVegetation tovt = m_map->SupplyVegType( a_polygon );
3137  // double l_magic = m_move_veg_const[ tovt ] * m_map->SupplyInsects( a_polygon );
3138  // TTypesOfLandscapeElement typ = m_map->SupplyElementType( a_polygon );
3139  // if (typ==tole_HedgeBank) l_magic=l_magic*2.0;
3140 #ifdef CONF_INLINES
3141 inline
3142 #endif
3143 
3147 double Partridge_Covey::MoveMagicVegToFood( int a_polygon ) {
3148  double l_magic = m_map->SupplyInsects( a_polygon ) * cfg_parinsectScaler.value();
3149 #ifdef __P1950s
3150  // ***CJT***
3151  // Problem was that 1950s were calibrated with cfg_1950sinsects set to 1.0
3152  // we have therefore to scale the insects values we get for non-1950s to be lower somehow - preferably without making it run slow
3153  // Line removed
3154 #else
3155 
3161  //if ( (!m_map->SupplyVegPatchy(a_polygon)) || (Type == tole_Field || Type == tole_PermPastureTussocky || Type == tole_PermPasture || Type == tole_PermanentSetaside || Type == tole_PermPastureLowYield)) {
3162  if ((!m_map->SupplyVegPatchy(a_polygon)) ) {
3163  if ((Type == tole_Field || Type == tole_PermPastureTussocky || Type == tole_PermPasture || Type == tole_PermanentSetaside || Type == tole_PermPastureLowYield)) { l_magic*=(cfg_NOT1950sinsects.value());
3164  if (m_map->SupplyHasTramlines( a_polygon )) l_magic*=1.5; // extra for tramlines
3165  }
3166  } // otherwise we assume it is like the 1950s
3167 #endif
3168  /* **CJT** 20/7/2010
3169  double height = m_map->SupplyVegHeight( a_polygon );
3170  int l_height_bin = ( int )( height * cfg_par_hei_hindrance_inv.value() );
3171  if ( l_height_bin > 3 ) l_height_bin = 3;
3172  */
3173  // *** CJT *** 1 July 2010 Code below relies on biomass - but this is skylark based code and should be altered to
3174  // density. At the same time some alteration of the height response was required - hence change to HB_Impedence.txt
3175  /*
3176  double bio = m_map->SupplyVegBiomass( a_polygon );
3177  int l_biomass_bin = ( int )( bio * cfg_par_bio_hindrance_inv.value() );;
3178  if ( l_biomass_bin > 3 ) l_biomass_bin = 3;
3179  return l_magic * g_move_veg_structure[ l_height_bin ] [ l_biomass_bin ];
3180 
3181  /*/
3182  /*
3183  double dens = m_map->SupplyVegDensity( a_polygon );
3184  int l_density_bin = ( int )( dens * cfg_par_bio_hindrance_inv.value() );;
3185  if ( l_density_bin > 3 ) l_density_bin = 3;
3186  return l_magic * g_move_veg_structure[ l_height_bin ] [ l_density_bin ];
3187  */
3188  // This section calculates the hindrance based on linear interpolation after the first height category
3189  // The slope (0.25) is scaled by cfg_par_hei_hindrance_inv and cfg_par_bio_hindrance_inv
3190  double height = m_map->SupplyVegHeight( a_polygon );
3191  double l_height_bin = ( height * cfg_par_hei_hindrance_inv.value() ) - 1.0;
3192  if (l_height_bin < 0.0 ) return l_magic; // So short there is no hindrance
3193  double dens = m_map->SupplyVegDensity( a_polygon );
3194  double l_density_bin = ( dens * cfg_par_bio_hindrance_inv.value() );
3195  // We need to restrict the upper end to avoid one factor outweighing the other e.g. if density is very high but height is only just >0.0
3196  if (l_density_bin > 4.0 ) l_density_bin = 4.0;
3197  if (l_height_bin > 4.0 ) l_height_bin = 4.0;
3198  double l_intermediate = 1.0 -(( l_density_bin + l_height_bin - 2.0 ) * 0.25);
3199  if (l_intermediate <0.0) return 0.0;
3200  if (l_intermediate >= 1.0) return l_magic;
3201  return l_magic * l_intermediate;
3202 
3203 }
3204 
3205 
3206 
3207 // Returns -1: Cannot move here.
3208 // 0: OK to go here.
3209 // 1: Exceptionally favorable terrain (for detecting
3210 // hedges etc.)
3211 //
3212 // Are areas like tole_LargeRoad really acceptable here? The coveys will
3213 // move onto highway crossings etc. if they are. -- Frank.
3214 //
3215 #ifdef CONF_INLINES
3216 inline
3217 #endif
3218 
3222  switch ( a_ele ) {
3223  case tole_StoneWall:
3224  case tole_Fence:
3225  case tole_Garden:
3226  case tole_Building:
3227  case tole_Pond:
3228  case tole_Freshwater:
3229  case tole_River:
3230  case tole_Saltwater:
3231  case tole_Coast:
3232  case tole_Churchyard:
3233  case tole_Stream:
3234  return -1;
3235 
3236  case tole_IndividualTree:
3237  case tole_PlantNursery:
3238  case tole_WindTurbine:
3239  case tole_WoodyEnergyCrop:
3240  case tole_WoodlandMargin:
3241  case tole_Pylon:
3242  case tole_PermPasture:
3243  case tole_Scrub:
3244  case tole_RiversidePlants:
3245  case tole_RiversideTrees:
3246  case tole_DeciduousForest:
3247  case tole_MixedForest:
3248  case tole_ConiferousForest:
3249  case tole_Marsh:
3250  case tole_PitDisused:
3251  case tole_Track:
3252  case tole_SmallRoad:
3253  case tole_LargeRoad:
3254  case tole_ActivePit:
3255  case tole_Hedges:
3256  case tole_Railway:
3257  case tole_Field:
3262  case tole_YoungForest:
3263  case tole_NaturalGrassDry:
3264  case tole_Heath:
3265  case tole_OrchardBand:
3266  case tole_MownGrass:
3267  case tole_Orchard:
3268  case tole_BareRock:
3269  case tole_AmenityGrass:
3270  case tole_Parkland:
3271  case tole_UrbanNoVeg:
3272  case tole_UrbanPark:
3274  case tole_SandDune:
3275  case tole_Copse:
3276  case tole_NaturalGrassWet:
3277  case tole_RoadsideSlope:
3278  case tole_MetalledPath:
3279  case tole_Carpark:
3280  case tole_Saltmarsh:
3281  case tole_HeritageSite:
3282  return 0;
3283 
3284  case tole_RoadsideVerge:
3285  case tole_FieldBoundary:
3286  case tole_HedgeBank:
3287  case tole_BeetleBank:
3288  case tole_Vildtager:
3289  return 1;
3290 
3291  default:
3292  g_msg->Warn( WARN_BUG, "Partridge_Covey::MoveCanMove(): Unknown tole type", "" );
3293  exit( 1 );
3294  break;
3295  }
3296 }
3297 
3298 
3299 static bool m_move_veg_const_init_done = false;
3300 
3306  return;
3308 
3318  m_move_veg_const[tov_Maize] = 1.0;
3322  m_move_veg_const[tov_None] = 1.0;
3323  m_move_veg_const[tov_Oats] = 1.0;
3324 
3325  // 10
3338 
3339  // 20
3340  m_move_veg_const[tov_OOats] = 1.0;
3350 
3351  // 30
3364 
3365  // 40
3377 
3378  // 50
3394  m_move_veg_const[tov_Heath] = 1.0;
3395 
3396  // Must be here. tov_Undefined is returned by polygons
3397  // without growth.
3399 }
3400 
3401 
3402 
3403 
3414  // The number of steps for a diagonal move is less than step size
3415  // by 1/sqrt(2), as each step is sqrt(2) meters long.
3416  int l_diag_length = ( int )( ( double )m_move_step_size * 0.71 );
3417 
3418  double l_quality = 0.0;
3419  double l_qual_cache = 0.0;
3420  int l_fantastic = 0;
3421  int l_poly_cache = -1;
3422  int l_geo_cache = 0;
3423 
3424  // Current pos to the north (decreasing y).
3425 
3426  // Use current spot in movement list as a temporary flag.
3428 
3429  // Notice: y is allowed to grow negative, this is OK!
3430  // We normalize to the height of the map before using it.
3431  if ( m_move_allowed[ direction_n ] ) {
3432  for ( int y = a_y - 1; y >= a_y - m_move_step_size; y-- ) {
3433  int l_poly = m_map->SupplyPolyRef( a_x, NormDec( y, m_height ) );
3434  if ( l_poly != l_poly_cache ) {
3435  // Crossed into new polygon. Compute new values for
3436  // cache etc.
3437  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3438  if ( l_geo_cache == -1 ) {
3439  // This direction is blocked.
3440  m_move_list[ direction_n ] = 0;
3441  break;
3442  }
3443  l_poly_cache = l_poly;
3444  l_qual_cache = MoveMagicVegToFood( l_poly );
3445  }
3446  }
3447  // Sum up number of especially good edge squares.
3448  l_fantastic += l_geo_cache;
3449  // Sum up food quality.
3450  l_quality += l_qual_cache;
3451  }
3452  m_move_dir_qual[ direction_n ] = l_quality;
3453  if ( m_move_list[ direction_n ] ) {
3454  // This direction isn't blocked, so evaluate and assign
3455  // priority in movement list.
3456  m_move_list[ direction_n ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3457  }
3458 
3459  // Northeast.
3460  l_quality = 0.0;
3461  l_fantastic = 0;
3463  l_qual_cache = 0.0;
3464  l_poly_cache = -1;
3465 
3466  if ( m_move_allowed[ direction_ne ] ) {
3467  for ( int y = a_y - 1, x = a_x + 1; y >= a_y - l_diag_length; y--, x++ ) {
3468  int l_poly = m_map->SupplyPolyRef( NormInc( x, m_width ), NormDec( y, m_height ) );
3469  if ( l_poly != l_poly_cache ) {
3470  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3471  if ( l_geo_cache == -1 ) {
3472  m_move_list[ direction_ne ] = 0;
3473  break;
3474  }
3475  l_poly_cache = l_poly;
3476  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3477  }
3478  l_fantastic += l_geo_cache;
3479  l_quality += l_qual_cache;
3480  }
3481  }
3482  m_move_dir_qual[ direction_ne ] = l_quality;
3483  if ( m_move_list[ direction_ne ] ) {
3484  m_move_list[ direction_ne ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3485  }
3486 
3487  // East.
3488  l_quality = 0.0;
3489  l_fantastic = 0;
3491  l_qual_cache = 0.0;
3492  l_poly_cache = -1;
3493 
3494  if ( m_move_allowed[ direction_e ] ) {
3495  for ( int x = a_x + 1; x <= a_x + m_move_step_size; x++ ) {
3496  int l_poly = m_map->SupplyPolyRef( NormInc( x, m_width ), a_y );
3497  if ( l_poly != l_poly_cache ) {
3498  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3499  if ( l_geo_cache == -1 ) {
3500  m_move_list[ direction_e ] = 0;
3501  break;
3502  }
3503  l_poly_cache = l_poly;
3504  l_qual_cache = MoveMagicVegToFood( l_poly );
3505  }
3506  l_fantastic += l_geo_cache;
3507  l_quality += l_qual_cache;
3508  }
3509  }
3510  m_move_dir_qual[ direction_e ] = l_quality;
3511  if ( m_move_list[ direction_e ] ) {
3512  m_move_list[ direction_e ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3513  }
3514 
3515  // Southeast.
3516  l_quality = 0.0;
3517  l_fantastic = 0;
3519  l_qual_cache = 0.0;
3520  l_poly_cache = -1;
3521 
3522  if ( m_move_allowed[ direction_se ] ) {
3523  for ( int x = a_x + 1, y = a_y + 1; x <= a_x + l_diag_length; x++, y++ ) {
3524  int l_poly = m_map->SupplyPolyRef( NormInc( x, m_width ), NormInc( y, m_height ) );
3525  if ( l_poly != l_poly_cache ) {
3526  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3527  if ( l_geo_cache == -1 ) {
3528  m_move_list[ direction_se ] = 0;
3529  break;
3530  }
3531  l_poly_cache = l_poly;
3532  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3533  }
3534  l_fantastic += l_geo_cache;
3535  l_quality += l_qual_cache;
3536  }
3537  }
3538  m_move_dir_qual[ direction_se ] = l_quality;
3539  if ( m_move_list[ direction_se ] ) {
3540  m_move_list[ direction_se ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3541  }
3542 
3543  // South.
3544  l_quality = 0.0;
3545  l_fantastic = 0;
3546  l_qual_cache = 0.0;
3547  l_poly_cache = -1;
3549 
3550  if ( m_move_allowed[ direction_s ] ) {
3551  for ( int y = a_y + 1; y <= a_y + m_move_step_size; y++ ) {
3552  int l_poly = m_map->SupplyPolyRef( a_x, NormInc( y, m_height ) );
3553  if ( l_poly != l_poly_cache ) {
3554  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3555  if ( l_geo_cache == -1 ) {
3556  m_move_list[ direction_s ] = 0;
3557  break;
3558  }
3559  l_poly_cache = l_poly;
3560  l_qual_cache = MoveMagicVegToFood( l_poly );
3561  }
3562  l_fantastic += l_geo_cache;
3563  l_quality += l_qual_cache;
3564  }
3565  }
3566  m_move_dir_qual[ direction_s ] = l_quality;
3567  if ( m_move_list[ direction_s ] ) {
3568  m_move_list[ direction_s ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3569  }
3570 
3571  // Southwest.
3572  l_quality = 0.0;
3573  l_fantastic = 0;
3575  l_qual_cache = 0.0;
3576  l_poly_cache = -1;
3577 
3578  if ( m_move_allowed[ direction_sw ] ) {
3579  for ( int x = a_x - 1, y = a_y + 1; x >= a_x - l_diag_length; x--, y++ ) {
3580  int l_poly = m_map->SupplyPolyRef( NormDec( x, m_width ), NormInc( y, m_height ) );
3581  if ( l_poly != l_poly_cache ) {
3582  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3583  if ( l_geo_cache == -1 ) {
3584  m_move_list[ direction_sw ] = 0;
3585  break;
3586  }
3587  l_poly_cache = l_poly;
3588  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3589  }
3590  l_fantastic += l_geo_cache;
3591  l_quality += l_qual_cache;
3592  }
3593  }
3594  m_move_dir_qual[ direction_sw ] = l_quality;
3595  if ( m_move_list[ direction_sw ] ) {
3596  m_move_list[ direction_sw ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3597  }
3598 
3599  // West.
3600  l_quality = 0.0;
3601  l_fantastic = 0;
3603  l_qual_cache = 0.0;
3604  l_poly_cache = -1;
3605 
3606  if ( m_move_allowed[ direction_w ] ) {
3607  for ( int x = a_x - 1; x >= a_x - m_move_step_size; x-- ) {
3608  int l_poly = m_map->SupplyPolyRef( NormDec( x, m_width ), a_y );
3609  if ( l_poly != l_poly_cache ) {
3610  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3611  if ( l_geo_cache == -1 ) {
3612  m_move_list[ direction_w ] = 0;
3613  break;
3614  }
3615  l_poly_cache = l_poly;
3616  l_qual_cache = MoveMagicVegToFood( l_poly );
3617  }
3618  l_fantastic += l_geo_cache;
3619  l_quality += l_qual_cache;
3620  }
3621  }
3622  m_move_dir_qual[ direction_w ] = l_quality;
3623  if ( m_move_list[ direction_w ] ) {
3624  m_move_list[ direction_w ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3625  }
3626 
3627  // Northwest.
3628  l_quality = 0.0;
3629  l_fantastic = 0;
3631  l_qual_cache = 0.0;
3632  l_poly_cache = -1;
3633 
3634  if ( m_move_allowed[ direction_nw ] ) {
3635  for ( int y = a_y - 1, x = a_x - 1; y >= a_y - l_diag_length; y--, x-- ) {
3636  int l_poly = m_map->SupplyPolyRef( NormDec( x, m_width ), NormDec( y, m_height ) );
3637  if ( l_poly != l_poly_cache ) {
3638  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3639  if ( l_geo_cache == -1 ) {
3640  m_move_list[ direction_nw ] = 0;
3641  break;
3642  }
3643  l_poly_cache = l_poly;
3644  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3645  }
3646  l_fantastic += l_geo_cache;
3647  l_quality += l_qual_cache;
3648  }
3649  }
3650  m_move_dir_qual[ direction_nw ] = l_quality;
3651  if ( m_move_list[ direction_nw ] ) {
3652  m_move_list[ direction_nw ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3653  }
3654 }
3655 
3656 
3657 
3668  int l_diag_length = ( int )( ( double )m_move_step_size * 0.71 );
3669 
3670  int l_geo_cache = 0;
3671  double l_quality = 0.0;
3672  double l_qual_cache = 0.0;
3673  int l_fantastic = 0;
3674  int l_poly_cache = -1;
3675 
3676  // North.
3678 
3679  if ( m_move_allowed[ direction_n ] ) {
3680  for ( int y = a_y - 1; y >= a_y - m_move_step_size; y-- ) {
3681  int l_poly = m_map->SupplyPolyRef( a_x, y );
3682  if ( l_poly != l_poly_cache ) {
3683  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3684  if ( l_geo_cache == -1 ) {
3685  m_move_list[ direction_n ] = 0;
3686  break;
3687  }
3688  l_poly_cache = l_poly;
3689  l_qual_cache = MoveMagicVegToFood( l_poly );
3690  }
3691  l_fantastic += l_geo_cache;
3692  l_quality += l_qual_cache;
3693  }
3694  }
3695  m_move_dir_qual[ direction_n ] = l_quality;
3696  if ( m_move_list[ direction_n ] ) {
3697  m_move_list[ direction_n ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3698  }
3699 
3700  // Northeast.
3701  l_quality = 0.0;
3702  l_fantastic = 0;
3704  l_qual_cache = 0.0;
3705  l_poly_cache = -1;
3706 
3707  if ( m_move_allowed[ direction_ne ] ) {
3708  for ( int y = a_y - 1, x = a_x + 1; y >= a_y - l_diag_length; y--, x++ ) {
3709  int l_poly = m_map->SupplyPolyRef( x, y );
3710  if ( l_poly != l_poly_cache ) {
3711  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3712  if ( l_geo_cache == -1 ) {
3713  m_move_list[ direction_ne ] = 0;
3714  break;
3715  }
3716  l_poly_cache = l_poly;
3717  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3718  }
3719  l_fantastic += l_geo_cache;
3720  l_quality += l_qual_cache;
3721  }
3722  }
3723  m_move_dir_qual[ direction_ne ] = l_quality;
3724  if ( m_move_list[ direction_ne ] ) {
3725  m_move_list[ direction_ne ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3726  }
3727 
3728  // East.
3729  l_quality = 0.0;
3730  l_fantastic = 0;
3732  l_qual_cache = 0.0;
3733  l_poly_cache = -1;
3734 
3735  if ( m_move_allowed[ direction_e ] ) {
3736  for ( int x = a_x + 1; x <= a_x + m_move_step_size; x++ ) {
3737  int l_poly = m_map->SupplyPolyRef( x, a_y );
3738  if ( l_poly != l_poly_cache ) {
3739  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3740  if ( l_geo_cache == -1 ) {
3741  m_move_list[ direction_e ] = 0;
3742  break;
3743  }
3744  l_poly_cache = l_poly;
3745  l_qual_cache = MoveMagicVegToFood( l_poly );
3746  }
3747  l_fantastic += l_geo_cache;
3748  l_quality += l_qual_cache;
3749  }
3750  }
3751  m_move_dir_qual[ direction_e ] = l_quality;
3752  if ( m_move_list[ direction_e ] ) {
3753  m_move_list[ direction_e ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3754  }
3755 
3756  // Southeast.
3757  l_quality = 0.0;
3758  l_fantastic = 0;
3760  l_qual_cache = 0.0;
3761  l_poly_cache = -1;
3762 
3763  if ( m_move_allowed[ direction_se ] ) {
3764  for ( int x = a_x + 1, y = a_y + 1; x <= a_x + l_diag_length; x++, y++ ) {
3765  int l_poly = m_map->SupplyPolyRef( x, y );
3766  if ( l_poly != l_poly_cache ) {
3767  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3768  if ( l_geo_cache == -1 ) {
3769  m_move_list[ direction_se ] = 0;
3770  break;
3771  }
3772  l_poly_cache = l_poly;
3773  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3774  }
3775  l_fantastic += l_geo_cache;
3776  l_quality += l_qual_cache;
3777  }
3778  }
3779  m_move_dir_qual[ direction_se ] = l_quality;
3780  if ( m_move_list[ direction_se ] ) {
3781  m_move_list[ direction_se ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3782  }
3783 
3784  // South.
3785  l_quality = 0.0;
3786  l_fantastic = 0;
3787  l_qual_cache = 0.0;
3788  l_poly_cache = -1;
3790 
3791  if ( m_move_allowed[ direction_s ] ) {
3792  for ( int y = a_y + 1; y <= a_y + m_move_step_size; y++ ) {
3793  int l_poly = m_map->SupplyPolyRef( a_x, y );
3794  if ( l_poly != l_poly_cache ) {
3795  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3796  if ( l_geo_cache == -1 ) {
3797  m_move_list[ direction_s ] = 0;
3798  break;
3799  }
3800  l_poly_cache = l_poly;
3801  l_qual_cache = MoveMagicVegToFood( l_poly );
3802  }
3803  l_fantastic += l_geo_cache;
3804  l_quality += l_qual_cache;
3805  }
3806  }
3807  m_move_dir_qual[ direction_s ] = l_quality;
3808  if ( m_move_list[ direction_s ] ) {
3809  m_move_list[ direction_s ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3810  }
3811 
3812  // Southwest.
3813  l_quality = 0.0;
3814  l_fantastic = 0;
3816  l_qual_cache = 0.0;
3817  l_poly_cache = -1;
3818 
3819  if ( m_move_allowed[ direction_sw ] ) {
3820  for ( int x = a_x - 1, y = a_y + 1; x >= a_x - l_diag_length; x--, y++ ) {
3821  int l_poly = m_map->SupplyPolyRef( x, y );
3822  if ( l_poly != l_poly_cache ) {
3823  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3824  if ( l_geo_cache == -1 ) {
3825  m_move_list[ direction_sw ] = 0;
3826  break;
3827  }
3828  l_poly_cache = l_poly;
3829  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3830  }
3831  l_fantastic += l_geo_cache;
3832  l_quality += l_qual_cache;
3833  }
3834  }
3835  m_move_dir_qual[ direction_sw ] = l_quality;
3836  if ( m_move_list[ direction_sw ] ) {
3837  m_move_list[ direction_sw ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3838  }
3839 
3840  // West.
3841  l_quality = 0.0;
3842  l_fantastic = 0;
3844  l_qual_cache = 0.0;
3845  l_poly_cache = -1;
3846 
3847  if ( m_move_allowed[ direction_w ] ) {
3848  for ( int x = a_x - 1; x >= a_x - m_move_step_size; x-- ) {
3849  int l_poly = m_map->SupplyPolyRef( x, a_y );
3850  if ( l_poly != l_poly_cache ) {
3851  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3852  if ( l_geo_cache == -1 ) {
3853  m_move_list[ direction_w ] = 0;
3854  break;
3855  }
3856  l_poly_cache = l_poly;
3857  l_qual_cache = MoveMagicVegToFood( l_poly );
3858  }
3859  l_fantastic += l_geo_cache;
3860  l_quality += l_qual_cache;
3861  }
3862  }
3863  m_move_dir_qual[ direction_w ] = l_quality;
3864  if ( m_move_list[ direction_w ] ) {
3865  m_move_list[ direction_w ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3866  }
3867 
3868  // Northwest.
3869  l_quality = 0.0;
3870  l_fantastic = 0;
3872  l_qual_cache = 0.0;
3873  l_poly_cache = -1;
3874 
3875  if ( m_move_allowed[ direction_nw ] ) {
3876  for ( int y = a_y - 1, x = a_x - 1; y >= a_y - l_diag_length; y--, x-- ) {
3877  int l_poly = m_map->SupplyPolyRef( x, y );
3878  if ( l_poly != l_poly_cache ) {
3879  l_geo_cache = MoveCanMove( m_map->SupplyElementType( l_poly ) );
3880  if ( l_geo_cache == -1 ) {
3881  m_move_list[ direction_nw ] = 0;
3882  break;
3883  }
3884  l_poly_cache = l_poly;
3885  l_qual_cache = MoveMagicVegToFood( l_poly ) * 1.41;
3886  }
3887  l_fantastic += l_geo_cache;
3888  l_quality += l_qual_cache;
3889  }
3890  }
3891  m_move_dir_qual[ direction_nw ] = l_quality;
3892  if ( m_move_list[ direction_nw ] ) {
3893  m_move_list[ direction_nw ] = MoveEvalEdgesAndQual( l_fantastic, l_quality );
3894  }
3895 }
3896 
tov_AgroChemIndustryCereal
Definition: tov_declaration.h:55
Partridge_Covey::m_covey_x
int m_covey_x
Covey x-coord.
Definition: Partridge_Covey.h:146
cfg_par_chick_extra_mort
CfgInt cfg_par_chick_extra_mort("PAR_CHICK_EXTRA_MORT", CFG_CUSTOM, 200)
Extra mortality applied to chicks on death of parents.
CoveyManager::m_world_width_div2
int m_world_width_div2
Half landscape width.
Definition: Partridge_Covey.h:800
Partridge_Covey::m_state
Partridge_State m_state
The current behavioural state.
Definition: Partridge_Covey.h:124
tov_OSpringBarleyClover
Definition: tov_declaration.h:46
tole_HedgeBank
Definition: tole_declaration.h:68
tole_UrbanNoVeg
Definition: tole_declaration.h:78
Partridge_Covey::m_ourChicks
int m_ourChicks
No chicks in covey.
Definition: Partridge_Covey.h:381
Partridge_Base::SetUncleStatus
void SetUncleStatus(bool a_Status)
Set uncle status.
Definition: Partridge_All.h:442
Partridge_Covey::m_essence_low
bool m_essence_low
flag for excess density - unused
Definition: Partridge_Covey.h:100
Partridge_Covey::NestBadAreasScanFast
bool NestBadAreasScanFast(int a_min_x, int a_min_y, int a_length, int a_x, int a_y)
Nest location evaluation function.
Definition: Partridge_Covey.cpp:1170
Partridge_Covey::m_force_low
bool m_force_low
unused
Definition: Partridge_Covey.h:122
tole_Saltwater
Definition: tole_declaration.h:66
Partridge_Covey::BeginStep
void BeginStep(void)
Covey BeginStep.
Definition: Partridge_Covey.cpp:1583
Partridge_Covey::m_assess_qual
double m_assess_qual
Habitat quality.
Definition: Partridge_Covey.h:160
g_MaxWalk
int g_MaxWalk[200]
Definition: Partridge_Population_Manager.cpp:66
Partridge_Covey::OntheMumDead
void OntheMumDead()
Behaviour when alpha female is killed.
Definition: Partridge_Covey.cpp:2494
tov_Oats
Definition: tov_declaration.h:40
tole_UnsprayedFieldMargin
Definition: tole_declaration.h:72
tov_OWinterBarley
Definition: tov_declaration.h:47
Partridge_Covey::MoveSelectFuzzy
int MoveSelectFuzzy(void)
Fuzzdy movement selection.
Definition: Partridge_Covey.cpp:244
Partridge_Covey::ManagerIsPermanant
bool ManagerIsPermanant(void)
Unused
Definition: Partridge_Covey.h:767
Partridge_Covey::RemoveMember
int RemoveMember(Partridge_Base *a_former_member)
Remove a member from the covey.
Definition: Partridge_Covey.cpp:1664
Partridge_Covey::Pressure
double Pressure(double a_distance)
Get the pressure force.
Definition: Partridge_Covey.cpp:1724
pars_FCaringForYoung
Definition: Partridge_All.h:283
Partridge_Covey::OnAddChick
void OnAddChick(Partridge_Female *a_pf)
Add a chick.
Definition: Partridge_Covey.cpp:2451
Partridge_Covey::MoveTo
void MoveTo(int a_x, int a_y)
unused
Definition: Partridge_Covey.cpp:570
ForIterator::m_list
int * m_list
List of points
Definition: Partridge_Covey.h:50
Partridge_Male
The partridge male class.
Definition: Partridge_All.h:657
CoveyManager::Getpar_force_ignore_below
double Getpar_force_ignore_below()
Get the minimum interesting force.
Definition: Partridge_Covey.h:822
Partridge_Female
The partridge female class.
Definition: Partridge_All.h:770
Partridge_Covey::m_maxFoodNeedToday
double m_maxFoodNeedToday
Food needed today.
Definition: Partridge_Covey.h:395
tole_Building
Definition: tole_declaration.h:62
Partridge_Communication::PassMessage
bool PassMessage(PartridgeCommunicationData *pc_data, TypeOfPartridge_Communication pc)
Pass a message.
Definition: Partridge_Communication.cpp:86
Partridge_Chick::OnYouAreDead
void OnYouAreDead()
Message handler.
Definition: Partridge_All.cpp:1016
Partridge_Covey::MoveDirectionsAllowed
void MoveDirectionsAllowed(int a_x, int a_y)
Test possible movement directions.
Definition: Partridge_Covey.cpp:397
Partridge_Covey::m_center_y
int m_center_y
Covey centre.
Definition: Partridge_Covey.h:144
direction_nw
Definition: landscape.h:60
Partridge_Covey::GetMaleInCovey
Partridge_Male * GetMaleInCovey()
Find a male in the covey.
Definition: Partridge_Covey.cpp:2323
Partridge_Covey::OnDissolve
void OnDissolve(int date)
Dissolve message handler.
Definition: Partridge_Covey.cpp:1624
tole_Freshwater
Definition: tole_declaration.h:64
tov_OPermanentGrassGrazed
Definition: tov_declaration.h:44
Partridge_Covey::NormInc
int NormInc(int a_coord, int a_size)
Wrap-around utility function.
Definition: Partridge_Covey.cpp:895
Partridge_Covey::GetMember
Partridge_Base * GetMember(int a_member)
Returns pointer to a_member.
Definition: Partridge_Covey.cpp:1638
Landscape::SupplyVegType
TTypesOfVegetation SupplyVegType(int a_x, int a_y)
Definition: landscape.h:1321
Partridge_Covey::NormDec
int NormDec(int a_coord, int a_size)
Wrap-around utility function.
Definition: Partridge_Covey.cpp:882
ForIterator::m_limit
int m_limit
How many points
Definition: Partridge_Covey.h:52
Partridge_Covey::MoveCanMove
int MoveCanMove(TTypesOfLandscapeElement a_ele)
Test if we can go there.
Definition: Partridge_Covey.cpp:3221
Partridge_Population_Manager
The population manager for partridge objects.
Definition: Partridge_Population_Manager.h:83
Landscape::SupplyElementType
TTypesOfLandscapeElement SupplyElementType(int a_polyref)
Definition: landscape.h:1110
tole_Parkland
Definition: tole_declaration.h:77
Partridge_Population_Manager::ObjectLoopFetch
TAnimal * ObjectLoopFetch(void)
Definition: Partridge_Population_Manager.cpp:196
Partridge_Covey::ManagerUpdatePos
void ManagerUpdatePos(void)
Definition: Partridge_Covey.cpp:1948
Partridge_Covey::SupplyChickAge
int SupplyChickAge(void)
Returns the age of the chicks.
Definition: Partridge_Covey.cpp:2608
tole_StoneWall
Definition: tole_declaration.h:56
Partridge_Covey::NestGetX
int NestGetX(void)
Return nest x-coord.
Definition: Partridge_Covey.h:521
ForIterator
Iterator class for wrap around landscape
Definition: Partridge_Covey.h:48
tole_RiversidePlants
Definition: tole_declaration.h:49
cfg_par_movequal_histlimit
CfgInt cfg_par_movequal_histlimit("PAR_MOVEQUAL_HISTLIMIT", CFG_CUSTOM, 3)
The length of memory for backtracking.
Partridge_Covey::m_move_get_index
int m_move_get_index
Internal variable.
Definition: Partridge_Covey.h:304
tole_Garden
Definition: tole_declaration.h:58
Partridge_Covey::GetAMember
Partridge_Base * GetAMember()
Returns a random member.
Definition: Partridge_Covey.cpp:1634
tov_OOats
Definition: tov_declaration.h:44
tole_Churchyard
Definition: tole_declaration.h:86
CoveyManager::CoveyManager
CoveyManager(unsigned int a_world_width, unsigned int a_world_height, Landscape *a_map)
Constructor.
Definition: Partridge_Covey.cpp:2072
tole_RoadsideSlope
Definition: tole_declaration.h:83
tole_MixedForest
Definition: tole_declaration.h:53
Partridge_Covey::m_new_center_y_float
double m_new_center_y_float
Covey centre as float.
Definition: Partridge_Covey.h:140
cfg_par_move_fuzzy_chance
CfgInt cfg_par_move_fuzzy_chance("PAR_MOVE_FUZZY_CHANCE", CFG_CUSTOM, 50)
Chance of imperfect movement decisions.
tov_OSetaside
Definition: tov_declaration.h:46
direction_sw
Definition: landscape.h:60
tov_OTriticale
Definition: tov_declaration.h:47
cfg_IndividualEmigration
CfgInt cfg_IndividualEmigration
Emigration rate of alone individuals (of 10000)
pars_MCaringForYoung
Definition: Partridge_All.h:279
Partridge_Covey::m_map
Landscape * m_map
A pointer to the landscape.
Definition: Partridge_Covey.h:126
Partridge_Covey::CoveyUpdateMemberPositions
void CoveyUpdateMemberPositions(int a_x, int a_y)
Update all covey members x,y coords.
Definition: Partridge_Covey.cpp:1093
tov_OWinterWheatUndersown
Definition: tov_declaration.h:49
tole_Copse
Definition: tole_declaration.h:82
tov_Undefined
Definition: tov_declaration.h:114
Partridge_Covey::m_CoveyDissolveDate
int m_CoveyDissolveDate
Date for covey dissolve.
Definition: Partridge_Covey.h:383
Partridge_Covey::m_width
int m_width
Landscape width.
Definition: Partridge_Covey.h:128
cfg_par_mature_threshold
CfgInt cfg_par_mature_threshold
Age at maturing in days.
Partridge_Covey::NestFindSlow
bool NestFindSlow(int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl)
Find nest location (wrap around)
Definition: Partridge_Covey.cpp:1236
cfg_nest_fieldboundary
CfgInt cfg_nest_fieldboundary("PAR_NEST_FIELDBOUNDARY", CFG_CUSTOM, 200)
Nesting quality for field boundaries.
cfg_par_highqualthreshold
CfgInt cfg_par_highqualthreshold("PAR_HIGHQUALTHRESHOLD", CFG_CUSTOM, 18)
An arbitrary value for determine movement quality.
tole_BareRock
Definition: tole_declaration.h:75
tole_Saltmarsh
Definition: tole_declaration.h:88
Partridge_Covey::NestFindFast
bool NestFindFast(int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl)
Find nest location.
Definition: Partridge_Covey.cpp:1207
Partridge_Covey::PressureLimitExceeded
bool PressureLimitExceeded(double a_pressure)
Test for exceedence of pressure limit.
Definition: Partridge_Covey.cpp:1737
Partridge_Covey::SanityCheck3
void SanityCheck3()
Debug method.
Definition: Partridge_Covey.cpp:2430
TAnimal::m_OurLandscape
Landscape * m_OurLandscape
Definition: populationmanager.h:229
Partridge_Covey::ManagerDriftPos
void ManagerDriftPos(void)
Definition: Partridge_Covey.cpp:1745
tov_WinterWheat
Definition: tov_declaration.h:55
Partridge_Covey::OnChickDeath
void OnChickDeath()
Remove a dead chick.
Definition: Partridge_Covey.cpp:2477
tov_OCloverGrassSilage1
Definition: tov_declaration.h:43
cfg_nest_field
CfgInt cfg_nest_field("PAR_NEST_FIELD", CFG_CUSTOM, 1)
Nesting quality for fields.
Partridge_Covey::XCenterF
double XCenterF(void)
Definition: Partridge_Covey.h:728
tov_PermanentGrassTussocky
Definition: tov_declaration.h:49
Partridge_Base::SetState
void SetState(Partridge_State a_pars)
Set state.
Definition: Partridge_All.h:462
tole_Railway
Definition: tole_declaration.h:39
tov_Heath
Definition: tov_declaration.h:66
Partridge_Covey::m_center_x_float
double m_center_x_float
Covey centre as float.
Definition: Partridge_Covey.h:134
pcomm_ChicksMature
Definition: Partridge_Communication.h:56
Partridge_Population_Manager::m_comms_data
PartridgeCommunicationData * m_comms_data
Message data.
Definition: Partridge_Population_Manager.h:161
Partridge_Covey::m_height
int m_height
Landscape height.
Definition: Partridge_Covey.h:130
Partridge_Covey::AssessHabitatQualityFaster
double AssessHabitatQualityFaster()
Assess habitat quality (efficient)
Definition: Partridge_Covey.cpp:1068
CoveyManager::m_world_height
int m_world_height
Landscape height.
Definition: Partridge_Covey.h:798
g_covey_list
static vector< Partridge_Covey * > g_covey_list
Definition: Partridge_Covey.h:782
tole_RoadsideVerge
Definition: tole_declaration.h:38
cfg_par_parentdead_age2
CfgInt cfg_par_parentdead_age2("PAR_PARENTDEAD_AGETWO", CFG_CUSTOM, 63)
Mortalty chance on parent death, older.
m_move_select_list
static int m_move_select_list[8]
Definition: Partridge_Covey.cpp:229
tole_Pylon
Definition: tole_declaration.h:96
pars_CoveyDissolve
Definition: Partridge_All.h:285
Partridge_Covey::FindNeighbour
Partridge_Covey * FindNeighbour()
Finds the closest other covey.
Definition: Partridge_Covey.cpp:2290
tov_OCloverGrassGrazed2
Definition: tov_declaration.h:43
Partridge_Covey::AllFlocking2
bool AllFlocking2()
Debug method.
Definition: Partridge_Covey.cpp:2373
WARN_BUG
Definition: maperrormsg.h:34
Partridge_Covey::m_maxAllowedMove
int m_maxAllowedMove
Max move distance today.
Definition: Partridge_Covey.h:390
cfg_nest_permsetaside
CfgInt cfg_nest_permsetaside("PAR_NEST_PERMSETASIDE", CFG_CUSTOM, 100)
Nesting quality for setaside.
tole_WoodlandMargin
Definition: tole_declaration.h:98
CoveyManager::m_world_width
int m_world_width
Landscape width.
Definition: Partridge_Covey.h:796
CoverTempMap::GetQualIndexed
double GetQualIndexed(int a_x, int a_y)
Definition: Partridge_Population_Manager.h:78
Partridge_Covey::MoveDistance
void MoveDistance(int a_max_distance, int a_step_size, double a_food_density_needed)
Entry point for movement.
Definition: Partridge_Covey.cpp:652
Partridge_Base
Base class for all partridge classes.
Definition: Partridge_All.h:401
Partridge_Covey::ActOnParentDeath
void ActOnParentDeath()
Determine the chick mortality on parent death.
Definition: Partridge_Covey.cpp:2516
tov_PermanentSetaside
Definition: tov_declaration.h:49
tole_WindTurbine
Definition: tole_declaration.h:97
Partridge_Covey::GetOurChicks
int GetOurChicks()
Return the number of chicks.
Definition: Partridge_Covey.h:471
tole_ActivePit
Definition: tole_declaration.h:63
Partridge_Covey::m_theMum
Partridge_Female * m_theMum
Pointer to the alpha male.
Definition: Partridge_Covey.h:377
Partridge_Covey::m_flyto_steps
int m_flyto_steps
costly intermediate variable
Definition: Partridge_Covey.h:94
cfg_nest_roadside
CfgInt cfg_nest_roadside("PAR_NEST_ROADSIDE", CFG_CUSTOM, 100)
Nesting quality for roadsize verges.
TAnimal::Supply_m_Location_x
int Supply_m_Location_x()
Definition: populationmanager.h:213
Partridge_Covey::SupplyDistanceMoved
double SupplyDistanceMoved(void)
Return the distance moved today.
Definition: Partridge_Covey.cpp:914
Partridge_Male::GetMate
Partridge_Female * GetMate(void)
Are we paired?
Definition: Partridge_All.h:719
tov_OSpringBarley
Definition: tov_declaration.h:46
Partridge_Covey::DistanceUpdate
void DistanceUpdate(void)
Updates distance to nearest covey.
Definition: Partridge_Covey.cpp:1301
tov_Setaside
Definition: tov_declaration.h:50
cfg_nest_permpastlowyield
CfgInt cfg_nest_permpastlowyield("PAR_NEST_PERMPASTLOWYIELD", CFG_CUSTOM, 1)
Nesting quality for low yield pasture.
TAnimal::Dying
virtual void Dying()
Definition: populationmanager.h:266
Partridge_Covey::MoveMagicVegToFood
double MoveMagicVegToFood(int a_polygon)
Move optimising food intake.
Definition: Partridge_Covey.cpp:3147
Partridge_Covey::FindMeAMateInCovey
Partridge_Female * FindMeAMateInCovey(int a_family_counter)
Is their a suitable female mate in the covey?
Definition: Partridge_Covey.cpp:2334
ForIterator::ForIterator
ForIterator(int a_min_incl, int a_max_excl, int a_step_size, int a_norm_min_incl, int a_norm_max_excl)
Constructor
Definition: Partridge_Covey.cpp:2256
Partridge_Covey::MoveVegConstInit
void MoveVegConstInit(void)
Part of movement evaluation.
Definition: Partridge_Covey.cpp:3304
tov_SpringBarleySeed
Definition: tov_declaration.h:52
Partridge_Covey::MoveSelect
int MoveSelect(void)
Part of movement evaluation.
Definition: Partridge_Covey.cpp:330
tov_SpringBarleySKManagement
Definition: tov_declaration.h:65
Partridge_Covey::KillChicks
void KillChicks(int percent)
Kill a proportion of the chicks.
Definition: Partridge_Covey.cpp:2595
pars_FAttractingMate
Definition: Partridge_All.h:283
Landscape::SupplyVegDensity
int SupplyVegDensity(int a_polyref)
Definition: landscape.h:975
Partridge_Female::GetMate
Partridge_Male * GetMate(void)
Supply mate pointer.
Definition: Partridge_All.h:872
tov_WWheatPToxicControl
Definition: tov_declaration.h:55
tole_MownGrass
Definition: tole_declaration.h:74
CoveyManager::CoveyDensity
int CoveyDensity(int x, int y, int radius)
Unused.
Definition: Partridge_Covey.cpp:2178
tov_OWinterWheat
Definition: tov_declaration.h:66
Partridge_Covey::MoveOptimalDirectionSlow
void MoveOptimalDirectionSlow(int a_x, int a_y)
Choose best foraging direction.
Definition: Partridge_Covey.cpp:3404
tov_OCarrots
Definition: tov_declaration.h:43
tole_YoungForest
Definition: tole_declaration.h:55
tole_Stream
Definition: tole_declaration.h:89
PartridgeCommunicationData::m_male
Partridge_Male * m_male
Definition: Partridge_Communication.h:83
Partridge_Covey::NestGoodSpot
bool NestGoodSpot(int a_x, int a_y)
Evaluate x,y as a nest location.
Definition: Partridge_Covey.cpp:2876
cfg_par_firstmerge
CfgInt cfg_par_firstmerge("PAR_FIRSTMERGE", CFG_CUSTOM, 150)
The Earliest merging date.
TRIG_TABLE_LENGTH
#define TRIG_TABLE_LENGTH
Definition: Partridge_Covey.cpp:233
tov_OBarleyPeaCloverGrass
Definition: tov_declaration.h:41
tole_ConiferousForest
Definition: tole_declaration.h:54
tov_WinterWheatShort
Definition: tov_declaration.h:56
g_msg
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:41
Partridge_Covey::m_assess_done
bool m_assess_done
Have assessed habitat quality?
Definition: Partridge_Covey.h:158
tov_SpringBarleyGrass
Definition: tov_declaration.h:52
cfg_par_bio_hindrance_inv
CfgFloat cfg_par_bio_hindrance_inv("PAR_BIO_HINDRANCE", CFG_CUSTOM, 0.00667)
direction_s
Definition: landscape.h:60
CoveyManager::DelCovey
bool DelCovey(Partridge_Covey *a_covey)
Remove a covey.
Definition: Partridge_Covey.cpp:2230
Partridge_Covey::FindMateInArea
Partridge_Female * FindMateInArea(int a_max_distance)
Find mate in area.
Definition: Partridge_Covey.cpp:1561
cfg_par_force_abs_limit
CfgFloat cfg_par_force_abs_limit("PAR_COVEY_FORCE_ABS_LIMIT", CFG_CUSTOM, 100.0)
Partridge_Covey::MoveOptimalDirectionFast
void MoveOptimalDirectionFast(int a_x, int a_y)
Choose best foraging direction (wrap around)
Definition: Partridge_Covey.cpp:3667
tole_LargeRoad
Definition: tole_declaration.h:61
Partridge_Covey::m_theDad
Partridge_Male * m_theDad
Pointer to the alpha female.
Definition: Partridge_Covey.h:379
Partridge_Covey::YCenterF
double YCenterF(void)
Definition: Partridge_Covey.h:733
cfg_par_lastmerge
CfgInt cfg_par_lastmerge("PAR_LASTMERGE", CFG_CUSTOM, 59)
The latest merging date.
Partridge_Population_Manager::m_territoryqualmap
CoverTempMap * m_territoryqualmap
Pointer to territory quality map.
Definition: Partridge_Population_Manager.h:165
Partridge_Covey::NestNearBadAreas
bool NestNearBadAreas(int a_x, int a__y)
Test for proximity to unacceptable areas.
Definition: Partridge_Covey.cpp:1131
Landscape
The landscape class containing all environmental and topographical data.
Definition: landscape.h:112
Partridge_Covey::AllFlocking
bool AllFlocking()
Debug method.
Definition: Partridge_Covey.cpp:2362
Partridge_Covey::m_manager
Partridge_Population_Manager * m_manager
Covey's population manager.
Definition: Partridge_Covey.h:132
tov_YoungForest
Definition: tov_declaration.h:60
Partridge_Covey::ManagerRethinkPos
void ManagerRethinkPos(void)
Definition: Partridge_Covey.cpp:1855
tov_OWinterBarleyExt
Definition: tov_declaration.h:65
tov_SpringBarleySilage
Definition: tov_declaration.h:52
Partridge_Covey::TooClose
bool TooClose()
Test for another covey too close.
Definition: Partridge_Covey.cpp:1271
g_FoodNeed
double g_FoodNeed[200]
Definition: Partridge_Population_Manager.cpp:65
CoveyManager::Tick
void Tick(void)
Do the covey management for the time-step.
Definition: Partridge_Covey.cpp:2144
TAnimal::SetX
void SetX(int a_x)
Definition: populationmanager.h:240
Partridge_Base::GetID
long GetID(void)
Supply ID.
Definition: Partridge_All.h:482
tole_Marsh
Definition: tole_declaration.h:41
TTypesOfVegetation
TTypesOfVegetation
Definition: tov_declaration.h:30
tole_OrchardBand
Definition: tole_declaration.h:73
CoveyManager::m_par_force_ignore_below
double m_par_force_ignore_below
Minimum interesting force.
Definition: Partridge_Covey.h:806
Partridge_Covey::NestBadArea
bool NestBadArea(int a_x, int a__y)
Nest location evaluation function.
Definition: Partridge_Covey.cpp:2947
PartridgeCommunicationData::m_female
Partridge_Female * m_female
Definition: Partridge_Communication.h:84
tov_SpringRape
Definition: tov_declaration.h:53
m_move_veg_const_init_done
static bool m_move_veg_const_init_done
Definition: Partridge_Covey.cpp:3299
Partridge_Covey::NestNearNests
bool NestNearNests(int a_x, int a_y, int a_min_dist_sq)
Nest location evaluation function.
Definition: Partridge_Covey.cpp:1188
tole_Pond
Definition: tole_declaration.h:101
Partridge_Covey::m_terr_qual
double m_terr_qual
Homerange evaluation score
Definition: Partridge_Covey.h:120
Landscape::SupplySimAreaHeight
int SupplySimAreaHeight(void)
Definition: landscape.h:1637
Partridge_Covey::m_move_step_size_inv
double m_move_step_size_inv
Internal variable.
Definition: Partridge_Covey.h:320
tov_PotatoesIndustry
Definition: tov_declaration.h:50
Partridge_Covey::GetCoveySize
unsigned int GetCoveySize()
Return the covey size.
Definition: Partridge_Covey.h:476
Landscape::SupplySimAreaWidth
int SupplySimAreaWidth(void)
Definition: landscape.h:1632
Partridge_Covey::m_neighbourlist_size
int m_neighbourlist_size
Number of coveys close to this covey.
Definition: Partridge_Covey.h:286
tov_SpringBarleyPTreatment
Definition: tov_declaration.h:63
TAnimal::m_Location_y
int m_Location_y
Definition: populationmanager.h:228
cfg_par_covey_drift_enable
CfgBool cfg_par_covey_drift_enable("PAR_COVEY_DRIFT_ENABLE", CFG_CUSTOM, true)
tov_FodderGrass
Definition: tov_declaration.h:62
CoveyManager::Setpar_force_ignore_below
void Setpar_force_ignore_below(double ff)
Set the minimum interesting force.
Definition: Partridge_Covey.cpp:2113
direction_n
Definition: landscape.h:60
tov_Carrots
Definition: tov_declaration.h:31
ForIterator::~ForIterator
~ForIterator(void)
Destructor
Definition: Partridge_Covey.cpp:2284
Partridge_Covey::MoveTryExcludeHarder
bool MoveTryExcludeHarder(int a_dist_sq)
Uses the peg force to exclude possible movement directions.
Definition: Partridge_Covey.cpp:2750
CoveyManager::~CoveyManager
~CoveyManager(void)
Destructor.
Definition: Partridge_Covey.cpp:2099
direction_e
Definition: landscape.h:60
CfgBool
Bool configurator entry class.
Definition: configurator.h:127
tole_PermPasture
Definition: tole_declaration.h:47
pob_Chick2
Definition: Partridge_All.h:297
m_move_select_size
static int m_move_select_size
Definition: Partridge_Covey.cpp:230
Partridge_Covey::ID
unsigned int ID(void)
Definition: Partridge_Covey.h:738
Partridge_Covey::DistanceUpdate2
void DistanceUpdate2(void)
Updates distance to fixed nearest covey.
Definition: Partridge_Covey.cpp:1281
pob_Covey
Definition: Partridge_All.h:297
Partridge_Covey::HabitatEvaluateSlow
double HabitatEvaluateSlow(int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl)
Definition: Partridge_Covey.cpp:952
m_move_allowed
bool m_move_allowed[8]
Definition: Partridge_Covey.cpp:228
Partridge_Covey::SupplyHabitatQuality
double SupplyHabitatQuality()
Return habitat quality at our location.
Definition: Partridge_Covey.cpp:1050
TAnimal
The base class for all ALMaSS animal classes.
Definition: populationmanager.h:205
Partridge_Covey
The collective for a family of partridges
Definition: Partridge_Covey.h:90
Partridge_Covey::m_nearest_covey_dist
double m_nearest_covey_dist
Closest covey distance
Definition: Partridge_Covey.h:116
tov_SpringBarleyCloverGrass
Definition: tov_declaration.h:52
Partridge_Covey::Step
void Step(void)
Covey Step.
Definition: Partridge_Covey.cpp:1607
Partridge_Female::GetOldMate
Partridge_Male * GetOldMate(void)
Supply old mate pointer.
Definition: Partridge_All.h:893
tov_WinterRape
Definition: tov_declaration.h:53
tov_OGrazingPigs
Definition: tov_declaration.h:44
tov_SugarBeet
Definition: tov_declaration.h:66
Landscape::SupplyVegPatchy
bool SupplyVegPatchy(int a_polyref)
Definition: landscape.h:986
Partridge_Covey::m_members_size
unsigned int m_members_size
Size of covey
Definition: Partridge_Covey.h:110
m_move_veg_const
double m_move_veg_const[]
Definition: Partridge_Covey.cpp:223
tole_PermanentSetaside
Definition: tole_declaration.h:46
tov_OSBarleySilage
Definition: tov_declaration.h:56
Partridge_Covey::FindMeAWife
Partridge_Female * FindMeAWife(Partridge_Male *a_male)
Find mate in covey.
Definition: Partridge_Covey.cpp:1518
Partridge_Covey::MoveWeighDirection
int MoveWeighDirection(int a_x, int a_y)
Weighted foraging walk.
Definition: Partridge_Covey.cpp:344
tov_PermanentGrassGrazed
Definition: tov_declaration.h:49
g_covey_manager
class CoveyManager * g_covey_manager
Definition: Partridge_Covey.cpp:2070
tole_UrbanPark
Definition: tole_declaration.h:79
PartridgeCommunicationData::m_covey
Partridge_Covey * m_covey
Definition: Partridge_Communication.h:85
Partridge_Covey::SetFixed
void SetFixed(bool a_is_fixed)
Prevent/enable peg drift.
Definition: Partridge_Covey.h:572
Partridge_Covey::m_center_x
int m_center_x
Covey centre.
Definition: Partridge_Covey.h:142
tov_CloverGrassGrazed2
Definition: tov_declaration.h:33
TAnimal::SetY
void SetY(int a_y)
Definition: populationmanager.h:243
tole_Track
Definition: tole_declaration.h:59
tov_WWheatPControl
Definition: tov_declaration.h:55
Partridge_Covey::m_flyto_ts
double m_flyto_ts
costly intermediate variable
Definition: Partridge_Covey.h:98
MapErrorMsg::Warn
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:59
Partridge_Covey::m_move_qual_hist
int m_move_qual_hist[4][MOVE_QUAL_HIST_SIZE]
Internal variable.
Definition: Partridge_Covey.h:310
tov_Potatoes
Definition: tov_declaration.h:50
cfg_par_force_enable
CfgBool cfg_par_force_enable("PAR_COVEY_FORCE_ENABLE", CFG_CUSTOM, true)
Enable the calculation of the repulsive inter-covey 'force'.
cfg_terr_qual_good
CfgFloat cfg_terr_qual_good("PAR_TERR_QUAL_GOOD", CFG_CUSTOM, 4.0)
Nesting quality for OK areas.
Landscape::SupplyDayInYear
int SupplyDayInYear(void)
Definition: landscape.h:1596
pcomm_AllChicksDead
Definition: Partridge_Communication.h:63
Partridge_Population_Manager::m_messagecentre
Partridge_Communication m_messagecentre
Message class pointer.
Definition: Partridge_Population_Manager.h:163
Partridge_Base::GetFamily
int GetFamily(void)
Supply family ID.
Definition: Partridge_All.h:467
cfg_nest_naturalgrass
CfgInt cfg_nest_naturalgrass("PAR_NEST_NATURALGRASS", CFG_CUSTOM, 100)
Nesting quality for natural grass.
Partridge_Covey::NestBadAreasScanSlow
bool NestBadAreasScanSlow(int a_min_x, int a_min_y, int a_length, int a_x, int a_y)
Nest location evaluation function.
Definition: Partridge_Covey.cpp:1150
Partridge_Covey::m_assess_size
int m_assess_size
Current homerange assessment radius.
Definition: Partridge_Covey.h:296
Landscape::SupplyHasTramlines
bool SupplyHasTramlines(int a_x, int a_y)
Definition: landscape.h:1252
cfg_par_force_ignore_below
CfgFloat cfg_par_force_ignore_below("PAR_COVEY_FORCE_IGNORE_BELOW", CFG_CUSTOM, 0.0)
WARN_MSG
Definition: maperrormsg.h:38
TALMaSSObject::m_StepDone
bool m_StepDone
Indicates whether the iterative step code is done for this timestep.
Definition: populationmanager.h:118
direction_ne
Definition: landscape.h:60
Partridge_Covey::m_id
unsigned int m_id
Unique ID no-
Definition: Partridge_Covey.h:106
Partridge_Covey::CoveyIndividualEmigrate
void CoveyIndividualEmigrate()
Test for individuals from covey emigrating.
Definition: Partridge_Covey.cpp:2655
pars_CoveyBeing
Definition: Partridge_All.h:285
tole_NaturalGrassWet
Definition: tole_declaration.h:87
cfg_par_parentdead_age1
CfgInt cfg_par_parentdead_age1("PAR_PARENTDEAD_AGEONE", CFG_CUSTOM, 35)
Mortalty chance on parent death, young.
Partridge_Covey::GetObjectType
Partridge_Object GetObjectType(void)
Return object type.
Definition: Partridge_Covey.h:582
tov_OMaizeSilage
Definition: tov_declaration.h:65
tole_Orchard
Definition: tole_declaration.h:71
tole_MetalledPath
Definition: tole_declaration.h:84
Partridge_Covey::SetCoveyDissolveDate
void SetCoveyDissolveDate(int date)
Set the dissolve date.
Definition: Partridge_Covey.h:430
tov_Maize
Definition: tov_declaration.h:36
Partridge_Covey::ChickExtraMortality
void ChickExtraMortality()
Apply extra chick mortality.
Definition: Partridge_Covey.cpp:2671
Partridge_Covey::FlyTo
bool FlyTo(int a_distance)
Fly to
Definition: Partridge_Covey.cpp:1484
Partridge_Covey::m_food_today
double m_food_today
Food collected.
Definition: Partridge_Covey.h:166
Partridge_Covey::m_covey_y
int m_covey_y
Covey y-coord.
Definition: Partridge_Covey.h:148
Partridge_Covey::MoveQualMemory
void MoveQualMemory(int a_qual)
Make a move based on memory of quality.
Definition: Partridge_Covey.cpp:538
cfg_par_force_speed
CfgFloat cfg_par_force_speed("PAR_COVEY_FORCE_SPEED", CFG_CUSTOM, 2.0)
Partridge_Covey::FlyToFast
bool FlyToFast(int a_distance)
Move a_distance from current covey position.
Definition: Partridge_Covey.cpp:1349
cfg_parinsectScaler
CfgFloat cfg_parinsectScaler("PAR_INSECTSCALER", CFG_CUSTOM, 0.5)
Default for 2000s, 1950s=1.0.
Partridge_Covey::GetUnpairedFemale
Partridge_Female * GetUnpairedFemale()
Finds the first unpaired female in the covey.
Definition: Partridge_Covey.cpp:2304
Partridge_Covey::m_move_done
bool m_move_done
Have moved?
Definition: Partridge_Covey.h:162
tov_OWinterRape
Definition: tov_declaration.h:47
tov_WWheatPTreatment
Definition: tov_declaration.h:55
tole_SandDune
Definition: tole_declaration.h:81
CfgFloat::value
double value(void)
Definition: configurator.h:118
tole_WoodyEnergyCrop
Definition: tole_declaration.h:94
CoveyManager::BroodGeoMean
double BroodGeoMean()
Calculate the geometric mean of no of chicks.
Definition: Partridge_Covey.cpp:2117
tov_FieldPeas
Definition: tov_declaration.h:34
Partridge_Covey::m_move_step_size
int m_move_step_size
Internal variable.
Definition: Partridge_Covey.h:318
tov_BroadBeans
Definition: tov_declaration.h:66
cfg_nest_permpasttussocky
CfgInt cfg_nest_permpasttussocky("PAR_NEST_PERMPASTTUSSOCKY", CFG_CUSTOM, 1)
Nesting quality for very low grazed pasture.
Partridge_Covey::SanityCheck
void SanityCheck()
Debug method.
Definition: Partridge_Covey.cpp:2403
Partridge_Covey::NestOnNest
bool NestOnNest(void)
Are we nesting?
Definition: Partridge_Covey.h:511
Partridge_Covey::m_ChickAge
int m_ChickAge
Age of chicks.
Definition: Partridge_Covey.h:397
tole_River
Definition: tole_declaration.h:65
Partridge_Covey::NestFindLocation
bool NestFindLocation(void)
Try to locate a suitable nesting location.
Definition: Partridge_Covey.cpp:1107
tov_OSeedGrass1
Definition: tov_declaration.h:46
Partridge_Base::SetCovey
void SetCovey(Partridge_Covey *a_covey)
Set covey pointer.
Definition: Partridge_All.h:492
g_par_terr_max_width
CfgInt g_par_terr_max_width("PAR_TERR_MAX_WIDTH", CFG_CUSTOM, 500)
Limit to homerange radius.
Partridge_Covey::SanityCheck2
void SanityCheck2(int no_chicks)
Debug method.
Definition: Partridge_Covey.cpp:2416
Partridge_Covey::AssessHabitatQuality
double AssessHabitatQuality(int &a_sz)
Assess habitat quality (with checks)
Definition: Partridge_Covey.cpp:1059
tov_OFodderBeet
Definition: tov_declaration.h:65
tole_Scrub
Definition: tole_declaration.h:42
Partridge_Covey::Partridge_Covey
Partridge_Covey(Partridge_Base *a_first_member, Partridge_Population_Manager *a_manager, unsigned int a_center_x, unsigned int a_center_y, Landscape *a_map)
Constructor.
Definition: Partridge_Covey.cpp:1977
Partridge_Covey::HabitatEvalPoly
double HabitatEvalPoly(TTypesOfLandscapeElement a_cet, int a_poly)
Definition: Partridge_Covey.cpp:2769
CFG_CUSTOM
Definition: configurator.h:60
tov_OCloverGrassGrazed1
Definition: tov_declaration.h:43
Partridge_Covey::IsMember
bool IsMember(Partridge_Base *a_possible_member)
Definition: Partridge_Covey.cpp:1709
tole_PermPastureTussocky
Definition: tole_declaration.h:45
Partridge_Covey::FixHabitat
void FixHabitat(void)
Accept this breeding location.
Definition: Partridge_Covey.cpp:1074
tov_OSpringBarleyPigs
Definition: tov_declaration.h:47
Partridge_Covey::FlyToSlow
bool FlyToSlow(int a_distance)
Move a_distance from current covey position (wraparound)
Definition: Partridge_Covey.cpp:1422
Landscape::SupplyInsects
double SupplyInsects(int a_polyref)
Definition: landscape.h:1088
cfg_par_covey_drift_speed
CfgFloat cfg_par_covey_drift_speed("PAR_COVEY_DRIFT_SPEED", CFG_CUSTOM, 2.0)
Drift force on the peg.
tov_SpringBarleySpr
Definition: tov_declaration.h:66
Partridge_Covey::m_nest_on_nest
bool m_nest_on_nest
Nesting flag.
Definition: Partridge_Covey.h:152
Partridge_Covey::DistanceToCovey
double DistanceToCovey(Partridge_Covey *a_covey)
Get distance too covey.
Definition: Partridge_Covey.cpp:1319
June
const int June
Definition: landscape.h:41
cfg_min_merge_dist
CfgFloat cfg_min_merge_dist("PAR_MIN_MERGE_DIST", CFG_CUSTOM, 50.0)
The minimum merging distance.
tov_PermanentGrassLowYield
Definition: tov_declaration.h:63
cfg_nest_railway
CfgInt cfg_nest_railway("PAR_NEST_RAILWAY", CFG_CUSTOM, 100)
Nesting quality for railway ebankments.
Landscape::SupplyVegHeight
double SupplyVegHeight(int a_polyref)
Definition: landscape.h:936
Partridge_Covey::m_dist_moved
double m_dist_moved
Distance moved.
Definition: Partridge_Covey.h:164
tole_Field
Definition: tole_declaration.h:43
Partridge_Chick
Partridge chick class.
Definition: Partridge_All.h:581
Partridge_Covey::ManagerCheckMerge
void ManagerCheckMerge(void)
Definition: Partridge_Covey.cpp:1794
tole_FieldBoundary
Definition: tole_declaration.h:40
CoveyManager::m_world_height_div2
int m_world_height_div2
Half landscape height.
Definition: Partridge_Covey.h:802
tole_PermPastureLowYield
Definition: tole_declaration.h:44
Partridge_Covey::m_terr_size
int m_terr_size
Homerange width.
Definition: Partridge_Covey.h:150
Partridge_Covey::SetUncle
void SetUncle()
Swap uncle to alhpha.
Definition: Partridge_Covey.cpp:2540
Partridge_Covey::MoveTryExclude
bool MoveTryExclude(int a_dist_sq)
Uses the peg force to exclude possible movement directions.
Definition: Partridge_Covey.cpp:2735
g_trig_sin
static double * g_trig_sin
Definition: Partridge_Covey.cpp:235
g_par_nest_min_dist_bad_areas
CfgInt g_par_nest_min_dist_bad_areas("PAR_NEST_MIN_DIST_BAD_AREAS", CFG_CUSTOM, 25)
Minimum nest distance to 'bad' areas.
CfgInt
Integer configurator entry class.
Definition: configurator.h:87
tole_RiversideTrees
Definition: tole_declaration.h:51
Partridge_Covey::m_move_qual_memory
int m_move_qual_memory[4]
Steps remembered.
Definition: Partridge_Covey.h:308
tov_WinterBarley
Definition: tov_declaration.h:53
g_trig_cos
static double * g_trig_cos
Definition: Partridge_Covey.cpp:236
direction_w
Definition: landscape.h:60
Partridge_Population_Manager::DissolveCovey
void DissolveCovey(Partridge_Covey *a_covey)
Definition: Partridge_Population_Manager.cpp:1475
tov_NaturalGrass
Definition: tov_declaration.h:37
pars_MFlocking
Definition: Partridge_All.h:279
cfg_nest_hedgebank2
CfgInt cfg_nest_hedgebank2("PAR_NEST_HEDGEBANKTWO", CFG_CUSTOM, 200)
Nesting quality for hedgebank type 2.
TTypesOfLandscapeElement
TTypesOfLandscapeElement
Definition: tole_declaration.h:36
tole_IndividualTree
Definition: tole_declaration.h:93
cfg_par_force_ignore_dist_sq
CfgFloat cfg_par_force_ignore_dist_sq("PAR_COVEY_FORCE_IGNORE_DIST_SQ", CFG_CUSTOM, 250000.0)
Partridge_Covey::m_new_center_x_float
double m_new_center_x_float
Covey centre as float.
Definition: Partridge_Covey.h:138
tov_SeedGrass2
Definition: tov_declaration.h:50
Partridge_Covey::m_nest_y
int m_nest_y
Nest coord-y.
Definition: Partridge_Covey.h:156
TAnimal::Supply_m_Location_y
int Supply_m_Location_y()
Definition: populationmanager.h:216
Partridge_Population_Manager::ObjectLoopInit
void ObjectLoopInit(int ob_type)
Definition: Partridge_Population_Manager.cpp:187
Partridge_Covey::GetUncleNumber
int GetUncleNumber()
Returns the number of uncles.
Definition: Partridge_Covey.cpp:2560
CfgFloat
Double configurator entry class.
Definition: configurator.h:106
Partridge_Covey::SanityCheck4
void SanityCheck4()
Debug method.
Definition: Partridge_Covey.cpp:2439
Partridge_Covey::AddMember
void AddMember(Partridge_Base *a_new_member)
Definition: Partridge_Covey.cpp:1644
tole_PitDisused
Definition: tole_declaration.h:50
tov_MaizeSilage
Definition: tov_declaration.h:62
ForIterator::GetLimit
int GetLimit(void)
Get how many points
Definition: Partridge_Covey.h:61
Partridge_Covey::CoveyEmigrate
bool CoveyEmigrate()
Test for covey emigration.
Definition: Partridge_Covey.cpp:2642
tov_NoGrowth
Definition: tov_declaration.h:38
tov_OPotatoes
Definition: tov_declaration.h:44
tole_HeritageSite
Definition: tole_declaration.h:90
Partridge_Covey::m_peg_is_fixed
bool m_peg_is_fixed
flag for fixed homerange
Definition: Partridge_Covey.h:102
Partridge_Covey::HabitatEvaluateFaster
double HabitatEvaluateFaster(int a_center_x, int a_center_y)
Evaluate habitat fast.
Definition: Partridge_Covey.cpp:1027
CfgInt::value
int value(void)
Definition: configurator.h:98
Partridge_Covey::m_move_whence_we_came
int m_move_whence_we_came
Internal variable.
Definition: Partridge_Covey.h:316
tole_PlantNursery
Definition: tole_declaration.h:95
Partridge_Covey::OntheDadDead
void OntheDadDead()
Behaviour when alpha male is killed.
Definition: Partridge_Covey.cpp:2502
pars_FFlocking
Definition: Partridge_All.h:282
Partridge_Covey::m_members
Partridge_Base * m_members[100]
List of covey members
Definition: Partridge_Covey.h:108
Partridge_Covey::SupplyFoodToday
double SupplyFoodToday(void)
Return the food obtained today.
Definition: Partridge_Covey.cpp:905
Partridge_Covey::HaveWeChicks
bool HaveWeChicks(void)
Check if covey contains chicks.
Definition: Partridge_Covey.cpp:2626
tov_OSeedGrass2
Definition: tov_declaration.h:46
cfg_par_force_below
CfgFloat cfg_par_force_below("PAR_COVEY_FORCE_BELOW", CFG_CUSTOM, 0.1)
Partridge_Covey::m_flyto_dist
int m_flyto_dist
costly intermediate variable
Definition: Partridge_Covey.h:96
cfg_nest_hedgebank0
CfgInt cfg_nest_hedgebank0("PAR_NEST_HEDGEBANKZERO", CFG_CUSTOM, 1)
Nesting quality for hedgebank type 0.
pob_Male
Definition: Partridge_All.h:297
m_move_list
int m_move_list[8]
Definition: Partridge_Covey.cpp:226
cfg_NOT1950sinsects
CfgFloat cfg_NOT1950sinsects("PAR_NOTFIFTIESINSECTSSCALER", CFG_CUSTOM, 0.1)
Default for 2000s, 1950s=1.0.
Partridge_Covey::ArePaired
bool ArePaired()
Debug method.
Definition: Partridge_Covey.cpp:2384
tov_OFieldPeasSilage
Definition: tov_declaration.h:56
CoveyManager::m_map
Landscape * m_map
Pointer to the landscape.
Definition: Partridge_Covey.h:804
Partridge_Covey::IsFixed
bool IsFixed(void)
Wonder whether the peg is fixed?
Definition: Partridge_Covey.h:577
tov_SpringWheat
Definition: tov_declaration.h:53
Partridge_Covey::GetUnpairedFemale_virgin
Partridge_Female * GetUnpairedFemale_virgin()
Finds the first never paired female in the covey.
Definition: Partridge_Covey.cpp:2350
tov_SpringBarley
Definition: tov_declaration.h:52
tov_OWinterRye
Definition: tov_declaration.h:49
tole_Carpark
Definition: tole_declaration.h:85
Partridge_Covey::HabitatEvaluate
double HabitatEvaluate(int a_center_x, int a_center_y, int *a_size_used, bool a_rethink_size)
Entry point for habitat evaluation.
Definition: Partridge_Covey.cpp:991
tov_OFirstYearDanger
Definition: tov_declaration.h:44
tole_DeciduousForest
Definition: tole_declaration.h:52
TALMaSSObject::m_CurrentStateNo
int m_CurrentStateNo
The basic state number for all objects - '-1' indicates death.
Definition: populationmanager.h:116
tov_CloverGrassGrazed1
Definition: tov_declaration.h:32
Partridge_Covey::MoveDoIt
double MoveDoIt(int *a_x, int *a_y, int a_dir, int a_step_size)
We know where we want to go. Now do it!
Definition: Partridge_Covey.cpp:811
Partridge_Covey::KillExcessChicks
void KillExcessChicks(int remaining)
Kill extra chicks.
Definition: Partridge_Covey.cpp:2573
tole_Hedges
Definition: tole_declaration.h:37
tov_OFieldPeas
Definition: tov_declaration.h:43
tov_FodderBeet
Definition: tov_declaration.h:35
CoveyManager::AddCovey
void AddCovey(Partridge_Covey *a_covey)
Add a new covey.
Definition: Partridge_Covey.cpp:2222
pob_Clutch
Definition: Partridge_All.h:297
tov_WinterRye
Definition: tov_declaration.h:55
tov_Triticale
Definition: tov_declaration.h:53
CoveyManager::SanityCheck1
void SanityCheck1()
A debug function.
Definition: Partridge_Covey.cpp:2104
pob_Chick
Definition: Partridge_All.h:297
tole_Vildtager
Definition: tole_declaration.h:99
Partridge_Covey::CanWeMerge
bool CanWeMerge(int a_NoUncles)
Merging test.
Definition: Partridge_Covey.cpp:1833
cfg_par_merging_chance
CfgInt cfg_par_merging_chance("PAR_MERGE_CHANCE", CFG_CUSTOM, 5)
The merging probability.
Partridge_Covey::HabitatEvalPolyField
int HabitatEvalPolyField(int a_field)
Evaluate a field's habitat quality.
Definition: Partridge_Covey.cpp:3028
Partridge_Covey::m_neighbourlist
Partridge_Covey * m_neighbourlist[50]
List of coveys close to this covey.
Definition: Partridge_Covey.h:284
Partridge_Female::RemoveOldMate
void RemoveOldMate(bool a_knockon)
Forget old mate.
Definition: Partridge_All.h:903
CfgBool::value
bool value(void)
Definition: configurator.h:135
cfg_nest_hedgebank1
CfgInt cfg_nest_hedgebank1("PAR_NEST_HEDGEBANKONE", CFG_CUSTOM, 100)
Nesting quality for hedgebank type 1.
tole_AmenityGrass
Definition: tole_declaration.h:76
TAnimal::m_Location_x
int m_Location_x
Definition: populationmanager.h:225
Partridge_Covey::MoveSelectLimit
bool MoveSelectLimit(int a_limit, int a_x, int a_y)
Part of movement evaluation.
Definition: Partridge_Covey.cpp:261
Partridge_Covey::EndStep
void EndStep(void)
Covey EndStep.
Definition: Partridge_Covey.cpp:1616
Partridge_Covey::MoveEvalEdgesAndQual
int MoveEvalEdgesAndQual(int a_edges, double a_qual)
Move evaluation taking edges into account.
Definition: Partridge_Covey.cpp:2684
tole_NaturalGrassDry
Definition: tole_declaration.h:48
cfg_par_flyto_stepsize
CfgInt cfg_par_flyto_stepsize("PAR_FLYTO_STEPSIZE", CFG_CUSTOM, 1)
g_par_nest_min_dist_other_nest
CfgInt g_par_nest_min_dist_other_nest("PAR_NEST_MIN_DIST_OTHER_NEST", CFG_CUSTOM, 50)
Minimum nest distance to other nests.
tole_BeetleBank
Definition: tole_declaration.h:69
Landscape::SupplyPolyRef
int SupplyPolyRef(int a_x, int a_y)
Definition: landscape.h:1488
Partridge_Covey::~Partridge_Covey
virtual ~Partridge_Covey(void)
Destructor.
Definition: Partridge_Covey.cpp:1971
Partridge_Covey::OnChickMature
void OnChickMature()
Remove a matured chick.
Definition: Partridge_Covey.cpp:2460
tov_SeedGrass1
Definition: tov_declaration.h:50
m_move_dir_qual
double m_move_dir_qual[8]
Definition: Partridge_Covey.cpp:227
pob_Female
Definition: Partridge_All.h:297
Partridge_Covey::m_dist_done
bool m_dist_done
Signals distance updating is done for today
Definition: Partridge_Covey.h:114
cfg_par_hei_hindrance_inv
CfgFloat cfg_par_hei_hindrance_inv("PAR_HEI_HINDRANCE", CFG_CUSTOM, 0.04)
g_covey_id_counter
static unsigned int g_covey_id_counter
Definition: Partridge_Covey.cpp:231
tov_OSpringBarleyGrass
Definition: tov_declaration.h:46
Partridge_Base::GetAge
int GetAge(void)
Supply age.
Definition: Partridge_All.h:472
Partridge_Covey::m_nest_x
int m_nest_x
Nest coord-x.
Definition: Partridge_Covey.h:154
tole_Coast
Definition: tole_declaration.h:67
Partridge_Covey::m_terr_done
bool m_terr_done
Signals homerange evaluation done
Definition: Partridge_Covey.h:118
tole_BuiltUpWithParkland
Definition: tole_declaration.h:80
Partridge_Covey::FindMeAHusband
Partridge_Male * FindMeAHusband(Partridge_Female *a_female)
Find mate in covey.
Definition: Partridge_Covey.cpp:1534
cfg_par_parentdead_mort
CfgInt cfg_par_parentdead_mort("PAR_PARENTDEAD_MORT", CFG_CUSTOM, 100)
Mortalty chance on parent death.
tole_SmallRoad
Definition: tole_declaration.h:60
tov_None
Definition: tov_declaration.h:39
Landscape::SupplyElementSubType
int SupplyElementSubType(int a_polyref)
Definition: landscape.h:1121
Partridge_Covey::Norm
int Norm(int a_coord, int a_size)
Wrap-around utility function.
Definition: Partridge_Covey.cpp:866
tole_Fence
Definition: tole_declaration.h:57
Partridge_Covey::m_step_done
bool m_step_done
Signals Step is done for today
Definition: Partridge_Covey.h:112
tov_OSpringBarleyExt
Definition: tov_declaration.h:63
direction_se
Definition: landscape.h:60
Partridge_Covey::HabitatEvaluateFast
double HabitatEvaluateFast(int a_min_x_incl, int a_max_x_excl, int a_min_y_incl, int a_max_y_excl)
Evaluate habitat (wrap around)
Definition: Partridge_Covey.cpp:926
Partridge_Covey::m_permanent_marker
bool m_permanent_marker
Unused
Definition: Partridge_Covey.h:104
Partridge_Covey::m_center_y_float
double m_center_y_float
Covey centre as float.
Definition: Partridge_Covey.h:136
CoveyManager
The covey manager class.
Definition: Partridge_Covey.h:792
Partridge_Population_Manager::AddObject
void AddObject(int ob_type, TAnimal *pTAo)
Definition: Partridge_Population_Manager.cpp:457
ForIterator::GetList
int * GetList(void)
Get pointer to list of points
Definition: Partridge_Covey.h:56
tole_Heath
Definition: tole_declaration.h:70