before adding day/night lighting
--HG-- rename : data/light.png => data/cloud.pngmaster
parent
385dd9917f
commit
15a43c5ed0
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
@ -38,6 +38,9 @@ Configuration file:
|
||||||
../minetest.conf
|
../minetest.conf
|
||||||
../../minetest.conf
|
../../minetest.conf
|
||||||
|
|
||||||
|
Command-line options:
|
||||||
|
- Use --help
|
||||||
|
|
||||||
Running on Windows:
|
Running on Windows:
|
||||||
- The working directory should be ./bin
|
- The working directory should be ./bin
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ cp -r data/water.png $PACKAGEPATH/data/
|
||||||
cp -r data/tree.png $PACKAGEPATH/data/
|
cp -r data/tree.png $PACKAGEPATH/data/
|
||||||
cp -r data/leaves.png $PACKAGEPATH/data/
|
cp -r data/leaves.png $PACKAGEPATH/data/
|
||||||
cp -r data/mese.png $PACKAGEPATH/data/
|
cp -r data/mese.png $PACKAGEPATH/data/
|
||||||
cp -r data/light.png $PACKAGEPATH/data/
|
cp -r data/cloud.png $PACKAGEPATH/data/
|
||||||
cp -r data/sign.png $PACKAGEPATH/data/
|
cp -r data/sign.png $PACKAGEPATH/data/
|
||||||
cp -r data/sign_back.png $PACKAGEPATH/data/
|
cp -r data/sign_back.png $PACKAGEPATH/data/
|
||||||
cp -r data/rat.png $PACKAGEPATH/data/
|
cp -r data/rat.png $PACKAGEPATH/data/
|
||||||
|
|
|
@ -1140,6 +1140,35 @@ bool Client::AsyncProcessPacket(LazyMeshUpdater &mesh_updater)
|
||||||
block->deSerialize(istr, ser_version);
|
block->deSerialize(istr, ser_version);
|
||||||
sector->insertBlock(block);
|
sector->insertBlock(block);
|
||||||
//block->setChangedFlag();
|
//block->setChangedFlag();
|
||||||
|
|
||||||
|
//DEBUG
|
||||||
|
/*NodeMod mod;
|
||||||
|
mod.type = NODEMOD_CHANGECONTENT;
|
||||||
|
mod.param = CONTENT_MESE;
|
||||||
|
block->setTempMod(v3s16(8,10,8), mod);
|
||||||
|
block->setTempMod(v3s16(8,9,8), mod);
|
||||||
|
block->setTempMod(v3s16(8,8,8), mod);
|
||||||
|
block->setTempMod(v3s16(8,7,8), mod);
|
||||||
|
block->setTempMod(v3s16(8,6,8), mod);*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Add some coulds
|
||||||
|
Well, this is a dumb way to do it, they should just
|
||||||
|
be drawn as separate objects.
|
||||||
|
*/
|
||||||
|
/*if(p.Y == 3)
|
||||||
|
{
|
||||||
|
NodeMod mod;
|
||||||
|
mod.type = NODEMOD_CHANGECONTENT;
|
||||||
|
mod.param = CONTENT_CLOUD;
|
||||||
|
v3s16 p2;
|
||||||
|
p2.Y = 8;
|
||||||
|
for(p2.X=3; p2.X<=13; p2.X++)
|
||||||
|
for(p2.Z=3; p2.Z<=13; p2.Z++)
|
||||||
|
{
|
||||||
|
block->setTempMod(p2, mod);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
} //envlock
|
} //envlock
|
||||||
|
|
||||||
|
@ -1412,16 +1441,20 @@ void Client::pressGround(u8 button, v3s16 nodepos_undersurface,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
length: 19
|
length: 17
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
[2] u8 button (0=left, 1=right)
|
[2] u8 action
|
||||||
[3] v3s16 nodepos_undersurface
|
[3] v3s16 nodepos_undersurface
|
||||||
[9] v3s16 nodepos_abovesurface
|
[9] v3s16 nodepos_abovesurface
|
||||||
[15] u16 item
|
[15] u16 item
|
||||||
|
actions:
|
||||||
|
0: start digging
|
||||||
|
1: place block
|
||||||
|
2: stop digging (all parameters ignored)
|
||||||
*/
|
*/
|
||||||
u8 datasize = 2 + 1 + 6 + 6 + 2;
|
u8 datasize = 2 + 1 + 6 + 6 + 2;
|
||||||
SharedBuffer<u8> data(datasize);
|
SharedBuffer<u8> data(datasize);
|
||||||
writeU16(&data[0], TOSERVER_PRESS_GROUND);
|
writeU16(&data[0], TOSERVER_GROUND_ACTION);
|
||||||
writeU8(&data[2], button);
|
writeU8(&data[2], button);
|
||||||
writeV3S16(&data[3], nodepos_undersurface);
|
writeV3S16(&data[3], nodepos_undersurface);
|
||||||
writeV3S16(&data[9], nodepos_oversurface);
|
writeV3S16(&data[9], nodepos_oversurface);
|
||||||
|
@ -1455,9 +1488,35 @@ void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
|
||||||
Send(0, data, true);
|
Send(0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::release(u8 button)
|
void Client::stopDigging()
|
||||||
{
|
{
|
||||||
//TODO
|
if(connectedAndInitialized() == false){
|
||||||
|
dout_client<<DTIME<<"Client::release() "
|
||||||
|
"cancelled (not connected)"
|
||||||
|
<<std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
length: 17
|
||||||
|
[0] u16 command
|
||||||
|
[2] u8 action
|
||||||
|
[3] v3s16 nodepos_undersurface
|
||||||
|
[9] v3s16 nodepos_abovesurface
|
||||||
|
[15] u16 item
|
||||||
|
actions:
|
||||||
|
0: start digging
|
||||||
|
1: place block
|
||||||
|
2: stop digging (all parameters ignored)
|
||||||
|
*/
|
||||||
|
u8 datasize = 2 + 1 + 6 + 6 + 2;
|
||||||
|
SharedBuffer<u8> data(datasize);
|
||||||
|
writeU16(&data[0], TOSERVER_GROUND_ACTION);
|
||||||
|
writeU8(&data[2], 2);
|
||||||
|
writeV3S16(&data[3], v3s16(0,0,0));
|
||||||
|
writeV3S16(&data[9], v3s16(0,0,0));
|
||||||
|
writeU16(&data[15], 0);
|
||||||
|
Send(0, data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
|
void Client::sendSignText(v3s16 blockpos, s16 id, std::string text)
|
||||||
|
|
|
@ -196,7 +196,7 @@ public:
|
||||||
void pressGround(u8 button, v3s16 nodepos_undersurface,
|
void pressGround(u8 button, v3s16 nodepos_undersurface,
|
||||||
v3s16 nodepos_oversurface, u16 item);
|
v3s16 nodepos_oversurface, u16 item);
|
||||||
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
|
void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item);
|
||||||
void release(u8 button);
|
void stopDigging();
|
||||||
|
|
||||||
void sendSignText(v3s16 blockpos, s16 id, std::string text);
|
void sendSignText(v3s16 blockpos, s16 id, std::string text);
|
||||||
|
|
||||||
|
|
|
@ -159,22 +159,21 @@ enum ToServerCommand
|
||||||
[11] u16 item
|
[11] u16 item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_PRESS_GROUND = 0x28,
|
TOSERVER_GROUND_ACTION = 0x28,
|
||||||
/*
|
/*
|
||||||
length: 17
|
length: 17
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
[2] u8 button (0=left, 1=right)
|
[2] u8 action
|
||||||
[3] v3s16 nodepos_undersurface
|
[3] v3s16 nodepos_undersurface
|
||||||
[9] v3s16 nodepos_abovesurface
|
[9] v3s16 nodepos_abovesurface
|
||||||
[15] u16 item
|
[15] u16 item
|
||||||
|
actions:
|
||||||
|
0: start digging (from undersurface)
|
||||||
|
1: place block (to abovesurface)
|
||||||
|
2: stop digging (all parameters ignored)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
TOSERVER_RELEASE = 0x29,
|
TOSERVER_RELEASE = 0x29, // Not used
|
||||||
/*
|
|
||||||
length: 3
|
|
||||||
[0] u16 command
|
|
||||||
[2] u8 button
|
|
||||||
*/
|
|
||||||
|
|
||||||
TOSERVER_SIGNTEXT = 0x30,
|
TOSERVER_SIGNTEXT = 0x30,
|
||||||
/*
|
/*
|
||||||
|
|
112
src/light.cpp
112
src/light.cpp
|
@ -19,49 +19,45 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
#include "light.h"
|
#include "light.h"
|
||||||
|
|
||||||
/*
|
// LIGHT_MAX is 15, 0-15 is 16 values
|
||||||
|
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
from math import *
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
# We want 0 at light=0 and 255 at light=LIGHT_MAX
|
|
||||||
LIGHT_MAX = 15
|
|
||||||
|
|
||||||
L = []
|
|
||||||
for i in range(1,LIGHT_MAX+1):
|
|
||||||
L.append(int(round(255.0 * 0.69 ** (i-1))))
|
|
||||||
L.append(0)
|
|
||||||
|
|
||||||
L.reverse()
|
|
||||||
for i in L:
|
|
||||||
stdout.write(str(i)+",\n")
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
The first value should be 0, the last value should be 255.
|
|
||||||
*/
|
|
||||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||||
{
|
{
|
||||||
0,
|
0,
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
6,
|
|
||||||
9,
|
9,
|
||||||
13,
|
12,
|
||||||
19,
|
14,
|
||||||
28,
|
16,
|
||||||
40,
|
20,
|
||||||
58,
|
26,
|
||||||
84,
|
34,
|
||||||
121,
|
45,
|
||||||
176,
|
61,
|
||||||
|
81,
|
||||||
|
108,
|
||||||
|
143,
|
||||||
|
191,
|
||||||
255,
|
255,
|
||||||
};*/
|
};*/
|
||||||
|
u8 light_decode_table[LIGHT_MAX+1] =
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
5,
|
||||||
|
12,
|
||||||
|
22,
|
||||||
|
35,
|
||||||
|
50,
|
||||||
|
65,
|
||||||
|
85,
|
||||||
|
100,
|
||||||
|
120,
|
||||||
|
140,
|
||||||
|
160,
|
||||||
|
185,
|
||||||
|
215,
|
||||||
|
255,
|
||||||
|
};
|
||||||
|
|
||||||
|
#if 0
|
||||||
/*
|
/*
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
@ -100,48 +96,6 @@ u8 light_decode_table[LIGHT_MAX+1] =
|
||||||
191,
|
191,
|
||||||
255,
|
255,
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
/*
|
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
from math import *
|
|
||||||
from sys import stdout
|
|
||||||
|
|
||||||
# We want 0 at light=0 and 255 at light=LIGHT_MAX
|
|
||||||
LIGHT_MAX = 14
|
|
||||||
#FACTOR = 0.69
|
|
||||||
FACTOR = 0.75
|
|
||||||
|
|
||||||
maxlight = 255
|
|
||||||
minlight = 8
|
|
||||||
|
|
||||||
L = []
|
|
||||||
for i in range(1,LIGHT_MAX+1):
|
|
||||||
L.append(minlight+int(round((maxlight-minlight) * FACTOR ** (i-1))))
|
|
||||||
#L.append(int(round(255.0 * FACTOR ** (i-1))))
|
|
||||||
L.append(minlight)
|
|
||||||
|
|
||||||
L.reverse()
|
|
||||||
for i in L:
|
|
||||||
stdout.write(str(i)+",\n")
|
|
||||||
*/
|
|
||||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
|
||||||
{
|
|
||||||
8,
|
|
||||||
14,
|
|
||||||
16,
|
|
||||||
18,
|
|
||||||
22,
|
|
||||||
27,
|
|
||||||
33,
|
|
||||||
41,
|
|
||||||
52,
|
|
||||||
67,
|
|
||||||
86,
|
|
||||||
112,
|
|
||||||
147,
|
|
||||||
193,
|
|
||||||
255,
|
|
||||||
};*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
|
||||||
// This directly sets the range of light
|
// This directly sets the range of light
|
||||||
#define LIGHT_MAX 14
|
#define LIGHT_MAX 14
|
||||||
|
// Light is stored as 4 bits, thus 15 is the maximum.
|
||||||
// This brightness is reserved for sunlight
|
// This brightness is reserved for sunlight
|
||||||
#define LIGHT_SUN 15
|
#define LIGHT_SUN 15
|
||||||
|
|
||||||
|
|
323
src/main.cpp
323
src/main.cpp
|
@ -27,50 +27,7 @@ NOTE: VBO cannot be turned on for fast-changing stuff because there
|
||||||
NOTE: iostream.imbue(std::locale("C")) is very slow
|
NOTE: iostream.imbue(std::locale("C")) is very slow
|
||||||
NOTE: Global locale is now set at initialization
|
NOTE: Global locale is now set at initialization
|
||||||
|
|
||||||
SUGGESTION: add a second lighting value to the MS nibble of param of
|
SUGG: Fix address to be ipv6 compatible
|
||||||
air to tell how bright the air node is when there is no sunlight.
|
|
||||||
When day changes to night, these two values can be interpolated.
|
|
||||||
|
|
||||||
TODO: Fix address to be ipv6 compatible
|
|
||||||
|
|
||||||
TODO: ESC Pause mode in which the cursor is not kept at the center of window.
|
|
||||||
TODO: Stop player if focus of window is taken away (go to pause mode)
|
|
||||||
TODO: Optimize and fix makeFastFace or whatever it's called
|
|
||||||
- Face calculation is the source of CPU usage on the client
|
|
||||||
SUGGESTION: The client will calculate and send lighting changes and
|
|
||||||
the server will randomly check some of them and kick the client out
|
|
||||||
if it fails to calculate them right.
|
|
||||||
- Actually, it could just start ignoring them and calculate them
|
|
||||||
itself.
|
|
||||||
SUGGESTION: Combine MapBlock's face caches to so big pieces that VBO
|
|
||||||
gets used
|
|
||||||
- That is >500 vertices
|
|
||||||
|
|
||||||
TODO: Better dungeons
|
|
||||||
TODO: There should be very slight natural caves also, starting from
|
|
||||||
only a straightened-up cliff
|
|
||||||
|
|
||||||
TODO: Changing of block with mouse wheel or something
|
|
||||||
TODO: Menus
|
|
||||||
|
|
||||||
TODO: Mobs
|
|
||||||
- Server:
|
|
||||||
- One single map container with ids as keys
|
|
||||||
- Client:
|
|
||||||
- ?
|
|
||||||
TODO: - Keep track of the place of the mob in the last few hundreth's
|
|
||||||
of a second - then, if a player hits it, take the value that is
|
|
||||||
avg_rtt/2 before the moment the packet is received.
|
|
||||||
TODO: - Scripting
|
|
||||||
|
|
||||||
SUGGESTION: Modify client to calculate single changes asynchronously
|
|
||||||
|
|
||||||
TODO: Moving players more smoothly. Calculate moving animation
|
|
||||||
in a way that doesn't make the player jump to the right place
|
|
||||||
immediately when the server sends a new position
|
|
||||||
|
|
||||||
TODO: There are some lighting-related todos and fixmes in
|
|
||||||
ServerMap::emergeBlock
|
|
||||||
|
|
||||||
FIXME: When a new sector is generated, it may change the ground level
|
FIXME: When a new sector is generated, it may change the ground level
|
||||||
of it's and it's neighbors border that two blocks that are
|
of it's and it's neighbors border that two blocks that are
|
||||||
|
@ -81,15 +38,7 @@ SUGGESTION: Use same technique for sector heightmaps as what we're
|
||||||
using for UnlimitedHeightmap? (getting all neighbors
|
using for UnlimitedHeightmap? (getting all neighbors
|
||||||
when generating)
|
when generating)
|
||||||
|
|
||||||
TODO: Proper handling of spawning place (try to find something that
|
SUGG: Transfer more blocks in a single packet
|
||||||
is not in the middle of an ocean (some land to stand on at
|
|
||||||
least) and save it in map config.
|
|
||||||
SUGG: Set server to automatically find a good spawning place in some
|
|
||||||
place where there is water and land.
|
|
||||||
- Map to have a getWalkableNear(p)
|
|
||||||
- Is this a good idea? It's part of the game to find a good place.
|
|
||||||
|
|
||||||
TODO: Transfer more blocks in a single packet
|
|
||||||
SUGG: A blockdata combiner class, to which blocks are added and at
|
SUGG: A blockdata combiner class, to which blocks are added and at
|
||||||
destruction it sends all the stuff in as few packets as possible.
|
destruction it sends all the stuff in as few packets as possible.
|
||||||
|
|
||||||
|
@ -100,53 +49,18 @@ SUGG: Expose Connection's seqnums and ACKs to server and client.
|
||||||
- This enables saving many packets and making a faster connection
|
- This enables saving many packets and making a faster connection
|
||||||
- This also enables server to check if client has received the
|
- This also enables server to check if client has received the
|
||||||
most recent block sent, for example.
|
most recent block sent, for example.
|
||||||
TODO: Add a sane bandwidth throttling system to Connection
|
SUGG: Add a sane bandwidth throttling system to Connection
|
||||||
|
|
||||||
SUGG: More fine-grained control of client's dumping of blocks from
|
SUGG: More fine-grained control of client's dumping of blocks from
|
||||||
memory
|
memory
|
||||||
- ...What does this mean in the first place?
|
- ...What does this mean in the first place?
|
||||||
|
|
||||||
TODO: Make the amount of blocks sending to client and the total
|
|
||||||
amount of blocks dynamically limited. Transferring blocks is the
|
|
||||||
main network eater of this system, so it is the one that has
|
|
||||||
to be throttled so that RTTs stay low.
|
|
||||||
|
|
||||||
TODO: Server to load starting inventory from disk
|
|
||||||
|
|
||||||
TODO: PLayers to only be hidden when the client quits.
|
|
||||||
TODO: - Players to be saved on disk, with inventory
|
|
||||||
TODO: Players to be saved as text in map/players/<name>
|
|
||||||
|
|
||||||
SUGG: A map editing mode (similar to dedicated server mode)
|
SUGG: A map editing mode (similar to dedicated server mode)
|
||||||
|
|
||||||
TODO: Make fetching sector's blocks more efficient when rendering
|
|
||||||
sectors that have very large amounts of blocks (on client)
|
|
||||||
|
|
||||||
TODO: Make the video backend selectable
|
|
||||||
|
|
||||||
Block object server side:
|
|
||||||
- A "near blocks" buffer, in which some nearby blocks are stored.
|
|
||||||
- For all blocks in the buffer, objects are stepped(). This
|
|
||||||
means they are active.
|
|
||||||
- TODO: A global active buffer is needed for the server
|
|
||||||
- TODO: All blocks going in and out of the buffer are recorded.
|
|
||||||
- TODO: For outgoing blocks, a timestamp is written.
|
|
||||||
- TODO: For incoming blocks, the time difference is calculated and
|
|
||||||
objects are stepped according to it.
|
|
||||||
TODO: A timestamp to blocks
|
|
||||||
|
|
||||||
SUGG: Add a time value to the param of footstepped grass and check it
|
SUGG: Add a time value to the param of footstepped grass and check it
|
||||||
against a global timer when a block is accessed, to make old
|
against a global timer when a block is accessed, to make old
|
||||||
steps fade away.
|
steps fade away.
|
||||||
|
|
||||||
TODO: Add config parameters for server's sending and generating distance
|
|
||||||
|
|
||||||
TODO: Copy the text of the last picked sign to inventory in creative
|
|
||||||
mode
|
|
||||||
|
|
||||||
TODO: Untie client network operations from framerate
|
|
||||||
- Needs some input queues or something
|
|
||||||
|
|
||||||
SUGG: Make a copy of close-range environment on client for showing
|
SUGG: Make a copy of close-range environment on client for showing
|
||||||
on screen, with minimal mutexes to slow down the main loop
|
on screen, with minimal mutexes to slow down the main loop
|
||||||
|
|
||||||
|
@ -161,15 +75,9 @@ SUGG: Split MapBlockObject serialization to to-client and to-disk
|
||||||
- This will allow saving ages of rats on disk but not sending
|
- This will allow saving ages of rats on disk but not sending
|
||||||
them to clients
|
them to clients
|
||||||
|
|
||||||
TODO: Get rid of GotSplitPacketException
|
|
||||||
|
|
||||||
SUGG: Implement lighting using VoxelManipulator
|
SUGG: Implement lighting using VoxelManipulator
|
||||||
- Would it be significantly faster?
|
- Would it be significantly faster?
|
||||||
|
|
||||||
TODO: Check what goes wrong with caching map to disk (Kray)
|
|
||||||
|
|
||||||
TODO: Remove LazyMeshUpdater. It is not used as supposed.
|
|
||||||
|
|
||||||
FIXME: Rats somehow go underground sometimes (you can see it in water)
|
FIXME: Rats somehow go underground sometimes (you can see it in water)
|
||||||
- Does their position get saved to a border value or something?
|
- Does their position get saved to a border value or something?
|
||||||
- Does this happen anymore?
|
- Does this happen anymore?
|
||||||
|
@ -184,9 +92,97 @@ SUGG: Implement a "Fast check queue" (a queue with a map for checking
|
||||||
SUGG: Signs could be done in the same way as torches. For this, blocks
|
SUGG: Signs could be done in the same way as torches. For this, blocks
|
||||||
need an additional metadata field for the texts
|
need an additional metadata field for the texts
|
||||||
|
|
||||||
|
SUGG: Precalculate lighting translation table at runtime (at startup)
|
||||||
|
|
||||||
|
SUGG: A version number to blocks, which increments when the block is
|
||||||
|
modified (node add/remove, water update, lighting update)
|
||||||
|
- This can then be used to make sure the most recent version of
|
||||||
|
a block has been sent to client
|
||||||
|
|
||||||
|
TODO: Stop player if focus of window is taken away (go to pause mode)
|
||||||
|
|
||||||
|
TODO: Combine MapBlock's face caches to so big pieces that VBO
|
||||||
|
gets used
|
||||||
|
- That is >500 vertices
|
||||||
|
|
||||||
|
TODO: Better dungeons
|
||||||
|
TODO: Cliffs, arcs
|
||||||
|
|
||||||
|
TODO: Menus
|
||||||
|
|
||||||
|
TODO: Mobs
|
||||||
|
- Server:
|
||||||
|
- One single map container with ids as keys
|
||||||
|
- Client:
|
||||||
|
- ?
|
||||||
|
TODO: - Keep track of the place of the mob in the last few hundreth's
|
||||||
|
of a second - then, if a player hits it, take the value that is
|
||||||
|
avg_rtt/2 before the moment the packet is received.
|
||||||
|
TODO: - Scripting
|
||||||
|
|
||||||
|
TODO: Moving players more smoothly. Calculate moving animation
|
||||||
|
in a way that doesn't make the player jump to the right place
|
||||||
|
immediately when the server sends a new position
|
||||||
|
|
||||||
|
TODO: There are some lighting-related todos and fixmes in
|
||||||
|
ServerMap::emergeBlock
|
||||||
|
|
||||||
|
TODO: Proper handling of spawning place (try to find something that
|
||||||
|
is not in the middle of an ocean (some land to stand on at
|
||||||
|
least) and save it in map config.
|
||||||
|
|
||||||
|
TODO: Make the amount of blocks sending to client and the total
|
||||||
|
amount of blocks dynamically limited. Transferring blocks is the
|
||||||
|
main network eater of this system, so it is the one that has
|
||||||
|
to be throttled so that RTTs stay low.
|
||||||
|
|
||||||
|
TODO: Server to load starting inventory from disk
|
||||||
|
|
||||||
|
TODO: Players to only be hidden when the client quits.
|
||||||
|
TODO: - Players to be saved on disk, with inventory
|
||||||
|
TODO: Players to be saved as text in map/players/<name>
|
||||||
|
|
||||||
|
TODO: Make fetching sector's blocks more efficient when rendering
|
||||||
|
sectors that have very large amounts of blocks (on client)
|
||||||
|
|
||||||
|
TODO: Make the video backend selectable
|
||||||
|
|
||||||
|
Block object server side:
|
||||||
|
- A "near blocks" buffer, in which some nearby blocks are stored.
|
||||||
|
- For all blocks in the buffer, objects are stepped(). This
|
||||||
|
means they are active.
|
||||||
|
- TODO: A global active buffer is needed for the server
|
||||||
|
- TODO: A timestamp to blocks
|
||||||
|
- TODO: All blocks going in and out of the buffer are recorded.
|
||||||
|
- TODO: For outgoing blocks, timestamp is written.
|
||||||
|
- TODO: For incoming blocks, time difference is calculated and
|
||||||
|
objects are stepped according to it.
|
||||||
|
|
||||||
|
TODO: Add config parameters for server's sending and generating distance
|
||||||
|
|
||||||
|
TODO: Copy the text of the last picked sign to inventory in creative
|
||||||
|
mode
|
||||||
|
|
||||||
|
TODO: Untie client network operations from framerate
|
||||||
|
- Needs some input queues or something
|
||||||
|
|
||||||
|
TODO: Get rid of GotSplitPacketException
|
||||||
|
|
||||||
|
TODO: Check what goes wrong with caching map to disk (Kray)
|
||||||
|
|
||||||
|
TODO: Remove LazyMeshUpdater. It is not used as supposed.
|
||||||
|
|
||||||
|
TODO: Node cracking animation when digging
|
||||||
|
- TODO: A way to generate new textures by combining textures
|
||||||
|
- TODO: Mesh update to fetch cracked faces from the former
|
||||||
|
|
||||||
Doing now:
|
Doing now:
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
TODO: Add a second lighting value to the MS nibble of param of
|
||||||
|
air to tell how bright the air node is when there is no sunlight.
|
||||||
|
When day changes to night, these two values can be interpolated.
|
||||||
|
- The biggest job is to add support to the lighting routines
|
||||||
|
|
||||||
======================================================================
|
======================================================================
|
||||||
|
|
||||||
|
@ -486,6 +482,10 @@ public:
|
||||||
|
|
||||||
if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
|
if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
|
||||||
{
|
{
|
||||||
|
left_active = event.MouseInput.isLeftPressed();
|
||||||
|
middle_active = event.MouseInput.isMiddlePressed();
|
||||||
|
right_active = event.MouseInput.isRightPressed();
|
||||||
|
|
||||||
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
||||||
{
|
{
|
||||||
leftclicked = true;
|
leftclicked = true;
|
||||||
|
@ -494,6 +494,14 @@ public:
|
||||||
{
|
{
|
||||||
rightclicked = true;
|
rightclicked = true;
|
||||||
}
|
}
|
||||||
|
if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
|
||||||
|
{
|
||||||
|
leftreleased = true;
|
||||||
|
}
|
||||||
|
if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
|
||||||
|
{
|
||||||
|
rightreleased = true;
|
||||||
|
}
|
||||||
if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
|
if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
|
||||||
{
|
{
|
||||||
/*dstream<<"event.MouseInput.Wheel="
|
/*dstream<<"event.MouseInput.Wheel="
|
||||||
|
@ -530,10 +538,23 @@ public:
|
||||||
keyIsDown[i] = false;
|
keyIsDown[i] = false;
|
||||||
leftclicked = false;
|
leftclicked = false;
|
||||||
rightclicked = false;
|
rightclicked = false;
|
||||||
|
leftreleased = false;
|
||||||
|
rightreleased = false;
|
||||||
|
|
||||||
|
left_active = false;
|
||||||
|
middle_active = false;
|
||||||
|
right_active = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool leftclicked;
|
bool leftclicked;
|
||||||
bool rightclicked;
|
bool rightclicked;
|
||||||
|
bool leftreleased;
|
||||||
|
bool rightreleased;
|
||||||
|
|
||||||
|
bool left_active;
|
||||||
|
bool middle_active;
|
||||||
|
bool right_active;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// We use this array to store the current state of each key
|
// We use this array to store the current state of each key
|
||||||
bool keyIsDown[KEY_KEY_CODES_COUNT];
|
bool keyIsDown[KEY_KEY_CODES_COUNT];
|
||||||
|
@ -550,14 +571,25 @@ public:
|
||||||
virtual ~InputHandler()
|
virtual ~InputHandler()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool isKeyDown(EKEY_CODE keyCode) = 0;
|
virtual bool isKeyDown(EKEY_CODE keyCode) = 0;
|
||||||
|
|
||||||
virtual v2s32 getMousePos() = 0;
|
virtual v2s32 getMousePos() = 0;
|
||||||
virtual void setMousePos(s32 x, s32 y) = 0;
|
virtual void setMousePos(s32 x, s32 y) = 0;
|
||||||
|
|
||||||
|
virtual bool getLeftState() = 0;
|
||||||
|
virtual bool getRightState() = 0;
|
||||||
|
|
||||||
virtual bool getLeftClicked() = 0;
|
virtual bool getLeftClicked() = 0;
|
||||||
virtual bool getRightClicked() = 0;
|
virtual bool getRightClicked() = 0;
|
||||||
virtual void resetLeftClicked() = 0;
|
virtual void resetLeftClicked() = 0;
|
||||||
virtual void resetRightClicked() = 0;
|
virtual void resetRightClicked() = 0;
|
||||||
|
|
||||||
|
virtual bool getLeftReleased() = 0;
|
||||||
|
virtual bool getRightReleased() = 0;
|
||||||
|
virtual void resetLeftReleased() = 0;
|
||||||
|
virtual void resetRightReleased() = 0;
|
||||||
|
|
||||||
virtual void step(float dtime) {};
|
virtual void step(float dtime) {};
|
||||||
|
|
||||||
virtual void clear() {};
|
virtual void clear() {};
|
||||||
|
@ -597,6 +629,15 @@ public:
|
||||||
m_device->getCursorControl()->setPosition(x, y);
|
m_device->getCursorControl()->setPosition(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getLeftState()
|
||||||
|
{
|
||||||
|
return m_receiver->left_active;
|
||||||
|
}
|
||||||
|
virtual bool getRightState()
|
||||||
|
{
|
||||||
|
return m_receiver->right_active;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool getLeftClicked()
|
virtual bool getLeftClicked()
|
||||||
{
|
{
|
||||||
if(g_game_focused == false)
|
if(g_game_focused == false)
|
||||||
|
@ -618,6 +659,27 @@ public:
|
||||||
m_receiver->rightclicked = false;
|
m_receiver->rightclicked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getLeftReleased()
|
||||||
|
{
|
||||||
|
if(g_game_focused == false)
|
||||||
|
return false;
|
||||||
|
return m_receiver->leftreleased;
|
||||||
|
}
|
||||||
|
virtual bool getRightReleased()
|
||||||
|
{
|
||||||
|
if(g_game_focused == false)
|
||||||
|
return false;
|
||||||
|
return m_receiver->rightreleased;
|
||||||
|
}
|
||||||
|
virtual void resetLeftReleased()
|
||||||
|
{
|
||||||
|
m_receiver->leftreleased = false;
|
||||||
|
}
|
||||||
|
virtual void resetRightReleased()
|
||||||
|
{
|
||||||
|
m_receiver->rightreleased = false;
|
||||||
|
}
|
||||||
|
|
||||||
void clear()
|
void clear()
|
||||||
{
|
{
|
||||||
resetRightClicked();
|
resetRightClicked();
|
||||||
|
@ -651,6 +713,15 @@ public:
|
||||||
mousepos = v2s32(x,y);
|
mousepos = v2s32(x,y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getLeftState()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool getRightState()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool getLeftClicked()
|
virtual bool getLeftClicked()
|
||||||
{
|
{
|
||||||
return leftclicked;
|
return leftclicked;
|
||||||
|
@ -668,6 +739,21 @@ public:
|
||||||
rightclicked = false;
|
rightclicked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual bool getLeftReleased()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual bool getRightReleased()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
virtual void resetLeftReleased()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual void resetRightReleased()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
virtual void step(float dtime)
|
virtual void step(float dtime)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -1563,6 +1649,11 @@ int main(int argc, char *argv[])
|
||||||
//gui::IGUIWindow* input_window = NULL;
|
//gui::IGUIWindow* input_window = NULL;
|
||||||
gui::IGUIStaticText* input_guitext = NULL;
|
gui::IGUIStaticText* input_guitext = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Digging animation
|
||||||
|
*/
|
||||||
|
//f32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Main loop
|
Main loop
|
||||||
*/
|
*/
|
||||||
|
@ -1921,6 +2012,10 @@ int main(int argc, char *argv[])
|
||||||
else // selected_object == NULL
|
else // selected_object == NULL
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Find out which node we are pointing at
|
||||||
|
*/
|
||||||
|
|
||||||
bool nodefound = false;
|
bool nodefound = false;
|
||||||
v3s16 nodepos;
|
v3s16 nodepos;
|
||||||
v3s16 neighbourpos;
|
v3s16 neighbourpos;
|
||||||
|
@ -2066,6 +2161,9 @@ int main(int argc, char *argv[])
|
||||||
} // regular block
|
} // regular block
|
||||||
} // for coords
|
} // for coords
|
||||||
|
|
||||||
|
/*static v3s16 oldnodepos;
|
||||||
|
static bool oldnodefound = false;*/
|
||||||
|
|
||||||
if(nodefound)
|
if(nodefound)
|
||||||
{
|
{
|
||||||
//std::cout<<DTIME<<"nodefound == true"<<std::endl;
|
//std::cout<<DTIME<<"nodefound == true"<<std::endl;
|
||||||
|
@ -2076,41 +2174,54 @@ int main(int argc, char *argv[])
|
||||||
if(nodepos != nodepos_old){
|
if(nodepos != nodepos_old){
|
||||||
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
|
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
|
||||||
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
<<nodepos.Y<<","<<nodepos.Z<<")"<<std::endl;
|
||||||
nodepos_old = nodepos;
|
|
||||||
|
|
||||||
/*wchar_t positiontext[20];
|
|
||||||
swprintf(positiontext, 20, L"(%i,%i,%i)",
|
|
||||||
nodepos.X, nodepos.Y, nodepos.Z);
|
|
||||||
positiontextgui->setText(positiontext);*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hilightboxes.push_back(nodefacebox);
|
hilightboxes.push_back(nodefacebox);
|
||||||
|
|
||||||
if(g_input->getLeftClicked())
|
//if(g_input->getLeftClicked())
|
||||||
|
if(g_input->getLeftClicked() ||
|
||||||
|
(g_input->getLeftState() && nodepos != nodepos_old))
|
||||||
{
|
{
|
||||||
//std::cout<<DTIME<<"Removing node"<<std::endl;
|
|
||||||
//client.removeNode(nodepos);
|
|
||||||
std::cout<<DTIME<<"Ground left-clicked"<<std::endl;
|
std::cout<<DTIME<<"Ground left-clicked"<<std::endl;
|
||||||
client.pressGround(0, nodepos, neighbourpos, g_selected_item);
|
client.pressGround(0, nodepos, neighbourpos, g_selected_item);
|
||||||
}
|
}
|
||||||
if(g_input->getRightClicked())
|
if(g_input->getRightClicked())
|
||||||
|
/*if(g_input->getRightClicked() ||
|
||||||
|
(g_input->getRightState() && nodepos != nodepos_old))*/
|
||||||
{
|
{
|
||||||
//std::cout<<DTIME<<"Placing node"<<std::endl;
|
|
||||||
//client.addNodeFromInventory(neighbourpos, g_selected_item);
|
|
||||||
std::cout<<DTIME<<"Ground right-clicked"<<std::endl;
|
std::cout<<DTIME<<"Ground right-clicked"<<std::endl;
|
||||||
client.pressGround(1, nodepos, neighbourpos, g_selected_item);
|
client.pressGround(1, nodepos, neighbourpos, g_selected_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodepos_old = nodepos;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
//std::cout<<DTIME<<"nodefound == false"<<std::endl;
|
//std::cout<<DTIME<<"nodefound == false"<<std::endl;
|
||||||
//positiontextgui->setText(L"");
|
//positiontextgui->setText(L"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*oldnodefound = nodefound;
|
||||||
|
oldnodepos = nodepos;*/
|
||||||
|
|
||||||
} // selected_object == NULL
|
} // selected_object == NULL
|
||||||
|
|
||||||
g_input->resetLeftClicked();
|
g_input->resetLeftClicked();
|
||||||
g_input->resetRightClicked();
|
g_input->resetRightClicked();
|
||||||
|
|
||||||
|
if(g_input->getLeftReleased())
|
||||||
|
{
|
||||||
|
std::cout<<DTIME<<"Left released"<<std::endl;
|
||||||
|
client.stopDigging();
|
||||||
|
}
|
||||||
|
if(g_input->getRightReleased())
|
||||||
|
{
|
||||||
|
//std::cout<<DTIME<<"Right released"<<std::endl;
|
||||||
|
// Nothing here
|
||||||
|
}
|
||||||
|
|
||||||
|
g_input->resetLeftReleased();
|
||||||
|
g_input->resetRightReleased();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Calculate stuff for drawing
|
Calculate stuff for drawing
|
||||||
*/
|
*/
|
||||||
|
|
181
src/map.cpp
181
src/map.cpp
|
@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
//#include "player.h"
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "jmutexautolock.h"
|
#include "jmutexautolock.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
@ -112,13 +111,6 @@ Map::~Map()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*bool Map::sectorExists(v2s16 p)
|
|
||||||
{
|
|
||||||
JMutexAutoLock lock(m_sector_mutex);
|
|
||||||
core::map<v2s16, MapSector*>::Node *n = m_sectors.find(p);
|
|
||||||
return (n != NULL);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
MapSector * Map::getSectorNoGenerate(v2s16 p)
|
MapSector * Map::getSectorNoGenerate(v2s16 p)
|
||||||
{
|
{
|
||||||
JMutexAutoLock lock(m_sector_mutex);
|
JMutexAutoLock lock(m_sector_mutex);
|
||||||
|
@ -160,20 +152,6 @@ MapBlock * Map::getBlockNoCreate(v3s16 p3d)
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*MapBlock * Map::getBlock(v3s16 p3d, bool generate)
|
|
||||||
{
|
|
||||||
dstream<<"Map::getBlock() with generate=true called"
|
|
||||||
<<std::endl;
|
|
||||||
v2s16 p2d(p3d.X, p3d.Z);
|
|
||||||
//MapSector * sector = getSector(p2d, generate);
|
|
||||||
MapSector * sector = getSectorNoGenerate(p2d);
|
|
||||||
|
|
||||||
if(sector == NULL)
|
|
||||||
throw InvalidPositionException();
|
|
||||||
|
|
||||||
return sector->getBlockNoCreate(p3d.Y);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
f32 Map::getGroundHeight(v2s16 p, bool generate)
|
f32 Map::getGroundHeight(v2s16 p, bool generate)
|
||||||
{
|
{
|
||||||
try{
|
try{
|
||||||
|
@ -215,156 +193,6 @@ bool Map::isNodeUnderground(v3s16 p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
void Map::interpolate(v3s16 block,
|
|
||||||
core::map<v3s16, MapBlock*> & modified_blocks)
|
|
||||||
{
|
|
||||||
const v3s16 dirs[6] = {
|
|
||||||
v3s16(0,0,1), // back
|
|
||||||
v3s16(0,1,0), // top
|
|
||||||
v3s16(1,0,0), // right
|
|
||||||
v3s16(0,0,-1), // front
|
|
||||||
v3s16(0,-1,0), // bottom
|
|
||||||
v3s16(-1,0,0), // left
|
|
||||||
};
|
|
||||||
|
|
||||||
if(from_nodes.size() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
u32 blockchangecount = 0;
|
|
||||||
|
|
||||||
core::map<v3s16, bool> lighted_nodes;
|
|
||||||
core::map<v3s16, bool>::Iterator j;
|
|
||||||
j = from_nodes.getIterator();
|
|
||||||
|
|
||||||
/*
|
|
||||||
Initialize block cache
|
|
||||||
*/
|
|
||||||
v3s16 blockpos_last;
|
|
||||||
MapBlock *block = NULL;
|
|
||||||
// Cache this a bit, too
|
|
||||||
bool block_checked_in_modified = false;
|
|
||||||
|
|
||||||
for(; j.atEnd() == false; j++)
|
|
||||||
//for(; j != from_nodes.end(); j++)
|
|
||||||
{
|
|
||||||
v3s16 pos = j.getNode()->getKey();
|
|
||||||
//v3s16 pos = *j;
|
|
||||||
//dstream<<"pos=("<<pos.X<<","<<pos.Y<<","<<pos.Z<<")"<<std::endl;
|
|
||||||
v3s16 blockpos = getNodeBlockPos(pos);
|
|
||||||
|
|
||||||
// Only fetch a new block if the block position has changed
|
|
||||||
try{
|
|
||||||
if(block == NULL || blockpos != blockpos_last){
|
|
||||||
block = getBlockNoCreate(blockpos);
|
|
||||||
blockpos_last = blockpos;
|
|
||||||
|
|
||||||
block_checked_in_modified = false;
|
|
||||||
blockchangecount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(block->isDummy())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Calculate relative position in block
|
|
||||||
v3s16 relpos = pos - blockpos_last * MAP_BLOCKSIZE;
|
|
||||||
|
|
||||||
// Get node straight from the block
|
|
||||||
MapNode n = block->getNode(relpos);
|
|
||||||
|
|
||||||
u8 oldlight = n.getLight();
|
|
||||||
u8 newlight = diminish_light(oldlight);
|
|
||||||
|
|
||||||
// Loop through 6 neighbors
|
|
||||||
for(u16 i=0; i<6; i++){
|
|
||||||
// Get the position of the neighbor node
|
|
||||||
v3s16 n2pos = pos + dirs[i];
|
|
||||||
|
|
||||||
// Get the block where the node is located
|
|
||||||
v3s16 blockpos = getNodeBlockPos(n2pos);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Only fetch a new block if the block position has changed
|
|
||||||
try{
|
|
||||||
if(block == NULL || blockpos != blockpos_last){
|
|
||||||
block = getBlockNoCreate(blockpos);
|
|
||||||
blockpos_last = blockpos;
|
|
||||||
|
|
||||||
block_checked_in_modified = false;
|
|
||||||
blockchangecount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate relative position in block
|
|
||||||
v3s16 relpos = n2pos - blockpos * MAP_BLOCKSIZE;
|
|
||||||
// Get node straight from the block
|
|
||||||
MapNode n2 = block->getNode(relpos);
|
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
/*
|
|
||||||
If the neighbor is brighter than the current node,
|
|
||||||
add to list (it will light up this node on its turn)
|
|
||||||
*/
|
|
||||||
if(n2.getLight() > undiminish_light(oldlight))
|
|
||||||
{
|
|
||||||
lighted_nodes.insert(n2pos, true);
|
|
||||||
//lighted_nodes.push_back(n2pos);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
If the neighbor is dimmer than how much light this node
|
|
||||||
would spread on it, add to list
|
|
||||||
*/
|
|
||||||
if(n2.getLight() < newlight)
|
|
||||||
{
|
|
||||||
if(n2.light_propagates())
|
|
||||||
{
|
|
||||||
n2.setLight(newlight);
|
|
||||||
block->setNode(relpos, n2);
|
|
||||||
lighted_nodes.insert(n2pos, true);
|
|
||||||
//lighted_nodes.push_back(n2pos);
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to modified_blocks
|
|
||||||
if(changed == true && block_checked_in_modified == false)
|
|
||||||
{
|
|
||||||
// If the block is not found in modified_blocks, add.
|
|
||||||
if(modified_blocks.find(blockpos) == NULL)
|
|
||||||
{
|
|
||||||
modified_blocks.insert(blockpos, block);
|
|
||||||
}
|
|
||||||
block_checked_in_modified = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(InvalidPositionException &e)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*dstream<<"spreadLight(): Changed block "
|
|
||||||
<<blockchangecount<<" times"
|
|
||||||
<<" for "<<from_nodes.size()<<" nodes"
|
|
||||||
<<std::endl;*/
|
|
||||||
|
|
||||||
if(lighted_nodes.size() > 0)
|
|
||||||
spreadLight(lighted_nodes, modified_blocks);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Goes recursively through the neighbours of the node.
|
Goes recursively through the neighbours of the node.
|
||||||
|
|
||||||
|
@ -813,11 +641,6 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
||||||
bool debug=false;
|
bool debug=false;
|
||||||
u32 count_was = modified_blocks.size();
|
u32 count_was = modified_blocks.size();
|
||||||
|
|
||||||
/*core::list<MapBlock *>::Iterator i = a_blocks.begin();
|
|
||||||
for(; i != a_blocks.end(); i++)
|
|
||||||
{
|
|
||||||
MapBlock *block = *i;*/
|
|
||||||
|
|
||||||
core::map<v3s16, bool> light_sources;
|
core::map<v3s16, bool> light_sources;
|
||||||
|
|
||||||
core::map<v3s16, u8> unlight_from;
|
core::map<v3s16, u8> unlight_from;
|
||||||
|
@ -2764,6 +2587,8 @@ ClientMap::ClientMap(
|
||||||
m_client(client),
|
m_client(client),
|
||||||
mesh(NULL)
|
mesh(NULL)
|
||||||
{
|
{
|
||||||
|
mesh_mutex.Init();
|
||||||
|
|
||||||
/*m_box = core::aabbox3d<f32>(0,0,0,
|
/*m_box = core::aabbox3d<f32>(0,0,0,
|
||||||
map->getW()*BS, map->getH()*BS, map->getD()*BS);*/
|
map->getW()*BS, map->getH()*BS, map->getD()*BS);*/
|
||||||
/*m_box = core::aabbox3d<f32>(0,0,0,
|
/*m_box = core::aabbox3d<f32>(0,0,0,
|
||||||
|
@ -2773,7 +2598,7 @@ ClientMap::ClientMap(
|
||||||
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
|
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
|
||||||
BS*1000000,BS*1000000,BS*1000000);
|
BS*1000000,BS*1000000,BS*1000000);
|
||||||
|
|
||||||
mesh_mutex.Init();
|
//setPosition(v3f(BS,BS,BS));
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientMap::~ClientMap()
|
ClientMap::~ClientMap()
|
||||||
|
|
|
@ -68,7 +68,7 @@ void MapBlock::setNodeParent(v3s16 p, MapNode & n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p,
|
FastFace * MapBlock::makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||||
v3s16 dir, v3f scale, v3f posRelative_f)
|
v3s16 dir, v3f scale, v3f posRelative_f)
|
||||||
{
|
{
|
||||||
FastFace *f = new FastFace;
|
FastFace *f = new FastFace;
|
||||||
|
@ -118,7 +118,7 @@ FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p,
|
||||||
|
|
||||||
u8 alpha = 255;
|
u8 alpha = 255;
|
||||||
|
|
||||||
if(tile == TILE_WATER)
|
if(tile.id == TILE_WATER)
|
||||||
{
|
{
|
||||||
alpha = 128;
|
alpha = 128;
|
||||||
}
|
}
|
||||||
|
@ -184,25 +184,78 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Gets node tile from any place relative to block.
|
Gets node tile from any place relative to block.
|
||||||
Returns CONTENT_IGNORE if doesn't exist or should not be drawn.
|
Returns TILE_NODE if doesn't exist or should not be drawn.
|
||||||
*/
|
*/
|
||||||
u16 MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
|
TileSpec MapBlock::getNodeTile(v3s16 p, v3s16 face_dir)
|
||||||
{
|
{
|
||||||
|
TileSpec spec;
|
||||||
|
|
||||||
|
spec.feature = TILEFEAT_NONE;
|
||||||
try{
|
try{
|
||||||
MapNode n = getNodeParent(p);
|
MapNode n = getNodeParent(p);
|
||||||
|
|
||||||
//return content_tile(n.d);
|
spec.id = n.getTile(face_dir);
|
||||||
return n.getTile(face_dir);
|
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
//return CONTENT_IGNORE;
|
spec.id = TILE_NONE;
|
||||||
return TILE_NONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check temporary modifications on this node
|
||||||
|
*/
|
||||||
|
core::map<v3s16, NodeMod>::Node *n;
|
||||||
|
n = m_temp_mods.find(p);
|
||||||
|
|
||||||
|
// If modified
|
||||||
|
if(n != NULL)
|
||||||
|
{
|
||||||
|
struct NodeMod mod = n->getValue();
|
||||||
|
if(mod.type == NODEMOD_CHANGECONTENT)
|
||||||
|
{
|
||||||
|
spec.id = content_tile(mod.param, face_dir);
|
||||||
|
}
|
||||||
|
if(mod.type == NODEMOD_CRACK)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 MapBlock::getNodeContent(v3s16 p)
|
u8 MapBlock::getNodeContent(v3s16 p)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Check temporary modifications on this node
|
||||||
|
*/
|
||||||
|
core::map<v3s16, NodeMod>::Node *n;
|
||||||
|
n = m_temp_mods.find(p);
|
||||||
|
|
||||||
|
// If modified
|
||||||
|
if(n != NULL)
|
||||||
|
{
|
||||||
|
struct NodeMod mod = n->getValue();
|
||||||
|
if(mod.type == NODEMOD_CHANGECONTENT)
|
||||||
|
{
|
||||||
|
// Overrides content
|
||||||
|
return mod.param;
|
||||||
|
}
|
||||||
|
if(mod.type == NODEMOD_CRACK)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Content doesn't change.
|
||||||
|
|
||||||
|
face_contents works just like it should, because
|
||||||
|
there should not be faces between differently cracked
|
||||||
|
nodes.
|
||||||
|
|
||||||
|
If a semi-transparent node is cracked in front an
|
||||||
|
another one, it really doesn't matter whether there
|
||||||
|
is a cracked face drawn in between or not.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try{
|
try{
|
||||||
MapNode n = getNodeParent(p);
|
MapNode n = getNodeParent(p);
|
||||||
|
|
||||||
|
@ -243,16 +296,16 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
|
||||||
|
|
||||||
u16 continuous_tiles_count = 0;
|
u16 continuous_tiles_count = 0;
|
||||||
|
|
||||||
u8 tile0 = getNodeTile(p, face_dir);
|
TileSpec tile0 = getNodeTile(p, face_dir);
|
||||||
u8 tile1 = getNodeTile(p + face_dir, -face_dir);
|
TileSpec tile1 = getNodeTile(p + face_dir, -face_dir);
|
||||||
|
|
||||||
for(u16 j=0; j<length; j++)
|
for(u16 j=0; j<length; j++)
|
||||||
{
|
{
|
||||||
bool next_is_different = true;
|
bool next_is_different = true;
|
||||||
|
|
||||||
v3s16 p_next;
|
v3s16 p_next;
|
||||||
u8 tile0_next = 0;
|
TileSpec tile0_next;
|
||||||
u8 tile1_next = 0;
|
TileSpec tile1_next;
|
||||||
u8 light_next = 0;
|
u8 light_next = 0;
|
||||||
|
|
||||||
if(j != length - 1){
|
if(j != length - 1){
|
||||||
|
@ -494,18 +547,22 @@ void MapBlock::updateMesh()
|
||||||
|
|
||||||
const u16 indices[] = {0,1,2,2,3,0};
|
const u16 indices[] = {0,1,2,2,3,0};
|
||||||
|
|
||||||
/*collector.append(g_materials[f->material], f->vertices, 4,
|
if(f->tile.feature == TILEFEAT_NONE)
|
||||||
indices, 6);*/
|
{
|
||||||
/*collector.append(g_materials[f->tile], f->vertices, 4,
|
collector.append(g_tile_materials[f->tile.id], f->vertices, 4,
|
||||||
indices, 6);*/
|
|
||||||
collector.append(g_tile_materials[f->tile], f->vertices, 4,
|
|
||||||
indices, 6);
|
indices, 6);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not implemented
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
collector.fillMesh(mesh_new);
|
collector.fillMesh(mesh_new);
|
||||||
|
|
||||||
// Use VBO for mesh (this just would set this for ever buffer)
|
// Use VBO for mesh (this just would set this for ever buffer)
|
||||||
//mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
|
mesh_new->setHardwareMappingHint(scene::EHM_STATIC);
|
||||||
|
|
||||||
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
|
/*std::cout<<"MapBlock has "<<fastfaces_new->getSize()<<" faces "
|
||||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||||
|
|
|
@ -46,10 +46,27 @@ enum{
|
||||||
|
|
||||||
struct FastFace
|
struct FastFace
|
||||||
{
|
{
|
||||||
u16 tile;
|
TileSpec tile;
|
||||||
video::S3DVertex vertices[4]; // Precalculated vertices
|
video::S3DVertex vertices[4]; // Precalculated vertices
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum NodeModType
|
||||||
|
{
|
||||||
|
NODEMOD_NONE,
|
||||||
|
NODEMOD_CHANGECONTENT, //param is content id
|
||||||
|
NODEMOD_CRACK // param is crack progression
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NodeMod
|
||||||
|
{
|
||||||
|
NodeMod()
|
||||||
|
{
|
||||||
|
type = NODEMOD_NONE;
|
||||||
|
}
|
||||||
|
enum NodeModType type;
|
||||||
|
u16 param;
|
||||||
|
};
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
NODECONTAINER_ID_MAPBLOCK,
|
NODECONTAINER_ID_MAPBLOCK,
|
||||||
|
@ -283,12 +300,12 @@ public:
|
||||||
setNode(x0+x, y0+y, z0+z, node);
|
setNode(x0+x, y0+y, z0+z, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static FastFace * makeFastFace(u16 tile, u8 light, v3f p,
|
static FastFace * makeFastFace(TileSpec tile, u8 light, v3f p,
|
||||||
v3s16 dir, v3f scale, v3f posRelative_f);
|
v3s16 dir, v3f scale, v3f posRelative_f);
|
||||||
|
|
||||||
u8 getFaceLight(v3s16 p, v3s16 face_dir);
|
u8 getFaceLight(v3s16 p, v3s16 face_dir);
|
||||||
|
|
||||||
u16 getNodeTile(v3s16 p, v3s16 face_dir);
|
TileSpec getNodeTile(v3s16 p, v3s16 face_dir);
|
||||||
u8 getNodeContent(v3s16 p);
|
u8 getNodeContent(v3s16 p);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -381,6 +398,24 @@ public:
|
||||||
return m_objects.getCount();
|
return m_objects.getCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Methods for setting temporary modifications to nodes for
|
||||||
|
drawing
|
||||||
|
*/
|
||||||
|
void setTempMod(v3s16 p, NodeMod mod)
|
||||||
|
{
|
||||||
|
m_temp_mods[p] = mod;
|
||||||
|
}
|
||||||
|
void clearTempMod(v3s16 p)
|
||||||
|
{
|
||||||
|
if(m_temp_mods.find(p))
|
||||||
|
m_temp_mods.remove(p);
|
||||||
|
}
|
||||||
|
void clearTempMods()
|
||||||
|
{
|
||||||
|
m_temp_mods.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Serialization
|
Serialization
|
||||||
*/
|
*/
|
||||||
|
@ -432,6 +467,9 @@ private:
|
||||||
|
|
||||||
MapBlockObjectList m_objects;
|
MapBlockObjectList m_objects;
|
||||||
|
|
||||||
|
// Temporary modifications to nodes
|
||||||
|
// These are only used when drawing
|
||||||
|
core::map<v3s16, NodeMod> m_temp_mods;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool blockpos_over_limit(v3s16 p)
|
inline bool blockpos_over_limit(v3s16 p)
|
||||||
|
|
|
@ -41,6 +41,7 @@ u16 g_content_tiles[USEFUL_CONTENT_COUNT][6] =
|
||||||
{TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE},
|
{TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE,TILE_MESE},
|
||||||
{TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
|
{TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
|
||||||
{TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER},
|
{TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER,TILE_WATER},
|
||||||
|
{TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD,TILE_CLOUD},
|
||||||
};
|
};
|
||||||
|
|
||||||
const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
|
const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
|
||||||
|
@ -55,5 +56,6 @@ const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
|
||||||
"mese",
|
"mese",
|
||||||
"mud",
|
"mud",
|
||||||
"water",
|
"water",
|
||||||
|
"cloud",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ enum Content
|
||||||
CONTENT_MESE,
|
CONTENT_MESE,
|
||||||
CONTENT_MUD,
|
CONTENT_MUD,
|
||||||
CONTENT_OCEAN,
|
CONTENT_OCEAN,
|
||||||
|
CONTENT_CLOUD,
|
||||||
|
|
||||||
// This is set to the number of the actual values in this enum
|
// This is set to the number of the actual values in this enum
|
||||||
USEFUL_CONTENT_COUNT
|
USEFUL_CONTENT_COUNT
|
||||||
|
@ -367,7 +368,8 @@ struct MapNode
|
||||||
// If not transparent, can't set light
|
// If not transparent, can't set light
|
||||||
if(light_propagates() == false)
|
if(light_propagates() == false)
|
||||||
return;
|
return;
|
||||||
param = a_light;
|
param &= 0xf0;
|
||||||
|
param |= a_light;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 getTile(v3s16 dir)
|
u16 getTile(v3s16 dir)
|
||||||
|
|
220
src/server.cpp
220
src/server.cpp
|
@ -1101,22 +1101,110 @@ void Server::AsyncRunStep()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run time- and client- related stuff
|
/*
|
||||||
// NOTE: If you intend to add something here, check that it
|
Update digging
|
||||||
// doesn't fit in RemoteClient::GetNextBlocks for example.
|
|
||||||
/*{
|
NOTE: Some of this could be moved to RemoteClient
|
||||||
// Clients are behind connection lock
|
*/
|
||||||
JMutexAutoLock lock(m_con_mutex);
|
|
||||||
|
{
|
||||||
|
JMutexAutoLock envlock(m_env_mutex);
|
||||||
|
JMutexAutoLock conlock(m_con_mutex);
|
||||||
|
|
||||||
for(core::map<u16, RemoteClient*>::Iterator
|
for(core::map<u16, RemoteClient*>::Iterator
|
||||||
i = m_clients.getIterator();
|
i = m_clients.getIterator();
|
||||||
i.atEnd() == false; i++)
|
i.atEnd() == false; i++)
|
||||||
{
|
{
|
||||||
RemoteClient *client = i.getNode()->getValue();
|
RemoteClient *client = i.getNode()->getValue();
|
||||||
//con::Peer *peer = m_con.GetPeer(client->peer_id);
|
Player *player = m_env.getPlayer(client->peer_id);
|
||||||
//client->RunSendingTimeouts(dtime, peer->resend_timeout);
|
|
||||||
|
JMutexAutoLock digmutex(client->m_dig_mutex);
|
||||||
|
|
||||||
|
if(client->m_dig_tool_item == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
client->m_dig_time_remaining -= dtime;
|
||||||
|
|
||||||
|
if(client->m_dig_time_remaining > 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
v3s16 p_under = client->m_dig_position;
|
||||||
|
|
||||||
|
// Mandatory parameter; actually used for nothing
|
||||||
|
core::map<v3s16, MapBlock*> modified_blocks;
|
||||||
|
|
||||||
|
u8 material;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get material at position
|
||||||
|
material = m_env.getMap().getNode(p_under).d;
|
||||||
|
// If it's not diggable, do nothing
|
||||||
|
if(content_diggable(material) == false)
|
||||||
|
{
|
||||||
|
derr_server<<"Server: Not finishing digging: Node not diggable"
|
||||||
|
<<std::endl;
|
||||||
|
client->m_dig_tool_item = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPositionException &e)
|
||||||
|
{
|
||||||
|
derr_server<<"Server: Not finishing digging: Node not found"
|
||||||
|
<<std::endl;
|
||||||
|
client->m_dig_tool_item = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create packet
|
||||||
|
u32 replysize = 8;
|
||||||
|
SharedBuffer<u8> reply(replysize);
|
||||||
|
writeU16(&reply[0], TOCLIENT_REMOVENODE);
|
||||||
|
writeS16(&reply[2], p_under.X);
|
||||||
|
writeS16(&reply[4], p_under.Y);
|
||||||
|
writeS16(&reply[6], p_under.Z);
|
||||||
|
// Send as reliable
|
||||||
|
m_con.SendToAll(0, reply, true);
|
||||||
|
|
||||||
|
if(g_settings.getBool("creative_mode") == false)
|
||||||
|
{
|
||||||
|
// Add to inventory and send inventory
|
||||||
|
InventoryItem *item = new MaterialItem(material, 1);
|
||||||
|
player->inventory.addItem(item);
|
||||||
|
SendInventory(player->peer_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Remove the node
|
||||||
|
(this takes some time so it is done after the quick stuff)
|
||||||
|
*/
|
||||||
|
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Update water
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Update water pressure around modification
|
||||||
|
// This also adds it to m_flow_active_nodes if appropriate
|
||||||
|
|
||||||
|
MapVoxelManipulator v(&m_env.getMap());
|
||||||
|
v.m_disable_water_climb =
|
||||||
|
g_settings.getBool("disable_water_climb");
|
||||||
|
|
||||||
|
VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
||||||
|
}
|
||||||
|
catch(ProcessingLimitException &e)
|
||||||
|
{
|
||||||
|
dstream<<"Processing limit reached (1)"<<std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.blitBack(modified_blocks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
// Send object positions
|
// Send object positions
|
||||||
{
|
{
|
||||||
|
@ -1466,19 +1554,23 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
block->removeObject(id);
|
block->removeObject(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(command == TOSERVER_PRESS_GROUND)
|
else if(command == TOSERVER_GROUND_ACTION)
|
||||||
{
|
{
|
||||||
if(datasize < 17)
|
if(datasize < 17)
|
||||||
return;
|
return;
|
||||||
/*
|
/*
|
||||||
length: 17
|
length: 17
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
[2] u8 button (0=left, 1=right)
|
[2] u8 action
|
||||||
[3] v3s16 nodepos_undersurface
|
[3] v3s16 nodepos_undersurface
|
||||||
[9] v3s16 nodepos_abovesurface
|
[9] v3s16 nodepos_abovesurface
|
||||||
[15] u16 item
|
[15] u16 item
|
||||||
|
actions:
|
||||||
|
0: start digging
|
||||||
|
1: place block
|
||||||
|
2: stop digging (all parameters ignored)
|
||||||
*/
|
*/
|
||||||
u8 button = readU8(&data[2]);
|
u8 action = readU8(&data[2]);
|
||||||
v3s16 p_under;
|
v3s16 p_under;
|
||||||
p_under.X = readS16(&data[3]);
|
p_under.X = readS16(&data[3]);
|
||||||
p_under.Y = readS16(&data[5]);
|
p_under.Y = readS16(&data[5]);
|
||||||
|
@ -1492,13 +1584,11 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
//TODO: Check that target is reasonably close
|
//TODO: Check that target is reasonably close
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Left button digs ground
|
0: start digging
|
||||||
*/
|
*/
|
||||||
if(button == 0)
|
if(action == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
core::map<v3s16, MapBlock*> modified_blocks;
|
|
||||||
|
|
||||||
u8 material;
|
u8 material;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -1513,70 +1603,39 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
catch(InvalidPositionException &e)
|
catch(InvalidPositionException &e)
|
||||||
{
|
{
|
||||||
derr_server<<"Server: Ignoring REMOVENODE: Node not found"
|
derr_server<<"Server: Not starting digging: Node not found"
|
||||||
<<std::endl;
|
<<std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set stuff in RemoteClient
|
||||||
|
*/
|
||||||
|
RemoteClient *client = getClient(peer->id);
|
||||||
|
JMutexAutoLock(client->m_dig_mutex);
|
||||||
|
client->m_dig_tool_item = 0;
|
||||||
|
client->m_dig_position = p_under;
|
||||||
|
client->m_dig_time_remaining = 1.0;
|
||||||
|
|
||||||
// Reset build time counter
|
// Reset build time counter
|
||||||
getClient(peer->id)->m_time_from_building.set(0.0);
|
getClient(peer->id)->m_time_from_building.set(0.0);
|
||||||
|
|
||||||
// Create packet
|
} // action == 0
|
||||||
u32 replysize = 8;
|
|
||||||
SharedBuffer<u8> reply(replysize);
|
|
||||||
writeU16(&reply[0], TOCLIENT_REMOVENODE);
|
|
||||||
writeS16(&reply[2], p_under.X);
|
|
||||||
writeS16(&reply[4], p_under.Y);
|
|
||||||
writeS16(&reply[6], p_under.Z);
|
|
||||||
// Send as reliable
|
|
||||||
m_con.SendToAll(0, reply, true);
|
|
||||||
|
|
||||||
if(g_settings.getBool("creative_mode") == false)
|
/*
|
||||||
|
2: stop digging
|
||||||
|
*/
|
||||||
|
else if(action == 2)
|
||||||
{
|
{
|
||||||
// Add to inventory and send inventory
|
RemoteClient *client = getClient(peer->id);
|
||||||
InventoryItem *item = new MaterialItem(material, 1);
|
JMutexAutoLock digmutex(client->m_dig_mutex);
|
||||||
player->inventory.addItem(item);
|
client->m_dig_tool_item = -1;
|
||||||
SendInventory(player->peer_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Remove the node
|
1: place block
|
||||||
(this takes some time so it is done after the quick stuff)
|
|
||||||
*/
|
*/
|
||||||
m_env.getMap().removeNodeAndUpdate(p_under, modified_blocks);
|
else if(action == 1)
|
||||||
|
|
||||||
/*
|
|
||||||
Update water
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Update water pressure around modification
|
|
||||||
// This also adds it to m_flow_active_nodes if appropriate
|
|
||||||
|
|
||||||
MapVoxelManipulator v(&m_env.getMap());
|
|
||||||
v.m_disable_water_climb =
|
|
||||||
g_settings.getBool("disable_water_climb");
|
|
||||||
|
|
||||||
VoxelArea area(p_under-v3s16(1,1,1), p_under+v3s16(1,1,1));
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
v.updateAreaWaterPressure(area, m_flow_active_nodes);
|
|
||||||
}
|
|
||||||
catch(ProcessingLimitException &e)
|
|
||||||
{
|
|
||||||
dstream<<"Processing limit reached (1)"<<std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
v.blitBack(modified_blocks);
|
|
||||||
|
|
||||||
// Add the node to m_flow_active_nodes.
|
|
||||||
//m_flow_active_nodes[p_under] = 1;
|
|
||||||
|
|
||||||
} // button == 0
|
|
||||||
/*
|
|
||||||
Right button places blocks and stuff
|
|
||||||
*/
|
|
||||||
else if(button == 1)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// Get item
|
// Get item
|
||||||
|
@ -1772,16 +1831,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // button == 1
|
} // action == 1
|
||||||
/*
|
/*
|
||||||
Catch invalid buttons
|
Catch invalid actions
|
||||||
*/
|
*/
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
derr_server<<"WARNING: Server: Invalid button "
|
derr_server<<"WARNING: Server: Invalid action "
|
||||||
<<button<<std::endl;
|
<<action<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
else if(command == TOSERVER_RELEASE)
|
else if(command == TOSERVER_RELEASE)
|
||||||
{
|
{
|
||||||
if(datasize < 3)
|
if(datasize < 3)
|
||||||
|
@ -1791,8 +1851,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
||||||
[0] u16 command
|
[0] u16 command
|
||||||
[2] u8 button
|
[2] u8 button
|
||||||
*/
|
*/
|
||||||
//TODO
|
dstream<<"TOSERVER_RELEASE ignored"<<std::endl;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else if(command == TOSERVER_SIGNTEXT)
|
else if(command == TOSERVER_SIGNTEXT)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -1979,20 +2040,25 @@ void Server::peerAdded(con::Peer *peer)
|
||||||
Set player position
|
Set player position
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// We're going to throw the player to this position
|
||||||
|
//v2s16 nodepos(29990,29990);
|
||||||
|
//v2s16 nodepos(9990,9990);
|
||||||
|
v2s16 nodepos(0,0);
|
||||||
|
v2s16 sectorpos = getNodeSectorPos(nodepos);
|
||||||
// Get zero sector (it could have been unloaded to disk)
|
// Get zero sector (it could have been unloaded to disk)
|
||||||
m_env.getMap().emergeSector(v2s16(0,0));
|
m_env.getMap().emergeSector(sectorpos);
|
||||||
// Get ground height at origin
|
// Get ground height at origin
|
||||||
f32 groundheight = m_env.getMap().getGroundHeight(v2s16(0,0), true);
|
f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true);
|
||||||
// The zero sector should have been generated
|
// The sector should have been generated -> groundheight exists
|
||||||
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
||||||
// Don't go underwater
|
// Don't go underwater
|
||||||
if(groundheight < WATER_LEVEL)
|
if(groundheight < WATER_LEVEL)
|
||||||
groundheight = WATER_LEVEL;
|
groundheight = WATER_LEVEL;
|
||||||
|
|
||||||
player->setPosition(intToFloat(v3s16(
|
player->setPosition(intToFloat(v3s16(
|
||||||
0,
|
nodepos.X,
|
||||||
groundheight + 1,
|
groundheight + 1,
|
||||||
0
|
nodepos.Y
|
||||||
)));
|
)));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
13
src/server.h
13
src/server.h
|
@ -276,7 +276,6 @@ public:
|
||||||
|
|
||||||
RemoteClient():
|
RemoteClient():
|
||||||
m_time_from_building(9999)
|
m_time_from_building(9999)
|
||||||
//m_num_blocks_in_emerge_queue(0)
|
|
||||||
{
|
{
|
||||||
peer_id = 0;
|
peer_id = 0;
|
||||||
serialization_version = SER_FMT_VER_INVALID;
|
serialization_version = SER_FMT_VER_INVALID;
|
||||||
|
@ -285,6 +284,10 @@ public:
|
||||||
|
|
||||||
m_blocks_sent_mutex.Init();
|
m_blocks_sent_mutex.Init();
|
||||||
m_blocks_sending_mutex.Init();
|
m_blocks_sending_mutex.Init();
|
||||||
|
|
||||||
|
m_dig_mutex.Init();
|
||||||
|
m_dig_time_remaining = 0;
|
||||||
|
m_dig_tool_item = -1;
|
||||||
}
|
}
|
||||||
~RemoteClient()
|
~RemoteClient()
|
||||||
{
|
{
|
||||||
|
@ -338,8 +341,6 @@ public:
|
||||||
JMutexAutoLock l2(m_blocks_sent_mutex);
|
JMutexAutoLock l2(m_blocks_sent_mutex);
|
||||||
JMutexAutoLock l3(m_blocks_sending_mutex);
|
JMutexAutoLock l3(m_blocks_sending_mutex);
|
||||||
o<<"RemoteClient "<<peer_id<<": "
|
o<<"RemoteClient "<<peer_id<<": "
|
||||||
/*<<"m_num_blocks_in_emerge_queue="
|
|
||||||
<<m_num_blocks_in_emerge_queue.get()*/
|
|
||||||
<<", m_blocks_sent.size()="<<m_blocks_sent.size()
|
<<", m_blocks_sent.size()="<<m_blocks_sent.size()
|
||||||
<<", m_blocks_sending.size()="<<m_blocks_sending.size()
|
<<", m_blocks_sending.size()="<<m_blocks_sending.size()
|
||||||
<<", m_nearest_unsent_d="<<m_nearest_unsent_d
|
<<", m_nearest_unsent_d="<<m_nearest_unsent_d
|
||||||
|
@ -349,6 +350,12 @@ public:
|
||||||
// Time from last placing or removing blocks
|
// Time from last placing or removing blocks
|
||||||
MutexedVariable<float> m_time_from_building;
|
MutexedVariable<float> m_time_from_building;
|
||||||
|
|
||||||
|
JMutex m_dig_mutex;
|
||||||
|
float m_dig_time_remaining;
|
||||||
|
// -1 = not digging
|
||||||
|
s16 m_dig_tool_item;
|
||||||
|
v3s16 m_dig_position;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
All members that are accessed by many threads should
|
All members that are accessed by many threads should
|
||||||
|
|
|
@ -32,6 +32,7 @@ const char * g_tile_texture_names[TILES_COUNT] =
|
||||||
"mud",
|
"mud",
|
||||||
"tree_top",
|
"tree_top",
|
||||||
"mud_with_grass",
|
"mud_with_grass",
|
||||||
|
"cloud",
|
||||||
};
|
};
|
||||||
|
|
||||||
video::SMaterial g_tile_materials[TILES_COUNT];
|
video::SMaterial g_tile_materials[TILES_COUNT];
|
||||||
|
|
50
src/tile.h
50
src/tile.h
|
@ -38,11 +38,61 @@ enum TileID
|
||||||
TILE_MUD,
|
TILE_MUD,
|
||||||
TILE_TREE_TOP,
|
TILE_TREE_TOP,
|
||||||
TILE_MUD_WITH_GRASS,
|
TILE_MUD_WITH_GRASS,
|
||||||
|
TILE_CLOUD,
|
||||||
|
|
||||||
// Count of tile ids
|
// Count of tile ids
|
||||||
TILES_COUNT
|
TILES_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum TileSpecialFeature
|
||||||
|
{
|
||||||
|
TILEFEAT_NONE,
|
||||||
|
TILEFEAT_CRACK,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TileCrackParam
|
||||||
|
{
|
||||||
|
bool operator==(TileCrackParam &other)
|
||||||
|
{
|
||||||
|
return progression == other.progression;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 progression;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TileSpec
|
||||||
|
{
|
||||||
|
TileSpec()
|
||||||
|
{
|
||||||
|
id = TILE_NONE;
|
||||||
|
feature = TILEFEAT_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(TileSpec &other)
|
||||||
|
{
|
||||||
|
if(id != other.id)
|
||||||
|
return false;
|
||||||
|
if(feature != other.feature)
|
||||||
|
return false;
|
||||||
|
if(feature == TILEFEAT_NONE)
|
||||||
|
return true;
|
||||||
|
if(feature == TILEFEAT_CRACK)
|
||||||
|
{
|
||||||
|
return param.crack == other.param.crack;
|
||||||
|
}
|
||||||
|
// Invalid feature
|
||||||
|
assert(0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u16 id; // Id in g_tile_materials, TILE_NONE=none
|
||||||
|
enum TileSpecialFeature feature;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
TileCrackParam crack;
|
||||||
|
} param;
|
||||||
|
};
|
||||||
|
|
||||||
// A mapping from tiles to names of cached textures
|
// A mapping from tiles to names of cached textures
|
||||||
extern const char * g_tile_texture_names[TILES_COUNT];
|
extern const char * g_tile_texture_names[TILES_COUNT];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue