Merge branch 'main' into user-properties
This commit is contained in:
@@ -75,6 +75,13 @@ void BlocksController::breakBlock(
|
||||
void BlocksController::placeBlock(
|
||||
Player* player, const Block& def, blockstate state, int x, int y, int z
|
||||
) {
|
||||
auto voxel = chunks.get(x, y, z);
|
||||
if (voxel == nullptr) {
|
||||
return;
|
||||
}
|
||||
const auto& prevDef = level.content->getIndices()->blocks.require(voxel->id);
|
||||
scripting::on_block_replaced(player, prevDef, {x, y, z});
|
||||
|
||||
onBlockInteraction(
|
||||
player, glm::ivec3(x, y, z), def, BlockInteraction::placing
|
||||
);
|
||||
|
||||
@@ -125,6 +125,10 @@ namespace cmd {
|
||||
const std::unordered_map<std::string, Command>& getCommands() const {
|
||||
return commands;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
commands.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class CommandsInterpreter {
|
||||
@@ -158,5 +162,10 @@ namespace cmd {
|
||||
CommandsRepository* getRepository() const {
|
||||
return repository.get();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
repository->clear();
|
||||
variables.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "debug/Logger.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "files/WorldFiles.hpp"
|
||||
#include "interfaces/Object.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "physics/Hitbox.hpp"
|
||||
#include "settings.hpp"
|
||||
@@ -26,7 +25,7 @@ LevelController::LevelController(Engine* engine, std::unique_ptr<Level> levelPtr
|
||||
*level, settings.chunks.padding.get()
|
||||
)),
|
||||
player(std::make_unique<PlayerController>(
|
||||
settings, this->level.get(), blocks.get()
|
||||
settings, level.get(), blocks.get()
|
||||
)) {
|
||||
scripting::on_world_load(this);
|
||||
}
|
||||
@@ -45,11 +44,6 @@ void LevelController::update(float delta, bool input, bool pause) {
|
||||
|
||||
if (!pause) {
|
||||
// update all objects that needed
|
||||
for (const auto& obj : level->objects) {
|
||||
if (obj && obj->shouldUpdate) {
|
||||
obj->update(delta);
|
||||
}
|
||||
}
|
||||
blocks->update(delta);
|
||||
player->update(delta, input, pause);
|
||||
level->entities->updatePhysics(delta);
|
||||
@@ -57,17 +51,6 @@ void LevelController::update(float delta, bool input, bool pause) {
|
||||
}
|
||||
level->entities->clean();
|
||||
player->postUpdate(delta, input, pause);
|
||||
|
||||
// erease null pointers
|
||||
auto& objects = level->objects;
|
||||
objects.erase(
|
||||
std::remove_if(
|
||||
objects.begin(),
|
||||
objects.end(),
|
||||
[](auto obj) { return obj == nullptr; }
|
||||
),
|
||||
objects.end()
|
||||
);
|
||||
}
|
||||
|
||||
void LevelController::saveWorld() {
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "lighting/Lighting.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
#include "objects/Players.hpp"
|
||||
#include "physics/Hitbox.hpp"
|
||||
#include "physics/PhysicsSolver.hpp"
|
||||
#include "settings.hpp"
|
||||
@@ -40,7 +41,7 @@ const float C_ZOOM = 0.1f;
|
||||
const float CROUCH_SHIFT_Y = -0.2f;
|
||||
|
||||
CameraControl::CameraControl(
|
||||
const std::shared_ptr<Player>& player, const CameraSettings& settings
|
||||
Player* player, const CameraSettings& settings
|
||||
)
|
||||
: player(player),
|
||||
camera(player->fpCamera),
|
||||
@@ -193,7 +194,7 @@ PlayerController::PlayerController(
|
||||
BlocksController* blocksController
|
||||
)
|
||||
: settings(settings), level(level),
|
||||
player(level->getObject<Player>(0)),
|
||||
player(level->players->get(0)),
|
||||
camControl(player, settings.camera),
|
||||
blocksController(blocksController),
|
||||
playerTickClock(20, 3) {
|
||||
@@ -215,7 +216,7 @@ void PlayerController::onFootstep(const Hitbox& hitbox) {
|
||||
continue;
|
||||
}
|
||||
blocksController->onBlockInteraction(
|
||||
player.get(),
|
||||
player,
|
||||
glm::ivec3(x, y, z),
|
||||
def,
|
||||
BlockInteraction::step
|
||||
@@ -254,7 +255,7 @@ void PlayerController::update(float delta, bool input, bool pause) {
|
||||
if (playerTickClock.update(delta)) {
|
||||
if (player->getId() % playerTickClock.getParts() ==
|
||||
playerTickClock.getPart()) {
|
||||
scripting::on_player_tick(player.get(), playerTickClock.getTickRate());
|
||||
scripting::on_player_tick(player, playerTickClock.getTickRate());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,12 +391,12 @@ voxel* PlayerController::updateSelection(float maxDistance) {
|
||||
if (selection.entity != prevEntity) {
|
||||
if (prevEntity != ENTITY_NONE) {
|
||||
if (auto pentity = level->entities->get(prevEntity)) {
|
||||
scripting::on_aim_off(*pentity, player.get());
|
||||
scripting::on_aim_off(*pentity, player);
|
||||
}
|
||||
}
|
||||
if (selection.entity != ENTITY_NONE) {
|
||||
if (auto pentity = level->entities->get(selection.entity)) {
|
||||
scripting::on_aim_on(*pentity, player.get());
|
||||
scripting::on_aim_on(*pentity, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -432,8 +433,8 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
||||
|
||||
if (!input.shift && target.rt.funcsset.oninteract) {
|
||||
if (scripting::on_block_interact(
|
||||
player.get(), target, selection.actualPosition
|
||||
)) {
|
||||
player, target, selection.actualPosition
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -474,7 +475,7 @@ void PlayerController::processRightClick(const Block& def, const Block& target)
|
||||
slot.setCount(slot.getCount()-1);
|
||||
}
|
||||
blocksController->placeBlock(
|
||||
player.get(), def, state, coord.x, coord.y, coord.z
|
||||
player, def, state, coord.x, coord.y, coord.z
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -488,10 +489,10 @@ void PlayerController::updateEntityInteraction(
|
||||
}
|
||||
auto entity = *entityOpt;
|
||||
if (lclick) {
|
||||
scripting::on_attacked(entity, player.get(), player->getEntity());
|
||||
scripting::on_attacked(entity, player, player->getEntity());
|
||||
}
|
||||
if (rclick) {
|
||||
scripting::on_entity_used(entity, player.get());
|
||||
scripting::on_entity_used(entity, player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,7 +524,7 @@ void PlayerController::updateInteraction(float delta) {
|
||||
auto vox = updateSelection(maxDistance);
|
||||
if (vox == nullptr) {
|
||||
if (rclick && item.rt.funcsset.on_use) {
|
||||
scripting::on_item_use(player.get(), item);
|
||||
scripting::on_item_use(player, item);
|
||||
}
|
||||
if (selection.entity) {
|
||||
updateEntityInteraction(selection.entity, lattack, rclick);
|
||||
@@ -534,7 +535,7 @@ void PlayerController::updateInteraction(float delta) {
|
||||
auto iend = selection.position;
|
||||
if (lclick && !input.shift && item.rt.funcsset.on_block_break_by) {
|
||||
if (scripting::on_item_break_block(
|
||||
player.get(), item, iend.x, iend.y, iend.z
|
||||
player, item, iend.x, iend.y, iend.z
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
@@ -543,7 +544,7 @@ void PlayerController::updateInteraction(float delta) {
|
||||
if (lclick) {
|
||||
if (player->isInstantDestruction() && target.breakable) {
|
||||
blocksController->breakBlock(
|
||||
player.get(), target, iend.x, iend.y, iend.z
|
||||
player, target, iend.x, iend.y, iend.z
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -551,10 +552,10 @@ void PlayerController::updateInteraction(float delta) {
|
||||
bool preventDefault = false;
|
||||
if (item.rt.funcsset.on_use_on_block) {
|
||||
preventDefault = scripting::on_item_use_on_block(
|
||||
player.get(), item, iend, selection.normal
|
||||
player, item, iend, selection.normal
|
||||
);
|
||||
} else if (item.rt.funcsset.on_use) {
|
||||
preventDefault = scripting::on_item_use(player.get(), item);
|
||||
preventDefault = scripting::on_item_use(player, item);
|
||||
}
|
||||
if (preventDefault) {
|
||||
return;
|
||||
@@ -566,10 +567,10 @@ void PlayerController::updateInteraction(float delta) {
|
||||
}
|
||||
if (Events::jactive(BIND_PLAYER_PICK)) {
|
||||
auto coord = selection.actualPosition;
|
||||
pick_block(indices, chunks, player.get(), coord.x, coord.y, coord.z);
|
||||
pick_block(indices, chunks, player, coord.x, coord.y, coord.z);
|
||||
}
|
||||
}
|
||||
|
||||
Player* PlayerController::getPlayer() {
|
||||
return player.get();
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ struct CameraSettings;
|
||||
struct EngineSettings;
|
||||
|
||||
class CameraControl {
|
||||
std::shared_ptr<Player> player;
|
||||
Player* player;
|
||||
std::shared_ptr<Camera> camera;
|
||||
const CameraSettings& settings;
|
||||
glm::vec3 offset;
|
||||
@@ -40,7 +40,7 @@ class CameraControl {
|
||||
void switchCamera();
|
||||
public:
|
||||
CameraControl(
|
||||
const std::shared_ptr<Player>& player, const CameraSettings& settings
|
||||
Player* player, const CameraSettings& settings
|
||||
);
|
||||
void updateMouse(PlayerInput& input);
|
||||
void update(PlayerInput input, float delta, Chunks* chunks);
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
class PlayerController {
|
||||
const EngineSettings& settings;
|
||||
Level* level;
|
||||
std::shared_ptr<Player> player;
|
||||
Player* player;
|
||||
PlayerInput input {};
|
||||
CameraControl camControl;
|
||||
BlocksController* blocksController;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "lighting/Lighting.hpp"
|
||||
#include "logic/BlocksController.hpp"
|
||||
#include "logic/LevelController.hpp"
|
||||
#include "objects/Players.hpp"
|
||||
#include "voxels/Block.hpp"
|
||||
#include "voxels/Chunk.hpp"
|
||||
#include "voxels/Chunks.hpp"
|
||||
@@ -350,9 +351,9 @@ static int l_place(lua::State* L) {
|
||||
"there is no block with index " + std::to_string(id)
|
||||
);
|
||||
}
|
||||
auto player = level->getObject<Player>(playerid);
|
||||
auto player = level->players->get(playerid);
|
||||
controller->getBlocksController()->placeBlock(
|
||||
player ? player.get() : nullptr, *def, int2blockstate(state), x, y, z
|
||||
player, *def, int2blockstate(state), x, y, z
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
@@ -367,10 +368,8 @@ static int l_destruct(lua::State* L) {
|
||||
return 0;
|
||||
}
|
||||
auto& def = level->content->getIndices()->blocks.require(voxel->id);
|
||||
auto player = level->getObject<Player>(playerid);
|
||||
controller->getBlocksController()->breakBlock(
|
||||
player ? player.get() : nullptr, def, x, y, z
|
||||
);
|
||||
auto player = level->players->get(playerid);
|
||||
controller->getBlocksController()->breakBlock(player, def, x, y, z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
static int l_get_version(lua::State* L) {
|
||||
return lua::pushvec_stack(
|
||||
L, glm::vec2(ENGINE_VERSION_MAJOR, ENGINE_VERSION_MINOR)
|
||||
);
|
||||
}
|
||||
|
||||
/// @brief Creating new world
|
||||
/// @param name Name world
|
||||
/// @param seed Seed world
|
||||
@@ -239,6 +245,7 @@ static int l_quit(lua::State*) {
|
||||
}
|
||||
|
||||
const luaL_Reg corelib[] = {
|
||||
{"get_version", lua::wrap<l_get_version>},
|
||||
{"new_world", lua::wrap<l_new_world>},
|
||||
{"open_world", lua::wrap<l_open_world>},
|
||||
{"reopen_world", lua::wrap<l_reopen_world>},
|
||||
|
||||
@@ -19,7 +19,7 @@ static fs::path resolve_path(const std::string& path) {
|
||||
|
||||
static fs::path resolve_path_soft(const std::string& path) {
|
||||
if (path.find(':') == std::string::npos) {
|
||||
return path;
|
||||
return fs::u8path("");
|
||||
}
|
||||
return engine->getPaths()->resolve(path, false);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "items/Inventory.hpp"
|
||||
#include "objects/Entities.hpp"
|
||||
#include "objects/Player.hpp"
|
||||
#include "objects/Players.hpp"
|
||||
#include "physics/Hitbox.hpp"
|
||||
#include "window/Camera.hpp"
|
||||
#include "world/Level.hpp"
|
||||
@@ -11,8 +12,8 @@
|
||||
|
||||
using namespace scripting;
|
||||
|
||||
inline std::shared_ptr<Player> get_player(lua::State* L, int idx) {
|
||||
return level->getObject<Player>(lua::tointeger(L, idx));
|
||||
inline Player* get_player(lua::State* L, int idx) {
|
||||
return level->players->get(lua::tointeger(L, idx));
|
||||
}
|
||||
|
||||
static int l_get_pos(lua::State* L) {
|
||||
@@ -235,6 +236,20 @@ static int l_set_camera(lua::State* L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_get_name(lua::State* L) {
|
||||
if (auto player = get_player(L, 1)) {
|
||||
return lua::pushstring(L, player->getName());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int l_set_name(lua::State* L) {
|
||||
if (auto player = get_player(L, 1)) {
|
||||
player->setName(lua::require_string(L, 2));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg playerlib[] = {
|
||||
{"get_pos", lua::wrap<l_get_pos>},
|
||||
{"set_pos", lua::wrap<l_set_pos>},
|
||||
@@ -260,5 +275,7 @@ const luaL_Reg playerlib[] = {
|
||||
{"set_entity", lua::wrap<l_set_entity>},
|
||||
{"get_camera", lua::wrap<l_get_camera>},
|
||||
{"set_camera", lua::wrap<l_set_camera>},
|
||||
{"get_name", lua::wrap<l_get_name>},
|
||||
{"set_name", lua::wrap<l_set_name>},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
|
||||
#include "assets/Assets.hpp"
|
||||
#include "assets/AssetsLoader.hpp"
|
||||
#include "coders/json.hpp"
|
||||
#include "engine.hpp"
|
||||
#include "files/files.hpp"
|
||||
#include "files/engine_paths.hpp"
|
||||
#include "world/Level.hpp"
|
||||
#include "world/World.hpp"
|
||||
@@ -32,22 +34,34 @@ static int l_get_list(lua::State* L) {
|
||||
for (size_t i = 0; i < worlds.size(); i++) {
|
||||
lua::createtable(L, 0, 1);
|
||||
|
||||
auto name = worlds[i].filename().u8string();
|
||||
const auto& folder = worlds[i];
|
||||
|
||||
auto root = json::parse(files::read_string(folder/fs::u8path("world.json")));
|
||||
const auto& versionMap = root["version"];
|
||||
int versionMajor = versionMap["major"].asInteger();
|
||||
int versionMinor = versionMap["minor"].asInteger();
|
||||
|
||||
|
||||
auto name = folder.filename().u8string();
|
||||
lua::pushstring(L, name);
|
||||
lua::setfield(L, "name");
|
||||
|
||||
auto assets = engine->getAssets();
|
||||
std::string icon = "world#" + name + ".icon";
|
||||
if (!AssetsLoader::loadExternalTexture(
|
||||
assets,
|
||||
icon,
|
||||
{worlds[i] / fs::path("icon.png"),
|
||||
worlds[i] / fs::path("preview.png")}
|
||||
)) {
|
||||
assets,
|
||||
icon,
|
||||
{worlds[i] / fs::path("icon.png"),
|
||||
worlds[i] / fs::path("preview.png")}
|
||||
)) {
|
||||
icon = "gui/no_world_icon";
|
||||
}
|
||||
lua::pushstring(L, icon);
|
||||
lua::setfield(L, "icon");
|
||||
|
||||
lua::pushvec2(L, {versionMajor, versionMinor});
|
||||
lua::setfield(L, "version");
|
||||
|
||||
lua::rawseti(L, i + 1);
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -68,7 +68,6 @@ void scripting::initialize(Engine* engine) {
|
||||
lua::initialize(*engine->getPaths());
|
||||
|
||||
load_script(fs::path("stdlib.lua"), true);
|
||||
load_script(fs::path("stdcmd.lua"), true);
|
||||
load_script(fs::path("classes.lua"), true);
|
||||
}
|
||||
|
||||
@@ -196,6 +195,7 @@ void scripting::on_content_load(Content* content) {
|
||||
lua::setfield(L, "properties");
|
||||
lua::pop(L);
|
||||
}
|
||||
load_script(fs::path("stdcmd.lua"), true);
|
||||
}
|
||||
|
||||
void scripting::on_world_load(LevelController* controller) {
|
||||
@@ -308,6 +308,32 @@ void scripting::on_block_placed(
|
||||
}
|
||||
}
|
||||
|
||||
void scripting::on_block_replaced(
|
||||
Player* player, const Block& block, const glm::ivec3& pos
|
||||
) {
|
||||
if (block.rt.funcsset.onreplaced) {
|
||||
std::string name = block.name + ".replaced";
|
||||
lua::emit_event(lua::get_main_state(), name, [pos, player](auto L) {
|
||||
lua::pushivec_stack(L, pos);
|
||||
lua::pushinteger(L, player ? player->getId() : -1);
|
||||
return 4;
|
||||
});
|
||||
}
|
||||
auto args = [&](lua::State* L) {
|
||||
lua::pushinteger(L, block.rt.id);
|
||||
lua::pushivec_stack(L, pos);
|
||||
lua::pushinteger(L, player ? player->getId() : -1);
|
||||
return 5;
|
||||
};
|
||||
for (auto& [packid, pack] : content->getPacks()) {
|
||||
if (pack->worldfuncsset.onblockreplaced) {
|
||||
lua::emit_event(
|
||||
lua::get_main_state(), packid + ":.blockreplaced", args
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scripting::on_block_broken(
|
||||
Player* player, const Block& block, const glm::ivec3& pos
|
||||
) {
|
||||
@@ -725,6 +751,8 @@ void scripting::load_content_script(
|
||||
register_event(env, "on_random_update", prefix + ".randupdate");
|
||||
funcsset.onbroken = register_event(env, "on_broken", prefix + ".broken");
|
||||
funcsset.onplaced = register_event(env, "on_placed", prefix + ".placed");
|
||||
funcsset.onreplaced =
|
||||
register_event(env, "on_replaced", prefix + ".replaced");
|
||||
funcsset.oninteract =
|
||||
register_event(env, "on_interact", prefix + ".interact");
|
||||
funcsset.onblockstick =
|
||||
@@ -776,6 +804,8 @@ void scripting::load_world_script(
|
||||
register_event(env, "on_block_placed", prefix + ":.blockplaced");
|
||||
funcsset.onblockbroken =
|
||||
register_event(env, "on_block_broken", prefix + ":.blockbroken");
|
||||
funcsset.onblockreplaced =
|
||||
register_event(env, "on_block_replaced", prefix + ":.blockreplaced");
|
||||
funcsset.onblockinteract =
|
||||
register_event(env, "on_block_interact", prefix + ":.blockinteract");
|
||||
funcsset.onplayertick =
|
||||
|
||||
@@ -71,6 +71,9 @@ namespace scripting {
|
||||
void on_block_placed(
|
||||
Player* player, const Block& block, const glm::ivec3& pos
|
||||
);
|
||||
void on_block_replaced(
|
||||
Player* player, const Block& block, const glm::ivec3& pos
|
||||
);
|
||||
void on_block_broken(
|
||||
Player* player, const Block& block, const glm::ivec3& pos
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user