Merge remote-tracking branch 'origin/master'

This commit is contained in:
Weblate 2013-05-01 15:33:15 +02:00
commit 97cddd1b96
45 changed files with 1717 additions and 162 deletions

@ -24,4 +24,5 @@ dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua") dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua") dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua")
dofile(minetest.get_modpath("__builtin").."/falling.lua") dofile(minetest.get_modpath("__builtin").."/falling.lua")
dofile(minetest.get_modpath("__builtin").."/features.lua")

@ -675,7 +675,7 @@ minetest.register_chatcommand("msg", {
if found then if found then
if minetest.env:get_player_by_name(sendto) then if minetest.env:get_player_by_name(sendto) then
minetest.log("action", "PM from "..name.." to "..sendto..": "..message) minetest.log("action", "PM from "..name.." to "..sendto..": "..message)
minetest.chat_send_player(sendto, "PM from "..name..": "..message) minetest.chat_send_player(sendto, "PM from "..name..": "..message, false)
minetest.chat_send_player(name, "Message sent") minetest.chat_send_player(name, "Message sent")
else else
minetest.chat_send_player(name, "The player "..sendto.." is not online") minetest.chat_send_player(name, "The player "..sendto.." is not online")

28
builtin/features.lua Normal file

@ -0,0 +1,28 @@
-- Minetest: builtin/features.lua
minetest.features = {
"glasslike_framed" = true,
"nodebox_as_selectionbox" = true,
"chat_send_player_param3" = true,
"get_all_craft_recipes_works" = true,
"use_texture_alpha" = true,
}
function minetest.has_feature(arg)
if type(arg) == "table" then
missing_features = {}
result = true
for ft, _ in pairs(arg) do
if not minetest.features[ftr] then
missing_features[ftr] = true
result = false
end
end
return result, missing_features
elseif type(arg) == "string" then
if not minetest.features[arg] then
return false, {[arg]=true}
end
return true, {}
end
end

@ -0,0 +1 @@
trans_alphach

@ -0,0 +1,25 @@
uniform sampler2D myTexture;
uniform float fogDistance;
varying vec3 vPosition;
void main (void)
{
vec4 col = texture2D(myTexture, vec2(gl_TexCoord[0]));
col *= gl_Color;
float a = col.a;
col = col * col; // SRGB -> Linear
col *= 1.8;
col.r = 1.0 - exp(1.0 - col.r) / exp(1.0);
col.g = 1.0 - exp(1.0 - col.g) / exp(1.0);
col.b = 1.0 - exp(1.0 - col.b) / exp(1.0);
col = sqrt(col); // Linear -> SRGB
if(fogDistance != 0.0){
float d = max(0.0, min(vPosition.z / fogDistance * 1.5 - 0.6, 1.0));
a = mix(a, 0.0, d);
}
gl_FragColor = vec4(col.r, col.g, col.b, a);
}

@ -0,0 +1,51 @@
uniform mat4 mWorldViewProj;
uniform mat4 mInvWorld;
uniform mat4 mTransWorld;
uniform float dayNightRatio;
varying vec3 vPosition;
void main(void)
{
gl_Position = mWorldViewProj * gl_Vertex;
vPosition = (mWorldViewProj * gl_Vertex).xyz;
vec4 color;
//color = vec4(1.0, 1.0, 1.0, 1.0);
float day = gl_Color.r;
float night = gl_Color.g;
float light_source = gl_Color.b;
/*color.r = mix(night, day, dayNightRatio);
color.g = color.r;
color.b = color.r;*/
float rg = mix(night, day, dayNightRatio);
rg += light_source * 1.0; // Make light sources brighter
float b = rg;
// Moonlight is blue
b += (day - night) / 13.0;
rg -= (day - night) / 13.0;
// Emphase blue a bit in darker places
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
b += max(0.0, (1.0 - abs(b - 0.13)/0.17) * 0.025);
// Artificial light is yellow-ish
// See C++ implementation in mapblock_mesh.cpp finalColorBlend()
rg += max(0.0, (1.0 - abs(rg - 0.85)/0.15) * 0.065);
color.r = rg;
color.g = rg;
color.b = b;
color.a = gl_Color.a;
gl_FrontColor = gl_BackColor = color;
gl_TexCoord[0] = gl_MultiTexCoord0;
}

@ -329,6 +329,7 @@ Look for examples in games/minimal or games/minetest_game.
- liquid - liquid
- flowingliquid - flowingliquid
- glasslike - glasslike
- glasslike_framed
- allfaces - allfaces
- allfaces_optional - allfaces_optional
- torchlike - torchlike
@ -409,6 +410,12 @@ ranging in value from 0 to 1.
The name field is not yet used, but should contain a description of what the HUD element represents. The name field is not yet used, but should contain a description of what the HUD element represents.
The direction field is the direction in which something is drawn. The direction field is the direction in which something is drawn.
0 draws from left to right, 1 draws from right to left, 2 draws from top to bottom, and 3 draws from bottom to top. 0 draws from left to right, 1 draws from right to left, 2 draws from top to bottom, and 3 draws from bottom to top.
The alignment field specifies how the item will be aligned. It ranges from -1 to 1,
with 0 being the center, -1 is moved to the left/up, and 1 is to the right/down. Fractional
values can be used.
The offset field specifies a pixel offset from the position. Contrary to position,
the offset is not scaled to screen size. This allows for some precisely-positioned
items in the HUD.
Below are the specific uses for fields in each type; fields not listed for that type are ignored. Below are the specific uses for fields in each type; fields not listed for that type are ignored.
Note: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages. Note: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages.
@ -418,6 +425,8 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
- scale: The scale of the image, with 1 being the original texture size. - scale: The scale of the image, with 1 being the original texture size.
Only the X coordinate scale is used. Only the X coordinate scale is used.
- text: The name of the texture that is displayed. - text: The name of the texture that is displayed.
- alignment: The alignment of the image.
- offset: offset in pixels from position.
- text - text
Displays text on the HUD. Displays text on the HUD.
- scale: Defines the bounding rectangle of the text. - scale: Defines the bounding rectangle of the text.
@ -425,12 +434,15 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
- text: The text to be displayed in the HUD element. - text: The text to be displayed in the HUD element.
- number: An integer containing the RGB value of the color used to draw the text. - number: An integer containing the RGB value of the color used to draw the text.
Specify 0xFFFFFF for white text, 0xFF0000 for red, and so on. Specify 0xFFFFFF for white text, 0xFF0000 for red, and so on.
- alignment: The alignment of the text.
- offset: offset in pixels from position.
- statbar - statbar
Displays a horizontal bar made up of half-images. Displays a horizontal bar made up of half-images.
- text: The name of the texture that is used. - text: The name of the texture that is used.
- number: The number of half-textures that are displayed. - number: The number of half-textures that are displayed.
If odd, will end with a vertically center-split texture. If odd, will end with a vertically center-split texture.
- direction - direction
- offset: offset in pixels from position.
- inventory - inventory
- text: The name of the inventory list to be displayed. - text: The name of the inventory list to be displayed.
- number: Number of items in the inventory to be displayed. - number: Number of items in the inventory to be displayed.
@ -900,6 +912,11 @@ minetest.get_modnames() -> list of installed mods
minetest.get_worldpath() -> eg. "/home/user/.minetest/world" minetest.get_worldpath() -> eg. "/home/user/.minetest/world"
^ Useful for storing custom data ^ Useful for storing custom data
minetest.is_singleplayer() minetest.is_singleplayer()
minetest.features
^ table containing API feature flags: {foo=true, bar=true}
minetest.has_feature(arg) -> bool, missing_features
^ arg: string or table in format {foo=true, bar=true}
^ missing_features: {foo=true, bar=true}
minetest.debug(line) minetest.debug(line)
^ Always printed to stderr and logfile (print() is redirected here) ^ Always printed to stderr and logfile (print() is redirected here)
@ -991,10 +1008,12 @@ minetest.auth_reload()
^ These call the authentication handler ^ These call the authentication handler
minetest.check_player_privs(name, {priv1=true,...}) -> bool, missing_privs minetest.check_player_privs(name, {priv1=true,...}) -> bool, missing_privs
^ A quickhand for checking privileges ^ A quickhand for checking privileges
minetest.get_player_ip(name) -> IP address string
Chat: Chat:
minetest.chat_send_all(text) minetest.chat_send_all(text)
minetest.chat_send_player(name, text) minetest.chat_send_player(name, text, prepend)
^ prepend: optional, if it is set to false "Server -!- " will not be prepended to the message
Inventory: Inventory:
minetest.get_inventory(location) -> InvRef minetest.get_inventory(location) -> InvRef
@ -1420,6 +1439,10 @@ Player-only: (no-op for other objects)
- hud_change(id, stat, value): change a value of a previously added HUD element - hud_change(id, stat, value): change a value of a previously added HUD element
^ element stat values: position, name, scale, text, number, item, dir ^ element stat values: position, name, scale, text, number, item, dir
- hud_get(id): gets the HUD element definition structure of the specified ID - hud_get(id): gets the HUD element definition structure of the specified ID
- hud_set_flags(flags): sets specified HUD flags to true/false
^ flags: (is visible) hotbar, healthbar, crosshair, wielditem
^ pass a table containing a true/false value of each flag to be set or unset
^ if a flag is nil, the flag is not modified
InvRef: Reference to an inventory InvRef: Reference to an inventory
methods: methods:
@ -1636,6 +1659,7 @@ Node definition (register_node)
^ Special textures of node; used rarely (old field name: special_materials) ^ Special textures of node; used rarely (old field name: special_materials)
^ List can be shortened to needed length ^ List can be shortened to needed length
alpha = 255, alpha = 255,
use_texture_alpha = false, -- Use texture's alpha channel
post_effect_color = {a=0, r=0, g=0, b=0}, -- If player is inside node post_effect_color = {a=0, r=0, g=0, b=0}, -- If player is inside node
paramtype = "none", -- See "Nodes" paramtype = "none", -- See "Nodes"
paramtype2 = "none", -- See "Nodes" paramtype2 = "none", -- See "Nodes"
@ -1857,4 +1881,8 @@ HUD Definition (hud_add, hud_get)
^ Selected item in inventory. 0 for no item selected. ^ Selected item in inventory. 0 for no item selected.
direction = 0, direction = 0,
^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top ^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
alignment = {x=0, y=0},
^ See "HUD Element Types"
offset = {x=0, y=0},
^ See "HUD Element Types"
} }

@ -136,6 +136,8 @@
#screenshot_path = . #screenshot_path = .
# Amount of view bobbing (0 = no view bobbing, 1.0 = normal, 2.0 = double) # Amount of view bobbing (0 = no view bobbing, 1.0 = normal, 2.0 = double)
#view_bobbing_amount = 1.0 #view_bobbing_amount = 1.0
# Amount of fall bobbing (0 = no fall bobbing, 1.0 = normal, 2.0 = double)
#fall_bobbing_amount = 0.0
# Anaglyph stereo # Anaglyph stereo
#anaglyph = false #anaglyph = false
#anaglyph_strength = 0.1 #anaglyph_strength = 0.1

757
po/no/minetest.po Normal file

