SSEs will get deleted when deleted on the server, ortho model shading.

* register_on supports place & break, not after_* yet
* fixed a potential segfault loading an invalid mod
* added @aurailus:item_collection, converted `drop` params to `yields`
master
Nicole Collings 2020-02-28 13:03:19 -08:00
parent 3093d53ea2
commit c1dc594d54
35 changed files with 208 additions and 93 deletions

View File

@ -2,6 +2,7 @@
in vec4 colorData;
in vec3 colorBlend;
in float normalShading;
in float useTex;
out vec4 fragColor;
@ -10,17 +11,23 @@ uniform sampler2D tex;
uniform vec4 uClipBounds;
void main() {
// Overflow clipping
if (uClipBounds.z != 0 && uClipBounds.w != 0
&&(gl_FragCoord.x < uClipBounds.x || gl_FragCoord.y < uClipBounds.y
|| gl_FragCoord.x > uClipBounds.z || gl_FragCoord.y > uClipBounds.w)) discard;
vec4 color = vec4(1, 1, 1, 1);
if (useTex > 0.5) {
vec4 spec = texture(tex, colorData.xy) * vec4(colorBlend, colorData.w);
if (spec.a <= 0) discard;
fragColor = spec;
color = spec;
}
else {
if (colorData.a <= 0) discard;
fragColor = colorData * vec4(colorBlend, 1);
color = colorData * vec4(colorBlend, 1);
}
color *= vec4(vec3(normalShading), 1);
fragColor = color;
}

View File

