Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ obj/lens_flyeye.o \
obj/lens_mist.o \
obj/light_data.o \
obj/lua_api.o \
obj/lua_api_camera.o \
obj/lua_api_player.o \
obj/lua_api_room.o \
obj/lua_api_things.o \
Expand Down
10 changes: 10 additions & 0 deletions config/fxdata/lua/bindings/things.lua
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,13 @@ function ChangeCreatureOwner(creature,new_owner) end
---@param operation any
---@param annoyance integer
function ChangeCreaturesAnnoyance(player,creature,operation,annoyance) end


---Place any object at a specific place on the map
---@param shot_type shot_type The shot name from fxdata\magic.cfg
---@param location location
---@param player playersingle When used it sets the owner of the object.
---@param hit_type hittypes What the shot can hit
---@param target? Thing When used the shot will target the thing
---@return Thing shot
function AddShotToLevel(shot_type,location,player, hit_type,target) local shot return shot end
6 changes: 6 additions & 0 deletions config/fxdata/lua/classes/Thing.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ end
function Thing:isValid() return false end

function Thing:delete() end

---sets the velocity of the thing
---@param angle_xy integer 0-2047, the angle to move in the X/Y plane
---@param angle_z integer 0-2047, the angle to move in the Z plane
---@param dist integer speed/ how far to move every tick
function Thing:set_velocity(angle_xy,angle_z,dist) end
2 changes: 2 additions & 0 deletions config/fxdata/lua/config-api/native_types.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
---@alias effect_type "NULL"|"EFFECT_EXPLOSION_1"|"EFFECT_EXPLOSION_2"|"EFFECT_EXPLOSION_3"|"EFFECT_EXPLOSION_4"|"EFFECT_EXPLOSION_5"|"EFFECT_BLOOD_HIT"|"EFFECT_BLOOD_CHICKEN"|"EFFECT_BLOOD_3"|"EFFECT_BLOOD_4"|"EFFECT_BLOOD_5"|"EFFECT_GAS_1"|"EFFECT_GAS_2"|"EFFECT_GAS_3"|"EFFECT_WORD_OF_POWER"|"EFFECT_ICE_SHARD"|"EFFECT_HARMLESS_GAS_1"|"EFFECT_HARMLESS_GAS_2"|"EFFECT_HARMLESS_GAS_3"|"EFFECT_DRIP_1"|"EFFECT_DRIP_2"|"EFFECT_DRIP_3"|"EFFECT_HIT_FROZEN_UNIT"|"EFFECT_HAIL"|"EFFECT_ICE_DEATH"|"EFFECT_DIRT_RUBBLE_SMALL"|"EFFECT_DIRT_RUBBLE"|"EFFECT_DIRT_RUBBLE_BIG"|"EFFECT_SPANGLE_RED"|"EFFECT_DRIP_4"|"EFFECT_CLOUD"|"EFFECT_HARMLESS_GAS_4"|"EFFECT_GOLD_RUBBLE_1"|"EFFECT_GOLD_RUBBLE_2"|"EFFECT_GOLD_RUBBLE_3"|"EFFECT_TEMPLE_SPLASH"|"EFFECT_CEILING_BREACH"|"EFFECT_STRANGE_GAS_1"|"EFFECT_STRANGE_GAS_2"|"EFFECT_STRANGE_GAS_3"|"EFFECT_GAS_SLOW_1"|"EFFECT_GAS_SLOW_2"|"EFFECT_GAS_SLOW_3"|"EFFECT_ERUPTION"|"EFFECT_ELECTRIC_BALLS"|"EFFECT_EXPLOSION_6"|"EFFECT_SPANGLE_RED_BIG"|"EFFECT_COLOURFUL_FIRE_CIRCLE"|"EFFECT_FLASH"|"EFFECT_DUMMY"|"EFFECT_EXPLOSION_7"|"EFFECT_FEATHER_PUFF"|"EFFECT_EXPLOSION_8"|"EFFECT_RESEARCH_COMPLETE"|"EFFECT_COLFOUNTN_1"|"EFFECT_COLFOUNTN_2"|"EFFECT_COLFOUNTN_3"|"EFFECT_SPANGLE_BLUE"|"EFFECT_SPANGLE_GREEN"|"EFFECT_SPANGLE_YELLOW"|"EFFECT_BALL_PUFF_RED"|"EFFECT_BALL_PUFF_BLUE"|"EFFECT_BALL_PUFF_GREEN"|"EFFECT_BALL_PUFF_YELLOW"|"EFFECT_BALL_PUFF_WHITE"|"EFFECT_BLOOD_7"|"EFFECT_BLOOD_FOOTSTEP"|"EFFECT_SPANGLE_MULTICOLOURED"|"EFFECT_BOULDER_BREAK_WATER"|"EFFECT_SPANGLE_WHITE"|"EFFECT_SPANGLE_PURPLE"|"EFFECT_BALL_PUFF_PURPLE"|"EFFECT_SPANGLE_BLACK"|"EFFECT_BALL_PUFF_BLACK"|"EFFECT_SPANGLE_ORANGE"|"EFFECT_BALL_PUFF_ORANGE"|"EFFECT_FALLING_ICE_BLOCKS"|"EFFECT_SLOW_KEEPER_POWER"|"EFFECT_TINY_SPARKS"|"EFFECT_COIN_FOUNTAIN"|"EFFECT_FEAR_CIRCLE"|"EFFECT_CRAZY_GAS"|"EFFECT_SENTRY_SMOKE"
---@alias spell_type "NOSPELL"|"SPELL_FIREBALL"|"SPELL_SUMMON_SPIDERLING"|"SPELL_FREEZE"|"SPELL_ARMOUR"|"SPELL_LIGHTNING"|"SPELL_REBOUND"|"SPELL_HEAL"|"SPELL_POISON_CLOUD"|"SPELL_INVISIBILITY"|"SPELL_TELEPORT"|"SPELL_SPEED"|"SPELL_SLOW"|"SPELL_DRAIN"|"SPELL_FEAR"|"SPELL_MELEE_SLOW"|"SPELL_NAVI_MISSILE"|"SPELL_FLAME_BREATH"|"SPELL_WIND"|"SPELL_LIGHT"|"SPELL_FLIGHT"|"SPELL_SIGHT"|"SPELL_GRENADE"|"SPELL_HAILSTORM"|"SPELL_WORD_OF_POWER"|"SPELL_CRAZY_GAS"|"SPELL_DISEASE"|"SPELL_CHICKEN"|"SPELL_TIME_BOMB"|"SPELL_LIZARD"|"SPELL_SUMMON_FAMILIAR"|"SPELL_SUMMON_CREATURE"
---@alias slab_type "HARD"|"GOLD"|"DIRT"|"TORCH_DIRT"|"DRAPE_WALL"|"TORCH_WALL"|"TWINS_WALL"|"WOMAN_WALL"|"PAIR_WALL"|"DAMAGED_WALL"|"PATH"|"PRETTY_PATH"|"LAVA"|"WATER"|"ENTRANCE_ZONE"|"ENTRANCE_WALL"|"TREASURY_AREA"|"TREASURY_WALL"|"BOOK_SHELVES"|"LIBRARY_WALL"|"PRISON_AREA"|"PRISON_WALL"|"TORTURE_AREA"|"TORTURE_WALL"|"TRAINING_AREA"|"TRAINING_WALL"|"HEART_PEDESTAL"|"HEART_WALL"|"WORKSHOP_AREA"|"WORKSHOP_WALL"|"SCAVENGE_AREA"|"SCAVENGER_WALL"|"TEMPLE_POOL"|"TEMPLE_WALL"|"GRAVE_AREA"|"GRAVE_WALL"|"HATCHERY"|"HATCHERY_WALL"|"LAIR_AREA"|"LAIR_WALL"|"BARRACK_AREA"|"BARRACK_WALL"|"DOOR_WOODEN"|"DOOR_WOODEN2"|"DOOR_BRACE"|"DOOR_BRACE2"|"DOOR_STEEL"|"DOOR_STEEL2"|"DOOR_MAGIC"|"DOOR_MAGIC2"|"SLAB50"|"BRIDGE_FRAME"|"GEMS"|"GUARD_AREA"|"PURPLE_PATH"|"DOOR_SECRET"|"DOOR_SECRET2"|"HARD_FLOOR"|"DOOR_MIDAS"|"DOOR_MIDAS2"|"DENSE_GOLD"
---@alias shot_type string
---@alias hit_type "THit_None"|"THit_CrtrsNObjcts"|"THit_CrtrsOnly"|"THit_CrtrsNObjctsNotOwn"|"THit_CrtrsOnlyNotOwn"|"THit_CrtrsNotArmourNotOwn"|"THit_All"|"THit_HeartOnly"|"THit_HeartOnlyNotOwn"|"THit_CrtrsNObjctsNShot"|"THit_TrapsAll"|"THit_CrtrsOnlyOwn"

