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
)
115 for(i
=0; i
<NUM_SS_STRUCTURALS
; i
++) {
116 if (BV_ISSET(ship
->structure
, i
)) num
++;
121 /****************************************************************************
122 Find (default) place for next spaceship component.
123 ****************************************************************************/
124 bool next_spaceship_component(struct player
*pplayer
,
125 struct player_spaceship
*ship
,
126 struct spaceship_component
*fill
)
128 fc_assert_ret_val(fill
!= NULL
, FALSE
);
130 if (ship
->modules
> (ship
->habitation
+ ship
->life_support
131 + ship
->solar_panels
)) {
132 /* "nice" governments prefer to keep success 100%;
133 * others build habitation first (for score?) (Thanks Massimo.)
136 (ship
->habitation
== 0) ? SSHIP_PLACE_HABITATION
:
137 (ship
->life_support
== 0) ? SSHIP_PLACE_LIFE_SUPPORT
:
138 (ship
->solar_panels
== 0) ? SSHIP_PLACE_SOLAR_PANELS
:
139 ((ship
->habitation
< ship
->life_support
)
140 && (ship
->solar_panels
*2 >= ship
->habitation
+ ship
->life_support
+ 1))
141 ? SSHIP_PLACE_HABITATION
:
142 (ship
->solar_panels
*2 < ship
->habitation
+ ship
->life_support
)
143 ? SSHIP_PLACE_SOLAR_PANELS
:
144 (ship
->life_support
< ship
->habitation
)
145 ? SSHIP_PLACE_LIFE_SUPPORT
:
146 ((ship
->life_support
<= ship
->habitation
)
147 && (ship
->solar_panels
* 2 >= ship
->habitation
+ ship
->life_support
+ 1))
148 ? SSHIP_PLACE_LIFE_SUPPORT
:
149 SSHIP_PLACE_SOLAR_PANELS
;
151 if (fill
->type
== SSHIP_PLACE_HABITATION
) {
152 fill
->num
= ship
->habitation
+ 1;
153 } else if (fill
->type
== SSHIP_PLACE_LIFE_SUPPORT
) {
154 fill
->num
= ship
->life_support
+ 1;
156 fill
->num
= ship
->solar_panels
+ 1;
158 fc_assert(fill
->num
<= NUM_SS_MODULES
/ 3);
162 if (ship
->components
> ship
->fuel
+ ship
->propulsion
) {
163 if (ship
->fuel
<= ship
->propulsion
) {
164 fill
->type
= SSHIP_PLACE_FUEL
;
165 fill
->num
= ship
->fuel
+ 1;
167 fill
->type
= SSHIP_PLACE_PROPULSION
;
168 fill
->num
= ship
->propulsion
+ 1;
172 if (ship
->structurals
> num_spaceship_structurals_placed(ship
)) {
173 /* Want to choose which structurals are most important.
174 Else we first want to connect one of each type of module,
175 then all placed components, pairwise, then any remaining
176 modules, or else finally in numerical order.
181 if (!BV_ISSET(ship
->structure
, 0)) {
182 /* if we don't have the first structural, place that! */
183 fill
->type
= SSHIP_PLACE_STRUCTURAL
;
188 if (ship
->habitation
>= 1
189 && !BV_ISSET(ship
->structure
, modules_info
[0].required
)) {
190 req
= modules_info
[0].required
;
191 } else if (ship
->life_support
>= 1
192 && !BV_ISSET(ship
->structure
, modules_info
[1].required
)) {
193 req
= modules_info
[1].required
;
194 } else if (ship
->solar_panels
>= 1
195 && !BV_ISSET(ship
->structure
, modules_info
[2].required
)) {
196 req
= modules_info
[2].required
;
198 for (i
= 0; i
< NUM_SS_COMPONENTS
; i
++) {
199 if ((i
% 2 == 0 && ship
->fuel
> (i
/2))
200 || (i
% 2 == 1 && ship
->propulsion
> (i
/2))) {
201 if (!BV_ISSET(ship
->structure
, components_info
[i
].required
)) {
202 req
= components_info
[i
].required
;
209 for (i
= 0; i
< NUM_SS_MODULES
; i
++) {
210 if ((i
% 3 == 0 && ship
->habitation
> (i
/3))
211 || (i
% 3 == 1 && ship
->life_support
> (i
/3))
212 || (i
% 3 == 2 && ship
->solar_panels
> (i
/3))) {
213 if (!BV_ISSET(ship
->structure
, modules_info
[i
].required
)) {
214 req
= modules_info
[i
].required
;
221 for (i
= 0; i
< NUM_SS_STRUCTURALS
; i
++) {
222 if (!BV_ISSET(ship
->structure
, i
)) {
229 fc_assert(req
!= -1);
230 fc_assert(!BV_ISSET(ship
->structure
, req
));
232 /* Now we want to find a structural we can build which leads to req.
233 This loop should bottom out, because everything leads back to s0,
234 and we made sure above that we do s0 first.
236 while(!BV_ISSET(ship
->structure
, structurals_info
[req
].required
)) {
237 req
= structurals_info
[req
].required
;
239 fill
->type
= SSHIP_PLACE_STRUCTURAL
;