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
|
||||
|
||||
Command-line options:
|
||||
- Use --help
|
||||
|
||||
Running on Windows:
|
||||
- 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/leaves.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_back.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);
|
||||
sector->insertBlock(block);
|
||||
//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
|
||||
|
||||
|
@ -1412,16 +1441,20 @@ void Client::pressGround(u8 button, v3s16 nodepos_undersurface,
|
|||
}
|
||||
|
||||
/*
|
||||
length: 19
|
||||
length: 17
|
||||
[0] u16 command
|
||||
[2] u8 button (0=left, 1=right)
|
||||
[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_PRESS_GROUND);
|
||||
writeU16(&data[0], TOSERVER_GROUND_ACTION);
|
||||
writeU8(&data[2], button);
|
||||
writeV3S16(&data[3], nodepos_undersurface);
|
||||
writeV3S16(&data[9], nodepos_oversurface);
|
||||
|
@ -1455,9 +1488,35 @@ void Client::clickObject(u8 button, v3s16 blockpos, s16 id, u16 item)
|
|||
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)
|
||||
|
|
|
@ -196,7 +196,7 @@ public:
|
|||
void pressGround(u8 button, v3s16 nodepos_undersurface,
|
||||
v3s16 nodepos_oversurface, 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);
|
||||
|
||||
|
|
|
@ -159,22 +159,21 @@ enum ToServerCommand
|
|||
[11] u16 item
|
||||
*/
|
||||
|
||||
TOSERVER_PRESS_GROUND = 0x28,
|
||||
TOSERVER_GROUND_ACTION = 0x28,
|
||||
/*
|
||||
length: 17
|
||||
[0] u16 command
|
||||
[2] u8 button (0=left, 1=right)
|
||||
[2] u8 action
|
||||
[3] v3s16 nodepos_undersurface
|
||||
[9] v3s16 nodepos_abovesurface
|
||||
[15] u16 item
|
||||
actions:
|
||||
0: start digging (from undersurface)
|
||||
1: place block (to abovesurface)
|
||||
2: stop digging (all parameters ignored)
|
||||
*/
|
||||
|
||||
TOSERVER_RELEASE = 0x29,
|
||||
/*
|
||||
length: 3
|
||||
[0] u16 command
|
||||
[2] u8 button
|
||||
*/
|
||||
TOSERVER_RELEASE = 0x29, // Not used
|
||||
|
||||
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"
|
||||
|
||||
/*
|
||||
|
||||
#!/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.
|
||||
*/
|
||||
// LIGHT_MAX is 15, 0-15 is 16 values
|
||||
/*u8 light_decode_table[LIGHT_MAX+1] =
|
||||
{
|
||||
0,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
6,
|
||||
9,
|
||||
13,
|
||||
19,
|
||||
28,
|
||||
40,
|
||||
58,
|
||||
84,
|
||||
121,
|
||||
176,
|
||||
12,
|
||||
14,
|
||||
16,
|
||||
20,
|
||||
26,
|
||||
34,
|
||||
45,
|
||||
61,
|
||||
81,
|
||||
108,
|
||||
143,
|
||||
191,
|
||||
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
|
||||
|
||||
|
@ -100,48 +96,6 @@ u8 light_decode_table[LIGHT_MAX+1] =
|
|||
191,
|
||||
255,
|
||||
};
|
||||
|
||||
/*
|
||||
#!/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,
|
||||
};*/
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
// This directly sets the range of light
|
||||
#define LIGHT_MAX 14
|
||||
// Light is stored as 4 bits, thus 15 is the maximum.
|
||||
// This brightness is reserved for sunlight
|
||||
#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: Global locale is now set at initialization
|
||||
|
||||
SUGGESTION: 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.
|
||||
|
||||
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
|
||||
SUGG: Fix address to be ipv6 compatible
|
||||
|
||||
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
|
||||
|
@ -81,15 +38,7 @@ SUGGESTION: Use same technique for sector heightmaps as what we're
|
|||
using for UnlimitedHeightmap? (getting all neighbors
|
||||
when generating)
|
||||
|
||||
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.
|
||||
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: Transfer more blocks in a single packet
|
||||
SUGG: A blockdata combiner class, to which blocks are added and at
|
||||
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 also enables server to check if client has received the
|
||||
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
|
||||
memory
|
||||
- ...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)
|
||||
|
||||
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
|
||||
against a global timer when a block is accessed, to make old
|
||||
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
|
||||
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
|
||||
them to clients
|
||||
|
||||
TODO: Get rid of GotSplitPacketException
|
||||
|
||||
SUGG: Implement lighting using VoxelManipulator
|
||||
- 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)
|
||||
- Does their position get saved to a border value or something?
|
||||
- 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
|
||||
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:
|
||||
======================================================================
|
||||
|
||||
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)
|
||||
{
|
||||
left_active = event.MouseInput.isLeftPressed();
|
||||
middle_active = event.MouseInput.isMiddlePressed();
|
||||
right_active = event.MouseInput.isRightPressed();
|
||||
|
||||
if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
|
||||
{
|
||||
leftclicked = true;
|
||||
|
@ -494,6 +494,14 @@ public:
|
|||
{
|
||||
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)
|
||||
{
|
||||
/*dstream<<"event.MouseInput.Wheel="
|
||||
|
@ -530,10 +538,23 @@ public:
|
|||
keyIsDown[i] = false;
|
||||
leftclicked = false;
|
||||
rightclicked = false;
|
||||
leftreleased = false;
|
||||
rightreleased = false;
|
||||
|
||||
left_active = false;
|
||||
middle_active = false;
|
||||
right_active = false;
|
||||
}
|
||||
|
||||
bool leftclicked;
|
||||
bool rightclicked;
|
||||
bool leftreleased;
|
||||
bool rightreleased;
|
||||
|
||||
bool left_active;
|
||||
bool middle_active;
|
||||
bool right_active;
|
||||
|
||||
private:
|
||||
// We use this array to store the current state of each key
|
||||
bool keyIsDown[KEY_KEY_CODES_COUNT];
|
||||
|
@ -550,13 +571,24 @@ public:
|
|||
virtual ~InputHandler()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool isKeyDown(EKEY_CODE keyCode) = 0;
|
||||
|
||||
virtual v2s32 getMousePos() = 0;
|
||||
virtual void setMousePos(s32 x, s32 y) = 0;
|
||||
|
||||
virtual bool getLeftState() = 0;
|
||||
virtual bool getRightState() = 0;
|
||||
|
||||
virtual bool getLeftClicked() = 0;
|
||||
virtual bool getRightClicked() = 0;
|
||||
virtual void resetLeftClicked() = 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) {};
|
||||
|
||||
|
@ -597,6 +629,15 @@ public:
|
|||
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()
|
||||
{
|
||||
if(g_game_focused == false)
|
||||
|
@ -618,6 +659,27 @@ public:
|
|||
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()
|
||||
{
|
||||
resetRightClicked();
|
||||
|
@ -651,6 +713,15 @@ public:
|
|||
mousepos = v2s32(x,y);
|
||||
}
|
||||
|
||||
virtual bool getLeftState()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool getRightState()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool getLeftClicked()
|
||||
{
|
||||
return leftclicked;
|
||||
|
@ -668,6 +739,21 @@ public:
|
|||
rightclicked = false;
|
||||
}
|
||||
|
||||
virtual bool getLeftReleased()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool getRightReleased()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual void resetLeftReleased()
|
||||
{
|
||||
}
|
||||
virtual void resetRightReleased()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void step(float dtime)
|
||||
{
|
||||
{
|
||||
|
@ -1563,6 +1649,11 @@ int main(int argc, char *argv[])
|
|||
//gui::IGUIWindow* input_window = NULL;
|
||||
gui::IGUIStaticText* input_guitext = NULL;
|
||||
|
||||
/*
|
||||
Digging animation
|
||||
*/
|
||||
//f32
|
||||
|
||||
/*
|
||||
Main loop
|
||||
*/
|
||||
|
@ -1920,6 +2011,10 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
else // selected_object == NULL
|
||||
{
|
||||
|
||||
/*
|
||||
Find out which node we are pointing at
|
||||
*/
|
||||
|
||||
bool nodefound = false;
|
||||
v3s16 nodepos;
|
||||
|
@ -2066,6 +2161,9 @@ int main(int argc, char *argv[])
|
|||
} // regular block
|
||||
} // for coords
|
||||
|
||||
/*static v3s16 oldnodepos;
|
||||
static bool oldnodefound = false;*/
|
||||
|
||||
if(nodefound)
|
||||
{
|
||||
//std::cout<<DTIME<<"nodefound == true"<<std::endl;
|
||||
|
@ -2076,41 +2174,54 @@ int main(int argc, char *argv[])
|
|||
if(nodepos != nodepos_old){
|
||||
std::cout<<DTIME<<"Pointing at ("<<nodepos.X<<","
|
||||
<<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);
|
||||
|
||||
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;
|
||||
client.pressGround(0, nodepos, neighbourpos, g_selected_item);
|
||||
}
|
||||
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;
|
||||
client.pressGround(1, nodepos, neighbourpos, g_selected_item);
|
||||
}
|
||||
|
||||
nodepos_old = nodepos;
|
||||
}
|
||||
else{
|
||||
//std::cout<<DTIME<<"nodefound == false"<<std::endl;
|
||||
//positiontextgui->setText(L"");
|
||||
}
|
||||
|
||||
/*oldnodefound = nodefound;
|
||||
oldnodepos = nodepos;*/
|
||||
|
||||
} // selected_object == NULL
|
||||
|
||||
g_input->resetLeftClicked();
|
||||
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
|
||||
*/
|
||||
|
|
183
src/map.cpp
183
src/map.cpp
|
@ -18,7 +18,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
#include "map.h"
|
||||
//#include "player.h"
|
||||
#include "main.h"
|
||||
#include "jmutexautolock.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)
|
||||
{
|
||||
JMutexAutoLock lock(m_sector_mutex);
|
||||
|
@ -160,20 +152,6 @@ MapBlock * Map::getBlockNoCreate(v3s16 p3d)
|
|||
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)
|
||||
{
|
||||
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.
|
||||
|
||||
|
@ -813,11 +641,6 @@ void Map::updateLighting(core::map<v3s16, MapBlock*> & a_blocks,
|
|||
bool debug=false;
|
||||
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, u8> unlight_from;
|
||||
|
@ -2764,6 +2587,8 @@ ClientMap::ClientMap(
|
|||
m_client(client),
|
||||
mesh(NULL)
|
||||
{
|
||||
mesh_mutex.Init();
|
||||
|
||||
/*m_box = core::aabbox3d<f32>(0,0,0,
|
||||
map->getW()*BS, map->getH()*BS, map->getD()*BS);*/
|
||||
/*m_box = core::aabbox3d<f32>(0,0,0,
|
||||
|
@ -2772,8 +2597,8 @@ ClientMap::ClientMap(
|
|||
map->getSizeNodes().Z * BS);*/
|
||||
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
|
||||
BS*1000000,BS*1000000,BS*1000000);
|
||||
|
||||
mesh_mutex.Init();
|
||||
|
||||
//setPosition(v3f(BS,BS,BS));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
FastFace *f = new FastFace;
|
||||
|
@ -118,7 +118,7 @@ FastFace * MapBlock::makeFastFace(u16 tile, u8 light, v3f p,
|
|||
|
||||
u8 alpha = 255;
|
||||
|
||||
if(tile == TILE_WATER)
|
||||
if(tile.id == TILE_WATER)
|
||||
{
|
||||
alpha = 128;
|
||||
}
|
||||
|
@ -184,25 +184,78 @@ u8 MapBlock::getFaceLight(v3s16 p, v3s16 face_dir)
|
|||
|
||||
/*
|
||||
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{
|
||||
MapNode n = getNodeParent(p);
|
||||
|
||||
//return content_tile(n.d);
|
||||
return n.getTile(face_dir);
|
||||
spec.id = n.getTile(face_dir);
|
||||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
//return CONTENT_IGNORE;
|
||||
return TILE_NONE;
|
||||
spec.id = 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)
|
||||
{
|
||||
/*
|
||||
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{
|
||||
MapNode n = getNodeParent(p);
|
||||
|
||||
|
@ -243,16 +296,16 @@ void MapBlock::updateFastFaceRow(v3s16 startpos,
|
|||
|
||||
u16 continuous_tiles_count = 0;
|
||||
|
||||
u8 tile0 = getNodeTile(p, face_dir);
|
||||
u8 tile1 = getNodeTile(p + face_dir, -face_dir);
|
||||
TileSpec tile0 = getNodeTile(p, face_dir);
|
||||
TileSpec tile1 = getNodeTile(p + face_dir, -face_dir);
|
||||
|
||||
for(u16 j=0; j<length; j++)
|
||||
{
|
||||
bool next_is_different = true;
|
||||
|
||||
v3s16 p_next;
|
||||
u8 tile0_next = 0;
|
||||
u8 tile1_next = 0;
|
||||
TileSpec tile0_next;
|
||||
TileSpec tile1_next;
|
||||
u8 light_next = 0;
|
||||
|
||||
if(j != length - 1){
|
||||
|
@ -493,19 +546,23 @@ void MapBlock::updateMesh()
|
|||
FastFace *f = *i;
|
||||
|
||||
const u16 indices[] = {0,1,2,2,3,0};
|
||||
|
||||
/*collector.append(g_materials[f->material], f->vertices, 4,
|
||||
indices, 6);*/
|
||||
/*collector.append(g_materials[f->tile], f->vertices, 4,
|
||||
indices, 6);*/
|
||||
collector.append(g_tile_materials[f->tile], f->vertices, 4,
|
||||
indices, 6);
|
||||
|
||||
if(f->tile.feature == TILEFEAT_NONE)
|
||||
{
|
||||
collector.append(g_tile_materials[f->tile.id], f->vertices, 4,
|
||||
indices, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not implemented
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
collector.fillMesh(mesh_new);
|
||||
|
||||
// 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 "
|
||||
<<"and uses "<<mesh_new->getMeshBufferCount()
|
||||
|
|
|
@ -46,10 +46,27 @@ enum{
|
|||
|
||||
struct FastFace
|
||||
{
|
||||
u16 tile;
|
||||
TileSpec tile;
|
||||
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
|
||||
{
|
||||
NODECONTAINER_ID_MAPBLOCK,
|
||||
|
@ -283,12 +300,12 @@ public:
|
|||
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);
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
|
@ -380,6 +397,24 @@ public:
|
|||
{
|
||||
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
|
||||
|
@ -432,6 +467,9 @@ private:
|
|||
|
||||
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)
|
||||
|
|
|
@ -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_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD,TILE_MUD},
|
||||
{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] =
|
||||
|
@ -55,5 +56,6 @@ const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] =
|
|||
"mese",
|
||||
"mud",
|
||||
"water",
|
||||
"cloud",
|
||||
};
|
||||
|
||||
|
|
|
@ -75,6 +75,7 @@ enum Content
|
|||
CONTENT_MESE,
|
||||
CONTENT_MUD,
|
||||
CONTENT_OCEAN,
|
||||
CONTENT_CLOUD,
|
||||
|
||||
// This is set to the number of the actual values in this enum
|
||||
USEFUL_CONTENT_COUNT
|
||||
|
@ -367,7 +368,8 @@ struct MapNode
|
|||
// If not transparent, can't set light
|
||||
if(light_propagates() == false)
|
||||
return;
|
||||
param = a_light;
|
||||
param &= 0xf0;
|
||||
param |= a_light;
|
||||
}
|
||||
|
||||
u16 getTile(v3s16 dir)
|
||||
|
|
228
src/server.cpp
228
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
|
||||
// doesn't fit in RemoteClient::GetNextBlocks for example.
|
||||
/*{
|
||||
// Clients are behind connection lock
|
||||
JMutexAutoLock lock(m_con_mutex);
|
||||
/*
|
||||
Update digging
|
||||
|
||||
NOTE: Some of this could be moved to RemoteClient
|
||||
*/
|
||||
|
||||
{
|
||||
JMutexAutoLock envlock(m_env_mutex);
|
||||
JMutexAutoLock conlock(m_con_mutex);
|
||||
|
||||
for(core::map<u16, RemoteClient*>::Iterator
|
||||
i = m_clients.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
RemoteClient *client = i.getNode()->getValue();
|
||||
//con::Peer *peer = m_con.GetPeer(client->peer_id);
|
||||
//client->RunSendingTimeouts(dtime, peer->resend_timeout);
|
||||
Player *player = m_env.getPlayer(client->peer_id);
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -1466,19 +1554,23 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
block->removeObject(id);
|
||||
}
|
||||
}
|
||||
else if(command == TOSERVER_PRESS_GROUND)
|
||||
else if(command == TOSERVER_GROUND_ACTION)
|
||||
{
|
||||
if(datasize < 17)
|
||||
return;
|
||||
/*
|
||||
length: 17
|
||||
[0] u16 command
|
||||
[2] u8 button (0=left, 1=right)
|
||||
[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 button = readU8(&data[2]);
|
||||
u8 action = readU8(&data[2]);
|
||||
v3s16 p_under;
|
||||
p_under.X = readS16(&data[3]);
|
||||
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
|
||||
|
||||
/*
|
||||
Left button digs ground
|
||||
0: start digging
|
||||
*/
|
||||
if(button == 0)
|
||||
if(action == 0)
|
||||
{
|
||||
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
|
||||
u8 material;
|
||||
|
||||
try
|
||||
|
@ -1513,70 +1603,39 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
}
|
||||
catch(InvalidPositionException &e)
|
||||
{
|
||||
derr_server<<"Server: Ignoring REMOVENODE: Node not found"
|
||||
derr_server<<"Server: Not starting digging: Node not found"
|
||||
<<std::endl;
|
||||
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
|
||||
getClient(peer->id)->m_time_from_building.set(0.0);
|
||||
|
||||
// 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);
|
||||
}
|
||||
} // action == 0
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
// Add the node to m_flow_active_nodes.
|
||||
//m_flow_active_nodes[p_under] = 1;
|
||||
|
||||
} // button == 0
|
||||
/*
|
||||
Right button places blocks and stuff
|
||||
2: stop digging
|
||||
*/
|
||||
else if(button == 1)
|
||||
else if(action == 2)
|
||||
{
|
||||
RemoteClient *client = getClient(peer->id);
|
||||
JMutexAutoLock digmutex(client->m_dig_mutex);
|
||||
client->m_dig_tool_item = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
1: place block
|
||||
*/
|
||||
else if(action == 1)
|
||||
{
|
||||
|
||||
// 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
|
||||
{
|
||||
derr_server<<"WARNING: Server: Invalid button "
|
||||
<<button<<std::endl;
|
||||
derr_server<<"WARNING: Server: Invalid action "
|
||||
<<action<<std::endl;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else if(command == TOSERVER_RELEASE)
|
||||
{
|
||||
if(datasize < 3)
|
||||
|
@ -1791,8 +1851,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
[0] u16 command
|
||||
[2] u8 button
|
||||
*/
|
||||
//TODO
|
||||
dstream<<"TOSERVER_RELEASE ignored"<<std::endl;
|
||||
}
|
||||
#endif
|
||||
else if(command == TOSERVER_SIGNTEXT)
|
||||
{
|
||||
/*
|
||||
|
@ -1978,21 +2039,26 @@ void Server::peerAdded(con::Peer *peer)
|
|||
/*
|
||||
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)
|
||||
m_env.getMap().emergeSector(v2s16(0,0));
|
||||
m_env.getMap().emergeSector(sectorpos);
|
||||
// Get ground height at origin
|
||||
f32 groundheight = m_env.getMap().getGroundHeight(v2s16(0,0), true);
|
||||
// The zero sector should have been generated
|
||||
f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true);
|
||||
// The sector should have been generated -> groundheight exists
|
||||
assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE);
|
||||
// Don't go underwater
|
||||
if(groundheight < WATER_LEVEL)
|
||||
groundheight = WATER_LEVEL;
|
||||
|
||||
player->setPosition(intToFloat(v3s16(
|
||||
0,
|
||||
nodepos.X,
|
||||
groundheight + 1,
|
||||
0
|
||||
nodepos.Y
|
||||
)));
|
||||
|
||||
/*
|
||||
|
|
13
src/server.h
13
src/server.h
|
@ -276,7 +276,6 @@ public:
|
|||
|
||||
RemoteClient():
|
||||
m_time_from_building(9999)
|
||||
//m_num_blocks_in_emerge_queue(0)
|
||||
{
|
||||
peer_id = 0;
|
||||
serialization_version = SER_FMT_VER_INVALID;
|
||||
|
@ -285,6 +284,10 @@ public:
|
|||
|
||||
m_blocks_sent_mutex.Init();
|
||||
m_blocks_sending_mutex.Init();
|
||||
|
||||
m_dig_mutex.Init();
|
||||
m_dig_time_remaining = 0;
|
||||
m_dig_tool_item = -1;
|
||||
}
|
||||
~RemoteClient()
|
||||
{
|
||||
|
@ -338,8 +341,6 @@ public:
|
|||
JMutexAutoLock l2(m_blocks_sent_mutex);
|
||||
JMutexAutoLock l3(m_blocks_sending_mutex);
|
||||
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_sending.size()="<<m_blocks_sending.size()
|
||||
<<", m_nearest_unsent_d="<<m_nearest_unsent_d
|
||||
|
@ -349,6 +350,12 @@ public:
|
|||
// Time from last placing or removing blocks
|
||||
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:
|
||||
/*
|
||||
All members that are accessed by many threads should
|
||||
|
|
|
@ -32,6 +32,7 @@ const char * g_tile_texture_names[TILES_COUNT] =
|
|||
"mud",
|
||||
"tree_top",
|
||||
"mud_with_grass",
|
||||
"cloud",
|
||||
};
|
||||
|
||||
video::SMaterial g_tile_materials[TILES_COUNT];
|
||||
|
|
50
src/tile.h
50
src/tile.h
|
@ -38,11 +38,61 @@ enum TileID
|
|||
TILE_MUD,
|
||||
TILE_TREE_TOP,
|
||||
TILE_MUD_WITH_GRASS,
|
||||
TILE_CLOUD,
|
||||
|
||||
// Count of tile ids
|
||||
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
|
||||
extern const char * g_tile_texture_names[TILES_COUNT];
|
||||
|
||||
|
|
Loading…
Reference in New Issue