Merge remote branch 'origin/master'

This commit is contained in:
Weblate 2013-04-18 20:00:16 +02:00
commit 9e6376bd95
59 changed files with 2505 additions and 582 deletions

@ -197,7 +197,7 @@ local function unit_test()
unitTest("test 1b", unittest_input.cat.speed == unittest_output.cat.speed) unitTest("test 1b", unittest_input.cat.speed == unittest_output.cat.speed)
unitTest("test 1c", unittest_input.dog.sound == unittest_output.dog.sound) unitTest("test 1c", unittest_input.dog.sound == unittest_output.dog.sound)
unittest_input = {escapechars="\n\r\t\v\\\"\'\[\]", noneuropean="θשׁ٩∂"} unittest_input = {escapechars="\n\r\t\v\\\"\'", noneuropean="θשׁ٩∂"}
unittest_output = minetest.deserialize(minetest.serialize(unittest_input)) unittest_output = minetest.deserialize(minetest.serialize(unittest_input))
unitTest("test 3a", unittest_input.escapechars == unittest_output.escapechars) unitTest("test 3a", unittest_input.escapechars == unittest_output.escapechars)
unitTest("test 3b", unittest_input.noneuropean == unittest_output.noneuropean) unitTest("test 3b", unittest_input.noneuropean == unittest_output.noneuropean)

@ -401,6 +401,43 @@ Currently supported flags: absheight
Also produce this same ore between the height range of -height_max and -height_min. Also produce this same ore between the height range of -height_max and -height_min.
Useful for having ore in sky realms without having to duplicate ore entries. Useful for having ore in sky realms without having to duplicate ore entries.
HUD element types
-------------------
The position field is used for all element types.
To account for differing resolutions, the position coordinates are the percentage of the screen,
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.
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.
- image
Displays an image on the HUD.
- scale: The scale of the image, with 1 being the original texture size.
Only the X coordinate scale is used.
- text: The name of the texture that is displayed.
- text
Displays text on the HUD.
- scale: Defines the bounding rectangle of the text.
A value such as {x=100, y=100} should work.
- 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.
Specify 0xFFFFFF for white text, 0xFF0000 for red, and so on.
- statbar
Displays a horizontal bar made up of half-images.
- text: The name of the texture that is used.
- number: The number of half-textures that are displayed.
If odd, will end with a vertically center-split texture.
- inventory
- text: The name of the inventory list to be displayed.
- number: Number of items in the inventory to be displayed.
- item: Position of item that is selected.
- direction: Direction in which the inventory list 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.
Representations of simple things Representations of simple things
-------------------------------- --------------------------------
Position/vector: Position/vector:
@ -1002,10 +1039,23 @@ minetest.get_craft_recipe(output) -> input
^ input.items = for example { stack 1, stack 2, stack 3, stack 4, ^ input.items = for example { stack 1, stack 2, stack 3, stack 4,
stack 5, stack 6, stack 7, stack 8, stack 9 } stack 5, stack 6, stack 7, stack 8, stack 9 }
^ input.items = nil if no recipe found ^ input.items = nil if no recipe found
minetest.get_all_craft_recipes(output) -> table or nil minetest.get_all_craft_recipes(query item) -> table or nil
^ returns table with all registered recipes for output item (node) ^ returns indexed table with all registered recipes for query item (node)
^ returns nil if no recipe was found or nil if no recipe was found
^ table entries have same format as minetest.get_craft_recipe recipe entry table:
{
method = 'normal' or 'cooking' or 'fuel'
width = 0-3, 0 means shapeless recipe
items = indexed [1-9] table with recipe items
output = string with item name and quantity
}
Example query for default:gold_ingot will return table:
{
1={type = "cooking", width = 3, output = "default:gold_ingot",
items = {1 = "default:gold_lump"}},
2={type = "normal", width = 1, output = "default:gold_ingot 9",
items = {1 = "default:goldblock"}}
}
minetest.handle_node_drops(pos, drops, digger) minetest.handle_node_drops(pos, drops, digger)
^ drops: list of itemstrings ^ drops: list of itemstrings
^ Handles drops from nodes after digging: Default action is to put them into ^ Handles drops from nodes after digging: Default action is to put them into
@ -1366,6 +1416,11 @@ Player-only: (no-op for other objects)
modifies per-player walking speed, jump height, and gravity. modifies per-player walking speed, jump height, and gravity.
Values default to 1 and act as offsets to the physics settings Values default to 1 and act as offsets to the physics settings
in minetest.conf. nil will keep the current setting. in minetest.conf. nil will keep the current setting.
- hud_add(hud definition): add a HUD element described by HUD def, returns ID number on success
- hud_remove(id): remove the HUD element of the specified id
- hud_change(id, stat, value): change a value of a previously added HUD element
^ element stat values: position, name, scale, text, number, item, dir
- hud_get(id): gets the HUD element definition structure of the specified ID
InvRef: Reference to an inventory InvRef: Reference to an inventory
methods: methods:
@ -1789,3 +1844,18 @@ Detached inventory callbacks
^ No return value ^ No return value
} }
HUD Definition (hud_add, hud_get)
{
type = "image",
^ type of HUD element, can be either of "image", "text", "statbar", or "inventory"
position = {x=0.5, y=0.5},
^ Left corner position of element
name = "<name>",
scale = {x=2, y=2},
text = "<text>",
number = 2,
item = 3,
^ Selected item in inventory. 0 for no item selected.
dir = 0,
^ Direction: 0: left-right, 1: right-left, 2: top-bottom, 3: bottom-top
}

@ -1,90 +0,0 @@
# Makefile for Irrlicht Examples
# It's usually sufficient to change just the target name and source file list
# and be sure that CXX is set to a valid compiler
SOURCE_FILES = porting.cpp guiMessageMenu.cpp materials.cpp guiTextInputMenu.cpp guiInventoryMenu.cpp irrlichtwrapper.cpp guiPauseMenu.cpp defaultsettings.cpp mapnode.cpp tile.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp client.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp main.cpp test.cpp
DEBUG_TARGET = debugtest
DEBUG_SOURCES = $(addprefix src/, $(SOURCE_FILES))
DEBUG_BUILD_DIR = debugbuild
DEBUG_OBJECTS = $(addprefix $(DEBUG_BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))
FAST_TARGET = fasttest
FAST_SOURCES = $(addprefix src/, $(SOURCE_FILES))
FAST_BUILD_DIR = fastbuild
FAST_OBJECTS = $(addprefix $(FAST_BUILD_DIR)/, $(SOURCE_FILES:.cpp=.o))
SERVER_TARGET = server
SERVER_SOURCE_FILES = porting.cpp materials.cpp defaultsettings.cpp mapnode.cpp voxel.cpp mapblockobject.cpp inventory.cpp debug.cpp serialization.cpp light.cpp filesys.cpp connection.cpp environment.cpp server.cpp socket.cpp mapblock.cpp mapsector.cpp heightmap.cpp map.cpp player.cpp utility.cpp servermain.cpp test.cpp
SERVER_SOURCES = $(addprefix src/, $(SERVER_SOURCE_FILES))
SERVER_BUILD_DIR = serverbuild
SERVER_OBJECTS = $(addprefix $(SERVER_BUILD_DIR)/, $(SERVER_SOURCE_FILES:.cpp=.o))
IRRLICHTPATH = ../irrlicht/irrlicht-1.7.1
JTHREADPATH = ../jthread/jthread-1.2.1
all: fast
ifeq ($(HOSTTYPE), x86_64)
LIBSELECT=64
endif
debug: CXXFLAGS = -Wall -g -O1
debug: CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src -DDEBUG -DRUN_IN_PLACE
debug: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L$(IRRLICHTPATH)/lib/Linux -L$(JTHREADPATH)/src/.libs -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -ljthread -lz
fast: CXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686
fast: CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src -DUNITTEST_DISABLE -DRUN_IN_PLACE
fast: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L$(IRRLICHTPATH)/lib/Linux -L$(JTHREADPATH)/src/.libs -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -ljthread -lz
server: CXXFLAGS = -O3 -ffast-math -Wall -fomit-frame-pointer -pipe -funroll-loops -mtune=i686
server: CPPFLAGS = -I$(IRRLICHTPATH)/include -I/usr/X11R6/include -I$(JTHREADPATH)/src -DSERVER -DUNITTEST_DISABLE -DRUN_IN_PLACE
server: LDFLAGS = -L$(JTHREADPATH)/src/.libs -ljthread -lz -lpthread
DEBUG_DESTPATH = bin/$(DEBUG_TARGET)
FAST_DESTPATH = bin/$(FAST_TARGET)
SERVER_DESTPATH = bin/$(SERVER_TARGET)
# Build commands
debug: $(DEBUG_BUILD_DIR) $(DEBUG_DESTPATH)
fast: $(FAST_BUILD_DIR) $(FAST_DESTPATH)
server: $(SERVER_BUILD_DIR) $(SERVER_DESTPATH)
$(DEBUG_BUILD_DIR):
mkdir -p $(DEBUG_BUILD_DIR)
$(FAST_BUILD_DIR):
mkdir -p $(FAST_BUILD_DIR)
$(SERVER_BUILD_DIR):
mkdir -p $(SERVER_BUILD_DIR)
$(DEBUG_DESTPATH): $(DEBUG_OBJECTS)
$(CXX) -o $@ $(DEBUG_OBJECTS) $(LDFLAGS)
$(FAST_DESTPATH): $(FAST_OBJECTS)
$(CXX) -o $@ $(FAST_OBJECTS) $(LDFLAGS)
$(SERVER_DESTPATH): $(SERVER_OBJECTS)
$(CXX) -o $@ $(SERVER_OBJECTS) $(LDFLAGS)
$(DEBUG_BUILD_DIR)/%.o: src/%.cpp
$(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)
$(FAST_BUILD_DIR)/%.o: src/%.cpp
$(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)
$(SERVER_BUILD_DIR)/%.o: src/%.cpp
$(CXX) -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS)
clean: clean_debug clean_fast clean_server
clean_debug:
@$(RM) $(DEBUG_OBJECTS) $(DEBUG_DESTPATH)
clean_fast:
@$(RM) $(FAST_OBJECTS) $(FAST_DESTPATH)
clean_server:
@$(RM) $(SERVER_OBJECTS) $(SERVER_DESTPATH)
.PHONY: all all_win32 clean clean_debug clean_win32 clean_fast clean_server

776
po/du/minetest.po Normal file

@ -0,0 +1,776 @@
# SOME DESCRIPTIVE TITLE. DUTCH TRANSLATION
# 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.
#
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: 2013-04-18 15:28+0100\n"
"Last-Translator: LS-Steeef \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 1.5.5\n"
"Language: dutch\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 ""
"Let op: Nog niet alle mods zijn geconfigueerd. \n"
"De mods zullen automatisch worden ingeschakeld als je de configuratie "
"bewaard."
#: src/guiConfigureWorld.cpp:144
msgid ""
"Warning: Some configured mods are missing.\n"
"Their setting will be removed when you save the configuration. "
msgstr ""
"LEt op: Sommige ingestelde mods zijn vermist.\n"
"Hun instellingen worden verwijderd als je de configuratie opslaat."
#: src/guiConfigureWorld.cpp:208
msgid "enabled"
msgstr "ingeschakeld"
#: src/guiConfigureWorld.cpp:215
msgid "Enable All"
msgstr "Allen inschakelen"
#: src/guiConfigureWorld.cpp:222
msgid "Disable All"
msgstr "Allen uitschakelen"
#: src/guiConfigureWorld.cpp:228
msgid "depends on:"
msgstr "heeft nodig:"
#: src/guiConfigureWorld.cpp:240
msgid "is required by:"
msgstr "is benodigd voor:"
#: src/guiConfigureWorld.cpp:262 src/guiCreateWorld.cpp:165
#: src/guiKeyChangeMenu.cpp:179 src/keycode.cpp:223
msgid "Cancel"
msgstr "Annuleer"
#: src/guiConfigureWorld.cpp:268 src/guiKeyChangeMenu.cpp:173
msgid "Save"
msgstr "Bewaar"
#: src/guiConfigureWorld.cpp:394
msgid "Configuration saved. "
msgstr "Instellingen bewaard."
#: src/guiConfigureWorld.cpp:402
msgid "Warning: Configuration not consistent. "
msgstr "Waarschuwing: Instellingen niet consistent."
#: src/guiConfirmMenu.cpp:120
msgid "Yes"
msgstr "Ja"
#: src/guiConfirmMenu.cpp:126
msgid "No"
msgstr "Nee"
#: src/guiCreateWorld.cpp:116
msgid "World name"
msgstr "Naam wereld"
#: src/guiCreateWorld.cpp:135
msgid "Game"
msgstr "Spel"
#: src/guiCreateWorld.cpp:159
msgid "Create"
msgstr "Maak aan"
#: src/guiDeathScreen.cpp:96
msgid "You died."
msgstr "Je bent gestorven."
#: src/guiDeathScreen.cpp:104
msgid "Respawn"
msgstr "Respawn"
#: src/guiFormSpecMenu.cpp:582
msgid "Left click: Move all items, Right click: Move single item"
msgstr ""
"Linkermuisknop: Verplaats alle items. Rechtermuisknop: Verplaats één item."
#: src/guiFormSpecMenu.cpp:607 src/guiMessageMenu.cpp:109
#: src/guiTextInputMenu.cpp:131
msgid "Proceed"
msgstr "Volgende"
#: src/guiKeyChangeMenu.cpp:114
msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)"
msgstr "Sneltoetsen."
#: src/guiKeyChangeMenu.cpp:151
msgid "\"Use\" = climb down"
msgstr "\"Use\" = Omlaag klimmen"
#: src/guiKeyChangeMenu.cpp:164
msgid "Double tap \"jump\" to toggle fly"
msgstr "Dubbelklik op \"jump\" om te vliegen"
#: src/guiKeyChangeMenu.cpp:269
msgid "Key already in use"
msgstr "Toets is al in gebruik"
#: src/guiKeyChangeMenu.cpp:347
msgid "press key"
msgstr "druk op"
#: src/guiKeyChangeMenu.cpp:372
msgid "Forward"
msgstr "Vooruit"
#: src/guiKeyChangeMenu.cpp:373
msgid "Backward"
msgstr "Achteruit"
#: src/guiKeyChangeMenu.cpp:374 src/keycode.cpp:228
msgid "Left"
msgstr "Links"
#: src/guiKeyChangeMenu.cpp:375 src/keycode.cpp:228
msgid "Right"
msgstr "Rechts"
#: src/guiKeyChangeMenu.cpp:376
msgid "Use"
msgstr "Gebruikwn"
#: src/guiKeyChangeMenu.cpp:377
msgid "Jump"
msgstr "Springen"
#: src/guiKeyChangeMenu.cpp:378
msgid "Sneak"
msgstr "Kruipen"
#: src/guiKeyChangeMenu.cpp:379
msgid "Drop"
msgstr "Weggooien"
#: src/guiKeyChangeMenu.cpp:380
msgid "Inventory"
msgstr "Rugzak"
#: src/guiKeyChangeMenu.cpp:381
msgid "Chat"
msgstr "Chat"
#: src/guiKeyChangeMenu.cpp:382
msgid "Command"
msgstr "Opdracht"
#: src/guiKeyChangeMenu.cpp:383
msgid "Console"
msgstr "Console"
#: src/guiKeyChangeMenu.cpp:384
msgid "Toggle fly"
msgstr "Vliegen aan/uit"
#: src/guiKeyChangeMenu.cpp:385
msgid "Toggle fast"
msgstr "Snel bewegen aan/uit"
#: src/guiKeyChangeMenu.cpp:386
msgid "Toggle noclip"
msgstr "Noclip aan/uit"
#: src/guiKeyChangeMenu.cpp:387
msgid "Range select"
msgstr "Range instellen"
#: src/guiKeyChangeMenu.cpp:388
msgid "Print stacks"
msgstr "Print stacks"
#: src/guiMainMenu.cpp:92
msgid "Cannot create world: Name contains invalid characters"
msgstr "Kan geen nieuwe wereld aanmaken: de naam bevat onjuiste tekens."
#: src/guiMainMenu.cpp:101
msgid "Cannot create world: A world by this name already exists"
msgstr "Kan geen nieuwe wereld aanmaken: De naam bestaat al."
#: src/guiMainMenu.cpp:283
msgid "Singleplayer"
msgstr "Singleplayer"
#: src/guiMainMenu.cpp:284
msgid "Multiplayer"
msgstr "Multiplayer"
#: src/guiMainMenu.cpp:285
msgid "Advanced"
msgstr "Geavanceerd"
#: src/guiMainMenu.cpp:286
msgid "Settings"
msgstr "Instellingen"
#: src/guiMainMenu.cpp:287
msgid "Credits"
msgstr "Credits"
#: src/guiMainMenu.cpp:317
msgid "Select World:"
msgstr "Selecteer Wereld:"
#: src/guiMainMenu.cpp:339 src/guiMainMenu.cpp:511 src/keycode.cpp:229
msgid "Delete"
msgstr "Verwijderen"
#: src/guiMainMenu.cpp:346
msgid "New"
msgstr "Nieuw"
#: src/guiMainMenu.cpp:354
msgid "Configure"
msgstr "Instellingen"
#: src/guiMainMenu.cpp:369 src/keycode.cpp:248
msgid "Play"
msgstr "Speel!"
#: src/guiMainMenu.cpp:380 src/guiMainMenu.cpp:619
msgid "Creative Mode"
msgstr "Creative Modus"
#: src/guiMainMenu.cpp:386 src/guiMainMenu.cpp:625
msgid "Enable Damage"
msgstr "Schade inschakelen"
#: src/guiMainMenu.cpp:406 src/guiMainMenu.cpp:541
msgid "Name/Password"
msgstr "Naam/Wachtwoord"
#: src/guiMainMenu.cpp:442 src/guiMainMenu.cpp:459 src/guiMainMenu.cpp:1184
msgid "Favorites:"
msgstr "Favourieten:"
#: src/guiMainMenu.cpp:450 src/guiMainMenu.cpp:1194
msgid "Public Server List:"
msgstr "Publieke Server lijst:"
#: src/guiMainMenu.cpp:470 src/guiMainMenu.cpp:568
msgid "Address/Port"
msgstr "IP-Adres/Poort"
#: src/guiMainMenu.cpp:497 src/guiMainMenu.cpp:1183
msgid "Show Public"
msgstr "Publieke server"
#: src/guiMainMenu.cpp:501 src/guiMainMenu.cpp:1193
msgid "Show Favorites"
msgstr "Favourieten"
#: src/guiMainMenu.cpp:521
msgid "Connect"
msgstr "Verbinden"
#: src/guiMainMenu.cpp:591
msgid "Leave address blank to start a local server."
msgstr "Laat het adres leeg om een lokale server te starten."
#: src/guiMainMenu.cpp:600
msgid "Start Game / Connect"
msgstr "Start het spel / Verbind"
#: src/guiMainMenu.cpp:632
msgid "Public"
msgstr "Publiek"
#: src/guiMainMenu.cpp:640 src/guiMainMenu.cpp:1113
msgid "Delete world"
msgstr "Verwijder wereld"
#: src/guiMainMenu.cpp:647
msgid "Create world"
msgstr "Maak wereld aan"
#: src/guiMainMenu.cpp:681
msgid "Fancy trees"
msgstr "Mooie bomen"
#: src/guiMainMenu.cpp:687
msgid "Smooth Lighting"
msgstr "Mooie verlichting"
#: src/guiMainMenu.cpp:693
msgid "3D Clouds"
msgstr "3D wolken"
#: src/guiMainMenu.cpp:699
msgid "Opaque water"
msgstr "Doorzichtig water"
#: src/guiMainMenu.cpp:709
msgid "Mip-Mapping"
msgstr "Mip-Mapping"
#: src/guiMainMenu.cpp:716
msgid "Anisotropic Filtering"
msgstr "Bi-Linear Filtering"
#: src/guiMainMenu.cpp:723
msgid "Bi-Linear Filtering"
msgstr "Bi-Linear Filtering"
#: src/guiMainMenu.cpp:730
msgid "Tri-Linear Filtering"
msgstr "Tri-Linear Filtering"
#: src/guiMainMenu.cpp:738
msgid "Shaders"
msgstr "Shaders"
#: src/guiMainMenu.cpp:745
msgid "Preload item visuals"
msgstr "Preload item visuals"
#: src/guiMainMenu.cpp:752
msgid "Enable Particles"
msgstr "Enable Particles"
#: src/guiMainMenu.cpp:759
msgid "Finite liquid"
msgstr "Finite liquid"
#: src/guiMainMenu.cpp:769
msgid "Change keys"
msgstr "Sneltoetsen veranderen"
#: src/guiMainMenu.cpp:1084
msgid "Address required."
msgstr "IP-adres nodig."
#: src/guiMainMenu.cpp:1102
msgid "Cannot delete world: Nothing selected"
msgstr "Kan niets verwijderen: Geen wereld geselecteerd."
#: src/guiMainMenu.cpp:1117
msgid "Files to be deleted"
msgstr "Deze bestanden worden verwijderd"
#: src/guiMainMenu.cpp:1133
msgid "Cannot create world: No games found"
msgstr "Kan geen wereld aanmaken: Geen games gevonden"
#: src/guiMainMenu.cpp:1149
msgid "Cannot configure world: Nothing selected"
msgstr "Kan instellingen niet aanpassen: Niets geselecteerd"
#: src/guiMainMenu.cpp:1256
msgid "Failed to delete all world files"
msgstr "Niet alle bestanden zijn verwijderd"
#: src/guiPasswordChange.cpp:108
msgid "Old Password"
msgstr "Huidig wachtwoord"
#: src/guiPasswordChange.cpp:125
msgid "New Password"
msgstr "Nieuw wachtwoord"
#: src/guiPasswordChange.cpp:141
msgid "Confirm Password"
msgstr "Herhaal wachtwoord"
#: src/guiPasswordChange.cpp:158
msgid "Change"
msgstr "Veranderen"
#: src/guiPasswordChange.cpp:167
msgid "Passwords do not match!"
msgstr "Wachtwoorden zijn niet gelijk!"
#: src/guiPauseMenu.cpp:123
msgid "Continue"
msgstr "Volgende"
#: src/guiPauseMenu.cpp:132
msgid "Change Password"
msgstr "Verander wachtwoord"
#: src/guiPauseMenu.cpp:140
msgid "Sound Volume"
msgstr "Volume"
#: src/guiPauseMenu.cpp:147
msgid "Exit to Menu"
msgstr "Exit naar menu"
#: src/guiPauseMenu.cpp:154
msgid "Exit to OS"
msgstr "Afsluiten"
#: 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 ""
"Default Besturing:\n"
"- WASD: Lopen\n"
"- Linkermuisknop: Graaf/Sla\n"
"- Rechtmuisknop: Plaats/Gebruik\n"
"- Muiswiel: selecteer item\n"
"- 0...9: selecteer item\n"
"- Shift: kruipen\n"
"- R: Toggle viewing all loaded chunks\n"
"- I: Rugzak\n"
"- ESC: Menu\n"
"- T: Chat\n"
#: src/guiVolumeChange.cpp:108
msgid "Sound Volume: "
msgstr "Volume:"
#: src/guiVolumeChange.cpp:121
msgid "Exit"
msgstr "Exit"
#: src/keycode.cpp:223
msgid "Left Button"
msgstr "Linkermuisknop"
#: src/keycode.cpp:223
msgid "Middle Button"
msgstr "Muiswielknop"
#: src/keycode.cpp:223
msgid "Right Button"
msgstr "Rechtmuisknop"
#: src/keycode.cpp:223
msgid "X Button 1"
msgstr "X knop 1"
#: src/keycode.cpp:224
msgid "Back"
msgstr "Terug"
#: src/keycode.cpp:224
msgid "Clear"
msgstr "Wissen"
#: src/keycode.cpp:224
msgid "Return"
msgstr "Return"
#: src/keycode.cpp:224
msgid "Tab"
msgstr "Tab"
#: src/keycode.cpp:224
msgid "X Button 2"
msgstr "X knop 2"
#: src/keycode.cpp:225
msgid "Capital"
msgstr "Kapitaal"
#: src/keycode.cpp:225
msgid "Control"
msgstr "Control"
#: src/keycode.cpp:225
msgid "Kana"
msgstr "Kana"
#: src/keycode.cpp:225
msgid "Menu"
msgstr "Menu"
#: src/keycode.cpp:225
msgid "Pause"
msgstr "Pauze"
#: src/keycode.cpp:225
msgid "Shift"
msgstr "Shift"
#: src/keycode.cpp:226
msgid "Convert"
msgstr "Converteren"
#: src/keycode.cpp:226
msgid "Escape"
msgstr "Escape"
#: src/keycode.cpp:226
msgid "Final"
msgstr "Final"
#: src/keycode.cpp:226
msgid "Junja"
msgstr "Junja"
#: src/keycode.cpp:226
msgid "Kanji"
msgstr "Kanji"
#: src/keycode.cpp:226
msgid "Nonconvert"
msgstr "Nonconvert"
#: src/keycode.cpp:227
msgid "Accept"
msgstr "Accepteren"
#: src/keycode.cpp:227
msgid "End"
msgstr "End"
#: src/keycode.cpp:227
msgid "Home"
msgstr "Home"
#: src/keycode.cpp:227
msgid "Mode Change"
msgstr "Modus veranderen"
#: src/keycode.cpp:227
msgid "Next"
msgstr "Volgende"
#: src/keycode.cpp:227
msgid "Prior"
msgstr "Eerste"
#: src/keycode.cpp:227
msgid "Space"
msgstr "Spatie"
#: src/keycode.cpp:228
msgid "Down"
msgstr "Omlaag"
#: src/keycode.cpp:228
msgid "Execute"
msgstr "Uitvoeren"
#: src/keycode.cpp:228
msgid "Print"
msgstr "Print"
#: src/keycode.cpp:228
msgid "Select"
msgstr "Selecteren"
#: src/keycode.cpp:228
msgid "Up"
msgstr "Omhoog"
#: src/keycode.cpp:229
msgid "Help"
msgstr "Help"
#: src/keycode.cpp:229
msgid "Insert"
msgstr "Insert"
#: src/keycode.cpp:229
msgid "Snapshot"
msgstr "Screenshot"
#: src/keycode.cpp:232
msgid "Left Windows"
msgstr "Linker Windowstoets"
#: src/keycode.cpp:233
msgid "Apps"
msgstr "Apps"
#: src/keycode.cpp:233
msgid "Numpad 0"
msgstr "Numpad 0"
#: src/keycode.cpp:233
msgid "Numpad 1"
msgstr "Numpad 1"
#: src/keycode.cpp:233
msgid "Right Windows"
msgstr "Rechter Windowstoets"
#: src/keycode.cpp:233
msgid "Sleep"
msgstr "Slaapknop"
#: src/keycode.cpp:234
msgid "Numpad 2"
msgstr "Numpad 2"
#: src/keycode.cpp:234
msgid "Numpad 3"
msgstr "Numpad 3"
#: src/keycode.cpp:234
msgid "Numpad 4"
msgstr "Numpad 4"
#: src/keycode.cpp:234
msgid "Numpad 5"
msgstr "Numpad 5"
#: src/keycode.cpp:234
msgid "Numpad 6"
msgstr "Numpad 6"
#: src/keycode.cpp:234
msgid "Numpad 7"
msgstr "Numpad 7"
#: src/keycode.cpp:235
msgid "Numpad *"
msgstr "Numpad *"
#: src/keycode.cpp:235
msgid "Numpad +"
msgstr "Numpad +"
#: src/keycode.cpp:235
msgid "Numpad -"
msgstr "Numpad -"
#: src/keycode.cpp:235
msgid "Numpad /"
msgstr "Numpad /"
#: src/keycode.cpp:235
msgid "Numpad 8"
msgstr "Numpad 8"
#: src/keycode.cpp:235
msgid "Numpad 9"
msgstr "Numpad 9"
#: src/keycode.cpp:239
msgid "Num Lock"
msgstr "Num Lock"
#: src/keycode.cpp:239
msgid "Scroll Lock"
msgstr "Scroll Lock"
#: src/keycode.cpp:240
msgid "Left Shift"
msgstr "Linker Shift"
#: src/keycode.cpp:240
msgid "Right Shift"
msgstr "Rechter Shift"
#: src/keycode.cpp:241
msgid "Left Control"
msgstr "Linker Ctrl"
#: src/keycode.cpp:241
msgid "Left Menu"
msgstr "Linker Menu"
#: src/keycode.cpp:241
msgid "Right Control"
msgstr "Rechter Ctrl"
#: src/keycode.cpp:241
msgid "Right Menu"
msgstr "Rechter Menu"
#: src/keycode.cpp:243
msgid "Comma"
msgstr "Komma"
#: src/keycode.cpp:243
msgid "Minus"
msgstr "Min"
#: src/keycode.cpp:243
msgid "Period"
msgstr "Punt"
#: src/keycode.cpp:243
msgid "Plus"
msgstr "Plus"
#: src/keycode.cpp:247
msgid "Attn"
msgstr "Attn"
#: src/keycode.cpp:247
msgid "CrSel"
msgstr "CrSel"
#: src/keycode.cpp:248
msgid "Erase OEF"
msgstr "Erase OEF"
#: src/keycode.cpp:248
msgid "ExSel"
msgstr "ExSel"
#: src/keycode.cpp:248
msgid "OEM Clear"
msgstr "OEM Clear"
#: src/keycode.cpp:248
msgid "PA1"
msgstr "PA1"
#: src/keycode.cpp:248
msgid "Zoom"
msgstr "Zoom"
#: src/main.cpp:1506
msgid "Main Menu"
msgstr "Hoofdmenu"
#: src/main.cpp:1830
msgid "Failed to initialize world"
msgstr "Laden van wereld is mislukt"
#: src/main.cpp:1842
msgid "No world selected and no address provided. Nothing to do."
msgstr "Geen wereld en adres geselecteerd. Niks te doen."
#: src/main.cpp:1850
msgid "Could not find or load game \""
msgstr "Kan niet de game laden of vinden."
#: src/main.cpp:1864
msgid "Invalid gamespec."
msgstr "Onjuiste gamespec."
#: src/main.cpp:1904
msgid "Connection error (timed out?)"
msgstr "Connection error (timed out?)"
#: src/main.cpp:1915
msgid ""
"\n"
"Check debug.txt for details."
msgstr ""
"\n"
"Check debug.txt for details."

