Freeciv-3.4
Loading...
Searching...
No Matches
api_server_edit.c
Go to the documentation of this file.
1/*****************************************************************************
2 Freeciv - Copyright (C) 2005 - The Freeciv Project
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/* utility */
19#include "rand.h"
20
21/* common */
22#include "citizens.h"
23#include "map.h"
24#include "movement.h"
25#include "research.h"
26#include "unittype.h"
27
28/* common/scriptcore */
29#include "api_game_find.h"
30#include "luascript.h"
31
32/* server */
33#include "aiiface.h"
34#include "barbarian.h"
35#include "citytools.h"
36#include "cityturn.h" /* city_refresh() auto_arrange_workers() */
37#include "console.h" /* enum rfc_status */
38#include "gamehand.h"
39#include "maphand.h"
40#include "notify.h"
41#include "plrhand.h"
42#include "srv_main.h" /* game_was_started() */
43#include "stdinhand.h"
44#include "techtools.h"
45#include "unithand.h"
46#include "unittools.h"
47
48/* server/scripting */
49#include "script_server.h"
50
51/* server/generator */
52#include "mapgen_utils.h"
53
54#include "api_server_edit.h"
55
56
57/**********************************************************************/
67
68/**********************************************************************/
72static bool
74 int vet_loss)
75{
77 /* Avoid getting overt veteranship if a user requests increasing it */
78 if (vet_loss < 0) {
80
81 vl = punit->veteran - vl + 1;
82 if (vl >= 0) {
83 vet_loss = 0;
84 } else {
86 }
87 }
89 return TRUE;
90 } else {
91 return FALSE;
92 }
93}
94
95/**********************************************************************/
99 int count, int sq_radius)
100{
102 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 2, Tile);
103 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 3, Player);
104 LUASCRIPT_CHECK_ARG(L, 0 <= sq_radius, 5, "radius must be positive");
106 "no partisans in ruleset");
107
108 return place_partisans(ptile, pplayer, count, sq_radius);
109}
110
111/**********************************************************************/
116 City *homecity, int moves_left)
117{
118 return api_edit_create_unit_full(L, pplayer, ptile, ptype, veteran_level,
119 homecity, moves_left, -1, NULL);
120}
121
122/**********************************************************************/
126 Tile *ptile,
128 City *homecity, int moves_left,
129 int hp_left,
131{
132 struct fc_lua *fcl;
133 struct city *pcity;
134 struct unit *punit;
135#ifndef FREECIV_NDEBUG
136 bool placed;
137#endif
138
140 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player, NULL);
141 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 3, Tile, NULL);
142
144
145 LUASCRIPT_CHECK(L, fcl != NULL, "Undefined Freeciv lua state!", NULL);
146
147 if (ptype == NULL
149 return NULL;
150 }
151
152 if (is_non_allied_unit_tile(ptile, pplayer,
154 luascript_log(fcl, LOG_ERROR, "create_unit_full: tile is occupied by "
155 "enemy unit");
156 return NULL;
157 }
158
159 pcity = tile_city(ptile);
160 if (pcity != NULL && !pplayers_allied(pplayer, city_owner(pcity))) {
161 luascript_log(fcl, LOG_ERROR, "create_unit_full: tile is occupied by "
162 "enemy city");
163 return NULL;
164 }
165
168 "create_unit_full: player already has unique unit");
169 return NULL;
170 }
171
173 homecity ? homecity->id : 0,
175 if (ptransport) {
176 /* The unit maybe can't freely load into the transport
177 * but must be able to be in it, see can_unit_load() */
178 int ret = same_pos(ptile, unit_tile(ptransport))
180
181 if (!ret) {
183 luascript_log(fcl, LOG_ERROR, "create_unit_full: '%s' cannot transport "
184 "'%s' here",
187 return NULL;
188 }
189 } else if (!can_exist_at_tile(&(wld.map), ptype, ptile)) {
191 luascript_log(fcl, LOG_ERROR, "create_unit_full: '%s' cannot exist at "
192 "tile", utype_rule_name(ptype));
193 return NULL;
194 }
195
196#ifndef FREECIV_NDEBUG
197 placed =
198#endif
201
202 return punit;
203}
204
205/**********************************************************************/
210 bool conquer_city, bool conquer_extra,
211 bool enter_hut, bool frighten_hut)
212{
213 bool alive;
214
218
220 "Can't both enter and frighten a hut at the same time",
221 TRUE);
222
224 /* Can't leave the transport. */
225 return TRUE;
226 }
227
229 unit_tile(punit), dest, FALSE,
230 embark_to, TRUE) != MR_OK) {
231 /* Can't teleport to target. Return that unit is still alive. */
232 return TRUE;
233 }
234
235 /* Teleport first so destination is revealed even if unit dies */
236 alive = unit_move(punit, dest, 0,
240 if (alive) {
241 struct player *owner = unit_owner(punit);
242 struct city *pcity = tile_city(dest);
243
244 if (!can_unit_exist_at_tile(&(wld.map), punit, dest)
245 && !unit_transported(punit)) {
247 return FALSE;
248 }
251 || (pcity != NULL
254 return FALSE;
255 }
256 }
257
258 return alive;
259}
260
261/***********************************************************************/
265 Action *paction, City *tgt)
266{
271 "Not a unit-performed action", FALSE);
273 "Not a city-targeted action", FALSE);
275
279 tgt->id, IDENTITY_NUMBER_ZERO, "",
281 } else {
282 /* Action not enabled */
283 return FALSE;
284 }
285}
286
287/***********************************************************************/
291 Action *paction, City *tgt,
293{
298 "Not a unit-performed action", FALSE);
300 "Not a city-targeted action", FALSE);
303
307 tgt->id, sub_tgt->item_number, "",
309 } else {
310 /* Action not enabled */
311 return FALSE;
312 }
313}
314
315/***********************************************************************/
319 Action *paction, City *tgt,
321{
326 "Not a unit-performed action", FALSE);
328 "Not a city-targeted action", FALSE);
331
335 tgt->id, sub_tgt->item_number, "",
337 } else {
338 /* Action not enabled */
339 return FALSE;
340 }
341}
342
343/***********************************************************************/
347 Action *paction, Unit *tgt)
348{
349 const struct civ_map *nmap = &(wld.map);
350
355 "Not a unit-performed action", FALSE);
357 "Not a unit-targeted action", FALSE);
359
363 tgt->id, IDENTITY_NUMBER_ZERO, "",
365 } else {
366 /* Action not enabled */
367 return FALSE;
368 }
369}
370
371/***********************************************************************/
375 Action *paction, Tile *tgt)
376{
377 bool enabled = FALSE;
378 const struct civ_map *nmap = &(wld.map);
379
384 "Not a unit-performed action", FALSE);
386
388 case ATK_STACK:
390 break;
391 case ATK_TILE:
393 tgt, NULL);
394 break;
395 case ATK_EXTRAS:
397 tgt, NULL);
398 break;
399 case ATK_CITY:
400 /* Not handled here. */
402 "City-targeted action applied to tile", FALSE);
403 break;
404 case ATK_UNIT:
405 /* Not handled here. */
407 "Unit-targeted action applied to tile", FALSE);
408 break;
409 case ATK_SELF:
410 /* Not handled here. */
412 "Self-targeted action applied to tile", FALSE);
413 break;
414 case ATK_COUNT:
415 /* Should not exist */
417 break;
418 }
419
420 if (enabled) {
425 } else {
426 /* Action not enabled */
427 return FALSE;
428 }
429}
430
431/***********************************************************************/
435 Action *paction, Tile *tgt,
436 const char *sub_tgt)
437{
438 struct extra_type *sub_target;
439 bool enabled = FALSE;
440 const struct civ_map *nmap = &(wld.map);
441
446 "Not a unit-performed action", FALSE);
449
450 sub_target = extra_type_by_rule_name(sub_tgt);
451 LUASCRIPT_CHECK_ARG(L, sub_target != NULL, 5, "No such extra", FALSE);
452
454 case ATK_STACK:
456 break;
457 case ATK_TILE:
459 tgt, sub_target);
460 break;
461 case ATK_EXTRAS:
463 tgt, sub_target);
464 break;
465 case ATK_CITY:
466 /* Not handled here. */
468 "City-targeted action applied to tile", FALSE);
469 break;
470 case ATK_UNIT:
471 /* Not handled here. */
473 "Unit-targeted action applied to tile", FALSE);
474 break;
475 case ATK_SELF:
476 /* Not handled here. */
478 "Self-targeted action applied to tile", FALSE);
479 break;
480 case ATK_COUNT:
481 /* Should not exist */
483 break;
484 }
485
486 if (enabled) {
488 tile_index(tgt), sub_target->id,
491 } else {
492 /* Action not enabled */
493 return FALSE;
494 }
495}
496
497/***********************************************************************/
502{
503 const struct civ_map *nmap = &(wld.map);
504
509 "Not a unit-performed action", FALSE);
511 "Not a self-targeted action", FALSE);
516 "",
518 } else {
519 /* Action not enabled */
520 return FALSE;
521 }
522}
523
524/**********************************************************************/
528{
531
532 if (direction8_is_valid(dir)) {
533 punit->facing = dir;
534
536 } else {
537 log_error("Illegal direction %d for unit from lua script", dir);
538 }
539}
540
541/**********************************************************************/
558
559/**********************************************************************/
572
573/**********************************************************************/
592
593/**********************************************************************/
597 const char *reason, Player *killer)
598{
601
602 self->hp += change;
603
604 if (self->hp <= 0) {
607
609
610 /* Intentionally only after wiping, so that unit is never left with
611 * zero or less hit points. */
613 "Invalid unit loss reason", FALSE);
614
615 return FALSE;
616 } else {
617 int max = unit_type_get(self)->hp;
618
619 if (self->hp > max) {
620 self->hp = max;
621 }
622 }
623
625
626 return TRUE;
627}
628
629/**********************************************************************/
633{
634 bool was_exhausted = FALSE;
635
638
639 if (self->moves_left == 0 && self->done_moving) {
641 }
642
643 self->moves_left += change;
644
645 if (self->moves_left <= 0) {
646 self->moves_left = 0;
647 } else if (was_exhausted && !unit_has_orders(self)) {
648 /* Unit has regained ability to move. */
649 self->done_moving = FALSE;
650 }
651
653}
654
655/**********************************************************************/
659{
660 struct terrain *old_terrain;
661
663 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 2, Tile, FALSE);
665
666 old_terrain = tile_terrain(ptile);
667
668 if (old_terrain == pterr
670 && tile_city(ptile) != NULL)) {
671 return FALSE;
672 }
673
678
679 /* FIXME: adv / ai phase handling like in check_terrain_change() */
680
682 }
683
685
687
688 return TRUE;
689}
690
691/**********************************************************************/
695 const char *name, Player *nationality)
696{
698 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player, FALSE);
699 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 3, Tile, FALSE);
700
701 return create_city_for_player(pplayer, ptile, name, nationality);
702}
703
704/**********************************************************************/
714
715/**********************************************************************/
726
727/**********************************************************************/
731{
735 /* FIXME: may "Special" impr be buildable? */
737 "It is a special item, not a city building");
738
739 if (!city_has_building(pcity, impr)) {
740 bool need_game_info = FALSE;
741 bool need_plr_info = FALSE;
742 struct player *old_owner = NULL, *pplayer = city_owner(pcity);
743 struct city *oldcity;
744
746 if (oldcity) {
748 }
749 if (old_owner && old_owner != pplayer) {
750 /* Great wonders make more changes. */
752 }
753
754 if (oldcity) {
755 if (city_refresh(oldcity)) {
757 }
759 }
760
761 if (city_refresh(pcity)) {
763 }
765 if (need_game_info) {
768 }
769 if (need_plr_info) {
770 send_player_info_c(pplayer, NULL);
771 }
772 }
773}
774
775/**********************************************************************/
796
797/**********************************************************************/
805 Specialist *s, int amount)
806{
808
812 LUASCRIPT_CHECK_ARG(L, amount >= 0, 3, "must be non-negative", FALSE);
813
814 from = specialist_index(s);
815 if (pcity->specialists[from] < amount) {
816 return FALSE;
817 }
818
819 if (is_super_specialist_id(from)) {
820 /* Just reduce superspecialists */
821 pcity->specialists[from] -= amount;
822 } else {
823 /* Toggle normal specialist */
824 Specialist_type_id to = from;
825
826 do {
827 to = (to + 1) % normal_specialist_count();
828 } while (to != from && !city_can_use_specialist(pcity, to));
829
830 if (to == from) {
831 /* We can use only the default specialist */
832 return FALSE;
833 } else {
834 /* City population must be correct */
835 fc_assert_ret_val_msg(pcity->specialists[to] <= amount - MAX_CITY_SIZE,
836 FALSE, "Wrong specialist number in %s",
838 pcity->specialists[from] -= amount;
839 pcity->specialists[to] += amount;
840 }
841 }
842
844 /* sanity_check_city(pcity); -- hopefully we don't break things here? */
846
847 return TRUE;
848}
849
850/**********************************************************************/
857 Specialist *s, int amount)
858{
860 int csize = 0;
861
865 LUASCRIPT_CHECK_ARG(L, amount >= 0, 3, "must be non-negative", FALSE);
866
868
870 /* Can't employ this one */
871 return FALSE;
872 }
873 if (is_super_specialist(s)) {
874 if (pcity->specialists[sid] > MAX_CITY_SIZE - amount) {
875 /* No place for the specialist */
876 return FALSE;
877 }
878 pcity->specialists[sid] += amount;
881 } else {
883
884 if (csize > MAX_CITY_SIZE - amount) {
885 /* No place for the specialist */
886 return FALSE;
887 }
890 send_city_info(nullptr, pcity);
891 }
892
893 return TRUE;
894}
895
896/**********************************************************************/
899Player *api_edit_create_player(lua_State *L, const char *username,
900 Nation_Type *pnation, const char *ai)
901{
902 struct player *pplayer = NULL;
903 char buf[128] = "";
904 struct fc_lua *fcl;
905
907 LUASCRIPT_CHECK_ARG_NIL(L, username, 2, string, NULL);
908 if (!ai) {
910 }
911
913
914 LUASCRIPT_CHECK(L, fcl != NULL, "Undefined Freeciv lua state!", NULL);
915
916 if (game_was_started()) {
917 create_command_newcomer(username, ai, FALSE, pnation, &pplayer,
918 buf, sizeof(buf));
919 } else {
920 create_command_pregame(username, ai, FALSE, &pplayer,
921 buf, sizeof(buf));
922 }
923
924 if (strlen(buf) > 0) {
926 }
927
928 return pplayer;
929}
930
931/**********************************************************************/
935{
937 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player);
938
939 pplayer->economic.gold = MAX(0, pplayer->economic.gold + amount);
940
941 send_player_info_c(pplayer, NULL);
942}
943
944/**********************************************************************/
948{
950 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player);
951
952 pplayer->economic.infra_points
953 = MAX(0, pplayer->economic.infra_points + amount);
954
955 send_player_info_c(pplayer, NULL);
956}
957
958/**********************************************************************/
965 Tech_Type *ptech, int cost,
966 bool notify,
967 const char *reason)
968{
969 struct research *presearch;
971 Tech_Type *result;
972
974 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player, NULL);
975 LUASCRIPT_CHECK_ARG(L, cost >= -3, 4, "Unknown give_tech() cost value", NULL);
976
977 presearch = research_get(pplayer);
978 if (ptech) {
979 id = advance_number(ptech);
980 } else {
982 }
983
984 if (is_future_tech(id)
986 if (cost < 0) {
987 if (cost == -1) {
989 } else if (cost == -2) {
991 } else if (cost == -3) {
993 } else {
994 cost = 0;
995 }
996 }
999 result = advance_by_number(id);
1000 script_tech_learned(presearch, pplayer, result, reason);
1001
1002 if (notify && result != NULL) {
1004 char research_name[MAX_LEN_NAME * 2];
1005
1007
1009 Q_("?fromscript:You acquire %s."), adv_name);
1011 /* TRANS: "The Greeks ..." or "The members of
1012 * team Red ..." */
1013 Q_("?fromscript:The %s acquire %s and share this "
1014 "advance with you."),
1017 /* TRANS: "The Greeks ..." or "The members of
1018 * team Red ..." */
1019 Q_("?fromscript:The %s acquire %s."),
1021 }
1022
1023 return result;
1024 } else {
1025 return NULL;
1026 }
1027}
1028
1029/**********************************************************************/
1033 const char *tname, const int mod)
1034{
1035 enum trait tr;
1036
1038 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player, FALSE);
1039 LUASCRIPT_CHECK_ARG_NIL(L, tname, 3, string, FALSE);
1040
1042
1043 LUASCRIPT_CHECK_ARG(L, trait_is_valid(tr), 3, "no such trait", 0);
1044
1045 pplayer->ai_common.traits[tr].mod += mod;
1046
1047 return TRUE;
1048}
1049
1050/**********************************************************************/
1054 const char *name, Player *pplayer)
1055{
1056 struct extra_type *pextra;
1057
1059 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 2, Tile);
1060
1061 if (name == NULL) {
1062 return;
1063 }
1064
1065 pextra = extra_type_by_rule_name(name);
1066
1067 if (pextra != NULL) {
1068 create_extra(ptile, pextra, pplayer);
1069 update_tile_knowledge(ptile);
1071 }
1072}
1073
1074/**********************************************************************/
1077void api_edit_create_extra(lua_State *L, Tile *ptile, const char *name)
1078{
1080}
1081
1082/**********************************************************************/
1085void api_edit_create_base(lua_State *L, Tile *ptile, const char *name,
1086 Player *pplayer)
1087{
1088 api_edit_create_owned_extra(L, ptile, name, pplayer);
1089}
1090
1091/**********************************************************************/
1094void api_edit_create_road(lua_State *L, Tile *ptile, const char *name)
1095{
1097}
1098
1099/**********************************************************************/
1102void api_edit_remove_extra(lua_State *L, Tile *ptile, const char *name)
1103{
1104 struct extra_type *pextra;
1105
1107 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 2, Tile);
1108
1109 if (name == NULL) {
1110 return;
1111 }
1112
1113 pextra = extra_type_by_rule_name(name);
1114
1115 if (pextra != NULL && tile_has_extra(ptile, pextra)) {
1116 tile_extra_rm_apply(ptile, pextra);
1117 update_tile_knowledge(ptile);
1119 }
1120}
1121
1122/**********************************************************************/
1125void api_edit_tile_set_label(lua_State *L, Tile *ptile, const char *label)
1126{
1128 LUASCRIPT_CHECK_SELF(L, ptile);
1129 LUASCRIPT_CHECK_ARG_NIL(L, label, 3, string);
1130
1131 tile_set_label(ptile, label);
1132 if (server_state() >= S_S_RUNNING) {
1133 send_tile_info(NULL, ptile, FALSE);
1134 }
1135}
1136
1137/**********************************************************************/
1140void api_edit_tile_show(lua_State *L, Tile *ptile, Player *pplayer)
1141{
1143 LUASCRIPT_CHECK_SELF(L, ptile);
1144 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 3, Player);
1145
1146 map_show_tile(pplayer, ptile);
1147}
1148
1149/**********************************************************************/
1152bool api_edit_tile_hide(lua_State *L, Tile *ptile, Player *pplayer)
1153{
1154 struct city *pcity;
1155
1157 LUASCRIPT_CHECK_SELF(L, ptile, FALSE);
1158 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 3, Player, FALSE);
1159
1160 if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
1161 /* Can't hide currently seen tile */
1162 return FALSE;
1163 }
1164
1165 pcity = tile_city(ptile);
1166
1167 if (pcity != NULL) {
1168 trade_partners_iterate(pcity, partner) {
1169 if (really_gives_vision(pplayer, city_owner(partner))) {
1170 /* Can't remove vision about trade partner */
1171 return FALSE;
1172 }
1174 }
1175
1176 dbv_clr(&pplayer->tile_known, tile_index(ptile));
1177
1178 send_tile_info(pplayer->connections, ptile, TRUE);
1179
1180 return TRUE;
1181}
1182
1183/**********************************************************************/
1187 int effect)
1188{
1192 2, "invalid climate change type");
1193 LUASCRIPT_CHECK_ARG(L, effect > 0, 3, "effect must be greater than zero");
1194
1196}
1197
1198/**********************************************************************/
1202{
1204 LUASCRIPT_CHECK_ARG_NIL(L, pplayer, 2, Player, NULL);
1206 3, "must be a percentage", NULL);
1207
1208 if (!civil_war_possible(pplayer, FALSE, FALSE)) {
1209 return NULL;
1210 }
1211
1212 if (probability == 0) {
1213 /* Calculate chance with normal rules */
1214 if (!civil_war_triggered(pplayer)) {
1215 return NULL;
1216 }
1217 } else {
1218 /* Fixed chance specified by script */
1219 if (fc_rand(100) >= probability) {
1220 return NULL;
1221 }
1222 }
1223
1224 return civil_war(pplayer);
1225}
1226
1227/**********************************************************************/
1231{
1233 LUASCRIPT_CHECK_SELF(L, pplayer);
1234
1236}
1237
1238/**********************************************************************/
1242 int movecost,
1243 Unit *embark_to, bool disembark,
1244 bool conquer_city, bool conquer_extra,
1245 bool enter_hut, bool frighten_hut)
1246{
1249 LUASCRIPT_CHECK_ARG_NIL(L, ptile, 3, Tile, FALSE);
1250 LUASCRIPT_CHECK_ARG(L, movecost >= 0, 4, "Negative move cost!", FALSE);
1251
1253 "Can't both enter and frighten a hut at the same time",
1254 TRUE);
1255
1256 if (!disembark && unit_transported(punit)) {
1257 /* Can't leave the transport. */
1258 return TRUE;
1259 }
1260
1262 unit_tile(punit), ptile, TRUE,
1263 FALSE, embark_to, TRUE) != MR_OK) {
1264 /* Can't move to target. Return that unit is still alive. */
1265 return TRUE;
1266 }
1267
1268 return unit_move(punit, ptile, movecost,
1272}
1273
1274/**********************************************************************/
1278{
1281
1282 if (punit != NULL) {
1283 punit->stay = TRUE;
1284 }
1285}
1286
1287/**********************************************************************/
1291{
1294
1295 if (punit != NULL) {
1296 punit->stay = FALSE;
1297 }
1298}
1299
1300/**********************************************************************/
1304{
1307
1308 pcity->history += amount;
1309}
1310
1311/**********************************************************************/
1315{
1317 LUASCRIPT_CHECK_SELF(L, pplayer);
1318
1319 pplayer->history += amount;
1320}
1321
1322/**********************************************************************/
1334 Tech_Type *tech)
1335{
1336 struct research *presearch;
1337
1339 LUASCRIPT_CHECK_SELF(L, pplayer);
1340 presearch = research_get(pplayer);
1342
1343 if (!tech) {
1344 update_bulbs(pplayer, amount, TRUE, TRUE);
1345
1347 } else if (advance_number(tech) == presearch->researching) {
1348 update_bulbs(pplayer, amount, TRUE, FALSE);
1349 /* Clean the saved tech to get no surprizes switching */
1350 presearch->researching_saved = A_UNKNOWN;
1351
1353 } else {
1354 /* Sometimes we may set negative bulbs, it's normal though lurking */
1356 presearch->inventions[advance_number(tech)].bulbs_researched_saved
1357 += amount;
1358 /* Currently, multiresearch data are not sent to clients */
1359 } else {
1360 int oldb = presearch->bulbs_researched;
1361
1362 /* NOTE: We can set a tech we already know / can't research here.
1363 * Probably it's safe as we can't switch into it any way. */
1364 if (presearch->researching_saved != advance_number(tech)) {
1365 presearch->researching_saved = advance_number(tech);
1366 presearch->bulbs_researching_saved
1367 = amount + presearch->free_bulbs;
1368 } else {
1369 presearch->bulbs_researching_saved
1370 += amount + presearch->free_bulbs;
1371 }
1372 /* For consistency, modify current bulbs alongside
1373 * (sometimes getting into "overresearch" situation, but ok) */
1374 presearch->bulbs_researched = amount
1375 - amount * game.server.techpenalty / 100 + presearch->free_bulbs;
1376 if (oldb != presearch->bulbs_researched) {
1378 }
1379 }
1380 }
1381}
1382
1383/**********************************************************************/
1387{
1388 struct player *pplayer, *partner_player;
1389
1391 LUASCRIPT_CHECK_ARG_NIL(L, from, 2, City, FALSE);
1393
1394 /* Priority zero -> never replace old routes. */
1395 if (!can_establish_trade_route(from, to, 0)) {
1396 return FALSE;
1397 }
1398
1400
1401 /* Refresh the cities. */
1402 city_refresh(from);
1403 city_refresh(to);
1404
1405 pplayer = city_owner(from);
1407
1408 send_city_info(pplayer, from);
1410
1411 /* Notify each player about the other's cities. */
1412 if (pplayer != partner_player && game.info.reveal_trade_partner) {
1415 map_show_tile(pplayer, city_tile(to));
1416 send_city_info(pplayer, to);
1417 }
1418
1419 return TRUE;
1420}
1421
1422/**********************************************************************/
1426 Player *nationality)
1427{
1430
1431 if (nationality == nullptr) {
1432 nationality = city_owner(pcity);
1433 }
1434
1435 city_change_size(pcity, city_size_get(pcity) + change, nationality,
1436 -1, "script");
1437}
1438
1439/**********************************************************************/
enum action_actor_kind action_get_actor_kind(const struct action *paction)
Definition actions.c:1119
bool is_action_enabled_unit_on_stack(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:3268
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:3344
bool is_action_enabled_unit_on_city(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Definition actions.c:3103
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:3180
enum action_target_kind action_get_target_kind(const struct action *paction)
Definition actions.c:1129
bool is_action_enabled_unit_on_self(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit)
Definition actions.c:3493
bool is_action_enabled_unit_on_extras(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:3421
#define action_has_result(_act_, _res_)
Definition actions.h:184
const char * default_ai_type_name(void)
Definition aiiface.c:249
void api_edit_change_city_size(lua_State *L, City *pcity, int change, Player *nationality)
static bool ur_transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
bool api_edit_perform_action_unit_vs_tile_extra(lua_State *L, Unit *punit, Action *paction, Tile *tgt, const char *sub_tgt)
bool api_edit_perform_action_unit_vs_tile(lua_State *L, Unit *punit, Action *paction, Tile *tgt)
void api_edit_climate_change(lua_State *L, enum climate_change_type type, int effect)
void api_edit_player_give_bulbs(lua_State *L, Player *pplayer, int amount, Tech_Type *tech)
bool api_edit_city_add_specialist(lua_State *L, City *pcity, Specialist *s, int amount)
void api_edit_unit_moving_allow(lua_State *L, Unit *punit)
void api_edit_remove_city(lua_State *L, City *pcity)
bool api_edit_trait_mod_set(lua_State *L, Player *pplayer, const char *tname, const int mod)
bool api_edit_unleash_barbarians(lua_State *L, Tile *ptile)
void api_edit_remove_building(lua_State *L, City *pcity, Building_Type *impr)
void api_edit_player_victory(lua_State *L, Player *pplayer)
void api_edit_create_extra(lua_State *L, Tile *ptile, const char *name)
void api_edit_unit_movepoints(lua_State *L, Unit *self, int change)
Unit * api_edit_create_unit(lua_State *L, Player *pplayer, Tile *ptile, Unit_Type *ptype, int veteran_level, City *homecity, int moves_left)
bool api_edit_perform_action_unit_vs_unit(lua_State *L, Unit *punit, Action *paction, Unit *tgt)
void api_edit_player_add_history(lua_State *L, Player *pplayer, int amount)
Tech_Type * api_edit_give_technology(lua_State *L, Player *pplayer, Tech_Type *ptech, int cost, bool notify, const char *reason)
bool api_edit_perform_action_unit_vs_city_impr(lua_State *L, Unit *punit, Action *paction, City *tgt, Building_Type *sub_tgt)
void api_edit_create_building(lua_State *L, City *pcity, Building_Type *impr)
Unit * api_edit_create_unit_full(lua_State *L, Player *pplayer, Tile *ptile, Unit_Type *ptype, int veteran_level, City *homecity, int moves_left, int hp_left, Unit *ptransport)
bool api_edit_transfer_city(lua_State *L, City *pcity, Player *new_owner)
bool api_edit_change_terrain(lua_State *L, Tile *ptile, Terrain *pterr)
void api_edit_create_owned_extra(lua_State *L, Tile *ptile, const char *name, Player *pplayer)
void api_edit_tile_show(lua_State *L, Tile *ptile, Player *pplayer)
void api_edit_unit_kill(lua_State *L, Unit *punit, const char *reason, Player *killer)
bool api_edit_tile_hide(lua_State *L, Tile *ptile, Player *pplayer)
void api_edit_unit_turn(lua_State *L, Unit *punit, Direction dir)
void api_edit_place_partisans(lua_State *L, Tile *ptile, Player *pplayer, int count, int sq_radius)
void api_edit_remove_extra(lua_State *L, Tile *ptile, const char *name)
bool api_edit_city_reduce_specialists(lua_State *L, City *pcity, Specialist *s, int amount)
bool api_edit_unit_hitpoints(lua_State *L, Unit *self, int change, const char *reason, Player *killer)
void api_edit_tile_set_label(lua_State *L, Tile *ptile, const char *label)
void api_edit_create_road(lua_State *L, Tile *ptile, const char *name)
void api_edit_change_citizen_nationality(lua_State *L, City *pcity, Player *from, Player *to, int amount)
bool api_edit_perform_action_unit_vs_city(lua_State *L, Unit *punit, Action *paction, City *tgt)
void api_edit_city_add_history(lua_State *L, City *pcity, int amount)
bool api_edit_unit_teleport(lua_State *L, Unit *punit, Tile *dest, Unit *embark_to, bool allow_disembark, bool conquer_city, bool conquer_extra, bool enter_hut, bool frighten_hut)
void api_edit_unit_moving_disallow(lua_State *L, Unit *punit)
bool api_edit_unit_upgrade(lua_State *L, Unit *punit, int vet_loss)
bool api_edit_create_city(lua_State *L, Player *pplayer, Tile *ptile, const char *name, Player *nationality)
bool api_edit_create_trade_route(lua_State *L, City *from, City *to)
bool api_edit_unit_move(lua_State *L, Unit *punit, Tile *ptile, int movecost, Unit *embark_to, bool disembark, bool conquer_city, bool conquer_extra, bool enter_hut, bool frighten_hut)
void api_edit_change_infrapoints(lua_State *L, Player *pplayer, int amount)
bool api_edit_perform_action_unit_vs_self(lua_State *L, Unit *punit, Action *paction)
Player * api_edit_create_player(lua_State *L, const char *username, Nation_Type *pnation, const char *ai)
bool api_edit_unit_transform(lua_State *L, Unit *punit, Unit_Type *ptype, int vet_loss)
void api_edit_change_gold(lua_State *L, Player *pplayer, int amount)
Player * api_edit_civil_war(lua_State *L, Player *pplayer, int probability)
bool api_edit_perform_action_unit_vs_city_tech(lua_State *L, Unit *punit, Action *paction, City *tgt, Tech_Type *sub_tgt)
void api_edit_create_base(lua_State *L, Tile *ptile, const char *name, Player *pplayer)
climate_change_type
@ CLIMATE_CHANGE_GLOBAL_WARMING
@ CLIMATE_CHANGE_NUCLEAR_WINTER
bool unleash_barbarians(struct tile *ptile)
Definition barbarian.c:272
void dbv_clr(struct dbv *pdbv, int bit)
Definition bitvector.c:163
void citizens_nation_move(struct city *pcity, const struct player_slot *pslot_from, const struct player_slot *pslot_to, int move)
Definition citizens.c:130
bool city_has_building(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:1240
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
void city_remove_improvement(struct city *pcity, const struct impr_type *pimprove)
Definition city.c:3411
bool city_can_use_specialist(const struct city *pcity, Specialist_type_id type)
Definition city.c:1065
#define city_tile(_pcity_)
Definition city.h:564
static citizens city_size_get(const struct city *pcity)
Definition city.h:569
#define city_owner(_pcity_)
Definition city.h:563
#define MAX_CITY_SIZE
Definition city.h:104
bool create_city_for_player(struct player *pplayer, struct tile *ptile, const char *name, struct player *nationality)
Definition citytools.c:1681
const char * city_name_suggestion(struct player *pplayer, struct tile *ptile)
Definition citytools.c:458
void send_city_info(struct player *dest, struct city *pcity)
Definition citytools.c:2368
struct city * build_or_move_building(struct city *pcity, struct impr_type *pimprove, struct player **oldcity_owner)
Definition citytools.c:3032
void remove_city(struct city *pcity)
Definition citytools.c:1713
bool transfer_city(struct player *ptaker, struct city *pcity, int kill_outside, bool transfer_unit_verbose, bool resolve_stack, bool raze, bool build_free)
Definition citytools.c:1077
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
bool city_refresh(struct city *pcity)
Definition cityturn.c:159
bool city_change_size(struct city *pcity, citizens size, struct player *nationality, Specialist_type_id sid, const char *reason)
Definition cityturn.c:1068
static struct ai_type * self
Definition classicai.c:46
char * incite_cost
Definition comments.c:77
static void enter_hut(QVariant data1, QVariant data2)
Definition dialogs.cpp:2681
static void frighten_hut(QVariant data1, QVariant data2)
Definition dialogs.cpp:2711
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
int int id
Definition editgui_g.h:28
struct extra_type * extra_type_by_rule_name(const char *name)
Definition extras.c:212
int Tech_type_id
Definition fc_types.h:238
int Specialist_type_id
Definition fc_types.h:236
#define MAX_LEN_NAME
Definition fc_types.h:68
#define IDENTITY_NUMBER_ZERO
Definition fc_types.h:94
#define Q_(String)
Definition fcintl.h:70
const struct ft_color ftc_server
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
void send_game_info(struct conn_list *dest)
Definition gamehand.c:910
struct city * owner
Definition citydlg.c:226
GType type
Definition repodlgs.c:1313
bool is_special_improvement(const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
bool is_great_wonder(const struct impr_type *pimprove)
const char * name
Definition inputfile.c:127
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_assert_action(condition, action)
Definition log.h:188
@ LOG_ERROR
Definition log.h:31
@ LOG_NORMAL
Definition log.h:33
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
void luascript_log(struct fc_lua *fcl, enum log_level level, const char *format,...)
Definition luascript.c:409
struct fc_lua * luascript_get_fcl(lua_State *L)
Definition luascript.c:366
#define LUASCRIPT_CHECK_STATE(L,...)
Definition luascript.h:117
#define LUASCRIPT_CHECK_SELF(L, value,...)
Definition luascript.h:146
#define LUASCRIPT_CHECK_ARG_NIL(L, value, narg, type,...)
Definition luascript.h:138
#define LUASCRIPT_CHECK_ARG(L, check, narg, msg,...)
Definition luascript.h:131
#define LUASCRIPT_CHECK(L, check, msg,...)
Definition luascript.h:124
enum direction8 Direction
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:1076
void assign_continent_numbers(void)
bool really_gives_vision(struct player *me, struct player *them)
Definition maphand.c:343
void send_tile_info(struct conn_list *dest, struct tile *ptile, bool send_unknown)
Definition maphand.c:489
void send_all_known_tiles(struct conn_list *dest)
Definition maphand.c:442
bool need_to_reassign_continents(const struct terrain *oldter, const struct terrain *newter)
Definition maphand.c:1944
void climate_change(bool warming, int effect)
Definition maphand.c:131
void create_extra(struct tile *ptile, struct extra_type *pextra, struct player *pplayer)
Definition maphand.c:2512
void map_show_tile(struct player *src_player, struct tile *ptile)
Definition maphand.c:773
void tile_change_side_effects(struct tile *ptile, bool refresh_city)
Definition maphand.c:2680
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:925
void fix_tile_on_terrain_change(struct tile *ptile, struct terrain *oldter, bool extend_rivers)
Definition maphand.c:1982
void update_tile_knowledge(struct tile *ptile)
Definition maphand.c:1444
bool can_exist_at_tile(const struct civ_map *nmap, const struct unit_type *utype, const struct tile *ptile)
Definition movement.c:278
enum unit_move_result unit_move_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool igzoc, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:661
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
enum unit_move_result unit_teleport_to_tile_test(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, const struct tile *src_tile, const struct tile *dst_tile, bool enter_transport, struct unit *embark_to, bool enter_enemy_city)
Definition movement.c:815
@ MR_OK
Definition movement.h:35
const char * nation_plural_for_player(const struct player *pplayer)
Definition nation.c:178
void notify_research(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:393
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:291
void notify_research_embassies(const struct research *presearch, const struct player *exclude, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:433
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
void player_status_add(struct player *plr, enum player_status pstatus)
Definition plrhand.c:3217
bool civil_war_triggered(struct player *pplayer)
Definition plrhand.c:2963
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
struct player * civil_war(struct player *pplayer)
Definition plrhand.c:3008
bool civil_war_possible(struct player *pplayer, bool conquering_city, bool honour_server_option)
Definition plrhand.c:2915
#define fc_rand(_size)
Definition rand.h:56
const char * research_advance_name_translation(const struct research *presearch, Tech_type_id tech)
Definition research.c:276
struct research * research_get(const struct player *pplayer)
Definition research.c:130
enum tech_state research_invention_state(const struct research *presearch, Tech_type_id tech)
Definition research.c:622
int research_pretty_name(const struct research *presearch, char *buf, size_t buf_len)
Definition research.c:171
#define MAX(x, y)
Definition shared.h:54
bool is_super_specialist_id(Specialist_type_id sp)
Definition specialist.c:184
Specialist_type_id specialist_index(const struct specialist *sp)
Definition specialist.c:90
Specialist_type_id normal_specialist_count(void)
Definition specialist.c:79
bool is_super_specialist(const struct specialist *sp)
Definition specialist.c:208
bool game_was_started(void)
Definition srv_main.c:355
enum server_states server_state(void)
Definition srv_main.c:339
enum rfc_status create_command_newcomer(const char *name, const char *ai, bool check, struct nation_type *pnation, struct player **newplayer, char *buf, size_t buflen)
Definition stdinhand.c:782
enum rfc_status create_command_pregame(const char *name, const char *ai, bool check, struct player **newplayer, char *buf, size_t buflen)
Definition stdinhand.c:970
int mod
Definition traits.h:39
Definition city.h:318
int id
Definition city.h:324
bool multiresearch
Definition game.h:170
struct packet_game_info info
Definition game.h:89
int diplbulbcost
Definition game.h:146
int conquercost
Definition game.h:143
int freecost
Definition game.h:155
struct civ_game::@32::@36 server
int techpenalty
Definition game.h:203
int id
Definition extras.h:89
struct ai_trait * traits
Definition player.h:126
int infra_points
Definition player.h:67
struct player_ai ai_common
Definition player.h:288
struct dbv tile_known
Definition player.h:310
struct conn_list * connections
Definition player.h:298
struct player_economic economic
Definition player.h:284
struct player_slot * slot
Definition player.h:250
int history
Definition player.h:316
Definition tile.h:50
Definition unit.h:140
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
bool stay
Definition unit.h:208
enum direction8 facing
Definition unit.h:144
int homecity
Definition unit.h:148
int veteran
Definition unit.h:154
struct civ_map map
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
struct advance * advance_by_number(const Tech_type_id atype)
Definition tech.c:107
bool is_future_tech(Tech_type_id tech)
Definition tech.c:281
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define A_UNKNOWN
Definition tech.h:49
void found_new_tech(struct research *presearch, Tech_type_id tech_found, bool was_discovery, bool saving_bulbs)
Definition techtools.c:347
void research_apply_penalty(struct research *presearch, Tech_type_id tech, int penalty_percent)
Definition techtools.c:67
Tech_type_id pick_free_tech(struct research *presearch)
Definition techtools.c:1388
void send_research_info(const struct research *presearch, const struct conn_list *dest)
Definition techtools.c:293
void script_tech_learned(struct research *presearch, struct player *originating_plr, struct advance *tech, const char *reason)
Definition techtools.c:84
void update_bulbs(struct player *pplayer, int bulbs, bool check_tech, bool free_bulbs)
Definition techtools.c:654
#define terrain_has_flag(terr, flag)
Definition terrain.h:177
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:497
bool tile_extra_rm_apply(struct tile *ptile, struct extra_type *tgt)
Definition tile.c:602
bool tile_set_label(struct tile *ptile, const char *label)
Definition tile.c:1098
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:89
#define tile_terrain(_tile)
Definition tile.h:115
#define tile_has_extra(ptile, pextra)
Definition tile.h:152
struct goods_type * goods_from_city_to_unit(const struct city *src, const struct unit *punit)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2, int priority)
#define trade_partners_iterate_end
#define trade_partners_iterate(c, p)
enum unit_upgrade_result unit_transform_result(const struct civ_map *nmap, const struct unit *punit, const struct unit_type *to_unittype)
Definition unit.c:2020
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1793
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2529
bool unit_has_orders(const struct unit *punit)
Definition unit.c:221
bool could_unit_be_in_transport(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:711
#define unit_tile(_pu)
Definition unit.h:407
#define unit_owner(_pu)
Definition unit.h:406
@ UU_OK
Definition unit.h:62
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:443
bool unit_perform_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id_incoming, const char *name, const action_id action_type, const enum action_requester requester)
Definition unithand.c:3369
void create_trade_route(struct city *from, struct city *to, struct goods_type *goods)
Definition unithand.c:6415
void place_partisans(struct tile *pcenter, struct player *powner, int count, int sq_radius)
Definition unittools.c:1164
void transform_unit(struct unit *punit, const struct unit_type *to_unit, int vet_loss)
Definition unittools.c:1558
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2882
bool place_unit(struct unit *punit, struct player *pplayer, struct city *pcity, struct unit *ptrans, bool force)
Definition unittools.c:1718
struct unit * unit_virtual_prepare(struct player *pplayer, struct tile *ptile, const struct unit_type *type, int veteran_level, int homecity_id, int moves_left, int hp_left)
Definition unittools.c:1670
void wipe_unit(struct unit *punit, enum unit_loss_reason reason, struct player *killer)
Definition unittools.c:2144
bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, bool enter_hut, bool frighten_hut)
Definition unittools.c:4083
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126
struct unit_type * unit_type_array_first(void)
Definition unittype.c:58
int num_role_units(int role)
Definition unittype.c:2229
bool utype_player_already_has_this_unique(const struct player *pplayer, const struct unit_type *putype)
Definition unittype.c:1953
const struct unit_type * can_upgrade_unittype(const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1729
int utype_veteran_levels(const struct unit_type *punittype)
Definition unittype.c:2657
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1604
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:215
const struct unit_type * unit_type_array_last(void)
Definition unittype.c:70
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624