summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/builtin.lua1
-rw-r--r--builtin/chatcommands.lua4
-rw-r--r--builtin/falling.lua141
-rw-r--r--builtin/misc_register.lua2
-rw-r--r--doc/lua_api.txt8
-rw-r--r--games/minimal/mods/default/init.lua79
-rw-r--r--games/minimal/mods/default/textures/default_nc_back.pngbin303 -> 317 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_front.pngbin410 -> 378 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_rb.pngbin203 -> 206 bytes
-rw-r--r--games/minimal/mods/default/textures/default_nc_side.pngbin260 -> 231 bytes
-rw-r--r--src/camera.cpp12
-rw-r--r--src/clientmap.cpp9
-rw-r--r--src/content_mapblock.cpp16
-rw-r--r--src/defaultsettings.cpp5
-rw-r--r--src/guiFormSpecMenu.cpp61
-rw-r--r--src/guiFormSpecMenu.h1
-rw-r--r--src/guiMainMenu.cpp60
-rw-r--r--src/guiMainMenu.h4
-rw-r--r--src/main.cpp14
-rw-r--r--src/map.cpp4
-rw-r--r--src/mapgen.cpp2
-rw-r--r--src/mesh.cpp3
-rw-r--r--src/nodedef.cpp7
-rw-r--r--src/nodedef.h2
-rw-r--r--src/noise.cpp2
-rw-r--r--src/scriptapi.cpp1
-rw-r--r--src/tile.cpp40
27 files changed, 368 insertions, 110 deletions
diff --git a/builtin/builtin.lua b/builtin/builtin.lua
index a17841fc8..f2811fa9c 100644
--- a/builtin/builtin.lua
+++ b/builtin/builtin.lua
@@ -22,4 +22,5 @@ dofile(minetest.get_modpath("__builtin").."/auth.lua")
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua")
+dofile(minetest.get_modpath("__builtin").."/falling.lua")
diff --git a/builtin/chatcommands.lua b/builtin/chatcommands.lua
index 9f55f1afc..f25a276ea 100644
--- a/builtin/chatcommands.lua
+++ b/builtin/chatcommands.lua
@@ -215,8 +215,8 @@ minetest.register_chatcommand("clearpassword", {
privs = {password=true},
func = function(name, param)
toname = param
- if not toname then
- minetest.chat_send_player(toname, "Name field required")
+ if toname == "" then
+ minetest.chat_send_player(name, "Name field required")
return
end
minetest.set_player_password(toname, '')
diff --git a/builtin/falling.lua b/builtin/falling.lua
new file mode 100644
index 000000000..3912727c3
--- /dev/null
+++ b/builtin/falling.lua
@@ -0,0 +1,141 @@
+-- Minetest: builtin/item.lua
+
+--
+-- Falling stuff
+--
+
+minetest.register_entity("__builtin:falling_node", {
+ initial_properties = {
+ physical = true,
+ collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
+ visual = "wielditem",
+ textures = {},
+ visual_size = {x=0.667, y=0.667},
+ },
+
+ nodename = "",
+
+ set_node = function(self, nodename)
+ self.nodename = nodename
+ local stack = ItemStack(nodename)
+ local itemtable = stack:to_table()
+ local itemname = nil
+ if itemtable then
+ itemname = stack:to_table().name
+ end
+ local item_texture = nil
+ local item_type = ""
+ if minetest.registered_items[itemname] then
+ item_texture = minetest.registered_items[itemname].inventory_image
+ item_type = minetest.registered_items[itemname].type
+ end
+ prop = {
+ is_visible = true,
+ textures = {nodename},
+ }
+ self.object:set_properties(prop)
+ end,
+
+ get_staticdata = function(self)
+ return self.nodename
+ end,
+
+ on_activate = function(self, staticdata)
+ self.nodename = staticdata
+ self.object:set_armor_groups({immortal=1})
+ --self.object:setacceleration({x=0, y=-10, z=0})
+ self:set_node(self.nodename)
+ end,
+
+ on_step = function(self, dtime)
+ -- Set gravity
+ self.object:setacceleration({x=0, y=-10, z=0})
+ -- Turn to actual sand when collides to ground or just move
+ local pos = self.object:getpos()
+ local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
+ local bcn = minetest.env:get_node(bcp)
+ -- Note: walkable is in the node definition, not in item groups
+ if minetest.registered_nodes[bcn.name] and
+ minetest.registered_nodes[bcn.name].walkable then
+ local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
+ -- Check what's here
+ local n2 = minetest.env:get_node(np)
+ -- If it's not air or liquid, remove node and replace it with
+ -- it's drops
+ if n2.name ~= "air" and (not minetest.registered_nodes[n2.name] or
+ minetest.registered_nodes[n2.name].liquidtype == "none") then
+ local drops = minetest.get_node_drops(n2.name, "")
+ minetest.env:remove_node(np)
+ -- Add dropped items
+ local _, dropped_item
+ for _, dropped_item in ipairs(drops) do
+ minetest.env:add_item(np, dropped_item)
+ end
+ -- Run script hook
+ local _, callback
+ for _, callback in ipairs(minetest.registered_on_dignodes) do
+ callback(np, n2, nil)
+ end
+ end
+ -- Create node and remove entity
+ minetest.env:add_node(np, {name=self.nodename})
+ self.object:remove()
+ else
+ -- Do nothing
+ end
+ end
+})
+
+function spawn_falling_node(p, nodename)
+ obj = minetest.env:add_entity(p, "__builtin:falling_node")
+ obj:get_luaentity():set_node(nodename)
+end
+
+--
+-- Some common functions
+--
+
+function nodeupdate_single(p)
+ n = minetest.env:get_node(p)
+ if minetest.get_node_group(n.name, "falling_node") ~= 0 then
+ p_bottom = {x=p.x, y=p.y-1, z=p.z}
+ n_bottom = minetest.env:get_node(p_bottom)
+ -- Note: walkable is in the node definition, not in item groups
+ if minetest.registered_nodes[n_bottom.name] and
+ not minetest.registered_nodes[n_bottom.name].walkable then
+ minetest.env:remove_node(p)
+ spawn_falling_node(p, n.name)
+ nodeupdate(p)
+ end
+ end
+end
+
+function nodeupdate(p)
+ -- Round p to prevent falling entities to get stuck
+ p.x = math.floor(p.x+0.5)
+ p.y = math.floor(p.y+0.5)
+ p.z = math.floor(p.z+0.5)
+
+ for x = -1,1 do
+ for y = -1,1 do
+ for z = -1,1 do
+ p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
+ nodeupdate_single(p2)
+ end
+ end
+ end
+end
+
+--
+-- Global callbacks
+--
+
+function on_placenode(p, node)
+ nodeupdate(p)
+end
+minetest.register_on_placenode(on_placenode)
+
+function on_dignode(p, node)
+ nodeupdate(p)
+end
+minetest.register_on_dignode(on_dignode)
diff --git a/builtin/misc_register.lua b/builtin/misc_register.lua
index 4894e71bc..77c594de2 100644
--- a/builtin/misc_register.lua
+++ b/builtin/misc_register.lua
@@ -259,6 +259,7 @@ minetest.register_node(":air", {
diggable = false,
buildable_to = true,
air_equivalent = true,
+ drop = "",
groups = {not_in_creative_inventory=1},
})
@@ -274,6 +275,7 @@ minetest.register_node(":ignore", {
diggable = false,
buildable_to = true, -- A way to remove accidentally placed ignores
air_equivalent = true,
+ drop = "",
groups = {not_in_creative_inventory=1},
})
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 442937bd1..500b514d9 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -456,6 +456,7 @@ Special groups
- disable_jump: Player (and possibly other things) cannot jump from node
- fall_damage_add_percent: damage speed = speed * (1 + value/100)
- bouncy: value is bounce speed in percent
+- falling_node: if there is no walkable block under the node it will fall
Known damage and digging time defining groups
----------------------------------------------
@@ -693,6 +694,11 @@ image[<X>,<Y>;<W>,<H>;<texture name>]
^ Show an image
^ Position and size units are inventory slots
+background[<X>,<Y>;<W>,<H>;<texture name>]
+^ Use a background. Inventory rectangles are not drawn then.
+^ Position and size units are inventory slots
+^ Example for formspec 8x4 in 16x resolution: image shall be sized 8*16px x 4*16px
+
field[<X>,<Y>;<W>,<H>;<name>;<label>;<default>]
^ Textual field; will be sent to server when a button is clicked
^ x and y position the field relative to the top left of the menu
@@ -1346,6 +1352,8 @@ Node definition (register_node)
liquid_alternative_flowing = "", -- Flowing version of source liquid
liquid_alternative_source = "", -- Source version of flowing liquid
liquid_viscosity = 0, -- Higher viscosity = slower flow (max. 7)
+ liquid_renewable = true, -- Can new liquid source be created by placing
+ two or more sources nearly?
light_source = 0, -- Amount of light emitted by node
damage_per_second = 0, -- If player is inside node, this damage is caused
node_box = {type="regular"}, -- See "Node boxes"
diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua
index 176fe899b..5f4d8e063 100644
--- a/games/minimal/mods/default/init.lua
+++ b/games/minimal/mods/default/init.lua
@@ -769,7 +769,7 @@ minetest.register_node("default:sand", {
description = "Sand",
tiles ={"default_sand.png"},
is_ground_content = true,
- groups = {crumbly=3},
+ groups = {crumbly=3, falling_node=1},
sounds = default.node_sound_sand_defaults(),
})
@@ -777,7 +777,7 @@ minetest.register_node("default:gravel", {
description = "Gravel",
tiles ={"default_gravel.png"},
is_ground_content = true,
- groups = {crumbly=2},
+ groups = {crumbly=2, falling_node=1},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_gravel_footstep", gain=0.45},
}),
@@ -1586,73 +1586,22 @@ minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")
---
--- Some common functions
---
-
-default.falling_node_names = {}
-
-function nodeupdate_single(p)
- n = minetest.env:get_node(p)
- if default.falling_node_names[n.name] ~= nil then
- p_bottom = {x=p.x, y=p.y-1, z=p.z}
- n_bottom = minetest.env:get_node(p_bottom)
- if n_bottom.name == "air" then
- minetest.env:remove_node(p)
- minetest.env:add_entity(p, "default:falling_"..n.name)
- nodeupdate(p)
- end
- end
-end
-
-function nodeupdate(p)
- for x = -1,1 do
- for y = -1,1 do
- for z = -1,1 do
- p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
- nodeupdate_single(p2)
- end
- end
- end
+-- Support old code
+function default.spawn_falling_node(p, nodename)
+ spawn_falling_node(p, nodename)
end
---
--- Falling stuff
---
-
+-- Horrible crap to support old code
+-- Don't use this and never do what this does, it's completely wrong!
+-- (More specifically, the client and the C++ code doesn't get the group)
function default.register_falling_node(nodename, texture)
- default.falling_node_names[nodename] = true
- -- Override naming conventions for stuff like :default:falling_default:sand
- minetest.register_entity(":default:falling_"..nodename, {
- -- Static definition
- physical = true,
- collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
- visual = "cube",
- textures = {texture,texture,texture,texture,texture,texture},
- -- State
- -- Methods
- on_step = function(self, dtime)
- -- Set gravity
- self.object:setacceleration({x=0, y=-10, z=0})
- -- Turn to actual sand when collides to ground or just move
- local pos = self.object:getpos()
- local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
- local bcn = minetest.env:get_node(bcp)
- if bcn.name ~= "air" then
- -- Turn to a sand node
- local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
- minetest.env:add_node(np, {name=nodename})
- self.object:remove()
- else
- -- Do nothing
- end
- end
- })
+ minetest.log("error", debug.traceback())
+ minetest.log('error', "WARNING: default.register_falling_node is deprecated")
+ if minetest.registered_nodes[nodename] then
+ minetest.registered_nodes[nodename].groups.falling_node = 1
+ end
end
-default.register_falling_node("default:sand", "default_sand.png")
-default.register_falling_node("default:gravel", "default_gravel.png")
-
--
-- Global callbacks
--
@@ -1665,13 +1614,11 @@ minetest.register_globalstep(on_step)
function on_placenode(p, node)
--print("on_placenode")
- nodeupdate(p)
end
minetest.register_on_placenode(on_placenode)
function on_dignode(p, node)
--print("on_dignode")
- nodeupdate(p)
end
minetest.register_on_dignode(on_dignode)
diff --git a/games/minimal/mods/default/textures/default_nc_back.png b/games/minimal/mods/default/textures/default_nc_back.png
index f09f41658..febd7384a 100644
--- a/games/minimal/mods/default/textures/default_nc_back.png
+++ b/games/minimal/mods/default/textures/default_nc_back.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_front.png b/games/minimal/mods/default/textures/default_nc_front.png
index cad9edab1..53b02d174 100644
--- a/games/minimal/mods/default/textures/default_nc_front.png
+++ b/games/minimal/mods/default/textures/default_nc_front.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_rb.png b/games/minimal/mods/default/textures/default_nc_rb.png
index 7ebc9930d..7183e6986 100644
--- a/games/minimal/mods/default/textures/default_nc_rb.png
+++ b/games/minimal/mods/default/textures/default_nc_rb.png
Binary files differ
diff --git a/games/minimal/mods/default/textures/default_nc_side.png b/games/minimal/mods/default/textures/default_nc_side.png
index f954045fb..0a34c8bef 100644
--- a/games/minimal/mods/default/textures/default_nc_side.png
+++ b/games/minimal/mods/default/textures/default_nc_side.png
Binary files differ
diff --git a/src/camera.cpp b/src/camera.cpp
index f87f660e9..43f26cd8f 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -189,7 +189,7 @@ void Camera::step(f32 dtime)
if (m_digging_button != -1)
{
- f32 offset = dtime * 3.5;
+ f32 offset = dtime * 4.5;
float m_digging_anim_was = m_digging_anim;
m_digging_anim += offset;
if (m_digging_anim >= 1)
@@ -336,13 +336,13 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
if (m_digging_button != -1)
{
f32 digfrac = m_digging_anim;
- wield_position.X -= 30 * sin(pow(digfrac, 0.8f) * M_PI);
- wield_position.Y += 15 * sin(digfrac * 2 * M_PI);
- wield_position.Z += 5 * digfrac;
-
+ wield_position.X -= 50 * sin(pow(digfrac, 0.8f) * M_PI);
+ wield_position.Y += 24 * sin(digfrac * 1.8 * M_PI);
+ wield_position.Z += 25 * 0.5;
+
// Euler angles are PURE EVIL, so why not use quaternions?
core::quaternion quat_begin(wield_rotation * core::DEGTORAD);
- core::quaternion quat_end(v3f(90, -10, -130) * core::DEGTORAD);
+ core::quaternion quat_end(v3f(80, 30, 100) * core::DEGTORAD);
core::quaternion quat_slerp;
quat_slerp.slerp(quat_begin, quat_end, sin(digfrac * M_PI));
quat_slerp.toEuler(wield_rotation);
diff --git a/src/clientmap.cpp b/src/clientmap.cpp
index 64d5656d4..02c9fe9b1 100644
--- a/src/clientmap.cpp
+++ b/src/clientmap.cpp
@@ -413,6 +413,10 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
m_last_drawn_sectors.clear();
}
+ bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
+ bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
+ bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");
+
/*
Get time for measuring timeout.
@@ -544,6 +548,11 @@ void ClientMap::renderMap(video::IVideoDriver* driver, s32 pass)
for(u32 i=0; i<c; i++)
{
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
+
+ buf->getMaterial().setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
+ buf->getMaterial().setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
+ buf->getMaterial().setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
+
const video::SMaterial& material = buf->getMaterial();
video::IMaterialRenderer* rnd =
driver->getMaterialRenderer(material.MaterialType);
diff --git a/src/content_mapblock.cpp b/src/content_mapblock.cpp
index ad819e793..ff8ef5276 100644
--- a/src/content_mapblock.cpp
+++ b/src/content_mapblock.cpp
@@ -492,15 +492,15 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
// -Z towards +Z, thus the direction is +Z.
// Rotate texture to make animation go in flow direction
// Positive if liquid moves towards +Z
- int dz = (corner_levels[side_corners[2][0]] +
- corner_levels[side_corners[2][1]] <
- corner_levels[side_corners[3][0]] +
- corner_levels[side_corners[3][1]]);
+ int dz = (corner_levels[side_corners[3][0]] +
+ corner_levels[side_corners[3][1]]) -
+ (corner_levels[side_corners[2][0]] +
+ corner_levels[side_corners[2][1]]);
// Positive if liquid moves towards +X
- int dx = (corner_levels[side_corners[0][0]] +
- corner_levels[side_corners[0][1]] <
- corner_levels[side_corners[1][0]] +
- corner_levels[side_corners[1][1]]);
+ int dx = (corner_levels[side_corners[1][0]] +
+ corner_levels[side_corners[1][1]]) -
+ (corner_levels[side_corners[0][0]] +
+ corner_levels[side_corners[0][1]]);
// -X
if(-dx >= abs(dz))
{
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 3b37c18dc..6eaa28410 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -142,5 +142,10 @@ void set_default_settings(Settings *settings)
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
settings->setDefault("dedicated_server_step", "0.05");
settings->setDefault("ignore_world_load_errors", "false");
+ settings->setDefault("mip_map", "false");
+ settings->setDefault("anisotropic_filter", "false");
+ settings->setDefault("bilinear_filter", "false");
+ settings->setDefault("trilinear_filter", "false");
+
}
diff --git a/src/guiFormSpecMenu.cpp b/src/guiFormSpecMenu.cpp
index 9bdcdd5fb..4db020c11 100644
--- a/src/guiFormSpecMenu.cpp
+++ b/src/guiFormSpecMenu.cpp
@@ -199,6 +199,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
m_inventorylists.clear();
m_images.clear();
+ m_backgrounds.clear();
m_fields.clear();
Strfnd f(m_formspec_string);
@@ -278,9 +279,26 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
<<", geom=("<<geom.X<<","<<geom.Y<<")"
<<std::endl;
if(bp_set != 2)
- errorstream<<"WARNING: invalid use of button without a size[] element"<<std::endl;
+ errorstream<<"WARNING: invalid use of image without a size[] element"<<std::endl;
m_images.push_back(ImageDrawSpec(name, pos, geom));
}
+ else if(type == "background")
+ {
+ v2s32 pos = basepos;
+ pos.X += stof(f.next(",")) * (float)spacing.X - ((float)spacing.X-(float)imgsize.X)/2;
+ pos.Y += stof(f.next(";")) * (float)spacing.Y - ((float)spacing.Y-(float)imgsize.Y)/2;
+ v2s32 geom;
+ geom.X = stof(f.next(",")) * (float)spacing.X;
+ geom.Y = stof(f.next(";")) * (float)spacing.Y;
+ std::string name = f.next("]");
+ infostream<<"image name="<<name
+ <<", pos=("<<pos.X<<","<<pos.Y<<")"
+ <<", geom=("<<geom.X<<","<<geom.Y<<")"
+ <<std::endl;
+ if(bp_set != 2)
+ errorstream<<"WARNING: invalid use of background without a size[] element"<<std::endl;
+ m_backgrounds.push_back(ImageDrawSpec(name, pos, geom));
+ }
else if(type == "field")
{
std::string fname = f.next(";");
@@ -693,17 +711,28 @@ void GUIFormSpecMenu::drawMenu()
m_tooltip_element->setVisible(false);
/*
- Draw items
- Phase 0: Item slot rectangles
- Phase 1: Item images; prepare tooltip
+ Draw backgrounds
*/
-
- for(int phase=0; phase<=1; phase++)
- for(u32 i=0; i<m_inventorylists.size(); i++)
+ for(u32 i=0; i<m_backgrounds.size(); i++)
{
- drawList(m_inventorylists[i], phase);
+ const ImageDrawSpec &spec = m_backgrounds[i];
+ video::ITexture *texture =
+ m_gamedef->tsrc()->getTextureRaw(spec.name);
+ // Image size on screen
+ core::rect<s32> imgrect(0, 0, spec.geom.X, spec.geom.Y);
+ // Image rectangle on screen
+ core::rect<s32> rect = imgrect + spec.pos;
+ const video::SColor color(255,255,255,255);
+ const video::SColor colors[] = {color,color,color,color};
+ driver->draw2DImage(texture, rect,
+ core::rect<s32>(core::position2d<s32>(0,0),
+ core::dimension2di(texture->getOriginalSize())),
+ NULL/*&AbsoluteClippingRect*/, colors, true);
}
-
+
+ /*
+ Draw images
+ */
for(u32 i=0; i<m_images.size(); i++)
{
const ImageDrawSpec &spec = m_images[i];
@@ -722,6 +751,20 @@ void GUIFormSpecMenu::drawMenu()
}
/*
+ Draw items
+ Phase 0: Item slot rectangles
+ Phase 1: Item images; prepare tooltip
+ If backgrounds used, do not draw Item slot rectangles
+ */
+ int start_phase=0;
+ if (m_backgrounds.size() > 0) start_phase=1;
+ for(int phase=start_phase; phase<=1; phase++)
+ for(u32 i=0; i<m_inventorylists.size(); i++)
+ {
+ drawList(m_inventorylists[i], phase);
+ }
+
+ /*
Draw dragged item stack
*/
drawSelectedItem();
diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h
index 5c01bdcd2..890b54d61 100644
--- a/src/guiFormSpecMenu.h
+++ b/src/guiFormSpecMenu.h
@@ -206,6 +206,7 @@ protected:
TextDest *m_text_dst;
core::array<ListDrawSpec> m_inventorylists;
+ core::array<ImageDrawSpec> m_backgrounds;
core::array<ImageDrawSpec> m_images;
core::array<FieldSpec> m_fields;
diff --git a/src/guiMainMenu.cpp b/src/guiMainMenu.cpp
index 5e0a3c38f..0bdb44e5d 100644
--- a/src/guiMainMenu.cpp
+++ b/src/guiMainMenu.cpp
@@ -98,6 +98,10 @@ enum
GUI_ID_SMOOTH_LIGHTING_CB,
GUI_ID_3D_CLOUDS_CB,
GUI_ID_OPAQUE_WATER_CB,
+ GUI_ID_MIPMAP_CB,
+ GUI_ID_ANISOTROPIC_CB,
+ GUI_ID_BILINEAR_CB,
+ GUI_ID_TRILINEAR_CB,
GUI_ID_DAMAGE_CB,
GUI_ID_CREATIVE_CB,
GUI_ID_JOIN_GAME_BUTTON,
@@ -580,6 +584,38 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
Environment->addCheckBox(m_data->opaque_water, rect, this,
GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water"));
}
+
+
+ // Anisotropic/mipmap/bi-/trilinear settings
+
+ {
+ core::rect<s32> rect(0, 0, option_w+20, 30);
+ rect += m_topleft_client + v2s32(option_x+175, option_y);
+ Environment->addCheckBox(m_data->mip_map, rect, this,
+ GUI_ID_MIPMAP_CB, wgettext("Mip-Mapping"));
+ }
+
+ {
+ core::rect<s32> rect(0, 0, option_w+20, 30);
+ rect += m_topleft_client + v2s32(option_x+175, option_y+20);
+ Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
+ GUI_ID_ANISOTROPIC_CB, wgettext("Anisotropic Filtering"));
+ }
+
+ {
+ core::rect<s32> rect(0, 0, option_w+20, 30);
+ rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
+ Environment->addCheckBox(m_data->bilinear_filter, rect, this,
+ GUI_ID_BILINEAR_CB, wgettext("Bi-Linear Filtering"));
+ }
+
+ {
+ core::rect<s32> rect(0, 0, option_w+20, 30);
+ rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
+ Environment->addCheckBox(m_data->trilinear_filter, rect, this,
+ GUI_ID_TRILINEAR_CB, wgettext("Tri-Linear Filtering"));
+ }
+
// Key change button
{
core::rect<s32> rect(0, 0, 120, 30);
@@ -761,6 +797,30 @@ void GUIMainMenu::readInput(MainMenuData *dst)
}
{
+ gui::IGUIElement *e = getElementFromId(GUI_ID_MIPMAP_CB);
+ if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
+ dst->mip_map = ((gui::IGUICheckBox*)e)->isChecked();
+ }
+
+ {
+ gui::IGUIElement *e = getElementFromId(GUI_ID_ANISOTROPIC_CB);
+ if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
+ dst->anisotropic_filter = ((gui::IGUICheckBox*)e)->isChecked();
+ }
+
+ {
+ gui::IGUIElement *e = getElementFromId(GUI_ID_BILINEAR_CB);
+ if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
+ dst->bilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
+ }
+
+ {
+ gui::IGUIElement *e = getElementFromId(GUI_ID_TRILINEAR_CB);
+ if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
+ dst->trilinear_filter = ((gui::IGUICheckBox*)e)->isChecked();
+ }
+
+ {
gui::IGUIElement *e = getElementFromId(GUI_ID_WORLD_LISTBOX);
if(e != NULL && e->getType() == gui::EGUIET_LIST_BOX)
dst->selected_world = ((gui::IGUIListBox*)e)->getSelected();
diff --git a/src/guiMainMenu.h b/src/guiMainMenu.h
index 715deb47d..abfc6bdb4 100644
--- a/src/guiMainMenu.h
+++ b/src/guiMainMenu.h
@@ -41,6 +41,10 @@ struct MainMenuData
bool smooth_lighting;
bool clouds_3d;
bool opaque_water;
+ bool mip_map;
+ bool anisotropic_filter;
+ bool bilinear_filter;
+ bool trilinear_filter;
// Server options
bool creative_mode;
bool enable_damage;
diff --git a/src/main.cpp b/src/main.cpp
index 6075e9d10..dcc47cd6b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1292,9 +1292,6 @@ int main(int argc, char *argv[])
video::IVideoDriver* driver = device->getVideoDriver();
- // Disable mipmaps (because some of them look ugly)
- driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
-
/*
This changes the minimum allowed number of vertices in a VBO.
Default is 500.
@@ -1439,6 +1436,11 @@ int main(int argc, char *argv[])
menudata.smooth_lighting = g_settings->getBool("smooth_lighting");
menudata.clouds_3d = g_settings->getBool("enable_3d_clouds");
menudata.opaque_water = g_settings->getBool("opaque_water");
+ menudata.mip_map = g_settings->getBool("mip_map");
+ menudata.anisotropic_filter = g_settings->getBool("anisotropic_filter");
+ menudata.bilinear_filter = g_settings->getBool("bilinear_filter");
+ menudata.trilinear_filter = g_settings->getBool("trilinear_filter");
+ driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, menudata.mip_map);
menudata.creative_mode = g_settings->getBool("creative_mode");
menudata.enable_damage = g_settings->getBool("enable_damage");
// Default to selecting nothing
@@ -1552,6 +1554,12 @@ int main(int argc, char *argv[])
g_settings->set("smooth_lighting", itos(menudata.smooth_lighting));
g_settings->set("enable_3d_clouds", itos(menudata.clouds_3d));
g_settings->set("opaque_water", itos(menudata.opaque_water));
+
+ g_settings->set("mip_map", itos(menudata.mip_map));
+ g_settings->set("anisotropic_filter", itos(menudata.anisotropic_filter));
+ g_settings->set("bilinear_filter", itos(menudata.bilinear_filter));
+ g_settings->set("trilinear_filter", itos(menudata.trilinear_filter));
+
g_settings->set("creative_mode", itos(menudata.creative_mode));
g_settings->set("enable_damage", itos(menudata.enable_damage));
g_settings->set("name", playername);
diff --git a/src/map.cpp b/src/map.cpp
index 39c6d292b..2845f3a67 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -1746,12 +1746,12 @@ void Map::transformLiquids(core::map<v3s16, MapBlock*> & modified_blocks)
content_t new_node_content;
s8 new_node_level = -1;
s8 max_node_level = -1;
- if (num_sources >= 2 || liquid_type == LIQUID_SOURCE) {
+ if ((num_sources >= 2 && nodemgr->get(liquid_kind).liquid_renewable) || liquid_type == LIQUID_SOURCE) {
// liquid_kind will be set to either the flowing alternative of the node (if it's a liquid)
// or the flowing alternative of the first of the surrounding sources (if it's air), so
// it's perfectly safe to use liquid_kind here to determine the new node content.
new_node_content = nodemgr->getId(nodemgr->get(liquid_kind).liquid_alternative_source);
- } else if (num_sources == 1 && sources[0].t != NEIGHBOR_LOWER) {
+ } else if (num_sources >= 1 && sources[0].t != NEIGHBOR_LOWER) {
// liquid_kind is set properly, see above
new_node_content = liquid_kind;
max_node_level = new_node_level = LIQUID_LEVEL_MAX;
diff --git a/src/mapgen.cpp b/src/mapgen.cpp
index 67e92f449..77b133020 100644
--- a/src/mapgen.cpp
+++ b/src/mapgen.cpp
@@ -1228,7 +1228,7 @@ double base_rock_level_2d(u64 seed, v2s16 p)
0.5+(float)p.X/125., 0.5+(float)p.Y/125.,
seed-932, 5, 0.7);
b = rangelim(b, 0.0, 1000.0);
- b = pow(b, 7);
+ b = b*b*b*b*b*b*b;
b *= 5;
b = rangelim(b, 0.5, 1000.0);
// Values 1.5...100 give quite horrible looking slopes
diff --git a/src/mesh.cpp b/src/mesh.cpp
index 0f075f72b..b9ec82e18 100644
--- a/src/mesh.cpp
+++ b/src/mesh.cpp
@@ -433,6 +433,9 @@ video::ITexture *generateTextureFromMesh(scene::IMesh *mesh,
}
// Create render target texture
+ video::ITexture *oldtexture = driver->findTexture(texture_name.c_str());
+ if(oldtexture)
+ driver->removeTexture(oldtexture);
video::ITexture *rtt = driver->addRenderTargetTexture(
dim, texture_name.c_str(), video::ECF_A8R8G8B8);
if(rtt == NULL)
diff --git a/src/nodedef.cpp b/src/nodedef.cpp
index d644dc229..180219ba8 100644
--- a/src/nodedef.cpp
+++ b/src/nodedef.cpp
@@ -203,6 +203,7 @@ void ContentFeatures::reset()
liquid_alternative_flowing = "";
liquid_alternative_source = "";
liquid_viscosity = 0;
+ liquid_renewable = true;
light_source = 0;
damage_per_second = 0;
node_box = NodeBox();
@@ -262,6 +263,9 @@ void ContentFeatures::serialize(std::ostream &os)
serializeSimpleSoundSpec(sound_footstep, os);
serializeSimpleSoundSpec(sound_dig, os);
serializeSimpleSoundSpec(sound_dug, os);
+ // Stuff below should be moved to correct place in a version that otherwise changes
+ // the protocol version
+ writeU8(os, liquid_renewable);
}
void ContentFeatures::deSerialize(std::istream &is)
@@ -319,6 +323,9 @@ void ContentFeatures::deSerialize(std::istream &is)
// If you add anything here, insert it primarily inside the try-catch
// block to not need to increase the version.
try{
+ // Stuff below should be moved to correct place in a version that
+ // otherwise changes the protocol version
+ liquid_renewable = readU8(is);
}catch(SerializationError &e) {};
}
diff --git a/src/nodedef.h b/src/nodedef.h
index 7c6931834..4ff6c6b48 100644
--- a/src/nodedef.h
+++ b/src/nodedef.h
@@ -209,6 +209,8 @@ struct ContentFeatures
// 1 giving almost instantaneous propagation and 7 being
// the slowest possible
u8 liquid_viscosity;
+ // Is liquid renewable (new liquid source will be created between 2 existing)
+ bool liquid_renewable;
// Amount of light the node emits
u8 light_source;
u32 damage_per_second;
diff --git a/src/noise.cpp b/src/noise.cpp
index 4a7fc87e7..e75fbf4bd 100644
--- a/src/noise.cpp
+++ b/src/noise.cpp
@@ -37,7 +37,7 @@ double dotProduct(double vx, double vy, double wx, double wy){
}
double easeCurve(double t){
- return 6*pow(t,5)-15*pow(t,4)+10*pow(t,3);
+ return t * t * t * (6. * t * t - 15. * t + 10.);
}
double linearInterpolation(double x0, double x1, double t){
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 9fa927ff3..09900ce1f 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -1238,6 +1238,7 @@ static ContentFeatures read_content_features(lua_State *L, int index)
// the slowest possible
f.liquid_viscosity = getintfield_default(L, index,
"liquid_viscosity", f.liquid_viscosity);
+ getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
// Amount of light the node emits
f.light_source = getintfield_default(L, index,
"light_source", f.light_source);
diff --git a/src/tile.cpp b/src/tile.cpp
index f7f1779ca..e676c56c4 100644
--- a/src/tile.cpp
+++ b/src/tile.cpp
@@ -519,6 +519,15 @@ core::dimension2d<u32> imageTransformDimension(u32 transform, core::dimension2d<
void imageTransform(u32 transform, video::IImage *src, video::IImage *dst);
/*
+ Adds a new texture to the video driver and returns a pointer to it.
+ This pointer should not be dropped. Any texture that was registered
+ with that name before is removed (this may invalidate some ITexture
+ pointers).
+*/
+video::ITexture* register_texture(video::IVideoDriver *driver,
+ std::string name, video::IImage *img);
+
+/*
Generate image based on a string like "stone.png" or "[crack0".
if baseimg is NULL, it is created. Otherwise stuff is made on it.
*/
@@ -686,11 +695,9 @@ u32 TextureSource::getTextureIdDirect(const std::string &name)
" create texture \""<<name<<"\""<<std::endl;
}
+ // Create texture from resulting image
if(baseimg != NULL)
- {
- // Create texture from resulting image
- t = driver->addTexture(name.c_str(), baseimg);
- }
+ t = register_texture(driver, name, baseimg);
/*
Add texture to caches (add NULL textures too)
@@ -809,7 +816,7 @@ void TextureSource::rebuildImagesAndTextures()
// Create texture from resulting image
video::ITexture *t = NULL;
if(img)
- t = driver->addTexture(sap->name.c_str(), img);
+ t = register_texture(driver, sap->name, img);
// Replace texture
sap->a.atlas = t;
@@ -1044,7 +1051,7 @@ void TextureSource::buildMainAtlas(class IGameDef *gamedef)
/*
Make texture
*/
- video::ITexture *t = driver->addTexture("__main_atlas__", atlas_img);
+ video::ITexture *t = register_texture(driver, "__main_atlas__", atlas_img);
assert(t);
/*
@@ -1135,6 +1142,15 @@ video::IImage* generate_image_from_scratch(std::string name,
return baseimg;
}
+video::ITexture* register_texture(video::IVideoDriver *driver,
+ std::string name, video::IImage *img)
+{
+ video::ITexture *old_texture = driver->findTexture(name.c_str());
+ if(old_texture)
+ driver->removeTexture(old_texture);
+ return driver->addTexture(name.c_str(), img);
+}
+
bool generate_image(std::string part_of_name, video::IImage *& baseimg,
IrrlichtDevice *device, SourceImageCache *sourcecache)
{
@@ -1541,12 +1557,12 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
assert(img_top && img_left && img_right);
// Create textures from images
- video::ITexture *texture_top = driver->addTexture(
- (imagename_top + "__temp__").c_str(), img_top);
- video::ITexture *texture_left = driver->addTexture(
- (imagename_left + "__temp__").c_str(), img_left);
- video::ITexture *texture_right = driver->addTexture(
- (imagename_right + "__temp__").c_str(), img_right);
+ video::ITexture *texture_top = register_texture(driver,
+ imagename_top + "__temp1__", img_top);
+ video::ITexture *texture_left = register_texture(driver,
+ imagename_left + "__temp2__", img_left);
+ video::ITexture *texture_right = register_texture(driver,
+ imagename_right + "__temp3__", img_right);
assert(texture_top && texture_left && texture_right);
// Drop images