Merge Minetest commits
This commit is contained in:
commit
ae66c6a782
|
@ -848,14 +848,25 @@ core.register_chatcommand("kick", {
|
|||
})
|
||||
|
||||
core.register_chatcommand("clearobjects", {
|
||||
params = "[full|quick]",
|
||||
description = "clear all objects in world",
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
core.log("action", name .. " clears all objects.")
|
||||
options = {}
|
||||
if param == "" or param == "full" then
|
||||
options.mode = "full"
|
||||
elseif param == "quick" then
|
||||
options.mode = "quick"
|
||||
else
|
||||
return false, "Invalid usage, see /help clearobjects."
|
||||
end
|
||||
|
||||
core.log("action", name .. " clears all objects ("
|
||||
.. options.mode .. " mode).")
|
||||
core.chat_send_all("Clearing all objects. This may take long."
|
||||
.. " You may experience a timeout. (by "
|
||||
.. name .. ")")
|
||||
core.clear_objects()
|
||||
core.clear_objects(options)
|
||||
core.log("action", "Object clearing done.")
|
||||
core.chat_send_all("*** Cleared all objects.")
|
||||
end,
|
||||
|
|
|
@ -88,25 +88,26 @@ function core.dir_to_facedir(dir, is6d)
|
|||
end
|
||||
end
|
||||
|
||||
-- Table of possible dirs
|
||||
local facedir_to_dir = {
|
||||
{x= 0, y=0, z= 1},
|
||||
{x= 1, y=0, z= 0},
|
||||
{x= 0, y=0, z=-1},
|
||||
{x=-1, y=0, z= 0},
|
||||
{x= 0, y=-1, z= 0},
|
||||
{x= 0, y=1, z= 0},
|
||||
}
|
||||
-- Mapping from facedir value to index in facedir_to_dir.
|
||||
local facedir_to_dir_map = {
|
||||
[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
1, 5, 3, 6,
|
||||
1, 6, 3, 5,
|
||||
1, 4, 3, 2,
|
||||
}
|
||||
function core.facedir_to_dir(facedir)
|
||||
--a table of possible dirs
|
||||
return ({{x=0, y=0, z=1},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
{x=0, y=1, z=0}})
|
||||
|
||||
--indexed into by a table of correlating facedirs
|
||||
[({[0]=1, 2, 3, 4,
|
||||
5, 2, 6, 4,
|
||||
6, 2, 5, 4,
|
||||
1, 5, 3, 6,
|
||||
1, 6, 3, 5,
|
||||
1, 4, 3, 2})
|
||||
|
||||
--indexed into by the facedir in question
|
||||
[facedir]]
|
||||
return facedir_to_dir[facedir_to_dir_map[facedir]]
|
||||
end
|
||||
|
||||
function core.dir_to_wallmounted(dir)
|
||||
|
@ -131,17 +132,17 @@ function core.dir_to_wallmounted(dir)
|
|||
end
|
||||
end
|
||||
|
||||
-- table of dirs in wallmounted order
|
||||
local wallmounted_to_dir = {
|
||||
[0] = {x = 0, y = 1, z = 0},
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1},
|
||||
}
|
||||
function core.wallmounted_to_dir(wallmounted)
|
||||
-- table of dirs in wallmounted order
|
||||
return ({[0] = {x = 0, y = 1, z = 0},
|
||||
{x = 0, y = -1, z = 0},
|
||||
{x = 1, y = 0, z = 0},
|
||||
{x = -1, y = 0, z = 0},
|
||||
{x = 0, y = 0, z = 1},
|
||||
{x = 0, y = 0, z = -1}})
|
||||
|
||||
--indexed into by the wallmounted in question
|
||||
[wallmounted]
|
||||
return wallmounted_to_dir[wallmounted]
|
||||
end
|
||||
|
||||
function core.get_node_drops(nodename, toolname)
|
||||
|
|
|
@ -326,6 +326,11 @@ fsaa (FSAA) enum 0 0,1,2,4,8,16
|
|||
# Thy only work with the OpenGL video backend.
|
||||
enable_shaders (Shaders) bool true
|
||||
|
||||
[****Tone Mapping]
|
||||
|
||||
# Enables filmic tone mapping
|
||||
tone_mapping (Filmic tone mapping) bool false
|
||||
|
||||
[****Bumpmapping]
|
||||
|
||||
# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack
|
||||
|
@ -697,12 +702,6 @@ enable_pvp (Player versus Player) bool true
|
|||
# If this is set, players will always (re)spawn at the given position.
|
||||
static_spawnpoint (Static spawnpoint) string
|
||||
|
||||
# Maximum distance above water level for player spawn.
|
||||
# Larger values result in spawn points closer to (x = 0, z = 0).
|
||||
# Smaller values may result in a suitable spawn point not being found,
|
||||
# resulting in a spawn at (0, 0, 0) possibly buried underground.
|
||||
vertical_spawn_range (Vertical spawn range) int 16
|
||||
|
||||
# If enabled, new players cannot join with an empty password.
|
||||
disallow_empty_password (Disallow empty passwords) bool false
|
||||
|
||||
|
|
|
@ -20,6 +20,38 @@ bool normalTexturePresent = false;
|
|||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
|
||||
/* Hable's UC2 Tone mapping parameters
|
||||
A = 0.22;
|
||||
B = 0.30;
|
||||
C = 0.10;
|
||||
D = 0.20;
|
||||
E = 0.01;
|
||||
F = 0.30;
|
||||
W = 11.2;
|
||||
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
||||
*/
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
|
||||
}
|
||||
|
||||
vec4 applyToneMapping(vec4 color)
|
||||
{
|
||||
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
||||
const float gamma = 1.6;
|
||||
const float exposureBias = 5.5;
|
||||
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
||||
// Precalculated white_scale from
|
||||
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
vec3 whiteScale = vec3(1.036015346);
|
||||
color.rgb *= whiteScale;
|
||||
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
||||
}
|
||||
#endif
|
||||
|
||||
void get_texture_flags()
|
||||
{
|
||||
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
|
||||
|
@ -160,22 +192,26 @@ void main(void)
|
|||
color = base.rgb;
|
||||
#endif
|
||||
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, base.a);
|
||||
col = vec4(col.rgb, base.a);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -22,6 +22,38 @@ bool texSeamless = false;
|
|||
const float e = 2.718281828459;
|
||||
const float BS = 10.0;
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
|
||||
/* Hable's UC2 Tone mapping parameters
|
||||
A = 0.22;
|
||||
B = 0.30;
|
||||
C = 0.10;
|
||||
D = 0.20;
|
||||
E = 0.01;
|
||||
F = 0.30;
|
||||
W = 11.2;
|
||||
equation used: ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F
|
||||
*/
|
||||
|
||||
vec3 uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
return ((x * (0.22 * x + 0.03) + 0.002) / (x * (0.22 * x + 0.3) + 0.06)) - 0.03334;
|
||||
}
|
||||
|
||||
vec4 applyToneMapping(vec4 color)
|
||||
{
|
||||
color = vec4(pow(color.rgb, vec3(2.2)), color.a);
|
||||
const float gamma = 1.6;
|
||||
const float exposureBias = 5.5;
|
||||
color.rgb = uncharted2Tonemap(exposureBias * color.rgb);
|
||||
// Precalculated white_scale from
|
||||
//vec3 whiteScale = 1.0 / uncharted2Tonemap(vec3(W));
|
||||
vec3 whiteScale = vec3(1.036015346);
|
||||
color.rgb *= whiteScale;
|
||||
return vec4(pow(color.rgb, vec3(1.0 / gamma)), color.a);
|
||||
}
|
||||
#endif
|
||||
|
||||
void get_texture_flags()
|
||||
{
|
||||
vec4 flags = texture2D(textureFlags, vec2(0.0, 0.0));
|
||||
|
@ -116,22 +148,26 @@ vec4 base = texture2D(baseTexture, uv).rgba;
|
|||
color = base.rgb;
|
||||
#endif
|
||||
|
||||
vec4 col = vec4(color.rgb * gl_Color.rgb, 1.0);
|
||||
|
||||
#if MATERIAL_TYPE == TILE_MATERIAL_LIQUID_TRANSPARENT || MATERIAL_TYPE == TILE_MATERIAL_LIQUID_OPAQUE
|
||||
float alpha = gl_Color.a;
|
||||
vec4 col = vec4(color.rgb, alpha);
|
||||
col *= gl_Color;
|
||||
if(fogDistance != 0.0){
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
alpha = mix(alpha, 0.0, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, alpha);
|
||||
col = vec4(col.rgb, alpha);
|
||||
#else
|
||||
vec4 col = vec4(color.rgb, base.a);
|
||||
col *= gl_Color;
|
||||
if(fogDistance != 0.0){
|
||||
if (fogDistance != 0.0) {
|
||||
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
|
||||
col = mix(col, skyBgColor, d);
|
||||
}
|
||||
gl_FragColor = vec4(col.rgb, base.a);
|
||||
col = vec4(col.rgb, base.a);
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_TONE_MAPPING
|
||||
gl_FragColor = applyToneMapping(col);
|
||||
#else
|
||||
gl_FragColor = col;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2046,8 +2046,12 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* `minetest.generate_decorations(vm, pos1, pos2)`
|
||||
* Generate all registered decorations within the VoxelManip `vm` and in the area from `pos1` to `pos2`.
|
||||
* `pos1` and `pos2` are optional and default to mapchunk minp and maxp.
|
||||
* `minetest.clear_objects()`
|
||||
* clear all objects in the environments
|
||||
* `minetest.clear_objects([options])`
|
||||
* Clear all objects in the environment
|
||||
* Takes an optional table as an argument with the field `mode`.
|
||||
* mode = `"full"`: Load and go through every mapblock, clearing objects (default).
|
||||
* mode = `"quick"`: Clear objects immediately in loaded mapblocks;
|
||||
clear objects in unloaded mapblocks only when the mapblocks are next activated.
|
||||
* `minetest.emerge_area(pos1, pos2, [callback], [param])`
|
||||
* Queue all blocks in the area from `pos1` to `pos2`, inclusive, to be asynchronously
|
||||
* fetched from memory, loaded from disk, or if inexistent, generates them.
|
||||
|
@ -2149,6 +2153,8 @@ and `minetest.auth_reload` call the authetification handler.
|
|||
* Convert a facedir back into a vector aimed directly out the "back" of a node
|
||||
* `minetest.dir_to_wallmounted(dir)`
|
||||
* Convert a vector to a wallmounted value, used for `paramtype2="wallmounted"`
|
||||
* `minetest.wallmounted_to_dir(wallmounted)`
|
||||
* Convert a wallmounted value back into a vector aimed directly out the "back" of a node
|
||||
* `minetest.get_node_drops(nodename, toolname)`
|
||||
* Returns list of item names.
|
||||
* **Note**: This will be removed or modified in a future version.
|
||||
|
|
|
@ -353,6 +353,12 @@
|
|||
# type: bool
|
||||
# enable_shaders = true
|
||||
|
||||
##### Tone mapping
|
||||
# Enables filmic tone mapping.
|
||||
# Requires shaders to be enabled.
|
||||
# type: bool
|
||||
# tone_mapping = false
|
||||
|
||||
##### Bumpmapping
|
||||
|
||||
# Enables bumpmapping for textures. Normalmaps need to be supplied by the texture pack
|
||||
|
@ -833,13 +839,6 @@
|
|||
# type: string
|
||||
# static_spawnpoint =
|
||||
|
||||
# Maximum distance above water level for player spawn.
|
||||
# Larger values result in spawn points closer to (x = 0, z = 0).
|
||||
# Smaller values may result in a suitable spawn point not being found,
|
||||
# resulting in a spawn at (0, 0, 0) possibly buried underground.
|
||||
# type: int
|
||||
# vertical_spawn_range = 16
|
||||
|
||||
# If enabled, new players cannot join with an empty password.
|
||||
# type: bool
|
||||
# disallow_empty_password = false
|
||||
|
|
|
@ -1471,13 +1471,13 @@ ClientActiveObject * Client::getSelectedActiveObject(
|
|||
{
|
||||
ClientActiveObject *obj = objects[i].obj;
|
||||
|
||||
core::aabbox3d<f32> *selection_box = obj->getSelectionBox();
|
||||
aabb3f *selection_box = obj->getSelectionBox();
|
||||
if(selection_box == NULL)
|
||||
continue;
|
||||
|
||||
v3f pos = obj->getPosition();
|
||||
|
||||
core::aabbox3d<f32> offsetted_box(
|
||||
aabb3f offsetted_box(
|
||||
selection_box->MinEdge + pos,
|
||||
selection_box->MaxEdge + pos
|
||||
);
|
||||
|
|
|
@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define TILE_HEADER
|
||||
|
||||
#include "irrlichttypes.h"
|
||||
#include "irr_v2d.h"
|
||||
#include "irr_v3d.h"
|
||||
#include <ITexture.h>
|
||||
#include <IrrlichtDevice.h>
|
||||
|
|
|
@ -50,7 +50,7 @@ ClientMap::ClientMap(
|
|||
m_camera_direction(0,0,1),
|
||||
m_camera_fov(M_PI)
|
||||
{
|
||||
m_box = core::aabbox3d<f32>(-BS*1000000,-BS*1000000,-BS*1000000,
|
||||
m_box = aabb3f(-BS*1000000,-BS*1000000,-BS*1000000,
|
||||
BS*1000000,BS*1000000,BS*1000000);
|
||||
|
||||
/* TODO: Add a callback function so these can be updated when a setting
|
||||
|
@ -157,12 +157,9 @@ void ClientMap::updateDrawList(video::IVideoDriver* driver)
|
|||
}
|
||||
m_drawlist.clear();
|
||||
|
||||
m_camera_mutex.lock();
|
||||
v3f camera_position = m_camera_position;
|
||||
v3f camera_direction = m_camera_direction;
|
||||
f32 camera_fov = m_camera_fov;
|
||||
//v3s16 camera_offset = m_camera_offset;
|
||||
m_camera_mutex.unlock();
|
||||
|
||||
// Use a higher fov to accomodate faster camera movements.
|
||||
// Blocks are cropped better when they are drawn.
|
||||
|
@ -433,11 +430,9 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
|
|||
int crack = m_client->getCrackLevel();
|
||||
u32 daynight_ratio = m_client->getEnv().getDayNightRatio();
|
||||
|
||||
m_camera_mutex.lock();
|
||||
v3f camera_position = m_camera_position;
|
||||
v3f camera_direction = m_camera_direction;
|
||||
f32 camera_fov = m_camera_fov;
|
||||
m_camera_mutex.unlock();
|
||||
|
||||
/*
|
||||
Get all blocks and draw all visible ones
|
||||
|
@ -799,11 +794,7 @@ void ClientMap::renderPostFx(CameraMode cam_mode)
|
|||
// Sadly ISceneManager has no "post effects" render pass, in that case we
|
||||
// could just register for that and handle it in renderMap().
|
||||
|
||||
m_camera_mutex.lock();
|
||||
v3f camera_position = m_camera_position;
|
||||
m_camera_mutex.unlock();
|
||||
|
||||
MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
|
||||
MapNode n = getNodeNoEx(floatToInt(m_camera_position, BS));
|
||||
|
||||
// - If the player is in a solid node, make everything black.
|
||||
// - If the player is in liquid, draw a semi-transparent overlay.
|
||||
|
|
|
@ -89,7 +89,6 @@ public:
|
|||
|
||||
void updateCamera(v3f pos, v3f dir, f32 fov, v3s16 offset)
|
||||
{
|
||||
MutexAutoLock lock(m_camera_mutex);
|
||||
m_camera_position = pos;
|
||||
m_camera_direction = dir;
|
||||
m_camera_fov = fov;
|
||||
|
@ -116,7 +115,7 @@ public:
|
|||
renderMap(driver, SceneManager->getSceneNodeRenderPass());
|
||||
}
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
virtual const aabb3f &getBoundingBox() const
|
||||
{
|
||||
return m_box;
|
||||
}
|
||||
|
@ -141,7 +140,7 @@ public:
|
|||
private:
|
||||
Client *m_client;
|
||||
|
||||
core::aabbox3d<f32> m_box;
|
||||
aabb3f m_box;
|
||||
|
||||
MapDrawControl &m_control;
|
||||
|
||||
|
@ -149,7 +148,6 @@ private:
|
|||
v3f m_camera_direction;
|
||||
f32 m_camera_fov;
|
||||
v3s16 m_camera_offset;
|
||||
Mutex m_camera_mutex;
|
||||
|
||||
std::map<v3s16, MapBlock*> m_drawlist;
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
virtual void updateLight(u8 light_at_pos){}
|
||||
virtual void updateLightNoCheck(u8 light_at_pos){}
|
||||
virtual v3s16 getLightPosition(){return v3s16(0,0,0);}
|
||||
virtual core::aabbox3d<f32>* getSelectionBox(){return NULL;}
|
||||
virtual aabb3f *getSelectionBox() { return NULL; }
|
||||
virtual bool getCollisionBox(aabb3f *toset){return false;}
|
||||
virtual bool collideWithObjects(){return false;}
|
||||
virtual v3f getPosition(){return v3f(0,0,0);}
|
||||
|
|
|
@ -62,7 +62,7 @@ Clouds::Clouds(
|
|||
g_settings->registerChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
|
||||
m_box = core::aabbox3d<f32>(-BS*1000000,m_cloud_y-BS,-BS*1000000,
|
||||
m_box = aabb3f(-BS*1000000,m_cloud_y-BS,-BS*1000000,
|
||||
BS*1000000,m_cloud_y+BS,BS*1000000);
|
||||
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
virtual const aabb3f &getBoundingBox() const
|
||||
{
|
||||
return m_box;
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
m_camera_offset = camera_offset;
|
||||
m_box = core::aabbox3d<f32>(-BS * 1000000, m_cloud_y - BS - BS * camera_offset.Y, -BS * 1000000,
|
||||
m_box = aabb3f(-BS * 1000000, m_cloud_y - BS - BS * camera_offset.Y, -BS * 1000000,
|
||||
BS * 1000000, m_cloud_y + BS - BS * camera_offset.Y, BS * 1000000);
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ public:
|
|||
|
||||
private:
|
||||
video::SMaterial m_material;
|
||||
core::aabbox3d<f32> m_box;
|
||||
aabb3f m_box;
|
||||
s16 m_passed_cloud_y;
|
||||
float m_cloud_y;
|
||||
u16 m_cloud_radius_i;
|
||||
|
|
|
@ -309,7 +309,7 @@ public:
|
|||
|
||||
void initialize(const std::string &data);
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox()
|
||||
aabb3f *getSelectionBox()
|
||||
{return &m_selection_box;}
|
||||
v3f getPosition()
|
||||
{return m_position;}
|
||||
|
@ -319,7 +319,7 @@ public:
|
|||
|
||||
bool getCollisionBox(aabb3f *toset) { return false; }
|
||||
private:
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
aabb3f m_selection_box;
|
||||
scene::IMeshSceneNode *m_node;
|
||||
v3f m_position;
|
||||
std::string m_itemstring;
|
||||
|
@ -674,7 +674,7 @@ GenericCAO::~GenericCAO()
|
|||
removeFromScene(true);
|
||||
}
|
||||
|
||||
core::aabbox3d<f32>* GenericCAO::getSelectionBox()
|
||||
aabb3f *GenericCAO::getSelectionBox()
|
||||
{
|
||||
if(!m_prop.is_visible || !m_is_visible || m_is_local_player || getParent() != NULL)
|
||||
return NULL;
|
||||
|
@ -1185,7 +1185,7 @@ void GenericCAO::step(float dtime, ClientEnvironment *env)
|
|||
|
||||
if(m_prop.physical)
|
||||
{
|
||||
core::aabbox3d<f32> box = m_prop.collisionbox;
|
||||
aabb3f box = m_prop.collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
|
|
|
@ -65,7 +65,7 @@ private:
|
|||
//
|
||||
scene::ISceneManager *m_smgr;
|
||||
IrrlichtDevice *m_irr;
|
||||
core::aabbox3d<f32> m_selection_box;
|
||||
aabb3f m_selection_box;
|
||||
scene::IMeshSceneNode *m_meshnode;
|
||||
scene::IAnimatedMeshSceneNode *m_animated_meshnode;
|
||||
WieldMeshSceneNode *m_wield_meshnode;
|
||||
|
@ -127,7 +127,7 @@ public:
|
|||
|
||||
bool collideWithObjects();
|
||||
|
||||
core::aabbox3d<f32>* getSelectionBox();
|
||||
aabb3f *getSelectionBox();
|
||||
|
||||
v3f getPosition();
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
|
|||
else
|
||||
{
|
||||
if(m_prop.physical){
|
||||
core::aabbox3d<f32> box = m_prop.collisionbox;
|
||||
aabb3f box = m_prop.collisionbox;
|
||||
box.MinEdge *= BS;
|
||||
box.MaxEdge *= BS;
|
||||
collisionMoveResult moveresult;
|
||||
|
@ -786,7 +786,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
|||
m_prop.hp_max = PLAYER_MAX_HP;
|
||||
m_prop.physical = false;
|
||||
m_prop.weight = 75;
|
||||
m_prop.collisionbox = core::aabbox3d<f32>(-1/3.,-1.0,-1/3., 1/3.,1.0,1/3.);
|
||||
m_prop.collisionbox = aabb3f(-1/3.,-1.0,-1/3., 1/3.,1.0,1/3.);
|
||||
// start of default appearance, this should be overwritten by LUA
|
||||
m_prop.visual = "upright_sprite";
|
||||
m_prop.visual_size = v2f(1, 2);
|
||||
|
|
|
@ -159,6 +159,7 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("texture_clean_transparent", "false");
|
||||
settings->setDefault("texture_min_size", "32");
|
||||
settings->setDefault("preload_item_visuals", "false");
|
||||
settings->setDefault("tone_mapping", "false");
|
||||
settings->setDefault("enable_bumpmapping", "false");
|
||||
settings->setDefault("enable_parallax_occlusion", "false");
|
||||
settings->setDefault("generate_normalmaps", "false");
|
||||
|
@ -246,7 +247,6 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("default_privs", "interact, shout");
|
||||
settings->setDefault("player_transfer_distance", "0");
|
||||
settings->setDefault("enable_pvp", "true");
|
||||
settings->setDefault("vertical_spawn_range", "128");
|
||||
settings->setDefault("disallow_empty_password", "false");
|
||||
settings->setDefault("disable_anticheat", "false");
|
||||
settings->setDefault("enable_rollback_recording", "false");
|
||||
|
|
|
@ -334,6 +334,18 @@ v3s16 EmergeManager::getContainingChunk(v3s16 blockpos, s16 chunksize)
|
|||
}
|
||||
|
||||
|
||||
int EmergeManager::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
if (m_mapgens.size() == 0 || !m_mapgens[0]) {
|
||||
errorstream << "EmergeManager: getSpawnLevelAtPoint() called"
|
||||
" before mapgen init" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return m_mapgens[0]->getSpawnLevelAtPoint(p);
|
||||
}
|
||||
|
||||
|
||||
int EmergeManager::getGroundLevelAtPoint(v2s16 p)
|
||||
{
|
||||
if (m_mapgens.size() == 0 || !m_mapgens[0]) {
|
||||
|
|
|
@ -136,6 +136,7 @@ public:
|
|||
|
||||
// Mapgen helpers methods
|
||||
Biome *getBiomeAtPoint(v3s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
bool isBlockUnderground(v3s16 blockpos);
|
||||
|
||||
|
|
|
@ -354,6 +354,7 @@ ServerEnvironment::ServerEnvironment(ServerMap *map,
|
|||
m_active_block_interval_overload_skip(0),
|
||||
m_game_time(0),
|
||||
m_game_time_fraction_counter(0),
|
||||
m_last_clear_objects_time(0),
|
||||
m_recommended_send_interval(0.1),
|
||||
m_max_lag_estimate(0.1)
|
||||
{
|
||||
|
@ -503,6 +504,7 @@ void ServerEnvironment::saveMeta()
|
|||
Settings args;
|
||||
args.setU64("game_time", m_game_time);
|
||||
args.setU64("time_of_day", getTimeOfDay());
|
||||
args.setU64("last_clear_objects_time", m_last_clear_objects_time);
|
||||
args.writeLines(ss);
|
||||
ss<<"EnvArgsEnd\n";
|
||||
|
||||
|
@ -546,6 +548,13 @@ void ServerEnvironment::loadMeta()
|
|||
// This is not as important
|
||||
setTimeOfDay(9000);
|
||||
}
|
||||
|
||||
try {
|
||||
m_last_clear_objects_time = args.getU64("last_clear_objects_time");
|
||||
} catch (SettingNotFoundException &e) {
|
||||
// If missing, do as if clearObjects was never called
|
||||
m_last_clear_objects_time = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct ActiveABM
|
||||
|
@ -739,13 +748,19 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
|
|||
// Get time difference
|
||||
u32 dtime_s = 0;
|
||||
u32 stamp = block->getTimestamp();
|
||||
if(m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
|
||||
dtime_s = m_game_time - block->getTimestamp();
|
||||
if (m_game_time > stamp && stamp != BLOCK_TIMESTAMP_UNDEFINED)
|
||||
dtime_s = m_game_time - stamp;
|
||||
dtime_s += additional_dtime;
|
||||
|
||||
/*infostream<<"ServerEnvironment::activateBlock(): block timestamp: "
|
||||
<<stamp<<", game time: "<<m_game_time<<std::endl;*/
|
||||
|
||||
// Remove stored static objects if clearObjects was called since block's timestamp
|
||||
if (stamp == BLOCK_TIMESTAMP_UNDEFINED || stamp < m_last_clear_objects_time) {
|
||||
block->m_static_objects.m_stored.clear();
|
||||
// do not set changed flag to avoid unnecessary mapblock writes
|
||||
}
|
||||
|
||||
// Set current time as timestamp
|
||||
block->setTimestampNoChangedFlag(m_game_time);
|
||||
|
||||
|
@ -858,22 +873,22 @@ void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f po
|
|||
}
|
||||
}
|
||||
|
||||
void ServerEnvironment::clearAllObjects()
|
||||
void ServerEnvironment::clearObjects(ClearObjectsMode mode)
|
||||
{
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Removing all active objects"<<std::endl;
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Removing all active objects" << std::endl;
|
||||
std::vector<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
for (std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
if(obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||
if (obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||
continue;
|
||||
u16 id = i->first;
|
||||
// Delete static object if block is loaded
|
||||
if(obj->m_static_exists){
|
||||
if (obj->m_static_exists) {
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(obj->m_static_block);
|
||||
if(block){
|
||||
if (block) {
|
||||
block->m_static_objects.remove(id);
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||
MOD_REASON_CLEAR_ALL_OBJECTS);
|
||||
|
@ -881,7 +896,7 @@ void ServerEnvironment::clearAllObjects()
|
|||
}
|
||||
}
|
||||
// If known by some client, don't delete immediately
|
||||
if(obj->m_known_by_count > 0){
|
||||
if (obj->m_known_by_count > 0) {
|
||||
obj->m_pending_deactivation = true;
|
||||
obj->m_removed = true;
|
||||
continue;
|
||||
|
@ -893,39 +908,46 @@ void ServerEnvironment::clearAllObjects()
|
|||
m_script->removeObjectReference(obj);
|
||||
|
||||
// Delete active object
|
||||
if(obj->environmentDeletes())
|
||||
if (obj->environmentDeletes())
|
||||
delete obj;
|
||||
// Id to be removed from m_active_objects
|
||||
objects_to_remove.push_back(id);
|
||||
}
|
||||
|
||||
// Remove references from m_active_objects
|
||||
for(std::vector<u16>::iterator i = objects_to_remove.begin();
|
||||
for (std::vector<u16>::iterator i = objects_to_remove.begin();
|
||||
i != objects_to_remove.end(); ++i) {
|
||||
m_active_objects.erase(*i);
|
||||
}
|
||||
|
||||
// Get list of loaded blocks
|
||||
std::vector<v3s16> loaded_blocks;
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Listing all loaded blocks"<<std::endl;
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Listing all loaded blocks" << std::endl;
|
||||
m_map->listAllLoadedBlocks(loaded_blocks);
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Done listing all loaded blocks: "
|
||||
<<loaded_blocks.size()<<std::endl;
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Done listing all loaded blocks: "
|
||||
<< loaded_blocks.size()<<std::endl;
|
||||
|
||||
// Get list of loadable blocks
|
||||
std::vector<v3s16> loadable_blocks;
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Listing all loadable blocks"<<std::endl;
|
||||
m_map->listAllLoadableBlocks(loadable_blocks);
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Done listing all loadable blocks: "
|
||||
<<loadable_blocks.size()
|
||||
<<", now clearing"<<std::endl;
|
||||
if (mode == CLEAR_OBJECTS_MODE_FULL) {
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Listing all loadable blocks" << std::endl;
|
||||
m_map->listAllLoadableBlocks(loadable_blocks);
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Done listing all loadable blocks: "
|
||||
<< loadable_blocks.size() << std::endl;
|
||||
} else {
|
||||
loadable_blocks = loaded_blocks;
|
||||
}
|
||||
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Now clearing objects in " << loadable_blocks.size()
|
||||
<< " blocks" << std::endl;
|
||||
|
||||
// Grab a reference on each loaded block to avoid unloading it
|
||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
for (std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i) {
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
|
@ -934,24 +956,27 @@ void ServerEnvironment::clearAllObjects()
|
|||
}
|
||||
|
||||
// Remove objects in all loadable blocks
|
||||
u32 unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks");
|
||||
unload_interval = MYMAX(unload_interval, 1);
|
||||
u32 unload_interval = U32_MAX;
|
||||
if (mode == CLEAR_OBJECTS_MODE_FULL) {
|
||||
unload_interval = g_settings->getS32("max_clearobjects_extra_loaded_blocks");
|
||||
unload_interval = MYMAX(unload_interval, 1);
|
||||
}
|
||||
u32 report_interval = loadable_blocks.size() / 10;
|
||||
u32 num_blocks_checked = 0;
|
||||
u32 num_blocks_cleared = 0;
|
||||
u32 num_objs_cleared = 0;
|
||||
for(std::vector<v3s16>::iterator i = loadable_blocks.begin();
|
||||
for (std::vector<v3s16>::iterator i = loadable_blocks.begin();
|
||||
i != loadable_blocks.end(); ++i) {
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->emergeBlock(p, false);
|
||||
if(!block){
|
||||
errorstream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Failed to emerge block "<<PP(p)<<std::endl;
|
||||
if (!block) {
|
||||
errorstream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Failed to emerge block " << PP(p) << std::endl;
|
||||
continue;
|
||||
}
|
||||
u32 num_stored = block->m_static_objects.m_stored.size();
|
||||
u32 num_active = block->m_static_objects.m_active.size();
|
||||
if(num_stored != 0 || num_active != 0){
|
||||
if (num_stored != 0 || num_active != 0) {
|
||||
block->m_static_objects.m_stored.clear();
|
||||
block->m_static_objects.m_active.clear();
|
||||
block->raiseModified(MOD_STATE_WRITE_NEEDED,
|
||||
|
@ -961,23 +986,23 @@ void ServerEnvironment::clearAllObjects()
|
|||
}
|
||||
num_blocks_checked++;
|
||||
|
||||
if(report_interval != 0 &&
|
||||
num_blocks_checked % report_interval == 0){
|
||||
if (report_interval != 0 &&
|
||||
num_blocks_checked % report_interval == 0) {
|
||||
float percent = 100.0 * (float)num_blocks_checked /
|
||||
loadable_blocks.size();
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Cleared "<<num_objs_cleared<<" objects"
|
||||
<<" in "<<num_blocks_cleared<<" blocks ("
|
||||
<<percent<<"%)"<<std::endl;
|
||||
loadable_blocks.size();
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Cleared " << num_objs_cleared << " objects"
|
||||
<< " in " << num_blocks_cleared << " blocks ("
|
||||
<< percent << "%)" << std::endl;
|
||||
}
|
||||
if(num_blocks_checked % unload_interval == 0){
|
||||
if (num_blocks_checked % unload_interval == 0) {
|
||||
m_map->unloadUnreferencedBlocks();
|
||||
}
|
||||
}
|
||||
m_map->unloadUnreferencedBlocks();
|
||||
|
||||
// Drop references that were added above
|
||||
for(std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
for (std::vector<v3s16>::iterator i = loaded_blocks.begin();
|
||||
i != loaded_blocks.end(); ++i) {
|
||||
v3s16 p = *i;
|
||||
MapBlock *block = m_map->getBlockNoCreateNoEx(p);
|
||||
|
@ -985,9 +1010,11 @@ void ServerEnvironment::clearAllObjects()
|
|||
block->refDrop();
|
||||
}
|
||||
|
||||
infostream<<"ServerEnvironment::clearAllObjects(): "
|
||||
<<"Finished: Cleared "<<num_objs_cleared<<" objects"
|
||||
<<" in "<<num_blocks_cleared<<" blocks"<<std::endl;
|
||||
m_last_clear_objects_time = m_game_time;
|
||||
|
||||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Finished: Cleared " << num_objs_cleared << " objects"
|
||||
<< " in " << num_blocks_cleared << " blocks" << std::endl;
|
||||
}
|
||||
|
||||
void ServerEnvironment::step(float dtime)
|
||||
|
|
|
@ -203,6 +203,18 @@ public:
|
|||
private:
|
||||
};
|
||||
|
||||
/*
|
||||
Operation mode for ServerEnvironment::clearObjects()
|
||||
*/
|
||||
enum ClearObjectsMode {
|
||||
// Load and go through every mapblock, clearing objects
|
||||
CLEAR_OBJECTS_MODE_FULL,
|
||||
|
||||
// Clear objects immediately in loaded mapblocks;
|
||||
// clear objects in unloaded mapblocks only when the mapblocks are next activated.
|
||||
CLEAR_OBJECTS_MODE_QUICK,
|
||||
};
|
||||
|
||||
/*
|
||||
The server-side environment.
|
||||
|
||||
|
@ -319,8 +331,8 @@ public:
|
|||
// Find all active objects inside a radius around a point
|
||||
void getObjectsInsideRadius(std::vector<u16> &objects, v3f pos, float radius);
|
||||
|
||||
// Clear all objects, loading and going through every MapBlock
|
||||
void clearAllObjects();
|
||||
// Clear objects, loading and going through every MapBlock
|
||||
void clearObjects(ClearObjectsMode mode);
|
||||
|
||||
// This makes stuff happen
|
||||
void step(f32 dtime);
|
||||
|
@ -410,6 +422,10 @@ private:
|
|||
u32 m_game_time;
|
||||
// A helper variable for incrementing the latter
|
||||
float m_game_time_fraction_counter;
|
||||
// Time of last clearObjects call (game time).
|
||||
// When a mapblock older than this is loaded, its objects are cleared.
|
||||
u32 m_last_clear_objects_time;
|
||||
// Active block modifiers
|
||||
std::vector<ABMWithState> m_abms;
|
||||
// An interval for generally sending object positions and stuff
|
||||
float m_recommended_send_interval;
|
||||
|
|
|
@ -1497,7 +1497,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
|
|||
258 + m_fields.size()
|
||||
);
|
||||
|
||||
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, spec.flabel.c_str());
|
||||
gui::IGUIButton *e = Environment->addButton(rect, this, spec.fid, L"");
|
||||
|
||||
if (spec.fname == data->focused_fieldname) {
|
||||
Environment->setFocus(e);
|
||||
|
@ -1515,6 +1515,12 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
|
|||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
m_itemimages.push_back(ImageDrawSpec("", item_name, pos, geom));
|
||||
|
||||
StaticTextSpec label_spec(
|
||||
utf8_to_wide(label),
|
||||
rect
|
||||
);
|
||||
m_static_texts.push_back(label_spec);
|
||||
return;
|
||||
}
|
||||
errorstream<< "Invalid ItemImagebutton element(" << parts.size() << "): '" << element << "'" << std::endl;
|
||||
|
@ -1883,6 +1889,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||
m_boxes.clear();
|
||||
m_tooltips.clear();
|
||||
m_inventory_rings.clear();
|
||||
m_static_texts.clear();
|
||||
|
||||
// Set default values (fits old formspec values)
|
||||
m_bgcolor = video::SColor(140,0,0,0);
|
||||
|
@ -2462,6 +2469,15 @@ void GUIFormSpecMenu::drawMenu()
|
|||
m_pointer = m_device->getCursorControl()->getPosition();
|
||||
#endif
|
||||
|
||||
/*
|
||||
Draw static text elements
|
||||
*/
|
||||
for (u32 i = 0; i < m_static_texts.size(); i++) {
|
||||
const StaticTextSpec &spec = m_static_texts[i];
|
||||
video::SColor color(255, 255, 255, 255);
|
||||
m_font->draw(spec.text.c_str(), spec.rect, color, true, true, &spec.rect);
|
||||
}
|
||||
|
||||
/*
|
||||
Draw fields/buttons tooltips
|
||||
*/
|
||||
|
|
|
@ -228,6 +228,20 @@ class GUIFormSpecMenu : public GUIModalMenu
|
|||
irr::video::SColor color;
|
||||
};
|
||||
|
||||
struct StaticTextSpec {
|
||||
StaticTextSpec()
|
||||
{
|
||||
}
|
||||
StaticTextSpec(const std::wstring &a_text,
|
||||
const core::rect<s32> &a_rect):
|
||||
text(a_text),
|
||||
rect(a_rect)
|
||||
{
|
||||
}
|
||||
std::wstring text;
|
||||
core::rect<s32> rect;
|
||||
};
|
||||
|
||||
public:
|
||||
GUIFormSpecMenu(irr::IrrlichtDevice* dev,
|
||||
gui::IGUIElement* parent, s32 id,
|
||||
|
@ -339,6 +353,7 @@ protected:
|
|||
std::vector<ImageDrawSpec> m_itemimages;
|
||||
std::vector<BoxDrawSpec> m_boxes;
|
||||
std::vector<FieldSpec> m_fields;
|
||||
std::vector<StaticTextSpec> m_static_texts;
|
||||
std::vector<std::pair<FieldSpec,GUITable*> > m_tables;
|
||||
std::vector<std::pair<FieldSpec,gui::IGUICheckBox*> > m_checkboxes;
|
||||
std::map<std::string, TooltipSpec> m_tooltips;
|
||||
|
|
21
src/hud.cpp
21
src/hud.cpp
|
@ -84,6 +84,8 @@ Hud::Hud(video::IVideoDriver *driver, scene::ISceneManager* smgr,
|
|||
|
||||
m_selection_mesh = NULL;
|
||||
m_selection_boxes.clear();
|
||||
m_halo_boxes.clear();
|
||||
|
||||
m_selection_pos = v3f(0.0, 0.0, 0.0);
|
||||
std::string mode = g_settings->get("node_highlighting");
|
||||
m_selection_material.Lighting = false;
|
||||
|
@ -574,10 +576,23 @@ void Hud::updateSelectionMesh(const v3s16 &camera_offset)
|
|||
0,0,1,1
|
||||
};
|
||||
|
||||
m_selection_mesh = convertNodeboxesToMesh(m_selection_boxes, texture_uv);
|
||||
// Use single halo box instead of multiple overlapping boxes.
|
||||
// Temporary solution - problem can be solved with multiple
|
||||
// rendering targets, or some method to remove inner surfaces.
|
||||
// Thats because of halo transparency.
|
||||
|
||||
// scale final halo mesh
|
||||
scaleMesh(m_selection_mesh, v3f(1.08, 1.08, 1.08));
|
||||
aabb3f halo_box(100.0, 100.0, 100.0, -100.0, -100.0, -100.0);
|
||||
m_halo_boxes.clear();
|
||||
|
||||
for (std::vector<aabb3f>::iterator
|
||||
i = m_selection_boxes.begin();
|
||||
i != m_selection_boxes.end(); ++i) {
|
||||
halo_box.addInternalBox(*i);
|
||||
}
|
||||
|
||||
m_halo_boxes.push_back(halo_box);
|
||||
m_selection_mesh = convertNodeboxesToMesh(
|
||||
m_halo_boxes, texture_uv, 0.5);
|
||||
}
|
||||
|
||||
void Hud::resizeHotbar() {
|
||||
|
|
|
@ -162,6 +162,7 @@ private:
|
|||
video::SColor hbar_colors[4];
|
||||
|
||||
std::vector<aabb3f> m_selection_boxes;
|
||||
std::vector<aabb3f> m_halo_boxes;
|
||||
v3f m_selection_pos;
|
||||
v3f m_selection_pos_with_offset;
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3.0 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef LUAENTITY_COMMON_HEADER
|
||||
#define LUAENTITY_COMMON_HEADER
|
||||
|
||||
#define LUAENTITY_CMD_UPDATE_POSITION 0
|
||||
#define LUAENTITY_CMD_SET_TEXTURE_MOD 1
|
||||
#define LUAENTITY_CMD_SET_SPRITE 2
|
||||
#define LUAENTITY_CMD_PUNCHED 3
|
||||
#define LUAENTITY_CMD_UPDATE_ARMOR_GROUPS 4
|
||||
|
||||
#endif
|
||||
|
|
@ -181,6 +181,13 @@ public:
|
|||
virtual void makeChunk(BlockMakeData *data) {}
|
||||
virtual int getGroundLevelAtPoint(v2s16 p) { return 0; }
|
||||
|
||||
// getSpawnLevelAtPoint() is a function within each mapgen that returns a
|
||||
// suitable y co-ordinate for player spawn ('suitable' usually meaning
|
||||
// within 16 nodes of water_level). If a suitable spawn level cannot be
|
||||
// found at the specified (X, Z) 'MAX_MAP_GENERATION_LIMIT' is returned to
|
||||
// signify this and to cause Server::findSpawnPos() to try another (X, Z).
|
||||
virtual int getSpawnLevelAtPoint(v2s16 p) { return 0; }
|
||||
|
||||
private:
|
||||
DISABLE_CLASS_COPY(Mapgen);
|
||||
};
|
||||
|
|
|
@ -192,18 +192,25 @@ void MapgenFlatParams::writeParams(Settings *settings) const
|
|||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
int MapgenFlat::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenFlat::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
s16 level_at_point = ground_level;
|
||||
float n_terrain = NoisePerlin2D(&noise_terrain->np, p.X, p.Y, seed);
|
||||
|
||||
if ((spflags & MGFLAT_LAKES) && n_terrain < lake_threshold) {
|
||||
s16 depress = (lake_threshold - n_terrain) * lake_steepness;
|
||||
return ground_level - depress;
|
||||
level_at_point = ground_level -
|
||||
(lake_threshold - n_terrain) * lake_steepness;
|
||||
} else if ((spflags & MGFLAT_HILLS) && n_terrain > hill_threshold) {
|
||||
s16 rise = (n_terrain - hill_threshold) * hill_steepness;
|
||||
return ground_level + rise;
|
||||
} else {
|
||||
return ground_level;
|
||||
level_at_point = ground_level +
|
||||
(n_terrain - hill_threshold) * hill_steepness;
|
||||
}
|
||||
|
||||
if (ground_level < water_level) // Ocean world, allow spawn in water
|
||||
return MYMAX(level_at_point, water_level);
|
||||
else if (level_at_point > water_level)
|
||||
return level_at_point; // Spawn on land
|
||||
else
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
~MapgenFlat();
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
void calculateNoise();
|
||||
s16 generateTerrain();
|
||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
||||
|
|
|
@ -209,17 +209,28 @@ void MapgenFractalParams::writeParams(Settings *settings) const
|
|||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
int MapgenFractal::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenFractal::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
s16 search_start = 128;
|
||||
s16 search_end = -128;
|
||||
|
||||
for (s16 y = search_start; y >= search_end; y--) {
|
||||
if (getFractalAtPoint(p.X, y, p.Y))
|
||||
return y;
|
||||
bool solid_below = false; // Dry solid node is present below to spawn on
|
||||
u8 air_count = 0; // Consecutive air nodes above the dry solid node
|
||||
s16 seabed_level = NoisePerlin2D(&noise_seabed->np, p.X, p.Y, seed);
|
||||
// Seabed can rise above water_level or might be raised to create dry land
|
||||
s16 search_start = MYMAX(seabed_level, water_level + 1);
|
||||
if (seabed_level > water_level)
|
||||
solid_below = true;
|
||||
|
||||
for (s16 y = search_start; y <= search_start + 128; y++) {
|
||||
if (getFractalAtPoint(p.X, y, p.Y)) { // Fractal node
|
||||
solid_below = true;
|
||||
air_count = 0;
|
||||
} else if (solid_below) { // Air above solid node
|
||||
air_count++;
|
||||
if (air_count == 2)
|
||||
return y - 2;
|
||||
}
|
||||
}
|
||||
|
||||
return -MAX_MAP_GENERATION_LIMIT;
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ public:
|
|||
~MapgenFractal();
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
void calculateNoise();
|
||||
bool getFractalAtPoint(s16 x, s16 y, s16 z);
|
||||
s16 generateTerrain();
|
||||
|
|
|
@ -99,7 +99,7 @@ void MapgenSinglenode::makeChunk(BlockMakeData *data)
|
|||
}
|
||||
|
||||
|
||||
int MapgenSinglenode::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenSinglenode::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public:
|
|||
~MapgenSinglenode();
|
||||
|
||||
void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
};
|
||||
|
||||
struct MapgenFactorySinglenode : public MapgenFactory {
|
||||
|
|
|
@ -171,7 +171,7 @@ void MapgenV5Params::writeParams(Settings *settings) const
|
|||
}
|
||||
|
||||
|
||||
int MapgenV5::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenV5::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
//TimeTaker t("getGroundLevelAtPoint", NULL, PRECISION_MICRO);
|
||||
|
||||
|
@ -182,24 +182,25 @@ int MapgenV5::getGroundLevelAtPoint(v2s16 p)
|
|||
f *= 1.6;
|
||||
float h = NoisePerlin2D(&noise_height->np, p.X, p.Y, seed);
|
||||
|
||||
s16 search_start = 128; // Only bother searching this range, actual
|
||||
s16 search_end = -128; // ground level is rarely higher or lower.
|
||||
|
||||
for (s16 y = search_start; y >= search_end; y--) {
|
||||
for (s16 y = 128; y >= -128; y--) {
|
||||
float n_ground = NoisePerlin3D(&noise_ground->np, p.X, y, p.Y, seed);
|
||||
// If solid
|
||||
if (n_ground * f > y - h) {
|
||||
|
||||
if (n_ground * f > y - h) { // If solid
|
||||
// If either top 2 nodes of search are solid this is inside a
|
||||
// mountain or floatland with no space for the player to spawn.
|
||||
if (y >= search_start - 1)
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
else
|
||||
return y; // Ground below at least 2 nodes of space
|
||||
// mountain or floatland with possibly no space for the player to spawn.
|
||||
if (y >= 127) {
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
} else { // Ground below at least 2 nodes of empty space
|
||||
if (y <= water_level || y > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
return y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//printf("getGroundLevelAtPoint: %dus\n", t.stop());
|
||||
return -MAX_MAP_GENERATION_LIMIT;
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn position, no ground found
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ public:
|
|||
~MapgenV5();
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
void calculateNoise();
|
||||
int generateBaseTerrain();
|
||||
MgStoneType generateBiomes(float *heat_map, float *humidity_map);
|
||||
|
|
|
@ -318,6 +318,17 @@ int MapgenV6::getGroundLevelAtPoint(v2s16 p)
|
|||
}
|
||||
|
||||
|
||||
int MapgenV6::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
s16 level_at_point = baseTerrainLevelFromNoise(p) + MGV6_AVERAGE_MUD_AMOUNT;
|
||||
if (level_at_point <= water_level ||
|
||||
level_at_point > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
return level_at_point;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////// Noise functions
|
||||
|
||||
float MapgenV6::getMudAmount(v2s16 p)
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
|
||||
void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
|
||||
float baseTerrainLevel(float terrain_base, float terrain_higher,
|
||||
float steepness, float height_select);
|
||||
|
|
|
@ -202,7 +202,7 @@ void MapgenV7Params::writeParams(Settings *settings) const
|
|||
///////////////////////////////////////
|
||||
|
||||
|
||||
int MapgenV7::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
// Base terrain calculation
|
||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
||||
|
@ -210,22 +210,24 @@ int MapgenV7::getGroundLevelAtPoint(v2s16 p)
|
|||
// Ridge/river terrain calculation
|
||||
float width = 0.2;
|
||||
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||
// actually computing the depth of the ridge is much more expensive;
|
||||
// if inside a river, simply guess
|
||||
// if inside a river this is an unsuitable spawn point
|
||||
if (fabs(uwatern) <= width)
|
||||
return water_level - 10;
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
|
||||
// Mountain terrain calculation
|
||||
int iters = 128; // don't even bother iterating more than 128 times..
|
||||
int iters = 128;
|
||||
while (iters--) {
|
||||
//current point would have been air
|
||||
if (!getMountainTerrainAtPoint(p.X, y, p.Y))
|
||||
return y;
|
||||
|
||||
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // Air, y is ground level
|
||||
if (y <= water_level || y > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
return y;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
|
||||
return y;
|
||||
// Unsuitable spawn point, no ground surface found
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
~MapgenV7();
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
Biome *getBiomeAtPoint(v3s16 p);
|
||||
|
||||
float baseTerrainLevelAtPoint(s16 x, s16 z);
|
||||
|
|
|
@ -56,8 +56,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
//Profiler *mapgen_profiler = &mapgen_prof;
|
||||
|
||||
static FlagDesc flagdesc_mapgen_valleys[] = {
|
||||
{"altitude_chill", MG_VALLEYS_ALT_CHILL},
|
||||
{"humid_rivers", MG_VALLEYS_HUMID_RIVERS},
|
||||
{"altitude_chill", MGVALLEYS_ALT_CHILL},
|
||||
{"humid_rivers", MGVALLEYS_HUMID_RIVERS},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -86,8 +86,8 @@ MapgenValleys::MapgenValleys(int mapgenid, MapgenParams *params, EmergeManager *
|
|||
MapgenValleysParams *sp = (MapgenValleysParams *)params->sparams;
|
||||
this->spflags = sp->spflags;
|
||||
|
||||
this->humid_rivers = (spflags & MG_VALLEYS_HUMID_RIVERS);
|
||||
this->use_altitude_chill = (spflags & MG_VALLEYS_ALT_CHILL);
|
||||
this->humid_rivers = (spflags & MGVALLEYS_HUMID_RIVERS);
|
||||
this->use_altitude_chill = (spflags & MGVALLEYS_ALT_CHILL);
|
||||
|
||||
this->altitude_chill = sp->altitude_chill;
|
||||
this->humidity_adjust = params->np_biome_humidity.offset - 50.f;
|
||||
|
@ -181,7 +181,7 @@ MapgenValleys::~MapgenValleys()
|
|||
|
||||
MapgenValleysParams::MapgenValleysParams()
|
||||
{
|
||||
spflags = MG_VALLEYS_HUMID_RIVERS | MG_VALLEYS_ALT_CHILL;
|
||||
spflags = MGVALLEYS_HUMID_RIVERS | MGVALLEYS_ALT_CHILL;
|
||||
|
||||
altitude_chill = 90; // The altitude at which temperature drops by 20C.
|
||||
large_cave_depth = -33;
|
||||
|
@ -513,24 +513,19 @@ float MapgenValleys::adjustedTerrainLevelFromNoise(TerrainNoise *tn)
|
|||
}
|
||||
|
||||
|
||||
int MapgenValleys::getGroundLevelAtPoint(v2s16 p)
|
||||
int MapgenValleys::getSpawnLevelAtPoint(v2s16 p)
|
||||
{
|
||||
// ***********************************
|
||||
// This method (deliberately) does not
|
||||
// return correct terrain values.
|
||||
// ***********************************
|
||||
|
||||
// Since MT doesn't normally deal with rivers, check
|
||||
// to make sure this isn't a request for a location
|
||||
// in a river.
|
||||
// Check to make sure this isn't a request for a location in a river.
|
||||
float rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed);
|
||||
|
||||
// If it's wet, return an unusable number.
|
||||
if (fabs(rivers) < river_size_factor)
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
|
||||
// Otherwise, return the real result.
|
||||
return terrainLevelAtPoint(p.X, p.Y);
|
||||
s16 level_at_point = terrainLevelAtPoint(p.X, p.Y);
|
||||
if (level_at_point <= water_level ||
|
||||
level_at_point > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
return level_at_point;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
|
||||
#include "mapgen.h"
|
||||
|
||||
/////////////////// Mapgen Valleys flags
|
||||
#define MG_VALLEYS_ALT_CHILL 0x01
|
||||
#define MG_VALLEYS_HUMID_RIVERS 0x02
|
||||
////////////// Mapgen Valleys flags
|
||||
#define MGVALLEYS_ALT_CHILL 0x01
|
||||
#define MGVALLEYS_HUMID_RIVERS 0x02
|
||||
|
||||
// Feed only one variable into these.
|
||||
#define MYSQUARE(x) (x) * (x)
|
||||
|
@ -96,7 +96,7 @@ public:
|
|||
~MapgenValleys();
|
||||
|
||||
virtual void makeChunk(BlockMakeData *data);
|
||||
int getGroundLevelAtPoint(v2s16 p);
|
||||
int getSpawnLevelAtPoint(v2s16 p);
|
||||
|
||||
s16 large_cave_depth;
|
||||
|
||||
|
|
36
src/mesh.cpp
36
src/mesh.cpp
|
@ -104,7 +104,7 @@ void scaleMesh(scene::IMesh *mesh, v3f scale)
|
|||
if (mesh == NULL)
|
||||
return;
|
||||
|
||||
core::aabbox3d<f32> bbox;
|
||||
aabb3f bbox;
|
||||
bbox.reset(0, 0, 0);
|
||||
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
|
@ -132,7 +132,7 @@ void translateMesh(scene::IMesh *mesh, v3f vec)
|
|||
if (mesh == NULL)
|
||||
return;
|
||||
|
||||
core::aabbox3d<f32> bbox;
|
||||
aabb3f bbox;
|
||||
bbox.reset(0, 0, 0);
|
||||
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
|
@ -346,7 +346,7 @@ void rotateMeshBy6dFacedir(scene::IMesh *mesh, int facedir)
|
|||
|
||||
void recalculateBoundingBox(scene::IMesh *src_mesh)
|
||||
{
|
||||
core::aabbox3d<f32> bbox;
|
||||
aabb3f bbox;
|
||||
bbox.reset(0,0,0);
|
||||
for (u16 j = 0; j < src_mesh->getMeshBufferCount(); j++) {
|
||||
scene::IMeshBuffer *buf = src_mesh->getMeshBuffer(j);
|
||||
|
@ -406,7 +406,7 @@ scene::IMesh* cloneMesh(scene::IMesh *src_mesh)
|
|||
}
|
||||
|
||||
scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
|
||||
const f32 *uv_coords)
|
||||
const f32 *uv_coords, float expand)
|
||||
{
|
||||
scene::SMesh* dst_mesh = new scene::SMesh();
|
||||
|
||||
|
@ -421,31 +421,19 @@ scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
|
|||
|
||||
video::SColor c(255,255,255,255);
|
||||
|
||||
for(std::vector<aabb3f>::const_iterator
|
||||
for (std::vector<aabb3f>::const_iterator
|
||||
i = boxes.begin();
|
||||
i != boxes.end(); ++i)
|
||||
{
|
||||
aabb3f box = *i;
|
||||
box.repair();
|
||||
|
||||
f32 temp;
|
||||
if (box.MinEdge.X > box.MaxEdge.X)
|
||||
{
|
||||
temp=box.MinEdge.X;
|
||||
box.MinEdge.X=box.MaxEdge.X;
|
||||
box.MaxEdge.X=temp;
|
||||
}
|
||||
if (box.MinEdge.Y > box.MaxEdge.Y)
|
||||
{
|
||||
temp=box.MinEdge.Y;
|
||||
box.MinEdge.Y=box.MaxEdge.Y;
|
||||
box.MaxEdge.Y=temp;
|
||||
}
|
||||
if (box.MinEdge.Z > box.MaxEdge.Z)
|
||||
{
|
||||
temp=box.MinEdge.Z;
|
||||
box.MinEdge.Z=box.MaxEdge.Z;
|
||||
box.MaxEdge.Z=temp;
|
||||
}
|
||||
box.MinEdge.X -= expand;
|
||||
box.MinEdge.Y -= expand;
|
||||
box.MinEdge.Z -= expand;
|
||||
box.MaxEdge.X += expand;
|
||||
box.MaxEdge.Y += expand;
|
||||
box.MaxEdge.Z += expand;
|
||||
|
||||
// Compute texture UV coords
|
||||
f32 tx1 = (box.MinEdge.X / BS) + 0.5;
|
||||
|
|
|
@ -86,9 +86,10 @@ scene::IMesh* cloneMesh(scene::IMesh *src_mesh);
|
|||
Convert nodeboxes to mesh.
|
||||
boxes - set of nodeboxes to be converted into cuboids
|
||||
uv_coords[24] - table of texture uv coords for each cuboid face
|
||||
expand - factor by which cuboids will be resized
|
||||
*/
|
||||
scene::IMesh* convertNodeboxesToMesh(const std::vector<aabb3f> &boxes,
|
||||
const f32 *uv_coords = NULL);
|
||||
const f32 *uv_coords = NULL, float expand = 0);
|
||||
|
||||
/*
|
||||
Update bounding box for a mesh.
|
||||
|
|
|
@ -139,7 +139,7 @@ void TileDef::serialize(std::ostream &os, u16 protocol_version) const
|
|||
}
|
||||
}
|
||||
|
||||
void TileDef::deSerialize(std::istream &is, bool culling_ignore)
|
||||
void TileDef::deSerialize(std::istream &is, const u8 contenfeatures_version, const NodeDrawType drawtype)
|
||||
{
|
||||
int version = readU8(is);
|
||||
name = deSerializeString(is);
|
||||
|
@ -153,10 +153,12 @@ void TileDef::deSerialize(std::istream &is, bool culling_ignore)
|
|||
tileable_horizontal = readU8(is);
|
||||
tileable_vertical = readU8(is);
|
||||
}
|
||||
// when connecting to old servers - do not use
|
||||
// provided values here since culling needs to be
|
||||
// disabled by default for these drawtypes
|
||||
if (culling_ignore)
|
||||
|
||||
if ((contenfeatures_version < 8) &&
|
||||
((drawtype == NDT_MESH) ||
|
||||
(drawtype == NDT_FIRELIKE) ||
|
||||
(drawtype == NDT_LIQUID) ||
|
||||
(drawtype == NDT_PLANTLIKE)))
|
||||
backface_culling = false;
|
||||
}
|
||||
|
||||
|
@ -268,7 +270,8 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
|
|||
return;
|
||||
}
|
||||
|
||||
writeU8(os, 7); // version
|
||||
writeU8(os, protocol_version < 27 ? 7 : 8);
|
||||
|
||||
os<<serializeString(name);
|
||||
writeU16(os, groups.size());
|
||||
for(ItemGroupList::const_iterator
|
||||
|
@ -330,9 +333,11 @@ void ContentFeatures::serialize(std::ostream &os, u16 protocol_version) const
|
|||
void ContentFeatures::deSerialize(std::istream &is)
|
||||
{
|
||||
int version = readU8(is);
|
||||
if(version != 7){
|
||||
if (version < 7) {
|
||||
deSerializeOld(is, version);
|
||||
return;
|
||||
} else if (version > 8) {
|
||||
throw SerializationError("unsupported ContentFeatures version");
|
||||
}
|
||||
|
||||
name = deSerializeString(is);
|
||||
|
@ -345,21 +350,15 @@ void ContentFeatures::deSerialize(std::istream &is)
|
|||
}
|
||||
drawtype = (enum NodeDrawType)readU8(is);
|
||||
|
||||
bool ignore_culling = ((version <= 26) &&
|
||||
((drawtype == NDT_MESH) ||
|
||||
(drawtype == NDT_PLANTLIKE) ||
|
||||
(drawtype == NDT_FIRELIKE) ||
|
||||
(drawtype == NDT_LIQUID)));
|
||||
|
||||
visual_scale = readF1000(is);
|
||||
if(readU8(is) != 6)
|
||||
throw SerializationError("unsupported tile count");
|
||||
for(u32 i = 0; i < 6; i++)
|
||||
tiledef[i].deSerialize(is, ignore_culling);
|
||||
tiledef[i].deSerialize(is, version, drawtype);
|
||||
if(readU8(is) != CF_SPECIAL_COUNT)
|
||||
throw SerializationError("unsupported CF_SPECIAL_COUNT");
|
||||
for(u32 i = 0; i < CF_SPECIAL_COUNT; i++)
|
||||
tiledef_special[i].deSerialize(is, ignore_culling);
|
||||
tiledef_special[i].deSerialize(is, version, drawtype);
|
||||
alpha = readU8(is);
|
||||
post_effect_color.setAlpha(readU8(is));
|
||||
post_effect_color.setRed(readU8(is));
|
||||
|
@ -1284,21 +1283,15 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
|
|||
}
|
||||
drawtype = (enum NodeDrawType)readU8(is);
|
||||
|
||||
bool ignore_culling = ((version <= 26) &&
|
||||
((drawtype == NDT_MESH) ||
|
||||
(drawtype == NDT_PLANTLIKE) ||
|
||||
(drawtype == NDT_FIRELIKE) ||
|
||||
(drawtype == NDT_LIQUID)));
|
||||
|
||||
visual_scale = readF1000(is);
|
||||
if (readU8(is) != 6)
|
||||
throw SerializationError("unsupported tile count");
|
||||
for (u32 i = 0; i < 6; i++)
|
||||
tiledef[i].deSerialize(is, ignore_culling);
|
||||
tiledef[i].deSerialize(is, version, drawtype);
|
||||
if (readU8(is) != CF_SPECIAL_COUNT)
|
||||
throw SerializationError("unsupported CF_SPECIAL_COUNT");
|
||||
for (u32 i = 0; i < CF_SPECIAL_COUNT; i++)
|
||||
tiledef_special[i].deSerialize(is, ignore_culling);
|
||||
tiledef_special[i].deSerialize(is, version, drawtype);
|
||||
alpha = readU8(is);
|
||||
post_effect_color.setAlpha(readU8(is));
|
||||
post_effect_color.setRed(readU8(is));
|
||||
|
@ -1342,12 +1335,12 @@ void ContentFeatures::deSerializeOld(std::istream &is, int version)
|
|||
if (readU8(is) != 6)
|
||||
throw SerializationError("unsupported tile count");
|
||||
for (u32 i = 0; i < 6; i++)
|
||||
tiledef[i].deSerialize(is, drawtype);
|
||||
tiledef[i].deSerialize(is, version, drawtype);
|
||||
// CF_SPECIAL_COUNT in version 6 = 2
|
||||
if (readU8(is) != 2)
|
||||
throw SerializationError("unsupported CF_SPECIAL_COUNT");
|
||||
for (u32 i = 0; i < 2; i++)
|
||||
tiledef_special[i].deSerialize(is, drawtype);
|
||||
tiledef_special[i].deSerialize(is, version, drawtype);
|
||||
alpha = readU8(is);
|
||||
post_effect_color.setAlpha(readU8(is));
|
||||
post_effect_color.setRed(readU8(is));
|
||||
|
|
|
@ -104,6 +104,30 @@ struct NodeBox
|
|||
struct MapNode;
|
||||
class NodeMetadata;
|
||||
|
||||
enum NodeDrawType
|
||||
{
|
||||
NDT_NORMAL, // A basic solid block
|
||||
NDT_AIRLIKE, // Nothing is drawn
|
||||
NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
|
||||
NDT_FLOWINGLIQUID, // A very special kind of thing
|
||||
NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
|
||||
NDT_ALLFACES, // Leaves-like, draw all faces no matter what
|
||||
NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
|
||||
NDT_TORCHLIKE,
|
||||
NDT_SIGNLIKE,
|
||||
NDT_PLANTLIKE,
|
||||
NDT_FENCELIKE,
|
||||
NDT_RAILLIKE,
|
||||
NDT_NODEBOX,
|
||||
NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
|
||||
// visible faces
|
||||
// uses 2 textures, one for frames, second for faces
|
||||
NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
|
||||
NDT_GLASSLIKE_FRAMED_OPTIONAL, // enabled -> connected, disabled -> Glass-like
|
||||
// uses 2 textures, one for frames, second for faces
|
||||
NDT_MESH, // Uses static meshes
|
||||
};
|
||||
|
||||
/*
|
||||
Stand-alone definition of a TileSpec (basically a server-side TileSpec)
|
||||
*/
|
||||
|
@ -137,31 +161,7 @@ struct TileDef
|
|||
}
|
||||
|
||||
void serialize(std::ostream &os, u16 protocol_version) const;
|
||||
void deSerialize(std::istream &is, bool culling_ignore);
|
||||
};
|
||||
|
||||
enum NodeDrawType
|
||||
{
|
||||
NDT_NORMAL, // A basic solid block
|
||||
NDT_AIRLIKE, // Nothing is drawn
|
||||
NDT_LIQUID, // Do not draw face towards same kind of flowing/source liquid
|
||||
NDT_FLOWINGLIQUID, // A very special kind of thing
|
||||
NDT_GLASSLIKE, // Glass-like, don't draw faces towards other glass
|
||||
NDT_ALLFACES, // Leaves-like, draw all faces no matter what
|
||||
NDT_ALLFACES_OPTIONAL, // Fancy -> allfaces, fast -> normal
|
||||
NDT_TORCHLIKE,
|
||||
NDT_SIGNLIKE,
|
||||
NDT_PLANTLIKE,
|
||||
NDT_FENCELIKE,
|
||||
NDT_RAILLIKE,
|
||||
NDT_NODEBOX,
|
||||
NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
|
||||
// visible faces
|
||||
// uses 2 textures, one for frames, second for faces
|
||||
NDT_FIRELIKE, // Draw faces slightly rotated and only on connecting nodes,
|
||||
NDT_GLASSLIKE_FRAMED_OPTIONAL, // enabled -> connected, disabled -> Glass-like
|
||||
// uses 2 textures, one for frames, second for faces
|
||||
NDT_MESH, // Uses static meshes
|
||||
void deSerialize(std::istream &is, const u8 contentfeatures_version, const NodeDrawType drawtype);
|
||||
};
|
||||
|
||||
#define CF_SPECIAL_COUNT 6
|
||||
|
|
|
@ -33,7 +33,7 @@ struct ObjectProperties
|
|||
bool physical;
|
||||
bool collideWithObjects;
|
||||
float weight;
|
||||
core::aabbox3d<f32> collisionbox;
|
||||
aabb3f collisionbox;
|
||||
std::string visual;
|
||||
std::string mesh;
|
||||
v2f visual_size;
|
||||
|
|
|
@ -88,7 +88,7 @@ Particle::Particle(
|
|||
m_vertical = vertical;
|
||||
|
||||
// Irrlicht stuff
|
||||
m_collisionbox = core::aabbox3d<f32>
|
||||
m_collisionbox = aabb3f
|
||||
(-size/2,-size/2,-size/2,size/2,size/2,size/2);
|
||||
this->setAutomaticCulling(scene::EAC_OFF);
|
||||
|
||||
|
@ -128,7 +128,7 @@ void Particle::step(float dtime)
|
|||
m_time += dtime;
|
||||
if (m_collisiondetection)
|
||||
{
|
||||
core::aabbox3d<f32> box = m_collisionbox;
|
||||
aabb3f box = m_collisionbox;
|
||||
v3f p_pos = m_pos*BS;
|
||||
v3f p_velocity = m_velocity*BS;
|
||||
collisionMoveSimple(m_env, m_gamedef,
|
||||
|
|
|
@ -52,7 +52,7 @@ class Particle : public scene::ISceneNode
|
|||
);
|
||||
~Particle();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
virtual const aabb3f &getBoundingBox() const
|
||||
{
|
||||
return m_box;
|
||||
}
|
||||
|
@ -85,8 +85,8 @@ private:
|
|||
|
||||
ClientEnvironment *m_env;
|
||||
IGameDef *m_gamedef;
|
||||
core::aabbox3d<f32> m_box;
|
||||
core::aabbox3d<f32> m_collisionbox;
|
||||
aabb3f m_box;
|
||||
aabb3f m_collisionbox;
|
||||
video::SMaterial m_material;
|
||||
v2f m_texpos;
|
||||
v2f m_texsize;
|
||||
|
|
|
@ -198,7 +198,7 @@ public:
|
|||
return m_name;
|
||||
}
|
||||
|
||||
core::aabbox3d<f32> getCollisionbox()
|
||||
aabb3f getCollisionbox()
|
||||
{
|
||||
return m_collisionbox;
|
||||
}
|
||||
|
@ -398,7 +398,7 @@ protected:
|
|||
f32 m_yaw;
|
||||
v3f m_speed;
|
||||
v3f m_position;
|
||||
core::aabbox3d<f32> m_collisionbox;
|
||||
aabb3f m_collisionbox;
|
||||
|
||||
bool m_dirty;
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "lua_api/l_internal.h"
|
||||
#include "common/c_converter.h"
|
||||
#include "cpp_api/s_security.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "areastore.h"
|
||||
#include "filesys.h"
|
||||
#ifndef ANDROID
|
||||
|
|
|
@ -21,7 +21,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define L_AREASTORE_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "irr_v3d.h"
|
||||
#include "areastore.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -36,6 +36,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "emerge.h"
|
||||
#include "pathfinder.h"
|
||||
|
||||
struct EnumString ModApiEnvMod::es_ClearObjectsMode[] =
|
||||
{
|
||||
{CLEAR_OBJECTS_MODE_FULL, "full"},
|
||||
{CLEAR_OBJECTS_MODE_QUICK, "quick"},
|
||||
{0, NULL},
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
@ -727,13 +734,20 @@ int ModApiEnvMod::l_get_voxel_manip(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
// clear_objects()
|
||||
// clear_objects([options])
|
||||
// clear all objects in the environment
|
||||
// where options = {mode = "full" or "quick"}
|
||||
int ModApiEnvMod::l_clear_objects(lua_State *L)
|
||||
{
|
||||
GET_ENV_PTR;
|
||||
|
||||
env->clearAllObjects();
|
||||
ClearObjectsMode mode = CLEAR_OBJECTS_MODE_FULL;
|
||||
if (lua_istable(L, 1)) {
|
||||
mode = (ClearObjectsMode)getenumfield(L, 1, "mode",
|
||||
ModApiEnvMod::es_ClearObjectsMode, mode);
|
||||
}
|
||||
|
||||
env->clearObjects(mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,6 +170,8 @@ private:
|
|||
|
||||
public:
|
||||
static void Initialize(lua_State *L, int top);
|
||||
|
||||
static struct EnumString es_ClearObjectsMode[];
|
||||
};
|
||||
|
||||
class LuaABM : public ActiveBlockModifier {
|
||||
|
|
|
@ -3376,26 +3376,24 @@ v3f Server::findSpawnPos()
|
|||
return nodeposf * BS;
|
||||
}
|
||||
|
||||
s16 water_level = map.getWaterLevel();
|
||||
s16 vertical_spawn_range = g_settings->getS16("vertical_spawn_range");
|
||||
bool is_good = false;
|
||||
|
||||
// Try to find a good place a few times
|
||||
for(s32 i = 0; i < 1000 && !is_good; i++) {
|
||||
for(s32 i = 0; i < 4000 && !is_good; i++) {
|
||||
s32 range = 1 + i;
|
||||
// We're going to try to throw the player to this position
|
||||
v2s16 nodepos2d = v2s16(
|
||||
-range + (myrand() % (range * 2)),
|
||||
-range + (myrand() % (range * 2)));
|
||||
|
||||
// Get ground height at point
|
||||
s16 groundheight = map.findGroundLevel(nodepos2d);
|
||||
// Don't go underwater or to high places
|
||||
if (groundheight <= water_level ||
|
||||
groundheight > water_level + vertical_spawn_range)
|
||||
// Get spawn level at point
|
||||
s16 spawn_level = m_emerge->getSpawnLevelAtPoint(nodepos2d);
|
||||
// Continue if MAX_MAP_GENERATION_LIMIT was returned by
|
||||
// the mapgen to signify an unsuitable spawn position
|
||||
if (spawn_level == MAX_MAP_GENERATION_LIMIT)
|
||||
continue;
|
||||
|
||||
v3s16 nodepos(nodepos2d.X, groundheight, nodepos2d.Y);
|
||||
v3s16 nodepos(nodepos2d.X, spawn_level, nodepos2d.Y);
|
||||
|
||||
s32 air_count = 0;
|
||||
for (s32 i = 0; i < 10; i++) {
|
||||
|
|
|
@ -764,22 +764,25 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
|
|||
else
|
||||
shaders_header += "0\n";
|
||||
|
||||
if(pixel_program != "")
|
||||
pixel_program = shaders_header + pixel_program;
|
||||
if(vertex_program != "")
|
||||
vertex_program = shaders_header + vertex_program;
|
||||
if(geometry_program != "")
|
||||
geometry_program = shaders_header + geometry_program;
|
||||
if (g_settings->getBool("tone_mapping"))
|
||||
shaders_header += "#define ENABLE_TONE_MAPPING\n";
|
||||
|
||||
// Call addHighLevelShaderMaterial() or addShaderMaterial()
|
||||
const c8* vertex_program_ptr = 0;
|
||||
const c8* pixel_program_ptr = 0;
|
||||
const c8* geometry_program_ptr = 0;
|
||||
if(vertex_program != "")
|
||||
if (!vertex_program.empty()) {
|
||||
vertex_program = shaders_header + vertex_program;
|
||||
vertex_program_ptr = vertex_program.c_str();
|
||||
if(pixel_program != "")
|
||||
}
|
||||
if (!pixel_program.empty()) {
|
||||
pixel_program = shaders_header + pixel_program;
|
||||
pixel_program_ptr = pixel_program.c_str();
|
||||
if(geometry_program != "")
|
||||
}
|
||||
if (!geometry_program.empty()) {
|
||||
geometry_program = shaders_header + geometry_program;
|
||||
geometry_program_ptr = geometry_program.c_str();
|
||||
}
|
||||
s32 shadermat = -1;
|
||||
if(is_highlevel){
|
||||
infostream<<"Compiling high level shaders for "<<name<<std::endl;
|
||||
|
@ -789,7 +792,7 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
|
|||
video::EVST_VS_1_1, // Vertex shader version
|
||||
pixel_program_ptr, // Pixel shader program
|
||||
"pixelMain", // Pixel shader entry point
|
||||
video::EPST_PS_1_1, // Pixel shader version
|
||||
video::EPST_PS_1_2, // Pixel shader version
|
||||
geometry_program_ptr, // Geometry shader program
|
||||
"geometryMain", // Geometry shader entry point
|
||||
video::EGST_GS_4_0, // Geometry shader version
|
||||
|
@ -805,6 +808,9 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
|
|||
"failed to generate \""<<name<<"\", "
|
||||
"addHighLevelShaderMaterial failed."
|
||||
<<std::endl;
|
||||
dumpShaderProgram(warningstream, "Vertex", vertex_program);
|
||||
dumpShaderProgram(warningstream, "Pixel", pixel_program);
|
||||
dumpShaderProgram(warningstream, "Geometry", geometry_program);
|
||||
return shaderinfo;
|
||||
}
|
||||
}
|
||||
|
@ -823,6 +829,8 @@ ShaderInfo generate_shader(std::string name, u8 material_type, u8 drawtype,
|
|||
"failed to generate \""<<name<<"\", "
|
||||
"addShaderMaterial failed."
|
||||
<<std::endl;
|
||||
dumpShaderProgram(warningstream, "Vertex", vertex_program);
|
||||
dumpShaderProgram(warningstream,"Pixel", pixel_program);
|
||||
return shaderinfo;
|
||||
}
|
||||
}
|
||||
|
@ -868,3 +876,21 @@ void load_shaders(std::string name, SourceShaderCache *sourcecache,
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
void dumpShaderProgram(std::ostream &output_stream,
|
||||
const std::string &program_type, const std::string &program)
|
||||
{
|
||||
output_stream << program_type << " shader program:" << std::endl <<
|
||||
"----------------------------------" << std::endl;
|
||||
size_t pos = 0;
|
||||
size_t prev = 0;
|
||||
s16 line = 1;
|
||||
while ((pos = program.find("\n", prev)) != std::string::npos) {
|
||||
output_stream << line++ << ": "<< program.substr(prev, pos - prev) <<
|
||||
std::endl;
|
||||
prev = pos + 1;
|
||||
}
|
||||
output_stream << line << ": " << program.substr(prev) << std::endl <<
|
||||
"End of " << program_type << " shader program." << std::endl <<
|
||||
" " << std::endl;
|
||||
}
|
||||
|
|
|
@ -110,4 +110,7 @@ public:
|
|||
|
||||
IWritableShaderSource* createShaderSource(IrrlichtDevice *device);
|
||||
|
||||
void dumpShaderProgram(std::ostream &output_stream,
|
||||
const std::string &program_type, const std::string &program);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,8 +25,8 @@ Sky::Sky(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id,
|
|||
m_cloudcolor_bright_f(1,1,1,1)
|
||||
{
|
||||
setAutomaticCulling(scene::EAC_OFF);
|
||||
Box.MaxEdge.set(0,0,0);
|
||||
Box.MinEdge.set(0,0,0);
|
||||
m_box.MaxEdge.set(0,0,0);
|
||||
m_box.MinEdge.set(0,0,0);
|
||||
|
||||
// create material
|
||||
|
||||
|
@ -94,11 +94,6 @@ void Sky::OnRegisterSceneNode()
|
|||
scene::ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
const core::aabbox3d<f32>& Sky::getBoundingBox() const
|
||||
{
|
||||
return Box;
|
||||
}
|
||||
|
||||
//! renders the node.
|
||||
void Sky::render()
|
||||
{
|
||||
|
|
|
@ -42,7 +42,8 @@ public:
|
|||
//! renders the node.
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
virtual const aabb3f &getBoundingBox() const
|
||||
{ return m_box; }
|
||||
|
||||
// Used by Irrlicht for optimizing rendering
|
||||
virtual video::SMaterial& getMaterial(u32 i)
|
||||
|
@ -74,7 +75,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
core::aabbox3d<f32> Box;
|
||||
aabb3f m_box;
|
||||
video::SMaterial m_materials[SKY_MATERIAL_COUNT];
|
||||
|
||||
// How much sun & moon transition should affect horizon color
|
||||
|
|
|
@ -310,9 +310,9 @@ inline v3f intToFloat(v3s16 p, f32 d)
|
|||
}
|
||||
|
||||
// Random helper. Usually d=BS
|
||||
inline core::aabbox3d<f32> getNodeBox(v3s16 p, float d)
|
||||
inline aabb3f getNodeBox(v3s16 p, float d)
|
||||
{
|
||||
return core::aabbox3d<f32>(
|
||||
return aabb3f(
|
||||
(float)p.X * d - 0.5*d,
|
||||
(float)p.Y * d - 0.5*d,
|
||||
(float)p.Z * d - 0.5*d,
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
|
||||
virtual void render();
|
||||
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const
|
||||
virtual const aabb3f &getBoundingBox() const
|
||||
{ return m_bounding_box; }
|
||||
|
||||
private:
|
||||
|
@ -74,7 +74,7 @@ private:
|
|||
// Bounding box culling is disabled for this type of scene node,
|
||||
// so this variable is just required so we can implement
|
||||
// getBoundingBox() and is set to an empty box.
|
||||
core::aabbox3d<f32> m_bounding_box;
|
||||
aabb3f m_bounding_box;
|
||||
};
|
||||
|
||||
scene::IMesh *getItemMesh(IGameDef *gamedef, const ItemStack &item);
|
||||
|
|
Loading…
Reference in New Issue