5 #include "gb/commands/capture.h" 11 #include "gb/GB_server.h" 12 #include "gb/buffers.h" 13 #include "gb/defense.h" 15 #include "gb/files_shl.h" 17 #include "gb/getplace.h" 20 #include "gb/shlmisc.h" 22 #include "gb/tweakables.h" 23 #include "gb/utils/rand.h" 26 void capture(
const command_t &argv, GameObj &g) {
27 const player_t Playernum = g.player;
28 const governor_t Governor = g.governor;
29 const int APcount = 1;
41 population_t olddpopn;
42 population_t olddtroops;
43 population_t casualties = 0;
44 population_t casualties1 = 0;
45 population_t casualties2 = 0;
46 population_t casualty_scale = 0;
52 if (argv.size() < 2) {
53 g.out <<
"Capture what?\n";
56 if (Governor && Stars[g.snum]->governor[Playernum - 1] != Governor) {
57 g.out <<
"You are not authorized in this system.\n";
60 nextshipno = start_shiplist(g, argv[1]);
62 if (ship->owner != Playernum &&
63 in_list(ship->owner, argv[1], *ship, &nextshipno)) {
65 sprintf(buf,
"%s #%ld is not landed on a planet.\n",
66 Shipnames[ship->type], shipno);
67 notify(Playernum, Governor, buf);
71 if (ship->type == ShipType::OTYPE_VN) {
72 g.out <<
"You can't capture Von Neumann machines.\n";
76 if (!
enufAP(Playernum
, Governor
, Stars[ship->storbits]->AP[Playernum - 1]
, 88 if (sect.owner != Playernum) {
90 "You don't own the sector where the ship is landed [%d].\n",
92 notify(Playernum, Governor, buf);
99 else if (argv[3] ==
"civilians")
101 else if (argv[3] ==
"military")
104 g.out <<
"Capture with what?\n";
109 population_t boarders;
110 if (argv.size() < 3) {
112 boarders = sect.popn;
114 boarders = sect.troops;
116 boarders = std::stoul(argv[2]);
119 g.out <<
"Illegal number of boarders.\n";
124 if ((boarders > sect.popn) && what ==
CIV)
125 boarders = sect.popn;
126 else if ((boarders > sect.troops) && what ==
MIL)
127 boarders = sect.troops;
129 Race = races[Playernum - 1];
130 alien = races[ship->owner - 1];
132 if (
isset(Race->allied, (ship->owner))) {
133 sprintf(buf,
"Boarding the ship of your ally, %s\n", alien->name);
134 notify(Playernum, Governor, buf);
137 olddpopn = ship->popn;
138 olddtroops = ship->troops;
139 oldowner = ship->owner;
140 oldgov = ship->governor;
141 bcopy(ship, &s,
sizeof(Ship));
149 sect.popn -= boarders;
150 else if (what ==
MIL)
151 sect.troops -= boarders;
153 if (olddpopn + olddtroops) {
155 buf,
"Attack strength: %.2f Defense strength: %.2f\n",
156 astrength = (
double)boarders *
157 (what ==
MIL ? (
double)Race->fighters * 10.0 : 1.0) *
159 (Race->likes[sect.condition] + 0.01) *
160 ((
double)Defensedata[sect.condition] + 1.0) *
162 dstrength = ((
double)ship->popn + (
double)ship->troops * 10.0 *
163 (
double)alien->fighters) *
164 .01 * alien->tech * ((
double)(armor(*ship)) + 0.01) *
165 .01 * (100.0 - (
double)ship->damage) *
167 notify(Playernum, Governor, buf);
168 casualty_scale = std::min(boarders, ship->popn + ship->troops);
171 int_rand(0, round_rand((
double)casualty_scale *
172 (dstrength + 1.0) / (astrength + 1.0)));
174 if (dstrength > 0.0) {
176 int_rand(0, round_rand((
double)casualty_scale *
177 (astrength + 1.0) / (dstrength + 1.0)));
179 int_rand(0, round_rand((
double)casualty_scale *
180 (astrength + 1.0) / (dstrength + 1.0)));
182 0, round_rand(25. * (astrength + 1.0) / (dstrength + 1.0)));
183 ship->damage = std::min(100, ship->damage + shipdam);
186 casualties = std::min(boarders, casualties);
187 boarders -= casualties;
189 casualties1 = std::min(olddpopn, casualties1);
190 ship->popn -= casualties1;
191 ship->mass -= casualties1 * alien->mass;
193 casualties2 = std::min(olddtroops, casualties2);
194 ship->troops -= casualties2;
195 ship->mass -= casualties2 * alien->mass;
197 }
else if (ship->destruct) {
198 booby = int_rand(0, 10 * ship->destruct);
199 booby = std::min(100, booby);
200 casualties = casualties2 = 0;
201 for (
unsigned long i = 0; i < boarders; i++)
202 casualties += (int_rand(1, 100) < booby);
203 boarders -= casualties;
205 ship->damage += booby;
207 shipdam = std::min(100, shipdam);
208 if (ship->damage >= 100) kill_ship(Playernum, ship);
210 if (!(ship->popn + ship->troops) && ship->alive) {
212 ship->owner = Playernum;
213 ship->governor = Governor;
215 ship->popn = std::min(boarders, max_crew(*ship));
216 sect.popn += boarders - ship->popn;
217 ship->mass += ship->popn * Race->mass;
218 }
else if (what ==
MIL) {
219 ship->troops = std::min(boarders, max_mil(*ship));
220 sect.troops += boarders - ship->troops;
221 ship->mass += ship->troops * Race->mass;
223 if (olddpopn + olddtroops && ship->type != ShipType::OTYPE_FACTORY)
224 adjust_morale(Race, alien, ship->build_cost);
228 sect.popn += boarders;
229 else if (what ==
MIL)
230 sect.troops += boarders;
233 if (!(sect.popn + sect.troops)) sect.owner = 0;
235 sprintf(buf,
"BULLETIN from %s/%s!!\n", Stars[ship->storbits]->name,
236 Stars[ship->storbits]->pnames[ship->pnumorbits]);
237 strcpy(telegram_buf, buf);
239 buf,
"You are being attacked by%s Player #%d (%s)!!!\n",
240 (
isset(alien->allied, Playernum)
242 : (
isset(alien->atwar, Playernum) ?
" your enemy" :
" neutral")),
243 Playernum, Race->name);
244 strcat(telegram_buf, buf);
245 sprintf(buf,
"%s at sector %d,%d [owner %d] !\n",
246 ship_to_string(*ship).c_str(), x, y, sect.owner);
247 strcat(telegram_buf, buf);
250 sprintf(buf,
"Booby trap triggered causing %d%% damage.\n", booby);
251 strcat(telegram_buf, buf);
252 notify(Playernum, Governor, buf);
256 sprintf(buf,
"Total damage: %d%% (now %d%%)\n", shipdam, ship->damage);
257 strcat(telegram_buf, buf);
258 sprintf(buf,
"Damage inflicted: Them: %d%% (now %d%%)\n", shipdam,
260 notify(Playernum, Governor, buf);
264 sprintf(buf,
" YOUR SHIP WAS DESTROYED!!!\n");
265 strcat(telegram_buf, buf);
266 g.out <<
" Their ship DESTROYED!!!\n";
267 sprintf(short_buf,
"%s: %s [%d] DESTROYED %s\n", Dispshiploc(ship),
268 Race->name, Playernum, ship_to_string(s).c_str());
271 if (ship->owner == Playernum) {
272 sprintf(buf,
"%s CAPTURED!\n", ship_to_string(s).c_str());
273 notify(oldowner, oldgov, buf);
274 sprintf(buf,
"VICTORY! The ship is yours!\n");
275 notify(Playernum, Governor, buf);
277 sprintf(buf,
"%lu boarders move in.\n",
278 std::min(boarders, ship->popn));
279 else if (what ==
MIL)
280 sprintf(buf,
"%lu troops move in.\n",
281 std::min(boarders, ship->troops));
282 notify(Playernum, Governor, buf);
283 capture_stuff(*ship, g);
284 sprintf(short_buf,
"%s: %s [%d] CAPTURED %s\n", Dispshiploc(ship),
285 Race->name, Playernum, ship_to_string(s).c_str());
286 }
else if (ship->popn + ship->troops) {
287 sprintf(buf,
"You fought them off!\n");
288 notify(oldowner, oldgov, buf);
289 g.out <<
"The boarding was repulsed; try again.\n";
290 sprintf(short_buf,
"%s: %s [%d] assaults %s\n", Dispshiploc(ship),
291 Race->name, Playernum, ship_to_string(s).c_str());
294 if (sect.popn + sect.troops + boarders) {
295 sprintf(buf,
"You killed all the aliens in this sector!\n");
296 strcat(telegram_buf, buf);
297 p.info[Playernum - 1].mob_points -= sect.mobilization;
300 g.out <<
"Oh no! They killed your party to the last man!\n";
303 sprintf(buf,
"Your ship was weakened too much!\n");
304 strcat(telegram_buf, buf);
305 g.out <<
"The assault weakened their ship too much!\n";
308 if (casualties || casualties1 || casualties2) {
309 sprintf(buf,
"Casualties: Yours: %ld civ/%ld mil, Theirs: %ld %s\n",
310 casualties1, casualties2, casualties,
311 what ==
CIV ?
"civ" :
"mil");
312 strcat(telegram_buf, buf);
313 sprintf(buf,
"Casualties: Yours: %ld %s, Theirs: %ld civ/%ld mil\n",
314 casualties, what ==
CIV ?
"civ" :
"mil", casualties1,
316 notify(Playernum, Governor, buf);
318 warn(oldowner, oldgov, telegram_buf);
319 if (ship->owner != oldowner || !ship->alive)
post(short_buf
, COMBAT);
320 notify_star(Playernum, Governor, ship->storbits, short_buf);
void post(const char *origmsg, int type)
double morale_factor(double x)
Planet getplanet(const starnum_t star, const planetnum_t pnum)
void putsector(const Sector &s, const Planet &p, const int x, const int y)
void deductAPs(const player_t Playernum, const governor_t Governor, unsigned int n, starnum_t snum, int sdata)
int enufAP(int Playernum, int Governor, unsigned short AP, int x)
void capture(const command_t &argv, GameObj &g)
shipnum_t do_shiplist(Ship **s, shipnum_t *nextshipno)
void putplanet(const Planet &p, startype *star, const int pnum)
Sector getsector(const Planet &p, const int x, const int y)