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) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "nel/3d/u_camera.h"
30 #include "../../input.h"
31 #include "../user_controls.h"
32 #include "../../actions_client.h"
33 #include "../../user_entity.h"
34 #include "../../view.h"
35 #include "../../interface_v3/interface_manager.h"
36 #include "../../time_client.h"
39 #include "../../r2/editor.h"
45 using namespace NLMISC
;
52 extern sint CompassMode
;
53 extern UCamera MainCam
;
54 extern CEventsListener EventsListener
; // Inputs Manager
59 //-----------------------------------------------
61 // Manage the Fly Mode (start).
62 //-----------------------------------------------
63 void CUserControls::aiModeStart()
65 // Third person view, user is selectable.
66 UserEntity
->selectable(true);
69 _FlyVerticalVelocity
= 0;
70 _FlyFrontVelocity
= 0;
71 _FlyLateralVelocity
= 0;
72 _RotateUserLRVelocity
= 0;
73 _RotateUserUDVelocity
= 0;
75 _InternalView
= false;
77 // Show/hide all or parts of the user body (after _InternaView is set).
78 UserEntity
->updateVisualDisplay();
81 //-----------------------------------------------
83 // Manage the Fly Mode (stop).
84 //-----------------------------------------------
85 void CUserControls::aiModeStop()
89 //-----------------------------------------------
91 // Manage the Fly Mode.
92 //-----------------------------------------------
93 void CUserControls::aiMode()
95 CInterfaceManager
*IM
= CInterfaceManager::getInstance ();
97 // Left Click and Dbl Click
98 bool dblClickLeft
= false;
99 if(EventsListener
.isMouseButtonPushed(leftButton
))
101 _LeftClickStart
= T1
;
103 if( EventsListener
.isMouseButtonReleased (leftButton
) )
105 if(T1
<= _LeftClickEnd
+ CWidgetManager::getInstance()->getUserDblClickDelay())
112 // Right Click and Dbl Click
113 bool dblClickRight
= false;
114 if(EventsListener
.isMouseButtonPushed(rightButton
))
116 _RightClickStart
= T1
;
118 if( EventsListener
.isMouseButtonReleased (rightButton
) )
120 if(T1
<= _RightClickEnd
+ CWidgetManager::getInstance()->getUserDblClickDelay())
122 dblClickRight
= true;
127 if (EventsListener
.isMouseButtonReleased (rightButton
))
129 // Short Right Click -> Check Action
130 if((T1
-_RightClickStart
) <= _TimeLongClick
)
132 if(ClientCfg
.SelectWithRClick
)
133 execActionCursorPos(true,dblClickRight
);
135 // Launch Context Menu
136 if (!R2::isEditionCurrent()) // context menu managed in a different fashion for R2ED
138 IM
->launchContextMenuInGame("ui:interface:game_context_menu");
143 EventsListener
.enableMouseSmoothing(false);
146 // Give back the mouse handling to the interface.
147 CWidgetManager::getInstance()->enableMouseHandling(true);
149 else if (EventsListener
.isMouseButtonDown (rightButton
))
151 if((T1
-_RightClickStart
) > _TimeLongClick
)
153 CWidgetManager::getInstance()->enableMouseHandling(false);
154 EventsListener
.enableMouseSmoothing(true);
155 // Get the cursor instance and hide.
156 CViewPointer
*cursor
= static_cast< CViewPointer
* >( CWidgetManager::getInstance()->getPointer() );
163 if (EventsListener
.isMouseAngleX())
168 m
.rotateZ(-EventsListener
.getMouseAngleX ());
169 View
.view((m
* View
.view()).normed());
172 if (EventsListener
.isMouseAngleY())
175 // Get the rotation axis.
176 CVector v
= View
.view() ^ CVector(0,0,1);
177 // Transform to a Quaternion
178 CQuat
quat(v
, EventsListener
.getMouseAngleY ());
180 // Get the rotation matrix.
183 // Create a front vector from the view.
184 CVector front
= View
.view();
188 v
= (m
* View
.view()).normed();
199 // Is the left click activated.
200 if (EventsListener
.isMouseButtonReleased (leftButton
))
201 execActionCursorPos(true,dblClickLeft
);
205 // Turn the camera to the left.
206 if(Actions
.valide("turn_left"))
208 CMatrix camMatrix
= MainCam
.getMatrix();
209 camMatrix
.rotateZ(DT
*ClientCfg
.RotKeySpeedMax
);
210 View
.view(camMatrix
.getJ());
212 // Turn the camera to the right.
213 if(Actions
.valide("turn_right"))
215 CMatrix camMatrix
= MainCam
.getMatrix();
216 camMatrix
.rotateZ(-DT
*ClientCfg
.RotKeySpeedMax
);
217 View
.view(camMatrix
.getJ());
221 if (Actions
.valide("look_up"))
223 CMatrix camMatrix
= MainCam
.getMatrix();
225 float angle
= DT
*ClientCfg
.RotKeySpeedMax
;
226 float curAngle
= asinf(camMatrix
.getJ().z
);
227 if(curAngle
+angle
> float(0.95*Pi
/2))
228 angle
= float(0.95*Pi
/2) - curAngle
;
230 camMatrix
.rotateX(angle
);
231 View
.view(camMatrix
.getJ());
234 if (Actions
.valide("look_down"))
236 CMatrix camMatrix
= MainCam
.getMatrix();
238 float angle
= -DT
*ClientCfg
.RotKeySpeedMax
;
239 float curAngle
= asinf(camMatrix
.getJ().z
);
240 if(curAngle
+angle
< float(-0.95*Pi
/2))
241 angle
= float(-0.95*Pi
/2) - curAngle
;
243 camMatrix
.rotateX(angle
);
244 View
.view(camMatrix
.getJ());
249 if (Actions
.valide("camera_up"))
250 accel
+= ClientCfg
.FlyAccel
;
252 if (Actions
.valide("camera_down"))
253 accel
-= ClientCfg
.FlyAccel
;
254 updateVelocity (DT
, accel
, ClientCfg
.FlyAccel
, ClientCfg
.Fly
, _FlyVerticalVelocity
);
256 // Action "Foraward" is valide -> Autowalk false, forward true.
258 if(Actions
.valide("forward"))
259 accel
+= ClientCfg
.FlyAccel
;
260 // Action "backward" is valide -> Autowalk false, backward true.
261 if(Actions
.valide("backward"))
262 accel
-= ClientCfg
.FlyAccel
;
263 updateVelocity (DT
, accel
, ClientCfg
.FlyAccel
, ClientCfg
.Fly
, _FlyFrontVelocity
);
265 // Action "strafe_left" is valide -> strafeLeft true.
267 if(Actions
.valide("strafe_left"))
268 accel
-= ClientCfg
.FlyAccel
;
269 // Action "strafe_right" is valide -> strafeRight true.
270 if(Actions
.valide("strafe_right"))
271 accel
+= ClientCfg
.FlyAccel
;
272 updateVelocity (DT
, accel
, ClientCfg
.FlyAccel
, ClientCfg
.Fly
, _FlyLateralVelocity
);
275 const CMatrix
&camMatrix
= MainCam
.getMatrix();
276 View
.viewPos(View
.viewPos() + camMatrix
.getI()*(_FlyLateralVelocity
*DT
) + camMatrix
.getJ()*(_FlyFrontVelocity
*DT
) + camMatrix
.getK()*(_FlyVerticalVelocity
*DT
));