@ -0,0 +1,757 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: minetest\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-03-30 19:56+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
#: src/guiConfigureWorld.cpp:125
msgid ""
"Warning: Some mods are not configured yet.\n"
"They will be enabled by default when you save the configuration. "
msgstr ""
#: src/guiConfigureWorld.cpp:144
msgid ""
"Warning: Some configured mods are missing.\n"
"Their setting will be removed when you save the configuration. "
msgstr ""
#: src/guiConfigureWorld.cpp:208
msgid "enabled"
msgstr ""
#: src/guiConfigureWorld.cpp:215
msgid "Enable All"
msgstr ""
#: src/guiConfigureWorld.cpp:222
msgid "Disable All"
msgstr ""
#: src/guiConfigureWorld.cpp:228
msgid "depends on:"
msgstr ""
#: src/guiConfigureWorld.cpp:240
msgid "is required by:"
msgstr ""
#: src/guiConfigureWorld.cpp:262 src/guiCreateWorld.cpp:165
#: src/guiKeyChangeMenu.cpp:179 src/keycode.cpp:223
msgid "Cancel"
msgstr ""
#: src/guiConfigureWorld.cpp:268 src/guiKeyChangeMenu.cpp:173
msgid "Save"
msgstr ""
#: src/guiConfigureWorld.cpp:394
msgid "Configuration saved. "
msgstr ""
#: src/guiConfigureWorld.cpp:402
msgid "Warning: Configuration not consistent. "
msgstr ""
#: src/guiConfirmMenu.cpp:120
msgid "Yes"
msgstr ""
#: src/guiConfirmMenu.cpp:126
msgid "No"
msgstr ""
#: src/guiCreateWorld.cpp:116
msgid "World name"
msgstr ""
#: src/guiCreateWorld.cpp:135
msgid "Game"
msgstr ""
#: src/guiCreateWorld.cpp:159
msgid "Create"
msgstr ""
#: src/guiDeathScreen.cpp:96
msgid "You died."
msgstr ""
#: src/guiDeathScreen.cpp:104
msgid "Respawn"
msgstr ""
#: src/guiFormSpecMenu.cpp:582
msgid "Left click: Move all items, Right click: Move single item"
msgstr ""
#: src/guiFormSpecMenu.cpp:607 src/guiMessageMenu.cpp:109
#: src/guiTextInputMenu.cpp:131
msgid "Proceed"
msgstr ""
#: src/guiKeyChangeMenu.cpp:114
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
msgstr ""
#: src/guiKeyChangeMenu.cpp:151
msgid "\"Use\" = climb down"
msgstr ""
#: src/guiKeyChangeMenu.cpp:164
msgid "Double tap \"jump\" to toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:269
msgid "Key already in use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:347
msgid "press key"
msgstr ""
#: src/guiKeyChangeMenu.cpp:372
msgid "Forward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:373
msgid "Backward"
msgstr ""
#: src/guiKeyChangeMenu.cpp:374 src/keycode.cpp:228
msgid "Left"
msgstr ""
#: src/guiKeyChangeMenu.cpp:375 src/keycode.cpp:228
msgid "Right"
msgstr ""
#: src/guiKeyChangeMenu.cpp:376
msgid "Use"
msgstr ""
#: src/guiKeyChangeMenu.cpp:377
msgid "Jump"
msgstr ""
#: src/guiKeyChangeMenu.cpp:378
msgid "Sneak"
msgstr ""
#: src/guiKeyChangeMenu.cpp:379
msgid "Drop"
msgstr ""
#: src/guiKeyChangeMenu.cpp:380
msgid "Inventory"
msgstr ""
#: src/guiKeyChangeMenu.cpp:381
msgid "Chat"
msgstr ""
#: src/guiKeyChangeMenu.cpp:382
msgid "Command"
msgstr ""
#: src/guiKeyChangeMenu.cpp:383
msgid "Console"
msgstr ""
#: src/guiKeyChangeMenu.cpp:384
msgid "Toggle fly"
msgstr ""
#: src/guiKeyChangeMenu.cpp:385
msgid "Toggle fast"
msgstr ""
#: src/guiKeyChangeMenu.cpp:386
msgid "Toggle noclip"
msgstr ""
#: src/guiKeyChangeMenu.cpp:387
msgid "Range select"
msgstr ""
#: src/guiKeyChangeMenu.cpp:388
msgid "Print stacks"
msgstr ""
#: src/guiMainMenu.cpp:92
msgid "Cannot create world: Name contains invalid characters"
msgstr ""
#: src/guiMainMenu.cpp:101
msgid "Cannot create world: A world by this name already exists"
msgstr ""
#: src/guiMainMenu.cpp:283
msgid "Singleplayer"
msgstr ""
#: src/guiMainMenu.cpp:284
msgid "Multiplayer"
msgstr ""
#: src/guiMainMenu.cpp:285
msgid "Advanced"
msgstr ""
#: src/guiMainMenu.cpp:286
msgid "Settings"
msgstr ""
#: src/guiMainMenu.cpp:287
msgid "Credits"
msgstr ""
#: src/guiMainMenu.cpp:317
msgid "Select World:"
msgstr ""
#: src/guiMainMenu.cpp:339 src/guiMainMenu.cpp:511 src/keycode.cpp:229
msgid "Delete"
msgstr ""
#: src/guiMainMenu.cpp:346
msgid "New"
msgstr ""
#: src/guiMainMenu.cpp:354
msgid "Configure"
msgstr ""
#: src/guiMainMenu.cpp:369 src/keycode.cpp:248
msgid "Play"
msgstr ""
#: src/guiMainMenu.cpp:380 src/guiMainMenu.cpp:619
msgid "Creative Mode"
msgstr ""
#: src/guiMainMenu.cpp:386 src/guiMainMenu.cpp:625
msgid "Enable Damage"
msgstr ""
#: src/guiMainMenu.cpp:406 src/guiMainMenu.cpp:541
msgid "Name/Password"
msgstr ""
#: src/guiMainMenu.cpp:442 src/guiMainMenu.cpp:459 src/guiMainMenu.cpp:1184
msgid "Favorites:"
msgstr ""
#: src/guiMainMenu.cpp:450 src/guiMainMenu.cpp:1194
msgid "Public Server List:"
msgstr ""
#: src/guiMainMenu.cpp:470 src/guiMainMenu.cpp:568
msgid "Address/Port"
msgstr ""
#: src/guiMainMenu.cpp:497 src/guiMainMenu.cpp:1183
msgid "Show Public"
msgstr ""
#: src/guiMainMenu.cpp:501 src/guiMainMenu.cpp:1193
msgid "Show Favorites"
msgstr ""
#: src/guiMainMenu.cpp:521
msgid "Connect"
msgstr ""
#: src/guiMainMenu.cpp:591
msgid "Leave address blank to start a local server."
msgstr ""
#: src/guiMainMenu.cpp:600
msgid "Start Game / Connect"
msgstr ""
#: src/guiMainMenu.cpp:632
msgid "Public"
msgstr ""
#: src/guiMainMenu.cpp:640 src/guiMainMenu.cpp:1113
msgid "Delete world"
msgstr ""
#: src/guiMainMenu.cpp:647
msgid "Create world"
msgstr ""
#: src/guiMainMenu.cpp:681
msgid "Fancy trees"
msgstr ""
#: src/guiMainMenu.cpp:687
msgid "Smooth Lighting"
msgstr ""
#: src/guiMainMenu.cpp:693
msgid "3D Clouds"
msgstr ""
#: src/guiMainMenu.cpp:699
msgid "Opaque water"
msgstr ""
#: src/guiMainMenu.cpp:709
msgid "Mip-Mapping"
msgstr ""
#: src/guiMainMenu.cpp:716
msgid "Anisotropic Filtering"
msgstr ""
#: src/guiMainMenu.cpp:723
msgid "Bi-Linear Filtering"
msgstr ""
#: src/guiMainMenu.cpp:730
msgid "Tri-Linear Filtering"
msgstr ""
#: src/guiMainMenu.cpp:738
msgid "Shaders"
msgstr ""
#: src/guiMainMenu.cpp:745
msgid "Preload item visuals"
msgstr ""
#: src/guiMainMenu.cpp:752
msgid "Enable Particles"
msgstr ""
#: src/guiMainMenu.cpp:759
msgid "Finite liquid"
msgstr ""
#: src/guiMainMenu.cpp:769
msgid "Change keys"
msgstr ""
#: src/guiMainMenu.cpp:1084
msgid "Address required."
msgstr ""
#: src/guiMainMenu.cpp:1102
msgid "Cannot delete world: Nothing selected"
msgstr ""
#: src/guiMainMenu.cpp:1117
msgid "Files to be deleted"
msgstr ""
#: src/guiMainMenu.cpp:1133
msgid "Cannot create world: No games found"
msgstr ""
#: src/guiMainMenu.cpp:1149
msgid "Cannot configure world: Nothing selected"
msgstr ""
#: src/guiMainMenu.cpp:1256
msgid "Failed to delete all world files"
msgstr ""
#: src/guiPasswordChange.cpp:108
msgid "Old Password"
msgstr ""
#: src/guiPasswordChange.cpp:125
msgid "New Password"
msgstr ""
#: src/guiPasswordChange.cpp:141
msgid "Confirm Password"
msgstr ""
#: src/guiPasswordChange.cpp:158
msgid "Change"
msgstr ""
#: src/guiPasswordChange.cpp:167
msgid "Passwords do not match!"
msgstr ""
#: src/guiPauseMenu.cpp:123
msgid "Continue"
msgstr ""
#: src/guiPauseMenu.cpp:132
msgid "Change Password"
msgstr ""
#: src/guiPauseMenu.cpp:140
msgid "Sound Volume"
msgstr ""
#: src/guiPauseMenu.cpp:147
msgid "Exit to Menu"
msgstr ""
#: src/guiPauseMenu.cpp:154
msgid "Exit to OS"
msgstr ""
#: src/guiPauseMenu.cpp:161
msgid ""
"Default Controls:\n"
"- WASD: Walk\n"
"- Mouse left: dig/hit\n"
"- Mouse right: place/use\n"
"- Mouse wheel: select item\n"
"- 0...9: select item\n"
"- Shift: sneak\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Inventory menu\n"
"- ESC: This menu\n"
"- T: Chat\n"
msgstr ""
#: src/guiVolumeChange.cpp:108
msgid "Sound Volume: "
msgstr ""
#: src/guiVolumeChange.cpp:121
msgid "Exit"
msgstr ""
#: src/keycode.cpp:223
msgid "Left Button"
msgstr ""
#: src/keycode.cpp:223
msgid "Middle Button"
msgstr ""
#: src/keycode.cpp:223
msgid "Right Button"
msgstr ""
#: src/keycode.cpp:223
msgid "X Button 1"
msgstr ""
#: src/keycode.cpp:224
msgid "Back"
msgstr ""
#: src/keycode.cpp:224
msgid "Clear"
msgstr ""
#: src/keycode.cpp:224
msgid "Return"
msgstr ""
#: src/keycode.cpp:224
msgid "Tab"
msgstr ""
#: src/keycode.cpp:224
msgid "X Button 2"
msgstr ""
#: src/keycode.cpp:225
msgid "Capital"
msgstr ""
#: src/keycode.cpp:225
msgid "Control"
msgstr ""
#: src/keycode.cpp:225
msgid "Kana"
msgstr ""
#: src/keycode.cpp:225
msgid "Menu"
msgstr ""
#: src/keycode.cpp:225
msgid "Pause"
msgstr ""
#: src/keycode.cpp:225
msgid "Shift"
msgstr ""
#: src/keycode.cpp:226
msgid "Convert"
msgstr ""
#: src/keycode.cpp:226
msgid "Escape"
msgstr ""
#: src/keycode.cpp:226
msgid "Final"
msgstr ""
#: src/keycode.cpp:226
msgid "Junja"
msgstr ""
#: src/keycode.cpp:226
msgid "Kanji"
msgstr ""
#: src/keycode.cpp:226
msgid "Nonconvert"
msgstr ""
#: src/keycode.cpp:227
msgid "Accept"
msgstr ""
#: src/keycode.cpp:227
msgid "End"
msgstr ""
#: src/keycode.cpp:227
msgid "Home"
msgstr ""
#: src/keycode.cpp:227
msgid "Mode Change"
msgstr ""
#: src/keycode.cpp:227
msgid "Next"
msgstr ""
#: src/keycode.cpp:227
msgid "Prior"
msgstr ""
#: src/keycode.cpp:227
msgid "Space"
msgstr ""
#: src/keycode.cpp:228
msgid "Down"
msgstr ""
#: src/keycode.cpp:228
msgid "Execute"
msgstr ""
#: src/keycode.cpp:228
msgid "Print"
msgstr ""
#: src/keycode.cpp:228
msgid "Select"
msgstr ""
#: src/keycode.cpp:228
msgid "Up"
msgstr ""
#: src/keycode.cpp:229
msgid "Help"
msgstr ""
#: src/keycode.cpp:229
msgid "Insert"
msgstr ""
#: src/keycode.cpp:229
msgid "Snapshot"
msgstr ""
#: src/keycode.cpp:232
msgid "Left Windows"
msgstr ""
#: src/keycode.cpp:233
msgid "Apps"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 0"
msgstr ""
#: src/keycode.cpp:233
msgid "Numpad 1"
msgstr ""
#: src/keycode.cpp:233
msgid "Right Windows"
msgstr ""
#: src/keycode.cpp:233
msgid "Sleep"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 2"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 3"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 4"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 5"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 6"
msgstr ""
#: src/keycode.cpp:234
msgid "Numpad 7"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad *"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad +"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad -"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad /"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad 8"
msgstr ""
#: src/keycode.cpp:235
msgid "Numpad 9"
msgstr ""
#: src/keycode.cpp:239
msgid "Num Lock"
msgstr ""
#: src/keycode.cpp:239
msgid "Scroll Lock"
msgstr ""
#: src/keycode.cpp:240
msgid "Left Shift"
msgstr ""
#: src/keycode.cpp:240
msgid "Right Shift"
msgstr ""
#: src/keycode.cpp:241
msgid "Left Control"
msgstr ""
#: src/keycode.cpp:241
msgid "Left Menu"
msgstr ""
#: src/keycode.cpp:241
msgid "Right Control"
msgstr ""
#: src/keycode.cpp:241
msgid "Right Menu"
msgstr ""
#: src/keycode.cpp:243
msgid "Comma"
msgstr ""
#: src/keycode.cpp:243
msgid "Minus"
msgstr ""
#: src/keycode.cpp:243
msgid "Period"
msgstr ""
#: src/keycode.cpp:243
msgid "Plus"
msgstr ""
#: src/keycode.cpp:247
msgid "Attn"
msgstr ""
#: src/keycode.cpp:247
msgid "CrSel"
msgstr ""
#: src/keycode.cpp:248
msgid "Erase OEF"
msgstr ""
#: src/keycode.cpp:248
msgid "ExSel"
msgstr ""
#: src/keycode.cpp:248
msgid "OEM Clear"
msgstr ""
#: src/keycode.cpp:248
msgid "PA1"
msgstr ""
#: src/keycode.cpp:248
msgid "Zoom"
msgstr ""
#: src/main.cpp:1506
msgid "Main Menu"
msgstr ""
#: src/main.cpp:1830
msgid "Failed to initialize world"
msgstr ""
#: src/main.cpp:1842
msgid "No world selected and no address provided. Nothing to do."
msgstr ""
#: src/main.cpp:1850
msgid "Could not find or load game \""
msgstr ""
#: src/main.cpp:1864
msgid "Invalid gamespec."
msgstr ""
#: src/main.cpp:1904
msgid "Connection error (timed out?)"
msgstr ""
#: src/main.cpp:1915
msgid ""
"\n"
"Check debug.txt for details."
msgstr ""

