Allow binding dig, place actions to keys; remove LMB/RMB hardcoding

Co-authored-by: Sam Caulfield <sam@samcaulfield.com>
This commit is contained in:
ANAND 2020-06-05 18:36:35 +05:30 committed by celeron55
parent fff0393187
commit 291a6b70d6
14 changed files with 284 additions and 310 deletions

@ -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

@ -1100,8 +1100,8 @@ Methods:
aux1 = boolean,
sneak = boolean,
zoom = boolean,
LMB = boolean,
RMB = boolean,
dig = boolean,
place = boolean,
}
```

@ -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`)

@ -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;

@ -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();
}
}

@ -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);

@ -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;
}

@ -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;
};

@ -35,6 +35,8 @@ public:
SPECIAL1,
SNEAK,
AUTOFORWARD,
DIG,
PLACE,
ESC,

@ -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");

@ -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);

@ -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;

@ -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;
}

@ -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");