Galactic Bloodshed
bombard.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/bombard.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/files.h"
14 #include "gb/files_shl.h"
15 #include "gb/max.h"
16 #include "gb/perm.h"
17 #include "gb/races.h"
18 #include "gb/ships.h"
19 #include "gb/shootblast.h"
20 #include "gb/tele.h"
21 #include "gb/tweakables.h"
22 #include "gb/vars.h"
23 
24 /* ship #shipno bombards planet, then alert whom it may concern.
25  */
26 int bombard(Ship *ship, Planet *planet, Race *r) {
27  int x;
28  int y;
29  int x2 = -1;
30  int y2;
31  int oldown;
32  int numdest = 0;
33 
34  /* for telegramming */
35  bzero((char *)Nuked, sizeof(Nuked));
36 
37  /* check to see if PDNs are present */
38  Shiplist shiplist(planet->ships);
39  for (auto s : shiplist) {
40  if (s.alive && s.type == ShipType::OTYPE_PLANDEF &&
41  s.owner != ship->owner) {
42  sprintf(buf, "Bombardment of %s cancelled, PDNs are present.\n",
43  prin_ship_orbits(ship));
44  warn(ship->owner, ship->governor, buf);
45  return 0;
46  }
47  }
48 
49  auto smap = getsmap(*planet);
50 
51  /* look for someone to bombard-check for war */
52  (void)Getxysect(*planet, nullptr, nullptr, 1); /* reset */
53  bool found = false;
54  while (!found && Getxysect(*planet, &x, &y, 0)) {
55  if (smap.get(x, y).owner && smap.get(x, y).owner != ship->owner &&
56  (smap.get(x, y).condition != SectorType::SEC_WASTED)) {
57  if (isset(r->atwar, smap.get(x, y).owner) ||
58  (ship->type == ShipType::OTYPE_BERS &&
59  smap.get(x, y).owner == ship->special.mind.target))
60  found = true;
61  else {
62  x2 = x;
63  y2 = y;
64  }
65  }
66  }
67  if (x2 != -1) {
68  x = x2; /* no one we're at war with; bomb someone else. */
69  y = y2;
70  found = true;
71  }
72 
73  if (found) {
74  int str;
75  str = MIN(Shipdata[ship->type][ABIL_GUNS] * (100 - ship->damage) / 100.,
76  ship->destruct);
77  /* save owner of destroyed sector */
78  if (str) {
79  bzero(Nuked, sizeof(Nuked));
80  oldown = smap.get(x, y).owner;
81  ship->destruct -= str;
82  ship->mass -= str * MASS_DESTRUCT;
83 
84  numdest = shoot_ship_to_planet(ship, planet, str, x, y, smap, 0, 0,
85  long_buf, short_buf);
86  /* (0=dont get smap) */
87  if (numdest < 0) numdest = 0;
88 
89  /* tell the bombarding player about it.. */
90  sprintf(telegram_buf, "REPORT from ship #%lu\n\n", ship->number);
91  strcat(telegram_buf, short_buf);
92  sprintf(buf, "sector %d,%d (owner %d). %d sectors destroyed.\n", x, y,
93  oldown, numdest);
94  strcat(telegram_buf, buf);
95  notify(ship->owner, ship->governor, telegram_buf);
96 
97  /* notify other player. */
98  sprintf(telegram_buf, "ALERT from planet /%s/%s\n",
99  Stars[ship->storbits]->name,
100  Stars[ship->storbits]->pnames[ship->pnumorbits]);
101  sprintf(buf, "%c%lu%s bombarded sector %d,%d; %d sectors destroyed.\n",
102  Shipltrs[ship->type], ship->number, ship->name, x, y, numdest);
103  strcat(telegram_buf, buf);
104  sprintf(buf, "%c%lu %s [%d] bombards %s/%s\n", Shipltrs[ship->type],
105  ship->number, ship->name, ship->owner,
106  Stars[ship->storbits]->name,
107  Stars[ship->storbits]->pnames[ship->pnumorbits]);
108  for (player_t i = 1; i <= Num_races; i++)
109  if (Nuked[i - 1] && i != ship->owner)
110  warn(i, Stars[ship->storbits]->governor[i - 1], telegram_buf);
111  post(buf, COMBAT);
112 
113  /* enemy planet retaliates along with defending forces */
114  } else {
115  /* no weapons! */
116  if (!ship->notified) {
117  ship->notified = 1;
118  sprintf(telegram_buf,
119  "Bulletin\n\n %c%lu %s has no weapons to bombard with.\n",
120  Shipltrs[ship->type], ship->number, ship->name);
121  warn(ship->owner, ship->governor, telegram_buf);
122  }
123  }
124 
125  putsmap(smap, *planet);
126 
127  } else {
128  /* there were no sectors worth bombing. */
129  if (!ship->notified) {
130  ship->notified = 1;
131  sprintf(telegram_buf, "Report from %c%lu %s\n\n", Shipltrs[ship->type],
132  ship->number, ship->name);
133  sprintf(buf, "Planet /%s/%s has been saturation bombed.\n",
134  Stars[ship->storbits]->name,
135  Stars[ship->storbits]->pnames[ship->pnumorbits]);
136  strcat(telegram_buf, buf);
137  notify(ship->owner, ship->governor, telegram_buf);
138  }
139  }
140  return numdest;
141 }
void post(const char *origmsg, int type)
Definition: tele.cc:63
int bombard(Ship *, Planet *, Race *)
Definition: bombard.cc:26
#define MASS_DESTRUCT
Definition: tweakables.h:100
#define isset(a, i)
Definition: vars.h:312
int shoot_ship_to_planet(Ship *, Planet *, int, int, int, SectorMap &, int, int, char *, char *)
Definition: shootblast.cc:188
#define MIN(x, y)
Definition: tweakables.h:213
char * prin_ship_orbits(Ship *s)
Definition: max.cc:63
void putsmap(SectorMap &map, Planet &p)
Definition: files_shl.cc:1108
SectorMap getsmap(const Planet &p)
Definition: files_shl.cc:522
int Getxysect(const Planet &p, int *x, int *y, int r)
Definition: perm.cc:39
#define COMBAT
Definition: files.h:19