New scripting features
This commit is contained in:
parent
05fe86e64c
commit
faabb8178a
Binary file not shown.
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 16 KiB |
@ -126,7 +126,7 @@ void WorldRenderer::drawChunks(Chunks* chunks,
|
||||
}
|
||||
|
||||
|
||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera){
|
||||
void WorldRenderer::draw(const GfxContext& pctx, Camera* camera, bool hudVisible){
|
||||
EngineSettings& settings = engine->getSettings();
|
||||
skybox->refresh(level->world->daytime,
|
||||
1.0f+fog*2.0f, 4);
|
||||
@ -187,7 +187,7 @@ void WorldRenderer::draw(const GfxContext& pctx, Camera* camera){
|
||||
drawChunks(level->chunks, camera, shader);
|
||||
|
||||
// Selected block
|
||||
if (PlayerController::selectedBlockId != -1){
|
||||
if (PlayerController::selectedBlockId != -1 && hudVisible){
|
||||
blockid_t id = PlayerController::selectedBlockId;
|
||||
Block* block = contentIds->getBlockDef(id);
|
||||
assert(block != nullptr);
|
||||
|
||||
@ -37,7 +37,7 @@ public:
|
||||
WorldRenderer(Engine* engine, LevelFrontend* frontend);
|
||||
~WorldRenderer();
|
||||
|
||||
void draw(const GfxContext& context, Camera* camera);
|
||||
void draw(const GfxContext& context, Camera* camera, bool hudVisible);
|
||||
void drawDebug(const GfxContext& context, Camera* camera);
|
||||
void drawBorders(int sx, int sy, int sz, int ex, int ey, int ez);
|
||||
|
||||
|
||||
@ -149,7 +149,7 @@ void LevelScreen::draw(float delta) {
|
||||
Viewport viewport(Window::width, Window::height);
|
||||
GfxContext ctx(nullptr, viewport, batch.get());
|
||||
|
||||
worldRenderer->draw(ctx, camera.get());
|
||||
worldRenderer->draw(ctx, camera.get(), hudVisible);
|
||||
|
||||
if (hudVisible) {
|
||||
hud->draw(ctx);
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
struct item_funcs_set {
|
||||
bool init: 1;
|
||||
bool on_use_on_block: 1;
|
||||
bool on_block_break_by: 1;
|
||||
};
|
||||
|
||||
enum class item_icon_type {
|
||||
|
||||
@ -13,7 +13,7 @@ LevelController::LevelController(EngineSettings& settings, Level* level)
|
||||
chunks = std::make_unique<ChunksController>(level, settings.chunks.padding);
|
||||
player = std::make_unique<PlayerController>(level, settings, blocks.get());
|
||||
|
||||
scripting::on_world_load(level);
|
||||
scripting::on_world_load(level, blocks.get());
|
||||
}
|
||||
|
||||
LevelController::~LevelController() {
|
||||
|
||||
@ -259,10 +259,23 @@ void PlayerController::updateInteraction(){
|
||||
}
|
||||
}
|
||||
|
||||
if (lclick) {
|
||||
if (!input.shift && item->rt.funcsset.on_use_on_block) {
|
||||
if (scripting::on_item_break_block(player, item, x, y, z))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Block* target = contentIds->getBlockDef(vox->id);
|
||||
if (lclick && target->breakable){
|
||||
blocksController->breakBlock(player, target, x, y, z);
|
||||
}
|
||||
if (rclick) {
|
||||
if (!input.shift && item->rt.funcsset.on_use_on_block) {
|
||||
if (scripting::on_item_use_on_block(player, item, x, y, z))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (def && rclick){
|
||||
if (!input.shift && target->rt.funcsset.oninteract) {
|
||||
scripting::on_block_interact(player, target, x, y, z);
|
||||
|
||||
@ -6,19 +6,49 @@
|
||||
#include "../../physics/Hitbox.h"
|
||||
#include "../../objects/Player.h"
|
||||
#include "../../world/Level.h"
|
||||
#include "../../world/World.h"
|
||||
#include "../../content/Content.h"
|
||||
#include "../../voxels/Block.h"
|
||||
#include "../../voxels/Chunks.h"
|
||||
#include "../../voxels/voxel.h"
|
||||
#include "../../lighting/Lighting.h"
|
||||
#include "../../logic/BlocksController.h"
|
||||
|
||||
int l_block_name(lua_State* L) {
|
||||
static int l_world_get_day_time(lua_State* L) {
|
||||
lua_pushnumber(L, scripting::level->world->daytime);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_world_set_day_time(lua_State* L) {
|
||||
double value = scripting::level->world->daytime;
|
||||
scripting::level->world->daytime = fmod(value, 1.0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_world_get_seed(lua_State* L) {
|
||||
lua_pushinteger(L, scripting::level->world->seed);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const luaL_Reg worldlib [] = {
|
||||
{"get_day_time", l_world_get_day_time},
|
||||
{"set_day_time", l_world_set_day_time},
|
||||
{"get_seed", l_world_get_seed},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
int luaopen_world(lua_State* L) {
|
||||
luaL_openlib(L, "world", worldlib, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_block_name(lua_State* L) {
|
||||
int id = lua_tointeger(L, 1);
|
||||
lua_pushstring(L, scripting::content->indices->getBlockDef(id)->name.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_is_solid_at(lua_State* L) {
|
||||
static int l_is_solid_at(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -27,29 +57,32 @@ int l_is_solid_at(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_blocks_count(lua_State* L) {
|
||||
static int l_blocks_count(lua_State* L) {
|
||||
lua_pushinteger(L, scripting::content->indices->countBlockDefs());
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_block_index(lua_State* L) {
|
||||
static int l_block_index(lua_State* L) {
|
||||
auto name = lua_tostring(L, 1);
|
||||
lua_pushinteger(L, scripting::content->requireBlock(name)->rt.id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_set_block(lua_State* L) {
|
||||
static int l_set_block(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
int id = lua_tointeger(L, 4);
|
||||
int states = lua_tointeger(L, 5);
|
||||
bool noupdate = lua_toboolean(L, 6);
|
||||
scripting::level->chunks->set(x, y, z, id, states);
|
||||
scripting::level->lighting->onBlockSet(x,y,z, id);
|
||||
if (!noupdate)
|
||||
scripting::blocks->updateSides(x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_get_block(lua_State* L) {
|
||||
static int l_get_block(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -66,7 +99,7 @@ inline int lua_pushivec3(lua_State* L, int x, int y, int z) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
int l_get_block_x(lua_State* L) {
|
||||
static int l_get_block_x(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -83,7 +116,7 @@ int l_get_block_x(lua_State* L) {
|
||||
}
|
||||
}
|
||||
|
||||
int l_get_block_y(lua_State* L) {
|
||||
static int l_get_block_y(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -100,7 +133,7 @@ int l_get_block_y(lua_State* L) {
|
||||
}
|
||||
}
|
||||
|
||||
int l_get_block_z(lua_State* L) {
|
||||
static int l_get_block_z(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -117,7 +150,7 @@ int l_get_block_z(lua_State* L) {
|
||||
}
|
||||
}
|
||||
|
||||
int l_get_player_pos(lua_State* L) {
|
||||
static int l_get_player_pos(lua_State* L) {
|
||||
glm::vec3 pos = scripting::level->player->hitbox->position;
|
||||
lua_pushnumber(L, pos.x);
|
||||
lua_pushnumber(L, pos.y);
|
||||
@ -125,14 +158,14 @@ int l_get_player_pos(lua_State* L) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
int l_get_player_rot(lua_State* L) {
|
||||
static int l_get_player_rot(lua_State* L) {
|
||||
glm::vec2 rot = scripting::level->player->cam;
|
||||
lua_pushnumber(L, rot.x);
|
||||
lua_pushnumber(L, rot.y);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int l_set_player_rot(lua_State* L) {
|
||||
static int l_set_player_rot(lua_State* L) {
|
||||
double x = lua_tonumber(L, 1);
|
||||
double y = lua_tonumber(L, 2);
|
||||
glm::vec2& cam = scripting::level->player->cam;
|
||||
@ -141,7 +174,7 @@ int l_set_player_rot(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_set_player_pos(lua_State* L) {
|
||||
static int l_set_player_pos(lua_State* L) {
|
||||
double x = lua_tonumber(L, 1);
|
||||
double y = lua_tonumber(L, 2);
|
||||
double z = lua_tonumber(L, 3);
|
||||
@ -149,7 +182,7 @@ int l_set_player_pos(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_get_block_states(lua_State* L) {
|
||||
static int l_get_block_states(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -159,7 +192,7 @@ int l_get_block_states(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_get_block_user_bits(lua_State* L) {
|
||||
static int l_get_block_user_bits(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -177,7 +210,7 @@ int l_get_block_user_bits(lua_State* L) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int l_set_block_user_bits(lua_State* L) {
|
||||
static int l_set_block_user_bits(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -195,7 +228,7 @@ int l_set_block_user_bits(lua_State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int l_is_replaceable_at(lua_State* L) {
|
||||
static int l_is_replaceable_at(lua_State* L) {
|
||||
int x = lua_tointeger(L, 1);
|
||||
int y = lua_tointeger(L, 2);
|
||||
int z = lua_tointeger(L, 3);
|
||||
@ -208,6 +241,8 @@ int l_is_replaceable_at(lua_State* L) {
|
||||
lua_setglobal(L, NAME))
|
||||
|
||||
void apilua::create_funcs(lua_State* L) {
|
||||
luaopen_world(L);
|
||||
|
||||
lua_addfunc(L, l_block_index, "block_index");
|
||||
lua_addfunc(L, l_block_name, "block_name");
|
||||
lua_addfunc(L, l_blocks_count, "blocks_count");
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "../../world/Level.h"
|
||||
#include "../../voxels/Block.h"
|
||||
#include "../../items/ItemDef.h"
|
||||
#include "../../logic/BlocksController.h"
|
||||
#include "api_lua.h"
|
||||
|
||||
using namespace scripting;
|
||||
@ -23,6 +24,14 @@ lua_State* scripting::L = nullptr;
|
||||
Level* scripting::level = nullptr;
|
||||
const Content* scripting::content = nullptr;
|
||||
EnginePaths* scripting::paths = nullptr;
|
||||
BlocksController* scripting::blocks = nullptr;
|
||||
|
||||
inline int lua_pushivec3(lua_State* L, int x, int y, int z) {
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
return 3;
|
||||
}
|
||||
|
||||
void delete_global(lua_State* L, const char* name) {
|
||||
lua_pushnil(L);
|
||||
@ -40,11 +49,15 @@ bool rename_global(lua_State* L, const char* src, const char* dst) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void call_func(lua_State* L, int argc, const std::string& name) {
|
||||
int call_func(lua_State* L, int argc, const std::string& name) {
|
||||
if (lua_pcall(L, argc, LUA_MULTRET, 0)) {
|
||||
std::cerr << "Lua error in " << name << ": ";
|
||||
std::cerr << lua_tostring(L,-1) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
int res_count = lua_tointeger(L, -1);
|
||||
lua_pop(L, -1);
|
||||
return res_count;
|
||||
}
|
||||
|
||||
void scripting::initialize(EnginePaths* paths) {
|
||||
@ -72,9 +85,10 @@ void scripting::initialize(EnginePaths* paths) {
|
||||
apilua::create_funcs(L);
|
||||
}
|
||||
|
||||
void scripting::on_world_load(Level* level) {
|
||||
void scripting::on_world_load(Level* level, BlocksController* blocks) {
|
||||
scripting::level = level;
|
||||
scripting::content = level->content;
|
||||
scripting::blocks = blocks;
|
||||
|
||||
fs::path file = paths->getResources()/fs::path("scripts/world.lua");
|
||||
std::string src = files::read_string(file);
|
||||
@ -90,46 +104,61 @@ void scripting::on_world_quit() {
|
||||
void scripting::update_block(const Block* block, int x, int y, int z) {
|
||||
std::string name = block->name+".update";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
lua_pushivec3(L, x, y, z);
|
||||
call_func(L, 3, name);
|
||||
}
|
||||
|
||||
void scripting::random_update_block(const Block* block, int x, int y, int z) {
|
||||
std::string name = block->name+".randupdate";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
lua_pushivec3(L, x, y, z);
|
||||
call_func(L, 3, name);
|
||||
}
|
||||
|
||||
void scripting::on_block_placed(Player* player, const Block* block, int x, int y, int z) {
|
||||
std::string name = block->name+".placed";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
call_func(L, 3, name);
|
||||
lua_pushivec3(L, x, y, z);
|
||||
lua_pushinteger(L, 1);
|
||||
call_func(L, 4, name);
|
||||
}
|
||||
|
||||
void scripting::on_block_broken(Player* player, const Block* block, int x, int y, int z) {
|
||||
std::string name = block->name+".broken";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
call_func(L, 3, name);
|
||||
lua_pushivec3(L, x, y, z);
|
||||
lua_pushinteger(L, 1);
|
||||
call_func(L, 4, name);
|
||||
}
|
||||
|
||||
void scripting::on_block_interact(Player* player, const Block* block, int x, int y, int z) {
|
||||
std::string name = block->name+".oninteract";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushinteger(L, x);
|
||||
lua_pushinteger(L, y);
|
||||
lua_pushinteger(L, z);
|
||||
call_func(L, 3, name);
|
||||
lua_pushivec3(L, x, y, z);
|
||||
lua_pushinteger(L, 1);
|
||||
call_func(L, 4, name);
|
||||
}
|
||||
|
||||
bool scripting::on_item_use_on_block(Player* player, const ItemDef* item, int x, int y, int z) {
|
||||
std::string name = item->name+".useon";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushivec3(L, x, y, z);
|
||||
lua_pushinteger(L, 1);
|
||||
if (call_func(L, 4, name)) {
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z) {
|
||||
std::string name = item->name+".blockbreakby";
|
||||
lua_getglobal(L, name.c_str());
|
||||
lua_pushivec3(L, x, y, z);
|
||||
lua_pushinteger(L, 1);
|
||||
if (call_func(L, 4, name)) {
|
||||
return lua_toboolean(L, -1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// todo: refactor
|
||||
@ -159,6 +188,8 @@ void scripting::load_item_script(std::string prefix, fs::path file, item_funcs_s
|
||||
}
|
||||
call_func(L, 0, "<script>");
|
||||
funcsset->init=rename_global(L, "init", (prefix+".init").c_str());
|
||||
funcsset->on_use_on_block=rename_global(L, "on_use_on_block", (prefix+".useon").c_str());
|
||||
funcsset->on_block_break_by=rename_global(L, "on_block_break_by", (prefix+".blockbreakby").c_str());
|
||||
}
|
||||
|
||||
void scripting::close() {
|
||||
|
||||
@ -8,21 +8,26 @@ class Content;
|
||||
class Level;
|
||||
class Block;
|
||||
class Player;
|
||||
class ItemDef;
|
||||
struct block_funcs_set;
|
||||
struct item_funcs_set;
|
||||
class BlocksController;
|
||||
|
||||
namespace scripting {
|
||||
extern const Content* content;
|
||||
extern Level* level;
|
||||
extern BlocksController* blocks;
|
||||
|
||||
void initialize(EnginePaths* paths);
|
||||
void on_world_load(Level* level);
|
||||
void on_world_load(Level* level, BlocksController* blocks);
|
||||
void on_world_quit();
|
||||
void update_block(const Block* block, int x, int y, int z);
|
||||
void random_update_block(const Block* block, int x, int y, int z);
|
||||
void on_block_placed(Player* player, const Block* block, int x, int y, int z);
|
||||
void on_block_broken(Player* player, const Block* block, int x, int y, int z);
|
||||
void on_block_interact(Player* player, const Block* block, int x, int y, int z);
|
||||
bool on_item_use_on_block(Player* player, const ItemDef* item, int x, int y, int z);
|
||||
bool on_item_break_block(Player* player, const ItemDef* item, int x, int y, int z);
|
||||
void load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset);
|
||||
void load_item_script(std::string prefix, fs::path file, item_funcs_set* funcsset);
|
||||
void close();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user