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/***************************************************************************** 15 ADVERTISEMENT: do not attempt to change the name of the API functions. 16 They may be in use in Lua scripts in savefiles, so once released, the 17 name and signature cannot change shape even in new major versions of 18 Freeciv, until the relevant save format version can no longer be loaded. 19 If you really like to change a function name, be sure to keep also the 20 old one running. 21*****************************************************************************/ 22 23$#ifdef HAVE_CONFIG_H 24$#include <fc_config.h> 25$#endif 26 27/* common/scriptcore */ 28$#include "api_common_utilities.h" 29$#include "api_game_effects.h" 30$#include "api_game_find.h" 31$#include "api_game_methods.h" 32$#include "luascript_types.h" 33 34/* Classes. */ 35struct Player { 36 const char *name; 37 Nation_Type *nation; 38 bool ai_controlled; 39 bool is_alive; 40}; 41 42struct City { 43 const char *name; 44 Player *owner; 45 Player *original; 46 47 const int id; 48}; 49 50struct Connection { 51 const int id; 52}; 53 54struct Unit { 55 Unit_Type *utype; 56 Player *owner; 57 58 /* This used to be @ homecity_id, but it does not work with toluaxx. */ 59 int homecity; 60 61 const int id; 62}; 63 64struct Tile { 65 Terrain *terrain; 66 67 const int index @ id; 68}; 69 70struct Government { 71 const int item_number @ id; 72}; 73 74struct Nation_Type { 75 const int item_number @ id; 76}; 77 78struct Building_Type { 79 int build_cost; 80 81 const int item_number @ id; 82}; 83 84struct Unit_Type { 85 int build_cost; 86 87 const int item_number @ id; 88}; 89 90struct Tech_Type { 91 const int item_number @ id; 92}; 93 94struct Terrain { 95 const int item_number @ id; 96}; 97 98struct Disaster { 99 const int id; 100}; 101 102struct Achievement { 103 const int id; 104}; 105 106struct Action { 107 const int id; 108}; 109 110struct Unit_List_Link { 111}; 112 113struct City_List_Link { 114}; 115 116/* Module Game */ 117module game { 118 int api_methods_game_turn 119 @ turn (lua_State *L); 120} 121 122/* Module Player. */ 123module Player { 124 module properties { 125 int api_methods_player_number 126 @ id (lua_State *L, Player *self); 127 } 128 129 int api_methods_player_num_cities 130 @ num_cities (lua_State *L, Player *self); 131 int api_methods_player_num_units 132 @ num_units (lua_State *L, Player *self); 133 bool api_methods_player_has_wonder 134 @ has_wonder (lua_State *L, Player *self, Building_Type *building); 135 int api_methods_player_gold 136 @ gold (lua_State *L, Player *self); 137 bool api_methods_player_knows_tech 138 @ knows_tech (lua_State *L, Player *self, Tech_Type *ptech); 139 bool api_methods_player_shares_research 140 @ shares_research (lua_State *L, Player *self, Player *other); 141 const char *api_methods_research_rule_name 142 @ research_rule_name (lua_State *L, Player *self); 143 const char *api_methods_research_name_translation 144 @ research_name_translation (lua_State *L, Player *self); 145 146 int api_methods_player_culture_get 147 @ culture(lua_State *L, Player *self); 148} 149 150module methods_private { 151 lua_Object api_methods_private_list_players 152 @ list_players (lua_State *L); 153 module Player { 154 Unit_List_Link *api_methods_private_player_unit_list_head 155 @ unit_list_head (lua_State *L, Player *self); 156 City_List_Link *api_methods_private_player_city_list_head 157 @ city_list_head (lua_State *L, Player *self); 158 } 159} 160 161$[ 162 163-- Player methods 164function Player:is_human() 165 return not self.ai_controlled 166end 167 168function Player:exists() 169 return true 170end 171 172$] 173 174/* Module City. */ 175module City { 176 module properties { 177 int api_methods_city_size_get 178 @ size(lua_State *L, City *self); 179 Tile *api_methods_city_tile_get 180 @ tile(lua_State *L, City *self); 181 } 182 183 bool api_methods_city_has_building 184 @ has_building(lua_State *L, City *self, Building_Type *building); 185 int api_methods_city_map_sq_radius 186 @ map_sq_radius(lua_State *L, City *self); 187 int api_methods_city_inspire_partisans 188 @ inspire_partisans(lua_State *L, City *self, Player *inspirer); 189 190 int api_methods_city_culture_get 191 @ culture(lua_State *L, City *self); 192 193 bool api_methods_is_city_happy 194 @ is_happy(lua_State *L, City *self); 195 bool api_methods_is_city_unhappy 196 @ is_unhappy(lua_State *L, City *self); 197 bool api_methods_is_city_celebrating 198 @ is_celebrating(lua_State *L, City *self); 199 bool api_methods_is_gov_center 200 @ is_gov_center(lua_State *L, City *self); 201 bool api_methods_is_capital 202 @ is_capital(lua_State *L, City *self); 203} 204 205$[ 206 207-- City methods. 208function City:exists() 209 return true 210end 211 212$] 213 214/* Module Unit. */ 215module Unit { 216 module properties { 217 Tile *api_methods_unit_tile_get 218 @ tile(lua_State *L, Unit *self); 219 } 220 221 Unit *api_methods_unit_transporter 222 @ transporter (lua_State *L, Unit *self); 223 bool api_methods_unit_city_can_be_built_here 224 @ is_on_possible_city_tile (lua_State *L, Unit *self); 225 Direction *api_methods_unit_orientation_get 226 @ facing(lua_State *L, Unit *self); 227} 228 229module methods_private { 230 module Unit { 231 Unit_List_Link *api_methods_private_unit_cargo_list_head 232 @ cargo_list_head (lua_State *L, Unit *self); 233 } 234} 235 236$[ 237 238-- Unit methods. 239function Unit:exists() 240 return true 241end 242 243function Unit:get_homecity() 244 return find.city(self.owner, self.homecity) 245end 246$] 247 248/* Module Tile. */ 249module Tile { 250 module properties { 251 int api_methods_tile_nat_x 252 @ nat_x (lua_State *L, Tile *self); 253 int api_methods_tile_nat_y 254 @ nat_y (lua_State *L, Tile *self); 255 int api_methods_tile_map_x 256 @ x (lua_State *L, Tile *self); 257 int api_methods_tile_map_y 258 @ y (lua_State *L, Tile *self); 259 } 260 261 City *api_methods_tile_city 262 @ city (lua_State *L, Tile *self); 263 bool api_methods_tile_city_exists_within_max_city_map 264 @ city_exists_within_max_city_map (lua_State *L, Tile *self, bool center); 265 bool api_methods_tile_has_extra 266 @ has_extra(lua_State *L, Tile *self, const char *name); 267 bool api_methods_tile_has_base 268 @ has_base(lua_State *L, Tile *self, const char *name); 269 bool api_methods_tile_has_road 270 @ has_road(lua_State *L, Tile *self, const char *name); 271 int api_methods_tile_num_units 272 @ num_units (lua_State *L, Tile *self); 273 int api_methods_tile_sq_distance 274 @ sq_distance (lua_State *L, Tile *self, Tile *other); 275} 276 277$[ 278 279-- *************************************************************************** 280-- Deprecated. New one is Tile:city_exists_within_max_city_map(). 281-- *************************************************************************** 282function Tile:city_exists_within_city_radius(center) 283 log.deprecation_warning("city_exists_within_city_radius()", "city_exists_within_max_city_map()", 284 "2.3"); 285 return self:city_exists_within_max_city_map(center) 286end 287 288$] 289 290module methods_private { 291 module Tile { 292 int api_methods_private_tile_next_outward_index 293 @ next_outward_index (lua_State *L, Tile *pcenter, int tindex, 294 int max_dist); 295 Tile *api_methods_private_tile_for_outward_index 296 @ tile_for_outward_index (lua_State *L, Tile *pcenter, int tindex); 297 Unit_List_Link *api_methods_private_tile_unit_list_head 298 @ unit_list_head (lua_State *L, Tile *self); 299 } 300} 301 302/* Module Government. */ 303module Government { 304 const char *api_methods_government_rule_name 305 @ rule_name (lua_State *L, Government *self); 306 const char *api_methods_government_name_translation 307 @ name_translation (lua_State *L, Government *self); 308} 309 310/* Module Nation_Type. */ 311module Nation_Type { 312 const char *api_methods_nation_type_rule_name 313 @ rule_name (lua_State *L, Nation_Type *self); 314 const char *api_methods_nation_type_name_translation 315 @ name_translation (lua_State *L, Nation_Type *self); 316 const char *api_methods_nation_type_plural_translation 317 @ plural_translation (lua_State *L, Nation_Type *self); 318} 319 320/* Module Building_Type. */ 321module Building_Type { 322 bool api_methods_building_type_is_wonder 323 @ is_wonder (lua_State *L, Building_Type *self); 324 bool api_methods_building_type_is_great_wonder 325 @ is_great_wonder (lua_State *L, Building_Type *self); 326 bool api_methods_building_type_is_small_wonder 327 @ is_small_wonder (lua_State *L, Building_Type *self); 328 bool api_methods_building_type_is_improvement 329 @ is_improvement (lua_State *L, Building_Type *self); 330 const char *api_methods_building_type_rule_name 331 @ rule_name (lua_State *L, Building_Type *self); 332 const char *api_methods_building_type_name_translation 333 @ name_translation (lua_State *L, Building_Type *self); 334} 335 336$[ 337 338-- Building_Type methods. 339function Building_Type:build_shield_cost() 340 return self.build_cost 341end 342 343$] 344 345/* Module Unit_Type. */ 346module Unit_Type { 347 bool api_methods_unit_type_has_flag 348 @ has_flag (lua_State *L, Unit_Type *self, const char *flag); 349 bool api_methods_unit_type_has_role 350 @ has_role (lua_State *L, Unit_Type *self, const char *role); 351 const char *api_methods_unit_type_rule_name 352 @ rule_name (lua_State *L, Unit_Type *self); 353 const char *api_methods_unit_type_name_translation 354 @ name_translation (lua_State *L, Unit_Type *self); 355 bool api_methods_unit_type_can_exist_at_tile 356 @ can_exist_at_tile(lua_State *L, Unit_Type *self, Tile *ptile); 357} 358 359$[ 360 361-- Unit_Type methods. 362function Unit_Type:build_shield_cost() 363 return self.build_cost 364end 365 366$] 367 368/* Module Tech_Type. */ 369module Tech_Type { 370 const char *api_methods_tech_type_rule_name 371 @ rule_name (lua_State *L, Tech_Type *self); 372 const char *api_methods_tech_type_name_translation 373 @ name_translation (lua_State *L, Tech_Type *self); 374} 375 376/* Module Terrain. */ 377module Terrain { 378 const char *api_methods_terrain_rule_name 379 @ rule_name (lua_State *L, Terrain *self); 380 const char *api_methods_terrain_name_translation 381 @ name_translation (lua_State *L, Terrain *self); 382 const char *api_methods_terrain_class_name 383 @ class_name (lua_State *L, Terrain *self); 384} 385 386/* Module Disaster. */ 387module Disaster { 388 const char *api_methods_disaster_rule_name 389 @ rule_name (lua_State *L, Disaster *self); 390 const char *api_methods_disaster_name_translation 391 @ name_translation (lua_State *L, Disaster *self); 392} 393 394/* Module Achievement. */ 395module Achievement { 396 const char *api_methods_achievement_rule_name 397 @ rule_name (lua_State *L, Achievement *self); 398 const char *api_methods_achievement_name_translation 399 @ name_translation (lua_State *L, Achievement *self); 400} 401 402/* Module Action. */ 403module Action { 404 const char *api_methods_action_rule_name 405 @ rule_name (lua_State *L, Action *self); 406 const char *api_methods_action_name_translation 407 @ name_translation (lua_State *L, Action *self); 408} 409 410/* Module Unit_List_Link. */ 411module Unit_List_Link { 412 Unit *api_methods_unit_list_link_data 413 @ data (lua_State *L, Unit_List_Link *self); 414 Unit_List_Link *api_methods_unit_list_next_link 415 @ next (lua_State *L, Unit_List_Link *self); 416} 417 418/* Module City_List_Link. */ 419module City_List_Link { 420 City *api_methods_city_list_link_data 421 @ data (lua_State *L, City_List_Link *self); 422 City_List_Link *api_methods_city_list_next_link 423 @ next (lua_State *L, City_List_Link *self); 424} 425 426/* Module find. */ 427module find { 428 Player *api_find_player 429 @ player (lua_State *L, int player_id); 430 City *api_find_city 431 @ city (lua_State *L, Player *pplayer, int city_id); 432 Unit *api_find_unit 433 @ unit (lua_State *L, Player *pplayer, int unit_id); 434 Unit *api_find_transport_unit 435 @ transport_unit (lua_State *L, Player *pplayer, Unit_Type *ptype, 436 Tile *ptile); 437 Tile *api_find_tile 438 @ tile (lua_State *L, int nat_x, int nat_y); 439 Tile *api_find_tile_by_index 440 @ tile (lua_State *L, int tindex); 441 442 /* NOTE: For overloading to work correctly, the string function 443 * must be before the integer function for each case below. */ 444 Government *api_find_government_by_name 445 @ government (lua_State *L, const char *name_orig); 446 Government *api_find_government 447 @ government (lua_State *L, int government_id); 448 Nation_Type *api_find_nation_type_by_name 449 @ nation_type (lua_State *L, const char *name_orig); 450 Nation_Type *api_find_nation_type 451 @ nation_type (lua_State *L, int nation_type_id); 452 Building_Type *api_find_building_type_by_name 453 @ building_type (lua_State *L, const char *name_orig); 454 Building_Type *api_find_building_type 455 @ building_type (lua_State *L, int building_type_id); 456 Unit_Type *api_find_unit_type_by_name 457 @ unit_type (lua_State *L, const char *name_orig); 458 Unit_Type *api_find_unit_type 459 @ unit_type (lua_State *L, int unit_type_id); 460 Unit_Type *api_find_role_unit_type 461 @ role_unit_type (lua_State *L, const char *role_name, Player *pplayer); 462 Tech_Type *api_find_tech_type_by_name 463 @ tech_type (lua_State *L, const char *name_orig); 464 Tech_Type *api_find_tech_type 465 @ tech_type (lua_State *L, int tech_type_id); 466 Terrain *api_find_terrain_by_name 467 @ terrain (lua_State *L, const char *name_orig); 468 Terrain *api_find_terrain 469 @ terrain (lua_State *L, int terrain_id); 470 Nonexistent *api_find_nonexistent 471 @ nonexistent (lua_State *L); 472} 473 474module E { 475 /* Notify events module is exported by api_specenum */ 476} 477 478/* Effects module */ 479module effects { 480 int api_effects_world_bonus 481 @ world_bonus (lua_State *L, const char *effect_type); 482 int api_effects_player_bonus 483 @ player_bonus (lua_State *L, Player *pplayer, const char *effect_type); 484 int api_effects_city_bonus 485 @ city_bonus (lua_State *L, City *pcity, const char *effect_type); 486} 487 488/* Direction module */ 489module direction { 490 Direction *api_utilities_str2dir 491 @ str2dir(lua_State *L, const char *str); 492 Direction *api_utilities_dir_ccw 493 @ next_ccw(lua_State *L, Direction self); 494 Direction *api_utilities_dir_cw 495 @ next_cw(lua_State *L, Direction self); 496 Direction *api_utilities_opposite_dir 497 @ opposite(lua_State *L, Direction self); 498} 499 500$[ 501-- ************************************************************************** 502-- Convert direction describing text to direction 503-- ************************************************************************** 504function str2direction(str) 505 return direction.str2dir(str) 506end 507$] 508 509$[ 510 511-- *************************************************************************** 512-- Player and Tile: cities_iterate and units_iterate methods 513-- *************************************************************************** 514do 515 local private = methods_private 516 517 -- Iterate over the values of 'array' in order: 518 -- array[1], array[2], array[3], etc. 519 local function value_iterator(array) 520 local i = 0 521 local function iterator() 522 i = i + 1 523 return array[i] 524 end 525 return iterator 526 end 527 528 -- use a copy of the list for safe iteration 529 local function safe_iterate_list(link) 530 local objs = {} 531 while link do 532 objs[#objs + 1] = link:data() 533 link = link:next() 534 end 535 return value_iterator(objs) 536 end 537 538 -- Safe iteration over all units that belong to Player 539 function Player:units_iterate() 540 return safe_iterate_list(private.Player.unit_list_head(self)) 541 end 542 543 -- Safe iteration over all cities that belong to Player 544 function Player:cities_iterate() 545 return safe_iterate_list(private.Player.city_list_head(self)) 546 end 547 548 -- Safe iteration over the units on Tile 549 function Tile:units_iterate() 550 return safe_iterate_list(private.Tile.unit_list_head(self)) 551 end 552 553 -- Safe iteration over the units transported by Unit 554 function Unit:cargo_iterate() 555 return safe_iterate_list(private.Unit.cargo_list_head(self)) 556 end 557end 558 559-- *************************************************************************** 560-- Tile: square_iterate, circle_iterate 561-- *************************************************************************** 562do 563 local next_outward_index = methods_private.Tile.next_outward_index 564 local tile_for_outward_index = methods_private.Tile.tile_for_outward_index 565 566 -- iterate over tiles at distance 'radius' 567 function Tile:square_iterate(radius) 568 local index = -1 569 local function iterator() 570 index = next_outward_index(self, index, radius) 571 if index < 0 then 572 return nil 573 else 574 return tile_for_outward_index(self, index) 575 end 576 end 577 return iterator 578 end 579 580 -- iterate over tiles at squared distance 'sq_radius' 581 function Tile:circle_iterate(sq_radius) 582 local cr_radius = math.floor(math.sqrt(sq_radius)) 583 local sq_iter = self:square_iterate(cr_radius) 584 local function iterator() 585 local tile = nil 586 repeat 587 tile = sq_iter() 588 until not tile or self:sq_distance(tile) <= sq_radius 589 return tile 590 end 591 return iterator 592 end 593end 594 595$] 596 597$[ 598-- *************************************************************************** 599-- Iteration constructs for game-global objects 600-- *************************************************************************** 601do 602 -- iterate over the values returned by lookup 603 -- until nil is returned: 604 -- lookup(0), lookup(1), lookup(2), etc 605 local function index_iterate(lookup) 606 local index = -1 607 local function iterator() 608 index = index + 1 609 return lookup(index) 610 end 611 return iterator 612 end 613 614 -- Iterate over all players of the game (note: indices may have gaps) 615 local listp = methods_private.list_players 616 function players_iterate() 617 local plist = listp() 618 local index = 0 619 return function() 620 index = index + 1 621 return plist[index] 622 end 623 end 624 625 -- Iterate over all tiles of the game 626 function whole_map_iterate() 627 return index_iterate(find.tile) 628 end 629 630 -- NOTE: Identical further definitions can be made for 631 -- governments, tech_types, building_types etc 632end 633 634$] 635