@ -180,10 +180,26 @@ if(USE_FREETYPE)
set(CGUITTFONT_LIBRARY cguittfont) set(CGUITTFONT_LIBRARY cguittfont)
endif(USE_FREETYPE) endif(USE_FREETYPE)
# Do not use system-wide installation of Lua, because it'll likely be a
# different version and/or has different build options. find_library(LUA_LIBRARY luajit
NAMES luajit-5.1)
find_path(LUA_INCLUDE_DIR luajit.h
NAMES luajit.h
PATH_SUFFIXES luajit-2.0)
message (STATUS "LuaJIT library: ${LUA_LIBRARY}")
message (STATUS "LuaJIT headers: ${LUA_INCLUDE_DIR}")
if(LUA_LIBRARY AND LUA_INCLUDE_DIR)
message (STATUS "LuaJIT found.")
else(LUA_LIBRARY AND LUA_INCLUDE_DIR)
message (STATUS "LuaJIT not found, using bundled Lua.")
set(LUA_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lua/src") set(LUA_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/lua/src")
set(LUA_LIBRARY "lua") set(LUA_LIBRARY "lua")
add_subdirectory(lua)
endif(LUA_LIBRARY AND LUA_INCLUDE_DIR)
mark_as_advanced(LUA_LIBRARY)
mark_as_advanced(LUA_INCLUDE_DIR)
configure_file( configure_file(
"${PROJECT_SOURCE_DIR}/cmake_config.h.in" "${PROJECT_SOURCE_DIR}/cmake_config.h.in"
@ -311,6 +327,7 @@ set(minetest_SRCS
particles.cpp particles.cpp
clientobject.cpp clientobject.cpp
chat.cpp chat.cpp
hud.cpp
guiMainMenu.cpp guiMainMenu.cpp
guiKeyChangeMenu.cpp guiKeyChangeMenu.cpp
guiMessageMenu.cpp guiMessageMenu.cpp
@ -601,11 +618,6 @@ if (BUILD_CLIENT AND USE_FREETYPE)
add_subdirectory(cguittfont) add_subdirectory(cguittfont)
endif (BUILD_CLIENT AND USE_FREETYPE) endif (BUILD_CLIENT AND USE_FREETYPE)
if (LUA_FOUND)
else (LUA_FOUND)
add_subdirectory(lua)
endif (LUA_FOUND)
if (JSON_FOUND) if (JSON_FOUND)
else (JSON_FOUND) else (JSON_FOUND)
add_subdirectory(json) add_subdirectory(json)

@ -67,9 +67,11 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
m_view_bobbing_anim(0), m_view_bobbing_anim(0),
m_view_bobbing_state(0), m_view_bobbing_state(0),
m_view_bobbing_speed(0), m_view_bobbing_speed(0),
m_view_bobbing_fall(0),
m_digging_anim(0), m_digging_anim(0),
m_digging_button(-1) m_digging_button(-1),
m_dummymesh(createCubeMesh(v3f(1,1,1)))
{ {
//dstream<<__FUNCTION_NAME<<std::endl; //dstream<<__FUNCTION_NAME<<std::endl;
@ -84,13 +86,14 @@ Camera::Camera(scene::ISceneManager* smgr, MapDrawControl& draw_control,
// all other 3D scene nodes and before the GUI. // all other 3D scene nodes and before the GUI.
m_wieldmgr = smgr->createNewSceneManager(); m_wieldmgr = smgr->createNewSceneManager();
m_wieldmgr->addCameraSceneNode(); m_wieldmgr->addCameraSceneNode();
m_wieldnode = m_wieldmgr->addMeshSceneNode(createCubeMesh(v3f(1,1,1)), NULL); // need a dummy mesh m_wieldnode = m_wieldmgr->addMeshSceneNode(m_dummymesh, NULL); // need a dummy mesh
} }
Camera::~Camera() Camera::~Camera()
{ {
m_wieldnode->setMesh(NULL);
m_wieldmgr->drop(); m_wieldmgr->drop();
delete m_dummymesh;
} }
bool Camera::successfullyCreated(std::wstring& error_message) bool Camera::successfullyCreated(std::wstring& error_message)
@ -132,6 +135,13 @@ inline f32 my_modf(f32 x)
void Camera::step(f32 dtime) void Camera::step(f32 dtime)
{ {
if(m_view_bobbing_fall > 0)
{
m_view_bobbing_fall -= 3 * dtime;
if(m_view_bobbing_fall <= 0)
m_view_bobbing_fall = -1; // Mark the effect as finished
}
if (m_view_bobbing_state != 0) if (m_view_bobbing_state != 0)
{ {
//f32 offset = dtime * m_view_bobbing_speed * 0.035; //f32 offset = dtime * m_view_bobbing_speed * 0.035;
@ -238,8 +248,25 @@ void Camera::update(LocalPlayer* player, f32 frametime, v2u32 screensize,
// Get camera tilt timer (hurt animation) // Get camera tilt timer (hurt animation)
float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75); float cameratilt = fabs(fabs(player->hurt_tilt_timer-0.75)-0.75);
// Fall bobbing animation
float fall_bobbing = 0;
if(player->camera_impact >= 1)
{
if(m_view_bobbing_fall == -1) // Effect took place and has finished
player->camera_impact = m_view_bobbing_fall = 0;
else if(m_view_bobbing_fall == 0) // Initialize effect
m_view_bobbing_fall = 1;
// Convert 0 -> 1 to 0 -> 1 -> 0
fall_bobbing = m_view_bobbing_fall < 0.5 ? m_view_bobbing_fall * 2 : -(m_view_bobbing_fall - 0.5) * 2 + 1;
// Smoothen and invert the above
fall_bobbing = sin(fall_bobbing * 0.5 * M_PI) * -1;
// Amplify according to the intensity of the impact
fall_bobbing *= (1 - rangelim(50 / player->camera_impact, 0, 1)) * 5;
}
// Set head node transformation // Set head node transformation
m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength,0)); m_headnode->setPosition(player->getEyeOffset()+v3f(0,cameratilt*-player->hurt_tilt_strength+fall_bobbing,0));
m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength)); m_headnode->setRotation(v3f(player->getPitch(), 0, cameratilt*player->hurt_tilt_strength));
m_headnode->updateAbsolutePosition(); m_headnode->updateAbsolutePosition();

@ -166,6 +166,8 @@ private:
s32 m_view_bobbing_state; s32 m_view_bobbing_state;
// Speed of view bobbing animation // Speed of view bobbing animation
f32 m_view_bobbing_speed; f32 m_view_bobbing_speed;
// Fall view bobbing
f32 m_view_bobbing_fall;
// Digging animation frame (0 <= m_digging_anim < 1) // Digging animation frame (0 <= m_digging_anim < 1)
f32 m_digging_anim; f32 m_digging_anim;
@ -173,6 +175,9 @@ private:
// If 0, left-click digging animation // If 0, left-click digging animation
// If 1, right-click digging animation // If 1, right-click digging animation
s32 m_digging_button; s32 m_digging_button;
//dummymesh for camera
irr::scene::IAnimatedMesh* m_dummymesh;
}; };
#endif #endif

@ -363,6 +363,15 @@ Client::~Client()
for (std::list<MediaFetchThread*>::iterator i = m_media_fetch_threads.begin(); for (std::list<MediaFetchThread*>::iterator i = m_media_fetch_threads.begin();
i != m_media_fetch_threads.end(); ++i) i != m_media_fetch_threads.end(); ++i)
delete *i; delete *i;
// cleanup 3d model meshes on client shutdown
while (m_device->getSceneManager()->getMeshCache()->getMeshCount() != 0) {
scene::IAnimatedMesh * mesh =
m_device->getSceneManager()->getMeshCache()->getMeshByIndex(0);
if (mesh != NULL)
m_device->getSceneManager()->getMeshCache()->removeMesh(mesh);
}
} }
void Client::connect(Address address) void Client::connect(Address address)
@ -976,16 +985,28 @@ bool Client::loadMedia(const std::string &data, const std::string &filename)
{ {
verbosestream<<"Client: Storing model into Irrlicht: " verbosestream<<"Client: Storing model into Irrlicht: "
<<"\""<<filename<<"\""<<std::endl; <<"\""<<filename<<"\""<<std::endl;
scene::ISceneManager *smgr = m_device->getSceneManager();
//check if mesh was already cached
scene::IAnimatedMesh *mesh =
smgr->getMeshCache()->getMeshByName(filename.c_str());
if (mesh != NULL) {
errorstream << "Multiple models with name: " << filename.c_str() <<
" found replacing previous model!" << std::endl;
smgr->getMeshCache()->removeMesh(mesh);
mesh = 0;
}
io::IFileSystem *irrfs = m_device->getFileSystem(); io::IFileSystem *irrfs = m_device->getFileSystem();
io::IReadFile *rfile = irrfs->createMemoryReadFile( io::IReadFile *rfile = irrfs->createMemoryReadFile(
*data_rw, data_rw.getSize(), filename.c_str()); *data_rw, data_rw.getSize(), filename.c_str());
assert(rfile); assert(rfile);
scene::ISceneManager *smgr = m_device->getSceneManager(); mesh = smgr->getMesh(rfile);
scene::IAnimatedMesh *mesh = smgr->getMesh(rfile);
smgr->getMeshCache()->addMesh(filename.c_str(), mesh); smgr->getMeshCache()->addMesh(filename.c_str(), mesh);
rfile->drop();
return true; return true;
} }
@ -2019,6 +2040,74 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
m_client_event_queue.push_back(event); m_client_event_queue.push_back(event);
} }
else if(command == TOCLIENT_HUDADD)
{
std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
u32 id = readU32(is);
u8 type = readU8(is);
v2f pos = readV2F1000(is);
std::string name = deSerializeString(is);
v2f scale = readV2F1000(is);
std::string text = deSerializeString(is);
u32 number = readU32(is);
u32 item = readU32(is);
u32 dir = readU32(is);
ClientEvent event;
event.type = CE_HUDADD;
event.hudadd.id = id;
event.hudadd.type = type;
event.hudadd.pos = new v2f(pos);
event.hudadd.name = new std::string(name);
event.hudadd.scale = new v2f(scale);
event.hudadd.text = new std::string(text);
event.hudadd.number = number;
event.hudadd.item = item;
event.hudadd.dir = dir;
m_client_event_queue.push_back(event);
}
else if(command == TOCLIENT_HUDRM)
{
std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
u32 id = readU32(is);
ClientEvent event;
event.type = CE_HUDRM;
event.hudrm.id = id;
m_client_event_queue.push_back(event);
}
else if(command == TOCLIENT_HUDCHANGE)
{
std::string sdata;
v2f v2fdata;
u32 intdata = 0;
std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
u32 id = readU32(is);
u8 stat = (HudElementStat)readU8(is);
if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE)
v2fdata = readV2F1000(is);
else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT)
sdata = deSerializeString(is);
else
intdata = readU32(is);
ClientEvent event;
event.type = CE_HUDCHANGE;
event.hudchange.id = id;
event.hudchange.stat = (HudElementStat)stat;
event.hudchange.v2fdata = new v2f(v2fdata);
event.hudchange.sdata = new std::string(sdata);
event.hudchange.data = intdata;
m_client_event_queue.push_back(event);
}
else else
{ {
infostream<<"Client: Ignoring unknown command " infostream<<"Client: Ignoring unknown command "

@ -160,7 +160,10 @@ enum ClientEventType
CE_SHOW_FORMSPEC, CE_SHOW_FORMSPEC,
CE_SPAWN_PARTICLE, CE_SPAWN_PARTICLE,
CE_ADD_PARTICLESPAWNER, CE_ADD_PARTICLESPAWNER,
CE_DELETE_PARTICLESPAWNER CE_DELETE_PARTICLESPAWNER,
CE_HUDADD,
CE_HUDRM,
CE_HUDCHANGE
}; };
struct ClientEvent struct ClientEvent
@ -217,6 +220,27 @@ struct ClientEvent
struct{ struct{
u32 id; u32 id;
} delete_particlespawner; } delete_particlespawner;
struct{
u32 id;
u8 type;
v2f *pos;
std::string *name;
v2f *scale;
std::string *text;
u32 number;
u32 item;
u32 dir;
} hudadd;
struct{
u32 id;
} hudrm;
struct{
u32 id;
HudElementStat stat;
v2f *v2fdata;
std::string *sdata;
u32 data;
} hudchange;
}; };
}; };