@ -16,6 +16,7 @@ uniform mat4 uBones[MAX_BONES];
out vec4 colorData;
out vec3 colorBlend;
out float normalShading;
out float useTex;
void main() {
@ -28,7 +29,12 @@ void main() {
boneTransform = (boneTransform * totalWeight) + (mat4(1.0) * (1 - totalWeight));
// normal = transpose(inverse(mat3(model))) * (boneTransform * vec4(normalize(aNormal), 0.0)).xyz;
if (aNormal == vec3(0, 0, 0)) normalShading = 1;
else {
vec3 normal = normalize(transpose(inverse(mat3(model))) * (boneTransform * vec4(normalize(aNormal), 0.0)).xyz);
normalShading = 1 + (normal.x * -normal.z * 0.15) - (normal.y * 0.18);
}
gl_Position = ortho * model * boneTransform * vec4(aPos, 1);
colorData = aColorData;
colorBlend = aColorBlend;

View File

@ -71,7 +71,6 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
}
case PacketType::THIS_PLAYER_INFO: {
while (!d.atEnd()) {
switch (d.read<unsigned int>()) {
case static_cast<unsigned int>(NetPlayerField::ID): {
@ -92,10 +91,8 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
}
}
}
break;
}
case PacketType::PLAYER_INFO: {
unsigned int cid = d.read<unsigned int>();
if (this->cid == cid) break;
@ -118,29 +115,28 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
world->dimension.playerEntities.emplace_back(d.read<glm::vec3>(), cid, playerModel);
break;
}
case PacketType::ENTITY_INFO: {
world->dimension.handleServerEntity(*p);
world->dimension.serverEntityInfo(*p);
break;
}
case PacketType::ENTITY_REMOVED: {
world->dimension.serverEntityRemoved(d.read<unsigned int>());
break;
}
case PacketType::BLOCK_SET: {
auto pos = d.read<glm::ivec3>();
auto block = d.read<unsigned int>();
world->setBlock(pos, block);
break;
}
case PacketType::CHUNK: {
world->loadChunkPacket(std::move(p));
break;
}
case PacketType::SERVER_INFO: {
serverSideChunkGens = d.read<unsigned int>();
break;
}
case PacketType::INV_INVALID: {
std::string source = d.read<std::string>();
std::string list = d.read<std::string>();
@ -148,7 +144,6 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<Packet> p) {
std::cout << Log::err << "Invalid inventory " << source << ":" << list << " was requested by client." << Log::endl;
exit(1);
}
case PacketType::INVENTORY: {
onInvPacket(std::move(p));
break;

View File

@ -6,15 +6,26 @@
enum class Callback {
CONSTRUCT,
DESTRUCT,
AFTER_CONSTRUCT,
DESTRUCT,
AFTER_DESTRUCT,
PLACE,
PLACE_CLIENT,
AFTER_PLACE,
AFTER_PLACE_CLIENT,
BREAK,
BREAK_CLIENT,
INTERACT,
INTERACT_CLIENT,
HIT,
HIT_CLIENT
AFTER_BREAK,
AFTER_BREAK_CLIENT,
// INTERACT,
// INTERACT_CLIENT,
//
// HIT,
// HIT_CLIENT
};

View File

@ -7,9 +7,14 @@
namespace Api {
static void register_on_s(sol::state& lua, sol::table& core, ServerLuaParser& parser) {
core["registered_callbacks"] = lua.create_table();
core["registered_callbacks"]["player_join"] = lua.create_table();
core["registered_callbacks"]["player_connect"] = lua.create_table();
core["registered_callbacks"]["player_disconnect"] = lua.create_table();
core["registered_callbacks"]["new_player"] = lua.create_table();
core["registered_callbacks"]["player_join"] = lua.create_table();
core["registered_callbacks"]["player_leave"] = lua.create_table();
core["registered_callbacks"]["place"] = lua.create_table();
core["registered_callbacks"]["break"] = lua.create_table();
core["registered_callbacks"]["after_place"] = lua.create_table();
core["registered_callbacks"]["after_break"] = lua.create_table();
lua.script(R"(
zepha.register_on = function(event, callback)

View File

@ -38,7 +38,6 @@ namespace Api {
if (onDestruct) (*onDestruct)();
core["entities"][(*object)->id] = sol::nil;
// TODO: Tell the client when entities are deleted.
world.dimension.removeLuaEntity(*object);
});
}

View File

@ -147,10 +147,17 @@ sol::protected_function_result LocalLuaParser::errorCallback(lua_State*, sol::pr
sol::protected_function_result LocalLuaParser::runFileSandboxed(std::string file) {
size_t modname_length = file.find('/');
if (modname_length == std::string::npos) {
std::cout << Log::err << "Filestring \"" + file + "\" is invalid." << Log::endl;
return nullptr;
}
std::string modname = file.substr(0, modname_length);
for (const LuaMod& mod : handler.cGetMods()) {
if (strncmp(mod.config.name.c_str(), modname.c_str(), modname_length) == 0) {
if (modname == mod.config.name) {
for (const LuaModFile& f : mod.files) {
if (f.path == file) {

View File

@ -74,8 +74,9 @@ void ServerLuaParser::sendModsPacket(ENetPeer* peer) const {
void ServerLuaParser::playerConnected(std::shared_ptr<ServerClient> client) {
auto players = core.get<sol::table>("players");
players.add(ServerLuaPlayer(*client));
core["__builtin"]["trigger_event"]("new_player", players[players.size()]);
core["__builtin"]["trigger_event"]("player_join", players[players.size()]);
core["__builtin"]["trigger_event"]("player_connect", players[players.size()]);
}
void ServerLuaParser::playerDisconnected(std::shared_ptr<ServerClient> client) {
@ -125,7 +126,7 @@ void ServerLuaParser::loadApi(ServerGame &defs, ServerWorld &world) {
Api::remove_entity_s (lua, core, defs, world);
// Functions
Api::trigger_event(lua);
Api::trigger_event (lua);
Api::update_entities(lua);
// Create sandboxed runfile()
@ -177,10 +178,17 @@ sol::protected_function_result ServerLuaParser::errorCallback(lua_State*, sol::p
sol::protected_function_result ServerLuaParser::runFileSandboxed(const std::string& file) {
size_t modname_length = file.find('/');
if (modname_length == std::string::npos) {
std::cout << Log::err << "Filestring \"" + file + "\" is invalid." << Log::endl;
return nullptr;
}
std::string modname = file.substr(0, modname_length);
for (const LuaMod& mod : handler.cGetMods()) {
if (strncmp(mod.config.name.c_str(), modname.c_str(), modname_length) == 0) {
if (modname == mod.config.name) {
for (const LuaModFile& f : mod.files) {
if (f.path == file) {

View File

@ -242,6 +242,11 @@ namespace RegisterBlocks {
return {model, farModel};
}
static void addCallback(BlockDef* blockDef, sol::table& blockTable, const std::string& name, Callback enumType) {
auto cb = blockTable.get<sol::optional<sol::function>>(name);
if (cb) blockDef->callbacks.insert({enumType, *cb});
}
static void registerBlocks(sol::table source, sol::table blockModels, DefinitionAtlas& defs, TextureAtlas* atlas) {
// Parses through all of the zepha.registered_blocks and makes BlockDefs.
for (auto blockRef : source) {
@ -292,31 +297,25 @@ namespace RegisterBlocks {
if (atlas) blockDef->createModel();
// Bind Callbacks
auto on_place = blockTable.get<sol::optional<sol::function>>("on_place");
if (on_place) blockDef->callbacks.insert({Callback::PLACE, *on_place});
addCallback(blockDef, blockTable, "on_construct", Callback::CONSTRUCT);
addCallback(blockDef, blockTable, "after_construct", Callback::AFTER_CONSTRUCT);
auto on_place_client = blockTable.get<sol::optional<sol::function>>("on_place_client");
if (on_place_client) blockDef->callbacks.insert({Callback::PLACE_CLIENT, *on_place_client});
addCallback(blockDef, blockTable, "on_destruct", Callback::DESTRUCT);
addCallback(blockDef, blockTable, "after_destruct", Callback::AFTER_DESTRUCT);
auto on_break = blockTable.get<sol::optional<sol::function>>("on_break");
if (on_break) blockDef->callbacks.insert({Callback::BREAK, *on_break});
addCallback(blockDef, blockTable, "on_place", Callback::PLACE);
addCallback(blockDef, blockTable, "on_place_client", Callback::PLACE_CLIENT);
auto on_break_client = blockTable.get<sol::optional<sol::function>>("on_break_client");
if (on_break_client) blockDef->callbacks.insert({Callback::BREAK_CLIENT, *on_break_client});
addCallback(blockDef, blockTable, "after_place", Callback::AFTER_PLACE);
addCallback(blockDef, blockTable, "after_place_client", Callback::AFTER_PLACE_CLIENT);
auto on_construct = blockTable.get<sol::optional<sol::function>>("on_construct");
if (on_construct) blockDef->callbacks.insert({Callback::CONSTRUCT, *on_construct});
addCallback(blockDef, blockTable, "on_break", Callback::BREAK);
addCallback(blockDef, blockTable, "on_break_client", Callback::BREAK_CLIENT);
auto after_construct = blockTable.get<sol::optional<sol::function>>("after_construct");
if (after_construct) blockDef->callbacks.insert({Callback::AFTER_CONSTRUCT, *after_construct});
addCallback(blockDef, blockTable, "after_break", Callback::AFTER_BREAK);
addCallback(blockDef, blockTable, "after_break_client", Callback::AFTER_BREAK_CLIENT);
auto on_destruct = blockTable.get<sol::optional<sol::function>>("on_destruct");
if (on_destruct) blockDef->callbacks.insert({Callback::DESTRUCT, *on_destruct});
auto after_destruct = blockTable.get<sol::optional<sol::function>>("after_destruct");
if (after_destruct) blockDef->callbacks.insert({Callback::AFTER_DESTRUCT, *after_destruct});
// Add Block Definition to the Atlas
// Add Block Definition to the AtlasK
defs.registerDef(blockDef);
}
}

View File

@ -4,10 +4,11 @@
#include <thread>
#include "../util/Timer.h"
#include "Server.h"
#include "../util/Timer.h"
#include "../lua/api/class/ServerLuaPlayer.h"
Server::Server(unsigned short port, const std::string& subgame) :
port(port),
config(defs),
@ -125,19 +126,32 @@ void Server::handlePlayerPacket(ServerClient &client, Packet& p) {
unsigned int worldBlock = (block == DefinitionAtlas::AIR ? world.getBlock(pos) : 0);
if (block == DefinitionAtlas::AIR) {
auto def = defs.defs.blockFromId(worldBlock);
if (def.callbacks.count(Callback::BREAK))
def.callbacks[Callback::BREAK](defs.parser.vecToTable(pos), ServerLuaPlayer(client));
defs.parser.core["__builtin"]["trigger_event"]("break", defs.parser.vecToTable(pos), ServerLuaPlayer(client));
}
else {
auto def = defs.defs.blockFromId(block);
if (def.callbacks.count(Callback::PLACE))
def.callbacks[Callback::PLACE](defs.parser.vecToTable(pos), ServerLuaPlayer(client));
defs.parser.core["__builtin"]["trigger_event"]("place", defs.parser.vecToTable(pos), ServerLuaPlayer(client));
}
world.setBlock(pos, block);
if (block == DefinitionAtlas::AIR) {
auto def = defs.defs.blockFromId(worldBlock);
if (def.callbacks.count(Callback::BREAK)) {
def.callbacks[Callback::BREAK](defs.parser.vecToTable(pos));
}
if (def.callbacks.count(Callback::AFTER_BREAK))
def.callbacks[Callback::AFTER_BREAK](defs.parser.vecToTable(pos), ServerLuaPlayer(client));
defs.parser.core["__builtin"]["trigger_event"]("after_break", defs.parser.vecToTable(pos), ServerLuaPlayer(client));
}
else {
auto def = defs.defs.blockFromId(block);
if (def.callbacks.count(Callback::PLACE)) {
def.callbacks[Callback::PLACE](defs.parser.vecToTable(pos));
}
if (def.callbacks.count(Callback::AFTER_PLACE))
def.callbacks[Callback::AFTER_PLACE](defs.parser.vecToTable(pos), ServerLuaPlayer(client));
defs.parser.core["__builtin"]["trigger_event"]("after_place", defs.parser.vecToTable(pos), ServerLuaPlayer(client));
}
break;
}

View File

@ -103,6 +103,18 @@ void ServerWorld::update(double delta) {
}
}
}
for (unsigned int entity : dimension.getRemovedEntities()) {
Packet p = Serializer()
.append<unsigned int>(entity)
.packet(PacketType::ENTITY_REMOVED);
for (auto& client : clientList.clients) {
if (client->hasPlayer) p.sendTo(client->peer, PacketChannel::ENTITY);
}
}
dimension.clearRemovedEntities();
}
void ServerWorld::changedChunks(ServerClient& client) {

View File

@ -23,6 +23,7 @@ enum class PacketType {
CHUNK,
BLOCK_SET,
ENTITY_INFO,
ENTITY_REMOVED,
// Inventory
WATCH_INV,

View File

@ -158,7 +158,7 @@ void LocalDimension::removeLocalEntity(std::shared_ptr<LocalLuaEntity> &entity)
localEntityRefs.erase(entity->id);
}
void LocalDimension::handleServerEntity(const Packet& p) {
void LocalDimension::serverEntityInfo(const Packet& p) {
Deserializer d(p.data);
auto id = d.read<unsigned int>();
@ -196,6 +196,14 @@ void LocalDimension::handleServerEntity(const Packet& p) {
}
}
void LocalDimension::serverEntityRemoved(unsigned int id) {
if (!serverEntityRefs.count(id)) return;
auto refIter = serverEntityRefs.at(id);
serverEntities.erase(refIter);
serverEntityRefs.erase(id);
}
int LocalDimension::getMeshChunkCount() {
return static_cast<int>(renderElems.size());
}
@ -237,4 +245,4 @@ bool LocalDimension::getAdjacentExists(glm::vec3 pos, bool updateAdjacents) {
if (chunk == nullptr) return false;
if (updateAdjacents) attemptMeshChunk(chunk, false);
return true;
}
}

View File

@ -30,7 +30,8 @@ public:
void addLocalEntity(std::shared_ptr<LocalLuaEntity>& entity);
void removeLocalEntity(std::shared_ptr<LocalLuaEntity>& entity);
void handleServerEntity(const Packet& p);
void serverEntityInfo(const Packet& p);
void serverEntityRemoved(unsigned int id);
int renderChunks(Renderer &renderer);
void renderEntities(Renderer &renderer);

View File

@ -58,6 +58,8 @@ void ServerDimension::removeLuaEntity(std::shared_ptr<ServerLuaEntity> &entity)
if (!luaEntityRefs.count(entity->id)) return;
auto refIter = luaEntityRefs.at(entity->id);
removedEntities.push_back(entity->id);
luaEntities.erase(refIter);
luaEntityRefs.erase(entity->id);
}
@ -69,4 +71,12 @@ unsigned long long ServerDimension::getMapBlockIntegrity(glm::ivec3 mapBlock) {
std::list<std::shared_ptr<ServerLuaEntity>> &ServerDimension::getLuaEntities() {
return luaEntities;
}
}
const std::list<unsigned int> &ServerDimension::getRemovedEntities() const {
return removedEntities;
}
void ServerDimension::clearRemovedEntities() {
removedEntities.clear();
}

View File

@ -24,11 +24,14 @@ public:
unsigned long long getMapBlockIntegrity(glm::ivec3 mapBlock);
std::list<std::shared_ptr<ServerLuaEntity>>& getLuaEntities();
const std::list<unsigned int>& getRemovedEntities() const;
void clearRemovedEntities();
private:
typedef std::list<std::shared_ptr<ServerLuaEntity>>::iterator luaent_ref;
std::unordered_map<unsigned int, luaent_ref> luaEntityRefs {};
std::list<std::shared_ptr<ServerLuaEntity>> luaEntities {};
std::list<unsigned int> removedEntities {};
std::unordered_map<glm::ivec3, unsigned long long, Vec::ivec3> mapBlockIntegrity {};
};

View File

@ -0,0 +1,5 @@
{
"name": "@aurailus:item_collection",
"description": "A mod to enable collecting items from blocks when mined. Can be configured to use dropped items or just directly add to inventory.",
"version": "0.0.1"
}

View File

@ -1,13 +1,13 @@
fn collides(entity) {
local fn collides(entity) {
return zepha.get_block({
x = math.floor(entity.pos.x),
y = math.floor(entity.pos.y - 0.5),
z = math.floor(entity.pos.z)}) ~= "air"
}
zepha.register_entity("zeus:default:dropped_item", {
zepha.register_entity("@aurailus:item_collection:dropped_item", {
display = "gameobject",
display_object = "zeus:default:stone",
display_object = "invalid",
on_create = fn(self, static) {
static = static or {}
@ -88,10 +88,9 @@ zepha.register_entity("zeus:default:dropped_item", {
self.object.pos = vector.add(p.pos, v(0, 0.90, 0))
self.scooping = true
zepha.delay(() => {
zepha.remove_entity(self)
p:get_inventory():get_list("main"):add_stack({self.item, 1})
zepha.remove_entity(self)
}, 2/20)
}
}

View File

@ -0,0 +1,10 @@
return fn(pos) {
local def = zepha.registered_blocks[zepha.get_block(pos)]
if (def == nil) { return nil }
local yields = def.yields
if (type(yields) == "function") { yields = yields(pos) }
if (yields == nil or type(yields) ~= "string") { return nil }
return yields
}

View File

@ -0,0 +1,9 @@
runfile("@aurailus:item_collection/dropped_item")
local DROP_ENTITY = true
if (DROP_ENTITY) {
runfile("@aurailus:item_collection/mode/entity")
}
else {
runfile("@aurailus:item_collection/mode/direct")
}

View File

@ -0,0 +1,10 @@
local get_yield = runfile("@aurailus:item_collection/get_yield")
if (zepha.server) {
zepha.register_on("break", (pos, player) => {
local yields = get_yield(pos)
if (yields == nil) { return }
player.get_inventory():get_list("main"):add_stack({yields, 1})
})
}

View File

@ -0,0 +1,10 @@
local get_yield = runfile("@aurailus:item_collection/get_yield")
if (zepha.server) {
zepha.register_on("break", (pos) => {
local yields = get_yield(pos)
if (yields == nil) { return }
zepha.add_entity("@aurailus:item_collection:dropped_item", vector.add(pos, v(0.5)), { item = yields });
})
}

View File

@ -11,5 +11,5 @@ zepha.register_block("zeus:default:bush_stem", {
hand = 0.3,
axe = 0.1
},
drop = "zeus:default:wood"
yields = "zeus:materials:stick"
})

View File

@ -6,5 +6,5 @@ zepha.register_block("zeus:default:cobblestone", {
hand = 14,
pick = 3
},
drop = "zeus:default:cobblestone"
yields = "zeus:default:cobblestone"
})

View File

@ -7,5 +7,5 @@ zepha.register_block("zeus:default:dirt", {
shovel = 1,
pick = 2
},
drop = "zeus:materials:rock"
yields = "zeus:default:dirt"
})

View File

@ -17,11 +17,7 @@ zepha.register_block("zeus:default:grass", {
shovel = 1,
pick = 2
},
drop = "zeus:default:dirt",
on_break = fn(pos) {
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{item = zepha.registered_blocks["zeus:default:grass"].drop});
}
yields = "zeus:default:dirt"
})
zepha.register_block("zeus:default:grass_slab", {
@ -48,5 +44,5 @@ zepha.register_block("zeus:default:grass_slab", {
collision_box = {
{0, 0, 0, 1, 0.5, 1}
},
drop = "zeus:default:grass_slab"
yields = "zeus:default:grass_slab"
})

View File

@ -14,5 +14,5 @@ zepha.register_block("zeus:default:leaves", {
hand = 1,
axe = 0.2,
},
drop = "zeus:materials:stick"
yields = "zeus:materials:stick"
})

View File

@ -7,5 +7,5 @@ zepha.register_block("zeus:default:sand", {
shovel = 1,
pick = 2
},
drop = "zeus:default:sand"
yields = "zeus:default:sand"
})

View File

@ -1,4 +1,3 @@
zepha.register_block("zeus:default:sandstone", {
name = "Sandstone",
model = "base:block",
@ -7,5 +6,5 @@ zepha.register_block("zeus:default:sandstone", {
hand = 14,
pick = 3
},
drop = "zeus:default:sand"
yields = "zeus:default:sand"
})

View File

@ -6,5 +6,5 @@ zepha.register_block("zeus:default:stone", {
hand = 14,
pick = 3
},
drop = "zeus:default:cobblestone"
yields = "zeus:default:cobblestone"
})

View File

@ -13,6 +13,11 @@ for i = 1, 5, 1 {
},
toughness = {
hand = 0
},
yields = fn(pos) {
if (math.random() > 0.8) {
return "zeus:materials:plant_fibre"
}
}
})
}

View File

@ -10,5 +10,5 @@ zepha.register_block("zeus:default:wood", {
hand = 5,
axe = 3,
},
drop = "zeus:default:wood"
yields = "zeus:default:wood"
})

View File

@ -1,4 +1,3 @@
runfile(_PATH .. "dropped_item")
runfile(_PATH .. "rabbit")
runfile(_PATH .. "raven")
runfile(_PATH .. "bee")

View File

@ -11,8 +11,6 @@ local blockTypes = {
"zeus:default:dirt",
"zeus:default:grass",
"zeus:default:leaves",
"zeus:default:sand",
"zeus:default:sandstone",
"zeus:default:tallgrass_5"
}
@ -31,13 +29,4 @@ zepha.register_keybind("zeus:default:open_chat", {
description = "Open Chat",
default = zepha.keys.t,
on_press = () => { print "Opened chat!" }
})
##if (zepha.server) {
## zepha.delay(() => {
## foreach player in zepha.players {
## player:get_inventory():get_list("main"):add_stack({"zeus:default:dirt", 1})
## }
## return true
## }, 1/20)
##}
})

View File

@ -1,17 +1,15 @@
zepha.register_on("player_join", (p) => {
zepha.register_on("new_player", (p) => {
## Create the main inventory list
local inv = p:get_inventory()
local main = inv:add_list("main", 44, 11)
## Bind crafting
local craft_input = inv:add_list("craft", 4, 2)
local craft_output = inv:add_list("craft_result", 2, 2)
crafting.bind(craft_input, craft_output)
## Make hot wheel
local invs = {
inv:add_list("hot_wheel_1", 5, 5),
inv:add_list("hot_wheel_2", 5, 5),