@ -263,6 +263,8 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1; fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1;
// Amplify according to the intensity of the impact // Amplify according to the intensity of the impact
fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5; fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5;
fall_bobbing *= g_settings->getFloat("fall_bobbing_amount");
} }
// Set head node transformation // Set head node transformation

@ -20,18 +20,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "util/numeric.h" #include "util/numeric.h"
#include "map.h" #include "map.h"
#include "mapgen.h" #include "mapgen.h"
#include "mapgen_v6.h"
#include "mapgen_v7.h"
#include "cavegen.h" #include "cavegen.h"
CaveV6::CaveV6(Mapgen *mg, PseudoRandom *ps, PseudoRandom *ps2, CaveV6::CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool is_large_cave) {
bool is_large_cave, content_t c_water, content_t c_lava) { this->mg = mg;
this->vm = mg->vm; this->vm = mg->vm;
this->ndef = mg->ndef;
this->water_level = mg->water_level; this->water_level = mg->water_level;
this->large_cave = is_large_cave; this->large_cave = is_large_cave;
this->ps = ps; this->ps = ps;
this->ps2 = ps2; this->ps2 = ps2;
this->c_water_source = c_water; this->c_water_source = mg->c_water_source;
this->c_lava_source = c_lava; this->c_lava_source = mg->c_lava_source;
min_tunnel_diameter = 2; min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2, 6); max_tunnel_diameter = ps->range(2, 6);
@ -152,13 +155,6 @@ void CaveV6::makeTunnel(bool dirswitch) {
); );
} }
/*if(large_cave){
v3f p = orp + vec;
s16 h = find_ground_level_clever(vmanip, v2s16(p.X, p.Z), ndef);
route_y_min = h - rs/3;
route_y_max = h + rs;
}*/
vec += main_direction; vec += main_direction;
v3f rp = orp + vec; v3f rp = orp + vec;
@ -181,7 +177,7 @@ void CaveV6::makeTunnel(bool dirswitch) {
float veclen = vec.getLength(); float veclen = vec.getLength();
// As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE // As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE
if (veclen == 0.0) if (veclen < 0.05)
veclen = 1.0; veclen = 1.0;
// Every second section is rough // Every second section is rough
@ -220,11 +216,7 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) { for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
s16 maxabsxz = MYMAX(abs(x0), abs(z0)); s16 maxabsxz = MYMAX(abs(x0), abs(z0));
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1); s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
for (s16 y0 = -si2; y0 <= si2; y0++) { for (s16 y0 = -si2; y0 <= si2; y0++) {
// Make better floors in small caves
//if(y0 <= -rs/2 && rs<=7)
// continue;
if (large_cave_is_flat) { if (large_cave_is_flat) {
// Make large caves not so tall // Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3) if (rs > 7 && abs(y0) >= rs / 3)
@ -242,7 +234,7 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
if (large_cave) { if (large_cave) {
int full_ymin = node_min.Y - MAP_BLOCKSIZE; int full_ymin = node_min.Y - MAP_BLOCKSIZE;
int full_ymax = node_max.Y + MAP_BLOCKSIZE; int full_ymax = node_max.Y + MAP_BLOCKSIZE;
if (flooded && full_ymin < water_level && full_ymax > water_level) { if (flooded && full_ymin < water_level && full_ymax > water_level) {
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode; vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
} else if (flooded && full_ymax < water_level) { } else if (flooded && full_ymax < water_level) {
@ -264,3 +256,278 @@ void CaveV6::carveRoute(v3f vec, float f, bool randomize_xz) {
} }
} }
} }
///////////////////////////////////////// Caves V7
CaveV7::CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool is_large_cave) {
this->mg = mg;
this->vm = mg->vm;
this->ndef = mg->ndef;
this->water_level = mg->water_level;
this->large_cave = is_large_cave;
this->ps = ps;
this->c_water_source = mg->c_water_source;
this->c_lava_source = mg->c_lava_source;
dswitchint = ps->range(1, 14);
flooded = ps->range(1, 2) == 2;
if (large_cave) {
part_max_length_rs = ps->range(2, 4);
tunnel_routepoints = ps->range(5, ps->range(15, 30));
min_tunnel_diameter = 5;
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
} else {
part_max_length_rs = ps->range(2, 9);
tunnel_routepoints = ps->range(10, ps->range(15, 30));
min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2, 6);
}
large_cave_is_flat = (ps->range(0, 1) == 0);
}
void CaveV7::makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height) {
node_min = nmin;
node_max = nmax;
max_stone_y = max_stone_height;
main_direction = v3f(0, 0, 0);
// Allowed route area size in nodes
ar = node_max - node_min + v3s16(1, 1, 1);
// Area starting point in nodes
of = node_min;
// Allow a bit more
//(this should be more than the maximum radius of the tunnel)
s16 insure = 10;
s16 more = MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure;
ar += v3s16(1,0,1) * more * 2;
of -= v3s16(1,0,1) * more;
route_y_min = 0;
// Allow half a diameter + 7 over stone surface
route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7;
// Limit maximum to area
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
if (large_cave) {
s16 min = 0;
if (node_min.Y < water_level && node_max.Y > water_level) {
min = water_level - max_tunnel_diameter/3 - of.Y;
route_y_max = water_level + max_tunnel_diameter/3 - of.Y;
}
route_y_min = ps->range(min, min + max_tunnel_diameter);
route_y_min = rangelim(route_y_min, 0, route_y_max);
}
s16 route_start_y_min = route_y_min;
s16 route_start_y_max = route_y_max;
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1);
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1);
// Randomize starting position
orp = v3f(
(float)(ps->next() % ar.X) + 0.5,
(float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5,
(float)(ps->next() % ar.Z) + 0.5
);
// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);
}
void CaveV7::makeTunnel(bool dirswitch) {
if (dirswitch && !large_cave) {
main_direction = v3f(
((float)(ps->next() % 20) - (float)10) / 10,
((float)(ps->next() % 20) - (float)10) / 30,
((float)(ps->next() % 20) - (float)10) / 10
);
main_direction *= (float)ps->range(0, 10) / 10;
}
// Randomize size
s16 min_d = min_tunnel_diameter;
s16 max_d = max_tunnel_diameter;
rs = ps->range(min_d, max_d);
v3s16 maxlen;
if (large_cave) {
maxlen = v3s16(
rs * part_max_length_rs,
rs * part_max_length_rs / 2,
rs * part_max_length_rs
);
} else {
maxlen = v3s16(
rs * part_max_length_rs,
ps->range(1, rs * part_max_length_rs),
rs * part_max_length_rs
);
}
v3f vec;
// Jump downward sometimes
if (!large_cave && ps->range(0, 12) == 0) {
vec = v3f(
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
(float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y,
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
);
} else {
vec = v3f(
(float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2,
(float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2,
(float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2
);
}
// Do not make large caves that are above ground.
// It is only necessary to check the startpoint and endpoint.
if (large_cave) {
v3s16 orpi(orp.X, orp.Y, orp.Z);
v3s16 veci(vec.X, vec.Y, vec.Z);
v3s16 p;
p = orpi + veci + of + rs / 2;
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
s16 h = mg->ridge_heightmap[index];
if (h < p.Y)
return;
} else if (p.Y > water_level) {
return; // If it's not in our heightmap, use a simple heuristic
}
p = orpi + of + rs / 2;
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
u32 index = (p.Z - node_min.Z) * mg->ystride + (p.X - node_min.X);
s16 h = mg->ridge_heightmap[index];
if (h < p.Y)
return;
} else if (p.Y > water_level) {
return;
}
}
vec += main_direction;
v3f rp = orp + vec;
if (rp.X < 0)
rp.X = 0;
else if (rp.X >= ar.X)
rp.X = ar.X - 1;
if (rp.Y < route_y_min)
rp.Y = route_y_min;
else if (rp.Y >= route_y_max)
rp.Y = route_y_max - 1;
if (rp.Z < 0)
rp.Z = 0;
else if (rp.Z >= ar.Z)
rp.Z = ar.Z - 1;
vec = rp - orp;
float veclen = vec.getLength();
if (veclen < 0.05)
veclen = 1.0;
// Every second section is rough
bool randomize_xz = (ps->range(1, 2) == 1);
// Make a ravine every once in a while if it's long enough
float xylen = vec.X * vec.X + vec.Z * vec.Z;
bool is_ravine = (xylen > 500.0) && !large_cave && (ps->range(1, 8) == 1);
// Carve routes
for (float f = 0; f < 1.0; f += 1.0 / veclen)
carveRoute(vec, f, randomize_xz, is_ravine);
orp = rp;
}
void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine) {
MapNode airnode(CONTENT_AIR);
MapNode waternode(c_water_source);
MapNode lavanode(c_lava_source);
MapNode liquidnode = ps->range(0, 4) ? lavanode : waternode;
v3s16 startp(orp.X, orp.Y, orp.Z);
startp += of;
v3f fp = orp + vec * f;
fp.X += 0.1 * ps->range(-10, 10);
fp.Z += 0.1 * ps->range(-10, 10);
v3s16 cp(fp.X, fp.Y, fp.Z);
s16 d0 = -rs/2;
s16 d1 = d0 + rs;
if (randomize_xz) {
d0 += ps->range(-1, 1);
d1 += ps->range(-1, 1);
}
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
for (s16 z0 = d0; z0 <= d1; z0++) {
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
s16 si2 = is_ravine ? MYMIN(ps->range(25, 26), ar.Y) :
rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
for (s16 y0 = -si2; y0 <= si2; y0++) {
// Make better floors in small caves
if(flat_cave_floor && y0 <= -rs/2 && rs<=7)
continue;
if (large_cave_is_flat) {
// Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3)
continue;
}
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
p += of;
if (vm->m_area.contains(p) == false)
continue;
u32 i = vm->m_area.index(p);
// Don't replace air or water or lava
content_t c = vm->m_data[i].getContent();
if (c == CONTENT_AIR || c == c_water_source || c == c_lava_source)
continue;
if (large_cave) {
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
if (flooded && full_ymin < water_level && full_ymax > water_level)
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
else if (flooded && full_ymax < water_level)
vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode;
else
vm->m_data[i] = airnode;
} else {
vm->m_data[i] = airnode;
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
}
}
}
}
}

