From f1195c7c62ee451b356b1d4e0f224e971b3ed920 Mon Sep 17 00:00:00 2001
From: Ihnatus <ignatus31oct@mail.ru>
Date: Tue, 27 May 2025 23:34:34 +0300
Subject: [PATCH] Lua API: introduce Specialist class

See FCRM#1451

Signed-off-by: Ihnatus <ignatus31oct@mail.ru>
---
 common/scriptcore/api_game_find.c    | 21 +++++++++++++++++++++
 common/scriptcore/api_game_find.h    |  3 +++
 common/scriptcore/api_game_methods.c | 23 +++++++++++++++++++++++
 common/scriptcore/api_game_methods.h |  5 +++++
 common/scriptcore/luascript_types.h  |  4 ++++
 common/scriptcore/tolua_common_z.pkg |  1 +
 common/scriptcore/tolua_game.pkg     | 16 ++++++++++++++++
 7 files changed, 73 insertions(+)

diff --git a/common/scriptcore/api_game_find.c b/common/scriptcore/api_game_find.c
index 250c05952a..3ac9f5b8f6 100644
--- a/common/scriptcore/api_game_find.c
+++ b/common/scriptcore/api_game_find.c
@@ -318,6 +318,27 @@ Achievement *api_find_achievement_by_name(lua_State *L, const char *name_orig)
   return achievement_by_rule_name(name_orig);
 }
 
+/**********************************************************************//**
+  Return the specialist with the given name_orig.
+**************************************************************************/
+Specialist *api_find_specialist_by_name(lua_State *L, const char *name_orig)
+{
+  LUASCRIPT_CHECK_STATE(L, nullptr);
+  LUASCRIPT_CHECK_ARG_NIL(L, name_orig, 2, string, nullptr);
+
+  return specialist_by_rule_name(name_orig);
+}
+
+/**********************************************************************//**
+  Return the specialist with the given spec_id index.
+**************************************************************************/
+Specialist *api_find_specialist(lua_State *L, int spec_id)
+{
+  LUASCRIPT_CHECK_STATE(L, nullptr);
+
+  return specialist_by_number((Specialist_type_id) spec_id);
+}
+
 /**********************************************************************//**
   Return the disaster with the given disaster_id index.
 **************************************************************************/
diff --git a/common/scriptcore/api_game_find.h b/common/scriptcore/api_game_find.h
index 921586de5b..18cffa84a7 100644
--- a/common/scriptcore/api_game_find.h
+++ b/common/scriptcore/api_game_find.h
@@ -63,6 +63,9 @@ Terrain *api_find_terrain_by_name(lua_State *L, const char *name_orig);
 Achievement *api_find_achievement(lua_State *L, int achievement_id);
 Achievement *api_find_achievement_by_name(lua_State *L, const char *name_orig);
 
+Specialist *api_find_specialist_by_name(lua_State *L, const char *name_orig);
+Specialist *api_find_specialist(lua_State *L, int spec_id);
+
 Disaster *api_find_disaster(lua_State *L, int disaster_id);
 Disaster *api_find_disaster_by_name(lua_State *L, const char *name_orig);
 
diff --git a/common/scriptcore/api_game_methods.c b/common/scriptcore/api_game_methods.c
index 5015d06e61..62e4ca8cfc 100644
--- a/common/scriptcore/api_game_methods.c
+++ b/common/scriptcore/api_game_methods.c
@@ -1100,6 +1100,29 @@ const char *api_methods_action_target_kind(lua_State *L, Action *pact)
   return action_target_kind_name(action_get_target_kind(paction));
 }
 
+/**********************************************************************//**
+  Return specialist rule name
+**************************************************************************/
+const char *api_methods_specialist_rule_name(lua_State *L, Specialist *s)
+{
+  LUASCRIPT_CHECK_STATE(L, nullptr);
+  LUASCRIPT_CHECK_SELF(L, s, nullptr);
+
+  return specialist_rule_name(s);
+}
+
+/**********************************************************************//**
+  Return translated name for specialist
+**************************************************************************/
+const char *api_methods_specialist_name_translation(lua_State *L,
+                                                    Specialist *s)
+{
+  LUASCRIPT_CHECK_STATE(L, nullptr);
+  LUASCRIPT_CHECK_SELF(L, s, nullptr);
+
+  return specialist_plural_translation(s);
+}
+
 /**********************************************************************//**
   Return the native x coordinate of the tile.
 **************************************************************************/
