Fix round-down division bug causing issues with block position

This fixes rendering issues with weird transparent blocks.
Also deletes underscore pointer manager, replacing it with
std::unique_ptr.
master
Dorian Wouters 2015-08-24 18:42:54 +02:00
parent ad6aed5179
commit 47ecebae40
16 changed files with 126 additions and 190 deletions

View File

@ -3,7 +3,7 @@
2. Backward compatibility is for the weak 2. Backward compatibility is for the weak
(i.e. If mod shit breaks, that's none of the engine developers' problems.) (i.e. If mod shit breaks, that's none of the engine developers' problems.)
- There's a sight chance it breaks - There's a sight chance it breaks
- I can break - It can break
- Expect it to break - Expect it to break
- It will likely break - It will likely break
- It WILL break - It WILL break

View File

@ -29,8 +29,8 @@ void main(void) {
#endif #endif
vec3 coord = coord.xyz; vec3 coord = coord.xyz;
#ifdef WAVE #ifdef WAVE
if (wave != 0) { if (wave != 0.0) {
float yShift = sin(time+(coord.x+coord.z)/16.0*6*PI)*wave - wave; float yShift = sin(time+(coord.x+coord.z)/16.0*6.0*PI)*wave - wave;
coord.y += yShift; coord.y += yShift;
//v_texcoord.y -= yShift/8.0; //v_texcoord.y -= yShift/8.0;
} }

View File

@ -1,10 +1,10 @@
Diggler save/network format spec Hexedryne save/network format spec
[TOC] [TOC]
## Binary format details # Binary format details
### Numbers ## Numbers
Number types are denoted by the following table: Number types are denoted by the following table:
Symbol | C(++) type Symbol | C(++) type
------------|-------------- ------------|--------------
@ -20,7 +20,7 @@ Symbol | C(++) type
`d` | `double` (64-bit) `d` | `double` (64-bit)
All specified formats are little-endian, and floats/doubles are IEEE 754. All specified formats are little-endian, and floats/doubles are IEEE 754.
### Varints ## Varints
(`u`)`varint`s are variable-length integers, stored in a big-endian fashion, each byte's most significant bit indicating continuation, and the actual binary data in the lower 7 bits. (`u`)`varint`s are variable-length integers, stored in a big-endian fashion, each byte's most significant bit indicating continuation, and the actual binary data in the lower 7 bits.
`uvarint`s are, are their name implies, unsigned. Their signed counterpart (`varint`s) are encoded using a zigzag encoding, that is, `n` is encoded as `(n << 1) ^ (n >> B-1)` where `B` is the original integer's bit length. `uvarint`s are, are their name implies, unsigned. Their signed counterpart (`varint`s) are encoded using a zigzag encoding, that is, `n` is encoded as `(n << 1) ^ (n >> B-1)` where `B` is the original integer's bit length.
Their max bit length are specified by a suffix, e.g. `varint64` -- note therefore (`u`)`varint8` would be pointless. Their max bit length are specified by a suffix, e.g. `varint64` -- note therefore (`u`)`varint8` would be pointless.
@ -33,11 +33,11 @@ Their names are shortened to, respectively
They come from [Google's Protobuf](https://developers.google.com/protocol-buffers/docs/encoding) library. They come from [Google's Protobuf](https://developers.google.com/protocol-buffers/docs/encoding) library.
### Vectors ## Vectors
Vectors can be of dimensions 2 to 4. They are simply stored member-by-member, in `<x><y>[z][w]` order, with the type determined by the prefix. Vectors can be of dimensions 2 to 4. They are simply stored member-by-member, in `<x><y>[z][w]` order, with the type determined by the prefix.
E.g. `fvec3` is a 3-dimensional vector stored as 3 consecutive 32-bit IEEE754 floating-point numbers. E.g. `fvec3` is a 3-dimensional vector stored as 3 consecutive 32-bit IEEE754 floating-point numbers.
### Strings ## Strings
Strings are arrays of arbitrary binary data -- usually text, in which case the UTF-8 enoding is used. Strings are arrays of arbitrary binary data -- usually text, in which case the UTF-8 enoding is used.
* `string` = `uv32 length; byte data[length];` * `string` = `uv32 length; byte data[length];`
@ -45,36 +45,30 @@ Strings are arrays of arbitrary binary data -- usually text, in which case the U
* `mstring` (medium string) = `u16 length; byte data[length];` * `mstring` (medium string) = `u16 length; byte data[length];`
* `lstring` (long string) = `u32 length; byte data[length];` * `lstring` (long string) = `u32 length; byte data[length];`
### Arrays ## Arrays
Arrays are sequences of tightly-packed data of an unique type. Arrays are sequences of tightly-packed data of an unique type.
#### Static arrays Their length as well as their type can be either hard-coded or determined from another variable.
Their length is either hard-coded or determined from another variable, and their type is fixed and must be known in advance. They are denoted by:
They are denoted by *`type`*`[SIZE]`, e.g. `int[42]`.
* *`type`*`[SIZE]`, e.g. `int[42]`
* *`type name`*`[SIZE]` when named
#### Variable arrays
```
u8 type;
v32 length;
@type data[length];
```
Where `type` is the `TypeID` (see below) of the data elements. Where `type` is the `TypeID` (see below) of the data elements.
Denoted by *`type`*`[]`, e.g. `byte[]`. Can be nested, too, i.e. it is possible to have *`type`*`[][]`. ## Datrees
### Datrees
Datrees (*Data Trees*) are key/value maps able to hold a variety of data types bound to a `string` key. Datrees (*Data Trees*) are key/value maps able to hold a variety of data types bound to a `string` key.
``` ```
v64 nElements; uv32 entryCount;
nElements times { struct DatreeEntry {
string key; string key;
TypeID type; TypeID type;
@type data; @type data;
} } entries[entryCount];
``` ```
Type is represented by `datree`, and a hint about a sole data type is given by writing `datree<type>` (this does not, however, replace each entry's `type` field, and any badly-formatted data encountered should be discarded/ignored). Type is represented by `datree`, and a hint about a sole data type is given by writing `datree<type>` (this does not, however, replace each entry's `type` field, and any badly-formatted data encountered should be discarded/ignored).
### TypeIDs ## TypeIDs
A `TypeID` is a `uv16` defining a type, of all presented above. It is made of two parts (bitwise diagram): A `TypeID` is a `uv16` defining a type, of all presented above. It is made of two parts (bitwise diagram):
``` ```
15 14 7 6 0 15 14 7 6 0
@ -113,8 +107,8 @@ XType | Modifier
3 | `vec3` 3 | `vec3`
4 | `vec4` 4 | `vec4`
### Other ID/status tables ## Other ID/status tables
#### Compression ### Compression
ID | Compression algorithm ID | Compression algorithm
---|---------------------- ---|----------------------
0 | None 0 | None
@ -125,7 +119,7 @@ ID | Compression algorithm
*: Unimplemented *: Unimplemented
°: Have a dictionary that can be relocated/shared °: Have a dictionary that can be relocated/shared
#### Chunk status ### Chunk status
ID | Status ID | Status
---|------- ---|-------
0 | Unemerged 0 | Unemerged
@ -135,6 +129,8 @@ ID | Status
4 | Emerged, modified by non-player action (mobs, map update...) 4 | Emerged, modified by non-player action (mobs, map update...)
5 | Emerged, modified by player action 5 | Emerged, modified by player action
# Save files # Save files
## Overall structure ## Overall structure
Universes are stored in folders containing the worlds it is made of as well as other (meta)data files. Universes are stored in folders containing the worlds it is made of as well as other (meta)data files.
@ -142,13 +138,13 @@ Universes are stored in folders containing the worlds it is made of as well as o
### Header ### Header
Type | Name | Value Type | Name | Value
---------:|:------|----------------- ---------:|:------|-----------------
`byte[8]` | `HDs` | `\x01\xD1GLRusv` `byte[8]` | `HDs` | `\x01HX\xEDNusv`
`u32` | `Hui` | Universe ID `u32` | `Hui` | Universe ID
`u8` | `Hst` | Save file type `u8` | `Hst` | Save file type
`u64` | `HTs` | [UNIX Timestamp](https://en.wikipedia.org/wiki/Unix_time) of last edit `u64` | `HTs` | [UNIX Timestamp](https://en.wikipedia.org/wiki/Unix_time) of last edit
`uv32` | `Hfv` | Save format version `u32` | `Hfv` | Save format version
`v` | `Hfl` | Flags `v` | `Hfl` | Flags
`u8` | `HDc` | XOR checksum of previous bytes `u8` | `HDc` | XOR checksum of previous bytes, `0xAA` as starting byte
`u8` | `HDe` | `\x02` `u8` | `HDe` | `\x02`
### Footer ### Footer
@ -156,7 +152,7 @@ Type | Name | Value
Type | Name | Value Type | Name | Value
---------:|:------|----------------- ---------:|:------|-----------------
`uint64` | `Fcs` | 64-bit FastHash checksum of all previous bytes `uint64` | `Fcs` | 64-bit FastHash checksum of all previous bytes
`byte[8]` | `FTs` | `eu\xD1GLR\x04\x1C` `byte[8]` | `FTs` | `euHX\xEDN\x04\x1C`
## Save file types ## Save file types
### Universe Root (`Hst = 0x00`) ### Universe Root (`Hst = 0x00`)
@ -177,7 +173,7 @@ uint16 areasIDs[];
``` ```
### World Area (`Hst = 0x02`) ### World Area (`Hst = 0x02`)
An Area equates to 8×8×8 = 512 Chunks, themselves storing 16×16×16 blocks each, resulting in a maximum of 2 097 152 blocks stored, 8 MB of raw data if no extra buffers are added. An Area equates to 8×8×8 = 512 Chunks, themselves storing 16×16×16 blocks each, resulting in a maximum of 2 097 152 blocks stored, 8 MB of (uncompressed) raw data if no extra buffers are added.
#### Chunk #### Chunk
```c++ ```c++
@ -190,20 +186,22 @@ struct Chunk {
compressed using @compID { compressed using @compID {
uint16 ids[16*16*16]; // Block IDs uint16 ids[16*16*16]; // Block IDs
uint16 data[16*16*16]; // Block data uint16 data[16*16*16]; // Block data
datree<?[16*16*16]> extraBuffers; datree<?[16*16*16]> buffers; // See Bufferspecs section
datree metadata[]; uint16 metadataCount;
datree metadata[metadataCount];
} }
} }
// Entity data // Entity data
uv32 entityCount;
struct Entity { struct Entity {
uint64 id; uint64 id;
fvec3 position; // Relative to the current Chunk's origin fvec3 position; // Relative to the current Chunk's origin
fvec3 velocity; fvec3 velocity;
datree properties; datree properties;
} entities[]; } entities[entityCount];
}; };
``` ```
Block IDs are indexed in the flat array by `index = x + y*16 + z*16*16`. Block IDs and data are indexed in the flat array by `index = x + y*16 + z*16*16`.
Block data (let's call it `bdata`) matching the bitmask `0x8000`indicate a metadata pointer -- that is, said block has a metadata Datree stored in `metadata` at index `bdata & 0x7FFFF`. This Datree can contain arbitrarily-defined data (as mods please) about the block. It has a special entry called `__data` containing the block's actual `bdata` if it wasn't a metadata pointer and isn't zero, and is the value returned by functions getting the block's data. Block data (let's call it `bdata`) matching the bitmask `0x8000`indicate a metadata pointer -- that is, said block has a metadata Datree stored in `metadata` at index `bdata & 0x7FFFF`. This Datree can contain arbitrarily-defined data (as mods please) about the block. It has a special entry called `__data` containing the block's actual `bdata` if it wasn't a metadata pointer and isn't zero, and is the value returned by functions getting the block's data.
@ -234,3 +232,17 @@ Registered by mods upon their load. Like block names, they are prefixed with the
* TBD (2nd light computation) * TBD (2nd light computation)
* `equilibrium` * `equilibrium`
* Params TBD (conductivity, ...) * Params TBD (conductivity, ...)
# Network
## Messages
All network communication in Diggler is done via sequential messages, delivered by the [ENet library](http://enet.bespin.org) on multiple ENet channels.
### Message channels
Channel | Usage
--------|------
0 | Base
1 | Chat
2 | Life (player/entity spawn/death)
3 | Movement (player/entity movement)
4 | Metadata (Universe/World/entity metadata transfer)
5 | ChunkTransfer
6 | ChunkUpdate

View File

@ -1,4 +1,4 @@
local D = require('Diggler') local H = require('hexedryne')
local TestMod = { local TestMod = {
id = "TestMod", id = "TestMod",
@ -6,18 +6,24 @@ local TestMod = {
version = 1, version = 1,
versionStr = "1.0.0", versionStr = "1.0.0",
description = "A mod to test Lua scripting ability", description = "A mod to test Lua scripting ability",
tags = {"test"},
authors = {"gravgun"}, authors = {"gravgun"},
license = "GPLv3", license = "GPLv3",
deps = {}, deps = {},
optdeps = {}, optdeps = {},
clientside = true, clientside = true,
serverside = true serverside = true,
providesInterfaces = {
"diggler.isBlockUseless",
}
} }
function TestMod.init() function TestMod.init()
print("Hey i'm " .. CurrentMod.id) print("Hey i'm " .. CurrentMod.id)
D.registerBlock('test', { H.registerBlock('test', {
dispname = 'block.test.name', dispname = 'block.test.name',
sandboxTab = 'blocks', sandboxTab = 'blocks',
harvest = { pickaxe = 0, shovel = 10000 }, harvest = { pickaxe = 0, shovel = 10000 },
@ -30,6 +36,6 @@ function TestMod.deinit()
print("Bye") print("Bye")
end end
print(D.mods) print(H.mods)
return TestMod return TestMod

View File

@ -1,16 +1,16 @@
require('io') require('io')
local Diggler = { local hexedryne = {
mods = {}, mods = {},
exportedFuncs = {} exportedFuncs = {}
} }
function Diggler.export(name, func) function hexedryne.export(name, func)
Diggler.exportedFuncs[name] = func hexedryne.exportedFuncs[name] = func
end end
package.loaded['Diggler'] = Diggler package.loaded['hexedryne'] = hexedryne
local function setoverlay(tab, orig) local function setoverlay(tab, orig)
local mt = getmetatable(tab) or {} local mt = getmetatable(tab) or {}
@ -24,7 +24,7 @@ local function setoverlay(tab, orig)
setmetatable(tab, mt) setmetatable(tab, mt)
end end
Diggler.MODSTATUS = { hexedryne.MODSTATUS = {
UNAVAILABLE = 0, UNAVAILABLE = 0,
DISABLED = 1, DISABLED = 1,
ERRORED = 2, ERRORED = 2,
@ -34,9 +34,9 @@ Diggler.MODSTATUS = {
UNLOADED = 100 UNLOADED = 100
} }
function Diggler.loadModLua(path) function hexedryne.loadModLua(path)
local digglerOverlay = {} local digglerOverlay = {}
local packageOverlay = { ['path'] = path .. '/?.lua;' .. package.path, ['loaded'] = packageLoadedOverlay } local packageOverlay = { ['path'] = path .. '/?.lua;' .. package.path }
setoverlay(packageOverlay, package) setoverlay(packageOverlay, package)
local env = { local env = {
['package'] = packageOverlay, ['package'] = packageOverlay,
@ -44,7 +44,7 @@ function Diggler.loadModLua(path)
print("<init>", ...) print("<init>", ...)
end, end,
['require'] = function (module) ['require'] = function (module)
if module == 'Diggler' then if module == 'hexedryne' then
return digglerOverlay return digglerOverlay
end end
return require(module) return require(module)
@ -70,7 +70,7 @@ function Diggler.loadModLua(path)
env.print = function (...) env.print = function (...)
print(env.CurrentMod.id..":", ...) print(env.CurrentMod.id..":", ...)
end end
for name, func in pairs(Diggler.exportedFuncs) do for name, func in pairs(hexedryne.exportedFuncs) do
digglerOverlay[name] = function (...) digglerOverlay[name] = function (...)
func(env.CurrentMod, ...) func(env.CurrentMod, ...)
end end
@ -82,14 +82,14 @@ function Diggler.loadModLua(path)
return r1, r2 return r1, r2
end end
function Diggler.loadMod(path) function hexedryne.loadMod(path)
local mod, err = Diggler.loadModLua(path) local mod, err = hexedryne.loadModLua(path)
if mod then if mod then
if Diggler.mods[mod.id] then if hexedryne.mods[mod.id] then
error("Mod already loaded") error("Mod already loaded")
end end
mod.status = Diggler.MODSTATUS.LOADED mod.status = hexedryne.MODSTATUS.LOADED
Diggler.mods[mod.id] = mod hexedryne.mods[mod.id] = mod
print("Loaded mod '" .. mod.name .. "' <" .. mod.id .. "> v" .. mod.versionStr .. " (" .. mod.version .. ")") print("Loaded mod '" .. mod.name .. "' <" .. mod.id .. "> v" .. mod.versionStr .. " (" .. mod.version .. ")")
return mod return mod
else else
@ -98,21 +98,20 @@ function Diggler.loadMod(path)
return nil return nil
end end
function Diggler.initMod(id) function hexedryne.initMod(mod)
local mod = Diggler.mods[id]
mod.init() mod.init()
mod.status = Diggler.MODSTATUS.INITIALIZED mod.status = hexedryne.MODSTATUS.INITIALIZED
end end
function Diggler.getMod(mod, id) function hexedryne.getMod(mod, id)
return Diggler.mods[id] return hexedryne.mods[id]
end end
Diggler.export("getMod", Diggler.getMod) hexedryne.export("getMod", hexedryne.getMod)
function Diggler.registerBlock(mod, name, block) function hexedryne.registerBlock(mod, name, block)
print("Calling registerBlock from mod " .. (mod and mod.id or "<none>")) print("Calling registerBlock from mod " .. (mod and mod.id or "<none>"))
end end
Diggler.export("registerBlock", Diggler.registerBlock) hexedryne.export("registerBlock", hexedryne.registerBlock)
Diggler.loadMod('TestMod') local m = hexedryne.loadMod('TestMod')
Diggler.initMod('TestMod') hexedryne.initMod(m)

View File

@ -227,16 +227,12 @@ void CaveGenerator::Generate(WorldRef wr, const GenConf &gc, ChunkRef cr) {
c.setBlock(x, y, 0, Content::BlockUnknownId); c.setBlock(x, y, 0, Content::BlockUnknownId);
c.setBlock(x, y, CZ-1, Content::BlockUnknownId); c.setBlock(x, y, CZ-1, Content::BlockUnknownId);
}*/ }*/
/*glm::ivec3 cp = c.getWorldChunkPos() * glm::ivec3(CX, CY, CZ);
glm::ivec3 cp = c.getWorldChunkPos() * glm::ivec3(CX, CY, CZ);
for (int y = 0; y < CY; ++y) for (int y = 0; y < CY; ++y)
for (int x = 0; x < CX; ++x) for (int x = 0; x < CX; ++x)
for (int z = 0; z < CZ; ++z) for (int z = 0; z < CZ; ++z)
c.setBlock(x, y, z, stb_perlin_noise3((cp.x + x)/8.f, (cp.y + y)/8.f, (cp.z + z)/8.f) > 0 ? Content::BlockUnknownId : Content::BlockAirId); c.setBlock(x, y, z, stb_perlin_noise3((cp.x + x)/8.f, (cp.y + y)/8.f, (cp.z + z)/8.f) > 0 ? Content::BlockUnknownId : Content::BlockAirId);
*/
for (int y = 0; y < CY; ++y)
for (int x = 0; x < CX; ++x)
for (int z = 0; z < CZ; ++z)
c.setBlock(x, y, z, !(x==0||x==15||y==0||y==15||z==0||z==15) ? Content::BlockUnknownId : Content::BlockAirId);
#if 0 #if 0
if (gc.ore.enabled) if (gc.ore.enabled)

View File

@ -16,7 +16,7 @@
#define CXY (CX*CY) #define CXY (CX*CY)
#define I(x,y,z) (x+y*CX+z*CXY) #define I(x,y,z) (x+y*CX+z*CXY)
#define SHOW_CHUNK_UPDATES 0 #define SHOW_CHUNK_UPDATES 1
namespace Diggler { namespace Diggler {
@ -73,8 +73,9 @@ void Chunk::ChangeHelper::discard(){
} }
Chunk::Chunk(Game *G, WorldRef W, int X, int Y, int Z) : scx(X), scy(Y), scz(Z), Chunk::Chunk(Game *G, WorldRef W, int X, int Y, int Z) : scx(X), scy(Y), scz(Z),
data(nullptr), data2(nullptr), G(G), W(W), vbo(nullptr), CH(*this), G(G), W(W), vbo(nullptr), data(nullptr), data2(nullptr),
state(State::Unavailable) { state(State::Unavailable),
CH(*this) {
dirty = true; dirty = true;
data = new Data; data = new Data;
data->clear(); data->clear();
@ -319,9 +320,9 @@ void Chunk::updateClient() {
BlockId bt, bu /*BlockUp*/, bn /*BlockNear*/; BlockId bt, bu /*BlockUp*/, bn /*BlockNear*/;
bool mayDisp; bool mayDisp;
const AtlasCreator::Coord *tc; const AtlasCreator::Coord *tc;
for(uint8 x = 0; x < CX; x++) { for(int8 x = 0; x < CX; x++) {
for(uint8 y = 0; y < CY; y++) { for(int8 y = 0; y < CY; y++) {
for(uint8 z = 0; z < CZ; z++) { for(int8 z = 0; z < CZ; z++) {
bt = data->id[I(x,y,z)]; bt = data->id[I(x,y,z)];
// Empty block? // Empty block?
@ -482,7 +483,7 @@ void Chunk::updateClient() {
void Chunk::render(const glm::mat4& transform) { void Chunk::render(const glm::mat4& transform) {
#if SHOW_CHUNK_UPDATES #if SHOW_CHUNK_UPDATES
glUniform4f(R.uni_unicolor, 1.f, changed ? 0.f : 1.f, changed ? 0.f : 1.f, 1.f); glUniform4f(R.uni_unicolor, 1.f, dirty ? 0.f : 1.f, dirty ? 0.f : 1.f, 1.f);
#endif #endif
if (dirty) if (dirty)
updateClient(); updateClient();

View File

@ -236,6 +236,11 @@ void GameState::onKey(int key, int scancode, int action, int mods) {
G->U->getWorld(0)->onRenderPropertiesChanged(); G->U->getWorld(0)->onRenderPropertiesChanged();
} }
break; break;
case GLFW_KEY_F8:
if (action == GLFW_PRESS) {
G->U->getWorld(0)->refresh();
}
break;
default: default:
break; break;
} }
@ -771,7 +776,10 @@ void GameState::updateUI() {
"vy: " << LP.velocity.y << std::endl << "vy: " << LP.velocity.y << std::endl <<
"rx: " << LP.angle << std::endl << "rx: " << LP.angle << std::endl <<
// TODO reintroduce "chunk tris: " << lastVertCount / 3 << std::endl << // TODO reintroduce "chunk tris: " << lastVertCount / 3 << std::endl <<
"chunk mem: " << chunkMem / 1024 << " kib / " << (chunkMem*100/maxChunkMem) << '%'; "chunk mem: " << chunkMem / 1024 << " kib / " << (chunkMem*100/maxChunkMem) << '%' << std::endl <<
"Pointing at: " << LP.W->getBlockId(m_pointedBlock.x, m_pointedBlock.y, m_pointedBlock.z) << " @ " <<
m_pointedBlock.x << ' ' << m_pointedBlock.y << ' ' << m_pointedBlock.z <<
" C: " << divrd(m_pointedBlock.x, CX) << ' ' << divrd(m_pointedBlock.y, CZ) << ' ' << divrd(m_pointedBlock.z, CZ);
UI.DebugInfo->setText(oss.str()); UI.DebugInfo->setText(oss.str());
} }
} }

View File

@ -86,8 +86,8 @@ void LocalPlayer::update(float delta) {
// Apply gravity // Apply gravity
if (hasGravity) { if (hasGravity) {
if (!onGround && velocity.y <= HurtYVelocity) { if (!onGround && velocity.y <= HurtYVelocity) {
BlockId b = W->get(position.x, position.y-1, position.z); BlockId b = W->getBlockId(position.x, position.y-1, position.z);
onGround = !Blocks::canGoThrough(b, team) && (b != BlockType::Jump); onGround = !b; //!Blocks::canGoThrough(b, team) && (b != BlockType::Jump);
if (onGround) { if (onGround) {
if (velocity.y <= LethalYVelocity) { if (velocity.y <= LethalYVelocity) {
setDead(true, DeathReason::Fall, true); setDead(true, DeathReason::Fall, true);
@ -105,13 +105,13 @@ void LocalPlayer::update(float delta) {
} }
} }
if (onGround) { if (onGround) {
BlockType b = G->SC->get(position.x, position.y-1, position.z); BlockId b = W->getBlockId(position.x, position.y-1, position.z);
onGround = !Blocks::canGoThrough(b, team); onGround = !b; //!Blocks::canGoThrough(b, team);
if (onRoad) { /*if (onRoad) {
onRoad = (!onGround || b == BlockType::Road || b == BlockType::Jump); onRoad = (!onGround || b == BlockType::Road || b == BlockType::Jump);
} else { } else {
onRoad = (b == BlockType::Road); onRoad = (b == BlockType::Road);
} }*/
} }
if (!onGround) if (!onGround)
velocity.y -= Gravity * delta; velocity.y -= Gravity * delta;
@ -143,8 +143,8 @@ void LocalPlayer::update(float delta) {
#if 0 #if 0
else { else {
float x = destPos.x, y = destPos.y, z = destPos.z; float x = destPos.x, y = destPos.y, z = destPos.z;
BlockType bTop = G->SC->get(x, y+size.y, z), BlockId bTop = W->getBlockId(x, floor(y+size.y), z),
bBottom = G->SC->get(x, y, z); bBottom = W->getBlockId(x, y, z);
if (velocity.y > 0.f) if (velocity.y > 0.f)
if (!Blocks::canGoThrough(bTop, team)) { if (!Blocks::canGoThrough(bTop, team)) {
velocity.y = 0.f; velocity.y = 0.f;

View File

@ -1,5 +1,4 @@
#include "MessageState.hpp" #include "MessageState.hpp"
#include "_.hpp"
#include "ui/Text.hpp" #include "ui/Text.hpp"
#include "Game.hpp" #include "Game.hpp"
#include "GlobalProperties.hpp" #include "GlobalProperties.hpp"

View File

@ -143,15 +143,17 @@ double rmod(double x, double y);
/// Divide rounding down / Modulo quotient /// Divide rounding down / Modulo quotient
/// @returns x/y rounded down / Q in modulus' A=B*Q+R equation /// @returns x/y rounded down / Q in modulus' A=B*Q+R equation
/// ///
/*[[gnu::always_inline]]*/ inline int divrd(int x, uint y) { /*[[gnu::always_inline]] constexpr*/ inline int divrd(int x, uint y) {
return x/(int)y - (x < 0 ? 1 : 0); if (x < 0)
return (x+1)/(int)y - 1;
return x/(int)y;
} }
/// ///
/// @return Floored value of f, as an integer /// @return Floored value of f, as an integer
/// @see ::std::floor For results as float or double /// @see ::std::floor For results as float or double
/// ///
/*[[gnu::always_inline]]*/ inline int floor(const float f) { /*[[gnu::always_inline]] constexpr*/ inline int floor(const float f) {
if (f >= 0) if (f >= 0)
return (int)f; return (int)f;
return ((int)f)-1; return ((int)f)-1;

View File

@ -85,9 +85,9 @@ void Server::handlePlayerJoin(InMessage &msg, Peer &peer) {
H.send(p.P, broadcast, Tfer::Rel); H.send(p.P, broadcast, Tfer::Rel);
} }
getOutputStream() << plr.name << " joined from " << peer.getHost() << endl; getOutputStream() << plr.name << " joined from " << peer.getHost() << endl;
for (int x = -8; x < 0; ++x) for (int x = -2; x < 2; ++x)
for (int y = -1; y < 0; ++y) for (int y = -2; y < 2; ++y)
for (int z = -8; z < 0; ++z) for (int z = -2; z < 2; ++z)
schedSendChunk(G.U->getWorld(0)->getChunkEx(x, y, z), plr); schedSendChunk(G.U->getWorld(0)->getChunkEx(x, y, z), plr);
} }

View File

@ -19,7 +19,7 @@ class OutMessage;
typedef int WorldId; typedef int WorldId;
struct WorldChunkMapSorter { struct WorldChunkMapSorter {
/*constexpr*/ bool operator()(const glm::ivec3& lhs, const glm::ivec3& rhs) const { /*constexpr*/ bool operator()(const glm::ivec3 &lhs, const glm::ivec3 &rhs) const {
if (lhs.x == rhs.x) if (lhs.x == rhs.x)
if (lhs.y == rhs.y) if (lhs.y == rhs.y)
if (lhs.z == rhs.z) if (lhs.z == rhs.z)

View File

@ -1,87 +0,0 @@
#ifndef UNDERSCORE_HPP
#define UNDERSCORE_HPP
#include <utility>
template<class T> struct _ {
T *ptr;
// Construct
_() : ptr(nullptr) {}
_(decltype(nullptr)) : ptr(nullptr) {}
_(T *t) : ptr(t) {}
template<typename... Args> _(Args&&... args) {
ptr = new T(std::forward<Args>(args)...);
}
// No copy
_(const _&) = delete;
_& operator=(const _&) = delete;
// Move
_(_ &&o) {
delete ptr;
ptr = o.ptr;
o.ptr = nullptr;
}
_& operator=(_ &&o) {
delete ptr;
ptr = o.ptr;
o.ptr = nullptr;
return *this;
}
// Assign
_& operator=(T *t) {
delete ptr;
ptr = t;
return *this;
}
// Comparison
bool operator==(T *t) const {
return t == ptr;
}
bool operator!=(T *t) const {
return t != ptr;
}
// Get
T* get() const {
return ptr;
}
T& operator[](int i) const {
return ptr[i];
}
T& operator*() const {
return *ptr;
}
T* operator->() const {
return ptr;
}
// Addressof, use at your own risk
T** operator&() const {
return &ptr;
}
// Cast
operator T*() const {
return ptr;
}
operator const T*() const {
return ptr;
}
template<typename R> operator R*() const {
return (R*)ptr;
}
operator bool() const {
return ptr;
}
// Destruct
~_() {
delete ptr;
}
};
#endif

View File

@ -36,7 +36,7 @@ void Manager::setup(Game *G) {
RR.uni_mvp = RR.prog->uni("mvp"); RR.uni_mvp = RR.prog->uni("mvp");
RR.uni_unicolor = RR.prog->uni("unicolor"); RR.uni_unicolor = RR.prog->uni("unicolor");
} }
m_rectVbo = new VBO(); m_rectVbo.reset(new VBO);
uint8 verts[6*4] = { uint8 verts[6*4] = {
0, 0, 0, 1, 0, 0, 0, 1,
1, 0, 1, 1, 1, 0, 1, 1,
@ -59,11 +59,11 @@ void Manager::add(Element *e) {
void Manager::remove(Element *e) { void Manager::remove(Element *e) {
m_elements.remove_if([&e](_<Element> &l) -> bool { return l == e; }); m_elements.remove_if([&e](std::unique_ptr<Element> &l) -> bool { return l.get() == e; });
} }
void Manager::render() { void Manager::render() {
for (_<Element>& e : m_elements) { for (std::unique_ptr<Element> &e : m_elements) {
if (e->m_isVisible) if (e->m_isVisible)
e->render(); e->render();
} }

View File

@ -1,8 +1,8 @@
#ifndef UI_MANAGER_HPP #ifndef UI_MANAGER_HPP
#define UI_MANAGER_HPP #define UI_MANAGER_HPP
#include <list> #include <list>
#include <memory>
#include "Element.hpp" #include "Element.hpp"
#include "../_.hpp"
namespace Diggler { namespace Diggler {
@ -14,8 +14,8 @@ namespace UI {
class Manager { class Manager {
private: private:
_<VBO> m_rectVbo; std::unique_ptr<VBO> m_rectVbo;
std::list<_<Element>> m_elements; std::list<std::unique_ptr<Element>> m_elements;
glm::mat4 m_projMatrix, m_projMat1, m_projMat1V; glm::mat4 m_projMatrix, m_projMat1, m_projMat1V;
friend GameWindow; friend GameWindow;