Galactic Bloodshed
moveship.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 /* moveship -- moves specified ship according to its orders.
6  * also deducts fuel from the ship's stores. */
7 
8 #include "gb/moveship.h"
9 
10 #include <cmath>
11 #include <cstdio>
12 #include <cstdlib>
13 #include <cstring>
14 
15 #include "gb/GB_server.h"
16 #include "gb/buffers.h"
17 #include "gb/files_shl.h"
18 #include "gb/fire.h"
19 #include "gb/load.h"
20 #include "gb/max.h"
21 #include "gb/misc.h"
22 #include "gb/order.h"
23 #include "gb/races.h"
24 #include "gb/ships.h"
25 #include "gb/shlmisc.h"
26 #include "gb/tele.h"
27 #include "gb/tweakables.h"
28 #include "gb/vars.h"
29 
30 /* amount to move for each dir level. I arrived on these #'s only after
31  hours of dilligent tweaking */
32 /* amount to move for each directory level */
33 static const double MoveConsts[] = {600.0, 300.0, 50.0};
34 /* amnt to move for each ship speed level (ordered) */
35 static const double SpeedConsts[] = {0.0, 0.61, 1.26, 1.50, 1.73,
36  1.81, 1.90, 1.93, 1.96, 1.97};
37 /* amount of fuel it costs to move at speed level */
38 
39 static int do_merchant(Ship *, Planet *);
40 
41 void moveship(Ship *s, int mode, int send_messages, int checking_fuel) {
42  double stardist;
43  double movedist;
44  double truedist;
45  double dist;
46  double xdest;
47  double ydest;
48  double sn;
49  double cs;
50  double mfactor;
51  double heading;
52  double distfac;
53  double fuse;
54  ScopeLevel destlevel;
55  int deststar = 0;
56  int destpnum = 0;
57  Ship *dsh;
58  startype *ost;
59  startype *dst;
60 
61  if (s->hyper_drive.has && s->hyper_drive.on) { /* do a hyperspace jump */
62  if (!mode) return; /* we're not ready to jump until the update */
63  if (s->hyper_drive.ready) {
64  dist = sqrt(Distsq(s->xpos, s->ypos, Stars[s->deststar]->xpos,
65  Stars[s->deststar]->ypos));
66  distfac = HYPER_DIST_FACTOR * (s->tech + 100.0);
67  if (s->mounted && dist > distfac)
68  fuse = HYPER_DRIVE_FUEL_USE * sqrt(s->mass) * (dist / distfac);
69  else
70  fuse = HYPER_DRIVE_FUEL_USE * sqrt(s->mass) * (dist / distfac) *
71  (dist / distfac);
72 
73  if (s->fuel < fuse) {
74  sprintf(telegram_buf,
75  "%s at system %s does not have %.1ff to do hyperspace jump.",
76  ship_to_string(*s).c_str(), prin_ship_orbits(s), fuse);
77  if (send_messages)
78  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
79  s->hyper_drive.on = 0;
80  return;
81  }
82  use_fuel(s, fuse);
83  heading = atan2(Stars[s->deststar]->xpos - s->xpos,
84  Stars[s->deststar]->ypos - s->ypos);
85  sn = sin(heading);
86  cs = cos(heading);
87  s->xpos = Stars[s->deststar]->xpos - sn * 0.9 * SYSTEMSIZE;
88  s->ypos = Stars[s->deststar]->ypos - cs * 0.9 * SYSTEMSIZE;
89  s->whatorbits = ScopeLevel::LEVEL_STAR;
90  s->storbits = s->deststar;
91  s->protect.planet = 0;
92  s->hyper_drive.on = 0;
93  s->hyper_drive.ready = 0;
94  s->hyper_drive.charge = 0;
95  sprintf(telegram_buf, "%s arrived at %s.", ship_to_string(*s).c_str(),
96  prin_ship_orbits(s));
97  if (send_messages)
98  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
99  } else if (s->mounted) {
100  s->hyper_drive.ready = 1;
101  s->hyper_drive.charge = HYPER_DRIVE_READY_CHARGE;
102  } else {
103  if (s->hyper_drive.charge == HYPER_DRIVE_READY_CHARGE)
104  s->hyper_drive.ready = 1;
105  else
106  s->hyper_drive.charge += 1;
107  }
108  return;
109  }
110  if (s->speed && !s->docked && s->alive &&
111  (s->whatdest != ScopeLevel::LEVEL_UNIV || s->navigate.on)) {
112  fuse = 0.5 * s->speed * (1 + s->protect.evade) * s->mass * FUEL_USE /
113  (double)segments;
114  if (s->fuel < fuse) {
115  if (send_messages) msg_OOF(s); /* send OOF notify */
116  if (s->whatorbits == ScopeLevel::LEVEL_UNIV &&
117  (s->build_cost <= 50 || s->type == ShipType::OTYPE_VN ||
118  s->type == ShipType::OTYPE_BERS)) {
119  sprintf(telegram_buf, "%s has been lost in deep space.",
120  ship_to_string(*s).c_str());
121  if (send_messages)
122  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
123  if (send_messages) kill_ship((int)(s->owner), s);
124  }
125  return;
126  }
127  if (s->navigate.on) { /* follow navigational orders */
128  heading = .0174329252 * s->navigate.bearing;
129  mfactor = SHIP_MOVE_SCALE * (1.0 - .01 * s->rad) *
130  (1.0 - .01 * s->damage) * SpeedConsts[s->speed] *
131  MoveConsts[s->whatorbits] / (double)segments;
132  use_fuel(s, (double)fuse);
133  sn = sin(heading);
134  cs = cos(heading);
135  xdest = sn * mfactor;
136  ydest = -cs * mfactor;
137  s->xpos += xdest;
138  s->ypos += ydest;
139  s->navigate.turns--;
140  if (!s->navigate.turns) s->navigate.on = 0;
141  /* check here for orbit breaking as well. Maarten */
142  ost = Stars[s->storbits];
143  const auto &opl = planets[s->storbits][s->pnumorbits];
144  if (s->whatorbits == ScopeLevel::LEVEL_PLAN) {
145  dist = sqrt(Distsq(s->xpos, s->ypos, ost->xpos + opl->xpos,
146  ost->ypos + opl->ypos));
147  if (dist > PLORBITSIZE) {
148  s->whatorbits = ScopeLevel::LEVEL_STAR;
149  s->protect.planet = 0;
150  }
151  } else if (s->whatorbits == ScopeLevel::LEVEL_STAR) {
152  dist = sqrt(Distsq(s->xpos, s->ypos, ost->xpos, ost->ypos));
153  if (dist > SYSTEMSIZE) {
154  s->whatorbits = ScopeLevel::LEVEL_UNIV;
155  s->protect.evade = 0;
156  s->protect.planet = 0;
157  }
158  }
159  } else { /* navigate is off */
160  destlevel = s->whatdest;
161  if (destlevel == ScopeLevel::LEVEL_SHIP) {
162  dsh = ships[s->destshipno];
163  s->deststar = dsh->storbits;
164  s->destpnum = dsh->pnumorbits;
165  xdest = dsh->xpos;
166  ydest = dsh->ypos;
167  switch (dsh->whatorbits) {
168  case ScopeLevel::LEVEL_UNIV:
169  break;
170  case ScopeLevel::LEVEL_PLAN:
171  if (s->whatorbits != dsh->whatorbits ||
172  s->pnumorbits != dsh->pnumorbits)
173  destlevel = ScopeLevel::LEVEL_PLAN;
174  break;
175  case ScopeLevel::LEVEL_STAR:
176  if (s->whatorbits != dsh->whatorbits ||
177  s->storbits != dsh->storbits)
178  destlevel = ScopeLevel::LEVEL_STAR;
179  break;
180  case ScopeLevel::LEVEL_SHIP:
181  // TODO(jeffbailey): Prove that this is impossible.
182  break;
183  }
184  /* if (sqrt( (double)Distsq(s->xpos, s->ypos,
185  xdest,
186  ydest))
187  <= DIST_TO_LAND || !(dsh->alive)) {
188  destlevel = ScopeLevel::LEVEL_UNIV;
189  s->whatdest=ScopeLevel::LEVEL_UNIV;
190  } */
191  }
192  /* else */
193  if (destlevel == ScopeLevel::LEVEL_STAR ||
194  (destlevel == ScopeLevel::LEVEL_PLAN &&
195  (s->storbits != s->deststar ||
196  s->whatorbits == ScopeLevel::LEVEL_UNIV))) {
197  destlevel = ScopeLevel::LEVEL_STAR;
198  deststar = s->deststar;
199  xdest = Stars[deststar]->xpos;
200  ydest = Stars[deststar]->ypos;
201  } else if (destlevel == ScopeLevel::LEVEL_PLAN &&
202  s->storbits == s->deststar) {
203  destlevel = ScopeLevel::LEVEL_PLAN;
204  deststar = s->deststar;
205  destpnum = s->destpnum;
206  xdest = Stars[deststar]->xpos + planets[deststar][destpnum]->xpos;
207  ydest = Stars[deststar]->ypos + planets[deststar][destpnum]->ypos;
208  if (sqrt(Distsq(s->xpos, s->ypos, xdest, ydest)) <= DIST_TO_LAND)
209  destlevel = ScopeLevel::LEVEL_UNIV;
210  }
211  dst = Stars[deststar];
212  ost = Stars[s->storbits];
213  const auto &dpl = planets[deststar][destpnum];
214  const auto &opl = planets[s->storbits][s->pnumorbits];
215  truedist = movedist = sqrt(Distsq(s->xpos, s->ypos, xdest, ydest));
216  /* Save some unneccesary calculation and domain errors for atan2
217  Maarten */
218  if (truedist < DIST_TO_LAND && s->whatorbits == destlevel &&
219  s->storbits == deststar && s->pnumorbits == destpnum)
220  return;
221  heading = atan2((double)(xdest - s->xpos), (double)(-ydest + s->ypos));
222  mfactor = SHIP_MOVE_SCALE * (1. - .01 * (double)s->rad) *
223  (1. - .01 * (double)s->damage) * SpeedConsts[s->speed] *
224  MoveConsts[s->whatorbits] / (double)segments;
225 
226  /* keep from ending up in the middle of the system. */
227  if (destlevel == ScopeLevel::LEVEL_STAR &&
228  (s->storbits != deststar || s->whatorbits == ScopeLevel::LEVEL_UNIV))
229  movedist -= SYSTEMSIZE * 0.90;
230  else if (destlevel == ScopeLevel::LEVEL_PLAN &&
231  s->whatorbits == ScopeLevel::LEVEL_STAR &&
232  s->storbits == deststar && truedist >= PLORBITSIZE)
233  movedist -= PLORBITSIZE * 0.90;
234 
235  if (s->whatdest == ScopeLevel::LEVEL_SHIP &&
236  !followable(s, ships[s->destshipno])) {
237  s->whatdest = ScopeLevel::LEVEL_UNIV;
238  s->protect.evade = 0;
239  sprintf(telegram_buf, "%s at %s lost sight of destination ship #%ld.",
240  ship_to_string(*s).c_str(), prin_ship_orbits(s), s->destshipno);
241  if (send_messages)
242  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
243  return;
244  }
245  if (truedist > DIST_TO_LAND) {
246  use_fuel(s, (double)fuse);
247  /* dont overshoot */
248  sn = sin(heading);
249  cs = cos(heading);
250  xdest = sn * mfactor;
251  ydest = -cs * mfactor;
252  if (hypot(xdest, ydest) > movedist) {
253  xdest = sn * movedist;
254  ydest = -cs * movedist;
255  }
256  s->xpos += xdest;
257  s->ypos += ydest;
258  }
259  /***** check if far enough away from object it's orbiting to break orbit
260  * *****/
261  if (s->whatorbits == ScopeLevel::LEVEL_PLAN) {
262  dist = sqrt(Distsq(s->xpos, s->ypos, ost->xpos + opl->xpos,
263  ost->ypos + opl->ypos));
264  if (dist > PLORBITSIZE) {
265  s->whatorbits = ScopeLevel::LEVEL_STAR;
266  s->protect.planet = 0;
267  }
268  } else if (s->whatorbits == ScopeLevel::LEVEL_STAR) {
269  dist = sqrt(Distsq(s->xpos, s->ypos, ost->xpos, ost->ypos));
270  if (dist > SYSTEMSIZE) {
271  s->whatorbits = ScopeLevel::LEVEL_UNIV;
272  s->protect.evade = 0;
273  s->protect.planet = 0;
274  }
275  }
276 
277  /******* check for arriving at destination *******/
278  if (destlevel == ScopeLevel::LEVEL_STAR ||
279  (destlevel == ScopeLevel::LEVEL_PLAN &&
280  (s->storbits != deststar ||
281  s->whatorbits == ScopeLevel::LEVEL_UNIV))) {
282  stardist = sqrt(Distsq(s->xpos, s->ypos, dst->xpos, dst->ypos));
283  if (stardist <= SYSTEMSIZE * 1.5) {
284  s->whatorbits = ScopeLevel::LEVEL_STAR;
285  s->protect.planet = 0;
286  s->storbits = deststar;
287  /* if this system isn't inhabited by you, give it to the
288  governor of the ship */
289  if (!checking_fuel && (s->popn || s->type == ShipType::OTYPE_PROBE)) {
290  if (!isset(dst->inhabited, (int)s->owner))
291  dst->governor[s->owner - 1] = s->governor;
292  setbit(dst->explored, (int)s->owner);
293  setbit(dst->inhabited, (int)s->owner);
294  }
295  if (s->type != ShipType::OTYPE_VN) {
296  sprintf(telegram_buf, "%s arrived at %s.",
297  ship_to_string(*s).c_str(), prin_ship_orbits(s));
298  if (send_messages)
299  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
300  }
301  if (s->whatdest == ScopeLevel::LEVEL_STAR)
302  s->whatdest = ScopeLevel::LEVEL_UNIV;
303  }
304  } else if (destlevel == ScopeLevel::LEVEL_PLAN &&
305  deststar == s->storbits) {
306  /* headed for a planet in the same system, & not already there.. */
307  dist = sqrt(Distsq(s->xpos, s->ypos, dst->xpos + dpl->xpos,
308  dst->ypos + dpl->ypos));
309  if (dist <= PLORBITSIZE) {
310  if (!checking_fuel && (s->popn || s->type == ShipType::OTYPE_PROBE)) {
311  dpl->info[s->owner - 1].explored = 1;
312  setbit(dst->explored, (int)(s->owner));
313  setbit(dst->inhabited, (int)(s->owner));
314  }
315  s->whatorbits = ScopeLevel::LEVEL_PLAN;
316  s->pnumorbits = destpnum;
317  if (dist <= (double)DIST_TO_LAND) {
318  sprintf(telegram_buf, "%s within landing distance of %s.",
319  ship_to_string(*s).c_str(), prin_ship_orbits(s));
320  if (checking_fuel || !do_merchant(s, dpl))
321  if (s->whatdest == ScopeLevel::LEVEL_PLAN)
322  s->whatdest = ScopeLevel::LEVEL_UNIV;
323  } else {
324  sprintf(telegram_buf, "%s arriving at %s.",
325  ship_to_string(*s).c_str(), prin_ship_orbits(s));
326  }
327  if (s->type == ShipType::STYPE_OAP) {
328  sprintf(buf, "\nEnslavement of the planet is now possible.");
329  strcat(telegram_buf, buf);
330  }
331  if (send_messages && s->type != ShipType::OTYPE_VN)
332  push_telegram((int)(s->owner), (int)s->governor, telegram_buf);
333  }
334  } else if (destlevel == ScopeLevel::LEVEL_SHIP) {
335  dist = sqrt(Distsq(s->xpos, s->ypos, dsh->xpos, dsh->ypos));
336  if (dist <= PLORBITSIZE) {
337  if (dsh->whatorbits == ScopeLevel::LEVEL_PLAN) {
338  s->whatorbits = ScopeLevel::LEVEL_PLAN;
339  s->storbits = dsh->storbits;
340  s->pnumorbits = dsh->pnumorbits;
341  } else if (dsh->whatorbits == ScopeLevel::LEVEL_STAR) {
342  s->whatorbits = ScopeLevel::LEVEL_STAR;
343  s->storbits = dsh->storbits;
344  s->protect.planet = 0;
345  }
346  }
347  }
348  } /* 'destination' orders */
349  } /* if impulse drive */
350 }
351 
352 /* deliver an "out of fuel" message. Used by a number of ship-updating
353  * code segments; so that code isn't duplicated.
354  */
355 void msg_OOF(Ship *s) {
356  sprintf(buf, "%s is out of fuel at %s.", ship_to_string(*s).c_str(),
357  prin_ship_orbits(s));
358  push_telegram((int)(s->owner), (int)s->governor, buf);
359 }
360 
361 /* followable: returns 1 iff s1 can follow s2 */
362 int followable(Ship *s1, Ship *s2) {
363  double dx;
364  double dy;
365  Race *r;
366  double range;
367  int allied[2];
368 
369  if (!s2->alive || !s1->active || s2->whatorbits == ScopeLevel::LEVEL_SHIP)
370  return 0;
371 
372  dx = s1->xpos - s2->xpos;
373  dy = s1->ypos - s2->ypos;
374 
375  range = 4.0 * logscale((int)(s1->tech + 1.0)) * SYSTEMSIZE;
376 
377  r = races[s2->owner - 1];
378  allied[0] = r->allied[0];
379  allied[1] = r->allied[1];
380  /* You can follow your own ships, your allies' ships, or nearby ships */
381  return (s1->owner == s2->owner) || (isset(allied, (int)s1->owner)) ||
382  (sqrt(dx * dx + dy * dy) <= range);
383 }
384 
385 /* this routine will do landing, launching, loading, unloading, etc
386  for merchant ships. The ship is within landing distance of
387  the target Planet */
388 static int do_merchant(Ship *s, Planet *p) {
389  int i;
390  int j;
391  double fuel;
392  char load;
393  char unload;
394  int amount;
395 
396  i = s->owner - 1;
397  j = s->merchant - 1; /* try to speed things up a bit */
398 
399  if (!s->merchant || !p->info[i].route[j].set) /* not on shipping route */
400  return 0;
401  /* check to see if the sector is owned by the player */
402  auto sect = getsector(*p, p->info[i].route[j].x, p->info[i].route[j].y);
403  if (sect.owner && (sect.owner != s->owner)) {
404  return 0;
405  }
406 
407  if (!landed(*s)) { /* try to land the ship */
408  fuel = s->mass * gravity(*p) * LAND_GRAV_MASS_FACTOR;
409  if (s->fuel < fuel) { /* ship can't land - cancel all orders */
410  s->whatdest = ScopeLevel::LEVEL_UNIV;
411  strcat(telegram_buf, "\t\tNot enough fuel to land!\n");
412  return 1;
413  }
414  s->land_x = p->info[i].route[j].x;
415  s->land_y = p->info[i].route[j].y;
416  sprintf(buf, "\t\tLanded on sector %d,%d\n", s->land_x, s->land_y);
417  strcat(telegram_buf, buf);
418  s->xpos = p->xpos + Stars[s->storbits]->xpos;
419  s->ypos = p->ypos + Stars[s->storbits]->ypos;
420  use_fuel(s, fuel);
421  s->docked = 1;
422  s->whatdest = ScopeLevel::LEVEL_PLAN;
423  s->deststar = s->storbits;
424  s->destpnum = s->pnumorbits;
425  }
426  /* load and unload supplies specified by the planet */
427  load = p->info[i].route[j].load;
428  unload = p->info[i].route[j].unload;
429  if (load) {
430  strcat(telegram_buf, "\t\t");
431  if (Fuel(load)) {
432  amount = (int)s->max_fuel - (int)s->fuel;
433  if (amount > p->info[i].fuel) amount = p->info[i].fuel;
434  p->info[i].fuel -= amount;
435  rcv_fuel(s, (double)amount);
436  sprintf(buf, "%df ", amount);
437  strcat(telegram_buf, buf);
438  }
439  if (Resources(load)) {
440  amount = (int)s->max_resource - (int)s->resource;
441  if (amount > p->info[i].resource) amount = p->info[i].resource;
442  p->info[i].resource -= amount;
443  rcv_resource(s, amount);
444  sprintf(buf, "%dr ", amount);
445  strcat(telegram_buf, buf);
446  }
447  if (Crystals(load)) {
448  amount = p->info[i].crystals;
449  p->info[i].crystals -= amount;
450  s->crystals += amount;
451  sprintf(buf, "%dx ", amount);
452  strcat(telegram_buf, buf);
453  }
454  if (Destruct(load)) {
455  amount = (int)s->max_destruct - (int)s->destruct;
456  if (amount > p->info[i].destruct) amount = p->info[i].destruct;
457  p->info[i].destruct -= amount;
458  rcv_destruct(s, amount);
459  sprintf(buf, "%dd ", amount);
460  strcat(telegram_buf, buf);
461  }
462  strcat(telegram_buf, "loaded\n");
463  }
464  if (unload) {
465  strcat(telegram_buf, "\t\t");
466  if (Fuel(unload)) {
467  amount = (int)s->fuel;
468  p->info[i].fuel += amount;
469  sprintf(buf, "%df ", amount);
470  strcat(telegram_buf, buf);
471  use_fuel(s, (double)amount);
472  }
473  if (Resources(unload)) {
474  amount = s->resource;
475  p->info[i].resource += amount;
476  sprintf(buf, "%dr ", amount);
477  strcat(telegram_buf, buf);
478  use_resource(s, amount);
479  }
480  if (Crystals(unload)) {
481  amount = s->crystals;
482  p->info[i].crystals += amount;
483  sprintf(buf, "%dx ", amount);
484  strcat(telegram_buf, buf);
485  s->crystals -= amount;
486  }
487  if (Destruct(unload)) {
488  amount = s->destruct;
489  p->info[i].destruct += amount;
490  sprintf(buf, "%dd ", amount);
491  strcat(telegram_buf, buf);
492  use_destruct(s, amount);
493  }
494  strcat(telegram_buf, "unloaded\n");
495  }
496 
497  /* launch the ship */
498  fuel = s->mass * gravity(*p) * LAUNCH_GRAV_MASS_FACTOR;
499  if (s->fuel < fuel) {
500  strcat(telegram_buf, "\t\tNot enough fuel to launch!\n");
501  return 1;
502  }
503  /* ship is ready to fly - order the ship to its next destination */
504  s->whatdest = ScopeLevel::LEVEL_PLAN;
505  s->deststar = p->info[i].route[j].dest_star;
506  s->destpnum = p->info[i].route[j].dest_planet;
507  s->docked = 0;
508  use_fuel(s, fuel);
509  sprintf(buf, "\t\tDestination set to %s\n", prin_ship_dest(*s).c_str());
510  strcat(telegram_buf, buf);
511  if (s->hyper_drive.has) { /* order the ship to jump if it can */
512  if (s->storbits != s->deststar) {
513  s->navigate.on = 0;
514  s->hyper_drive.on = 1;
515  if (s->mounted) {
516  s->hyper_drive.charge = 1;
517  s->hyper_drive.ready = 1;
518  } else {
519  s->hyper_drive.charge = 0;
520  s->hyper_drive.ready = 0;
521  }
522  strcat(telegram_buf, "\t\tJump orders set\n");
523  }
524  }
525  return 1;
526 }
void msg_OOF(Ship *)
Definition: moveship.cc:355
void use_fuel(Ship *s, double amt)
Definition: load.cc:876
#define LAND_GRAV_MASS_FACTOR
Definition: tweakables.h:126
#define Distsq(x1, y1, x2, y2)
Definition: tweakables.h:218
static const double SpeedConsts[]
Definition: moveship.cc:35
#define SYSTEMSIZE
Definition: tweakables.h:81
void rcv_resource(Ship *s, int amt)
Definition: load.cc:896
#define DIST_TO_LAND
Definition: tweakables.h:194
void rcv_fuel(Ship *s, double amt)
Definition: load.cc:891
#define Resources(x)
Definition: vars.h:104
#define Fuel(x)
Definition: vars.h:102
#define isset(a, i)
Definition: vars.h:312
#define setbit(a, i)
Definition: vars.h:310
#define HYPER_DIST_FACTOR
Definition: tweakables.h:160
#define HYPER_DRIVE_FUEL_USE
Definition: tweakables.h:159
#define HYPER_DRIVE_READY_CHARGE
Definition: tweakables.h:158
#define LAUNCH_GRAV_MASS_FACTOR
Definition: tweakables.h:125
int followable(Ship *, Ship *)
Definition: moveship.cc:362
void use_destruct(Ship *s, int amt)
Definition: load.cc:881
#define PLORBITSIZE
Definition: tweakables.h:82
#define Crystals(x)
Definition: vars.h:105
void use_resource(Ship *s, int amt)
Definition: load.cc:886
void moveship(Ship *, int, int, int)
Definition: moveship.cc:41
#define FUEL_USE
Definition: tweakables.h:132
void rcv_destruct(Ship *s, int amt)
Definition: load.cc:901
double gravity(const Planet &p)
Definition: max.cc:59
static const double MoveConsts[]
Definition: moveship.cc:33
static int do_merchant(Ship *, Planet *)
Definition: moveship.cc:388
#define SHIP_MOVE_SCALE
Definition: tweakables.h:207
#define Destruct(x)
Definition: vars.h:103
Sector getsector(const Planet &p, const int x, const int y)
Definition: files_shl.cc:480