diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index 01736f586..3aa113190 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -110,9 +110,9 @@ doubletap_jump (Double tap jump for fly) bool false # enabled. always_fly_fast (Always fly and fast) bool true -# The time in seconds it takes between repeated right clicks when holding the right -# mouse button. -repeat_rightclick_time (Rightclick repetition interval) float 0.25 0.001 +# The time in seconds it takes between repeated node placements when holding +# the place button. +repeat_place_time (Place repetition interval) float 0.25 0.001 # Automatically jump up single-node obstacles. autojump (Automatic jumping) bool false @@ -182,6 +182,14 @@ keymap_jump (Jump key) key KEY_SPACE # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 keymap_sneak (Sneak key) key KEY_LSHIFT +# Key for digging. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_dig (Dig key) key KEY_LBUTTON + +# Key for placing. +# See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 +keymap_place (Place key) key KEY_RBUTTON + # Key for opening the inventory. # See http://irrlicht.sourceforge.net/docu/namespaceirr.html#a54da2a0e231901735e3da1b0edf72eb3 keymap_inventory (Inventory key) key KEY_KEY_I diff --git a/doc/client_lua_api.txt b/doc/client_lua_api.txt index 3b0046b4f..4c5231b79 100644 --- a/doc/client_lua_api.txt +++ b/doc/client_lua_api.txt @@ -1100,8 +1100,8 @@ Methods: aux1 = boolean, sneak = boolean, zoom = boolean, - LMB = boolean, - RMB = boolean, + dig = boolean, + place = boolean, } ``` diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 6366a34c3..88d99fcd5 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -6163,15 +6163,23 @@ object you are working with still exists. * Only affects formspecs shown after this is called. * `get_formspec_prepend(formspec)`: returns a formspec string. * `get_player_control()`: returns table with player pressed keys - * The table consists of fields with boolean value representing the pressed - keys, the fields are jump, right, left, LMB, RMB, sneak, aux1, down, up, zoom. - * example: `{jump=false, right=true, left=false, LMB=false, RMB=false, - sneak=true, aux1=false, down=false, up=false, zoom=false}` - * The `zoom` field is available since 5.3 + * The table consists of fields with the following boolean values + representing the pressed keys: `up`, `down`, `left`, `right`, `jump`, + `aux1`, `sneak`, `dig`, `place`, `LMB`, `RMB`, and `zoom`. + * The fields `LMB` and `RMB` are equal to `dig` and `place` respectively, + and exist only to preserve backwards compatibility. * `get_player_control_bits()`: returns integer with bit packed player pressed - keys. - * bit nr/meaning: 0/up, 1/down, 2/left, 3/right, 4/jump, 5/aux1, 6/sneak, - 7/LMB, 8/RMB, 9/zoom (zoom available since 5.3) + keys. Bits: + * 0 - up + * 1 - down + * 2 - left + * 3 - right + * 4 - jump + * 5 - aux1 + * 6 - sneak + * 7 - dig + * 8 - place + * 9 - zoom * `set_physics_override(override_table)` * `override_table` is a table with the following fields: * `speed`: multiplier to default walking speed value (default: `1`) diff --git a/src/client/client.cpp b/src/client/client.cpp index 65e5b3d8c..745cce900 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -1307,7 +1307,7 @@ void Client::sendPlayerPos() player->last_pitch == player->getPitch() && player->last_yaw == player->getYaw() && player->last_keyPressed == player->keyPressed && - player->last_camera_fov == camera_fov && + player->last_camera_fov == camera_fov && player->last_wanted_range == wanted_range) return; diff --git a/src/client/content_cao.cpp b/src/client/content_cao.cpp index 88688d18c..599139aa3 100644 --- a/src/client/content_cao.cpp +++ b/src/client/content_cao.cpp @@ -975,13 +975,13 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) if (controls.sneak && walking) new_speed /= 2; - if (walking && (controls.LMB || controls.RMB)) { + if (walking && (controls.dig || controls.place)) { new_anim = player->local_animations[3]; player->last_animation = WD_ANIM; - } else if(walking) { + } else if (walking) { new_anim = player->local_animations[1]; player->last_animation = WALK_ANIM; - } else if(controls.LMB || controls.RMB) { + } else if (controls.dig || controls.place) { new_anim = player->local_animations[2]; player->last_animation = DIG_ANIM; } @@ -1004,9 +1004,9 @@ void GenericCAO::step(float dtime, ClientEnvironment *env) // Update local player animations if ((player->last_animation != old_anim || - m_animation_speed != old_anim_speed) && - player->last_animation != NO_ANIM && allow_update) - updateAnimation(); + m_animation_speed != old_anim_speed) && + player->last_animation != NO_ANIM && allow_update) + updateAnimation(); } } diff --git a/src/client/game.cpp b/src/client/game.cpp index 20d2c6f90..0d3a0ca15 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -604,7 +604,6 @@ public: #endif /**************************************************************************** - ****************************************************************************/ const float object_hit_delay = 0.2; @@ -625,15 +624,15 @@ struct GameRunData { u16 new_playeritem; PointedThing pointed_old; bool digging; - bool ldown_for_dig; + bool punching; + bool btn_down_for_dig; bool dig_instantly; bool digging_blocked; - bool left_punch; bool reset_jump_timer; float nodig_delay_timer; float dig_time; float dig_time_complete; - float repeat_rightclick_timer; + float repeat_place_timer; float object_hit_delay_timer; float time_from_last_punch; ClientActiveObject *selected_object; @@ -787,6 +786,14 @@ protected: { return input->wasKeyDown(k); } + inline bool wasKeyPressed(GameKeyType k) + { + return input->wasKeyPressed(k); + } + inline bool wasKeyReleased(GameKeyType k) + { + return input->wasKeyReleased(k); + } #ifdef __ANDROID__ void handleAndroidChatInput(); @@ -900,7 +907,7 @@ private: bool m_cache_enable_free_move; f32 m_cache_mouse_sensitivity; f32 m_cache_joystick_frustum_sensitivity; - f32 m_repeat_right_click_time; + f32 m_repeat_place_time; f32 m_cache_cam_smoothing; f32 m_cache_fog_start; @@ -934,7 +941,7 @@ Game::Game() : &settingChangedCallback, this); g_settings->registerChangedCallback("joystick_frustum_sensitivity", &settingChangedCallback, this); - g_settings->registerChangedCallback("repeat_rightclick_time", + g_settings->registerChangedCallback("repeat_place_time", &settingChangedCallback, this); g_settings->registerChangedCallback("noclip", &settingChangedCallback, this); @@ -992,7 +999,7 @@ Game::~Game() &settingChangedCallback, this); g_settings->deregisterChangedCallback("mouse_sensitivity", &settingChangedCallback, this); - g_settings->deregisterChangedCallback("repeat_rightclick_time", + g_settings->deregisterChangedCallback("repeat_place_time", &settingChangedCallback, this); g_settings->deregisterChangedCallback("noclip", &settingChangedCallback, this); @@ -2465,8 +2472,8 @@ void Game::updatePlayerControl(const CameraOrientation &cam) isKeyDown(KeyType::SPECIAL1), isKeyDown(KeyType::SNEAK), isKeyDown(KeyType::ZOOM), - input->getLeftState(), - input->getRightState(), + isKeyDown(KeyType::DIG), + isKeyDown(KeyType::PLACE), cam.camera_pitch, cam.camera_yaw, input->joystick.getAxisWithoutDead(JA_SIDEWARD_MOVE), @@ -2481,8 +2488,8 @@ void Game::updatePlayerControl(const CameraOrientation &cam) ( (u32)(isKeyDown(KeyType::JUMP) & 0x1) << 4) | ( (u32)(isKeyDown(KeyType::SPECIAL1) & 0x1) << 5) | ( (u32)(isKeyDown(KeyType::SNEAK) & 0x1) << 6) | - ( (u32)(input->getLeftState() & 0x1) << 7) | - ( (u32)(input->getRightState() & 0x1) << 8) | + ( (u32)(isKeyDown(KeyType::DIG) & 0x1) << 7) | + ( (u32)(isKeyDown(KeyType::PLACE) & 0x1) << 8) | ( (u32)(isKeyDown(KeyType::ZOOM) & 0x1) << 9) ); @@ -3064,7 +3071,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) PointedThing pointed = updatePointedThing(shootline, selected_def.liquids_pointable, - !runData.ldown_for_dig, + !runData.btn_down_for_dig, camera_offset); if (pointed != runData.pointed_old) { @@ -3072,20 +3079,18 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) hud->updateSelectionMesh(camera_offset); } - if (runData.digging_blocked && !input->getLeftState()) { - // allow digging again if button is not pressed + // Allow digging again if button is not pressed + if (runData.digging_blocked && !isKeyDown(KeyType::DIG)) runData.digging_blocked = false; - } /* Stop digging when - - releasing left mouse button + - releasing dig button - pointing away from node */ if (runData.digging) { - if (input->getLeftReleased()) { - infostream << "Left button released" - << " (stopped digging)" << std::endl; + if (wasKeyReleased(KeyType::DIG)) { + infostream << "Dig button released (stopped digging)" << std::endl; runData.digging = false; } else if (pointed != runData.pointed_old) { if (pointed.type == POINTEDTHING_NODE @@ -3095,8 +3100,7 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) // Still pointing to the same node, but a different face. // Don't reset. } else { - infostream << "Pointing away from node" - << " (stopped digging)" << std::endl; + infostream << "Pointing away from node (stopped digging)" << std::endl; runData.digging = false; hud->updateSelectionMesh(camera_offset); } @@ -3107,55 +3111,57 @@ void Game::processPlayerInteraction(f32 dtime, bool show_hud, bool show_debug) client->setCrack(-1, v3s16(0, 0, 0)); runData.dig_time = 0.0; } - } else if (runData.dig_instantly && input->getLeftReleased()) { - // Remove e.g. torches faster when clicking instead of holding LMB + } else if (runData.dig_instantly && wasKeyReleased(KeyType::DIG)) { + // Remove e.g. torches faster when clicking instead of holding dig button runData.nodig_delay_timer = 0; runData.dig_instantly = false; } - if (!runData.digging && runData.ldown_for_dig && !input->getLeftState()) { - runData.ldown_for_dig = false; - } + if (!runData.digging && runData.btn_down_for_dig && !isKeyDown(KeyType::DIG)) + runData.btn_down_for_dig = false; - runData.left_punch = false; + runData.punching = false; soundmaker->m_player_leftpunch_sound.name = ""; // Prepare for repeating, unless we're not supposed to - if (input->getRightState() && !g_settings->getBool("safe_dig_and_place")) - runData.repeat_rightclick_timer += dtime; + if (isKeyDown(KeyType::PLACE) && !g_settings->getBool("safe_dig_and_place")) + runData.repeat_place_timer += dtime; else - runData.repeat_rightclick_timer = 0; + runData.repeat_place_timer = 0; - if (selected_def.usable && input->getLeftState()) { - if (input->getLeftClicked() && (!client->modsLoaded() - || !client->getScript()->on_item_use(selected_item, pointed))) + if (selected_def.usable && isKeyDown(KeyType::DIG)) { + if (wasKeyPressed(KeyType::DIG) && (!client->modsLoaded() || + !client->getScript()->on_item_use(selected_item, pointed))) client->interact(INTERACT_USE, pointed); } else if (pointed.type == POINTEDTHING_NODE) { handlePointingAtNode(pointed, selected_item, hand_item, dtime); } else if (pointed.type == POINTEDTHING_OBJECT) { v3f player_position = player->getPosition(); handlePointingAtObject(pointed, tool_item, player_position, show_debug); - } else if (input->getLeftState()) { + } else if (isKeyDown(KeyType::DIG)) { // When button is held down in air, show continuous animation - runData.left_punch = true; + runData.punching = true; // Run callback even though item is not usable - if (input->getLeftClicked() && client->modsLoaded()) + if (wasKeyPressed(KeyType::DIG) && client->modsLoaded()) client->getScript()->on_item_use(selected_item, pointed); - } else if (input->getRightClicked()) { + } else if (wasKeyPressed(KeyType::PLACE)) { handlePointingAtNothing(selected_item); } runData.pointed_old = pointed; - if (runData.left_punch || input->getLeftClicked()) - camera->setDigging(0); // left click animation + if (runData.punching || wasKeyPressed(KeyType::DIG)) + camera->setDigging(0); // dig animation - input->resetLeftClicked(); - input->resetRightClicked(); + input->clearWasKeyPressed(); + input->clearWasKeyReleased(); - input->resetLeftReleased(); - input->resetRightReleased(); + input->joystick.clearWasKeyDown(KeyType::MOUSE_L); + input->joystick.clearWasKeyDown(KeyType::MOUSE_R); + + input->joystick.clearWasKeyReleased(KeyType::MOUSE_L); + input->joystick.clearWasKeyReleased(KeyType::MOUSE_R); } @@ -3255,7 +3261,7 @@ PointedThing Game::updatePointedThing( void Game::handlePointingAtNothing(const ItemStack &playerItem) { - infostream << "Right Clicked in Air" << std::endl; + infostream << "Attempted to place item while pointing at nothing" << std::endl; PointedThing fauxPointed; fauxPointed.type = POINTEDTHING_NOTHING; client->interact(INTERACT_ACTIVATE, fauxPointed); @@ -3274,7 +3280,7 @@ void Game::handlePointingAtNode(const PointedThing &pointed, ClientMap &map = client->getEnv().getClientMap(); - if (runData.nodig_delay_timer <= 0.0 && input->getLeftState() + if (runData.nodig_delay_timer <= 0.0 && isKeyDown(KeyType::DIG) && !runData.digging_blocked && client->checkPrivilege("interact")) { handleDigging(pointed, nodepos, selected_item, hand_item, dtime); @@ -3295,13 +3301,14 @@ void Game::handlePointingAtNode(const PointedThing &pointed, } } - if ((input->getRightClicked() || - runData.repeat_rightclick_timer >= m_repeat_right_click_time) && + if ((wasKeyPressed(KeyType::PLACE) || + runData.repeat_place_timer >= m_repeat_place_time) && client->checkPrivilege("interact")) { - runData.repeat_rightclick_timer = 0; - infostream << "Ground right-clicked" << std::endl; + runData.repeat_place_timer = 0; + infostream << "Place button pressed while looking at ground" << std::endl; - camera->setDigging(1); // right click animation (always shown for feedback) + // Placing animation (always shown for feedback) + camera->setDigging(1); soundmaker->m_player_rightpunch_sound = SimpleSoundSpec(); @@ -3367,8 +3374,7 @@ bool Game::nodePlacement(const ItemDefinition &selected_def, } verbosestream << "Node placement prediction for " - << selected_def.name << " is " - << prediction << std::endl; + << selected_def.name << " is " << prediction << std::endl; v3s16 p = neighbourpos; // Place inside node itself if buildable_to @@ -3529,7 +3535,7 @@ void Game::handlePointingAtObject(const PointedThing &pointed, m_game_ui->setInfoText(infotext); - if (input->getLeftState()) { + if (isKeyDown(KeyType::DIG)) { bool do_punch = false; bool do_punch_damage = false; @@ -3539,12 +3545,12 @@ void Game::handlePointingAtObject(const PointedThing &pointed, runData.object_hit_delay_timer = object_hit_delay; } - if (input->getLeftClicked()) + if (wasKeyPressed(KeyType::DIG)) do_punch = true; if (do_punch) { - infostream << "Left-clicked object" << std::endl; - runData.left_punch = true; + infostream << "Punched object" << std::endl; + runData.punching = true; } if (do_punch_damage) { @@ -3559,8 +3565,8 @@ void Game::handlePointingAtObject(const PointedThing &pointed, if (!disable_send) client->interact(INTERACT_START_DIGGING, pointed); } - } else if (input->getRightClicked()) { - infostream << "Right-clicked object" << std::endl; + } else if (wasKeyDown(KeyType::PLACE)) { + infostream << "Pressed place button while pointing at object" << std::endl; client->interact(INTERACT_PLACE, pointed); // place } } @@ -3606,7 +3612,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, return; client->interact(INTERACT_START_DIGGING, pointed); runData.digging = true; - runData.ldown_for_dig = true; + runData.btn_down_for_dig = true; } if (!runData.dig_instantly) { @@ -3700,7 +3706,7 @@ void Game::handleDigging(const PointedThing &pointed, const v3s16 &nodepos, client->setCrack(-1, nodepos); } - camera->setDigging(0); // left click animation + camera->setDigging(0); // Dig animation } @@ -4039,7 +4045,7 @@ void Game::readSettings() m_cache_enable_fog = g_settings->getBool("enable_fog"); m_cache_mouse_sensitivity = g_settings->getFloat("mouse_sensitivity"); m_cache_joystick_frustum_sensitivity = g_settings->getFloat("joystick_frustum_sensitivity"); - m_repeat_right_click_time = g_settings->getFloat("repeat_rightclick_time"); + m_repeat_place_time = g_settings->getFloat("repeat_place_time"); m_cache_enable_noclip = g_settings->getBool("noclip"); m_cache_enable_free_move = g_settings->getBool("free_move"); @@ -4131,30 +4137,32 @@ void Game::showPauseMenu() "- %s: move backwards\n" "- %s: move left\n" "- %s: move right\n" - "- %s: jump/climb\n" - "- %s: sneak/go down\n" + "- %s: jump/climb up\n" + "- %s: dig/punch\n" + "- %s: place/use\n" + "- %s: sneak/climb down\n" "- %s: drop item\n" "- %s: inventory\n" "- Mouse: turn/look\n" - "- Mouse left: dig/punch\n" - "- Mouse right: place/use\n" "- Mouse wheel: select item\n" "- %s: chat\n" ); - char control_text_buf[600]; + char control_text_buf[600]; - porting::mt_snprintf(control_text_buf, sizeof(control_text_buf), control_text_template.c_str(), - GET_KEY_NAME(keymap_forward), - GET_KEY_NAME(keymap_backward), - GET_KEY_NAME(keymap_left), - GET_KEY_NAME(keymap_right), - GET_KEY_NAME(keymap_jump), - GET_KEY_NAME(keymap_sneak), - GET_KEY_NAME(keymap_drop), - GET_KEY_NAME(keymap_inventory), - GET_KEY_NAME(keymap_chat) - ); + porting::mt_snprintf(control_text_buf, sizeof(control_text_buf), control_text_template.c_str(), + GET_KEY_NAME(keymap_forward), + GET_KEY_NAME(keymap_backward), + GET_KEY_NAME(keymap_left), + GET_KEY_NAME(keymap_right), + GET_KEY_NAME(keymap_jump), + GET_KEY_NAME(keymap_dig), + GET_KEY_NAME(keymap_place), + GET_KEY_NAME(keymap_sneak), + GET_KEY_NAME(keymap_drop), + GET_KEY_NAME(keymap_inventory), + GET_KEY_NAME(keymap_chat) + ); std::string control_text = std::string(control_text_buf); str_formspec_escape(control_text); diff --git a/src/client/inputhandler.cpp b/src/client/inputhandler.cpp index a79b04a90..608a405a8 100644 --- a/src/client/inputhandler.cpp +++ b/src/client/inputhandler.cpp @@ -37,6 +37,8 @@ void KeyCache::populate() key[KeyType::JUMP] = getKeySetting("keymap_jump"); key[KeyType::SPECIAL1] = getKeySetting("keymap_special1"); key[KeyType::SNEAK] = getKeySetting("keymap_sneak"); + key[KeyType::DIG] = getKeySetting("keymap_dig"); + key[KeyType::PLACE] = getKeySetting("keymap_place"); key[KeyType::AUTOFORWARD] = getKeySetting("keymap_autoforward"); @@ -111,57 +113,81 @@ bool MyEventReceiver::OnEvent(const SEvent &event) if (event.EventType == irr::EET_KEY_INPUT_EVENT) { const KeyPress &keyCode = event.KeyInput; if (keysListenedFor[keyCode]) { + // If the key is being held down then the OS may + // send a continuous stream of keydown events. + // In this case, we don't want to let this + // stream reach the application as it will cause + // certain actions to repeat constantly. if (event.KeyInput.PressedDown) { + if (!IsKeyDown(keyCode)) { + keyWasDown.set(keyCode); + keyWasPressed.set(keyCode); + } keyIsDown.set(keyCode); - keyWasDown.set(keyCode); } else { + if (IsKeyDown(keyCode)) + keyWasReleased.set(keyCode); + keyIsDown.unset(keyCode); } + return true; } - } #ifdef HAVE_TOUCHSCREENGUI - // case of touchscreengui we have to handle different events - if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) { + } else if (m_touchscreengui && event.EventType == irr::EET_TOUCH_INPUT_EVENT) { + // In case of touchscreengui, we have to handle different events m_touchscreengui->translateEvent(event); return true; - } #endif - if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { + } else if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT) { /* TODO add a check like: if (event.JoystickEvent != joystick_we_listen_for) return false; */ return joystick->handleEvent(event.JoystickEvent); - } - // handle mouse events - if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) { - if (isMenuActive()) { - left_active = false; - middle_active = false; - right_active = false; - } else { - left_active = event.MouseInput.isLeftPressed(); - middle_active = event.MouseInput.isMiddlePressed(); - right_active = event.MouseInput.isRightPressed(); - - if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN) { - leftclicked = true; - } - if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN) { - rightclicked = true; - } - if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP) { - leftreleased = true; - } - if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP) { - rightreleased = true; - } - if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) { - mouse_wheel += event.MouseInput.Wheel; - } + } else if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) { + // Handle mouse events + KeyPress key; + switch (event.MouseInput.Event) { + case EMIE_LMOUSE_PRESSED_DOWN: + key = "KEY_LBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_MMOUSE_PRESSED_DOWN: + key = "KEY_MBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_RMOUSE_PRESSED_DOWN: + key = "KEY_RBUTTON"; + keyIsDown.set(key); + keyWasDown.set(key); + keyWasPressed.set(key); + break; + case EMIE_LMOUSE_LEFT_UP: + key = "KEY_LBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MMOUSE_LEFT_UP: + key = "KEY_MBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_RMOUSE_LEFT_UP: + key = "KEY_RBUTTON"; + keyIsDown.unset(key); + keyWasReleased.set(key); + break; + case EMIE_MOUSE_WHEEL: + mouse_wheel += event.MouseInput.Wheel; + break; + default: break; } } else if (event.EventType == irr::EET_LOG_TEXT_EVENT) { static const LogLevel irr_loglev_conv[] = { @@ -188,38 +214,28 @@ s32 RandomInputHandler::Rand(s32 min, s32 max) return (myrand() % (max - min + 1)) + min; } +struct RandomInputHandlerSimData { + std::string key; + float counter; + int time_max; +}; + void RandomInputHandler::step(float dtime) { - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_jump")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_special1")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_forward")); - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 40); - keydown.toggle(getKeySetting("keymap_left")); + static RandomInputHandlerSimData rnd_data[] = { + { "keymap_jump", 0.0f, 40 }, + { "keymap_special1", 0.0f, 40 }, + { "keymap_forward", 0.0f, 40 }, + { "keymap_left", 0.0f, 40 }, + { "keymap_dig", 0.0f, 30 }, + { "keymap_place", 0.0f, 15 } + }; + + for (auto &i : rnd_data) { + i.counter -= dtime; + if (i.counter < 0.0) { + i.counter = 0.1 * Rand(1, i.time_max); + keydown.toggle(getKeySetting(i.key.c_str())); } } { @@ -230,29 +246,5 @@ void RandomInputHandler::step(float dtime) mousespeed = v2s32(Rand(-20, 20), Rand(-15, 20)); } } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 30); - leftdown = !leftdown; - if (leftdown) - leftclicked = true; - if (!leftdown) - leftreleased = true; - } - } - { - static float counter1 = 0; - counter1 -= dtime; - if (counter1 < 0.0) { - counter1 = 0.1 * Rand(1, 15); - rightdown = !rightdown; - if (rightdown) - rightclicked = true; - if (!rightdown) - rightreleased = true; - } - } mousepos += mousespeed; } diff --git a/src/client/inputhandler.h b/src/client/inputhandler.h index fc7998f20..def147a82 100644 --- a/src/client/inputhandler.h +++ b/src/client/inputhandler.h @@ -144,6 +144,14 @@ public: return b; } + // Checks whether a key was just pressed. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } + + // Checks whether a key was just released. State will be cleared + // in the subsequent iteration of Game::processPlayerInteraction + bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } + void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); } void dontListenForKeys() { keysListenedFor.clear(); } @@ -158,19 +166,22 @@ public: { keyIsDown.clear(); keyWasDown.clear(); - - leftclicked = false; - rightclicked = false; - leftreleased = false; - rightreleased = false; - - left_active = false; - middle_active = false; - right_active = false; + keyWasPressed.clear(); + keyWasReleased.clear(); mouse_wheel = 0; } + void clearWasKeyPressed() + { + keyWasPressed.clear(); + } + + void clearWasKeyReleased() + { + keyWasReleased.clear(); + } + MyEventReceiver() { #ifdef HAVE_TOUCHSCREENGUI @@ -178,15 +189,6 @@ public: #endif } - bool leftclicked = false; - bool rightclicked = false; - bool leftreleased = false; - bool rightreleased = false; - - bool left_active = false; - bool middle_active = false; - bool right_active = false; - s32 mouse_wheel = 0; JoystickController *joystick = nullptr; @@ -198,8 +200,16 @@ public: private: // The current state of keys KeyList keyIsDown; - // Whether a key has been pressed or not + + // Whether a key was down KeyList keyWasDown; + + // Whether a key has just been pressed + KeyList keyWasPressed; + + // Whether a key has just been released + KeyList keyWasReleased; + // List of keys we listen for // TODO perhaps the type of this is not really // performant as KeyList is designed for few but @@ -226,27 +236,19 @@ public: virtual bool isKeyDown(GameKeyType k) = 0; virtual bool wasKeyDown(GameKeyType k) = 0; + virtual bool wasKeyPressed(GameKeyType k) = 0; + virtual bool wasKeyReleased(GameKeyType k) = 0; virtual bool cancelPressed() = 0; + virtual void clearWasKeyPressed() {} + virtual void clearWasKeyReleased() {} + virtual void listenForKey(const KeyPress &keyCode) {} virtual void dontListenForKeys() {} virtual v2s32 getMousePos() = 0; virtual void setMousePos(s32 x, s32 y) = 0; - virtual bool getLeftState() = 0; - virtual bool getRightState() = 0; - - virtual bool getLeftClicked() = 0; - virtual bool getRightClicked() = 0; - virtual void resetLeftClicked() = 0; - virtual void resetRightClicked() = 0; - - virtual bool getLeftReleased() = 0; - virtual bool getRightReleased() = 0; - virtual void resetLeftReleased() = 0; - virtual void resetRightReleased() = 0; - virtual s32 getMouseWheel() = 0; virtual void step(float dtime) {} @@ -275,10 +277,26 @@ public: { return m_receiver->WasKeyDown(keycache.key[k]) || joystick.wasKeyDown(k); } + virtual bool wasKeyPressed(GameKeyType k) + { + return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyReleased(k); + } + virtual bool wasKeyReleased(GameKeyType k) + { + return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k); + } virtual bool cancelPressed() { return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey); } + virtual void clearWasKeyPressed() + { + m_receiver->clearWasKeyPressed(); + } + virtual void clearWasKeyReleased() + { + m_receiver->clearWasKeyReleased(); + } virtual void listenForKey(const KeyPress &keyCode) { m_receiver->listenForKey(keyCode); @@ -306,59 +324,6 @@ public: } } - virtual bool getLeftState() - { - return m_receiver->left_active || joystick.isKeyDown(KeyType::MOUSE_L); - } - virtual bool getRightState() - { - return m_receiver->right_active || joystick.isKeyDown(KeyType::MOUSE_R); - } - - virtual bool getLeftClicked() - { - return m_receiver->leftclicked || - joystick.getWasKeyDown(KeyType::MOUSE_L); - } - virtual bool getRightClicked() - { - return m_receiver->rightclicked || - joystick.getWasKeyDown(KeyType::MOUSE_R); - } - - virtual void resetLeftClicked() - { - m_receiver->leftclicked = false; - joystick.clearWasKeyDown(KeyType::MOUSE_L); - } - virtual void resetRightClicked() - { - m_receiver->rightclicked = false; - joystick.clearWasKeyDown(KeyType::MOUSE_R); - } - - virtual bool getLeftReleased() - { - return m_receiver->leftreleased || - joystick.wasKeyReleased(KeyType::MOUSE_L); - } - virtual bool getRightReleased() - { - return m_receiver->rightreleased || - joystick.wasKeyReleased(KeyType::MOUSE_R); - } - - virtual void resetLeftReleased() - { - m_receiver->leftreleased = false; - joystick.clearWasKeyReleased(KeyType::MOUSE_L); - } - virtual void resetRightReleased() - { - m_receiver->rightreleased = false; - joystick.clearWasKeyReleased(KeyType::MOUSE_R); - } - virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); } void clear() @@ -384,23 +349,12 @@ public: virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } virtual bool wasKeyDown(GameKeyType k) { return false; } + virtual bool wasKeyPressed(GameKeyType k) { return false; } + virtual bool wasKeyReleased(GameKeyType k) { return false; } virtual bool cancelPressed() { return false; } virtual v2s32 getMousePos() { return mousepos; } virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); } - virtual bool getLeftState() { return leftdown; } - virtual bool getRightState() { return rightdown; } - - virtual bool getLeftClicked() { return leftclicked; } - virtual bool getRightClicked() { return rightclicked; } - virtual void resetLeftClicked() { leftclicked = false; } - virtual void resetRightClicked() { rightclicked = false; } - - virtual bool getLeftReleased() { return leftreleased; } - virtual bool getRightReleased() { return rightreleased; } - virtual void resetLeftReleased() { leftreleased = false; } - virtual void resetRightReleased() { rightreleased = false; } - virtual s32 getMouseWheel() { return 0; } virtual void step(float dtime); @@ -411,10 +365,4 @@ private: KeyList keydown; v2s32 mousepos; v2s32 mousespeed; - bool leftdown = false; - bool rightdown = false; - bool leftclicked = false; - bool rightclicked = false; - bool leftreleased = false; - bool rightreleased = false; }; diff --git a/src/client/keys.h b/src/client/keys.h index 50d3d194b..b6ce59b4a 100644 --- a/src/client/keys.h +++ b/src/client/keys.h @@ -35,6 +35,8 @@ public: SPECIAL1, SNEAK, AUTOFORWARD, + DIG, + PLACE, ESC, diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index 07bf0ebb8..103f0fb02 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -73,6 +73,8 @@ void set_default_settings(Settings *settings) settings->setDefault("keymap_right", "KEY_KEY_D"); settings->setDefault("keymap_jump", "KEY_SPACE"); settings->setDefault("keymap_sneak", "KEY_LSHIFT"); + settings->setDefault("keymap_dig", "KEY_LBUTTON"); + settings->setDefault("keymap_place", "KEY_RBUTTON"); settings->setDefault("keymap_drop", "KEY_KEY_Q"); settings->setDefault("keymap_zoom", "KEY_KEY_Z"); settings->setDefault("keymap_inventory", "KEY_KEY_I"); @@ -269,7 +271,7 @@ void set_default_settings(Settings *settings) // Input settings->setDefault("invert_mouse", "false"); settings->setDefault("mouse_sensitivity", "0.2"); - settings->setDefault("repeat_rightclick_time", "0.25"); + settings->setDefault("repeat_place_time", "0.25"); settings->setDefault("safe_dig_and_place", "false"); settings->setDefault("random_input", "false"); settings->setDefault("aux1_descends", "false"); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index b3008bb50..dcbb114bf 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -491,17 +491,18 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, playersao->setPlayerYaw(yaw); playersao->setFov(fov); playersao->setWantedRange(wanted_range); + player->keyPressed = keyPressed; - player->control.up = (keyPressed & 1); - player->control.down = (keyPressed & 2); - player->control.left = (keyPressed & 4); - player->control.right = (keyPressed & 8); - player->control.jump = (keyPressed & 16); - player->control.aux1 = (keyPressed & 32); - player->control.sneak = (keyPressed & 64); - player->control.LMB = (keyPressed & 128); - player->control.RMB = (keyPressed & 256); - player->control.zoom = (keyPressed & 512); + player->control.up = (keyPressed & (0x1 << 0)); + player->control.down = (keyPressed & (0x1 << 1)); + player->control.left = (keyPressed & (0x1 << 2)); + player->control.right = (keyPressed & (0x1 << 3)); + player->control.jump = (keyPressed & (0x1 << 4)); + player->control.aux1 = (keyPressed & (0x1 << 5)); + player->control.sneak = (keyPressed & (0x1 << 6)); + player->control.dig = (keyPressed & (0x1 << 7)); + player->control.place = (keyPressed & (0x1 << 8)); + player->control.zoom = (keyPressed & (0x1 << 9)); if (playersao->checkMovementCheat()) { // Call callbacks @@ -1670,7 +1671,7 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt) if (client->chosen_mech != AUTH_MECHANISM_SRP && client->chosen_mech != AUTH_MECHANISM_LEGACY_PASSWORD) { actionstream << "Server: got SRP _M packet, while auth" - << "is going on with mech " << client->chosen_mech << " from " + << "is going on with mech " << client->chosen_mech << " from " << addr_s << " (wantSudo=" << wantSudo << "). Denying." << std::endl; if (wantSudo) { DenySudoAccess(peer_id); diff --git a/src/player.h b/src/player.h index 3bc7762fa..ec068a8b1 100644 --- a/src/player.h +++ b/src/player.h @@ -57,8 +57,8 @@ struct PlayerControl bool a_aux1, bool a_sneak, bool a_zoom, - bool a_LMB, - bool a_RMB, + bool a_dig, + bool a_place, float a_pitch, float a_yaw, float a_sidew_move_joystick_axis, @@ -73,8 +73,8 @@ struct PlayerControl aux1 = a_aux1; sneak = a_sneak; zoom = a_zoom; - LMB = a_LMB; - RMB = a_RMB; + dig = a_dig; + place = a_place; pitch = a_pitch; yaw = a_yaw; sidew_move_joystick_axis = a_sidew_move_joystick_axis; @@ -88,8 +88,8 @@ struct PlayerControl bool aux1 = false; bool sneak = false; bool zoom = false; - bool LMB = false; - bool RMB = false; + bool dig = false; + bool place = false; float pitch = 0.0f; float yaw = 0.0f; float sidew_move_joystick_axis = 0.0f; diff --git a/src/script/lua_api/l_localplayer.cpp b/src/script/lua_api/l_localplayer.cpp index 851ede535..33fa27c8b 100644 --- a/src/script/lua_api/l_localplayer.cpp +++ b/src/script/lua_api/l_localplayer.cpp @@ -231,8 +231,8 @@ int LuaLocalPlayer::l_get_control(lua_State *L) set("aux1", c.aux1); set("sneak", c.sneak); set("zoom", c.zoom); - set("LMB", c.LMB); - set("RMB", c.RMB); + set("dig", c.dig); + set("place", c.place); return 1; } diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index e7394133a..495d8bced 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1455,9 +1455,14 @@ int ObjectRef::l_get_player_control(lua_State *L) lua_setfield(L, -2, "aux1"); lua_pushboolean(L, control.sneak); lua_setfield(L, -2, "sneak"); - lua_pushboolean(L, control.LMB); + lua_pushboolean(L, control.dig); + lua_setfield(L, -2, "dig"); + lua_pushboolean(L, control.place); + lua_setfield(L, -2, "place"); + // Legacy fields to ensure mod compatibility + lua_pushboolean(L, control.dig); lua_setfield(L, -2, "LMB"); - lua_pushboolean(L, control.RMB); + lua_pushboolean(L, control.place); lua_setfield(L, -2, "RMB"); lua_pushboolean(L, control.zoom); lua_setfield(L, -2, "zoom");