Galactic Bloodshed
getplace.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 /*
6  * getplace -- returns directory level from string and game object
7  * Dispplace -- returns string from directory level
8  * testship(ship) -- tests various things for the ship.
9  */
10 
11 #include "gb/getplace.h"
12 
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 #include <sstream>
17 #include <string>
18 
19 #include "gb/GB_server.h"
20 #include "gb/buffers.h"
21 #include "gb/files_shl.h"
22 #include "gb/races.h"
23 #include "gb/ships.h"
24 #include "gb/shlmisc.h"
25 #include "gb/tweakables.h"
26 #include "gb/vars.h"
27 
28 static char Disps[PLACENAMESIZE];
29 
30 static placetype getplace2(int Playernum, int Governor, const char *string,
31  placetype *where, int ignoreexpl, int God);
32 
33 placetype getplace(GameObj &g, const std::string &string,
34  const int ignoreexpl) {
35  player_t Playernum = g.player;
36  governor_t Governor = g.governor;
37  placetype where; /* return value */
38 
39  const auto God = races[Playernum - 1]->God;
40 
41  where.err = 0;
42 
43  if (string.size() != 0) {
44  switch (string[0]) {
45  case '/':
46  where.level = ScopeLevel::LEVEL_UNIV; /* scope = root (universe) */
47  where.snum = 0;
48  where.pnum = where.shipno = 0;
49  return (getplace2(Playernum, Governor, string.c_str() + 1, &where,
50  ignoreexpl, God));
51  case '#': {
52  auto shipnotmp = string_to_shipnum(string);
53  if (shipnotmp)
54  where.shipno = *shipnotmp;
55  else
56  where.shipno = -1;
57 
58  auto ship = getship(where.shipno);
59  if (!ship) {
60  DontOwnErr(Playernum, Governor, where.shipno);
61  where.err = 1;
62  return where;
63  }
64  if ((ship->owner == Playernum || ignoreexpl || God) &&
65  (ship->alive || God)) {
66  where.level = ScopeLevel::LEVEL_SHIP;
67  where.snum = ship->storbits;
68  where.pnum = ship->pnumorbits;
69  return where;
70  }
71  where.err = 1;
72  return where;
73  }
74  case '-':
75  /* no destination */
76  where.level = ScopeLevel::LEVEL_UNIV;
77  return where;
78  }
79  }
80 
81  /* copy current scope to scope */
82  where.level = g.level;
83  where.snum = g.snum;
84  where.pnum = g.pnum;
85  if (where.level == ScopeLevel::LEVEL_SHIP) where.shipno = g.shipno;
86  if (string.size() != 0 && string[0] == CHAR_CURR_SCOPE) return where;
87 
88  return getplace2(Playernum, Governor, string.c_str(), &where, ignoreexpl,
89  God);
90 }
91 
92 static placetype getplace2(const int Playernum, const int Governor,
93  const char *string, placetype *where,
94  const int ignoreexpl, const int God) {
95  char substr[NAMESIZE];
96  uint8_t i;
97  size_t l;
98  int tick;
99 
100  if (where->err || string == nullptr || *string == '\0' || *string == '\n')
101  return (*where); /* base cases */
102  if (*string == '.') {
103  if (where->level == ScopeLevel::LEVEL_UNIV) {
104  sprintf(buf, "Can't go higher.\n");
105  notify(Playernum, Governor, buf);
106  where->err = 1;
107  return (*where);
108  }
109  if (where->level == ScopeLevel::LEVEL_SHIP) {
110  auto ship = getship(where->shipno);
111  where->level = ship->whatorbits;
112  /* Fix 'cs .' for ships within ships. Maarten */
113  if (where->level == ScopeLevel::LEVEL_SHIP)
114  where->shipno = ship->destshipno;
115  } else if (where->level == ScopeLevel::LEVEL_STAR) {
116  where->level = ScopeLevel::LEVEL_UNIV;
117  } else if (where->level == ScopeLevel::LEVEL_PLAN) {
118  where->level = ScopeLevel::LEVEL_STAR;
119  }
120  while (*string == '.') string++;
121  while (*string == '/') string++;
122  return (getplace2(Playernum, Governor, string, where, ignoreexpl, God));
123  }
124  /* is a char string, name of something */
125  sscanf(string, "%[^/ \n]", substr);
126  do {
127  /*if (isupper(*string) )
128  (*string) = tolower(*string);*/
129  string++;
130  } while (*string != '/' && *string != '\n' && *string != '\0');
131  l = strlen(substr);
132  if (where->level == ScopeLevel::LEVEL_UNIV) {
133  for (i = 0; i < Sdata.numstars; i++)
134  if (!strncmp(substr, Stars[i]->name, l)) {
135  where->level = ScopeLevel::LEVEL_STAR;
136  where->snum = i;
137  if (ignoreexpl || isset(Stars[where->snum]->explored, Playernum) ||
138  God) {
139  tick = (*string == '/');
140  return (getplace2(Playernum, Governor, string + tick, where,
141  ignoreexpl, God));
142  }
143  sprintf(buf, "You have not explored %s yet.\n",
144  Stars[where->snum]->name);
145  notify(Playernum, Governor, buf);
146  where->err = 1;
147  return (*where);
148  }
149  if (i >= Sdata.numstars) {
150  sprintf(buf, "No such star %s.\n", substr);
151  notify(Playernum, Governor, buf);
152  where->err = 1;
153  return (*where);
154  }
155  } else if (where->level == ScopeLevel::LEVEL_STAR) {
156  for (i = 0; i < Stars[where->snum]->numplanets; i++)
157  if (!strncmp(substr, Stars[where->snum]->pnames[i], l)) {
158  where->level = ScopeLevel::LEVEL_PLAN;
159  where->pnum = i;
160  const auto p = getplanet(where->snum, i);
161  if (ignoreexpl || p.info[Playernum - 1].explored || God) {
162  tick = (*string == '/');
163  return (getplace2(Playernum, Governor, string + tick, where,
164  ignoreexpl, God));
165  }
166  sprintf(buf, "You have not explored %s yet.\n",
167  Stars[where->snum]->pnames[i]);
168  notify(Playernum, Governor, buf);
169  where->err = 1;
170  return (*where);
171  }
172  if (i >= Stars[where->snum]->numplanets) {
173  sprintf(buf, "No such planet %s.\n", substr);
174  notify(Playernum, Governor, buf);
175  where->err = 1;
176  return (*where);
177  }
178  } else {
179  sprintf(buf, "Can't descend to %s.\n", substr);
180  notify(Playernum, Governor, buf);
181  where->err = 1;
182  return (*where);
183  }
184 
185  return (*where);
186 }
187 
188 char *Dispshiploc_brief(Ship *ship) {
189  int i;
190 
191  switch (ship->whatorbits) {
192  case ScopeLevel::LEVEL_STAR:
193  sprintf(Disps, "/%-4.4s", Stars[ship->storbits]->name);
194  return (Disps);
195  case ScopeLevel::LEVEL_PLAN:
196  sprintf(Disps, "/%s", Stars[ship->storbits]->name);
197  for (i = 2; (Disps[i] && (i < 5)); i++)
198  ;
199  sprintf(Disps + i, "/%-4.4s",
200  Stars[ship->storbits]->pnames[ship->pnumorbits]);
201  return (Disps);
202  case ScopeLevel::LEVEL_SHIP:
203  sprintf(Disps, "#%lu", ship->destshipno);
204  return (Disps);
205  case ScopeLevel::LEVEL_UNIV:
206  sprintf(Disps, "/");
207  return (Disps);
208  }
209 }
210 
211 char *Dispshiploc(Ship *ship) {
212  switch (ship->whatorbits) {
213  case ScopeLevel::LEVEL_STAR:
214  sprintf(Disps, "/%s", Stars[ship->storbits]->name);
215  return (Disps);
216  case ScopeLevel::LEVEL_PLAN:
217  sprintf(Disps, "/%s/%s", Stars[ship->storbits]->name,
218  Stars[ship->storbits]->pnames[ship->pnumorbits]);
219  return (Disps);
220  case ScopeLevel::LEVEL_SHIP:
221  sprintf(Disps, "#%lu", ship->destshipno);
222  return (Disps);
223  case ScopeLevel::LEVEL_UNIV:
224  sprintf(Disps, "/");
225  return (Disps);
226  }
227 }
228 
230  std::ostringstream out;
231  switch (where.level) {
232  case ScopeLevel::LEVEL_STAR:
233  out << "/" << Stars[where.snum]->name;
234  return out.str();
235  case ScopeLevel::LEVEL_PLAN:
236  out << "/" << Stars[where.snum]->name << "/"
237  << Stars[where.snum]->pnames[where.pnum];
238  return out.str();
239  case ScopeLevel::LEVEL_SHIP:
240  out << "#" << where.shipno;
241  return out.str();
242  case ScopeLevel::LEVEL_UNIV:
243  out << "/";
244  return out.str();
245  }
246 }
247 
248 bool testship(const player_t playernum, const governor_t governor,
249  const Ship &s) {
250  if (!s.alive) {
251  sprintf(buf, "%s has been destroyed.\n", ship_to_string(s).c_str());
252  notify(playernum, governor, buf);
253  return true;
254  }
255 
256  if (s.owner != playernum || !authorized(governor, s)) {
257  DontOwnErr(playernum, governor, s.number);
258  return true;
259  }
260 
261  if (!s.active) {
262  sprintf(buf, "%s is irradiated %d%% and inactive.\n",
263  ship_to_string(s).c_str(), s.rad);
264  notify(playernum, governor, buf);
265  return true;
266  }
267 
268  return false;
269 }
#define PLACENAMESIZE
Definition: tweakables.h:70
char * Dispshiploc(Ship *ship)
Definition: getplace.cc:211
char * Dispshiploc_brief(Ship *ship)
Definition: getplace.cc:188
Planet getplanet(const starnum_t star, const planetnum_t pnum)
Definition: files_shl.cc:335
void DontOwnErr(int Playernum, int Governor, shipnum_t shipno)
Definition: shlmisc.cc:126
static placetype getplace2(int Playernum, int Governor, const char *string, placetype *where, int ignoreexpl, int God)
Definition: getplace.cc:92
#define isset(a, i)
Definition: vars.h:312
placetype getplace(GameObj &g, const std::string &string, const int ignoreexpl)
Definition: getplace.cc:33
#define NAMESIZE
Definition: tweakables.h:66
static char Disps[PLACENAMESIZE]
Definition: getplace.cc:28
bool testship(const player_t playernum, const governor_t governor, const Ship &s)
Definition: getplace.cc:248
std::string Dispplace(const placetype &where)
Definition: getplace.cc:229