@ -90,9 +90,13 @@ SharedBuffer<u8> makePacket_TOCLIENT_TIME_OF_DAY(u16 time, float time_speed);
sound_place added to ItemDefinition sound_place added to ItemDefinition
PROTOCOL_VERSION 19: PROTOCOL_VERSION 19:
GENERIC_CMD_SET_PHYSICS_OVERRIDE GENERIC_CMD_SET_PHYSICS_OVERRIDE
PROTOCOL_VERSION 20:
TOCLIENT_HUD_ADD
TOCLIENT_HUD_RM
TOCLIENT_HUD_CHANGE
*/ */
#define LATEST_PROTOCOL_VERSION 19 #define LATEST_PROTOCOL_VERSION 20
// Server's supported network protocol range // Server's supported network protocol range
#define SERVER_PROTOCOL_VERSION_MIN 13 #define SERVER_PROTOCOL_VERSION_MIN 13
@ -433,6 +437,39 @@ enum ToClientCommand
u16 command u16 command
u32 id u32 id
*/ */
TOCLIENT_HUDADD = 0x49,
/*
u16 command
u32 id
u8 type
v2f1000 pos
u32 len
u8[len] name
v2f1000 scale
u32 len2
u8[len2] text
u32 number
u32 item
u32 dir
*/
TOCLIENT_HUDRM = 0x50,
/*
u16 command
u32 id
*/
TOCLIENT_HUDCHANGE = 0x51,
/*
u16 command
u32 id
u8 stat
[v2f1000 data |
u32 len
u8[len] data |
u32 data]
*/
}; };
enum ToServerCommand enum ToServerCommand

@ -192,7 +192,7 @@ bool wouldCollideWithCeiling(
collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef, collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
f32 pos_max_d, const aabb3f &box_0, f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime, f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f) v3f &pos_f, v3f &speed_f, v3f &accel_f,ActiveObject* self)
{ {
Map *map = &env->getMap(); Map *map = &env->getMap();
//TimeTaker tt("collisionMoveSimple"); //TimeTaker tt("collisionMoveSimple");
@ -300,9 +300,11 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects); c_env->getActiveObjects(pos_f,distance * 1.5,clientobjects);
for (int i=0; i < clientobjects.size(); i++) for (int i=0; i < clientobjects.size(); i++)
{ {
if ((self == 0) || (self != clientobjects[i].obj)) {
objects.push_back((ActiveObject*)clientobjects[i].obj); objects.push_back((ActiveObject*)clientobjects[i].obj);
} }
} }
}
else else
#endif #endif
{ {
@ -314,10 +316,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++) for (std::set<u16>::iterator iter = s_objects.begin(); iter != s_objects.end(); iter++)
{ {
ServerActiveObject *current = s_env->getActiveObject(*iter); ServerActiveObject *current = s_env->getActiveObject(*iter);
if ((self == 0) || (self != current)) {
objects.push_back((ActiveObject*)current); objects.push_back((ActiveObject*)current);
} }
} }
} }
}
for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter) for (std::list<ActiveObject*>::const_iterator iter = objects.begin();iter != objects.end(); ++iter)
{ {
@ -458,8 +462,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
if (is_object[nearest_boxindex]) { if (is_object[nearest_boxindex]) {
info.type = COLLISION_OBJECT; info.type = COLLISION_OBJECT;
} }
else else {
info.type = COLLISION_NODE; info.type = COLLISION_NODE;
}
info.node_p = node_positions[nearest_boxindex]; info.node_p = node_positions[nearest_boxindex];
info.bouncy = bouncy; info.bouncy = bouncy;
info.old_speed = speed_f; info.old_speed = speed_f;

@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class Map; class Map;
class IGameDef; class IGameDef;
class Environment; class Environment;
class ActiveObject;
enum CollisionType enum CollisionType
{ {
@ -70,7 +71,7 @@ struct collisionMoveResult
collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef, collisionMoveResult collisionMoveSimple(Environment *env,IGameDef *gamedef,
f32 pos_max_d, const aabb3f &box_0, f32 pos_max_d, const aabb3f &box_0,
f32 stepheight, f32 dtime, f32 stepheight, f32 dtime,
v3f &pos_f, v3f &speed_f, v3f &accel_f); v3f &pos_f, v3f &speed_f, v3f &accel_f,ActiveObject* self=0);
#if 0 #if 0
// This doesn't seem to work and isn't used // This doesn't seem to work and isn't used

@ -1152,7 +1152,7 @@ public:
v3f p_acceleration = m_acceleration; v3f p_acceleration = m_acceleration;
moveresult = collisionMoveSimple(env,env->getGameDef(), moveresult = collisionMoveSimple(env,env->getGameDef(),
pos_max_d, box, stepheight, dtime, pos_max_d, box, stepheight, dtime,
p_pos, p_velocity, p_acceleration); p_pos, p_velocity, p_acceleration,this);
// Apply results // Apply results
m_position = p_pos; m_position = p_pos;
m_velocity = p_velocity; m_velocity = p_velocity;

@ -502,7 +502,7 @@ void LuaEntitySAO::step(float dtime, bool send_recommended)
v3f p_acceleration = m_acceleration; v3f p_acceleration = m_acceleration;
moveresult = collisionMoveSimple(m_env,m_env->getGameDef(), moveresult = collisionMoveSimple(m_env,m_env->getGameDef(),
pos_max_d, box, stepheight, dtime, pos_max_d, box, stepheight, dtime,
p_pos, p_velocity, p_acceleration); p_pos, p_velocity, p_acceleration,this);
// Apply results // Apply results
m_base_position = p_pos; m_base_position = p_pos;
m_velocity = p_velocity; m_velocity = p_velocity;

@ -96,9 +96,20 @@ EmergeManager::~EmergeManager() {
delete emergethread[i]; delete emergethread[i];
delete mapgen[i]; delete mapgen[i];
} }
emergethread.clear();
mapgen.clear();
for (unsigned int i = 0; i < ores.size(); i++)
delete ores[i];
ores.clear();
for (std::map<std::string, MapgenFactory *>::iterator iter = mglist.begin();
iter != mglist.end(); iter ++) {
delete iter->second;
}
mglist.clear();
delete biomedef; delete biomedef;
delete params;
} }

@ -25,6 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <IGUIStaticText.h> #include <IGUIStaticText.h>
#include <IGUIFont.h> #include <IGUIFont.h>
#include <IMaterialRendererServices.h> #include <IMaterialRendererServices.h>
#include "IMeshCache.h"
#include "client.h" #include "client.h"
#include "server.h" #include "server.h"
#include "guiPauseMenu.h" #include "guiPauseMenu.h"
@ -58,6 +59,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "subgame.h" #include "subgame.h"
#include "quicktune_shortcutter.h" #include "quicktune_shortcutter.h"
#include "clientmap.h" #include "clientmap.h"
#include "hud.h"
#include "sky.h" #include "sky.h"
#include "sound.h" #include "sound.h"
#if USE_SOUND #if USE_SOUND
@ -227,137 +229,6 @@ public:
std::string m_formspec; std::string m_formspec;
FormspecFormSource** m_game_formspec; FormspecFormSource** m_game_formspec;
}; };
/*
Hotbar draw routine
*/
void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
IGameDef *gamedef,
v2s32 centerlowerpos, s32 imgsize, s32 itemcount,
Inventory *inventory, s32 halfheartcount, u16 playeritem)
{
InventoryList *mainlist = inventory->getList("main");
if(mainlist == NULL)
{
errorstream<<"draw_hotbar(): mainlist == NULL"<<std::endl;
return;
}
s32 padding = imgsize/12;
//s32 height = imgsize + padding*2;
s32 width = itemcount*(imgsize+padding*2);
// Position of upper left corner of bar
v2s32 pos = centerlowerpos - v2s32(width/2, imgsize+padding*2);
// Draw background color
/*core::rect<s32> barrect(0,0,width,height);
barrect += pos;
video::SColor bgcolor(255,128,128,128);
driver->draw2DRectangle(bgcolor, barrect, NULL);*/
core::rect<s32> imgrect(0,0,imgsize,imgsize);
for(s32 i=0; i<itemcount; i++)
{
const ItemStack &item = mainlist->getItem(i);
core::rect<s32> rect = imgrect + pos
+ v2s32(padding+i*(imgsize+padding*2), padding);
if(playeritem == i)
{
video::SColor c_outside(255,255,0,0);
//video::SColor c_outside(255,0,0,0);
//video::SColor c_inside(255,192,192,192);
s32 x1 = rect.UpperLeftCorner.X;
s32 y1 = rect.UpperLeftCorner.Y;
s32 x2 = rect.LowerRightCorner.X;
s32 y2 = rect.LowerRightCorner.Y;
// Black base borders
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y1 - padding),
v2s32(x2 + padding, y1)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y2),
v2s32(x2 + padding, y2 + padding)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y1),
v2s32(x1, y2)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x2, y1),
v2s32(x2 + padding, y2)
), NULL);
/*// Light inside borders
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y1 - padding/2),
v2s32(x2 + padding/2, y1)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y2),
v2s32(x2 + padding/2, y2 + padding/2)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y1),
v2s32(x1, y2)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x2, y1),
v2s32(x2 + padding/2, y2)
), NULL);
*/
}
video::SColor bgcolor2(128,0,0,0);
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, font, item, rect, NULL, gamedef);
}
/*
Draw hearts
*/
video::ITexture *heart_texture =
gamedef->getTextureSource()->getTextureRaw("heart.png");
if(heart_texture)
{
v2s32 p = pos + v2s32(0, -20);
for(s32 i=0; i<halfheartcount/2; i++)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
core::rect<s32> rect(0,0,16,16);
rect += p;
driver->draw2DImage(heart_texture, rect,
core::rect<s32>(core::position2d<s32>(0,0),
core::dimension2di(heart_texture->getOriginalSize())),
NULL, colors, true);
p += v2s32(16,0);
}
if(halfheartcount % 2 == 1)
{
const video::SColor color(255,255,255,255);
const video::SColor colors[] = {color,color,color,color};
core::rect<s32> rect(0,0,16/2,16);
rect += p;
core::dimension2di srcd(heart_texture->getOriginalSize());
srcd.Width /= 2;
driver->draw2DImage(heart_texture, rect,
core::rect<s32>(core::position2d<s32>(0,0), srcd),
NULL, colors, true);
p += v2s32(16,0);
}
}
}
/* /*
Check if a node is pointable Check if a node is pointable
@ -943,14 +814,8 @@ void the_game(
// Calculate text height using the font // Calculate text height using the font
u32 text_height = font->getDimension(L"Random test string").Height; u32 text_height = font->getDimension(L"Random test string").Height;
v2u32 screensize(0,0);
v2u32 last_screensize(0,0); v2u32 last_screensize(0,0);
screensize = driver->getScreenSize(); v2u32 screensize = driver->getScreenSize();
const s32 hotbar_itemcount = 8;
//const s32 hotbar_imagesize = 36;
//const s32 hotbar_imagesize = 64;
s32 hotbar_imagesize = 48;
/* /*
Draw "Loading" screen Draw "Loading" screen
@ -992,6 +857,9 @@ void the_game(
sound_is_dummy = true; sound_is_dummy = true;
} }
Server *server = NULL;
try{
// Event manager // Event manager
EventManager eventmgr; EventManager eventmgr;
@ -1007,9 +875,8 @@ void the_game(
/* /*
Create server. Create server.
SharedPtr will delete it when it goes out of scope.
*/ */
SharedPtr<Server> server;
if(address == ""){ if(address == ""){
draw_load_screen(L"Creating server...", driver, font); draw_load_screen(L"Creating server...", driver, font);
infostream<<"Creating server"<<std::endl; infostream<<"Creating server"<<std::endl;
@ -1018,7 +885,6 @@ void the_game(
server->start(port); server->start(port);
} }
try{
do{ // Client scope (breakable do-while(0)) do{ // Client scope (breakable do-while(0))
/* /*
@ -1374,6 +1240,12 @@ void the_game(
player->hurt_tilt_timer = 0; player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0; player->hurt_tilt_strength = 0;
/*
HUD object
*/
Hud hud(driver, guienv, font, text_height,
gamedef, player, &local_inventory);
for(;;) for(;;)
{ {
if(device->run() == false || kill == true) if(device->run() == false || kill == true)
@ -1546,13 +1418,11 @@ void the_game(
v2s32 displaycenter(screensize.X/2,screensize.Y/2); v2s32 displaycenter(screensize.X/2,screensize.Y/2);
//bool screensize_changed = screensize != last_screensize; //bool screensize_changed = screensize != last_screensize;
// Resize hotbar
if(screensize.Y <= 800) // Update HUD values
hotbar_imagesize = 32; hud.screensize = screensize;
else if(screensize.Y <= 1280) hud.displaycenter = displaycenter;
hotbar_imagesize = 48; hud.resizeHotbar();
else
hotbar_imagesize = 64;
// Hilight boxes collected during the loop and displayed // Hilight boxes collected during the loop and displayed
std::vector<aabb3f> hilightboxes; std::vector<aabb3f> hilightboxes;
@ -1916,7 +1786,7 @@ void the_game(
{ {
s32 wheel = input->getMouseWheel(); s32 wheel = input->getMouseWheel();
u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE-1, u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE-1,
hotbar_itemcount-1); hud.hotbar_itemcount-1);
if(wheel < 0) if(wheel < 0)
{ {
@ -1940,7 +1810,7 @@ void the_game(
const KeyPress *kp = NumberKey + (i + 1) % 10; const KeyPress *kp = NumberKey + (i + 1) % 10;
if(input->wasKeyDown(*kp)) if(input->wasKeyDown(*kp))
{ {
if(i < PLAYER_INVENTORY_SIZE && i < hotbar_itemcount) if(i < PLAYER_INVENTORY_SIZE && i < hud.hotbar_itemcount)
{ {
new_playeritem = i; new_playeritem = i;
@ -2227,6 +2097,83 @@ void the_game(
{ {
delete_particlespawner (event.delete_particlespawner.id); delete_particlespawner (event.delete_particlespawner.id);
} }
else if (event.type == CE_HUDADD)
{
u32 id = event.hudadd.id;
size_t nhudelem = player->hud.size();
if (id > nhudelem || (id < nhudelem && player->hud[id])) {
delete event.hudadd.pos;
delete event.hudadd.name;
delete event.hudadd.scale;
delete event.hudadd.text;
continue;
}
HudElement *e = new HudElement;
e->type = (HudElementType)event.hudadd.type;
e->pos = *event.hudadd.pos;
e->name = *event.hudadd.name;
e->scale = *event.hudadd.scale;
e->text = *event.hudadd.text;
e->number = event.hudadd.number;
e->item = event.hudadd.item;
e->dir = event.hudadd.dir;
if (id == nhudelem)
player->hud.push_back(e);
else
player->hud[id] = e;
delete event.hudadd.pos;
delete event.hudadd.name;
delete event.hudadd.scale;
delete event.hudadd.text;
}
else if (event.type == CE_HUDRM)
{
u32 id = event.hudrm.id;
if (id < player->hud.size() && player->hud[id]) {
delete player->hud[id];
player->hud[id] = NULL;
}
}
else if (event.type == CE_HUDCHANGE)
{
u32 id = event.hudchange.id;
if (id >= player->hud.size() || !player->hud[id]) {
delete event.hudchange.v2fdata;
delete event.hudchange.sdata;
continue;
}
HudElement* e = player->hud[id];
switch (event.hudchange.stat) {
case HUD_STAT_POS:
e->pos = *event.hudchange.v2fdata;
break;
case HUD_STAT_NAME:
e->name = *event.hudchange.sdata;
break;
case HUD_STAT_SCALE:
e->scale = *event.hudchange.v2fdata;
break;
case HUD_STAT_TEXT:
e->text = *event.hudchange.sdata;
break;
case HUD_STAT_NUMBER:
e->number = event.hudchange.data;
break;
case HUD_STAT_ITEM:
e->item = event.hudchange.data;
break;
case HUD_STAT_DIR:
e->dir = event.hudchange.data;
break;
}
delete event.hudchange.v2fdata;
delete event.hudchange.sdata;
}
} }
} }
@ -3004,7 +2951,6 @@ void the_game(
TimeTaker tt_draw("mainloop: draw"); TimeTaker tt_draw("mainloop: draw");
{ {
TimeTaker timer("beginScene"); TimeTaker timer("beginScene");
//driver->beginScene(false, true, bgcolor); //driver->beginScene(false, true, bgcolor);
@ -3108,25 +3054,7 @@ void the_game(
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
if (show_hud) if (show_hud)
{ hud.drawSelectionBoxes(hilightboxes);
v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
u32 selectionbox_color_r = rangelim(myround(selectionbox_color.X), 0, 255);
u32 selectionbox_color_g = rangelim(myround(selectionbox_color.Y), 0, 255);
u32 selectionbox_color_b = rangelim(myround(selectionbox_color.Z), 0, 255);
for(std::vector<aabb3f>::const_iterator
i = hilightboxes.begin();
i != hilightboxes.end(); i++)
{
/*infostream<<"hilightbox min="
<<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
<<" max="
<<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
<<std::endl;*/
driver->draw3DBox(*i, video::SColor(255,selectionbox_color_r,selectionbox_color_g,selectionbox_color_b));
}
}
/* /*
Wielded tool Wielded tool
*/ */
@ -3155,20 +3083,7 @@ void the_game(
Draw crosshair Draw crosshair
*/ */
if (show_hud) if (show_hud)
{ hud.drawCrosshair();
v3f crosshair_color = g_settings->getV3F("crosshair_color");
u32 crosshair_color_r = rangelim(myround(crosshair_color.X), 0, 255);
u32 crosshair_color_g = rangelim(myround(crosshair_color.Y), 0, 255);
u32 crosshair_color_b = rangelim(myround(crosshair_color.Z), 0, 255);
u32 crosshair_alpha = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
displaycenter + core::vector2d<s32>(10,0),
video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
displaycenter + core::vector2d<s32>(0,10),
video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
}
} // timer } // timer
@ -3181,9 +3096,7 @@ void the_game(
*/ */
if (show_hud) if (show_hud)
{ {
draw_hotbar(driver, font, gamedef, hud.drawHotbar(v2s32(displaycenter.X, screensize.Y),
v2s32(displaycenter.X, screensize.Y),
hotbar_imagesize, hotbar_itemcount, &local_inventory,
client.getHP(), client.getPlayerItem()); client.getHP(), client.getPlayerItem());
} }
@ -3210,6 +3123,12 @@ void the_game(
player->hurt_tilt_strength = 0; player->hurt_tilt_strength = 0;
} }
/*
Draw lua hud items
*/
if (show_hud)
hud.drawLuaElements();
/* /*
Draw gui Draw gui
*/ */
@ -3290,14 +3209,44 @@ void the_game(
L" running a different version of Minetest."; L" running a different version of Minetest.";
errorstream<<wide_to_narrow(error_message)<<std::endl; errorstream<<wide_to_narrow(error_message)<<std::endl;
} }
catch(ServerError &e)
{
error_message = narrow_to_wide(e.what());
errorstream<<wide_to_narrow(error_message)<<std::endl;
}
catch(ModError &e)
{
errorstream<<e.what()<<std::endl;
error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details.");
}
if(!sound_is_dummy) if(!sound_is_dummy)
delete sound; delete sound;
//has to be deleted first to stop all server threads
delete server;
delete tsrc; delete tsrc;
delete shsrc; delete shsrc;
delete nodedef; delete nodedef;
delete itemdef; delete itemdef;
//extended resource accounting
infostream << "Irrlicht resources after cleanup:" << std::endl;
infostream << "\tRemaining meshes : "
<< device->getSceneManager()->getMeshCache()->getMeshCount() << std::endl;
infostream << "\tRemaining textures : "
<< driver->getTextureCount() << std::endl;
for (unsigned int i = 0; i < driver->getTextureCount(); i++ ) {
irr::video::ITexture* texture = driver->getTextureByIndex(i);
infostream << "\t\t" << i << ":" << texture->getName().getPath().c_str()
<< std::endl;
}
infostream << "\tRemaining materials: "
<< driver-> getMaterialRendererCount ()
<< " (note: irrlicht doesn't support removing renderers)"<< std::endl;
} }

@ -120,11 +120,12 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
} }
if(!m_new_mod_names.empty()) if(!m_new_mod_names.empty())
{ {
wchar_t* text = wgettext("Warning: Some mods are not configured yet.\n"
"They will be enabled by default when you save the configuration. ");
GUIMessageMenu *menu = GUIMessageMenu *menu =
new GUIMessageMenu(Environment, Parent, -1, m_menumgr, new GUIMessageMenu(Environment, Parent, -1, m_menumgr, text);
wgettext("Warning: Some mods are not configured yet.\n"
"They will be enabled by default when you save the configuration. "));
menu->drop(); menu->drop();
delete[] text;
} }
@ -139,10 +140,11 @@ GUIConfigureWorld::GUIConfigureWorld(gui::IGUIEnvironment* env,
} }
if(!missing_mods.empty()) if(!missing_mods.empty())
{ {
wchar_t* text = wgettext("Warning: Some configured mods are missing.\n"
"Their setting will be removed when you save the configuration. ");
GUIMessageMenu *menu = GUIMessageMenu *menu =
new GUIMessageMenu(Environment, Parent, -1, m_menumgr, new GUIMessageMenu(Environment, Parent, -1, m_menumgr, text);
wgettext("Warning: Some configured mods are missing.\n" delete[] text;
"Their setting will be removed when you save the configuration. "));
for(std::set<std::string>::iterator it = missing_mods.begin(); for(std::set<std::string>::iterator it = missing_mods.begin();
it != missing_mods.end(); ++it) it != missing_mods.end(); ++it)
m_settings.remove("load_mod_"+(*it)); m_settings.remove("load_mod_"+(*it));
@ -203,30 +205,36 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 200, 20); core::rect<s32> rect(0, 0, 200, 20);
rect += v2s32(0, 25) + topleft; rect += v2s32(0, 25) + topleft;
wchar_t* text = wgettext("enabled");
m_enabled_checkbox = m_enabled_checkbox =
Environment->addCheckBox(false, rect, this, GUI_ID_ENABLED_CHECKBOX, Environment->addCheckBox(false, rect, this, GUI_ID_ENABLED_CHECKBOX,
wgettext("enabled")); text);
delete[] text;
m_enabled_checkbox->setVisible(false); m_enabled_checkbox->setVisible(false);
} }
{ {
core::rect<s32> rect(0, 0, 85, 30); core::rect<s32> rect(0, 0, 85, 30);
rect = rect + v2s32(0, 25) + topleft; rect = rect + v2s32(0, 25) + topleft;
wchar_t* text = wgettext("Enable All");
m_enableall = Environment->addButton(rect, this, GUI_ID_ENABLEALL, m_enableall = Environment->addButton(rect, this, GUI_ID_ENABLEALL,
wgettext("Enable All")); text);
delete[] text;
m_enableall->setVisible(false); m_enableall->setVisible(false);
} }
{ {
core::rect<s32> rect(0, 0, 85, 30); core::rect<s32> rect(0, 0, 85, 30);
rect = rect + v2s32(115, 25) + topleft; rect = rect + v2s32(115, 25) + topleft;
m_disableall = Environment->addButton(rect, this, GUI_ID_DISABLEALL, wchar_t* text = wgettext("Disable All");
wgettext("Disable All")); m_disableall = Environment->addButton(rect, this, GUI_ID_DISABLEALL, text );
delete[] text;
m_disableall->setVisible(false); m_disableall->setVisible(false);
} }
{ {
core::rect<s32> rect(0, 0, 200, 20); core::rect<s32> rect(0, 0, 200, 20);
rect += v2s32(0, 60) + topleft; rect += v2s32(0, 60) + topleft;
Environment->addStaticText(wgettext("depends on:"), wchar_t* text = wgettext("depends on:");
rect, false, false, this, -1); Environment->addStaticText(text, rect, false, false, this, -1);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 200, 85); core::rect<s32> rect(0, 0, 200, 85);
@ -237,8 +245,9 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 200, 20); core::rect<s32> rect(0, 0, 200, 20);
rect += v2s32(0, 175) + topleft; rect += v2s32(0, 175) + topleft;
Environment->addStaticText(wgettext("is required by:"), wchar_t* text = wgettext("is required by:");
rect, false, false, this, -1); Environment->addStaticText( text, rect, false, false, this, -1);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 200, 85); core::rect<s32> rect(0, 0, 200, 85);
@ -258,14 +267,16 @@ void GUIConfigureWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect = rect + v2s32(330, 270) - topleft; rect = rect + v2s32(330, 270) - topleft;
Environment->addButton(rect, this, GUI_ID_CANCEL, wchar_t* text = wgettext("Cancel");
wgettext("Cancel")); Environment->addButton(rect, this, GUI_ID_CANCEL, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect = rect + v2s32(460, 270) - topleft; rect = rect + v2s32(460, 270) - topleft;
Environment->addButton(rect, this, GUI_ID_SAVE, wchar_t* text = wgettext("Save");
wgettext("Save")); Environment->addButton(rect, this, GUI_ID_SAVE, text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
@ -389,17 +400,21 @@ bool GUIConfigureWorld::OnEvent(const SEvent& event)
// bug in the text-size calculation. if the trailing // bug in the text-size calculation. if the trailing
// spaces are removed from the message text, the // spaces are removed from the message text, the
// message gets wrapped and parts of it are cut off: // message gets wrapped and parts of it are cut off:
wchar_t* text = wgettext("Configuration saved. ");
GUIMessageMenu *menu = GUIMessageMenu *menu =
new GUIMessageMenu(Environment, Parent, -1, m_menumgr, new GUIMessageMenu(Environment, Parent, -1, m_menumgr,
wgettext("Configuration saved. ")); text );
delete[] text;
menu->drop(); menu->drop();
ModConfiguration modconf(m_wspec.path); ModConfiguration modconf(m_wspec.path);
if(!modconf.isConsistent()) if(!modconf.isConsistent())
{ {
wchar_t* text = wgettext("Warning: Configuration not consistent. ");
GUIMessageMenu *menu = GUIMessageMenu *menu =
new GUIMessageMenu(Environment, Parent, -1, m_menumgr, new GUIMessageMenu(Environment, Parent, -1, m_menumgr,
wgettext("Warning: Configuration not consistent. ")); text );
delete[] text;
menu->drop(); menu->drop();
} }

@ -116,14 +116,18 @@ void GUIConfirmMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, bw, 30); core::rect<s32> rect(0, 0, bw, 30);
rect = rect + v2s32(size.X/2-bw/2-(bw/2+5), size.Y/2-30/2+5 + msg_h/2); rect = rect + v2s32(size.X/2-bw/2-(bw/2+5), size.Y/2-30/2+5 + msg_h/2);
wchar_t* text = wgettext("Yes");
Environment->addButton(rect, this, GUI_ID_YES, Environment->addButton(rect, this, GUI_ID_YES,
wgettext("Yes")); text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, bw, 30); core::rect<s32> rect(0, 0, bw, 30);
rect = rect + v2s32(size.X/2-bw/2+(bw/2+5), size.Y/2-30/2+5 + msg_h/2); rect = rect + v2s32(size.X/2-bw/2+(bw/2+5), size.Y/2-30/2+5 + msg_h/2);
wchar_t* text = wgettext("No");
Environment->addButton(rect, this, GUI_ID_NO, Environment->addButton(rect, this, GUI_ID_NO,
wgettext("No")); text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }

@ -113,8 +113,9 @@ void GUICreateWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 100, 20); core::rect<s32> rect(0, 0, 100, 20);
rect += v2s32(0, 5) + topleft; rect += v2s32(0, 5) + topleft;
Environment->addStaticText(wgettext("World name"), wchar_t* text = wgettext("World name");
rect, false, true, this, -1); Environment->addStaticText(text, rect, false, true, this, -1);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 300, 30); core::rect<s32> rect(0, 0, 300, 30);
@ -132,8 +133,9 @@ void GUICreateWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 100, 20); core::rect<s32> rect(0, 0, 100, 20);
rect += v2s32(0, 40+5) + topleft; rect += v2s32(0, 40+5) + topleft;
Environment->addStaticText(wgettext("Game"), wchar_t* text = wgettext("Game");
rect, false, true, this, -1); Environment->addStaticText(text, rect, false, true, this, -1);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 300, 80); core::rect<s32> rect(0, 0, 300, 80);
@ -155,14 +157,18 @@ void GUICreateWorld::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect = rect + v2s32(170, 140) + topleft; rect = rect + v2s32(170, 140) + topleft;
wchar_t* text = wgettext("Create");
Environment->addButton(rect, this, GUI_ID_CREATE, Environment->addButton(rect, this, GUI_ID_CREATE,
wgettext("Create")); text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect = rect + v2s32(300, 140) + topleft; rect = rect + v2s32(300, 140) + topleft;
wchar_t* text = wgettext("Cancel");
Environment->addButton(rect, this, GUI_ID_CANCEL, Environment->addButton(rect, this, GUI_ID_CANCEL,
wgettext("Cancel")); text);
delete [] text;
} }
changeCtype("C"); changeCtype("C");
} }

@ -93,15 +93,19 @@ void GUIDeathScreen::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 400, 50); core::rect<s32> rect(0, 0, 400, 50);
rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25); rect = rect + v2s32(size.X/2-400/2, size.Y/2-50/2-25);
Environment->addStaticText(wgettext("You died."), rect, false, wchar_t* text = wgettext("You died.");
Environment->addStaticText(text, rect, false,
true, this, 256); true, this, 256);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 140, 30); core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25); rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
wchar_t* text = wgettext("Respawn");
gui::IGUIElement *e = gui::IGUIElement *e =
Environment->addButton(rect, this, 257, Environment->addButton(rect, this, 257,
wgettext("Respawn")); text);
delete[] text;
Environment->setFocus(e); Environment->setFocus(e);
} }
changeCtype("C"); changeCtype("C");

@ -581,6 +581,7 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
size.Y-rect.getHeight()-5); size.Y-rect.getHeight()-5);
const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item"); const wchar_t *text = wgettext("Left click: Move all items, Right click: Move single item");
Environment->addStaticText(text, rect, false, true, this, 256); Environment->addStaticText(text, rect, false, true, this, 256);
delete[] text;
changeCtype("C"); changeCtype("C");
} }
// If there's fields, add a Proceed button // If there's fields, add a Proceed button
@ -604,7 +605,9 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
v2s32 size = DesiredRect.getSize(); v2s32 size = DesiredRect.getSize();
rect = core::rect<s32>(size.X/2-70, pos.Y, (size.X/2-70)+140, pos.Y+30); rect = core::rect<s32>(size.X/2-70, pos.Y, (size.X/2-70)+140, pos.Y+30);
Environment->addButton(rect, this, 257, wgettext("Proceed")); wchar_t* text = wgettext("Proceed");
Environment->addButton(rect, this, 257, text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }

@ -75,6 +75,13 @@ GUIModalMenu(env, parent, id, menumgr)
GUIKeyChangeMenu::~GUIKeyChangeMenu() GUIKeyChangeMenu::~GUIKeyChangeMenu()
{ {
removeChildren(); removeChildren();
for (std::vector<key_setting*>::iterator iter = key_settings.begin();
iter != key_settings.end(); iter ++) {
delete[] (*iter)->button_name;
delete (*iter);
}
key_settings.clear();
} }
void GUIKeyChangeMenu::removeChildren() void GUIKeyChangeMenu::removeChildren()
@ -111,8 +118,10 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
core::rect < s32 > rect(0, 0, 600, 40); core::rect < s32 > rect(0, 0, 600, 40);
rect += topleft + v2s32(25, 3); rect += topleft + v2s32(25, 3);
//gui::IGUIStaticText *t = //gui::IGUIStaticText *t =
Environment->addStaticText(wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)"), wchar_t* text = wgettext("Keybindings. (If this menu screws up, remove stuff from minetest.conf)");
Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete[] text;
//t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT); //t->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
} }
@ -132,7 +141,9 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{ {
core::rect < s32 > rect(0, 0, 100, 30); core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(offset.X + 105, offset.Y - 5); rect += topleft + v2s32(offset.X + 105, offset.Y - 5);
k->button = Environment->addButton(rect, this, k->id, wgettext(k->key.name())); wchar_t* text = wgettext(k->key.name());
k->button = Environment->addButton(rect, this, k->id, text );
delete[] text;
} }
if(i + 1 == KMaxButtonPerColumns) if(i + 1 == KMaxButtonPerColumns)
offset = v2s32(250, 60); offset = v2s32(250, 60);
@ -147,8 +158,10 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += topleft + v2s32(option_x, option_y); rect += topleft + v2s32(option_x, option_y);
wchar_t* text = wgettext("\"Use\" = climb down");
Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this, Environment->addCheckBox(g_settings->getBool("aux1_descends"), rect, this,
GUI_ID_CB_AUX1_DESCENDS, wgettext("\"Use\" = climb down")); GUI_ID_CB_AUX1_DESCENDS, text);
delete[] text;
} }
offset += v2s32(0, 25); offset += v2s32(0, 25);
} }
@ -160,8 +173,10 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += topleft + v2s32(option_x, option_y); rect += topleft + v2s32(option_x, option_y);
wchar_t* text = wgettext("Double tap \"jump\" to toggle fly");
Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this, Environment->addCheckBox(g_settings->getBool("doubletap_jump"), rect, this,
GUI_ID_CB_DOUBLETAP_JUMP, wgettext("Double tap \"jump\" to toggle fly")); GUI_ID_CB_DOUBLETAP_JUMP, text);
delete[] text;
} }
offset += v2s32(0, 25); offset += v2s32(0, 25);
} }
@ -169,14 +184,18 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
{ {
core::rect < s32 > rect(0, 0, 100, 30); core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40); rect += topleft + v2s32(size.X - 100 - 20, size.Y - 40);
wchar_t* text = wgettext("Save");
Environment->addButton(rect, this, GUI_ID_BACK_BUTTON, Environment->addButton(rect, this, GUI_ID_BACK_BUTTON,
wgettext("Save")); text);
delete[] text;
} }
{ {
core::rect < s32 > rect(0, 0, 100, 30); core::rect < s32 > rect(0, 0, 100, 30);
rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40); rect += topleft + v2s32(size.X - 100 - 20 - 100 - 20, size.Y - 40);
wchar_t* text = wgettext("Cancel");
Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON, Environment->addButton(rect, this, GUI_ID_ABORT_BUTTON,
wgettext("Cancel")); text );
delete[] text;
} }
changeCtype("C"); changeCtype("C");
@ -230,7 +249,9 @@ bool GUIKeyChangeMenu::resetMenu()
key_setting *k = key_settings.at(i); key_setting *k = key_settings.at(i);
if(k->id == activeKey) if(k->id == activeKey)
{ {
k->button->setText(wgettext(k->key.name())); wchar_t* text = wgettext(k->key.name());
k->button->setText(text);
delete[] text;
break; break;
} }
} }
@ -266,8 +287,10 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
{ {
core::rect < s32 > rect(0, 0, 600, 40); core::rect < s32 > rect(0, 0, 600, 40);
rect += v2s32(0, 0) + v2s32(25, 30); rect += v2s32(0, 0) + v2s32(25, 30);
this->key_used_text = Environment->addStaticText(wgettext("Key already in use"), wchar_t* text = wgettext("Key already in use");
this->key_used_text = Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete[] text;
//infostream << "Key already in use" << std::endl; //infostream << "Key already in use" << std::endl;
} }
@ -284,7 +307,9 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
} }
assert(k); assert(k);
k->key = kp; k->key = kp;
k->button->setText(wgettext(k->key.name())); wchar_t* text = wgettext(k->key.name());
k->button->setText(text);
delete[] text;
this->key_used.push_back(kp); this->key_used.push_back(kp);
@ -344,7 +369,9 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
resetMenu(); resetMenu();
shift_down = false; shift_down = false;
activeKey = event.GUIEvent.Caller->getID(); activeKey = event.GUIEvent.Caller->getID();
k->button->setText(wgettext("press key")); wchar_t* text = wgettext("press key");
k->button->setText(text);
delete[] text;
this->key_used.erase(std::remove(this->key_used.begin(), this->key_used.erase(std::remove(this->key_used.begin(),
this->key_used.end(), k->key), this->key_used.end()); this->key_used.end(), k->key), this->key_used.end());
break; break;
@ -357,11 +384,12 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
return Parent ? Parent->OnEvent(event) : false; return Parent ? Parent->OnEvent(event) : false;
} }
void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string setting_name) void GUIKeyChangeMenu::add_key(int id, wchar_t* button_name, std::string setting_name)
{ {
key_setting *k = new key_setting; key_setting *k = new key_setting;
k->id = id; k->id = id;
k->button_name = wgettext(button_name.c_str());
k->button_name = button_name;
k->setting_name = setting_name; k->setting_name = setting_name;
k->key = getKeySetting(k->setting_name.c_str()); k->key = getKeySetting(k->setting_name.c_str());
key_settings.push_back(k); key_settings.push_back(k);
@ -369,21 +397,21 @@ void GUIKeyChangeMenu::add_key(int id, std::string button_name, std::string sett
void GUIKeyChangeMenu::init_keys() void GUIKeyChangeMenu::init_keys()
{ {
this->add_key(GUI_ID_KEY_FORWARD_BUTTON, gettext("Forward"), "keymap_forward"); this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, gettext("Backward"), "keymap_backward"); this->add_key(GUI_ID_KEY_BACKWARD_BUTTON, wgettext("Backward"), "keymap_backward");
this->add_key(GUI_ID_KEY_LEFT_BUTTON, gettext("Left"), "keymap_left"); this->add_key(GUI_ID_KEY_LEFT_BUTTON, wgettext("Left"), "keymap_left");
this->add_key(GUI_ID_KEY_RIGHT_BUTTON, gettext("Right"), "keymap_right"); this->add_key(GUI_ID_KEY_RIGHT_BUTTON, wgettext("Right"), "keymap_right");
this->add_key(GUI_ID_KEY_USE_BUTTON, gettext("Use"), "keymap_special1"); this->add_key(GUI_ID_KEY_USE_BUTTON, wgettext("Use"), "keymap_special1");
this->add_key(GUI_ID_KEY_JUMP_BUTTON, gettext("Jump"), "keymap_jump"); this->add_key(GUI_ID_KEY_JUMP_BUTTON, wgettext("Jump"), "keymap_jump");
this->add_key(GUI_ID_KEY_SNEAK_BUTTON, gettext("Sneak"), "keymap_sneak"); this->add_key(GUI_ID_KEY_SNEAK_BUTTON, wgettext("Sneak"), "keymap_sneak");
this->add_key(GUI_ID_KEY_DROP_BUTTON, gettext("Drop"), "keymap_drop"); this->add_key(GUI_ID_KEY_DROP_BUTTON, wgettext("Drop"), "keymap_drop");
this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, gettext("Inventory"), "keymap_inventory"); this->add_key(GUI_ID_KEY_INVENTORY_BUTTON, wgettext("Inventory"), "keymap_inventory");
this->add_key(GUI_ID_KEY_CHAT_BUTTON, gettext("Chat"), "keymap_chat"); this->add_key(GUI_ID_KEY_CHAT_BUTTON, wgettext("Chat"), "keymap_chat");
this->add_key(GUI_ID_KEY_CMD_BUTTON, gettext("Command"), "keymap_cmd"); this->add_key(GUI_ID_KEY_CMD_BUTTON, wgettext("Command"), "keymap_cmd");
this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, gettext("Console"), "keymap_console"); this->add_key(GUI_ID_KEY_CONSOLE_BUTTON, wgettext("Console"), "keymap_console");
this->add_key(GUI_ID_KEY_FLY_BUTTON, gettext("Toggle fly"), "keymap_freemove"); this->add_key(GUI_ID_KEY_FLY_BUTTON, wgettext("Toggle fly"), "keymap_freemove");
this->add_key(GUI_ID_KEY_FAST_BUTTON, gettext("Toggle fast"), "keymap_fastmove"); this->add_key(GUI_ID_KEY_FAST_BUTTON, wgettext("Toggle fast"), "keymap_fastmove");
this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, gettext("Toggle noclip"), "keymap_noclip"); this->add_key(GUI_ID_KEY_NOCLIP_BUTTON, wgettext("Toggle noclip"), "keymap_noclip");
this->add_key(GUI_ID_KEY_RANGE_BUTTON, gettext("Range select"), "keymap_rangeselect"); this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
this->add_key(GUI_ID_KEY_DUMP_BUTTON, gettext("Print stacks"), "keymap_print_debug_stacks"); this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");
} }

