Galactic Bloodshed
map.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/map.h"
6 
7 #include <cstdio>
8 #include <cstdlib>
9 #include <cstring>
10 
11 #include "gb/GB_server.h"
12 #include "gb/buffers.h"
13 #include "gb/commands/orbit.h"
14 #include "gb/files_shl.h"
15 #include "gb/fire.h"
16 #include "gb/getplace.h"
17 #include "gb/max.h"
18 #include "gb/races.h"
19 #include "gb/ships.h"
20 #include "gb/shlmisc.h"
21 #include "gb/tweakables.h"
22 #include "gb/utils/rand.h"
23 #include "gb/vars.h"
24 
25 static void show_map(const player_t, const governor_t, const starnum_t,
26  const planetnum_t, const Planet &);
27 
28 void map(const command_t &argv, GameObj &g) {
29  const player_t Playernum = g.player;
30  const governor_t Governor = g.governor;
31  placetype where;
32 
33  if (argv.size() > 1) {
34  where = getplace(g, argv[1], 0);
35  } else {
36  where = getplace(g, "", 0);
37  }
38 
39  if (where.err) return;
40 
41  switch (where.level) {
42  case ScopeLevel::LEVEL_SHIP:
43  g.out << "Bad scope.\n";
44  return;
45  case ScopeLevel::LEVEL_PLAN: {
46  const auto p = getplanet(where.snum, where.pnum);
47  show_map(Playernum, Governor, where.snum, where.pnum, p);
48  if (Stars[where.snum]->stability > 50)
49  g.out << "WARNING! This planet's primary is unstable.\n";
50  } break;
51  default:
52  orbit(argv, g); /* make orbit map instead */
53  }
54 }
55 
56 static void show_map(const player_t Playernum, const governor_t Governor,
57  const starnum_t snum, const planetnum_t pnum,
58  const Planet &p) {
59  int i;
60  int f = 0;
61  int iq = 0;
62  char shiplocs[MAX_X][MAX_Y] = {};
63  hugestr output;
64 
65  const int show = 1; // TODO(jeffbailey): This was always set to on, but this
66  // fact is output to the client, which might affect the
67  // client interface. Can remove the conditional as soon
68  // as we know that it's not client affecting.
69 
70  auto Race = races[Playernum - 1];
71  auto smap = getsmap(p);
72  if (!Race->governor[Governor].toggle.geography) {
73  /* traverse ship list on planet; find out if we can look at
74  ships here. */
75  iq = !!p.info[Playernum - 1].numsectsowned;
76 
77  Shiplist shiplist{p.ships};
78  for (const auto &s : shiplist) {
79  if (s.owner == Playernum && authorized(Governor, s) &&
80  (s.popn || (s.type == ShipType::OTYPE_PROBE)))
81  iq = 1;
82  if (s.alive && landed(s)) shiplocs[s.land_x][s.land_y] = Shipltrs[s.type];
83  }
84  }
85  /* report that this is a planet map */
86  sprintf(output, "$");
87 
88  sprintf(buf, "%s;", Stars[snum]->pnames[pnum]);
89  strcat(output, buf);
90 
91  sprintf(buf, "%d;%d;%d;", p.Maxx, p.Maxy, show);
92  strcat(output, buf);
93 
94  /* send map data */
95  for (const auto &sector : smap) {
96  bool owned1 = (sector.owner == Race->governor[Governor].toggle.highlight);
97  if (shiplocs[sector.x][sector.y] && iq) {
98  if (Race->governor[Governor].toggle.color)
99  sprintf(buf, "%c%c", (char)(sector.owner + '?'),
100  shiplocs[sector.x][sector.y]);
101  else {
102  if (owned1 && Race->governor[Governor].toggle.inverse)
103  sprintf(buf, "1%c", shiplocs[sector.x][sector.y]);
104  else
105  sprintf(buf, "0%c", shiplocs[sector.x][sector.y]);
106  }
107  } else {
108  if (Race->governor[Governor].toggle.color)
109  sprintf(buf, "%c%c", (char)(sector.owner + '?'),
110  desshow(Playernum, Governor, Race, sector));
111  else {
112  if (owned1 && Race->governor[Governor].toggle.inverse)
113  sprintf(buf, "1%c", desshow(Playernum, Governor, Race, sector));
114  else
115  sprintf(buf, "0%c", desshow(Playernum, Governor, Race, sector));
116  }
117  }
118  strcat(output, buf);
119  }
120  strcat(output, "\n");
121  notify(Playernum, Governor, output);
122 
123  if (show) {
124  sprintf(temp, "Type: %8s Sects %7s: %3u Aliens:", Planet_types[p.type],
125  Race->Metamorph ? "covered" : "owned",
126  p.info[Playernum - 1].numsectsowned);
127  if (p.explored || Race->tech >= TECH_EXPLORE) {
128  f = 0;
129  for (i = 1; i < MAXPLAYERS; i++)
130  if (p.info[i - 1].numsectsowned && i != Playernum) {
131  f = 1;
132  sprintf(buf, "%c%d", isset(Race->atwar, i) ? '*' : ' ', i);
133  strcat(temp, buf);
134  }
135  if (!f) strcat(temp, "(none)");
136  } else
137  strcat(temp, R"(???)");
138  strcat(temp, "\n");
139  notify(Playernum, Governor, temp);
140  sprintf(temp, " Guns : %3d Mob Points : %ld\n",
141  p.info[Playernum - 1].guns, p.info[Playernum - 1].mob_points);
142  notify(Playernum, Governor, temp);
143  sprintf(temp, " Mobilization : %3d (%3d) Compatibility: %.2f%%",
144  p.info[Playernum - 1].comread, p.info[Playernum - 1].mob_set,
145  compatibility(p, Race));
146  if (p.conditions[TOXIC] > 50) {
147  sprintf(buf, " (%d%% TOXIC)", p.conditions[TOXIC]);
148  strcat(temp, buf);
149  }
150  strcat(temp, "\n");
151  notify(Playernum, Governor, temp);
152  sprintf(temp, "Resource stockpile : %-9lu Fuel stockpile: %u\n",
153  p.info[Playernum - 1].resource, p.info[Playernum - 1].fuel);
154  notify(Playernum, Governor, temp);
155  sprintf(temp, " Destruct cap : %-9u%18s: %-5lu (%lu/%u)\n",
156  p.info[Playernum - 1].destruct,
157  Race->Metamorph ? "Tons of biomass" : "Total Population",
158  p.info[Playernum - 1].popn, p.popn,
159  round_rand(.01 * (100. - p.conditions[TOXIC]) * p.maxpopn));
160  notify(Playernum, Governor, temp);
161  sprintf(temp, " Crystals : %-9u%18s: %-5lu (%lu)\n",
162  p.info[Playernum - 1].crystals, "Ground forces",
163  p.info[Playernum - 1].troops, p.troops);
164  notify(Playernum, Governor, temp);
165  sprintf(temp, "%ld Total Resource Deposits Tax rate %u%% New %u%%\n",
166  p.total_resources, p.info[Playernum - 1].tax,
167  p.info[Playernum - 1].newtax);
168  notify(Playernum, Governor, temp);
169  sprintf(temp, "Estimated Production Next Update : %.2f\n",
170  p.info[Playernum - 1].est_production);
171  notify(Playernum, Governor, temp);
172  if (p.slaved_to) {
173  sprintf(temp, " ENSLAVED to player %d\n", p.slaved_to);
174  notify(Playernum, Governor, temp);
175  }
176  }
177 }
178 
179 char desshow(const player_t Playernum, const governor_t Governor, const Race *r,
180  const Sector &s) {
181  if (s.troops && !r->governor[Governor].toggle.geography) {
182  if (s.owner == Playernum) return CHAR_MY_TROOPS;
183  if (isset(r->allied, s.owner)) return CHAR_ALLIED_TROOPS;
184  if (isset(r->atwar, s.owner)) return CHAR_ATWAR_TROOPS;
185 
186  return CHAR_NEUTRAL_TROOPS;
187  }
188 
189  if (s.owner && !r->governor[Governor].toggle.geography &&
190  !r->governor[Governor].toggle.color) {
191  if (!r->governor[Governor].toggle.inverse ||
192  s.owner != r->governor[Governor].toggle.highlight) {
193  if (!r->governor[Governor].toggle.double_digits)
194  return s.owner % 10 + '0';
195 
196  if (s.owner < 10 || s.x % 2) return s.owner % 10 + '0';
197 
198  return s.owner / 10 + '0';
199  }
200  }
201 
202  if (s.crystals && (r->discoveries[D_CRYSTAL] || r->God)) return CHAR_CRYSTAL;
203 
204  switch (s.condition) {
205  case SectorType::SEC_WASTED:
206  return CHAR_WASTED;
207  case SectorType::SEC_SEA:
208  return CHAR_SEA;
209  case SectorType::SEC_LAND:
210  return CHAR_LAND;
211  case SectorType::SEC_MOUNT:
212  return CHAR_MOUNT;
213  case SectorType::SEC_GAS:
214  return CHAR_GAS;
215  case SectorType::SEC_PLATED:
216  return CHAR_PLATED;
217  case SectorType::SEC_ICE:
218  return CHAR_ICE;
219  case SectorType::SEC_DESERT:
220  return CHAR_DESERT;
221  case SectorType::SEC_FOREST:
222  return CHAR_FOREST;
223  default:
224  return ('?');
225  }
226 }
void map(const command_t &argv, GameObj &g)
Definition: map.cc:28
Planet getplanet(const starnum_t star, const planetnum_t pnum)
Definition: files_shl.cc:335
#define isset(a, i)
Definition: vars.h:312
#define TOXIC
Definition: tweakables.h:39
#define MAX_X
Definition: tweakables.h:75
#define TECH_EXPLORE
Definition: tweakables.h:185
#define MAX_Y
Definition: tweakables.h:76
static void show_map(const player_t, const governor_t, const starnum_t, const planetnum_t, const Planet &)
Definition: map.cc:56
#define D_CRYSTAL
Definition: races.h:111
SectorMap getsmap(const Planet &p)
Definition: files_shl.cc:522
char desshow(const player_t Playernum, const governor_t Governor, const Race *r, const Sector &s)
Definition: map.cc:179
#define MAXPLAYERS
Definition: vars.h:45