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
parent
ad6aed5179
commit
47ecebae40
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
@ -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)
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
87
src/_.hpp
87
src/_.hpp
|
@ -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
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue