Freeciv-3.1: /fast/freeciv/nightly/S3_1/server/spacerace.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
spacerace.c
Go to the documentation of this file.
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.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <string.h>
19
20/* utility */
21#include "fcintl.h"
22#include "log.h"
23#include "shared.h"
24
25/* common */
26#include "calendar.h"
27#include "events.h"
28#include "game.h"
29#include "packets.h"
30#include "spaceship.h"
31
32/* server */
33#include "plrhand.h"
34#include "notify.h"
35#include "srv_main.h"
36
37#include "spacerace.h"
38
39/**********************************************************************/
45 void spaceship_calc_derived(struct player_spaceship *ship)
46{
47 int i;
48 /* these are how many are connected: */
49 int fuel = 0;
50 int propulsion = 0;
51 int habitation = 0;
52 int life_support = 0;
53 int solar_panels = 0;
54
55 fc_assert_ret(ship->structurals <= NUM_SS_STRUCTURALS);
56 fc_assert_ret(ship->components <= NUM_SS_COMPONENTS);
57 fc_assert_ret(ship->modules <= NUM_SS_MODULES);
58
59 ship->mass = 0;
60 ship->support_rate = ship->energy_rate =
61 ship->success_rate = ship->travel_time = 0.0;
62
63 for (i = 0; i < NUM_SS_STRUCTURALS; i++) {
64 if (BV_ISSET(ship->structure, i)) {
65 ship->mass += (i < 6) ? 200 : 100;
66 /* s0 to s3 are heavier; actually in Civ1 its a bit stranger
67 than this, but not worth figuring out --dwp */
68 }
69 }
70 for (i = 0; i < ship->fuel; i++) {
71 if (BV_ISSET(ship->structure, components_info[i * 2].required)) {
72 fuel++;
73 }
74 }
75 for (i = 0; i < ship->propulsion; i++) {
76 if (BV_ISSET(ship->structure, components_info[i * 2 + 1].required)) {
77 propulsion++;
78 }
79 }
80 for (i = 0; i < ship->habitation; i++) {
81 if (BV_ISSET(ship->structure, modules_info[i * 3].required)) {
82 habitation++;
83 }
84 }
85 for (i = 0; i < ship->life_support; i++) {
86 if (BV_ISSET(ship->structure, modules_info[i * 3 + 1].required)) {
87 life_support++;
88 }
89 }
90 for (i = 0; i < ship->solar_panels; i++) {
91 if (BV_ISSET(ship->structure, modules_info[i * 3 + 2].required)) {
92 solar_panels++;
93 }
94 }
95
96 ship->mass += 1600 * (habitation + life_support)
97 + 400 * (solar_panels + propulsion + fuel);
98
99 ship->population = habitation * 10000;
100
101 if (habitation > 0) {
102 ship->support_rate = life_support / (double) habitation;
103 }
104 if (life_support + habitation > 0) {
105 ship->energy_rate = 2.0 * solar_panels / (double)(life_support+habitation);
106 }
107 if (fuel>0 && propulsion>0) {
108 ship->success_rate =
109 MIN(ship->support_rate, 1.0) * MIN(ship->energy_rate, 1.0);
110 }
111
112 /* The Success% can be less by up to a few % in some cases
113 (I think if P != F or if P and/or F too small (eg <= 2?) ?)
114 but probably not worth worrying about.
115 Actually, the Civ1 manual suggests travel time is relevant. --dwp
116 */
117
118 ship->travel_time = ship->mass * game.server.spaceship_travel_time
119 / 100 / (200.0 * MIN(propulsion,fuel) + 20.0);
120
121}
122
123/**********************************************************************/
128 void send_spaceship_info(struct player *src, struct conn_list *dest)
129{
130 if (!dest) {
131 dest = game.est_connections;
132 }
133
134 players_iterate(pplayer) {
135 if (!src || pplayer == src) {
136 struct packet_spaceship_info info;
137 struct player_spaceship *ship = &pplayer->spaceship;
138
139 info.player_num = player_number(pplayer);
140 info.sship_state = ship->state;
141 info.structurals = ship->structurals;
142 info.components = ship->components;
143 info.modules = ship->modules;
144 info.fuel = ship->fuel;
145 info.propulsion = ship->propulsion;
146 info.habitation = ship->habitation;
147 info.life_support = ship->life_support;
148 info.solar_panels = ship->solar_panels;
149 info.launch_year = ship->launch_year;
150 info.population = ship->population;
151 info.mass = ship->mass;
152 info.support_rate = ship->support_rate;
153 info.energy_rate = ship->energy_rate;
154 info.success_rate = ship->success_rate;
155 info.travel_time = ship->travel_time;
156 info.structure = ship->structure;
157
158 lsend_packet_spaceship_info(dest, &info);
159 }
160 } players_iterate_end;
161}
162
163/**********************************************************************/
166 void handle_spaceship_launch(struct player *pplayer)
167{
168 struct player_spaceship *ship = &pplayer->spaceship;
169 int arrival;
170
171 if (!player_primary_capital(pplayer)) {
172 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
173 _("You need to have a capital in order to launch "
174 "your spaceship."));
175 return;
176 }
177 if (ship->state >= SSHIP_LAUNCHED) {
178 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
179 _("Your spaceship is already launched!"));
180 return;
181 }
182 if (ship->state != SSHIP_STARTED
183 || ship->success_rate == 0.0) {
184 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
185 _("Your spaceship can't be launched yet!"));
186 return;
187 }
188
189 ship->state = SSHIP_LAUNCHED;
190 ship->launch_year = game.info.year;
191 arrival = ship->launch_year + (int) ship->travel_time;
192
193 notify_player(NULL, NULL, E_SPACESHIP, ftc_server,
194 _("The %s have launched a spaceship! "
195 "It is estimated to arrive at Alpha Centauri in %s."),
196 nation_plural_for_player(pplayer),
197 textyear(arrival));
198
199 send_spaceship_info(pplayer, NULL);
200}
201
202/**********************************************************************/
205 void handle_spaceship_place(struct player *pplayer,
206 enum spaceship_place_type type, int num)
207{
208 (void) do_spaceship_place(pplayer, ACT_REQ_PLAYER, type, num);
209}
210
211/**********************************************************************/
214 bool do_spaceship_place(struct player *pplayer, enum action_requester from,
215 enum spaceship_place_type type, int num)
216{
217 struct player_spaceship *ship = &pplayer->spaceship;
218
219 if (ship->state == SSHIP_NONE) {
220 if (from == ACT_REQ_PLAYER) {
221 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
222 _("Spaceship action received,"
223 " but you don't have a spaceship!"));
224 }
225
226 return FALSE;
227 }
228
229 if (ship->state >= SSHIP_LAUNCHED) {
230 if (from == ACT_REQ_PLAYER) {
231 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
232 _("You can't modify your spaceship after launch!"));
233 }
234
235 return FALSE;
236 }
237
238 if (type == SSHIP_PLACE_STRUCTURAL) {
239 if (num < 0 || num >= NUM_SS_STRUCTURALS
240 || BV_ISSET(ship->structure, num)) {
241 return FALSE;
242 }
243 if (num_spaceship_structurals_placed(ship) >= ship->structurals) {
244 if (from == ACT_REQ_PLAYER) {
245 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
246 _("You don't have any unplaced Space Structurals!"));
247 }
248
249 return FALSE;
250 }
251 if (num != 0
252 && !BV_ISSET(ship->structure, structurals_info[num].required)) {
253 if (from == ACT_REQ_PLAYER) {
254 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
255 _("That Space Structural would not be connected!"));
256 }
257
258 return FALSE;
259 }
260
261 BV_SET(ship->structure, num);
262 spaceship_calc_derived(ship);
263 send_spaceship_info(pplayer, NULL);
264 return TRUE;
265 }
266
267 if (type == SSHIP_PLACE_FUEL) {
268 if (ship->fuel != num - 1) {
269 return FALSE;
270 }
271 if (ship->fuel + ship->propulsion >= ship->components) {
272 if (from == ACT_REQ_PLAYER) {
273 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
274 _("You don't have any unplaced Space Components!"));
275 }
276
277 return FALSE;
278 }
279 if (num > NUM_SS_COMPONENTS/2) {
280 if (from == ACT_REQ_PLAYER) {
281 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
282 _("Your spaceship already has"
283 " the maximum number of Fuel Components!"));
284 }
285
286 return FALSE;
287 }
288
289 ship->fuel++;
290 spaceship_calc_derived(ship);
291 send_spaceship_info(pplayer, NULL);
292 return TRUE;
293 }
294
295 if (type == SSHIP_PLACE_PROPULSION) {
296 if (ship->propulsion != num - 1) {
297 return FALSE;
298 }
299 if (ship->fuel + ship->propulsion >= ship->components) {
300 if (from == ACT_REQ_PLAYER) {
301 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
302 _("You don't have any unplaced"
303 " Space Components!"));
304 }
305
306 return FALSE;
307 }
308 if (num > NUM_SS_COMPONENTS/2) {
309 if (from == ACT_REQ_PLAYER) {
310 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
311 _("Your spaceship already has the"
312 " maximum number of Propulsion Components!"));
313 }
314
315 return FALSE;
316 }
317
318 ship->propulsion++;
319 spaceship_calc_derived(ship);
320 send_spaceship_info(pplayer, NULL);
321 return TRUE;
322 }
323
324 if (type == SSHIP_PLACE_HABITATION) {
325 if (ship->habitation != num - 1) {
326 return FALSE;
327 }
328 if (ship->habitation + ship->life_support + ship->solar_panels
329 >= ship->modules) {
330 if (from == ACT_REQ_PLAYER) {
331 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
332 _("You don't have any unplaced Space Modules!"));
333 }
334
335 return FALSE;
336 }
337 if (num > NUM_SS_MODULES / 3) {
338 if (from == ACT_REQ_PLAYER) {
339 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
340 _("Your spaceship already has the"
341 " maximum number of Habitation Modules!"));
342 }
343
344 return FALSE;
345 }
346
347 ship->habitation++;
348 spaceship_calc_derived(ship);
349 send_spaceship_info(pplayer, NULL);
350 return TRUE;
351 }
352
353 if (type == SSHIP_PLACE_LIFE_SUPPORT) {
354 if (ship->life_support != num - 1) {
355 return FALSE;
356 }
357 if (ship->habitation + ship->life_support + ship->solar_panels
358 >= ship->modules) {
359 if (from == ACT_REQ_PLAYER) {
360 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
361 _("You don't have any unplaced Space Modules!"));
362 }
363
364 return FALSE;
365 }
366 if (num > NUM_SS_MODULES / 3) {
367 if (from == ACT_REQ_PLAYER) {
368 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
369 _("Your spaceship already has the"
370 " maximum number of Life Support Modules!"));
371 }
372
373 return FALSE;
374 }
375
376 ship->life_support++;
377 spaceship_calc_derived(ship);
378 send_spaceship_info(pplayer, NULL);
379 return TRUE;
380 }
381
382 if (type == SSHIP_PLACE_SOLAR_PANELS) {
383 if (ship->solar_panels != num - 1) {
384 return FALSE;
385 }
386 if (ship->habitation + ship->life_support + ship->solar_panels
387 >= ship->modules) {
388 if (from == ACT_REQ_PLAYER) {
389 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
390 _("You don't have any unplaced Space Modules!"));
391 }
392
393 return FALSE;
394 }
395 if (num > NUM_SS_MODULES / 3) {
396 if (from == ACT_REQ_PLAYER) {
397 notify_player(pplayer, NULL, E_SPACESHIP, ftc_server,
398 _("Your spaceship already has the"
399 " maximum number of Solar Panel Modules!"));
400 }
401
402 return FALSE;
403 }
404
405 ship->solar_panels++;
406 spaceship_calc_derived(ship);
407 send_spaceship_info(pplayer, NULL);
408 return TRUE;
409 }
410
411 log_error("Received unknown spaceship place type %d from %s",
412 type, player_name(pplayer));
413 return FALSE;
414}
415
416/**********************************************************************/
419 void spaceship_arrived(struct player *pplayer)
420{
421 notify_player(NULL, NULL, E_SPACESHIP, ftc_server,
422 _("The %s spaceship has arrived at Alpha Centauri."),
423 nation_adjective_for_player(pplayer));
424 pplayer->spaceship.state = SSHIP_ARRIVED;
425}
426
427/**********************************************************************/
430 void spaceship_lost(struct player *pplayer)
431{
432 notify_player(NULL, NULL, E_SPACESHIP, ftc_server,
433 _("Without guidance from the capital, the %s "
434 "spaceship is lost!"),
435 nation_adjective_for_player(pplayer));
436 spaceship_init(&pplayer->spaceship);
437 send_spaceship_info(pplayer, NULL);
438}
439
440/**********************************************************************/
445 double spaceship_arrival(const struct player *pplayer)
446{
447 const struct player_spaceship *ship = &pplayer->spaceship;
448
449 return ship->launch_year + ship->travel_time;
450}
451
452/**********************************************************************/
459 int rank_spaceship_arrival(struct player **result)
460{
461 int n = 0, i;
462
463 shuffled_players_iterate(pplayer) {
464 struct player_spaceship *ship = &pplayer->spaceship;
465
466 if (ship->state == SSHIP_LAUNCHED) {
467 result[n++] = pplayer;
468 }
469 } shuffled_players_iterate_end;
470
471 /* An insertion sort will do; n is probably small, and we need a
472 * stable sort to preserve the shuffled order for tie-breaking, so can't
473 * use qsort() */
474 for (i = 1; i < n; i++) {
475 int j;
476 for (j = i;
477 j > 0
478 && spaceship_arrival(result[j-1]) > spaceship_arrival(result[j]);
479 j--) {
480 struct player *tmp = result[j];
481 result[j] = result[j-1];
482 result[j-1] = tmp;
483 }
484 }
485
486 return n;
487}
n
#define n
Definition astring.c:77
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
textyear
const char * textyear(int year)
Definition calendar.c:120
calendar.h
events.h
spaceship_place_type
spaceship_place_type
Definition fc_types.h:1148
SSHIP_PLACE_PROPULSION
@ SSHIP_PLACE_PROPULSION
Definition fc_types.h:1151
SSHIP_PLACE_STRUCTURAL
@ SSHIP_PLACE_STRUCTURAL
Definition fc_types.h:1149
SSHIP_PLACE_LIFE_SUPPORT
@ SSHIP_PLACE_LIFE_SUPPORT
Definition fc_types.h:1153
SSHIP_PLACE_SOLAR_PANELS
@ SSHIP_PLACE_SOLAR_PANELS
Definition fc_types.h:1154
SSHIP_PLACE_FUEL
@ SSHIP_PLACE_FUEL
Definition fc_types.h:1150
SSHIP_PLACE_HABITATION
@ SSHIP_PLACE_HABITATION
Definition fc_types.h:1152
fcintl.h
_
#define _(String)
Definition fcintl.h:67
ftc_server
const struct ft_color ftc_server
Definition featured_text.c:77
game
struct civ_game game
Definition game.c:57
game.h
type
GType type
Definition repodlgs.c:1312
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_error
#define log_error(message,...)
Definition log.h:103
nation_adjective_for_player
const char * nation_adjective_for_player(const struct player *pplayer)
Definition nation.c:168
nation_plural_for_player
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:177
notify_player
void notify_player(const struct player *pplayer, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:292
notify.h
packets.h
lsend_packet_spaceship_info
void lsend_packet_spaceship_info(struct conn_list *dest, const struct packet_spaceship_info *packet)
Definition packets_gen.c:53886
player_number
int player_number(const struct player *pplayer)
Definition player.c:828
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:886
player_primary_capital
struct city * player_primary_capital(const struct player *pplayer)
Definition player.c:1313
players_iterate_end
#define players_iterate_end
Definition player.h:535
players_iterate
#define players_iterate(_pplayer)
Definition player.h:530
plrhand.h
shuffled_players_iterate_end
#define shuffled_players_iterate_end
Definition plrhand.h:106
shuffled_players_iterate
#define shuffled_players_iterate(NAME_pplayer)
Definition plrhand.h:96
shared.h
MIN
#define MIN(x, y)
Definition shared.h:55
rank_spaceship_arrival
int rank_spaceship_arrival(struct player **result)
Definition spacerace.c:459
spaceship_lost
void spaceship_lost(struct player *pplayer)
Definition spacerace.c:430
do_spaceship_place
bool do_spaceship_place(struct player *pplayer, enum action_requester from, enum spaceship_place_type type, int num)
Definition spacerace.c:214
spaceship_arrival
double spaceship_arrival(const struct player *pplayer)
Definition spacerace.c:445
spaceship_calc_derived
void spaceship_calc_derived(struct player_spaceship *ship)
Definition spacerace.c:45
send_spaceship_info
void send_spaceship_info(struct player *src, struct conn_list *dest)
Definition spacerace.c:128
handle_spaceship_place
void handle_spaceship_place(struct player *pplayer, enum spaceship_place_type type, int num)
Definition spacerace.c:205
handle_spaceship_launch
void handle_spaceship_launch(struct player *pplayer)
Definition spacerace.c:166
spaceship_arrived
void spaceship_arrived(struct player *pplayer)
Definition spacerace.c:419
spacerace.h
num_spaceship_structurals_placed
int num_spaceship_structurals_placed(const struct player_spaceship *ship)
Definition spaceship.c:113
spaceship_init
void spaceship_init(struct player_spaceship *ship)
Definition spaceship.c:96
structurals_info
const struct sship_part_info structurals_info[NUM_SS_STRUCTURALS]
Definition spaceship.c:23
modules_info
const struct sship_part_info modules_info[NUM_SS_MODULES]
Definition spaceship.c:77
components_info
const struct sship_part_info components_info[NUM_SS_COMPONENTS]
Definition spaceship.c:58
spaceship.h
NUM_SS_MODULES
#define NUM_SS_MODULES
Definition spaceship.h:89
NUM_SS_COMPONENTS
#define NUM_SS_COMPONENTS
Definition spaceship.h:88
NUM_SS_STRUCTURALS
#define NUM_SS_STRUCTURALS
Definition spaceship.h:87
SSHIP_ARRIVED
@ SSHIP_ARRIVED
Definition spaceship.h:85
SSHIP_STARTED
@ SSHIP_STARTED
Definition spaceship.h:84
SSHIP_LAUNCHED
@ SSHIP_LAUNCHED
Definition spaceship.h:85
SSHIP_NONE
@ SSHIP_NONE
Definition spaceship.h:84
srv_main.h
civ_game::server
struct civ_game::@30::@34 server
civ_game::spaceship_travel_time
int spaceship_travel_time
Definition game.h:178
civ_game::est_connections
struct conn_list * est_connections
Definition game.h:97
civ_game::info
struct packet_game_info info
Definition game.h:89
packet_game_info::year
int year
Definition packets_gen.h:243
packet_spaceship_info
Definition packets_gen.h:951
packet_spaceship_info::sship_state
int sship_state
Definition packets_gen.h:953
packet_spaceship_info::propulsion
int propulsion
Definition packets_gen.h:958
packet_spaceship_info::habitation
int habitation
Definition packets_gen.h:959
packet_spaceship_info::mass
int mass
Definition packets_gen.h:964
packet_spaceship_info::life_support
int life_support
Definition packets_gen.h:960
packet_spaceship_info::structure
bv_spaceship_structure structure
Definition packets_gen.h:965
packet_spaceship_info::structurals
int structurals
Definition packets_gen.h:954
packet_spaceship_info::fuel
int fuel
Definition packets_gen.h:957
packet_spaceship_info::population
int population
Definition packets_gen.h:963
packet_spaceship_info::success_rate
float success_rate
Definition packets_gen.h:968
packet_spaceship_info::player_num
int player_num
Definition packets_gen.h:952
packet_spaceship_info::launch_year
int launch_year
Definition packets_gen.h:962
packet_spaceship_info::travel_time
float travel_time
Definition packets_gen.h:969
packet_spaceship_info::energy_rate
float energy_rate
Definition packets_gen.h:967
packet_spaceship_info::solar_panels
int solar_panels
Definition packets_gen.h:961
packet_spaceship_info::support_rate
float support_rate
Definition packets_gen.h:966
packet_spaceship_info::modules
int modules
Definition packets_gen.h:956
packet_spaceship_info::components
int components
Definition packets_gen.h:955
player_spaceship
Definition spaceship.h:94
player_spaceship::energy_rate
double energy_rate
Definition spaceship.h:114
player_spaceship::modules
int modules
Definition spaceship.h:98
player_spaceship::mass
int mass
Definition spaceship.h:112
player_spaceship::fuel
int fuel
Definition spaceship.h:102
player_spaceship::solar_panels
int solar_panels
Definition spaceship.h:106
player_spaceship::structure
bv_spaceship_structure structure
Definition spaceship.h:100
player_spaceship::components
int components
Definition spaceship.h:97
player_spaceship::population
int population
Definition spaceship.h:111
player_spaceship::life_support
int life_support
Definition spaceship.h:105
player_spaceship::success_rate
double success_rate
Definition spaceship.h:115
player_spaceship::support_rate
double support_rate
Definition spaceship.h:113
player_spaceship::travel_time
double travel_time
Definition spaceship.h:116
player_spaceship::state
enum spaceship_state state
Definition spaceship.h:108
player_spaceship::structurals
int structurals
Definition spaceship.h:96
player_spaceship::habitation
int habitation
Definition spaceship.h:104
player_spaceship::propulsion
int propulsion
Definition spaceship.h:103
player_spaceship::launch_year
int launch_year
Definition spaceship.h:109
player
Definition player.h:249
player::spaceship
struct player_spaceship spaceship
Definition player.h:286
sship_part_info::required
int required
Definition spaceship.h:121
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47