Galactic Bloodshed
dosector.cc
Go to the documentation of this file.
1 // Copyright 2014 The Galactic Bloodshed Authors. All rights reserved.
2 // Use of this source code is governed by a license that can be
3 // found in the COPYING file.
4 
5 #include "gb/dosector.h"
6 
7 #include "gb/doturn.h"
8 #include "gb/max.h"
9 #include "gb/races.h"
10 #include "gb/tweakables.h"
11 #include "gb/utils/rand.h"
12 #include "gb/vars.h"
13 
14 static const int x_adj[] = {-1, 0, 1, -1, 1, -1, 0, 1};
15 static const int y_adj[] = {1, 1, 1, 0, 0, -1, -1, -1};
16 
17 static void Migrate2(const Planet &, int, int, Sector &, int *, SectorMap &);
18 static void plate(Sector &);
19 
20 // produce() -- produce, stuff like that, on a sector.
21 void produce(startype *star, const Planet &planet, Sector &s) {
22  int ss;
23  int maxsup;
24  int pfuel = 0;
25  int pdes = 0;
26  int pres = 0;
27  resource_t prod;
28  long diff;
29  racetype *Race;
30 
31  if (!s.owner) return;
32  Race = races[s.owner - 1];
33 
34  if (s.resource && success(s.eff)) {
35  prod = round_rand(Race->metabolism) * int_rand(1, s.eff);
36  prod = std::min(prod, s.resource);
37  s.resource -= prod;
38  pfuel = prod * (1 + (s.condition == SectorType::SEC_GAS));
39  if (success(s.mobilization))
40  pdes = prod;
41  else
42  pres = prod;
43  prod_fuel[s.owner - 1] += pfuel;
44  prod_res[s.owner - 1] += pres;
45  prod_destruct[s.owner - 1] += pdes;
46  }
47 
48  /* try to find crystals */
49  /* chance of digging out a crystal depends on efficiency */
50  if (s.crystals && Crystal(Race) && success(s.eff)) {
51  prod_crystals[s.owner - 1]++;
52  s.crystals--;
53  }
54  const auto pinf = &planet.info[s.owner - 1];
55 
56  /* increase mobilization to planetary quota */
57  if (s.mobilization < pinf->mob_set) {
58  if (pinf->resource + prod_res[s.owner - 1] > 0) {
59  s.mobilization++;
60  prod_res[s.owner - 1] -= round_rand(MOB_COST);
61  prod_mob++;
62  }
63  } else if (s.mobilization > pinf->mob_set) {
64  s.mobilization--;
65  prod_mob--;
66  }
67 
68  avg_mob[s.owner - 1] += s.mobilization;
69 
70  /* do efficiency */
71  if (s.eff < 100) {
72  int chance;
73  chance = round_rand((100.0 - (double)planet.info[s.owner - 1].tax) *
74  Race->likes[s.condition]);
75  if (success(chance)) {
76  s.eff += round_rand(Race->metabolism);
77  if (s.eff >= 100) plate(s);
78  }
79  } else
80  plate(s);
81 
82  if ((s.condition != SectorType::SEC_WASTED) && Race->fertilize &&
83  (s.fert < 100))
84  s.fert += (int_rand(0, 100) < Race->fertilize);
85  if (s.fert > 100) s.fert = 100;
86 
87  if (s.condition == SectorType::SEC_WASTED && success(NATURAL_REPAIR))
88  s.condition = s.type;
89 
90  maxsup = maxsupport(Race, s, Compat[s.owner - 1], planet.conditions[TOXIC]);
91  if ((diff = s.popn - maxsup) < 0) {
92  if (s.popn >= Race->number_sexes)
93  ss = round_rand(-(double)diff * Race->birthrate);
94  else
95  ss = 0;
96  } else
97  ss = -int_rand(0, std::min(2 * static_cast<unsigned long>(diff), s.popn));
98  s.popn += ss;
99 
100  if (s.troops)
101  Race->governor[star->governor[s.owner - 1]].maintain +=
102  UPDATE_TROOP_COST * s.troops;
103  else if (!s.popn)
104  s.owner = 0;
105 }
106 
107 // spread() -- spread population around.
108 void spread(const Planet &pl, Sector &s, int x, int y, SectorMap &smap) {
109  int people;
110  int x2;
111  int y2;
112  int j;
113  int check;
114  racetype *Race;
115 
116  if (!s.owner) return;
117  if (pl.slaved_to && pl.slaved_to != s.owner)
118  return; /* no one wants to go anywhere */
119 
120  Race = races[s.owner - 1];
121 
122  /* the higher the fertility, the less people like to leave */
123  people = round_rand((double)Race->adventurism * (double)s.popn *
124  (100. - (double)s.fert) / 100.) -
125  Race->number_sexes; /* how many people want to move -
126  one family stays behind */
127 
128  check = round_rand(6.0 * Race->adventurism); /* more rounds for
129  high advent */
130  while (people > 0 && check) {
131  j = int_rand(0, 7);
132  x2 = x_adj[j];
133  y2 = y_adj[j];
134  Migrate2(pl, x + x2, y + y2, s, &people, smap);
135  check--;
136  }
137 }
138 
139 static void Migrate2(const Planet &planet, int xd, int yd, Sector &ps,
140  int *people, SectorMap &smap) {
141  int move;
142 
143  /* attempt to migrate beyond screen, or too many people */
144  if (yd > planet.Maxy - 1 || yd < 0) return;
145 
146  if (xd < 0)
147  xd = planet.Maxx - 1;
148  else if (xd > planet.Maxx - 1)
149  xd = 0;
150 
151  auto &pd = smap.get(xd, yd);
152 
153  if (!pd.owner) {
154  move = (int)((double)(*people) * Compat[ps.owner - 1] *
155  races[ps.owner - 1]->likes[pd.condition] / 100.0);
156  if (!move) return;
157  *people -= move;
158  pd.popn += move;
159  ps.popn -= move;
160  pd.owner = ps.owner;
161  tot_captured++;
162  Claims = 1;
163  }
164 }
165 
166 /* mark sectors on the planet as having been "explored." for sea exploration
167  on earthtype planets. */
168 
169 // explore() -- mark sector and surrounding sectors as having been explored.
170 void explore(const Planet &planet, Sector &s, int x, int y, int p) {
171  int d;
172 
173  /* explore sectors surrounding sectors currently explored. */
174  if (Sectinfo[x][y].explored) {
175  Sectinfo[mod(x - 1, planet.Maxx, d)][y].explored = p;
176  Sectinfo[mod(x + 1, planet.Maxx, d)][y].explored = p;
177  if (y == 0) {
178  Sectinfo[x][1].explored = p;
179  } else if (y == planet.Maxy - 1) {
180  Sectinfo[x][y - 1].explored = p;
181  } else {
182  Sectinfo[x][y - 1].explored = Sectinfo[x][y + 1].explored = p;
183  }
184 
185  } else if (s.owner == p)
186  Sectinfo[x][y].explored = p;
187 }
188 
189 static void plate(Sector &s) {
190  s.eff = 100;
191  if (s.condition != SectorType::SEC_GAS) s.condition = SectorType::SEC_PLATED;
192 }
#define mod(a, b, dum)
Definition: tweakables.h:216
void explore(const Planet &, Sector &, int, int, int)
Definition: dosector.cc:170
#define MOB_COST
Definition: tweakables.h:165
#define Crystal(r)
Definition: races.h:122
void spread(const Planet &, Sector &, int, int, SectorMap &)
Definition: dosector.cc:108
#define UPDATE_TROOP_COST
Definition: tweakables.h:179
#define NATURAL_REPAIR
Definition: tweakables.h:141
#define TOXIC
Definition: tweakables.h:39
static const int y_adj[]
Definition: dosector.cc:15
static const int x_adj[]
Definition: dosector.cc:14
static void Migrate2(const Planet &, int, int, Sector &, int *, SectorMap &)
Definition: dosector.cc:139
int maxsupport(const Race *r, const Sector &s, const double c, const int toxic)
Definition: max.cc:26
void produce(startype *, const Planet &, Sector &)
Definition: dosector.cc:21
static void plate(Sector &)
Definition: dosector.cc:189