diff --git a/common/scriptcore/api_game_methods.h b/common/scriptcore/api_game_methods.h
index cf75ff86e8..a95cbeb13f 100644
--- a/common/scriptcore/api_game_methods.h
+++ b/common/scriptcore/api_game_methods.h
@@ -155,6 +155,11 @@ const char *api_methods_action_name_translation(lua_State *L,
                                                 Action *pact);
 const char *api_methods_action_target_kind(lua_State *L, Action *pact);
 
+/* Specialist */
+const char *api_methods_specialist_rule_name(lua_State *L, Specialist *s);
+const char *api_methods_specialist_name_translation(lua_State *L,
+                                                    Specialist *s);
+
 /* Tile */
 int api_methods_tile_nat_x(lua_State *L, Tile *ptile);
 int api_methods_tile_nat_y(lua_State *L, Tile *ptile);
diff --git a/common/scriptcore/luascript_types.h b/common/scriptcore/luascript_types.h
index ede832e145..30a81c88ec 100644
--- a/common/scriptcore/luascript_types.h
+++ b/common/scriptcore/luascript_types.h
@@ -33,6 +33,7 @@ extern "C" {
 #include "improvement.h"
 #include "nation.h"
 #include "player.h"
+#include "specialist.h"
 #include "tech.h"
 #include "terrain.h"
 #include "tile.h"
@@ -60,6 +61,7 @@ typedef enum direction8 Direction;
 typedef struct disaster_type Disaster;
 typedef struct achievement Achievement;
 typedef struct action Action;
+typedef struct specialist Specialist;
 typedef struct packet_game_info Game_Info;
 
 typedef void Nonexistent;
@@ -108,6 +110,8 @@ typedef const struct city_list_link City_List_Link;
 #define SPECENUM_VALUE16NAME "Achievement"
 #define SPECENUM_VALUE17      API_TYPE_ACTION
 #define SPECENUM_VALUE17NAME "Action"
+#define SPECENUM_VALUE18      API_TYPE_SPECIALIST
+#define SPECENUM_VALUE18NAME "Specialist"
 #include "specenum_gen.h"
 
 #ifdef __cplusplus
diff --git a/common/scriptcore/tolua_common_z.pkg b/common/scriptcore/tolua_common_z.pkg
index 1369f67b30..a624f37dfa 100644
--- a/common/scriptcore/tolua_common_z.pkg
+++ b/common/scriptcore/tolua_common_z.pkg
@@ -52,6 +52,7 @@ do
     "Disaster",
     "Achievement",
     "Action",
+    "Specialist",
     "Direction",
     "Game_Info"
   }
diff --git a/common/scriptcore/tolua_game.pkg b/common/scriptcore/tolua_game.pkg
index 944ed35a4e..723ff23ec4 100644
--- a/common/scriptcore/tolua_game.pkg
+++ b/common/scriptcore/tolua_game.pkg
@@ -116,6 +116,10 @@ struct Action {
   const int id;
 };
 
+struct Specialist {
+  const int item_number @ id;
+};
+
 struct Direction {
   /* nothing here, it's enum */
 };
@@ -541,6 +545,14 @@ module Action {
     @ target_kind (lua_State *L, Action *self);
 }
 
+/* Module Specialist */
+module Specialist {
+  const char *api_methods_specialist_rule_name
+    @ rule_name (lua_State *L, Specialist *self);
+  const char *api_methods_specialist_name_translation
+    @ name_translation (lua_State *L, Specialist *self);
+}
+
 /* Module Unit_List_Link. */
 module Unit_List_Link {
   Unit *api_methods_unit_list_link_data
@@ -615,6 +627,10 @@ module find {
     @ achievement (lua_State *L, const char *name_orig);
   Achievement *api_find_achievement
     @ achievement (lua_State *L, int achievement_id);
+  Specialist *api_find_specialist_by_name
+    @ specialist (lua_State *L, const char *name_orig);
+  Specialist *api_find_specialist
+    @ specialist (lua_State *L, int spec_id);
   Disaster *api_find_disaster_by_name
     @ disaster (lua_State *L, const char *name_orig);
   Disaster *api_find_disaster
-- 
2.45.2

