Stop sharing requirement_unit_state_ereq().
[freeciv.git] / common / spaceship.c
blobc82611a9b65f5c018ab846d9d5e707fed77c6b8d
1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 #include "shared.h" /* TRUE, FALSE */
20 #include "spaceship.h"
22 const struct sship_part_info structurals_info[NUM_SS_STRUCTURALS] = {
23 {19, 13, -1}, /* -1 means none required */
24 {19, 15, 0},
25 {19, 11, 0},
26 {19, 17, 1},
27 {19, 9, 2},
28 {19, 19, 3},
29 {17, 9, 4},
30 {17, 19, 5},
31 {21, 11, 2},
32 {21, 17, 3},
33 {15, 9, 6},
34 {15, 19, 7},
35 {23, 11, 8},
36 {23, 17, 9},
37 {13, 9, 10},
38 {13, 19, 11},
39 {11, 9, 14},
40 {11, 19, 15},
41 { 9, 9, 16},
42 { 9, 19, 17},
43 { 7, 9, 18},
44 { 7, 19, 19},
45 {19, 7, 4},
46 {19, 21, 5},
47 {19, 5, 22},
48 {19, 23, 23},
49 {21, 5, 24},
50 {21, 23, 25},
51 {23, 5, 26},
52 {23, 23, 27},
53 { 5, 9, 20},
54 { 5, 19, 21}
57 const struct sship_part_info components_info[NUM_SS_COMPONENTS] = {
58 {21, 13, 0},
59 {24, 13, 12},
60 {21, 15, 1},
61 {24, 15, 13},
62 {21, 9, 8}, /* or 4 */
63 {24, 9, 12},
64 {21, 19, 9}, /* or 5 */
65 {24, 19, 13},
66 {21, 7, 22},
67 {24, 7, 28},
68 {21, 21, 23},
69 {24, 21, 29},
70 {21, 3, 26},
71 {24, 3, 28},
72 {21, 25, 27},
73 {24, 25, 29}
76 const struct sship_part_info modules_info[NUM_SS_MODULES] = {
77 {16, 12, 0},
78 {16, 16, 1},
79 {14, 6, 10},
80 {12, 16, 15},
81 {12, 12, 14},
82 {14, 22, 11},
83 { 8, 12, 18},
84 { 8, 16, 19},
85 { 6, 6, 20},
86 { 4, 16, 31},
87 { 4, 12, 30},
88 { 6, 22, 21}
91 /**********************************************************************
92 Initialize spaceship struct; could also be used to "cancel" a
93 spaceship (eg, if/when capital-capture effect implemented).
94 **********************************************************************/
95 void spaceship_init(struct player_spaceship *ship)
97 ship->structurals = ship->components = ship->modules = 0;
98 BV_CLR_ALL(ship->structure);
99 ship->fuel = ship->propulsion = 0;
100 ship->habitation = ship->life_support = ship->solar_panels = 0;
101 ship->state = SSHIP_NONE;
102 ship->launch_year = 9999;
104 ship->population = ship->mass = 0;
105 ship->support_rate = ship->energy_rate =
106 ship->success_rate = ship->travel_time = 0.0;
109 /**********************************************************************
110 Count the number of structurals placed; that is, in ship->structure[]
111 **********************************************************************/
112 int num_spaceship_structurals_placed(const struct player_spaceship *ship)
114 int i;
115 int num = 0;
117 for (i = 0; i < NUM_SS_STRUCTURALS; i++) {
118 if (BV_ISSET(ship->structure, i)) {
119 num++;
123 return num;
126 /****************************************************************************
127 Find (default) place for next spaceship component.
128 ****************************************************************************/
129 bool next_spaceship_component(struct player *pplayer,
130 struct player_spaceship *ship,
131 struct spaceship_component *fill)
133 fc_assert_ret_val(fill != NULL, FALSE);
135 if (ship->modules > (ship->habitation + ship->life_support
136 + ship->solar_panels)) {
137 /* "nice" governments prefer to keep success 100%;
138 * others build habitation first (for score?) (Thanks Massimo.)
140 fill->type =
141 (ship->habitation == 0) ? SSHIP_PLACE_HABITATION :
142 (ship->life_support == 0) ? SSHIP_PLACE_LIFE_SUPPORT :
143 (ship->solar_panels == 0) ? SSHIP_PLACE_SOLAR_PANELS :
144 ((ship->habitation < ship->life_support)
145 && (ship->solar_panels*2 >= ship->habitation + ship->life_support + 1))
146 ? SSHIP_PLACE_HABITATION :
147 (ship->solar_panels*2 < ship->habitation + ship->life_support)
148 ? SSHIP_PLACE_SOLAR_PANELS :
149 (ship->life_support < ship->habitation)
150 ? SSHIP_PLACE_LIFE_SUPPORT :
151 ((ship->life_support <= ship->habitation)
152 && (ship->solar_panels * 2 >= ship->habitation + ship->life_support + 1))
153 ? SSHIP_PLACE_LIFE_SUPPORT :
154 SSHIP_PLACE_SOLAR_PANELS;
156 if (fill->type == SSHIP_PLACE_HABITATION) {
157 fill->num = ship->habitation + 1;
158 } else if (fill->type == SSHIP_PLACE_LIFE_SUPPORT) {
159 fill->num = ship->life_support + 1;
160 } else {
161 fill->num = ship->solar_panels + 1;
163 fc_assert(fill->num <= NUM_SS_MODULES / 3);
165 return TRUE;
167 if (ship->components > ship->fuel + ship->propulsion) {
168 if (ship->fuel <= ship->propulsion) {
169 fill->type = SSHIP_PLACE_FUEL;
170 fill->num = ship->fuel + 1;
171 } else {
172 fill->type = SSHIP_PLACE_PROPULSION;
173 fill->num = ship->propulsion + 1;
175 return TRUE;
177 if (ship->structurals > num_spaceship_structurals_placed(ship)) {
178 /* Want to choose which structurals are most important.
179 Else we first want to connect one of each type of module,
180 then all placed components, pairwise, then any remaining
181 modules, or else finally in numerical order.
183 int req = -1;
184 int i;
186 if (!BV_ISSET(ship->structure, 0)) {
187 /* if we don't have the first structural, place that! */
188 fill->type = SSHIP_PLACE_STRUCTURAL;
189 fill->num = 0;
190 return TRUE;
193 if (ship->habitation >= 1
194 && !BV_ISSET(ship->structure, modules_info[0].required)) {
195 req = modules_info[0].required;
196 } else if (ship->life_support >= 1
197 && !BV_ISSET(ship->structure, modules_info[1].required)) {
198 req = modules_info[1].required;
199 } else if (ship->solar_panels >= 1
200 && !BV_ISSET(ship->structure, modules_info[2].required)) {
201 req = modules_info[2].required;
202 } else {
203 for (i = 0; i < NUM_SS_COMPONENTS; i++) {
204 if ((i % 2 == 0 && ship->fuel > (i/2))
205 || (i % 2 == 1 && ship->propulsion > (i/2))) {
206 if (!BV_ISSET(ship->structure, components_info[i].required)) {
207 req = components_info[i].required;
208 break;
213 if (req == -1) {
214 for (i = 0; i < NUM_SS_MODULES; i++) {
215 if ((i % 3 == 0 && ship->habitation > (i/3))
216 || (i % 3 == 1 && ship->life_support > (i/3))
217 || (i % 3 == 2 && ship->solar_panels > (i/3))) {
218 if (!BV_ISSET(ship->structure, modules_info[i].required)) {
219 req = modules_info[i].required;
220 break;
225 if (req == -1) {
226 for (i = 0; i < NUM_SS_STRUCTURALS; i++) {
227 if (!BV_ISSET(ship->structure, i)) {
228 req = i;
229 break;
233 /* sanity: */
234 fc_assert(req != -1);
235 fc_assert(!BV_ISSET(ship->structure, req));
237 /* Now we want to find a structural we can build which leads to req.
238 This loop should bottom out, because everything leads back to s0,
239 and we made sure above that we do s0 first.
241 while (!BV_ISSET(ship->structure, structurals_info[req].required)) {
242 req = structurals_info[req].required;
244 fill->type = SSHIP_PLACE_STRUCTURAL;
245 fill->num = req;
247 return TRUE;
250 return FALSE;