---@class roomfields
---@field NULL integer
Expand Down
1 change: 1 addition & 0 deletions keeperfx_vs2010.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
<ClCompile Include="src\lens_mist.cpp" />
<ClCompile Include="src\light_data.c" />
<ClCompile Include="src\lua_api.c" />
<ClCompile Include="src\lua_api_camera.c" />
<ClCompile Include="src\lua_api_player.c" />
<ClCompile Include="src\lua_api_slabs.c" />
<ClCompile Include="src\lua_api_things.c" />
Expand Down
3 changes: 3 additions & 0 deletions keeperfx_vs2010.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,9 @@
<ClCompile Include="src\lua_utils.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\lua_api_camera.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\actionpt.h">
Expand Down
27 changes: 27 additions & 0 deletions src/lua_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "power_specials.h"
#include "thing_creature.h"
#include "thing_effects.h"
#include "thing_shots.h"
#include "magic_powers.h"

#include "lua_base.h"
Expand Down Expand Up @@ -881,6 +882,29 @@ static int lua_Add_object_to_level_at_pos(lua_State *L)
return 1;
}

static int lua_Add_shot_to_level(lua_State *L)
{
ThingModel shot_id = luaL_checkNamedCommand(L,1,shot_desc);
TbMapLocation location = luaL_checkLocation(L, 2);
PlayerNumber owner = luaL_checkPlayerSingle(L, 3);
int hittype = luaL_checkHitType(L, 4);
struct Thing *target = luaL_optCheckThing(L, 5);

ThingIndex target_index;

if (thing_is_invalid(target))
{
target_index = 0;
}
else
{
target_index = target->index;
}

lua_pushThing(L,script_process_new_shot(shot_id, location, owner, target_index, hittype));
return 1;
}

