Entity collision boxes, entity selecting, Target refactor.

master
Auri 2020-12-04 01:32:27 -08:00
parent a53f627acd
commit 29239b52f3
50 changed files with 527 additions and 335 deletions

View File

@ -97,7 +97,7 @@ void main() {
}
vec4 worldPos = model * pos;
worldPos.y -= pow(length(view * worldPos * 0.025) - 0, 2);
// worldPos.y -= pow(length(view * worldPos * 0.025) - 0, 2);
gl_Position = projection * view * worldPos;
fragPos = (view * worldPos).xyz;

View File

@ -104,22 +104,22 @@ void ClientNetworkInterpreter::receivedPacket(std::unique_ptr<PacketView> p) {
}
void ClientNetworkInterpreter::blockHit(const Target& target) {
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
Serializer().append<glm::ivec3>(target.data.block.pos).append(static_cast<unsigned short>(target.data.block.face))
.packet(Packet::Type::BLOCK_HIT).sendTo(connection.getPeer(), Packet::Channel::INTERACT);
}
void ClientNetworkInterpreter::blockPlace(const Target& target) {
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
Serializer().append<glm::ivec3>(target.data.block.pos).append(static_cast<unsigned short>(target.data.block.face))
.packet(Packet::Type::BLOCK_PLACE).sendTo(connection.getPeer(), Packet::Channel::INTERACT);
}
void ClientNetworkInterpreter::blockInteract(const Target& target) {
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
Serializer().append<glm::ivec3>(target.data.block.pos).append(static_cast<unsigned short>(target.data.block.face))
.packet(Packet::Type::BLOCK_INTERACT).sendTo(connection.getPeer(), Packet::Channel::INTERACT);
}
void ClientNetworkInterpreter::blockPlaceOrInteract(const Target& target) {
Serializer().append<glm::ivec3>(target.pos).append(static_cast<unsigned short>(target.face))
Serializer().append<glm::ivec3>(target.data.block.pos).append(static_cast<unsigned short>(target.data.block.face))
.packet(Packet::Type::BLOCK_PLACE_OR_INTERACT).sendTo(connection.getPeer(), Packet::Channel::INTERACT);
}

View File