@ -64,7 +64,7 @@ private:
bool resetMenu(); bool resetMenu();
void add_key(int id, std::string setting_name, std::string button_name); void add_key(int id, wchar_t* button_name, std::string setting_name);
bool shift_down; bool shift_down;

@ -89,7 +89,9 @@ struct CreateWorldDestMainMenu : public CreateWorldDest
std::string name_narrow = wide_to_narrow(name); std::string name_narrow = wide_to_narrow(name);
if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS)) if(!string_allowed_blacklist(name_narrow, WORLDNAME_BLACKLISTED_CHARS))
{ {
m_menu->displayMessageMenu(wgettext("Cannot create world: Name contains invalid characters")); wchar_t* text = wgettext("Cannot create world: Name contains invalid characters");
m_menu->displayMessageMenu(text);
delete[] text;
return; return;
} }
std::vector<WorldSpec> worlds = getAvailableWorlds(); std::vector<WorldSpec> worlds = getAvailableWorlds();
@ -98,7 +100,9 @@ struct CreateWorldDestMainMenu : public CreateWorldDest
{ {
if((*i).name == name_narrow) if((*i).name == name_narrow)
{ {
m_menu->displayMessageMenu(wgettext("Cannot create world: A world by this name already exists")); wchar_t* text = wgettext("Cannot create world: A world by this name already exists");
m_menu->displayMessageMenu(text);
delete[] text;
return; return;
} }
} }
@ -280,12 +284,24 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
rect += m_topleft_client + v2s32(0, -30); rect += m_topleft_client + v2s32(0, -30);
gui::IGUITabControl *e = Environment->addTabControl( gui::IGUITabControl *e = Environment->addTabControl(
rect, this, true, true, GUI_ID_TAB_CONTROL); rect, this, true, true, GUI_ID_TAB_CONTROL);
e->addTab(wgettext("Singleplayer")); wchar_t* text = wgettext("Singleplayer");
e->addTab(wgettext("Multiplayer")); e->addTab(text);
e->addTab(wgettext("Advanced")); delete[] text;
e->addTab(wgettext("Settings")); text = wgettext("Multiplayer");
e->addTab(wgettext("Credits")); e->addTab(text);
delete[] text;
text = wgettext("Advanced");
e->addTab(text);
delete[] text;
text = wgettext("Settings");
e->addTab(text);
delete[] text;
text = wgettext("Credits");
e->addTab(text);
delete[] text;
e->setActiveTab(m_data->selected_tab); e->setActiveTab(m_data->selected_tab);
} }
if(m_data->selected_tab == TAB_SINGLEPLAYER) if(m_data->selected_tab == TAB_SINGLEPLAYER)
@ -313,9 +329,11 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, world_sel_w-4, 20); core::rect<s32> rect(0, 0, world_sel_w-4, 20);
rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20); rect += m_topleft_client + v2s32(world_sel_x+4, world_sel_y-20);
wchar_t* text = wgettext("Select World:");
/*gui::IGUIStaticText *e =*/ Environment->addStaticText( /*gui::IGUIStaticText *e =*/ Environment->addStaticText(
wgettext("Select World:"), text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete[] text;
/*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/ /*e->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER);*/
} }
{ {
@ -335,23 +353,29 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, world_button_w, 30); core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0); rect += m_topleft_client + v2s32(world_sel_x, world_sel_y+world_sel_h+0);
wchar_t* text = wgettext("Delete");
Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON, Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
wgettext("Delete")); text);
delete[] text;
} }
// Create world button // Create world button
{ {
core::rect<s32> rect(0, 0, world_button_w, 30); core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0); rect += m_topleft_client + v2s32(world_sel_x+world_button_w+bs, world_sel_y+world_sel_h+0);
wchar_t* text = wgettext("New");
Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON, Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
wgettext("New")); text);
delete[] text;
} }
// Configure world button // Configure world button
{ {
core::rect<s32> rect(0, 0, world_button_w, 30); core::rect<s32> rect(0, 0, world_button_w, 30);
rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2, rect += m_topleft_client + v2s32(world_sel_x+(world_button_w+bs)*2,
world_sel_y+world_sel_h+0); world_sel_y+world_sel_h+0);
wchar_t* text = wgettext("Configure");
Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON, Environment->addButton(rect, this, GUI_ID_CONFIGURE_WORLD_BUTTON,
wgettext("Configure")); text);
delete[] text;
} }
// Start game button // Start game button
{ {
@ -365,8 +389,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, bw, 30); core::rect<s32> rect(0, 0, bw, 30);
rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw, rect += m_topleft_client + v2s32(world_sel_x+world_sel_w-bw,
world_sel_y+world_sel_h+30+bs); world_sel_y+world_sel_h+30+bs);
wchar_t* text = wgettext("Play");
Environment->addButton(rect, this, Environment->addButton(rect, this,
GUI_ID_JOIN_GAME_BUTTON, wgettext("Play")); GUI_ID_JOIN_GAME_BUTTON, text);
delete[] text;
} }
// Options // Options
s32 option_x = 50; s32 option_x = 50;
@ -376,14 +402,18 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*0); rect += m_topleft_client + v2s32(option_x, option_y+20*0);
wchar_t* text = wgettext("Creative Mode");
Environment->addCheckBox(m_data->creative_mode, rect, this, Environment->addCheckBox(m_data->creative_mode, rect, this,
GUI_ID_CREATIVE_CB, wgettext("Creative Mode")); GUI_ID_CREATIVE_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*1); rect += m_topleft_client + v2s32(option_x, option_y+20*1);
wchar_t* text = wgettext("Enable Damage");
Environment->addCheckBox(m_data->enable_damage, rect, this, Environment->addCheckBox(m_data->enable_damage, rect, this,
GUI_ID_DAMAGE_CB, wgettext("Enable Damage")); GUI_ID_DAMAGE_CB, text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }
@ -402,9 +432,11 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
// Nickname + password // Nickname + password
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
wchar_t* text = wgettext("Name/Password");
rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6); rect += m_topleft_client + v2s32(m_size_client.X-60-100, 10+6);
Environment->addStaticText(wgettext("Name/Password"), Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete [] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -467,8 +499,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6); rect += m_topleft_client + v2s32(50, m_size_client.Y-50-15+6);
Environment->addStaticText(wgettext("Address/Port"), wchar_t* text = wgettext("Address/Port");
Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete [] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -493,13 +527,17 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
core::rect<s32> rect(0, 0, 260, 30); core::rect<s32> rect(0, 0, 260, 30);
rect += m_topleft_client + v2s32(50, rect += m_topleft_client + v2s32(50,
180); 180);
wchar_t* text = wgettext("Show Public");
gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE, gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_TOGGLE,
wgettext("Show Public")); text);
delete[] text;
e->setIsPushButton(true); e->setIsPushButton(true);
if (m_data->selected_serverlist == SERVERLIST_PUBLIC) if (m_data->selected_serverlist == SERVERLIST_PUBLIC)
{ {
e->setText(wgettext("Show Favorites")); wchar_t* text = wgettext("Show Favorites");
e->setText(text);
e->setPressed(); e->setPressed();
delete[] text;
} }
} }
#endif #endif
@ -507,18 +545,23 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(50+260+10, 180); rect += m_topleft_client + v2s32(50+260+10, 180);
wchar_t* text = wgettext("Delete");
gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE, gui::IGUIButton *e = Environment->addButton(rect, this, GUI_ID_SERVERLIST_DELETE,
wgettext("Delete")); text);
if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // Hidden when on public list if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // Hidden when on public list
e->setVisible(false); e->setVisible(false);
delete [] text;
} }
// Start game button // Start game button
{ {
core::rect<s32> rect(0, 0, 120, 30); core::rect<s32> rect(0, 0, 120, 30);
rect += m_topleft_client + v2s32(m_size_client.X-130-30, rect += m_topleft_client + v2s32(m_size_client.X-130-30,
m_size_client.Y-25-15); m_size_client.Y-25-15);
wchar_t* text = wgettext("Connect");
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
wgettext("Connect")); text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }
@ -538,8 +581,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += m_topleft_client + v2s32(35+30, 35+6); rect += m_topleft_client + v2s32(35+30, 35+6);
Environment->addStaticText(wgettext("Name/Password"), wchar_t* text = wgettext("Name/Password");
Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete [] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -565,8 +610,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += m_topleft_client + v2s32(35+30, 75+6); rect += m_topleft_client + v2s32(35+30, 75+6);
Environment->addStaticText(wgettext("Address/Port"), wchar_t* text = wgettext("Address/Port");
Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -588,16 +635,20 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 400, 20); core::rect<s32> rect(0, 0, 400, 20);
rect += m_topleft_client + v2s32(160+30, 75+35); rect += m_topleft_client + v2s32(160+30, 75+35);
Environment->addStaticText(wgettext("Leave address blank to start a local server."), wchar_t* text = wgettext("Leave address blank to start a local server.");
Environment->addStaticText(text,
rect, false, true, this, -1); rect, false, true, this, -1);
delete[] text;
} }
// Start game button // Start game button
{ {
core::rect<s32> rect(0, 0, 180, 30); core::rect<s32> rect(0, 0, 180, 30);
rect += m_topleft_client + v2s32(m_size_client.X-180-30, rect += m_topleft_client + v2s32(m_size_client.X-180-30,
m_size_client.Y-30-20); m_size_client.Y-30-20);
wchar_t* text = wgettext("Start Game / Connect");
Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON, Environment->addButton(rect, this, GUI_ID_JOIN_GAME_BUTTON,
wgettext("Start Game / Connect")); text);
delete[] text;
} }
/* /*
Server section Server section
@ -615,36 +666,46 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 250, 30); core::rect<s32> rect(0, 0, 250, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 20); rect += m_topleft_server + v2s32(30+20+250+20, 20);
wchar_t* text = wgettext("Creative Mode");
Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB, Environment->addCheckBox(m_data->creative_mode, rect, this, GUI_ID_CREATIVE_CB,
wgettext("Creative Mode")); text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 250, 30); core::rect<s32> rect(0, 0, 250, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 40); rect += m_topleft_server + v2s32(30+20+250+20, 40);
wchar_t* text = wgettext("Enable Damage");
Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB, Environment->addCheckBox(m_data->enable_damage, rect, this, GUI_ID_DAMAGE_CB,
wgettext("Enable Damage")); text);
delete[] text;
} }
#if USE_CURL #if USE_CURL
{ {
core::rect<s32> rect(0, 0, 250, 30); core::rect<s32> rect(0, 0, 250, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 60); rect += m_topleft_server + v2s32(30+20+250+20, 60);
wchar_t* text = wgettext("Public");
Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB, Environment->addCheckBox(m_data->enable_public, rect, this, GUI_ID_PUBLIC_CB,
wgettext("Public")); text);
delete[] text;
} }
#endif #endif
// Delete world button // Delete world button
{ {
core::rect<s32> rect(0, 0, 130, 30); core::rect<s32> rect(0, 0, 130, 30);
rect += m_topleft_server + v2s32(30+20+250+20, 90); rect += m_topleft_server + v2s32(30+20+250+20, 90);
wchar_t* text = wgettext("Delete world");
Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON, Environment->addButton(rect, this, GUI_ID_DELETE_WORLD_BUTTON,
wgettext("Delete world")); text );
delete[] text;
} }
// Create world button // Create world button
{ {
core::rect<s32> rect(0, 0, 130, 30); core::rect<s32> rect(0, 0, 130, 30);
rect += m_topleft_server + v2s32(30+20+250+20+140, 90); rect += m_topleft_server + v2s32(30+20+250+20+140, 90);
wchar_t* text = wgettext("Create world");
Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON, Environment->addButton(rect, this, GUI_ID_CREATE_WORLD_BUTTON,
wgettext("Create world")); text );
delete[] text;
} }
// World selection listbox // World selection listbox
{ {
@ -677,26 +738,34 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y); rect += m_topleft_client + v2s32(option_x, option_y);
wchar_t* text = wgettext("Fancy trees");
Environment->addCheckBox(m_data->fancy_trees, rect, this, Environment->addCheckBox(m_data->fancy_trees, rect, this,
GUI_ID_FANCYTREE_CB, wgettext("Fancy trees")); GUI_ID_FANCYTREE_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20); rect += m_topleft_client + v2s32(option_x, option_y+20);
wchar_t* text = wgettext("Smooth Lighting");
Environment->addCheckBox(m_data->smooth_lighting, rect, this, Environment->addCheckBox(m_data->smooth_lighting, rect, this,
GUI_ID_SMOOTH_LIGHTING_CB, wgettext("Smooth Lighting")); GUI_ID_SMOOTH_LIGHTING_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*2); rect += m_topleft_client + v2s32(option_x, option_y+20*2);
wchar_t* text = wgettext("3D Clouds");
Environment->addCheckBox(m_data->clouds_3d, rect, this, Environment->addCheckBox(m_data->clouds_3d, rect, this,
GUI_ID_3D_CLOUDS_CB, wgettext("3D Clouds")); GUI_ID_3D_CLOUDS_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w, 30); core::rect<s32> rect(0, 0, option_w, 30);
rect += m_topleft_client + v2s32(option_x, option_y+20*3); rect += m_topleft_client + v2s32(option_x, option_y+20*3);
wchar_t* text = wgettext("Opaque water");
Environment->addCheckBox(m_data->opaque_water, rect, this, Environment->addCheckBox(m_data->opaque_water, rect, this,
GUI_ID_OPAQUE_WATER_CB, wgettext("Opaque water")); GUI_ID_OPAQUE_WATER_CB, text);
delete[] text;
} }
@ -705,58 +774,74 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, option_w+20, 30); core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y); rect += m_topleft_client + v2s32(option_x+175, option_y);
wchar_t* text = wgettext("Mip-Mapping");
Environment->addCheckBox(m_data->mip_map, rect, this, Environment->addCheckBox(m_data->mip_map, rect, this,
GUI_ID_MIPMAP_CB, wgettext("Mip-Mapping")); GUI_ID_MIPMAP_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20, 30); core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20); rect += m_topleft_client + v2s32(option_x+175, option_y+20);
wchar_t* text = wgettext("Anisotropic Filtering");
Environment->addCheckBox(m_data->anisotropic_filter, rect, this, Environment->addCheckBox(m_data->anisotropic_filter, rect, this,
GUI_ID_ANISOTROPIC_CB, wgettext("Anisotropic Filtering")); GUI_ID_ANISOTROPIC_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20, 30); core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20*2); rect += m_topleft_client + v2s32(option_x+175, option_y+20*2);
wchar_t* text = wgettext("Bi-Linear Filtering");
Environment->addCheckBox(m_data->bilinear_filter, rect, this, Environment->addCheckBox(m_data->bilinear_filter, rect, this,
GUI_ID_BILINEAR_CB, wgettext("Bi-Linear Filtering")); GUI_ID_BILINEAR_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20, 30); core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175, option_y+20*3); rect += m_topleft_client + v2s32(option_x+175, option_y+20*3);
wchar_t* text = wgettext("Tri-Linear Filtering");
Environment->addCheckBox(m_data->trilinear_filter, rect, this, Environment->addCheckBox(m_data->trilinear_filter, rect, this,
GUI_ID_TRILINEAR_CB, wgettext("Tri-Linear Filtering")); GUI_ID_TRILINEAR_CB, text);
delete[] text;
} }
// shader/on demand image loading/particles settings // shader/on demand image loading/particles settings
{ {
core::rect<s32> rect(0, 0, option_w+20, 30); core::rect<s32> rect(0, 0, option_w+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y); rect += m_topleft_client + v2s32(option_x+175*2, option_y);
wchar_t* text = wgettext("Shaders");
Environment->addCheckBox(m_data->enable_shaders, rect, this, Environment->addCheckBox(m_data->enable_shaders, rect, this,
GUI_ID_SHADERS_CB, wgettext("Shaders")); GUI_ID_SHADERS_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20+20, 30); core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20); rect += m_topleft_client + v2s32(option_x+175*2, option_y+20);
wchar_t* text = wgettext("Preload item visuals");
Environment->addCheckBox(m_data->preload_item_visuals, rect, this, Environment->addCheckBox(m_data->preload_item_visuals, rect, this,
GUI_ID_PRELOAD_ITEM_VISUALS_CB, wgettext("Preload item visuals")); GUI_ID_PRELOAD_ITEM_VISUALS_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20+20, 30); core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2); rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*2);
wchar_t* text = wgettext("Enable Particles");
Environment->addCheckBox(m_data->enable_particles, rect, this, Environment->addCheckBox(m_data->enable_particles, rect, this,
GUI_ID_ENABLE_PARTICLES_CB, wgettext("Enable Particles")); GUI_ID_ENABLE_PARTICLES_CB, text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, option_w+20+20, 30); core::rect<s32> rect(0, 0, option_w+20+20, 30);
rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*3); rect += m_topleft_client + v2s32(option_x+175*2, option_y+20*3);
wchar_t* text = wgettext("Finite liquid");
Environment->addCheckBox(m_data->liquid_finite, rect, this, Environment->addCheckBox(m_data->liquid_finite, rect, this,
GUI_ID_LIQUID_FINITE_CB, wgettext("Finite liquid")); GUI_ID_LIQUID_FINITE_CB, text);
delete[] text;
} }
// Key change button // Key change button
@ -765,8 +850,10 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
/*rect += m_topleft_client + v2s32(m_size_client.X-120-30, /*rect += m_topleft_client + v2s32(m_size_client.X-120-30,
m_size_client.Y-30-20);*/ m_size_client.Y-30-20);*/
rect += m_topleft_client + v2s32(option_x, option_y+120); rect += m_topleft_client + v2s32(option_x, option_y+120);
wchar_t* text = wgettext("Change keys");
Environment->addButton(rect, this, Environment->addButton(rect, this,
GUI_ID_CHANGE_KEYS_BUTTON, wgettext("Change keys")); GUI_ID_CHANGE_KEYS_BUTTON, text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }
@ -1080,9 +1167,11 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
readInput(&cur); readInput(&cur);
if (getTab() == TAB_MULTIPLAYER && cur.address == L"") if (getTab() == TAB_MULTIPLAYER && cur.address == L"")
{ {
wchar_t* text = wgettext("Address required.");
(new GUIMessageMenu(env, parent, -1, menumgr, (new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Address required.")) text)
)->drop(); )->drop();
delete[] text;
return true; return true;
} }
acceptInput(); acceptInput();
@ -1098,9 +1187,11 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
MainMenuData cur; MainMenuData cur;
readInput(&cur); readInput(&cur);
if(cur.selected_world == -1){ if(cur.selected_world == -1){
wchar_t* text = wgettext("Cannot delete world: Nothing selected");
(new GUIMessageMenu(env, parent, -1, menumgr, (new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Cannot delete world: Nothing selected")) text)
)->drop(); )->drop();
delete[] text;
} else { } else {
WorldSpec spec = m_data->worlds[cur.selected_world]; WorldSpec spec = m_data->worlds[cur.selected_world];
// Get files and directories involved // Get files and directories involved
@ -1110,12 +1201,16 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
// Launch confirmation dialog // Launch confirmation dialog
ConfirmDestDeleteWorld *dest = new ConfirmDestDeleteWorld *dest = new
ConfirmDestDeleteWorld(spec, this, paths); ConfirmDestDeleteWorld(spec, this, paths);
std::wstring text = wgettext("Delete world"); wchar_t* text1 = wgettext("Delete world");
wchar_t* text2 = wgettext("Files to be deleted");
std::wstring text = text1;
text += L" \""; text += L" \"";
text += narrow_to_wide(spec.name); text += narrow_to_wide(spec.name);
text += L"\"?\n\n"; text += L"\"?\n\n";
text += wgettext("Files to be deleted"); text += text2;
text += L":\n"; text += L":\n";
delete[] text1;
delete[] text2;
for(u32 i=0; i<paths.size(); i++){ for(u32 i=0; i<paths.size(); i++){
if(i == 3){ text += L"..."; break; } if(i == 3){ text += L"..."; break; }
text += narrow_to_wide(paths[i]) + L"\n"; text += narrow_to_wide(paths[i]) + L"\n";
@ -1128,10 +1223,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
case GUI_ID_CREATE_WORLD_BUTTON: { case GUI_ID_CREATE_WORLD_BUTTON: {
std::vector<SubgameSpec> games = getAvailableGames(); std::vector<SubgameSpec> games = getAvailableGames();
if(games.size() == 0){ if(games.size() == 0){
wchar_t* text = wgettext("Cannot create world: No games found");
GUIMessageMenu *menu = new GUIMessageMenu(env, parent, GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
-1, menumgr, -1, menumgr,
wgettext("Cannot create world: No games found")); text);
menu->drop(); menu->drop();
delete[] text;
} else { } else {
CreateWorldDest *dest = new CreateWorldDestMainMenu(this); CreateWorldDest *dest = new CreateWorldDestMainMenu(this);
GUICreateWorld *menu = new GUICreateWorld(env, parent, -1, GUICreateWorld *menu = new GUICreateWorld(env, parent, -1,
@ -1145,9 +1242,11 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
readInput(&cur); readInput(&cur);
if(cur.selected_world == -1) if(cur.selected_world == -1)
{ {
wchar_t* text = wgettext("Cannot configure world: Nothing selected");
(new GUIMessageMenu(env, parent, -1, menumgr, (new GUIMessageMenu(env, parent, -1, menumgr,
wgettext("Cannot configure world: Nothing selected")) text)
)->drop(); )->drop();
delete[] text;
} }
else else
{ {
@ -1180,8 +1279,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // switch to favorite list if (m_data->selected_serverlist == SERVERLIST_PUBLIC) // switch to favorite list
{ {
m_data->servers = ServerList::getLocal(); m_data->servers = ServerList::getLocal();
togglebutton->setText(wgettext("Show Public")); wchar_t* text1 = wgettext("Show Public");
title->setText(wgettext("Favorites:")); wchar_t* text2 = wgettext("Favorites:");
togglebutton->setText(text1);
title->setText(text2);
delete[] text1;
delete[] text2;
deletebutton->setVisible(true); deletebutton->setVisible(true);
updateGuiServerList(); updateGuiServerList();
serverlist->setSelected(0); serverlist->setSelected(0);
@ -1190,8 +1293,12 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
else // switch to online list else // switch to online list
{ {
m_data->servers = ServerList::getOnline(); m_data->servers = ServerList::getOnline();
togglebutton->setText(wgettext("Show Favorites")); wchar_t* text1 = wgettext("Show Favorites");
title->setText(wgettext("Public Server List:")); wchar_t* text2 = wgettext("Public Server List:");
togglebutton->setText(text1);
title->setText(text2);
delete[] text1;
delete[] text2;
deletebutton->setVisible(false); deletebutton->setVisible(false);
updateGuiServerList(); updateGuiServerList();
serverlist->setSelected(0); serverlist->setSelected(0);
@ -1261,8 +1368,10 @@ void GUIMainMenu::deleteWorld(const std::vector<std::string> &paths)
// Delete files // Delete files
bool did = fs::DeletePaths(paths); bool did = fs::DeletePaths(paths);
if(!did){ if(!did){
wchar_t* text = wgettext("Failed to delete all world files");
GUIMessageMenu *menu = new GUIMessageMenu(env, parent, GUIMessageMenu *menu = new GUIMessageMenu(env, parent,
-1, menumgr, wgettext("Failed to delete all world files")); -1, menumgr, text);
delete[] text;
menu->drop(); menu->drop();
} }
// Quit menu to refresh it // Quit menu to refresh it

@ -104,10 +104,12 @@ void GUIMessageMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, bw, 30); core::rect<s32> rect(0, 0, bw, 30);
rect = rect + v2s32(size.X/2-bw/2, size.Y/2-30/2+5 + msg_h/2); rect = rect + v2s32(size.X/2-bw/2, size.Y/2-30/2+5 + msg_h/2);
wchar_t* text = wgettext("Proceed");
gui::IGUIElement *e = gui::IGUIElement *e =
Environment->addButton(rect, this, 257, Environment->addButton(rect, this, 257,
wgettext("Proceed")); text);
Environment->setFocus(e); Environment->setFocus(e);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }

@ -105,8 +105,9 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6); rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(wgettext("Old Password"), wchar_t* text = wgettext("Old Password");
rect, false, true, this, -1); Environment->addStaticText(text, rect, false, true, this, -1);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -122,8 +123,9 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6); rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(wgettext("New Password"), wchar_t* text = wgettext("New Password");
rect, false, true, this, -1); Environment->addStaticText(text, rect, false, true, this, -1);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -138,8 +140,9 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 110, 20); core::rect<s32> rect(0, 0, 110, 20);
rect += topleft_client + v2s32(35, ypos+6); rect += topleft_client + v2s32(35, ypos+6);
Environment->addStaticText(wgettext("Confirm Password"), wchar_t* text = wgettext("Confirm Password");
rect, false, true, this, -1); Environment->addStaticText(text, rect, false, true, this, -1);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
{ {
@ -155,18 +158,22 @@ void GUIPasswordChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 140, 30); core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, ypos); rect = rect + v2s32(size.X/2-140/2, ypos);
Environment->addButton(rect, this, ID_change, wgettext("Change")); wchar_t* text = wgettext("Change");
Environment->addButton(rect, this, ID_change, text);
delete[] text;
} }
ypos += 50; ypos += 50;
{ {
core::rect<s32> rect(0, 0, 300, 20); core::rect<s32> rect(0, 0, 300, 20);
rect += topleft_client + v2s32(35, ypos); rect += topleft_client + v2s32(35, ypos);
wchar_t* text = wgettext("Passwords do not match!");
IGUIElement *e = IGUIElement *e =
Environment->addStaticText( Environment->addStaticText(
wgettext("Passwords do not match!"), text,
rect, false, true, this, ID_message); rect, false, true, this, ID_message);
e->setVisible(false); e->setVisible(false);
delete[] text;
} }
changeCtype("C"); changeCtype("C");

@ -119,8 +119,10 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 140, btn_height); core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y); rect = rect + v2s32(size.X/2-140/2, btn_y);
wchar_t* text = wgettext("Continue");
Environment->addButton(rect, this, 256, Environment->addButton(rect, this, 256,
wgettext("Continue")); text);
delete[] text;
} }
btn_y += btn_height + btn_gap; btn_y += btn_height + btn_gap;
if(!m_simple_singleplayer_mode) if(!m_simple_singleplayer_mode)
@ -128,37 +130,44 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 140, btn_height); core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y); rect = rect + v2s32(size.X/2-140/2, btn_y);
wchar_t* text = wgettext("Change Password");
Environment->addButton(rect, this, 261, Environment->addButton(rect, this, 261,
wgettext("Change Password")); text);
delete[] text;
} }
btn_y += btn_height + btn_gap; btn_y += btn_height + btn_gap;
} }
{ {
core::rect<s32> rect(0, 0, 140, btn_height); core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y); rect = rect + v2s32(size.X/2-140/2, btn_y);
wchar_t* text = wgettext("Sound Volume");
Environment->addButton(rect, this, 262, Environment->addButton(rect, this, 262,
wgettext("Sound Volume")); text);
delete[] text;
} }
btn_y += btn_height + btn_gap; btn_y += btn_height + btn_gap;
{ {
core::rect<s32> rect(0, 0, 140, btn_height); core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y); rect = rect + v2s32(size.X/2-140/2, btn_y);
wchar_t* text = wgettext("Exit to Menu");
Environment->addButton(rect, this, 260, Environment->addButton(rect, this, 260,
wgettext("Exit to Menu")); text);
delete[] text;
} }
btn_y += btn_height + btn_gap; btn_y += btn_height + btn_gap;
{ {
core::rect<s32> rect(0, 0, 140, btn_height); core::rect<s32> rect(0, 0, 140, btn_height);
rect = rect + v2s32(size.X/2-140/2, btn_y); rect = rect + v2s32(size.X/2-140/2, btn_y);
wchar_t* text = wgettext("Exit to OS");
Environment->addButton(rect, this, 257, Environment->addButton(rect, this, 257,
wgettext("Exit to OS")); text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 180, 240); core::rect<s32> rect(0, 0, 180, 240);
rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2); rect = rect + v2s32(size.X/2 + 90, size.Y/2-rect.getHeight()/2);
Environment->addStaticText(chartowchar_t(gettext( wchar_t* text = wgettext("Default Controls:\n"
"Default Controls:\n"
"- WASD: Walk\n" "- WASD: Walk\n"
"- Mouse left: dig/hit\n" "- Mouse left: dig/hit\n"
"- Mouse right: place/use\n" "- Mouse right: place/use\n"
@ -169,7 +178,10 @@ void GUIPauseMenu::regenerateGui(v2u32 screensize)
"- I: Inventory menu\n" "- I: Inventory menu\n"
"- ESC: This menu\n" "- ESC: This menu\n"
"- T: Chat\n" "- T: Chat\n"
)), rect, false, true, this, 258); );
Environment->addStaticText(text, rect, false, true, this, 258);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 180, 220); core::rect<s32> rect(0, 0, 180, 220);

