Merge branch 'master' into sphere
commit
7b9cf89c1d
36
.travis.yml
36
.travis.yml
|
@ -1,14 +1,4 @@
|
|||
language: cpp
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
env:
|
||||
- PLATFORM=Win32
|
||||
- PLATFORM=Win64
|
||||
- PLATFORM=Unix
|
||||
before_install: ./util/travis/before_install.sh
|
||||
script: ./util/travis/script.sh
|
||||
sudo: required
|
||||
|
@ -16,14 +6,26 @@ notifications:
|
|||
email: false
|
||||
matrix:
|
||||
fast_finish: true
|
||||
exclude:
|
||||
include:
|
||||
- env: PLATFORM=Win32
|
||||
compiler: clang
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Win64
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=clang
|
||||
compiler: clang
|
||||
- env: PLATFORM=Win32
|
||||
os: osx
|
||||
- env: PLATFORM=Win64
|
||||
os: osx
|
||||
- compiler: gcc
|
||||
os: osx
|
||||
- env: PLATFORM=Unix COMPILER=g++
|
||||
compiler: gcc
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=clang
|
||||
compiler: clang
|
||||
os: linux
|
||||
- env: PLATFORM=Unix COMPILER=g++-6
|
||||
compiler: gcc
|
||||
os: linux
|
||||
addons:
|
||||
apt:
|
||||
sources: &sources
|
||||
- ubuntu-toolchain-r-test
|
||||
|
|
63
README.txt
63
README.txt
|
@ -27,39 +27,47 @@ This game is not finished
|
|||
- Don't expect it to work as well as a finished game will.
|
||||
- Please report any bugs. When doing that, debug.txt is useful.
|
||||
|
||||
Default Controls
|
||||
Default controls
|
||||
-----------------
|
||||
- WASD: move
|
||||
- Space: jump/climb
|
||||
- Shift: sneak/go down
|
||||
- Q: drop itemstack (+ SHIFT for single item)
|
||||
- I: inventory
|
||||
- Mouse: turn/look
|
||||
- Mouse left: dig/punch
|
||||
- Mouse right: place/use
|
||||
- Mouse wheel: select item
|
||||
- T: chat
|
||||
- 1-8: select item
|
||||
- Move mouse: Look around
|
||||
- W, A, S, D: Move
|
||||
- Space: Jump/move up
|
||||
- Shift: Sneak/move down
|
||||
- Q: Drop itemstack
|
||||
- Shift + Q: Drop single item
|
||||
- Left mouse button: Dig/punch/take item
|
||||
- Right mouse button: Place/use
|
||||
- Shift + right mouse button: Build (without using)
|
||||
- I: Inventory menu
|
||||
- Mouse wheel: Select item
|
||||
- 0-9: Select item
|
||||
- Z: Zoom (needs zoom privilege)
|
||||
- T: Chat
|
||||
- /: Commad
|
||||
|
||||
- Esc: pause menu (pauses only singleplayer game)
|
||||
- R: Enable/Disable full range view
|
||||
- Esc: Pause menu/abort/exit (pauses only singleplayer game)
|
||||
- R: Enable/disable full range view
|
||||
- +: Increase view range
|
||||
- -: Decrease view range
|
||||
- K: Enable/Disable fly (needs fly privilege)
|
||||
- J: Enable/Disable fast (needs fast privilege)
|
||||
- H: Enable/Disable noclip (needs noclip privilege)
|
||||
- K: Enable/disable fly mode (needs fly privilege)
|
||||
- J: Enable/disable fast mode (needs fast privilege)
|
||||
- H: Enable/disable noclip mode (needs noclip privilege)
|
||||
|
||||
- F1: Hide/Show HUD
|
||||
- F2: Hide/Show Chat
|
||||
- F3: Disable/Enable Fog
|
||||
- F4: Disable/Enable Camera update (Mapblocks are not updated anymore when disabled)
|
||||
- F5: Toogle through debug info screens
|
||||
- F6: Toogle through output data
|
||||
- F7: Toggle through camera modes
|
||||
- F10: Show/Hide console
|
||||
- F1: Hide/show HUD
|
||||
- F2: Hide/show chat
|
||||
- F3: Disable/enable fog
|
||||
- F4: Disable/enable camera update (Mapblocks are not updated anymore when disabled, disabled in release builds)
|
||||
- F5: Cycle through debug info screens
|
||||
- F6: Cycle through profiler info screens
|
||||
- F7: Cycle through camera modes
|
||||
- F8: Toggle cinematic mode
|
||||
- F9: Cycle through minimap modes
|
||||
- Shift + F9: Change minimap orientation
|
||||
- F10: Show/hide console
|
||||
- F12: Take screenshot
|
||||
- P: Write stack traces into debug.txt
|
||||
|
||||
- Settable in the configuration file, see the section below.
|
||||
Most controls are settable in the configuration file, see the section below.
|
||||
|
||||
Paths
|
||||
------
|
||||
|
@ -403,6 +411,9 @@ Authors of media files
|
|||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
ShadowNinja:
|
||||
textures/base/pack/smoke_puff.png
|
||||
|
||||
Paramat:
|
||||
textures/base/pack/menu_header.png
|
||||
|
||||
|
|
|
@ -19,4 +19,9 @@ core.EMERGE_FROM_DISK = 3
|
|||
core.EMERGE_GENERATED = 4
|
||||
|
||||
-- constants.h
|
||||
-- Size of mapblocks in nodes
|
||||
core.MAP_BLOCKSIZE = 16
|
||||
|
||||
-- light.h
|
||||
-- Maximum value for node 'light_source' parameter
|
||||
core.LIGHT_MAX = 14
|
||||
|
|
|
@ -130,7 +130,11 @@ function check_attached_node(p, n)
|
|||
local def = core.registered_nodes[n.name]
|
||||
local d = {x = 0, y = 0, z = 0}
|
||||
if def.paramtype2 == "wallmounted" then
|
||||
d = core.wallmounted_to_dir(n.param2)
|
||||
-- The fallback vector here is in case 'wallmounted to dir' is nil due
|
||||
-- to voxelmanip placing a wallmounted node without resetting a
|
||||
-- pre-existing param2 value that is out-of-range for wallmounted.
|
||||
-- The fallback vector corresponds to param2 = 0.
|
||||
d = core.wallmounted_to_dir(n.param2) or {x = 0, y = 1, z = 0}
|
||||
else
|
||||
d.y = -1
|
||||
end
|
||||
|
|
|
@ -5,6 +5,7 @@ core.forceload_block = nil
|
|||
core.forceload_free_block = nil
|
||||
|
||||
local blocks_forceloaded
|
||||
local blocks_temploaded = {}
|
||||
local total_forceloaded = 0
|
||||
|
||||
local BLOCKSIZE = core.MAP_BLOCKSIZE
|
||||
|
@ -15,32 +16,52 @@ local function get_blockpos(pos)
|
|||
z = math.floor(pos.z/BLOCKSIZE)}
|
||||
end
|
||||
|
||||
function core.forceload_block(pos)
|
||||
-- When we create/free a forceload, it's either transient or persistent. We want
|
||||
-- to add to/remove from the table that corresponds to the type of forceload, but
|
||||
-- we also need the other table because whether we forceload a block depends on
|
||||
-- both tables.
|
||||
-- This function returns the "primary" table we are adding to/removing from, and
|
||||
-- the other table.
|
||||
local function get_relevant_tables(transient)
|
||||
if transient then
|
||||
return blocks_temploaded, blocks_forceloaded
|
||||
else
|
||||
return blocks_forceloaded, blocks_temploaded
|
||||
end
|
||||
end
|
||||
|
||||
function core.forceload_block(pos, transient)
|
||||
local blockpos = get_blockpos(pos)
|
||||
local hash = core.hash_node_position(blockpos)
|
||||
if blocks_forceloaded[hash] ~= nil then
|
||||
blocks_forceloaded[hash] = blocks_forceloaded[hash] + 1
|
||||
local relevant_table, other_table = get_relevant_tables(transient)
|
||||
if relevant_table[hash] ~= nil then
|
||||
relevant_table[hash] = relevant_table[hash] + 1
|
||||
return true
|
||||
elseif other_table[hash] ~= nil then
|
||||
relevant_table[hash] = 1
|
||||
else
|
||||
if total_forceloaded >= (tonumber(core.setting_get("max_forceloaded_blocks")) or 16) then
|
||||
return false
|
||||
end
|
||||
total_forceloaded = total_forceloaded+1
|
||||
blocks_forceloaded[hash] = 1
|
||||
relevant_table[hash] = 1
|
||||
forceload_block(blockpos)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function core.forceload_free_block(pos)
|
||||
function core.forceload_free_block(pos, transient)
|
||||
local blockpos = get_blockpos(pos)
|
||||
local hash = core.hash_node_position(blockpos)
|
||||
if blocks_forceloaded[hash] == nil then return end
|
||||
if blocks_forceloaded[hash] > 1 then
|
||||
blocks_forceloaded[hash] = blocks_forceloaded[hash] - 1
|
||||
local relevant_table, other_table = get_relevant_tables(transient)
|
||||
if relevant_table[hash] == nil then return end
|
||||
if relevant_table[hash] > 1 then
|
||||
relevant_table[hash] = relevant_table[hash] - 1
|
||||
elseif other_table[hash] ~= nil then
|
||||
relevant_table[hash] = nil
|
||||
else
|
||||
total_forceloaded = total_forceloaded-1
|
||||
blocks_forceloaded[hash] = nil
|
||||
relevant_table[hash] = nil
|
||||
forceload_free_block(blockpos)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,7 +38,7 @@ core.register_globalstep(function(dtime)
|
|||
end)
|
||||
|
||||
function core.after(after, func, ...)
|
||||
assert(tonumber(time) and type(func) == "function",
|
||||
assert(tonumber(after) and type(func) == "function",
|
||||
"Invalid core.after invocation")
|
||||
jobs[#jobs + 1] = {
|
||||
func = func,
|
||||
|
|
|
@ -127,6 +127,11 @@ function core.register_item(name, itemdef)
|
|||
fixed = {-1/8, -1/2, -1/8, 1/8, 1/2, 1/8},
|
||||
}
|
||||
end
|
||||
if itemdef.light_source and itemdef.light_source > core.LIGHT_MAX then
|
||||
itemdef.light_source = core.LIGHT_MAX
|
||||
core.log("warning", "Node 'light_source' value exceeds maximum," ..
|
||||
" limiting to maximum: " ..name)
|
||||
end
|
||||
setmetatable(itemdef, {__index = core.nodedef_default})
|
||||
core.registered_nodes[itemdef.name] = itemdef
|
||||
elseif itemdef.type == "craft" then
|
||||
|
|
|
@ -659,5 +659,12 @@ function create_adv_settings_dlg()
|
|||
return dlg
|
||||
end
|
||||
|
||||
-- generate minetest.conf.example and settings_translation_file.cpp:
|
||||
-- Generate minetest.conf.example and settings_translation_file.cpp
|
||||
|
||||
-- *** Please note ***
|
||||
-- There is text in minetest.conf.example that will not be generated from
|
||||
-- settingtypes.txt but must be preserved:
|
||||
-- The documentation of mapgen noise parameter formats (title plus 16 lines)
|
||||
-- Noise parameter 'mgv5_np_ground' in group format (13 lines)
|
||||
|
||||
--assert(loadfile(core.get_mainmenu_path()..DIR_DELIM.."generate_from_settingtypes.lua"))(parse_config_file(true, false))
|
||||
|
|
|
@ -73,7 +73,7 @@ local function get_formspec(tabview, name, tabdata)
|
|||
if not file_exists(infofile) then
|
||||
infofile = current_texture_path .. DIR_DELIM .. "info.txt"
|
||||
if file_exists(infofile) then
|
||||
core.log("info.txt is depreciated. description.txt should be used instead.")
|
||||
core.log("deprecated", "info.txt is deprecated. description.txt should be used instead.")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -561,13 +561,13 @@ freetype (Freetype fonts) bool true
|
|||
# Path to TrueTypeFont or bitmap.
|
||||
font_path (Font path) path fonts/liberationsans.ttf
|
||||
|
||||
font_size (Font size) int 15
|
||||
font_size (Font size) int 16
|
||||
|
||||
# Font shadow offset, if 0 then shadow will not be drawn.
|
||||
font_shadow (Font shadow) int 1
|
||||
|
||||
# Font shadow alpha (opaqueness, between 0 and 255).
|
||||
font_shadow_alpha (Font shadow alpha) int 128 0 255
|
||||
font_shadow_alpha (Font shadow alpha) int 127 0 255
|
||||
|
||||
mono_font_path (Monospace font path) path fonts/liberationmono.ttf
|
||||
|
||||
|
@ -774,6 +774,15 @@ time_speed (Time speed) int 72
|
|||
# Interval of saving important changes in the world, stated in seconds.
|
||||
server_map_save_interval (Map save interval) float 5.3
|
||||
|
||||
# Set the maximum character length of a chat message sent by clients.
|
||||
# chat_message_max_size int 500
|
||||
|
||||
# Limit a single player to send X messages per 10 seconds.
|
||||
# chat_message_limit_per_10sec float 10.0
|
||||
|
||||
# Kick player if send more than X messages per 10 seconds.
|
||||
# chat_message_limit_trigger_kick int 50
|
||||
|
||||
[**Physics]
|
||||
|
||||
movement_acceleration_default (Default acceleration) float 3
|
||||
|
|
|
@ -263,7 +263,17 @@ Textures can be grouped together by enclosing them in `(` and `)`.
|
|||
Example: `cobble.png^(thing1.png^thing2.png)`
|
||||
|
||||
A texture for `thing1.png^thing2.png` is created and the resulting
|
||||
texture is overlaid over `cobble.png`.
|
||||
texture is overlaid on top of `cobble.png`.
|
||||
|
||||
### Escaping
|
||||
Modifiers that accept texture names (e.g. `[combine`) accept escaping to allow
|
||||
passing complex texture names as arguments. Escaping is done with backslash and
|
||||
is required for `^` and `:`.
|
||||
|
||||
Example: `cobble.png^[lowpart:50:color.png\^[mask\:trans.png`
|
||||
|
||||
The lower 50 percent of `color.png^[mask:trans.png` are overlaid
|
||||
on top of `cobble.png`.
|
||||
|
||||
### Advanced texture modifiers
|
||||
|
||||
|
@ -308,6 +318,15 @@ Example:
|
|||
|
||||
default_sandstone.png^[opacity:127
|
||||
|
||||
#### `[invert:<mode>`
|
||||
Inverts the given channels of the base image.
|
||||
Mode may contain the characters "r", "g", "b", "a".
|
||||
Only the channels that are mentioned in the mode string will be inverted.
|
||||
|
||||
Example:
|
||||
|
||||
default_apple.png^[invert:rgb
|
||||
|
||||
#### `[brighten`
|
||||
Brightens the texture.
|
||||
|
||||
|
@ -351,7 +370,7 @@ Example:
|
|||
default_stone.png^[transformFXR90
|
||||
|
||||
#### `[inventorycube{<top>{<left>{<right>`
|
||||
`^` is replaced by `&` in texture names.
|
||||
Escaping does not apply here and `^` is replaced by `&` in texture names instead.
|
||||
|
||||
Create an inventory cube texture using the side textures.
|
||||
|
||||
|
@ -1450,6 +1469,15 @@ examples.
|
|||
* `fixed_size`: `true`/`false` (optional)
|
||||
* deprecated: `invsize[<W>,<H>;]`
|
||||
|
||||
#### `container[<X>,<Y>]`
|
||||
* Start of a container block, moves all physical elements in the container by (X, Y)
|
||||
* Must have matching container_end
|
||||
* Containers can be nested, in which case the offsets are added
|
||||
(child containers are relative to parent containers)
|
||||
|
||||
#### `container_end[]`
|
||||
* End of a container, following elements are no longer relative to this container
|
||||
|
||||
#### `list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;]`
|
||||
* Show an inventory list
|
||||
|
||||
|
@ -2594,13 +2622,17 @@ These functions return the leftover itemstack.
|
|||
the creative mode setting, and checks for "sneak" to set the `invert_wall`
|
||||
parameter.
|
||||
|
||||
* `minetest.forceload_block(pos)`
|
||||
* `minetest.forceload_block(pos[, transient])`
|
||||
* forceloads the position `pos`.
|
||||
* returns `true` if area could be forceloaded
|
||||
* Please note that forceloaded areas are saved when the server restarts.
|
||||
* If `transient` is `false` or absent, the forceload will be persistent
|
||||
(saved between server runs). If `true`, the forceload will be transient
|
||||
(not saved between server runs).
|
||||
|
||||
* `minetest.forceload_free_block(pos)`
|
||||
* `minetest.forceload_free_block(pos[, transient])`
|
||||
* stops forceloading the position `pos`
|
||||
* If `transient` is `false` or absent, frees a persistent forceload.
|
||||
If `true`, frees a transient forceload.
|
||||
|
||||
* `minetest.request_insecure_environment()`: returns an environment containing
|
||||
insecure functions if the calling mod has been listed as trusted in the
|
||||
|
@ -2886,6 +2918,7 @@ chosen for you.
|
|||
#### Methods
|
||||
* `get_area(id, include_borders, include_data)`: returns the area with the id `id`.
|
||||
(optional) Boolean values `include_borders` and `include_data` control what's copied.
|
||||
Returns nil if specified area id does not exist.
|
||||
* `get_areas_for_pos(pos, include_borders, include_data)`: returns all areas that contain
|
||||
the position `pos`. (optional) Boolean values `include_borders` and `include_data` control
|
||||
what's copied.
|
||||
|
@ -3328,13 +3361,15 @@ Registered entities
|
|||
* It has the member `.object`, which is an `ObjectRef` pointing to the object
|
||||
* The original prototype stuff is visible directly via a metatable
|
||||
* Callbacks:
|
||||
* `on_activate(self, staticdata)`
|
||||
* `on_activate(self, staticdata, dtime_s)`
|
||||
* Called when the object is instantiated.
|
||||
* `dtime_s` is the time passed since the object was unloaded, which can
|
||||
be used for updating the entity state.
|
||||
* `on_step(self, dtime)`
|
||||
* Called on every server tick, after movement and collision processing.
|
||||
`dtime` is usually 0.1 seconds, as per the `dedicated_server_step` setting
|
||||
`in minetest.conf`.
|
||||
* `on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir`
|
||||
* `on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir)`
|
||||
* Called when somebody punches the object.
|
||||
* Note that you probably want to handle most punches using the
|
||||
automatic armor group system.
|
||||
|
@ -3462,7 +3497,7 @@ Definition tables
|
|||
|
||||
on_activate = function(self, staticdata, dtime_s),
|
||||
on_step = function(self, dtime),
|
||||
on_punch = function(self, hitter),
|
||||
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir),
|
||||
on_rightclick = function(self, clicker),
|
||||
get_staticdata = function(self),
|
||||
-- ^ Called sometimes; the string returned is passed to on_activate when
|
||||
|
@ -3642,7 +3677,10 @@ Definition tables
|
|||
^ Don't forget to use "leveled" type nodebox. ]]
|
||||
liquid_range = 8, -- number of flowing nodes around source (max. 8)
|
||||
drowning = 0, -- Player will take this amount of damage if no bubbles are left
|
||||
light_source = 0, -- Amount of light emitted by node
|
||||
light_source = 0, --[[
|
||||
^ Amount of light emitted by node.
|
||||
^ To set the maximum (currently 14), use the value 'minetest.LIGHT_MAX'.
|
||||
^ A value outside the range 0 to minetest.LIGHT_MAX causes undefined behavior.]]
|
||||
damage_per_second = 0, -- If player is inside node, this damage is caused
|
||||
node_box = {type="regular"}, -- See "Node boxes"
|
||||
connects_to = nodenames, --[[
|
||||
|
@ -3896,7 +3934,7 @@ The Biome API is still in an experimental phase and subject to change.
|
|||
{
|
||||
deco_type = "simple", -- See "Decoration types"
|
||||
place_on = "default:dirt_with_grass",
|
||||
-- ^ Node that decoration can be placed on
|
||||
-- ^ Node (or list of nodes) that the decoration can be placed on
|
||||
sidelen = 8,
|
||||
-- ^ Size of divisions made in the chunk being generated.
|
||||
-- ^ If the chunk size is not evenly divisible by sidelen, sidelen is made equal to the chunk size.
|
||||
|
@ -3915,6 +3953,13 @@ The Biome API is still in an experimental phase and subject to change.
|
|||
-- ^ Minimum and maximum `y` positions these decorations can be generated at.
|
||||
-- ^ This parameter refers to the `y` position of the decoration base, so
|
||||
-- the actual maximum height would be `height_max + size.Y`.
|
||||
spawn_by = "default:water",
|
||||
-- ^ Node (or list of nodes) that the decoration only spawns next to.
|
||||
-- ^ Checks two horizontal planes of neighbouring nodes (including diagonal neighbours),
|
||||
-- ^ one plane at Y = surface and one plane at Y = surface = + 1.
|
||||
num_spawn_by = 1,
|
||||
-- ^ Number of spawn_by nodes that must be surrounding the decoration position to occur.
|
||||
-- ^ If absent or -1, decorations occur next to any nodes.
|
||||
flags = "liquid_surface, force_placement",
|
||||
-- ^ Flags for all decoration types.
|
||||
-- ^ "liquid_surface": Instead of placement on the highest solid surface
|
||||
|
@ -3932,13 +3977,6 @@ The Biome API is still in an experimental phase and subject to change.
|
|||
height_max = 0,
|
||||
-- ^ Number of nodes the decoration can be at maximum.
|
||||
-- ^ If absent, the parameter 'height' is used as a constant.
|
||||
spawn_by = "default:water",
|
||||
-- ^ Node that the decoration only spawns next to.
|
||||
-- ^ The neighbours checked are the 8 nodes horizontally surrounding the lowest node of the
|
||||
-- ^ decoration, and the 8 nodes horizontally surrounding the ground node below the decoration.
|
||||
num_spawn_by = 1,
|
||||
-- ^ Number of spawn_by nodes that must be surrounding the decoration position to occur.
|
||||
-- ^ If absent or -1, decorations occur next to any nodes.
|
||||
|
||||
----- Schematic-type parameters
|
||||
schematic = "foobar.mts",
|
||||
|
|
|
@ -655,7 +655,7 @@
|
|||
# font_path = fonts/liberationsans.ttf
|
||||
|
||||
# type: int
|
||||
# font_size = 15
|
||||
# font_size = 16
|
||||
|
||||
# Font shadow offset, if 0 then shadow will not be drawn.
|
||||
# type: int
|
||||
|
@ -663,7 +663,7 @@
|
|||
|
||||
# Font shadow alpha (opaqueness, between 0 and 255).
|
||||
# type: int min: 0 max: 255
|
||||
# font_shadow_alpha = 128
|
||||
# font_shadow_alpha = 127
|
||||
|
||||
# type: path
|
||||
# mono_font_path = fonts/liberationmono.ttf
|
||||
|
@ -933,6 +933,18 @@
|
|||
# type: float
|
||||
# server_map_save_interval = 5.3
|
||||
|
||||
# Set the maximum character length of a chat message sent by clients. (0 to disable)
|
||||
# type: integer
|
||||
# chat_message_max_size = 500
|
||||
|
||||
# Limit a single player to send X messages per 10 seconds. (0 to disable)
|
||||
# type: float
|
||||
# chat_message_limit_per_10sec = 8.0
|
||||
|
||||
# Kick player if send more than X messages per 10 seconds. (0 to disable)
|
||||
# type: integer
|
||||
# chat_message_limit_trigger_kick = 50
|
||||
|
||||
### Physics
|
||||
|
||||
# type: float
|
||||
|
@ -1099,6 +1111,25 @@
|
|||
# type: int
|
||||
# num_emerge_threads = 1
|
||||
|
||||
#### Noise parameters and formats
|
||||
|
||||
# Noise parameters can be specified as a set of positional values, for example:
|
||||
# Offset, scale, (spread factors), seed offset, number of octaves, persistence, lacunarity
|
||||
# mgv6_np_terrain_base = -4, 20, (250, 250, 250), 82341, 5, 0.6, 2.0
|
||||
# Or the group format can be used instead, for example:
|
||||
# mgv6_np_terrain_base = {
|
||||
# offset = -4,
|
||||
# scale = 20,
|
||||
# spread = (250, 250, 250),
|
||||
# seed = 82341,
|
||||
# octaves = 5,
|
||||
# persistence = 0.6,
|
||||
# lacunarity = 2.0,
|
||||
# flags = "defaults"
|
||||
# }
|
||||
# Only the group format supports noise flags which are needed for eased noise.
|
||||
# Mgv5 uses eased noise for np_ground so this is shown in group format below.
|
||||
|
||||
# Noise parameters for biome API temperature, humidity and biome blend.
|
||||
# type: noise_params
|
||||
# mg_biome_np_heat = 50, 50, (750, 750, 750), 5349, 3, 0.5, 2.0
|
||||
|
@ -1133,6 +1164,20 @@
|
|||
# type: noise_params
|
||||
# mgv5_np_cave2 = 0, 12, (50, 50, 50), 10325, 4, 0.5, 2.0
|
||||
|
||||
# Noise parameters in group format, unsupported by advanced settings
|
||||
# menu but settable in minetest.conf.
|
||||
# See documentation of noise parameter formats above.
|
||||
# mgv5_np_ground = {
|
||||
# offset = 0,
|
||||
# scale = 40,
|
||||
# spread = (80, 80, 80),
|
||||
# seed = 983240,
|
||||
# octaves = 4,
|
||||
# persistence = 0.55,
|
||||
# lacunarity = 2.0,
|
||||
# flags = "eased"
|
||||
# }
|
||||
|
||||
#### Mapgen v6
|
||||
|
||||
# Map generation attributes specific to Mapgen v6.
|
||||
|
@ -1490,7 +1535,7 @@
|
|||
# profiler.default_report_format = txt
|
||||
|
||||
# The file path relative to your worldpath in which profiles will be saved to.
|
||||
#
|
||||
#
|
||||
# type: string
|
||||
# profiler.report_path = ""
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.6)
|
|||
project(minetest)
|
||||
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
|
||||
# Add custom SemiDebug build mode
|
||||
set(CMAKE_CXX_FLAGS_SEMIDEBUG "-O1 -g -Wall -Wabi" CACHE STRING
|
||||
|
@ -292,9 +293,10 @@ if(WIN32)
|
|||
set(ZLIB_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/../../zlib/zlib-1.2.5"
|
||||
CACHE PATH "Zlib include directory")
|
||||
set(ZLIB_LIBRARIES "${PROJECT_SOURCE_DIR}/../../zlib125dll/dll32/zlibwapi.lib"
|
||||
CACHE FILEPATH "Path to zlibwapi.lib")
|
||||
CACHE FILEPATH "Path to zlib library (usually zlibwapi.lib)")
|
||||
set(ZLIB_DLL "${PROJECT_SOURCE_DIR}/../../zlib125dll/dll32/zlibwapi.dll"
|
||||
CACHE FILEPATH "Path to zlibwapi.dll (for installation)")
|
||||
CACHE FILEPATH "Path to zlib DLL (for installation)")
|
||||
set(ZLIBWAPI_DLL "" CACHE FILEPATH "Path to zlibwapi DLL")
|
||||
set(IRRLICHT_SOURCE_DIR "${PROJECT_SOURCE_DIR}/../../irrlicht-1.7.2"
|
||||
CACHE PATH "irrlicht dir")
|
||||
if(USE_FREETYPE)
|
||||
|
@ -536,6 +538,7 @@ set(client_SRCS
|
|||
sky.cpp
|
||||
wieldmesh.cpp
|
||||
${client_SCRIPT_SRCS}
|
||||
${UNITTEST_CLIENT_SRCS}
|
||||
)
|
||||
list(SORT client_SRCS)
|
||||
|
||||
|
@ -722,8 +725,14 @@ else()
|
|||
set(OTHER_FLAGS "${OTHER_FLAGS} -Wsign-compare")
|
||||
endif()
|
||||
|
||||
if(NOT ZLIBWAPI_DLL AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
set(OTHER_FLAGS "${OTHER_FLAGS} -DWIN32_NO_ZLIB_WINAPI")
|
||||
message(WARNING "Defaulting to cdecl for zlib on win32 because ZLIBWAPI_DLL"
|
||||
" isn't set, ensure that ZLIBWAPI_DLL is set if you want stdcall.")
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
set(OTHER_FLAGS "-mthreads -fexceptions")
|
||||
set(OTHER_FLAGS "${OTHER_FLAGS} -mthreads -fexceptions")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${RELEASE_WARNING_FLAGS} ${WARNING_FLAGS} ${OTHER_FLAGS} -ffast-math -Wall -pipe -funroll-loops")
|
||||
|
|
|
@ -303,7 +303,7 @@ Client::~Client()
|
|||
delete m_inventory_from_server;
|
||||
|
||||
// Delete detached inventories
|
||||
for (std::map<std::string, Inventory*>::iterator
|
||||
for (UNORDERED_MAP<std::string, Inventory*>::iterator
|
||||
i = m_detached_inventories.begin();
|
||||
i != m_detached_inventories.end(); ++i) {
|
||||
delete i->second;
|
||||
|
@ -1437,7 +1437,7 @@ Inventory* Client::getInventory(const InventoryLocation &loc)
|
|||
break;
|
||||
case InventoryLocation::DETACHED:
|
||||
{
|
||||
if(m_detached_inventories.count(loc.name) == 0)
|
||||
if (m_detached_inventories.count(loc.name) == 0)
|
||||
return NULL;
|
||||
return m_detached_inventories[loc.name];
|
||||
}
|
||||
|
|
|
@ -462,7 +462,7 @@ public:
|
|||
u16 getHP();
|
||||
u16 getBreath();
|
||||
|
||||
bool checkPrivilege(const std::string &priv)
|
||||
bool checkPrivilege(const std::string &priv) const
|
||||
{ return (m_privileges.count(priv) != 0); }
|
||||
|
||||
bool getChatMessage(std::wstring &message);
|
||||
|
@ -670,11 +670,11 @@ private:
|
|||
std::map<int, u16> m_sounds_to_objects;
|
||||
|
||||
// Privileges
|
||||
std::set<std::string> m_privileges;
|
||||
UNORDERED_SET<std::string> m_privileges;
|
||||
|
||||
// Detached inventories
|
||||
// key = name
|
||||
std::map<std::string, Inventory*> m_detached_inventories;
|
||||
UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
|
||||
|
||||
// Storage for mesh data for creating multiple instances of the same mesh
|
||||
StringMap m_mesh_data;
|
||||
|
|
|
@ -948,11 +948,10 @@ video::ITexture* TextureSource::generateTextureFromMesh(
|
|||
|
||||
video::IImage* TextureSource::generateImage(const std::string &name)
|
||||
{
|
||||
/*
|
||||
Get the base image
|
||||
*/
|
||||
// Get the base image
|
||||
|
||||
const char separator = '^';
|
||||
const char escape = '\\';
|
||||
const char paren_open = '(';
|
||||
const char paren_close = ')';
|
||||
|
||||
|
@ -960,7 +959,9 @@ video::IImage* TextureSource::generateImage(const std::string &name)
|
|||
s32 last_separator_pos = -1;
|
||||
u8 paren_bal = 0;
|
||||
for (s32 i = name.size() - 1; i >= 0; i--) {
|
||||
switch(name[i]) {
|
||||
if (i > 0 && name[i-1] == escape)
|
||||
continue;
|
||||
switch (name[i]) {
|
||||
case separator:
|
||||
if (paren_bal == 0) {
|
||||
last_separator_pos = i;
|
||||
|
@ -1028,10 +1029,12 @@ video::IImage* TextureSource::generateImage(const std::string &name)
|
|||
return NULL;
|
||||
}
|
||||
core::dimension2d<u32> dim = tmp->getDimension();
|
||||
if (!baseimg)
|
||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
|
||||
blit_with_alpha(tmp, baseimg, v2s32(0, 0), v2s32(0, 0), dim);
|
||||
tmp->drop();
|
||||
if (baseimg) {
|
||||
blit_with_alpha(tmp, baseimg, v2s32(0, 0), v2s32(0, 0), dim);
|
||||
tmp->drop();
|
||||
} else {
|
||||
baseimg = tmp;
|
||||
}
|
||||
} else if (!generateImagePart(last_part_of_name, baseimg)) {
|
||||
// Generate image according to part of name
|
||||
errorstream << "generateImage(): "
|
||||
|
@ -1099,9 +1102,27 @@ video::IImage * Align2Npot2(video::IImage * image,
|
|||
|
||||
#endif
|
||||
|
||||
static std::string unescape_string(const std::string &str, const char esc = '\\')
|
||||
{
|
||||
std::string out;
|
||||
size_t pos = 0, cpos;
|
||||
out.reserve(str.size());
|
||||
while (1) {
|
||||
cpos = str.find_first_of(esc, pos);
|
||||
if (cpos == std::string::npos) {
|
||||
out += str.substr(pos);
|
||||
break;
|
||||
}
|
||||
out += str.substr(pos, cpos - pos) + str[cpos + 1];
|
||||
pos = cpos + 2;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool TextureSource::generateImagePart(std::string part_of_name,
|
||||
video::IImage *& baseimg)
|
||||
{
|
||||
const char escape = '\\'; // same as in generateImage()
|
||||
video::IVideoDriver* driver = m_device->getVideoDriver();
|
||||
sanity_check(driver);
|
||||
|
||||
|
@ -1251,7 +1272,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
}
|
||||
/*
|
||||
[combine:WxH:X,Y=filename:X,Y=filename2
|
||||
Creates a bigger texture from an amount of smaller ones
|
||||
Creates a bigger texture from any amount of smaller ones
|
||||
*/
|
||||
else if (str_starts_with(part_of_name, "[combine"))
|
||||
{
|
||||
|
@ -1259,7 +1280,6 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
sf.next(":");
|
||||
u32 w0 = stoi(sf.next("x"));
|
||||
u32 h0 = stoi(sf.next(":"));
|
||||
//infostream<<"combined w="<<w0<<" h="<<h0<<std::endl;
|
||||
core::dimension2d<u32> dim(w0,h0);
|
||||
if (baseimg == NULL) {
|
||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, dim);
|
||||
|
@ -1268,11 +1288,11 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
while (sf.at_end() == false) {
|
||||
u32 x = stoi(sf.next(","));
|
||||
u32 y = stoi(sf.next("="));
|
||||
std::string filename = sf.next(":");
|
||||
std::string filename = unescape_string(sf.next_esc(":", escape), escape);
|
||||
infostream<<"Adding \""<<filename
|
||||
<<"\" to combined ("<<x<<","<<y<<")"
|
||||
<<std::endl;
|
||||
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
|
||||
video::IImage *img = generateImage(filename);
|
||||
if (img) {
|
||||
core::dimension2d<u32> dim = img->getDimension();
|
||||
infostream<<"Size "<<dim.Width
|
||||
|
@ -1295,7 +1315,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
}
|
||||
}
|
||||
/*
|
||||
"[brighten"
|
||||
[brighten
|
||||
*/
|
||||
else if (str_starts_with(part_of_name, "[brighten"))
|
||||
{
|
||||
|
@ -1309,7 +1329,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
brighten(baseimg);
|
||||
}
|
||||
/*
|
||||
"[noalpha"
|
||||
[noalpha
|
||||
Make image completely opaque.
|
||||
Used for the leaves texture when in old leaves mode, so
|
||||
that the transparent parts don't look completely black
|
||||
|
@ -1336,7 +1356,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
}
|
||||
}
|
||||
/*
|
||||
"[makealpha:R,G,B"
|
||||
[makealpha:R,G,B
|
||||
Convert one color to transparent.
|
||||
*/
|
||||
else if (str_starts_with(part_of_name, "[makealpha:"))
|
||||
|
@ -1375,7 +1395,7 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
}
|
||||
}
|
||||
/*
|
||||
"[transformN"
|
||||
[transformN
|
||||
Rotates and/or flips the image.
|
||||
|
||||
N can be a number (between 0 and 7) or a transform name.
|
||||
|
@ -1543,12 +1563,11 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
Strfnd sf(part_of_name);
|
||||
sf.next(":");
|
||||
u32 percent = stoi(sf.next(":"));
|
||||
std::string filename = sf.next(":");
|
||||
//infostream<<"power part "<<percent<<"%% of "<<filename<<std::endl;
|
||||
std::string filename = unescape_string(sf.next_esc(":", escape), escape);
|
||||
|
||||
if (baseimg == NULL)
|
||||
baseimg = driver->createImage(video::ECF_A8R8G8B8, v2u32(16,16));
|
||||
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
|
||||
video::IImage *img = generateImage(filename);
|
||||
if (img)
|
||||
{
|
||||
core::dimension2d<u32> dim = img->getDimension();
|
||||
|
@ -1628,9 +1647,9 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
}
|
||||
Strfnd sf(part_of_name);
|
||||
sf.next(":");
|
||||
std::string filename = sf.next(":");
|
||||
std::string filename = unescape_string(sf.next_esc(":", escape), escape);
|
||||
|
||||
video::IImage *img = m_sourcecache.getOrLoad(filename, m_device);
|
||||
video::IImage *img = generateImage(filename);
|
||||
if (img) {
|
||||
apply_mask(img, baseimg, v2s32(0, 0), v2s32(0, 0),
|
||||
img->getDimension());
|
||||
|
@ -1673,6 +1692,10 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
|
||||
apply_colorize(baseimg, v2u32(0, 0), baseimg->getDimension(), color, ratio, keep_alpha);
|
||||
}
|
||||
/*
|
||||
[applyfiltersformesh
|
||||
Internal modifier
|
||||
*/
|
||||
else if (str_starts_with(part_of_name, "[applyfiltersformesh"))
|
||||
{
|
||||
// Apply the "clean transparent" filter, if configured.
|
||||
|
@ -1760,9 +1783,48 @@ bool TextureSource::generateImagePart(std::string part_of_name,
|
|||
for (u32 y = 0; y < dim.Height; y++)
|
||||
for (u32 x = 0; x < dim.Width; x++)
|
||||
{
|
||||
video::SColor c = baseimg->getPixel(x,y);
|
||||
video::SColor c = baseimg->getPixel(x, y);
|
||||
c.setAlpha(floor((c.getAlpha() * ratio) / 255 + 0.5));
|
||||
baseimg->setPixel(x,y,c);
|
||||
baseimg->setPixel(x, y, c);
|
||||
}
|
||||
}
|
||||
/*
|
||||
[invert:mode
|
||||
Inverts the given channels of the base image.
|
||||
Mode may contain the characters "r", "g", "b", "a".
|
||||
Only the channels that are mentioned in the mode string
|
||||
will be inverted.
|
||||
*/
|
||||
else if (str_starts_with(part_of_name, "[invert:")) {
|
||||
if (baseimg == NULL) {
|
||||
errorstream << "generateImagePart(): baseimg == NULL "
|
||||
<< "for part_of_name=\"" << part_of_name
|
||||
<< "\", cancelling." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
Strfnd sf(part_of_name);
|
||||
sf.next(":");
|
||||
|
||||
std::string mode = sf.next("");
|
||||
u32 mask = 0;
|
||||
if (mode.find("a") != std::string::npos)
|
||||
mask |= 0xff000000UL;
|
||||
if (mode.find("r") != std::string::npos)
|
||||
mask |= 0x00ff0000UL;
|
||||
if (mode.find("g") != std::string::npos)
|
||||
mask |= 0x0000ff00UL;
|
||||
if (mode.find("b") != std::string::npos)
|
||||
mask |= 0x000000ffUL;
|
||||
|
||||
core::dimension2d<u32> dim = baseimg->getDimension();
|
||||
|
||||
for (u32 y = 0; y < dim.Height; y++)
|
||||
for (u32 x = 0; x < dim.Width; x++)
|
||||
{
|
||||
video::SColor c = baseimg->getPixel(x, y);
|
||||
c.color ^= mask;
|
||||
baseimg->setPixel(x, y, c);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -617,11 +617,8 @@ ClientInterface::~ClientInterface()
|
|||
{
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
|
||||
for(std::map<u16, RemoteClient*>::iterator
|
||||
i = m_clients.begin();
|
||||
i != m_clients.end(); ++i)
|
||||
{
|
||||
|
||||
for (UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
|
||||
i != m_clients.end(); ++i) {
|
||||
// Delete client
|
||||
delete i->second;
|
||||
}
|
||||
|
@ -633,10 +630,8 @@ std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
|
|||
std::vector<u16> reply;
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
|
||||
for(std::map<u16, RemoteClient*>::iterator
|
||||
i = m_clients.begin();
|
||||
i != m_clients.end(); ++i)
|
||||
{
|
||||
for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
|
||||
i != m_clients.end(); ++i) {
|
||||
if (i->second->getState() >= min_state)
|
||||
reply.push_back(i->second->peer_id);
|
||||
}
|
||||
|
@ -703,8 +698,7 @@ void ClientInterface::sendToAll(u16 channelnum,
|
|||
NetworkPacket* pkt, bool reliable)
|
||||
{
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
for(std::map<u16, RemoteClient*>::iterator
|
||||
i = m_clients.begin();
|
||||
for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
|
||||
i != m_clients.end(); ++i) {
|
||||
RemoteClient *client = i->second;
|
||||
|
||||
|
@ -717,11 +711,10 @@ void ClientInterface::sendToAll(u16 channelnum,
|
|||
RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
|
||||
{
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client may not exist; clients are immediately removed if their
|
||||
// access is denied, and this event occurs later then.
|
||||
if(n == m_clients.end())
|
||||
if (n == m_clients.end())
|
||||
return NULL;
|
||||
|
||||
if (n->second->getState() >= state_min)
|
||||
|
@ -732,11 +725,10 @@ RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
|
|||
|
||||
RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
|
||||
{
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client may not exist; clients are immediately removed if their
|
||||
// access is denied, and this event occurs later then.
|
||||
if(n == m_clients.end())
|
||||
if (n == m_clients.end())
|
||||
return NULL;
|
||||
|
||||
if (n->second->getState() >= state_min)
|
||||
|
@ -748,11 +740,10 @@ RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState stat
|
|||
ClientState ClientInterface::getClientState(u16 peer_id)
|
||||
{
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client may not exist; clients are immediately removed if their
|
||||
// access is denied, and this event occurs later then.
|
||||
if(n == m_clients.end())
|
||||
if (n == m_clients.end())
|
||||
return CS_Invalid;
|
||||
|
||||
return n->second->getState();
|
||||
|
@ -761,11 +752,10 @@ ClientState ClientInterface::getClientState(u16 peer_id)
|
|||
void ClientInterface::setPlayerName(u16 peer_id,std::string name)
|
||||
{
|
||||
MutexAutoLock clientslock(m_clients_mutex);
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client may not exist; clients are immediately removed if their
|
||||
// access is denied, and this event occurs later then.
|
||||
if(n != m_clients.end())
|
||||
if (n != m_clients.end())
|
||||
n->second->setName(name);
|
||||
}
|
||||
|
||||
|
@ -774,11 +764,10 @@ void ClientInterface::DeleteClient(u16 peer_id)
|
|||
MutexAutoLock conlock(m_clients_mutex);
|
||||
|
||||
// Error check
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client may not exist; clients are immediately removed if their
|
||||
// access is denied, and this event occurs later then.
|
||||
if(n == m_clients.end())
|
||||
if (n == m_clients.end())
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -809,10 +798,9 @@ void ClientInterface::CreateClient(u16 peer_id)
|
|||
MutexAutoLock conlock(m_clients_mutex);
|
||||
|
||||
// Error check
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
// The client shouldn't already exist
|
||||
if(n != m_clients.end()) return;
|
||||
if (n != m_clients.end()) return;
|
||||
|
||||
// Create client
|
||||
RemoteClient *client = new RemoteClient();
|
||||
|
@ -826,8 +814,7 @@ void ClientInterface::event(u16 peer_id, ClientStateEvent event)
|
|||
MutexAutoLock clientlock(m_clients_mutex);
|
||||
|
||||
// Error check
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
|
||||
// No client to deliver event
|
||||
if (n == m_clients.end())
|
||||
|
@ -848,8 +835,7 @@ u16 ClientInterface::getProtocolVersion(u16 peer_id)
|
|||
MutexAutoLock conlock(m_clients_mutex);
|
||||
|
||||
// Error check
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
|
||||
// No client to get version
|
||||
if (n == m_clients.end())
|
||||
|
@ -863,8 +849,7 @@ void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch
|
|||
MutexAutoLock conlock(m_clients_mutex);
|
||||
|
||||
// Error check
|
||||
std::map<u16, RemoteClient*>::iterator n;
|
||||
n = m_clients.find(peer_id);
|
||||
UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
|
||||
|
||||
// No client to set versions
|
||||
if (n == m_clients.end())
|
||||
|
|
|
@ -25,10 +25,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "serialization.h" // for SER_FMT_VER_INVALID
|
||||
#include "threading/mutex.h"
|
||||
#include "network/networkpacket.h"
|
||||
#include "util/cpp11_container.h"
|
||||
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
class MapBlock;
|
||||
|
@ -502,8 +502,7 @@ protected:
|
|||
void lock() { m_clients_mutex.lock(); }
|
||||
void unlock() { m_clients_mutex.unlock(); }
|
||||
|
||||
std::map<u16, RemoteClient*>& getClientList()
|
||||
{ return m_clients; }
|
||||
UNORDERED_MAP<u16, RemoteClient*>& getClientList() { return m_clients; }
|
||||
|
||||
private:
|
||||
/* update internal player list */
|
||||
|
@ -513,7 +512,7 @@ private:
|
|||
con::Connection* m_con;
|
||||
Mutex m_clients_mutex;
|
||||
// Connected clients (behind the con mutex)
|
||||
std::map<u16, RemoteClient*> m_clients;
|
||||
UNORDERED_MAP<u16, RemoteClient*> m_clients;
|
||||
std::vector<std::string> m_clients_names; //for announcing masterserver
|
||||
|
||||
// Environment
|
||||
|
|
|
@ -34,6 +34,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
//#define COLL_ZERO 0.032 // broken unit tests
|
||||
#define COLL_ZERO 0
|
||||
|
||||
|
||||
struct NearbyCollisionInfo {
|
||||
NearbyCollisionInfo(bool is_ul, bool is_obj, int bouncy,
|
||||
const v3s16 &pos, const aabb3f &box) :
|
||||
is_unloaded(is_ul),
|
||||
is_step_up(false),
|
||||
is_object(is_obj),
|
||||
bouncy(bouncy),
|
||||
position(pos),
|
||||
box(box)
|
||||
{}
|
||||
|
||||
bool is_unloaded;
|
||||
bool is_step_up;
|
||||
bool is_object;
|
||||
int bouncy;
|
||||
v3s16 position;
|
||||
aabb3f box;
|
||||
};
|
||||
|
||||
|
||||
// Helper function:
|
||||
// Checks for collision of a moving aabbox with a static aabbox
|
||||
// Returns -1 if no collision, 0 if X collision, 1 if Y collision, 2 if Z collision
|
||||
|
@ -160,7 +181,7 @@ int axisAlignedCollision(
|
|||
// Helper function:
|
||||
// Checks if moving the movingbox up by the given distance would hit a ceiling.
|
||||
bool wouldCollideWithCeiling(
|
||||
const std::vector<aabb3f> &staticboxes,
|
||||
const std::vector<NearbyCollisionInfo> &cinfo,
|
||||
const aabb3f &movingbox,
|
||||
f32 y_increase, f32 d)
|
||||
{
|
||||
|
@ -168,12 +189,10 @@ bool wouldCollideWithCeiling(
|
|||
|
||||
assert(y_increase >= 0); // pre-condition
|
||||
|
||||
for(std::vector<aabb3f>::const_iterator
|
||||
i = staticboxes.begin();
|
||||
i != staticboxes.end(); ++i)
|
||||
{
|
||||
const aabb3f& staticbox = *i;
|
||||
if((movingbox.MaxEdge.Y - d <= staticbox.MinEdge.Y) &&
|
||||
for (std::vector<NearbyCollisionInfo>::const_iterator it = cinfo.begin();
|
||||
it != cinfo.end(); ++it) {
|
||||
const aabb3f &staticbox = it->box;
|
||||
if ((movingbox.MaxEdge.Y - d <= staticbox.MinEdge.Y) &&
|
||||
(movingbox.MaxEdge.Y + y_increase > staticbox.MinEdge.Y) &&
|
||||
(movingbox.MinEdge.X < staticbox.MaxEdge.X) &&
|
||||
(movingbox.MaxEdge.X > staticbox.MinEdge.X) &&
|
||||
|
@ -234,12 +253,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
/*
|
||||
Collect node boxes in movement range
|
||||
*/
|
||||
std::vector<aabb3f> cboxes;
|
||||
std::vector<bool> is_unloaded;
|
||||
std::vector<bool> is_step_up;
|
||||
std::vector<bool> is_object;
|
||||
std::vector<int> bouncy_values;
|
||||
std::vector<v3s16> node_positions;
|
||||
std::vector<NearbyCollisionInfo> cinfo;
|
||||
{
|
||||
//TimeTaker tt2("collisionMoveSimple collect boxes");
|
||||
ScopeProfiler sp(g_profiler, "collisionMoveSimple collect boxes avg", SPT_AVG);
|
||||
|
@ -318,23 +332,13 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
aabb3f box = *i;
|
||||
box.MinEdge += v3f(x, y, z)*BS;
|
||||
box.MaxEdge += v3f(x, y, z)*BS;
|
||||
cboxes.push_back(box);
|
||||
is_unloaded.push_back(false);
|
||||
is_step_up.push_back(false);
|
||||
bouncy_values.push_back(n_bouncy_value);
|
||||
node_positions.push_back(p);
|
||||
is_object.push_back(false);
|
||||
cinfo.push_back(NearbyCollisionInfo(false,
|
||||
false, n_bouncy_value, p, box));
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// Collide with unloaded nodes
|
||||
aabb3f box = getNodeBox(p, BS);
|
||||
cboxes.push_back(box);
|
||||
is_unloaded.push_back(true);
|
||||
is_step_up.push_back(false);
|
||||
bouncy_values.push_back(0);
|
||||
node_positions.push_back(p);
|
||||
is_object.push_back(false);
|
||||
cinfo.push_back(NearbyCollisionInfo(true, false, 0, p, box));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -352,7 +356,7 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
ScopeProfiler sp(g_profiler, "collisionMoveSimple objects avg", SPT_AVG);
|
||||
//TimeTaker tt3("collisionMoveSimple collect object boxes");
|
||||
|
||||
/* add object boxes to cboxes */
|
||||
/* add object boxes to cinfo */
|
||||
|
||||
std::vector<ActiveObject*> objects;
|
||||
#ifndef SERVER
|
||||
|
@ -392,23 +396,12 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
aabb3f object_collisionbox;
|
||||
if (object->getCollisionBox(&object_collisionbox) &&
|
||||
object->collideWithObjects()) {
|
||||
cboxes.push_back(object_collisionbox);
|
||||
is_unloaded.push_back(false);
|
||||
is_step_up.push_back(false);
|
||||
bouncy_values.push_back(0);
|
||||
node_positions.push_back(v3s16(0,0,0));
|
||||
is_object.push_back(true);
|
||||
cinfo.push_back(NearbyCollisionInfo(false, true, 0, v3s16(), object_collisionbox));
|
||||
}
|
||||
}
|
||||
}
|
||||
} //tt3
|
||||
|
||||
assert(cboxes.size() == is_unloaded.size()); // post-condition
|
||||
assert(cboxes.size() == is_step_up.size()); // post-condition
|
||||
assert(cboxes.size() == bouncy_values.size()); // post-condition
|
||||
assert(cboxes.size() == node_positions.size()); // post-condition
|
||||
assert(cboxes.size() == is_object.size()); // post-condition
|
||||
|
||||
/*
|
||||
Collision detection
|
||||
*/
|
||||
|
@ -448,15 +441,16 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
/*
|
||||
Go through every nodebox, find nearest collision
|
||||
*/
|
||||
for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
|
||||
for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) {
|
||||
NearbyCollisionInfo box_info = cinfo[boxindex];
|
||||
// Ignore if already stepped up this nodebox.
|
||||
if(is_step_up[boxindex])
|
||||
if (box_info.is_step_up)
|
||||
continue;
|
||||
|
||||
// Find nearest collision of the two boxes (raytracing-like)
|
||||
f32 dtime_tmp;
|
||||
int collided = axisAlignedCollision(
|
||||
cboxes[boxindex], movingbox, *speed_f, d, &dtime_tmp);
|
||||
int collided = axisAlignedCollision(box_info.box,
|
||||
movingbox, *speed_f, d, &dtime_tmp);
|
||||
|
||||
if (collided == -1 || dtime_tmp >= nearest_dtime)
|
||||
continue;
|
||||
|
@ -472,19 +466,19 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
dtime = 0; // Set to 0 to avoid "infinite" loop due to small FP numbers
|
||||
} else {
|
||||
// Otherwise, a collision occurred.
|
||||
|
||||
const aabb3f& cbox = cboxes[nearest_boxindex];
|
||||
NearbyCollisionInfo &nearest_info = cinfo[nearest_boxindex];
|
||||
const aabb3f& cbox = nearest_info.box;
|
||||
// Check for stairs.
|
||||
bool step_up = (nearest_collided != 1) && // must not be Y direction
|
||||
(movingbox.MinEdge.Y < cbox.MaxEdge.Y) &&
|
||||
(movingbox.MinEdge.Y + stepheight > cbox.MaxEdge.Y) &&
|
||||
(!wouldCollideWithCeiling(cboxes, movingbox,
|
||||
(!wouldCollideWithCeiling(cinfo, movingbox,
|
||||
cbox.MaxEdge.Y - movingbox.MinEdge.Y,
|
||||
d));
|
||||
|
||||
// Get bounce multiplier
|
||||
bool bouncy = (bouncy_values[nearest_boxindex] >= 1);
|
||||
float bounce = -(float)bouncy_values[nearest_boxindex] / 100.0;
|
||||
bool bouncy = (nearest_info.bouncy >= 1);
|
||||
float bounce = -(float)nearest_info.bouncy / 100.0;
|
||||
|
||||
// Move to the point of collision and reduce dtime by nearest_dtime
|
||||
if (nearest_dtime < 0) {
|
||||
|
@ -503,39 +497,38 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
}
|
||||
|
||||
bool is_collision = true;
|
||||
if (is_unloaded[nearest_boxindex])
|
||||
if (nearest_info.is_unloaded)
|
||||
is_collision = false;
|
||||
|
||||
CollisionInfo info;
|
||||
if (is_object[nearest_boxindex])
|
||||
if (nearest_info.is_object)
|
||||
info.type = COLLISION_OBJECT;
|
||||
else
|
||||
info.type = COLLISION_NODE;
|
||||
|
||||
info.node_p = node_positions[nearest_boxindex];
|
||||
info.node_p = nearest_info.position;
|
||||
info.bouncy = bouncy;
|
||||
info.old_speed = *speed_f;
|
||||
|
||||
// Set the speed component that caused the collision to zero
|
||||
if (step_up) {
|
||||
// Special case: Handle stairs
|
||||
is_step_up[nearest_boxindex] = true;
|
||||
nearest_info.is_step_up = true;
|
||||
is_collision = false;
|
||||
} else if(nearest_collided == 0) { // X
|
||||
} else if (nearest_collided == 0) { // X
|
||||
if (fabs(speed_f->X) > BS * 3)
|
||||
speed_f->X *= bounce;
|
||||
else
|
||||
speed_f->X = 0;
|
||||
result.collides = true;
|
||||
result.collides_xz = true;
|
||||
}
|
||||
else if(nearest_collided == 1) { // Y
|
||||
if (fabs(speed_f->Y) > BS * 3)
|
||||
} else if (nearest_collided == 1) { // Y
|
||||
if(fabs(speed_f->Y) > BS * 3)
|
||||
speed_f->Y *= bounce;
|
||||
else
|
||||
speed_f->Y = 0;
|
||||
result.collides = true;
|
||||
} else if(nearest_collided == 2) { // Z
|
||||
} else if (nearest_collided == 2) { // Z
|
||||
if (fabs(speed_f->Z) > BS * 3)
|
||||
speed_f->Z *= bounce;
|
||||
else
|
||||
|
@ -560,8 +553,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
aabb3f box = box_0;
|
||||
box.MinEdge += *pos_f;
|
||||
box.MaxEdge += *pos_f;
|
||||
for (u32 boxindex = 0; boxindex < cboxes.size(); boxindex++) {
|
||||
const aabb3f& cbox = cboxes[boxindex];
|
||||
for (u32 boxindex = 0; boxindex < cinfo.size(); boxindex++) {
|
||||
NearbyCollisionInfo &box_info = cinfo[boxindex];
|
||||
const aabb3f &cbox = box_info.box;
|
||||
|
||||
/*
|
||||
See if the object is touching ground.
|
||||
|
@ -575,8 +569,8 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
if (cbox.MaxEdge.X - d > box.MinEdge.X && cbox.MinEdge.X + d < box.MaxEdge.X &&
|
||||
cbox.MaxEdge.Z - d > box.MinEdge.Z &&
|
||||
cbox.MinEdge.Z + d < box.MaxEdge.Z) {
|
||||
if (is_step_up[boxindex]) {
|
||||
pos_f->Y += (cbox.MaxEdge.Y - box.MinEdge.Y);
|
||||
if (box_info.is_step_up) {
|
||||
pos_f->Y += cbox.MaxEdge.Y - box.MinEdge.Y;
|
||||
box = box_0;
|
||||
box.MinEdge += *pos_f;
|
||||
box.MaxEdge += *pos_f;
|
||||
|
@ -584,9 +578,9 @@ collisionMoveResult collisionMoveSimple(Environment *env, IGameDef *gamedef,
|
|||
if (fabs(cbox.MaxEdge.Y - box.MinEdge.Y) < 0.15 * BS) {
|
||||
result.touching_ground = true;
|
||||
|
||||
if (is_object[boxindex])
|
||||
if (box_info.is_object)
|
||||
result.standing_on_object = true;
|
||||
if (is_unloaded[boxindex])
|
||||
if (box_info.is_unloaded)
|
||||
result.standing_on_unloaded = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#if defined(_WIN32)
|
||||
#define TTF_DEFAULT_FONT_SIZE (18)
|
||||
#else
|
||||
#define TTF_DEFAULT_FONT_SIZE (15)
|
||||
#define TTF_DEFAULT_FONT_SIZE (16)
|
||||
#endif
|
||||
#define DEFAULT_FONT_SIZE (10)
|
||||
|
||||
|
|
|
@ -566,7 +566,7 @@ GenericCAO::GenericCAO(IGameDef *gamedef, ClientEnvironment *env):
|
|||
m_animation_speed(15),
|
||||
m_animation_blend(0),
|
||||
m_animation_loop(true),
|
||||
m_bone_position(std::map<std::string, core::vector2d<v3f> >()),
|
||||
m_bone_position(UNORDERED_MAP<std::string, core::vector2d<v3f> >()),
|
||||
m_attachment_bone(""),
|
||||
m_attachment_position(v3f(0,0,0)),
|
||||
m_attachment_rotation(v3f(0,0,0)),
|
||||
|
@ -1573,10 +1573,8 @@ void GenericCAO::updateBonePosition()
|
|||
return;
|
||||
|
||||
m_animated_meshnode->setJointMode(irr::scene::EJUOR_CONTROL); // To write positions to the mesh on render
|
||||
for(std::map<std::string,
|
||||
core::vector2d<v3f> >::const_iterator ii = m_bone_position.begin();
|
||||
ii != m_bone_position.end(); ++ii)
|
||||
{
|
||||
for(UNORDERED_MAP<std::string, core::vector2d<v3f> >::const_iterator
|
||||
ii = m_bone_position.begin(); ii != m_bone_position.end(); ++ii) {
|
||||
std::string bone_name = (*ii).first;
|
||||
v3f bone_pos = (*ii).second.X;
|
||||
v3f bone_rot = (*ii).second.Y;
|
||||
|
|
|
@ -90,7 +90,7 @@ private:
|
|||
int m_animation_speed;
|
||||
int m_animation_blend;
|
||||
bool m_animation_loop;
|
||||
std::map<std::string, core::vector2d<v3f> > m_bone_position; // stores position and rotation for each bone name
|
||||
UNORDERED_MAP<std::string, core::vector2d<v3f> > m_bone_position; // stores position and rotation for each bone name
|
||||
std::string m_attachment_bone;
|
||||
v3f m_attachment_position;
|
||||
v3f m_attachment_rotation;
|
||||
|
|
|
@ -172,6 +172,15 @@ static inline void getNeighborConnectingFace(v3s16 p, INodeDefManager *nodedef,
|
|||
*neighbors |= v;
|
||||
}
|
||||
|
||||
// For use in mapblock_mesh_generate_special
|
||||
// X,Y,Z of position must be -1,0,1
|
||||
// This expression is a simplification of
|
||||
// 3 * 3 * (pos.X + 1) + 3 * (pos.Y + 1) + (pos.Z + 1)
|
||||
static inline int NeighborToIndex(const v3s16 &pos)
|
||||
{
|
||||
return 9 * pos.X + 3 * pos.Y + pos.Z + 13;
|
||||
}
|
||||
|
||||
/*
|
||||
TODO: Fix alpha blending for special nodes
|
||||
Currently only the last element rendered is blended correct
|
||||
|
@ -401,9 +410,14 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
|
||||
// Neighbor liquid levels (key = relative position)
|
||||
// Includes current node
|
||||
std::map<v3s16, f32> neighbor_levels;
|
||||
std::map<v3s16, content_t> neighbor_contents;
|
||||
std::map<v3s16, u8> neighbor_flags;
|
||||
|
||||
struct NeighborData {
|
||||
f32 level;
|
||||
content_t content;
|
||||
u8 flags;
|
||||
};
|
||||
NeighborData neighbor_data_matrix[27];
|
||||
|
||||
const u8 neighborflag_top_is_same_liquid = 0x01;
|
||||
v3s16 neighbor_dirs[9] = {
|
||||
v3s16(0,0,0),
|
||||
|
@ -449,9 +463,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
flags |= neighborflag_top_is_same_liquid;
|
||||
}
|
||||
|
||||
neighbor_levels[neighbor_dirs[i]] = level;
|
||||
neighbor_contents[neighbor_dirs[i]] = content;
|
||||
neighbor_flags[neighbor_dirs[i]] = flags;
|
||||
NeighborData &neighbor_data =
|
||||
neighbor_data_matrix[NeighborToIndex(neighbor_dirs[i])];
|
||||
|
||||
neighbor_data.level = level;
|
||||
neighbor_data.content = content;
|
||||
neighbor_data.flags = flags;
|
||||
}
|
||||
|
||||
// Corner heights (average between four liquids)
|
||||
|
@ -472,10 +489,12 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
for(u32 j=0; j<4; j++)
|
||||
{
|
||||
v3s16 neighbordir = cornerdir - halfdirs[j];
|
||||
content_t content = neighbor_contents[neighbordir];
|
||||
|
||||
NeighborData &neighbor_data =
|
||||
neighbor_data_matrix[NeighborToIndex(neighbordir)];
|
||||
content_t content = neighbor_data.content;
|
||||
// If top is liquid, draw starting from top of node
|
||||
if(neighbor_flags[neighbordir] &
|
||||
neighborflag_top_is_same_liquid)
|
||||
if (neighbor_data.flags & neighborflag_top_is_same_liquid)
|
||||
{
|
||||
cornerlevel = 0.5*BS;
|
||||
valid_count = 1;
|
||||
|
@ -491,7 +510,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
// Flowing liquid has level information
|
||||
else if(content == c_flowing)
|
||||
{
|
||||
cornerlevel += neighbor_levels[neighbordir];
|
||||
cornerlevel += neighbor_data.level;
|
||||
valid_count++;
|
||||
}
|
||||
else if(content == CONTENT_AIR)
|
||||
|
@ -526,15 +545,17 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
{
|
||||
v3s16 dir = side_dirs[i];
|
||||
|
||||
NeighborData& neighbor_data =
|
||||
neighbor_data_matrix[NeighborToIndex(dir)];
|
||||
/*
|
||||
If our topside is liquid and neighbor's topside
|
||||
is liquid, don't draw side face
|
||||
*/
|
||||
if(top_is_same_liquid &&
|
||||
neighbor_flags[dir] & neighborflag_top_is_same_liquid)
|
||||
if (top_is_same_liquid &&
|
||||
neighbor_data.flags & neighborflag_top_is_same_liquid)
|
||||
continue;
|
||||
|
||||
content_t neighbor_content = neighbor_contents[dir];
|
||||
content_t neighbor_content = neighbor_data.content;
|
||||
const ContentFeatures &n_feat = nodedef->get(neighbor_content);
|
||||
|
||||
// Don't draw face if neighbor is blocking the view
|
||||
|
@ -1138,7 +1159,7 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
u8 p2mesh = 0;
|
||||
if (f.param_type_2 == CPT2_DEGROTATE)
|
||||
rotate_degree = n.param2 * 2;
|
||||
else if (f.param_type_2 != CPT2_MESHOPTIONS) {
|
||||
if (f.param_type_2 != CPT2_MESHOPTIONS) {
|
||||
if (j == 0) {
|
||||
for (u16 i = 0; i < 4; i++)
|
||||
vertices[i].Pos.rotateXZBy(46 + rotate_degree);
|
||||
|
@ -1506,8 +1527,8 @@ void mapblock_mesh_generate_special(MeshMakeData *data,
|
|||
continue;
|
||||
MapNode n_xy = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x + xz, y + y0, z));
|
||||
MapNode n_zy = data->m_vmanip.getNodeNoEx(blockpos_nodes + v3s16(x, y + y0, z + xz));
|
||||
ContentFeatures def_xy = nodedef->get(n_xy);
|
||||
ContentFeatures def_zy = nodedef->get(n_zy);
|
||||
const ContentFeatures &def_xy = nodedef->get(n_xy);
|
||||
const ContentFeatures &def_zy = nodedef->get(n_zy);
|
||||
|
||||
// Check if current node would connect with the rail
|
||||
is_rail_x[index] = ((def_xy.drawtype == NDT_RAILLIKE
|
||||
|
|
|
@ -213,7 +213,7 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("freetype", "true");
|
||||
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "liberationsans.ttf"));
|
||||
settings->setDefault("font_shadow", "1");
|
||||
settings->setDefault("font_shadow_alpha", "128");
|
||||
settings->setDefault("font_shadow_alpha", "127");
|
||||
settings->setDefault("mono_font_path", porting::getDataPath("fonts" DIR_DELIM "liberationmono.ttf"));
|
||||
settings->setDefault("fallback_font_path", porting::getDataPath("fonts" DIR_DELIM "DroidSansFallbackFull.ttf"));
|
||||
|
||||
|
@ -285,6 +285,9 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("server_unload_unused_data_timeout", "29");
|
||||
settings->setDefault("max_objects_per_block", "49");
|
||||
settings->setDefault("server_map_save_interval", "5.3");
|
||||
settings->setDefault("chat_message_max_size", "500");
|
||||
settings->setDefault("chat_message_limit_per_10sec", "8.0");
|
||||
settings->setDefault("chat_message_limit_trigger_kick", "50");
|
||||
settings->setDefault("sqlite_synchronous", "2");
|
||||
settings->setDefault("full_block_send_enable_min_time_from_building", "2.0");
|
||||
settings->setDefault("dedicated_server_step", "0.1");
|
||||
|
|
|
@ -369,12 +369,10 @@ bool EmergeManager::pushBlockEmergeData(
|
|||
}
|
||||
|
||||
|
||||
bool EmergeManager::popBlockEmergeData(
|
||||
v3s16 pos,
|
||||
BlockEmergeData *bedata)
|
||||
bool EmergeManager::popBlockEmergeData(v3s16 pos, BlockEmergeData *bedata)
|
||||
{
|
||||
std::map<v3s16, BlockEmergeData>::iterator it;
|
||||
std::map<u16, u16>::iterator it2;
|
||||
UNORDERED_MAP<u16, u16>::iterator it2;
|
||||
|
||||
it = m_blocks_enqueued.find(pos);
|
||||
if (it == m_blocks_enqueued.end())
|
||||
|
|
|
@ -156,7 +156,7 @@ private:
|
|||
|
||||
Mutex m_queue_mutex;
|
||||
std::map<v3s16, BlockEmergeData> m_blocks_enqueued;
|
||||
std::map<u16, u16> m_peer_queue_count;
|
||||
UNORDERED_MAP<u16, u16> m_peer_queue_count;
|
||||
|
||||
u16 m_qlimit_total;
|
||||
u16 m_qlimit_diskonly;
|
||||
|
|
|
@ -1146,14 +1146,12 @@ bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n)
|
|||
|
||||
void ServerEnvironment::getObjectsInsideRadius(std::vector<u16> &objects, v3f pos, float radius)
|
||||
{
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i)
|
||||
{
|
||||
for (ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
u16 id = i->first;
|
||||
v3f objectpos = obj->getBasePosition();
|
||||
if(objectpos.getDistanceFrom(pos) > radius)
|
||||
if (objectpos.getDistanceFrom(pos) > radius)
|
||||
continue;
|
||||
objects.push_back(id);
|
||||
}
|
||||
|
@ -1164,8 +1162,7 @@ void ServerEnvironment::clearObjects(ClearObjectsMode mode)
|
|||
infostream << "ServerEnvironment::clearObjects(): "
|
||||
<< "Removing all active objects" << std::endl;
|
||||
std::vector<u16> objects_to_remove;
|
||||
for (std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
for (ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
if (obj->getType() == ACTIVEOBJECT_TYPE_PLAYER)
|
||||
|
@ -1540,10 +1537,8 @@ void ServerEnvironment::step(float dtime)
|
|||
send_recommended = true;
|
||||
}
|
||||
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i)
|
||||
{
|
||||
for(ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
// Don't step if is to be removed or stored statically
|
||||
if(obj->m_removed || obj->m_pending_deactivation)
|
||||
|
@ -1576,7 +1571,7 @@ void ServerEnvironment::step(float dtime)
|
|||
Manage particle spawner expiration
|
||||
*/
|
||||
if (m_particle_management_interval.step(dtime, 1.0)) {
|
||||
for (std::map<u32, float>::iterator i = m_particle_spawners.begin();
|
||||
for (UNORDERED_MAP<u32, float>::iterator i = m_particle_spawners.begin();
|
||||
i != m_particle_spawners.end(); ) {
|
||||
//non expiring spawners
|
||||
if (i->second == PARTICLE_SPAWNER_NO_EXPIRY) {
|
||||
|
@ -1601,8 +1596,7 @@ u32 ServerEnvironment::addParticleSpawner(float exptime)
|
|||
u32 id = 0;
|
||||
for (;;) { // look for unused particlespawner id
|
||||
id++;
|
||||
std::map<u32, float>::iterator f;
|
||||
f = m_particle_spawners.find(id);
|
||||
UNORDERED_MAP<u32, float>::iterator f = m_particle_spawners.find(id);
|
||||
if (f == m_particle_spawners.end()) {
|
||||
m_particle_spawners[id] = time;
|
||||
break;
|
||||
|
@ -1611,31 +1605,21 @@ u32 ServerEnvironment::addParticleSpawner(float exptime)
|
|||
return id;
|
||||
}
|
||||
|
||||
void ServerEnvironment::deleteParticleSpawner(u32 id)
|
||||
{
|
||||
m_particle_spawners.erase(id);
|
||||
}
|
||||
|
||||
ServerActiveObject* ServerEnvironment::getActiveObject(u16 id)
|
||||
{
|
||||
std::map<u16, ServerActiveObject*>::iterator n;
|
||||
n = m_active_objects.find(id);
|
||||
if(n == m_active_objects.end())
|
||||
return NULL;
|
||||
return n->second;
|
||||
ActiveObjectMap::iterator n = m_active_objects.find(id);
|
||||
return (n != m_active_objects.end() ? n->second : NULL);
|
||||
}
|
||||
|
||||
bool isFreeServerActiveObjectId(u16 id,
|
||||
std::map<u16, ServerActiveObject*> &objects)
|
||||
bool isFreeServerActiveObjectId(u16 id, ActiveObjectMap &objects)
|
||||
{
|
||||
if(id == 0)
|
||||
if (id == 0)
|
||||
return false;
|
||||
|
||||
return objects.find(id) == objects.end();
|
||||
}
|
||||
|
||||
u16 getFreeServerActiveObjectId(
|
||||
std::map<u16, ServerActiveObject*> &objects)
|
||||
u16 getFreeServerActiveObjectId(ActiveObjectMap &objects)
|
||||
{
|
||||
//try to reuse id's as late as possible
|
||||
static u16 last_used_id = 0;
|
||||
|
@ -1684,8 +1668,7 @@ void ServerEnvironment::getAddedActiveObjects(Player *player, s16 radius,
|
|||
- discard objects that are found in current_objects.
|
||||
- add remaining objects to added_objects
|
||||
*/
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
for(ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
u16 id = i->first;
|
||||
|
||||
|
@ -1810,8 +1793,7 @@ void ServerEnvironment::setStaticForActiveObjectsInBlock(
|
|||
so_it = block->m_static_objects.m_active.begin();
|
||||
so_it != block->m_static_objects.m_active.end(); ++so_it) {
|
||||
// Get the ServerActiveObject counterpart to this StaticObject
|
||||
std::map<u16, ServerActiveObject *>::iterator ao_it;
|
||||
ao_it = m_active_objects.find(so_it->first);
|
||||
ActiveObjectMap::iterator ao_it = m_active_objects.find(so_it->first);
|
||||
if (ao_it == m_active_objects.end()) {
|
||||
// If this ever happens, there must be some kind of nasty bug.
|
||||
errorstream << "ServerEnvironment::setStaticForObjectsInBlock(): "
|
||||
|
@ -1860,8 +1842,8 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
|||
verbosestream<<"ServerEnvironment::addActiveObjectRaw(): "
|
||||
<<"supplied with id "<<object->getId()<<std::endl;
|
||||
}
|
||||
if(isFreeServerActiveObjectId(object->getId(), m_active_objects) == false)
|
||||
{
|
||||
|
||||
if(!isFreeServerActiveObjectId(object->getId(), m_active_objects)) {
|
||||
errorstream<<"ServerEnvironment::addActiveObjectRaw(): "
|
||||
<<"id is not free ("<<object->getId()<<")"<<std::endl;
|
||||
if(object->environmentDeletes())
|
||||
|
@ -1929,8 +1911,7 @@ u16 ServerEnvironment::addActiveObjectRaw(ServerActiveObject *object,
|
|||
void ServerEnvironment::removeRemovedObjects()
|
||||
{
|
||||
std::vector<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
for(ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
u16 id = i->first;
|
||||
ServerActiveObject* obj = i->second;
|
||||
|
@ -1948,7 +1929,7 @@ void ServerEnvironment::removeRemovedObjects()
|
|||
We will delete objects that are marked as removed or thatare
|
||||
waiting for deletion after deactivation
|
||||
*/
|
||||
if(obj->m_removed == false && obj->m_pending_deactivation == false)
|
||||
if (!obj->m_removed && !obj->m_pending_deactivation)
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -2148,8 +2129,7 @@ void ServerEnvironment::activateObjects(MapBlock *block, u32 dtime_s)
|
|||
void ServerEnvironment::deactivateFarObjects(bool force_delete)
|
||||
{
|
||||
std::vector<u16> objects_to_remove;
|
||||
for(std::map<u16, ServerActiveObject*>::iterator
|
||||
i = m_active_objects.begin();
|
||||
for(ActiveObjectMap::iterator i = m_active_objects.begin();
|
||||
i != m_active_objects.end(); ++i) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
assert(obj);
|
||||
|
|
|
@ -300,6 +300,8 @@ enum ClearObjectsMode {
|
|||
This is not thread-safe. Server uses an environment mutex.
|
||||
*/
|
||||
|
||||
typedef UNORDERED_MAP<u16, ServerActiveObject *> ActiveObjectMap;
|
||||
|
||||
class ServerEnvironment : public Environment
|
||||
{
|
||||
public:
|
||||
|
@ -338,7 +340,7 @@ public:
|
|||
void loadDefaultMeta();
|
||||
|
||||
u32 addParticleSpawner(float exptime);
|
||||
void deleteParticleSpawner(u32 id);
|
||||
void deleteParticleSpawner(u32 id) { m_particle_spawners.erase(id); }
|
||||
|
||||
/*
|
||||
External ActiveObject interface
|
||||
|
@ -491,7 +493,7 @@ private:
|
|||
// World path
|
||||
const std::string m_path_world;
|
||||
// Active object list
|
||||
std::map<u16, ServerActiveObject*> m_active_objects;
|
||||
ActiveObjectMap m_active_objects;
|
||||
// Outgoing network message buffer for active objects
|
||||
std::queue<ActiveObjectMessage> m_active_object_messages;
|
||||
// Some timers
|
||||
|
@ -522,7 +524,7 @@ private:
|
|||
|
||||
// Particles
|
||||
IntervalLimiter m_particle_management_interval;
|
||||
std::map<u32, float> m_particle_spawners;
|
||||
UNORDERED_MAP<u32, float> m_particle_spawners;
|
||||
};
|
||||
|
||||
#ifndef SERVER
|
||||
|
|
|
@ -605,7 +605,7 @@ public:
|
|||
void draw(s32 x_left, s32 y_bottom, video::IVideoDriver *driver,
|
||||
gui::IGUIFont *font) const
|
||||
{
|
||||
std::map<std::string, Meta> m_meta;
|
||||
UNORDERED_MAP<std::string, Meta> m_meta;
|
||||
|
||||
for (std::deque<Piece>::const_iterator k = m_log.begin();
|
||||
k != m_log.end(); ++k) {
|
||||
|
@ -615,8 +615,7 @@ public:
|
|||
i != piece.values.end(); ++i) {
|
||||
const std::string &id = i->first;
|
||||
const float &value = i->second;
|
||||
std::map<std::string, Meta>::iterator j =
|
||||
m_meta.find(id);
|
||||
UNORDERED_MAP<std::string, Meta>::iterator j = m_meta.find(id);
|
||||
|
||||
if (j == m_meta.end()) {
|
||||
m_meta[id] = Meta(value);
|
||||
|
@ -643,7 +642,7 @@ public:
|
|||
sizeof(usable_colors) / sizeof(*usable_colors);
|
||||
u32 next_color_i = 0;
|
||||
|
||||
for (std::map<std::string, Meta>::iterator i = m_meta.begin();
|
||||
for (UNORDERED_MAP<std::string, Meta>::iterator i = m_meta.begin();
|
||||
i != m_meta.end(); ++i) {
|
||||
Meta &meta = i->second;
|
||||
video::SColor color(255, 200, 200, 200);
|
||||
|
@ -659,7 +658,7 @@ public:
|
|||
s32 textx2 = textx + 200 - 15;
|
||||
s32 meta_i = 0;
|
||||
|
||||
for (std::map<std::string, Meta>::const_iterator i = m_meta.begin();
|
||||
for (UNORDERED_MAP<std::string, Meta>::const_iterator i = m_meta.begin();
|
||||
i != m_meta.end(); ++i) {
|
||||
const std::string &id = i->first;
|
||||
const Meta &meta = i->second;
|
||||
|
|
|
@ -279,6 +279,32 @@ void GUIFormSpecMenu::parseSize(parserData* data,std::string element)
|
|||
errorstream<< "Invalid size element (" << parts.size() << "): '" << element << "'" << std::endl;
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseContainer(parserData* data, std::string element)
|
||||
{
|
||||
std::vector<std::string> parts = split(element, ',');
|
||||
|
||||
if (parts.size() >= 2) {
|
||||
if (parts[1].find(';') != std::string::npos)
|
||||
parts[1] = parts[1].substr(0, parts[1].find(';'));
|
||||
|
||||
container_stack.push(pos_offset);
|
||||
pos_offset.X += MYMAX(0, stof(parts[0]));
|
||||
pos_offset.Y += MYMAX(0, stof(parts[1]));
|
||||
return;
|
||||
}
|
||||
errorstream<< "Invalid container start element (" << parts.size() << "): '" << element << "'" << std::endl;
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseContainerEnd(parserData* data)
|
||||
{
|
||||
if (container_stack.empty()) {
|
||||
errorstream<< "Invalid container end element, no matching container start element" << std::endl;
|
||||
} else {
|
||||
pos_offset = container_stack.top();
|
||||
container_stack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
void GUIFormSpecMenu::parseList(parserData* data,std::string element)
|
||||
{
|
||||
if (m_gamedef == 0) {
|
||||
|
@ -309,7 +335,7 @@ void GUIFormSpecMenu::parseList(parserData* data,std::string element)
|
|||
else
|
||||
loc.deSerialize(location);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -386,7 +412,7 @@ void GUIFormSpecMenu::parseCheckbox(parserData* data,std::string element)
|
|||
|
||||
MY_CHECKPOS("checkbox",0);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
|
@ -437,7 +463,7 @@ void GUIFormSpecMenu::parseScrollBar(parserData* data, std::string element)
|
|||
|
||||
MY_CHECKPOS("scrollbar",0);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
|
@ -495,10 +521,10 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
|
|||
std::vector<std::string> v_geom = split(parts[1],',');
|
||||
std::string name = unescape_string(parts[2]);
|
||||
|
||||
MY_CHECKPOS("image",0);
|
||||
MY_CHECKGEOM("image",1);
|
||||
MY_CHECKPOS("image", 0);
|
||||
MY_CHECKGEOM("image", 1);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
|
@ -506,23 +532,21 @@ void GUIFormSpecMenu::parseImage(parserData* data,std::string element)
|
|||
geom.X = stof(v_geom[0]) * (float)imgsize.X;
|
||||
geom.Y = stof(v_geom[1]) * (float)imgsize.Y;
|
||||
|
||||
if(!data->explicit_size)
|
||||
if (!data->explicit_size)
|
||||
warningstream<<"invalid use of image without a size[] element"<<std::endl;
|
||||
m_images.push_back(ImageDrawSpec(name, pos, geom));
|
||||
return;
|
||||
}
|
||||
|
||||
if (parts.size() == 2) {
|
||||
} else if (parts.size() == 2) {
|
||||
std::vector<std::string> v_pos = split(parts[0],',');
|
||||
std::string name = unescape_string(parts[1]);
|
||||
|
||||
MY_CHECKPOS("image",0);
|
||||
MY_CHECKPOS("image", 0);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
if(!data->explicit_size)
|
||||
if (!data->explicit_size)
|
||||
warningstream<<"invalid use of image without a size[] element"<<std::endl;
|
||||
m_images.push_back(ImageDrawSpec(name, pos));
|
||||
return;
|
||||
|
@ -544,7 +568,7 @@ void GUIFormSpecMenu::parseItemImage(parserData* data,std::string element)
|
|||
MY_CHECKPOS("itemimage",0);
|
||||
MY_CHECKGEOM("itemimage",1);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
|
@ -576,7 +600,7 @@ void GUIFormSpecMenu::parseButton(parserData* data,std::string element,
|
|||
MY_CHECKPOS("button",0);
|
||||
MY_CHECKGEOM("button",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -629,9 +653,9 @@ void GUIFormSpecMenu::parseBackground(parserData* data,std::string element)
|
|||
MY_CHECKPOS("background",0);
|
||||
MY_CHECKGEOM("background",1);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X - ((float)spacing.X-(float)imgsize.X)/2;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y - ((float)spacing.Y-(float)imgsize.Y)/2;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X - ((float)spacing.X - (float)imgsize.X)/2;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y - ((float)spacing.Y - (float)imgsize.Y)/2;
|
||||
|
||||
v2s32 geom;
|
||||
geom.X = stof(v_geom[0]) * (float)spacing.X;
|
||||
|
@ -705,7 +729,7 @@ void GUIFormSpecMenu::parseTable(parserData* data,std::string element)
|
|||
MY_CHECKPOS("table",0);
|
||||
MY_CHECKGEOM("table",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -776,7 +800,7 @@ void GUIFormSpecMenu::parseTextList(parserData* data,std::string element)
|
|||
MY_CHECKPOS("textlist",0);
|
||||
MY_CHECKGEOM("textlist",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -841,7 +865,7 @@ void GUIFormSpecMenu::parseDropDown(parserData* data,std::string element)
|
|||
|
||||
MY_CHECKPOS("dropdown",0);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -905,7 +929,7 @@ void GUIFormSpecMenu::parsePwdField(parserData* data,std::string element)
|
|||
MY_CHECKPOS("pwdfield",0);
|
||||
MY_CHECKGEOM("pwdfield",1);
|
||||
|
||||
v2s32 pos;
|
||||
v2s32 pos = pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -975,7 +999,7 @@ void GUIFormSpecMenu::parseSimpleField(parserData* data,
|
|||
if(data->explicit_size)
|
||||
warningstream<<"invalid use of unpositioned \"field\" in inventory"<<std::endl;
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.Y = ((m_fields.size()+2)*60);
|
||||
v2s32 size = DesiredRect.getSize();
|
||||
|
||||
|
@ -1058,9 +1082,9 @@ void GUIFormSpecMenu::parseTextArea(parserData* data,
|
|||
MY_CHECKPOS(type,0);
|
||||
MY_CHECKGEOM(type,1);
|
||||
|
||||
v2s32 pos;
|
||||
pos.X = stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y = stof(v_pos[1]) * (float) spacing.Y;
|
||||
v2s32 pos = pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
v2s32 geom;
|
||||
|
||||
|
@ -1185,7 +1209,7 @@ void GUIFormSpecMenu::parseLabel(parserData* data,std::string element)
|
|||
|
||||
MY_CHECKPOS("label",0);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += (stof(v_pos[1]) + 7.0/30.0) * (float)spacing.Y;
|
||||
|
||||
|
@ -1242,7 +1266,7 @@ void GUIFormSpecMenu::parseVertLabel(parserData* data,std::string element)
|
|||
|
||||
MY_CHECKPOS("vertlabel",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
|
||||
|
@ -1296,7 +1320,7 @@ void GUIFormSpecMenu::parseImageButton(parserData* data,std::string element,
|
|||
MY_CHECKPOS("imagebutton",0);
|
||||
MY_CHECKGEOM("imagebutton",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
v2s32 geom;
|
||||
|
@ -1401,7 +1425,7 @@ void GUIFormSpecMenu::parseTabHeader(parserData* data,std::string element)
|
|||
|
||||
spec.ftype = f_TabHeader;
|
||||
|
||||
v2s32 pos(0,0);
|
||||
v2s32 pos = pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y - m_btn_height * 2;
|
||||
v2s32 geom;
|
||||
|
@ -1466,7 +1490,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
|
|||
MY_CHECKPOS("itemimagebutton",0);
|
||||
MY_CHECKGEOM("itemimagebutton",1);
|
||||
|
||||
v2s32 pos = padding;
|
||||
v2s32 pos = padding + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float)spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float)spacing.Y;
|
||||
v2s32 geom;
|
||||
|
@ -1504,7 +1528,7 @@ void GUIFormSpecMenu::parseItemImageButton(parserData* data,std::string element)
|
|||
rect+=data->basepos-padding;
|
||||
spec.rect=rect;
|
||||
m_fields.push_back(spec);
|
||||
pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
m_itemimages.push_back(ImageDrawSpec("", item_name, e, pos, geom));
|
||||
|
@ -1527,7 +1551,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element)
|
|||
MY_CHECKPOS("box",0);
|
||||
MY_CHECKGEOM("box",1);
|
||||
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner;
|
||||
v2s32 pos = padding + AbsoluteRect.UpperLeftCorner + pos_offset * spacing;
|
||||
pos.X += stof(v_pos[0]) * (float) spacing.X;
|
||||
pos.Y += stof(v_pos[1]) * (float) spacing.Y;
|
||||
|
||||
|
@ -1689,8 +1713,18 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
|||
std::string type = trim(parts[0]);
|
||||
std::string description = trim(parts[1]);
|
||||
|
||||
if (type == "container") {
|
||||
parseContainer(data, description);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "container_end") {
|
||||
parseContainerEnd(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "list") {
|
||||
parseList(data,description);
|
||||
parseList(data, description);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1700,22 +1734,22 @@ void GUIFormSpecMenu::parseElement(parserData* data, std::string element)
|
|||
}
|
||||
|
||||
if (type == "checkbox") {
|
||||
parseCheckbox(data,description);
|
||||
parseCheckbox(data, description);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "image") {
|
||||
parseImage(data,description);
|
||||
parseImage(data, description);
|
||||
return;
|
||||
}
|
||||
|
||||
if (type == "item_image") {
|
||||
parseItemImage(data,description);
|
||||
parseItemImage(data, description);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((type == "button") || (type == "button_exit")) {
|
||||
parseButton(data,description,type);
|
||||
if (type == "button" || type == "button_exit") {
|
||||
parseButton(data, description, type);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2036,10 +2070,16 @@ void GUIFormSpecMenu::regenerateGui(v2u32 screensize)
|
|||
gui::IGUIFont *old_font = skin->getFont();
|
||||
skin->setFont(m_font);
|
||||
|
||||
pos_offset = v2s32();
|
||||
for (; i< elements.size(); i++) {
|
||||
parseElement(&mydata, elements[i]);
|
||||
}
|
||||
|
||||
if (!container_stack.empty()) {
|
||||
errorstream << "Invalid formspec string: container was never closed!"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
// If there are fields without explicit size[], add a "Proceed"
|
||||
// button and adjust size to fit all the fields.
|
||||
if (m_fields.size() && !mydata.explicit_size) {
|
||||
|
|
|
@ -22,6 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define GUIINVENTORYMENU_HEADER
|
||||
|
||||
#include <utility>
|
||||
#include <stack>
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "inventory.h"
|
||||
|
@ -380,6 +381,8 @@ protected:
|
|||
v2s32 spacing;
|
||||
v2s32 imgsize;
|
||||
v2s32 offset;
|
||||
v2s32 pos_offset;
|
||||
std::stack<v2s32> container_stack;
|
||||
|
||||
irr::IrrlichtDevice* m_device;
|
||||
InventoryManager *m_invmgr;
|
||||
|
@ -472,13 +475,15 @@ private:
|
|||
fs_key_pendig current_keys_pending;
|
||||
std::string current_field_enter_pending;
|
||||
|
||||
void parseElement(parserData* data,std::string element);
|
||||
void parseElement(parserData* data, std::string element);
|
||||
|
||||
void parseSize(parserData* data,std::string element);
|
||||
void parseList(parserData* data,std::string element);
|
||||
void parseListRing(parserData* data,std::string element);
|
||||
void parseCheckbox(parserData* data,std::string element);
|
||||
void parseImage(parserData* data,std::string element);
|
||||
void parseSize(parserData* data, std::string element);
|
||||
void parseContainer(parserData* data, std::string element);
|
||||
void parseContainerEnd(parserData* data);
|
||||
void parseList(parserData* data, std::string element);
|
||||
void parseListRing(parserData* data, std::string element);
|
||||
void parseCheckbox(parserData* data, std::string element);
|
||||
void parseImage(parserData* data, std::string element);
|
||||
void parseItemImage(parserData* data,std::string element);
|
||||
void parseButton(parserData* data,std::string element,std::string typ);
|
||||
void parseBackground(parserData* data,std::string element);
|
||||
|
|
|
@ -565,10 +565,8 @@ void GUITable::setSelected(s32 index)
|
|||
--index; // Switch from 1-based indexing to 0-based indexing
|
||||
|
||||
s32 rowcount = m_rows.size();
|
||||
if (rowcount == 0) {
|
||||
if (rowcount == 0 || index < 0) {
|
||||
return;
|
||||
} else if (index < 0) {
|
||||
index = 0;
|
||||
} else if (index >= rowcount) {
|
||||
index = rowcount - 1;
|
||||
}
|
||||
|
|
|
@ -146,9 +146,9 @@ void ItemDefinition::serialize(std::ostream &os, u16 protocol_version) const
|
|||
}
|
||||
os<<serializeString(tool_capabilities_s);
|
||||
writeU16(os, groups.size());
|
||||
for(std::map<std::string, int>::const_iterator
|
||||
for (ItemGroupList::const_iterator
|
||||
i = groups.begin(); i != groups.end(); ++i){
|
||||
os<<serializeString(i->first);
|
||||
os << serializeString(i->first);
|
||||
writeS16(os, i->second);
|
||||
}
|
||||
os<<serializeString(node_placement_prediction);
|
||||
|
|
|
@ -21,14 +21,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define ITEMGROUP_HEADER
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "util/cpp11_container.h"
|
||||
|
||||
typedef std::map<std::string, int> ItemGroupList;
|
||||
typedef UNORDERED_MAP<std::string, int> ItemGroupList;
|
||||
|
||||
static inline int itemgroup_get(const ItemGroupList &groups,
|
||||
const std::string &name)
|
||||
{
|
||||
std::map<std::string, int>::const_iterator i = groups.find(name);
|
||||
ItemGroupList::const_iterator i = groups.find(name);
|
||||
if(i == groups.end())
|
||||
return 0;
|
||||
return i->second;
|
||||
|
|
555
src/keycode.cpp
555
src/keycode.cpp
|
@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "log.h"
|
||||
#include "debug.h"
|
||||
#include "util/hex.h"
|
||||
#include "util/string.h"
|
||||
|
||||
class UnknownKeycode : public BaseException
|
||||
{
|
||||
|
@ -31,321 +32,335 @@ public:
|
|||
BaseException(s) {};
|
||||
};
|
||||
|
||||
#define CHECKKEY(x){if(strcmp(name, #x)==0) return irr::x;}
|
||||
struct table_key {
|
||||
const char *Name;
|
||||
irr::EKEY_CODE Key;
|
||||
wchar_t Char; // L'\0' means no character assigned
|
||||
const char *LangName; // NULL means it doesn't have a human description
|
||||
};
|
||||
|
||||
irr::EKEY_CODE keyname_to_keycode(const char *name)
|
||||
#define DEFINEKEY1(x, lang) /* Irrlicht key without character */ \
|
||||
{ #x, irr::x, L'\0', lang },
|
||||
#define DEFINEKEY2(x, ch, lang) /* Irrlicht key with character */ \
|
||||
{ #x, irr::x, ch, lang },
|
||||
#define DEFINEKEY3(ch) /* single Irrlicht key (e.g. KEY_KEY_X) */ \
|
||||
{ "KEY_KEY_" TOSTRING(ch), irr::KEY_KEY_ ## ch, (wchar_t) *TOSTRING(ch), TOSTRING(ch) },
|
||||
#define DEFINEKEY4(ch) /* single Irrlicht function key (e.g. KEY_F3) */ \
|
||||
{ "KEY_F" TOSTRING(ch), irr::KEY_F ## ch, L'\0', "F" TOSTRING(ch) },
|
||||
#define DEFINEKEY5(ch) /* key without Irrlicht keycode */ \
|
||||
{ ch, irr::KEY_KEY_CODES_COUNT, (wchar_t) *ch, ch },
|
||||
|
||||
#define N_(text) text
|
||||
|
||||
static const struct table_key table[] = {
|
||||
// Keys that can be reliably mapped between Char and Key
|
||||
DEFINEKEY3(0)
|
||||
DEFINEKEY3(1)
|
||||
DEFINEKEY3(2)
|
||||
DEFINEKEY3(3)
|
||||
DEFINEKEY3(4)
|
||||
DEFINEKEY3(5)
|
||||
DEFINEKEY3(6)
|
||||
DEFINEKEY3(7)
|
||||
DEFINEKEY3(8)
|
||||
DEFINEKEY3(9)
|
||||
DEFINEKEY3(A)
|
||||
DEFINEKEY3(B)
|
||||
DEFINEKEY3(C)
|
||||
DEFINEKEY3(D)
|
||||
DEFINEKEY3(E)
|
||||
DEFINEKEY3(F)
|
||||
DEFINEKEY3(G)
|
||||
DEFINEKEY3(H)
|
||||
DEFINEKEY3(I)
|
||||
DEFINEKEY3(J)
|
||||
DEFINEKEY3(K)
|
||||
DEFINEKEY3(L)
|
||||
DEFINEKEY3(M)
|
||||
DEFINEKEY3(N)
|
||||
DEFINEKEY3(O)
|
||||
DEFINEKEY3(P)
|
||||
DEFINEKEY3(Q)
|
||||
DEFINEKEY3(R)
|
||||
DEFINEKEY3(S)
|
||||
DEFINEKEY3(T)
|
||||
DEFINEKEY3(U)
|
||||
DEFINEKEY3(V)
|
||||
DEFINEKEY3(W)
|
||||
DEFINEKEY3(X)
|
||||
DEFINEKEY3(Y)
|
||||
DEFINEKEY3(Z)
|
||||
DEFINEKEY2(KEY_PLUS, L'+', "+")
|
||||
DEFINEKEY2(KEY_COMMA, L',', ",")
|
||||
DEFINEKEY2(KEY_MINUS, L'-', "-")
|
||||
DEFINEKEY2(KEY_PERIOD, L'.', ".")
|
||||
|
||||
// Keys without a Char
|
||||
DEFINEKEY1(KEY_LBUTTON, N_("Left Button"))
|
||||
DEFINEKEY1(KEY_RBUTTON, N_("Right Button"))
|
||||
DEFINEKEY1(KEY_CANCEL, N_("Cancel"))
|
||||
DEFINEKEY1(KEY_MBUTTON, N_("Middle Button"))
|
||||
DEFINEKEY1(KEY_XBUTTON1, N_("X Button 1"))
|
||||
DEFINEKEY1(KEY_XBUTTON2, N_("X Button 2"))
|
||||
DEFINEKEY1(KEY_BACK, N_("Back"))
|
||||
DEFINEKEY1(KEY_TAB, N_("Tab"))
|
||||
DEFINEKEY1(KEY_CLEAR, N_("Clear"))
|
||||
DEFINEKEY1(KEY_RETURN, N_("Return"))
|
||||
DEFINEKEY1(KEY_SHIFT, N_("Shift"))
|
||||
DEFINEKEY1(KEY_CONTROL, N_("Control"))
|
||||
DEFINEKEY1(KEY_MENU, N_("Menu"))
|
||||
DEFINEKEY1(KEY_PAUSE, N_("Pause"))
|
||||
DEFINEKEY1(KEY_CAPITAL, N_("Caps Lock"))
|
||||
DEFINEKEY1(KEY_SPACE, N_("Space"))
|
||||
DEFINEKEY1(KEY_PRIOR, N_("Prior"))
|
||||
DEFINEKEY1(KEY_NEXT, N_("Next"))
|
||||
DEFINEKEY1(KEY_END, N_("End"))
|
||||
DEFINEKEY1(KEY_HOME, N_("Home"))
|
||||
DEFINEKEY1(KEY_LEFT, N_("Left"))
|
||||
DEFINEKEY1(KEY_UP, N_("Up"))
|
||||
DEFINEKEY1(KEY_RIGHT, N_("Right"))
|
||||
DEFINEKEY1(KEY_DOWN, N_("Down"))
|
||||
DEFINEKEY1(KEY_SELECT, N_("Select"))
|
||||
DEFINEKEY1(KEY_PRINT, N_("Print"))
|
||||
DEFINEKEY1(KEY_EXECUT, N_("Execute"))
|
||||
DEFINEKEY1(KEY_SNAPSHOT, N_("Snapshot"))
|
||||
DEFINEKEY1(KEY_INSERT, N_("Insert"))
|
||||
DEFINEKEY1(KEY_DELETE, N_("Delete"))
|
||||
DEFINEKEY1(KEY_HELP, N_("Help"))
|
||||
DEFINEKEY1(KEY_LWIN, N_("Left Windows"))
|
||||
DEFINEKEY1(KEY_RWIN, N_("Right Windows"))
|
||||
DEFINEKEY1(KEY_NUMPAD0, N_("Numpad 0")) // These are not assigned to a char
|
||||
DEFINEKEY1(KEY_NUMPAD1, N_("Numpad 1")) // to prevent interference with KEY_KEY_[0-9].
|
||||
DEFINEKEY1(KEY_NUMPAD2, N_("Numpad 2"))
|
||||
DEFINEKEY1(KEY_NUMPAD3, N_("Numpad 3"))
|
||||
DEFINEKEY1(KEY_NUMPAD4, N_("Numpad 4"))
|
||||
DEFINEKEY1(KEY_NUMPAD5, N_("Numpad 5"))
|
||||
DEFINEKEY1(KEY_NUMPAD6, N_("Numpad 6"))
|
||||
DEFINEKEY1(KEY_NUMPAD7, N_("Numpad 7"))
|
||||
DEFINEKEY1(KEY_NUMPAD8, N_("Numpad 8"))
|
||||
DEFINEKEY1(KEY_NUMPAD9, N_("Numpad 9"))
|
||||
DEFINEKEY1(KEY_MULTIPLY, N_("Numpad *"))
|
||||
DEFINEKEY1(KEY_ADD, N_("Numpad +"))
|
||||
DEFINEKEY1(KEY_SEPARATOR, N_("Numpad ."))
|
||||
DEFINEKEY1(KEY_SUBTRACT, N_("Numpad -"))
|
||||
DEFINEKEY1(KEY_DECIMAL, NULL)
|
||||
DEFINEKEY1(KEY_DIVIDE, N_("Numpad /"))
|
||||
DEFINEKEY4(1)
|
||||
DEFINEKEY4(2)
|
||||
DEFINEKEY4(3)
|
||||
DEFINEKEY4(4)
|
||||
DEFINEKEY4(5)
|
||||
DEFINEKEY4(6)
|
||||
DEFINEKEY4(7)
|
||||
DEFINEKEY4(8)
|
||||
DEFINEKEY4(9)
|
||||
DEFINEKEY4(10)
|
||||
DEFINEKEY4(11)
|
||||
DEFINEKEY4(12)
|
||||
DEFINEKEY4(13)
|
||||
DEFINEKEY4(14)
|
||||
DEFINEKEY4(15)
|
||||
DEFINEKEY4(16)
|
||||
DEFINEKEY4(17)
|
||||
DEFINEKEY4(18)
|
||||
DEFINEKEY4(19)
|
||||
DEFINEKEY4(20)
|
||||
DEFINEKEY4(21)
|
||||
DEFINEKEY4(22)
|
||||
DEFINEKEY4(23)
|
||||
DEFINEKEY4(24)
|
||||
DEFINEKEY1(KEY_NUMLOCK, N_("Num Lock"))
|
||||
DEFINEKEY1(KEY_SCROLL, N_("Scroll Lock"))
|
||||
DEFINEKEY1(KEY_LSHIFT, N_("Left Shift"))
|
||||
DEFINEKEY1(KEY_RSHIFT, N_("Right Shift"))
|
||||
DEFINEKEY1(KEY_LCONTROL, N_("Left Control"))
|
||||
DEFINEKEY1(KEY_RCONTROL, N_("Right Control"))
|
||||
DEFINEKEY1(KEY_LMENU, N_("Left Menu"))
|
||||
DEFINEKEY1(KEY_RMENU, N_("Right Menu"))
|
||||
|
||||
// Rare/weird keys
|
||||
DEFINEKEY1(KEY_KANA, "Kana")
|
||||
DEFINEKEY1(KEY_HANGUEL, "Hangul")
|
||||
DEFINEKEY1(KEY_HANGUL, "Hangul")
|
||||
DEFINEKEY1(KEY_JUNJA, "Junja")
|
||||
DEFINEKEY1(KEY_FINAL, "Final")
|
||||
DEFINEKEY1(KEY_KANJI, "Kanji")
|
||||
DEFINEKEY1(KEY_HANJA, "Hanja")
|
||||
DEFINEKEY1(KEY_ESCAPE, N_("IME Escape"))
|
||||
DEFINEKEY1(KEY_CONVERT, N_("IME Convert"))
|
||||
DEFINEKEY1(KEY_NONCONVERT, N_("IME Nonconvert"))
|
||||
DEFINEKEY1(KEY_ACCEPT, N_("IME Accept"))
|
||||
DEFINEKEY1(KEY_MODECHANGE, N_("IME Mode Change"))
|
||||
DEFINEKEY1(KEY_APPS, N_("Apps"))
|
||||
DEFINEKEY1(KEY_SLEEP, N_("Sleep"))
|
||||
#if !(IRRLICHT_VERSION_MAJOR <= 1 && IRRLICHT_VERSION_MINOR <= 7 && IRRLICHT_VERSION_REVISION < 3)
|
||||
DEFINEKEY1(KEY_OEM_1, "OEM 1") // KEY_OEM_[0-9] and KEY_OEM_102 are assigned to multiple
|
||||
DEFINEKEY1(KEY_OEM_2, "OEM 2") // different chars (on different platforms too) and thus w/o char
|
||||
DEFINEKEY1(KEY_OEM_3, "OEM 3")
|
||||
DEFINEKEY1(KEY_OEM_4, "OEM 4")
|
||||
DEFINEKEY1(KEY_OEM_5, "OEM 5")
|
||||
DEFINEKEY1(KEY_OEM_6, "OEM 6")
|
||||
DEFINEKEY1(KEY_OEM_7, "OEM 7")
|
||||
DEFINEKEY1(KEY_OEM_8, "OEM 8")
|
||||
DEFINEKEY1(KEY_OEM_AX, "OEM AX")
|
||||
DEFINEKEY1(KEY_OEM_102, "OEM 102")
|
||||
#endif
|
||||
DEFINEKEY1(KEY_ATTN, "Attn")
|
||||
DEFINEKEY1(KEY_CRSEL, "CrSel")
|
||||
DEFINEKEY1(KEY_EXSEL, "ExSel")
|
||||
DEFINEKEY1(KEY_EREOF, N_("Erase EOF"))
|
||||
DEFINEKEY1(KEY_PLAY, N_("Play"))
|
||||
DEFINEKEY1(KEY_ZOOM, N_("Zoom"))
|
||||
DEFINEKEY1(KEY_PA1, "PA1")
|
||||
DEFINEKEY1(KEY_OEM_CLEAR, N_("OEM Clear"))
|
||||
|
||||
// Keys without Irrlicht keycode
|
||||
DEFINEKEY5("!")
|
||||
DEFINEKEY5("\"")
|
||||
DEFINEKEY5("#")
|
||||
DEFINEKEY5("$")
|
||||
DEFINEKEY5("%")
|
||||
DEFINEKEY5("&")
|
||||
DEFINEKEY5("'")
|
||||
DEFINEKEY5("(")
|
||||
DEFINEKEY5(")")
|
||||
DEFINEKEY5("*")
|
||||
DEFINEKEY5("/")
|
||||
DEFINEKEY5(":")
|
||||
DEFINEKEY5(";")
|
||||
DEFINEKEY5("<")
|
||||
DEFINEKEY5("=")
|
||||
DEFINEKEY5(">")
|
||||
DEFINEKEY5("?")
|
||||
DEFINEKEY5("@")
|
||||
DEFINEKEY5("[")
|
||||
DEFINEKEY5("\\")
|
||||
DEFINEKEY5("]")
|
||||
DEFINEKEY5("^")
|
||||
DEFINEKEY5("_")
|
||||
};
|
||||
|
||||
#undef N_
|
||||
|
||||
#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
struct table_key lookup_keyname(const char *name)
|
||||
{
|
||||
CHECKKEY(KEY_LBUTTON)
|
||||
CHECKKEY(KEY_RBUTTON)
|
||||
CHECKKEY(KEY_CANCEL)
|
||||
CHECKKEY(KEY_MBUTTON)
|
||||
CHECKKEY(KEY_XBUTTON1)
|
||||
CHECKKEY(KEY_XBUTTON2)
|
||||
CHECKKEY(KEY_BACK)
|
||||
CHECKKEY(KEY_TAB)
|
||||
CHECKKEY(KEY_CLEAR)
|
||||
CHECKKEY(KEY_RETURN)
|
||||
CHECKKEY(KEY_SHIFT)
|
||||
CHECKKEY(KEY_CONTROL)
|
||||
CHECKKEY(KEY_MENU)
|
||||
CHECKKEY(KEY_PAUSE)
|
||||
CHECKKEY(KEY_CAPITAL)
|
||||
CHECKKEY(KEY_KANA)
|
||||
CHECKKEY(KEY_HANGUEL)
|
||||
CHECKKEY(KEY_HANGUL)
|
||||
CHECKKEY(KEY_JUNJA)
|
||||
CHECKKEY(KEY_FINAL)
|
||||
CHECKKEY(KEY_HANJA)
|
||||
CHECKKEY(KEY_KANJI)
|
||||
CHECKKEY(KEY_ESCAPE)
|
||||
CHECKKEY(KEY_CONVERT)
|
||||
CHECKKEY(KEY_NONCONVERT)
|
||||
CHECKKEY(KEY_ACCEPT)
|
||||
CHECKKEY(KEY_MODECHANGE)
|
||||
CHECKKEY(KEY_SPACE)
|
||||
CHECKKEY(KEY_PRIOR)
|
||||
CHECKKEY(KEY_NEXT)
|
||||
CHECKKEY(KEY_END)
|
||||
CHECKKEY(KEY_HOME)
|
||||
CHECKKEY(KEY_LEFT)
|
||||
CHECKKEY(KEY_UP)
|
||||
CHECKKEY(KEY_RIGHT)
|
||||
CHECKKEY(KEY_DOWN)
|
||||
CHECKKEY(KEY_SELECT)
|
||||
CHECKKEY(KEY_PRINT)
|
||||
CHECKKEY(KEY_EXECUT)
|
||||
CHECKKEY(KEY_SNAPSHOT)
|
||||
CHECKKEY(KEY_INSERT)
|
||||
CHECKKEY(KEY_DELETE)
|
||||
CHECKKEY(KEY_HELP)
|
||||
CHECKKEY(KEY_KEY_0)
|
||||
CHECKKEY(KEY_KEY_1)
|
||||
CHECKKEY(KEY_KEY_2)
|
||||
CHECKKEY(KEY_KEY_3)
|
||||
CHECKKEY(KEY_KEY_4)
|
||||
CHECKKEY(KEY_KEY_5)
|
||||
CHECKKEY(KEY_KEY_6)
|
||||
CHECKKEY(KEY_KEY_7)
|
||||
CHECKKEY(KEY_KEY_8)
|
||||
CHECKKEY(KEY_KEY_9)
|
||||
CHECKKEY(KEY_KEY_A)
|
||||
CHECKKEY(KEY_KEY_B)
|
||||
CHECKKEY(KEY_KEY_C)
|
||||
CHECKKEY(KEY_KEY_D)
|
||||
CHECKKEY(KEY_KEY_E)
|
||||
CHECKKEY(KEY_KEY_F)
|
||||
CHECKKEY(KEY_KEY_G)
|
||||
CHECKKEY(KEY_KEY_H)
|
||||
CHECKKEY(KEY_KEY_I)
|
||||
CHECKKEY(KEY_KEY_J)
|
||||
CHECKKEY(KEY_KEY_K)
|
||||
CHECKKEY(KEY_KEY_L)
|
||||
CHECKKEY(KEY_KEY_M)
|
||||
CHECKKEY(KEY_KEY_N)
|
||||
CHECKKEY(KEY_KEY_O)
|
||||
CHECKKEY(KEY_KEY_P)
|
||||
CHECKKEY(KEY_KEY_Q)
|
||||
CHECKKEY(KEY_KEY_R)
|
||||
CHECKKEY(KEY_KEY_S)
|
||||
CHECKKEY(KEY_KEY_T)
|
||||
CHECKKEY(KEY_KEY_U)
|
||||
CHECKKEY(KEY_KEY_V)
|
||||
CHECKKEY(KEY_KEY_W)
|
||||
CHECKKEY(KEY_KEY_X)
|
||||
CHECKKEY(KEY_KEY_Y)
|
||||
CHECKKEY(KEY_KEY_Z)
|
||||
CHECKKEY(KEY_LWIN)
|
||||
CHECKKEY(KEY_RWIN)
|
||||
CHECKKEY(KEY_APPS)
|
||||
CHECKKEY(KEY_SLEEP)
|
||||
CHECKKEY(KEY_NUMPAD0)
|
||||
CHECKKEY(KEY_NUMPAD1)
|
||||
CHECKKEY(KEY_NUMPAD2)
|
||||
CHECKKEY(KEY_NUMPAD3)
|
||||
CHECKKEY(KEY_NUMPAD4)
|
||||
CHECKKEY(KEY_NUMPAD5)
|
||||
CHECKKEY(KEY_NUMPAD6)
|
||||
CHECKKEY(KEY_NUMPAD7)
|
||||
CHECKKEY(KEY_NUMPAD8)
|
||||
CHECKKEY(KEY_NUMPAD9)
|
||||
CHECKKEY(KEY_MULTIPLY)
|
||||
CHECKKEY(KEY_ADD)
|
||||
CHECKKEY(KEY_SEPARATOR)
|
||||
CHECKKEY(KEY_SUBTRACT)
|
||||
CHECKKEY(KEY_DECIMAL)
|
||||
CHECKKEY(KEY_DIVIDE)
|
||||
CHECKKEY(KEY_F1)
|
||||
CHECKKEY(KEY_F2)
|
||||
CHECKKEY(KEY_F3)
|
||||
CHECKKEY(KEY_F4)
|
||||
CHECKKEY(KEY_F5)
|
||||
CHECKKEY(KEY_F6)
|
||||
CHECKKEY(KEY_F7)
|
||||
CHECKKEY(KEY_F8)
|
||||
CHECKKEY(KEY_F9)
|
||||
CHECKKEY(KEY_F10)
|
||||
CHECKKEY(KEY_F11)
|
||||
CHECKKEY(KEY_F12)
|
||||
CHECKKEY(KEY_F13)
|
||||
CHECKKEY(KEY_F14)
|
||||
CHECKKEY(KEY_F15)
|
||||
CHECKKEY(KEY_F16)
|
||||
CHECKKEY(KEY_F17)
|
||||
CHECKKEY(KEY_F18)
|
||||
CHECKKEY(KEY_F19)
|
||||
CHECKKEY(KEY_F20)
|
||||
CHECKKEY(KEY_F21)
|
||||
CHECKKEY(KEY_F22)
|
||||
CHECKKEY(KEY_F23)
|
||||
CHECKKEY(KEY_F24)
|
||||
CHECKKEY(KEY_NUMLOCK)
|
||||
CHECKKEY(KEY_SCROLL)
|
||||
CHECKKEY(KEY_LSHIFT)
|
||||
CHECKKEY(KEY_RSHIFT)
|
||||
CHECKKEY(KEY_LCONTROL)
|
||||
CHECKKEY(KEY_RCONTROL)
|
||||
CHECKKEY(KEY_LMENU)
|
||||
CHECKKEY(KEY_RMENU)
|
||||
CHECKKEY(KEY_PLUS)
|
||||
CHECKKEY(KEY_COMMA)
|
||||
CHECKKEY(KEY_MINUS)
|
||||
CHECKKEY(KEY_PERIOD)
|
||||
CHECKKEY(KEY_ATTN)
|
||||
CHECKKEY(KEY_CRSEL)
|
||||
CHECKKEY(KEY_EXSEL)
|
||||
CHECKKEY(KEY_EREOF)
|
||||
CHECKKEY(KEY_PLAY)
|
||||
CHECKKEY(KEY_ZOOM)
|
||||
CHECKKEY(KEY_PA1)
|
||||
CHECKKEY(KEY_OEM_CLEAR)
|
||||
for (u16 i = 0; i < ARRAYSIZE(table); i++) {
|
||||
if (strcmp(table[i].Name, name) == 0)
|
||||
return table[i];
|
||||
}
|
||||
|
||||
throw UnknownKeycode(name);
|
||||
}
|
||||
|
||||
static const char *KeyNames[] =
|
||||
{ "-", "KEY_LBUTTON", "KEY_RBUTTON", "KEY_CANCEL", "KEY_MBUTTON", "KEY_XBUTTON1",
|
||||
"KEY_XBUTTON2", "-", "KEY_BACK", "KEY_TAB", "-", "-", "KEY_CLEAR", "KEY_RETURN", "-",
|
||||
"-", "KEY_SHIFT", "KEY_CONTROL", "KEY_MENU", "KEY_PAUSE", "KEY_CAPITAL", "KEY_KANA", "-",
|
||||
"KEY_JUNJA", "KEY_FINAL", "KEY_KANJI", "-", "KEY_ESCAPE", "KEY_CONVERT", "KEY_NONCONVERT",
|
||||
"KEY_ACCEPT", "KEY_MODECHANGE", "KEY_SPACE", "KEY_PRIOR", "KEY_NEXT", "KEY_END",
|
||||
"KEY_HOME", "KEY_LEFT", "KEY_UP", "KEY_RIGHT", "KEY_DOWN", "KEY_SELECT", "KEY_PRINT",
|
||||
"KEY_EXECUTE", "KEY_SNAPSHOT", "KEY_INSERT", "KEY_DELETE", "KEY_HELP", "KEY_KEY_0",
|
||||
"KEY_KEY_1", "KEY_KEY_2", "KEY_KEY_3", "KEY_KEY_4", "KEY_KEY_5",
|
||||
"KEY_KEY_6", "KEY_KEY_7", "KEY_KEY_8", "KEY_KEY_9", "-", "-", "-", "-",
|
||||
"-", "-", "-", "KEY_KEY_A", "KEY_KEY_B", "KEY_KEY_C", "KEY_KEY_D",
|
||||
"KEY_KEY_E", "KEY_KEY_F", "KEY_KEY_G", "KEY_KEY_H", "KEY_KEY_I",
|
||||
"KEY_KEY_J", "KEY_KEY_K", "KEY_KEY_L", "KEY_KEY_M", "KEY_KEY_N",
|
||||
"KEY_KEY_O", "KEY_KEY_P", "KEY_KEY_Q", "KEY_KEY_R", "KEY_KEY_S",
|
||||
"KEY_KEY_T", "KEY_KEY_U", "KEY_KEY_V", "KEY_KEY_W", "KEY_KEY_X",
|
||||
"KEY_KEY_Y", "KEY_KEY_Z", "KEY_LWIN", "KEY_RWIN", "KEY_APPS", "-",
|
||||
"KEY_SLEEP", "KEY_NUMPAD0", "KEY_NUMPAD1", "KEY_NUMPAD2", "KEY_NUMPAD3",
|
||||
"KEY_NUMPAD4", "KEY_NUMPAD5", "KEY_NUMPAD6", "KEY_NUMPAD7",
|
||||
"KEY_NUMPAD8", "KEY_NUMPAD9", "KEY_MULTIPLY", "KEY_ADD", "KEY_SEPERATOR",
|
||||
"KEY_SUBTRACT", "KEY_DECIMAL", "KEY_DIVIDE", "KEY_F1", "KEY_F2", "KEY_F3",
|
||||
"KEY_F4", "KEY_F5", "KEY_F6", "KEY_F7", "KEY_F8", "KEY_F9", "KEY_F10",
|
||||
"KEY_F11", "KEY_F12", "KEY_F13", "KEY_F14", "KEY_F15", "KEY_F16",
|
||||
"KEY_F17", "KEY_F18", "KEY_F19", "KEY_F20", "KEY_F21", "KEY_F22",
|
||||
"KEY_F23", "KEY_F24", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"KEY_NUMLOCK", "KEY_SCROLL", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "KEY_LSHIFT", "KEY_RSHIFT", "KEY_LCONTROL",
|
||||
"KEY_RCONTROL", "KEY_LMENU", "KEY_RMENU", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "KEY_PLUS", "KEY_COMMA", "KEY_MINUS", "KEY_PERIOD", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "KEY_ATTN", "KEY_CRSEL", "KEY_EXSEL",
|
||||
"KEY_EREOF", "KEY_PLAY", "KEY_ZOOM", "KEY_PA1", "KEY_OEM_CLEAR", "-" };
|
||||
struct table_key lookup_keykey(irr::EKEY_CODE key)
|
||||
{
|
||||
for (u16 i = 0; i < ARRAYSIZE(table); i++) {
|
||||
if (table[i].Key == key)
|
||||
return table[i];
|
||||
}
|
||||
|
||||
#define N_(text) text
|
||||
std::ostringstream os;
|
||||
os << "<Keycode " << (int) key << ">";
|
||||
throw UnknownKeycode(os.str().c_str());
|
||||
}
|
||||
|
||||
static const char *KeyNamesLang[] =
|
||||
{ "-", N_("Left Button"), N_("Right Button"), N_("Cancel"), N_("Middle Button"), N_("X Button 1"),
|
||||
N_("X Button 2"), "-", N_("Back"), N_("Tab"), "-", "-", N_("Clear"), N_("Return"), "-",
|
||||
"-", N_("Shift"), N_("Control"), N_("Menu"), N_("Pause"), N_("Capital"), N_("Kana"), "-",
|
||||
N_("Junja"), N_("Final"), N_("Kanji"), "-", N_("Escape"), N_("Convert"), N_("Nonconvert"),
|
||||
N_("Accept"), N_("Mode Change"), N_("Space"), N_("Prior"), N_("Next"), N_("End"), N_("Home"),
|
||||
N_("Left"), N_("Up"), N_("Right"), N_("Down"), N_("Select"), N_("Print"), N_("Execute"),
|
||||
N_("Snapshot"), N_("Insert"), N_("Delete"), N_("Help"), "0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "-", "-", "-", "-", "-", "-", "-", "A", "B", "C",
|
||||
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q",
|
||||
"R", "S", "T", "U", "V", "W", "X", "Y", "Z", N_("Left Windows"),
|
||||
N_("Right Windows"), N_("Apps"), "-", N_("Sleep"), N_("Numpad 0"), N_("Numpad 1"),
|
||||
N_("Numpad 2"), N_("Numpad 3"), N_("Numpad 4"), N_("Numpad 5"), N_("Numpad 6"), N_("Numpad 7"),
|
||||
N_("Numpad 8"), N_("Numpad 9"), N_("Numpad *"), N_("Numpad +"), N_("Numpad /"), N_("Numpad -"),
|
||||
"Numpad .", "Numpad /", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",
|
||||
"F9", "F10", "F11", "F12", "F13", "F14", "F15", "F16", "F17", "F18",
|
||||
"F19", "F20", "F21", "F22", "F23", "F24", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", N_("Num Lock"), N_("Scroll Lock"), "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", N_("Left Shift"), N_("Right Shift"),
|
||||
N_("Left Control"), N_("Right Control"), N_("Left Menu"), N_("Right Menu"), "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", N_("Plus"), N_("Comma"), N_("Minus"), N_("Period"), "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-",
|
||||
"-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", N_("Attn"), N_("CrSel"),
|
||||
N_("ExSel"), N_("Erase OEF"), N_("Play"), N_("Zoom"), N_("PA1"), N_("OEM Clear"), "-" };
|
||||
struct table_key lookup_keychar(wchar_t Char)
|
||||
{
|
||||
for (u16 i = 0; i < ARRAYSIZE(table); i++) {
|
||||
if (table[i].Char == Char)
|
||||
return table[i];
|
||||
}
|
||||
|
||||
#undef N_
|
||||
std::ostringstream os;
|
||||
os << "<Char " << hex_encode((char*) &Char, sizeof(wchar_t)) << ">";
|
||||
throw UnknownKeycode(os.str().c_str());
|
||||
}
|
||||
|
||||
KeyPress::KeyPress() :
|
||||
Key(irr::KEY_KEY_CODES_COUNT),
|
||||
Char(L'\0')
|
||||
Char(L'\0'),
|
||||
m_name("")
|
||||
{}
|
||||
|
||||
KeyPress::KeyPress(const char *name)
|
||||
{
|
||||
if (name[0] == 0) {
|
||||
if (strlen(name) == 0) {
|
||||
Key = irr::KEY_KEY_CODES_COUNT;
|
||||
Char = L'\0';
|
||||
m_name = "";
|
||||
return;
|
||||
} else if (strlen(name) > 4) {
|
||||
} else if (strlen(name) <= 4) {
|
||||
// Lookup by resulting character
|
||||
int chars_read = mbtowc(&Char, name, 1);
|
||||
FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
|
||||
try {
|
||||
Key = keyname_to_keycode(name);
|
||||
m_name = name;
|
||||
if (strlen(name) > 8 && strncmp(name, "KEY_KEY_", 8) == 0) {
|
||||
int chars_read = mbtowc(&Char, name + 8, 1);
|
||||
|
||||
FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
|
||||
} else
|
||||
Char = L'\0';
|
||||
struct table_key k = lookup_keychar(Char);
|
||||
m_name = k.Name;
|
||||
Key = k.Key;
|
||||
return;
|
||||
} catch (UnknownKeycode &e) {};
|
||||
} else {
|
||||
// see if we can set it up as a KEY_KEY_something
|
||||
m_name = "KEY_KEY_";
|
||||
m_name += name;
|
||||
// Lookup by name
|
||||
m_name = name;
|
||||
try {
|
||||
Key = keyname_to_keycode(m_name.c_str());
|
||||
int chars_read = mbtowc(&Char, name, 1);
|
||||
|
||||
FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
|
||||
struct table_key k = lookup_keyname(name);
|
||||
Key = k.Key;
|
||||
Char = k.Char;
|
||||
return;
|
||||
} catch (UnknownKeycode &e) {};
|
||||
}
|
||||
|
||||
// it's not a (known) key, just take the first char and use that
|
||||
|
||||
// It's not a known key, complain and try to do something
|
||||
Key = irr::KEY_KEY_CODES_COUNT;
|
||||
|
||||
int mbtowc_ret = mbtowc(&Char, name, 1);
|
||||
FATAL_ERROR_IF(mbtowc_ret != 1, "Unexpected multibyte character");
|
||||
m_name = name[0];
|
||||
int chars_read = mbtowc(&Char, name, 1);
|
||||
FATAL_ERROR_IF(chars_read != 1, "Unexpected multibyte character");
|
||||
m_name = "";
|
||||
warningstream << "KeyPress: Unknown key '" << name << "', falling back to first char.";
|
||||
}
|
||||
|
||||
KeyPress::KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character)
|
||||
{
|
||||
Key = in.Key;
|
||||
if (prefer_character)
|
||||
Key = irr::KEY_KEY_CODES_COUNT;
|
||||
else
|
||||
Key = in.Key;
|
||||
Char = in.Char;
|
||||
|
||||
if(prefer_character){
|
||||
m_name.resize(MB_CUR_MAX+1, '\0');
|
||||
int written = wctomb(&m_name[0], Char);
|
||||
if(written > 0){
|
||||
infostream<<"KeyPress: Preferring character for "<<m_name<<std::endl;
|
||||
Key = irr::KEY_KEY_CODES_COUNT;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (valid_kcode(Key)) {
|
||||
m_name = KeyNames[Key];
|
||||
} else {
|
||||
m_name.resize(MB_CUR_MAX+1, '\0');
|
||||
int written = wctomb(&m_name[0], Char);
|
||||
if(written < 0){
|
||||
std::string hexstr = hex_encode((const char*)&Char, sizeof(Char));
|
||||
errorstream<<"KeyPress: Unexpected multibyte character "<<hexstr<<std::endl;
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (valid_kcode(Key))
|
||||
m_name = lookup_keykey(Key).Name;
|
||||
else
|
||||
m_name = lookup_keychar(Char).Name;
|
||||
} catch (UnknownKeycode &e) {
|
||||
m_name = "";
|
||||
};
|
||||
}
|
||||
|
||||
const char *KeyPress::sym() const
|
||||
{
|
||||
if (Key && Key < irr::KEY_KEY_CODES_COUNT)
|
||||
return KeyNames[Key];
|
||||
else {
|
||||
return m_name.c_str();
|
||||
}
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
const char *KeyPress::name() const
|
||||
{
|
||||
if (Key && Key < irr::KEY_KEY_CODES_COUNT)
|
||||
return KeyNamesLang[Key];
|
||||
else {
|
||||
return m_name.c_str();
|
||||
}
|
||||
if (m_name == "")
|
||||
return "";
|
||||
const char *ret;
|
||||
if (valid_kcode(Key))
|
||||
ret = lookup_keykey(Key).LangName;
|
||||
else
|
||||
ret = lookup_keychar(Char).LangName;
|
||||
return ret ? ret : "<Unnamed key>";
|
||||
}
|
||||
|
||||
const KeyPress EscapeKey("KEY_ESCAPE");
|
||||
const KeyPress CancelKey("KEY_CANCEL");
|
||||
const KeyPress NumberKey[] = {
|
||||
KeyPress("KEY_KEY_0"), KeyPress("KEY_KEY_1"), KeyPress("KEY_KEY_2"),
|
||||
KeyPress("KEY_KEY_3"), KeyPress("KEY_KEY_4"), KeyPress("KEY_KEY_5"),
|
||||
KeyPress("KEY_KEY_6"), KeyPress("KEY_KEY_7"), KeyPress("KEY_KEY_8"),
|
||||
KeyPress("KEY_KEY_9")};
|
||||
KeyPress("0"), KeyPress("1"), KeyPress("2"), KeyPress("3"), KeyPress("4"),
|
||||
KeyPress("5"), KeyPress("6"), KeyPress("7"), KeyPress("8"), KeyPress("9")
|
||||
};
|
||||
|
||||
/*
|
||||
Key config
|
||||
|
@ -360,8 +375,10 @@ KeyPress getKeySetting(const char *settingname)
|
|||
n = g_key_setting_cache.find(settingname);
|
||||
if(n != g_key_setting_cache.end())
|
||||
return n->second;
|
||||
g_key_setting_cache[settingname] = g_settings->get(settingname).c_str();
|
||||
return g_key_setting_cache.find(settingname)->second;
|
||||
|
||||
KeyPress k(g_settings->get(settingname).c_str());
|
||||
g_key_setting_cache[settingname] = k;
|
||||
return k;
|
||||
}
|
||||
|
||||
void clearKeyCache()
|
||||
|
|
|
@ -44,8 +44,6 @@ public:
|
|||
|
||||
const char *sym() const;
|
||||
const char *name() const;
|
||||
|
||||
std::string debug() const;
|
||||
protected:
|
||||
static bool valid_kcode(irr::EKEY_CODE k)
|
||||
{
|
||||
|
|
|
@ -27,8 +27,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
*/
|
||||
|
||||
// This directly sets the range of light.
|
||||
// Actually this is not the real maximum, and this is not the
|
||||
// brightest. The brightest is LIGHT_SUN.
|
||||
// Actually this is not the real maximum, and this is not the brightest, the
|
||||
// brightest is LIGHT_SUN.
|
||||
// If changed, this constant as defined in builtin/game/constants.lua must
|
||||
// also be changed.
|
||||
#define LIGHT_MAX 14
|
||||
// Light is stored as 4 bits, thus 15 is the maximum.
|
||||
// This brightness is reserved for sunlight
|
||||
|
|
|
@ -154,17 +154,27 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
|||
// Base terrain calculation
|
||||
s16 y = baseTerrainLevelAtPoint(p.X, p.Y);
|
||||
|
||||
// Ridge/river terrain calculation
|
||||
float width = 0.2;
|
||||
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||
// if inside a river this is an unsuitable spawn point
|
||||
if (fabs(uwatern) <= width)
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
// If enabled, check if inside a river
|
||||
if (spflags & MGV7_RIDGES) {
|
||||
float width = 0.2;
|
||||
float uwatern = NoisePerlin2D(&noise_ridge_uwater->np, p.X, p.Y, seed) * 2;
|
||||
if (fabs(uwatern) <= width)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
}
|
||||
|
||||
// If mountains are disabled, terrain level is base terrain level
|
||||
// Avoids spawn on non-existant mountain terrain
|
||||
if (!(spflags & MGV7_MOUNTAINS)) {
|
||||
if (y <= water_level || y > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
return y;
|
||||
}
|
||||
|
||||
// Mountain terrain calculation
|
||||
int iters = 128;
|
||||
while (iters--) {
|
||||
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // Air, y is ground level
|
||||
if (!getMountainTerrainAtPoint(p.X, y + 1, p.Y)) { // If air above
|
||||
if (y <= water_level || y > water_level + 16)
|
||||
return MAX_MAP_GENERATION_LIMIT; // Unsuitable spawn point
|
||||
else
|
||||
|
@ -173,7 +183,7 @@ int MapgenV7::getSpawnLevelAtPoint(v2s16 p)
|
|||
y++;
|
||||
}
|
||||
|
||||
// Unsuitable spawn point, no ground surface found
|
||||
// Unsuitable spawn point, no mountain surface found
|
||||
return MAX_MAP_GENERATION_LIMIT;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,9 +42,8 @@ void MapSector::deleteBlocks()
|
|||
m_block_cache = NULL;
|
||||
|
||||
// Delete all
|
||||
for(std::map<s16, MapBlock*>::iterator i = m_blocks.begin();
|
||||
i != m_blocks.end(); ++i)
|
||||
{
|
||||
for (UNORDERED_MAP<s16, MapBlock*>::iterator i = m_blocks.begin();
|
||||
i != m_blocks.end(); ++i) {
|
||||
delete i->second;
|
||||
}
|
||||
|
||||
|
@ -56,20 +55,13 @@ MapBlock * MapSector::getBlockBuffered(s16 y)
|
|||
{
|
||||
MapBlock *block;
|
||||
|
||||
if(m_block_cache != NULL && y == m_block_cache_y){
|
||||
if (m_block_cache != NULL && y == m_block_cache_y) {
|
||||
return m_block_cache;
|
||||
}
|
||||
|
||||
// If block doesn't exist, return NULL
|
||||
std::map<s16, MapBlock*>::iterator n = m_blocks.find(y);
|
||||
if(n == m_blocks.end())
|
||||
{
|
||||
block = NULL;
|
||||
}
|
||||
// If block exists, return it
|
||||
else{
|
||||
block = n->second;
|
||||
}
|
||||
UNORDERED_MAP<s16, MapBlock*>::iterator n = m_blocks.find(y);
|
||||
block = (n != m_blocks.end() ? n->second : NULL);
|
||||
|
||||
// Cache the last result
|
||||
m_block_cache_y = y;
|
||||
|
@ -135,18 +127,12 @@ void MapSector::deleteBlock(MapBlock *block)
|
|||
|
||||
void MapSector::getBlocks(MapBlockVect &dest)
|
||||
{
|
||||
for(std::map<s16, MapBlock*>::iterator bi = m_blocks.begin();
|
||||
bi != m_blocks.end(); ++bi)
|
||||
{
|
||||
for (UNORDERED_MAP<s16, MapBlock*>::iterator bi = m_blocks.begin();
|
||||
bi != m_blocks.end(); ++bi) {
|
||||
dest.push_back(bi->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool MapSector::empty()
|
||||
{
|
||||
return m_blocks.empty();
|
||||
}
|
||||
|
||||
/*
|
||||
ServerMapSector
|
||||
*/
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
|
||||
void getBlocks(MapBlockVect &dest);
|
||||
|
||||
bool empty();
|
||||
bool empty() const { return m_blocks.empty(); }
|
||||
|
||||
// Always false at the moment, because sector contains no metadata.
|
||||
bool differs_from_disk;
|
||||
|
@ -71,7 +71,7 @@ public:
|
|||
protected:
|
||||
|
||||
// The pile of MapBlocks
|
||||
std::map<s16, MapBlock*> m_blocks;
|
||||
UNORDERED_MAP<s16, MapBlock*> m_blocks;
|
||||
|
||||
Map *m_parent;
|
||||
// Position on parent (in MapBlock widths)
|
||||
|
|
|
@ -26,12 +26,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "util/numeric.h"
|
||||
|
||||
FlagDesc flagdesc_deco[] = {
|
||||
{"place_center_x", DECO_PLACE_CENTER_X},
|
||||
{"place_center_y", DECO_PLACE_CENTER_Y},
|
||||
{"place_center_z", DECO_PLACE_CENTER_Z},
|
||||
{"place_center_x", DECO_PLACE_CENTER_X},
|
||||
{"place_center_y", DECO_PLACE_CENTER_Y},
|
||||
{"place_center_z", DECO_PLACE_CENTER_Z},
|
||||
{"force_placement", DECO_FORCE_PLACEMENT},
|
||||
{"liquid_surface", DECO_LIQUID_SURFACE},
|
||||
{NULL, 0}
|
||||
{"liquid_surface", DECO_LIQUID_SURFACE},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
|
@ -82,6 +82,56 @@ Decoration::~Decoration()
|
|||
void Decoration::resolveNodeNames()
|
||||
{
|
||||
getIdsFromNrBacklog(&c_place_on);
|
||||
getIdsFromNrBacklog(&c_spawnby);
|
||||
}
|
||||
|
||||
|
||||
bool Decoration::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
||||
{
|
||||
// Check if the decoration can be placed on this node
|
||||
u32 vi = vm->m_area.index(p);
|
||||
if (!CONTAINS(c_place_on, vm->m_data[vi].getContent()))
|
||||
return false;
|
||||
|
||||
// Don't continue if there are no spawnby constraints
|
||||
if (nspawnby == -1)
|
||||
return true;
|
||||
|
||||
int nneighs = 0;
|
||||
static const v3s16 dirs[16] = {
|
||||
v3s16( 0, 0, 1),
|
||||
v3s16( 0, 0, -1),
|
||||
v3s16( 1, 0, 0),
|
||||
v3s16(-1, 0, 0),
|
||||
v3s16( 1, 0, 1),
|
||||
v3s16(-1, 0, 1),
|
||||
v3s16(-1, 0, -1),
|
||||
v3s16( 1, 0, -1),
|
||||
|
||||
v3s16( 0, 1, 1),
|
||||
v3s16( 0, 1, -1),
|
||||
v3s16( 1, 1, 0),
|
||||
v3s16(-1, 1, 0),
|
||||
v3s16( 1, 1, 1),
|
||||
v3s16(-1, 1, 1),
|
||||
v3s16(-1, 1, -1),
|
||||
v3s16( 1, 1, -1)
|
||||
};
|
||||
|
||||
// Check these 16 neighbouring nodes for enough spawnby nodes
|
||||
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
||||
u32 index = vm->m_area.index(p + dirs[i]);
|
||||
if (!vm->m_area.contains(index))
|
||||
continue;
|
||||
|
||||
if (CONTAINS(c_spawnby, vm->m_data[index].getContent()))
|
||||
nneighs++;
|
||||
}
|
||||
|
||||
if (nneighs < nspawnby)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -236,66 +286,15 @@ void DecoSimple::resolveNodeNames()
|
|||
{
|
||||
Decoration::resolveNodeNames();
|
||||
getIdsFromNrBacklog(&c_decos);
|
||||
getIdsFromNrBacklog(&c_spawnby);
|
||||
}
|
||||
|
||||
|
||||
bool DecoSimple::canPlaceDecoration(MMVManip *vm, v3s16 p)
|
||||
{
|
||||
// Don't bother if there aren't any decorations to place
|
||||
if (c_decos.size() == 0)
|
||||
return false;
|
||||
|
||||
u32 vi = vm->m_area.index(p);
|
||||
|
||||
// Check if the decoration can be placed on this node
|
||||
if (!CONTAINS(c_place_on, vm->m_data[vi].getContent()))
|
||||
return false;
|
||||
|
||||
// Don't continue if there are no spawnby constraints
|
||||
if (nspawnby == -1)
|
||||
return true;
|
||||
|
||||
int nneighs = 0;
|
||||
v3s16 dirs[16] = {
|
||||
v3s16( 0, 0, 1),
|
||||
v3s16( 0, 0, -1),
|
||||
v3s16( 1, 0, 0),
|
||||
v3s16(-1, 0, 0),
|
||||
v3s16( 1, 0, 1),
|
||||
v3s16(-1, 0, 1),
|
||||
v3s16(-1, 0, -1),
|
||||
v3s16( 1, 0, -1),
|
||||
|
||||
v3s16( 0, 1, 1),
|
||||
v3s16( 0, 1, -1),
|
||||
v3s16( 1, 1, 0),
|
||||
v3s16(-1, 1, 0),
|
||||
v3s16( 1, 1, 1),
|
||||
v3s16(-1, 1, 1),
|
||||
v3s16(-1, 1, -1),
|
||||
v3s16( 1, 1, -1)
|
||||
};
|
||||
|
||||
// Check a Moore neighborhood if there are enough spawnby nodes
|
||||
for (size_t i = 0; i != ARRLEN(dirs); i++) {
|
||||
u32 index = vm->m_area.index(p + dirs[i]);
|
||||
if (!vm->m_area.contains(index))
|
||||
continue;
|
||||
|
||||
if (CONTAINS(c_spawnby, vm->m_data[index].getContent()))
|
||||
nneighs++;
|
||||
}
|
||||
|
||||
if (nneighs < nspawnby)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
size_t DecoSimple::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
||||
{
|
||||
// Don't bother if there aren't any decorations to place
|
||||
if (c_decos.size() == 0)
|
||||
return 0;
|
||||
|
||||
if (!canPlaceDecoration(vm, p))
|
||||
return 0;
|
||||
|
||||
|
@ -345,9 +344,7 @@ size_t DecoSchematic::generate(MMVManip *vm, PcgRandom *pr, v3s16 p)
|
|||
if (schematic == NULL)
|
||||
return 0;
|
||||
|
||||
u32 vi = vm->m_area.index(p);
|
||||
content_t c = vm->m_data[vi].getContent();
|
||||
if (!CONTAINS(c_place_on, c))
|
||||
if (!canPlaceDecoration(vm, p))
|
||||
return 0;
|
||||
|
||||
if (flags & DECO_PLACE_CENTER_X)
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
|
||||
virtual void resolveNodeNames();
|
||||
|
||||
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
|
||||
size_t placeDeco(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||
//size_t placeCutoffs(Mapgen *mg, u32 blockseed, v3s16 nmin, v3s16 nmax);
|
||||
|
||||
|
@ -82,6 +83,8 @@ public:
|
|||
s16 y_max;
|
||||
float fill_ratio;
|
||||
NoiseParams np;
|
||||
std::vector<content_t> c_spawnby;
|
||||
s16 nspawnby;
|
||||
|
||||
UNORDERED_SET<u8> biomes;
|
||||
//std::list<CutoffData> cutoffs;
|
||||
|
@ -90,17 +93,13 @@ public:
|
|||
|
||||
class DecoSimple : public Decoration {
|
||||
public:
|
||||
virtual void resolveNodeNames();
|
||||
virtual size_t generate(MMVManip *vm, PcgRandom *pr, v3s16 p);
|
||||
bool canPlaceDecoration(MMVManip *vm, v3s16 p);
|
||||
virtual int getHeight();
|
||||
|
||||
virtual void resolveNodeNames();
|
||||
|
||||
std::vector<content_t> c_decos;
|
||||
std::vector<content_t> c_spawnby;
|
||||
s16 deco_height;
|
||||
s16 deco_height_max;
|
||||
s16 nspawnby;
|
||||
};
|
||||
|
||||
class DecoSchematic : public Decoration {
|
||||
|
|
|
@ -564,14 +564,14 @@ void Schematic::applyProbabilities(v3s16 p0,
|
|||
void generate_nodelist_and_update_ids(MapNode *nodes, size_t nodecount,
|
||||
std::vector<std::string> *usednodes, INodeDefManager *ndef)
|
||||
{
|
||||
std::map<content_t, content_t> nodeidmap;
|
||||
UNORDERED_MAP<content_t, content_t> nodeidmap;
|
||||
content_t numids = 0;
|
||||
|
||||
for (size_t i = 0; i != nodecount; i++) {
|
||||
content_t id;
|
||||
content_t c = nodes[i].getContent();
|
||||
|
||||
std::map<content_t, content_t>::const_iterator it = nodeidmap.find(c);
|
||||
UNORDERED_MAP<content_t, content_t>::const_iterator it = nodeidmap.find(c);
|
||||
if (it == nodeidmap.end()) {
|
||||
id = numids;
|
||||
numids++;
|
||||
|
|
|
@ -1065,7 +1065,7 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt)
|
|||
std::wstring wname = narrow_to_wide(name);
|
||||
|
||||
std::wstring answer_to_sender = handleChat(name, wname, message,
|
||||
true, pkt->getPeerId());
|
||||
true, dynamic_cast<RemotePlayer *>(player));
|
||||
if (!answer_to_sender.empty()) {
|
||||
// Send the answer to sender
|
||||
SendChatMessage(pkt->getPeerId(), answer_to_sender);
|
||||
|
@ -1656,16 +1656,16 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
|
|||
}
|
||||
|
||||
} // action == 4
|
||||
|
||||
|
||||
/*
|
||||
5: rightclick air
|
||||
*/
|
||||
else if (action == 5) {
|
||||
ItemStack item = playersao->getWieldedItem();
|
||||
|
||||
actionstream << player->getName() << " activates "
|
||||
|
||||
actionstream << player->getName() << " activates "
|
||||
<< item.name << std::endl;
|
||||
|
||||
|
||||
if (m_script->item_OnSecondaryUse(
|
||||
item, playersao)) {
|
||||
if( playersao->setWieldedItem(item)) {
|
||||
|
|
|
@ -74,6 +74,11 @@ void NodeMetadata::clear()
|
|||
m_inventory->clear();
|
||||
}
|
||||
|
||||
bool NodeMetadata::empty() const
|
||||
{
|
||||
return m_stringvars.size() == 0 && m_inventory->getLists().size() == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
NodeMetadataList
|
||||
*/
|
||||
|
@ -84,14 +89,13 @@ void NodeMetadataList::serialize(std::ostream &os) const
|
|||
Version 0 is a placeholder for "nothing to see here; go away."
|
||||
*/
|
||||
|
||||
if(m_data.empty()){
|
||||
u16 count = countNonEmpty();
|
||||
if (count == 0) {
|
||||
writeU8(os, 0); // version
|
||||
return;
|
||||
}
|
||||
|
||||
writeU8(os, 1); // version
|
||||
|
||||
u16 count = m_data.size();
|
||||
writeU16(os, count);
|
||||
|
||||
for(std::map<v3s16, NodeMetadata*>::const_iterator
|
||||
|
@ -100,6 +104,8 @@ void NodeMetadataList::serialize(std::ostream &os) const
|
|||
{
|
||||
v3s16 p = i->first;
|
||||
NodeMetadata *data = i->second;
|
||||
if (data->empty())
|
||||
continue;
|
||||
|
||||
u16 p16 = p.Z * MAP_BLOCKSIZE * MAP_BLOCKSIZE + p.Y * MAP_BLOCKSIZE + p.X;
|
||||
writeU16(os, p16);
|
||||
|
@ -200,6 +206,17 @@ void NodeMetadataList::clear()
|
|||
m_data.clear();
|
||||
}
|
||||
|
||||
int NodeMetadataList::countNonEmpty() const
|
||||
{
|
||||
int n = 0;
|
||||
std::map<v3s16, NodeMetadata*>::const_iterator it;
|
||||
for (it = m_data.begin(); it != m_data.end(); ++it) {
|
||||
if (!it->second->empty())
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
std::string NodeMetadata::getString(const std::string &name,
|
||||
unsigned short recursion) const
|
||||
{
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
void deSerialize(std::istream &is);
|
||||
|
||||
void clear();
|
||||
bool empty() const;
|
||||
|
||||
// Generic key/value store
|
||||
std::string getString(const std::string &name, unsigned short recursion = 0) const;
|
||||
|
@ -94,6 +95,8 @@ public:
|
|||
void clear();
|
||||
|
||||
private:
|
||||
int countNonEmpty() const;
|
||||
|
||||
std::map<v3s16, NodeMetadata *> m_data;
|
||||
};
|
||||
|
||||
|
|
|
@ -227,10 +227,25 @@ void Player::clearHud()
|
|||
}
|
||||
}
|
||||
|
||||
// static config cache for remoteplayer
|
||||
bool RemotePlayer::m_setting_cache_loaded = false;
|
||||
float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
|
||||
u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;
|
||||
|
||||
RemotePlayer::RemotePlayer(IGameDef *gamedef, const char *name):
|
||||
Player(gamedef, name),
|
||||
m_sao(NULL)
|
||||
m_sao(NULL),
|
||||
m_last_chat_message_sent(time(NULL)),
|
||||
m_chat_message_allowance(5.0f),
|
||||
m_message_rate_overhead(0)
|
||||
{
|
||||
if (!RemotePlayer::m_setting_cache_loaded) {
|
||||
RemotePlayer::m_setting_chat_message_limit_per_10sec =
|
||||
g_settings->getFloat("chat_message_limit_per_10sec");
|
||||
RemotePlayer::m_setting_chat_message_limit_trigger_kick =
|
||||
g_settings->getU16("chat_message_limit_trigger_kick");
|
||||
RemotePlayer::m_setting_cache_loaded = true;
|
||||
}
|
||||
movement_acceleration_default = g_settings->getFloat("movement_acceleration_default") * BS;
|
||||
movement_acceleration_air = g_settings->getFloat("movement_acceleration_air") * BS;
|
||||
movement_acceleration_fast = g_settings->getFloat("movement_acceleration_fast") * BS;
|
||||
|
@ -304,3 +319,42 @@ void RemotePlayer::setPosition(const v3f &position)
|
|||
m_sao->setBasePosition(position);
|
||||
}
|
||||
|
||||
const RemotePlayerChatResult RemotePlayer::canSendChatMessage()
|
||||
{
|
||||
// Rate limit messages
|
||||
u32 now = time(NULL);
|
||||
float time_passed = now - m_last_chat_message_sent;
|
||||
m_last_chat_message_sent = now;
|
||||
|
||||
// If this feature is disabled
|
||||
if (m_setting_chat_message_limit_per_10sec <= 0.0) {
|
||||
return RPLAYER_CHATRESULT_OK;
|
||||
}
|
||||
|
||||
m_chat_message_allowance += time_passed * (m_setting_chat_message_limit_per_10sec / 8.0f);
|
||||
if (m_chat_message_allowance > m_setting_chat_message_limit_per_10sec) {
|
||||
m_chat_message_allowance = m_setting_chat_message_limit_per_10sec;
|
||||
}
|
||||
|
||||
if (m_chat_message_allowance < 1.0f) {
|
||||
infostream << "Player " << m_name
|
||||
<< " chat limited due to excessive message amount." << std::endl;
|
||||
|
||||
// Kick player if flooding is too intensive
|
||||
m_message_rate_overhead++;
|
||||
if (m_message_rate_overhead > RemotePlayer::m_setting_chat_message_limit_trigger_kick) {
|
||||
return RPLAYER_CHATRESULT_KICK;
|
||||
}
|
||||
|
||||
return RPLAYER_CHATRESULT_FLOODING;
|
||||
}
|
||||
|
||||
// Reinit message overhead
|
||||
if (m_message_rate_overhead > 0) {
|
||||
m_message_rate_overhead = 0;
|
||||
}
|
||||
|
||||
m_chat_message_allowance -= 1.0f;
|
||||
return RPLAYER_CHATRESULT_OK;
|
||||
}
|
||||
|
||||
|
|
16
src/player.h
16
src/player.h
|
@ -439,7 +439,11 @@ private:
|
|||
Mutex m_mutex;
|
||||
};
|
||||
|
||||
|
||||
enum RemotePlayerChatResult {
|
||||
RPLAYER_CHATRESULT_OK,
|
||||
RPLAYER_CHATRESULT_FLOODING,
|
||||
RPLAYER_CHATRESULT_KICK,
|
||||
};
|
||||
/*
|
||||
Player on the server
|
||||
*/
|
||||
|
@ -457,8 +461,18 @@ public:
|
|||
{ m_sao = sao; }
|
||||
void setPosition(const v3f &position);
|
||||
|
||||
const RemotePlayerChatResult canSendChatMessage();
|
||||
|
||||
private:
|
||||
PlayerSAO *m_sao;
|
||||
|
||||
static bool m_setting_cache_loaded;
|
||||
static float m_setting_chat_message_limit_per_10sec;
|
||||
static u16 m_setting_chat_message_limit_trigger_kick;
|
||||
|
||||
u32 m_last_chat_message_sent;
|
||||
float m_chat_message_allowance;
|
||||
u16 m_message_rate_overhead;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -613,10 +613,11 @@ void setXorgClassHint(const video::SExposedVideoData &video_data,
|
|||
|
||||
bool setXorgWindowIcon(IrrlichtDevice *device)
|
||||
{
|
||||
#if RUN_IN_PLACE
|
||||
#ifdef XORG_USED
|
||||
# if RUN_IN_PLACE
|
||||
return setXorgWindowIconFromPath(device,
|
||||
path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
|
||||
#else
|
||||
# else
|
||||
// We have semi-support for reading in-place data if we are
|
||||
// compiled with RUN_IN_PLACE. Don't break with this and
|
||||
// also try the path_share location.
|
||||
|
@ -625,6 +626,9 @@ bool setXorgWindowIcon(IrrlichtDevice *device)
|
|||
ICON_DIR "/hicolor/128x128/apps/" PROJECT_NAME ".png") ||
|
||||
setXorgWindowIconFromPath(device,
|
||||
path_share + "/misc/" PROJECT_NAME "-xorg-icon-128.png");
|
||||
# endif
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -829,20 +829,18 @@ void push_tool_capabilities(lua_State *L,
|
|||
// Create groupcaps table
|
||||
lua_newtable(L);
|
||||
// For each groupcap
|
||||
for(std::map<std::string, ToolGroupCap>::const_iterator
|
||||
i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
|
||||
for (ToolGCMap::const_iterator i = toolcap.groupcaps.begin();
|
||||
i != toolcap.groupcaps.end(); i++) {
|
||||
// Create groupcap table
|
||||
lua_newtable(L);
|
||||
const std::string &name = i->first;
|
||||
const ToolGroupCap &groupcap = i->second;
|
||||
// Create subtable "times"
|
||||
lua_newtable(L);
|
||||
for(std::map<int, float>::const_iterator
|
||||
i = groupcap.times.begin(); i != groupcap.times.end(); i++){
|
||||
int rating = i->first;
|
||||
float time = i->second;
|
||||
lua_pushinteger(L, rating);
|
||||
lua_pushnumber(L, time);
|
||||
for (UNORDERED_MAP<int, float>::const_iterator
|
||||
i = groupcap.times.begin(); i != groupcap.times.end(); i++) {
|
||||
lua_pushinteger(L, i->first);
|
||||
lua_pushnumber(L, i->second);
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
// Set subtable "times"
|
||||
|
@ -858,8 +856,8 @@ void push_tool_capabilities(lua_State *L,
|
|||
//Create damage_groups table
|
||||
lua_newtable(L);
|
||||
// For each damage group
|
||||
for(std::map<std::string, s16>::const_iterator
|
||||
i = toolcap.damageGroups.begin(); i != toolcap.damageGroups.end(); i++){
|
||||
for (DamageGroup::const_iterator i = toolcap.damageGroups.begin();
|
||||
i != toolcap.damageGroups.end(); i++) {
|
||||
// Create damage group table
|
||||
lua_pushinteger(L, i->second);
|
||||
lua_setfield(L, -2, i->first.c_str());
|
||||
|
@ -1065,8 +1063,7 @@ void push_flags_string(lua_State *L, FlagDesc *flagdesc, u32 flags, u32 flagmask
|
|||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
void read_groups(lua_State *L, int index,
|
||||
std::map<std::string, int> &result)
|
||||
void read_groups(lua_State *L, int index, ItemGroupList &result)
|
||||
{
|
||||
if (!lua_istable(L,index))
|
||||
return;
|
||||
|
@ -1085,11 +1082,10 @@ void read_groups(lua_State *L, int index,
|
|||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void push_groups(lua_State *L, const std::map<std::string, int> &groups)
|
||||
void push_groups(lua_State *L, const ItemGroupList &groups)
|
||||
{
|
||||
lua_newtable(L);
|
||||
std::map<std::string, int>::const_iterator it;
|
||||
for (it = groups.begin(); it != groups.end(); ++it) {
|
||||
for (ItemGroupList::const_iterator it = groups.begin(); it != groups.end(); ++it) {
|
||||
lua_pushnumber(L, it->second);
|
||||
lua_setfield(L, -2, it->first.c_str());
|
||||
}
|
||||
|
|
|
@ -33,11 +33,11 @@ extern "C" {
|
|||
}
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "util/string.h"
|
||||
#include "itemgroup.h"
|
||||
|
||||
namespace Json { class Value; }
|
||||
|
||||
|
@ -106,10 +106,10 @@ void pushnode (lua_State *L, const MapNode &n,
|
|||
NodeBox read_nodebox (lua_State *L, int index);
|
||||
|
||||
void read_groups (lua_State *L, int index,
|
||||
std::map<std::string, int> &result);
|
||||
ItemGroupList &result);
|
||||
|
||||
void push_groups (lua_State *L,
|
||||
const std::map<std::string, int> &groups);
|
||||
const ItemGroupList &groups);
|
||||
|
||||
//TODO rename to "read_enum_field"
|
||||
int getenumfield (lua_State *L, int table,
|
||||
|
|
|
@ -28,7 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define C_CONVERTER_H_
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include "util/cpp11_container.h"
|
||||
|
||||
#include "irrlichttypes_bloated.h"
|
||||
#include "common/c_types.h"
|
||||
|
@ -60,7 +60,7 @@ bool getintfield(lua_State *L, int table,
|
|||
bool getintfield(lua_State *L, int table,
|
||||
const char *fieldname, u32 &result);
|
||||
void read_groups(lua_State *L, int index,
|
||||
std::map<std::string, int> &result);
|
||||
UNORDERED_MAP<std::string, int> &result);
|
||||
bool getboolfield(lua_State *L, int table,
|
||||
const char *fieldname, bool &result);
|
||||
bool getfloatfield(lua_State *L, int table,
|
||||
|
|
|
@ -111,6 +111,9 @@ int LuaAreaStore::l_get_area(lua_State *L)
|
|||
const Area *res;
|
||||
|
||||
res = ast->getArea(id);
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
push_area(L, res, include_borders, include_data);
|
||||
|
||||
return 1;
|
||||
|
|
|
@ -902,6 +902,7 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02);
|
||||
deco->y_min = getintfield_default(L, index, "y_min", -31000);
|
||||
deco->y_max = getintfield_default(L, index, "y_max", 31000);
|
||||
deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||
deco->sidelen = getintfield_default(L, index, "sidelen", 8);
|
||||
if (deco->sidelen <= 0) {
|
||||
errorstream << "register_decoration: sidelen must be "
|
||||
|
@ -929,6 +930,14 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
errorstream << "register_decoration: couldn't get all biomes " << std::endl;
|
||||
lua_pop(L, 1);
|
||||
|
||||
//// Get node name(s) to 'spawn by'
|
||||
size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames);
|
||||
deco->m_nnlistsizes.push_back(nnames);
|
||||
if (nnames == 0 && deco->nspawnby != -1) {
|
||||
errorstream << "register_decoration: no spawn_by nodes defined,"
|
||||
" but num_spawn_by specified" << std::endl;
|
||||
}
|
||||
|
||||
//// Handle decoration type-specific parameters
|
||||
bool success = false;
|
||||
switch (decotype) {
|
||||
|
@ -962,12 +971,10 @@ int ModApiMapgen::l_register_decoration(lua_State *L)
|
|||
|
||||
bool read_deco_simple(lua_State *L, DecoSimple *deco)
|
||||
{
|
||||
size_t nnames;
|
||||
int index = 1;
|
||||
|
||||
deco->deco_height = getintfield_default(L, index, "height", 1);
|
||||
deco->deco_height_max = getintfield_default(L, index, "height_max", 0);
|
||||
deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1);
|
||||
|
||||
if (deco->deco_height <= 0) {
|
||||
errorstream << "register_decoration: simple decoration height"
|
||||
|
@ -975,7 +982,7 @@ bool read_deco_simple(lua_State *L, DecoSimple *deco)
|
|||
return false;
|
||||
}
|
||||
|
||||
nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames);
|
||||
size_t nnames = getstringlistfield(L, index, "decoration", &deco->m_nodenames);
|
||||
deco->m_nnlistsizes.push_back(nnames);
|
||||
if (nnames == 0) {
|
||||
errorstream << "register_decoration: no decoration nodes "
|
||||
|
@ -983,14 +990,6 @@ bool read_deco_simple(lua_State *L, DecoSimple *deco)
|
|||
return false;
|
||||
}
|
||||
|
||||
nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames);
|
||||
deco->m_nnlistsizes.push_back(nnames);
|
||||
if (nnames == 0 && deco->nspawnby != -1) {
|
||||
errorstream << "register_decoration: no spawn_by nodes defined,"
|
||||
" but num_spawn_by specified" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ int ModApiUtil::l_write_json(lua_State *L)
|
|||
int ModApiUtil::l_get_dig_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
ItemGroupList groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
|
@ -235,7 +235,7 @@ int ModApiUtil::l_get_dig_params(lua_State *L)
|
|||
int ModApiUtil::l_get_hit_params(lua_State *L)
|
||||
{
|
||||
NO_MAP_LOCK_REQUIRED;
|
||||
std::map<std::string, int> groups;
|
||||
UNORDERED_MAP<std::string, int> groups;
|
||||
read_groups(L, 1, groups);
|
||||
ToolCapabilities tp = read_tool_capabilities(L, 2);
|
||||
if(lua_isnoneornil(L, 3))
|
||||
|
|
|
@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "serialization.h"
|
||||
|
||||
#include "util/serialize.h"
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) && !defined(WIN32_NO_ZLIB_WINAPI)
|
||||
#define ZLIB_WINAPI
|
||||
#endif
|
||||
#include "zlib.h"
|
||||
|
|
|
@ -358,6 +358,7 @@ Server::Server(
|
|||
add_legacy_abms(m_env, m_nodedef);
|
||||
|
||||
m_liquid_transform_every = g_settings->getFloat("liquid_update");
|
||||
m_max_chatmessage_length = g_settings->getU16("chat_message_max_size");
|
||||
}
|
||||
|
||||
Server::~Server()
|
||||
|
@ -668,7 +669,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
MutexAutoLock envlock(m_env_mutex);
|
||||
|
||||
m_clients.lock();
|
||||
std::map<u16, RemoteClient*> clients = m_clients.getClientList();
|
||||
UNORDERED_MAP<u16, RemoteClient*> clients = m_clients.getClientList();
|
||||
ScopeProfiler sp(g_profiler, "Server: checking added and deleted objs");
|
||||
|
||||
// Radius inside which objects are active
|
||||
|
@ -684,8 +685,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
if (player_radius == 0 && is_transfer_limited)
|
||||
player_radius = radius;
|
||||
|
||||
for (std::map<u16, RemoteClient*>::iterator
|
||||
i = clients.begin();
|
||||
for (UNORDERED_MAP<u16, RemoteClient*>::iterator i = clients.begin();
|
||||
i != clients.end(); ++i) {
|
||||
RemoteClient *client = i->second;
|
||||
|
||||
|
@ -695,7 +695,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
continue;
|
||||
|
||||
Player *player = m_env->getPlayer(client->peer_id);
|
||||
if(player == NULL) {
|
||||
if (player == NULL) {
|
||||
// This can happen if the client timeouts somehow
|
||||
/*warningstream<<FUNCTION_NAME<<": Client "
|
||||
<<client->peer_id
|
||||
|
@ -816,10 +816,9 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
}
|
||||
|
||||
m_clients.lock();
|
||||
std::map<u16, RemoteClient*> clients = m_clients.getClientList();
|
||||
UNORDERED_MAP<u16, RemoteClient*> clients = m_clients.getClientList();
|
||||
// Route data to every client
|
||||
for (std::map<u16, RemoteClient*>::iterator
|
||||
i = clients.begin();
|
||||
for (UNORDERED_MAP<u16, RemoteClient*>::iterator i = clients.begin();
|
||||
i != clients.end(); ++i) {
|
||||
RemoteClient *client = i->second;
|
||||
std::string reliable_data;
|
||||
|
@ -2734,8 +2733,7 @@ void Server::handleChatInterfaceEvent(ChatEvent *evt)
|
|||
}
|
||||
|
||||
std::wstring Server::handleChat(const std::string &name, const std::wstring &wname,
|
||||
const std::wstring &wmessage, bool check_shout_priv,
|
||||
u16 peer_id_to_avoid_sending)
|
||||
const std::wstring &wmessage, bool check_shout_priv, RemotePlayer *player)
|
||||
{
|
||||
// If something goes wrong, this player is to blame
|
||||
RollbackScopeActor rollback_scope(m_rollback,
|
||||
|
@ -2753,6 +2751,28 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna
|
|||
if (ate)
|
||||
return L"";
|
||||
|
||||
if (player) {
|
||||
switch (player->canSendChatMessage()) {
|
||||
case RPLAYER_CHATRESULT_FLOODING: {
|
||||
std::wstringstream ws;
|
||||
ws << L"You cannot send more messages. You are limited to "
|
||||
<< g_settings->getFloat("chat_message_limit_per_10sec")
|
||||
<< " messages per 10 seconds.";
|
||||
return ws.str();
|
||||
}
|
||||
case RPLAYER_CHATRESULT_KICK:
|
||||
DenyAccess_Legacy(player->peer_id, L"You have been kicked due to message flooding.");
|
||||
return L"";
|
||||
case RPLAYER_CHATRESULT_OK: break;
|
||||
default: FATAL_ERROR("Unhandled chat filtering result found.");
|
||||
}
|
||||
}
|
||||
|
||||
if (m_max_chatmessage_length > 0 && wmessage.length() > m_max_chatmessage_length) {
|
||||
return L"Your message exceed the maximum chat message limit set on the server. "
|
||||
"It was refused. Send a shorter message";
|
||||
}
|
||||
|
||||
// Commands are implemented in Lua, so only catch invalid
|
||||
// commands that were not "eaten" and send an error back
|
||||
if (wmessage[0] == L'/') {
|
||||
|
@ -2787,6 +2807,7 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna
|
|||
|
||||
std::vector<u16> clients = m_clients.getClientIDs();
|
||||
|
||||
u16 peer_id_to_avoid_sending = (player ? player->peer_id : PEER_ID_INEXISTENT);
|
||||
for (u16 i = 0; i < clients.size(); i++) {
|
||||
u16 cid = clients[i];
|
||||
if (cid != peer_id_to_avoid_sending)
|
||||
|
|
|
@ -487,7 +487,7 @@ private:
|
|||
std::wstring handleChat(const std::string &name, const std::wstring &wname,
|
||||
const std::wstring &wmessage,
|
||||
bool check_shout_priv = false,
|
||||
u16 peer_id_to_avoid_sending = PEER_ID_INEXISTENT);
|
||||
RemotePlayer *player = NULL);
|
||||
void handleAdminChat(const ChatEventChat *evt);
|
||||
|
||||
v3f findSpawnPos();
|
||||
|
@ -522,6 +522,7 @@ private:
|
|||
// If true, do not allow multiple players and hide some multiplayer
|
||||
// functionality
|
||||
bool m_simple_singleplayer_mode;
|
||||
u16 m_max_chatmessage_length;
|
||||
|
||||
// Thread can set; step() will throw as ServerError
|
||||
MutexedVariable<std::string> m_async_fatal_error;
|
||||
|
|
|
@ -196,9 +196,8 @@ void Settings::writeLines(std::ostream &os, u32 tab_depth) const
|
|||
{
|
||||
MutexAutoLock lock(m_mutex);
|
||||
|
||||
for (std::map<std::string, SettingsEntry>::const_iterator
|
||||
it = m_settings.begin();
|
||||
it != m_settings.end(); ++it)
|
||||
for (SettingEntries::const_iterator it = m_settings.begin();
|
||||
it != m_settings.end(); ++it)
|
||||
printEntry(os, it->first, it->second, tab_depth);
|
||||
}
|
||||
|
||||
|
@ -231,7 +230,7 @@ void Settings::printEntry(std::ostream &os, const std::string &name,
|
|||
bool Settings::updateConfigObject(std::istream &is, std::ostream &os,
|
||||
const std::string &end, u32 tab_depth)
|
||||
{
|
||||
std::map<std::string, SettingsEntry>::const_iterator it;
|
||||
SettingEntries::const_iterator it;
|
||||
std::set<std::string> present_entries;
|
||||
std::string line, name, value;
|
||||
bool was_modified = false;
|
||||
|
@ -381,7 +380,7 @@ const SettingsEntry &Settings::getEntry(const std::string &name) const
|
|||
{
|
||||
MutexAutoLock lock(m_mutex);
|
||||
|
||||
std::map<std::string, SettingsEntry>::const_iterator n;
|
||||
SettingEntries::const_iterator n;
|
||||
if ((n = m_settings.find(name)) == m_settings.end()) {
|
||||
if ((n = m_defaults.find(name)) == m_defaults.end())
|
||||
throw SettingNotFoundException("Setting [" + name + "] not found.");
|
||||
|
@ -572,9 +571,8 @@ bool Settings::exists(const std::string &name) const
|
|||
std::vector<std::string> Settings::getNames() const
|
||||
{
|
||||
std::vector<std::string> names;
|
||||
for (std::map<std::string, SettingsEntry>::const_iterator
|
||||
i = m_settings.begin();
|
||||
i != m_settings.end(); ++i) {
|
||||
for (SettingEntries::const_iterator i = m_settings.begin();
|
||||
i != m_settings.end(); ++i) {
|
||||
names.push_back(i->first);
|
||||
}
|
||||
return names;
|
||||
|
@ -880,7 +878,7 @@ bool Settings::remove(const std::string &name)
|
|||
{
|
||||
MutexAutoLock lock(m_mutex);
|
||||
|
||||
std::map<std::string, SettingsEntry>::iterator it = m_settings.find(name);
|
||||
SettingEntries::iterator it = m_settings.find(name);
|
||||
if (it != m_settings.end()) {
|
||||
delete it->second.group;
|
||||
m_settings.erase(it);
|
||||
|
@ -912,7 +910,6 @@ void Settings::updateValue(const Settings &other, const std::string &name)
|
|||
|
||||
try {
|
||||
std::string val = other.get(name);
|
||||
|
||||
m_settings[name] = val;
|
||||
} catch (SettingNotFoundException &e) {
|
||||
}
|
||||
|
@ -968,8 +965,9 @@ void Settings::updateNoLock(const Settings &other)
|
|||
|
||||
void Settings::clearNoLock()
|
||||
{
|
||||
std::map<std::string, SettingsEntry>::const_iterator it;
|
||||
for (it = m_settings.begin(); it != m_settings.end(); ++it)
|
||||
|
||||
for (SettingEntries::const_iterator it = m_settings.begin();
|
||||
it != m_settings.end(); ++it)
|
||||
delete it->second.group;
|
||||
m_settings.clear();
|
||||
|
||||
|
@ -978,8 +976,8 @@ void Settings::clearNoLock()
|
|||
|
||||
void Settings::clearDefaultsNoLock()
|
||||
{
|
||||
std::map<std::string, SettingsEntry>::const_iterator it;
|
||||
for (it = m_defaults.begin(); it != m_defaults.end(); ++it)
|
||||
for (SettingEntries::const_iterator it = m_defaults.begin();
|
||||
it != m_defaults.end(); ++it)
|
||||
delete it->second.group;
|
||||
m_defaults.clear();
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "util/string.h"
|
||||
#include "threading/mutex.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "util/cpp11_container.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
|
@ -45,7 +45,7 @@ typedef std::vector<
|
|||
>
|
||||
> SettingsCallbackList;
|
||||
|
||||
typedef std::map<std::string, SettingsCallbackList> SettingsCallbackMap;
|
||||
typedef UNORDERED_MAP<std::string, SettingsCallbackList> SettingsCallbackMap;
|
||||
|
||||
enum ValueType {
|
||||
VALUETYPE_STRING,
|
||||
|
@ -98,6 +98,8 @@ struct SettingsEntry {
|
|||
bool is_group;
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<std::string, SettingsEntry> SettingEntries;
|
||||
|
||||
class Settings {
|
||||
public:
|
||||
Settings() {}
|
||||
|
@ -231,8 +233,8 @@ private:
|
|||
|
||||
void doCallbacks(const std::string &name) const;
|
||||
|
||||
std::map<std::string, SettingsEntry> m_settings;
|
||||
std::map<std::string, SettingsEntry> m_defaults;
|
||||
SettingEntries m_settings;
|
||||
SettingEntries m_defaults;
|
||||
|
||||
SettingsCallbackMap m_callbacks;
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ with this program; ifnot, write to the Free Software Foundation, Inc.,
|
|||
#include "log.h"
|
||||
#include "util/numeric.h" // myrand()
|
||||
#include "porting.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include "util/cpp11_container.h"
|
||||
|
||||
#define BUFFER_SIZE 30000
|
||||
|
||||
|
@ -271,8 +271,8 @@ private:
|
|||
ALCdevice *m_device;
|
||||
ALCcontext *m_context;
|
||||
int m_next_id;
|
||||
std::map<std::string, std::vector<SoundBuffer*> > m_buffers;
|
||||
std::map<int, PlayingSound*> m_sounds_playing;
|
||||
UNORDERED_MAP<std::string, std::vector<SoundBuffer*> > m_buffers;
|
||||
UNORDERED_MAP<int, PlayingSound*> m_sounds_playing;
|
||||
v3f m_listener_pos;
|
||||
public:
|
||||
bool m_is_initialized;
|
||||
|
@ -337,7 +337,7 @@ public:
|
|||
alcCloseDevice(m_device);
|
||||
m_device = NULL;
|
||||
|
||||
for (std::map<std::string, std::vector<SoundBuffer*> >::iterator i = m_buffers.begin();
|
||||
for (UNORDERED_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) {
|
||||
|
@ -351,7 +351,7 @@ public:
|
|||
|
||||
void addBuffer(const std::string &name, SoundBuffer *buf)
|
||||
{
|
||||
std::map<std::string, std::vector<SoundBuffer*> >::iterator i =
|
||||
UNORDERED_MAP<std::string, std::vector<SoundBuffer*> >::iterator i =
|
||||
m_buffers.find(name);
|
||||
if(i != m_buffers.end()){
|
||||
i->second.push_back(buf);
|
||||
|
@ -365,7 +365,7 @@ public:
|
|||
|
||||
SoundBuffer* getBuffer(const std::string &name)
|
||||
{
|
||||
std::map<std::string, std::vector<SoundBuffer*> >::iterator i =
|
||||
UNORDERED_MAP<std::string, std::vector<SoundBuffer*> >::iterator i =
|
||||
m_buffers.find(name);
|
||||
if(i == m_buffers.end())
|
||||
return NULL;
|
||||
|
@ -443,8 +443,7 @@ public:
|
|||
|
||||
void deleteSound(int id)
|
||||
{
|
||||
std::map<int, PlayingSound*>::iterator i =
|
||||
m_sounds_playing.find(id);
|
||||
UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.find(id);
|
||||
if(i == m_sounds_playing.end())
|
||||
return;
|
||||
PlayingSound *sound = i->second;
|
||||
|
@ -484,10 +483,8 @@ public:
|
|||
<<m_sounds_playing.size()<<" playing sounds, "
|
||||
<<m_buffers.size()<<" sound names loaded"<<std::endl;
|
||||
std::set<int> del_list;
|
||||
for(std::map<int, PlayingSound*>::iterator
|
||||
i = m_sounds_playing.begin();
|
||||
i != m_sounds_playing.end(); ++i)
|
||||
{
|
||||
for(UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.begin();
|
||||
i != m_sounds_playing.end(); ++i) {
|
||||
int id = i->first;
|
||||
PlayingSound *sound = i->second;
|
||||
// If not playing, remove it
|
||||
|
@ -583,9 +580,8 @@ public:
|
|||
}
|
||||
void updateSoundPosition(int id, v3f pos)
|
||||
{
|
||||
std::map<int, PlayingSound*>::iterator i =
|
||||
m_sounds_playing.find(id);
|
||||
if(i == m_sounds_playing.end())
|
||||
UNORDERED_MAP<int, PlayingSound*>::iterator i = m_sounds_playing.find(id);
|
||||
if (i == m_sounds_playing.end())
|
||||
return;
|
||||
PlayingSound *sound = i->second;
|
||||
|
||||
|
|
23
src/tool.cpp
23
src/tool.cpp
|
@ -34,24 +34,23 @@ void ToolCapabilities::serialize(std::ostream &os, u16 protocol_version) const
|
|||
writeF1000(os, full_punch_interval);
|
||||
writeS16(os, max_drop_level);
|
||||
writeU32(os, groupcaps.size());
|
||||
for(std::map<std::string, ToolGroupCap>::const_iterator
|
||||
i = groupcaps.begin(); i != groupcaps.end(); ++i){
|
||||
for (ToolGCMap::const_iterator i = groupcaps.begin(); i != groupcaps.end(); ++i) {
|
||||
const std::string *name = &i->first;
|
||||
const ToolGroupCap *cap = &i->second;
|
||||
os<<serializeString(*name);
|
||||
writeS16(os, cap->uses);
|
||||
writeS16(os, cap->maxlevel);
|
||||
writeU32(os, cap->times.size());
|
||||
for(std::map<int, float>::const_iterator
|
||||
i = cap->times.begin(); i != cap->times.end(); ++i){
|
||||
for (UNORDERED_MAP<int, float>::const_iterator
|
||||
i = cap->times.begin(); i != cap->times.end(); ++i) {
|
||||
writeS16(os, i->first);
|
||||
writeF1000(os, i->second);
|
||||
}
|
||||
}
|
||||
if(protocol_version > 17){
|
||||
writeU32(os, damageGroups.size());
|
||||
for(std::map<std::string, s16>::const_iterator
|
||||
i = damageGroups.begin(); i != damageGroups.end(); ++i){
|
||||
for (DamageGroup::const_iterator i = damageGroups.begin();
|
||||
i != damageGroups.end(); ++i) {
|
||||
os<<serializeString(i->first);
|
||||
writeS16(os, i->second);
|
||||
}
|
||||
|
@ -106,7 +105,7 @@ DigParams getDigParams(const ItemGroupList &groups,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Values to be returned (with a bit of conversion)
|
||||
bool result_diggable = false;
|
||||
float result_time = 0.0;
|
||||
|
@ -115,8 +114,8 @@ DigParams getDigParams(const ItemGroupList &groups,
|
|||
|
||||
int level = itemgroup_get(groups, "level");
|
||||
//infostream<<"level="<<level<<std::endl;
|
||||
for(std::map<std::string, ToolGroupCap>::const_iterator
|
||||
i = tp->groupcaps.begin(); i != tp->groupcaps.end(); ++i){
|
||||
for (ToolGCMap::const_iterator i = tp->groupcaps.begin();
|
||||
i != tp->groupcaps.end(); ++i) {
|
||||
const std::string &name = i->first;
|
||||
//infostream<<"group="<<name<<std::endl;
|
||||
const ToolGroupCap &cap = i->second;
|
||||
|
@ -163,8 +162,8 @@ HitParams getHitParams(const ItemGroupList &armor_groups,
|
|||
s16 damage = 0;
|
||||
float full_punch_interval = tp->full_punch_interval;
|
||||
|
||||
for(std::map<std::string, s16>::const_iterator
|
||||
i = tp->damageGroups.begin(); i != tp->damageGroups.end(); ++i){
|
||||
for (DamageGroup::const_iterator i = tp->damageGroups.begin();
|
||||
i != tp->damageGroups.end(); ++i) {
|
||||
s16 armor = itemgroup_get(armor_groups, i->first);
|
||||
damage += i->second * rangelim(time_from_last_punch / full_punch_interval, 0.0, 1.0)
|
||||
* armor / 100.0;
|
||||
|
@ -197,7 +196,7 @@ PunchDamageResult getPunchDamage(
|
|||
do_hit = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PunchDamageResult result;
|
||||
if(do_hit)
|
||||
{
|
||||
|
|
15
src/tool.h
15
src/tool.h
|
@ -23,12 +23,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "irrlichttypes.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include "util/cpp11_container.h"
|
||||
#include "itemgroup.h"
|
||||
|
||||
struct ToolGroupCap
|
||||
{
|
||||
std::map<int, float> times;
|
||||
UNORDERED_MAP<int, float> times;
|
||||
int maxlevel;
|
||||
int uses;
|
||||
|
||||
|
@ -39,8 +39,8 @@ struct ToolGroupCap
|
|||
|
||||
bool getTime(int rating, float *time) const
|
||||
{
|
||||
std::map<int, float>::const_iterator i = times.find(rating);
|
||||
if(i == times.end()){
|
||||
UNORDERED_MAP<int, float>::const_iterator i = times.find(rating);
|
||||
if (i == times.end()) {
|
||||
*time = 0;
|
||||
return false;
|
||||
}
|
||||
|
@ -50,22 +50,19 @@ struct ToolGroupCap
|
|||
};
|
||||
|
||||
|
||||
// CLANG SUCKS DONKEY BALLS
|
||||
typedef std::map<std::string, struct ToolGroupCap> ToolGCMap;
|
||||
typedef std::map<std::string, s16> DamageGroup;
|
||||
typedef UNORDERED_MAP<std::string, struct ToolGroupCap> ToolGCMap;
|
||||
typedef UNORDERED_MAP<std::string, s16> DamageGroup;
|
||||
|
||||
struct ToolCapabilities
|
||||
{
|
||||
float full_punch_interval;
|
||||
int max_drop_level;
|
||||
// CLANG SUCKS DONKEY BALLS
|
||||
ToolGCMap groupcaps;
|
||||
DamageGroup damageGroups;
|
||||
|
||||
ToolCapabilities(
|
||||
float full_punch_interval_=1.4,
|
||||
int max_drop_level_=1,
|
||||
// CLANG SUCKS DONKEY BALLS
|
||||
ToolGCMap groupcaps_=ToolGCMap(),
|
||||
DamageGroup damageGroups_=DamageGroup()
|
||||
):
|
||||
|
|
|
@ -23,3 +23,7 @@ set (UNITTEST_SRCS
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/test_voxelalgorithms.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_voxelmanipulator.cpp
|
||||
PARENT_SCOPE)
|
||||
|
||||
set (UNITTEST_CLIENT_SRCS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/test_keycode.cpp
|
||||
PARENT_SCOPE)
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
Minetest
|
||||
Copyright (C) 2016 sfan5 <sfan5@live.de>
|
||||
|
||||
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 "test.h"
|
||||
|
||||
#include <string>
|
||||
#include "exceptions.h"
|
||||
#include "keycode.h"
|
||||
|
||||
class TestKeycode : public TestBase {
|
||||
public:
|
||||
TestKeycode() { TestManager::registerTestModule(this); }
|
||||
const char *getName() { return "TestKeycode"; }
|
||||
|
||||
void runTests(IGameDef *gamedef);
|
||||
|
||||
void testCreateFromString();
|
||||
void testCreateFromSKeyInput();
|
||||
void testCompare();
|
||||
};
|
||||
|
||||
static TestKeycode g_test_instance;
|
||||
|
||||
void TestKeycode::runTests(IGameDef *gamedef)
|
||||
{
|
||||
TEST(testCreateFromString);
|
||||
TEST(testCreateFromSKeyInput);
|
||||
TEST(testCompare);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define UASSERTEQ_STR(one, two) UASSERT(strcmp(one, two) == 0)
|
||||
|
||||
void TestKeycode::testCreateFromString()
|
||||
{
|
||||
KeyPress k;
|
||||
|
||||
// Character key, from char
|
||||
k = KeyPress("R");
|
||||
UASSERTEQ_STR(k.sym(), "KEY_KEY_R");
|
||||
UASSERTCMP(int, >, strlen(k.name()), 0); // should have human description
|
||||
|
||||
// Character key, from identifier
|
||||
k = KeyPress("KEY_KEY_B");
|
||||
UASSERTEQ_STR(k.sym(), "KEY_KEY_B");
|
||||
UASSERTCMP(int, >, strlen(k.name()), 0);
|
||||
|
||||
// Non-Character key, from identifier
|
||||
k = KeyPress("KEY_UP");
|
||||
UASSERTEQ_STR(k.sym(), "KEY_UP");
|
||||
UASSERTCMP(int, >, strlen(k.name()), 0);
|
||||
|
||||
k = KeyPress("KEY_F6");
|
||||
UASSERTEQ_STR(k.sym(), "KEY_F6");
|
||||
UASSERTCMP(int, >, strlen(k.name()), 0);
|
||||
|
||||
// Irrlicht-unknown key, from char
|
||||
k = KeyPress("/");
|
||||
UASSERTEQ_STR(k.sym(), "/");
|
||||
UASSERTCMP(int, >, strlen(k.name()), 0);
|
||||
}
|
||||
|
||||
void TestKeycode::testCreateFromSKeyInput()
|
||||
{
|
||||
KeyPress k;
|
||||
irr::SEvent::SKeyInput in;
|
||||
|
||||
// Character key
|
||||
in.Key = irr::KEY_KEY_3;
|
||||
in.Char = L'3';
|
||||
k = KeyPress(in);
|
||||
UASSERTEQ_STR(k.sym(), "KEY_KEY_3");
|
||||
|
||||
// Non-Character key
|
||||
in.Key = irr::KEY_RSHIFT;
|
||||
in.Char = L'\0';
|
||||
k = KeyPress(in);
|
||||
UASSERTEQ_STR(k.sym(), "KEY_RSHIFT");
|
||||
|
||||
// Irrlicht-unknown key
|
||||
in.Key = irr::KEY_KEY_CODES_COUNT;
|
||||
in.Char = L'?';
|
||||
k = KeyPress(in);
|
||||
UASSERTEQ_STR(k.sym(), "?");
|
||||
|
||||
// prefer_character mode
|
||||
in.Key = irr::KEY_COMMA;
|
||||
in.Char = L'G';
|
||||
k = KeyPress(in, true);
|
||||
UASSERTEQ_STR(k.sym(), "KEY_KEY_G");
|
||||
}
|
||||
|
||||
void TestKeycode::testCompare()
|
||||
{
|
||||
// Basic comparison
|
||||
UASSERT(KeyPress("5") == KeyPress("KEY_KEY_5"));
|
||||
UASSERT(!(KeyPress("5") == KeyPress("KEY_NUMPAD_5")));
|
||||
|
||||
// Matching char suffices
|
||||
// note: This is a real-world example, Irrlicht maps XK_equal to irr::KEY_PLUS on Linux
|
||||
irr::SEvent::SKeyInput in;
|
||||
in.Key = irr::KEY_PLUS;
|
||||
in.Char = L'=';
|
||||
UASSERT(KeyPress("=") == KeyPress(in));
|
||||
|
||||
// Matching keycode suffices
|
||||
irr::SEvent::SKeyInput in2;
|
||||
in.Key = in2.Key = irr::KEY_OEM_CLEAR;
|
||||
in.Char = L'\0';
|
||||
in2.Char = L';';
|
||||
UASSERT(KeyPress(in) == KeyPress(in2));
|
||||
}
|
|
@ -32,7 +32,7 @@ public:
|
|||
void testAllSettings();
|
||||
|
||||
static const char *config_text_before;
|
||||
static const char *config_text_after;
|
||||
static const std::string config_text_after;
|
||||
};
|
||||
|
||||
static TestSettings g_test_instance;
|
||||
|
@ -69,7 +69,7 @@ const char *TestSettings::config_text_before =
|
|||
"np_terrain = 5, 40, (250, 250, 250), 12341, 5, 0.7, 2.4\n"
|
||||
"zoop = true";
|
||||
|
||||
const char *TestSettings::config_text_after =
|
||||
const std::string TestSettings::config_text_after =
|
||||
"leet = 1337\n"
|
||||
"leetleet = 13371337\n"
|
||||
"leetleet_neg = -13371337\n"
|
||||
|
@ -197,7 +197,10 @@ void TestSettings::testAllSettings()
|
|||
UASSERT(s.updateConfigObject(is, os, "", 0) == true);
|
||||
//printf(">>>> expected config:\n%s\n", TEST_CONFIG_TEXT_AFTER);
|
||||
//printf(">>>> actual config:\n%s\n", os.str().c_str());
|
||||
#if __cplusplus < 201103L
|
||||
// This test only works in older C++ versions than C++11 because we use unordered_map
|
||||
UASSERT(os.str() == config_text_after);
|
||||
#endif
|
||||
} catch (SettingNotFoundException &e) {
|
||||
UASSERT(!"Setting not found!");
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ private:
|
|||
void TestThreading::testAtomicSemaphoreThread()
|
||||
{
|
||||
Atomic<u32> val;
|
||||
val = 0;
|
||||
Semaphore trigger;
|
||||
static const u8 num_threads = 4;
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 202 B |
|
@ -13,15 +13,15 @@ packagedir=$builddir/packages
|
|||
libdir=$builddir/libs
|
||||
|
||||
toolchain_file=$dir/toolchain_mingw.cmake
|
||||
irrlicht_version=1.8.1
|
||||
ogg_version=1.2.1
|
||||
vorbis_version=1.3.3
|
||||
curl_version=7.38.0
|
||||
irrlicht_version=1.8.4
|
||||
ogg_version=1.3.2
|
||||
vorbis_version=1.3.5
|
||||
curl_version=7.50.3
|
||||
gettext_version=0.14.4
|
||||
freetype_version=2.3.5
|
||||
sqlite3_version=3.8.7.4
|
||||
freetype_version=2.7
|
||||
sqlite3_version=3.14.2
|
||||
luajit_version=2.0.1
|
||||
leveldb_version=1.15
|
||||
leveldb_version=1.18
|
||||
zlib_version=1.2.8
|
||||
|
||||
mkdir -p $packagedir
|
||||
|
@ -34,44 +34,38 @@ cd $builddir
|
|||
-c -O $packagedir/irrlicht-$irrlicht_version.zip
|
||||
[ -e $packagedir/zlib-$zlib_version.zip ] || wget http://minetest.kitsunemimi.pw/zlib-$zlib_version-win32.zip \
|
||||
-c -O $packagedir/zlib-$zlib_version.zip
|
||||
[ -e $packagedir/libogg-$ogg_version-dev.7z ] || wget http://minetest.kitsunemimi.pw/libogg-$ogg_version-dev.7z \
|
||||
-c -O $packagedir/libogg-$ogg_version-dev.7z
|
||||
[ -e $packagedir/libogg-$ogg_version-dll.7z ] || wget http://minetest.kitsunemimi.pw/libogg-$ogg_version-dll.7z \
|
||||
-c -O $packagedir/libogg-$ogg_version-dll.7z
|
||||
[ -e $packagedir/libvorbis-$vorbis_version-dev.7z ] || wget http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-dev.7z \
|
||||
-c -O $packagedir/libvorbis-$vorbis_version-dev.7z
|
||||
[ -e $packagedir/libvorbis-$vorbis_version-dll.7z ] || wget http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-dll.7z \
|
||||
-c -O $packagedir/libvorbis-$vorbis_version-dll.7z
|
||||
[ -e $packagedir/libcurl-$curl_version.zip ] || wget http://minetest.kitsunemimi.pw/libcurl-$curl_version-win32.zip \
|
||||
-c -O $packagedir/libcurl-$curl_version.zip
|
||||
[ -e $packagedir/libogg-$ogg_version.zip ] || wget http://minetest.kitsunemimi.pw/libogg-$ogg_version-win32.zip \
|
||||
-c -O $packagedir/libogg-$ogg_version.zip
|
||||
[ -e $packagedir/libvorbis-$vorbis_version.zip ] || wget http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-win32.zip \
|
||||
-c -O $packagedir/libvorbis-$vorbis_version.zip
|
||||
[ -e $packagedir/curl-$curl_version.zip ] || wget http://minetest.kitsunemimi.pw/curl-$curl_version-win32.zip \
|
||||
-c -O $packagedir/curl-$curl_version.zip
|
||||
[ -e $packagedir/gettext-$gettext_version.zip ] || wget http://minetest.kitsunemimi.pw/gettext-$gettext_version.zip \
|
||||
-c -O $packagedir/gettext-$gettext_version.zip
|
||||
[ -e $packagedir/libfreetype-$freetype_version.zip ] || wget http://minetest.kitsunemimi.pw/libfreetype-$freetype_version-win32.zip \
|
||||
-c -O $packagedir/libfreetype-$freetype_version.zip
|
||||
[ -e $packagedir/freetype2-$freetype_version.zip ] || wget http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win32.zip \
|
||||
-c -O $packagedir/freetype2-$freetype_version.zip
|
||||
[ -e $packagedir/sqlite3-$sqlite3_version.zip ] || wget http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win32.zip \
|
||||
-c -O $packagedir/sqlite3-$sqlite3_version.zip
|
||||
[ -e $packagedir/luajit-$luajit_version-static-win32.zip ] || wget http://minetest.kitsunemimi.pw/luajit-$luajit_version-static-win32.zip \
|
||||
-c -O $packagedir/luajit-$luajit_version-static-win32.zip
|
||||
[ -e $packagedir/libleveldb-$leveldb_version-win32.zip ] || wget http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win32.zip \
|
||||
-c -O $packagedir/libleveldb-$leveldb_version-win32.zip
|
||||
[ -e $packagedir/libleveldb-$leveldb_version.zip ] || wget http://minetest.kitsunemimi.pw/libleveldb-$leveldb_version-win32.zip \
|
||||
-c -O $packagedir/libleveldb-$leveldb_version.zip
|
||||
[ -e $packagedir/openal_stripped.zip ] || wget http://minetest.kitsunemimi.pw/openal_stripped.zip \
|
||||
-c -O $packagedir/openal_stripped.zip
|
||||
|
||||
# Extract stuff
|
||||
cd $libdir
|
||||
[ -d irrlicht-$irrlicht_version ] || unzip -o $packagedir/irrlicht-$irrlicht_version.zip
|
||||
[ -d irrlicht ] || unzip -o $packagedir/irrlicht-$irrlicht_version.zip -d irrlicht
|
||||
[ -d zlib ] || unzip -o $packagedir/zlib-$zlib_version.zip -d zlib
|
||||
[ -d libogg/include ] || 7z x -y -olibogg $packagedir/libogg-$ogg_version-dev.7z
|
||||
[ -d libogg/bin ] || 7z x -y -olibogg $packagedir/libogg-$ogg_version-dll.7z
|
||||
[ -d libvorbis/include ] || 7z x -y -olibvorbis $packagedir/libvorbis-$vorbis_version-dev.7z
|
||||
[ -d libvorbis/bin ] || 7z x -y -olibvorbis $packagedir/libvorbis-$vorbis_version-dll.7z
|
||||
[ -d libcurl ] || unzip -o $packagedir/libcurl-$curl_version.zip -d libcurl
|
||||
[ -d libogg ] || unzip -o $packagedir/libogg-$ogg_version.zip -d libogg
|
||||
[ -d libvorbis ] || unzip -o $packagedir/libvorbis-$vorbis_version.zip -d libvorbis
|
||||
[ -d libcurl ] || unzip -o $packagedir/curl-$curl_version.zip -d libcurl
|
||||
[ -d gettext ] || unzip -o $packagedir/gettext-$gettext_version.zip -d gettext
|
||||
[ -d freetype ] || unzip -o $packagedir/libfreetype-$freetype_version.zip -d freetype
|
||||
[ -d freetype ] || unzip -o $packagedir/freetype2-$freetype_version.zip -d freetype
|
||||
[ -d sqlite3 ] || unzip -o $packagedir/sqlite3-$sqlite3_version.zip -d sqlite3
|
||||
[ -d openal_stripped ] || unzip -o $packagedir/openal_stripped.zip
|
||||
[ -d luajit ] || unzip -o $packagedir/luajit-$luajit_version-static-win32.zip -d luajit
|
||||
[ -d leveldb ] || unzip -o $packagedir/libleveldb-$leveldb_version-win32.zip -d leveldb
|
||||
[ -d leveldb ] || unzip -o $packagedir/libleveldb-$leveldb_version.zip -d leveldb
|
||||
|
||||
# Get minetest
|
||||
cd $builddir
|
||||
|
@ -107,14 +101,13 @@ cmake .. \
|
|||
-DENABLE_FREETYPE=1 \
|
||||
-DENABLE_LEVELDB=1 \
|
||||
\
|
||||
-DIRRLICHT_INCLUDE_DIR=$libdir/irrlicht-$irrlicht_version/include \
|
||||
-DIRRLICHT_LIBRARY=$libdir/irrlicht-$irrlicht_version/lib/Win32-gcc/libIrrlicht.dll.a \
|
||||
-DIRRLICHT_DLL=$libdir/irrlicht-$irrlicht_version/bin/Win32-gcc/Irrlicht.dll \
|
||||
-DIRRLICHT_INCLUDE_DIR=$libdir/irrlicht/include \
|
||||
-DIRRLICHT_LIBRARY=$libdir/irrlicht/lib/Win32-gcc/libIrrlicht.dll.a \
|
||||
-DIRRLICHT_DLL=$libdir/irrlicht/bin/Win32-gcc/Irrlicht.dll \
|
||||
\
|
||||
-DZLIB_INCLUDE_DIR=$libdir/zlib/include \
|
||||
-DZLIB_LIBRARIES=$libdir/zlib/lib/zlibwapi.dll.a \
|
||||
-DZLIB_LIBRARIES=$libdir/zlib/lib/libz.dll.a \
|
||||
-DZLIB_DLL=$libdir/zlib/bin/zlib1.dll \
|
||||
-DZLIBWAPI_DLL=$libdir/zlib/bin/zlibwapi.dll \
|
||||
\
|
||||
-DLUA_INCLUDE_DIR=$libdir/luajit/include \
|
||||
-DLUA_LIBRARY=$libdir/luajit/libluajit.a \
|
||||
|
@ -145,9 +138,9 @@ cmake .. \
|
|||
-DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \
|
||||
\
|
||||
-DFREETYPE_INCLUDE_DIR_freetype2=$libdir/freetype/include/freetype2 \
|
||||
-DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include \
|
||||
-DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include/freetype2 \
|
||||
-DFREETYPE_LIBRARY=$libdir/freetype/lib/libfreetype.dll.a \
|
||||
-DFREETYPE_DLL=$libdir/freetype/bin/freetype6.dll \
|
||||
-DFREETYPE_DLL=$libdir/freetype/bin/libfreetype-6.dll \
|
||||
\
|
||||
-DSQLITE3_INCLUDE_DIR=$libdir/sqlite3/include \
|
||||
-DSQLITE3_LIBRARY=$libdir/sqlite3/lib/libsqlite3.dll.a \
|
||||
|
|
|
@ -13,15 +13,15 @@ packagedir=$builddir/packages
|
|||
libdir=$builddir/libs
|
||||
|
||||
toolchain_file=$dir/toolchain_mingw64.cmake
|
||||
irrlicht_version=1.8.1
|
||||
ogg_version=1.3.1
|
||||
vorbis_version=1.3.4
|
||||
curl_version=7.38.0
|
||||
irrlicht_version=1.8.4
|
||||
ogg_version=1.3.2
|
||||
vorbis_version=1.3.5
|
||||
curl_version=7.50.3
|
||||
gettext_version=0.18.2
|
||||
freetype_version=2.5.3
|
||||
sqlite3_version=3.8.7.4
|
||||
freetype_version=2.7
|
||||
sqlite3_version=3.14.2
|
||||
luajit_version=2.0.3
|
||||
leveldb_version=1.15
|
||||
leveldb_version=1.18
|
||||
zlib_version=1.2.8
|
||||
|
||||
mkdir -p $packagedir
|
||||
|
@ -38,12 +38,12 @@ cd $builddir
|
|||
-c -O $packagedir/libogg-$ogg_version.zip
|
||||
[ -e $packagedir/libvorbis-$vorbis_version.zip ] || wget http://minetest.kitsunemimi.pw/libvorbis-$vorbis_version-win64.zip \
|
||||
-c -O $packagedir/libvorbis-$vorbis_version.zip
|
||||
[ -e $packagedir/libcurl-$curl_version.zip ] || wget http://minetest.kitsunemimi.pw/libcurl-$curl_version-win64.zip \
|
||||
-c -O $packagedir/libcurl-$curl_version.zip
|
||||
[ -e $packagedir/curl-$curl_version.zip ] || wget http://minetest.kitsunemimi.pw/curl-$curl_version-win64.zip \
|
||||
-c -O $packagedir/curl-$curl_version.zip
|
||||
[ -e $packagedir/gettext-$gettext_version.zip ] || wget http://minetest.kitsunemimi.pw/gettext-$gettext_version-win64.zip \
|
||||
-c -O $packagedir/gettext-$gettext_version.zip
|
||||
[ -e $packagedir/freetype-$freetype_version.zip ] || wget http://minetest.kitsunemimi.pw/libfreetype-$freetype_version-win64.zip \
|
||||
-c -O $packagedir/freetype-$freetype_version.zip
|
||||
[ -e $packagedir/freetype2-$freetype_version.zip ] || wget http://minetest.kitsunemimi.pw/freetype2-$freetype_version-win64.zip \
|
||||
-c -O $packagedir/freetype2-$freetype_version.zip
|
||||
[ -e $packagedir/sqlite3-$sqlite3_version.zip ] || wget http://minetest.kitsunemimi.pw/sqlite3-$sqlite3_version-win64.zip \
|
||||
-c -O $packagedir/sqlite3-$sqlite3_version.zip
|
||||
[ -e $packagedir/luajit-$luajit_version.zip ] || wget http://minetest.kitsunemimi.pw/luajit-$luajit_version-static-win64.zip \
|
||||
|
@ -56,13 +56,13 @@ cd $builddir
|
|||
|
||||
# Extract stuff
|
||||
cd $libdir
|
||||
[ -d irrlicht-$irrlicht_version ] || unzip -o $packagedir/irrlicht-$irrlicht_version.zip
|
||||
[ -d irrlicht ] || unzip -o $packagedir/irrlicht-$irrlicht_version.zip -d irrlicht
|
||||
[ -d zlib ] || unzip -o $packagedir/zlib-$zlib_version.zip -d zlib
|
||||
[ -d libogg ] || unzip -o $packagedir/libogg-$ogg_version.zip -d libogg
|
||||
[ -d libvorbis ] || unzip -o $packagedir/libvorbis-$vorbis_version.zip -d libvorbis
|
||||
[ -d libcurl ] || unzip -o $packagedir/libcurl-$curl_version.zip -d libcurl
|
||||
[ -d libcurl ] || unzip -o $packagedir/curl-$curl_version.zip -d libcurl
|
||||
[ -d gettext ] || unzip -o $packagedir/gettext-$gettext_version.zip -d gettext
|
||||
[ -d freetype ] || unzip -o $packagedir/freetype-$freetype_version.zip -d freetype
|
||||
[ -d freetype ] || unzip -o $packagedir/freetype2-$freetype_version.zip -d freetype
|
||||
[ -d sqlite3 ] || unzip -o $packagedir/sqlite3-$sqlite3_version.zip -d sqlite3
|
||||
[ -d openal_stripped ] || unzip -o $packagedir/openal_stripped.zip
|
||||
[ -d luajit ] || unzip -o $packagedir/luajit-$luajit_version.zip -d luajit
|
||||
|
@ -102,9 +102,9 @@ cmake .. \
|
|||
-DENABLE_FREETYPE=1 \
|
||||
-DENABLE_LEVELDB=1 \
|
||||
\
|
||||
-DIRRLICHT_INCLUDE_DIR=$libdir/irrlicht-$irrlicht_version/include \
|
||||
-DIRRLICHT_LIBRARY=$libdir/irrlicht-$irrlicht_version/lib/Win64-gcc/libIrrlicht.dll.a \
|
||||
-DIRRLICHT_DLL=$libdir/irrlicht-$irrlicht_version/bin/Win64-gcc/Irrlicht.dll \
|
||||
-DIRRLICHT_INCLUDE_DIR=$libdir/irrlicht/include \
|
||||
-DIRRLICHT_LIBRARY=$libdir/irrlicht/lib/Win64-gcc/libIrrlicht.dll.a \
|
||||
-DIRRLICHT_DLL=$libdir/irrlicht/bin/Win64-gcc/Irrlicht.dll \
|
||||
\
|
||||
-DZLIB_INCLUDE_DIR=$libdir/zlib/include \
|
||||
-DZLIB_LIBRARIES=$libdir/zlib/lib/libz.dll.a \
|
||||
|
@ -131,6 +131,13 @@ cmake .. \
|
|||
-DCURL_INCLUDE_DIR=$libdir/libcurl/include \
|
||||
-DCURL_LIBRARY=$libdir/libcurl/lib/libcurl.dll.a \
|
||||
\
|
||||
-DCUSTOM_GETTEXT_PATH=$libdir/gettext \
|
||||
-DGETTEXT_MSGFMT=`which msgfmt` \
|
||||
-DGETTEXT_DLL=$libdir/gettext/bin/libintl-8.dll \
|
||||
-DGETTEXT_ICONV_DLL=$libdir/gettext/bin/libiconv-2.dll \
|
||||
-DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \
|
||||
-DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a \
|
||||
\
|
||||
-DFREETYPE_INCLUDE_DIR_freetype2=$libdir/freetype/include/freetype2 \
|
||||
-DFREETYPE_INCLUDE_DIR_ft2build=$libdir/freetype/include/freetype2 \
|
||||
-DFREETYPE_LIBRARY=$libdir/freetype/lib/libfreetype.dll.a \
|
||||
|
@ -142,14 +149,7 @@ cmake .. \
|
|||
\
|
||||
-DLEVELDB_INCLUDE_DIR=$libdir/leveldb/include \
|
||||
-DLEVELDB_LIBRARY=$libdir/leveldb/lib/libleveldb.dll.a \
|
||||
-DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll \
|
||||
\
|
||||
-DCUSTOM_GETTEXT_PATH=$libdir/gettext \
|
||||
-DGETTEXT_MSGFMT=`which msgfmt` \
|
||||
-DGETTEXT_DLL=$libdir/gettext/bin/libintl-8.dll \
|
||||
-DGETTEXT_ICONV_DLL=$libdir/gettext/bin/libiconv-2.dll \
|
||||
-DGETTEXT_INCLUDE_DIR=$libdir/gettext/include \
|
||||
-DGETTEXT_LIBRARY=$libdir/gettext/lib/libintl.dll.a
|
||||
-DLEVELDB_DLL=$libdir/leveldb/bin/libleveldb.dll
|
||||
|
||||
make package -j2
|
||||
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
if [[ $TRAVIS_OS_NAME == "linux" ]]; then
|
||||
if [[ $CC == "clang" ]]; then
|
||||
export PATH="/usr/bin/:$PATH"
|
||||
sudo sh -c 'echo "deb http://ppa.launchpad.net/eudoxos/llvm-3.1/ubuntu precise main" >> /etc/apt/sources.list'
|
||||
sudo apt-key adv --keyserver pool.sks-keyservers.net --recv-keys 92DE8183
|
||||
sudo apt-get update
|
||||
sudo apt-get install llvm-3.1
|
||||
sudo apt-get install clang
|
||||
fi
|
||||
sudo apt-get update
|
||||
sudo apt-get install p7zip-full
|
||||
sudo apt-get install p7zip-full $COMPILER
|
||||
fi
|
||||
|
||||
if [[ $PLATFORM == "Unix" ]]; then
|
||||
|
@ -25,7 +17,7 @@ if [[ $PLATFORM == "Unix" ]]; then
|
|||
else
|
||||
brew update
|
||||
brew install freetype gettext hiredis irrlicht jpeg leveldb libogg libvorbis luajit
|
||||
brew upgrade postgresql
|
||||
#brew upgrade postgresql
|
||||
fi
|
||||
elif [[ $PLATFORM == "Win32" ]]; then
|
||||
wget http://minetest.kitsunemimi.pw/mingw_w64_i686_ubuntu12.04_4.9.1.7z -O mingw.7z
|
||||
|
|
|
@ -4,6 +4,10 @@ if [[ $PLATFORM == "Unix" ]]; then
|
|||
mkdir -p travisbuild
|
||||
cd travisbuild || exit 1
|
||||
CMAKE_FLAGS=''
|
||||
if [[ $COMPILER == "g++-6" ]]; then
|
||||
export CC=gcc-6
|
||||
export CXX=g++-6
|
||||
fi
|
||||
# Clang builds with FreeType fail on Travis
|
||||
if [[ $CC == "clang" ]]; then
|
||||
CMAKE_FLAGS+=' -DENABLE_FREETYPE=FALSE'
|
||||
|
|
Loading…
Reference in New Issue