@ -22,9 +22,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1 #define VMANIP_FLAG_CAVE VOXELFLAG_CHECKED1
class MapgenV6;
class MapgenV7;
class CaveV6 { class CaveV6 {
public: public:
MapgenV6 *mg;
ManualMapVoxelManipulator *vm; ManualMapVoxelManipulator *vm;
INodeDefManager *ndef;
s16 min_tunnel_diameter; s16 min_tunnel_diameter;
s16 max_tunnel_diameter; s16 max_tunnel_diameter;
@ -40,10 +45,10 @@ public:
v3s16 node_min; v3s16 node_min;
v3s16 node_max; v3s16 node_max;
v3f orp; //original point v3f orp; // starting point, relative to caved space
v3s16 of; v3s16 of; // absolute coordinates of caved space
v3s16 ar; // allowed route area v3s16 ar; // allowed route area
s16 rs; // radius size s16 rs; // tunnel radius size
v3f main_direction; v3f main_direction;
s16 route_y_min; s16 route_y_min;
@ -58,11 +63,53 @@ public:
int water_level; int water_level;
CaveV6() {} CaveV6() {}
CaveV6(Mapgen *mg, PseudoRandom *ps, PseudoRandom *ps2, bool large_cave, CaveV6(MapgenV6 *mg, PseudoRandom *ps, PseudoRandom *ps2, bool large_cave);
content_t c_water, content_t c_lava);
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height); void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
void makeTunnel(bool dirswitch); void makeTunnel(bool dirswitch);
void carveRoute(v3f vec, float f, bool randomize_xz); void carveRoute(v3f vec, float f, bool randomize_xz);
}; };
class CaveV7 {
public:
MapgenV7 *mg;
ManualMapVoxelManipulator *vm;
INodeDefManager *ndef;
s16 min_tunnel_diameter;
s16 max_tunnel_diameter;
u16 tunnel_routepoints;
int dswitchint;
int part_max_length_rs;
bool large_cave;
bool large_cave_is_flat;
bool flooded;
s16 max_stone_y;
v3s16 node_min;
v3s16 node_max;
v3f orp; // starting point, relative to caved space
v3s16 of; // absolute coordinates of caved space
v3s16 ar; // allowed route area
s16 rs; // tunnel radius size
v3f main_direction;
s16 route_y_min;
s16 route_y_max;
PseudoRandom *ps;
content_t c_water_source;
content_t c_lava_source;
int water_level;
CaveV7() {}
CaveV7(MapgenV7 *mg, PseudoRandom *ps, bool large_cave);
void makeCave(v3s16 nmin, v3s16 nmax, int max_stone_height);
void makeTunnel(bool dirswitch);
void carveRoute(v3f vec, float f, bool randomize_xz, bool is_ravine);
};
#endif #endif

@ -45,6 +45,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "IMeshCache.h" #include "IMeshCache.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "config.h" #include "config.h"
#include "util/directiontables.h"
#if USE_CURL #if USE_CURL
#include <curl/curl.h> #include <curl/curl.h>
@ -2054,6 +2055,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
u32 number = readU32(is); u32 number = readU32(is);
u32 item = readU32(is); u32 item = readU32(is);
u32 dir = readU32(is); u32 dir = readU32(is);
v2f align = readV2F1000(is);
v2f offset = readV2F1000(is);
ClientEvent event; ClientEvent event;
event.type = CE_HUDADD; event.type = CE_HUDADD;
@ -2066,6 +2069,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
event.hudadd.number = number; event.hudadd.number = number;
event.hudadd.item = item; event.hudadd.item = item;
event.hudadd.dir = dir; event.hudadd.dir = dir;
event.hudadd.align = new v2f(align);
event.hudadd.offset = new v2f(offset);
m_client_event_queue.push_back(event); m_client_event_queue.push_back(event);
} }
else if(command == TOCLIENT_HUDRM) else if(command == TOCLIENT_HUDRM)
@ -2092,7 +2097,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
u32 id = readU32(is); u32 id = readU32(is);
u8 stat = (HudElementStat)readU8(is); u8 stat = (HudElementStat)readU8(is);
if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE) if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE ||
stat == HUD_STAT_ALIGN || stat == HUD_STAT_OFFSET)
v2fdata = readV2F1000(is); v2fdata = readV2F1000(is);
else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT) else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT)
sdata = deSerializeString(is); sdata = deSerializeString(is);
@ -2108,6 +2114,20 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
event.hudchange.data = intdata; event.hudchange.data = intdata;
m_client_event_queue.push_back(event); m_client_event_queue.push_back(event);
} }
else if(command == TOCLIENT_HUD_SET_FLAGS)
{
std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
Player *player = m_env.getLocalPlayer();
assert(player != NULL);
u32 flags = readU32(is);
u32 mask = readU32(is);
player->hud_flags &= ~mask;
player->hud_flags |= flags;
}
else else
{ {
infostream<<"Client: Ignoring unknown command " infostream<<"Client: Ignoring unknown command "
@ -2719,21 +2739,14 @@ void Client::addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server, bool
} }
catch(InvalidPositionException &e){} catch(InvalidPositionException &e){}
// Leading edge // Leading edge
try{ for (int i=0;i<6;i++)
v3s16 p = blockpos + v3s16(-1,0,0); {
addUpdateMeshTask(p, false, urgent); try{
v3s16 p = blockpos + g_6dirs[i];
addUpdateMeshTask(p, false, urgent);
}
catch(InvalidPositionException &e){}
} }
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,-1,0);
addUpdateMeshTask(p, false, urgent);
}
catch(InvalidPositionException &e){}
try{
v3s16 p = blockpos + v3s16(0,0,-1);
addUpdateMeshTask(p, false, urgent);
}
catch(InvalidPositionException &e){}
} }
void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent) void Client::addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server, bool urgent)

@ -230,6 +230,8 @@ struct ClientEvent
u32 number; u32 number;
u32 item; u32 item;
u32 dir; u32 dir;
v2f *align;
v2f *offset;
} hudadd; } hudadd;
struct{ struct{
u32 id; u32 id;

@ -94,6 +94,7 @@ SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
TOCLIENT_HUD_ADD TOCLIENT_HUD_ADD
TOCLIENT_HUD_RM TOCLIENT_HUD_RM
TOCLIENT_HUD_CHANGE TOCLIENT_HUD_CHANGE
TOCLIENT_HUD_BUILTIN_ENABLE
*/ */
#define LATEST_PROTOCOL_VERSION 20 #define LATEST_PROTOCOL_VERSION 20
@ -452,15 +453,17 @@ enum ToClientCommand
u32 number u32 number
u32 item u32 item
u32 dir u32 dir
v2f1000 align
v2f1000 offset
*/ */
TOCLIENT_HUDRM = 0x50, TOCLIENT_HUDRM = 0x4a,
/* /*
u16 command u16 command
u32 id u32 id
*/ */
TOCLIENT_HUDCHANGE = 0x51, TOCLIENT_HUDCHANGE = 0x4b,
/* /*
u16 command u16 command
u32 id u32 id
@ -470,6 +473,13 @@ enum ToClientCommand
u8[len] data | u8[len] data |
u32 data] u32 data]
*/ */
TOCLIENT_HUD_SET_FLAGS = 0x4c,
/*
u16 command
u32 flags
u32 mask
*/
}; };
enum ToServerCommand enum ToServerCommand

@ -51,11 +51,15 @@ public:
ServerMap *map = &env->getServerMap(); ServerMap *map = &env->getServerMap();
MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0)); MapNode n_top = map->getNodeNoEx(p+v3s16(0,1,0));
content_t c_snow = ndef->getId("snow");
if(ndef->get(n_top).light_propagates && if(ndef->get(n_top).light_propagates &&
!ndef->get(n_top).isLiquid() && !ndef->get(n_top).isLiquid() &&
n_top.getLightBlend(env->getDayNightRatio(), ndef) >= 13) n_top.getLightBlend(env->getDayNightRatio(), ndef) >= 13)
{ {
n.setContent(ndef->getId("mapgen_dirt_with_grass")); if(c_snow != CONTENT_IGNORE && n_top.getContent() == c_snow)
n.setContent(ndef->getId("dirt_with_snow"));
else
n.setContent(ndef->getId("mapgen_dirt_with_grass"));
map->addNodeWithEvent(p, n); map->addNodeWithEvent(p, n);
} }
} }

