Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "JSInterface_GameView.h"
21 :
22 : #include "graphics/Camera.h"
23 : #include "graphics/GameView.h"
24 : #include "graphics/Terrain.h"
25 : #include "maths/FixedVector3D.h"
26 : #include "ps/Game.h"
27 : #include "ps/World.h"
28 : #include "ps/CLogger.h"
29 : #include "scriptinterface/FunctionWrapper.h"
30 : #include "simulation2/helpers/Position.h"
31 :
32 : namespace JSI_GameView
33 : {
34 : #define IMPLEMENT_BOOLEAN_SCRIPT_SETTING(NAME) \
35 : bool Get##NAME##Enabled() \
36 : { \
37 : if (!g_Game || !g_Game->GetView()) \
38 : { \
39 : LOGERROR("Trying to get a setting from GameView when it's not initialized!"); \
40 : return false; \
41 : } \
42 : return g_Game->GetView()->Get##NAME##Enabled(); \
43 : } \
44 : \
45 : void Set##NAME##Enabled(bool Enabled) \
46 : { \
47 : if (!g_Game || !g_Game->GetView()) \
48 : { \
49 : LOGERROR("Trying to set a setting of GameView when it's not initialized!"); \
50 : return; \
51 : } \
52 : g_Game->GetView()->Set##NAME##Enabled(Enabled); \
53 : }
54 :
55 0 : IMPLEMENT_BOOLEAN_SCRIPT_SETTING(Culling);
56 0 : IMPLEMENT_BOOLEAN_SCRIPT_SETTING(LockCullCamera);
57 0 : IMPLEMENT_BOOLEAN_SCRIPT_SETTING(ConstrainCamera);
58 :
59 : #undef IMPLEMENT_BOOLEAN_SCRIPT_SETTING
60 :
61 :
62 : #define REGISTER_BOOLEAN_SCRIPT_SETTING(NAME) \
63 : ScriptFunction::Register<&Get##NAME##Enabled>(rq, "GameView_Get" #NAME "Enabled"); \
64 : ScriptFunction::Register<&Set##NAME##Enabled>(rq, "GameView_Set" #NAME "Enabled");
65 :
66 12 : void RegisterScriptFunctions_Settings(const ScriptRequest& rq)
67 : {
68 12 : REGISTER_BOOLEAN_SCRIPT_SETTING(Culling);
69 12 : REGISTER_BOOLEAN_SCRIPT_SETTING(LockCullCamera);
70 12 : REGISTER_BOOLEAN_SCRIPT_SETTING(ConstrainCamera);
71 12 : }
72 :
73 : #undef REGISTER_BOOLEAN_SCRIPT_SETTING
74 :
75 0 : JS::Value GetCameraRotation(const ScriptRequest& rq)
76 : {
77 0 : if (!g_Game || !g_Game->GetView())
78 0 : return JS::UndefinedValue();
79 :
80 0 : const CVector3D rotation = g_Game->GetView()->GetCameraRotation();
81 0 : JS::RootedValue val(rq.cx);
82 0 : Script::CreateObject(rq, &val, "x", rotation.X, "y", rotation.Y);
83 0 : return val;
84 : }
85 :
86 0 : JS::Value GetCameraZoom()
87 : {
88 0 : if (!g_Game || !g_Game->GetView())
89 0 : return JS::UndefinedValue();
90 0 : return JS::NumberValue(g_Game->GetView()->GetCameraZoom());
91 : }
92 :
93 0 : JS::Value GetCameraPivot(const ScriptRequest& rq)
94 : {
95 0 : if (!g_Game || !g_Game->GetView())
96 0 : return JS::UndefinedValue();
97 :
98 0 : const CVector3D pivot = g_Game->GetView()->GetCameraPivot();
99 0 : JS::RootedValue pivotValue(rq.cx);
100 0 : Script::CreateObject(rq, &pivotValue, "x", pivot.X, "z", pivot.Z);
101 0 : return pivotValue;
102 : }
103 :
104 0 : JS::Value GetCameraPosition(const ScriptRequest& rq)
105 : {
106 0 : if (!g_Game || !g_Game->GetView())
107 0 : return JS::UndefinedValue();
108 :
109 0 : const CVector3D position = g_Game->GetView()->GetCameraPosition();
110 0 : JS::RootedValue positionValue(rq.cx);
111 0 : Script::CreateObject(rq, &positionValue, "x", position.X, "y", position.Y, "z", position.Z);
112 0 : return positionValue;
113 : }
114 :
115 : /**
116 : * Move camera to a 2D location.
117 : */
118 0 : void CameraMoveTo(entity_pos_t x, entity_pos_t z)
119 : {
120 0 : if (!g_Game || !g_Game->GetWorld() || !g_Game->GetView() || !g_Game->GetWorld()->GetTerrain())
121 0 : return;
122 :
123 0 : CTerrain* terrain = g_Game->GetWorld()->GetTerrain();
124 :
125 0 : CVector3D target;
126 0 : target.X = x.ToFloat();
127 0 : target.Z = z.ToFloat();
128 0 : target.Y = terrain->GetExactGroundLevel(target.X, target.Z);
129 :
130 0 : g_Game->GetView()->MoveCameraTarget(target);
131 : }
132 :
133 : /**
134 : * Set the camera to look at the given location.
135 : */
136 0 : void SetCameraTarget(float x, float y, float z)
137 : {
138 0 : if (!g_Game || !g_Game->GetView())
139 0 : return;
140 0 : g_Game->GetView()->MoveCameraTarget(CVector3D(x, y, z));
141 : }
142 :
143 : /**
144 : * Set the data (position, orientation and zoom) of the camera.
145 : */
146 0 : void SetCameraData(entity_pos_t x, entity_pos_t y, entity_pos_t z, entity_pos_t rotx, entity_pos_t roty, entity_pos_t zoom)
147 : {
148 0 : if (!g_Game || !g_Game->GetView())
149 0 : return;
150 :
151 0 : CVector3D pos(x.ToFloat(), y.ToFloat(), z.ToFloat());
152 :
153 0 : g_Game->GetView()->SetCamera(pos, rotx.ToFloat(), roty.ToFloat(), zoom.ToFloat());
154 : }
155 :
156 : /**
157 : * Start / stop camera following mode.
158 : * @param entityid unit id to follow. If zero, stop following mode
159 : */
160 0 : void CameraFollow(entity_id_t entityid)
161 : {
162 0 : if (!g_Game || !g_Game->GetView())
163 0 : return;
164 :
165 0 : g_Game->GetView()->FollowEntity(entityid, false);
166 : }
167 :
168 : /**
169 : * Start / stop first-person camera following mode.
170 : * @param entityid unit id to follow. If zero, stop following mode.
171 : */
172 0 : void CameraFollowFPS(entity_id_t entityid)
173 : {
174 0 : if (!g_Game || !g_Game->GetView())
175 0 : return;
176 :
177 0 : g_Game->GetView()->FollowEntity(entityid, true);
178 : }
179 :
180 0 : entity_id_t GetFollowedEntity()
181 : {
182 0 : if (!g_Game || !g_Game->GetView())
183 0 : return INVALID_ENTITY;
184 :
185 0 : return g_Game->GetView()->GetFollowedEntity();
186 : }
187 :
188 0 : CFixedVector3D GetTerrainAtScreenPoint(int x, int y)
189 : {
190 0 : CVector3D pos = g_Game->GetView()->GetCamera()->GetWorldCoordinates(x, y, true);
191 0 : return CFixedVector3D(fixed::FromFloat(pos.X), fixed::FromFloat(pos.Y), fixed::FromFloat(pos.Z));
192 : }
193 :
194 12 : void RegisterScriptFunctions(const ScriptRequest& rq)
195 : {
196 12 : RegisterScriptFunctions_Settings(rq);
197 :
198 12 : ScriptFunction::Register<&GetCameraRotation>(rq, "GetCameraRotation");
199 12 : ScriptFunction::Register<&GetCameraZoom>(rq, "GetCameraZoom");
200 12 : ScriptFunction::Register<&GetCameraPivot>(rq, "GetCameraPivot");
201 12 : ScriptFunction::Register<&GetCameraPosition>(rq, "GetCameraPosition");
202 12 : ScriptFunction::Register<&CameraMoveTo>(rq, "CameraMoveTo");
203 12 : ScriptFunction::Register<&SetCameraTarget>(rq, "SetCameraTarget");
204 12 : ScriptFunction::Register<&SetCameraData>(rq, "SetCameraData");
205 12 : ScriptFunction::Register<&CameraFollow>(rq, "CameraFollow");
206 12 : ScriptFunction::Register<&CameraFollowFPS>(rq, "CameraFollowFPS");
207 12 : ScriptFunction::Register<&GetFollowedEntity>(rq, "GetFollowedEntity");
208 12 : ScriptFunction::Register<&GetTerrainAtScreenPoint>(rq, "GetTerrainAtScreenPoint");
209 12 : }
210 3 : }
|