@ -127,8 +127,10 @@ void GUITextInputMenu::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 140, 30); core::rect<s32> rect(0, 0, 140, 30);
rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25); rect = rect + v2s32(size.X/2-140/2, size.Y/2-30/2+25);
wchar_t* text = wgettext("Proceed");
Environment->addButton(rect, this, 257, Environment->addButton(rect, this, 257,
wgettext("Proceed")); text);
delete[] text;
} }
changeCtype("C"); changeCtype("C");
} }

@ -105,8 +105,10 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 120, 20); core::rect<s32> rect(0, 0, 120, 20);
rect = rect + v2s32(size.X/2-60, size.Y/2-35); rect = rect + v2s32(size.X/2-60, size.Y/2-35);
Environment->addStaticText(wgettext("Sound Volume: "), rect, false, wchar_t* text = wgettext("Sound Volume: ");
Environment->addStaticText(text, rect, false,
true, this, ID_soundText1); true, this, ID_soundText1);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 30, 20); core::rect<s32> rect(0, 0, 30, 20);
@ -117,8 +119,10 @@ void GUIVolumeChange::regenerateGui(v2u32 screensize)
{ {
core::rect<s32> rect(0, 0, 80, 30); core::rect<s32> rect(0, 0, 80, 30);
rect = rect + v2s32(size.X/2-80/2, size.Y/2+55); rect = rect + v2s32(size.X/2-80/2, size.Y/2+55);
wchar_t* text = wgettext("Exit");
Environment->addButton(rect, this, ID_soundExitButton, Environment->addButton(rect, this, ID_soundExitButton,
wgettext("Exit")); text);
delete[] text;
} }
{ {
core::rect<s32> rect(0, 0, 300, 20); core::rect<s32> rect(0, 0, 300, 20);

291
src/hud.cpp Normal file

@ -0,0 +1,291 @@
/*
Minetest
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu>
Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <IGUIStaticText.h>
#include "guiFormSpecMenu.h"
#include "main.h"
#include "util/numeric.h"
#include "log.h"
#include "client.h"
#include "hud.h"
Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory) {
this->driver = driver;
this->guienv = guienv;
this->font = font;
this->text_height = text_height;
this->gamedef = gamedef;
this->player = player;
this->inventory = inventory;
screensize = v2u32(0, 0);
displaycenter = v2s32(0, 0);
hotbar_imagesize = 48;
hotbar_itemcount = 8;
v3f crosshair_color = g_settings->getV3F("crosshair_color");
u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
}
//NOTE: selectitem = 0 -> no selected; selectitem 1-based
void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
InventoryList *mainlist, u16 selectitem, u16 direction)
{
s32 padding = imgsize / 12;
s32 height = imgsize + padding * 2;
s32 width = itemcount * (imgsize + padding * 2);
if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
width = imgsize + padding * 2;
height = itemcount * (imgsize + padding * 2);
}
s32 fullimglen = imgsize + padding * 2;
// Position of upper left corner of bar
v2s32 pos = upperleftpos;
// Draw background color
/*core::rect<s32> barrect(0,0,width,height);
barrect += pos;
video::SColor bgcolor(255,128,128,128);
driver->draw2DRectangle(bgcolor, barrect, NULL);*/
core::rect<s32> imgrect(0, 0, imgsize, imgsize);
for (s32 i = 0; i < itemcount; i++)
{
const ItemStack &item = mainlist->getItem(i);
v2s32 steppos;
switch (direction) {
case HUD_DIR_RIGHT_LEFT:
steppos = v2s32(-(padding + i * fullimglen), padding);
break;
case HUD_DIR_TOP_BOTTOM:
steppos = v2s32(padding, padding + i * fullimglen);
break;
case HUD_DIR_BOTTOM_TOP:
steppos = v2s32(padding, -(padding + i * fullimglen));
break;
default:
steppos = v2s32(padding + i * fullimglen, padding);
}
core::rect<s32> rect = imgrect + pos + steppos;
if (selectitem == i + 1)
{
video::SColor c_outside(255,255,0,0);
//video::SColor c_outside(255,0,0,0);
//video::SColor c_inside(255,192,192,192);
s32 x1 = rect.UpperLeftCorner.X;
s32 y1 = rect.UpperLeftCorner.Y;
s32 x2 = rect.LowerRightCorner.X;
s32 y2 = rect.LowerRightCorner.Y;
// Black base borders
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y1 - padding),
v2s32(x2 + padding, y1)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y2),
v2s32(x2 + padding, y2 + padding)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x1 - padding, y1),
v2s32(x1, y2)
), NULL);
driver->draw2DRectangle(c_outside,
core::rect<s32>(
v2s32(x2, y1),
v2s32(x2 + padding, y2)
), NULL);
/*// Light inside borders
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y1 - padding/2),
v2s32(x2 + padding/2, y1)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y2),
v2s32(x2 + padding/2, y2 + padding/2)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x1 - padding/2, y1),
v2s32(x1, y2)
), NULL);
driver->draw2DRectangle(c_inside,
core::rect<s32>(
v2s32(x2, y1),
v2s32(x2 + padding/2, y2)
), NULL);
*/
}
video::SColor bgcolor2(128, 0, 0, 0);
driver->draw2DRectangle(bgcolor2, rect, NULL);
drawItemStack(driver, font, item, rect, NULL, gamedef);
}
}
void Hud::drawLuaElements() {
for (size_t i = 0; i != player->hud.size(); i++) {
HudElement *e = player->hud[i];
if (!e)
continue;
v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y);
switch (e->type) {
case HUD_ELEM_IMAGE: {
video::ITexture *texture =
gamedef->getTextureSource()->getTextureRaw(e->text);
if (!texture)
continue;
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
core::dimension2di imgsize(texture->getOriginalSize());
core::rect<s32> rect(0, 0, imgsize.Width * e->scale.X,
imgsize.Height * e->scale.X);
rect += pos;
driver->draw2DImage(texture, rect,
core::rect<s32>(core::position2d<s32>(0,0), imgsize),
NULL, colors, true);
break; }
case HUD_ELEM_TEXT: {
video::SColor color(255, (e->number >> 16) & 0xFF,
(e->number >> 8) & 0xFF,
(e->number >> 0) & 0xFF);
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);
break; }
case HUD_ELEM_STATBAR:
drawStatbar(pos, e->text, e->number);
break;
case HUD_ELEM_INVENTORY: {
InventoryList *inv = inventory->getList(e->text);
drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir);
break; }
default:
infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
"of hud element ID " << i << " due to unrecognized type" << std::endl;
}
}
}
void Hud::drawStatbar(v2s32 upperleftpos, std::string texture, s32 count) {
video::ITexture *stat_texture =
gamedef->getTextureSource()->getTextureRaw(texture);
if (!stat_texture)
return;
v2s32 p = upperleftpos;
for (s32 i = 0; i < count / 2; i++)
{
core::dimension2di srcd(stat_texture->getOriginalSize());
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
core::rect<s32> rect(0, 0, srcd.Width, srcd.Height);
rect += p;
driver->draw2DImage(stat_texture, rect,
core::rect<s32>(core::position2d<s32>(0, 0), srcd),
NULL, colors, true);
p += v2s32(srcd.Width, 0);
}
if (count % 2 == 1)
{
core::dimension2di srcd(stat_texture->getOriginalSize());
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
core::rect<s32> rect(0, 0, srcd.Width / 2, srcd.Height);
rect += p;
srcd.Width /= 2;
driver->draw2DImage(stat_texture, rect,
core::rect<s32>(core::position2d<s32>(0, 0), srcd),
NULL, colors, true);
p += v2s32(srcd.Width * 2, 0);
}
}
void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
InventoryList *mainlist = inventory->getList("main");
if (mainlist == NULL) {
errorstream << "draw_hotbar(): mainlist == NULL" << std::endl;
return;
}
s32 padding = hotbar_imagesize / 12;
s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2);
v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2);
drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0);
drawStatbar(pos + v2s32(0, -20), "heart.png", halfheartcount);
}
void Hud::drawCrosshair() {
driver->draw2DLine(displaycenter - v2s32(10,0),
displaycenter + v2s32(10, 0), crosshair_argb);
driver->draw2DLine(displaycenter - v2s32(0,10),
displaycenter + v2s32(0, 10), crosshair_argb);
}
void Hud::drawSelectionBoxes(std::vector<aabb3f> &hilightboxes) {
for (std::vector<aabb3f>::const_iterator
i = hilightboxes.begin();
i != hilightboxes.end(); i++) {
driver->draw3DBox(*i, selectionbox_argb);
}
}
void Hud::resizeHotbar() {
if (screensize.Y <= 800)
hotbar_imagesize = 32;
else if (screensize.Y <= 1280)
hotbar_imagesize = 48;
else
hotbar_imagesize = 64;
}

116
src/hud.h Normal file