@ -740,8 +740,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
continue; continue;
// The face at Z+ // The face at Z+
video::S3DVertex vertices[4] = video::S3DVertex vertices[4] = {
{
video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c, video::S3DVertex(-BS/2,-BS/2,BS/2, 0,0,0, c,
ap.x0(), ap.y1()), ap.x0(), ap.y1()),
video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c, video::S3DVertex(BS/2,-BS/2,BS/2, 0,0,0, c,
@ -781,6 +780,132 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
collector.append(tile, vertices, 4, indices, 6); collector.append(tile, vertices, 4, indices, 6);
} }
break;} break;}
case NDT_GLASSLIKE_FRAMED:
{
static const v3s16 dirs[6] = {
v3s16( 0, 1, 0),
v3s16( 0,-1, 0),
v3s16( 1, 0, 0),
v3s16(-1, 0, 0),
v3s16( 0, 0, 1),
v3s16( 0, 0,-1)
};
TileSpec tiles[2];
tiles[0] = getNodeTile(n, p, dirs[0], data);
tiles[1] = getNodeTile(n, p, dirs[1], data);
u16 l = getInteriorLight(n, 1, data);
video::SColor c = MapBlock_LightColor(255, l, decode_light(f.light_source));
v3f pos = intToFloat(p, BS);
static const float a=BS/2;
static const float b=.876*(BS/2);
static const aabb3f frame_edges[12] = {
aabb3f( b, b,-a, a, a, a), // y+
aabb3f(-a, b,-a,-b, a, a), // y+
aabb3f( b,-a,-a, a,-b, a), // y-
aabb3f(-a,-a,-a,-b,-b, a), // y-
aabb3f( b,-a, b, a, a, a), // x+
aabb3f( b,-a,-a, a, a,-b), // x+
aabb3f(-a,-a, b,-b, a, a), // x-
aabb3f(-a,-a,-a,-b, a,-b), // x-
aabb3f(-a, b, b, a, a, a), // z+
aabb3f(-a,-a, b, a,-b, a), // z+
aabb3f(-a,-a,-a, a,-b,-b), // z-
aabb3f(-a, b,-a, a, a,-b) // z-
};
aabb3f glass_faces[6] = {
aabb3f(-a, a,-a, a, a, a), // y+
aabb3f(-a,-a,-a, a,-a, a), // y-
aabb3f( a,-a,-a, a, a, a), // x+
aabb3f(-a,-a,-a,-a, a, a), // x-
aabb3f(-a,-a, a, a, a, a), // z+
aabb3f(-a,-a,-a, a, a,-a) // z-
};
int visible_faces[6] = {0,0,0,0,0,0};
int nb[18] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
u8 i;
content_t current = n.getContent();
content_t content;
MapNode n2;
v3s16 n2p;
for(i=0; i<18; i++)
{
n2p = blockpos_nodes + p + g_26dirs[i];
n2 = data->m_vmanip.getNodeNoEx(n2p);
content_t n2c = n2.getContent();
//TODO: remove CONTENT_IGNORE check when getNodeNoEx is fixed
if (n2c == current || n2c == CONTENT_IGNORE)
nb[i]=1;
}
for(i=0; i<6; i++)
{
n2p = blockpos_nodes + p + dirs[i];
n2 = data->m_vmanip.getNodeNoEx(n2p);
content = n2.getContent();
const ContentFeatures &f2 = nodedef->get(content);
if (content == CONTENT_AIR || f2.isLiquid())
visible_faces[i]=1;
}
static const u8 nb_triplet[12*3] = {
1,2, 7, 1,5, 6, 4,2,15, 4,5,14,
2,0,11, 2,3,13, 5,0,10, 5,3,12,
0,1, 8, 0,4,16, 3,4,17, 3,1, 9
};
f32 tx1,ty1,tz1,tx2,ty2,tz2;
aabb3f box;
for(i=0; i<12; i++)
{
int edge_invisible;
if (nb[nb_triplet[i*3+2]]==1)
edge_invisible=nb[nb_triplet[i*3]] & nb[nb_triplet[i*3+1]];
else
edge_invisible=nb[nb_triplet[i*3]] ^ nb[nb_triplet[i*3+1]];
if (edge_invisible)
continue;
box=frame_edges[i];
box.MinEdge += pos;
box.MaxEdge += pos;
tx1 = (box.MinEdge.X/BS)+0.5;
ty1 = (box.MinEdge.Y/BS)+0.5;
tz1 = (box.MinEdge.Z/BS)+0.5;
tx2 = (box.MaxEdge.X/BS)+0.5;
ty2 = (box.MaxEdge.Y/BS)+0.5;
tz2 = (box.MaxEdge.Z/BS)+0.5;
f32 txc1[24] = {
tx1, 1-tz2, tx2, 1-tz1,
tx1, tz1, tx2, tz2,
tz1, 1-ty2, tz2, 1-ty1,
1-tz2, 1-ty2, 1-tz1, 1-ty1,
1-tx2, 1-ty2, 1-tx1, 1-ty1,
tx1, 1-ty2, tx2, 1-ty1,
};
makeCuboid(&collector, box, &tiles[0], 1, c, txc1);
}
for(i=0; i<6; i++)
{
if (visible_faces[i]==0)
continue;
box=glass_faces[i];
box.MinEdge += pos;
box.MaxEdge += pos;
tx1 = (box.MinEdge.X/BS)+0.5;
ty1 = (box.MinEdge.Y/BS)+0.5;
tz1 = (box.MinEdge.Z/BS)+0.5;
tx2 = (box.MaxEdge.X/BS)+0.5;
ty2 = (box.MaxEdge.Y/BS)+0.5;
tz2 = (box.MaxEdge.Z/BS)+0.5;
f32 txc2[24] = {
tx1, 1-tz2, tx2, 1-tz1,
tx1, tz1, tx2, tz2,
tz1, 1-ty2, tz2, 1-ty1,
1-tz2, 1-ty2, 1-tz1, 1-ty1,
1-tx2, 1-ty2, 1-tx1, 1-ty1,
tx1, 1-ty2, tx2, 1-ty1,
};
makeCuboid(&collector, box, &tiles[1], 1, c, txc2);
}
break;}
case NDT_ALLFACES: case NDT_ALLFACES:
{ {
TileSpec tile_leaves = getNodeTile(n, p, TileSpec tile_leaves = getNodeTile(n, p,

@ -1472,6 +1472,11 @@ std::string PlayerSAO::getPropertyPacket()
} }
bool PlayerSAO::getCollisionBox(aabb3f *toset) { bool PlayerSAO::getCollisionBox(aabb3f *toset) {
//player collision handling is already done clientside no need to do it twice //update collision box
return false; *toset = m_player->getCollisionbox();
toset->MinEdge += m_base_position;
toset->MaxEdge += m_base_position;
return true;
} }

@ -107,6 +107,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("enable_clouds", "true"); settings->setDefault("enable_clouds", "true");
settings->setDefault("screenshot_path", "."); settings->setDefault("screenshot_path", ".");
settings->setDefault("view_bobbing_amount", "1.0"); settings->setDefault("view_bobbing_amount", "1.0");
settings->setDefault("fall_bobbing_amount", "0.0");
settings->setDefault("enable_3d_clouds", "true"); settings->setDefault("enable_3d_clouds", "true");
settings->setDefault("cloud_height", "120"); settings->setDefault("cloud_height", "120");
settings->setDefault("menu_clouds", "true"); settings->setDefault("menu_clouds", "true");

@ -1295,16 +1295,17 @@ bool isFreeServerActiveObjectId(u16 id,
u16 getFreeServerActiveObjectId( u16 getFreeServerActiveObjectId(
std::map<u16, ServerActiveObject*> &objects) std::map<u16, ServerActiveObject*> &objects)
{ {
u16 new_id = 1; //try to reuse id's as late as possible
static u16 last_used_id = 0;
u16 startid = last_used_id;
for(;;) for(;;)
{ {
if(isFreeServerActiveObjectId(new_id, objects)) last_used_id ++;
return new_id; if(isFreeServerActiveObjectId(last_used_id, objects))
return last_used_id;
if(new_id == 65535) if(last_used_id == startid)
return 0; return 0;
new_id++;
} }
} }
@ -2296,16 +2297,17 @@ bool isFreeClientActiveObjectId(u16 id,
u16 getFreeClientActiveObjectId( u16 getFreeClientActiveObjectId(
std::map<u16, ClientActiveObject*> &objects) std::map<u16, ClientActiveObject*> &objects)
{ {
u16 new_id = 1; //try to reuse id's as late as possible
static u16 last_used_id = 0;
u16 startid = last_used_id;
for(;;) for(;;)
{ {
if(isFreeClientActiveObjectId(new_id, objects)) last_used_id ++;
return new_id; if(isFreeClientActiveObjectId(last_used_id, objects))
return last_used_id;
if(new_id == 65535) if(last_used_id == startid)
return 0; return 0;
new_id++;
} }
} }

@ -2106,6 +2106,8 @@ void the_game(
delete event.hudadd.name; delete event.hudadd.name;
delete event.hudadd.scale; delete event.hudadd.scale;
delete event.hudadd.text; delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
continue; continue;
} }
@ -2118,6 +2120,8 @@ void the_game(
e->number = event.hudadd.number; e->number = event.hudadd.number;
e->item = event.hudadd.item; e->item = event.hudadd.item;
e->dir = event.hudadd.dir; e->dir = event.hudadd.dir;
e->align = *event.hudadd.align;
e->offset = *event.hudadd.offset;
if (id == nhudelem) if (id == nhudelem)
player->hud.push_back(e); player->hud.push_back(e);
@ -2128,6 +2132,8 @@ void the_game(
delete event.hudadd.name; delete event.hudadd.name;
delete event.hudadd.scale; delete event.hudadd.scale;
delete event.hudadd.text; delete event.hudadd.text;
delete event.hudadd.align;
delete event.hudadd.offset;
} }
else if (event.type == CE_HUDRM) else if (event.type == CE_HUDRM)
{ {
@ -2169,6 +2175,12 @@ void the_game(
case HUD_STAT_DIR: case HUD_STAT_DIR:
e->dir = event.hudchange.data; e->dir = event.hudchange.data;
break; break;
case HUD_STAT_ALIGN:
e->align = *event.hudchange.v2fdata;
break;
case HUD_STAT_OFFSET:
e->offset = *event.hudchange.v2fdata;
break;
} }
delete event.hudchange.v2fdata; delete event.hudchange.v2fdata;
@ -3058,7 +3070,7 @@ void the_game(
/* /*
Wielded tool Wielded tool
*/ */
if(show_hud) if(show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE))
{ {
// Warning: This clears the Z buffer. // Warning: This clears the Z buffer.
camera.drawWieldedTool(); camera.drawWieldedTool();

@ -57,6 +57,7 @@ const wchar_t *contrib_core_strs[] = {
}; };
const wchar_t *contrib_active_strs[] = { const wchar_t *contrib_active_strs[] = {
L"kahrl <kahrl@gmx.net>",
L"sfan5 <sfan5@live.de>", L"sfan5 <sfan5@live.de>",
L"sapier <sapier@gmx.net>", L"sapier <sapier@gmx.net>",
L"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>", L"Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>",
@ -69,7 +70,6 @@ const wchar_t *contrib_active_strs[] = {
}; };
const wchar_t *contrib_previous_strs[] = { const wchar_t *contrib_previous_strs[] = {
L"kahrl <kahrl@gmx.net>",
L"Giuseppe Bilotta (Oblomov) <giuseppe.bilotta@gmail.com>", L"Giuseppe Bilotta (Oblomov) <giuseppe.bilotta@gmail.com>",
L"Jonathan Neuschafer <j.neuschaefer@gmx.net>", L"Jonathan Neuschafer <j.neuschaefer@gmx.net>",
L"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>", L"Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>",

@ -45,6 +45,8 @@ Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
hotbar_imagesize = 48; hotbar_imagesize = 48;
hotbar_itemcount = 8; hotbar_itemcount = 8;
tsrc = gamedef->getTextureSource();
v3f crosshair_color = g_settings->getV3F("crosshair_color"); v3f crosshair_color = g_settings->getV3F("crosshair_color");
u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255); u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255); u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
@ -57,6 +59,8 @@ Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255); u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255); u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b); selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
use_crosshair_image = tsrc->isKnownSourceImage("crosshair.png");
} }
@ -175,8 +179,7 @@ void Hud::drawLuaElements() {
v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y); v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y);
switch (e->type) { switch (e->type) {
case HUD_ELEM_IMAGE: { case HUD_ELEM_IMAGE: {
video::ITexture *texture = video::ITexture *texture = tsrc->getTextureRaw(e->text);
gamedef->getTextureSource()->getTextureRaw(e->text);
if (!texture) if (!texture)
continue; continue;
@ -186,6 +189,10 @@ void Hud::drawLuaElements() {
core::rect<s32> rect(0, 0, imgsize.Width * e->scale.X, core::rect<s32> rect(0, 0, imgsize.Width * e->scale.X,
imgsize.Height * e->scale.X); imgsize.Height * e->scale.X);
rect += pos; rect += pos;
v2s32 offset((e->align.X - 1.0) * ((imgsize.Width * e->scale.X) / 2),
(e->align.Y - 1.0) * ((imgsize.Height * e->scale.X) / 2));
rect += offset;
rect += v2s32(e->offset.X, e->offset.Y);
driver->draw2DImage(texture, rect, driver->draw2DImage(texture, rect,
core::rect<s32>(core::position2d<s32>(0,0), imgsize), core::rect<s32>(core::position2d<s32>(0,0), imgsize),
NULL, colors, true); NULL, colors, true);
@ -195,11 +202,17 @@ void Hud::drawLuaElements() {
(e->number >> 8) & 0xFF, (e->number >> 8) & 0xFF,
(e->number >> 0) & 0xFF); (e->number >> 0) & 0xFF);
core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y); core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
font->draw(narrow_to_wide(e->text).c_str(), size + pos, color); std::wstring text = narrow_to_wide(e->text);
core::dimension2d<u32> textsize = font->getDimension(text.c_str());
v2s32 offset((e->align.X - 1.0) * (textsize.Width / 2),
(e->align.Y - 1.0) * (textsize.Height / 2));
v2s32 offs(e->offset.X, e->offset.Y);
font->draw(text.c_str(), size + pos + offset + offs, color);
break; }
case HUD_ELEM_STATBAR: {
v2s32 offs(e->offset.X, e->offset.Y);
drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs);
break; } break; }
case HUD_ELEM_STATBAR:
drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number);
break;
case HUD_ELEM_INVENTORY: { case HUD_ELEM_INVENTORY: {
InventoryList *inv = inventory->getList(e->text); InventoryList *inv = inventory->getList(e->text);
drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir); drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir);
@ -212,12 +225,11 @@ void Hud::drawLuaElements() {
} }
void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count) { void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count, v2s32 offset) {
const video::SColor color(255, 255, 255, 255); const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color}; const video::SColor colors[] = {color, color, color, color};
video::ITexture *stat_texture = video::ITexture *stat_texture = tsrc->getTextureRaw(texture);
gamedef->getTextureSource()->getTextureRaw(texture);
if (!stat_texture) if (!stat_texture)
return; return;
@ -227,6 +239,8 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
if (corner & HUD_CORNER_LOWER) if (corner & HUD_CORNER_LOWER)
p -= srcd.Height; p -= srcd.Height;
p += offset;
v2s32 steppos; v2s32 steppos;
switch (drawdir) { switch (drawdir) {
case HUD_DIR_RIGHT_LEFT: case HUD_DIR_RIGHT_LEFT:
@ -276,17 +290,32 @@ void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2); s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2);
v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2); v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2);
drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0); if (player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE)
drawStatbar(pos - v2s32(0, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT, drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0);
"heart.png", halfheartcount); if (player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)
drawStatbar(pos - v2s32(0, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT,
"heart.png", halfheartcount, v2s32(0, 0));
} }
void Hud::drawCrosshair() { void Hud::drawCrosshair() {
driver->draw2DLine(displaycenter - v2s32(10, 0), if (!(player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE))
displaycenter + v2s32(10, 0), crosshair_argb); return;
driver->draw2DLine(displaycenter - v2s32(0, 10),
displaycenter + v2s32(0, 10), crosshair_argb); if (use_crosshair_image) {
video::ITexture *crosshair = tsrc->getTextureRaw("crosshair.png");
v2u32 size = crosshair->getOriginalSize();
v2s32 lsize = v2s32(displaycenter.X - (size.X / 2),
displaycenter.Y - (size.Y / 2));
driver->draw2DImage(crosshair, lsize,
core::rect<s32>(0, 0, size.X, size.Y),
0, crosshair_argb, true);
} else {
driver->draw2DLine(displaycenter - v2s32(10, 0),
displaycenter + v2s32(10, 0), crosshair_argb);
driver->draw2DLine(displaycenter - v2s32(0, 10),
displaycenter + v2s32(0, 10), crosshair_argb);
}
} }

