Skip to content

Commit 8b644d4

Browse files
Lua: expose more map and player infos (dkfans#4804)
1 parent 89fff06 commit 8b644d4

9 files changed

Lines changed: 214 additions & 3 deletions

File tree

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ obj/light_data.o \
258258
obj/lua_api.o \
259259
obj/lua_api_camera.o \
260260
obj/lua_api_lens.o \
261+
obj/lua_api_map.o \
261262
obj/lua_api_player.o \
262263
obj/lua_api_room.o \
263264
obj/lua_api_things.o \

config/fxdata/lua/classes/Map.lua

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---@meta
2+
3+
---@class Map
4+
---@field map_name string The name of the map
5+
---@field map_number integer The map number
6+
---@field campaign string The campaign/Mappack this map belongs to
7+
---@field map_type string The type of map (Campaign, Multiplayer, Bonus, Moon, MapPack)
8+
---@field width integer The width of the map in tiles
9+
---@field height integer The height of the map in tiles
10+
---@field default_texture texture_pack The default texture for the map, id for custom textures, or string for built-in textures
11+
---@field creature_pool table<string, integer> A table containing the creature pool for the map, with creature types as keys and their counts as values
12+
if not Map then Map = {} end

config/fxdata/lua/classes/Player.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@
8282
---@field MANAGE_SCORE integer Part of level score, based on quality of the dungeon
8383
---@field heart Thing The player's primary dungeon heart
8484
---@field camera Camera The player's camera
85+
---@field type string The type of player (Human, Computer, Roaming, Neutral, Inactive)
86+
---@field max_creatures integer The maximum number of creatures the player can have from portals
87+
---@field colour string The colour of the player
88+
---@field player_name string The name of the player
8589
if not Player then Player = {} end
8690

8791

keeperfx_vs2010.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@
187187
<ClCompile Include="src\lua_api_player.c" />
188188
<ClCompile Include="src\lua_api_slabs.c" />
189189
<ClCompile Include="src\lua_api_things.c" />
190+
<ClCompile Include="src\lua_api_map.c" />
190191
<ClCompile Include="src\lua_base.c" />
191192
<ClCompile Include="src\lua_cfg_funcs.c" />
192193
<ClCompile Include="src\lua_params.c" />

keeperfx_vs2010.vcxproj.filters

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,8 @@
752752
</ClCompile>
753753
<ClCompile Include="src\lua_api_slabs.c">
754754
<Filter>Source Files</Filter>
755+
<ClCompile Include="src\lua_api_map.c">
756+
<Filter>Source Files</Filter>
755757
</ClCompile>
756758
<ClCompile Include="src\lua_api_things.c">
757759
<Filter>Source Files</Filter>

linux.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ src/light_data.c \
181181
src/linux.cpp \
182182
src/lua_api.c \
183183
src/lua_api_lens.c \
184+
src/lua_api_map.c \
184185
src/lua_api_player.c \
185186
src/lua_api_room.c \
186187
src/lua_api_things.c \

src/lua_api.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,6 +2570,7 @@ static const luaL_Reg game_meta[] = {
25702570
{NULL, NULL}
25712571
};
25722572
*/
2573+
25732574
static void Global_register(lua_State *L)
25742575
{
25752576
//luaL_newlib(L, global_methods);
@@ -2587,6 +2588,7 @@ void Slab_register(lua_State *L);
25872588
void Room_register(lua_State *L);
25882589
void Camera_register(lua_State *L);
25892590
void Lens_register(lua_State *L);
2591+
void Map_register(lua_State *L);
25902592

25912593
void reg_host_functions(lua_State *L)
25922594
{
@@ -2597,4 +2599,5 @@ void reg_host_functions(lua_State *L)
25972599
Room_register(L);
25982600
Camera_register(L);
25992601
Lens_register(L);
2602+
Map_register(L);
26002603
}

src/lua_api_map.c

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "pre_inc.h"
2+
3+
#include <lua.h>
4+
#include <lauxlib.h>
5+
#include <lualib.h>
6+
7+
#include "globals.h"
8+
#include "game_legacy.h" // game.map_tiles_x/y, game.pool, game.texture_id
9+
#include "config_campaigns.h" // is_map_pack, campaign, LevelInformation, get_level_info
10+
#include "config.h" // LvKind_IsSingle, LvKind_IsMulti, etc.
11+
#include "config_creature.h" // creature_desc, CREATURE_TYPES_MAX
12+
#include "engine_textures.h" // load_texture_map_file
13+
#include "lvl_filesdk1.h" // get_loaded_level_number, get_level_fgroup
14+
#include "lvl_script_lib.h" // texture_pack_desc
15+
16+
#include "lua_base.h"
17+
#include "lua_params.h" // luaL_checkNamedCommand
18+
19+
#include "post_inc.h"
20+
21+
/**********************************************/
22+
23+
static int map_tostring(lua_State *L) {
24+
lua_pushfstring(L, "Map(%dx%d)", game.map_tiles_x, game.map_tiles_y);
25+
return 1;
26+
}
27+
28+
//read creature pool from a map
29+
static void push_map_pool(lua_State *L) {
30+
lua_newtable(L);
31+
for (int i = 0; i < CREATURE_TYPES_MAX; i++) {
32+
int n = game.pool.crtr_kind[i];
33+
if (n <= 0) continue;
34+
lua_pushstring(L, get_conf_parameter_text(creature_desc, i));
35+
lua_pushinteger(L, n);
36+
lua_rawset(L, -3);
37+
}
38+
}
39+
40+
41+
//read map fields
42+
static int map_get_field(lua_State *L){
43+
const char *key = luaL_checkstring(L, 2);
44+
LevelNumber lv_number = get_loaded_level_number();
45+
struct LevelInformation *lv_inf = get_level_info(lv_number);
46+
47+
const char *map_name = "";
48+
unsigned long ltype = 0;
49+
if (lv_inf) {
50+
map_name = lv_inf->name;
51+
ltype = lv_inf->level_type;
52+
}
53+
54+
if (strcmp(key, "creature_pool") == 0)
55+
push_map_pool(L);
56+
else if (strcmp(key, "map_name") == 0) {
57+
lua_pushstring(L, map_name);
58+
} else if (strcmp(key, "map_number") == 0)
59+
lua_pushinteger(L, lv_number);
60+
else if (strcmp(key, "campaign") == 0)
61+
lua_pushstring(L, campaign.name);
62+
else if (strcmp(key, "map_type") == 0) {
63+
if (ltype & LvKind_IsMulti) {
64+
lua_pushstring(L, "Multiplayer");
65+
} else if (ltype & LvKind_IsExtra) {
66+
lua_pushstring(L, "Moon");
67+
} else if (ltype & LvKind_IsBonus) {
68+
lua_pushstring(L, "Bonus");
69+
} else if (ltype & LvKind_IsFree) {
70+
lua_pushstring(L, "MapPack");
71+
} else if (ltype & LvKind_IsSingle) {
72+
lua_pushstring(L, "Campaign");
73+
} else {
74+
lua_pushstring(L, "Unknown");
75+
}
76+
} else if (strcmp(key, "width") == 0) {
77+
lua_pushinteger(L, game.map_tiles_x);
78+
} else if (strcmp(key, "height") == 0) {
79+
lua_pushinteger(L, game.map_tiles_y);
80+
} else if (strcmp(key, "default_texture") == 0) {
81+
const char *name = get_conf_parameter_text(texture_pack_desc, game.texture_id);
82+
if (name[0] != '\0') {
83+
lua_pushstring(L, name); // "STANDARD", "ANCIENT", ...
84+
} else {
85+
lua_pushinteger(L, game.texture_id); // 17, 20, ... (Custom)
86+
}
87+
} else {
88+
return luaL_error(L, "Unknown field '%s' for MAP", key);
89+
}
90+
return 1;
91+
}
92+
93+
//write map fields
94+
static int map_set_field(lua_State *L) {
95+
const char *key = luaL_checkstring(L, 2);
96+
97+
if (strcmp(key, "default_texture") == 0) {
98+
long texture_id = luaL_checkNamedCommand(L, 3, texture_pack_desc);
99+
game.texture_id = texture_id;
100+
LevelNumber lvnumb = get_loaded_level_number();
101+
load_texture_map_file(texture_id, lvnumb, get_level_fgroup(lvnumb));
102+
103+
return 0;
104+
}
105+
106+
return luaL_error(L, "MAP field '%s' is read-only", key);
107+
}
108+
109+
// Metamethod registration table for the MAP metatable.
110+
static const struct luaL_Reg map_meta[] = {
111+
{"__index", map_get_field},
112+
{"__newindex", map_set_field},
113+
{"__tostring", map_tostring},
114+
{NULL, NULL}
115+
};
116+
117+
// Builds the global MAP singleton and binds its metatable.
118+
void Map_register(lua_State *L) {
119+
luaL_newmetatable(L, "Map");
120+
luaL_setfuncs(L, map_meta, 0);
121+
122+
lua_pushliteral(L, "__metatable");
123+
lua_pushnil(L);
124+
lua_rawset(L, -3);
125+
126+
lua_pop(L, 1);
127+
128+
lua_newtable(L);
129+
130+
lua_pushstring(L, "Map");
131+
lua_setfield(L, -2, "__class");
132+
133+
luaL_getmetatable(L, "Map");
134+
lua_setmetatable(L, -2);
135+
136+
lua_setglobal(L, "Map");
137+
}

src/lua_api_player.c

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include "player_data.h"
1212
#include "lvl_script_lib.h"
1313
#include "player_utils.h"
14+
#include "dungeon_data.h"
15+
#include "config_campaigns.h"
1416

1517
#include "post_inc.h"
1618

@@ -142,6 +144,29 @@ static int player_set_field(lua_State *L) {
142144

143145
PlayerNumber player_idx = luaL_checkPlayerSingle(L, 1);
144146
const char* key = luaL_checkstring(L, 2);
147+
struct PlayerInfo *player = get_player(player_idx);
148+
149+
if (strcmp(key, "player_name") == 0) {
150+
const char* name = luaL_checkstring(L, 3);
151+
if (!player_invalid(player)) {
152+
snprintf(player->player_name, sizeof(player->player_name), "%s", name);
153+
}
154+
return 0;
155+
} else if (strcmp(key, "colour") == 0) {
156+
long colour_idx;
157+
if (lua_type(L, 3) == LUA_TSTRING) {
158+
const char* name = lua_tostring(L, 3);
159+
colour_idx = get_rid(cmpgn_human_player_options, name);
160+
if (colour_idx == -1) {
161+
return luaL_argerror(L, 3, "unrecognized colour name");
162+
}
163+
} else {
164+
colour_idx = luaL_checkinteger(L, 3);
165+
}
166+
set_player_colour(player_idx, (unsigned char)colour_idx);
167+
return 0;
168+
}
169+
145170
int value = luaL_checkinteger(L, 3);
146171

147172
int32_t variable_type;
@@ -159,7 +184,9 @@ static int player_set_field(lua_State *L) {
159184
static int player_get_field(lua_State *L) {
160185
const char* key = luaL_checkstring(L, 2);
161186
PlayerNumber plyr_idx = luaL_checkPlayerSingle(L, 1);
162-
187+
struct PlayerInfo *player = get_player(plyr_idx);
188+
struct Dungeon *dungeon = get_dungeon(plyr_idx);
189+
163190
int32_t variable_type, variable_id;
164191

165192
// C method lookup
@@ -177,8 +204,31 @@ static int player_get_field(lua_State *L) {
177204
} else if (strcmp(key, "available") == 0) {
178205
lua_pushinteger(L, plyr_idx);
179206
lua_pushcclosure(L, player_get_available, 1);
180-
}
181-
else if (parse_get_varib(key, &variable_id, &variable_type, 1)) {
207+
} else if (strcmp(key, "type") == 0) {
208+
if (player_invalid(player)) {
209+
lua_pushnil(L);
210+
} else if (player_is_roaming(plyr_idx)) {
211+
lua_pushstring(L, "Roaming");
212+
} else if (player_is_neutral(plyr_idx)) {
213+
lua_pushstring(L, "Neutral");
214+
} else if (player->allocflags & PlaF_CompCtrl) {
215+
lua_pushstring(L, "Computer");
216+
} else if (player->is_active) {
217+
lua_pushstring(L, "Human");
218+
} else {
219+
lua_pushstring(L, "Inactive");
220+
}
221+
} else if (strcmp(key, "max_creatures") == 0) {
222+
if (dungeon_invalid(dungeon)) {
223+
lua_pushinteger(L, 0);
224+
} else {
225+
lua_pushinteger(L, dungeon->max_creatures_attracted);
226+
}
227+
} else if (strcmp(key, "player_name") == 0) {
228+
lua_pushstring(L, player_invalid(player) ? "" : player->player_name);
229+
} else if (strcmp(key, "colour") == 0) {
230+
lua_pushstring(L, get_conf_parameter_text(cmpgn_human_player_options, get_player_color_idx(plyr_idx)));
231+
} else if (parse_get_varib(key, &variable_id, &variable_type, 1)) {
182232
lua_pushinteger(L, get_condition_value(plyr_idx, variable_type, variable_id));
183233
} else if (try_get_from_methods(L, 1, key)) {
184234
return 1;

0 commit comments

Comments
 (0)