~ubuntu-branches/debian/sid/freeciv/sid

« back to all changes in this revision

Viewing changes to client/climisc.c

  • Committer: Bazaar Package Importer
  • Author(s): Clint Adams, Karl Goetz, Clint Adams
  • Date: 2010-02-23 22:09:02 UTC
  • mfrom: (7.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20100223220902-s3spqi1x4e190y0t
[ Karl Goetz ]
* Remove civserver files in /etc/ggzd/ (Closes: 523772, 517787)
* Adding ${misc:Depends} to all binary packages (lintian warnings)

[ Clint Adams ]
* New upstream version.
  - Drop data_dsc_use_bindir.diff (binary pathnames have changed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#include <stdlib.h>
27
27
#include <string.h>
28
28
 
 
29
/* utility */
29
30
#include "fcintl.h"
30
31
#include "log.h"
31
32
#include "support.h"
32
33
 
 
34
/* common */
33
35
#include "city.h"
34
36
#include "diptreaty.h"
 
37
#include "featured_text.h"
35
38
#include "game.h"
36
39
#include "government.h"
37
40
#include "map.h"
39
42
#include "spaceship.h"
40
43
#include "unitlist.h"
41
44
 
 
45
/* include */
42
46
#include "chatline_g.h"
43
47
#include "citydlg_g.h"
44
48
#include "cityrep_g.h"
46
50
#include "gui_main_g.h"
47
51
#include "mapview_g.h"
48
52
 
49
 
#include "civclient.h"
 
53
/* client */
 
54
#include "client_main.h"
50
55
#include "climap.h"
51
56
#include "climisc.h"
52
 
#include "clinet.h"
53
57
#include "control.h"
54
58
#include "mapctrl_common.h"
 
59
#include "mapview_common.h"
55
60
#include "messagewin_common.h"
56
61
#include "packhand.h"
57
62
#include "plrdlg_common.h"
58
63
#include "repodlgs_common.h"
59
64
#include "tilespec.h"
60
65
 
61
 
/**************************************************************************
62
 
...
63
 
**************************************************************************/
64
 
void client_remove_player(int plrno)
65
 
{
66
 
  game_remove_player(get_player(plrno));
67
 
  game_renumber_players(plrno);
68
 
  update_conn_list_dialog();
69
 
  races_toggles_set_sensitive();
70
 
}
71
66
 
72
67
/**************************************************************************
73
68
...
98
93
    update_unit_info_label(get_units_in_focus());
99
94
  }
100
95
 
101
 
  pcity = tile_get_city(ptile);
 
96
  pcity = tile_city(ptile);
102
97
  if (pcity) {
103
 
    if (can_player_see_units_in_city(game.player_ptr, pcity)) {
 
98
    if (can_player_see_units_in_city(client.conn.playing, pcity)) {
104
99
      pcity->client.occupied =
105
100
        (unit_list_size(pcity->tile->units) > 0);
106
101
    }
113
108
  }
114
109
 
115
110
  /* FIXME: this can cause two refreshes to be done? */
116
 
  if (game.player_ptr) {
117
 
    pcity = player_find_city_by_id(game.player_ptr, hc);
 
111
  if (NULL != client.conn.playing) {
 
112
    pcity = player_find_city_by_id(client.conn.playing, hc);
118
113
    if (pcity) {
119
114
      refresh_city_dialog(pcity);
120
115
      freelog(LOG_DEBUG, "home city %s, %s, (%d %d)",
133
128
void client_remove_city(struct city *pcity)
134
129
{
135
130
  bool effect_update;
136
 
  struct tile *ptile = pcity->tile;
 
131
  struct tile *ptile = city_tile(pcity);
137
132
  struct city old_city = *pcity;
138
133
 
139
 
  freelog(LOG_DEBUG, "removing city %s, %s, (%d %d)",
140
 
          city_name(pcity),
141
 
          nation_rule_name(nation_of_city(pcity)),
142
 
          TILE_XY(ptile));
 
134
  freelog(LOG_DEBUG, "client_remove_city() %d, %s",
 
135
          pcity->id,
 
136
          city_name(pcity));
143
137
 
144
138
  /* Explicitly remove all improvements, to properly remove any global effects
145
139
     and to handle the preservation of "destroyed" effects. */
146
140
  effect_update=FALSE;
147
141
 
148
 
  built_impr_iterate(pcity, i) {
 
142
  city_built_iterate(pcity, pimprove) {
149
143
    effect_update = TRUE;
150
 
    city_remove_improvement(pcity, i);
151
 
  } built_impr_iterate_end;
 
144
    city_remove_improvement(pcity, pimprove);
 
145
  } city_built_iterate_end;
152
146
 
153
147
  if (effect_update) {
154
148
    /* nothing yet */
164
158
Change all cities building X to building Y, if possible.  X and Y
165
159
could be improvements or units. X and Y are compound ids.
166
160
**************************************************************************/
167
 
void client_change_all(struct city_production from,
168
 
                       struct city_production to)
 
161
void client_change_all(struct universal from,
 
162
                       struct universal to)
169
163
{
170
164
  int last_request_id = 0;
171
165
 
173
167
    return;
174
168
  }
175
169
 
176
 
  create_event(NULL, E_CITY_PRODUCTION_CHANGED,
177
 
               _("Changing production of every %s into %s."),
178
 
               from.is_unit
179
 
               ? utype_name_translation(utype_by_number(from.value))
180
 
               : improvement_name_translation(from.value),
181
 
               to.is_unit
182
 
               ? utype_name_translation(utype_by_number(to.value))
183
 
               : improvement_name_translation(to.value));
 
170
  create_event(NULL, E_CITY_PRODUCTION_CHANGED, ftc_client,
 
171
               _("Changing production of every %s into %s."),
 
172
               VUT_UTYPE == from.kind
 
173
               ? utype_name_translation(from.value.utype)
 
174
               : improvement_name_translation(from.value.building),
 
175
               VUT_UTYPE == to.kind
 
176
               ? utype_name_translation(to.value.utype)
 
177
               : improvement_name_translation(to.value.building));
184
178
 
185
 
  connection_do_buffer(&aconnection);
186
 
  city_list_iterate (game.player_ptr->cities, pcity) {
187
 
    if (from.is_unit == pcity->production.is_unit
188
 
        && from.value == pcity->production.value
189
 
        && ((to.is_unit
190
 
             && can_build_unit(pcity, utype_by_number(to.value)))
191
 
            || (!to.is_unit
192
 
                && can_build_improvement(pcity, to.value)))) {
 
179
  connection_do_buffer(&client.conn);
 
180
  city_list_iterate (client.conn.playing->cities, pcity) {
 
181
    if (are_universals_equal(&pcity->production, &from)
 
182
        && can_city_build_now(pcity, to)) {
193
183
      last_request_id = city_change_production(pcity, to);
194
184
    }
195
185
  } city_list_iterate_end;
196
186
 
197
 
  connection_do_unbuffer(&aconnection);
 
187
  connection_do_unbuffer(&client.conn);
198
188
  reports_freeze_till(last_request_id);
199
189
}
200
190
 
201
191
/***************************************************************************
 
192
  Client variant of city_tile().  This include the case of this could a
 
193
  ghost city (see client/packhand.c).  In a such case, the returned tile
 
194
  is an approximative position of the city on the map.
 
195
***************************************************************************/
 
196
struct tile *client_city_tile(const struct city *pcity)
 
197
{
 
198
  int dx, dy;
 
199
  double x = 0, y = 0;
 
200
  size_t num = 0;
 
201
 
 
202
  if (NULL == pcity) {
 
203
    return NULL;
 
204
  }
 
205
 
 
206
  if (NULL != city_tile(pcity)) {
 
207
    /* Normal city case. */
 
208
    return city_tile(pcity);
 
209
  }
 
210
 
 
211
  whole_map_iterate(ptile) {
 
212
    if (pcity == tile_worked(ptile)) {
 
213
      if (0 == num) {
 
214
        x = ptile->x;
 
215
        y = ptile->y;
 
216
        num = 1;
 
217
      } else {
 
218
        num++;
 
219
        base_map_distance_vector(&dx, &dy, (int) x, (int) y,
 
220
                                 ptile->x, ptile->y);
 
221
        x += (double) dx / num;
 
222
        y += (double) dy / num;
 
223
      }
 
224
    }
 
225
  } whole_map_iterate_end;
 
226
 
 
227
  if (0 < num) {
 
228
    return map_pos_to_tile((int) x, (int) y);
 
229
  } else {
 
230
    return NULL;
 
231
  }
 
232
}
 
233
 
 
234
/***************************************************************************
202
235
  Return a string indicating one nation's embassy status with another
203
236
***************************************************************************/
204
237
const char *get_embassy_status(const struct player *me,
218
251
    }
219
252
  } else if (player_has_embassy(them, me)) {
220
253
    return Q_("?embassy:With Us");
221
 
  } else if (me->diplstates[them->player_no].contact_turns_left > 0
222
 
             || them->diplstates[me->player_no].contact_turns_left > 0) {
 
254
  } else if (me->diplstates[player_index(them)].contact_turns_left > 0
 
255
             || them->diplstates[player_index(me)].contact_turns_left > 0) {
223
256
    return Q_("?embassy:Contact");
224
257
  } else {
225
258
    return Q_("?embassy:No Contact");
257
290
  case CLAUSE_ADVANCE:
258
291
    my_snprintf(buf, bufsiz, _("The %s give %s"),
259
292
                nation_plural_for_player(pclause->from),
260
 
                advance_name_for_player(game.player_ptr, pclause->value));
 
293
                advance_name_for_player(client.conn.playing, pclause->value));
261
294
    break;
262
295
  case CLAUSE_CITY:
263
296
    pcity = game_find_city_by_number(pclause->value);
314
347
**************************************************************************/
315
348
struct sprite *client_research_sprite(void)
316
349
{
317
 
  if (can_client_change_view() && game.player_ptr) {
 
350
  if (NULL != client.conn.playing && can_client_change_view()) {
318
351
    int index = 0;
319
352
 
320
 
    if (get_player_research(game.player_ptr)->researching != A_UNSET) {
 
353
    if (A_UNSET != get_player_research(client.conn.playing)->researching) {
321
354
      index = (NUM_TILES_PROGRESS
322
 
               * get_player_research(game.player_ptr)->bulbs_researched)
323
 
        / (total_bulbs_required(game.player_ptr) + 1);
 
355
               * get_player_research(client.conn.playing)->bulbs_researched)
 
356
        / (total_bulbs_required(client.conn.playing) + 1);
324
357
    }
325
358
 
326
359
    /* This clipping can be necessary since we can end up with excess
337
370
**************************************************************************/
338
371
struct sprite *client_warming_sprite(void)
339
372
{
340
 
  if (can_client_change_view() && game.player_ptr) {
 
373
  if (NULL != client.conn.playing && can_client_change_view()) {
341
374
    int index;
342
375
 
343
376
    if ((game.info.globalwarming <= 0) &&
387
420
**************************************************************************/
388
421
struct sprite *client_government_sprite(void)
389
422
{
390
 
  if (can_client_change_view() && game.player_ptr
391
 
      && game.control.government_count > 0) {
392
 
    struct government *gov = government_of_player(game.player_ptr);
 
423
  if (NULL != client.conn.playing && can_client_change_view()
 
424
      && government_count() > 0) {
 
425
    struct government *gov = government_of_player(client.conn.playing);
393
426
 
394
427
    return get_government_sprite(tileset, gov);
395
428
  } else {
415
448
  can_slide = FALSE;
416
449
  if (get_num_units_in_focus() > 0) {
417
450
    center_tile_mapcanvas(head_of_units_in_focus()->tile);
418
 
  } else if (game.player_ptr && (pcity = find_palace(game.player_ptr))) {
 
451
  } else if (NULL != client.conn.playing
 
452
             && NULL != (pcity = find_palace(client.conn.playing))) {
419
453
    /* Else focus on the capital. */
420
454
    center_tile_mapcanvas(pcity->tile);
421
 
  } else if (game.player_ptr && city_list_size(game.player_ptr->cities) > 0) {
 
455
  } else if (NULL != client.conn.playing
 
456
             && 0 < city_list_size(client.conn.playing->cities)) {
422
457
    /* Just focus on any city. */
423
 
    pcity = city_list_get(game.player_ptr->cities, 0);
 
458
    pcity = city_list_get(client.conn.playing->cities, 0);
424
459
    assert(pcity != NULL);
425
460
    center_tile_mapcanvas(pcity->tile);
426
 
  } else if (game.player_ptr && unit_list_size(game.player_ptr->units) > 0) {
 
461
  } else if (NULL != client.conn.playing
 
462
             && 0 < unit_list_size(client.conn.playing->units)) {
427
463
    /* Just focus on any unit. */
428
 
    punit = unit_list_get(game.player_ptr->units, 0);
 
464
    punit = unit_list_get(client.conn.playing->units, 0);
429
465
    assert(punit != NULL);
430
466
    center_tile_mapcanvas(punit->tile);
431
467
  } else {
451
487
/****************************************************************************
452
488
  Encode a CID for the target production.
453
489
****************************************************************************/
454
 
cid cid_encode(struct city_production target)
 
490
cid cid_encode(struct universal target)
455
491
{
456
 
  return target.value + (target.is_unit ? B_LAST : 0);
 
492
  return VUT_UTYPE == target.kind
 
493
         ? B_LAST + utype_number(target.value.utype)
 
494
         : improvement_number(target.value.building);
457
495
}
458
496
 
459
497
/****************************************************************************
460
498
  Encode a CID for the target unit type.
461
499
****************************************************************************/
462
 
cid cid_encode_unit(const struct unit_type *punittype)
 
500
cid cid_encode_unit(struct unit_type *punittype)
463
501
{
464
 
  struct city_production target
465
 
    = {.is_unit = TRUE, .value = punittype->index};
 
502
  struct universal target = {
 
503
    .kind = VUT_UTYPE,
 
504
    .value = {.utype = punittype}};
466
505
 
467
506
  return cid_encode(target);
468
507
}
470
509
/****************************************************************************
471
510
  Encode a CID for the target building.
472
511
****************************************************************************/
473
 
cid cid_encode_building(Impr_type_id building)
 
512
cid cid_encode_building(struct impr_type *pimprove)
474
513
{
475
 
  struct city_production target
476
 
    = {.is_unit = FALSE, .value = building};
 
514
  struct universal target = {
 
515
    .kind = VUT_IMPROVEMENT,
 
516
    .value = {.building = pimprove}
 
517
  };
477
518
 
478
519
  return cid_encode(target);
479
520
}
489
530
/**************************************************************************
490
531
  Decode the CID into a city_production structure.
491
532
**************************************************************************/
492
 
struct city_production cid_decode(cid cid)
 
533
struct universal cid_decode(cid cid)
493
534
{
494
 
  struct city_production target = {
495
 
    .value = (cid >= B_LAST) ? (cid - B_LAST) : cid,
496
 
    .is_unit = (cid >= B_LAST)
497
 
  };
 
535
  struct universal target;
 
536
 
 
537
  if (cid >= B_LAST) {
 
538
    target.kind = VUT_UTYPE;
 
539
    target.value.utype = utype_by_number(cid - B_LAST);
 
540
  } else {
 
541
    target.kind = VUT_IMPROVEMENT;
 
542
    target.value.building = improvement_by_number(cid);
 
543
  }
498
544
 
499
545
  return target;
500
546
}
501
547
 
502
 
/****************************************************************
503
 
...
504
 
*****************************************************************/
505
 
bool city_can_build_impr_or_unit(const struct city *pcity,
506
 
                                 struct city_production target)
507
 
{
508
 
  if (target.is_unit) {
509
 
    return can_build_unit(pcity, utype_by_number(target.value));
510
 
  } else {
511
 
    return can_build_improvement(pcity, target.value);
512
 
  }
513
 
}
514
 
 
515
548
/****************************************************************************
516
549
  Return TRUE if the city supports at least one unit of the given
517
550
  production type (returns FALSE if the production is a building).
518
551
****************************************************************************/
519
552
bool city_unit_supported(const struct city *pcity,
520
 
                         struct city_production target)
 
553
                         struct universal target)
521
554
{
522
 
  if (target.is_unit) {
523
 
    struct unit_type *tvtype = utype_by_number(target.value);
 
555
  if (VUT_UTYPE == target.kind) {
 
556
    struct unit_type *tvtype = target.value.utype;
524
557
 
525
558
    unit_list_iterate(pcity->units_supported, punit) {
526
559
      if (unit_type(punit) == tvtype)
535
568
  production type (returns FALSE if the production is a building).
536
569
****************************************************************************/
537
570
bool city_unit_present(const struct city *pcity,
538
 
                       struct city_production target)
 
571
                       struct universal target)
539
572
{
540
 
  if (target.is_unit) {
541
 
    struct unit_type *tvtype = utype_by_number(target.value);
 
573
  if (VUT_UTYPE == target.kind) {
 
574
    struct unit_type *tvtype = target.value.utype;
542
575
 
543
576
    unit_list_iterate(pcity->tile->units, punit) {
544
577
      if (unit_type(punit) == tvtype)
553
586
  A TestCityFunc to tell whether the item is a building and is present.
554
587
****************************************************************************/
555
588
bool city_building_present(const struct city *pcity,
556
 
                           struct city_production target)
 
589
                           struct universal target)
557
590
{
558
 
  return !target.is_unit && city_got_building(pcity, target.value);
 
591
  return VUT_IMPROVEMENT == target.kind
 
592
      && city_has_building(pcity, target.value.building);
559
593
}
560
594
 
561
595
/**************************************************************************
562
596
  Return the numerical "section" of an item.  This is used for sorting.
563
597
**************************************************************************/
564
 
static int target_get_section(struct city_production target)
 
598
static int target_get_section(struct universal target)
565
599
{
566
 
  if (target.is_unit) {
567
 
    if (utype_has_flag(utype_by_number(target.value), F_NONMIL)) {
 
600
  if (VUT_UTYPE == target.kind) {
 
601
    if (utype_has_flag(target.value.utype, F_CIVILIAN)) {
568
602
      return 2;
569
603
    } else {
570
604
      return 3;
571
605
    }
572
606
  } else {
573
 
    if (improvement_has_flag(target.value, IF_GOLD)) {
 
607
    if (improvement_has_flag(target.value.building, IF_GOLD)) {
574
608
      return 1;
575
 
    } else if (is_small_wonder(target.value)) {
 
609
    } else if (is_small_wonder(target.value.building)) {
576
610
      return 4;
577
 
    } else if (is_great_wonder(target.value)) {
 
611
    } else if (is_great_wonder(target.value.building)) {
578
612
      return 5;
579
613
    } else {
580
614
      return 0;
603
637
 
604
638
 section 0: normal buildings
605
639
 section 1: Capitalization
606
 
 section 2: F_NONMIL units
 
640
 section 2: F_CIVILIAN units
607
641
 section 3: other units
608
642
 section 4: small wonders
609
643
 section 5: great wonders
610
644
**************************************************************************/
611
 
void name_and_sort_items(struct city_production *targets, int num_targets,
 
645
void name_and_sort_items(struct universal *targets, int num_targets,
612
646
                         struct item *items,
613
647
                         bool show_cost, struct city *pcity)
614
648
{
615
649
  int i;
616
650
 
617
651
  for (i = 0; i < num_targets; i++) {
618
 
    struct city_production target = targets[i];
 
652
    struct universal target = targets[i];
619
653
    int cost;
620
654
    struct item *pitem = &items[i];
621
655
    const char *name;
622
656
 
623
657
    pitem->item = target;
624
658
 
625
 
    if (target.is_unit) {
626
 
      name = utype_values_translation(utype_by_number(target.value));
627
 
      cost = unit_build_shield_cost(utype_by_number(target.value));
 
659
    if (VUT_UTYPE == target.kind) {
 
660
      name = utype_values_translation(target.value.utype);
 
661
      cost = utype_build_shield_cost(target.value.utype);
628
662
    } else {
629
 
      name = get_impr_name_ex(pcity, target.value);
630
 
      if (improvement_has_flag(target.value, IF_GOLD)) {
 
663
      name = city_improvement_name_translation(pcity, target.value.building);
 
664
      if (improvement_has_flag(target.value.building, IF_GOLD)) {
631
665
        cost = -1;
632
666
      } else {
633
 
        cost = impr_build_shield_cost(target.value);
 
667
        cost = impr_build_shield_cost(target.value.building);
634
668
      }
635
669
    }
636
670
 
653
687
 
654
688
  FIXME: this should probably take a pplayer argument.
655
689
**************************************************************************/
656
 
int collect_production_targets(struct city_production *targets,
 
690
int collect_production_targets(struct universal *targets,
657
691
                               struct city **selected_cities,
658
692
                               int num_selected_cities, bool append_units,
659
693
                               bool append_wonders, bool change_prod,
661
695
{
662
696
  cid first = append_units ? B_LAST : 0;
663
697
  cid last = (append_units
664
 
              ? game.control.num_unit_types + B_LAST
665
 
              : game.control.num_impr_types);
 
698
              ? utype_count() + B_LAST
 
699
              : improvement_count());
666
700
  cid cid;
667
701
  int items_used = 0;
668
702
 
669
 
  if (!game.player_ptr) {
 
703
  if (NULL == client.conn.playing) {
670
704
    return 0;
671
705
  }
672
706
 
673
707
  for (cid = first; cid < last; cid++) {
674
708
    bool append = FALSE;
675
 
    struct city_production target = cid_decode(cid);
 
709
    struct universal target = cid_decode(cid);
676
710
 
677
 
    if (!append_units && (append_wonders != is_wonder(target.value))) {
 
711
    if (!append_units && (append_wonders != is_wonder(target.value.building))) {
678
712
      continue;
679
713
    }
680
714
 
681
715
    if (!change_prod) {
682
 
      city_list_iterate(game.player_ptr->cities, pcity) {
 
716
      city_list_iterate(client.conn.playing->cities, pcity) {
683
717
        append |= test_func(pcity, cid_decode(cid));
684
718
      }
685
719
      city_list_iterate_end;
706
740
 
707
741
  FIXME: this should probably take a pplayer argument.
708
742
**************************************************************************/
709
 
int collect_currently_building_targets(struct city_production *targets)
 
743
int collect_currently_building_targets(struct universal *targets)
710
744
{
711
745
  bool mapping[MAX_NUM_PRODUCTION_TARGETS];
712
746
  int cids_used = 0;
713
747
  cid cid;
714
748
 
715
 
  if (!game.player_ptr) {
 
749
  if (NULL == client.conn.playing) {
716
750
    return 0;
717
751
  }
718
752
 
719
753
  memset(mapping, 0, sizeof(mapping));
720
 
  city_list_iterate(game.player_ptr->cities, pcity) {
 
754
  city_list_iterate(client.conn.playing->cities, pcity) {
721
755
    mapping[cid_encode_from_city(pcity)] = TRUE;
722
756
  }
723
757
  city_list_iterate_end;
737
771
 
738
772
  FIXME: this should probably take a pplayer argument.
739
773
**************************************************************************/
740
 
int collect_buildable_targets(struct city_production *targets)
 
774
int collect_buildable_targets(struct universal *targets)
741
775
{
742
776
  int cids_used = 0;
743
777
 
744
 
  if (!game.player_ptr) {
 
778
  if (NULL == client.conn.playing) {
745
779
    return 0;
746
780
  }
747
781
 
748
 
  impr_type_iterate(id) {
749
 
    if (can_player_build_improvement(game.player_ptr, id)) {
750
 
      targets[cids_used].is_unit = FALSE;
751
 
      targets[cids_used].value = id;
 
782
  improvement_iterate(pimprove) {
 
783
    if (can_player_build_improvement_now(client.conn.playing, pimprove)) {
 
784
      targets[cids_used].kind = VUT_IMPROVEMENT;
 
785
      targets[cids_used].value.building = pimprove;
752
786
      cids_used++;
753
787
    }
754
 
  } impr_type_iterate_end;
 
788
  } improvement_iterate_end;
755
789
 
756
790
  unit_type_iterate(punittype) {
757
 
    if (can_player_build_unit(game.player_ptr, punittype)) {
758
 
      targets[cids_used].is_unit = TRUE;
759
 
      targets[cids_used].value = punittype->index;
 
791
    if (can_player_build_unit_now(client.conn.playing, punittype)) {
 
792
      targets[cids_used].kind = VUT_UTYPE;
 
793
      targets[cids_used].value.utype = punittype;
760
794
      cids_used++;
761
795
    }
762
796
  } unit_type_iterate_end
770
804
 
771
805
  FIXME: this should probably take a pplayer argument.
772
806
**************************************************************************/
773
 
int collect_eventually_buildable_targets(struct city_production *targets,
 
807
int collect_eventually_buildable_targets(struct universal *targets,
774
808
                                         struct city *pcity,
775
809
                                         bool advanced_tech)
776
810
{
777
811
  int cids_used = 0;
778
812
 
779
 
  if (!game.player_ptr) {
 
813
  if (NULL == client.conn.playing) {
780
814
    return 0;
781
815
  }
782
816
 
783
 
  impr_type_iterate(id) {
784
 
    bool can_build = can_player_build_improvement(game.player_ptr, id);
 
817
  improvement_iterate(pimprove) {
 
818
    bool can_build = can_player_build_improvement_now(client.conn.playing, pimprove);
785
819
    bool can_eventually_build =
786
 
        can_player_eventually_build_improvement(game.player_ptr, id);
 
820
        can_player_build_improvement_later(client.conn.playing, pimprove);
787
821
 
788
822
    /* If there's a city, can the city build the improvement? */
789
823
    if (pcity) {
790
 
      can_build = can_build && can_build_improvement(pcity, id);
 
824
      can_build = can_build && can_city_build_improvement_now(pcity, pimprove);
791
825
      can_eventually_build = can_eventually_build &&
792
 
          can_eventually_build_improvement(pcity, id);
 
826
          can_city_build_improvement_later(pcity, pimprove);
793
827
    }
794
828
 
795
829
    if ((advanced_tech && can_eventually_build) ||
796
830
        (!advanced_tech && can_build)) {
797
 
      targets[cids_used].is_unit = FALSE;
798
 
      targets[cids_used].value = id;
 
831
      targets[cids_used].kind = VUT_IMPROVEMENT;
 
832
      targets[cids_used].value.building = pimprove;
799
833
      cids_used++;
800
834
    }
801
 
  } impr_type_iterate_end;
 
835
  } improvement_iterate_end;
802
836
 
803
837
  unit_type_iterate(punittype) {
804
 
    bool can_build = can_player_build_unit(game.player_ptr, punittype);
 
838
    bool can_build = can_player_build_unit_now(client.conn.playing, punittype);
805
839
    bool can_eventually_build =
806
 
        can_player_eventually_build_unit(game.player_ptr, punittype);
 
840
        can_player_build_unit_later(client.conn.playing, punittype);
807
841
 
808
842
    /* If there's a city, can the city build the unit? */
809
843
    if (pcity) {
810
 
      can_build = can_build && can_build_unit(pcity, punittype);
 
844
      can_build = can_build && can_city_build_unit_now(pcity, punittype);
811
845
      can_eventually_build = can_eventually_build &&
812
 
          can_eventually_build_unit(pcity, punittype);
 
846
          can_city_build_unit_later(pcity, punittype);
813
847
    }
814
848
 
815
849
    if ((advanced_tech && can_eventually_build) ||
816
850
        (!advanced_tech && can_build)) {
817
 
      targets[cids_used].is_unit = TRUE;
818
 
      targets[cids_used].value = punittype->index;
 
851
      targets[cids_used].kind = VUT_UTYPE;
 
852
      targets[cids_used].value.utype = punittype;
819
853
      cids_used++;
820
854
    }
821
855
  } unit_type_iterate_end;
826
860
/**************************************************************************
827
861
 Collect the cids of all improvements which are built in the given city.
828
862
**************************************************************************/
829
 
int collect_already_built_targets(struct city_production *targets,
 
863
int collect_already_built_targets(struct universal *targets,
830
864
                                  struct city *pcity)
831
865
{
832
866
  int cids_used = 0;
833
867
 
834
868
  assert(pcity != NULL);
835
869
 
836
 
  built_impr_iterate(pcity, id) {
837
 
    targets[cids_used].is_unit = FALSE;
838
 
    targets[cids_used].value = id;
 
870
  city_built_iterate(pcity, pimprove) {
 
871
    targets[cids_used].kind = VUT_IMPROVEMENT;
 
872
    targets[cids_used].value.building = pimprove;
839
873
    cids_used++;
840
 
  } built_impr_iterate_end;
 
874
  } city_built_iterate_end;
841
875
 
842
876
  return cids_used;
843
877
}
849
883
{
850
884
  struct unit_list *plist;
851
885
 
852
 
  if (can_player_see_city_internals(game.player_ptr, pcity)) {
 
886
  if (can_player_see_city_internals(client.conn.playing, pcity)) {
853
887
    /* Other players don't see inside the city (but observers do). */
854
888
    plist = pcity->info_units_supported;
855
889
  } else {
866
900
{
867
901
  struct unit_list *plist;
868
902
 
869
 
  if (can_player_see_units_in_city(game.player_ptr, pcity)) {
 
903
  if (can_player_see_units_in_city(client.conn.playing, pcity)) {
870
904
    /* Other players don't see inside the city (but observers do). */
871
905
    plist = pcity->info_units_present;
872
906
  } else {
877
911
}
878
912
 
879
913
/**************************************************************************
880
 
  Handles a chat message.
 
914
  Handles a chat or event message.
881
915
**************************************************************************/
882
 
void handle_event(char *message, struct tile *ptile,
 
916
void handle_event(const char *featured_text, struct tile *ptile,
883
917
                  enum event_type event, int conn_id)
884
918
{
 
919
  char plain_text[MAX_LEN_MSG];
 
920
  struct text_tag_list *tags = text_tag_list_new();
885
921
  int where = MW_OUTPUT;        /* where to display the message */
886
 
  
 
922
  bool fallback_needed = FALSE; /* we want fallback if actual 'where' is not
 
923
                                 * usable */
 
924
  bool shown = FALSE;           /* Message displayed somewhere at least */
 
925
 
887
926
  if (event >= E_LAST)  {
888
927
    /* Server may have added a new event; leave as MW_OUTPUT */
889
 
    freelog(LOG_NORMAL, "Unknown event type %d!", event);
 
928
    freelog(LOG_VERBOSE, "Unknown event type %d!", event);
890
929
  } else if (event >= 0)  {
891
930
    where = messages_where[event];
892
931
  }
893
932
 
894
 
  if (BOOL_VAL(where & MW_OUTPUT)
895
 
      || C_S_RUNNING != client_state()) {
896
 
    /* When the game isn't running, the messages dialog isn't present and
897
 
     * we want to send all messages to the chatline.  There shouldn't be
898
 
     * any problem with server spam in pregame anyway. */
899
 
    append_output_window_full(message, conn_id);
900
 
  }
 
933
  /* Get the original text. */
 
934
  featured_text_to_plain_text(featured_text, plain_text,
 
935
                              sizeof(plain_text), tags);
 
936
 
 
937
  /* Display link marks when an user is pointed us something. */
 
938
  if (conn_id != -1) {
 
939
    text_tag_list_iterate(tags, ptag) {
 
940
      if (text_tag_type(ptag) == TTT_LINK) {
 
941
        link_mark_add_new(text_tag_link_type(ptag), text_tag_link_id(ptag));
 
942
      }
 
943
    } text_tag_list_iterate_end;
 
944
  }
 
945
 
 
946
  /* Maybe highlight our player and user names if someone is talking
 
947
   * about us. */
 
948
  if (highlight_our_names[0] != '\0'
 
949
      && conn_id != -1 && conn_id != client.conn.id) {
 
950
    const char *username = client.conn.username;
 
951
    size_t userlen = strlen(username);
 
952
    const char *playername = ((client_player() && !client_is_observer())
 
953
                              ? player_name(client_player()) : NULL);
 
954
    size_t playerlen = playername ? strlen(playername) : 0;
 
955
    const char *p;
 
956
 
 
957
    if (playername && playername[0] == '\0') {
 
958
      playername = NULL;
 
959
    }
 
960
 
 
961
    if (username && username[0] == '\0') {
 
962
      username = NULL;
 
963
    }
 
964
 
 
965
    for (p = plain_text; *p != '\0'; p++) {
 
966
      if (username
 
967
          && 0 == mystrncasecmp(p, username, userlen)) {
 
968
        /* Appends to be sure it will be applied at last. */
 
969
        text_tag_list_append(tags, text_tag_new(TTT_COLOR, p - plain_text,
 
970
                             p - plain_text + userlen,
 
971
                             ft_color(NULL, highlight_our_names)));
 
972
      } else if (playername
 
973
                 && 0 == mystrncasecmp(p, playername, playerlen)) {
 
974
        /* Appends to be sure it will be applied at last. */
 
975
        text_tag_list_append(tags, text_tag_new(TTT_COLOR, p - plain_text,
 
976
                             p - plain_text + playerlen,
 
977
                             ft_color(NULL, highlight_our_names)));
 
978
      }
 
979
    }
 
980
  }
 
981
 
 
982
  /* Popup */
 
983
  if (BOOL_VAL(where & MW_POPUP)) {
 
984
    /* Popups are usually not shown if player is under AI control.
 
985
     * Server operator messages are shown always. */
 
986
    if (NULL == client.conn.playing
 
987
        || !client.conn.playing->ai_data.control
 
988
        || event == E_MESSAGE_WALL) {
 
989
      popup_notify_goto_dialog(_("Popup Request"), plain_text, tags, ptile);
 
990
      shown = TRUE;
 
991
    } else {
 
992
      /* Force to chatline so it will be visible somewhere at least.
 
993
       * Messages window may still handle this so chatline is not needed
 
994
       * after all. */
 
995
      fallback_needed = TRUE;
 
996
    }
 
997
  }
 
998
 
 
999
  /* Message window */
901
1000
  if (BOOL_VAL(where & MW_MESSAGES)) {
902
 
    add_notify_window(message, ptile, event);
 
1001
    /* When the game isn't running, the messages dialog isn't present. */
 
1002
    if (C_S_RUNNING <= client_state()) {
 
1003
      add_notify_window(plain_text, tags, ptile, event);
 
1004
      shown = TRUE;
 
1005
    } else {
 
1006
      /* Force to chatline instead. */
 
1007
      fallback_needed = TRUE;
 
1008
    }
903
1009
  }
904
 
  if (BOOL_VAL(where & MW_POPUP)
905
 
      && (!game.player_ptr || !game.player_ptr->ai.control)) {
906
 
    popup_notify_goto_dialog(_("Popup Request"), message, ptile);
 
1010
 
 
1011
  /* Chatline */
 
1012
  if (BOOL_VAL(where & MW_OUTPUT) || (fallback_needed && !shown)) {
 
1013
    output_window_event(plain_text, tags, conn_id);
907
1014
  }
908
1015
 
909
1016
  play_sound_for_event(event);
 
1017
 
 
1018
  /* Free tags */
 
1019
  text_tag_list_clear_all(tags);
 
1020
  text_tag_list_free(tags);
910
1021
}
911
1022
 
912
1023
/**************************************************************************
914
1025
  handle_chat_msg.
915
1026
**************************************************************************/
916
1027
void create_event(struct tile *ptile, enum event_type event,
917
 
                  const char *format, ...)
 
1028
                  const struct ft_color color, const char *format, ...)
918
1029
{
919
1030
  va_list ap;
920
1031
  char message[MAX_LEN_MSG];
923
1034
  my_vsnprintf(message, sizeof(message), format, ap);
924
1035
  va_end(ap);
925
1036
 
926
 
  handle_event(message, ptile, event, aconnection.id);
 
1037
  if (ft_color_requested(color)) {
 
1038
    char colored_text[MAX_LEN_MSG];
 
1039
 
 
1040
    featured_text_apply_tag(message, colored_text, sizeof(colored_text),
 
1041
                            TTT_COLOR, 0, OFFSET_UNSET, color);
 
1042
    handle_event(colored_text, ptile, event, -1);
 
1043
  } else {
 
1044
    handle_event(message, ptile, event, -1);
 
1045
  }
927
1046
}
928
1047
 
929
1048
/**************************************************************************
931
1050
**************************************************************************/
932
1051
void write_chatline_content(const char *txt)
933
1052
{
934
 
  FILE *fp = fopen("civgame.log", "w"); /* should allow choice of name? */
 
1053
  FILE *fp = fc_fopen("civgame.log", "w");      /* should allow choice of name? */
935
1054
 
936
 
  append_output_window(_("Exporting output window to civgame.log ..."));
 
1055
  output_window_append(ftc_client,
 
1056
                       _("Exporting output window to civgame.log ..."));
937
1057
  if (fp) {
938
1058
    fputs(txt, fp);
939
1059
    fclose(fp);
940
 
    append_output_window(_("Export complete."));
 
1060
    output_window_append(ftc_client, _("Export complete."));
941
1061
  } else {
942
 
    append_output_window(_("Export failed, couldn't write to file."));
 
1062
    output_window_append(ftc_client,
 
1063
                         _("Export failed, couldn't write to file."));
943
1064
  }
944
1065
}
945
1066
 
1002
1123
  struct city *pcity_near;
1003
1124
  int pcity_near_dist;
1004
1125
 
1005
 
  if ((pcity_near = tile_get_city(punit->tile))) {
 
1126
  if ((pcity_near = tile_city(punit->tile))) {
1006
1127
    pcity_near_dist = 0;
1007
1128
  } else {
1008
1129
    pcity_near = NULL;
1034
1155
**************************************************************************/
1035
1156
void cityrep_buy(struct city *pcity)
1036
1157
{
1037
 
  int value = city_buy_cost(pcity);
 
1158
  int value;
1038
1159
 
1039
 
  if (!pcity->production.is_unit
1040
 
      && improvement_has_flag(pcity->production.value, IF_GOLD)) {
1041
 
    create_event(pcity->tile, E_BAD_COMMAND,
1042
 
                _("You don't buy %s in %s!"),
1043
 
                improvement_name_translation(pcity->production.value),
1044
 
                city_name(pcity));
 
1160
  if (city_production_has_flag(pcity, IF_GOLD)) {
 
1161
    create_event(pcity->tile, E_BAD_COMMAND, ftc_client,
 
1162
                 _("You don't buy %s in %s!"),
 
1163
                 improvement_name_translation(pcity->production.value.building),
 
1164
                 city_link(pcity));
1045
1165
    return;
1046
1166
  }
 
1167
  value = city_production_buy_gold_cost(pcity);
1047
1168
 
1048
1169
  if (city_owner(pcity)->economic.gold >= value) {
1049
1170
    city_buy_production(pcity);
1050
1171
  } else {
1051
 
    const char *name;
1052
 
 
1053
 
    if (pcity->production.is_unit) {
1054
 
      name = utype_name_translation(utype_by_number(pcity->production.value));
1055
 
    } else {
1056
 
      name = get_impr_name_ex(pcity, pcity->production.value);
1057
 
    }
1058
 
 
1059
 
    create_event(NULL, E_BAD_COMMAND,
1060
 
                 _("%s costs %d gold and you only have %d gold."),
1061
 
                 name, value, city_owner(pcity)->economic.gold);
 
1172
    create_event(NULL, E_BAD_COMMAND, ftc_client,
 
1173
                 _("%s costs %d gold and you only have %d gold."),
 
1174
                 city_production_name_translation(pcity),
 
1175
                 value,
 
1176
                 city_owner(pcity)->economic.gold);
1062
1177
  }
1063
1178
}
1064
1179
 
1071
1186
    return;
1072
1187
  }
1073
1188
 
1074
 
  lux_end = game.player_ptr->economic.luxury;
1075
 
  sci_end = lux_end + game.player_ptr->economic.science;
 
1189
  lux_end = client.conn.playing->economic.luxury;
 
1190
  sci_end = lux_end + client.conn.playing->economic.science;
1076
1191
  tax_end = 100;
1077
1192
 
1078
 
  lux = game.player_ptr->economic.luxury;
1079
 
  sci = game.player_ptr->economic.science;
1080
 
  tax = game.player_ptr->economic.tax;
 
1193
  lux = client.conn.playing->economic.luxury;
 
1194
  sci = client.conn.playing->economic.science;
 
1195
  tax = client.conn.playing->economic.tax;
1081
1196
 
1082
1197
  i *= 10;
1083
1198
  if (i < lux_end) {
1090
1205
    tax -= delta;
1091
1206
    lux += delta;
1092
1207
  }
1093
 
  dsend_packet_player_rates(&aconnection, tax, lux, sci);
 
1208
  dsend_packet_player_rates(&client.conn, tax, lux, sci);
1094
1209
}
1095
1210
 
1096
1211
/****************************************************************************
1109
1224
}
1110
1225
 
1111
1226
/****************************************************************************
 
1227
  Determines which color type should be used for unit background.
 
1228
  This is only guesswork based on unit properties. One should not
 
1229
  take UNIT_BG_FLYING seriously meaning that unit can fly - custom
 
1230
  ruleset might have units with similar properties but explains these
 
1231
  properties by some other means than by flying. 
 
1232
****************************************************************************/
 
1233
enum unit_bg_color_type unit_color_type(const struct unit_type *punittype)
 
1234
{
 
1235
  struct unit_class *pclass = utype_class(punittype);
 
1236
 
 
1237
  if (pclass->hp_loss_pct > 0) {
 
1238
    return UNIT_BG_HP_LOSS;
 
1239
  }
 
1240
 
 
1241
  if (pclass->move_type == LAND_MOVING) {
 
1242
    return UNIT_BG_LAND;
 
1243
  }
 
1244
  if (pclass->move_type == SEA_MOVING) {
 
1245
    return UNIT_BG_SEA;
 
1246
  }
 
1247
 
 
1248
  assert(pclass->move_type == BOTH_MOVING);
 
1249
 
 
1250
  if (uclass_has_flag(pclass, UCF_TERRAIN_SPEED)) {
 
1251
    /* Unit moves on both sea and land by speed determined by terrain */
 
1252
    return UNIT_BG_AMPHIBIOUS;
 
1253
  }
 
1254
 
 
1255
  return UNIT_BG_FLYING;
 
1256
}
 
1257
 
 
1258
/****************************************************************************
1112
1259
  Comparison function used by qsort in buy_production_in_selected_cities().
1113
1260
****************************************************************************/
1114
1261
static int city_buy_cost_compare(const void *a, const void *b)
1116
1263
  const struct city *ca, *cb;
1117
1264
  ca = *((const struct city **) a);
1118
1265
  cb = *((const struct city **) b);
1119
 
  return city_buy_cost(ca) - city_buy_cost(cb);
 
1266
  return (city_production_buy_gold_cost(ca)
 
1267
          - city_production_buy_gold_cost(cb));
1120
1268
}
1121
1269
 
1122
1270
/****************************************************************************
1125
1273
****************************************************************************/
1126
1274
void buy_production_in_selected_cities(void)
1127
1275
{
1128
 
  const struct player *pplayer = game.player_ptr;
 
1276
  const struct player *pplayer = client_player();
1129
1277
  if (!pplayer || !pplayer->cities
1130
1278
      || city_list_size(pplayer->cities) < 1) {
1131
1279
    return;
1153
1301
 
1154
1302
  qsort(cities, count, sizeof(*cities), city_buy_cost_compare);
1155
1303
 
1156
 
  struct connection *pconn = &aconnection;
 
1304
  struct connection *pconn = &client.conn;
1157
1305
  connection_do_buffer(pconn);
1158
1306
 
1159
1307
  for (i = 0; i < count && gold > 0; i++) {
1160
 
    gold -= city_buy_cost(cities[i]);
 
1308
    gold -= city_production_buy_gold_cost(cities[i]);
1161
1309
    city_buy_production(cities[i]);
1162
1310
  }
1163
1311