@ -31,6 +31,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define HUD_CORNER_LOWER 1 #define HUD_CORNER_LOWER 1
#define HUD_CORNER_CENTER 2 #define HUD_CORNER_CENTER 2
#define HUD_FLAG_HOTBAR_VISIBLE (1 << 0)
#define HUD_FLAG_HEALTHBAR_VISIBLE (1 << 1)
#define HUD_FLAG_CROSSHAIR_VISIBLE (1 << 2)
#define HUD_FLAG_WIELDITEM_VISIBLE (1 << 3)
class Player; class Player;
enum HudElementType { enum HudElementType {
@ -47,7 +52,9 @@ enum HudElementStat {
HUD_STAT_TEXT, HUD_STAT_TEXT,
HUD_STAT_NUMBER, HUD_STAT_NUMBER,
HUD_STAT_ITEM, HUD_STAT_ITEM,
HUD_STAT_DIR HUD_STAT_DIR,
HUD_STAT_ALIGN,
HUD_STAT_OFFSET
}; };
struct HudElement { struct HudElement {
@ -59,6 +66,8 @@ struct HudElement {
u32 number; u32 number;
u32 item; u32 item;
u32 dir; u32 dir;
v2f align;
v2f offset;
}; };
@ -73,8 +82,6 @@ inline u32 hud_get_free_id(Player *player) {
#ifndef SERVER #ifndef SERVER
#include <deque>
#include <IGUIFont.h> #include <IGUIFont.h>
#include "gamedef.h" #include "gamedef.h"
@ -90,7 +97,8 @@ public:
IGameDef *gamedef; IGameDef *gamedef;
LocalPlayer *player; LocalPlayer *player;
Inventory *inventory; Inventory *inventory;
ITextureSource *tsrc;
v2u32 screensize; v2u32 screensize;
v2s32 displaycenter; v2s32 displaycenter;
s32 hotbar_imagesize; s32 hotbar_imagesize;
@ -98,6 +106,7 @@ public:
video::SColor crosshair_argb; video::SColor crosshair_argb;
video::SColor selectionbox_argb; video::SColor selectionbox_argb;
bool use_crosshair_image;
Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv, Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
gui::IGUIFont *font, u32 text_height, IGameDef *gamedef, gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
@ -106,7 +115,8 @@ public:
void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount, void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
InventoryList *mainlist, u16 selectitem, u16 direction); InventoryList *mainlist, u16 selectitem, u16 direction);
void drawLuaElements(); void drawLuaElements();
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count); void drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
std::string texture, s32 count, v2s32 offset);
void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem); void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem);
void resizeHotbar(); void resizeHotbar();

@ -247,7 +247,8 @@ public:
i = values.begin(); i != values.end(); ++i) i = values.begin(); i != values.end(); ++i)
{ {
ClientCached *cc = *i; ClientCached *cc = *i;
cc->wield_mesh->drop(); if (cc->wield_mesh)
cc->wield_mesh->drop();
delete cc; delete cc;
} }

