/************************************************************************** Handle spaceship launch request. **************************************************************************/ void handle_spaceship_launch(struct player *pplayer) { struct player_spaceship *ship = &pplayer->spaceship; int arrival; if (!player_capital(pplayer)) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You need to have a capital in order to launch " "your spaceship.")); return; } if (ship->state >= SSHIP_LAUNCHED) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship is already launched!")); return; } if (ship->state != SSHIP_STARTED || ship->success_rate == 0.0) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship can't be launched yet!")); return; } ship->state = SSHIP_LAUNCHED; ship->launch_year = game.info.year; arrival = ship->launch_year + (int) ship->travel_time; notify_player(NULL, NULL, E_SPACESHIP, ftc_server, _("The %s have launched a spaceship! " "It is estimated to arrive at Alpha Centauri in %s."), nation_plural_for_player(pplayer), textyear(arrival)); send_spaceship_info(pplayer, NULL); }
/***************************************************************************** Notify pplayer of a complex event. *****************************************************************************/ void api_notify_event_msg(lua_State *L, Player *pplayer, Tile *ptile, int event, const char *message) { LUASCRIPT_CHECK_STATE(L); notify_player(pplayer, ptile, event, ftc_any, "%s", message); }
/************************************************************************** Handle spaceship loss. **************************************************************************/ void spaceship_lost(struct player *pplayer) { notify_player(NULL, NULL, E_SPACESHIP, ftc_server, _("Without guidance from the capital, the %s " "spaceship is lost!"), nation_adjective_for_player(pplayer)); spaceship_init(&pplayer->spaceship); send_spaceship_info(pplayer, NULL); }
/**************************************************************************** Give technologies to players with EFT_TECH_PARASITE (traditionally from the Great Library). ****************************************************************************/ void do_tech_parasite_effect(struct player *pplayer) { int mod; struct effect_list *plist = effect_list_new(); /* Note that two EFT_TECH_PARASITE effects will combine into a single, * much worse effect. */ if ((mod = get_player_bonus_effects(plist, pplayer, EFT_TECH_PARASITE)) > 0) { char buf[512]; buf[0] = '\0'; effect_list_iterate(plist, peffect) { if (buf[0] != '\0') { sz_strlcat(buf, ", "); } get_effect_req_text(peffect, buf, sizeof(buf)); } effect_list_iterate_end; advance_index_iterate(A_FIRST, i) { if (player_invention_reachable(pplayer, i) && player_invention_state(pplayer, i) != TECH_KNOWN) { int num_players = 0; players_iterate(aplayer) { if (player_invention_state(aplayer, i) == TECH_KNOWN) { num_players++; } } players_iterate_end; if (num_players >= mod) { notify_player(pplayer, NULL, E_TECH_GAIN, FTC_SERVER_INFO, NULL, _("%s acquired from %s!"), advance_name_for_player(pplayer, i), buf); notify_embassies(pplayer, NULL, NULL, E_TECH_GAIN, FTC_SERVER_INFO, NULL, _("The %s have acquired %s from %s."), nation_plural_for_player(pplayer), advance_name_for_player(pplayer, i), buf); do_free_cost(pplayer, i); found_new_tech(pplayer, i, FALSE, TRUE); script_signal_emit("tech_researched", 3, API_TYPE_TECH_TYPE, advance_by_number(i), API_TYPE_PLAYER, pplayer, API_TYPE_STRING, "stolen"); break; } } } advance_index_iterate_end;
/************************************************************************** ... **************************************************************************/ void handle_diplomacy_cancel_meeting(struct player *pplayer, struct packet_diplomacy_info *packet) { struct Treaty *ptreaty; struct player *plr0, *plr1, *theother; plr0=&game.players[packet->plrno0]; plr1=&game.players[packet->plrno1]; theother=(pplayer==plr0) ? plr1 : plr0; if((ptreaty=find_treaty(pplayer, theother))) { send_packet_diplomacy_info(theother->conn, PACKET_DIPLOMACY_CANCEL_MEETING, packet); notify_player(theother, "Game: %s canceled the meeting!", pplayer->name); genlist_unlink(&treaties, ptreaty); free(ptreaty); } }
/************************************************************************** Place a spaceship part **************************************************************************/ bool do_spaceship_place(struct player *pplayer, bool user_initiated, enum spaceship_place_type type, int num) { struct player_spaceship *ship = &pplayer->spaceship; if (ship->state == SSHIP_NONE) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Spaceship action received," " but you don't have a spaceship!")); } return FALSE; } if (ship->state >= SSHIP_LAUNCHED) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You can't modify your spaceship after launch!")); } return FALSE; } if (type == SSHIP_PLACE_STRUCTURAL) { if (num < 0 || num >= NUM_SS_STRUCTURALS || BV_ISSET(ship->structure, num)) { return FALSE; } if (num_spaceship_structurals_placed(ship) >= ship->structurals) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced Space Structurals!")); } return FALSE; } if (num != 0 && !BV_ISSET(ship->structure, structurals_info[num].required)) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("That Space Structural would not be connected!")); } return FALSE; } BV_SET(ship->structure, num); spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } if (type == SSHIP_PLACE_FUEL) { if (ship->fuel != num - 1) { return FALSE; } if (ship->fuel + ship->propulsion >= ship->components) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced Space Components!")); } return FALSE; } if (num > NUM_SS_COMPONENTS/2) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship already has" " the maximum number of Fuel Components!")); } return FALSE; } ship->fuel++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } if (type == SSHIP_PLACE_PROPULSION) { if (ship->propulsion != num - 1) { return FALSE; } if (ship->fuel + ship->propulsion >= ship->components) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced" " Space Components!")); } return FALSE; } if (num > NUM_SS_COMPONENTS/2) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship already has the" " maximum number of Propulsion Components!")); } return FALSE; } ship->propulsion++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } if (type == SSHIP_PLACE_HABITATION) { if (ship->habitation != num - 1) { return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced Space Modules!")); } return FALSE; } if (num > NUM_SS_MODULES / 3) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship already has the" " maximum number of Habitation Modules!")); } return FALSE; } ship->habitation++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } if (type == SSHIP_PLACE_LIFE_SUPPORT) { if (ship->life_support != num - 1) { return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced Space Modules!")); } return FALSE; } if (num > NUM_SS_MODULES / 3) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship already has the" " maximum number of Life Support Modules!")); } return FALSE; } ship->life_support++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } if (type == SSHIP_PLACE_SOLAR_PANELS) { if (ship->solar_panels != num - 1) { return FALSE; } if (ship->habitation + ship->life_support + ship->solar_panels >= ship->modules) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("You don't have any unplaced Space Modules!")); } return FALSE; } if (num > NUM_SS_MODULES / 3) { if (user_initiated) { notify_player(pplayer, NULL, E_SPACESHIP, ftc_server, _("Your spaceship already has the" " maximum number of Solar Panel Modules!")); } return FALSE; } ship->solar_panels++; spaceship_calc_derived(ship); send_spaceship_info(pplayer, NULL); return TRUE; } log_error("Received unknown spaceship place type %d from %s", type, player_name(pplayer)); return FALSE; }
/************************************************************************** ... **************************************************************************/ void handle_diplomacy_accept_treaty(struct player *pplayer, struct packet_diplomacy_info *packet) { struct Treaty *ptreaty; struct player *plr0, *plr1, *pgiver, *pdest; plr0=&game.players[packet->plrno0]; plr1=&game.players[packet->plrno1]; pgiver=&game.players[packet->plrno_from]; if((ptreaty=find_treaty(plr0, plr1)) && pgiver==pplayer) { if(ptreaty->plr0==pgiver) ptreaty->accept0=!ptreaty->accept0; else ptreaty->accept1=!ptreaty->accept1; send_packet_diplomacy_info(plr0->conn, PACKET_DIPLOMACY_ACCEPT_TREATY, packet); send_packet_diplomacy_info(plr1->conn, PACKET_DIPLOMACY_ACCEPT_TREATY, packet); if(ptreaty->accept0 && ptreaty->accept1) { struct genlist_iterator myiter; send_packet_diplomacy_info(plr0->conn, PACKET_DIPLOMACY_CANCEL_MEETING, packet); send_packet_diplomacy_info(plr1->conn, PACKET_DIPLOMACY_CANCEL_MEETING, packet); notify_player(plr0, "Game: A treaty containing %d clauses was agreed upon", genlist_size(&ptreaty->clauses)); notify_player(plr1, "Game: A treaty containing %d clauses was agreed upon", genlist_size(&ptreaty->clauses)); /* verify gold! the player's gold amount could have changed during * the meeting */ genlist_iterator_init(&myiter, &ptreaty->clauses, 0); for(;ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter)) { struct Clause *pclause=(struct Clause *)ITERATOR_PTR(myiter); pgiver=pclause->from; if(pclause->type==CLAUSE_GOLD && pgiver->economic.gold<pclause->value) { notify_player(plr0, "Game: The %s don't have the promised amount of gold! Treaty canceled!", get_race_name_plural(pgiver->race)); notify_player(plr1, "Game: The %s don't have the promised amount of gold! Treaty canceled!", get_race_name_plural(pgiver->race)); goto cleanup; } } genlist_iterator_init(&myiter, &ptreaty->clauses, 0); for(;ITERATOR_PTR(myiter); ITERATOR_NEXT(myiter)) { struct Clause *pclause=(struct Clause *)ITERATOR_PTR(myiter); pgiver=pclause->from; pdest=(plr0==pgiver) ? plr1 : plr0; switch(pclause->type) { case CLAUSE_ADVANCE: notify_player(pdest, "Game: You are taught the knowledge of %s", advances[pclause->value].name); set_invention(pdest, pclause->value, TECH_KNOWN); pdest->research.researchpoints++; break; case CLAUSE_GOLD: notify_player(pdest, "Game: You get %d gold", pclause->value); pgiver->economic.gold-=pclause->value; pdest->economic.gold+=pclause->value; break; case CLAUSE_MAP: give_map_from_player_to_player(pgiver, pdest); notify_player(pdest, "Game: You receive %s's worldmap", pgiver->name); break; } } cleanup: genlist_unlink(&treaties, ptreaty); free(ptreaty); send_player_info(plr0, 0); send_player_info(plr1, 0); } } }