@ -0,0 +1,116 @@
/*
Minetest
Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef HUD_HEADER
#define HUD_HEADER
#include "irrlichttypes_extrabloated.h"
#define HUD_DIR_LEFT_RIGHT 0
#define HUD_DIR_RIGHT_LEFT 1
#define HUD_DIR_TOP_BOTTOM 2
#define HUD_DIR_BOTTOM_TOP 3
class Player;
enum HudElementType {
HUD_ELEM_IMAGE = 0,
HUD_ELEM_TEXT = 1,
HUD_ELEM_STATBAR = 2,
HUD_ELEM_INVENTORY = 3
};
enum HudElementStat {
HUD_STAT_POS,
HUD_STAT_NAME,
HUD_STAT_SCALE,
HUD_STAT_TEXT,
HUD_STAT_NUMBER,
HUD_STAT_ITEM,
HUD_STAT_DIR
};
struct HudElement {
HudElementType type;
v2f pos;
std::string name;
v2f scale;
std::string text;
u32 number;
u32 item;
u32 dir;
};
inline u32 hud_get_free_id(Player *player) {
size_t size = player->hud.size();
for (size_t i = 0; i != size; i++) {
if (!player->hud[i])
return i;
}
return size;
}
#ifndef SERVER
#include <deque>
#include <IGUIFont.h>
#include "gamedef.h"
#include "inventory.h"
#include "localplayer.h"
class Hud {
public:
video::IVideoDriver *driver;
gui::IGUIEnvironment *guienv;
gui::IGUIFont *font;
u32 text_height;
IGameDef *gamedef;
LocalPlayer *player;
Inventory *inventory;
v2u32 screensize;
v2s32 displaycenter;
s32 hotbar_imagesize;
s32 hotbar_itemcount;
video::SColor crosshair_argb;
video::SColor selectionbox_argb;
Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory);
void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
InventoryList *mainlist, u16 selectitem, u16 direction);
void drawLuaElements();
void drawStatbar(v2s32 upperleftpos, std::string texture, s32 count);
void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem);
void resizeHotbar();
void drawCrosshair();
void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes);
};
#endif
#endif

@ -226,8 +226,15 @@ class CItemDefManager: public IWritableItemDefManager
public: public:
CItemDefManager() CItemDefManager()
{ {
for (std::map<std::string, ItemDefinition*>::iterator iter =
m_item_definitions.begin(); iter != m_item_definitions.end();
iter ++) {
delete iter->second;
}
m_item_definitions.clear();
#ifndef SERVER #ifndef SERVER
m_main_thread = get_current_thread_id(); m_main_thread = get_current_thread_id();
m_driver = NULL;
#endif #endif
clear(); clear();
@ -241,7 +248,16 @@ public:
{ {
ClientCached *cc = *i; ClientCached *cc = *i;
cc->wield_mesh->drop(); cc->wield_mesh->drop();
delete cc;
} }
if (m_driver != NULL) {
for (unsigned int i = 0; i < m_extruded_textures.size(); i++) {
m_driver->removeTexture(m_extruded_textures[i]);
}
m_extruded_textures.clear();
}
m_driver = NULL;
#endif #endif
} }
virtual const ItemDefinition& get(const std::string &name_) const virtual const ItemDefinition& get(const std::string &name_) const
@ -290,6 +306,10 @@ public:
return m_item_definitions.find(name) != m_item_definitions.end(); return m_item_definitions.find(name) != m_item_definitions.end();
} }
#ifndef SERVER #ifndef SERVER
private:
static video::IVideoDriver * m_driver;
static std::vector<video::ITexture*> m_extruded_textures;
public:
ClientCached* createClientCachedDirect(const std::string &name, ClientCached* createClientCachedDirect(const std::string &name,
IGameDef *gamedef) const IGameDef *gamedef) const
{ {
@ -328,11 +348,7 @@ public:
} }
// Create a wield mesh // Create a wield mesh
if(cc->wield_mesh != NULL) assert(cc->wield_mesh == NULL);
{
cc->wield_mesh->drop();
cc->wield_mesh = NULL;
}
if(def->type == ITEM_NODE && def->wield_image == "") if(def->type == ITEM_NODE && def->wield_image == "")
{ {
need_node_mesh = true; need_node_mesh = true;
@ -432,20 +448,27 @@ public:
tsrc->getTextureRaw(f.tiledef[0].name); tsrc->getTextureRaw(f.tiledef[0].name);
} }
} }
else
{
if (m_driver == 0)
m_driver = driver;
m_extruded_textures.push_back(cc->inventory_texture);
}
/* /*
Use the node mesh as the wield mesh Use the node mesh as the wield mesh
*/ */
if(cc->wield_mesh == NULL)
{
// Scale to proper wield mesh proportions // Scale to proper wield mesh proportions
scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0) scaleMesh(node_mesh, v3f(30.0, 30.0, 30.0)
* def->wield_scale); * def->wield_scale);
cc->wield_mesh = node_mesh; cc->wield_mesh = node_mesh;
cc->wield_mesh->grab(); cc->wield_mesh->grab();
}
// falling outside of here deletes node_mesh //no way reference count can be smaller than 2 in this place!
assert(cc->wield_mesh->getReferenceCount() >= 2);
} }
// Put in cache // Put in cache
@ -658,3 +681,8 @@ IWritableItemDefManager* createItemDefManager()
return new CItemDefManager(); return new CItemDefManager();
} }
#ifndef SERVER
//TODO very very very dirty hack!
video::IVideoDriver * CItemDefManager::m_driver = 0;
std::vector<video::ITexture*> CItemDefManager::m_extruded_textures;
#endif

@ -329,6 +329,9 @@ void LocalPlayer::move(f32 dtime, ClientEnvironment *env, f32 pos_max_d,
if(!touching_ground_was && touching_ground){ if(!touching_ground_was && touching_ground){
MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround"); MtEvent *e = new SimpleTriggerEvent("PlayerRegainGround");
m_gamedef->event()->put(e); m_gamedef->event()->put(e);
// Set camera impact value to be used for view bobbing
camera_impact = getSpeed().Y * -1;
} }
{ {

@ -59,6 +59,8 @@ public:
float last_yaw; float last_yaw;
unsigned int last_keyPressed; unsigned int last_keyPressed;
float camera_impact;
private: private:
// This is used for determining the sneaking range // This is used for determining the sneaking range
v3s16 m_sneak_node; v3s16 m_sneak_node;

@ -1501,7 +1501,9 @@ int main(int argc, char *argv[])
while(device->run() && kill == false) while(device->run() && kill == false)
{ {
// Set the window caption // Set the window caption
device->setWindowCaption((std::wstring(L"Minetest [")+wgettext("Main Menu")+L"]").c_str()); wchar_t* text = wgettext("Main Menu");
device->setWindowCaption((std::wstring(L"Minetest [")+text+L"]").c_str());
delete[] text;
// This is used for catching disconnects // This is used for catching disconnects
try try
@ -1902,16 +1904,6 @@ int main(int argc, char *argv[])
error_message = wgettext("Connection error (timed out?)"); error_message = wgettext("Connection error (timed out?)");
errorstream<<wide_to_narrow(error_message)<<std::endl; errorstream<<wide_to_narrow(error_message)<<std::endl;
} }
catch(ServerError &e)
{
error_message = narrow_to_wide(e.what());
errorstream<<wide_to_narrow(error_message)<<std::endl;
}
catch(ModError &e)
{
errorstream<<e.what()<<std::endl;
error_message = narrow_to_wide(e.what()) + wgettext("\nCheck debug.txt for details.");
}
#ifdef NDEBUG #ifdef NDEBUG
catch(std::exception &e) catch(std::exception &e)
{ {

@ -2494,6 +2494,8 @@ ServerMap::~ServerMap()
delete chunk; delete chunk;
} }
#endif #endif
delete m_mgparams;
} }
bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos) bool ServerMap::initBlockMake(BlockMakeData *data, v3s16 blockpos)

@ -94,7 +94,7 @@ void Ore::resolveNodeNames(INodeDefManager *ndef) {
} }
void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { void Ore::placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
int in_range = 0; int in_range = 0;
in_range |= (nmin.Y <= height_max && nmax.Y >= height_min); in_range |= (nmin.Y <= height_max && nmax.Y >= height_min);
@ -105,9 +105,6 @@ void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
resolveNodeNames(mg->ndef); resolveNodeNames(mg->ndef);
MapNode n_ore(ore);
ManualMapVoxelManipulator *vm = mg->vm;
PseudoRandom pr(blockseed);
int ymin, ymax; int ymin, ymax;
if (in_range & ORE_RANGE_MIRROR) { if (in_range & ORE_RANGE_MIRROR) {
@ -120,6 +117,17 @@ void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
if (clust_size >= ymax - ymin + 1) if (clust_size >= ymax - ymin + 1)
return; return;
nmin.Y = ymin;
nmax.Y = ymax;
generate(mg->vm, mg->seed, blockseed, nmin, nmax);
}
void OreScatter::generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax) {
PseudoRandom pr(blockseed);
MapNode n_ore(ore, 0, ore_param2);
int volume = (nmax.X - nmin.X + 1) * int volume = (nmax.X - nmin.X + 1) *
(nmax.Y - nmin.Y + 1) * (nmax.Y - nmin.Y + 1) *
(nmax.Z - nmin.Z + 1); (nmax.Z - nmin.Z + 1);
@ -129,10 +137,10 @@ void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
for (int i = 0; i != nclusters; i++) { for (int i = 0; i != nclusters; i++) {
int x0 = pr.range(nmin.X, nmax.X - csize + 1); int x0 = pr.range(nmin.X, nmax.X - csize + 1);
int y0 = pr.range(ymin, ymax - csize + 1); int y0 = pr.range(nmin.Y, nmax.Y - csize + 1);
int z0 = pr.range(nmin.Z, nmax.Z - csize + 1); int z0 = pr.range(nmin.Z, nmax.Z - csize + 1);
if (np && (NoisePerlin3D(np, x0, y0, z0, mg->seed) < nthresh)) if (np && (NoisePerlin3D(np, x0, y0, z0, seed) < nthresh))
continue; continue;
for (int z1 = 0; z1 != csize; z1++) for (int z1 = 0; z1 != csize; z1++)
@ -149,53 +157,25 @@ void OreScatter::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) {
} }
void OreSheet::generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) { void OreSheet::generate(ManualMapVoxelManipulator *vm, int seed,
int in_range = 0; u32 blockseed, v3s16 nmin, v3s16 nmax) {
in_range |= (nmin.Y <= height_max && nmax.Y >= height_min);
if (flags & OREFLAG_ABSHEIGHT)
in_range |= (nmin.Y >= -height_max && nmax.Y <= -height_min) << 1;
if (!in_range)
return;
resolveNodeNames(mg->ndef);
MapNode n_ore(ore);
ManualMapVoxelManipulator *vm = mg->vm;
PseudoRandom pr(blockseed + 4234); PseudoRandom pr(blockseed + 4234);
int ymin, ymax; MapNode n_ore(ore, 0, ore_param2);
if (in_range & ORE_RANGE_MIRROR) {
ymin = MYMAX(nmin.Y, -height_max);
ymax = MYMIN(nmax.Y, -height_min);
} else {
ymin = MYMAX(nmin.Y, height_min);
ymax = MYMIN(nmax.Y, height_max);
}
if (clust_size >= ymax - ymin + 1)
return;
int x0 = nmin.X;
int z0 = nmin.Z;
int x1 = nmax.X;
int z1 = nmax.Z;
int max_height = clust_size; int max_height = clust_size;
int y_start = pr.range(ymin, ymax - max_height); int y_start = pr.range(nmin.Y, nmax.Y - max_height);
if (!noise) { if (!noise) {
int sx = nmax.X - nmin.X + 1; int sx = nmax.X - nmin.X + 1;
int sz = nmax.Z - nmin.Z + 1; int sz = nmax.Z - nmin.Z + 1;
noise = new Noise(np, 0, sx, sz); noise = new Noise(np, 0, sx, sz);
} }
noise->seed = mg->seed + y_start; noise->seed = seed + y_start;
noise->perlinMap2D(x0, z0); noise->perlinMap2D(nmin.X, nmin.Z);
int index = 0; int index = 0;
for (int z = z0; z != z1; z++) for (int z = nmin.Z; z <= nmax.Z; z++)
for (int x = x0; x != x1; x++) { for (int x = nmin.X; x <= nmax.X; x++) {
float noiseval = noise->result[index++]; float noiseval = noise->result[index++];
if (noiseval < nthresh) if (noiseval < nthresh)
continue; continue;

@ -120,7 +120,6 @@ class Ore {
public: public:
std::string ore_name; std::string ore_name;
std::string wherein_name; std::string wherein_name;
content_t ore; content_t ore;
content_t wherein; // the node to be replaced content_t wherein; // the node to be replaced
u32 clust_scarcity; // ore cluster has a 1-in-clust_scarcity chance of appearing at a node u32 clust_scarcity; // ore cluster has a 1-in-clust_scarcity chance of appearing at a node
@ -128,6 +127,7 @@ public:
s16 clust_size; // how large (in nodes) a chunk of ore is s16 clust_size; // how large (in nodes) a chunk of ore is
s16 height_min; s16 height_min;
s16 height_max; s16 height_max;
u8 ore_param2; // to set node-specific attributes
u32 flags; // attributes for this ore u32 flags; // attributes for this ore
float nthresh; // threshhold for noise at which an ore is placed float nthresh; // threshhold for noise at which an ore is placed
NoiseParams *np; // noise for distribution of clusters (NULL for uniform scattering) NoiseParams *np; // noise for distribution of clusters (NULL for uniform scattering)
@ -141,15 +141,19 @@ public:
} }
void resolveNodeNames(INodeDefManager *ndef); void resolveNodeNames(INodeDefManager *ndef);
virtual void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax) = 0; void placeOre(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
virtual void generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax) = 0;
}; };
class OreScatter : public Ore { class OreScatter : public Ore {
void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); virtual void generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax);
}; };
class OreSheet : public Ore { class OreSheet : public Ore {
void generate(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax); virtual void generate(ManualMapVoxelManipulator *vm, int seed,
u32 blockseed, v3s16 nmin, v3s16 nmax);
}; };
Ore *createOre(OreType type); Ore *createOre(OreType type);

@ -467,7 +467,7 @@ void MapgenV6::makeChunk(BlockMakeData *data) {
// Generate the registered ores // Generate the registered ores
for (unsigned int i = 0; i != emerge->ores.size(); i++) { for (unsigned int i = 0; i != emerge->ores.size(); i++) {
Ore *ore = emerge->ores[i]; Ore *ore = emerge->ores[i];
ore->generate(this, blockseed + i, node_min, node_max); ore->placeOre(this, blockseed + i, node_min, node_max);
} }
// Calculate lighting // Calculate lighting

@ -180,7 +180,7 @@ void MapgenV7::makeChunk(BlockMakeData *data) {
for (size_t i = 0; i != emerge->ores.size(); i++) { for (size_t i = 0; i != emerge->ores.size(); i++) {
Ore *ore = emerge->ores[i]; Ore *ore = emerge->ores[i];
ore->generate(this, blockseed + i, node_min, node_max); ore->placeOre(this, blockseed + i, node_min, node_max);
} }
//printf("makeChunk: %dms\n", t.stop()); //printf("makeChunk: %dms\n", t.stop());

@ -246,6 +246,8 @@ static scene::IAnimatedMesh* extrudeARGB(u32 twidth, u32 theight, u8 *data)
} }
} }
delete[] solidity;
// Add to mesh // Add to mesh
scene::SMesh *mesh = new scene::SMesh(); scene::SMesh *mesh = new scene::SMesh();
mesh->addMeshBuffer(buf); mesh->addMeshBuffer(buf);