@ -154,9 +154,6 @@ void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d,
// This should always apply, otherwise there are glitches // This should always apply, otherwise there are glitches
assert(d > pos_max_d); assert(d > pos_max_d);
float player_radius = BS*0.30;
float player_height = BS*1.55;
// Maximum distance over border for sneaking // Maximum distance over border for sneaking
f32 sneak_max = BS*0.4; f32 sneak_max = BS*0.4;
@ -184,24 +181,12 @@ void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d,
} }
} }
/*
Calculate player collision box (new and old)
*/
core::aabbox3d<f32> playerbox(
-player_radius,
0.0,
-player_radius,
player_radius,
player_height,
player_radius
);
float player_stepheight = touching_ground ? (BS*0.6) : (BS*0.2); float player_stepheight = touching_ground ? (BS*0.6) : (BS*0.2);
v3f accel_f = v3f(0,0,0); v3f accel_f = v3f(0,0,0);
collisionMoveResult result = collisionMoveSimple(env, m_gamedef, collisionMoveResult result = collisionMoveSimple(env, m_gamedef,
pos_max_d, playerbox, player_stepheight, dtime, pos_max_d, m_collisionbox, player_stepheight, dtime,
position, m_speed, accel_f); position, m_speed, accel_f);
/* /*

@ -1764,7 +1764,7 @@ void Map::transformLiquidsFinite(std::map<v3s16, MapBlock*> & modified_blocks)
} }
// prevent lakes in air above unloaded blocks // prevent lakes in air above unloaded blocks
if (p0.Y > water_level && neighbors[D_BOTTOM].n.getContent() == CONTENT_IGNORE) { if (liquid_levels[D_TOP] == 0 && (p0.Y > water_level || !fast_flood) && neighbors[D_BOTTOM].n.getContent() == CONTENT_IGNORE) {
--total_level; --total_level;
} }

@ -1099,6 +1099,8 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
getShader("test_shader_1").material; getShader("test_shader_1").material;
video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()-> video::E_MATERIAL_TYPE shadermat2 = m_gamedef->getShaderSource()->
getShader("test_shader_2").material; getShader("test_shader_2").material;
video::E_MATERIAL_TYPE shadermat3 = m_gamedef->getShaderSource()->
getShader("test_shader_3").material;
for(u32 i = 0; i < collector.prebuffers.size(); i++) for(u32 i = 0; i < collector.prebuffers.size(); i++)
{ {
PreMeshBuffer &p = collector.prebuffers[i]; PreMeshBuffer &p = collector.prebuffers[i];
@ -1174,7 +1176,7 @@ MapBlockMesh::MapBlockMesh(MeshMakeData *data):
= video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
material.setTexture(0, p.tile.texture.atlas); material.setTexture(0, p.tile.texture.atlas);
if(enable_shaders) if(enable_shaders)
p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2); p.tile.applyMaterialOptionsWithShaders(material, shadermat1, shadermat2, shadermat3);
else else
p.tile.applyMaterialOptions(material); p.tile.applyMaterialOptions(material);

@ -274,23 +274,21 @@ void MapgenIndev::generateCaves(int max_stone_y) {
for (u32 i = 0; i < caves_count + bruises_count; i++) { for (u32 i = 0; i < caves_count + bruises_count; i++) {
bool large_cave = (i >= caves_count); bool large_cave = (i >= caves_count);
CaveIndev cave(this, &ps, &ps2, node_min, large_cave, CaveIndev cave(this, &ps, &ps2, node_min, large_cave);
c_water_source, c_lava_source);
cave.makeCave(node_min, node_max, max_stone_y); cave.makeCave(node_min, node_max, max_stone_y);
} }
} }
CaveIndev::CaveIndev(Mapgen *mg, PseudoRandom *ps, PseudoRandom *ps2, CaveIndev::CaveIndev(MapgenIndev *mg, PseudoRandom *ps, PseudoRandom *ps2,
v3s16 node_min, bool is_large_cave, v3s16 node_min, bool is_large_cave) {
content_t c_water, content_t c_lava) {
this->vm = mg->vm; this->vm = mg->vm;
this->water_level = mg->water_level; this->water_level = mg->water_level;
this->large_cave = is_large_cave; this->large_cave = is_large_cave;
this->ps = ps; this->ps = ps;
this->ps2 = ps2; this->ps2 = ps2;
this->c_water_source = c_water; this->c_water_source = mg->c_water_source;
this->c_lava_source = c_lava; this->c_lava_source = mg->c_lava_source;
min_tunnel_diameter = 2; min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2,6); max_tunnel_diameter = ps->range(2,6);
@ -303,7 +301,7 @@ CaveIndev::CaveIndev(Mapgen *mg, PseudoRandom *ps, PseudoRandom *ps2,
flooded = !ps->range(0, 3); flooded = !ps->range(0, 3);
tunnel_routepoints = ps->range(5, 30); tunnel_routepoints = ps->range(5, 30);
min_tunnel_diameter = 30; min_tunnel_diameter = 30;
max_tunnel_diameter = ps->range(40, ps->range(80, 200)); max_tunnel_diameter = ps->range(40, ps->range(80, 150));
} else { } else {
tunnel_routepoints = ps->range(5, ps->range(15,30)); tunnel_routepoints = ps->range(5, ps->range(15,30));
min_tunnel_diameter = 5; min_tunnel_diameter = 5;

@ -153,8 +153,8 @@ struct MapgenFactoryIndev : public MapgenFactoryV6 {
class CaveIndev : public CaveV6 { class CaveIndev : public CaveV6 {
public: public:
CaveIndev(Mapgen *mg, PseudoRandom *ps, PseudoRandom *ps2, v3s16 node_min, CaveIndev(MapgenIndev *mg, PseudoRandom *ps, PseudoRandom *ps2,
bool is_large_cave, content_t c_water, content_t c_lava); v3s16 node_min, bool is_large_cave);
}; };
#endif #endif

@ -948,7 +948,7 @@ void MapgenV6::generateCaves(int max_stone_y) {
for (u32 i = 0; i < caves_count + bruises_count; i++) { for (u32 i = 0; i < caves_count + bruises_count; i++) {
bool large_cave = (i >= caves_count); bool large_cave = (i >= caves_count);
CaveV6 cave(this, &ps, &ps2, large_cave, c_water_source, c_lava_source); CaveV6 cave(this, &ps, &ps2, large_cave);
cave.makeCave(node_min, node_max, max_stone_y); cave.makeCave(node_min, node_max, max_stone_y);
} }

@ -78,7 +78,7 @@ MapgenV7::MapgenV7(int mapgenid, MapgenV7Params *params, EmergeManager *emerge)
this->water_level = params->water_level; this->water_level = params->water_level;
this->flags = params->flags; this->flags = params->flags;
this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE; this->csize = v3s16(1, 1, 1) * params->chunksize * MAP_BLOCKSIZE;
// this->ystride = csize.X; //////fix this this->ystride = csize.X; //////fix this
this->biomemap = new u8[csize.X * csize.Z]; this->biomemap = new u8[csize.X * csize.Z];
this->heightmap = new s16[csize.X * csize.Z]; this->heightmap = new s16[csize.X * csize.Z];
@ -187,7 +187,6 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
generateCaves(stone_surface_max_y); generateCaves(stone_surface_max_y);
addTopNodes(); addTopNodes();
//v3s16 central_area_size = node_max - node_min + v3s16(1,1,1);
if (flags & MG_DUNGEONS) { if (flags & MG_DUNGEONS) {
DungeonGen dgen(ndef, data->seed, water_level); DungeonGen dgen(ndef, data->seed, water_level);
@ -452,7 +451,8 @@ void MapgenV7::addTopNodes() {
vm->m_area.add_y(em, i, 1); vm->m_area.add_y(em, i, 1);
} }
// If dirt, grow grass on it. // If dirt, grow grass on it.
if (vm->m_data[i].getContent() == CONTENT_AIR) { if (y > water_level - 10 &&
vm->m_data[i].getContent() == CONTENT_AIR) {
vm->m_area.add_y(em, i, -1); vm->m_area.add_y(em, i, -1);
if (vm->m_data[i].getContent() == c_dirt) if (vm->m_data[i].getContent() == c_dirt)
vm->m_data[i] = MapNode(c_dirt_with_grass); vm->m_data[i] = MapNode(c_dirt_with_grass);
@ -489,7 +489,8 @@ void MapgenV7::addTopNodes() {
vm->m_area.add_y(em, i, 1); vm->m_area.add_y(em, i, 1);
} }
// If dirt, grow grass on it. // If dirt, grow grass on it.
if (vm->m_data[i].getContent() == CONTENT_AIR) { if (y > water_level - 10 &&
vm->m_data[i].getContent() == CONTENT_AIR) {
vm->m_area.add_y(em, i, -1); vm->m_area.add_y(em, i, -1);
if (vm->m_data[i].getContent() == c_dirt) if (vm->m_data[i].getContent() == c_dirt)
vm->m_data[i] = MapNode(c_dirt_with_grass); vm->m_data[i] = MapNode(c_dirt_with_grass);
@ -502,22 +503,22 @@ void MapgenV7::addTopNodes() {
#include "mapgen_v6.h" #include "mapgen_v6.h"
void MapgenV7::generateCaves(int max_stone_y) { void MapgenV7::generateCaves(int max_stone_y) {
PseudoRandom ps(blockseed + 21343); PseudoRandom ps(blockseed + 21343);
PseudoRandom ps2(blockseed + 1032);
int volume_nodes = (node_max.X - node_min.X + 1) * int volume_nodes = (node_max.X - node_min.X + 1) *
(node_max.Y - node_min.Y + 1) * MAP_BLOCKSIZE; (node_max.Y - node_min.Y + 1) *
(node_max.Z - node_min.Z + 1);
float cave_amount = NoisePerlin2D(&nparams_v6_def_cave, float cave_amount = NoisePerlin2D(&nparams_v6_def_cave,
node_min.X, node_min.Y, seed); node_min.X, node_min.Y, seed);
u32 caves_count = MYMAX(0.0, cave_amount) * volume_nodes / 50000; u32 caves_count = MYMAX(0.0, cave_amount) * volume_nodes / 250000;
for (u32 i = 0; i < caves_count; i++) { for (u32 i = 0; i < caves_count; i++) {
CaveV6 cave(this, &ps, &ps2, false, c_water_source, c_lava_source); CaveV7 cave(this, &ps, false);
cave.makeCave(node_min, node_max, max_stone_y); cave.makeCave(node_min, node_max, max_stone_y);
} }
u32 bruises_count = (ps.range(1, 6) == 1) ? ps.range(0, ps.range(0, 2)) : 1; u32 bruises_count = (ps.range(1, 8) == 1) ? ps.range(0, ps.range(0, 2)) : 1;
for (u32 i = 0; i < bruises_count; i++) { for (u32 i = 0; i < bruises_count; i++) {
CaveV6 cave(this, &ps, &ps2, true, c_water_source, c_lava_source); CaveV7 cave(this, &ps, true);
cave.makeCave(node_min, node_max, max_stone_y); cave.makeCave(node_min, node_max, max_stone_y);
} }
} }

@ -628,6 +628,10 @@ public:
f->solidness = 0; f->solidness = 0;
f->visual_solidness = 1; f->visual_solidness = 1;
break; break;
case NDT_GLASSLIKE_FRAMED:
f->solidness = 0;
f->visual_solidness = 1;
break;
case NDT_ALLFACES: case NDT_ALLFACES:
f->solidness = 0; f->solidness = 0;
f->visual_solidness = 1; f->visual_solidness = 1;
@ -658,15 +662,11 @@ public:
break; break;
} }
u8 material_type = 0; u8 material_type;
if(is_liquid){ if (is_liquid)
if(f->alpha == 255) material_type = (f->alpha == 255) ? TILE_MATERIAL_LIQUID_OPAQUE : TILE_MATERIAL_LIQUID_TRANSPARENT;
material_type = TILE_MATERIAL_LIQUID_OPAQUE; else
else material_type = (f->alpha == 255) ? TILE_MATERIAL_BASIC : TILE_MATERIAL_ALPHA;
material_type = TILE_MATERIAL_LIQUID_TRANSPARENT;
} else{
material_type = TILE_MATERIAL_BASIC;
}
// Tiles (fill in f->tiles[]) // Tiles (fill in f->tiles[])
for(u16 j=0; j<6; j++){ for(u16 j=0; j<6; j++){

@ -141,6 +141,9 @@ enum NodeDrawType
NDT_FENCELIKE, NDT_FENCELIKE,
NDT_RAILLIKE, NDT_RAILLIKE,
NDT_NODEBOX, NDT_NODEBOX,
NDT_GLASSLIKE_FRAMED, // Glass-like, draw connected frames and all all
// visible faces
// uses 2 textures, one for frames, second for faces
}; };
#define CF_SPECIAL_COUNT 2 #define CF_SPECIAL_COUNT 2

@ -18,6 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
*/ */
#include "player.h" #include "player.h"
#include "hud.h"
#include "constants.h" #include "constants.h"
#include "gamedef.h" #include "gamedef.h"
#include "connection.h" // PEER_ID_INEXISTENT #include "connection.h" // PEER_ID_INEXISTENT
@ -41,7 +42,8 @@ Player::Player(IGameDef *gamedef):
m_pitch(0), m_pitch(0),
m_yaw(0), m_yaw(0),
m_speed(0,0,0), m_speed(0,0,0),
m_position(0,0,0) m_position(0,0,0),
m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.55,BS*0.30)
{ {
updateName("<not set>"); updateName("<not set>");
inventory.clear(); inventory.clear();
@ -52,30 +54,33 @@ Player::Player(IGameDef *gamedef):
inventory.addList("craftresult", 1); inventory.addList("craftresult", 1);
// Can be redefined via Lua // Can be redefined via Lua
inventory_formspec = "size[8,7.5]" inventory_formspec = "size[8,7.5]"
//"image[1,0.6;1,2;player.png]" //"image[1,0.6;1,2;player.png]"
"list[current_player;main;0,3.5;8,4;]" "list[current_player;main;0,3.5;8,4;]"
"list[current_player;craft;3,0;3,3;]" "list[current_player;craft;3,0;3,3;]"
"list[current_player;craftpreview;7,1;1,1;]"; "list[current_player;craftpreview;7,1;1,1;]";
// Initialize movement settings at default values, so movement can work if the server fails to send them // Initialize movement settings at default values, so movement can work if the server fails to send them
movement_acceleration_default = 3 * BS; movement_acceleration_default = 3 * BS;
movement_acceleration_air = 2 * BS; movement_acceleration_air = 2 * BS;
movement_acceleration_fast = 10 * BS; movement_acceleration_fast = 10 * BS;
movement_speed_walk = 4 * BS; movement_speed_walk = 4 * BS;
movement_speed_crouch = 1.35 * BS; movement_speed_crouch = 1.35 * BS;
movement_speed_fast = 20 * BS; movement_speed_fast = 20 * BS;
movement_speed_climb = 2 * BS; movement_speed_climb = 2 * BS;
movement_speed_jump = 6.5 * BS; movement_speed_jump = 6.5 * BS;
movement_liquid_fluidity = 1 * BS; movement_liquid_fluidity = 1 * BS;
movement_liquid_fluidity_smooth = 0.5 * BS; movement_liquid_fluidity_smooth = 0.5 * BS;
movement_liquid_sink = 10 * BS; movement_liquid_sink = 10 * BS;
movement_gravity = 9.81 * BS; movement_gravity = 9.81 * BS;
// Movement overrides are multipliers and must be 1 by default // Movement overrides are multipliers and must be 1 by default
physics_override_speed = 1; physics_override_speed = 1;
physics_override_jump = 1; physics_override_jump = 1;
physics_override_gravity = 1; physics_override_gravity = 1;
hud_flags = HUD_FLAG_HOTBAR_VISIBLE | HUD_FLAG_HEALTHBAR_VISIBLE |
HUD_FLAG_CROSSHAIR_VISIBLE | HUD_FLAG_WIELDITEM_VISIBLE;
} }
Player::~Player() Player::~Player()

@ -180,6 +180,10 @@ public:
return m_name; return m_name;
} }
core::aabbox3d<f32> getCollisionbox() {
return m_collisionbox;
}
virtual bool isLocal() const virtual bool isLocal() const
{ return false; } { return false; }
virtual PlayerSAO *getPlayerSAO() virtual PlayerSAO *getPlayerSAO()
@ -245,6 +249,7 @@ public:
u32 keyPressed; u32 keyPressed;
std::vector<HudElement *> hud; std::vector<HudElement *> hud;
u32 hud_flags;
protected: protected:
IGameDef *m_gamedef; IGameDef *m_gamedef;
@ -254,6 +259,7 @@ protected:
f32 m_yaw; f32 m_yaw;
v3f m_speed; v3f m_speed;
v3f m_position; v3f m_position;
core::aabbox3d<f32> m_collisionbox;
}; };

