Block collision boxes, Add Step-up functionality to Collidable

* Tweak player speed.
* Make Invalid display.
* Fix some mod bugs.
master
Nicole Collings 2019-12-09 21:19:02 -08:00
parent 4960942618
commit 851de85e70
43 changed files with 285 additions and 141 deletions

View File

@ -1,11 +1,13 @@
cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
set (CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set (PROJECT_NAME "Zepha")
set (MAIN_EXEC_NAME "Zepha")
set (TEST_EXEC_NAME "ZephaTest")
set(PROJECT_NAME "Zepha")
set(MAIN_EXEC_NAME "Zepha")
set(TEST_EXEC_NAME "ZephaTest")
project (${PROJECT_NAME})
project(${PROJECT_NAME})
find_path(GLEW_HEADERS GL/glew.h)
find_path(GLFW_HEADERS GLFW/glfw3.h)
@ -55,9 +57,9 @@ include_directories(
)
add_subdirectory (src)
add_executable (${MAIN_EXEC_NAME} src/Main.cpp)
target_link_libraries (${MAIN_EXEC_NAME} Zepha_Core)
add_subdirectory(src)
add_executable(${MAIN_EXEC_NAME} src/Main.cpp)
target_link_libraries(${MAIN_EXEC_NAME} Zepha_Core)
target_include_directories(${MAIN_EXEC_NAME} PRIVATE ${GLFW_HEADERS})
# Load Libraries

View File

@ -1,7 +1,7 @@
-- Register base models
runfile(_PATH .. "models/_index")
-- Load Libraries
runfile(_PATH .. "dump")
runfile(_PATH .. "math")
runfile(_PATH .. "vector")

View File

@ -3,8 +3,8 @@ zepha.register_biome("zeus:default:plains", {
humidity = 80/100,
roughness = 20/100,
blocks = {
top = "zeus:default:grass",
soil = "zeus:default:dirt",
top = "zeus:default:tallgrass_1",
soil = "zeus:default:grass",
rock = "zeus:default:stone"
},
biome_tint = "#aaed45"

View File

@ -13,7 +13,7 @@ zepha.register_block("zeus:default:bush_stem", {
},
drop = "zeus:default:wood",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:bush_stem"].drop});
end
})

View File

@ -8,7 +8,7 @@ zepha.register_block("zeus:default:cobblestone", {
},
drop = "zeus:default:cobblestone",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:cobblestone"].drop});
end
})

View File

@ -9,7 +9,7 @@ zepha.register_block("zeus:default:dirt", {
},
drop = "zeus:materials:rock",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:dirt"].drop});
end
})

View File

@ -20,7 +20,43 @@ zepha.register_block("zeus:default:grass", {
},
drop = "zeus:default:dirt",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:grass"].drop});
end
})
zepha.register_block("zeus:default:grass_slab", {
name = "Grass Slab",
model = "base:block_slab_foliage",
textures = {
"biometint(zeus:default:grass_top)",
"zeus:default:dirt",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_top)",
"biometint(zeus:default:grass_floating)",
},
culls = false,
-- lowdef_textures = {
-- "zeus:default:grass_top",
-- "zeus:default:dirt",
-- "zeus:default:grass_side_ld"
-- },
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
selection_box = {
{0, 0, 0, 1, 0.5, 1}
},
collision_box = {
{0, 0, 0, 1, 0.5, 1}
},
drop = "zeus:default:grass_slab",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:grass_slab"].drop});
end
})

View File

@ -16,7 +16,7 @@ zepha.register_block("zeus:default:leaves", {
},
drop = "zeus:materials:stick",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:leaves"].drop});
end
})

View File

@ -9,7 +9,7 @@ zepha.register_block("zeus:default:sand", {
},
drop = "zeus:default:sand",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:sand"].drop});
end
})

View File

@ -8,7 +8,7 @@ zepha.register_block("zeus:default:sandstone", {
},
drop = "zeus:default:sand",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:sandstone"].drop});
end
})

View File

@ -8,7 +8,7 @@ zepha.register_block("zeus:default:stone", {
},
drop = "zeus:default:cobblestone",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:stone"].drop});
end
})