@ -687,9 +687,8 @@ bool pathfinder::update_all_costs( v3s16 ipos,
if ((g_pos2.totalcost < 0) || if ((g_pos2.totalcost < 0) ||
(g_pos2.totalcost > new_cost)) { (g_pos2.totalcost > new_cost)) {
int old_cost = g_pos2.totalcost;
DEBUG_OUT(LVL "Pathfinder: updating path at: "<< DEBUG_OUT(LVL "Pathfinder: updating path at: "<<
PPOS(ipos2) << " from: " << old_cost << " to "<< PPOS(ipos2) << " from: " << g_pos2.totalcost << " to "<<
new_cost << std::endl); new_cost << std::endl);
if (update_all_costs(ipos2,invert(directions[i]), if (update_all_costs(ipos2,invert(directions[i]),
new_cost,level)) { new_cost,level)) {
@ -847,9 +846,8 @@ bool pathfinder::update_cost_heuristic( v3s16 ipos,
if ((g_pos2.totalcost < 0) || if ((g_pos2.totalcost < 0) ||
(g_pos2.totalcost > new_cost)) { (g_pos2.totalcost > new_cost)) {
int old_cost = g_pos2.totalcost;
DEBUG_OUT(LVL "Pathfinder: updating path at: "<< DEBUG_OUT(LVL "Pathfinder: updating path at: "<<
PPOS(ipos2) << " from: " << old_cost << " to "<< PPOS(ipos2) << " from: " << g_pos2.totalcost << " to "<<
new_cost << " srcdir=" << new_cost << " srcdir=" <<
PPOS(invert(direction))<< std::endl); PPOS(invert(direction))<< std::endl);
if (update_cost_heuristic(ipos2,invert(direction), if (update_cost_heuristic(ipos2,invert(direction),

@ -87,6 +87,7 @@ class Map;
class IGameDef; class IGameDef;
struct CollisionInfo; struct CollisionInfo;
class PlayerSAO; class PlayerSAO;
class HudElement;
class Player class Player
{ {
@ -243,6 +244,8 @@ public:
u32 keyPressed; u32 keyPressed;
std::vector<HudElement *> hud;
protected: protected:
IGameDef *m_gamedef; IGameDef *m_gamedef;
@ -253,6 +256,7 @@ protected:
v3f m_position; v3f m_position;
}; };
/* /*
Player on the server Player on the server
*/ */

@ -670,6 +670,7 @@ static int l_register_ore(lua_State *L)
} }
ore->ore_name = getstringfield_default(L, index, "ore", ""); ore->ore_name = getstringfield_default(L, index, "ore", "");
ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0);
ore->wherein_name = getstringfield_default(L, index, "wherein", ""); ore->wherein_name = getstringfield_default(L, index, "wherein", "");
ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1);
ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1);

@ -330,8 +330,7 @@ int l_get_craft_result(lua_State *L)
// get_craft_recipe(result item) // get_craft_recipe(result item)
int l_get_craft_recipe(lua_State *L) int l_get_craft_recipe(lua_State *L)
{ {
int k = 0; int k = 1;
char tmp[20];
int input_i = 1; int input_i = 1;
std::string o_item = luaL_checkstring(L,input_i); std::string o_item = luaL_checkstring(L,input_i);
@ -351,8 +350,7 @@ int l_get_craft_recipe(lua_State *L)
{ {
continue; continue;
} }
sprintf(tmp,"%d",k); lua_pushinteger(L,k);
lua_pushstring(L,tmp);
lua_pushstring(L,i->name.c_str()); lua_pushstring(L,i->name.c_str());
lua_settable(L, -3); lua_settable(L, -3);
} }
@ -383,9 +381,7 @@ int l_get_craft_recipe(lua_State *L)
// get_all_craft_recipes(result item) // get_all_craft_recipes(result item)
int l_get_all_craft_recipes(lua_State *L) int l_get_all_craft_recipes(lua_State *L)
{ {
char tmp[20]; std::string o_item = luaL_checkstring(L,1);
int input_i = 1;
std::string o_item = luaL_checkstring(L,input_i);
IGameDef *gdef = get_server(L); IGameDef *gdef = get_server(L);
ICraftDefManager *cdef = gdef->cdef(); ICraftDefManager *cdef = gdef->cdef();
CraftInput input; CraftInput input;
@ -411,28 +407,29 @@ int l_get_all_craft_recipes(lua_State *L)
tmpout.time = 0; tmpout.time = 0;
CraftDefinition *def = *i; CraftDefinition *def = *i;
tmpout = def->getOutput(input, gdef); tmpout = def->getOutput(input, gdef);
if(tmpout.item.substr(0,output.item.length()) == output.item) std::string query = tmpout.item;
char *fmtpos, *fmt = &query[0];
if (strtok_r(fmt, " ", &fmtpos) == output.item)
{ {
input = def->getInput(output, gdef); input = def->getInput(output, gdef);
lua_pushvalue(L, table_insert); lua_pushvalue(L, table_insert);
lua_pushvalue(L, table); lua_pushvalue(L, table);
lua_newtable(L); lua_newtable(L);
int k = 0; int k = 1;
lua_newtable(L); lua_newtable(L);
for(std::vector<ItemStack>::const_iterator for(std::vector<ItemStack>::const_iterator
i = input.items.begin(); i = input.items.begin();
i != input.items.end(); i++, k++) i != input.items.end(); i++, k++)
{ {
if (i->empty()) continue; if (i->empty())
sprintf(tmp,"%d",k); continue;
lua_pushstring(L,tmp); lua_pushinteger(L, k);
lua_pushstring(L, i->name.c_str()); lua_pushstring(L, i->name.c_str());
lua_settable(L, -3); lua_settable(L, -3);
} }
lua_setfield(L, -2, "items"); lua_setfield(L, -2, "items");
setintfield(L, -1, "width", input.width); setintfield(L, -1, "width", input.width);
switch (input.method) switch (input.method) {
{
case CRAFT_METHOD_NORMAL: case CRAFT_METHOD_NORMAL:
lua_pushstring(L,"normal"); lua_pushstring(L,"normal");
break; break;
@ -446,6 +443,8 @@ int l_get_all_craft_recipes(lua_State *L)
lua_pushstring(L,"unknown"); lua_pushstring(L,"unknown");
} }
lua_setfield(L, -2, "type"); lua_setfield(L, -2, "type");
lua_pushstring(L, &tmpout.item[0]);
lua_setfield(L, -2, "output");
if (lua_pcall(L, 2, 0, 0)) if (lua_pcall(L, 2, 0, 0))
script_error(L, "error: %s", lua_tostring(L, -1)); script_error(L, "error: %s", lua_tostring(L, -1));
} }

@ -664,7 +664,9 @@ int EnvRef::l_line_of_sight(lua_State *L) {
if(lua_isnumber(L, 3)) if(lua_isnumber(L, 3))
stepsize = lua_tonumber(L, 3); stepsize = lua_tonumber(L, 3);
return (env->line_of_sight(pos1,pos2,stepsize)); lua_pushboolean(L, env->line_of_sight(pos1,pos2,stepsize));
return 1;
} }
int EnvRef::l_find_path(lua_State *L) int EnvRef::l_find_path(lua_State *L)

@ -26,6 +26,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "scriptapi_item.h" #include "scriptapi_item.h"
#include "scriptapi_entity.h" #include "scriptapi_entity.h"
#include "scriptapi_common.h" #include "scriptapi_common.h"
#include "hud.h"
struct EnumString es_HudElementType[] =
{
{HUD_ELEM_IMAGE, "image"},
{HUD_ELEM_TEXT, "text"},
{HUD_ELEM_STATBAR, "statbar"},
{HUD_ELEM_INVENTORY, "inventory"},
{0, NULL},
};
struct EnumString es_HudElementStat[] =
{
{HUD_STAT_POS, "pos"},
{HUD_STAT_NAME, "name"},
{HUD_STAT_SCALE, "scale"},
{HUD_STAT_TEXT, "text"},
{HUD_STAT_NUMBER, "number"},
{HUD_STAT_ITEM, "item"},
{HUD_STAT_DIR, "direction"},
{0, NULL},
};
/* /*
ObjectRef ObjectRef
@ -700,6 +724,165 @@ int ObjectRef::l_get_player_control_bits(lua_State *L)
return 1; return 1;
} }
// hud_add(self, form)
int ObjectRef::l_hud_add(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
HudElement *elem = new HudElement;
elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
es_HudElementType, HUD_ELEM_TEXT);
lua_getfield(L, 2, "position");
elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
lua_getfield(L, 2, "scale");
elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
elem->name = getstringfield_default(L, 2, "name", "");
elem->text = getstringfield_default(L, 2, "text", "");
elem->number = getintfield_default(L, 2, "number", 0);
elem->item = getintfield_default(L, 2, "item", 0);
elem->dir = getintfield_default(L, 2, "dir", 0);
u32 id = get_server(L)->hudAdd(player, elem);
if (id == (u32)-1) {
delete elem;
return 0;
}
lua_pushnumber(L, id);
return 1;
}
// hud_remove(self, id)
int ObjectRef::l_hud_remove(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
u32 id = -1;
if (!lua_isnil(L, 2))
id = lua_tonumber(L, 2);
if (!get_server(L)->hudRemove(player, id))
return 0;
lua_pushboolean(L, true);
return 1;
}
// hud_change(self, id, stat, data)
int ObjectRef::l_hud_change(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
u32 id = -1;
if (!lua_isnil(L, 2))
id = lua_tonumber(L, 2);
HudElementStat stat = (HudElementStat)getenumfield(L, 3, "stat",
es_HudElementStat, HUD_STAT_NUMBER);
if (id >= player->hud.size())
return 0;
void *value = NULL;
HudElement *e = player->hud[id];
if (!e)
return 0;
switch (stat) {
case HUD_STAT_POS:
e->pos = read_v2f(L, 4);
value = &e->pos;
break;
case HUD_STAT_NAME:
e->name = lua_tostring(L, 4);
value = &e->name;
break;
case HUD_STAT_SCALE:
e->scale = read_v2f(L, 4);
value = &e->scale;
break;
case HUD_STAT_TEXT:
e->text = lua_tostring(L, 4);
value = &e->text;
break;
case HUD_STAT_NUMBER:
e->number = lua_tonumber(L, 4);
value = &e->number;
break;
case HUD_STAT_ITEM:
e->item = lua_tonumber(L, 4);
value = &e->item;
break;
case HUD_STAT_DIR:
e->dir = lua_tonumber(L, 4);
value = &e->dir;
}
get_server(L)->hudChange(player, id, stat, value);
lua_pushboolean(L, true);
return 1;
}
// hud_get(self, id)
int ObjectRef::l_hud_get(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
u32 id = lua_tonumber(L, -1);
if (id >= player->hud.size())
return 0;
HudElement *e = player->hud[id];
if (!e)
return 0;
lua_newtable(L);
lua_pushstring(L, es_HudElementType[(u8)e->type].str);
lua_setfield(L, -2, "type");
push_v2f(L, e->pos);
lua_setfield(L, -2, "position");
lua_pushstring(L, e->name.c_str());
lua_setfield(L, -2, "name");
push_v2f(L, e->scale);
lua_setfield(L, -2, "scale");
lua_pushstring(L, e->text.c_str());
lua_setfield(L, -2, "text");
lua_pushnumber(L, e->number);
lua_setfield(L, -2, "number");
lua_pushnumber(L, e->item);
lua_setfield(L, -2, "item");
lua_pushnumber(L, e->dir);
lua_setfield(L, -2, "dir");
return 1;
}
ObjectRef::ObjectRef(ServerActiveObject *object): ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object) m_object(object)
@ -807,6 +990,12 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, get_inventory_formspec), luamethod(ObjectRef, get_inventory_formspec),
luamethod(ObjectRef, get_player_control), luamethod(ObjectRef, get_player_control),
luamethod(ObjectRef, get_player_control_bits), luamethod(ObjectRef, get_player_control_bits),
luamethod(ObjectRef, hud_add),
luamethod(ObjectRef, hud_remove),
luamethod(ObjectRef, hud_change),
luamethod(ObjectRef, hud_get),
//luamethod(ObjectRef, hud_lock_next_bar),
//luamethod(ObjectRef, hud_unlock_bar),
{0,0} {0,0}
}; };

@ -190,6 +190,18 @@ private:
// get_player_control_bits(self) // get_player_control_bits(self)
static int l_get_player_control_bits(lua_State *L); static int l_get_player_control_bits(lua_State *L);
// hud_add(self, id, form)
static int l_hud_add(lua_State *L);
// hud_rm(self, id)
static int l_hud_remove(lua_State *L);
// hud_change(self, id, stat, data)
static int l_hud_change(lua_State *L);
// hud_get(self, id)
static int l_hud_get(lua_State *L);
public: public:
ObjectRef(ServerActiveObject *object); ObjectRef(ServerActiveObject *object);

@ -42,6 +42,15 @@ void push_v3f(lua_State *L, v3f p)
lua_setfield(L, -2, "z"); lua_setfield(L, -2, "z");
} }
void push_v2f(lua_State *L, v2f p)
{
lua_newtable(L);
lua_pushnumber(L, p.X);
lua_setfield(L, -2, "x");
lua_pushnumber(L, p.Y);
lua_setfield(L, -2, "y");
}
v2s16 read_v2s16(lua_State *L, int index) v2s16 read_v2s16(lua_State *L, int index)
{ {
v2s16 p; v2s16 p;

@ -81,6 +81,7 @@ std::vector<aabb3f>
void push_v3s16 (lua_State *L, v3s16 p); void push_v3s16 (lua_State *L, v3s16 p);
void pushFloatPos (lua_State *L, v3f p); void pushFloatPos (lua_State *L, v3f p);
void push_v3f (lua_State *L, v3f p); void push_v3f (lua_State *L, v3f p);
void push_v2f (lua_State *L, v2f p);
MapNode readnode(lua_State *L, int index, INodeDefManager *ndef); MapNode readnode(lua_State *L, int index, INodeDefManager *ndef);

@ -904,6 +904,9 @@ Server::~Server()
*/ */
stop(); stop();
//shutdown all emerge threads first!
delete m_emerge;
/* /*
Delete clients Delete clients
*/ */
@ -923,7 +926,6 @@ Server::~Server()
// Delete things in the reverse order of creation // Delete things in the reverse order of creation
delete m_env; delete m_env;
delete m_rollback; delete m_rollback;
delete m_emerge;
delete m_event; delete m_event;
delete m_itemdef; delete m_itemdef;
delete m_nodedef; delete m_nodedef;
@ -3447,7 +3449,9 @@ void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
// Send as reliable // Send as reliable
m_con.Send(peer_id, 0, data, true); m_con.Send(peer_id, 0, data, true);
} }
void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname)
void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec,
const std::string formname)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -3468,7 +3472,9 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, co
} }
// Spawns a particle on peer with peer_id // Spawns a particle on peer with peer_id
void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture) void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection,
std::string texture)
{ {
DSTACK(__FUNCTION_NAME); DSTACK(__FUNCTION_NAME);
@ -3490,7 +3496,9 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
} }
// Spawns a particle on all peers // Spawns a particle on all peers
void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture) void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
float expirationtime, float size, bool collisiondetection,
std::string texture)
{ {
for(std::map<u16, RemoteClient*>::iterator for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin(); i = m_clients.begin();
@ -3593,6 +3601,76 @@ void Server::SendDeleteParticleSpawnerAll(u32 id)
} }
} }
void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
{
std::ostringstream os(std::ios_base::binary);
// Write command
writeU16(os, TOCLIENT_HUDADD);
writeU32(os, id);
writeU8(os, (u8)form->type);
writeV2F1000(os, form->pos);
os << serializeString(form->name);
writeV2F1000(os, form->scale);
os << serializeString(form->text);
writeU32(os, form->number);
writeU32(os, form->item);
writeU32(os, form->dir);
// 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::SendHUDRemove(u16 peer_id, u32 id)
{
std::ostringstream os(std::ios_base::binary);
// Write command
writeU16(os, TOCLIENT_HUDRM);
writeU32(os, id);
// 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::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value)
{
std::ostringstream os(std::ios_base::binary);
// Write command
writeU16(os, TOCLIENT_HUDCHANGE);
writeU32(os, id);
writeU8(os, (u8)stat);
switch (stat) {
case HUD_STAT_POS:
case HUD_STAT_SCALE:
writeV2F1000(os, *(v2f *)value);
break;
case HUD_STAT_NAME:
case HUD_STAT_TEXT:
os << serializeString(*(std::string *)value);
break;
case HUD_STAT_NUMBER:
case HUD_STAT_ITEM:
case HUD_STAT_DIR:
default:
writeU32(os, *(u32 *)value);
break;
}
// 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
@ -4546,6 +4624,39 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, c
return true; return true;
} }
u32 Server::hudAdd(Player *player, HudElement *form) {
if (!player)
return -1;
u32 id = hud_get_free_id(player);
if (id < player->hud.size())
player->hud[id] = form;
else
player->hud.push_back(form);
SendHUDAdd(player->peer_id, id, form);
return id;
}
bool Server::hudRemove(Player *player, u32 id) {
if (!player || id >= player->hud.size() || !player->hud[id])
return false;
delete player->hud[id];
player->hud[id] = NULL;
SendHUDRemove(player->peer_id, id);
return true;
}
bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data) {
if (!player)
return false;
SendHUDChange(player->peer_id, id, stat, data);
return true;
}
void Server::notifyPlayers(const std::wstring msg) void Server::notifyPlayers(const std::wstring msg)
{ {
BroadcastChatMessage(msg); BroadcastChatMessage(msg);

@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h" #include "map.h"
#include "inventory.h" #include "inventory.h"
#include "ban.h" #include "ban.h"
#include "hud.h"
#include "gamedef.h" #include "gamedef.h"
#include "serialization.h" // For SER_FMT_VER_INVALID #include "serialization.h" // For SER_FMT_VER_INVALID
#include "mods.h" #include "mods.h"
@ -51,6 +52,7 @@ class EventManager;
class PlayerSAO; class PlayerSAO;
class IRollbackManager; class IRollbackManager;
class EmergeManager; class EmergeManager;
//struct HudElement;
class ServerError : public std::exception class ServerError : public std::exception
{ {
@ -534,6 +536,11 @@ public:
} }
bool showFormspec(const char *name, const std::string &formspec, const std::string &formname); bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
u32 hudAdd(Player *player, HudElement *element);
bool hudRemove(Player *player, u32 id);
bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
private: private:
// con::PeerHandler implementation. // con::PeerHandler implementation.
@ -573,6 +580,9 @@ private:
void SendPlayerPrivileges(u16 peer_id); void SendPlayerPrivileges(u16 peer_id);
void SendPlayerInventoryFormspec(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id);
void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname); void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
void SendHUDRemove(u16 peer_id, u32 id);
void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
/* /*
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

@ -388,6 +388,12 @@ ShaderSource::ShaderSource(IrrlichtDevice *device):
ShaderSource::~ShaderSource() ShaderSource::~ShaderSource()
{ {
//m_shader_callback->drop(); //m_shader_callback->drop();
for (std::vector<IShaderConstantSetter*>::iterator iter = m_global_setters.begin();
iter != m_global_setters.end(); iter++) {
delete *iter;
}
m_global_setters.clear();
} }
u32 ShaderSource::getShaderId(const std::string &name) u32 ShaderSource::getShaderId(const std::string &name)

@ -49,6 +49,7 @@ struct ShaderInfo
video::E_MATERIAL_TYPE material; video::E_MATERIAL_TYPE material;
ShaderInfo(): name(""), material(video::EMT_SOLID) {} ShaderInfo(): name(""), material(video::EMT_SOLID) {}
virtual ~ShaderInfo() {}
}; };
/* /*

@ -271,6 +271,16 @@ public:
m_context = NULL; m_context = NULL;
alcCloseDevice(m_device); alcCloseDevice(m_device);
m_device = NULL; m_device = NULL;
for (std::map<std::string, std::vector<SoundBuffer*> >::iterator i = m_buffers.begin();
i != m_buffers.end(); i++) {
for (std::vector<SoundBuffer*>::iterator iter = (*i).second.begin();
iter != (*i).second.end(); iter++) {
delete *iter;
}
(*i).second.clear();
}
m_buffers.clear();
infostream<<"Audio: Deinitialized."<<std::endl; infostream<<"Audio: Deinitialized."<<std::endl;
} }

@ -1781,5 +1781,7 @@ void run_tests()
errorstream<<"run_tests() aborting."<<std::endl; errorstream<<"run_tests() aborting."<<std::endl;
abort(); abort();
} }
delete idef;
delete ndef;
} }

@ -201,6 +201,13 @@ struct SourceAtlasPointer
class SourceImageCache class SourceImageCache
{ {
public: public:
~SourceImageCache() {
for(std::map<std::string, video::IImage*>::iterator iter = m_images.begin();
iter != m_images.end(); iter++) {
iter->second->drop();
}
m_images.clear();
}
void insert(const std::string &name, video::IImage *img, void insert(const std::string &name, video::IImage *img,
bool prefer_local, video::IVideoDriver *driver) bool prefer_local, video::IVideoDriver *driver)
{ {
@ -209,23 +216,28 @@ public:
std::map<std::string, video::IImage*>::iterator n; std::map<std::string, video::IImage*>::iterator n;
n = m_images.find(name); n = m_images.find(name);
if(n != m_images.end()){ if(n != m_images.end()){
video::IImage *oldimg = n->second; if(n->second)
if(oldimg) n->second->drop();
oldimg->drop();
} }
video::IImage* toadd = img;
bool need_to_grab = true;
// Try to use local texture instead if asked to // Try to use local texture instead if asked to
if(prefer_local){ if(prefer_local){
std::string path = getTexturePath(name.c_str()); std::string path = getTexturePath(name.c_str());
if(path != ""){ if(path != ""){
video::IImage *img2 = driver->createImageFromFile(path.c_str()); video::IImage *img2 = driver->createImageFromFile(path.c_str());
if(img2){ if(img2){
m_images[name] = img2; toadd = img2;
return; need_to_grab = false;
} }
} }
} }
img->grab();
m_images[name] = img; if (need_to_grab)
toadd->grab();
m_images[name] = toadd;
} }
video::IImage* get(const std::string &name) video::IImage* get(const std::string &name)
{ {
@ -254,8 +266,7 @@ public:
infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path infostream<<"SourceImageCache::getOrLoad(): Loading path \""<<path
<<"\""<<std::endl; <<"\""<<std::endl;
video::IImage *img = driver->createImageFromFile(path.c_str()); video::IImage *img = driver->createImageFromFile(path.c_str());
// Even if could not be loaded, put as NULL
//m_images[name] = img;
if(img){ if(img){
m_images[name] = img; m_images[name] = img;
img->grab(); // Grab for caller img->grab(); // Grab for caller
@ -274,7 +285,7 @@ class TextureSource : public IWritableTextureSource
{ {
public: public:
TextureSource(IrrlichtDevice *device); TextureSource(IrrlichtDevice *device);
~TextureSource(); virtual ~TextureSource();
/* /*
Example case: Example case:
@ -454,6 +465,28 @@ TextureSource::TextureSource(IrrlichtDevice *device):
TextureSource::~TextureSource() TextureSource::~TextureSource()
{ {
video::IVideoDriver* driver = m_device->getVideoDriver();
unsigned int textures_before = driver->getTextureCount();
for (std::vector<SourceAtlasPointer>::iterator iter =
m_atlaspointer_cache.begin(); iter != m_atlaspointer_cache.end();
iter++)
{
video::ITexture *t = driver->getTexture(iter->name.c_str());
//cleanup texture
if (t)
driver->removeTexture(t);
//cleanup source image
if (iter->atlas_img)
iter->atlas_img->drop();
}
m_atlaspointer_cache.clear();
infostream << "~TextureSource() "<< textures_before << "/"
<< driver->getTextureCount() << std::endl;
} }
u32 TextureSource::getTextureId(const std::string &name) u32 TextureSource::getTextureId(const std::string &name)
@ -1205,7 +1238,6 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
core::dimension2d<u32> dim = image->getDimension(); core::dimension2d<u32> dim = image->getDimension();
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
image->copyTo(baseimg); image->copyTo(baseimg);
image->drop();
} }
// Else blit on base. // Else blit on base.
else else
@ -1224,9 +1256,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
video::SColor(255,255,255,255), video::SColor(255,255,255,255),
NULL);*/ NULL);*/
blit_with_alpha(image, baseimg, pos_from, pos_to, dim); blit_with_alpha(image, baseimg, pos_from, pos_to, dim);
// Drop image
image->drop();
} }
//cleanup
image->drop();
} }
else else
{ {
@ -1630,6 +1662,9 @@ bool generate_image(std::string part_of_name, video::IImage *& baseimg,
video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim); video::IImage *image = driver->createImage(rtt, v2s32(0,0), dim);
assert(image); assert(image);
//cleanup texture
driver->removeTexture(rtt);
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim); baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
if(image) if(image)

@ -5,7 +5,7 @@
<title>Minetest server list</title> <title>Minetest server list</title>
<link rel="stylesheet" href="style.css"/> <link rel="stylesheet" href="style.css"/>
</head> </head>
<body><div id="table"></div></body> <body><div id="servers_table"></div></body>
</html> </html>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="list.js"></script> <script src="list.js"></script>

@ -1,3 +1,5 @@
var master_root, output_to;
function e(s) { function e(s) {
if (typeof s === "undefined") s = ''; if (typeof s === "undefined") s = '';
return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); //mc" return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); //mc"
@ -39,7 +41,7 @@ function human_time(t, abs) {
function success(r) { function success(r) {
if (!r || !r.list) return; if (!r || !r.list) return;
var h = '<table class="mts_table"><tr class="mts_head"><th>ip[:port]</th><th>clients/max</th><th>version gameid</th><th>name</th><th>desc</th><th>flags</th><th>uptime</th><th>ping</th></tr>'; var h = '<table class="mts_table"><tr class="mts_head"><th>ip[:port]</th><th>clients/max</th><th>version gameid</th><th>name</th><th>description</th><th>flags</th><th>uptime</th><th>ping</th></tr>';
for (var i = 0; i < r.list.length; ++i) { for (var i = 0; i < r.list.length; ++i) {
var s = r.list[i]; var s = r.list[i];
if (!s) continue; if (!s) continue;
@ -60,9 +62,8 @@ function success(r) {
h += '</tr>'; h += '</tr>';
} }
h += '</table>' h += '</table>'
jQuery('#table').html(h); jQuery(output_to || '#servers_table').html(h);
} }
var master_root;
function get() { function get() {
jQuery.getJSON((master_root || '') + 'list', success); jQuery.getJSON((master_root || '') + 'list', success);