1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2010 Robert TIMM (rti) <mail@rtti.de>
6 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // Copyright (C) 2013-2014 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
9 // This program is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU Affero General Public License as
11 // published by the Free Software Foundation, either version 3 of the
12 // License, or (at your option) any later version.
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU Affero General Public License for more details.
19 // You should have received a copy of the GNU Affero General Public License
20 // along with this program. If not, see <http://www.gnu.org/licenses/>.
31 #include "game_share/bot_chat_types.h"
33 #include "user_controls.h"
34 #include "../actions_client.h"
35 #include "../user_entity.h"
36 #include "../cursor_functions.h"
37 #include "../time_client.h"
38 #include "../interface_v3/interface_manager.h"
39 #include "../entities.h"
43 #include "../r2/editor.h"
53 using namespace NLMISC
;
60 extern UDriver
*Driver
;
62 extern CEventsListener EventsListener
; // Inputs Manager
67 // User Controls (mouse, keyboard, interfaces, ...)
68 CUserControls UserControls
;
71 H_AUTO_DECL ( RZ_Client_User_Controls_Update
)
74 // ----------------------------------------------------------------------------
75 static bool isSwimming()
77 if (UserEntity
!= NULL
)
78 return (UserEntity
->mode() == MBEHAV::SWIM
|| UserEntity
->mode() == MBEHAV::MOUNT_SWIM
);
86 return UserEntity
->isSit();
91 static bool isRiding()
94 return UserEntity
->isRiding();
103 //---------------------------------------------------
106 //---------------------------------------------------
107 CUserControls::CUserControls()
112 //---------------------------------------------------
114 // Initialize all the components.
115 //---------------------------------------------------
116 void CUserControls::init()
118 // Default Mode is Interface Mode.
119 _LastMode
= _Mode
= InterfaceMode
;
123 _RightClickStart
= 0;
125 _TimeBeforeMouseSlide
= 50;
126 _TimeLongClick
= 200;
143 _Start
= CVector(0,0,0);
144 _Destination
= _Start
;
148 _DirectionMove
= none
;
150 _Locked
= false; // Move is not locked.
153 _InternalView
= true;
155 _LastFrameBackward
= false;
156 _LastFrameForward
= false;
157 _LastFrameAutowalk
= false;
158 _LastFrameStrafeLeft
= false;
159 _LastFrameStrafeRight
= false;
160 _LastFrameTurnLeft
= false;
161 _LastFrameTurnRight
= false;
162 _LastFrameLeftButtonDown
= false;
163 _LastFrameMousePosX
= 0.f
;
164 _LastFrameMousePosY
= 0.f
;
169 _UserCameraDeltaYaw
= 0;
170 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
172 _CurrentFrameFreeLookCalled
= false;
174 _RotateUserLRVelocity
= 0.f
;
175 _RotateUserUDVelocity
= 0.f
;
176 _RotateCameraLRVelocity
= 0.f
;
178 _MouseCaptured
= false;
180 _NeedReleaseForward
= false;
181 _NextForwardCancelMoveTo
= false;
185 void CUserControls::reset()
190 //-----------------------------------------------
191 // needReleaseForward :
192 //-----------------------------------------------
193 void CUserControls::needReleaseForward()
195 if( Actions
.valide("forward") )
197 _NeedReleaseForward
= true;
202 //-----------------------------------------------
204 //-----------------------------------------------
205 void CUserControls::autowalkState(bool enable
)
209 _DirectionMove
|= autowalk
;
210 // If not backward, default is forward.
211 if(!(_DirectionMove
& backward
))
212 _DirectionMove
|= forward
;
215 _DirectionMove
&= ~(autowalk
|forward
|backward
);
219 //-----------------------------------------------
221 // Main function of the Class -> Call it each frame.
222 //-----------------------------------------------
223 void CUserControls::update()
225 H_AUTO_USE ( RZ_Client_User_Controls_Update
);
229 // Reset the moving direction.
230 _DirectionMove
&= ~(left
| right
);
232 // if not locked, move
235 // What is the current _Mode ?
258 // Third Person View Mode
267 _LastFrameForward
= Actions
.valide("forward") && !_NeedReleaseForward
;
268 if( UserEntity
->mode() != MBEHAV::MOUNT_SWIM
)
270 _LastFrameBackward
= Actions
.valide("backward");
272 _LastFrameAutowalk
= Actions
.valide("toggle_auto_walk");
273 if( isSit() || UserEntity
->isAFK() )
275 if( _LastFrameForward
|| _LastFrameBackward
)
277 UserEntity
->sit(false);
278 UserEntity
->setAFK(false);
281 if (isSwimming() || isRiding())
283 _LastFrameStrafeLeft
= false;
284 _LastFrameStrafeRight
= false;
288 _LastFrameStrafeLeft
= Actions
.valide("strafe_left");
289 _LastFrameStrafeRight
= Actions
.valide("strafe_right");
291 _LastFrameTurnLeft
= Actions
.valide("turn_left");
292 _LastFrameTurnRight
= Actions
.valide("turn_right");
293 _LastFrameLeftButtonDown
= EventsListener
.isMouseButtonDown(leftButton
);
294 _LastFrameMousePosX
= EventsListener
.getMousePosX();
295 _LastFrameMousePosY
= EventsListener
.getMousePosY();
298 // update the refinePos (for landscape refining...)
299 // In fly mode, take the view pos.
301 View
.refinePos(View
.viewPos());
302 // Else take the entity pos (for less update if 3rd personn)
304 View
.refinePos(UserEntity
->pos());
306 // update camera collision once per frame
307 View
.updateCameraCollision();
309 NLMISC::CCDBNodeLeaf
*node
= _UiVarMkMoveDB
? &*_UiVarMkMoveDB
310 : &*(_UiVarMkMoveDB
= NLGUI::CDBManager::getInstance()->getDbProp("UI:VARIABLES:MK_MOVE"));
311 node
->setValue32(autowalkState());
315 //-----------------------------------------------
316 // Acceleration helper
317 //-----------------------------------------------
318 void CUserControls::updateVelocity (float deltaTime
, float acceleration
, float brake
, float speedMax
, float &speed
)
320 speed
+= acceleration
* deltaTime
;
321 // No acclereration, brake
322 if (acceleration
== 0)
341 clamp (speed
, -speedMax
, speedMax
);
342 }// updateVelocity //
344 //-----------------------------------------------
345 // keyboardRotation :
346 // Manage keyboard rotation
347 //-----------------------------------------------
348 void CUserControls::keyboardRotationLR (bool left
, bool right
)
355 accel
+= ClientCfg
.RotAccel
;
356 _RotateUserLRVelocity
= std::max (_RotateUserLRVelocity
, ClientCfg
.RotKeySpeedMin
);
361 accel
-= ClientCfg
.RotAccel
;
362 _RotateUserLRVelocity
= std::min (_RotateUserLRVelocity
, -ClientCfg
.RotKeySpeedMin
);
364 updateVelocity (DT
, accel
, ClientCfg
.RotAccel
, ClientCfg
.RotKeySpeedMax
, _RotateUserLRVelocity
);
367 UserEntity
->rotate(DT
*_RotateUserLRVelocity
);
370 _RotateUserLRVelocity
= 0;
371 }// keyboardRotation //
373 //-----------------------------------------------
374 // keyboardRotationUD :
375 //-----------------------------------------------
376 void CUserControls::keyboardRotationUD (bool up
, bool down
)
383 accel
+= ClientCfg
.RotAccel
;
384 _RotateUserUDVelocity
= std::max (_RotateUserUDVelocity
, ClientCfg
.RotKeySpeedMin
);
389 accel
-= ClientCfg
.RotAccel
;
390 _RotateUserUDVelocity
= std::min (_RotateUserUDVelocity
, -ClientCfg
.RotKeySpeedMin
);
392 updateVelocity (DT
, accel
, ClientCfg
.RotAccel
, ClientCfg
.RotKeySpeedMax
, _RotateUserUDVelocity
);
394 UserEntity
->rotHeadVertically(DT
*_RotateUserUDVelocity
);
395 UserEntity
->stopForceHeadPitchInFollow();
398 _RotateUserUDVelocity
= 0;
399 }// keyboardRotationUD //
401 //-----------------------------------------------
402 // keyboardRotationCameraLR :
403 //-----------------------------------------------
404 void CUserControls::keyboardRotationCameraLR (bool left
, bool right
)
411 accel
+= ClientCfg
.RotAccel
;
412 _RotateCameraLRVelocity
= std::max (_RotateCameraLRVelocity
, ClientCfg
.RotKeySpeedMin
);
417 accel
-= ClientCfg
.RotAccel
;
418 _RotateCameraLRVelocity
= std::min (_RotateCameraLRVelocity
, -ClientCfg
.RotKeySpeedMin
);
420 updateVelocity (DT
, accel
, ClientCfg
.RotAccel
, ClientCfg
.RotKeySpeedMax
, _RotateCameraLRVelocity
);
423 appendCameraDeltaYaw(DT
*_RotateCameraLRVelocity
);
426 _RotateCameraLRVelocity
= 0;
429 //-----------------------------------------------
431 //-----------------------------------------------
432 void CUserControls::getMouseAngleMove(float &dx
, float &dy
)
437 // The mouse may still "StandardMove" ie through a CEventMouseMove
438 // This can happen because of the "Rotation Anti-Lag system" which
439 // start to rotate before the mouse is hid and message mode passed
440 // to updateFreeLookPos
442 // if the mouse position changed
443 if( EventsListener
.getMousePosX() != _LastFrameMousePosX
||
444 EventsListener
.getMousePosY() != _LastFrameMousePosY
)
446 // get the mouse movement delta
447 float dmpx
= EventsListener
.getMousePosX() - _LastFrameMousePosX
;
448 float dmpy
= EventsListener
.getMousePosY() - _LastFrameMousePosY
;
450 // simulate mickeys mode if there is a mouse device
451 dmpx
*= (float)Driver
->getWindowWidth();
452 dmpy
*= (float)Driver
->getWindowHeight();
454 // handle inverted mouse, if enabled
455 if (ClientCfg
.FreeLookInverted
) dmpy
= -dmpy
;
458 EventsListener
.updateFreeLookPos(dmpx
, dmpy
);
461 // If the mouse move on the axis X, with a CGDMouseMove
462 if (EventsListener
.isMouseAngleX())
463 dx
= -EventsListener
.getMouseAngleX();
465 // If the mouse move on the axis Y, with a CGDMouseMove
466 if (EventsListener
.isMouseAngleY())
467 dy
= EventsListener
.getMouseAngleY();
471 //-----------------------------------------------
473 // Manage a free look.
474 //-----------------------------------------------
475 void CUserControls::freeLook(bool fullMode
)
477 static bool leftButtonDownInFullMode
= false;
479 EventsListener
.enableMouseSmoothing(true);
480 // **** Mouse rotation => apply to user
482 getMouseAngleMove(dx
,dy
);
487 if( UserEntity
->canChangeFront() )
489 UserEntity
->rotate(dx
);
493 appendCameraDeltaYaw(dx
);
498 UserEntity
->rotHeadVertically(dy
);
499 UserEntity
->stopForceHeadPitchInFollow();
503 // **** Only in fullMode (longClick for instance)
506 _CurrentFrameFreeLookCalled
= true;
508 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
510 // FREE LOOK : Hide the cursor
511 // disable interface mouse handling.
512 CWidgetManager::getInstance()->enableMouseHandling(false);
513 // Get the cursor instance
514 CViewPointer
*cursor
= static_cast< CViewPointer
* >( CWidgetManager::getInstance()->getPointer() );
521 // **** special actions keys while in free look
522 if (isSwimming() || isRiding())
523 keyboardRotationLR (false, false);
525 keyboardRotationLR (Actions
.valide("strafe_left"), Actions
.valide("strafe_right"));
527 if(Actions
.valide("turn_left"))
528 _DirectionMove
|= left
;
530 if(Actions
.valide("turn_right"))
531 _DirectionMove
|= right
;
533 // **** Left mouse click while in freelook: forward
534 // NB: in commonMove() the case "rightButtonDown+leftButtonDown" is managed.
535 // but still important to test it here, in case of FreeLook mode (no right button down needed)
536 if(EventsListener
.isMouseButtonDown (leftButton
))
539 _DirectionMove
|= forward
;
540 _DirectionMove
&= ~backward
;
541 // Quit autowalk if first frame in this mode
542 if( !leftButtonDownInFullMode
)
543 _DirectionMove
&= ~autowalk
;
545 // Moving Break any Follow Mode
546 UserEntity
->disableFollow();
547 UserEntity
->moveTo(CLFECOMMON::INVALID_SLOT
, 0.0, CUserEntity::None
);
549 leftButtonDownInFullMode
= true;
553 leftButtonDownInFullMode
= false;
556 if( UserEntity
->canChangeFront() )
558 // **** reset delta camera
559 applyCameraDeltaYawToUser();
566 //-----------------------------------------------
568 // Manage the camera look.
569 //-----------------------------------------------
570 void CUserControls::cameraLook(bool fullMode
)
572 EventsListener
.enableMouseSmoothing(true);
573 // **** Mouse rotation => apply X to camera, Y to user
575 getMouseAngleMove(dx
,dy
);
579 appendCameraDeltaYaw(dx
);
580 // If the mouse move on the axis Y, cahnge the actual user pitch (not the delta camera)
583 UserEntity
->rotHeadVertically(dy
);
584 UserEntity
->stopForceHeadPitchInFollow();
588 // **** Only in fullMode (longClick for instance)
591 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
593 // CAMERA LOOK : Hide the cursor
594 // disable interface mouse handling.
595 CWidgetManager::getInstance()->enableMouseHandling(false);
596 // Get the cursor instance
597 CViewPointer
*cursor
= static_cast< CViewPointer
* >( CWidgetManager::getInstance()->getPointer() );
609 //-----------------------------------------------
611 // Manage some common actions.
612 // \todo GUIGUI : manage control before entities update, but view only after move
613 //-----------------------------------------------
614 void CUserControls::commonMove()
616 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
619 // RESET USER CAMERA YAW
620 testApplyCameraYawToUser();
624 CEventsListener::TWheelState wheelState
= EventsListener
.getWheelState(); // Done all the time, to reset the state
625 View
.changeCameraDist((wheelState
== CEventsListener::foreward
), (wheelState
== CEventsListener::backward
));
626 View
.changeCameraDist(Actions
.valide("camera_foreward"), Actions
.valide("camera_backward"));
628 View
.changeCameraHeight(Actions
.valide("camera_up"), Actions
.valide("camera_down"));
631 keyboardRotationUD(Actions
.valide("look_up"), Actions
.valide("look_down"));
635 if(Actions
.valide("forward") && !_NeedReleaseForward
)
638 _DirectionMove
|= forward
;
639 _DirectionMove
&= ~backward
;
642 if(!_LastFrameForward
)
644 // Start autowalk mode.
645 if(Actions
.valide("toggle_auto_walk"))
646 _DirectionMove
|= autowalk
;
647 // Leave autowalk mode.
649 _DirectionMove
&= ~autowalk
;
652 if( _NextForwardCancelMoveTo
)
654 _NextForwardCancelMoveTo
= false;
655 UserEntity
->moveTo(CLFECOMMON::INVALID_SLOT
, 0.0, CUserEntity::None
);
656 applyCameraDeltaYawToUser();
662 if(_LastFrameForward
)
663 if(!(_DirectionMove
& autowalk
))
664 _DirectionMove
&= ~forward
;
666 // since forward is released, forward is now enable again
667 if( !Actions
.valide("forward") && _NeedReleaseForward
)
669 _NeedReleaseForward
= false;
670 _NextForwardCancelMoveTo
= true;
676 if(Actions
.valide("backward"))
678 if( UserEntity
->mode()!=MBEHAV::MOUNT_SWIM
)
681 _DirectionMove
|= backward
;
682 _DirectionMove
&= ~forward
;
685 if(!_LastFrameBackward
)
687 // Start autowalk mode.
688 if(Actions
.valide("toggle_auto_walk"))
689 _DirectionMove
|= autowalk
;
690 // Leave autowalk mode.
692 _DirectionMove
&= ~autowalk
;
698 if(_LastFrameBackward
)
699 if(!(_DirectionMove
& autowalk
))
700 _DirectionMove
&= ~backward
;
703 // turn left or right will break the move-to, so forward is enable again here
704 if(Actions
.valide("turn_left") || Actions
.valide("turn_right"))
706 if( _NeedReleaseForward
)
708 _NeedReleaseForward
= false;
709 _NextForwardCancelMoveTo
= false;
710 // if free cam mode reset the view because move if target turned around camera may be
711 if( !ClientCfg
.AutomaticCamera
)
713 resetSmoothCameraDeltaYaw();
720 // Must be after forward and backward to know the autowalk direction
722 if(Actions
.valide("toggle_auto_walk"))
725 if(!_LastFrameAutowalk
)
727 // Leave autowalk if forward and backward not pushed and only if autowalk just pushed.
728 if((_DirectionMove
& autowalk
) && !Actions
.valide("forward") && !Actions
.valide("backward"))
729 _DirectionMove
&= ~(autowalk
|forward
|backward
);
733 _DirectionMove
|= autowalk
;
734 // If not backward, default is forward.
735 if(!(_DirectionMove
& backward
))
736 _DirectionMove
|= forward
;
746 // Left Click and Dbl Click
747 bool dblClickLeft
= false;
748 if(EventsListener
.isMouseButtonPushed(leftButton
))
750 _LeftClickStart
= T1
;
752 if( EventsListener
.isMouseButtonReleased (leftButton
) )
754 if(T1
<= _LeftClickEnd
+ CWidgetManager::getInstance()->getUserDblClickDelay())
761 // Right Click and Dbl Click
762 bool dblClickRight
= false;
763 if(EventsListener
.isMouseButtonPushed(rightButton
))
765 _RightClickStart
= T1
;
767 if( EventsListener
.isMouseButtonReleased (rightButton
) )
769 if(T1
<= _RightClickEnd
+ CWidgetManager::getInstance()->getUserDblClickDelay())
771 dblClickRight
= true;
776 _CurrentFrameFreeLookCalled
= false;
779 if(EventsListener
.isMouseButtonReleased (rightButton
))
781 // stop FreeLook (and restore mouse/cursor)
786 // if we are in follow mode, do a cameraLook instead
787 if(UserEntity
->follow() || UserEntity
->moveTo())
797 // if rightbutton release while left MouseButton UP
798 if ( EventsListener
.isMouseButtonReleased (rightButton
) && EventsListener
.isMouseButtonUp (leftButton
))
803 // Short Right Click -> Check Action
804 if((T1
-_RightClickStart
) <= _TimeLongClick
)
806 if(ClientCfg
.SelectWithRClick
|| R2::isEditionCurrent())
808 // nb : the ring editor also need that kind of events
809 execActionCursorPos(true,dblClickRight
);
812 // Launch Context Menu
813 if (R2::getEditor().getMode() != R2::CEditor::EditionMode
)
815 IM
->launchContextMenuInGame("ui:interface:game_context_menu");
820 // Give back the mouse handling to the interface.
821 CWidgetManager::getInstance()->enableMouseHandling(true);
822 EventsListener
.enableMouseSmoothing(false);
825 // if leftbutton release while right MouseButton UP
826 if ( EventsListener
.isMouseButtonReleased (leftButton
) && EventsListener
.isMouseButtonUp (rightButton
))
831 // Short Left Click -> Check Action
832 if((T1
-_LeftClickStart
) <= _TimeLongClick
)
834 execActionCursorPos(false, dblClickLeft
);
837 // Give back the mouse handling to the interface.
838 CWidgetManager::getInstance()->enableMouseHandling(true);
839 EventsListener
.enableMouseSmoothing(false);
843 // if Right button down
844 if (EventsListener
.isMouseButtonDown (rightButton
))
846 // NB: start the freeLook sooner than a longclick
847 if((T1
-_RightClickStart
) > _TimeBeforeMouseSlide
)
849 // if we are in follow mode, do a cameraLook on RightSlide, else do a freeLook
850 if(UserEntity
->follow() || UserEntity
->moveTo() || UserEntity
->isSit() || UserEntity
->isAFK())
851 // FullMode (hide mouse...) only if longClick
852 cameraLook(T1
-_RightClickStart
> _TimeLongClick
);
855 // FullMode (hide mouse...) only if longClick
856 freeLook(T1
-_RightClickStart
> _TimeLongClick
);
858 if( _NeedReleaseForward
)
860 _NeedReleaseForward
= false;
861 _NextForwardCancelMoveTo
= false;
862 // if free cam mode reset the view because move if target turned around camera may be
863 if( !ClientCfg
.AutomaticCamera
)
865 resetSmoothCameraDeltaYaw();
871 // if Right Mouse button is up
874 // mouse camera look: when the user hold down the left button for a time, while the right button is up
875 if (EventsListener
.isMouseButtonDown (leftButton
))
877 // NB: start the freeLook sooner than a longclick
878 if((T1
-_LeftClickStart
) > _TimeBeforeMouseSlide
)
879 // FullMode (hide mouse...) only if longClick
880 cameraLook(T1
-_LeftClickStart
> _TimeLongClick
);
883 if ( ! (isSwimming() || isRiding()))
886 if(Actions
.valide("strafe_left"))
887 _DirectionMove
|= left
;
889 if(Actions
.valide("strafe_right"))
890 _DirectionMove
|= right
;
893 if( !UserEntity
->isSit() && !UserEntity
->isAFK() )
895 // Test rotation keys
896 if( UserEntity
->canChangeFront() )
898 keyboardRotationLR (Actions
.valide("turn_left"), Actions
.valide("turn_right"));
902 keyboardRotationCameraLR (Actions
.valide("turn_left"), Actions
.valide("turn_right"));
911 // If both button are pressed in any case (whatever the _TimeBeforeMouseSlide time), treat as "forward"
912 static bool bothButtonPressed
= false;
913 if(EventsListener
.isMouseButtonDown (leftButton
) && EventsListener
.isMouseButtonDown (rightButton
))
916 _DirectionMove
|= forward
;
917 _DirectionMove
&= ~backward
;
918 // quit autowalk if entering both button pressed mode
919 if( !bothButtonPressed
)
921 _DirectionMove
&= ~autowalk
;
924 // Moving Break any Follow Mode
925 UserEntity
->disableFollow();
926 UserEntity
->moveTo(CLFECOMMON::INVALID_SLOT
, 0.0, CUserEntity::None
);
929 UserEntity
->sit(false);
930 // and no more in afk mode
931 UserEntity
->setAFK(false);
933 bothButtonPressed
= true;
937 bothButtonPressed
= false;
942 // Manage here the Release of Forward in any of third case (keyUP, leftButton in freeLook, and both buttons down)
943 if( (_DirectionMove
& forward
) && (_DirectionMove
& autowalk
)==0)
945 // freeLook() called and leftButton down => walk
946 bool walkInFreeLook
= _CurrentFrameFreeLookCalled
&& EventsListener
.isMouseButtonDown(leftButton
);
947 // both button down => walk too
948 bool walkWithBothButton
= (EventsListener
.isMouseButtonDown (leftButton
) && EventsListener
.isMouseButtonDown (rightButton
));
949 // if no forward action valid, quit forward
950 if(! (Actions
.valide("forward") || walkInFreeLook
|| walkWithBothButton
) )
951 _DirectionMove
&= ~forward
;
956 // CAMERA DELTA YAW ADDS
960 // reset too if middle button clicked
961 if(EventsListener
.isMouseButtonReleased(middleButton
))
963 resetSmoothCameraDeltaYaw();
966 // Handle rotations with keys
967 bool cameraLeft
,cameraRight
;
968 if( UserEntity
->isSit() || UserEntity
->isAFK() )
970 cameraLeft
= Actions
.valide("camera_turn_left") || Actions
.valide("turn_left");
971 cameraRight
= Actions
.valide("camera_turn_right") || Actions
.valide("turn_right");
975 cameraLeft
= Actions
.valide("camera_turn_left");
976 cameraRight
= Actions
.valide("camera_turn_right");
978 keyboardRotationCameraLR (cameraLeft
, cameraRight
);
982 if(_ResetSmoothCameraDeltaYaw
!=ResetCDYOff
)
984 // normalize in -Pi/Pi
985 _UserCameraDeltaYaw
= float(fmod(_UserCameraDeltaYaw
, 2.0f
*(float)Pi
));
986 if(_UserCameraDeltaYaw
>Pi
)
987 _UserCameraDeltaYaw
-= 2*float(Pi
);
988 else if(_UserCameraDeltaYaw
<-Pi
)
989 _UserCameraDeltaYaw
+= 2*float(Pi
);
992 if(_UserCameraDeltaYaw
<0)
994 _UserCameraDeltaYaw
+= DT
*ClientCfg
.CameraResetSpeed
;
995 if(_UserCameraDeltaYaw
>=0)
997 _UserCameraDeltaYaw
= 0;
998 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
1003 _UserCameraDeltaYaw
-= DT
*ClientCfg
.CameraResetSpeed
;
1004 if(_UserCameraDeltaYaw
<=0)
1006 _UserCameraDeltaYaw
= 0;
1007 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
1013 ////////////////////
1015 ////////////////////
1019 //-----------------------------------------------
1021 // Move the caracter according to the inputs.
1022 //-----------------------------------------------
1023 void CUserControls::move()
1025 // If the user is sit(), remove any move
1026 if( UserEntity
->isSit() || UserEntity
->isAFK() )
1027 _DirectionMove
= none
;
1029 if( _DirectionMove
!= none
)
1031 cancelActionsWhenMoving();
1034 // Forward/backward motion.
1035 float direction
= 0;
1036 if(_DirectionMove
&forward
)
1038 if( UserEntity
->mode() != MBEHAV::MOUNT_SWIM
)
1040 if(_DirectionMove
&backward
)
1043 // Changes the front velocity for the user.
1044 UserEntity
->frontVelocity(direction
);
1047 float directionStrafe
= 0;
1048 if( ! (isSwimming() || isRiding()) )
1050 if(_DirectionMove
&left
)
1051 directionStrafe
+= 1;
1052 if(_DirectionMove
&right
)
1053 directionStrafe
-= 1;
1055 else if ( isRiding() )
1057 // Check if the mount is able to run, and force walking mode if not, because the player can always switch the mode
1058 UserEntity
->checkMountAbleToRun();
1061 // Changes the lateral velocity for the user.
1062 UserEntity
->lateralVelocity(directionStrafe
);
1067 //-----------------------------------------------
1069 // Change the current Mode.
1070 //-----------------------------------------------
1071 void CUserControls::mode(const TMoveMode mode
)
1073 // Unlock the motion;
1076 // If the mode didn't change -> return.
1080 // Write that the last Mode end.
1084 interfaceModeStop();
1101 // Third Person View Mode
1110 // Backup the last Mode.
1112 // Set the new mode.
1115 // Write that the new Mode Start.
1119 interfaceModeStart();
1137 // Third Person View Mode
1147 //-----------------------------------------------
1149 // Return the string associated to the motion Mode.
1150 //-----------------------------------------------
1151 string
CUserControls::modeStr() const
1156 case CUserControls::InterfaceMode
:
1157 return "InterfaceMode";
1160 case CUserControls::AIMode
:
1164 case CUserControls::DeathMode
:
1168 case CUserControls::MountMode
:
1171 // Third Person View Mode
1172 case CUserControls::ThirdMode
:
1173 return "Third Person View Mode";
1177 return "Unknown Control Mode";
1181 //-----------------------------------------------
1183 //-----------------------------------------------
1184 // execActionCursorPos :
1185 // Execute action depending on the cursor position (left/right click).
1186 //-----------------------------------------------
1187 void CUserControls::execActionCursorPos(bool rightClick
, bool dblClick
)
1189 // Check there is no interface under the cursor.
1190 if( CWidgetManager::getInstance()->isMouseOverWindow())
1192 // Update the cursor.
1195 ContextCur
.execute(rightClick
,dblClick
);
1196 }// execActionCursorPos //
1199 //-----------------------------------------------
1200 // resetCameraDeltaYaw()
1201 //-----------------------------------------------
1202 void CUserControls::resetCameraDeltaYaw()
1204 _UserCameraDeltaYaw
= 0.f
;
1205 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
1209 //-----------------------------------------------
1210 // appendCameraDeltaYaw()
1211 //-----------------------------------------------
1212 void CUserControls::appendCameraDeltaYaw(float dYaw
)
1214 _UserCameraDeltaYaw
+= dYaw
;
1216 // Stop the smooth reset if any
1217 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
1221 //-----------------------------------------------
1222 // resetSmoothCameraDeltaYaw()
1223 //-----------------------------------------------
1224 void CUserControls::resetSmoothCameraDeltaYaw()
1226 // Force the reset if the user currently in follow/moveTo
1227 if(UserEntity
->follow() || UserEntity
->moveTo())
1228 _ResetSmoothCameraDeltaYaw
= ResetCDYForced
;
1230 _ResetSmoothCameraDeltaYaw
= ResetCDYOn
;
1234 //-----------------------------------------------
1235 // applyCameraDeltaYawToUser();
1236 //-----------------------------------------------
1237 void CUserControls::applyCameraDeltaYawToUser()
1239 // apply delta camera to the UserEntity
1240 UserEntity
->rotate(_UserCameraDeltaYaw
);
1242 _UserCameraDeltaYaw
= 0.f
;
1243 _ResetSmoothCameraDeltaYaw
= ResetCDYOff
;
1247 //-----------------------------------------------
1248 // testApplyCameraYawToUser()
1249 //-----------------------------------------------
1250 void CUserControls::testApplyCameraYawToUser()
1252 // only if not in "camera look" mode
1253 if(!EventsListener
.isMouseButtonDown(leftButton
))
1255 // if any of those actions start
1256 if( ( !_LastFrameForward
&& Actions
.valide("forward") && !_NeedReleaseForward
) ||
1257 ( !_LastFrameBackward
&& Actions
.valide("backward") ) ||
1258 ( !_LastFrameAutowalk
&& Actions
.valide("toggle_auto_walk") ) )
1259 /*( !_LastFrameStrafeLeft && Actions.valide("strafe_left") ) ||
1260 ( !_LastFrameStrafeRight && Actions.valide("strafe_right") ) ||
1261 ( !_LastFrameTurnLeft && Actions.valide("turn_left") ) ||
1262 ( !_LastFrameTurnRight && Actions.valide("turn_right") ) )*/
1264 applyCameraDeltaYawToUser();
1268 // if both buttons are pressed, then reset.
1269 // This is for the case where right button is pressed while left button was down for cameraLook()
1270 if( EventsListener
.isMouseButtonDown(leftButton
) && EventsListener
.isMouseButtonDown(rightButton
))
1272 applyCameraDeltaYawToUser();
1278 //-----------------------------------------------
1280 //-----------------------------------------------
1281 void CUserControls::commonSetView()
1283 // Set the view direction.
1286 camMat
.setRot(CVector(0,-1,0), CVector(1,0,0), CVector(0,0,1), true);
1287 camMat
.rotateZ(UserEntity
->frontYaw() + _UserCameraDeltaYaw
);
1288 camMat
.rotateX(float(UserEntity
->getHeadPitch()));
1289 View
.view(camMat
.getJ());
1291 // Update the mount direction.
1292 CEntityCL
*mount
= EntitiesMngr
.entity(UserEntity
->parent());
1295 mount
->front(UserEntity
->front());
1299 //-----------------------------------------------
1301 //-----------------------------------------------
1302 void CUserControls::startFreeLook()
1307 //-----------------------------------------------
1309 //-----------------------------------------------
1310 void CUserControls::stopFreeLook()
1312 EventsListener
.enableMouseSmoothing(false);
1317 // Give back the mouse handling to the interface.
1318 CWidgetManager::getInstance()->enableMouseHandling(true);
1322 //-----------------------------------------------
1323 // cancelActionsWhenMoving()
1324 //-----------------------------------------------
1325 void CUserControls::cancelActionsWhenMoving()
1327 if( UserEntity
->behaviour() == MBEHAV::EXTRACTING
||
1328 (UserEntity
->behaviour() >= MBEHAV::MAGIC_CASTING_BEHAVIOUR_BEGIN
&& UserEntity
->behaviour() <= MBEHAV::MAGIC_CASTING_BEHAVIOUR_END
) )
1330 UserEntity
->cancelAllPhrases();
1332 if( UserEntity
->behaviour() == MBEHAV::RANGE_ATTACK
)
1334 //UserEntity->disengage();