@ -10,14 +10,14 @@
#include "client/graph/mesh/EntityVertex.h"
class WireframeEntity : public DrawableEntity {
public:
public:
WireframeEntity(SubgamePtr game, DimensionPtr dim, glm::vec3 color) :
DrawableEntity(game, dim, std::make_shared<Model>()), Entity(game, dim),
color(color) {};
void updateMesh(const std::vector<SelectionBox>& boxes, float width);
private:
private:
std::vector<EntityVertex> vertices{};
std::vector<unsigned int> indices{};

View File

@ -84,7 +84,6 @@ void DebugGui::update(std::shared_ptr<LocalPlayer> player, double fps, int /*chu
auto& onBiomeDef = game->getBiomes().biomeFromId(
world.l()->getActiveDimension()->getBiome(glm::floor(player->getPos())));
auto& targetedBlockDef = game->getDefs().blockFromId(world.l()->getActiveDimension()->getBlock(target.pos));
/* Top-right Graphs */ {
get<GuiLabelledGraph>("fpsGraph")->pushValue(static_cast<float>(fps));
@ -142,18 +141,27 @@ void DebugGui::update(std::shared_ptr<LocalPlayer> player, double fps, int /*chu
if (target.type == Target::Type::BLOCK) {
std::string face =
target.face == EVec::TOP ? "TOP" :
target.face == EVec::BOTTOM ? "BOTTOM" :
target.face == EVec::LEFT ? "LEFT" :
target.face == EVec::RIGHT ? "RIGHT" :
target.face == EVec::FRONT ? "FRONT" :
target.face == EVec::BACK ? "BACK" :
target.data.block.face == EVec::TOP ? "TOP" :
target.data.block.face == EVec::BOTTOM ? "BOTTOM" :
target.data.block.face == EVec::LEFT ? "LEFT" :
target.data.block.face == EVec::RIGHT ? "RIGHT" :
target.data.block.face == EVec::FRONT ? "FRONT" :
target.data.block.face == EVec::BACK ? "BACK" :
"NONE";
str << "Pointing At: " << targetedBlockDef.identifier << " [" << targetedBlockDef.index << "]" << std::endl;
str << "Pointed Position: " << vecToString(target.pos) << std::endl;
const auto& def = game->getDefs().blockFromId(world.l()->getActiveDimension()->getBlock(target.data.block.pos));
str << "Pointing At: " << def.identifier << " [" << def.index << "]" << std::endl;
str << "Pointed Position: " << vecToString(target.data.block.pos) << std::endl;
str << "Pointed Face: " << face << std::endl;
}
else if (target.type == Target::Type::ENTITY) {
const auto& entity = **world.l()->getActiveDimension().l()->getEntityById(target.data.entity.id).entity;
str << "Pointing At: " << (target.data.entity.id < 0 ? "Local" : "Server")
<< " Entity #" << std::fabs(target.data.entity.id) << std::endl;
str << "Pointed Position: " << floatVecToString(entity.getPos()) << std::endl;
}
else {
str << "No Target";
}
@ -162,10 +170,11 @@ void DebugGui::update(std::shared_ptr<LocalPlayer> player, double fps, int /*chu
}
/* Crosshair Text */ {
if (target.type == Target::Type::BLOCK)
get<GuiText>("crosshairText")->setText(targetedBlockDef.name + " (" +
targetedBlockDef.identifier + ") [" +
std::to_string(targetedBlockDef.index) + "]");
if (target.type == Target::Type::BLOCK) {
const auto& def = game->getDefs().blockFromId(world.l()->getActiveDimension()->getBlock(target.data.block.pos));
get<GuiText>("crosshairText")->setText(
def.name + " (" + def.identifier + ") [" + std::to_string(def.index) + "]");
}
else get<GuiText>("crosshairText")->setText("");
}
}

View File

@ -29,11 +29,9 @@ class SelectionBox {
this->b = b;
}
EVec intersects(glm::vec3 vec, glm::vec3 blockOffset) {
EVec intersects(glm::vec3 vec) {
const float THRESH = 0.02f;
vec -= blockOffset; //Normalize Vector Position
if (std::abs(vec.y - b.y) < THRESH && vec.x > a.x && vec.x < b.x && vec.z > a.z && vec.z < b.z)
return EVec::TOP;
if (std::abs(vec.y - a.y) < THRESH && vec.x > a.x && vec.x < b.x && vec.z > a.z && vec.z < b.z)

View File

@ -45,6 +45,19 @@ glm::vec3 Api::Usertype::Entity::get_visual_offset() {
return entity->getVisualOffset();
}
void Api::Usertype::Entity::set_collision_box(sol::table box) {
SelectionBox c(box[1], box[2]);
entity->setCollisionBox(c);
}
sol::object Api::Usertype::Entity::get_collision_box(sol::this_state s) {
auto c = entity->getCollisionBox();
sol::table table;
table[0] = c.a;
table[1] = c.b;
return sol::make_object(s, table);
}
void Api::Usertype::Entity::snap_pitch(float rot) {
entity->setRotateX(rot);
}
@ -123,6 +136,8 @@ void Api::Usertype::Entity::bind(State, sol::state& lua, sol::table& core) {
"snap_visual_offset", &Entity::snap_visual_offset,
"set_visual_offset", &Entity::set_visual_offset,
"get_visual_offset", &Entity::get_visual_offset,
"set_collision_box", &Entity::set_collision_box,
"get_collision_box", &Entity::get_collision_box,
"snap_pitch", &Entity::snap_pitch,
"set_pitch", &Entity::set_pitch,
"get_pitch", &Entity::get_pitch,
@ -141,6 +156,7 @@ void Api::Usertype::Entity::bind(State, sol::state& lua, sol::table& core) {
"id", sol::property(&Entity::get_id),
"pos", sol::property(&Entity::get_pos, &Entity::set_pos),
"visual_offset", sol::property(&Entity::get_visual_offset, &Entity::set_visual_offset),
"collision_box", sol::property(&Entity::get_collision_box, &Entity::set_collision_box),
"pitch", sol::property(&Entity::get_pitch, &Entity::set_pitch),
"yaw", sol::property(&Entity::get_yaw, &Entity::set_yaw),
"roll", sol::property(&Entity::get_roll, &Entity::set_roll),
@ -149,4 +165,4 @@ void Api::Usertype::Entity::bind(State, sol::state& lua, sol::table& core) {
"anims", sol::property(&Entity::get_animation_manager)
);
}
}

View File

@ -15,12 +15,10 @@
namespace Api::Usertype {
class Entity : public SubgameUsertype {
public:
public:
Entity(EntityPtr entity) : entity(entity), animation(entity.isL() ?
std::static_pointer_cast<AnimationManager>(
std::make_shared<LocalAnimationManager>(entity)) :
std::static_pointer_cast<AnimationManager>(
std::make_shared<ServerAnimationManager>(entity))) {}
std::static_pointer_cast<AnimationManager>(std::make_shared<LocalAnimationManager>(entity)) :
std::static_pointer_cast<AnimationManager>(std::make_shared<ServerAnimationManager>(entity))) {}
EntityPtr entity;
std::shared_ptr<AnimationManager> animation;
@ -41,6 +39,10 @@ namespace Api::Usertype {
glm::vec3 get_visual_offset();
void set_collision_box(sol::table box);
sol::object get_collision_box(sol::this_state s);
void snap_pitch(float rot);
void set_pitch(float rot);

View File

@ -7,7 +7,7 @@
#include "../Lua.h"
Api::Usertype::Target::Target(const ::Target& target) :
pos(target.pos),
pos(target.data.block.pos),
type(target.type),
dim(Dimension(target.dim)),
pos_above(target.getAbovePos()) {}

View File

@ -7,51 +7,28 @@
#include <memory>
class World;
class LocalWorld;
class ServerWorld;
class Player;
class LocalPlayer;
class ServerPlayer;
class LuaEntity;
class LocalLuaEntity;
class ServerLuaEntity;
class Subgame;
class LocalSubgame;
class ServerSubgame;
class Dimension;
class LocalDimension;
class ServerDimension;
class Inventory;
class LocalInventory;
class ServerInventory;
class InventoryList;
class LocalInventoryList;
class ServerInventoryList;
class InventoryRefs;
class LocalInventoryRefs;
class ServerInventoryRefs;
template<typename B, typename L, typename S>

View File

@ -6,9 +6,13 @@
#include "game/def/mesh/SelectionBox.h"
Target::Target(DimensionPtr dim, unsigned int id) :
type(Type::ENTITY), dim(dim), data({ .entity = { id }}) {}
Target::Target(DimensionPtr dim, glm::ivec3 pos, EVec face) :
type(Type::BLOCK), dim(dim), pos(pos), face(face) {}
type(Type::BLOCK), dim(dim), data({ .block = { pos, face }}) {}
glm::ivec3 Target::getAbovePos() const {
return glm::ivec3(pos) + SelectionBox::faceToOffset(face);
}
if (type != Type::BLOCK) throw std::runtime_error("Attempt to getAbovePos on non-block target.");
return glm::ivec3(data.block.pos) + SelectionBox::faceToOffset(data.block.face);
}

View File

@ -1,30 +1,70 @@
//
// Created by aurailus on 13/05/19.
//
#pragma once
#include "util/Vec.h"
#include "util/CovariantPtr.h"
/**
* An structure representing a targeted element,
* be it a block, entity, or nothing.
*/
class Target {
public:
enum class Type {
ENTITY, BLOCK, NOTHING
};
public:
/** A struct containing data for a targeted entity. */
struct EntityData { unsigned int id; };
/** A struct containing data for a targeted block & face. */
struct BlockData { glm::ivec3 pos; EVec face; };
/** A struct containing no data for targets pointing to nothing. */
struct NothingData {};
/** An enum of the potential types of things a Target can point to. */
enum class Type { ENTITY, BLOCK, NOTHING };
/** A union of potential data structs for the three target types. */
union TargetData { EntityData entity; BlockData block; NothingData _; };
/**
* Creates an empty target pointing at nothing.
*/
Target() = default;
/**
* Copy constructor - duplicates a target.
* @param o - The target to copy.
*/
Target(const Target& o) = default;
/**
* Creates a target pointing at an entity, with the ID and dimension specified.
* @param dim - The dimension of the entity.
* @param id - The ID of the entity.
*/
Target(DimensionPtr dim, unsigned int id);
/**
* Creates a target pointing at a specific face of a block, in the dimension specified.
* @param dim - The dimension of the entity.
* @param pos - The block position to target.
* @param face - The face of the block to target.
*/
Target(DimensionPtr dim, glm::ivec3 pos, EVec face);
/**
* For block targets, gets the position that is one unit away from the targeted face.
* @throws if the target type is not a block.
* @returns the position above the targeted face.
*/
glm::ivec3 getAbovePos() const;
public:
/** The current type of thing being targeted. */
Type type = Target::Type::NOTHING;
glm::vec3 pos{};
DimensionPtr dim;
EVec face = EVec::NONE;
/** Data for the current targeted thing. */
TargetData data = { ._ = {} };
/** The dimension in which the current targeted thing resides. */
DimensionPtr dim = nullptr;
};

View File

@ -45,6 +45,10 @@ class Deserializer {
size_t ind = 0;
private:
typedef union {
int ln;
char bytes[8];
} long_long_union;
typedef union {
int in;
char bytes[4];
@ -67,6 +71,21 @@ class Deserializer {
} float_union;
};
template<>
inline long long Deserializer::read<long long>() {
long_long_union cv;
cv.bytes[0] = data[ind];
cv.bytes[1] = data[ind + 1];
cv.bytes[2] = data[ind + 2];
cv.bytes[3] = data[ind + 3];
cv.bytes[4] = data[ind + 4];
cv.bytes[5] = data[ind + 5];
cv.bytes[6] = data[ind + 6];
cv.bytes[7] = data[ind + 7];
ind += 4;
return cv.ln;
}
template<>
inline int Deserializer::read<int>() {
int_union cv;

View File

@ -24,6 +24,7 @@ enum class NetField {
// Entities
DISPLAY,
VISUAL_OFF,
COLLISION_BOX,
ANIM_RANGE,
ANIM_STATE,

View File

@ -33,6 +33,10 @@ class Serializer {
};
private:
typedef union {
long long ln;
char bytes[8];
} long_long_union;
typedef union {
int in;
char bytes[4];
@ -55,6 +59,20 @@ class Serializer {
} float_union;
};
template<>
inline Serializer& Serializer::append<long long>(const long long& elem) {
long_long_union cv = { elem };
data += cv.bytes[0];
data += cv.bytes[1];
data += cv.bytes[2];
data += cv.bytes[3];
data += cv.bytes[4];
data += cv.bytes[5];
data += cv.bytes[6];
data += cv.bytes[7];
return *this;
}
template<>
inline Serializer& Serializer::append<int>(const int& elem) {
int_union cv = { elem };

View File

@ -35,11 +35,6 @@ bool Dimension::setBlock(glm::ivec3 pos, unsigned int block) {
return true;
}
unsigned int Dimension::nextEntityInd() {
auto _ = getWriteLock();
return entityInd++;
}
//std::unordered_set<glm::ivec3, Vec::ivec3> Dimension::calculateEdgeLight(glm::ivec3 mbPos) {
// bool ypos = mapBlockGenerated(mbPos + glm::ivec3 {0, 1, 0});
// bool yneg = mapBlockGenerated(mbPos + glm::ivec3 {0, -1, 0});

View File

@ -13,11 +13,10 @@
#include "DimensionBase.h"
class Target;
class Player;
class Dimension : public DimensionBase {
public:
public:
typedef std::unordered_set<glm::ivec3, Vec::ivec3> relitChunks;
Dimension(const Dimension& o) = delete;
@ -37,12 +36,12 @@ class Dimension : public DimensionBase {
virtual void blockInteract(const Target& target, PlayerPtr player) = 0;
unsigned int nextEntityInd();
virtual long long nextEntityInd() = 0;
// Calculate light propogation around MapBlock edges,
// Called after a new mapblock is inserted into the dimension.
// relitChunks calculateEdgeLight(glm::ivec3 mbPos);
protected:
protected:
// Lighting propagation.
@ -50,7 +49,7 @@ class Dimension : public DimensionBase {
virtual relitChunks propogateRemoveNodes();
private:
private:
// Other Lighting methods.
@ -88,6 +87,4 @@ class Dimension : public DimensionBase {
static constexpr unsigned char SUNLIGHT_CHANNEL = 3;
std::array<std::queue<LightAddNode>, 4> lightAddQueue;
std::array<std::queue<LightRemoveNode>, 4> lightRemoveQueue;
unsigned int entityInd = 0;
};

View File

@ -13,17 +13,11 @@
#include "util/CovariantPtr.h"
class World;
class Chunk;
class MapGen;
class Region;
class Subgame;
class MapBlock;
class DefinitionAtlas;
class DimensionBase : protected Lockable {

View File

@ -42,8 +42,7 @@ void LocalDimension::deactivate() {
void LocalDimension::update(double delta) {
finishMeshes();
for (auto& entity : localEntities) entity.entity.l()->update(delta);
for (auto& entity : serverEntities) entity.entity.l()->update(delta);
for (auto& entity : entities) entity.entity.l()->update(delta);
for (auto& entity : playerEntities) entity.update(delta);
auto clientMapBlock = Space::MapBlock::world::fromBlock(static_cast<LocalWorld&>(world).getPlayer()->getPos());
@ -168,69 +167,92 @@ void LocalDimension::removeMeshChunk(const glm::ivec3& pos) {
}
}
long long LocalDimension::nextEntityInd() {
auto _ = getWriteLock();
return entityInd--;
}
void LocalDimension::addLocalEntity(Api::Usertype::Entity entity) {
unsigned int id = entity.get_id();
localEntities.push_back(entity);
localEntityRefs.emplace(id, --localEntities.end());
entities.push_back(entity);
entityRefs.emplace(id, --entities.end());
}
void LocalDimension::removeLocalEntity(Api::Usertype::Entity entity) {
unsigned int id = entity.get_id();
if (!localEntityRefs.count(id)) return;
auto refIter = localEntityRefs.at(id);
if (!entityRefs.count(id)) return;
auto refIter = entityRefs.at(id);
localEntities.erase(refIter);
localEntityRefs.erase(id);
entities.erase(refIter);
entityRefs.erase(id);
}
void LocalDimension::serverEntitiesInfo(Deserializer& e) {
bool boolean;
unsigned int x, y;
std::string type, a, b;
e.read<unsigned int>();
while (!e.atEnd()) {
std::string dat = e.read<std::string>();
Deserializer d(dat);
unsigned int id = d.read<unsigned int>();
long long id = d.read<long long>();
std::shared_ptr<LocalLuaEntity> activeEntity;
if (serverEntityRefs.count(id)) activeEntity = serverEntityRefs.at(id)->entity.l();
if (entityRefs.count(id)) activeEntity = entityRefs.at(id)->entity.l();
else {
auto ent = std::make_shared<LocalLuaEntity>(game, world.getDimension(getInd()));
auto entity = Api::Usertype::Entity(ent);
ent->setId(id);
serverEntities.push_back(entity);
serverEntityRefs.emplace(id, --serverEntities.end());
entities.push_back(entity);
entityRefs.emplace(id, --entities.end());
activeEntity = ent;
}
while (!d.atEnd()) {
switch (d.readE<NetField>()) {
case NetField::DIM: activeEntity->setDim(world.getDimension(d.read<unsigned int>()));
default:
break;
case NetField::POS: activeEntity->setPos(d.read<glm::vec3>());
case NetField::DIM:
activeEntity->setDim(world.getDimension(d.read<unsigned int>()));
break;
case NetField::VEL: activeEntity->setVel(d.read<glm::vec3>());
case NetField::POS:
activeEntity->setPos(d.read<glm::vec3>());
break;
case NetField::ROT: activeEntity->setRot(d.read<glm::vec3>());
case NetField::VEL:
activeEntity->setVel(d.read<glm::vec3>());
break;
case NetField::SCALE: activeEntity->setScale(d.read<glm::vec3>());
case NetField::ROT:
activeEntity->setRot(d.read<glm::vec3>());
break;
case NetField::VISUAL_OFF: activeEntity->setVisualOffset(d.read<glm::vec3>());
case NetField::SCALE:
activeEntity->setScale(d.read<glm::vec3>());
break;
case NetField::ANIM_STATE: d.read(boolean);
activeEntity->animation.setPlaying(boolean);
case NetField::VISUAL_OFF:
activeEntity->setVisualOffset(d.read<glm::vec3>());
break;
case NetField::DISPLAY: d.read(type).read(a).read(b);
activeEntity->setAppearance(type, a, b);
break;
case NetField::ANIM_RANGE: d.read(x).read(y).read(boolean);
activeEntity->animation.setAnim(glm::ivec2{ x, y }, 10, boolean);
case NetField::COLLISION_BOX: {
glm::vec3 a = d.read<glm::vec3>();
glm::vec3 b = d.read<glm::vec3>();
activeEntity->setCollisionBox({ a, b });
break;
}
case NetField::ANIM_STATE: {
bool b = d.read<bool>();
activeEntity->animation.setPlaying(b);
break;
}
case NetField::DISPLAY: {
std::string type, a, b;
d.read(type).read(a).read(b);
activeEntity->setAppearance(type, a, b);
break;
}
case NetField::ANIM_RANGE: {
bool b;
unsigned int x, y;
d.read(x).read(y).read(b);
activeEntity->animation.setAnim(glm::ivec2 { x, y }, 10, b);
break;
}}
}
}
}
@ -239,13 +261,23 @@ void LocalDimension::serverEntitiesRemoved(Deserializer& d) {
d.read<unsigned int>();
while (!d.atEnd()) {
unsigned int id = d.read<unsigned int>();
if (!serverEntityRefs.count(id)) continue;
auto refIter = serverEntityRefs.at(id);
serverEntities.erase(refIter);
serverEntityRefs.erase(id);
if (!entityRefs.count(id)) continue;
auto refIter = entityRefs.at(id);
entities.erase(refIter);
entityRefs.erase(id);
}
}
std::vector<Api::Usertype::Entity> LocalDimension::getEntitiesInRadius(glm::vec3 pos, float radius) {
std::vector<Api::Usertype::Entity> found {};
for (auto& entity : entities) if (glm::distance(pos, entity.entity->getPos()) <= radius) found.push_back(entity);
return found;
}
Api::Usertype::Entity& LocalDimension::getEntityById(long long id) {
return *entityRefs.at(id);
}
int LocalDimension::renderChunks(Renderer& renderer) {
int count = 0;
for (auto& renderElement : renderElems) {
@ -259,8 +291,7 @@ int LocalDimension::renderChunks(Renderer& renderer) {
}
void LocalDimension::renderEntities(Renderer& renderer) {
for (auto& entity : localEntities) entity.entity.l()->draw(renderer);
for (auto& entity : serverEntities) entity.entity.l()->draw(renderer);
for (auto& entity : entities) entity.entity.l()->draw(renderer);
for (auto& entity : playerEntities) entity.draw(renderer);
}

View File

@ -23,7 +23,7 @@ class MeshGenStream;
class ChunkRenderElem;
class LocalDimension : public Dimension {
public:
public:
const static int MB_STORE_H = 6;
const static int MB_STORE_V = 4;
@ -50,6 +50,8 @@ class LocalDimension : public Dimension {
void removeMeshChunk(const glm::ivec3& pos);
virtual long long nextEntityInd() override;
void addLocalEntity(Api::Usertype::Entity entity);
void removeLocalEntity(Api::Usertype::Entity entity);
@ -58,6 +60,10 @@ class LocalDimension : public Dimension {
void serverEntitiesRemoved(Deserializer& d);
std::vector<Api::Usertype::Entity> getEntitiesInRadius(glm::vec3 pos, float radius);
Api::Usertype::Entity& getEntityById(long long id);
int renderChunks(Renderer& renderer);
void renderEntities(Renderer& renderer);
@ -67,12 +73,12 @@ class LocalDimension : public Dimension {
int lastMeshUpdates = 0;
std::vector<PlayerEntity> playerEntities;
protected:
protected:
std::unordered_set<glm::ivec3, Vec::ivec3> propogateAddNodes() override;
std::unordered_set<glm::ivec3, Vec::ivec3> propogateRemoveNodes() override;
private:
private:
typedef std::list<Api::Usertype::Entity>::iterator ent_ref;
typedef std::list<std::shared_ptr<ChunkRenderElem>>::iterator chunk_ref;
@ -84,13 +90,12 @@ class LocalDimension : public Dimension {
std::shared_ptr<MeshGenStream> meshGenStream;
std::unordered_map<unsigned int, ent_ref> localEntityRefs{};
std::list<Api::Usertype::Entity> localEntities{};
std::unordered_map<unsigned int, ent_ref> serverEntityRefs{};
std::list<Api::Usertype::Entity> serverEntities{};
std::unordered_map<long long, ent_ref> entityRefs {};
std::list<Api::Usertype::Entity> entities {};
std::unordered_map<glm::vec3, chunk_ref, Vec::vec3> renderRefs{};
std::list<std::shared_ptr<ChunkRenderElem>> renderElems{};
long long entityInd = -1;
};

View File

@ -91,6 +91,11 @@ void ServerDimension::setChunk(std::shared_ptr<Chunk> chunk) {
Dimension::setChunk(chunk);
}
long long ServerDimension::nextEntityInd() {
auto _ = getWriteLock();
return entityInd++;
};
void ServerDimension::addLuaEntity(Api::Usertype::Entity entity) {
unsigned int id = entity.get_id();
luaEntities.push_back(std::move(entity));

View File

@ -33,6 +33,8 @@ class ServerDimension : public Dimension {
virtual double blockHit(const Target& target, PlayerPtr player) override;
virtual long long nextEntityInd() override;
void addLuaEntity(Api::Usertype::Entity entity);
void removeLuaEntity(Api::Usertype::Entity entity);
@ -51,5 +53,6 @@ class ServerDimension : public Dimension {
std::list<unsigned int> removedEntities{};
const glm::ivec2 discardRange = { 20, 20 };
long long entityInd = 1;
};

View File

@ -2,13 +2,13 @@
// Created by aurailus on 25/11/18.
//
#include <memory>
#include <utility>
#include <glm/gtc/matrix_transform.hpp>
#include "DrawableEntity.h"
#include "client/graph/Model.h"
#include "AnimationSegment.h"
#include "client/graph/Renderer.h"

View File

@ -8,12 +8,15 @@
#include <memory>
#include <glm/mat4x4.hpp>
#include "client/graph/Model.h"
#include "Entity.h"
#include "client/graph/Drawable.h"
#include "client/graph/Model.h"
class WireframeEntity;
class DrawableEntity : virtual public Entity, public Drawable {
public:
public:
DrawableEntity(const DrawableEntity& o) = delete;
DrawableEntity() = default;
@ -61,7 +64,8 @@ class DrawableEntity : virtual public Entity, public Drawable {
~DrawableEntity() override;
DrawableEntity* parent = nullptr;
protected:
protected:
glm::mat4 getModelMatrix();
glm::mat4 getRotationMatrix();

View File

@ -4,94 +4,102 @@
#include "Entity.h"
unsigned int Entity::getId() {
long long Entity::getId() const {
return id;
}
void Entity::setId(unsigned int id) {
this->id = id;
void Entity::setId(long long newId) {
id = newId;
}
glm::vec3 Entity::getPos() {
glm::vec3 Entity::getPos() const {
return pos;
}
void Entity::setPos(glm::vec3 position) {
this->pos = position;
pos = position;
}
glm::vec3 Entity::getVel() {
glm::vec3 Entity::getVel() const {
return vel;
}
void Entity::setVel(glm::vec3 velocity) {
this->vel = velocity;
vel = velocity;
}
glm::vec3 Entity::getRot() {
glm::vec3 Entity::getRot() const {
return rot;
}
void Entity::setRot(glm::vec3 rot) {
this->rot = rot;
void Entity::setRot(glm::vec3 newRot) {
rot = newRot;
}
glm::vec3 Entity::getVisualOffset() {
glm::vec3 Entity::getVisualOffset() const {
return visualOff;
}
void Entity::setVisualOffset(glm::vec3 vs) {
this->visualOff = vs;
visualOff = vs;
}
float Entity::getRotateX() {
SelectionBox Entity::getCollisionBox() const {
return collision;
}
void Entity::setCollisionBox(const SelectionBox& box) {
collision = box;
}
float Entity::getRotateX() const {
return rot.x;
}
void Entity::setRotateX(float rotation) {
this->rot.x = rotation;
rot.x = rotation;
}
float Entity::getRotateY() {
float Entity::getRotateY() const {
return rot.y;
}
void Entity::setRotateY(float rotation) {
this->rot.y = rotation;
rot.y = rotation;
}
float Entity::getRotateZ() {
float Entity::getRotateZ() const {
return rot.z;
}
void Entity::setRotateZ(float rotation) {
this->rot.z = rotation;
rot.z = rotation;
}
glm::vec3 Entity::getScale() {
glm::vec3 Entity::getScale() const {
return scale;
}
void Entity::setScale(float scale) {
this->scale = glm::vec3(scale);
void Entity::setScale(float newScale) {
scale = glm::vec3(newScale);
}
void Entity::setScale(glm::vec3 scale) {
this->scale = scale;
void Entity::setScale(glm::vec3 newScale) {
scale = newScale;
}
DimensionPtr Entity::getDim() {
DimensionPtr Entity::getDim() const {
return dim;
}
void Entity::setDim(DimensionPtr dim) {
this->dim = dim;
void Entity::setDim(DimensionPtr newDim) {
dim = newDim;
}
SubgamePtr Entity::getGame() {
SubgamePtr Entity::getGame() const {
return game;
}
void Entity::update(double delta) {
animation.update(delta);
}
}

View File

@ -11,69 +11,74 @@
#include "game/def/mesh/SelectionBox.h"
class Entity {
public:
public:
Entity() = default;
Entity(SubgamePtr game, DimensionPtr dim) : game(game), dim(dim) {};
virtual void update(double delta);
virtual long long getId() const;
virtual glm::vec3 getPos();
virtual void setId(long long newId);
virtual glm::vec3 getPos() const;
virtual void setPos(glm::vec3 position);
virtual glm::vec3 getVel();
virtual glm::vec3 getVel() const;
virtual void setVel(glm::vec3 velocity);
virtual glm::vec3 getRot();
virtual glm::vec3 getRot() const;
virtual void setRot(glm::vec3 rot);
virtual void setRot(glm::vec3 newRot);
virtual glm::vec3 getVisualOffset();
virtual glm::vec3 getVisualOffset() const;
virtual void setVisualOffset(glm::vec3 vs);
virtual float getRotateX();
virtual SelectionBox getCollisionBox() const;
virtual void setCollisionBox(const SelectionBox& box);
virtual float getRotateX() const;
virtual void setRotateX(float rotation);
virtual float getRotateY();
virtual float getRotateY() const;
virtual void setRotateY(float rotation);
virtual float getRotateZ();
virtual float getRotateZ() const;
virtual void setRotateZ(float rotation);
virtual glm::vec3 getScale();
virtual glm::vec3 getScale() const;
virtual void setScale(float scale);
virtual void setScale(float newScale);
virtual void setScale(glm::vec3 scale);
virtual void setScale(glm::vec3 newScale);
virtual unsigned int getId();
virtual DimensionPtr getDim() const;
virtual void setId(unsigned int id);
virtual void setDim(DimensionPtr newDim);
virtual DimensionPtr getDim();
SubgamePtr getGame() const;
virtual void setDim(DimensionPtr dim);
virtual void update(double delta);
SubgamePtr getGame();
AnimationState animation {};
AnimationState animation{};
protected:
protected:
SubgamePtr game = nullptr;
DimensionPtr dim = nullptr;
unsigned int id = 0;
long long id = 0;
glm::vec3 pos{};
glm::vec3 vel{};
glm::vec3 rot{};
glm::vec3 visualOff{};
glm::vec3 scale{ 1, 1, 1 };
glm::vec3 pos {};
glm::vec3 vel {};
glm::vec3 rot {};
glm::vec3 visualOff {};
glm::vec3 scale { 1, 1, 1 };
SelectionBox collision;
SelectionBox collision { {}, {} };
};

View File

@ -7,6 +7,7 @@
#include "game/def/ItemDef.h"
#include "game/LocalSubgame.h"
#include "game/atlas/DefinitionAtlas.h"
#include "client/entity/WireframeEntity.h"
LocalLuaEntity::LocalLuaEntity(SubgamePtr game, DimensionPtr dim) :
LuaEntity(game, dim), DrawableEntity(game, dim), Entity(game, dim) {}

View File

@ -8,7 +8,7 @@
#include "DrawableEntity.h"
class LocalLuaEntity : public virtual DrawableEntity, public LuaEntity {
public:
public:
LocalLuaEntity(SubgamePtr game, DimensionPtr dim);
virtual void setAppearance(const std::string& dMode, const std::string& argA, const std::string& argB) override;

View File

@ -7,7 +7,7 @@
#include "Entity.h"
class LuaEntity : public virtual Entity {
public:
public:
LuaEntity(SubgamePtr game, DimensionPtr dim);
virtual void setAppearance(const std::string& dMode, const std::string& argA, const std::string& argB) = 0;

View File

@ -59,6 +59,11 @@ void ServerLuaEntity::setVisualOffset(glm::vec3 vs) {
dirtyFields.emplace(NetField::VISUAL_OFF);
}
void ServerLuaEntity::setCollisionBox(const SelectionBox& box) {
Entity::setCollisionBox(box);
dirtyFields.emplace(NetField::COLLISION_BOX);
}
void ServerLuaEntity::setAppearance(const std::string& dMode, const std::string& argA, const std::string& argB) {
this->dMode = dMode;
this->dArgA = argA;
@ -74,7 +79,7 @@ std::string ServerLuaEntity::serialize() {
if (dirtyFields.empty() && !fullSend) return {};
Serializer s;
s.append<unsigned int>(id);
s.append<long long>(id);
if (dirtyFields.count(NetField::DIM) || fullSend) s.appendE(NetField::DIM).append(dim->getInd());
if (dirtyFields.count(NetField::POS) || fullSend) s.appendE(NetField::POS).append(pos);
@ -82,14 +87,19 @@ std::string ServerLuaEntity::serialize() {
if (dirtyFields.count(NetField::SCALE) || fullSend) s.appendE(NetField::SCALE).append(scale);
if (dirtyFields.count(NetField::ROT) || fullSend) s.appendE(NetField::ROT).append(rot);
if (dirtyFields.count(NetField::VISUAL_OFF) || fullSend) s.appendE(NetField::VISUAL_OFF).append(visualOff);
if (dirtyFields.count(NetField::COLLISION_BOX) || fullSend)
s.appendE(NetField::COLLISION_BOX).append(collision.a).append(collision.b);
if (dirtyFields.count(NetField::ANIM_STATE) || fullSend)
s.appendE(NetField::ANIM_STATE).append<bool>(animation.isPlaying());
if (dirtyFields.count(NetField::DISPLAY) || fullSend)
s.appendE(NetField::DISPLAY).append(dMode).append(dArgA).append(dArgB);
if (dirtyFields.count(NetField::ANIM_RANGE) || fullSend)
s.appendE(NetField::ANIM_RANGE)
.append<unsigned int>(animation.getBounds().x).append<unsigned int>(animation.getBounds().y).append<bool>(
animation.isLooping());
s.appendE(NetField::ANIM_RANGE).append<unsigned int>(animation.getBounds().x)
.append<unsigned int>(animation.getBounds().y).append<bool>(animation.isLooping());
dirtyFields.clear();
fullSend = false;

View File

@ -40,6 +40,8 @@ class ServerLuaEntity : public LuaEntity {
virtual void setVisualOffset(glm::vec3 vs) override;
virtual void setCollisionBox(const SelectionBox& box) override;
void setAppearance(const std::string& dMode, const std::string& argA, const std::string& argB) override;
void dirtyField(NetField field);

View File

@ -14,7 +14,7 @@
class DefinitionAtlas;
class InventoryList {
public:
public:
// enum class Callback { ALLOW_TAKE, ALLOW_PUT, ON_TAKE, ON_PUT };
InventoryList(const InventoryList& o) = delete;
@ -61,7 +61,7 @@ class InventoryList {
SubgamePtr getGame();
protected:
protected:
SubgamePtr game;
std::string name, invName;

View File

@ -11,7 +11,7 @@
class ClientNetworkInterpreter;
class LocalInventoryList : public InventoryList {
public:
public:
LocalInventoryList(SubgamePtr game, const std::string& name,
const std::string& invName, unsigned short size, unsigned short width,
ClientNetworkInterpreter& net);
@ -26,7 +26,7 @@ class LocalInventoryList : public InventoryList {
bool persistant = false;
double decayTime = 0;
private:
private:
void manipulated() override;
ClientNetworkInterpreter& net;

View File

@ -164,16 +164,16 @@ Target& LocalPlayer::getTarget() {
// Draw Functions
//
void LocalPlayer::draw(Renderer& renderer) {
void LocalPlayer::draw(Renderer&) {
wireframe.draw(renderer);
handItemModel.draw(renderer);
}
void LocalPlayer::drawHud(Renderer& renderer) {
void LocalPlayer::drawHud(Renderer&) {
gameGui.drawHud(renderer);
}
void LocalPlayer::drawMenu(Renderer& renderer) {
void LocalPlayer::drawMenu(Renderer&) {
gameGui.drawMenu(renderer);
}
@ -308,9 +308,12 @@ void LocalPlayer::findPointedThing(Input& input) {
glm::ivec3 chunkPos = {};
std::shared_ptr<Chunk> chunk = nullptr;
for (Ray ray(*this); ray.getLength() < LOOK_DISTANCE; ray.step(LOOK_PRECISION)) {
Target newTarget {};
float maxDistance = LOOK_DISTANCE;
for (Ray ray(*this); ray.getLength() < maxDistance; ray.step(LOOK_PRECISION)) {
glm::vec3 rayEnd = ray.getEnd();
glm::ivec3 roundedPos = glm::floor(rayEnd);
glm::vec3 roundedPos = glm::floor(rayEnd);
glm::ivec3 currChunkPos = Space::Chunk::world::fromBlock(roundedPos);
if (currChunkPos != chunkPos || chunk == nullptr) {
@ -323,33 +326,56 @@ void LocalPlayer::findPointedThing(Input& input) {
auto& boxes = game->getDefs().blockFromId(blockID).sBoxes;
for (auto& sBox : boxes) {
auto face = sBox.intersects(rayEnd, roundedPos);
auto face = sBox.intersects(rayEnd - roundedPos);
if (face != EVec::NONE) {
target = Target(dim, roundedPos, face);
return;
newTarget = Target(dim, roundedPos, face);
maxDistance = ray.getLength();
break;
}
}
if (newTarget.type != Target::Type::NOTHING) break;
}
target = Target{};
auto entities = dim.l()->getEntitiesInRadius(pos, maxDistance + 1);
for (Ray ray(*this); ray.getLength() < maxDistance; ray.step(LOOK_PRECISION)) {
for (auto& entity : entities) {
auto face = entity.entity->getCollisionBox().intersects(ray.getEnd() - entity.entity->getPos());
if (face != EVec::NONE) {
newTarget = Target(dim, entity.entity->getId());
break;
}
}
if (newTarget.type == Target::Type::ENTITY) break;
}
target = newTarget;
}
void LocalPlayer::updateWireframe() {
if (!gameGui.isVisible()) {
wireframe.setVisible(false);
}
else if (target.type == Target::Type::BLOCK) {
auto& boxes = game->getDefs().blockFromId(dim->getBlock(target.pos)).sBoxes;
float distance = glm::distance(pos, target.pos + glm::vec3(0.5));
if (gameGui.isVisible() && target.type != Target::Type::NOTHING) {
std::vector<SelectionBox> boxes {};
glm::vec3 renderPos {};
if (target.type == Target::Type::BLOCK) {
boxes = game->getDefs().blockFromId(dim->getBlock(target.data.block.pos)).sBoxes;
renderPos = target.data.block.pos;
}
else {
const auto& entity = **dim.l()->getEntityById(target.data.entity.id).entity;
boxes.push_back(entity.getCollisionBox());
renderPos = entity.getPos();
}
float distance = glm::distance(pos, renderPos + glm::vec3(0.5));
wireframe.updateMesh(boxes, 0.002f + distance * 0.0014f);
wireframe.setPos(target.pos);
wireframe.setPos(renderPos);
wireframe.setVisible(true);
}
else {
wireframe.setVisible(false);
}
else wireframe.setVisible(false);
}
void LocalPlayer::interact(Input& input, double delta) {

View File

@ -7,6 +7,5 @@ runfile(_PATH .. "sand")
runfile(_PATH .. "sandstone")
runfile(_PATH .. "stone")
runfile(_PATH .. "tallgrass")
runfile(_PATH .. "water")
runfile(_PATH .. "wood")
runfile(_PATH .. "light")

View File

@ -40,93 +40,93 @@
-- })
-- end
zepha.register_block("zeus:default:light_blue", {
name = "Blue Light",
model = "base:block",
textures = {"zeus:default:light_blue"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_blue",
light_source = {0, 0, 31}
})
zepha.register_block("zeus:default:light_teal", {
name = "Teal Light",
model = "base:block",
textures = {"zeus:default:light_blue"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_teal",
light_source = {0, 31, 31}
})
zepha.register_block("zeus:default:light_green", {
name = "Green Light",
model = "base:block",
textures = {"zeus:default:light_green"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_green",
light_source = {0, 31, 0}
})
zepha.register_block("zeus:default:light_yellow", {
name = "Yellow Light",
model = "base:block",
textures = {"zeus:default:light_green"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_yellow",
light_source = {31, 31, 0}
})
zepha.register_block("zeus:default:light_orange", {
name = "Orange Light",
model = "base:block",
textures = {"zeus:default:light_red"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_orange",
light_source = {31, 16, 0}
})
zepha.register_block("zeus:default:light_red", {
name = "Red Light",
model = "base:block",
textures = {"zeus:default:light_red"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light_red",
light_source = {31, 0, 0}
})
zepha.register_block("zeus:default:light_purple", {
name = "Purple Light",
model = "base:block",
textures = {"zeus:default:light_red"},
toughness = {
hand = 3,
shovel = 1,
pick = 2
},
yields = "zeus:default:light",
light_source = {31, 0, 31}
})
--zepha.register_block("zeus:default:light_blue", {
-- name = "Blue Light",
-- model = "base:block",
-- textures = {"zeus:default:light_blue"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_blue",
-- light_source = {0, 0, 31}
--})
--
--zepha.register_block("zeus:default:light_teal", {
-- name = "Teal Light",
-- model = "base:block",
-- textures = {"zeus:default:light_blue"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_teal",
-- light_source = {0, 31, 31}
--})
--
--zepha.register_block("zeus:default:light_green", {
-- name = "Green Light",
-- model = "base:block",
-- textures = {"zeus:default:light_green"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_green",
-- light_source = {0, 31, 0}
--})
--
--zepha.register_block("zeus:default:light_yellow", {
-- name = "Yellow Light",
-- model = "base:block",
-- textures = {"zeus:default:light_green"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_yellow",
-- light_source = {31, 31, 0}
--})
--
--zepha.register_block("zeus:default:light_orange", {
-- name = "Orange Light",
-- model = "base:block",
-- textures = {"zeus:default:light_red"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_orange",
-- light_source = {31, 16, 0}
--})
--
--zepha.register_block("zeus:default:light_red", {
-- name = "Red Light",
-- model = "base:block",
-- textures = {"zeus:default:light_red"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light_red",
-- light_source = {31, 0, 0}
--})
--
--zepha.register_block("zeus:default:light_purple", {
-- name = "Purple Light",
-- model = "base:block",
-- textures = {"zeus:default:light_red"},
-- toughness = {
-- hand = 3,
-- shovel = 1,
-- pick = 2
-- },
-- yields = "zeus:default:light",
-- light_source = {31, 0, 31}
--})

View File

@ -1,5 +0,0 @@
zepha.register_block(":water", {
name = "Water",
model = "base:block",
textures = {"zeus:default:water"}
})

View File

@ -1,14 +1,15 @@
zepha.register_entity("zeus:default:bee", {
display = "model",
display_object = "zeus:default:bee",
display_texture = "zeus:default:bee_shiny",
display_texture = "zeus:default:bee",
on_create = function(self)
self.object.scale = 1/12
self.object.collision_box = { V { -3/16, 0/16, -3/16 }, V { 3/16, 4/16, 3/16 } }
self.object.anims:define({
fly = {1, 45}
})
self.object.anims:set_anim("fly"):play()
end,
on_update = function(self, delta)
@ -18,15 +19,17 @@ zepha.register_entity("zeus:default:bee", {
end
})
zepha.register_keybind("zeus:default:spawn_bee", {
description = "Spawn Bee",
default = zepha.keys.b,
on_press = function()
zepha.send_message("zeus:default:spawn", "bee");
end
})
zepha.bind("message", function(channel, message, player)
if channel ~= "zeus:default:spawn" then return end
player.dim:add_entity(player.pos + V(0, 1.7, 0), "zeus:default:bee")
end)
if zepha.server then
zepha.bind("message", function(channel, message, player)
if channel ~= "zeus:default:spawn" then return end
player.dim:add_entity(player.pos + V(0, 1.7, 0), "zeus:default:bee")
end)
else
zepha.register_keybind("zeus:default:spawn_bee", {
description = "Spawn Bee",
default = zepha.keys.b,
on_press = function()
zepha.send_message("zeus:default:spawn", "bee");
end
})
end

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 576 B

View File

@ -1,11 +1,12 @@
runfile(_PATH.."register_biomes")
runfile(_PATH .. 'keys')
runfile(_PATH .. 'register_biomes')
zepha.create_dimension("zeus:world:default", {
biomes = { "#natural", "#default" }
zepha.create_dimension('zeus:world:default', {
biomes = { '#natural', '#default' }
})
zepha.create_dimension("zeus:world:endless_desert", {
biomes = { "zeus:world:desert" }
zepha.create_dimension('zeus:world:endless_desert', {
biomes = { 'zeus:world:desert' }
})
zepha.set_default_dimension("zeus:world:default")
zepha.set_default_dimension('zeus:world:default')

View File

@ -0,0 +1,24 @@
zepha.register_item(':key_iron', {
name = 'Iron Key',
textures = { 'zeus:world:key_iron' }
})
zepha.register_item(':key_silver', {
name = 'Silver Key',
textures = { 'zeus:world:key_silver' }
})
zepha.register_item(':key_gold', {
name = 'Gold Key',
textures = { 'zeus:world:key_gold' }
})
if zepha.server then
zepha.bind("new_player", function(player)
local inv = player:get_inventory():get_list('main')
inv:add_stack({'zeus:world:key_iron', 8})
inv:add_stack({'zeus:world:key_silver', 4})
inv:add_stack({'zeus:world:key_gold', 2})
end)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B