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)
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 ***********************************************************************/
15 #include <fc_config.h>
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 */
57 const struct sship_part_info components_info
[NUM_SS_COMPONENTS
] = {
62 {21, 9, 8}, /* or 4 */
64 {21, 19, 9}, /* or 5 */
76 const struct sship_part_info modules_info
[NUM_SS_MODULES
] = {
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
)
117 for (i
= 0; i
< NUM_SS_STRUCTURALS
; i
++) {
118 if (BV_ISSET(ship
->structure
, i
)) {
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.)
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;
161 fill
->num
= ship
->solar_panels
+ 1;
163 fc_assert(fill
->num
<= NUM_SS_MODULES
/ 3);
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;
172 fill
->type
= SSHIP_PLACE_PROPULSION
;
173 fill
->num
= ship
->propulsion
+ 1;
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.
186 if (!BV_ISSET(ship
->structure
, 0)) {
187 /* if we don't have the first structural, place that! */
188 fill
->type
= SSHIP_PLACE_STRUCTURAL
;
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
;
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
;
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
;
226 for (i
= 0; i
< NUM_SS_STRUCTURALS
; i
++) {
227 if (!BV_ISSET(ship
->structure
, i
)) {
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
;