@ -754,15 +754,18 @@ static int l_chat_send_all(lua_State *L)
return 0; return 0;
} }
// chat_send_player(name, text) // chat_send_player(name, text, prepend)
static int l_chat_send_player(lua_State *L) static int l_chat_send_player(lua_State *L)
{ {
const char *name = luaL_checkstring(L, 1); const char *name = luaL_checkstring(L, 1);
const char *text = luaL_checkstring(L, 2); const char *text = luaL_checkstring(L, 2);
bool prepend = true;
if (lua_isboolean(L, 3))
prepend = lua_toboolean(L, 3);
// Get server from registry // Get server from registry
Server *server = get_server(L); Server *server = get_server(L);
// Send // Send
server->notifyPlayer(name, narrow_to_wide(text)); server->notifyPlayer(name, narrow_to_wide(text), prepend);
return 0; return 0;
} }
@ -785,6 +788,31 @@ static int l_get_player_privs(lua_State *L)
return 1; return 1;
} }
// get_player_ip()
static int l_get_player_ip(lua_State *L)
{
const char * name = luaL_checkstring(L, 1);
Player *player = get_env(L)->getPlayer(name);
if(player == NULL)
{
lua_pushnil(L); // no such player
return 1;
}
try
{
Address addr = get_server(L)->getPeerAddress(get_env(L)->getPlayer(name)->peer_id);
std::string ip_str = addr.serializeString();
lua_pushstring(L, ip_str.c_str());
return 1;
}
catch(con::PeerNotFoundException) // unlikely
{
dstream << __FUNCTION_NAME << ": peer was not found" << std::endl;
lua_pushnil(L); // error
return 1;
}
}
// get_ban_list() // get_ban_list()
static int l_get_ban_list(lua_State *L) static int l_get_ban_list(lua_State *L)
{ {
@ -1081,6 +1109,7 @@ static const struct luaL_Reg minetest_f [] = {
{"chat_send_all", l_chat_send_all}, {"chat_send_all", l_chat_send_all},
{"chat_send_player", l_chat_send_player}, {"chat_send_player", l_chat_send_player},
{"get_player_privs", l_get_player_privs}, {"get_player_privs", l_get_player_privs},
{"get_player_ip", l_get_player_ip},
{"get_ban_list", l_get_ban_list}, {"get_ban_list", l_get_ban_list},
{"get_ban_description", l_get_ban_description}, {"get_ban_description", l_get_ban_description},
{"ban_player", l_ban_player}, {"ban_player", l_ban_player},

@ -225,6 +225,11 @@ ContentFeatures read_content_features(lua_State *L, int index)
lua_pop(L, 1); lua_pop(L, 1);
f.alpha = getintfield_default(L, index, "alpha", 255); f.alpha = getintfield_default(L, index, "alpha", 255);
bool usealpha = getboolfield_default(L, index,
"use_texture_alpha", false);
if (usealpha)
f.alpha = 0;
/* Other stuff */ /* Other stuff */

@ -34,6 +34,7 @@ struct EnumString es_DrawType[] =
{NDT_LIQUID, "liquid"}, {NDT_LIQUID, "liquid"},
{NDT_FLOWINGLIQUID, "flowingliquid"}, {NDT_FLOWINGLIQUID, "flowingliquid"},
{NDT_GLASSLIKE, "glasslike"}, {NDT_GLASSLIKE, "glasslike"},
{NDT_GLASSLIKE_FRAMED, "glasslike_framed"},
{NDT_ALLFACES, "allfaces"}, {NDT_ALLFACES, "allfaces"},
{NDT_ALLFACES_OPTIONAL, "allfaces_optional"}, {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
{NDT_TORCHLIKE, "torchlike"}, {NDT_TORCHLIKE, "torchlike"},

@ -47,6 +47,17 @@ struct EnumString es_HudElementStat[] =
{HUD_STAT_NUMBER, "number"}, {HUD_STAT_NUMBER, "number"},
{HUD_STAT_ITEM, "item"}, {HUD_STAT_ITEM, "item"},
{HUD_STAT_DIR, "direction"}, {HUD_STAT_DIR, "direction"},
{HUD_STAT_ALIGN, "alignment"},
{HUD_STAT_OFFSET, "offset"},
{0, NULL},
};
struct EnumString es_HudBuiltinElement[] =
{
{HUD_FLAG_HOTBAR_VISIBLE, "hotbar"},
{HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"},
{HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"},
{HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"},
{0, NULL}, {0, NULL},
}; };
@ -751,6 +762,14 @@ int ObjectRef::l_hud_add(lua_State *L)
elem->item = getintfield_default(L, 2, "item", 0); elem->item = getintfield_default(L, 2, "item", 0);
elem->dir = getintfield_default(L, 2, "direction", 0); elem->dir = getintfield_default(L, 2, "direction", 0);
lua_getfield(L, 2, "alignment");
elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
lua_getfield(L, 2, "offset");
elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
u32 id = get_server(L)->hudAdd(player, elem); u32 id = get_server(L)->hudAdd(player, elem);
if (id == (u32)-1) { if (id == (u32)-1) {
delete elem; delete elem;
@ -833,6 +852,12 @@ int ObjectRef::l_hud_change(lua_State *L)
case HUD_STAT_DIR: case HUD_STAT_DIR:
e->dir = lua_tonumber(L, 4); e->dir = lua_tonumber(L, 4);
value = &e->dir; value = &e->dir;
case HUD_STAT_ALIGN:
e->align = read_v2f(L, 4);
value = &e->align;
case HUD_STAT_OFFSET:
e->offset = read_v2f(L, 4);
value = &e->offset;
} }
get_server(L)->hudChange(player, id, stat, value); get_server(L)->hudChange(player, id, stat, value);
@ -886,6 +911,32 @@ int ObjectRef::l_hud_get(lua_State *L)
return 1; return 1;
} }
// hud_set_flags(self, flags)
int ObjectRef::l_hud_set_flags(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
u32 flags = 0;
u32 mask = 0;
bool flag;
const EnumString *esp = es_HudBuiltinElement;
for (int i = 0; esp[i].str; i++) {
if (getboolfield(L, 2, esp[i].str, flag)) {
flags |= esp[i].num * flag;
mask |= esp[i].num;
}
}
if (!get_server(L)->hudSetFlags(player, flags, mask))
return 0;
lua_pushboolean(L, true);
return 1;
}
ObjectRef::ObjectRef(ServerActiveObject *object): ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object) m_object(object)
{ {
@ -996,8 +1047,7 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, hud_remove), luamethod(ObjectRef, hud_remove),
luamethod(ObjectRef, hud_change), luamethod(ObjectRef, hud_change),
luamethod(ObjectRef, hud_get), luamethod(ObjectRef, hud_get),
//luamethod(ObjectRef, hud_lock_next_bar), luamethod(ObjectRef, hud_set_flags),
//luamethod(ObjectRef, hud_unlock_bar),
{0,0} {0,0}
}; };

@ -202,6 +202,9 @@ private:
// hud_get(self, id) // hud_get(self, id)
static int l_hud_get(lua_State *L); static int l_hud_get(lua_State *L);
// hud_set_flags(self, flags)
static int l_hud_set_flags(lua_State *L);
public: public:
ObjectRef(ServerActiveObject *object); ObjectRef(ServerActiveObject *object);

@ -3616,6 +3616,8 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
writeU32(os, form->number); writeU32(os, form->number);
writeU32(os, form->item); writeU32(os, form->item);
writeU32(os, form->dir); writeU32(os, form->dir);
writeV2F1000(os, form->align);
writeV2F1000(os, form->offset);
// Make data buffer // Make data buffer
std::string s = os.str(); std::string s = os.str();
@ -3650,6 +3652,8 @@ void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value
switch (stat) { switch (stat) {
case HUD_STAT_POS: case HUD_STAT_POS:
case HUD_STAT_SCALE: case HUD_STAT_SCALE:
case HUD_STAT_ALIGN:
case HUD_STAT_OFFSET:
writeV2F1000(os, *(v2f *)value); writeV2F1000(os, *(v2f *)value);
break; break;
case HUD_STAT_NAME: case HUD_STAT_NAME:
@ -3671,6 +3675,22 @@ void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value
m_con.Send(peer_id, 0, data, true); m_con.Send(peer_id, 0, data, true);
} }
void Server::SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask)
{
std::ostringstream os(std::ios_base::binary);
// Write command
writeU16(os, TOCLIENT_HUD_SET_FLAGS);
writeU32(os, flags);
writeU32(os, mask);
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
void Server::BroadcastChatMessage(const std::wstring &message) void Server::BroadcastChatMessage(const std::wstring &message)
{ {
for(std::map<u16, RemoteClient*>::iterator for(std::map<u16, RemoteClient*>::iterator
@ -4602,12 +4622,15 @@ void Server::saveConfig()
g_settings->updateConfigFile(m_path_config.c_str()); g_settings->updateConfigFile(m_path_config.c_str());
} }
void Server::notifyPlayer(const char *name, const std::wstring msg) void Server::notifyPlayer(const char *name, const std::wstring msg, const bool prepend = true)
{ {
Player *player = m_env->getPlayer(name); Player *player = m_env->getPlayer(name);
if(!player) if(!player)
return; return;
SendChatMessage(player->peer_id, std::wstring(L"Server: -!- ")+msg); if (prepend)
SendChatMessage(player->peer_id, std::wstring(L"Server -!- ")+msg);
else
SendChatMessage(player->peer_id, msg);
} }
bool Server::showFormspec(const char *playername, const std::string &formspec, const std::string &formname) bool Server::showFormspec(const char *playername, const std::string &formspec, const std::string &formname)
@ -4657,6 +4680,14 @@ bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data)
return true; return true;
} }
bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) {
if (!player)
return false;
SendHUDSetFlags(player->peer_id, flags, mask);
return true;
}
void Server::notifyPlayers(const std::wstring msg) void Server::notifyPlayers(const std::wstring msg)
{ {
BroadcastChatMessage(msg); BroadcastChatMessage(msg);

@ -456,7 +456,7 @@ public:
} }
// Envlock and conlock should be locked when calling this // Envlock and conlock should be locked when calling this
void notifyPlayer(const char *name, const std::wstring msg); void notifyPlayer(const char *name, const std::wstring msg, const bool prepend);
void notifyPlayers(const std::wstring msg); void notifyPlayers(const std::wstring msg);
void spawnParticle(const char *playername, void spawnParticle(const char *playername,
v3f pos, v3f velocity, v3f acceleration, v3f pos, v3f velocity, v3f acceleration,
@ -540,6 +540,7 @@ public:
u32 hudAdd(Player *player, HudElement *element); u32 hudAdd(Player *player, HudElement *element);
bool hudRemove(Player *player, u32 id); bool hudRemove(Player *player, u32 id);
bool hudChange(Player *player, u32 id, HudElementStat stat, void *value); bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
bool hudSetFlags(Player *player, u32 flags, u32 mask);
private: private:
@ -583,6 +584,8 @@ private:
void SendHUDAdd(u16 peer_id, u32 id, HudElement *form); void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
void SendHUDRemove(u16 peer_id, u32 id); void SendHUDRemove(u16 peer_id, u32 id);
void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value); void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
/* /*
Send a node removal/addition event to all clients except ignore_id. Send a node removal/addition event to all clients except ignore_id.
Additionally, if far_players!=NULL, players further away than Additionally, if far_players!=NULL, players further away than

@ -38,10 +38,12 @@ std::string getFilePath()
{ {
std::string serverlist_file = g_settings->get("serverlist_file"); std::string serverlist_file = g_settings->get("serverlist_file");
std::string rel_path = std::string("client") + DIR_DELIM std::string dir_path = std::string("client") + DIR_DELIM
+ "serverlist" + DIR_DELIM + "serverlist" + DIR_DELIM;
+ serverlist_file; fs::CreateDir(porting::path_user + DIR_DELIM + "client");
std::string path = porting::path_share + DIR_DELIM + rel_path; fs::CreateDir(porting::path_user + DIR_DELIM + dir_path);
std::string rel_path = dir_path + serverlist_file;
std::string path = porting::path_user + DIR_DELIM + rel_path;
return path; return path;
} }

@ -162,6 +162,7 @@ IWritableTextureSource* createTextureSource(IrrlichtDevice *device);
enum MaterialType{ enum MaterialType{
TILE_MATERIAL_BASIC, TILE_MATERIAL_BASIC,
TILE_MATERIAL_ALPHA,
TILE_MATERIAL_LIQUID_TRANSPARENT, TILE_MATERIAL_LIQUID_TRANSPARENT,
TILE_MATERIAL_LIQUID_OPAQUE, TILE_MATERIAL_LIQUID_OPAQUE,
}; };
@ -222,6 +223,9 @@ struct TileSpec
case TILE_MATERIAL_BASIC: case TILE_MATERIAL_BASIC:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
break; break;
case TILE_MATERIAL_ALPHA:
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
break;
case TILE_MATERIAL_LIQUID_TRANSPARENT: case TILE_MATERIAL_LIQUID_TRANSPARENT:
material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA; material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
break; break;
@ -233,12 +237,16 @@ struct TileSpec
} }
void applyMaterialOptionsWithShaders(video::SMaterial &material, void applyMaterialOptionsWithShaders(video::SMaterial &material,
const video::E_MATERIAL_TYPE &basic, const video::E_MATERIAL_TYPE &basic,
const video::E_MATERIAL_TYPE &liquid) const const video::E_MATERIAL_TYPE &liquid,
const video::E_MATERIAL_TYPE &alpha) const
{ {
switch(material_type){ switch(material_type){
case TILE_MATERIAL_BASIC: case TILE_MATERIAL_BASIC:
material.MaterialType = basic; material.MaterialType = basic;
break; break;
case TILE_MATERIAL_ALPHA:
material.MaterialType = alpha;
break;
case TILE_MATERIAL_LIQUID_TRANSPARENT: case TILE_MATERIAL_LIQUID_TRANSPARENT:
material.MaterialType = liquid; material.MaterialType = liquid;
break; break;