View File

@ -5,7 +5,7 @@ for i=1,5,1 do
name = "Tall Grass",
model = "base:cross_plant",
textures = {
"zeus:default:tallgrass_" .. i,
"biometint(zeus:default:tallgrass_"..i..")",
},
lowdef_render = false,
selection_box = {

View File

@ -12,7 +12,7 @@ zepha.register_block("zeus:default:wood", {
},
drop = "zeus:default:wood",
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
zepha.add_entity("zeus:default:dropped_item", vector.add(pos, v(0.5)),
{object = zepha.registered_blocks["zeus:default:wood"].drop});
end
})

View File

@ -1 +1,2 @@
runfile(_PATH .. "dropped_item")
runfile(_PATH .. "dropped_item")
runfile(_PATH .. "test")

View File

@ -5,36 +5,6 @@ local function collides(entity)
z = math.floor(entity.pos.z)}) ~= "air"
end
zepha.register_entity("zeus:default:test", {
display = "model",
display_object = "zeus:default:player",
display_texture = "zeus:default:player",
on_create = function(self)
-- self.object:set_scale(1/4)
end,
on_update = function(self)
-- local pos = self.object.pos
-- pos.z = pos.z + 0.08
-- if pos.z > 13 then
-- pos.z = 0
-- end
-- self.object:int_pos(pos)
-- self.object.yaw = self.object.yaw + 1;
self.object:int_pos({
x = self.object.pos.x + 0.08 * math.sin(math.rad(self.object.yaw)),
y = self.object.pos.y,
z = self.object.pos.z + 0.08 * math.cos(math.rad(self.object.yaw))})
self.object:int_yaw(self.object.yaw + 2)
--
-- self.object:int_yaw(math.deg(math.atan2(zepha.player.pos.x - self.object.pos.x, zepha.player.pos.z - self.object.pos.z)) + 180)
end
})
if not zepha.is_server() then
zepha.add_entity("zeus:default:test", {x = 10, y = 35, z = 0})
end
zepha.register_entity("zeus:default:dropped_item", {
display = "gameobject",
display_object = "zeus:default:stone",

View File

@ -0,0 +1,31 @@
zepha.register_entity("zeus:default:test", {
display = "model",
display_object = "zeus:default:player",
display_texture = "zeus:default:player",
on_create = function(self)
-- self.object:set_scale(1/4)
end,
on_update = function(self)
-- local pos = self.object.pos
-- pos.z = pos.z + 0.08
-- if pos.z > 13 then
-- pos.z = 0
-- end
-- self.object:int_pos(pos)
-- self.object.yaw = self.object.yaw + 1;
self.object:int_pos({
x = self.object.pos.x + 0.08 * math.sin(math.rad(self.object.yaw)),
y = self.object.pos.y,
z = self.object.pos.z + 0.08 * math.cos(math.rad(self.object.yaw))})
self.object:int_yaw(self.object.yaw + 2)
--
-- self.object:int_yaw(math.deg(math.atan2(zepha.player.pos.x - self.object.pos.x, zepha.player.pos.z - self.object.pos.z)) + 180)
end
})
if not zepha.is_server() then
-- for i = 0, 500 do
zepha.add_entity("zeus:default:test", {x = 10, y = 35, z = 0})
-- end
end

View File

@ -5,6 +5,8 @@ runfile(_PATH .. "entity/_index")
runfile(_PATH .. "biomes/_index")
local blockTypes = {
"zeus:default:grass_slab",
"zeus:kinetic:axle_0",
"zeus:default:stone",
"zeus:default:wood",
"zeus:default:cobblestone",
@ -72,4 +74,4 @@ zepha.register_keybind("open_chat", {
on_press = function()
print "Opened chat!"
end
})
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 416 B

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 428 B

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 425 B

View File

@ -6,27 +6,30 @@ zepha.register_block('zeus:kinetic:axle_0', {
selection_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
collision_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
drop = "kinetic:axle_0",
on_place = function(pos)
for i = 0, 9 do
pos.x = pos.x + 1
zepha.set_block(pos, "kinetic:axle_0")
zepha.set_block(pos, "zeus:kinetic:axle_0")
end
end,
on_place_client = function(pos)
for i = 0, 9 do
pos.x = pos.x + 1
zepha.set_block(pos, "kinetic:axle_0")
zepha.set_block(pos, "zeus:kinetic:axle_0")
end
end,
on_construct = function(pos)
zepha.delay(function()
zepha.set_block(pos, "kinetic:axle_1")
zepha.set_block(pos, "zeus:kinetic:axle_1")
end, 4)
end,
on_break_client = function(pos)
zepha.add_entity("zeus:default:dropped_item", {x = pos.x + 0.5, y = pos.y + 0.5, z = pos.z + 0.5},
{object = zepha.registered_blocks["kinetic:axle_0"].drop});
{object = zepha.registered_blocks["zeus:kinetic:axle_0"].drop});
end
})
@ -38,9 +41,12 @@ zepha.register_block('zeus:kinetic:axle_1', {
selection_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
collision_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
on_construct = function(pos)
zepha.delay(function()
zepha.set_block(pos, "kinetic:axle_2")
zepha.set_block(pos, "zeus:kinetic:axle_2")
end, 4)
end
})
@ -53,9 +59,12 @@ zepha.register_block('zeus:kinetic:axle_2', {
selection_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
collision_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
on_construct = function(pos)
zepha.delay(function()
zepha.set_block(pos, "kinetic:axle_3")
zepha.set_block(pos, "zeus:kinetic:axle_3")
end, 4)
end
})
@ -68,9 +77,12 @@ zepha.register_block('zeus:kinetic:axle_3', {
selection_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
collision_box = {
{0, 6/16, 6/16, 1, 10/16, 10/16}
},
on_construct = function(pos)
zepha.delay(function()
zepha.set_block(pos, "kinetic:axle_0")
zepha.set_block(pos, "zeus:kinetic:axle_0")
end, 4)
end
})

View File

@ -4,18 +4,16 @@
#include "LocalDefinitionAtlas.h"
LocalDefinitionAtlas::LocalDefinitionAtlas() {
BlockModel nullModel;
nullModel.visible = false,
nullModel.culls = false;
LocalDefinitionAtlas::LocalDefinitionAtlas(TextureAtlas& atlas) {
//Invalid Node
BlockDef* invalid = new BlockDef("invalid", 0, "Invalid (you broke the game!)", nullModel, true, {});
BlockModel invalidModel = BlockModel::createCube({atlas.getTextureRef("_missing")});
BlockDef* invalid = new BlockDef("invalid", 0, "Invalid (you broke the game!)", invalidModel, true, {{}}, {{}});
defs.push_back(invalid);
defTable.insert({"invalid", 0});
//Air Node
BlockDef* air = new BlockDef("air", 0, "Air", nullModel, false, {});
BlockModel nullModel {};
BlockDef* air = new BlockDef("air", 0, "Air", nullModel, false, {}, {});
defs.push_back(air);
defTable.insert({"air", 1});
}

View File

@ -11,7 +11,7 @@
class LocalDefinitionAtlas : public DefinitionAtlas {
public:
LocalDefinitionAtlas();
LocalDefinitionAtlas(TextureAtlas& atlas);
void registerDef(ItemDef* def) override;
void setIdentifiers(std::vector<std::string>& identifiers);

View File

@ -11,7 +11,8 @@ LocalDefs::LocalDefs(const std::string& path) :
luaApi(),
biomes(),
tex_path(path),
textureAtlas(2048) {
textureAtlas(2048),
blockAtlas(textureAtlas) {
textureAtlas.loadDirectory(tex_path);
}

View File

@ -5,16 +5,15 @@
#include "ServerDefinitionAtlas.h"
ServerDefinitionAtlas::ServerDefinitionAtlas() {
BlockModel nullModel;
nullModel.visible = false,
nullModel.culls = false;
//Invalid Node
BlockDef* invalid = new BlockDef("invalid", INVALID, "Invalid (you broke the game!)", nullModel, true, {});
BlockModel invalidModel = BlockModel::createCube({});
BlockDef* invalid = new BlockDef("invalid", INVALID, "Invalid (you broke the game!)", invalidModel, true, {{}}, {{}});
registerDef(invalid);
//Air Node
BlockDef* air = new BlockDef("air", AIR, "Air", nullModel, false, {});
BlockModel nullModel {};
BlockDef* air = new BlockDef("air", AIR, "Air", nullModel, false, {}, {});
registerDef(air);
}

View File

@ -17,16 +17,16 @@ void BiomeAtlas::generateVoronoi() {
}
voronoi.setPoints(points);
voronoi.setColorValues({{0, 0, 0}, {0.5, 0.5, 0.5}, {1, 1, 1}, {0.7, 0.7, 0.7}, {0.3, 0.3, 0.3}, {0.15, 0.15, 0.15}});
voronoi.generateImage(0);
voronoi.generateImage(7);
voronoi.generateImage(15);
voronoi.generateImage(23);
voronoi.generateImage(31);
voronoi.generateImage(39);
voronoi.generateImage(47);
voronoi.generateImage(55);
voronoi.generateImage(63);
// voronoi.setColorValues({{0, 0, 0}, {0.5, 0.5, 0.5}, {1, 1, 1}, {0.7, 0.7, 0.7}, {0.3, 0.3, 0.3}, {0.15, 0.15, 0.15}});
// voronoi.generateImage(0);
// voronoi.generateImage(7);
// voronoi.generateImage(15);
// voronoi.generateImage(23);
// voronoi.generateImage(31);
// voronoi.generateImage(39);
// voronoi.generateImage(47);
// voronoi.generateImage(55);
// voronoi.generateImage(63);
}
BiomeDef& BiomeAtlas::getBiomeAt(float temperature, float humidity, float roughness) {

View File

@ -5,15 +5,16 @@
#include "BlockDef.h"
BlockDef::BlockDef(const std::string &identifier, const std::string& name, const BlockModel &model, bool solid, const std::vector<SelectionBox>& sBoxes) :
BlockDef(identifier, 0, name, model, solid, sBoxes) {}
BlockDef::BlockDef(const std::string &identifier, const std::string& name, const BlockModel &model, bool solid, const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes) :
BlockDef(identifier, 0, name, model, solid, sBoxes, cBoxes) {}
BlockDef::BlockDef(const std::string& identifier, unsigned int index, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes) :
BlockDef::BlockDef(const std::string& identifier, unsigned int index, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes) :
ItemDef {identifier, name, index, ItemDef::Type::BLOCK},
model(model),
culls(model.culls),
solid(solid),
sBoxes(sBoxes) {}
sBoxes(sBoxes),
cBoxes(cBoxes) {}
void BlockDef::createModel() {
uptr<EntityMesh> mesh = std::make_unique<EntityMesh>();

View File

@ -15,8 +15,8 @@
class BlockDef : public ItemDef {
public:
BlockDef() = default;
BlockDef(const std::string& identifier, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes);
BlockDef(const std::string& identifier, unsigned int index, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes);
BlockDef(const std::string& identifier, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes);
BlockDef(const std::string& identifier, unsigned int index, const std::string& name, const BlockModel& model, bool solid, const std::vector<SelectionBox>& sBoxes, const std::vector<SelectionBox>& cBoxes);
void createModel();
@ -25,6 +25,7 @@ public:
bool solid = false;
std::vector<SelectionBox> sBoxes;
std::vector<SelectionBox> cBoxes;
sptr<Model> entityModel = std::make_shared<Model>();
std::unordered_map<Callback, sol::function, Util::EnumClassHash> callbacks {};

View File

@ -12,15 +12,17 @@
#include <limits>
struct BlockModel {
std::array<std::vector<MeshPart>, 7> parts;
std::vector<std::pair<MeshMod, float>> meshMods;
std::set<std::shared_ptr<AtlasRef>> textureRefs;
std::array<std::vector<MeshPart>, 7> parts {};
std::vector<std::pair<MeshMod, float>> meshMods {};
std::set<std::shared_ptr<AtlasRef>> textureRefs {};
bool culls = false;
bool visible = false;
static BlockModel createCube(const std::vector<std::shared_ptr<AtlasRef>>& textureRefs) {
BlockModel blockModel;
blockModel.visible = true;
blockModel.culls = true;
std::vector<BlockModelVertex> vertices {};
std::vector<unsigned int> indices {};

View File

@ -4,11 +4,12 @@
#include "Collidable.h"
Collidable::Collidable(LocalWorld &world, const SelectionBox& collisionBox) :
Collidable::Collidable(LocalWorld &world, LocalDefs& defs, const SelectionBox& collisionBox) :
world(world),
defs(defs),
collisionBox(collisionBox) {}
void Collidable::moveCollide() {
void Collidable::moveCollide(float stepUpAmount) {
const static double increment = 0.05;
double moved = 0;
@ -19,8 +20,8 @@ void Collidable::moveCollide() {
glm::vec3 newPos = pos;
newPos.y += move * (vel.y < 0 ? -1 : 1);
if (!collidesAt(newPos))
pos = newPos;
if (!collidesAt(newPos)) pos = newPos;
else if (vel.y > 0) vel.y = 0;
}
moved = 0;
@ -31,8 +32,8 @@ void Collidable::moveCollide() {
glm::vec3 newPos = pos;
newPos.x += move * (vel.x < 0 ? -1 : 1);
if (!collidesAt(newPos))
pos = newPos;
if (!collidesAt(newPos, stepUpAmount)) pos = newPos;
else vel.x = 0;
}
moved = 0;
@ -43,32 +44,83 @@ void Collidable::moveCollide() {
glm::vec3 newPos = pos;
newPos.z += move * (vel.z < 0 ? -1 : 1);
if (!collidesAt(newPos)) pos = newPos;
if (!collidesAt(newPos, stepUpAmount)) pos = newPos;
else vel.z = 0;
}
}
bool Collidable::collidesAt(const glm::vec3 &pos) {
float xOffset = collisionBox.a.x;
while (true) {
float yOffset = collisionBox.a.y;
while (true) {
float zOffset = collisionBox.a.z;
while (true) {
if (world.solidAt(pos + glm::vec3 {xOffset, yOffset, zOffset})) return true;
bool Collidable::collidesAt(glm::vec3& pos, float stepUpMax) {
// Find the minimum vertical increase needed to step up
float stepUpAmount = 0;
if (stepUpMax > 0) {
SelectionBox collidableBox = {collisionBox.a + pos, collisionBox.b + pos};
glm::vec3 offset {};
if (zOffset == collisionBox.b.z) break;
zOffset = std::min(std::floor(zOffset + 1), collisionBox.b.z);
offset.x = collisionBox.a.x;
while (true) {
offset.y = collisionBox.a.y;
while (true) {
offset.z = collisionBox.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto &def = defs.defs().blockFromId(world.getBlock(offsetPos));
if (def.solid)
for (auto &cBox : def.cBoxes)
stepUpAmount = std::max(cBox.b.y + offsetPos.y - pos.y, stepUpAmount);
if (offset.z == collisionBox.b.z) break;
offset.z = std::min(std::floor(offset.z + 1), collisionBox.b.z);
}
if (offset.y == collisionBox.a.y + stepUpMax + 0.025f) break; // Hack for precision errors
offset.y = std::min(std::floor(offset.y + 1), collisionBox.a.y + stepUpMax + 0.025f);
}
if (yOffset == collisionBox.b.y) break;
yOffset = std::min(std::floor(yOffset + 1), collisionBox.b.y);
if (offset.x == collisionBox.b.x) break;
offset.x = std::min(std::floor(offset.x + 1), collisionBox.b.x);
}
if (xOffset == collisionBox.b.x) break;
xOffset = std::min(std::floor(xOffset + 1), collisionBox.b.x);
}
// Step up if possible, or return false
if (stepUpAmount > stepUpMax) return true;
if (stepUpAmount > 0) pos.y += stepUpAmount + 0.025; // Hack for precision errors
SelectionBox collidableBox = {collisionBox.a + pos, collisionBox.b + pos};
glm::vec3 offset {};
// Regular collision check
offset.x = collisionBox.a.x;
while (true) {
offset.y = collisionBox.a.y;
while (true) {
offset.z = collisionBox.a.z;
while (true) {
glm::vec3 offsetPos = glm::floor(pos + offset);
auto& def = defs.defs().blockFromId(world.getBlock(offsetPos));
if (def.solid) {
for (auto &cBox : def.cBoxes) {
SelectionBox blockBox = {cBox.a + offsetPos, cBox.b + offsetPos};
if ((blockBox.a.x <= collidableBox.b.x && blockBox.b.x >= collidableBox.a.x) &&
(blockBox.a.y <= collidableBox.b.y && blockBox.b.y >= collidableBox.a.y) &&
(blockBox.a.z <= collidableBox.b.z && blockBox.b.z >= collidableBox.a.z)) return true;
}
}
if (offset.z == collisionBox.b.z) break;
offset.z = std::min(std::floor(offset.z + 1), collisionBox.b.z);
}
if (offset.y == collisionBox.b.y) break;
offset.y = std::min(std::floor(offset.y + 1), collisionBox.b.y);
}
if (offset.x == collisionBox.b.x) break;
offset.x = std::min(std::floor(offset.x + 1), collisionBox.b.x);
}
return false;
}
bool Collidable::isOnGround() {
return collidesAt(glm::vec3(pos.x, pos.y - 0.05f, pos.z)) && vel.y <= 0;
glm::vec3 test = {pos.x, pos.y - 0.05f, pos.z};
return collidesAt(test) && vel.y <= 0;
}

View File

@ -8,16 +8,17 @@
class Collidable {
public:
Collidable(LocalWorld& world, const SelectionBox& collisionBox);
Collidable(LocalWorld& world, LocalDefs& defs, const SelectionBox& collisionBox);
void moveCollide();
void moveCollide(float stepUpAmount = 0);
bool isOnGround();
glm::vec3 pos {};
glm::vec3 vel {};
protected:
LocalWorld& world;
LocalDefs& defs;
SelectionBox collisionBox {};
private:
bool collidesAt(const glm::vec3& pos);
bool collidesAt(glm::vec3& pos, float stepUpMax = 0);
};

View File

@ -46,7 +46,7 @@ private:
glm::mat4 orthographicMatrix;
//Perspective Matrix Properties
float fov = 70.0f;
float fov = 80.0f;
float ratio;
float nearClip = 0.1f;
float farClip = 1000.0f;

View File

@ -6,7 +6,7 @@
#include "../../../util/Ray.h"
Player::Player(LocalWorld& world, LocalDefs& defs, Renderer& renderer) :
Collidable(world, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
Collidable(world, defs, {{-0.3, 0, -0.3}, {0.3, 1.8, 0.3}}),
defs(defs),
renderer(renderer),
@ -38,7 +38,7 @@ void Player::moveAndLook(InputManager &input, double delta, double deltaX, doubl
//Position movement
bool sprinting = input.isKeyDown(GLFW_KEY_LEFT_CONTROL);
double moveSpeed = BASE_MOVE_SPEED * delta * (sprinting ? 1.5 : 1);
double moveSpeed = BASE_MOVE_SPEED * delta * (sprinting ? 1.6 : 1);
float friction = 0.3f;
if (flying) {
@ -66,7 +66,7 @@ void Player::moveAndLook(InputManager &input, double delta, double deltaX, doubl
if (input.isKeyDown(GLFW_KEY_LEFT_SHIFT)) mod.y -= 1;
}
else {
if (!isOnGround()) vel.y = std::fmax(vel.y - 0.01, -3);
if (!isOnGround()) vel.y = std::fmax(vel.y - 0.0085, -3);
else if (vel.y < 0) vel.y = 0;
}
@ -82,7 +82,7 @@ void Player::moveAndLook(InputManager &input, double delta, double deltaX, doubl
vel.z = velFlat.z;
}
else {
//If flying factor in verticle mod values.
//If flying factor in vertical mod values.
vel = vel * (1.0f-friction) + mod * friction;
}
@ -98,7 +98,7 @@ void Player::moveAndLook(InputManager &input, double delta, double deltaX, doubl
pitch = std::fmin(std::fmax(pitch, -90), 90);
moveCollide();
moveCollide(isOnGround() ? 0.6 : vel.y <= 0 ? 0.1 : 0);
updateCamera();
}

View File

@ -23,8 +23,8 @@ public:
static constexpr float LOOK_DISTANCE = 6.5f;
static constexpr float LOOK_PRECISION = 0.01f;
static constexpr float EYE_HEIGHT = 1.65f;
static constexpr float BASE_MOVE_SPEED = 7.5f;
static constexpr float JUMP_VEL = 0.15f;
static constexpr float BASE_MOVE_SPEED = 4.3f;
static constexpr float JUMP_VEL = 0.14f;
static constexpr float BLOCK_DAMAGE = 0.36f;
static constexpr float BLOCK_INTERVAL = 0.02f;

View File

@ -125,6 +125,7 @@ void LocalLuaParser::update(double delta, bool* keys) {
manager.triggerKeybinds();
this->delta -= 0.05f;
}
manager.update(keys);
}

View File

@ -20,6 +20,7 @@ LocalRegisterBlocks::LocalRegisterBlocks(sol::table& core, LocalDefs &defs) {
auto modelStrOpt = blockTable.get<sol::optional<std::string>>("model");
auto texturesOpt = blockTable.get<sol::optional<sol::table>> ("textures");
auto selectionOpt = blockTable.get<sol::optional<sol::table>> ("selection_box");
auto collisionOpt = blockTable.get<sol::optional<sol::table>> ("collision_box");
auto ldTexturesOpt= blockTable.get<sol::optional<sol::table>> ("lowdef_textures");
if (!nameOpt) throw identifier + " is missing name property!";
@ -42,9 +43,19 @@ LocalRegisterBlocks::LocalRegisterBlocks(sol::table& core, LocalDefs &defs) {
sol::table s = pair.second;
sBoxes.push_back({{s[1], s[2], s[3]}, {s[4], s[5], s[6]}});
}
} else {
sBoxes.push_back({{0, 0, 0}, {1, 1, 1}});
}
else sBoxes.push_back({{0, 0, 0}, {1, 1, 1}});
//Create a vector of collision boxes
std::vector<SelectionBox> cBoxes;
if (collisionOpt) {
for (auto pair : *collisionOpt) {
sol::table s = pair.second;
cBoxes.push_back({{s[1], s[2], s[3]}, {s[4], s[5], s[6]}});
}
}
else cBoxes.push_back({{0, 0, 0}, {1, 1, 1}});
//Create a block model from the above properties
sol::table model = *modelOpt;
@ -205,14 +216,21 @@ LocalRegisterBlocks::LocalRegisterBlocks(sol::table& core, LocalDefs &defs) {
std::vector<std::shared_ptr<AtlasRef>> refs;
for (auto i = 0; i < lowdef_textures.size(); i++) {
refs.push_back(defs.textures().getTextureRef(lowdef_textures[i]));
//TODO: More robust solution needed.
std::string texture = lowdef_textures[i];
bool biometint = false;
if (strncmp(texture.data(), "biometint(", 10) == 0) {
biometint = true;
texture = texture.substr(10, texture.length() - 11);
}
refs.push_back(defs.textures().getTextureRef(texture));
}
BlockModel lowdefBlockModel = BlockModel::createCube(refs);
lowdefBlockModel.culls = ldRender;
lowdefBlockModel.visible = ldRender;
BlockDef* blockDef = new BlockDef(identifier, defs.defs().size(), *nameOpt, blockModel, solid, std::move(sBoxes));
BlockDef* blockDef = new BlockDef(identifier, defs.defs().size(), *nameOpt, blockModel, solid, std::move(sBoxes), std::move(cBoxes));
blockDef->createModel();
//Bind Callbacks

View File

@ -53,7 +53,6 @@ ServerRegisterBiomes::ServerRegisterBiomes(sol::table& core, ServerDefs &defs) {
//Add Biome Definition to the Gen
defs.gen().registerBiome(biomeDef);
std::cout << "Registering " << biomeDef->index << ": " << biomeDef->identifier << std::endl;
}
defs.gen().generateVoronoi();

View File

@ -191,7 +191,7 @@ ServerRegisterBlocks::ServerRegisterBlocks(sol::table& core, ServerDefs &defs) {
lowdefBlockModel.culls = ldRender;
lowdefBlockModel.visible = ldRender;
BlockDef* blockDef = new BlockDef(identifier, defs.defs().size(), *nameOpt, lowdefBlockModel, solid, std::move(sBoxes));
BlockDef* blockDef = new BlockDef(identifier, defs.defs().size(), *nameOpt, lowdefBlockModel, solid, std::move(sBoxes), {});
//Bind Callbacks
auto on_place = blockTable.get<sol::optional<sol::function>>("on_place");

View File

@ -5,12 +5,9 @@
#include <algorithm>
#include <glm/glm.hpp>
#include "ServerWorld.h"
#include "../../util/net/PacketChannel.h"
#include "../../util/Timer.h"
#include "../../util/Util.h"
const static int MB_GEN_H = 3;
const static int MB_GEN_V = 3;
const static int MB_GEN_H = 2;
const static int MB_GEN_V = 2;
ServerWorld::ServerWorld(unsigned int seed, ServerDefs& defs, ServerClients& clients) :
seed(seed),
@ -145,18 +142,37 @@ void ServerWorld::sendChunk(const glm::vec3& pos, ServerClient &peer) {
}
void ServerWorld::sendMapBlock(const glm::vec3& pos, ServerClient &peer) {
//TODO: Make this a real function that sends an entire mapblock packet
unsigned long long mapBlockIntegrity = dimension.getMapBlockIntegrity(pos);
if (peer.getPlayer().getMapBlockIntegrity(pos) < mapBlockIntegrity) {
auto mapBlock = dimension.getMapBlock(pos);
assert(mapBlock != nullptr);
for (unsigned short i = 0; i < 63; i++) {
for (unsigned short i = 0; i < 64; i++) {
sendChunk((*mapBlock)[i], peer);
}
}
}
//void ServerWorld::sendMapBlock(const glm::vec3& pos, ServerClient &peer) {
// unsigned long long mapBlockIntegrity = dimension.getMapBlockIntegrity(pos);
// if (peer.getPlayer().getMapBlockIntegrity(pos) < mapBlockIntegrity) {
// Packet r(PacketType::MAPBLOCK);
//
// auto mapBlock = dimension.getMapBlock(pos);
// assert(mapBlock != nullptr);
//
// for (unsigned short i = 0; i < 64; i++) {
// auto chunk = (*mapBlock)[i];
// auto serialized = chunk->serialize();
//
// Serializer::encodeIntVec3(r.data, chunk->pos);
// Serializer::encodeString(r.data, serialized);
// }
//
// r.sendTo(peer.getPeer(), PacketChannel::CHUNK);
// }
//}
void ServerWorld::setBlock(glm::vec3 pos, unsigned int block) {
auto oldBlock = getBlock(pos);

View File

@ -21,6 +21,7 @@ enum class PacketType {
//Ingame Data Types
PLAYER,
CHUNK,
MAPBLOCK,
ENTITY_INFO,
SERVER_INFO,
BLOCK_SET,

View File

@ -20,7 +20,7 @@ BlockChunk::BlockChunk(const std::array<unsigned int, 4096>& blocks, const std::
pos(pos) {
for (unsigned int block : this->blocks) {
if (block > DefinitionAtlas::AIR) {
if (block != DefinitionAtlas::AIR) {
empty = false;
fullBlocks++;
}
@ -193,7 +193,7 @@ void BlockChunk::mgRegenEmpty() {
empty = true;
for (unsigned int block : this->blocks) {
if (block > DefinitionAtlas::AIR) {
if (block != DefinitionAtlas::AIR) {
empty = false;
fullBlocks++;
}