11 #include "gb/commands/rst.h" 19 #include "gb/GB_server.h" 20 #include "gb/buffers.h" 22 #include "gb/files_shl.h" 24 #include "gb/getplace.h" 28 #include "gb/shlmisc.h" 29 #include "gb/shootblast.h" 30 #include "gb/tweakables.h" 35 static const char Caliber[] = {
' ',
'L',
'M',
'H'};
59 static int Getrship(player_t, governor_t, shipnum_t);
60 static int listed(
int,
char *);
61 static void plan_getrships(player_t, governor_t, starnum_t, planetnum_t);
62 static void ship_report(GameObj &, shipnum_t,
const report_array &);
65 void rst(
const command_t &argv, GameObj &g) {
66 const player_t Playernum = g.player;
67 const governor_t Governor = g.governor;
70 report_array Report_types;
76 if (argv[0] ==
"report") {
79 }
else if (argv[0] ==
"stock") {
82 }
else if (argv[0] ==
"tactical") {
85 }
else if (argv[0] ==
"ship") {
89 }
else if (argv[0] ==
"stats") {
92 }
else if (argv[0] ==
"weapons") {
95 }
else if (argv[0] ==
"factories") {
100 rd = (
struct reportdata *)malloc(
sizeof(
struct reportdata) *
104 if (argv.size() == 3) {
105 if (isdigit(argv[2][0]))
106 who = std::stoi(argv[2]);
109 strcpy(shiplist, argv[2].c_str());
114 if (argv.size() >= 2) {
115 if (*argv[1].c_str() ==
'#' || isdigit(*argv[1].c_str())) {
118 while (l <
MAXARGS && *argv[l].c_str() !=
'\0') {
119 sscanf(argv[l].c_str() + (*argv[l].c_str() ==
'#'),
"%lu", &shipno);
120 if (shipno > n_ships || shipno < 1) {
121 sprintf(buf,
"rst: no such ship #%lu \n", shipno);
122 notify(Playernum, Governor, buf);
126 (
void)Getrship(Playernum, Governor, shipno);
127 if (rd[Num_ships - 1].s.whatorbits != ScopeLevel::LEVEL_UNIV) {
128 star_getrships(Playernum, Governor, rd[Num_ships - 1].s.storbits);
129 ship_report(g, Num_ships - 1, Report_types);
131 ship_report(g, Num_ships - 1, Report_types);
137 Report_types.fill(0);
139 for (
const auto &c : argv[1]) {
141 while (--i && Shipltrs[i] != c)
143 if (Shipltrs[i] != c) {
144 sprintf(buf,
"'%c' -- no such ship letter\n", c);
145 notify(Playernum, Governor, buf);
152 case ScopeLevel::LEVEL_UNIV:
153 if (!(Tactical && argv.size() < 2)) {
154 shipnum_t shn = Sdata.ships;
156 shn =
rd[Num_ships - 1]
.s.nextship;
158 for (starnum_t i = 0; i < Sdata.numstars; i++)
160 for (shipnum_t i = 0; i < Num_ships; i++)
161 ship_report(g, i, Report_types);
163 notify(Playernum, Governor,
164 "You can't do tactical option from universe level.\n");
169 case ScopeLevel::LEVEL_PLAN:
171 for (shipnum_t i = 0; i < Num_ships; i++) ship_report(g, i, Report_types);
173 case ScopeLevel::LEVEL_STAR:
175 for (shipnum_t i = 0; i < Num_ships; i++) ship_report(g, i, Report_types);
177 case ScopeLevel::LEVEL_SHIP:
179 ship_report(g, 0, Report_types);
180 shipnum_t shn =
rd[0]
.s.ships;
184 shn =
rd[Num_ships - 1]
.s.nextship;
186 for (shipnum_t i = 0; i < Num_ships; i++) ship_report(g, i, Report_types);
193 const report_array &rep_on) {
194 player_t Playernum = g.player;
195 governor_t Governor = g.governor;
210 auto &s =
rd[indx]
.s;
211 auto &p =
rd[indx]
.p;
212 shipnum_t shipno =
rd[indx]
.n;
215 if ((rd[indx].type ==
PLANET && p.info[Playernum - 1].numsectsowned) ||
216 (rd[indx].type !=
PLANET && s.alive && s.owner == Playernum &&
217 authorized(Governor, s) && rep_on[s.type] &&
218 !(s.type == ShipType::OTYPE_CANIST && !s.docked) &&
219 !(s.type == ShipType::OTYPE_GREEN && !s.docked))) {
223 " # name x hanger res des " 225 notify(Playernum, Governor, buf);
230 "%14.14s%3u%4u:%-3u%5lu:%-5ld%5u:%-5ld%7.1f:%-6ld%lu/%lu:%d\n",
231 shipno, Shipltrs[s.type], (s.active ? s.name :
"INACTIVE"),
232 s.crystals, s.hanger, s.max_hanger, s.resource, max_resource(s),
233 s.destruct, max_destruct(s), s.fuel, max_fuel(s), s.popn,
234 s.troops, s.max_crew);
235 notify(Playernum, Governor, buf);
241 " # name las cew hyp guns arm tech " 242 "spd cost mass size\n");
243 notify(Playernum, Governor, buf);
247 "%5lu %c %14.14s %s%s%s%3lu%c/%3lu%c%4lu%5.0f%4lu%5lu%7.1f%4u",
248 shipno, Shipltrs[s.type], (s.active ? s.name :
"INACTIVE"),
249 s.laser ?
"yes " :
" ", s.cew ?
"yes " :
" ",
250 s.hyper_drive.has ?
"yes " :
" ", s.primary,
252 s.tech, max_speed(s), shipcost(s), mass(s), size(s));
253 notify(Playernum, Governor, buf);
254 if (s.type == ShipType::STYPE_POD) {
255 sprintf(buf,
" (%d)", s.special.pod.temperature);
256 notify(Playernum, Governor, buf);
264 " # name laser cew safe guns " 266 notify(Playernum, Governor, buf);
271 "%5lu %c %14.14s %s %3d/%-4d %4d %3lu%c/%3lu%c %3d%% %c %s\n",
272 shipno, Shipltrs[s.type], (s.active ? s.name :
"INACTIVE"),
273 s.laser ?
"yes " :
" ", s.cew, s.cew_range,
274 (
int)((1.0 - .01 * s.damage) * s.tech / 4.0), s.primary,
276 s.type == ShipType::OTYPE_FACTORY ? Shipltrs[s.build_type] :
' ',
277 ((s.type == ShipType::OTYPE_TERRA) ||
278 (s.type == ShipType::OTYPE_PLOW))
281 notify(Playernum, Governor, buf);
285 (s.type == ShipType::OTYPE_FACTORY)) {
288 " # Cost Tech Mass Sz A Crw Ful Crg Hng Dst Sp " 289 "Weapons Lsr CEWs Range Dmg\n");
290 notify(Playernum, Governor, buf);
293 if ((s.build_type == 0) || (s.build_type == ShipType::OTYPE_FACTORY)) {
295 "%5lu (No ship type specified yet) " 298 notify(Playernum, Governor, buf);
301 sprintf(tmpbuf1,
"%2lu%s", s.primary,
302 s.primtype == GTYPE_LIGHT
304 : s.primtype == GTYPE_MEDIUM
306 : s.primtype == GTYPE_HEAVY ?
"H" :
"N");
308 strcpy(tmpbuf1,
"---");
310 sprintf(tmpbuf2,
"%2lu%s", s.secondary,
311 s.sectype == GTYPE_LIGHT
313 : s.sectype == GTYPE_MEDIUM
315 : s.sectype == GTYPE_HEAVY ?
"H" :
"N");
317 strcpy(tmpbuf2,
"---");
319 sprintf(tmpbuf3,
"%4d", s.cew);
321 strcpy(tmpbuf3,
"----");
323 sprintf(tmpbuf4,
"%5d", s.cew_range);
325 strcpy(tmpbuf4,
"-----");
327 "%5lu %c%4d%6.1f%5.1f%3d%2d%4d%4d%4lu%4d%4d %s%1d %s/%s %s " 329 shipno, Shipltrs[s.build_type], s.build_cost, s.complexity,
330 s.base_mass, ship_size(s), s.armor, s.max_crew, s.max_fuel,
331 s.max_resource, s.max_hanger, s.max_destruct,
332 s.hyper_drive.has ? (s.mount ?
"+" :
"*") :
" ", s.max_speed,
333 tmpbuf1, tmpbuf2, s.laser ?
"yes" :
" no", tmpbuf3, tmpbuf4,
334 s.damage, s.damage ? (s.on ?
"" :
"*") :
"");
335 notify(Playernum, Governor, buf);
342 " # name gov dam crew mil des fuel sp orbits " 344 notify(Playernum, Governor, buf);
348 if (s.whatdest == ScopeLevel::LEVEL_SHIP)
349 sprintf(locstrn,
"D#%ld", s.destshipno);
351 sprintf(locstrn,
"L%2d,%-2d", s.land_x, s.land_y);
352 else if (s.navigate.on)
353 sprintf(locstrn,
"nav:%d (%d)", s.navigate.bearing, s.navigate.turns);
355 strcpy(locstrn, prin_ship_dest(s).c_str());
358 sprintf(strng,
"INACTIVE(%d)", s.rad);
359 notify(Playernum, Governor, buf);
363 "%c%-5lu %12.12s %2d %3u%5lu%4lu%5u%5.0f %c%1u %-10s %-18s\n",
364 Shipltrs[s.type], shipno, (s.active ? s.name : strng), s.governor,
365 s.damage, s.popn, s.troops, s.destruct, s.fuel,
366 s.hyper_drive.has ? (s.mounted ?
'+' :
'*') :
' ', s.speed,
368 notify(Playernum, Governor, buf);
371 auto Race = races[Playernum - 1];
380 "\n # name tech guns armor size dest " 381 "fuel dam spd evad orbits\n");
382 notify(Playernum, Governor, buf);
387 sprintf(buf,
"(planet)%15.15s%4.0f %4dM %5u %6u\n",
389 p.info[Playernum - 1].guns, p.info[Playernum - 1].destruct,
390 p.info[Playernum - 1].fuel);
391 notify(Playernum, Governor, buf);
392 caliber = GTYPE_MEDIUM;
394 where.level = s.whatorbits;
395 where.snum = s.storbits;
396 where.pnum = s.pnumorbits;
399 if ((s.whatdest != ScopeLevel::LEVEL_UNIV || s.navigate.on) &&
400 !s.docked && s.active) {
402 fev = s.protect.evade;
405 sprintf(orb,
"%30.30s", Dispplace(where).c_str());
407 "%3lu %c %16.16s %4.0f%3lu%c/%3lu%c%6d%5d%5u%7.1f%3d%% %d " 409 shipno, Shipltrs[s.type], (s.active ? s.name :
"INACTIVE"),
410 s.tech, s.primary,
Caliber[s.primtype], s.secondary,
411 Caliber[s.sectype], s.armor, s.size, s.destruct, s.fuel,
412 s.damage, fspeed, (fev ?
"yes" :
" "), orb);
413 notify(Playernum, Governor, buf);
415 sprintf(buf,
" (%d,%d)", s.land_x, s.land_y);
416 notify(Playernum, Governor, buf);
419 sprintf(buf,
" INACTIVE(%d)", s.rad);
420 notify(Playernum, Governor, buf);
423 notify(Playernum, Governor, buf);
429 else if (shipsight(s))
434 "\n Tactical: # own typ name rng (50%%) size " 435 "spd evade hit dam loc\n");
436 notify(Playernum, Governor, buf);
439 for (i = 0; i < Num_ships; i++) {
441 (Dist = sqrt(
Distsq(rd[indx].x, rd[indx].y, rd[i].x, rd[i].y))) <
442 gun_range(Race, &rd[indx].s, (rd[indx].type ==
PLANET))) {
445 sprintf(buf,
" %13s(planet) %8.0f\n",
447 notify(Playernum, Governor, buf);
451 if ((
rd[i]
.s.owner != Playernum ||
452 !authorized(Governor,
rd[i]
.s)) &&
453 rd[i]
.s.alive &&
rd[i]
.s.type != ShipType::OTYPE_CANIST &&
454 rd[i]
.s.type != ShipType::OTYPE_GREEN) {
460 if ((
rd[i]
.s.whatdest != ScopeLevel::LEVEL_UNIV ||
461 rd[i]
.s.navigate.on) &&
462 !
rd[i]
.s.docked &&
rd[i]
.s.active) {
463 tspeed =
rd[i]
.s.speed;
464 tev =
rd[i]
.s.protect.evade;
466 body = size(
rd[i]
.s);
467 auto defense = getdefense(
rd[i]
.s);
469 tspeed
, body
, caliber
, defense
);
472 prob = prob * prob / 100;
475 "%13lu %s%2d,%1d %c%14.14s %4.0f %4d %4d %d %3s " 478 (
isset(races[Playernum - 1]->atwar, rd[i].s.owner))
480 : (
isset(races[Playernum - 1]->allied, rd[i].s.owner))
483 rd[i].s.owner, rd[i].s.governor, Shipltrs[rd[i].s.type],
484 rd[i].s.name, Dist, factor, body, tspeed,
485 (tev ?
"yes" :
" "), prob, rd[i].s.damage,
486 (rd[i].s.active ?
"" :
" INACTIVE"));
487 if ((enemies_only == 0) ||
488 ((enemies_only == 1) &&
489 (!
isset(races[Playernum - 1]->allied, rd[i].s.owner)))) {
490 notify(Playernum, Governor, buf);
491 if (landed(
rd[i]
.s)) {
492 sprintf(buf,
" (%d,%d)",
rd[i]
.s.land_x,
rd[i]
.s.land_y);
493 notify(Playernum, Governor, buf);
496 notify(Playernum, Governor, buf);
499 notify(Playernum, Governor, buf);
510 starnum_t snum, planetnum_t pnum) {
512 const auto &p =
rd[Num_ships]
.p;
518 rd[Num_ships]
.x = Stars[snum]->xpos + p.xpos;
519 rd[Num_ships]
.y = Stars[snum]->ypos + p.ypos;
522 if (p.info[Playernum - 1].explored) {
523 shipnum_t shn = p.ships;
525 shn =
rd[Num_ships - 1]
.s.nextship;
531 if (
isset(Stars[snum]->explored, Playernum)) {
532 shipnum_t shn = Stars[snum]->ships;
534 shn =
rd[Num_ships - 1]
.s.nextship;
535 for (planetnum_t i = 0; i < Stars[snum]->numplanets; i++)
541 static int Getrship(player_t Playernum, governor_t Governor, shipnum_t shipno) {
542 auto shiptmp = getship(shipno);
544 rd[Num_ships].s = *shiptmp;
546 rd[Num_ships]
.n = shipno;
547 rd[Num_ships]
.x =
rd[Num_ships]
.s.xpos;
548 rd[Num_ships]
.y =
rd[Num_ships]
.s.ypos;
552 sprintf(buf,
"Getrship: error on ship get (%lu).\n", shipno);
553 notify(Playernum, Governor, buf);
559 static int listed(
int type,
char *string) {
562 for (p = string; *p; p++) {
563 if (Shipltrs[type] == *p)
return 1;
static int Getrship(player_t, governor_t, shipnum_t)
#define Distsq(x1, y1, x2, y2)
static unsigned char Stock
static void ship_report(GameObj &, shipnum_t, const report_array &)
int current_caliber(Ship *)
char * Dispshiploc_brief(Ship *ship)
Planet getplanet(const starnum_t star, const planetnum_t pnum)
void rst(const command_t &argv, GameObj &g)
static void plan_getrships(player_t, governor_t, starnum_t, planetnum_t)
static unsigned char Status
static int listed(int, char *)
int hit_odds(double, int *, double, int, int, int, int, int, int, int, int)
static struct reportdata * rd
static unsigned char SHip
static unsigned char Factories
static unsigned char Weapons
static char shiplist[256]
static const char Caliber[]
static void star_getrships(player_t, governor_t, starnum_t)
static unsigned char Report
static unsigned char first