static int lua_Add_effect_generator_to_level(lua_State *L)
{
ThingModel gen_id = luaL_checkNamedCommand(L,1,effectgen_desc);
Expand Down Expand Up @@ -2133,6 +2157,7 @@ static const luaL_Reg global_methods[] = {
{"AddHeartHealth" ,lua_Add_heart_health },
{"AddObjectToLevel" ,lua_Add_object_to_level },
{"AddObjectToLevelAtPos" ,lua_Add_object_to_level_at_pos },
{"AddShotToLevel" ,lua_Add_shot_to_level },
{"AddEffectGeneratorToLevel" ,lua_Add_effect_generator_to_level },
{"PlaceDoor" ,lua_Place_door },
{"PlaceTrap" ,lua_Place_trap },
Expand Down Expand Up @@ -2248,6 +2273,7 @@ void Player_register(lua_State *L);
void Thing_register(lua_State *L);
void Slab_register(lua_State *L);
void room_register(lua_State *L);
void Camera_register(lua_State *L);

void reg_host_functions(lua_State *L)
{
Expand All @@ -2256,4 +2282,5 @@ void reg_host_functions(lua_State *L)
Thing_register(L);
Slab_register(L);
room_register(L);
Camera_register(L);
}
157 changes: 157 additions & 0 deletions src/lua_api_camera.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
#include "pre_inc.h"

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#include "bflib_basics.h"
#include "globals.h"
#include "map_blocks.h"
#include "map_data.h"
#include "thing_data.h"
#include "thing_creature.h"
#include "player_data.h"

#include "lua_base.h"
#include "lua_params.h"
#include "lua_utils.h"

#include "post_inc.h"
#include "game_merge.h"
#include "lvl_script_lib.h"

/**********************************************/

int luaL_checkCamera(lua_State *L, int idx)
{
if (!lua_istable(L, idx)) {
return luaL_argerror(L, idx, "Expected a table");
}

lua_getfield(L, idx, "playerId");
if (!lua_isnumber(L, -1)) {
return luaL_argerror(L, idx, "Table must have a numeric 'playerId' field");
}
PlayerNumber playerId = lua_tointeger(L, -1);
lua_pop(L, 1);

return playerId;
}

static const struct luaL_Reg slab_methods[] = {
{NULL, NULL}
};


static int camera_tostring(lua_State *L)
{
int playerId = luaL_checkCamera(L, 1);
char buffer[32];
snprintf(buffer, sizeof(buffer), "Camera(%d)", playerId);
lua_pushstring(L, buffer);
return 1;
}

// Function to set field values
static int camera_set_field(lua_State *L) {
int playerId = luaL_checkCamera(L, 1);
const char* key = luaL_checkstring(L, 2);

struct PlayerInfo *player = get_player(playerId);
struct Camera* cam = player->acamera;

if (strcmp(key, "pos") == 0) {
luaL_checkCoord3d(L, 3, &cam->mappos);
} else if (strcmp(key, "yaw") == 0) {
cam->rotation_angle_x = luaL_checkinteger(L, 3);
} else if (strcmp(key, "pitch") == 0) {
cam->rotation_angle_y = luaL_checkinteger(L, 3);
} else if (strcmp(key, "roll") == 0) {
cam->rotation_angle_z = luaL_checkinteger(L, 3);
} else if (strcmp(key, "horizontal_fov") == 0) {
cam->horizontal_fov = luaL_checkinteger(L, 3);
} else if (strcmp(key, "zoom") == 0) {
cam->zoom = luaL_checkinteger(L, 3);
} else if (strcmp(key, "view_mode") == 0) {
cam->view_mode = luaL_checkinteger(L, 3);
} else {
return luaL_error(L, "Unknown field '%s' for Camera", key);
}

return 0;
}

// Function to get field values
static int camera_get_field(lua_State *L) {

int playerId = luaL_checkCamera(L, 1);

const char* key = luaL_checkstring(L, 2);

if (try_get_c_method(L, key, slab_methods))
{
return 1;
}

struct PlayerInfo *player = get_player(playerId);
struct Camera* cam = player->acamera;

if (strcmp(key, "pos") == 0) {
lua_pushPos(L, &cam->mappos);
} else if (strcmp(key, "yaw") == 0) {
lua_pushinteger(L, cam->rotation_angle_x);
} else if (strcmp(key, "pitch") == 0) {
lua_pushinteger(L, cam->rotation_angle_y);
} else if (strcmp(key, "roll") == 0) {
lua_pushinteger(L, cam->rotation_angle_z);
} else if (strcmp(key, "horizontal_fov") == 0) {
lua_pushinteger(L, cam->horizontal_fov);
} else if (strcmp(key, "zoom") == 0) {
lua_pushinteger(L, cam->zoom);
} else if (strcmp(key, "view_mode") == 0) {
lua_pushinteger(L, cam->view_mode);
} else if (try_get_from_methods(L, 1, key)) {
return 1;
} else {
return luaL_error(L, "Unknown field or method '%s' for Player", key);
}

return 1;

}

static int camera_eq(lua_State *L) {
int playerId1, playerId2;

playerId1 = luaL_checkCamera(L, 1);
playerId2 = luaL_checkCamera(L, 2);

// Compare the coordinates
lua_pushboolean(L, (playerId1 == playerId2));
return 1;
}

static const struct luaL_Reg camera_meta[] = {
{"__tostring", camera_tostring},
{"__index", camera_get_field},
{"__newindex", camera_set_field},
{"__eq", camera_eq},
{NULL, NULL}
};

void Camera_register(lua_State *L) {
// Create a metatable for thing and add it to the registry
luaL_newmetatable(L, "Camera");

// Set the __index and __newindex metamethods
luaL_setfuncs(L, camera_meta, 0);

// Hide the metatable by setting the __metatable field to nil
lua_pushliteral(L, "__metatable");
lua_pushnil(L);
lua_rawset(L, -3);

// Pop the metatable from the stack
lua_pop(L, 1);

}
4 changes: 3 additions & 1 deletion src/lua_api_player.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,9 @@ static int player_get_field(lua_State *L) {
return 1;

// Built-in fields
if (strcmp(key, "heart") == 0) {
if (strcmp(key, "camera") == 0) {
lua_pushCamera(L, plyr_idx);
} else if (strcmp(key, "heart") == 0) {
lua_pushThing(L, get_player_soul_container(plyr_idx));
} else if (strcmp(key, "controls") == 0) {
lua_pushinteger(L, plyr_idx);
Expand Down
30 changes: 26 additions & 4 deletions src/lua_api_things.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,27 @@ static int make_thing_zombie (lua_State *L)
return 0;
}

static int lua_set_velocity (lua_State *L)
{
struct Thing *thing = luaL_checkThing(L, 1);
long angle_xy = luaL_checkinteger(L, 2);
long angle_z = luaL_checkinteger(L, 3);
long dist = luaL_checkinteger(L, 4);

struct ComponentVector cvect;
angles_to_vector(angle_xy, angle_z, dist, &cvect);
thing->veloc_push_add.x.val += cvect.x;
thing->veloc_push_add.y.val += cvect.y;
thing->veloc_push_add.z.val += cvect.z;
thing->state_flags |= TF1_PushAdd;

return 0;
}





static int lua_delete_thing(lua_State *L)
{
struct Thing *thing = luaL_checkThing(L, 1);
Expand Down Expand Up @@ -490,10 +511,11 @@ static const struct luaL_Reg thing_methods[] = {
{"delete", lua_delete_thing},
{"isValid", lua_is_valid},

{"transfer" ,lua_Transfer_creature },
{"level_up" ,lua_Level_up_creature },
{"teleport" ,lua_Teleport_creature },
{"change_owner" ,lua_Change_creature_owner },
{"transfer" ,lua_Transfer_creature },
{"level_up" ,lua_Level_up_creature },
{"teleport" ,lua_Teleport_creature },
{"change_owner" ,lua_Change_creature_owner },
{"set_velocity" ,lua_set_velocity },
{NULL, NULL}
};

Expand Down
Loading