Compare commits
111 Commits
f3ad75691a
...
b41251ac77
Author | SHA1 | Date |
---|---|---|
Brandon | b41251ac77 | |
Brandon | a2d83f3128 | |
stujones11 | c358004368 | |
Vincent Glize | c772e0e18c | |
stujones11 | 6e5588c8e1 | |
Brandon | 7c12549654 | |
Brandon | c99e2c8b1f | |
Brandon | 811c22d1d6 | |
Brandon | 3ee16f7ffa | |
Brandon | 75a15c932b | |
Brandon | 90df6de663 | |
Brandon | 8ce248b281 | |
Brandon | 9be4f5bcaa | |
Brandon | a8dc572ecd | |
Brandon | 68d51292ff | |
Brandon | 694766f4a7 | |
Brandon | 6ab6102116 | |
Brandon | a474d34fca | |
Brandon | 655a4c397b | |
Brandon | 4cb44572a5 | |
Brandon | 1833719166 | |
Brandon | 1e495af340 | |
Brandon | af279af6a7 | |
Brandon | f9d491769d | |
Brandon | bdd8f8f6e7 | |
Brandon | a8c3a394dd | |
Brandon | 718e4e6b91 | |
Brandon | f440ae1b2c | |
Brandon | 17ba127f25 | |
Brandon | a72a6c38f4 | |
Brandon | bb31e234ad | |
Brandon | 602d10a59c | |
Brandon | 4024161444 | |
raymoo | 2e6930223d | |
raymoo | 4dc4e1ebf9 | |
raymoo | 632398ca02 | |
Brandon | 9a31f90599 | |
Brandon | 88e7524250 | |
Brandon | 12c067592d | |
Brandon | ca675cfc55 | |
Brandon | 210e2326db | |
Brandon | 9e944a9386 | |
Brandon | c7d9314165 | |
Brandon | 5fe185141b | |
Brandon | b3d4b736ca | |
Brandon | 230a9d89c6 | |
Brandon | 5d740fcfa9 | |
Brandon | a418440adb | |
Brandon | 55925444eb | |
Brandon | aa91ec9a8a | |
Brandon | 51e65a38d4 | |
Brandon | bc936f1c93 | |
Brandon | 3c64860b41 | |
Brandon | f3ad82566e | |
Brandon | 40f170fc71 | |
Brandon | 2838a355ef | |
Brandon | ff154d490a | |
Brandon | 3661dff2b0 | |
Brandon | 2b8a3729c0 | |
Brandon | 7a2625b180 | |
Brandon | 563a9f54c9 | |
Brandon | 675756b648 | |
Brandon | 01410109f5 | |
Brandon | 50929077a0 | |
Brandon | 582d3e47cb | |
Brandon | d6539f9490 | |
Brandon | f6f365cc6e | |
Brandon | eb67a7c0dd | |
RealBadAngel | 3c4c7f777e | |
Brandon | ddafe44327 | |
Brandon | ac8420894b | |
Auke Kok | 51e002be83 | |
Brandon | 7fa524daa8 | |
Brandon | 650ad7aa5f | |
Brandon | 1656d50c9a | |
Brandon | 9ccb4a3084 | |
Brandon | 2bd9b66b4b | |
Brandon | 4b7dc459e1 | |
Brandon | c5526047de | |
Brandon | 2fb801ff9e | |
gregorycu | 2763e58881 | |
Brandon | 4c69477ee5 | |
Brandon | bb92e3b71f | |
Brandon | 2a18106c9d | |
Brandon | d97b4d420d | |
Brandon | 8ec1f8fec3 | |
Brandon | 2b90bf6435 | |
Brandon | e1db571d2f | |
Brandon | 70b7c2d01d | |
Brandon | 26426105a1 | |
Brandon | 1ecefadfca | |
Brandon | 8be989ed07 | |
Brandon | 1a56fa6aba | |
Brandon | 4e232c2378 | |
Brandon | f8126c2ab7 | |
Brandon | dd0b978d64 | |
Brandon | 21d2a36257 | |
Brandon | c351062c30 | |
Brandon | 859c5a9615 | |
Brandon | 861b011f51 | |
Brandon | 027f4d83cb | |
Brandon | 6d94cd3edf | |
Damien Moore | 187303d6d0 | |
Damien Moore | 3a72b6c07a | |
Damien Moore | 8b4c0451e5 | |
Damien Moore | 799a50eca8 | |
Damien Moore | 7fbaaf9801 | |
Damien Moore | 6b5240c24a | |
Damien Moore | 71f54d0380 | |
Jeija | 3e9499fca3 | |
Jeija | 69b75d5fbb |
|
@ -7,7 +7,7 @@ endif()
|
|||
|
||||
# This can be read from ${PROJECT_NAME} after project() is called
|
||||
project(minetest)
|
||||
set(PROJECT_NAME_CAPITALIZED "Minetest")
|
||||
set(PROJECT_NAME_CAPITALIZED "Voxel Adventures Client")
|
||||
|
||||
# Works only for cmake 3.1 and greater
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
@ -19,7 +19,7 @@ set(VERSION_PATCH 16)
|
|||
set(VERSION_EXTRA "" CACHE STRING "Stuff to append to version string")
|
||||
|
||||
# Change to false for releases
|
||||
set(DEVELOPMENT_BUILD TRUE)
|
||||
set(DEVELOPMENT_BUILD FALSE)
|
||||
|
||||
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
|
||||
if(VERSION_EXTRA)
|
||||
|
@ -73,11 +73,11 @@ if(WIN32)
|
|||
set(EXAMPLE_CONF_DIR ".")
|
||||
set(LOCALEDIR "locale")
|
||||
elseif(APPLE)
|
||||
set(BUNDLE_NAME ${PROJECT_NAME}.app)
|
||||
set(BUNDLE_NAME {$PROJECT_NAME}.app)
|
||||
set(BUNDLE_PATH "${BUNDLE_NAME}")
|
||||
set(BINDIR ${BUNDLE_NAME}/Contents/MacOS)
|
||||
set(SHAREDIR ${BUNDLE_NAME}/Contents/Resources)
|
||||
set(DOCDIR "${SHAREDIR}/${PROJECT_NAME}")
|
||||
set(DOCDIR "${SHAREDIR}/{$PROJECT_NAME}")
|
||||
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||
set(LOCALEDIR "${SHAREDIR}/locale")
|
||||
elseif(UNIX) # Linux, BSD etc
|
||||
|
@ -92,15 +92,15 @@ elseif(UNIX) # Linux, BSD etc
|
|||
set(ICONDIR "unix/icons")
|
||||
set(LOCALEDIR "locale")
|
||||
else()
|
||||
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}")
|
||||
set(SHAREDIR "${CMAKE_INSTALL_PREFIX}/share/{$PROJECT_NAME}")
|
||||
set(BINDIR "${CMAKE_INSTALL_PREFIX}/bin")
|
||||
set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}")
|
||||
set(DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/{$PROJECT_NAME}")
|
||||
set(MANDIR "${CMAKE_INSTALL_PREFIX}/share/man")
|
||||
set(EXAMPLE_CONF_DIR ${DOCDIR})
|
||||
set(XDG_APPS_DIR "${CMAKE_INSTALL_PREFIX}/share/applications")
|
||||
set(APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/metainfo")
|
||||
set(ICONDIR "${CMAKE_INSTALL_PREFIX}/share/icons")
|
||||
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/locale")
|
||||
set(LOCALEDIR "${CMAKE_INSTALL_PREFIX}/share/{$PROJECT_NAME}/locale")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -214,23 +214,23 @@ set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An InfiniMiner/Minecraft inspired game")
|
|||
set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||
set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||
set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
||||
set(CPACK_PACKAGE_VENDOR "celeron55")
|
||||
set(CPACK_PACKAGE_CONTACT "Perttu Ahola <celeron55@gmail.com>")
|
||||
set(CPACK_PACKAGE_VENDOR "bremaweb")
|
||||
set(CPACK_PACKAGE_CONTACT "Brandon <brandon@bremaweb.com>")
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win64")
|
||||
set(CPACK_PACKAGE_FILE_NAME "{$PROJECT_NAME}-${VERSION_STRING}-win64")
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-win32")
|
||||
set(CPACK_PACKAGE_FILE_NAME "{$PROJECT_NAME}-${VERSION_STRING}-win32")
|
||||
endif()
|
||||
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
elseif(APPLE)
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 0)
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-osx")
|
||||
set(CPACK_PACKAGE_FILE_NAME "{$PROJECT_NAME}-${VERSION_STRING}-osx")
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
else()
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}-${VERSION_STRING}-linux")
|
||||
set(CPACK_PACKAGE_FILE_NAME "{$PROJECT_NAME}-${VERSION_STRING}-linux")
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
set(CPACK_SOURCE_GENERATOR TGZ)
|
||||
endif()
|
||||
|
|
28
README.txt
|
@ -1,5 +1,7 @@
|
|||
Minetest
|
||||
========
|
||||
Voxel Adventures Client
|
||||
=======================
|
||||
|
||||
Based on Minetest
|
||||
|
||||
An InfiniMiner/Minecraft inspired game.
|
||||
|
||||
|
@ -127,30 +129,20 @@ For Fedora users:
|
|||
$ sudo dnf install git
|
||||
|
||||
Download source (this is the URL to the latest of source repository, which might not work at all times) using git:
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest.git
|
||||
$ cd minetest
|
||||
|
||||
Download minetest_game (otherwise only the "Minimal development test" game is available) using git:
|
||||
$ git clone --depth 1 https://github.com/minetest/minetest_game.git games/minetest_game
|
||||
$ git clone --depth 1 https://github.com/bremaweb/voxeladventures-client.git
|
||||
$ cd voxeladventures-client
|
||||
|
||||
Download source, without using git:
|
||||
$ wget https://github.com/minetest/minetest/archive/master.tar.gz
|
||||
$ wget https://github.com/bremaweb/voxeladventures-client/archive/master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ cd minetest-master
|
||||
|
||||
Download minetest_game, without using git:
|
||||
$ cd games/
|
||||
$ wget https://github.com/minetest/minetest_game/archive/master.tar.gz
|
||||
$ tar xf master.tar.gz
|
||||
$ mv minetest_game-master minetest_game
|
||||
$ cd ..
|
||||
|
||||
Build a version that runs directly from the source directory:
|
||||
$ cmake . -DRUN_IN_PLACE=TRUE
|
||||
Build a version that runs directly from the source directory (if you want to build the server change -DBUILD_SERVER=FALSE to -DBUILD_SERVER=TRUE):
|
||||
$ cmake . -DRUN_IN_PLACE=TRUE -DBUILD_CLIENT=TRUE -DBUILD_SERVER=FALSE
|
||||
$ make -j <number of processors>
|
||||
|
||||
Run it:
|
||||
$ ./bin/minetest
|
||||
$ ./bin/voxeladventures-client
|
||||
|
||||
- Use cmake . -LH to see all CMake options and their current state
|
||||
- If you want to install it system-wide (or are making a distribution package),
|
||||
|
|
|
@ -189,4 +189,4 @@ core.register_on_prejoinplayer(function(name, ip)
|
|||
"or use a different nickname.", name, k)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
|
@ -536,7 +536,7 @@ core.register_chatcommand("fixlight", {
|
|||
core.register_chatcommand("mods", {
|
||||
params = "",
|
||||
description = "List mods installed on the server",
|
||||
privs = {},
|
||||
privs = {server=true},
|
||||
func = function(name, param)
|
||||
return true, table.concat(core.get_modnames(), ", ")
|
||||
end,
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
--------------Music Lic:
|
||||
Amethystium:
|
||||
--Avalon
|
||||
--Ethereal
|
||||
--Faraway
|
||||
--Strangely Beautiful
|
||||
Used with kind permission from Øystein Ramfjord / AM.mu Records
|
||||
|
||||
Jordach:
|
||||
--dark_ambiance
|
||||
--eastern_feeling
|
||||
These sounds are used for the Mod for Minetest; Ambiance.
|
||||
The included sounds are http://creativecommons.org/licenses/by-nc-sa/3.0/
|
||||
Not Used:--mtest
|
||||
|
||||
-----------Sound Lic:
|
||||
--Nightime Sound, Recorded by Mike Koenig, License: Attribution 3.0 http://soundbible.com/951-Nightime.html
|
||||
--Crickets At Night Sound, License: Attribution 3.0 | Recorded by Mike Koenig |http://soundbible.com/365-Crickets-At-Night.html
|
||||
|
||||
--Medium Pack Of Wolves Howling, License: Public Domain | Recorded by fws.gov, http://soundbible.com/277-Medium-Pack-Of-Wolves-Howling.html
|
||||
|
||||
--Horned Owl Sound, License: Attribution 3.0 | Recorded by Mike Koenig , http://soundbible.com/1851-Horned-Owl.html
|
||||
--Bats In Cave Sound, License: Attr-Noncommercial 3.0 | Recorded by Mike Koenig , http://soundbible.com/1939-Bats-In-Cave.html
|
||||
|
||||
--Spooky Water Drops Sound, License: Attribution 3.0 | Recorded by Mike Koenig, http://soundbible.com/380-Spooky-Water-Drops.html
|
||||
|
||||
|
||||
-- Single Water Droplet Sound, License: Attribution 3.0 | Recorded by Mike Koenig, http://soundbible.com/384-Single-Water-Droplet.html
|
||||
|
||||
--HollowWind, Black Boe, Creative Commons 0 License, http://www.freesound.org/people/Black%20Boe/sounds/22331/
|
||||
|
||||
--drippingwater*.ogg sounds: CC0, Dripping Water Mod, by kddekadenz, http://minetest.net/forum/viewtopic.php?id=1688
|
||||
|
||||
--best cardinal bird: License: Attribution 3.0 | Recorded by PsychoBird, http://soundbible.com/1515-Best-Cardinal-Bird.html
|
||||
|
||||
--birdsongnl: the Attribution License, HerbertBoland, http://www.freesound.org/people/HerbertBoland/sounds/28312/ (end)
|
||||
|
||||
--robin2: Attribution License, reinsamba, http://www.freesound.org/people/reinsamba/sounds/32479/ (end)
|
||||
|
||||
--Craw.WAV, Attribution License, inchadney, http://www.freesound.org/people/inchadney/sounds/52450/
|
||||
|
||||
--bluejay.wav, Creative Commons 0 License, UncleSigmund, http://www.freesound.org/people/UncleSigmund/sounds/42382/
|
||||
|
||||
--scuba1*.ogg- digifishmusic, Attribution License, http://www.freesound.org/people/digifishmusic/sounds/45521/
|
||||
|
||||
--Underwater Pool - Attribution 3.0 | Recorded by Mike Koenig, http://soundbible.com/1660-Underwater-Pool.html
|
||||
|
||||
--dolphin_screaming - Creative Commons 0 License, felix.blume, http://www.freesound.org/people/felix.blume/sounds/161691/
|
||||
|
||||
--dolphins - Attribution Noncommercial License, acclivity, http://www.freesound.org/people/acclivity/sounds/13691/
|
||||
|
||||
ComboWind uses:
|
||||
--wind-in-the-trees -Attribution License, laurent, http://www.freesound.org/people/laurent/sounds/16995/
|
||||
--drygrassInWind- Creative Commons 0 License, felix.blume, http://www.freesound.org/people/felix.blume/sounds/146436/
|
||||
|
||||
--Splash: Attribution 3.0 | Recorded by BlastwaveFx.com, http://soundbible.com/546-Fish-Splashing.html
|
||||
|
||||
--small_waterfall Attribution License, volivieri, http://www.freesound.org/people/volivieri/sounds/38390/
|
||||
|
||||
--Lake_Waves_2*, Attribution License, Benboncan, http://www.freesound.org/people/Benboncan/sounds/67884/
|
||||
|
||||
--water_swimming_splashing*, Attribution Noncommercial License, Robinhood76, http://www.freesound.org/people/Robinhood76/sounds/79657/
|
||||
|
||||
--earth01a, Creative Commons 0 License., Halion , http://www.freesound.org/people/Halion/sounds/17785
|
||||
|
||||
--fiji_beach, Creative Commons 0 License, c97059890, http://www.freesound.org/people/c97059890/sounds/21754/
|
||||
|
||||
--seagull, Attribution Noncommercial License., hazure, http://www.freesound.org/people/hazure/sounds/23707/,
|
||||
|
||||
desert:
|
||||
coyote2, Attribution License, rogerforeman, http://www.freesound.org/people/rogerforeman/sounds/68068/
|
||||
http://www.freesound.org/people/Proxima4/sounds/104319/
|
||||
Desert Monolith.wav, Creative Commons 0 License, Proxima4, http://www.freesound.org/people/Proxima4/sounds/104319/
|
||||
Rattlesnake Rattle, Public Domain, fws.gov, http://soundbible.com/237-Rattlesnake-Rattle.html
|
||||
|
||||
flying:
|
||||
crystal_airlines: Attribution License, suonho, http://www.freesound.org/people/suonho/sounds/56364/
|
||||
|
||||
----------------Not used yet:
|
||||
desert:
|
||||
Desert Simple.wav, Creative Commons 0 License, Proxima4, http://www.freesound.org/people/Proxima4/sounds/104320/
|
||||
|
||||
313hummer (Jordan Craige)
|
||||
--echos http://soundcloud.com/jordan-craige/echos-1
|
||||
Creative Commons Attribution license (reuse allowed) Attribution 3.0 Unported (CC BY 3.0)
|
||||
Not Used:--FoamOfTheSea http://soundcloud.com/jordan-craige/foam-of-the-sea
|
||||
|
||||
xi-intersection:
|
||||
http://soundcloud.com/xi-intersection/mass-effect-uncharted-worlds Creative Commons License
|
||||
--not used:
|
||||
http://soundcloud.com/xi-intersection/donkey-kong-country-2-flight
|
||||
http://soundcloud.com/kogyo/kogyo-skalar-m1
|
||||
|
||||
lava:
|
||||
http://www.freesound.org/people/Halion/sounds/17785/ (almost as good cc) (combine with rocks falling?)
|
||||
http://www.freesound.org/people/pushtobreak/sounds/17823/ (attrib non cc really good)
|
||||
http://www.freesound.org/people/klankbeeld/sounds/123970/ (horror rhythm)
|
||||
Rockfall in mine.wav http://www.freesound.org/people/Benboncan/sounds/60085/
|
||||
|
||||
|
||||
http://www.freesound.org/people/snotch/sounds/96175/ (mud volcano)
|
||||
|
||||
--natural night sounds in Boquete.wav, Attribution License, laurent, http://www.freesound.org/people/laurent/sounds/15851/
|
||||
http://www.freesound.org/people/Dynamicell/sounds/17553/
|
||||
http://www.freesound.org/people/juskiddink/sounds/78955/ aspen tree in wind
|
||||
http://www.freesound.org/people/Benboncan/sounds/69761/ wind in hedge birds animals
|
||||
|
||||
|
||||
ButterflyTea:
|
||||
Creative Commons : Attribution-Noncommercial-Share Alike 3.0
|
||||
http://www.jamendo.com/en/track/904012/dance-of-magical-flowers
|
||||
http://www.jamendo.com/en/track/904013/magic-of-the-seventh-world
|
||||
http://www.jamendo.com/en/track/904016/in-search-of-the-soul
|
||||
|
||||
zero-project
|
Before Width: | Height: | Size: 587 B After Width: | Height: | Size: 851 B |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 3.7 KiB |
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
project(minetest)
|
||||
project(voxeladventures-client)
|
||||
|
||||
INCLUDE(CheckIncludeFiles)
|
||||
INCLUDE(CheckLibraryExists)
|
||||
|
@ -489,6 +489,7 @@ set(client_SRCS
|
|||
${sound_SRCS}
|
||||
${client_network_SRCS}
|
||||
${client_irrlicht_changes_SRCS}
|
||||
#ambiance.cpp
|
||||
camera.cpp
|
||||
client.cpp
|
||||
clientenvironment.cpp
|
||||
|
|
|
@ -0,0 +1,448 @@
|
|||
/*
|
||||
* ambience.cpp
|
||||
|
||||
*
|
||||
* Created on: Jun 13, 2015
|
||||
* Author: brandon
|
||||
*/
|
||||
|
||||
#include "ambiance.h"
|
||||
#include "log.h"
|
||||
#include "localplayer.h"
|
||||
#include "map.h"
|
||||
#include "clientmap.h"
|
||||
|
||||
const std::string DIRT = "default:dirt";//m_env.getGameDef()->getNodeDefManager()->getId("default:dirt");
|
||||
const std::string STONE = "default:stone";//m_env.getGameDef()->getNodeDefManager()->getId("default:stone");
|
||||
const std::string GRASS = "default:dirt_with_grass";//m_env.getGameDef()->getNodeDefManager()->getId("default:dirt_with_grass");
|
||||
const std::string TREE = "default:tree";//m_env.getGameDef()->getNodeDefManager()->getId("default:tree");
|
||||
const std::string LEAVES = "default:leaves";//m_env.getGameDef()->getNodeDefManager()->getId("default:leaves");
|
||||
const std::string WATER = "default:water_source";//m_env.getGameDef()->getNodeDefManager()->getId("default:water_source");
|
||||
const std::string WATER_FLOWING = "default:water_flowing";//m_env.getGameDef()->getNodeDefManager()->getId("default:water_flowing");
|
||||
const std::string MG_WATER = "default:mg_water_source";
|
||||
const std::string MG_WATER_FLOWING = "default:mg_water_flowing";
|
||||
const std::string SNOW = "default:snow";
|
||||
const std::string DIRT_SNOW = "default:dirt_with_snow";
|
||||
const std::string SAND = "default:sand";
|
||||
const std::string DESERT_STONE = "default:desert_stone";
|
||||
const std::string DESERT_SAND = "default:desert_sand";
|
||||
const std::string JUNGLE_TREE = "default:jungletree";
|
||||
const std::string JUNGLE_LEAVES = "default:jungleleaves";
|
||||
const std::string JUNGLE_GRASS = "default:junglegrass";
|
||||
|
||||
Ambiance::Ambiance(ISoundManager *sound, ClientEnvironment &e):
|
||||
m_sound(sound),
|
||||
m_env(e),
|
||||
currentEnv(0)
|
||||
{
|
||||
verbosestream << "[AMBIANCE] Loading sound files...";
|
||||
m_sound->loadSoundFile("bats","client/sounds/bats.ogg");
|
||||
m_sound->loadSoundFile("bird","client/sounds/bird.ogg");
|
||||
m_sound->loadSoundFile("bird2","client/sounds/bird2.ogg");
|
||||
m_sound->loadSoundFile("bird3","client/sounds/bird3.ogg");
|
||||
m_sound->loadSoundFile("bird4","client/sounds/bird4.ogg");
|
||||
m_sound->loadSoundFile("birdsong","client/sounds/birdsong.ogg");
|
||||
m_sound->loadSoundFile("coyote","client/sounds/coyote.ogg");
|
||||
m_sound->loadSoundFile("crickets","client/sounds/crickets.ogg");
|
||||
m_sound->loadSoundFile("crow","client/sounds/crow.ogg");
|
||||
m_sound->loadSoundFile("desert","client/sounds/desert.ogg");
|
||||
m_sound->loadSoundFile("drip_a","client/sounds/drippingwater_drip_a.ogg");
|
||||
m_sound->loadSoundFile("drip_b","client/sounds/drippingwater_drip_b.ogg");
|
||||
m_sound->loadSoundFile("drip_c","client/sounds/drippingwater_drip_c.ogg");
|
||||
m_sound->loadSoundFile("drip_d","client/sounds/drippingwater_drip_d.ogg");
|
||||
m_sound->loadSoundFile("drip_e","client/sounds/drippingwater_drip_e.ogg");
|
||||
m_sound->loadSoundFile("drowning_gasp","client/sounds/drowning_gasp.ogg");
|
||||
m_sound->loadSoundFile("lake_waves_calm","client/sounds/lake_waves_2_calm.ogg");
|
||||
m_sound->loadSoundFile("lake_waves_variety","client/sounds/lake_waves_2_variety.ogg");
|
||||
m_sound->loadSoundFile("owl","client/sounds/owl.ogg");
|
||||
m_sound->loadSoundFile("rattlesnake","client/sounds/rattlesnake.ogg");
|
||||
m_sound->loadSoundFile("rumble","client/sounds/rumble.ogg");
|
||||
m_sound->loadSoundFile("scuba1","client/sounds/scuba1bubbles.ogg");
|
||||
m_sound->loadSoundFile("scuba2","client/sounds/scuba1calm.ogg");
|
||||
m_sound->loadSoundFile("scuba3","client/sounds/scuba1calm2.ogg");
|
||||
m_sound->loadSoundFile("scuba4","client/sounds/scuba1interestingbubbles.ogg");
|
||||
m_sound->loadSoundFile("scuba5","client/sounds/scuba1tubulentbubbles.ogg");
|
||||
m_sound->loadSoundFile("splash","client/sounds/splash.ogg");
|
||||
m_sound->loadSoundFile("swimming1","client/sounds/water_swimming_splashing.ogg");
|
||||
m_sound->loadSoundFile("swimming2","client/sounds/water_swimming_splashing_breath.ogg");
|
||||
m_sound->loadSoundFile("waves","client/sounds/waves.ogg");
|
||||
m_sound->loadSoundFile("waves2","client/sounds/waves2.ogg");
|
||||
m_sound->loadSoundFile("wolves","client/sounds/wolves.ogg");
|
||||
|
||||
verbosestream << "done" << std::endl;
|
||||
|
||||
verbosestream << "[AMBIANCE] Setting up environments...";
|
||||
a_env[ENV_UNKNOWN] = ambiance_environment("Unknown", 0, 0, "", "", "", 0);
|
||||
|
||||
// setup the various environment's sounds and frequencies
|
||||
a_env[ENV_CAVE] = ambiance_environment("Cave", 400, 6, "", "", "", 5.75);
|
||||
a_env[ENV_CAVE].sounds[1] = env_sound("bats",.4);
|
||||
a_env[ENV_CAVE].sounds[2] = env_sound("drip_a",.8);
|
||||
a_env[ENV_CAVE].sounds[3] = env_sound("drip_b",.8);
|
||||
a_env[ENV_CAVE].sounds[4] = env_sound("drip_c",.6);
|
||||
a_env[ENV_CAVE].sounds[5] = env_sound("drip_d",.4);
|
||||
a_env[ENV_CAVE].sounds[6] = env_sound("drip_e",.5);
|
||||
|
||||
a_env[ENV_UNDERWATER] = ambiance_environment("Underwater", 1001, 5, "splash", "drowning_gasp", "", 0);
|
||||
a_env[ENV_UNDERWATER].sounds[1] = env_sound("scuba1",1);
|
||||
a_env[ENV_UNDERWATER].sounds[2] = env_sound("scuba2",1);
|
||||
a_env[ENV_UNDERWATER].sounds[3] = env_sound("scuba3",1);
|
||||
a_env[ENV_UNDERWATER].sounds[4] = env_sound("scuba4",1);
|
||||
a_env[ENV_UNDERWATER].sounds[5] = env_sound("scuba5",1);
|
||||
|
||||
a_env[ENV_INWATER] = ambiance_environment("Standing in Water", 1001, 2, "", "", "", 0);
|
||||
a_env[ENV_INWATER].sounds[1] = env_sound("swimming1",.6);
|
||||
a_env[ENV_INWATER].sounds[2] = env_sound("swimming2",.6);
|
||||
|
||||
a_env[ENV_PLAINS] = ambiance_environment("Plains", 300, 5, "", "", "", 4);
|
||||
a_env[ENV_PLAINS].sounds[1] = env_sound("bird2",.2);
|
||||
a_env[ENV_PLAINS].sounds[2] = env_sound("bird4",.2);
|
||||
a_env[ENV_PLAINS].sounds[3] = env_sound("bird3",.2);
|
||||
a_env[ENV_PLAINS].sounds[4] = env_sound("bird",.2);
|
||||
a_env[ENV_PLAINS].sounds[5] = env_sound("birdsong",.2);
|
||||
|
||||
a_env[ENV_PLAINS_NIGHT] = ambiance_environment("Plains Night", 300, 0, "", "", "crickets", 6);
|
||||
|
||||
a_env[ENV_FOREST] = ambiance_environment("Forest", 700, 5, "", "", "", 3);
|
||||
a_env[ENV_FOREST].sounds[1] = env_sound("bird2",.5);
|
||||
a_env[ENV_FOREST].sounds[2] = env_sound("bird4",.5);
|
||||
a_env[ENV_FOREST].sounds[3] = env_sound("bird3",.5);
|
||||
a_env[ENV_FOREST].sounds[4] = env_sound("bird",.5);
|
||||
a_env[ENV_FOREST].sounds[5] = env_sound("birdsong",.5);
|
||||
|
||||
a_env[ENV_FOREST_NIGHT] = ambiance_environment("Forest Night", 400, 3, "", "", "crickets", 4);
|
||||
a_env[ENV_FOREST_NIGHT].sounds[1] = env_sound("owl",.8);
|
||||
a_env[ENV_FOREST_NIGHT].sounds[2] = env_sound("coyote",.8);
|
||||
a_env[ENV_FOREST_NIGHT].sounds[3] = env_sound("wolves",.9);
|
||||
|
||||
a_env[ENV_SNOW] = ambiance_environment("Snow", -1, 0, "", "", "", 0);
|
||||
|
||||
a_env[ENV_SNOW_NIGHT] = ambiance_environment("Snow Night", -1, 0, "", "", "", 0);
|
||||
|
||||
a_env[ENV_OCEAN] = ambiance_environment("Ocean", 800, 3, "", "", "", 1);
|
||||
a_env[ENV_OCEAN].sounds[1] = env_sound("waves", .8);
|
||||
a_env[ENV_OCEAN].sounds[2] = env_sound("waves2",.8);
|
||||
a_env[ENV_OCEAN].sounds[3] = env_sound("seagull",.7);
|
||||
|
||||
a_env[ENV_DESERT] = ambiance_environment("Desert", 625, 1, "", "", "desert", 3);
|
||||
a_env[ENV_DESERT].sounds[1] = env_sound("rattlesnake", .6 );
|
||||
|
||||
a_env[ENV_DESERT_NIGHT] = ambiance_environment("Desert Night", 400, 1, "", "", "", 3);
|
||||
a_env[ENV_DESERT_NIGHT].sounds[1] = env_sound("desert", .8 );
|
||||
|
||||
a_env[ENV_JUNGLE] = ambiance_environment("Jungle", 725, 3, "", "", "", 2);
|
||||
a_env[ENV_JUNGLE].sounds[1] = env_sound("bird4",.6);
|
||||
a_env[ENV_JUNGLE].sounds[2] = env_sound("bird3",.6);
|
||||
a_env[ENV_JUNGLE].sounds[3] = env_sound("bird",.5);
|
||||
|
||||
a_env[ENV_JUNGLE_NIGHT] = ambiance_environment("Jungle Night", 300, 3, "", "", "crickets", 3);
|
||||
a_env[ENV_JUNGLE_NIGHT].sounds[1] = env_sound("owl",.7);
|
||||
a_env[ENV_JUNGLE_NIGHT].sounds[2] = env_sound("coyote",.7);
|
||||
a_env[ENV_JUNGLE_NIGHT].sounds[3] = env_sound("wolves",.8);
|
||||
|
||||
|
||||
verbosestream << "done" << std::endl;
|
||||
|
||||
}
|
||||
void Ambiance::doAmbiance(float dtime, u32 tod){
|
||||
static bool newEnv = false;
|
||||
m_timeOfDay = tod;
|
||||
tickDelay += dtime;
|
||||
doFades(dtime);
|
||||
if ( startDelay > 3 && tickDelay > .1 ) { // delay ambiance 3 seconds from launch of game
|
||||
lastPlay += dtime;
|
||||
tickDelay = 0;
|
||||
int env_result = readEnvironment();
|
||||
if ( env_result != currentEnv ){
|
||||
lastEnv = currentEnv;
|
||||
currentEnv = env_result;
|
||||
stopEnvironment(lastEnv); // change of enviroment stop all sounds that might be playing
|
||||
if ( !a_env[currentEnv].on_start.empty() ){
|
||||
playSound(a_env[currentEnv].on_start, 1);
|
||||
}
|
||||
newEnv = true;
|
||||
actionstream << "[AMBIANCE] readEnvironment Results: " << a_env[currentEnv].name << std::endl;
|
||||
if ( !a_env[currentEnv].background_sound.empty() ){
|
||||
m_background_sound = m_sound->playSound(a_env[currentEnv].background_sound,true,0.0);
|
||||
fadeSound(m_background_sound,1.25,0.6);
|
||||
} else {
|
||||
m_background_sound = 0;
|
||||
}
|
||||
} else {
|
||||
newEnv = false;
|
||||
}
|
||||
|
||||
if ( m_sounds_playing.rbegin() != m_sounds_playing.rend() ){
|
||||
if ( m_sound->soundExists(m_sounds_playing.rbegin()->second) ){
|
||||
return;
|
||||
} else {
|
||||
m_sounds_it it = m_sounds_playing.find(m_sounds_playing.rbegin()->first);
|
||||
m_sounds_playing.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
if ( a_env[currentEnv].sound_count > 0 ){
|
||||
if ( lastPlay >= a_env[currentEnv].next_sound_delay ){
|
||||
srand (time(NULL));
|
||||
int freq = rand() % 1000;
|
||||
//verbosestream << "[AMBIANCE] Freq Random Number: " << to_string(freq) << " :: " << to_string(a_env[currentEnv].frequency) << std::endl;
|
||||
if ( freq <= a_env[currentEnv].frequency ){
|
||||
int s = ( rand() % a_env[currentEnv].sound_count ) + 1;
|
||||
float v = ( rand() % 60 ); // add a little random variation to the sound volume
|
||||
if ( v > 0 )
|
||||
v = v / 100;
|
||||
verbosestream << "[AMBIANCE] Sound selected: " << std::to_string(s) << " " << a_env[currentEnv].sounds[s].name << std::endl;
|
||||
playSound(a_env[currentEnv].sounds[s].name, ( a_env[currentEnv].sounds[s].gain - v ));
|
||||
}
|
||||
} else {
|
||||
//verbosestream << "[AMBIANCE] No Play" << to_string(lastPlay) <<std::endl;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
startDelay += dtime;
|
||||
}
|
||||
}
|
||||
|
||||
// type is 0 - normal sound, 1 start sound, 2 stop sound
|
||||
bool Ambiance::playSound(std::string name, float gain, bool fade){
|
||||
float oGain = 0;
|
||||
verbosestream << "[AMBIANCE] playSound(" << name << ")" << std::endl;
|
||||
std::map<std::string, int>::iterator i = m_sounds_playing.find(name);
|
||||
if ( i != m_sounds_playing.end() ){
|
||||
// check the sound buffers to see if it's still playing
|
||||
if ( m_sound->soundExists(i->second) ){
|
||||
// get out of here so we don't play it again
|
||||
verbosestream << "[AMBIANCE] " << name << " is already playing" << std::endl;
|
||||
return false;
|
||||
} else {
|
||||
// remove it from our playing list
|
||||
m_sounds_playing.erase(name);
|
||||
}
|
||||
}
|
||||
|
||||
if ( fade == true ){
|
||||
oGain = gain;
|
||||
gain = 0;
|
||||
}
|
||||
|
||||
int id = m_sound->playSound(name, false, gain);
|
||||
m_sounds_playing[name] = id;
|
||||
|
||||
if ( fade == true ){
|
||||
fadeSound(id, 1.25, oGain);
|
||||
}
|
||||
|
||||
lastPlay = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Ambiance::fadeSound(int soundid, float step, float gain){
|
||||
float cGain = m_sound->getSoundGain(soundid);
|
||||
fade_status f = fade_status(step,cGain,gain);
|
||||
m_sounds_fading[soundid] = f;
|
||||
}
|
||||
|
||||
void Ambiance::doFades(float dtime){
|
||||
static float fadeDelay = 0;
|
||||
fadeDelay += dtime;
|
||||
if ( fadeDelay > 0.2 ){
|
||||
float chkGain = 0;
|
||||
for ( m_fading_it i = m_sounds_fading.begin(); i != m_sounds_fading.end(); i++ ){
|
||||
if ( i->second.step < 0 )
|
||||
chkGain = i->second.current_gain * -1;
|
||||
else
|
||||
chkGain = i->second.current_gain;
|
||||
|
||||
if ( chkGain < i->second.target_gain ){
|
||||
i->second.current_gain += (i->second.step * fadeDelay);
|
||||
if ( i->second.current_gain < 0 )
|
||||
i->second.current_gain = 0;
|
||||
|
||||
if ( i->second.current_gain > 1 )
|
||||
i->second.current_gain = 1;
|
||||
|
||||
|
||||
m_sound->updateSoundGain(i->first,i->second.current_gain);
|
||||
} else {
|
||||
if ( i->second.target_gain <= 0 ){
|
||||
m_sound->stopSound(i->first);
|
||||
}
|
||||
for ( m_sounds_it ii = m_sounds_playing.begin(); ii != m_sounds_playing.end(); ii++ ){
|
||||
if ( ii->second == i->first )
|
||||
m_sounds_playing.erase(ii->first);
|
||||
}
|
||||
m_sounds_fading.erase(i->first);
|
||||
}
|
||||
}
|
||||
fadeDelay = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int Ambiance::readEnvironment(){
|
||||
//actionstream << "[AMBIANCE] readEnvironment() ";
|
||||
ascending = false;
|
||||
descending = false;
|
||||
moving = false;
|
||||
underwater = false;
|
||||
|
||||
LocalPlayer *p = m_env.getLocalPlayer();
|
||||
v3f pos = p->getPosition();
|
||||
v3s16 spos = p->getStandingNodePos();
|
||||
|
||||
// DAY AND NIGHT ARE KIND OF CATCH ALLS
|
||||
// 19000 night starts
|
||||
// 5000 morning starts
|
||||
u32 t = m_timeOfDay;
|
||||
|
||||
if ( t > 5000 && t < 8000 )
|
||||
TOD = MORNING;
|
||||
|
||||
if ( t > 8000 && t < 18500 )
|
||||
TOD = DAY;
|
||||
|
||||
if ( t > 18500 && t < 19500 )
|
||||
TOD = DUSK;
|
||||
|
||||
if ( t > 19500 || t < 5000 )
|
||||
TOD = NIGHT;
|
||||
|
||||
if ( pos.Y > ( lastpos.Y + .5 ) )
|
||||
ascending = true;
|
||||
|
||||
if ( pos.Y < ( lastpos.Y - .5 ) )
|
||||
descending = true;
|
||||
|
||||
if ( pos.X != lastpos.X || pos.Z != lastpos.Z )
|
||||
moving = true;
|
||||
|
||||
// if they aren't moving and the time of day hasn't changed don't recheck the environment
|
||||
//if ( moving != true && TOD == lastTOD && currentEnv != ENV_INWATER )
|
||||
// return currentEnv;
|
||||
|
||||
lastpos = pos;
|
||||
lastTOD = TOD;
|
||||
|
||||
// find the nodes at their body positions
|
||||
std::string lowerBodyNode = getNodeName(v3s16(spos.X, (spos.Y+1), spos.Z));
|
||||
std::string upperBodyNode = getNodeName(v3s16(spos.X, (spos.Y+2), spos.Z));
|
||||
std::string standingOnNode = getNodeName(v3s16(spos.X, spos.Y, spos.Z));
|
||||
std::string aboveHeadNode = getNodeName(v3s16(spos.X, (spos.Y+3), spos.Z));
|
||||
|
||||
if ( ( upperBodyNode == WATER || upperBodyNode == MG_WATER || upperBodyNode == WATER_FLOWING || upperBodyNode == MG_WATER_FLOWING ) ){
|
||||
underwater = true;
|
||||
return ENV_UNDERWATER;
|
||||
}
|
||||
|
||||
if ( moving == true && ( lowerBodyNode == WATER || lowerBodyNode == WATER_FLOWING || lowerBodyNode == MG_WATER || lowerBodyNode == MG_WATER_FLOWING || standingOnNode == WATER || standingOnNode == WATER_FLOWING || standingOnNode == MG_WATER || standingOnNode == MG_WATER_FLOWING ) ){
|
||||
return ENV_INWATER;
|
||||
}
|
||||
|
||||
|
||||
// all of these happen above ground
|
||||
if ( spos.Y > 0 ){
|
||||
|
||||
if ( nodesInRange(spos,10, 3, -1, JUNGLE_TREE,1,15) || nodesInRange(spos,10,2,-1,JUNGLE_GRASS,1,5) ){
|
||||
if ( TOD == MORNING || TOD == DAY )
|
||||
return ENV_JUNGLE;
|
||||
else
|
||||
return ENV_JUNGLE_NIGHT;
|
||||
}
|
||||
|
||||
if ( nodesInRange(spos, 10, 4, -1, TREE,1,10) || nodesInRange(spos,10, 7, -1, LEAVES,1, 8 ) ){
|
||||
if ( TOD == MORNING || TOD == DAY )
|
||||
return ENV_FOREST;
|
||||
else
|
||||
return ENV_FOREST_NIGHT;
|
||||
}
|
||||
|
||||
if ( nodesInRange(spos, 5, 1, 1, GRASS,1,8) ){
|
||||
if ( TOD == MORNING || TOD == DAY )
|
||||
return ENV_PLAINS;
|
||||
else
|
||||
return ENV_PLAINS_NIGHT;
|
||||
}
|
||||
|
||||
if ( nodesInRange(spos, 5, 1, 2, SNOW, 1, 10) || nodesInRange(spos,5, 1, 2, DIRT_SNOW,1,10) ){
|
||||
if ( TOD == MORNING || TOD == DAY )
|
||||
return ENV_SNOW;
|
||||
else
|
||||
return ENV_SNOW_NIGHT;
|
||||
}
|
||||
|
||||
if ( nodesInRange(spos, 10, 1, 2, DESERT_SAND, 1, 15) || nodesInRange(spos,10,1,2,DESERT_STONE,1,15) ){
|
||||
if ( TOD == MORNING || TOD == DAY )
|
||||
return ENV_DESERT;
|
||||
else
|
||||
return ENV_DESERT_NIGHT;
|
||||
}
|
||||
|
||||
if ( spos.Y < 7 && spos.Y > -1 ){
|
||||
if ( nodesInRange(spos,10,2,7,SAND, 1, 10) ){
|
||||
if ( nodesInRange(spos, 20, 0, 7, WATER, 5, 8) || nodesInRange(spos, 20, 0, 7, MG_WATER, 5, 8) ){
|
||||
return ENV_OCEAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( nodesInRange(spos, 3, 6, 0, STONE,1,25) ){
|
||||
return ENV_CAVE;
|
||||
}
|
||||
|
||||
return ENV_UNKNOWN;
|
||||
}
|
||||
|
||||
bool Ambiance::nodesInRange(v3s16 pos, short searchRange, short searchAbove, short searchBelow, std::string nodeName, short accuracy, int count){
|
||||
//verbosestream << "[AMBIANCE] nodesInRange(pos, " << to_string(searchRange) << ", " << nodeName << ")" << std::endl;
|
||||
int nodeCount = 0;
|
||||
std::string cNode;
|
||||
// set positions for node checks
|
||||
v3s16 p1 = v3s16((pos.X - searchRange), (pos.Y - searchBelow), (pos.Z - searchRange));
|
||||
v3s16 p2 = v3s16((pos.X + searchRange), (pos.Y + searchAbove), (pos.Z + searchRange));
|
||||
for ( int y = p1.Y; y < p2.Y; y+=accuracy ){
|
||||
for ( int x = p1.X; x < p2.X; x+=accuracy ){
|
||||
for ( int z = p1.Z; z < p2.Z; z+=accuracy ){
|
||||
cNode = getNodeName(v3s16(x,y,z));
|
||||
if ( cNode == nodeName )
|
||||
nodeCount++;
|
||||
}
|
||||
if ( nodeCount > count )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Ambiance::getNodeName(v3s16 pos){
|
||||
MapNode n = m_env.getMap().getNodeNoEx(pos);
|
||||
ContentFeatures f = m_env.getGameDef()->getNodeDefManager()->get(n);
|
||||
return f.name;
|
||||
}
|
||||
|
||||
int Ambiance::getNodeId(v3s16 pos){
|
||||
MapNode n = m_env.getMap().getNodeNoEx(pos);
|
||||
return n.getContent();
|
||||
}
|
||||
|
||||
|
||||
void Ambiance::stopEnvironment(int env){
|
||||
// not going to bother seeing if the sounds playing are part of a certain environment just yet, just stop all sounds
|
||||
for ( m_sounds_it i = m_sounds_playing.begin(); i != m_sounds_playing.end(); i++ ){
|
||||
//m_sound->stopSound(i->second);
|
||||
fadeSound(i->second,-1.25,0);
|
||||
m_sounds_playing.erase(i->first); // go ahead and erase it here so we don't get double fade outs
|
||||
}
|
||||
|
||||
if ( m_background_sound != 0 ){
|
||||
fadeSound(m_background_sound,-0.5,0);
|
||||
//m_sound->stopSound(m_background_sound);
|
||||
m_background_sound = 0;
|
||||
}
|
||||
|
||||
if ( !a_env[env].on_stop.empty() ){
|
||||
playSound(a_env[env].on_stop,1);
|
||||
}
|
||||
|
||||
lastPlay = 0;
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* ambience.h
|
||||
*
|
||||
* Created on: Jun 13, 2015
|
||||
* Author: brandon
|
||||
*/
|
||||
#ifndef SRC_AMBIANCE_H_
|
||||
#define SRC_AMBIANCE_H_
|
||||
|
||||
#include "gamedef.h"
|
||||
#include "environment.h"
|
||||
#include "clientenvironment.h"
|
||||
#include "sound.h"
|
||||
#include "settings.h"
|
||||
#include "sound_openal.h"
|
||||
#include "nodedef.h"
|
||||
|
||||
class Ambiance
|
||||
{
|
||||
public:
|
||||
Ambiance(ISoundManager *sound, ClientEnvironment &e);
|
||||
void doAmbiance(float dtime, u32 tod);
|
||||
private:
|
||||
bool playSound(std::string name, float gain, bool fade = false);
|
||||
void doFades(float dtime);
|
||||
bool nodesInRange(v3s16 pos, short searchRange, short searchAbove, short searchBelow, std::string nodeName, short accuracy, int count);
|
||||
std::string getNodeName(v3s16 pos);
|
||||
int getNodeId(v3s16 pos);
|
||||
void stopEnvironment(int env);
|
||||
int readEnvironment();
|
||||
void fadeSound(int soundid, float step, float gain);
|
||||
|
||||
|
||||
u32 m_timeOfDay;
|
||||
|
||||
ISoundManager *m_sound;
|
||||
ClientEnvironment m_env;
|
||||
|
||||
int m_background_sound;
|
||||
std::map<std::string, int> m_sounds_playing;
|
||||
typedef std::map<std::string, int>::iterator m_sounds_it;
|
||||
|
||||
struct fade_status {
|
||||
fade_status() {}
|
||||
fade_status(float step, float current_gain, float target_gain):
|
||||
step(step),
|
||||
current_gain(current_gain),
|
||||
target_gain(target_gain){}
|
||||
float step;
|
||||
float current_gain;
|
||||
float target_gain;
|
||||
};
|
||||
|
||||
std::map<int, fade_status> m_sounds_fading; // 0 = step, 1 = current gain, 2 = goal gain
|
||||
typedef std::map<int, fade_status>::iterator m_fading_it;
|
||||
|
||||
v3f lastpos;
|
||||
bool ascending;
|
||||
bool descending;
|
||||
bool moving;
|
||||
bool underwater;
|
||||
|
||||
float startDelay;
|
||||
float envDelay;
|
||||
float tickDelay;
|
||||
|
||||
int currentEnv;
|
||||
int lastEnv;
|
||||
float lastPlay;
|
||||
int TOD;
|
||||
int lastTOD;
|
||||
|
||||
struct env_sound {
|
||||
env_sound() {}
|
||||
env_sound(std::string name,
|
||||
float gain):
|
||||
name(name),
|
||||
gain(gain) {}
|
||||
std::string name;
|
||||
float gain;
|
||||
};
|
||||
|
||||
struct ambiance_environment {
|
||||
ambiance_environment() {}
|
||||
ambiance_environment(std::string name,
|
||||
int frequency,
|
||||
int sound_count,
|
||||
std::string on_start,
|
||||
std::string on_stop,
|
||||
std::string background_sound,
|
||||
float next_sound_delay):
|
||||
name(name),
|
||||
frequency(frequency),
|
||||
sound_count(sound_count),
|
||||
on_start(on_start),
|
||||
on_stop(on_stop),
|
||||
background_sound(background_sound),
|
||||
next_sound_delay(next_sound_delay) {}
|
||||
std::string name;
|
||||
int frequency;
|
||||
int sound_count;
|
||||
std::string on_start;
|
||||
std::string on_stop;
|
||||
std::string background_sound;
|
||||
float next_sound_delay;
|
||||
env_sound sounds[10];
|
||||
bool on_start_played;
|
||||
bool on_stop_played;
|
||||
};
|
||||
|
||||
enum environment_ids {
|
||||
ENV_UNKNOWN,
|
||||
ENV_CAVE,
|
||||
ENV_UNDERWATER,
|
||||
ENV_INWATER,
|
||||
ENV_PLAINS,
|
||||
ENV_PLAINS_NIGHT,
|
||||
ENV_FOREST,
|
||||
ENV_FOREST_NIGHT,
|
||||
ENV_SNOW,
|
||||
ENV_SNOW_NIGHT,
|
||||
ENV_OCEAN,
|
||||
ENV_DESERT,
|
||||
ENV_DESERT_NIGHT,
|
||||
ENV_JUNGLE,
|
||||
ENV_JUNGLE_NIGHT
|
||||
};
|
||||
|
||||
enum time_of_day {
|
||||
MORNING,
|
||||
DAY,
|
||||
DUSK,
|
||||
NIGHT
|
||||
};
|
||||
|
||||
ambiance_environment a_env[15];
|
||||
|
||||
};
|
||||
|
||||
#endif /* SRC_AMBIANCE_H_ */
|
|
@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "util/string.h"
|
||||
#include "util/srp.h"
|
||||
#include "client.h"
|
||||
|
||||
//#include "ambiance.h"
|
||||
#include "network/clientopcodes.h"
|
||||
#include "filesys.h"
|
||||
#include "mapblock_mesh.h"
|
||||
|
@ -48,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "script/scripting_client.h"
|
||||
#include "game.h"
|
||||
|
||||
|
||||
extern gui::IGUIEnvironment* guienv;
|
||||
|
||||
/*
|
||||
|
@ -408,6 +411,10 @@ void Client::step(float dtime)
|
|||
m_env.step(dtime);
|
||||
m_sound->step(dtime);
|
||||
|
||||
//if ( g_settings->getBool("ambiance") ){
|
||||
// m_ambiance->doAmbiance(dtime,m_env.getTimeOfDay());
|
||||
//}
|
||||
|
||||
/*
|
||||
Get events
|
||||
*/
|
||||
|
|
|
@ -27,6 +27,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "ambiance.h"
|
||||
#include <unordered_set>
|
||||
#include "clientobject.h"
|
||||
#include "gamedef.h"
|
||||
|
@ -601,6 +603,7 @@ private:
|
|||
|
||||
MeshUpdateThread m_mesh_update_thread;
|
||||
ClientEnvironment m_env;
|
||||
//Ambiance *m_ambiance;
|
||||
ParticleManager m_particle_manager;
|
||||
con::Connection m_con;
|
||||
std::string m_address_name;
|
||||
|
|
|
@ -156,7 +156,8 @@ enum MaterialType{
|
|||
TILE_MATERIAL_LIQUID_TRANSPARENT,
|
||||
TILE_MATERIAL_LIQUID_OPAQUE,
|
||||
TILE_MATERIAL_WAVING_LEAVES,
|
||||
TILE_MATERIAL_WAVING_PLANTS
|
||||
TILE_MATERIAL_WAVING_PLANTS,
|
||||
TILE_MATERIAL_OPAQUE
|
||||
};
|
||||
|
||||
// Material flags
|
||||
|
@ -216,6 +217,10 @@ struct TileLayer
|
|||
void applyMaterialOptions(video::SMaterial &material) const
|
||||
{
|
||||
switch (material_type) {
|
||||
case TILE_MATERIAL_OPAQUE:
|
||||
case TILE_MATERIAL_LIQUID_OPAQUE:
|
||||
material.MaterialType = video::EMT_SOLID;
|
||||
break;
|
||||
case TILE_MATERIAL_BASIC:
|
||||
case TILE_MATERIAL_WAVING_LEAVES:
|
||||
case TILE_MATERIAL_WAVING_PLANTS:
|
||||
|
@ -225,9 +230,6 @@ struct TileLayer
|
|||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
break;
|
||||
case TILE_MATERIAL_LIQUID_OPAQUE:
|
||||
material.MaterialType = video::EMT_SOLID;
|
||||
break;
|
||||
}
|
||||
material.BackfaceCulling = (material_flags & MATERIAL_FLAG_BACKFACE_CULLING)
|
||||
? true : false;
|
||||
|
|
|
@ -37,6 +37,7 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("address", "");
|
||||
settings->setDefault("enable_sound", "true");
|
||||
settings->setDefault("sound_volume", "0.8");
|
||||
settings->setDefault("ambiance","true");
|
||||
settings->setDefault("enable_mesh_cache", "false");
|
||||
settings->setDefault("mesh_generation_interval", "0");
|
||||
settings->setDefault("meshgen_block_cache_size", "20");
|
||||
|
@ -217,6 +218,16 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("repeat_joystick_button_time", "0.17");
|
||||
settings->setDefault("joystick_frustum_sensitivity", "170");
|
||||
|
||||
settings->setDefault("serverlist_url", "voxeladventures.com");
|
||||
settings->setDefault("server_announce", "false");
|
||||
settings->setDefault("server_url", "");
|
||||
settings->setDefault("server_address", "");
|
||||
settings->setDefault("server_name", "");
|
||||
settings->setDefault("server_description", "");
|
||||
settings->setDefault("public_serverlist","true");
|
||||
|
||||
settings->setDefault("disable_escape_sequences", "false");
|
||||
|
||||
// Main menu
|
||||
settings->setDefault("main_menu_path", "");
|
||||
settings->setDefault("main_menu_mod_mgr", "1");
|
||||
|
@ -226,6 +237,7 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("modstore_details_url", "https://forum.minetest.net/mmdb/mod/*/");
|
||||
settings->setDefault("serverlist_file", "favoriteservers.txt");
|
||||
|
||||
|
||||
#if USE_FREETYPE
|
||||
settings->setDefault("freetype", "true");
|
||||
settings->setDefault("font_path", porting::getDataPath("fonts" DIR_DELIM "Arimo-Regular.ttf"));
|
||||
|
@ -261,13 +273,16 @@ void set_default_settings(Settings *settings)
|
|||
settings->setDefault("workaround_window_size","5");
|
||||
settings->setDefault("max_packets_per_iteration","1024");
|
||||
settings->setDefault("port", "30000");
|
||||
|
||||
settings->setDefault("bind_address", "");
|
||||
settings->setDefault("default_game", "adventuretest");
|
||||
|
||||
settings->setDefault("strict_protocol_version_checking", "false");
|
||||
settings->setDefault("player_transfer_distance", "0");
|
||||
settings->setDefault("max_simultaneous_block_sends_per_client", "10");
|
||||
settings->setDefault("max_simultaneous_block_sends_server_total", "40");
|
||||
settings->setDefault("time_send_interval", "5");
|
||||
|
||||
settings->setDefault("default_game", "minetest");
|
||||
settings->setDefault("motd", "");
|
||||
settings->setDefault("max_users", "15");
|
||||
settings->setDefault("creative_mode", "false");
|
||||
|
|
|
@ -49,7 +49,6 @@ public:
|
|||
// Environment will delete the map passed to the constructor
|
||||
Environment(IGameDef *gamedef);
|
||||
virtual ~Environment();
|
||||
DISABLE_CLASS_COPY(Environment);
|
||||
|
||||
/*
|
||||
Step everything in environment.
|
||||
|
|
79
src/game.cpp
|
@ -992,10 +992,10 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
|
|||
setStaticText(guitext_chat, recent_chat);
|
||||
|
||||
// Update gui element size and position
|
||||
s32 chat_y = 5;
|
||||
s32 chat_y = 5 + line_height;
|
||||
|
||||
if (show_debug)
|
||||
chat_y += 2 * line_height;
|
||||
chat_y += line_height;
|
||||
|
||||
// first pass to calculate height of text to be set
|
||||
const v2u32 &window_size = RenderingEngine::get_instance()->getWindowSize();
|
||||
|
@ -2589,6 +2589,53 @@ void Game::processKeyInput()
|
|||
<< std::endl;
|
||||
debug_stacks_print();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert user-specified keystrokes to chat commands
|
||||
static KeyPress mod_key_control = "KEY_CONTROL";
|
||||
static KeyPress mod_key_lcontrol = "KEY_LCONTROL";
|
||||
static KeyPress mod_key_rcontrol = "KEY_RCONTROL";
|
||||
static KeyPress mod_key_shift = "KEY_SHIFT";
|
||||
static KeyPress mod_key_lshift = "KEY_LSHIFT";
|
||||
static KeyPress mod_key_rshift = "KEY_RSHIFT";
|
||||
for (size_t i=0; i<getCommandKeySettingCount(); ++i)
|
||||
{
|
||||
KeyCommand kc = getCommandKeySetting(i);
|
||||
if (input->wasKeyDown(kc.key))
|
||||
{
|
||||
if (kc.modifier_control)
|
||||
{
|
||||
if (!input->wasKeyDown(mod_key_control) &&
|
||||
!input->wasKeyDown(mod_key_lcontrol) &&
|
||||
!input->wasKeyDown(mod_key_rcontrol))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input->wasKeyDown(mod_key_control) ||
|
||||
input->wasKeyDown(mod_key_lcontrol) ||
|
||||
input->wasKeyDown(mod_key_rcontrol))
|
||||
continue;
|
||||
}
|
||||
if (kc.modifier_shift)
|
||||
{
|
||||
if (!input->wasKeyDown(mod_key_shift) &&
|
||||
!input->wasKeyDown(mod_key_lshift) &&
|
||||
!input->wasKeyDown(mod_key_rshift))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (input->wasKeyDown(mod_key_shift) ||
|
||||
input->wasKeyDown(mod_key_lshift) ||
|
||||
input->wasKeyDown(mod_key_rshift))
|
||||
continue;
|
||||
}
|
||||
client->typeChatMessage(narrow_to_wide("/" + kc.command));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isKeyDown(KeyType::JUMP) && runData.reset_jump_timer) {
|
||||
runData.reset_jump_timer = false;
|
||||
|
@ -3487,6 +3534,8 @@ void Game::updateSound(f32 dtime)
|
|||
|
||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||
|
||||
|
||||
v3s16 spos = player->getStandingNodePos();
|
||||
// Tell the sound maker whether to make footstep sounds
|
||||
soundmaker->makes_footstep_sound = player->makes_footstep_sound;
|
||||
|
||||
|
@ -3495,8 +3544,15 @@ void Game::updateSound(f32 dtime)
|
|||
soundmaker->step(dtime);
|
||||
|
||||
ClientMap &map = client->getEnv().getClientMap();
|
||||
|
||||
MapNode n = map.getNodeNoEx(player->getFootstepNodePos());
|
||||
soundmaker->m_player_step_sound = nodedef_manager->get(n).sound_footstep;
|
||||
MapNode a = map.getNodeNoEx(v3s16(spos.X,(spos.Y+1),spos.Z));
|
||||
if ( !nodedef_manager->get(a).isLiquid() ){
|
||||
soundmaker->m_player_step_sound = nodedef_manager->get(n).sound_footstep;
|
||||
} else {
|
||||
SimpleSoundSpec no_sound;
|
||||
soundmaker->m_player_step_sound = no_sound;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -4293,6 +4349,7 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
|
|||
v2u32 screensize = driver->getScreenSize();
|
||||
LocalPlayer *player = client->getEnv().getLocalPlayer();
|
||||
v3f player_position = player->getPosition();
|
||||
v3s16 player_standing = player->getStandingNodePos();
|
||||
|
||||
if (flags.show_debug) {
|
||||
static float drawtime_avg = 0;
|
||||
|
@ -4316,6 +4373,16 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
|
|||
<< ", RTT = " << client->getRTT() << " s";
|
||||
setStaticText(guitext, utf8_to_wide(os.str()).c_str());
|
||||
guitext->setVisible(true);
|
||||
|
||||
} else if (flags.show_hud || flags.show_chat) {
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
os << PROJECT_NAME_C " " << g_version_hash
|
||||
<< " (" << (player_standing.X)
|
||||
<< ", " << (player_standing.Y)
|
||||
<< ", " << (player_standing.Z)
|
||||
<< ") " << yawToDirectionString(cam.camera_yaw);
|
||||
setStaticText(guitext, utf8_to_wide(os.str()).c_str());
|
||||
guitext->setVisible(true);
|
||||
} else {
|
||||
guitext->setVisible(false);
|
||||
}
|
||||
|
@ -4329,15 +4396,15 @@ void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &
|
|||
}
|
||||
|
||||
if (flags.show_debug) {
|
||||
|
||||
std::ostringstream os(std::ios_base::binary);
|
||||
os << std::setprecision(1) << std::fixed
|
||||
<< "(" << (player_position.X / BS)
|
||||
<< ", " << (player_position.Y / BS)
|
||||
<< ", " << (player_position.Z / BS)
|
||||
<< ") (yaw=" << (wrapDegrees_0_360(cam.camera_yaw)) << "°"
|
||||
<< ") (" << (wrapDegrees_0_360(cam.camera_yaw))
|
||||
<< " " << yawToDirectionString(cam.camera_yaw)
|
||||
<< ") (seed = " << ((u64)client->getMapSeed())
|
||||
<< ")";
|
||||
<< ") (seed = " << ((u64)client->getMapSeed()) << ")";
|
||||
|
||||
if (runData.pointed_old.type == POINTEDTHING_NODE) {
|
||||
ClientMap &map = client->getEnv().getClientMap();
|
||||
|
|
|
@ -3526,7 +3526,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
|
||||
// Possibly send inventory action to server
|
||||
if (move_amount > 0) {
|
||||
// Send IACTION_MOVE
|
||||
// Send IAction::Move
|
||||
|
||||
assert(m_selected_item && m_selected_item->isValid());
|
||||
assert(s.isValid());
|
||||
|
@ -3563,7 +3563,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
m_selected_content_guess = ItemStack(); // Clear
|
||||
}
|
||||
|
||||
infostream << "Handing IACTION_MOVE to manager" << std::endl;
|
||||
infostream << "Handing IAction::Move to manager" << std::endl;
|
||||
IMoveAction *a = new IMoveAction();
|
||||
a->count = move_amount;
|
||||
a->from_inv = m_selected_item->inventoryloc;
|
||||
|
@ -3599,7 +3599,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
ItemStack stack_from = list_from->getItem(s.i);
|
||||
assert(shift_move_amount <= stack_from.count);
|
||||
if (m_client->getProtoVersion() >= 25) {
|
||||
infostream << "Handing IACTION_MOVE to manager" << std::endl;
|
||||
infostream << "Handing IAction::Move to manager" << std::endl;
|
||||
IMoveAction *a = new IMoveAction();
|
||||
a->count = shift_move_amount;
|
||||
a->from_inv = s.inventoryloc;
|
||||
|
@ -3617,7 +3617,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
&& shift_move_amount > 0; slot_to++) {
|
||||
list_to->itemFits(slot_to, stack_from, &leftover);
|
||||
if (leftover.count < stack_from.count) {
|
||||
infostream << "Handing IACTION_MOVE to manager" << std::endl;
|
||||
infostream << "Handing IAction::Move to manager" << std::endl;
|
||||
IMoveAction *a = new IMoveAction();
|
||||
a->count = MYMIN(shift_move_amount,
|
||||
(u32) (stack_from.count - leftover.count));
|
||||
|
@ -3637,7 +3637,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
} else if (drop_amount > 0) {
|
||||
m_selected_content_guess = ItemStack(); // Clear
|
||||
|
||||
// Send IACTION_DROP
|
||||
// Send IAction::Drop
|
||||
|
||||
assert(m_selected_item && m_selected_item->isValid());
|
||||
assert(inv_selected);
|
||||
|
@ -3650,7 +3650,7 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
assert(drop_amount > 0 && drop_amount <= m_selected_amount);
|
||||
m_selected_amount -= drop_amount;
|
||||
|
||||
infostream << "Handing IACTION_DROP to manager" << std::endl;
|
||||
infostream << "Handing IAction::Drop to manager" << std::endl;
|
||||
IDropAction *a = new IDropAction();
|
||||
a->count = drop_amount;
|
||||
a->from_inv = m_selected_item->inventoryloc;
|
||||
|
@ -3660,12 +3660,12 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
|
|||
} else if (craft_amount > 0) {
|
||||
m_selected_content_guess = ItemStack(); // Clear
|
||||
|
||||
// Send IACTION_CRAFT
|
||||
// Send IAction::Craft
|
||||
|
||||
assert(s.isValid());
|
||||
assert(inv_s);
|
||||
|
||||
infostream << "Handing IACTION_CRAFT to manager" << std::endl;
|
||||
infostream << "Handing IAction::Craft to manager" << std::endl;
|
||||
ICraftAction *a = new ICraftAction();
|
||||
a->count = craft_amount;
|
||||
a->craft_inv = s.inventoryloc;
|
||||
|
|
|
@ -439,6 +439,7 @@ private:
|
|||
std::string m_focused_element = "";
|
||||
JoystickController *m_joystick;
|
||||
|
||||
|
||||
typedef struct {
|
||||
bool explicit_size;
|
||||
v2f invsize;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <IGUIButton.h>
|
||||
#include <IGUIStaticText.h>
|
||||
#include <IGUIFont.h>
|
||||
#include <IGUIComboBox.h>
|
||||
#include "settings.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -69,8 +70,36 @@ enum
|
|||
// other
|
||||
GUI_ID_CB_AUX1_DESCENDS,
|
||||
GUI_ID_CB_DOUBLETAP_JUMP,
|
||||
// key alias GUI
|
||||
GUI_ID_KEY_ALIAS_BUTTON, // opens the GUI for commands
|
||||
GUI_ID_KEY_ALIAS_COMBOBOX, // List box showing the list of commands
|
||||
GUI_ID_KEY_ALIAS_ADD, // Button to add new command
|
||||
GUI_ID_KEY_ALIAS_REMOVE, // Button to remove command
|
||||
GUI_ID_KEY_ALIAS_NAME_ENTRY, // Entry for the name of the command
|
||||
GUI_ID_KEY_ALIAS_COMMAND_ENTRY, // Entry for the chat command
|
||||
GUI_ID_KEY_ALIAS_KEY_BUTTON // Button used to set the keyboard shortcut
|
||||
};
|
||||
|
||||
static void set_text(gui::IGUIElement *el, const std::string &textval)
|
||||
{
|
||||
const wchar_t* text = wgettext(textval.c_str());
|
||||
el->setText(text);
|
||||
delete[] text;
|
||||
}
|
||||
|
||||
static void set_key_text(gui::IGUIElement *el, const KeyCommand &kc)
|
||||
{
|
||||
if (std::string(kc.key.name()) != "")
|
||||
{
|
||||
std::string keytext = std::string(kc.modifier_control?"[Ctrl]-":"")
|
||||
+ std::string(kc.modifier_shift?"[Shft]-":"")
|
||||
+ kc.key.name();
|
||||
set_text(el,keytext);
|
||||
}
|
||||
else
|
||||
set_text(el,"Not set");
|
||||
}
|
||||
|
||||
GUIKeyChangeMenu::GUIKeyChangeMenu(gui::IGUIEnvironment* env,
|
||||
gui::IGUIElement* parent, s32 id, IMenuManager *menumgr) :
|
||||
GUIModalMenu(env, parent, id, menumgr)
|
||||
|
@ -137,7 +166,7 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
|||
|
||||
v2s32 offset(25, 60);
|
||||
|
||||
for(size_t i = 0; i < key_settings.size(); i++)
|
||||
for (size_t i = 0; i < key_settings.size(); i++)
|
||||
{
|
||||
key_setting *k = key_settings.at(i);
|
||||
{
|
||||
|
@ -188,8 +217,117 @@ void GUIKeyChangeMenu::regenerateGui(v2u32 screensize)
|
|||
GUI_ID_CB_DOUBLETAP_JUMP, text);
|
||||
delete[] text;
|
||||
}
|
||||
offset += v2s32(0, 35);
|
||||
}
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 200;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("Chat Commands");
|
||||
Environment->addStaticText(text, rect, false, true, this,-1);
|
||||
delete[] text;
|
||||
}
|
||||
offset += v2s32(0, 25);
|
||||
}
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 200;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
m_command_combo = Environment->addComboBox(rect, this, GUI_ID_KEY_ALIAS_COMBOBOX);
|
||||
for (std::vector<KeyCommand>::iterator it = key_alias_settings.begin();
|
||||
it != key_alias_settings.end(); ++it)
|
||||
{
|
||||
const wchar_t* text = wgettext(it->setting_name.c_str());
|
||||
m_command_combo->addItem(text,it - key_alias_settings.begin());
|
||||
delete[] text;
|
||||
}
|
||||
}
|
||||
option_x += 210;
|
||||
option_w = 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("Add");
|
||||
m_command_add = Environment->addButton(rect, this, GUI_ID_KEY_ALIAS_ADD, text );
|
||||
delete[] text;
|
||||
}
|
||||
option_x += 50;
|
||||
option_w = 50;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("Delete");
|
||||
m_command_remove = Environment->addButton(rect, this, GUI_ID_KEY_ALIAS_REMOVE, text);
|
||||
delete[] text;
|
||||
}
|
||||
}
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 200;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("Command Name");
|
||||
m_command_name = Environment->addEditBox(text, rect, false, this,
|
||||
GUI_ID_KEY_ALIAS_NAME_ENTRY);
|
||||
m_command_name->setVisible(false);
|
||||
delete[] text;
|
||||
}
|
||||
offset += v2s32(0, 35);
|
||||
}
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 100;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y + 5);
|
||||
const wchar_t* text = wgettext("Command");
|
||||
m_command_label = Environment->addStaticText(text, rect, false, true, this,-1);
|
||||
delete[] text;
|
||||
}
|
||||
option_x += 110;
|
||||
option_w = 200;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("");
|
||||
m_command = Environment->addEditBox(text, rect, false, this,
|
||||
GUI_ID_KEY_ALIAS_COMMAND_ENTRY);
|
||||
delete[] text;
|
||||
}
|
||||
offset += v2s32(0, 35);
|
||||
}
|
||||
{
|
||||
s32 option_x = offset.X;
|
||||
s32 option_y = offset.Y;
|
||||
u32 option_w = 100;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y + 5);
|
||||
const wchar_t* text = wgettext("Key combo");
|
||||
m_command_key_label = Environment->addStaticText(text, rect, false, true, this,-1);
|
||||
delete[] text;
|
||||
}
|
||||
option_x += 110;
|
||||
option_w = 200;
|
||||
{
|
||||
core::rect<s32> rect(0, 0, option_w, 30);
|
||||
rect += topleft + v2s32(option_x, option_y);
|
||||
const wchar_t* text = wgettext("Key");
|
||||
m_command_key = Environment->addButton(rect, this,
|
||||
GUI_ID_KEY_ALIAS_KEY_BUTTON, text);
|
||||
delete[] text;
|
||||
}
|
||||
}
|
||||
commandComboChanged();
|
||||
|
||||
{
|
||||
core::rect < s32 > rect(0, 0, 100, 30);
|
||||
|
@ -229,23 +367,40 @@ void GUIKeyChangeMenu::drawMenu()
|
|||
|
||||
bool GUIKeyChangeMenu::acceptInput()
|
||||
{
|
||||
for(size_t i = 0; i < key_settings.size(); i++)
|
||||
for (size_t i = 0; i < key_settings.size(); i++)
|
||||
{
|
||||
key_setting *k = key_settings.at(i);
|
||||
g_settings->set(k->setting_name, k->key.sym());
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(GUI_ID_CB_AUX1_DESCENDS);
|
||||
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
|
||||
if (e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
|
||||
g_settings->setBool("aux1_descends", ((gui::IGUICheckBox*)e)->isChecked());
|
||||
}
|
||||
{
|
||||
gui::IGUIElement *e = getElementFromId(GUI_ID_CB_DOUBLETAP_JUMP);
|
||||
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
|
||||
if (e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
|
||||
g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked());
|
||||
}
|
||||
|
||||
commandComboChanged();
|
||||
for (std::vector<KeyCommand>::iterator it = key_alias_settings.begin(); it!=key_alias_settings.end(); ++it)
|
||||
{
|
||||
std::string aname = it->setting_name;
|
||||
g_settings->set("keymap_alias_" + aname, it->key.sym());
|
||||
g_settings->set("keymap_command_" + aname, it->command);
|
||||
std::string modifiers;
|
||||
if (it->modifier_control && it->modifier_shift)
|
||||
modifiers = "KEY_CONTROL, KEY_SHIFT";
|
||||
else if (it->modifier_control)
|
||||
modifiers = "KEY_CONTROL";
|
||||
else if (it->modifier_shift)
|
||||
modifiers = "KEY_SHIFT";
|
||||
g_settings->set("keymap_modifiers_" + aname, modifiers);
|
||||
}
|
||||
|
||||
clearKeyCache();
|
||||
clearCommandKeyCache();
|
||||
|
||||
g_gamecallback->signalKeyConfigChange();
|
||||
|
||||
|
@ -256,17 +411,25 @@ bool GUIKeyChangeMenu::resetMenu()
|
|||
{
|
||||
if (activeKey >= 0)
|
||||
{
|
||||
for(size_t i = 0; i < key_settings.size(); i++)
|
||||
if (activeKey != GUI_ID_KEY_ALIAS_BUTTON)
|
||||
{
|
||||
key_setting *k = key_settings.at(i);
|
||||
if(k->id == activeKey)
|
||||
for (size_t i = 0; i < key_settings.size(); i++)
|
||||
{
|
||||
const wchar_t *text = wgettext(k->key.name());
|
||||
k->button->setText(text);
|
||||
delete[] text;
|
||||
break;
|
||||
key_setting *k = key_settings.at(i);
|
||||
if (k->id == activeKey)
|
||||
{
|
||||
const wchar_t* text = wgettext(k->key.name());
|
||||
k->button->setText(text);
|
||||
delete[] text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyCommand &kc = key_alias_settings[m_command_active_id];
|
||||
set_key_text(m_command_key,kc);
|
||||
}
|
||||
activeKey = -1;
|
||||
return false;
|
||||
}
|
||||
|
@ -274,43 +437,51 @@ bool GUIKeyChangeMenu::resetMenu()
|
|||
}
|
||||
bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
||||
{
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0
|
||||
&& event.KeyInput.PressedDown) {
|
||||
|
||||
bool prefer_character = shift_down;
|
||||
if (event.EventType == EET_KEY_INPUT_EVENT && activeKey >= 0 && event.KeyInput.PressedDown)
|
||||
{
|
||||
bool prefer_character = shift_down && (activeKey != GUI_ID_KEY_ALIAS_BUTTON);
|
||||
KeyPress kp(event.KeyInput, prefer_character);
|
||||
|
||||
bool shift_went_down = false;
|
||||
if(!shift_down &&
|
||||
if (!shift_down &&
|
||||
(event.KeyInput.Key == irr::KEY_SHIFT ||
|
||||
event.KeyInput.Key == irr::KEY_LSHIFT ||
|
||||
event.KeyInput.Key == irr::KEY_RSHIFT))
|
||||
shift_went_down = true;
|
||||
|
||||
bool control_went_down = false;
|
||||
if (!control_down &&
|
||||
(event.KeyInput.Key == irr::KEY_CONTROL ||
|
||||
event.KeyInput.Key == irr::KEY_LCONTROL ||
|
||||
event.KeyInput.Key == irr::KEY_RCONTROL))
|
||||
control_went_down = true;
|
||||
|
||||
// Remove Key already in use message
|
||||
if(this->key_used_text)
|
||||
if (this->key_used_text)
|
||||
{
|
||||
this->key_used_text->remove();
|
||||
this->key_used_text = NULL;
|
||||
}
|
||||
// Display Key already in use message
|
||||
if (std::find(this->key_used.begin(), this->key_used.end(), kp) != this->key_used.end())
|
||||
std::wstring ku = keyUsedBy(activeKey, kp, shift_down, control_down);
|
||||
if (ku != L"")
|
||||
{
|
||||
core::rect < s32 > rect(0, 0, 600, 40);
|
||||
rect += v2s32(0, 0) + v2s32(25, 30);
|
||||
const wchar_t *text = wgettext("Key already in use");
|
||||
this->key_used_text = Environment->addStaticText(text,
|
||||
std::wstring text = std::wstring(L"Key already in use by ")+ku;
|
||||
this->key_used_text = Environment->addStaticText(text.c_str(),
|
||||
rect, false, true, this, -1);
|
||||
delete[] text;
|
||||
//infostream << "Key already in use" << std::endl;
|
||||
}
|
||||
|
||||
// But go on
|
||||
if (activeKey != GUI_ID_KEY_ALIAS_BUTTON)
|
||||
{
|
||||
key_setting *k = NULL;
|
||||
for(size_t i = 0; i < key_settings.size(); i++)
|
||||
key_setting *k=NULL;
|
||||
for (size_t i = 0; i < key_settings.size(); i++)
|
||||
{
|
||||
if(key_settings.at(i)->id == activeKey)
|
||||
if (key_settings.at(i)->id == activeKey)
|
||||
{
|
||||
k = key_settings.at(i);
|
||||
break;
|
||||
|
@ -322,23 +493,29 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
|||
k->button->setText(text);
|
||||
delete[] text;
|
||||
|
||||
this->key_used.push_back(kp);
|
||||
|
||||
// Allow characters made with shift
|
||||
if(shift_went_down){
|
||||
shift_down = true;
|
||||
return false;
|
||||
}else{
|
||||
activeKey = -1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (event.EventType == EET_KEY_INPUT_EVENT && activeKey < 0
|
||||
&& event.KeyInput.PressedDown
|
||||
&& event.KeyInput.Key == irr::KEY_ESCAPE) {
|
||||
quitMenu();
|
||||
return true;
|
||||
} else if (event.EventType == EET_GUI_EVENT) {
|
||||
else
|
||||
{
|
||||
KeyCommand &kc = key_alias_settings[m_command_active_id];
|
||||
kc.key = kp;
|
||||
kc.modifier_shift = shift_down;
|
||||
kc.modifier_control = control_down;
|
||||
set_key_text(m_command_key,kc);
|
||||
}
|
||||
|
||||
if (!shift_went_down && !control_went_down)
|
||||
{
|
||||
activeKey = -1;
|
||||
return true;
|
||||
}
|
||||
if (shift_went_down)
|
||||
shift_down = true;
|
||||
if (control_went_down)
|
||||
control_down = true;
|
||||
return false;
|
||||
}
|
||||
if (event.EventType == EET_GUI_EVENT)
|
||||
{
|
||||
if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
|
||||
&& isVisible())
|
||||
{
|
||||
|
@ -350,6 +527,11 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
if (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED)
|
||||
{
|
||||
commandComboChanged();
|
||||
return true;
|
||||
}
|
||||
if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED)
|
||||
{
|
||||
switch (event.GUIEvent.Caller->getID())
|
||||
|
@ -361,11 +543,97 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
|||
case GUI_ID_ABORT_BUTTON: //abort
|
||||
quitMenu();
|
||||
return true;
|
||||
case GUI_ID_KEY_ALIAS_ADD:
|
||||
if (!m_command_adding)
|
||||
{
|
||||
m_command_adding = true;
|
||||
m_command_name->setVisible(true);
|
||||
m_command_combo->setVisible(false);
|
||||
m_command_label->setVisible(false);
|
||||
m_command->setVisible(false);
|
||||
m_command_key_label->setVisible(false);
|
||||
m_command_key->setVisible(false);
|
||||
set_text(m_command_name,"Command Name");
|
||||
set_text(m_command_add,"Add");
|
||||
set_text(m_command_remove,"Cancel");
|
||||
Environment->setFocus(m_command_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyCommand kc;
|
||||
kc.setting_name = wide_to_narrow(m_command_name->getText());
|
||||
std::replace(kc.setting_name.begin(), kc.setting_name.end(), ' ', '_');
|
||||
bool exists = false;
|
||||
for (std::vector<KeyCommand>::iterator it = key_alias_settings.begin();
|
||||
it != key_alias_settings.end(); ++it)
|
||||
if (it->setting_name == kc.setting_name)
|
||||
{
|
||||
exists = true;
|
||||
m_command_combo->setSelected(it - key_alias_settings.begin());
|
||||
break;
|
||||
}
|
||||
if (!exists)
|
||||
{
|
||||
kc.modifier_control = false;
|
||||
kc.modifier_shift = false;
|
||||
kc.command = "";
|
||||
addCommandAliasKey(kc);
|
||||
const wchar_t* text = wgettext(kc.setting_name.c_str());
|
||||
m_command_combo->addItem(text,key_alias_settings.size()-1);
|
||||
delete[] text;
|
||||
m_command_combo->setSelected(key_alias_settings.size()-1);
|
||||
}
|
||||
commandComboChanged();
|
||||
|
||||
m_command_adding = false;
|
||||
m_command_name->setVisible(false);
|
||||
m_command_combo->setVisible(true);
|
||||
m_command->setVisible(true);
|
||||
m_command_label->setVisible(true);
|
||||
m_command_key->setVisible(true);
|
||||
m_command_key_label->setVisible(true);
|
||||
set_text(m_command_name,"Command Name");
|
||||
set_text(m_command_add,"Add");
|
||||
set_text(m_command_remove,"Delete");
|
||||
}
|
||||
return true;
|
||||
case GUI_ID_KEY_ALIAS_REMOVE:
|
||||
if (!m_command_adding)
|
||||
{
|
||||
s32 sel = m_command_combo->getSelected();
|
||||
m_command_combo->removeItem(sel);
|
||||
key_alias_settings.erase(key_alias_settings.begin()+sel);
|
||||
m_command_combo->setSelected(key_alias_settings.size()-1);
|
||||
m_command_active_id = -1;
|
||||
commandComboChanged();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_command_adding = false;
|
||||
m_command_name->setVisible(false);
|
||||
m_command_combo->setVisible(true);
|
||||
m_command->setVisible(true);
|
||||
m_command_label->setVisible(true);
|
||||
m_command_key->setVisible(true);
|
||||
m_command_key_label->setVisible(true);
|
||||
set_text(m_command_name,"Command Name");
|
||||
set_text(m_command_add,"Add");
|
||||
set_text(m_command_remove,"Delete");
|
||||
}
|
||||
case GUI_ID_KEY_ALIAS_KEY_BUTTON:
|
||||
// Key Alias
|
||||
resetMenu();
|
||||
shift_down = false;
|
||||
control_down = false;
|
||||
activeKey = GUI_ID_KEY_ALIAS_BUTTON;
|
||||
set_text(m_command_key, "press key");
|
||||
return true;
|
||||
default:
|
||||
key_setting *k = NULL;
|
||||
for(size_t i = 0; i < key_settings.size(); i++)
|
||||
for (size_t i = 0; i < key_settings.size(); i++)
|
||||
{
|
||||
if(key_settings.at(i)->id == event.GUIEvent.Caller->getID())
|
||||
if (key_settings.at(i)->id == event.GUIEvent.Caller->getID())
|
||||
{
|
||||
k = key_settings.at(i);
|
||||
break;
|
||||
|
@ -375,12 +643,9 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
|||
|
||||
resetMenu();
|
||||
shift_down = false;
|
||||
control_down = false;
|
||||
activeKey = event.GUIEvent.Caller->getID();
|
||||
const wchar_t *text = wgettext("press key");
|
||||
k->button->setText(text);
|
||||
delete[] text;
|
||||
this->key_used.erase(std::remove(this->key_used.begin(),
|
||||
this->key_used.end(), k->key), this->key_used.end());
|
||||
set_text(k->button,"press key");
|
||||
break;
|
||||
}
|
||||
Environment->setFocus(this);
|
||||
|
@ -389,6 +654,61 @@ bool GUIKeyChangeMenu::OnEvent(const SEvent& event)
|
|||
return Parent ? Parent->OnEvent(event) : false;
|
||||
}
|
||||
|
||||
void GUIKeyChangeMenu::commandComboChanged()
|
||||
{
|
||||
s32 active_id = m_command_combo->getSelected();
|
||||
if (activeKey == GUI_ID_KEY_ALIAS_BUTTON)
|
||||
resetMenu();
|
||||
if (m_command_active_id>=0)
|
||||
{
|
||||
KeyCommand &k = key_alias_settings[m_command_active_id];
|
||||
k.command = wide_to_narrow(m_command->getText());
|
||||
}
|
||||
if (active_id>=0)
|
||||
{
|
||||
KeyCommand k = key_alias_settings[active_id];
|
||||
set_text(m_command_name,k.setting_name);
|
||||
set_text(m_command,k.command);
|
||||
set_key_text(m_command_key,k);
|
||||
m_command->setEnabled(true);
|
||||
m_command_key->setEnabled(true);
|
||||
m_command_remove->setEnabled(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_command->setEnabled(false);
|
||||
m_command_key->setEnabled(false);
|
||||
m_command_remove->setEnabled(false);
|
||||
}
|
||||
m_command_active_id = active_id;
|
||||
}
|
||||
|
||||
std::wstring GUIKeyChangeMenu::keyUsedBy(int id, const KeyPress &key, bool modifier_shift, bool modifier_control)
|
||||
{
|
||||
for (std::vector<key_setting *>::iterator it = key_settings.begin(); it != key_settings.end(); ++it)
|
||||
{
|
||||
if ((*it)->id == id)
|
||||
continue;
|
||||
if ((*it)->key == key)
|
||||
return std::wstring((*it)->button_name);
|
||||
}
|
||||
for (std::vector<KeyCommand>::iterator it = key_alias_settings.begin(); it != key_alias_settings.end(); ++it)
|
||||
{
|
||||
if (id == GUI_ID_KEY_ALIAS_BUTTON && m_command_active_id == it - key_alias_settings.begin())
|
||||
continue;
|
||||
if (it->key == key)
|
||||
{
|
||||
if (id != GUI_ID_KEY_ALIAS_BUTTON)
|
||||
return std::wstring(L"chat command \"" + narrow_to_wide(it->setting_name) + L"\"");
|
||||
else
|
||||
if (it->modifier_shift == modifier_shift
|
||||
&& it->modifier_control == modifier_control)
|
||||
return std::wstring(L"chat command \"" + narrow_to_wide(it->setting_name) + L"\"");
|
||||
}
|
||||
}
|
||||
return L"";
|
||||
}
|
||||
|
||||
void GUIKeyChangeMenu::add_key(int id, const wchar_t *button_name, const std::string &setting_name)
|
||||
{
|
||||
key_setting *k = new key_setting;
|
||||
|
@ -400,6 +720,11 @@ void GUIKeyChangeMenu::add_key(int id, const wchar_t *button_name, const std::st
|
|||
key_settings.push_back(k);
|
||||
}
|
||||
|
||||
void GUIKeyChangeMenu::addCommandAliasKey(const KeyCommand &key)
|
||||
{
|
||||
key_alias_settings.push_back(key);
|
||||
}
|
||||
|
||||
void GUIKeyChangeMenu::init_keys()
|
||||
{
|
||||
this->add_key(GUI_ID_KEY_FORWARD_BUTTON, wgettext("Forward"), "keymap_forward");
|
||||
|
@ -427,5 +752,8 @@ void GUIKeyChangeMenu::init_keys()
|
|||
this->add_key(GUI_ID_KEY_RANGE_BUTTON, wgettext("Range select"), "keymap_rangeselect");
|
||||
this->add_key(GUI_ID_KEY_DUMP_BUTTON, wgettext("Print stacks"), "keymap_print_debug_stacks");
|
||||
this->add_key(GUI_ID_KEY_ZOOM_BUTTON, wgettext("Zoom"), "keymap_zoom");
|
||||
|
||||
for (size_t i = 0; i<getCommandKeySettingCount(); ++i)
|
||||
addCommandAliasKey(getCommandKeySetting(i));
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "keycode.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
struct key_setting
|
||||
{
|
||||
|
@ -39,7 +40,16 @@ struct key_setting
|
|||
gui::IGUIButton *button;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
KeyCommand key;
|
||||
std::string setting_name;
|
||||
std::string command_alias;
|
||||
} key_alias_setting;
|
||||
|
||||
|
||||
class GUIKeyChangeMenu : public GUIModalMenu
|
||||
|
||||
{
|
||||
public:
|
||||
GUIKeyChangeMenu(gui::IGUIEnvironment *env, gui::IGUIElement *parent, s32 id,
|
||||
|
@ -65,12 +75,30 @@ private:
|
|||
|
||||
void add_key(int id, const wchar_t *button_name, const std::string &setting_name);
|
||||
|
||||
|
||||
std::wstring keyUsedBy(int id, const KeyPress &key, bool modifier_shift, bool modifier_control);
|
||||
void addCommandAliasKey(const KeyCommand &key);
|
||||
void commandComboChanged();
|
||||
|
||||
bool control_down;
|
||||
bool shift_down = false;
|
||||
s32 activeKey = -1;
|
||||
|
||||
std::vector<KeyPress> key_used;
|
||||
gui::IGUIStaticText *key_used_text = nullptr;
|
||||
std::vector<key_setting *> key_settings;
|
||||
std::vector<KeyCommand> key_alias_settings;
|
||||
|
||||
s32 m_command_active_id;
|
||||
gui::IGUIEditBox *m_command_name;
|
||||
gui::IGUIStaticText *m_command_label;
|
||||
gui::IGUIEditBox *m_command;
|
||||
gui::IGUIStaticText *m_command_key_label;
|
||||
gui::IGUIButton *m_command_key;
|
||||
gui::IGUIButton *m_command_add;
|
||||
gui::IGUIButton *m_command_remove;
|
||||
gui::IGUIComboBox *m_command_combo;
|
||||
bool m_command_adding;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,9 @@ struct ItemStack
|
|||
void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
|
||||
void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
|
||||
|
||||
// Parse metadata to retrieve a custom description
|
||||
std::string getMetadataDescription();
|
||||
|
||||
// Returns the string used for inventory
|
||||
std::string getItemString() const;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ std::string InventoryLocation::dump() const
|
|||
|
||||
void InventoryLocation::serialize(std::ostream &os) const
|
||||
{
|
||||
switch(type){
|
||||
switch (type) {
|
||||
case InventoryLocation::UNDEFINED:
|
||||
os<<"undefined";
|
||||
break;
|
||||
|
@ -68,21 +68,14 @@ void InventoryLocation::deSerialize(std::istream &is)
|
|||
{
|
||||
std::string tname;
|
||||
std::getline(is, tname, ':');
|
||||
if(tname == "undefined")
|
||||
{
|
||||
if (tname == "undefined") {
|
||||
type = InventoryLocation::UNDEFINED;
|
||||
}
|
||||
else if(tname == "current_player")
|
||||
{
|
||||
} else if (tname == "current_player") {
|
||||
type = InventoryLocation::CURRENT_PLAYER;
|
||||
}
|
||||
else if(tname == "player")
|
||||
{
|
||||
} else if (tname == "player") {
|
||||
type = InventoryLocation::PLAYER;
|
||||
std::getline(is, name, '\n');
|
||||
}
|
||||
else if(tname == "nodemeta")
|
||||
{
|
||||
} else if (tname == "nodemeta") {
|
||||
type = InventoryLocation::NODEMETA;
|
||||
std::string pos;
|
||||
std::getline(is, pos, '\n');
|
||||
|
@ -90,14 +83,10 @@ void InventoryLocation::deSerialize(std::istream &is)
|
|||
p.X = stoi(fn.next(","));
|
||||
p.Y = stoi(fn.next(","));
|
||||
p.Z = stoi(fn.next(","));
|
||||
}
|
||||
else if(tname == "detached")
|
||||
{
|
||||
} else if (tname == "detached") {
|
||||
type = InventoryLocation::DETACHED;
|
||||
std::getline(is, name, '\n');
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
infostream<<"Unknown InventoryLocation type=\""<<tname<<"\""<<std::endl;
|
||||
throw SerializationError("Unknown InventoryLocation type");
|
||||
}
|
||||
|
@ -113,12 +102,12 @@ void InventoryLocation::deSerialize(std::string s)
|
|||
InventoryAction
|
||||
*/
|
||||
|
||||
InventoryAction * InventoryAction::deSerialize(std::istream &is)
|
||||
InventoryAction *InventoryAction::deSerialize(std::istream &is)
|
||||
{
|
||||
std::string type;
|
||||
std::getline(is, type, ' ');
|
||||
|
||||
InventoryAction *a = NULL;
|
||||
InventoryAction *a = nullptr;
|
||||
|
||||
if (type == "Move") {
|
||||
a = new IMoveAction(is, false);
|
||||
|
@ -126,7 +115,7 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
|
|||
a = new IMoveAction(is, true);
|
||||
} else if (type == "Drop") {
|
||||
a = new IDropAction(is);
|
||||
} else if(type == "Craft") {
|
||||
} else if (type == "Craft") {
|
||||
a = new ICraftAction(is);
|
||||
}
|
||||
|
||||
|
@ -137,12 +126,10 @@ InventoryAction * InventoryAction::deSerialize(std::istream &is)
|
|||
IMoveAction
|
||||
*/
|
||||
|
||||
IMoveAction::IMoveAction(std::istream &is, bool somewhere)
|
||||
IMoveAction::IMoveAction(std::istream &is, bool somewhere) :
|
||||
move_somewhere(somewhere)
|
||||
{
|
||||
std::string ts;
|
||||
move_somewhere = somewhere;
|
||||
caused_by_move_somewhere = false;
|
||||
move_count = 0;
|
||||
|
||||
std::getline(is, ts, ' ');
|
||||
count = stoi(ts);
|
||||
|
@ -265,7 +252,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
*/
|
||||
|
||||
int try_take_count = count;
|
||||
if(try_take_count == 0)
|
||||
if (try_take_count == 0)
|
||||
try_take_count = list_from->getItem(from_i).count;
|
||||
|
||||
int src_can_take_count = 0xffff;
|
||||
|
@ -274,28 +261,23 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
/* Query detached inventories */
|
||||
|
||||
// Move occurs in the same detached inventory
|
||||
if(from_inv.type == InventoryLocation::DETACHED &&
|
||||
if (from_inv.type == InventoryLocation::DETACHED &&
|
||||
to_inv.type == InventoryLocation::DETACHED &&
|
||||
from_inv.name == to_inv.name)
|
||||
{
|
||||
from_inv.name == to_inv.name) {
|
||||
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowMove(
|
||||
from_inv.name, from_list, from_i,
|
||||
to_list, to_i, try_take_count, player);
|
||||
dst_can_put_count = src_can_take_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Destination is detached
|
||||
if(to_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (to_inv.type == InventoryLocation::DETACHED) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = try_take_count;
|
||||
dst_can_put_count = PLAYER_TO_SA(player)->detached_inventory_AllowPut(
|
||||
to_inv.name, to_list, to_i, src_item, player);
|
||||
}
|
||||
// Source is detached
|
||||
if(from_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::DETACHED) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = try_take_count;
|
||||
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake(
|
||||
|
@ -307,28 +289,23 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
|
||||
// Both endpoints are nodemeta
|
||||
// Move occurs in the same nodemeta inventory
|
||||
if(from_inv.type == InventoryLocation::NODEMETA &&
|
||||
if (from_inv.type == InventoryLocation::NODEMETA &&
|
||||
to_inv.type == InventoryLocation::NODEMETA &&
|
||||
from_inv.p == to_inv.p)
|
||||
{
|
||||
from_inv.p == to_inv.p) {
|
||||
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowMove(
|
||||
from_inv.p, from_list, from_i,
|
||||
to_list, to_i, try_take_count, player);
|
||||
dst_can_put_count = src_can_take_count;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Destination is nodemeta
|
||||
if(to_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
if (to_inv.type == InventoryLocation::NODEMETA) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = try_take_count;
|
||||
dst_can_put_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowPut(
|
||||
to_inv.p, to_list, to_i, src_item, player);
|
||||
}
|
||||
// Source is nodemeta
|
||||
if(from_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::NODEMETA) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = try_take_count;
|
||||
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake(
|
||||
|
@ -340,17 +317,16 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
|
||||
/* Modify count according to collected data */
|
||||
count = try_take_count;
|
||||
if(src_can_take_count != -1 && count > src_can_take_count)
|
||||
if (src_can_take_count != -1 && count > src_can_take_count)
|
||||
count = src_can_take_count;
|
||||
if(dst_can_put_count != -1 && count > dst_can_put_count)
|
||||
if (dst_can_put_count != -1 && count > dst_can_put_count)
|
||||
count = dst_can_put_count;
|
||||
/* Limit according to source item count */
|
||||
if(count > list_from->getItem(from_i).count)
|
||||
if (count > list_from->getItem(from_i).count)
|
||||
count = list_from->getItem(from_i).count;
|
||||
|
||||
/* If no items will be moved, don't go further */
|
||||
if(count == 0)
|
||||
{
|
||||
if (count == 0) {
|
||||
infostream<<"IMoveAction::apply(): move was completely disallowed:"
|
||||
<<" count="<<old_count
|
||||
<<" from inv=\""<<from_inv.dump()<<"\""
|
||||
|
@ -403,7 +379,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
}
|
||||
}
|
||||
// If destination is infinite, reset it's stack and take count from source
|
||||
if(dst_can_put_count == -1){
|
||||
if (dst_can_put_count == -1) {
|
||||
list_to->deleteItem(to_i);
|
||||
list_to->addItem(to_i, to_stack_was);
|
||||
list_from->deleteItem(from_i);
|
||||
|
@ -426,19 +402,17 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
// If we are inside the move somewhere loop, we don't need to report
|
||||
// anything if nothing happened (perhaps we don't need to report
|
||||
// anything for caused_by_move_somewhere == true, but this way its safer)
|
||||
if (caused_by_move_somewhere && move_count == 0) {
|
||||
if (caused_by_move_somewhere && move_count == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
Record rollback information
|
||||
*/
|
||||
if(!ignore_rollback && gamedef->rollback())
|
||||
{
|
||||
if (!ignore_rollback && gamedef->rollback()) {
|
||||
IRollbackManager *rollback = gamedef->rollback();
|
||||
|
||||
// If source is not infinite, record item take
|
||||
if(src_can_take_count != -1){
|
||||
if (src_can_take_count != -1) {
|
||||
RollbackAction action;
|
||||
std::string loc;
|
||||
{
|
||||
|
@ -451,7 +425,7 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
rollback->reportAction(action);
|
||||
}
|
||||
// If destination is not infinite, record item put
|
||||
if(dst_can_put_count != -1){
|
||||
if (dst_can_put_count != -1) {
|
||||
RollbackAction action;
|
||||
std::string loc;
|
||||
{
|
||||
|
@ -472,25 +446,20 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
/* Detached inventories */
|
||||
|
||||
// Both endpoints are same detached
|
||||
if(from_inv.type == InventoryLocation::DETACHED &&
|
||||
if (from_inv.type == InventoryLocation::DETACHED &&
|
||||
to_inv.type == InventoryLocation::DETACHED &&
|
||||
from_inv.name == to_inv.name)
|
||||
{
|
||||
from_inv.name == to_inv.name) {
|
||||
PLAYER_TO_SA(player)->detached_inventory_OnMove(
|
||||
from_inv.name, from_list, from_i,
|
||||
to_list, to_i, count, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Destination is detached
|
||||
if(to_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (to_inv.type == InventoryLocation::DETACHED) {
|
||||
PLAYER_TO_SA(player)->detached_inventory_OnPut(
|
||||
to_inv.name, to_list, to_i, src_item, player);
|
||||
}
|
||||
// Source is detached
|
||||
if(from_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::DETACHED) {
|
||||
PLAYER_TO_SA(player)->detached_inventory_OnTake(
|
||||
from_inv.name, from_list, from_i, src_item, player);
|
||||
}
|
||||
|
@ -499,31 +468,27 @@ void IMoveAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
/* Node metadata inventories */
|
||||
|
||||
// Both endpoints are same nodemeta
|
||||
if(from_inv.type == InventoryLocation::NODEMETA &&
|
||||
if (from_inv.type == InventoryLocation::NODEMETA &&
|
||||
to_inv.type == InventoryLocation::NODEMETA &&
|
||||
from_inv.p == to_inv.p)
|
||||
{
|
||||
from_inv.p == to_inv.p) {
|
||||
PLAYER_TO_SA(player)->nodemeta_inventory_OnMove(
|
||||
from_inv.p, from_list, from_i,
|
||||
to_list, to_i, count, player);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
// Destination is nodemeta
|
||||
if(to_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
if (to_inv.type == InventoryLocation::NODEMETA) {
|
||||
PLAYER_TO_SA(player)->nodemeta_inventory_OnPut(
|
||||
to_inv.p, to_list, to_i, src_item, player);
|
||||
}
|
||||
// Source is nodemeta
|
||||
else if(from_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
else if (from_inv.type == InventoryLocation::NODEMETA) {
|
||||
PLAYER_TO_SA(player)->nodemeta_inventory_OnTake(
|
||||
from_inv.p, from_list, from_i, src_item, player);
|
||||
}
|
||||
}
|
||||
|
||||
mgr->setInventoryModified(from_inv, false);
|
||||
if(inv_from != inv_to)
|
||||
if (inv_from != inv_to)
|
||||
mgr->setInventoryModified(to_inv, false);
|
||||
}
|
||||
|
||||
|
@ -534,18 +499,18 @@ void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
|
|||
|
||||
Inventory *inv_from = mgr->getInventory(from_inv);
|
||||
Inventory *inv_to = mgr->getInventory(to_inv);
|
||||
if(!inv_from || !inv_to)
|
||||
if (!inv_from || !inv_to)
|
||||
return;
|
||||
|
||||
InventoryLocation current_player;
|
||||
current_player.setCurrentPlayer();
|
||||
Inventory *inv_player = mgr->getInventory(current_player);
|
||||
if(inv_from != inv_player || inv_to != inv_player)
|
||||
if (inv_from != inv_player || inv_to != inv_player)
|
||||
return;
|
||||
|
||||
InventoryList *list_from = inv_from->getList(from_list);
|
||||
InventoryList *list_to = inv_to->getList(to_list);
|
||||
if(!list_from || !list_to)
|
||||
if (!list_from || !list_to)
|
||||
return;
|
||||
|
||||
if (!move_somewhere)
|
||||
|
@ -554,7 +519,7 @@ void IMoveAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
|
|||
list_from->moveItemSomewhere(from_i, list_to, count);
|
||||
|
||||
mgr->setInventoryModified(from_inv);
|
||||
if(inv_from != inv_to)
|
||||
if (inv_from != inv_to)
|
||||
mgr->setInventoryModified(to_inv);
|
||||
}
|
||||
|
||||
|
@ -582,7 +547,7 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
{
|
||||
Inventory *inv_from = mgr->getInventory(from_inv);
|
||||
|
||||
if(!inv_from){
|
||||
if (!inv_from) {
|
||||
infostream<<"IDropAction::apply(): FAIL: source inventory not found: "
|
||||
<<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl;
|
||||
return;
|
||||
|
@ -593,13 +558,12 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
/*
|
||||
If a list doesn't exist or the source item doesn't exist
|
||||
*/
|
||||
if(!list_from){
|
||||
if (!list_from) {
|
||||
infostream<<"IDropAction::apply(): FAIL: source list not found: "
|
||||
<<"from_inv=\""<<from_inv.dump()<<"\""<<std::endl;
|
||||
return;
|
||||
}
|
||||
if(list_from->getItem(from_i).empty())
|
||||
{
|
||||
if (list_from->getItem(from_i).empty()) {
|
||||
infostream<<"IDropAction::apply(): FAIL: source item not found: "
|
||||
<<"from_inv=\""<<from_inv.dump()<<"\""
|
||||
<<", from_list=\""<<from_list<<"\""
|
||||
|
@ -617,13 +581,12 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
*/
|
||||
|
||||
int take_count = list_from->getItem(from_i).count;
|
||||
if(count != 0 && count < take_count)
|
||||
if (count != 0 && count < take_count)
|
||||
take_count = count;
|
||||
int src_can_take_count = take_count;
|
||||
|
||||
// Source is detached
|
||||
if(from_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::DETACHED) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = take_count;
|
||||
src_can_take_count = PLAYER_TO_SA(player)->detached_inventory_AllowTake(
|
||||
|
@ -631,15 +594,14 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
}
|
||||
|
||||
// Source is nodemeta
|
||||
if(from_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::NODEMETA) {
|
||||
ItemStack src_item = list_from->getItem(from_i);
|
||||
src_item.count = take_count;
|
||||
src_can_take_count = PLAYER_TO_SA(player)->nodemeta_inventory_AllowTake(
|
||||
from_inv.p, from_list, from_i, src_item, player);
|
||||
}
|
||||
|
||||
if(src_can_take_count != -1 && src_can_take_count < take_count)
|
||||
if (src_can_take_count != -1 && src_can_take_count < take_count)
|
||||
take_count = src_can_take_count;
|
||||
|
||||
int actually_dropped_count = 0;
|
||||
|
@ -649,22 +611,21 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
// Drop the item
|
||||
ItemStack item1 = list_from->getItem(from_i);
|
||||
item1.count = take_count;
|
||||
if(PLAYER_TO_SA(player)->item_OnDrop(item1, player,
|
||||
player->getBasePosition() + v3f(0,1,0)))
|
||||
{
|
||||
if (PLAYER_TO_SA(player)->item_OnDrop(item1, player,
|
||||
player->getBasePosition() + v3f(0,1,0))) {
|
||||
actually_dropped_count = take_count - item1.count;
|
||||
|
||||
if(actually_dropped_count == 0){
|
||||
if (actually_dropped_count == 0) {
|
||||
infostream<<"Actually dropped no items"<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// If source isn't infinite
|
||||
if(src_can_take_count != -1){
|
||||
if (src_can_take_count != -1) {
|
||||
// Take item from source list
|
||||
ItemStack item2 = list_from->takeItem(from_i, actually_dropped_count);
|
||||
|
||||
if(item2.count != actually_dropped_count)
|
||||
if (item2.count != actually_dropped_count)
|
||||
errorstream<<"Could not take dropped count of items"<<std::endl;
|
||||
|
||||
mgr->setInventoryModified(from_inv, false);
|
||||
|
@ -684,15 +645,13 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
*/
|
||||
|
||||
// Source is detached
|
||||
if(from_inv.type == InventoryLocation::DETACHED)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::DETACHED) {
|
||||
PLAYER_TO_SA(player)->detached_inventory_OnTake(
|
||||
from_inv.name, from_list, from_i, src_item, player);
|
||||
}
|
||||
|
||||
// Source is nodemeta
|
||||
if(from_inv.type == InventoryLocation::NODEMETA)
|
||||
{
|
||||
if (from_inv.type == InventoryLocation::NODEMETA) {
|
||||
PLAYER_TO_SA(player)->nodemeta_inventory_OnTake(
|
||||
from_inv.p, from_list, from_i, src_item, player);
|
||||
}
|
||||
|
@ -700,12 +659,11 @@ void IDropAction::apply(InventoryManager *mgr, ServerActiveObject *player, IGame
|
|||
/*
|
||||
Record rollback information
|
||||
*/
|
||||
if(!ignore_src_rollback && gamedef->rollback())
|
||||
{
|
||||
if (!ignore_src_rollback && gamedef->rollback()) {
|
||||
IRollbackManager *rollback = gamedef->rollback();
|
||||
|
||||
// If source is not infinite, record item take
|
||||
if(src_can_take_count != -1){
|
||||
if (src_can_take_count != -1) {
|
||||
RollbackAction action;
|
||||
std::string loc;
|
||||
{
|
||||
|
@ -726,20 +684,20 @@ void IDropAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
|
|||
// to make lag less apparent.
|
||||
|
||||
Inventory *inv_from = mgr->getInventory(from_inv);
|
||||
if(!inv_from)
|
||||
if (!inv_from)
|
||||
return;
|
||||
|
||||
InventoryLocation current_player;
|
||||
current_player.setCurrentPlayer();
|
||||
Inventory *inv_player = mgr->getInventory(current_player);
|
||||
if(inv_from != inv_player)
|
||||
if (inv_from != inv_player)
|
||||
return;
|
||||
|
||||
InventoryList *list_from = inv_from->getList(from_list);
|
||||
if(!list_from)
|
||||
if (!list_from)
|
||||
return;
|
||||
|
||||
if(count == 0)
|
||||
if (count == 0)
|
||||
list_from->changeItem(from_i, ItemStack());
|
||||
else
|
||||
list_from->takeItem(from_i, count);
|
||||
|
@ -881,7 +839,7 @@ void ICraftAction::clientApply(InventoryManager *mgr, IGameDef *gamedef)
|
|||
|
||||
|
||||
// Crafting helper
|
||||
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
||||
bool getCraftingResult(Inventory *inv, ItemStack &result,
|
||||
std::vector<ItemStack> &output_replacements,
|
||||
bool decrementInput, IGameDef *gamedef)
|
||||
{
|
||||
|
@ -891,28 +849,26 @@ bool getCraftingResult(Inventory *inv, ItemStack& result,
|
|||
|
||||
// Get the InventoryList in which we will operate
|
||||
InventoryList *clist = inv->getList("craft");
|
||||
if(!clist)
|
||||
if (!clist)
|
||||
return false;
|
||||
|
||||
// Mangle crafting grid to an another format
|
||||
CraftInput ci;
|
||||
ci.method = CRAFT_METHOD_NORMAL;
|
||||
ci.width = clist->getWidth() ? clist->getWidth() : 3;
|
||||
for(u16 i=0; i<clist->getSize(); i++)
|
||||
for (u16 i=0; i < clist->getSize(); i++)
|
||||
ci.items.push_back(clist->getItem(i));
|
||||
|
||||
// Find out what is crafted and add it to result item slot
|
||||
CraftOutput co;
|
||||
bool found = gamedef->getCraftDefManager()->getCraftResult(
|
||||
ci, co, output_replacements, decrementInput, gamedef);
|
||||
if(found)
|
||||
if (found)
|
||||
result.deSerialize(co.item, gamedef->getItemDefManager());
|
||||
|
||||
if(found && decrementInput)
|
||||
{
|
||||
if (found && decrementInput) {
|
||||
// CraftInput has been changed, apply changes in clist
|
||||
for(u16 i=0; i<clist->getSize(); i++)
|
||||
{
|
||||
for (u16 i=0; i < clist->getSize(); i++) {
|
||||
clist->changeItem(i, ci.items[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,15 +117,17 @@ public:
|
|||
virtual void inventoryAction(InventoryAction *a){}
|
||||
};
|
||||
|
||||
#define IACTION_MOVE 0
|
||||
#define IACTION_DROP 1
|
||||
#define IACTION_CRAFT 2
|
||||
enum class IAction : u16 {
|
||||
Move,
|
||||
Drop,
|
||||
Craft
|
||||
};
|
||||
|
||||
struct InventoryAction
|
||||
{
|
||||
static InventoryAction * deSerialize(std::istream &is);
|
||||
static InventoryAction *deSerialize(std::istream &is);
|
||||
|
||||
virtual u16 getType() const = 0;
|
||||
virtual IAction getType() const = 0;
|
||||
virtual void serialize(std::ostream &os) const = 0;
|
||||
virtual void apply(InventoryManager *mgr, ServerActiveObject *player,
|
||||
IGameDef *gamedef) = 0;
|
||||
|
@ -136,35 +138,27 @@ struct InventoryAction
|
|||
struct IMoveAction : public InventoryAction
|
||||
{
|
||||
// count=0 means "everything"
|
||||
u16 count;
|
||||
u16 count = 0;
|
||||
InventoryLocation from_inv;
|
||||
std::string from_list;
|
||||
s16 from_i;
|
||||
s16 from_i = -1;
|
||||
InventoryLocation to_inv;
|
||||
std::string to_list;
|
||||
s16 to_i;
|
||||
bool move_somewhere;
|
||||
s16 to_i = -1;
|
||||
bool move_somewhere = false;
|
||||
|
||||
// treat these as private
|
||||
// related to movement to somewhere
|
||||
bool caused_by_move_somewhere;
|
||||
u32 move_count;
|
||||
bool caused_by_move_somewhere = false;
|
||||
u32 move_count = 0;
|
||||
|
||||
IMoveAction()
|
||||
{
|
||||
count = 0;
|
||||
from_i = -1;
|
||||
to_i = -1;
|
||||
move_somewhere = false;
|
||||
caused_by_move_somewhere = false;
|
||||
move_count = 0;
|
||||
}
|
||||
IMoveAction() {}
|
||||
|
||||
IMoveAction(std::istream &is, bool somewhere);
|
||||
|
||||
u16 getType() const
|
||||
IAction getType() const
|
||||
{
|
||||
return IACTION_MOVE;
|
||||
return IAction::Move;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os) const
|
||||
|
@ -191,22 +185,18 @@ struct IMoveAction : public InventoryAction
|
|||
struct IDropAction : public InventoryAction
|
||||
{
|
||||
// count=0 means "everything"
|
||||
u16 count;
|
||||
u16 count = 0;
|
||||
InventoryLocation from_inv;
|
||||
std::string from_list;
|
||||
s16 from_i;
|
||||
s16 from_i = -1;
|
||||
|
||||
IDropAction()
|
||||
{
|
||||
count = 0;
|
||||
from_i = -1;
|
||||
}
|
||||
IDropAction() {}
|
||||
|
||||
IDropAction(std::istream &is);
|
||||
|
||||
u16 getType() const
|
||||
IAction getType() const
|
||||
{
|
||||
return IACTION_DROP;
|
||||
return IAction::Drop;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os) const
|
||||
|
@ -226,19 +216,16 @@ struct IDropAction : public InventoryAction
|
|||
struct ICraftAction : public InventoryAction
|
||||
{
|
||||
// count=0 means "everything"
|
||||
u16 count;
|
||||
u16 count = 0;
|
||||
InventoryLocation craft_inv;
|
||||
|
||||
ICraftAction()
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
ICraftAction() {}
|
||||
|
||||
ICraftAction(std::istream &is);
|
||||
|
||||
u16 getType() const
|
||||
IAction getType() const
|
||||
{
|
||||
return IACTION_CRAFT;
|
||||
return IAction::Craft;
|
||||
}
|
||||
|
||||
void serialize(std::ostream &os) const
|
||||
|
@ -254,7 +241,7 @@ struct ICraftAction : public InventoryAction
|
|||
};
|
||||
|
||||
// Crafting helper
|
||||
bool getCraftingResult(Inventory *inv, ItemStack& result,
|
||||
bool getCraftingResult(Inventory *inv, ItemStack &result,
|
||||
std::vector<ItemStack> &output_replacements,
|
||||
bool decrementInput, IGameDef *gamedef);
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#include "util/string.h"
|
||||
#include "util/basic_macros.h"
|
||||
|
||||
#include "util/string.h"
|
||||
|
||||
class UnknownKeycode : public BaseException
|
||||
{
|
||||
public:
|
||||
|
@ -380,6 +382,70 @@ void clearKeyCache()
|
|||
g_key_setting_cache.clear();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Config to Command key aliases
|
||||
|
||||
*/
|
||||
|
||||
// A simple cache for quicker lookup
|
||||
static std::vector<KeyCommand> g_command_key_setting_cache;
|
||||
static bool command_key_cache_loaded=false;
|
||||
|
||||
KeyCommand getCommandKeySetting(size_t i)
|
||||
{
|
||||
if (i>=0 && i<g_command_key_setting_cache.size())
|
||||
return g_command_key_setting_cache[i];
|
||||
return KeyCommand();
|
||||
}
|
||||
|
||||
size_t getCommandKeySettingCount()
|
||||
{
|
||||
if (!command_key_cache_loaded)
|
||||
{
|
||||
std::vector<std::string> names = g_settings->getNames();
|
||||
for (std::vector<std::string>::iterator it = names.begin(); it!=names.end(); ++it )
|
||||
{
|
||||
if (it->find("keymap_alias_") == 0)
|
||||
{
|
||||
std::string aname = it->substr(13);
|
||||
KeyCommand k;
|
||||
k.setting_name = aname;
|
||||
k.key = g_settings->get(*it).c_str();
|
||||
if (g_settings->exists("keymap_command_" + aname))
|
||||
k.command = g_settings->get("keymap_command_" + aname).c_str();
|
||||
k.modifier_control = false;
|
||||
k.modifier_shift = false;
|
||||
std::string modifier_list;
|
||||
if (g_settings->exists("keymap_modifiers_" + aname))
|
||||
modifier_list = g_settings->get("keymap_modifiers_" + aname).c_str();
|
||||
size_t pos;
|
||||
while(modifier_list != "")
|
||||
{
|
||||
pos = modifier_list.find(',');
|
||||
std::string modifier = trim(modifier_list.substr(0,pos));
|
||||
if (modifier == "KEY_CONTROL")
|
||||
k.modifier_control = true;
|
||||
if (modifier == "KEY_SHIFT")
|
||||
k.modifier_shift = true;
|
||||
if (pos == std::string::npos)
|
||||
break;
|
||||
modifier_list = modifier_list.substr(pos+1);
|
||||
}
|
||||
g_command_key_setting_cache.push_back(k);
|
||||
}
|
||||
}
|
||||
command_key_cache_loaded = true;
|
||||
}
|
||||
return g_command_key_setting_cache.size();
|
||||
}
|
||||
|
||||
void clearCommandKeyCache() //TODO: Not used, probably should be...
|
||||
{
|
||||
g_command_key_setting_cache.clear();
|
||||
command_key_cache_loaded=false;
|
||||
}
|
||||
|
||||
irr::EKEY_CODE keyname_to_keycode(const char *name)
|
||||
{
|
||||
return lookup_keyname(name).Key;
|
||||
|
|
|
@ -67,4 +67,21 @@ void clearKeyCache();
|
|||
|
||||
irr::EKEY_CODE keyname_to_keycode(const char *name);
|
||||
|
||||
|
||||
typedef struct {
|
||||
KeyPress key;
|
||||
bool modifier_shift;
|
||||
bool modifier_control;
|
||||
std::string setting_name;
|
||||
std::string command;
|
||||
} KeyCommand;
|
||||
|
||||
// Command Key configuration getter
|
||||
KeyCommand getCommandKeySetting(size_t i);
|
||||
size_t getCommandKeySettingCount();
|
||||
|
||||
// Clear fast lookup cache
|
||||
void clearCommandKeyCache();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -390,7 +390,7 @@ void Client::handleCommand_TimeOfDay(NetworkPacket* pkt)
|
|||
m_time_of_day_set = true;
|
||||
|
||||
u32 dr = m_env.getDayNightRatio();
|
||||
infostream << "Client: time_of_day=" << time_of_day
|
||||
infostream << "Client: time_of_day=" << time_of_day << "::" << m_env.getTimeOfDay()
|
||||
<< " time_speed=" << time_speed
|
||||
<< " dr=" << dr << std::endl;
|
||||
}
|
||||
|
@ -777,7 +777,7 @@ void Client::handleCommand_PlaySound(NetworkPacket* pkt)
|
|||
float fade = 0.0f;
|
||||
float pitch = 1.0f;
|
||||
|
||||
*pkt >> server_id >> name >> gain >> type >> pos >> object_id >> loop;
|
||||
*pkt >> server_id >> name >> gain >> type >> pos >> object_id >> loop >> fade;
|
||||
|
||||
try {
|
||||
*pkt >> fade;
|
||||
|
|
|
@ -908,7 +908,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
|
|||
std::istringstream is(datastring, std::ios_base::binary);
|
||||
// Create an action
|
||||
InventoryAction *a = InventoryAction::deSerialize(is);
|
||||
if (a == NULL) {
|
||||
if (!a) {
|
||||
infostream << "TOSERVER_INVENTORY_ACTION: "
|
||||
<< "InventoryAction::deSerialize() returned NULL"
|
||||
<< std::endl;
|
||||
|
@ -927,7 +927,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
|
|||
/*
|
||||
Handle restrictions and special cases of the move action
|
||||
*/
|
||||
if (a->getType() == IACTION_MOVE) {
|
||||
if (a->getType() == IAction::Move) {
|
||||
IMoveAction *ma = (IMoveAction*)a;
|
||||
|
||||
ma->from_inv.applyCurrentPlayer(player->getName());
|
||||
|
@ -982,7 +982,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
|
|||
/*
|
||||
Handle restrictions and special cases of the drop action
|
||||
*/
|
||||
else if (a->getType() == IACTION_DROP) {
|
||||
else if (a->getType() == IAction::Drop) {
|
||||
IDropAction *da = (IDropAction*)a;
|
||||
|
||||
da->from_inv.applyCurrentPlayer(player->getName());
|
||||
|
@ -1018,7 +1018,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
|
|||
/*
|
||||
Handle restrictions and special cases of the craft action
|
||||
*/
|
||||
else if (a->getType() == IACTION_CRAFT) {
|
||||
else if (a->getType() == IAction::Craft) {
|
||||
ICraftAction *ca = (ICraftAction*)a;
|
||||
|
||||
ca->craft_inv.applyCurrentPlayer(player->getName());
|
||||
|
|
|
@ -690,6 +690,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||
switch (drawtype) {
|
||||
default:
|
||||
case NDT_NORMAL:
|
||||
material_type = (alpha == 255) ?
|
||||
TILE_MATERIAL_OPAQUE : TILE_MATERIAL_ALPHA;
|
||||
solidness = 2;
|
||||
break;
|
||||
case NDT_AIRLIKE:
|
||||
|
@ -786,6 +788,16 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||
tile_shader[j] = shdsrc->getShader("nodes_shader",
|
||||
material_type, drawtype);
|
||||
}
|
||||
u8 overlay_material = material_type;
|
||||
if (overlay_material == TILE_MATERIAL_OPAQUE)
|
||||
overlay_material = TILE_MATERIAL_BASIC;
|
||||
else if (overlay_material == TILE_MATERIAL_LIQUID_OPAQUE)
|
||||
overlay_material = TILE_MATERIAL_LIQUID_TRANSPARENT;
|
||||
u32 overlay_shader[6];
|
||||
for (u16 j = 0; j < 6; j++) {
|
||||
overlay_shader[j] = shdsrc->getShader("nodes_shader",
|
||||
overlay_material, drawtype);
|
||||
}
|
||||
|
||||
// Tiles (fill in f->tiles[])
|
||||
for (u16 j = 0; j < 6; j++) {
|
||||
|
@ -794,8 +806,8 @@ void ContentFeatures::updateTextures(ITextureSource *tsrc, IShaderSource *shdsrc
|
|||
tdef[j].backface_culling, material_type);
|
||||
if (tdef_overlay[j].name != "")
|
||||
fillTileAttribs(tsrc, &tiles[j].layers[1], &tdef_overlay[j],
|
||||
tile_shader[j], tsettings.use_normal_texture,
|
||||
tdef[j].backface_culling, material_type);
|
||||
overlay_shader[j], tsettings.use_normal_texture,
|
||||
tdef[j].backface_culling, overlay_material);
|
||||
}
|
||||
|
||||
// Special tiles (fill in f->special_tiles[])
|
||||
|
|
|
@ -21,7 +21,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||
#define L_UTIL_H_
|
||||
|
||||
#include "lua_api/l_base.h"
|
||||
#include "config.h"
|
||||
|
||||
struct HTTPFetchRequest;
|
||||
struct HTTPFetchResult;
|
||||
class AsyncEngine;
|
||||
|
||||
class ModApiUtil : public ModApiBase
|
||||
|
@ -75,6 +78,7 @@ private:
|
|||
// decompress(data, method, ...)
|
||||
static int l_decompress(lua_State *L);
|
||||
|
||||
|
||||
// mkdir(path)
|
||||
static int l_mkdir(lua_State *L);
|
||||
|
||||
|
|
|
@ -488,10 +488,12 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
SendTimeOfDay(PEER_ID_INEXISTENT, time, time_speed);
|
||||
}
|
||||
|
||||
float _max_lag = 0;
|
||||
{
|
||||
MutexAutoLock lock(m_env_mutex);
|
||||
// Figure out and report maximum lag to environment
|
||||
float max_lag = m_env->getMaxLagEstimate();
|
||||
_max_lag = max_lag;
|
||||
max_lag *= 0.9998; // Decrease slowly (about half per 5 minutes)
|
||||
if(dtime > max_lag){
|
||||
if(dtime > 0.1 && dtime > max_lag * 2.0)
|
||||
|
@ -589,7 +591,7 @@ void Server::AsyncRunStep(bool initial_step)
|
|||
m_clients.getPlayerNames(),
|
||||
m_uptime.get(),
|
||||
m_env->getGameTime(),
|
||||
m_lag,
|
||||
_max_lag,
|
||||
m_gamespec.id,
|
||||
Mapgen::getMapgenName(m_emerge->mgparams->mgtype),
|
||||
m_mods,
|
||||
|
@ -3289,6 +3291,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
|
|||
if (playername != "") {
|
||||
RemotePlayer *player = m_env->getPlayer(playername.c_str());
|
||||
if (!player)
|
||||
|
||||
return;
|
||||
peer_id = player->peer_id;
|
||||
proto_ver = player->protocol_version;
|
||||
|
|
|
@ -216,6 +216,7 @@ public:
|
|||
std::wstring getStatusString();
|
||||
inline double getUptime() const { return m_uptime.m_value; }
|
||||
|
||||
|
||||
// read shutdown state
|
||||
inline bool getShutdownRequested() const { return m_shutdown_requested; }
|
||||
|
||||
|
|
|
@ -198,7 +198,6 @@ public:
|
|||
m_attached_particle_spawners.erase(id);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Number of players which know about this object. Object won't be
|
||||
deleted until this is 0 to keep the id preserved for the right
|
||||
|
|
|
@ -531,26 +531,19 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
|
|||
shaderinfo.drawtype = drawtype;
|
||||
shaderinfo.material = video::EMT_SOLID;
|
||||
switch (material_type) {
|
||||
case TILE_MATERIAL_BASIC:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
break;
|
||||
case TILE_MATERIAL_ALPHA:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
break;
|
||||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
break;
|
||||
case TILE_MATERIAL_LIQUID_OPAQUE:
|
||||
shaderinfo.base_material = video::EMT_SOLID;
|
||||
break;
|
||||
case TILE_MATERIAL_WAVING_LEAVES:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
break;
|
||||
case TILE_MATERIAL_WAVING_PLANTS:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case TILE_MATERIAL_OPAQUE:
|
||||
case TILE_MATERIAL_LIQUID_OPAQUE:
|
||||
shaderinfo.base_material = video::EMT_SOLID;
|
||||
break;
|
||||
case TILE_MATERIAL_ALPHA:
|
||||
case TILE_MATERIAL_LIQUID_TRANSPARENT:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
break;
|
||||
case TILE_MATERIAL_BASIC:
|
||||
case TILE_MATERIAL_WAVING_LEAVES:
|
||||
case TILE_MATERIAL_WAVING_PLANTS:
|
||||
shaderinfo.base_material = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
break;
|
||||
}
|
||||
|
||||
bool enable_shaders = g_settings->getBool("enable_shaders");
|
||||
|
@ -642,10 +635,11 @@ ShaderInfo generate_shader(const std::string &name, u8 material_type, u8 drawtyp
|
|||
"TILE_MATERIAL_LIQUID_TRANSPARENT",
|
||||
"TILE_MATERIAL_LIQUID_OPAQUE",
|
||||
"TILE_MATERIAL_WAVING_LEAVES",
|
||||
"TILE_MATERIAL_WAVING_PLANTS"
|
||||
"TILE_MATERIAL_WAVING_PLANTS",
|
||||
"TILE_MATERIAL_OPAQUE"
|
||||
};
|
||||
|
||||
for (int i = 0; i < 6; i++){
|
||||
for (int i = 0; i < 7; i++){
|
||||
shaders_header += "#define ";
|
||||
shaders_header += materialTypes[i];
|
||||
shaders_header += " ";
|
||||
|
|
|
@ -499,9 +499,9 @@ public:
|
|||
// Remove stopped sounds
|
||||
void maintain()
|
||||
{
|
||||
verbosestream<<"OpenALSoundManager::maintain(): "
|
||||
<<m_sounds_playing.size()<<" playing sounds, "
|
||||
<<m_buffers.size()<<" sound names loaded"<<std::endl;
|
||||
//verbosestream<<"OpenALSoundManager::maintain(): "
|
||||
// <<m_sounds_playing.size()<<" playing sounds, "
|
||||
// <<m_buffers.size()<<" sound names loaded"<<std::endl;
|
||||
std::set<int> del_list;
|
||||
for(std::unordered_map<int, PlayingSound*>::iterator i = m_sounds_playing.begin();
|
||||
i != m_sounds_playing.end(); ++i) {
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
This file is a part of the JThread package, which contains some object-
|
||||
oriented thread wrappers for different thread implementations.
|
||||
|
||||
Copyright (c) 2000-2006 Jori Liesenborgs (jori.liesenborgs@gmail.com)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef THREADING_MUTEX_H
|
||||
#define THREADING_MUTEX_H
|
||||
|
||||
#include "threads.h"
|
||||
|
||||
#if USE_CPP11_MUTEX
|
||||
#include <mutex>
|
||||
using Mutex = std::mutex;
|
||||
using RecursiveMutex = std::recursive_mutex;
|
||||
#else
|
||||
|
||||
#if USE_WIN_MUTEX
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "util/basic_macros.h"
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
Mutex();
|
||||
~Mutex();
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
bool try_lock();
|
||||
|
||||
protected:
|
||||
Mutex(bool recursive);
|
||||
void init_mutex(bool recursive);
|
||||
private:
|
||||
#if USE_WIN_MUTEX
|
||||
CRITICAL_SECTION mutex;
|
||||
#else
|
||||
pthread_mutex_t mutex;
|
||||
#endif
|
||||
|
||||
DISABLE_CLASS_COPY(Mutex);
|
||||
};
|
||||
|
||||
class RecursiveMutex : public Mutex
|
||||
{
|
||||
public:
|
||||
RecursiveMutex();
|
||||
|
||||
DISABLE_CLASS_COPY(RecursiveMutex);
|
||||
};
|
||||
|
||||
#endif // C++11
|
||||
|
||||
#endif
|
|
@ -49,7 +49,7 @@ private:
|
|||
sem_t semaphore;
|
||||
#endif
|
||||
|
||||
DISABLE_CLASS_COPY(Semaphore);
|
||||
//DISABLE_CLASS_COPY(Semaphore);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
After Width: | Height: | Size: 632 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 472 B |
After Width: | Height: | Size: 609 B |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 933 B |
After Width: | Height: | Size: 878 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 858 B |
After Width: | Height: | Size: 863 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 246 B |
After Width: | Height: | Size: 247 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 258 B |
After Width: | Height: | Size: 244 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 232 B |