Rise
The Vieneo Province
framemove.cpp
Go to the documentation of this file.
1 #include "Viewscreen.h"
2 #include "../MathUtilities.h"
3 #include "../Dialogs/InformationDialog.h"
4 
5 //#define SOFTRACKING
6 
7 bool Viewscreen::AssertTelemetry(const char* location, short id)
8 {
9  sprintf_s(msg, sizeof msg, "V::AssertTelemetry %s (%i)", location, id);
11 
12  msg[0] = 0;
13 
14  if (playerships[id].reference <= Reference::REF_ENUMMIN || playerships[id].reference >= Reference::REF_ENUMMAX)
15  {
16  sprintf_s(msg, sizeof msg, "Reference: %i", playerships[id].reference);
17  logger->Log(msg, Logger::Level::Debug);
18  }
19  if (_isnan(playerships[id].velocity.x) || isinf(playerships[id].velocity.x) || playerships[id].velocity.x > 100.0f || playerships[id].velocity.x < -100.0f)
20  {
21  sprintf_s(msg, sizeof msg, "Velocity I: %f", playerships[id].velocity.x);
22  logger->Log(msg, Logger::Level::Debug);
23  }
24  if (_isnan(playerships[id].velocity.y) || isinf(playerships[id].velocity.y) || playerships[id].velocity.y > 100.0f || playerships[id].velocity.y < -100.0f)
25  {
26  sprintf_s(msg, sizeof msg, "Velocity J: %f", playerships[id].velocity.y);
27  logger->Log(msg, Logger::Level::Debug);
28  }
29  if (_isnan(playerships[id].velocity.z) || isinf(playerships[id].velocity.z) || playerships[id].velocity.z > 100.0f || playerships[id].velocity.z < -100.0f)
30  {
31  sprintf_s(msg, sizeof msg, "Velocity K: %f", playerships[id].velocity.z);
32  logger->Log(msg, Logger::Level::Debug);
33  }
34  if (_isnan(playerships[id].veliter.x) || isinf(playerships[id].veliter.x) || playerships[id].veliter.x > 100.0f || playerships[id].veliter.x < -100.0f)
35  {
36  sprintf_s(msg, sizeof msg, "Velocity Iter I: %f", playerships[id].veliter.x);
37  logger->Log(msg, Logger::Level::Debug);
38  }
39  if (_isnan(playerships[id].veliter.y) || isinf(playerships[id].veliter.y) || playerships[id].veliter.y > 100.0f || playerships[id].veliter.y < -100.0f)
40  {
41  sprintf_s(msg, sizeof msg, "Velocity Iter J: %f", playerships[id].veliter.y);
42  logger->Log(msg, Logger::Level::Debug);
43  }
44  if (_isnan(playerships[id].veliter.z) || isinf(playerships[id].veliter.z) || playerships[id].veliter.z > 100.0f || playerships[id].veliter.z < -100.0f)
45  {
46  sprintf_s(msg, sizeof msg, "Velocity Iter K: %f", playerships[id].veliter.z);
47  logger->Log(msg, Logger::Level::Debug);
48  }
49  if (_isnan(playerships[id].velleft.x) || isinf(playerships[id].velleft.x) || playerships[id].velleft.x > 100.0f || playerships[id].velleft.x < -100.0f)
50  {
51  sprintf_s(msg, sizeof msg, "Velocity Left I: %f", playerships[id].velleft.x);
52  logger->Log(msg, Logger::Level::Debug);
53  }
54  if (_isnan(playerships[id].velleft.y) || isinf(playerships[id].velleft.y) || playerships[id].velleft.y > 100.0f || playerships[id].velleft.y < -100.0f)
55  {
56  sprintf_s(msg, sizeof msg, "Velocity Left J: %f", playerships[id].velleft.y);
57  logger->Log(msg, Logger::Level::Debug);
58  }
59  if (_isnan(playerships[id].velleft.z) || isinf(playerships[id].velleft.z) || playerships[id].velleft.z > 100.0f || playerships[id].velleft.z < -100.0f)
60  {
61  sprintf_s(msg, sizeof msg, "Velocity Left K: %f", playerships[id].velleft.z);
62  logger->Log(msg, Logger::Level::Debug);
63  }
64  if (_isnan(playerships[id].position.x) || isinf(playerships[id].position.x) || playerships[id].position.x > 1000000.0f || playerships[id].position.x < -1000000.0f)
65  {
66  sprintf_s(msg, sizeof msg, "Position X: %f", playerships[id].position.x);
67  logger->Log(msg, Logger::Level::Debug);
68  }
69  if (_isnan(playerships[id].position.y) || isinf(playerships[id].position.y) || playerships[id].position.y > 1000000.0f || playerships[id].position.y < -1000000.0f)
70  {
71  sprintf_s(msg, sizeof msg, "Position Y: %f", playerships[id].position.y);
72  logger->Log(msg, Logger::Level::Debug);
73  }
74  if (_isnan(playerships[id].position.z) || isinf(playerships[id].position.z) || playerships[id].position.z > 1000000.0f || playerships[id].position.z < -1000000.0f)
75  {
76  sprintf_s(msg, sizeof msg, "Position Z: %f", playerships[id].position.z);
77  logger->Log(msg, Logger::Level::Debug);
78  }
79  if (_isnan(playerships[id].positer.x) || isinf(playerships[id].positer.x) || playerships[id].positer.x > 1000000.0f || playerships[id].positer.x < -1000000.0f)
80  {
81  sprintf_s(msg, sizeof msg, "Position Iter I: %f", playerships[id].positer.x);
82  logger->Log(msg, Logger::Level::Debug);
83  }
84  if (_isnan(playerships[id].positer.y) || isinf(playerships[id].positer.y) || playerships[id].positer.y > 1000000.0f || playerships[id].positer.y < -1000000.0f)
85  {
86  sprintf_s(msg, sizeof msg, "Position Iter J: %f", playerships[id].positer.y);
87  logger->Log(msg, Logger::Level::Debug);
88  }
89  if (_isnan(playerships[id].positer.z) || isinf(playerships[id].positer.z) || playerships[id].positer.z > 1000000.0f || playerships[id].positer.z < -1000000.0f)
90  {
91  sprintf_s(msg, sizeof msg, "Position Iter K: %f", playerships[id].positer.z);
92  logger->Log(msg, Logger::Level::Debug);
93  }
94  if (_isnan(playerships[id].posleft.x) || isinf(playerships[id].posleft.x) || playerships[id].posleft.x > 1000000.0f || playerships[id].posleft.x < -1000000.0f)
95  {
96  sprintf_s(msg, sizeof msg, "Position Left I: %f", playerships[id].posleft.x);
97  logger->Log(msg, Logger::Level::Debug);
98  }
99  if (_isnan(playerships[id].posleft.y) || isinf(playerships[id].posleft.y) || playerships[id].posleft.y > 1000000.0f || playerships[id].posleft.y < -1000000.0f)
100  {
101  sprintf_s(msg, sizeof msg, "Position Left J: %f", playerships[id].posleft.y);
102  logger->Log(msg, Logger::Level::Debug);
103  }
104  if (_isnan(playerships[id].posleft.z) || isinf(playerships[id].posleft.z) || playerships[id].posleft.z > 1000000.0f || playerships[id].posleft.z < -1000000.0f)
105  {
106  sprintf_s(msg, sizeof msg, "Position Left K: %f", playerships[id].posleft.z);
107  logger->Log(msg, Logger::Level::Debug);
108  }
109  if (_isnan(playerships[id].pitchdeflect) || isinf(playerships[id].pitchdeflect) || playerships[id].pitchdeflect > 10.0f || playerships[id].pitchdeflect < -10.0f)
110  {
111  sprintf_s(msg, sizeof msg, "Pitchdeflect: %f", playerships[id].pitchdeflect);
112  logger->Log(msg, Logger::Level::Debug);
113  }
114  if (_isnan(playerships[id].rolldeflect) || isinf(playerships[id].rolldeflect) || playerships[id].rolldeflect > 10.0f || playerships[id].rolldeflect < -10.0f)
115  {
116  sprintf_s(msg, sizeof msg, "Rolldeflect: %f", playerships[id].rolldeflect);
117  logger->Log(msg, Logger::Level::Debug);
118  }
119  if (_isnan(playerships[id].yawdeflect) || isinf(playerships[id].yawdeflect) || playerships[id].yawdeflect > 10.0f || playerships[id].yawdeflect < -10.0f)
120  {
121  sprintf_s(msg, sizeof msg, "Yawdeflect: %f", playerships[id].yawdeflect);
122  logger->Log(msg, Logger::Level::Debug);
123  }
124  if (_isnan(playerships[id].pitch) || isinf(playerships[id].pitch) || playerships[id].pitch > 1000.0f || playerships[id].pitch < -1000.0f)
125  {
126  sprintf_s(msg, sizeof msg, "Pitch: %f", playerships[id].pitch);
127  logger->Log(msg, Logger::Level::Debug);
128  }
129  if (_isnan(playerships[id].roll) || isinf(playerships[id].roll) || playerships[id].roll > 1000.0f || playerships[id].roll < -1000.0f)
130  {
131  sprintf_s(msg, sizeof msg, "Roll: %f", playerships[id].roll);
132  logger->Log(msg, Logger::Level::Debug);
133  }
134  if (_isnan(playerships[id].yaw) || isinf(playerships[id].yaw) || playerships[id].yaw > 1000.0f || playerships[id].yaw < -1000.0f)
135  {
136  sprintf_s(msg, sizeof msg, "Yaw: %f", playerships[id].yaw);
137  logger->Log(msg, Logger::Level::Debug);
138  }
139  if (_isnan(playerships[id].acc.x) || isinf(playerships[id].acc.x) || playerships[id].acc.x > 1000.0f || playerships[id].acc.x < -1000.0f)
140  {
141  sprintf_s(msg, sizeof msg, "Acceleration I: %f", playerships[id].acc.x);
142  logger->Log(msg, Logger::Level::Debug);
143  }
144  if (_isnan(playerships[id].acc.y) || isinf(playerships[id].acc.y) || playerships[id].acc.y > 1000.0f || playerships[id].acc.y < -1000.0f)
145  {
146  sprintf_s(msg, sizeof msg, "Acceleration J: %f", playerships[id].acc.y);
147  logger->Log(msg, Logger::Level::Debug);
148  }
149  if (_isnan(playerships[id].acc.z) || isinf(playerships[id].acc.z) || playerships[id].acc.z > 1000.0f || playerships[id].acc.z < -1000.0f)
150  {
151  sprintf_s(msg, sizeof msg, "Acceleration K: %f", playerships[id].acc.z);
152  logger->Log(msg, Logger::Level::Debug);
153  }
154  if (_isnan(playerships[id].acciter.x) || isinf(playerships[id].acciter.x) || playerships[id].acciter.x > 1000.0f || playerships[id].acciter.x < -1000.0f)
155  {
156  sprintf_s(msg, sizeof msg, "Acc Iter I: %f", playerships[id].acciter.x);
157  logger->Log(msg, Logger::Level::Debug);
158  }
159  if (_isnan(playerships[id].acciter.y) || isinf(playerships[id].acciter.y) || playerships[id].acciter.y > 1000.0f || playerships[id].acciter.y < -1000.0f)
160  {
161  sprintf_s(msg, sizeof msg, "Acc Iter J: %f", playerships[id].acciter.y);
162  logger->Log(msg, Logger::Level::Debug);
163  }
164  if (_isnan(playerships[id].acciter.z) || isinf(playerships[id].acciter.z) || playerships[id].acciter.z > 1000.0f || playerships[id].acciter.z < -1000.0f)
165  {
166  sprintf_s(msg, sizeof msg, "Acc Iter K: %f", playerships[id].acciter.z);
167  logger->Log(msg, Logger::Level::Debug);
168  }
169  if (_isnan(playerships[id].accleft.x) || isinf(playerships[id].accleft.x) || playerships[id].accleft.x > 1000.0f || playerships[id].accleft.x < -1000.0f)
170  {
171  sprintf_s(msg, sizeof msg, "Acc Left I: %f", playerships[id].accleft.x);
172  logger->Log(msg, Logger::Level::Debug);
173  }
174  if (_isnan(playerships[id].accleft.y) || isinf(playerships[id].accleft.y) || playerships[id].accleft.y > 1000.0f || playerships[id].accleft.y < -1000.0f)
175  {
176  sprintf_s(msg, sizeof msg, "Acc Left J: %f", playerships[id].accleft.y);
177  logger->Log(msg, Logger::Level::Debug);
178  }
179  if (_isnan(playerships[id].accleft.z) || isinf(playerships[id].accleft.z) || playerships[id].accleft.z > 1000.0f || playerships[id].accleft.z < -1000.0f)
180  {
181  sprintf_s(msg, sizeof msg, "Acc Left K: %f", playerships[id].accleft.z);
182  logger->Log(msg, Logger::Level::Debug);
183  }
184  if (_isnan(playerships[id].tx) || isinf(playerships[id].tx) || playerships[id].tx > 1.0f || playerships[id].tx < -1.0f)
185  {
186  sprintf_s(msg, sizeof msg, "Thrust I: %f", playerships[id].tx);
187  logger->Log(msg, Logger::Level::Debug);
188  }
189  if (_isnan(playerships[id].ty) || isinf(playerships[id].ty) || playerships[id].ty > 1.0f || playerships[id].ty < -1.0f)
190  {
191  sprintf_s(msg, sizeof msg, "Thrust J: %f", playerships[id].ty);
192  logger->Log(msg, Logger::Level::Debug);
193  }
194  if (_isnan(playerships[id].tz) || isinf(playerships[id].tz) || playerships[id].tz > 1.0f || playerships[id].tz < -1.0f)
195  {
196  sprintf_s(msg, sizeof msg, "Thrust K: %f", playerships[id].tz);
197  logger->Log(msg, Logger::Level::Debug);
198  }
199  if (_isnan(playerships[id].orientation.x) || isinf(playerships[id].orientation.x) || playerships[id].orientation.x > 10.0f || playerships[id].orientation.x < -10.0f)
200  {
201  sprintf_s(msg, sizeof msg, "Orientation X: %f", playerships[id].orientation.x);
202  logger->Log(msg, Logger::Level::Debug);
203  }
204  if (_isnan(playerships[id].orientation.y) || isinf(playerships[id].orientation.y) || playerships[id].orientation.y > 10.0f || playerships[id].orientation.y < -10.0f)
205  {
206  sprintf_s(msg, sizeof msg, "Orientation Y: %f", playerships[id].orientation.y);
207  logger->Log(msg, Logger::Level::Debug);
208  }
209  if (_isnan(playerships[id].orientation.z) || isinf(playerships[id].orientation.z) || playerships[id].orientation.z > 10.0f || playerships[id].orientation.z < -10.0f)
210  {
211  sprintf_s(msg, sizeof msg, "Orientation Z: %f", playerships[id].orientation.z);
212  logger->Log(msg, Logger::Level::Debug);
213  }
214  if (_isnan(playerships[id].orientation.w) || isinf(playerships[id].orientation.w) || playerships[id].orientation.w > 10.0f || playerships[id].orientation.w < -10.0f)
215  {
216  sprintf_s(msg, sizeof msg, "Orientation W: %f", playerships[id].orientation.w);
217  logger->Log(msg, Logger::Level::Debug);
218  }
219 
220  //sprintf_s(msg, sizeof msg, "ID: %i (%i) (ours is %i (%i))", id, playerships[id].vehicleId, 0, playerships[0].vehicleId);
221  //logger->Log(msg, Logger::Level::Debug);
222  //sprintf_s(msg, sizeof msg, "Matrix: %f %f %f %f", playerships[id].matrixWorld._11, playerships[id].matrixWorld._12, playerships[id].matrixWorld._13, playerships[id].matrixWorld._14);
223  //logger->Log(msg, Logger::Level::Debug);
224  //sprintf_s(msg, sizeof msg, "Matrix: %f %f %f %f", playerships[id].matrixWorld._21, playerships[id].matrixWorld._22, playerships[id].matrixWorld._23, playerships[id].matrixWorld._24);
225  //logger->Log(msg, Logger::Level::Debug);
226  //sprintf_s(msg, sizeof msg, "Matrix: %f %f %f %f", playerships[id].matrixWorld._31, playerships[id].matrixWorld._32, playerships[id].matrixWorld._33, playerships[id].matrixWorld._34);
227  //logger->Log(msg, Logger::Level::Debug);
228  //sprintf_s(msg, sizeof msg, "Matrix: %f %f %f %f", playerships[id].matrixWorld._41, playerships[id].matrixWorld._42, playerships[id].matrixWorld._43, playerships[id].matrixWorld._44);
229  //logger->Log(msg, Logger::Level::Debug);
230 
231  if (msg[0])
232  {
233  sprintf_s(msg, sizeof msg, "Trapped a telemetry violation: %s (slot %i id %i)", location, id, playerships[id].vehicleId);
234  logger->Log(msg, Logger::Level::Error);
235 
236  if (id == 0)
237  {
238  DumpSofTracking();
239  deathinhibit = 15.0f;
240  dead = 8; // vessel had a problem
241  }
242 
243  gameclass->ToggleFullScreen(false);
244  MessageBox(DXUTGetHWND(), L"Encountered a telemetry error!\n\nWe automatically reported the details.\n\nSorry for the inconvenience and thanks for helping us track down a bug!", L"Program fault!", MB_OK | MB_ICONERROR);
245 
246  return false;
247  }
248 
249  logger->AddToCallStack("Viewscreen::AssertTelemetry END");
250 
251  return true;
252 }
253 
254 void Viewscreen::OutsideView(bool viewOutside)
255 {
256  outside = viewOutside;
262 }
263 
264 RECT Viewscreen::WhichRoom(const std::vector<tagRECT>& rooms, float x, float y, short* roomIndex)
265 {
266  for (size_t i = 0; i < rooms.size(); i++)
267  {
268  const RECT room = rooms.at(i);
269  if (x >= room.left && x <= room.right && y <= room.top && y >= room.bottom)
270  {
271  *roomIndex = static_cast<short>(i);
272  return room;
273  }
274  }
275  *roomIndex = -1;
276  return {};
277 }
278 
279 //-----------------------------------------------------------------------------
280 // Name: FrameMove()
281 // Desc: Animates the scene
282 //-----------------------------------------------------------------------------
283 void Viewscreen::OnFrameMove(double fTime, float fElapsedTime)
284 {
285  logger->AddToCallStack("Viewscreen::OnFrameMove");
286 
287  if (!g_bEnabled)
288  return;
289 
290  HRESULT hr;
291 
293  //QueryPerformanceCounter(&newTime);
294 
295  //float fElapsedTime = static_cast<float>(newTime.QuadPart - oldTime.QuadPart) / frequency.QuadPart;
296  //sprintf_s(msg, sizeof msg, "old %.3f new %.3f", oldElapsedTime, fElapsedTime);
297  //logger->Log(msg);
298 
299  //oldTime = newTime;
300 
301 
302  gameclass->bus->NormalAcceleration = sumofforces; // from previous frame
303  sumofforces = centerC; // reset sum of forces counter
304  sofTracking.clear();
305  causechain = 0;
306 
308 
310  D3DXVec3Normalize(&posnorml, &position);
311 
312  const D3DXVECTOR2 latlng = CalculateLatLng(playerships[0].position);
313  gameclass->bus->LatitudeDeg = latlng.x;
314  gameclass->bus->LongitudeDeg = latlng.y;
315  gameclass->bus->LatitudeRad = D3DXToRadian(latlng.x);
316  gameclass->bus->tcp = ptrGrid->tcp;
317 
318  gameclass->bus->ProgramTime = fTime;
319 
320  short t, r, s;
321 
322 
323 #ifndef _DEBUG
324  // Needs to be done before we manipulate fElapsedTime
325  const float m_fFPS = DXUTGetFPS();
326  lowframeTime = 0.0f;
327  const float minFrameRate = (DXUTGetHWNDFocus() == DXUTGetHWND()) ? 12.0f : 4.0f;
328  if (m_fFPS < minFrameRate)
329  {
330  lowframeTime += fElapsedTime;
331  if (lowframeTime > 5.0f)
332  {
333  sprintf_s(msg, sizeof msg, "FPS %.2f below threshold %.2f for %.1f seconds: %.1f", m_fFPS, minFrameRate, lowframeTime, fElapsedTime);
334  logger->Log(msg, Logger::Level::Debug);
335  }
336  if (lowframeTime > 60.0f && m_fFPS < 4.0f)
337  {
338  strcpy_s(msg, sizeof msg, "We're sorry, your computer does not have sufficient processing power to run this program.");
339  // Please check that your graphics drivers are up-to-date and close any other applications that may be using CPU and RAM to try again
340  logger->Log(msg, Logger::Level::Fatal);
341  }
342  }
343  else
344  {
345  lowframeTime = 0.0f;
346  }
347 #endif
348 
349  frameRateHeartbeat += fElapsedTime;
350  if (frameRateHeartbeat > 300.0f) // 5 minutes
351  {
352  frameRateHeartbeat = 0;
353  SClientPacket outpacket; // NOLINT
354  outpacket.type = 20; // Frame rate heartbeat
355  outpacket.f_x = DXUTGetFPS();
356  outpacket.f_y = 0.0f; // NULL static_cast<float>(frequency.QuadPart);
357  outpacket.f_z = 0.0f; // NULL
358  outpacket.f_w = 0.0f; // NULL
359  gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
360  }
361 
362 
363 
364  // Too short, fastest monitor in the world on 4/19/2020 is 360 HZ
365  if (fElapsedTime < 0.00277778f)
366  {
367  sprintf_s(msg, sizeof msg, "FrameMove() elapsed %.3f with deathinhibit %.3f set 0.00277778!", fElapsedTime, deathinhibit);
368  logger->Log(msg);
369  // Fast machines end up having too small of an elapsed time variable...
370  // We should never see these because of VSYNC?
371  const auto sleepMs = static_cast<DWORD>((0.00277778f - fElapsedTime) * 1000.0f);
372  Sleep(sleepMs);
373  fElapsedTime = 0.00277778f;
374  }
375 
376  // Too long
377  if (fElapsedTime > 1.0f)
378  {
379  sprintf_s(msg, sizeof msg, "FrameMove() elapsed %.3f with deathinhibit %.3f set 1.0f!", fElapsedTime, deathinhibit);
380  logger->Log(msg);
381  fElapsedTime = 1.0f;
382  }
383 
384 
385 
386  // for autoflyte acknowledgement indicators
387  verticaltime -= fElapsedTime;
388  if (verticaltime < 0.0f)
389  verticaltime = 0.0f;
390  lateraltime -= fElapsedTime;
391  if (lateraltime < 0.0f)
392  lateraltime = 0.0f;
393 
394 
395  // Shockwaves
396  for (size_t i = 0; i < shockwaves.size(); i++)
397  {
398  SShockWave* shockwave = &shockwaves.at(i);
399  shockwave->timetoshock -= fElapsedTime;
400  if (shockwave->timetoshock <= 0.0f)
401  {
402  shockwave->shockramp += shockwave->shockspeed * fElapsedTime;
403  if (shockwave->shockramp >= 2.0f)
404  {
405  shockwaves.erase(shockwaves.begin() + i);
406  break;
407  }
408 
409  float f_temp;
410  if (shockwave->shockramp > 1.0f)
411  f_temp = 2.0f - shockwave->shockramp;
412  else
413  f_temp = shockwave->shockramp;
414 
415  sprintf_s(msg, sizeof msg, "X%7.3f Y%7.3f Z%7.3f shockmag #%i", -f_temp * shockwave->shockmag.x * oneOvergForceKmSSC / fElapsedTime, -f_temp * shockwave->shockmag.y * oneOvergForceKmSSC / fElapsedTime, -f_temp * shockwave->shockmag.z * oneOvergForceKmSSC / fElapsedTime, i);
416  sofTracking.emplace_back(msg);
417 
418  sumofforces.x -= f_temp * shockwave->shockmag.x;
419  sumofforces.y -= f_temp * shockwave->shockmag.y;
420  sumofforces.z -= f_temp * shockwave->shockmag.z;
421  causechain = 10;
422  }
423  }
424 
425  // monitor interlacing
426  interlace += fElapsedTime;
427  if (interlace > 0.04f)
428  {
429  interlace = 0.0f;
430  if (flicker == 0)
431  flicker = 1;
432  else
433  flicker = 0;
434  }
435 
436  // Lamp test
437  lampTest -= fElapsedTime;
438  if (lampTest < 0.0f)
439  lampTest = 0.0f;
440 
441 
442 #ifdef _DEBUG
443  displaysFrameMoveTimer->startTimer();
444 #endif
445  // Display processing
446  gameclass->displays->FrameMove(fElapsedTime);
447 #ifdef _DEBUG
448  displaysFrameMoveTimer->stopTimer();
449 #endif
450 
451 
452 #ifdef _DEBUG
453  modulesFrameMoveTimer->startTimer();
454 #endif
455  // Module processing
456  for (UINT i = 0; i < gameclass->modules.size(); i++)
457  gameclass->modules.at(i)->FrameMove(fElapsedTime);
458 #ifdef _DEBUG
459  modulesFrameMoveTimer->stopTimer();
460 #endif
461 
462 
463  AssertTelemetry("FrameMove::OnFrameMove1", 0);
464 
465 
466 
467  D3DXMATRIX matrixTemp;
468 
469 
470  g_bRunning = true;
471 
472 
473  for (t = 0; t < 2; t++)
474  {
475  weapontimer[t] += fElapsedTime;
476  if (ourcockpit.vdat.weapontype[t] == 1 && weapontimer[t] > weaponfuzerreadyC)
478  else if (ourcockpit.vdat.weapontype[t] == 2 && weapontimer[t] > weaponsinkerreadyC)
480  else if (ourcockpit.vdat.weapontype[t] == 3 && weapontimer[t] > weaponlongarmreadyC)
482  }
483 
484 
485  deathinhibit -= fElapsedTime;
486  if (deathinhibit < 0.0f)
487  deathinhibit = 0.0f;
488 
489  // New hour
490  if ((g_UniverseTime + fTime) >= 3600.0f)
491  {
492  f_Uphours++;
493  g_UniverseTime = static_cast<float>(fTime) + g_UniverseTime - 3600.0f;
494  DXUTGetGlobalTimer()->Reset();
495  }
496 
497 
498  D3DXVECTOR3 result;
499 
500  static float m_fAnimateFrame = 0.0f;
501  m_fAnimateFrame += fElapsedTime;
502  if (m_fAnimateFrame > 0.0416667f)
503  {
504  m_fAnimateFrame -= 0.0416667f; // 24 fps
505  advanceframe = true;
506 
508  flasher += 0.0416667f;
509  if (flasher > 1.0f)
510  flasher = 0.0f;
511 
512  // Fireworks
513  for (t = 0; t < fireworksC; t++)
514  {
515  if (fireworks[t].inuse)
516  {
517  fireworks[t].texture++;
518  if (fireworks[t].texture >= firework1C && fireworks[t].type == 0)
519  fireworks[t].inuse = false;
520  else if (fireworks[t].texture >= firework2C && fireworks[t].type == 1)
521  fireworks[t].inuse = false;
522  else if (fireworks[t].texture >= firework3C && fireworks[t].type == 2)
523  fireworks[t].inuse = false;
524  }
525  }
526 
527  heartloop++;
528  if (heartloop == heartanimateC)
529  heartloop = 0;
530  }
531  else
532  advanceframe = false;
533 
534 
535  // water animation
536  H2Ooffsetu += 0.001f * fElapsedTime; // 2 m/s ... 2000 meters means 1000 seconds ... 1 UV per 1000 seconds
537  if (H2Ooffsetu > 1.0f)
538  H2Ooffsetu--;
539 
540 #ifdef _DEBUG
541  inputFrameMoveTimer->startTimer();
542 #endif
543  if (!dead)
544  {
545  ptrKeyboard->Update(fElapsedTime);
546  ptrJoystick->Update(fElapsedTime);
547  ptrFreeTrack->Poll();
548  }
549 #ifdef _DEBUG
550  inputFrameMoveTimer->stopTimer();
551 #endif
552 
553 
554 #ifdef _DEBUG
555  otherFrameMoveTimer->startTimer();
556 #endif
557 
558 
559 
560  // turned off 5/22/2018 because mouse for steering is pissing me off
561  /*
562  if (!game->gameclass->config.g_bMoveJoystick && game->gameclass->GUI->g_bLeftDown && !dead &&
563  game->gameclass->GUI->cursoroverwindow == -1 && !game->gameclass->GUI->g_bDragging)
564  {
565  // make sure ptClick is within the view region (not letterboxes)
566  if (game->gameclass->GUI->ptClick.x >= 0 && game->gameclass->GUI->ptClick.x <= (long)pp->Width &&
567  game->gameclass->GUI->ptClick.y >= 0 && game->gameclass->GUI->ptClick.y <= (long)pp->Height)
568  {
569  if (playerships[0].reference != REF_ONGROUND)
570  {
571  if (game->gameclass->bus->AFCS->CurrentLateralMode == Bus::Afcs::LateralModes::Takeoff && g_bCoupled)
572  {
573  desiredroll = (float)(game->gameclass->GUI->ptCursor.x - (long)pp->Width / 2)*0.0025f;
574  if (desiredroll > limiterC)
575  desiredroll = limiterC;
576  else if (desiredroll < -limiterC)
577  desiredroll = -limiterC;
578  }
579  else
580  {
581  game->roll = (float)(game->gameclass->GUI->ptCursor.x - (long)pp->Width / 2)*0.0025f;
582  if (game->roll > limiterC)
583  game->roll = limiterC;
584  else if (game->roll < -limiterC)
585  game->roll = -limiterC;
586  }
587  }
588  else
589  {
590  game->yaw = (float)(game->gameclass->GUI->ptCursor.x - (long)pp->Width / 2)*0.0025f;
591  float limit = limiterC*2.0f*0.001f / max(0.001f, fabsf(groundspeed));
592  if (game->yaw > limit)
593  game->yaw = limit;
594  else if (game->yaw < -limit)
595  game->yaw = -limit;
596  }
597 
598  if (game->gameclass->bus->AFCS->CurrentVerticalMode == Bus::Afcs::VerticalModes::Takeoff && g_bCoupled)
599  {
600  desiredvsi = (float)(game->gameclass->GUI->ptCursor.y - (long)pp->Height / 2)*0.0025f;
601  }
602  else
603  {
604  game->pitch = (float)(game->gameclass->GUI->ptCursor.y - (long)pp->Height / 2)*0.0025f;
605  if (game->pitch > limiterC)
606  game->pitch = limiterC;
607  else if (game->pitch < -limiterC)
608  game->pitch = -limiterC;
609  }
610  }
611  }
612  */
613  D3DXVECTOR3 cross;
614  D3DXQUATERNION quaternionTemp;
615 
616  float f_temp;
617 
618 
619  // Orbit processor for non-human-driven objects, not necessary here, no access protected
620  // should be done in heirarchy, the stars and sun then...
621  // the planets (including Iomere)
622  // the moons (including Vieneo)
623  // then do our barycentric trick to keep the ground steady
624  // then do the cloud layers
625  // and the docks
626  for (t = maxdockC; t < maxstarC; t++)
627  {
629 
630  if (t == BCLobjC)
631  {
632  // the rotprog for BCLobjC doesn't relate to this since we are looking at a section
633  // also want it to be based on our latitude
634  // equator=0, 15=1, 30=0, 45=-1, 60=0, 75=1, 90=0
635  f_temp = sinf(gameclass->bus->LatitudeRad*6.06f);
636  // supposed to take 6.06 days for clouds to circle, this texture adjustment runs for 8km
637  // so we take circumference / 8 is how much in 6 days then per day hour min sec
638  allobjects[t].rotprog += 0.007f*f_temp*fElapsedTime;
639  if (allobjects[t].rotprog >= 1.0f)
640  allobjects[t].rotprog--;
641  else if (allobjects[t].rotprog <= 0.0f)
642  allobjects[t].rotprog++;
643  }
644  else
645  {
646  if (allobjects[t].rotation > 0.0f)
647  {
648  const double dTemp = static_cast<double>(D3DX_TAU) / static_cast<double>(allobjects[t].rotation);
649  double test = static_cast<double>(allobjects[t].rotoffset);
650  test += static_cast<double>(f_Uphours) * 3600.0 / dTemp;
651  test -= floor(test);
652  test += (static_cast<double>(g_UniverseTime) + fTime) / dTemp;
653  test -= floor(test);
654  test *= static_cast<double>(D3DX_TAU);
655  allobjects[t].rotprog = static_cast<float>(test);
656 
657  /*f_temp = D3DX_TAU / allobjects[t].rotation;
658  allobjects[t].rotprog = allobjects[t].rotoffset;
659  allobjects[t].rotprog += f_Uphours * 3600.0f / f_temp;
660  allobjects[t].rotprog -= floorf(allobjects[t].rotprog);
661  allobjects[t].rotprog += (g_UniverseTime + (float)fTime) / f_temp;
662  allobjects[t].rotprog -= floorf(allobjects[t].rotprog);
663  allobjects[t].rotprog *= D3DX_TAU;*/
664  }
665  }
666 
667  if (allobjects[t].type != -1) // Don't rotate Vieneo, barycentric
668  {
669  D3DXMatrixRotationZ(&matrixTemp, allobjects[t].rotprog);
670  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &matrixTemp, &allobjects[t].matrixWorld);
671 
672  if (allobjects[t].revolution > 0.0f)
673  {
674  const double dTemp = static_cast<double>(D3DX_TAU) / static_cast<double>(allobjects[t].revolution);
675  double test = static_cast<double>(allobjects[t].revoffset);
676  test += static_cast<double>(f_Uphours) * 3600.0 / dTemp;
677  test -= floor(test);
678  test += (static_cast<double>(g_UniverseTime) + fTime) / dTemp;
679  test -= floor(test);
680  test *= static_cast<double>(D3DX_TAU);
681  allobjects[t].revprog = static_cast<float>(test);
682 
683  /*f_temp = D3DX_TAU / allobjects[t].revolution;
684  allobjects[t].revprog = allobjects[t].revoffset;
685  allobjects[t].revprog += f_Uphours * 3600.0f / f_temp;
686  allobjects[t].revprog -= floorf(allobjects[t].revprog);
687  allobjects[t].revprog += (g_UniverseTime + (float)fTime) / f_temp;
688  allobjects[t].revprog -= floorf(allobjects[t].revprog);
689  allobjects[t].revprog *= D3DX_TAU;*/
690  }
691 
692  // Rotation after tilt adjustment is remember LEFT=LOCAL
693  D3DXMatrixRotationZ(&matrixTemp, allobjects[t].revprog);
694  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
695  D3DXMatrixRotationX(&matrixTemp, allobjects[ourmoonC].tilt); // Rotate plane by tilt
696  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
697  D3DXMatrixRotationZ(&matrixTemp, -allobjects[ourmoonC].rotprog); // -barycentric
698  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
699  }
700 
701  // Save it so everyone can use it before it is mucked up
703 
704  // lets try the deal where the range has nothing to do with the matrix;
705 // allobjects[t].position.x=0.0f;
706 // allobjects[t].position.y=allobjects[t].range;
707 // allobjects[t].position.z=0.0f;
708 // D3DXVec3TransformCoord( &allobjects[t].position, &allobjects[t].position, &allobjects[t].matrixWorld );
709 
710  allobjects[t].position.x = -allobjects[t].matrixWorld._41;
711  allobjects[t].position.y = -allobjects[t].matrixWorld._42;
712  allobjects[t].position.z = -allobjects[t].matrixWorld._43;
713 
714  if (allobjects[t].type != -5 && allobjects[t].type != -7) // Static Stars and sun are always same distance from us
715  {
716  D3DXMatrixTranslation(&matrixTemp, playerships[0].position.x, playerships[0].position.y, playerships[0].position.z);
717  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
718  }
719  else if (allobjects[t].type == -7) // We grab sunlight parameters for Yonmara
720  {
721  // Universe coordinates for sunlight parameters
722  cross = allobjects[t].position;
723 
724  // Sunlight
725  D3DXVec3Normalize(&cross, &cross);
726  sunlight.Direction = cross; // Doesn't have to be normalized but later elevation dot
727  DXUTGetD3D9Device()->SetLight(0, &sunlight);
728 
729  // Clock
730  const float sunLogitudeNorm = CalculateLatLng(cross).y / 180.0f;
731  const float ourLogitudeNorm = (roundf(gameclass->bus->LongitudeDeg / 24.0f) * 24.0f) / 180.0f;
732  // 0 is midnight, 0.5 is 12 noon, 1 is midnight ... at .9 it is 23
733  float diff = (ourLogitudeNorm - sunLogitudeNorm) * 0.5f + 0.5f;
734  // we want 0 is 4am and 1 is 4pm
735  if (diff < 0.0f) diff += 1.0f;
736  else if (diff > 1.0f) diff -= 1.0f;
737  diff *= 24.0f; // to hours
738  gameclass->bus->LocalTimeHours = floorf(diff);
739  diff -= gameclass->bus->LocalTimeHours;
740  diff *= 36.075f;
741  gameclass->bus->LocalTimeMinutes = floorf(diff);
742  }
743 
744  if (t == UCLobjC && f_MSL != -1.0f) // upper cloud layer
745  {
746  // Always running closest facet regardless if on surface or in orbit
747  // Always running closest macro facet
748  float dist[4500];
749  bool swapflag;
750  D3DVERTEX temp_vertex2[3];
751  D3DXVECTOR3 temp_vector[3], temp, result1;
752  D3DXMatrixInverse(&matrixTemp, nullptr, &allobjects[t].matrixReal);
753  D3DXVec3TransformCoord(&result, &position, &matrixTemp);
754  for (s = 0; s < 4500; s++)
755  {
756  D3DXVec3Subtract(&temp, &result, &polyextras2.center[s]);
757  dist[s] = D3DXVec3LengthSq(&temp);
758  }
759  do
760  {
761  swapflag = false;
762  for (s = 0; s < 4499; s++) // 4500-1
763  {
764  if (dist[s] > dist[s + 1])
765  {
766  temp_vertex2[0] = polyextras2.vertexbackup[s * 3 + 0];
767  temp_vertex2[1] = polyextras2.vertexbackup[s * 3 + 1];
768  temp_vertex2[2] = polyextras2.vertexbackup[s * 3 + 2];
769  f_temp = dist[s]; temp = polyextras2.center[s]; r = polyextras2.index[s];
770  polyextras2.vertexbackup[s * 3 + 0] = polyextras2.vertexbackup[(s + 1) * 3 + 0];
771  polyextras2.vertexbackup[s * 3 + 1] = polyextras2.vertexbackup[(s + 1) * 3 + 1];
772  polyextras2.vertexbackup[s * 3 + 2] = polyextras2.vertexbackup[(s + 1) * 3 + 2];
773  dist[s] = dist[s + 1]; polyextras2.center[s] = polyextras2.center[s + 1]; polyextras2.index[s] = polyextras2.index[s + 1];
774  polyextras2.vertexbackup[(s + 1) * 3 + 0] = temp_vertex2[0];
775  polyextras2.vertexbackup[(s + 1) * 3 + 1] = temp_vertex2[1];
776  polyextras2.vertexbackup[(s + 1) * 3 + 2] = temp_vertex2[2];
777  dist[s + 1] = f_temp; polyextras2.center[s + 1] = temp; polyextras2.index[s + 1] = r;
778  swapflag = true;
779  }
780  }
781  } while (swapflag && g_bAboveClouds);
782 
783  D3DXPLANE aglplane;
784  temp_vector[0].x = polyextras2.vertexbackup[0].x;
785  temp_vector[0].y = polyextras2.vertexbackup[0].y;
786  temp_vector[0].z = polyextras2.vertexbackup[0].z;
787  temp_vector[1].x = polyextras2.vertexbackup[1].x;
788  temp_vector[1].y = polyextras2.vertexbackup[1].y;
789  temp_vector[1].z = polyextras2.vertexbackup[1].z;
790  temp_vector[2].x = polyextras2.vertexbackup[2].x;
791  temp_vector[2].y = polyextras2.vertexbackup[2].y;
792  temp_vector[2].z = polyextras2.vertexbackup[2].z;
793 
794  // temp=(temp_vector[0]+temp_vector[1]+temp_vector[2])/3.0f;
795  // sprintf_s(msg, sizeof msg, "Deep sucker %f", D3DXVec3Length(&temp) );
796  // _write(logfile, msg, strlen(msg));
797 
798  D3DXPlaneFromPoints(&aglplane, &temp_vector[0], &temp_vector[1], &temp_vector[2]);
799 
800  D3DXPlaneNormalize(&aglplane, &aglplane);
801  D3DXMatrixInverse(&matrixTemp, nullptr, &allobjects[t].matrixReal);
802  D3DXMatrixTranspose(&matrixTemp, &matrixTemp);
803 
804  D3DXPlaneTransform(&aglplane, &aglplane, &matrixTemp);
805 
806  // See where line intersects plane (line starts 5km below cloud tops to 5km above)
807  D3DXVec3Scale(&result, &posnorml, cloudTopsRadiusC - 5.0f);
808  D3DXVec3Scale(&result1, &posnorml, cloudTopsRadiusC + 5.0f);
809  D3DXPlaneIntersectLine(&temp, &aglplane, &result, &result1);
810  f_ACL = radiusC + f_MSL - D3DXVec3Length(&temp) - 0.5f; // take off 500 meters because of the polygons being clipped before we got to the cloud layer because of the size of the polygons probably
811  }
812  }
813 
814  // must do docks first since they can be reference items
815  for (t = 0; t < maxdockC; t++) // after the moon has been calculated, find the docks
816  {
818 
819  if (allobjects[t].revolution > 0.0f)
820  {
821  const double dTemp = static_cast<double>(D3DX_TAU) / static_cast<double>(allobjects[t].revolution);
822  double test = static_cast<double>(allobjects[t].revoffset);
823  test += static_cast<double>(f_Uphours) * 3600.0 / dTemp;
824  test -= floor(test);
825  test += (static_cast<double>(g_UniverseTime) + fTime) / dTemp;
826  test -= floor(test);
827  test *= static_cast<double>(D3DX_TAU);
828  allobjects[t].revprog = static_cast<float>(test);
829 
830  //f_temp = D3DX_TAU / allobjects[t].revolution;
831  //allobjects[t].revprog = allobjects[t].revoffset;
832  //allobjects[t].revprog += f_Uphours * 3600.0f / f_temp;
833  //allobjects[t].revprog -= floorf(allobjects[t].revprog);
834  //allobjects[t].revprog += (g_UniverseTime + (float)fTime) / f_temp;
835  //allobjects[t].revprog -= floorf(allobjects[t].revprog);
836  //allobjects[t].revprog *= D3DX_TAU;
837  }
838 
839  // Rotation after tilt adjustment is remember LEFT=LOCAL
840  D3DXMatrixRotationZ(&matrixTemp, allobjects[t].revprog);
841  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
842  // D3DXMatrixRotationX( &matrixTemp, allobjects[ourmoonC].tilt ); // Rotate plane by tilt
843  D3DXMatrixRotationX(&matrixTemp, allobjects[t].inclination); // Rotate plane by tilt
844  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
845  D3DXMatrixRotationZ(&matrixTemp, -allobjects[ourmoonC].rotprog); // -barycentric
846  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
847 
848  // Save it so everyone can use it before it is mucked up
850 
851  allobjects[t].position.x = -allobjects[t].matrixWorld._41;
852  allobjects[t].position.y = -allobjects[t].matrixWorld._42;
853  allobjects[t].position.z = -allobjects[t].matrixWorld._43;
854 
855  // calculate velocity (for TVM)
856  D3DXMATRIX matrixPos = allobjects[t].matrixBase;
857  D3DXMatrixRotationZ(&matrixTemp, allobjects[t].revprog + allobjects[t].revolution);
858  D3DXMatrixMultiply(&matrixPos, &matrixPos, &matrixTemp);
859  // D3DXMatrixRotationX( &matrixTemp, allobjects[ourmoonC].tilt ); // Rotate plane by tilt
860  D3DXMatrixRotationX(&matrixTemp, allobjects[t].inclination); // Rotate plane by tilt
861  D3DXMatrixMultiply(&matrixPos, &matrixPos, &matrixTemp);
862  D3DXMatrixRotationZ(&matrixTemp, -allobjects[ourmoonC].rotprog);
863  D3DXMatrixMultiply(&matrixPos, &matrixPos, &matrixTemp);
864 
865  // D3DXMatrixRotationZ( &matrixTemp, allobjects[t].revolution );
866  D3DXVECTOR3 newposition;
867  // D3DXVec3TransformCoord( &newposition, &allobjects[t].position, &matrixPos );
868  newposition.x = -matrixPos._41;
869  newposition.y = -matrixPos._42;
870  newposition.z = -matrixPos._43;
871 
872 
873  D3DXVec3Subtract(&allobjects[t].velocity, &newposition, &allobjects[t].position);
874 
875  /* // Is already adjusted for barycentric
876  // needs to be adjusted for barycentric
877  float radius=D3DXVec3Length( &allobjects[t].position );
878  D3DXVECTOR3 gthrust;
879  D3DXVec3Normalize( &gthrust, &allobjects[t].position );
880  D3DXVECTOR3 cross;
881  D3DXVec3Cross( &cross, &northpoleC, &gthrust ); // Find perpendicular vector
882  D3DXVec3Normalize( &cross, &cross ); // Shouldn't be necessary
883  float lat=D3DXVec3Dot( &gthrust, &northpoleC );
884  lat=acosf(lat)-D3DX_HALFPI; // Find the angle and reduce by 90�
885  float f_temp=allobjects[ourmoonC].rotation*radius*cosf(lat);
886  D3DXVec3Scale( &cross, &cross, f_temp );
887  allobjects[t].velocity+=cross;
888  */
889  // calculate orientation
890 // D3DXMatrixInverse( &matrixOrient, NULL, &matrixOrient );
891  D3DXQuaternionIdentity(&allobjects[t].orientation);//, &matrixOrient );
892 
893 
894  for (s = 0; s < allobjects[t].components; s++)
895  {
896  // Could be moved to framemove
897  allobjects[t].componentarray[s].extended += fElapsedTime * 0.05f;
898  if (allobjects[t].componentarray[s].extended >= 1.0f)
900  }
901  }
902 
903 
904 
905  logger->AddToCallStack("Viewscreen::OnFrameMove Network Objects1");
906  // Network objects processing for our parent vehicle
907  if (playerships[0].reference == REF_INANOTHER)
908  {
909  t = playerships[0].inarray;
910  if (playerships[t].visible && playerships[t].active)
911  {
912  // Nicely interpolate position
913  cross = playerships[t].positer*fElapsedTime;
914  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].posleft))
915  cross = playerships[t].posleft;
916  playerships[t].posleft -= cross;
917  if (playerships[t].reference < REF_INANOTHER)
918  {
919  playerships[t].precisionx += static_cast<double>(cross.x);
920  playerships[t].precisiony += static_cast<double>(cross.y);
921  playerships[t].precisionz += static_cast<double>(cross.z);
922  }
923  else
924  D3DXVec3Add(&playerships[t].dockoffset, &playerships[t].dockoffset, &cross);
925 
926  // Nicely interpolate velocity
927  cross = playerships[t].veliter*fElapsedTime;
928  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].velleft))
929  cross = playerships[t].velleft;
930  playerships[t].velleft -= cross;
931 
932  if (playerships[t].reference < REF_INANOTHER)
933  D3DXVec3Add(&playerships[t].velocity, &playerships[t].velocity, &cross);
934  else
935  D3DXVec3Add(&playerships[t].dockingvel, &playerships[t].dockingvel, &cross);
936 
937  // Nicely interpolate acceleration
938  cross = playerships[t].acciter*fElapsedTime;
939  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].accleft))
940  cross = playerships[t].accleft;
941  playerships[t].accleft -= cross;
942  D3DXVec3Add(&playerships[t].acc, &playerships[t].acc, &cross);
943 
944 #pragma region Nicely interpolate YPR
945  // so if iter is .2 and left is .1 then .2>.1 ... iter -.2 left is -.1
946  f_temp = playerships[t].pitchiter*fElapsedTime;
947  if (fabsf(f_temp) > fabsf(playerships[t].pitchleft))
948  f_temp = playerships[t].pitchleft;
949  playerships[t].pitchleft -= f_temp;
950  playerships[t].pitch += f_temp;
951 
952  f_temp = playerships[t].rolliter*fElapsedTime;
953  if (fabsf(f_temp) > fabsf(playerships[t].rollleft))
954  f_temp = playerships[t].rollleft;
955  playerships[t].rollleft -= f_temp;
956  playerships[t].roll += f_temp;
957 
958  f_temp = playerships[t].yawiter*fElapsedTime;
959  if (fabsf(f_temp) > fabsf(playerships[t].yawleft))
960  f_temp = playerships[t].yawleft;
961  playerships[t].yawleft -= f_temp;
962  playerships[t].yaw += f_temp;
963 #pragma endregion
964 
965 #pragma region Nicely interpolate Thrust
966  // so if iter is .2 and left is .1 then .2>.1 ... iter -.2 left is -.1
967  f_temp = playerships[t].txiter*fElapsedTime;
968  if (fabsf(f_temp) > fabsf(playerships[t].txleft))
969  f_temp = playerships[t].txleft;
970  playerships[t].txleft -= f_temp;
971  playerships[t].tx += f_temp;
972  playerships[t].tx = Clamp(playerships[t].tx, -1, 1);
973 
974  f_temp = playerships[t].tyiter*fElapsedTime;
975  if (fabsf(f_temp) > fabsf(playerships[t].tyleft))
976  f_temp = playerships[t].tyleft;
977  playerships[t].tyleft -= f_temp;
978  playerships[t].ty += f_temp;
979  playerships[t].ty = Clamp(playerships[t].ty, -1, 1);
980 
981  f_temp = playerships[t].tziter*fElapsedTime;
982  if (fabsf(f_temp) > fabsf(playerships[t].tzleft))
983  f_temp = playerships[t].tzleft;
984  playerships[t].tzleft -= f_temp;
985  playerships[t].tz += f_temp;
986  playerships[t].tz = Clamp(playerships[t].tz, -1, 1);
987 #pragma endregion
988 
989  // Move based on gravity and barycentric rotation adjustment depending on reference
990  Movement(t, fElapsedTime);
991  }
992  }
993 
994 
995 
996  // Has to be done here before the ship matrices are made
997  // MOVED TO DO THIS BEFORE MOVEMENT(T) on 9/2/2019 BECAUSE PODS WERE JUMPING AROUND IN BAY
998  const float ourPositionLength = D3DXVec3Length(&playerships[0].position);
999  f_MSL = ourPositionLength - radiusC;
1001  if (!dead && !gameclass->bus->FlightFreeze)
1002  {
1003  logger->AddToCallStack("Viewscreen::OnFrameMove Our Movement");
1004  Movement(0, fElapsedTime);
1005  }
1006 
1007 
1008 
1009  AssertTelemetry("FrameMove::OnFrameMove4", 0);
1010 
1011 
1012 
1013 
1014  logger->AddToCallStack("Viewscreen::OnFrameMove Network Objects2");
1015  // Network objects processing, everyone but us and our parent
1016  for (t = 1; t < MAX_SCAN; t++)
1017  {
1018  if (playerships[0].reference == REF_INANOTHER && t == playerships[0].inarray)
1019  continue;
1020 
1021  if (!playerships[t].visible || !playerships[t].active)
1022  continue;
1023 
1024  // Nicely interpolate position
1025  cross = playerships[t].positer*fElapsedTime;
1026  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].posleft))
1027  cross = playerships[t].posleft;
1028  playerships[t].posleft -= cross;
1029  if (playerships[t].reference < REF_INANOTHER)
1030  {
1031  playerships[t].precisionx += static_cast<double>(cross.x);
1032  playerships[t].precisiony += static_cast<double>(cross.y);
1033  playerships[t].precisionz += static_cast<double>(cross.z);
1034  }
1035  else
1036  D3DXVec3Add(&playerships[t].dockoffset, &playerships[t].dockoffset, &cross);
1037 
1038  // Nicely interpolate velocity
1039  cross = playerships[t].veliter*fElapsedTime;
1040  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].velleft))
1041  cross = playerships[t].velleft;
1042  playerships[t].velleft -= cross;
1043 
1044  if (playerships[t].reference < REF_INANOTHER)
1045  D3DXVec3Add(&playerships[t].velocity, &playerships[t].velocity, &cross);
1046  else
1047  D3DXVec3Add(&playerships[t].dockingvel, &playerships[t].dockingvel, &cross);
1048 
1049  // Nicely interpolate acceleration
1050  cross = playerships[t].acciter*fElapsedTime;
1051  if (D3DXVec3Length(&cross) > D3DXVec3Length(&playerships[t].accleft))
1052  cross = playerships[t].accleft;
1053  playerships[t].accleft -= cross;
1054  D3DXVec3Add(&playerships[t].acc, &playerships[t].acc, &cross);
1055 
1056 #pragma region Nicely interpolate YPR
1057  f_temp = playerships[t].pitchiter*fElapsedTime;
1058  if (fabsf(f_temp) > fabsf(playerships[t].pitchleft))
1059  f_temp = playerships[t].pitchleft;
1060  playerships[t].pitchleft -= f_temp;
1061  playerships[t].pitch += f_temp;
1062 
1063  f_temp = playerships[t].rolliter*fElapsedTime;
1064  if (fabsf(f_temp) > fabsf(playerships[t].rollleft))
1065  f_temp = playerships[t].rollleft;
1066  playerships[t].rollleft -= f_temp;
1067  playerships[t].roll += f_temp;
1068 
1069  f_temp = playerships[t].yawiter*fElapsedTime;
1070  if (fabsf(f_temp) > fabsf(playerships[t].yawleft))
1071  f_temp = playerships[t].yawleft;
1072  playerships[t].yawleft -= f_temp;
1073  playerships[t].yaw += f_temp;
1074 #pragma endregion
1075 
1076 #pragma region Nicely interpolate Thrust
1077  // so if iter is .2 and left is .1 then .2>.1 ... iter -.2 left is -.1
1078  f_temp = playerships[t].txiter*fElapsedTime;
1079  if (fabsf(f_temp) > fabsf(playerships[t].txleft))
1080  f_temp = playerships[t].txleft;
1081  playerships[t].txleft -= f_temp;
1082  playerships[t].tx += f_temp;
1083  playerships[t].tx = Clamp(playerships[t].tx, -1, 1);
1084 
1085  f_temp = playerships[t].tyiter*fElapsedTime;
1086  if (fabsf(f_temp) > fabsf(playerships[t].tyleft))
1087  f_temp = playerships[t].tyleft;
1088  playerships[t].tyleft -= f_temp;
1089  playerships[t].ty += f_temp;
1090  playerships[t].ty = Clamp(playerships[t].ty, -1, 1);
1091 
1092  f_temp = playerships[t].tziter*fElapsedTime;
1093  if (fabsf(f_temp) > fabsf(playerships[t].tzleft))
1094  f_temp = playerships[t].tzleft;
1095  playerships[t].tzleft -= f_temp;
1096  playerships[t].tz += f_temp;
1097  playerships[t].tz = Clamp(playerships[t].tz, -1, 1);
1098 #pragma endregion
1099 
1100  // Move based on gravity and barycentric rotation adjustment depending on reference
1101  Movement(t, fElapsedTime);
1102 
1103  if (playerships[t].tireCircumferenceKm)
1104  {
1106  D3DXVec3TransformCoord(&groundSpeedKms, &groundSpeedKms, &playerships[t].matrixInvOrientation);
1107  playerships[t].tireRotationRadians -= groundSpeedKms.z / playerships[t].tireCircumferenceKm * D3DX_TAU * fElapsedTime;
1108  playerships[t].tireRotationRadians = fmodf(playerships[t].tireRotationRadians, D3DX_TAU);
1109  }
1110  }
1111 
1112 
1113  // DOCKING ----------------------------------------------------------------------------------
1114  if (playerships[0].reference >= REF_DOCKCPOC)
1115  {
1116  logger->AddToCallStack("Viewscreen::OnFrameMove Docking");
1117  s = playerships[0].portassigned; // Interface
1118  t = playerships[0].reference - REF_DOCKCPOC;
1119 
1120  static short oldportassigned = -1;
1121  static bool olddocked = false;
1122  static D3DXQUATERNION startorient;
1123  static D3DXVECTOR3 startoffset;
1124  if (oldportassigned != playerships[0].portassigned || olddocked != playerships[0].docked)
1125  {
1126  oldportassigned = playerships[0].portassigned;
1127  olddocked = playerships[0].docked;
1128 
1129  if (s != -1)
1130  {
1131  // Extensions
1132  D3DXVec3Scale(&result, &allobjects[t].componentarray[s].extendby, allobjects[t].componentarray[s].extended);
1133  D3DXVec3Add(&result, &allobjects[t].componentarray[s].nominalxyz, &result);
1134  // result=allobjects[t].componentarray[s].nominalxyz;
1135 
1136  D3DXVECTOR3 docknormal, nosenormal;
1137  docknormal.x = 0.0f;
1138  docknormal.y = 0.0f;
1139  docknormal.z = 1.0f; // easydock down
1140  nosenormal.x = -cosf(allobjects[t].componentarray[s].nominalypr.z);
1141  nosenormal.y = -sinf(allobjects[t].componentarray[s].nominalypr.z);
1142  nosenormal.z = 0.0f;
1143 
1144  result -= 8.0f*shipdockscaleC*docknormal; // docking interface face is 8 dock units down from module CG
1145  result -= 4.0f*shipdockscaleC*nosenormal; // CG of ship is offset by 4 on the nose
1146 
1147  result -= ourcockpit.dockOffsetKmZ*docknormal; // CG of ship is 8 below interface
1148  result -= ourcockpit.dockOffsetKmY*nosenormal; // CG of ship is 8 below interface, might need to be a +
1149 
1150  D3DXMatrixRotationQuaternion(&matrixTemp, &allobjects[t].orientation);
1151  D3DXMatrixInverse(&matrixTemp, nullptr, &matrixTemp);
1152 
1153  D3DXVec3TransformCoord(&dockInterface, &result, &matrixTemp);
1155 
1156  result -= nosenormal; // 1km marker
1157 
1158  // This now contains rotated and adjusted for ship scale and CG offset
1159  D3DXVec3TransformCoord(&dockMarker, &result, &matrixTemp);
1161 
1162  startorient = playerships[0].orientation;
1163  startoffset = playerships[0].dockoffset;
1164  }
1165  }
1166 
1167  if (playerships[0].docked)
1168  {
1169  if (dockprogress < 1.0f)
1170  {
1172  dockprogress += fElapsedTime * 0.05f;
1173  if (dockprogress > 1.0f)
1174  {
1175  dockprogress = 1.0f;
1176 
1177  if (!playerships[0].simulator)
1178  {
1179  SClientPacket outpacket; // NOLINT
1180  outpacket.type = 2; // Docking change
1181  outpacket.f_x = static_cast<float>(playerships[0].portassigned);
1182  outpacket.f_y = 1.0f; // docked
1183  outpacket.f_z = 0.0f; // NULL
1184  outpacket.f_w = 0.0f; // NULL
1185  gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1186  }
1187 
1188  sprintf_s(msg, sizeof msg, "Client docked to port %i...", playerships[0].portassigned);
1189  logger->Log(msg);
1190 
1192  }
1193  }// progress less than 100%
1194 
1195  // Now come up with desired ship orientation
1196  D3DXQUATERNION desiredorient = allobjects[t].orientation;
1197  D3DXQUATERNION quatTemp;
1198  D3DXQuaternionRotationYawPitchRoll(&quatTemp, 0.0f, D3DX_HALFPI, ourcockpit.dockingOrientationZ*allobjects[t].componentarray[s].nominalypr.z + D3DX_HALFPI);
1199  desiredorient *= quatTemp;
1200 
1201  // First do this in the first 1/2 of dockprogress
1202  if (dockprogress <= 0.5f)
1203  f_temp = dockprogress * 2.0f;
1204  else
1205  f_temp = 1.0f;
1206 
1207  D3DXQuaternionSlerp(&playerships[0].orientation, &startorient, &desiredorient, f_temp);
1208 
1209  if (dockprogress >= 0.5f)
1210  D3DXVec3Lerp(&playerships[0].dockoffset, &dockMarker, &dockInterface, (dockprogress - 0.5f)*2.0f);
1211  else
1212  D3DXVec3Lerp(&playerships[0].dockoffset, &startoffset, &dockMarker, dockprogress*2.0f);
1213 
1214 
1216  playerships[0].pitch = playerships[0].roll = playerships[0].yaw = 0.0f;
1217  }
1218  else
1219  {
1220  if (dockprogress > 0.0f)
1221  {
1222  dockprogress -= fElapsedTime * 0.05f;
1223  if (dockprogress < 0.0f)
1224  {
1225  dockprogress = 0.0f;
1226 
1227  playerships[0].portassigned = -1;
1228 
1229  if (!playerships[0].simulator)
1230  {
1231  SClientPacket outpacket; // NOLINT
1232  outpacket.type = 2; // Docking change
1233  outpacket.f_x = -1.0f; // no more port
1234  outpacket.f_y = 0.0f; // undocked
1235  outpacket.f_z = 0.0f; // NULL
1236  outpacket.f_w = 0.0f; // NULL
1237  gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
1238  }
1239  }
1240 
1241  D3DXVec3Lerp(&playerships[0].dockoffset, &dockMarker, &dockInterface, dockprogress);
1242 
1244  playerships[0].pitch = playerships[0].roll = playerships[0].yaw = 0.0f;
1245  }
1246  }
1247  }
1248 
1249 
1250 
1251  AssertTelemetry("FrameMove::OnFrameMove2", 0);
1252 
1253 
1254 
1255  // Terrain and ground grid processor
1256  ptrGrid->Process(); // This shifts us to the correct location
1257  // AGL calc should be done BEFORE we move and AFTER we shift, so since AGL calc comes after this
1258  // we must use ACTUAL location NOT proposed
1259 
1260 
1261 
1262  AssertTelemetry("FrameMove::OnFrameMove3", 0);
1263 
1264 
1265 
1266  // Network objects processing, only protected section in FrameMove --------------------------
1267  logger->AddToCallStack("Viewscreen::OnFrameMove Network Objects");
1268  for (t = 0; t < MAX_SCAN; t++)
1269  {
1270  if (playerships[t].active && playerships[t].visible)
1271  {
1272  if (t != 0)
1273  {
1274  result = playerships[t].position- playerships[0].position;
1275  playerships[t].distance = D3DXVec3Length(&result);
1276 
1277  // 250 is too far away ... really I had this idea if they pull up to a vehicle
1278  const float olddistance = playerships[t].distance;
1279  if (playerships[t].distance < 0.05f && olddistance > 0.05f && playerships[0].reference != REF_BUILDING)
1281 
1283  if (playerships[t].distance < playerships[t].bound) // we are inside
1284  {
1285  playerships[t].drawflag = true;
1286  }
1287  else
1288  {
1289  D3DXVec3Normalize(&result, &result);
1290  D3DXVec3Normalize(&lookvec, &lookvec);
1291  const float directto = -D3DXVec3Dot(&result, &lookvec); // so that direct to is +1 and acos(1) is 0, acos(0) is 90, acos(-1) is 180
1292  if (t == scanslot[gameclass->bus->targetC])
1293  gameclass->bus->DebugFloat8 = directto;
1294 
1295  if (directto > 0.0f) // in front of our view
1296  {
1297  // if their bound is .349 they take up .349/1km dist radians or .349 radians
1298  // if it is 0 degrees, dot is 1, acos is 0
1299  // if it is 57.5 degrees, dot is XX, acos is 0.5373
1300  if ((acosf(directto) - atan(playerships[t].bound / playerships[t].distance)) < f_compareFOV)
1301  playerships[t].drawflag = true;
1302  else
1303  playerships[t].drawflag = false;
1304  }
1305  else
1306  playerships[t].drawflag = false;
1307  }
1308 
1309 
1310  // Nicely interpolate orientation to where they SHOULD be over 2 seconds
1311  if (playerships[t].reference != REF_INANOTHER)
1312  {
1313  D3DXQUATERNION crossorient = playerships[t].orientiter*fElapsedTime;
1314  if (D3DXQuaternionLength(&crossorient) > D3DXQuaternionLength(&playerships[t].orientleft))
1315  crossorient = playerships[t].orientleft;
1316  playerships[t].orientleft -= crossorient;
1317  playerships[t].orientation += crossorient;
1318 
1319  D3DXQuaternionRotationYawPitchRoll(&quaternionTemp, playerships[t].yaw*fElapsedTime, playerships[t].pitch*fElapsedTime, playerships[t].roll*fElapsedTime);
1320  D3DXQuaternionMultiply(&playerships[t].orientation, &playerships[t].orientation, &quaternionTemp);
1321  D3DXQuaternionNormalize(&playerships[t].orientation, &playerships[t].orientation);
1322  }
1323  }
1324 
1325  /* // Test for inertial rotation match
1326  location=-playerships[t].position;
1327  float radii=D3DXVec3Length( &location )/radiusC; // Radii from CM, could be stolen from earlier
1328  D3DXVec3Cross( &cross, &location, &playerships[t].velocity ); // Find perpendicular vector
1329  D3DXMatrixRotationAxis( &dor, &cross, D3DXVec3Length( &playerships[t].velocity )/(radiusC*radii)*fElapsedTime );
1330  D3DXMatrixMultiply( &matrixTempRotation, &dor, &matrixTempRotation );
1331  // End inertial rotation
1332  */
1333 
1334  D3DXMatrixRotationQuaternion(&playerships[t].matrixInvOrientation, &playerships[t].orientation);
1335  D3DXMatrixInverse(&playerships[t].matrixInvOrientation, nullptr, &playerships[t].matrixInvOrientation);
1336  D3DXMatrixMultiply(&playerships[t].dor, &playerships[t].matrixBase, &playerships[t].matrixInvOrientation);
1337 
1338  D3DXMatrixTranslation(&matrixTemp, static_cast<float>(playerships[0].precisionx - playerships[t].precisionx),
1339  static_cast<float>(playerships[0].precisiony - playerships[t].precisiony),
1340  static_cast<float>(playerships[0].precisionz - playerships[t].precisionz));
1341  D3DXMatrixMultiply(&playerships[t].matrixWorld, &playerships[t].dor, &matrixTemp);
1342 
1343  // cloaking
1344  if (t != 0 && (playerships[0].reference != REF_INANOTHER || t != playerships[0].inarray))
1345  {
1346  playerships[t].specular.r = playerships[t].specular.g = playerships[t].specular.b = 0.0f;
1347  if (!g_bAboveClouds)
1348  {
1349  const char cloudcube = CalculateCube(playerships[t].position);
1350  VECTOR2SHORT cloudtcp = CalculateCGC(playerships[t].position, cloudcube);
1351  cloudtcp.u = (ptrGrid->tcp.u - cloudtcp.u) + 31;
1352  cloudtcp.v = (ptrGrid->tcp.v - cloudtcp.v) + 31;
1353  if (cloudtcp.u >= 0 && cloudtcp.u <= 62 && cloudtcp.v >= 0 && cloudtcp.v <= 62) // within visible grid
1354  {
1355  const float shipMSL = D3DXVec3Length(&playerships[t].position) - radiusC;
1356  const float shipBCL = ptrWeather->GetCloudCeilingMslKm() - shipMSL;
1357 
1358  playerships[t].specular = gridarray[cloudtcp.u][cloudtcp.v].specular;
1359 
1360  if (shipBCL < 0.0f)
1361  {
1362  playerships[t].cloaking = 0.0f;
1363  }
1364  else
1365  {
1366  if (shipBCL <= 0.150f)
1367  playerships[t].cloaking = shipBCL / 0.150f;
1368  else
1369  playerships[t].cloaking = 1.0f;
1370  }
1371  }
1372  else
1373  {
1374  playerships[t].cloaking = 1.0f;
1375  }
1376  }
1377  else
1378  {
1379  // @todo we should be fading them into the top of the clouds too
1380  const float shipMSL = D3DXVec3Length(&playerships[t].position) - radiusC;
1381  if (shipMSL < cloudTopsMslC)
1382  playerships[t].cloaking = 0.0f;
1383  else
1384  playerships[t].cloaking = 1.0f;
1385  }
1386  }
1387  }
1388  else
1389  {
1390  playerships[t].drawflag = false;
1391  playerships[t].distance = -1.0f; // to keep TCAS from going off when they are added
1392  }
1393  }
1394 
1395  logger->AddToCallStack("Viewscreen::OnFrameMove DIHV");
1396  t = MAX_SCAN - 1;
1397  // For DIHV entrance/exit
1398  if (playerships[t].type == VehicleType::DIHV)
1399  {
1400  if (advanceframe)
1401  {
1402  if (dihvcoming)
1403  {
1404  if (dihvanimate > -1 && dihvanimate < 64) // hold at -1, play 0-64
1405  {
1406  dihvanimate++;
1407  if (dihvanimate == 0)
1408  {
1409  gameclass->sound->Play(SOUND_DIHV); // it is an interference noise that transends cockpit attenuation
1410  }
1411  else if (dihvanimate == 33)
1412  {
1413  playerships[t].visible = true;
1414  }
1415  else if (dihvanimate == 64)
1416  {
1417  playerships[t].docked = true;
1418  }
1419  }
1420  }
1421  else // going
1422  {
1423  if (dihvanimate > -1 && dihvanimate < 64) // hold at 64, play 63 to 0
1424  {
1425  dihvanimate--;
1426  if (dihvanimate == 62)
1427  {
1428  playerships[t].docked = false;
1429  }
1430  else if (dihvanimate == 32)
1431  {
1432  playerships[t].visible = false;
1433  }
1434  else if (dihvanimate == 10)
1435  {
1436  gameclass->sound->Play(SOUND_DIHV); // it is an interference noise that transends cockpit attenuation
1437  }
1438  else if (dihvanimate == -1)
1439  {
1440  playerships[t].active = false;
1441  }
1442  }
1443  }
1444  }
1445 
1446  dihvelapsed += fElapsedTime;
1447  if (dihvelapsed >= 1.0f)
1448  {
1449  // sprintf_s(msg, sizeof msg, "Dihv coming %i seq %i act %i vis %i init %i", dihvcoming, dihvtimeseq, playerships[t].active, playerships[t].visible, playerships[t].clientinit );
1450  // _write(logfile, msg, strlen(msg));
1451 
1452  dihvelapsed -= 1.0f;
1453  D3DXVECTOR3 shouldbe, newvel;
1454  D3DXQUATERNION shouldbeorient;
1455  if (dihvtimeseq > -1 && dihvtimeseq < 647)
1456  {
1457  int tempfile;
1458  _sopen_s(&tempfile, "Meshes\\Animations\\DIHV.ani", _O_RDONLY | O_BINARY, _SH_DENYWR, _S_IWRITE);
1459  if (tempfile == -1)
1460  {
1461  sprintf_s(msg, sizeof msg, R"(Could not find "Meshes\Animations\DIHV.ani"!)");
1462  logger->Log(msg, Logger::Level::Error);
1463  }
1464  _lseek(tempfile, dihvtimeseq * 40L, SEEK_SET);
1465  _read(tempfile, &shouldbe, 12);
1466  _read(tempfile, &shouldbeorient, 16);
1467  _read(tempfile, &newvel, 12);
1468 
1469  if (!dihvcoming)
1470  {
1471  shouldbe.x = -shouldbe.x - 0.047607f*2.0f; // to compensate for tower location
1472  if (dihvtimeseq == 0) // trigger departure animation
1473  dihvanimate = 63;
1474  }
1475  _close(tempfile);
1476  if (dihvcoming)
1477  dihvtimeseq++;
1478  else
1479  dihvtimeseq--;
1480 
1481  if (playerships[t].clientinit)
1482  {
1483  playerships[t].dockoffset = shouldbe;
1485  playerships[t].orientation = shouldbeorient;
1486  playerships[t].orientiter = playerships[t].orientleft = D3DXQUATERNION(0, 0, 0, 0);
1487  playerships[t].dockingvel = newvel;
1490  playerships[t].clientinit = false;
1491  }
1492  else
1493  {
1494  playerships[t].posleft = shouldbe - playerships[t].dockoffset;
1495  playerships[t].positer = playerships[t].posleft*0.25f; // 4 seconds
1496  playerships[t].orientleft = shouldbeorient - playerships[t].orientation;
1497  playerships[t].orientiter = playerships[t].orientleft*0.5f; // 2 seconds
1498  playerships[t].velleft = newvel - playerships[t].dockingvel; // 1 second
1499  playerships[t].veliter = playerships[t].velleft; // 1 second
1500  playerships[t].accleft = playerships[t].acciter; // 1 second
1501  }
1505  }
1506  else // cut the thrust that is in the ani
1508  }
1509  }
1510 
1511 
1512  logger->AddToCallStack("Viewscreen::OnFrameMove LGHT");
1513  for (t = 0; t < MAX_SCAN; t++)
1514  {
1515  if ((fTime - playerships[t].timer) > playerships[t].speed)
1516  {
1517  playerships[t].compare >>= 1;
1518  if (playerships[t].compare == 0)
1519  playerships[t].compare = maxcompareC >> 1;
1520  playerships[t].timer = static_cast<float>(fTime);
1521  }
1522  }
1523 
1524 
1525  logger->AddToCallStack("Viewscreen::OnFrameMove CMPT");
1526  for (t = 0; t < MAX_SCAN; t++)
1527  {
1528  for (s = 0; s < playerships[t].components; s++)
1529  {
1531  sprintf_s(msg, sizeof msg, "CMPT %i %i %i %i", t, playerships[t].type, s, playerships[t].componentarray[s].type);
1533 
1534  playerships[t].componentarray[s].visible = ((playerships[t].componentarray[s].attachto != 7 || // light bar
1535  playerships[t].police) && // not lightbar or is and they are police
1536  (playerships[t].componentarray[s].type != 54 || // geometry inside of bay
1537  playerships[t].baydoorextent || // door is open
1538  (playerships[0].reference == REF_INANOTHER && t == playerships[0].inarray))); // we are inside
1539 
1540  if (!playerships[t].componentarray[s].visible)
1541  continue;
1542 
1543  // Start by rotating to the correct orientation
1544  D3DXMatrixRotationYawPitchRoll(&playerships[t].componentarray[s].matWorld, playerships[t].componentarray[s].nominalypr.x, playerships[t].componentarray[s].nominalypr.y, playerships[t].componentarray[s].nominalypr.z);
1545 
1546  // Animated rotations...
1547  D3DXMatrixTranslation(&matrixTemp, -playerships[t].componentarray[s].hingeCG.x, -playerships[t].componentarray[s].hingeCG.y, -playerships[t].componentarray[s].hingeCG.z);
1549  D3DXMatrixRotationAxis(&matrixTemp, &playerships[t].componentarray[s].hingeaxis, playerships[t].componentarray[s].extended*playerships[t].componentarray[s].hingeextent);
1551 
1552  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
1553  switch (playerships[t].componentarray[s].type)
1554  {
1555  case 1: // Main gear
1556  case 2: // Nose gear
1557  case 6: // Main wheel
1558  case 9: // Nose wheel
1559  {
1560  if (playerships[t].geardown)
1561  {
1562  if (playerships[t].componentarray[s].extended < 1.0f) // not yet fully down
1564  if (playerships[t].componentarray[s].extended > 1.0f)
1565  {
1566  if (t == 0 && !ourcockpit.sentgearvoice)
1567  {
1568  Command command;
1569  command.name = "AuralGearDown";
1570  command.delay = 2.0f;
1571  gameclass->bus->commandStream.emplace_back(command);
1572  ourcockpit.sentgearvoice = true;
1573  }
1574  playerships[t].componentarray[s].extended = 1.0f;
1575  }
1576  }
1577  else
1578  {
1579  if (playerships[t].componentarray[s].extended > 0.0f) // not yet fully up
1581  if (playerships[t].componentarray[s].extended < 0.0f)
1582  {
1583  if (t == 0 && !ourcockpit.sentgearvoice)
1584  {
1585  Command command;
1586  command.name = "AuralGearUp";
1587  command.delay = 2.0f;
1588  gameclass->bus->commandStream.emplace_back(command);
1589  ourcockpit.sentgearvoice = true;
1590  }
1591  playerships[t].componentarray[s].extended = 0.0f;
1592  }
1593  }
1594  if (t == 0)
1595  {
1599  }
1600 
1601  // first spin the tires before we change the axis
1602  if (playerships[t].reference != REF_INANOTHER && (
1603  playerships[t].componentarray[s].type == 6 || // main wheel
1604  playerships[t].componentarray[s].type == 9)) // nose wheel
1605  {
1607  D3DXMatrixRotationX(&matrixTemp, -playerships[t].tireRotationRadians);
1609  D3DXMatrixInverse(&matrixTemp, nullptr, &playerships[t].matrixBase);
1611  }
1612 
1613  // now rotate the gear and wheel on the nose
1614  if (playerships[t].componentarray[s].type == 2 || // nose gear
1615  playerships[t].componentarray[s].type == 9) // nose wheel
1616  {
1617  D3DXMatrixRotationZ(&matrixTemp, playerships[t].yawdeflect*playerships[t].steerLimitRadian);
1618  D3DXMatrixInverse(&matrixTemp, nullptr, &matrixTemp);
1620  }
1621  }
1622  break;
1623  case 16: // flaps (TE)
1624  case 68: // flaps (LE)
1625  {
1626  if (playerships[t].componentarray[s].extended < playerships[t].flapdown)
1627  {
1629  if (playerships[t].componentarray[s].extended > playerships[t].flapdown)
1630  {
1631  //if (t == 0 && !ourcockpit.sentgearvoice)
1632  //{
1633  // gameclass->sound->Play(SOUND_MONROEGEARDOWN);
1634  // ourcockpit.sentgearvoice = true;
1635  //}
1637  }
1638  }
1639  else if (playerships[t].componentarray[s].extended > playerships[t].flapdown)
1640  {
1642  if (playerships[t].componentarray[s].extended < playerships[t].flapdown)
1643  {
1644  /*if (t == 0 && !ourcockpit.sentgearvoice)
1645  {
1646  gameclass->sound->Play(SOUND_MONROEGEARUP);
1647  ourcockpit.sentgearvoice = true;
1648  }*/
1650  }
1651  }
1652 
1653  if (t == 0)
1654  {
1658  }
1659  }
1660  break;
1661  case 30: // Bay doors
1662  {
1663  if (playerships[t].baydoor)
1664  {
1665  if (playerships[t].componentarray[s].extended < 1.0f) // not yet fully down
1667  if (playerships[t].componentarray[s].extended > 1.0f)
1668  {
1669  playerships[t].componentarray[s].extended = 1.0f;
1670  }
1671  }
1672  else
1673  {
1674  if (playerships[t].componentarray[s].extended > 0.0f) // not yet fully up
1676  if (playerships[t].componentarray[s].extended < 0.0f)
1677  {
1678  playerships[t].componentarray[s].extended = 0.0f;
1679  }
1680  }
1682  }
1683  break;
1684  case 10: // Ailerons Left
1685  case 11: // Ailerons Right
1686  {
1687  f_temp = -playerships[t].rolldeflect;
1688  f_temp -= playerships[t].componentarray[s].extended; // difference
1689  playerships[t].componentarray[s].extended += f_temp * fElapsedTime;
1690  }
1691  break;
1692  case 12: // Elevators
1693  {
1694  f_temp = -playerships[t].pitchdeflect;
1695  f_temp -= playerships[t].componentarray[s].extended; // difference
1696  playerships[t].componentarray[s].extended += f_temp * fElapsedTime;
1697  }
1698  break;
1699  case 13: // Rudders and steering
1700  {
1701  f_temp = playerships[t].yawdeflect;
1702  f_temp -= playerships[t].componentarray[s].extended; // difference
1703  playerships[t].componentarray[s].extended += f_temp * fElapsedTime;
1704  }
1705  break;
1706  case 14: // Left Ruddervator
1707  {
1708  f_temp = (playerships[t].yawdeflect + playerships[t].pitchdeflect)*0.5f;
1709  f_temp -= playerships[t].componentarray[s].extended; // difference
1710  playerships[t].componentarray[s].extended += f_temp * fElapsedTime;
1711  }
1712  break;
1713  case 15: // Right Ruddervator
1714  {
1715  f_temp = (playerships[t].yawdeflect - playerships[t].pitchdeflect)*0.5f;
1716  f_temp -= playerships[t].componentarray[s].extended; // difference
1717  playerships[t].componentarray[s].extended += f_temp * fElapsedTime;
1718  }
1719  break;
1720  case 200: // left engine accelerate cone
1721  case 210: // left engine accelerate cone
1722  case 220: // left engine accelerate cone
1723  {
1724  // extended will be used for thrust vectoring so we have no variable to smooth so we assume tz is smoothed
1725  const float extended = max(playerships[t].tz, 0);
1726 
1727  // fluctuate more rapidly the flicker and rotation based on thrust
1728  // speedExtend, speedRetract, extended, extendBy are all unused
1729  // so at 10% this is .9 ... at 0 it is 0
1730  playerships[t].componentarray[s].speedRetract = min(0.9f, extended * 4.5f) + extended * RandomFloat() * 0.1f;
1731 
1732  playerships[t].componentarray[s].speedExtend += extended * (RandomFloat() - 0.5f) * fElapsedTime * 25.0f;
1733  D3DXMatrixRotationY(&matrixTemp, playerships[t].componentarray[s].speedExtend);
1735 
1736  D3DXMatrixScaling(&matrixTemp, 1, 0.2f + extended, 1);
1738  }
1739  break;
1740  case 205: // left engine accelerate cone
1741  case 215: // left engine accelerate cone
1742  case 225: // left engine accelerate cone
1743  {
1744  // extended will be used for thrust vectoring so we have no variable to smooth so we assume tz is smoothed
1745  const float extended = max(-playerships[t].tz, 0);
1746 
1747  // fluctuate more rapidly the flicker and rotation based on thrust
1748  // speedExtend, speedRetract, extended, extendBy are all unused
1749  // so at 10% this is .9 ... at 0 it is 0
1750  playerships[t].componentarray[s].speedRetract = min(0.9f, extended * 4.5f) + extended * RandomFloat() * 0.1f;
1751 
1752  playerships[t].componentarray[s].speedExtend += extended * (RandomFloat() - 0.5f) * fElapsedTime * 25.0f;
1753  D3DXMatrixRotationY(&matrixTemp, playerships[t].componentarray[s].speedExtend);
1755 
1756  D3DXMatrixScaling(&matrixTemp, 1, 0.2f + extended, 1);
1758  }
1759  break;
1760  }
1761 
1762  // Animated extensions...
1763  D3DXVec3Scale(&result, &playerships[t].componentarray[s].extendby, playerships[t].componentarray[s].extended);
1764  D3DXVec3Add(&result, &playerships[t].componentarray[s].nominalxyz, &result);
1765 
1766  // If it is attached... move to correct location
1767  result += playerships[t].componentarray[s].hingeCG;
1768 
1769  D3DXMatrixTranslation(&matrixTemp, result.x, result.y, result.z);
1771 
1772  D3DXMatrixMultiply(&playerships[t].componentarray[s].matWorld, &playerships[t].componentarray[s].matWorld, &playerships[t].matrixWorld);
1773  }
1774  }
1775 
1776  logger->AddToCallStack("Viewscreen::OnFrameMove CMPT DONE");
1777 
1778 
1779 
1780  AssertTelemetry("FrameMove::OnFrameMove5", 0);
1781 
1782 
1783 
1784  logger->AddToCallStack("Viewscreen::OnFrameMove Dock Matrices");
1785  for (t = 0; t < maxdockC; t++) // matrices for docks
1786  {
1787  D3DXMatrixIdentity(&allobjects[t].matrixWorld);
1788  D3DXMatrixTranslation(&matrixTemp,
1789  static_cast<float>(playerships[0].precisionx - static_cast<double>(allobjects[t].position.x)),
1790  static_cast<float>(playerships[0].precisiony - static_cast<double>(allobjects[t].position.y)),
1791  static_cast<float>(playerships[0].precisionz - static_cast<double>(allobjects[t].position.z)));
1792  D3DXMatrixMultiply(&allobjects[t].matrixWorld, &allobjects[t].matrixWorld, &matrixTemp);
1793 
1795 
1796 #pragma region Dock Space calculation and port speed calculation
1798  {
1799  if (allobjects[t].distance < 30.0f)
1800  {
1801  if (playerships[0].reference < REF_INANOTHER)
1802  {
1803  playerships[0].reference = static_cast<char>(t) + REF_DOCKCPOC;
1804  D3DXVec3Subtract(&playerships[0].dockoffset, &playerships[0].position, &allobjects[t].position);
1805  D3DXVec3Subtract(&playerships[0].dockingvel, &playerships[0].velocity, &allobjects[t].velocity);
1806  logger->Log("Entered dock bubble!");
1807  }
1808 
1809  if (D3DXVec3Length(&playerships[0].dockingvel) > 0.250f)
1810  {
1812  }
1813  }
1814  else if (allobjects[t].distance > 40.0f && playerships[0].reference == (static_cast<char>(t) + REF_DOCKCPOC))
1815  {
1816  playerships[0].reference = REF_ACLMODE;
1817  sprintf_s(msg, sizeof msg, "Left dock bubble at %.3f km!", allobjects[t].distance);
1818  logger->Log(msg);
1819  sprintf_s(msg, sizeof msg, " Dock positionX %.3f Y %.3f Z %.3f (%.3f)!", allobjects[t].position.x, allobjects[t].position.y, allobjects[t].position.z, D3DXVec3Length(&allobjects[t].position));
1820  logger->Log(msg);
1821  sprintf_s(msg, sizeof msg, " Dock velocityX %.3f Y %.3f Z %.3f (%.3f)!", allobjects[t].velocity.x, allobjects[t].velocity.y, allobjects[t].velocity.z, D3DXVec3Length(&allobjects[t].velocity));
1822  logger->Log(msg);
1823  }
1824  }
1825 #pragma endregion
1826 
1827  if ((fTime - allobjects[t].timer) > allobjects[t].speed)
1828  {
1829  allobjects[t].compare >>= 1;
1830  if (allobjects[t].compare == 0)
1831  allobjects[t].compare = maxcompareC >> 1;
1832  allobjects[t].timer = static_cast<float>(fTime);
1833  }
1834  }
1835 
1836 
1837 
1838  // city lights
1839  logger->AddToCallStack("Viewscreen::OnFrameMove City Lights");
1840  for (t = 0; t < PlotType::PlotTypeEnum; t++)
1841  {
1842  if ((fTime - citystuff.timer[t]) > citystuff.speed[t])
1843  {
1844  citystuff.compare[t] >>= 1;
1845  if (citystuff.compare[t] == 0)
1846  citystuff.compare[t] = maxcompareC >> 1;
1847  citystuff.timer[t] = static_cast<float>(fTime);
1848  }
1849  }
1850 
1851 
1852  // buildings sort
1853  logger->AddToCallStack("Viewscreen::OnFrameMove Sort Buildings");
1854  const D3DXVECTOR3 position = -playerships[0].position;
1855  for (t = 0; t < buildingVBC; t++)
1856  {
1857  if (buildzone[t].VB)
1858  {
1859  result = position - buildzone[t].terpos;
1860  sortme[t].dist = D3DXVec3Length(&result);
1861  }
1862  else
1863  sortme[t].dist = 999.0f;
1864  sortme[t].buildzone = t;
1865 
1866  // sprintf_s(msg, sizeof msg, "Presort (type %i) %i is %f (%i %i)", buildzone[t].type, t, sortme[t].dist, buildzone[t].u-tcp.u, buildzone[t].v-tcp.v);
1867  // _write(logfile, msg, strlen(msg));
1868  }
1869  bool swapflag;
1870  do
1871  {
1872  swapflag = false;
1873  for (t = 0; t < (buildingVBC - 1); t++) // sort
1874  {
1875  if (sortme[t].dist > sortme[t + 1].dist)
1876  {
1877  sortmetemp = sortme[t];
1878  sortme[t] = sortme[t + 1];
1879  sortme[t + 1] = sortmetemp;
1880  swapflag = true;
1881  }
1882  }
1883  } while (swapflag);
1884 
1885 
1886 
1887 #pragma region Halloween 2018
1888 
1889  if (ourcockpit.vdat.holiday == -2) // start at -2, ends at 0
1890  {
1891  static float holidayTimer = 0.0f;
1892  if (leftright <= 0 && playerships[0].reference == REF_ONGROUND && !dead)
1893  {
1894  holidayTimer += fElapsedTime;
1895  if (holidayTimer >= 30.0f)
1896  {
1897  gameclass->sound->GlobalAttenuate(0.0f, 2.0f, 2.0f, SOUND_HOLIDAY2018, 0.0f, 4.0f, 0.0f);
1898  gameclass->sound->PlayEx(SOUND_HOLIDAY2018, false, 1, 1, 1); // right
1899 
1900  ourcockpit.vdat.holiday = 127;
1901  ourcockpit.vdatChanged = true;
1902  }
1903  }
1904  else
1905  holidayTimer = 0.0f;
1906  }
1907  else if (ourcockpit.vdat.holiday > 1)
1908  {
1909  // so 127 seconds in clouds or in heavy rain
1910  static float timeToNextDecrement = 1.0f;
1911  D3DXVECTOR3 speed = playerships[0].velocity - playerships[0].barycentric;
1912  const float speedFactor = fElapsedTime * min((D3DXVec3Length(&speed) + ptrWeather->GetWindspeedKms()) / 0.125f, 1.0f); // 0-1
1913  timeToNextDecrement -= speedFactor * max((ptrWeather->GetTurbidity() - 2.0f), 0.0f) / 14.0f; // 0-1 x 0-1
1914  timeToNextDecrement -= speedFactor * alphascreen.a * 0.2f; // 0-1 x 0.0-0.2
1915  timeToNextDecrement -= fElapsedTime * gammascreen.w * 3.0f; // 0-3 // reentry
1916  if (timeToNextDecrement < 0.0f)
1917  {
1918  ourcockpit.vdat.holiday--;
1919 
1920  ourcockpit.vdatChanged = true;
1921 
1922  timeToNextDecrement += 1.0f;
1923  }
1924  }
1925 
1926 #pragma endregion
1927 
1928 
1929 #ifdef _DEBUG
1930  otherFrameMoveTimer->stopTimer();
1931 #endif
1932 
1933 #ifdef _DEBUG
1934  weaponsFrameMoveTimer->startTimer();
1935 #endif
1936  //if (!gameclass->bus->FlightFreeze)
1937  ptrWeapon->Update(fElapsedTime);
1938 #ifdef _DEBUG
1939  weaponsFrameMoveTimer->stopTimer();
1940 #endif
1941 
1942 
1943  D3DXVec3Add(&compassnorth, &northpoleC, &playerships[0].position);
1944  D3DXVec3Normalize(&compassnorth, &compassnorth);
1945  D3DXVec3Scale(&compassnorth, &compassnorth, ourPositionLength);
1946  D3DXVec3Subtract(&compassnorth, &compassnorth, &playerships[0].position);
1947  D3DXVec3Normalize(&compassnorth, &compassnorth);
1948 
1949 
1950 #ifdef _DEBUG
1951  propulsionFrameMoveTimer->startTimer();
1952 #endif
1953  if (!dead)
1954  ptrPropulsion->Update(fElapsedTime);
1955  else
1956  {
1957  logger->AddToCallStack("Viewscreen::OnFrameMove Dead");
1958 
1959  // if at a dock then we set it zero in relation to the dock
1960  if (playerships[0].reference >= REF_DOCKCPOC)
1961  playerships[0].dockingvel = D3DXVECTOR3(0, 0, 0);
1962  else
1963  {
1964  D3DXVECTOR3 gthrust;
1965  float radius;
1967  }
1968 
1969  if (playerships[0].reference < REF_INANOTHER)
1970  {
1971  // below clouds we just put them safely on the ground
1972  if (!g_bAboveClouds)
1973  playerships[0].reference = REF_ONGROUND;
1974  else if (f_MSL > 5000.0f)
1975  {
1976  // above 5000km we put them at 5000km
1977  D3DXVec3Normalize(&playerships[0].position, &playerships[0].position);
1978  playerships[0].position *= radiusC + 5000.0f;
1982  logger->Log("Repositioned player at 5,000 km MSL because they were above 5,000 km MSL!", Logger::Level::Warn);
1983  }
1984  // Bill experienced multiple decompression deaths
1985  else if (ourcockpit.serviceCeilingKm > 0.0f && f_MSL > ourcockpit.serviceCeilingKm * 0.9f)
1986  {
1987  D3DXVec3Normalize(&playerships[0].position, &playerships[0].position);
1992  logger->Log("Repositioned player at serviceCeilingKm because they were above serviceCeilingKm!", Logger::Level::Warn);
1993  }
1994  }
1995 
1996  playerships[0].pitch = playerships[0].yaw = playerships[0].roll = 0.0f;
1997  pitchInput = rollInput = yawInput = 0.0f;
1998  for (int i = 0; i < MAX_ENGINES; i++)
1999  {
2000  gameclass->bus->EngineThrustLever[i] = 0.0f;
2001  gameclass->bus->ThrustReverserCommand[i] = false;
2002  }
2003 
2004  ourcockpit.gearshift = -2;
2006 
2008  // ReSharper disable once CppExpressionWithoutSideEffects
2009  gameclass->TurnOffTVM();
2010  // ReSharper disable once CppExpressionWithoutSideEffects
2011  gameclass->TurnOffDOR();
2012  }
2013 #ifdef _DEBUG
2014  propulsionFrameMoveTimer->stopTimer();
2015 #endif
2016 
2017 
2018 
2019 #ifdef _DEBUG
2020  otherFrameMoveTimer->startTimer();
2021 #endif
2022 
2023 
2024  logger->AddToCallStack("Viewscreen::OnFrameMove Reentry Effects");
2025  ptrPropulsion->tat_mod_qz_x = ptrPropulsion->tatCelsius*ptrPropulsion->qz; // tat runs up to 13000 in his video ... qz is 32 ... that is 416k is limit normally
2026  if (ptrPropulsion->tat_mod_qz_x > 140000.0f)
2027  {
2028  gammascreen.w = (ptrPropulsion->tat_mod_qz_x - 140000.0f) / 484000.0f; // 0-1 ... based on 1.5*normal limit of 416-140
2029  //gammascreen.w = powf(D3DXVec3Length(&playerships[0].velocity), 4.0f)*density; // convection rate doesn't work because if airframe is -200 it will heat quickly
2030  if (gammascreen.w > 1.0f)
2031  gammascreen.w = 1.0f;
2032  }
2033  else
2034  {
2035  gammascreen.w = 0.0f;
2036  }
2037 
2038  if (ptrWeather->gammascreenOverride != -1.0f)
2040 
2041  if (gammascreen.w > 0.0f)
2042  {
2043  // gammascreen.y is rate ... should be 12 to 24 fps with erratic nature based on qz
2044  //game->ptrPropulsion->qz;
2045  gammascreen.y = gammascreen.w*24.0f;
2046 
2047  gammascreen.x += gammascreen.y*fElapsedTime;
2048  if (gammascreen.x > 63.0f) gammascreen.x = 0.0f;
2049  gammascreen.z -= gammascreen.y*fElapsedTime;
2050  if (gammascreen.z <= 0.0f)
2051  {
2052  gammascreen.x = RandomFloat() * 63.0f;
2053  gammascreen.z = RandomFloat() * 63.0f * (1.0f - gammascreen.w);
2054  }
2055  }
2056 
2057  // Set up the D3DTS_VIEW based on the rotation and location of our ship ------------------
2058 
2059  D3DXMatrixRotationQuaternion(&matrixView, &playerships[0].orientation);
2060 
2062 
2063 
2064 
2065  D3DXMatrixMultiply(&matrixView, &matrixView, &matrixTemp);
2067  {
2068  static long old41 = gameclass->GUI->ptCursor.x;
2070  {
2072  targetLeftright -= static_cast<float>(old41 - gameclass->GUI->ptCursor.x)*0.0025f;
2073  else
2074  targetLeftright += static_cast<float>(old41 - gameclass->GUI->ptCursor.x)*0.0025f;
2078  }
2079  old41 = gameclass->GUI->ptCursor.x;
2080  }
2082  {
2083  static long old42 = gameclass->GUI->ptCursor.y;
2085  {
2087  targetUpdown += static_cast<float>(old42 - gameclass->GUI->ptCursor.y)*0.0025f;
2088  else
2089  targetUpdown -= static_cast<float>(old42 - gameclass->GUI->ptCursor.y)*0.0025f;
2093  }
2094  old42 = gameclass->GUI->ptCursor.y;
2095  }
2096 
2099 
2100  // need to identify per quadrant
2101  float mag = 1.0f;
2102  if (targetLeftright > 0.0f && targetUpdown > 0.0f) // up and right
2103  mag = sqrtf(powf(targetUpdown / uplimit, 2.0f) + powf(targetLeftright / rightlimit, 2.0f)); // avg
2104  else if (targetLeftright > 0.0f && targetUpdown < 0.0f) // down and right
2105  mag = sqrtf(powf(targetUpdown / downlimit, 2.0f) + powf(targetLeftright / rightlimit, 2.0f)); // avg
2106  else if (targetLeftright < 0.0f && targetUpdown < 0.0f) // down and left
2107  mag = sqrtf(powf(targetUpdown / downlimit, 2.0f) + powf(targetLeftright / leftlimit, 2.0f)); // avg
2108  else if (targetLeftright<0.0f && targetUpdown>0.0f) // up and left
2109  mag = sqrtf(powf(targetUpdown / uplimit, 2.0f) + powf(targetLeftright / leftlimit, 2.0f)); // avg
2110  if (mag > 1.0f)
2111  {
2112  targetUpdown /= mag;
2113  targetLeftright /= mag;
2114  }
2115 
2116  mag = 1.0f;
2117  if (targetLeftright > 0.0f && rolltilt > 0.0f) // up and right
2118  mag = sqrtf(powf(rolltilt / tiltlimitR, 2.0f) + powf(targetLeftright / rightlimit, 2.0f)); // avg
2119  else if (targetLeftright > 0.0f && rolltilt < 0.0f) // down and right
2120  mag = sqrtf(powf(rolltilt / tiltlimitL, 2.0f) + powf(targetLeftright / rightlimit, 2.0f)); // avg
2121  else if (targetLeftright < 0.0f && rolltilt < 0.0f) // down and left
2122  mag = sqrtf(powf(rolltilt / tiltlimitL, 2.0f) + powf(targetLeftright / leftlimit, 2.0f)); // avg
2123  else if (targetLeftright<0.0f && rolltilt>0.0f) // up and left
2124  mag = sqrtf(powf(rolltilt / tiltlimitR, 2.0f) + powf(targetLeftright / leftlimit, 2.0f)); // avg
2125  if (mag > 1.0f)
2126  {
2127  rolltilt /= mag;
2128  targetLeftright /= mag;
2129  }
2130 
2131 
2132  leftright += Clamp((targetLeftright - leftright)*fElapsedTime*8.0f, -0.1f, 0.1f);
2133  updown += Clamp((targetUpdown - updown)*fElapsedTime*8.0f, -0.1f, 0.1f);
2134 
2135 
2136 #pragma region Acceleration Effects
2137  // Rotational effects
2138  result = centerC;
2139  result.z -= ourcockpit.cockpitArmKm.z*powf(playerships[0].yaw, 2.0f)*fElapsedTime;
2140  result.z -= ourcockpit.cockpitArmKm.z*powf(playerships[0].pitch, 2.0f)*fElapsedTime;
2141  result.x += ourcockpit.cockpitArmKm.x*powf(playerships[0].roll, 2.0f)*fElapsedTime;
2142  sprintf_s(msg, sizeof msg, "X%7.3f Y%7.3f Z%7.3f centripetal", result.x * oneOvergForceKmSSC / fElapsedTime, result.y * oneOvergForceKmSSC / fElapsedTime, result.z * oneOvergForceKmSSC / fElapsedTime);
2143  sofTracking.emplace_back(msg);
2144  sumofforces += result; // centripetal
2145 
2146  result = centerC;
2147  // force into our seat or out of our seat as we increase or decrease pitch for example (or roll)
2150  // throw us left or right as we yaw
2152  sprintf_s(msg, sizeof msg, "X%7.3f Y%7.3f Z%7.3f rotRateDelta", result.x * oneOvergForceKmSSC / fElapsedTime, result.y * oneOvergForceKmSSC / fElapsedTime, result.z * oneOvergForceKmSSC / fElapsedTime);
2153  sofTracking.emplace_back(msg);
2154  sumofforces += result; // rotRateDelta
2155 
2156 
2157 
2158  // So these are the final sumofforces ... we now check the vehicle because in the simulator we would base damage off of the actual forces
2159  sumofforces *= oneOvergForceKmSSC / fElapsedTime;
2160 
2161 
2162  //sprintf_s(msg, sizeof msg, "forces x%f y%f z%f", sumofforces.x, sumofforces.y, sumofforces.z);
2163  //_write(logfile, msg, strlen(msg));
2164 
2165  f_temp = D3DXVec3Length(&sumofforces);
2166  if (f_temp > touchdownG)
2167  touchdownG = f_temp;
2168 
2169  // check accelerations for death limits exceeded
2170  if (advanceframe && !dead && playerships[0].reference != REF_BUILDING && playerships[0].reference != REF_SIMBAY && deathinhibit == 0.0f)
2171  {
2172  if (rand() < 2730 && ourcockpit.vdat.leftwing > 0) // one 12th the time or 2 times per second
2173  {
2174  // 4.4 and -1.8 with 1G bias
2175  f_temp = 3.8f*static_cast<float>(ourcockpit.vdat.leftwing) / 127.0f;
2176  // upside down this is -1.1, minus 1 is -2.1
2177  if (fabsf(sumofforces.y - 1.0f) > f_temp)
2178  {
2179  f_temp = fabsf(sumofforces.y - 1.0f) / f_temp - 1.0f; // 0.0f to 0.5f is ultimate limit
2180  char damage;
2181  if (f_temp > 0.5f)
2182  damage = 127; // failure
2183  else
2184  damage = static_cast<char>(f_temp / 0.03225806452f); // takes about a minute at 3.2G, 8 sec at 4.65
2185 
2186  if (damage > 64 || damage > ourcockpit.vdat.leftwing)
2187  {
2188  gameclass->sound->PlayEx(SOUND_ODEATH2, false, gameclass->sound->GetAttenuation(true), 1, -1);
2189  }
2190 
2191  if (damage > ourcockpit.vdat.leftwing)
2192  ourcockpit.vdat.leftwing = 0;
2193  else
2194  ourcockpit.vdat.leftwing -= damage;
2195 
2196  ourcockpit.vdatChanged = true;
2197  }
2198  }
2199  if (rand() < 2730 && ourcockpit.vdat.rightwing > 0) // one 12th the time or 2 times per second
2200  {
2201  // 4.4 and -1.8 with 1G bias
2202  f_temp = 3.8f*static_cast<float>(ourcockpit.vdat.rightwing) / 127.0f;
2203  if (fabsf(sumofforces.y - 1.0f) > f_temp)
2204  {
2205  f_temp = fabsf(sumofforces.y - 1.0f) / f_temp - 1.0f; // 0.0f to 0.5f is ultimate limit
2206  char damage;
2207  if (f_temp > 0.5f)
2208  damage = 127; // failure
2209  else
2210  damage = static_cast<char>(f_temp / 0.03225806452f); // takes about a minute at 3.2G
2211 
2212  if (damage > 64 || damage > ourcockpit.vdat.rightwing)
2213  {
2215  }
2216 
2217  if (damage > ourcockpit.vdat.rightwing)
2218  ourcockpit.vdat.rightwing = 0;
2219  else
2220  ourcockpit.vdat.rightwing -= damage;
2221 
2222  ourcockpit.vdatChanged = true;
2223  }
2224  }
2225 
2226  if (sumofforces.z<-22.5f || sumofforces.z>33.2f || // fwd/back
2227  fabsf(sumofforces.x) > 9.0f || // left/right
2228  sumofforces.y<-15.0f || sumofforces.y>20.0f) // up/down
2229  {
2230  // these are considered a crash, so we need to cue the crash noises
2231  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2232  switch (causechain)
2233  {
2234  case 1: // Ground impact
2235  logger->Log("Ground impact!");
2236  if (g_bEnabled)
2237  {
2238  if (rand() > 16383)
2240  else
2242  }
2243  break;
2244  case 4: // City impact
2245  logger->Log("Impacted with city!");
2246  if (g_bEnabled)
2247  {
2248  if (rand() > 16383)
2250  else
2252  }
2253  break;
2254  case 9: // Water impact
2255  logger->Log("Water impact!");
2256  if (g_bEnabled)
2257  {
2258  if (rand() > 16383)
2260  else
2262  }
2263  break;
2264  }
2265 
2266  // and for distributing damage
2267  if (ourcockpit.vdat.vtail > 0)
2268  {
2269  const auto damage = static_cast<char>(rand() % ourcockpit.vdat.vtail + 1); // thanks canary
2270  ourcockpit.vdat.vtail -= damage;
2271  ourcockpit.vdatChanged = true;
2272  if (damage > 32)
2273  {
2274  if (rand() < 16384)
2276  else
2278  }
2279  }
2280 
2281  if (ourcockpit.vdat.htail > 0)
2282  {
2283  // rand()%8 returns 0 to 7
2284  const auto damage = static_cast<char>(rand() % ourcockpit.vdat.htail + 1); // thanks canary
2285  ourcockpit.vdat.htail -= damage;
2286  if (ourcockpit.vdat.htail < 0)
2287  {
2288  ourcockpit.vdat.htail = 0;
2289  sprintf_s(msg, sizeof msg, "Trapped h-tail issue...");
2290  logger->Log(msg, Logger::Level::Fatal);
2291  }
2292  ourcockpit.vdatChanged = true;
2293  if (damage > 32)
2294  {
2295  if (rand() < 16384)
2297  else
2299  }
2300  }
2301  }
2302  }
2303 
2304 
2305 #ifdef SOFTRACKING
2306  if (D3DXVec3Length(&sumofforces) > 1.2f)
2307  DumpSofTracking();
2308 #endif
2309 
2310 
2311  // now if we are applying stuff to the character in the simulator it should be done with an amended value
2312  D3DXVECTOR3 charSumOfForces = sumofforces;
2313  if (playerships[0].simulator)
2314  {
2315  charSumOfForces.x = Clamp(charSumOfForces.x, -0.7f, 0.7f);
2316  charSumOfForces.y = Clamp(charSumOfForces.x, -0.7f, 0.7f);
2317  charSumOfForces.z = Clamp(charSumOfForces.x, -0.7f, 0.7f);
2318 
2319  if (ourcockpit.vdat.leftwing == 0 || ourcockpit.vdat.rightwing == 0 ||
2320  ourcockpit.vdat.htail == 0 || ourcockpit.vdat.vtail == 0)
2321  {
2322  dead = 2; // structural failure
2323  }
2324 }
2325 
2326 
2327  // if it is getting heavy make him grunt
2329  static bool grunt = false;
2330  if (!dead && deathinhibit == 0.0f &&
2331  playerships[0].reference != REF_BUILDING && playerships[0].reference != REF_SIMBAY)
2332  {
2333  static D3DXVECTOR3 oldsumofforces = charSumOfForces;
2334 
2335  if (oldsumofforces.x < charSumOfForces.x)
2336  oldsumofforces.x += 0.05f*fElapsedTime;
2337  else if (oldsumofforces.x > charSumOfForces.x)
2338  oldsumofforces.x -= 0.05f*fElapsedTime;
2339  if (oldsumofforces.y < charSumOfForces.y)
2340  oldsumofforces.y += 0.05f*fElapsedTime;
2341  else if (oldsumofforces.x > charSumOfForces.y)
2342  oldsumofforces.y -= 0.05f*fElapsedTime;
2343  if (oldsumofforces.z < charSumOfForces.z)
2344  oldsumofforces.z += 0.05f*fElapsedTime;
2345  else if (oldsumofforces.x > charSumOfForces.z)
2346  oldsumofforces.z -= 0.05f*fElapsedTime;
2347 
2348 
2349  // 1-6-12 seconds to get out of g-loc
2350  // usual relaxed tolerance is 5 g's
2351  // 2 g-s more based on training for 1 week
2352  // 1 g-s more with g-suit?
2353  // 2-6 second buffer period switching from + to - G?
2354  // same for women and men
2355  // track blood pressure as part of biometer
2356  // lowers blood pressure and pulse 10-15 seconds in response to -G
2357  // raise blood pressure and pulse 10 seconds in response to +G
2358  // brain functions for 6 seconds without any blood flow then shuts down!
2359 
2360  // so if you can tolerate +5G and you onset over 10 seconds you should be GTG
2361  // because your blood pressure and pulse will rise to compensate
2362 
2363  // max BP systolic 370
2364  // double the pulse so if they are 60 then it becomes 120
2365  // 2.5 each means 240 BP and 120 pulse
2366 
2367 
2368 
2369  if (fabsf(charSumOfForces.x - oldsumofforces.x) > 3.0f ||
2370  fabsf(charSumOfForces.z - oldsumofforces.z) > 6.0f ||
2371  fabsf(charSumOfForces.y - oldsumofforces.y) > 3.0f)
2372  {
2373  if (!grunt)
2374  {
2375  grunt = true;
2376  logger->Log("Pulling some G's!");
2377  // ReSharper disable once CppDefaultCaseNotHandledInSwitchStatement
2378  switch (rand() % 3)
2379  {
2380  case 0: gameclass->sound->Play(SOUND_PEOPLEGRUNT1); break;
2381  case 1: gameclass->sound->Play(SOUND_PEOPLEGRUNT2); break;
2382  case 2: gameclass->sound->Play(SOUND_PEOPLEGRUNT3); break;
2383  }
2384  }
2385  }
2386  else
2387  grunt = false;
2388 
2389 
2390  // above this level also starts to detract hitpoints from our character
2391  if (fabsf(charSumOfForces.x) > 5.0f ||
2392  fabsf(charSumOfForces.z) > 10.0f ||
2393  fabsf(charSumOfForces.y - 1.0f) > 5.0f)
2394  {
2395  float injury = 0.0f;
2396  // affect hitpoints, impacts are considered less than 1 second
2397 
2398  // into seat 6G for 5 seconds progressive blackout (30G for 1 sec)
2399  injury += powf(8.3f*(charSumOfForces.y - 1.0f)*fElapsedTime, 2.0f);
2400 
2401  // leftright 5G for 14.5 seconds results in external hemmoraging (72.5G for 1 sec)
2402  // 3.5 hp per G per sec
2403  injury += powf(3.4f*charSumOfForces.x*fElapsedTime, 2.0f);
2404 
2405  // decelleration forward >60G for <1 second tears the pulmonary artery, 35G breaks a rib
2406  // 4 hp per G per sec
2407  injury += powf(4.2f*charSumOfForces.z*fElapsedTime, 2.0f);
2408 
2409  // we can take 175-250G into back once but only 105-150G into bottom of seat
2410  const auto damage = static_cast<unsigned char>(floorf((injury * 2.5f)));
2411  if (damage <= ourcockpit.hitpoints)
2412  {
2413  ourcockpit.hitpoints -= damage;
2414 
2415  if (!DialogBase::dialogs[D_BIOMETER]->active)
2416  {
2419  }
2420 
2422 
2423  if (cash > 0.0f && !playerships[0].simulator)
2425 
2426  ourcockpit.vdatChanged = true;
2427  }
2428  else
2429  {
2430  // splat
2431  SClientPacket outpacket; // NOLINT
2432  outpacket.type = 15; // Death report
2433  outpacket.f_x = charSumOfForces.x;
2434  outpacket.f_y = charSumOfForces.y;
2435  if (causechain == 6) // collision with another vehicle
2436  outpacket.f_z = static_cast<float>(causearray);
2437  else
2438  outpacket.f_z = charSumOfForces.z;
2439  if (causechain)
2440  {
2441  outpacket.f_w = static_cast<float>(causechain);
2442  deathinhibit = 15.0f;
2443  dead = causechain;
2444  }
2445  else
2446  {
2447  outpacket.f_w = 3.0f; // must be translationally related
2448  deathinhibit = 15.0f;
2449  dead = 3; // acceleration
2450  }
2451 
2452  gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2453 
2455  gameclass->sound->GlobalAttenuate(0.5f, 1.5f, 6.0f, SOUND_EXPLODERING, 0.5f, 1.5f, 6.0f);
2456  gameclass->sound->PlayEx(SOUND_EXPLODERING, true, 0.0f);
2457 
2458  sprintf_s(msg, sizeof msg, "Player perished, cause %i, forces %.1f %.1f %.1f...", dead, charSumOfForces.x, charSumOfForces.y, charSumOfForces.z);
2459  logger->Log(msg);
2460 
2461  ourcockpit.hitpoints = 255;
2462  }
2463  }
2464 
2465  // non force related death like depressurization
2466  if (ourcockpit.serviceCeilingKm > 0.0f && f_MSL > ourcockpit.serviceCeilingKm && playerships[0].reference < REF_INANOTHER)
2467  {
2468  deathinhibit = 15.0f;
2469  dead = 7; // decompression
2470 
2471  if (!playerships[0].simulator)
2472  {
2473  SClientPacket outpacket; // NOLINT
2474  outpacket.type = 15; // Death report
2475  outpacket.f_x = f_MSL;
2476  outpacket.f_y = ourcockpit.serviceCeilingKm;
2477  outpacket.f_z = 0.0f; // NULL
2478  outpacket.f_w = static_cast<float>(dead);
2479  gameclass->networking->SendToServer(&outpacket, sizeof(SClientPacket), true);
2480  ourcockpit.hitpoints = 255;
2481 
2483  gameclass->sound->GlobalAttenuate(0.5f, 1.5f, 6.0f, SOUND_EXPLODERING, 0.5f, 1.5f, 6.0f);
2484  gameclass->sound->PlayEx(SOUND_EXPLODERING, true, 0.0f);
2485  }
2486  }
2487  }
2488 
2489 
2490  float igs = charSumOfForces.x - counteri;
2491  float jgs = charSumOfForces.y - counterj;
2492  float kgs = charSumOfForces.z - counterk;
2493 
2494  // we can only recover from 3G's and it is exponentially difficult
2495  f_temp = fabsf(counteri) / 3.0f; // we are doing 3g then 1 ... if we are doing 6g then 2 ... if we are doing 0 g then 0
2496  if (f_temp < 1.0f)
2497  f_temp = 1.0f; // now 100% effective at 0-3g, at 6g it is 2x as difficult, 9g is 3x
2498  counteri += igs * fElapsedTime*3.0f / f_temp;
2499  f_temp = fabsf(counterj) / 3.0f; // we are doing 3g then 1 ... if we are doing 6g then 2 ... if we are doing 0 g then 0
2500  if (f_temp < 1.0f)
2501  f_temp = 1.0f; // now 100% effective at 0-3g, at 6g it is 2x as difficult, 9g is 3x
2502  counterj += jgs * fElapsedTime*3.0f / f_temp;
2503  f_temp = fabsf(counterk) / 3.0f; // we are doing 3g then 1 ... if we are doing 6g then 2 ... if we are doing 0 g then 0
2504  if (f_temp < 1.0f)
2505  f_temp = 1.0f; // now 100% effective at 0-3g, at 6g it is 2x as difficult, 9g is 3x
2506  counterk += kgs * fElapsedTime*3.0f / f_temp;
2507 
2508  igs *= 0.25f; // scale to 1
2509  jgs *= 0.25f; // scale to 1
2510  kgs *= 0.25f; // scale to 1
2511 
2512  // set up for 4G's based on http://msis.jsc.nasa.gov/images/section03/image106.gif
2513  igs = Clamp(igs, -4.0f, 4.0f);
2514  jgs = Clamp(jgs, -4.0f, 4.0f);
2515  kgs = Clamp(kgs, -4.0f, 4.0f);
2516 
2517  // Head translation
2518  if (jgs > 0.0f)
2519  ourcockpit.position.z = 0.00003475f + Clamp(-jgs * 0.000015f + ptrFreeTrack->z, -0.00006f, 0.00006f) + ourcockpit.chaireye.z;
2520  else
2521  ourcockpit.position.z = 0.00003475f + Clamp(-jgs * 0.000015f + ptrFreeTrack->z, -0.00006f, 0.00006f) + ourcockpit.chaireye.z;
2522  if (kgs > 0.0f) // limit 0.6 travel into headrest?
2523  ourcockpit.position.y = 0.000018f + Clamp(kgs * 0.000009f + ptrFreeTrack->y, -0.00006f, 0.000009f + ourcockpit.chairFwdRemaining) + ourcockpit.chaireye.y;
2524  else
2525  ourcockpit.position.y = 0.000018f + Clamp(kgs * 0.000015f + ptrFreeTrack->y, -0.00006f, 0.000009f + ourcockpit.chairFwdRemaining) + ourcockpit.chaireye.y;
2526  if (igs > 0.0f) // side to side
2527  ourcockpit.position.x = Clamp(igs * 0.0001f + ptrFreeTrack->x, -0.0004f, 0.0004f) + ourcockpit.chaireye.x; // 15.75 inches?
2528  else
2529  ourcockpit.position.x = Clamp(igs * 0.0001f + ptrFreeTrack->x, -0.0004f, 0.0004f) + ourcockpit.chaireye.x;
2530  // ACCELERATION EFFECTS --------------------------------------------------------------------------
2531 #pragma endregion
2532 
2533 
2534  if (fuel <= 0.0f)
2535  fuel = 0.0f;
2537  if (deathfuel <= 0.0f)
2538  deathfuel = 0.0f;
2539 
2540  if (ourcockpit.power < 1.0f && fuel > 0.0f && ourcockpit.startcycle > 0 && ourcockpit.startcycle < 3)
2541  {
2542  ourcockpit.power += fElapsedTime * 0.1f; // 10 sec
2543  if (ourcockpit.power >= 1.0f)
2544  {
2545  ourcockpit.power = 1.0f;
2546  // turn on lights
2547  if (!playerships[0].logolight)
2548  {
2549  playerships[0].logolight = true;
2553  lampTest = 5.0f;
2554  }
2555 
2556  // Startup initiated by player
2558  Command command;
2559  command.name = "AuralScannerSync";
2560  command.delay = 2.0f;
2561  gameclass->bus->commandStream.emplace_back(command);
2562  }
2563  }
2564  else if (ourcockpit.power > 0.0f && (fuel == 0.0f || ourcockpit.startcycle == 0 || ourcockpit.startcycle == 3))
2565  {
2566  ourcockpit.power -= fElapsedTime * 0.1f; // 10 sec
2567 
2568  // Kill Autoflyte (autopilot)
2569  if (ourcockpit.power < 0.75f)
2571 
2572  if (ourcockpit.power <= 0.0f)
2573  {
2574  ourcockpit.power = 0.0f;
2575  // shut off lights
2576  if (playerships[0].logolight)
2577  {
2578  playerships[0].logolight = false;
2580  if (!playerships[0].simulator)
2582  }
2584  ourcockpit.gearshift = -2; // @bug https://jira.risetvp.com/view.php?id=1730
2585  }
2586  }
2587  if (ourcockpit.startcycle == 1) // starting
2588  {
2589  if (ourcockpit.startupextend < 1.0f) // not yet fully down
2590  ourcockpit.startupextend += fElapsedTime * 0.25f;
2591  if (ourcockpit.startupextend >= 1.0f)
2592  {
2593  ourcockpit.startupextend = 1.0f;
2594  ourcockpit.startcycle = 2; // running
2595  }
2596  }
2597  else if (ourcockpit.startcycle == 3) // stopping
2598  {
2599  if (ourcockpit.startupextend > 0.0f) // not yet fully down
2600  ourcockpit.startupextend -= fElapsedTime * 0.25f;
2601  if (ourcockpit.startupextend <= 0.0f)
2602  {
2603  ourcockpit.startupextend = 0.0f;
2604  ourcockpit.startcycle = 0; // off
2605  }
2606  }
2607 
2608 
2609  static float headback = 0.0f, headtilt = 0.0f;
2610  float targetheadback, targetheadtilt;
2611  if (kgs > 0.0f) // into headrest, limit 0.6
2612  targetheadback = kgs * uplimit*0.6f;
2613  else
2614  targetheadback = -kgs * downlimit;
2615  if (igs > 0.0f) // tilt right
2616  targetheadtilt = -igs * tiltlimitR*0.5f;
2617  else
2618  targetheadtilt = igs * tiltlimitL*0.5f;
2619 
2620  headback += (targetheadback - headback)*fElapsedTime;
2621  headtilt += (targetheadtilt - headtilt)*fElapsedTime;
2622 
2623 
2624 
2625 
2626 
2627  // first pass is where we are looking with mouse or VR or TrackIR
2628 
2629  D3DXMatrixRotationYawPitchRoll(&matrixTemp, leftright + gameclass->GUI->player[ourcockpit.ourplyrC].smoothhdg, -updown, rolltilt);
2630  D3DXMatrixInverse(&matrixLookAdj, nullptr, &matrixTemp);
2631 
2632 
2633  D3DXMATRIX accEffect;
2634  D3DXMatrixRotationYawPitchRoll(&accEffect, 0, -headback, headtilt);
2635  D3DXMatrixInverse(&accEffect, nullptr, &accEffect);
2636  D3DXMatrixMultiply(&matrixLookAdj, &accEffect, &matrixLookAdj);
2637 
2638 
2639 
2640  D3DXMatrixMultiply(&matrixLook, &matrixView, &matrixLookAdj);
2641 
2642  DXUTGetD3D9Device()->SetTransform(D3DTS_VIEW, &matrixLook);
2643 
2644 
2645 
2646 #pragma region lookhdg
2647 
2648  // Look heading -------------------------------------------------------------------------------------------
2649  result.x = 0.0f; result.y = 0.0f; result.z = -1.0f;
2650  D3DXMatrixInverse(&matrixTemp, nullptr, &matrixLook);
2651  D3DXVec3TransformCoord(&lookvec, &result, &matrixTemp); // Find straight ahead vector
2652  D3DXVec3Normalize(&lookvec, &lookvec);
2653  D3DXVECTOR3 result1;
2654  D3DXVec3Add(&result1, &lookvec, &playerships[0].position); // it is now a point 1km ahead
2655 
2656  // snap to present altitude
2657  D3DXVec3Normalize(&result1, &result1);
2658  D3DXVec3Scale(&result1, &result1, ourPositionLength);
2659 
2660  // our look vector snapped to the grid plane
2661  D3DXVec3Subtract(&result1, &result1, &playerships[0].position);
2662  D3DXVec3Normalize(&result1, &result1);
2663 
2664 
2665 
2666  // Now this one can be compared with the vector viewnorth
2667  f_temp = D3DXVec3Dot(&result1, &compassnorth);
2668  if (f_temp >= 1.0f)
2669  lookhdg = 0.0f;
2670  else if (f_temp <= -1.0f)
2671  lookhdg = 180.0f;
2672  else
2673  lookhdg = D3DXToDegree(acosf(f_temp));
2674 
2675  // Adjust for the 3rd and 4th quadrants
2676  D3DXVec3Cross(&result1, &result1, &compassnorth);
2677  D3DXVec3Add(&result1, &result1, &playerships[0].position);
2678  if (D3DXVec3Length(&result1) > ourPositionLength)
2679  lookhdg = 360.0f - lookhdg;
2680 
2681  //D3DXMatrixRotationZ(&matGridRot, -D3DXToRadian(lookhdg));
2682 
2684 #pragma endregion
2685 
2686 
2687 
2688  D3DXVECTOR3 plotnorth = gridarray[31][31].position - gridarray[31][32].position;
2689  D3DXVec3Normalize(&plotnorth, &plotnorth);
2690  D3DXVec3Add(&plotnorth, &plotnorth, &playerships[0].position);
2691  D3DXVec3Normalize(&plotnorth, &plotnorth);
2692  D3DXVec3Scale(&plotnorth, &plotnorth, ourPositionLength);
2693  D3DXVec3Subtract(&plotnorth, &plotnorth, &playerships[0].position);
2694  D3DXVec3Normalize(&plotnorth, &plotnorth);
2695 
2696  // Look heading -------------------------------------------------------------------------------------------
2697  D3DXVec3Add(&result1, &lookvec, &playerships[0].position); // it is now a point 1km ahead
2698 
2699  // snap to present altitude
2700  D3DXVec3Normalize(&result1, &result1);
2701  D3DXVec3Scale(&result1, &result1, ourPositionLength);
2702 
2703  // our look vector snapped to the grid plane
2704  D3DXVec3Subtract(&result1, &result1, &playerships[0].position);
2705  D3DXVec3Normalize(&result1, &result1);
2706 
2707  // Now this one can be compared with the vector viewnorth
2708  f_temp = D3DXVec3Dot(&result1, &plotnorth);
2709  float plothdg;
2710  if (f_temp >= 1.0f)
2711  plothdg = 0.0f;
2712  else if (f_temp <= -1.0f)
2713  plothdg = 180.0f;
2714  else
2715  plothdg = D3DXToDegree(acosf(f_temp));
2716 
2717  // Adjust for the 3rd and 4th quadrants
2718  D3DXVec3Cross(&result1, &result1, &plotnorth);
2719  D3DXVec3Add(&result1, &result1, &playerships[0].position);
2720  if (D3DXVec3Length(&result1) > ourPositionLength)
2721  plothdg = 360.0f - plothdg;
2722 
2723  D3DXMatrixRotationZ(&matGridRot, -D3DXToRadian(plothdg));
2725 
2726  gameclass->bus->DebugFloat9 = plothdg;
2727 
2728 
2729 
2730 
2731  D3DXMATRIX matrixInverse;
2732  D3DXMatrixInverse(&matrixInverse, nullptr, &playerships[0].matrixWorld);
2733  D3DXMatrixMultiply(&matrixInverse, &allobjects[ourmoonC].matrixWorld, &matrixInverse);
2734  D3DXMatrixMultiply(&matrixInverse, &matrixInverse, &matrixLookAdj);
2735  result.x = matrixInverse._41;
2736  result.y = matrixInverse._42;
2737  result.z = matrixInverse._43;
2738  if (fabsf(result.y) > FLT_EPSILON)
2739  lookAzimuthDegrees = -D3DXToDegree(atanf(result.z / sqrtf(result.y*result.y + result.x*result.x)));
2740  else
2741  lookAzimuthDegrees = 0.0f;
2742 
2743 
2744 
2745 
2746  for (t = 0; t < MAX_SCAN; t++)
2747  {
2748  if (scanslot[t] != 0 && playerships[scanslot[t]].active &&
2749  playerships[scanslot[t]].visible &&
2750  playerships[scanslot[t]].distance < ourcockpit.scanrange)
2751  {
2753  // if (playerships[game->scanslot[t]].type>=10 && playerships[game->scanslot[t]].type<=19 &&
2754  // game->scandist[t]>1.0f) // PODS
2755  // game->scandist[t]=FLT_MAX;
2756  if (playerships[scanslot[t]].groundvehicle && !gameclass->GUI->g_bGVfilter)
2757  {
2758  scandist[t] = FLT_MAX;
2759  if (gameclass->bus->targetC == t)
2760  gameclass->LostScannerTarget("Framemove1");
2761  }
2762  else
2763  {
2765  }
2766 
2767  // hide these special ones from the scanners
2768  if (playerships[scanslot[t]].type == VehicleType::FloatingMan || playerships[scanslot[t]].type == VehicleType::BeishtKione)
2769  {
2770  if (playerships[scanslot[t]].distance < 0.016f)
2771  {
2772  gameclass->sound->GlobalAttenuate(0.0f, 2.0f, 2.0f, SOUND_HOLIDAY2019, 0.0f, 4.0f, 0.0f);
2773  gameclass->sound->PlayEx(SOUND_HOLIDAY2019, false, 1, 1, 0.4f); // right
2774  playerships[scanslot[t]].visible = false;
2776  gameclass->bus->ProximityAlert = false;
2777  }
2778  else if (playerships[scanslot[t]].distance < 0.25f)
2779  {
2780  gameclass->bus->ProximityAlert = true;
2781  }
2782  scandist[t] = FLT_MAX;
2783  }
2784  }
2785  else
2786  {
2787  scandist[t] = FLT_MAX;
2788  if (gameclass->bus->targetC == t)
2789  gameclass->LostScannerTarget("Framemove2");
2790  }
2791  }
2792 
2793  // For Sorting
2794  for (t = 0; t < (MAX_SCAN - 1); t++)
2795  {
2796  if (scandist[t] > scandist[t + 1])
2797  {
2798  f_temp = scandist[t + 1];
2799  const short i_temp = scanslot[t + 1];
2800  scandist[t + 1] = scandist[t];
2801  scanslot[t + 1] = scanslot[t];
2802  scandist[t] = f_temp;
2803  scanslot[t] = i_temp;
2804  if (gameclass->bus->targetC == t)
2805  gameclass->bus->targetC++;
2806  else if (gameclass->bus->targetC == (t + 1))
2807  gameclass->bus->targetC--;
2808  }
2809  }
2810 
2811  // For scrolling
2812  topscroll = 0;
2813  for (t = 0; t < MAX_SCAN; t++)
2814  {
2815  if (scandist[t] < 999.0f)
2816  topscroll = t;
2817  }
2820  if (scanscroll < 0)
2821  scanscroll = 0;
2822 
2823 
2824  // For trees
2825 #ifdef treetestC
2826  D3DXVECTOR3 position = playerships[0].position;
2827  for (t = 0; t < treesC; t++)
2828  {
2829  treepos[t] = treelist[t] - position;
2830  treedist[t] = D3DXVec3Length(&treepos[t]);
2831  }
2832 
2833  bool swapflag;
2834  do
2835  {
2836  swapflag = false;
2837  for (t = 1; t < treesC; t++)
2838  {
2839  if (treedist[t] > treedist[t - 1])
2840  {
2841  result = treelist[t - 1];
2842  treelist[t - 1] = treelist[t];
2843  treelist[t] = result;
2844  result = treepos[t - 1];
2845  treepos[t - 1] = treepos[t];
2846  treepos[t] = result;
2847  f_temp = treedist[t - 1];
2848  treedist[t - 1] = treedist[t];
2849  treedist[t] = f_temp;
2850  swapflag = true;
2851  }
2852  }
2853  } while (swapflag);
2854 #endif
2855 
2856 
2857  // Rain
2858  if (!gameclass->bus->FlightFreeze && ptrWeather->GetTurbidity() > 5.0f)
2859  {
2860  static double oldprecisionx = playerships[0].precisionx;
2861  static double oldprecisiony = playerships[0].precisiony;
2862  static double oldprecisionz = playerships[0].precisionz;
2863  D3DXVECTOR3 posnorml;
2864  D3DXVec3Normalize(&posnorml, &playerships[0].position);
2865  posnorml = -posnorml;
2866 
2867  D3DXMatrixLookAtRH(&matrixTemp, &centerC, &headlightvec, &posnorml); // eye at up
2868  result.x = static_cast<float>(playerships[0].precisionx - oldprecisionx);
2869  result.y = static_cast<float>(playerships[0].precisiony - oldprecisiony);
2870  result.z = static_cast<float>(playerships[0].precisionz - oldprecisionz);
2871 
2872  D3DXVec3TransformNormal(&result, &result, &matrixTemp);
2873 
2874 
2875  if (ptrWeather->GetTurbidity() > 6.0f)
2877  else
2878  {
2879  raindrops = static_cast<short>((ptrWeather->GetTurbidity() - 5.0f) * MAX_RAINDROPS);
2880  if (raindrops % 2 == 1) // must be divisible by 2
2881  raindrops++;
2882  }
2883 
2884  if (m_avRainDrops)
2885  {
2886  D3DRAINDROP* vtxs;
2887  // Lock the vertex buffer
2888  V(m_avRainDrops->Lock(0, 0, reinterpret_cast<void**>(&vtxs), D3DLOCK_DISCARD));
2889  const float adj = (ptrWeather->GetTurbidity() - 5.0f) / 11.0f*0.00015f + 0.00005f;
2890  for (t = 0; t < raindrops; t++)
2891  {
2892  (*vtxs).x = rainarray[t].x; (*vtxs).y = rainarray[t].y; (*vtxs).z = rainarray[t].z;
2893  (*vtxs).nx = 0.0f; (*vtxs).ny = 0.0f; (*vtxs).nz = 0.0f;
2894  (*vtxs).diffuse = D3DCOLOR_ARGB(0, 192, 192, 192);
2895 
2896  rainarray[t] += result;
2897  rainarray[t].y -= adj; // 14 mph average drop is 0.00625 // 0.00005 is mist, 0.0002 is downpour
2898  D3DXMatrixRotationYawPitchRoll(&matrixTemp, -playerships[0].yaw*fElapsedTime, -playerships[0].pitch*fElapsedTime, -playerships[0].roll*fElapsedTime);
2899  // rainarray[t].x-=playerships[0].yaw*0.01f*rainarray[t].z;
2900  // rainarray[t].y+=playerships[0].pitch*0.01f*rainarray[t].z;
2901  D3DXVec3TransformCoord(&rainarray[t], &rainarray[t], &matrixTemp);
2902  if (fabsf(rainarray[t].y) > 0.025f || // above or below out of site
2903  fabsf(rainarray[t].x) > 0.1f ||//half || //(-rainarray[t].z/0.2f*half))
2904  fabsf(rainarray[t].z) > 0.2f) //rainarray[t].z<-0.2f || rainarray[t].z>=0.0f)
2905  {
2906  const float width = RandomFloat()*0.2f - 0.1f;//wide-half; // 200m wide
2907  const float zdist = RandomFloat(); // percentage of 200m distance
2908  rainarray[t].x = width;
2909  rainarray[t].y = RandomFloat()*0.05f - 0.025f; // vertically 100m above/below
2910  rainarray[t].z = zdist * 0.4f - 0.2f;
2911  (*vtxs).x = rainarray[t].x; (*vtxs).y = rainarray[t].y; (*vtxs).z = rainarray[t].z;
2912  }
2913 
2914  vtxs++;
2915  (*vtxs).x = rainarray[t].x; (*vtxs).y = rainarray[t].y; (*vtxs).z = rainarray[t].z;
2916  (*vtxs).nx = 0.0f; (*vtxs).ny = 0.0f; (*vtxs).nz = 1.0f;
2917  (*vtxs).diffuse = D3DCOLOR_ARGB(static_cast<int>(128.0f*(1.0f - (-rainarray[t].z / 0.2f))), 192, 192, 192);//0xFF7F7F7F;//;
2918  vtxs++;
2919  }
2920  V(m_avRainDrops->Unlock());
2921  }
2922 
2923  oldprecisionx = playerships[0].precisionx;
2924  oldprecisiony = playerships[0].precisiony;
2925  oldprecisionz = playerships[0].precisionz;
2926  }
2927  else
2928  raindrops = 0;
2929 
2930 
2931  AssertTelemetry("FrameMove::OnFrameMove6", 0);
2932 
2933 
2934  if (outside && !gameclass->GUI->IsAdmin && (gameclass->GUI->player[ourcockpit.ourplyrC].frame != REF_INANOTHER || playerships[0].simulator))
2935  OutsideView(false);
2936 
2937 
2938  if (gameclass->GUI->player[ourcockpit.ourplyrC].frame > REF_INANOTHER) // in a building
2939  {
2940  //for (t = 0; t < MAX_ONLINEPLAYERS; t++)
2941  t = ourcockpit.ourplyrC;
2942  {
2943  //gameclass->GUI->player[t].smoothleftright += ((float)gameclass->GUI->player[t].leftright*0.014981273408239700374531835205993f - gameclass->GUI->player[t].smoothleftright)*fElapsedTime;
2944  //gameclass->GUI->player[t].smoothupdown += ((float)gameclass->GUI->player[t].updown*0.014981273408239700374531835205993f - gameclass->GUI->player[t].smoothupdown)*fElapsedTime;
2945  //gameclass->GUI->player[t].smoothrolltilt += ((float)gameclass->GUI->player[t].rolltilt*0.014981273408239700374531835205993f - gameclass->GUI->player[t].smoothrolltilt)*fElapsedTime;
2946 
2947  gameclass->GUI->player[t].smoothhdg = D3DXToRadian(gameclass->GUI->player[t].hdg);
2948 
2949  if (t == ourcockpit.ourplyrC)
2950  {
2951  static bool leftfoot = false; // start on the right
2952  static float footstep = 0.0f;
2953  if (ourcockpit.moving > 0.0f) // wanting to walk forward
2954  {
2955  footstep += fElapsedTime * 6.0f;
2956  if (footstep >= 1.0f)
2957  {
2958  footstep = 0.0f;
2959  gameclass->sound->PlayEx(SOUND_COCKPITLAND, false, 1, 1, leftfoot ? -0.25f : 0.25f, false);
2960  leftfoot = !leftfoot;
2961  }
2962  if (gameclass->GUI->player[t].ani == 1 || gameclass->GUI->player[t].ani == 2 || gameclass->GUI->player[t].ani == 10 || gameclass->GUI->player[t].ani == 12) // started walking on left, was on left
2963  {
2964  //if (ourcockpit.turnin < 0) // left turn with right foot
2965  // gameclass->GUI->player[t].queueani = 11;
2966  //else if (ourcockpit.turnin > 0) // right turn with right foot
2967  // gameclass->GUI->player[t].queueani = 13;
2968  //else
2969  gameclass->GUI->player[t].queueani = 4; // right foot
2970  }
2971  else if (gameclass->GUI->player[t].ani == 4 || gameclass->GUI->player[t].ani == 11 || gameclass->GUI->player[t].ani == 13) // was on right foot
2972  {
2973  //if (ourcockpit.turnin < 0) // left turn with left foot
2974  // gameclass->GUI->player[t].queueani = 10;
2975  //else if (ourcockpit.turnin > 0) // right turn with left foot
2976  // gameclass->GUI->player[t].queueani = 12;
2977  //else
2978  gameclass->GUI->player[t].queueani = 2; // left foot
2979  }
2980  else if (gameclass->GUI->player[t].ani == 0 || gameclass->GUI->player[t].ani == 14) // had hand on hip
2981  gameclass->GUI->player[t].queueani = 15; // put arm down
2982  else
2983  gameclass->GUI->player[t].queueani = 1; // start walking
2984  ourcockpit.impatientime = 0.0f;
2985  gameclass->GUI->player[t].hdg += 100.0f * ourcockpit.turnin * fElapsedTime;
2986  }
2987  else if (ourcockpit.turnin != 0.0f) // wanting to turn in place
2988  {
2989  if (gameclass->GUI->player[t].ani == 0 || gameclass->GUI->player[t].ani == 14)
2990  gameclass->GUI->player[t].ani = 15;
2991  else if (gameclass->GUI->player[t].ani == 7)
2992  {
2993  if (ourcockpit.turnin < 0) // left
2994  gameclass->GUI->player[t].queueani = 8;
2995  else
2996  gameclass->GUI->player[t].queueani = 9;
2997  }
2998  ourcockpit.impatientime = 0.0f;
2999  gameclass->GUI->player[t].hdg += 100.0f * ourcockpit.turnin * fElapsedTime;
3000  }
3001  else if (ourcockpit.moving <= 0) // wanting to stop
3002  {
3003  if (gameclass->GUI->player[t].ani == 7) // was ready
3004  {
3005  if (ourcockpit.impatientime > 20.0f) // standing for 20 sec
3006  {
3007  gameclass->GUI->player[t].queueani = 0; // impatiently standing
3008  }
3009  else
3010  {
3011  gameclass->GUI->player[t].queueani = 7; // still ready
3012  ourcockpit.impatientime += fElapsedTime;
3013  leftfoot = false;
3014  footstep = 0.0f;
3015  }
3016  }
3017  else if (gameclass->GUI->player[t].ani == 0 || gameclass->GUI->player[t].ani == 14)
3018  gameclass->GUI->player[t].queueani = 14;
3019  else if (gameclass->GUI->player[t].ani == 1 || gameclass->GUI->player[t].ani == 2 || gameclass->GUI->player[t].ani == 10 || gameclass->GUI->player[t].ani == 12) // walk loop or started
3020  gameclass->GUI->player[t].queueani = 3;
3021  else if (gameclass->GUI->player[t].ani == 4 || gameclass->GUI->player[t].ani == 11 || gameclass->GUI->player[t].ani == 13)
3022  gameclass->GUI->player[t].queueani = 5;
3023  else
3024  gameclass->GUI->player[t].queueani = 7;
3025  }
3026 
3028  {
3029  if (ourcockpit.turnin != 0.0f && ourcockpit.moving > 0.0f)
3030  {
3031  const float newOnFootTarget = ourcockpit.turnin * D3DXToRadian(15.0f);
3032  targetLeftright += (newOnFootTarget - targetLeftright)*fElapsedTime*2.0f;
3033  }
3034  else if (ourcockpit.moving > 0.0f)
3035  {
3036  if (targetLeftright > 0)
3037  {
3038  targetLeftright -= fElapsedTime;
3039  if (targetLeftright < 0)
3040  targetLeftright = 0;
3041  }
3042  else if (targetLeftright < 0)
3043  {
3044  targetLeftright += fElapsedTime;
3045  if (targetLeftright > 0)
3046  targetLeftright = 0;
3047  }
3048  }
3049  }
3050 
3051  //if (!gameclass->config.inputConfigWalkLateral.g_pJoystick)
3052  ourcockpit.turnin = 0;
3053  //if (!gameclass->config.inputConfigWalkVertical.g_pJoystick)
3054  ourcockpit.moving = 0; // 1 is walking forward by keyboard request
3055  }
3056 
3057  gameclass->GUI->player[t].anitime += fElapsedTime;// *max(fabsf(ourcockpit.moving), 0.2f);
3058  Sani tempani = GetAni(gameclass->GUI->player[t].anitime, gameclass->GUI->player[t].ani);
3059 
3060  if (tempani.end == -353.0f || // end
3061  (gameclass->GUI->player[t].ani != gameclass->GUI->player[t].queueani && // new ani
3062  gameclass->GUI->player[t].queueani != 7 && gameclass->GUI->player[t].queueani != 14 && // not to interrupt for
3063  (gameclass->GUI->player[t].ani == 7 || gameclass->GUI->player[t].ani == 14))) // interrupt-able
3064  {
3065  gameclass->GUI->player[t].ani = gameclass->GUI->player[t].queueani;
3066  gameclass->GUI->player[t].anitime = 0.0f;
3067  tempani = GetAni(gameclass->GUI->player[t].anitime, gameclass->GUI->player[t].ani);
3068  // set new start (right now we have end in .x and .y)
3069  //Sani offset = game->GetAni(10.0f, game->gameclass->GUI->player[t].ani); // where they end up
3070  gameclass->GUI->player[t].startx = static_cast<float>(gameclass->GUI->player[t].x);
3071  gameclass->GUI->player[t].starty = static_cast<float>(gameclass->GUI->player[t].y);
3072  }
3073 
3074  float proposedX = gameclass->GUI->player[t].startx + cosf(gameclass->GUI->player[t].smoothhdg + D3DX_HALFPI) * static_cast<float>(tempani.xyz.y) + sinf(gameclass->GUI->player[t].smoothhdg + D3DX_HALFPI)*static_cast<float>(tempani.xyz.x);
3075  float proposedY = gameclass->GUI->player[t].starty - sinf(gameclass->GUI->player[t].smoothhdg + D3DX_HALFPI) * static_cast<float>(tempani.xyz.y) - cosf(gameclass->GUI->player[t].smoothhdg + D3DX_HALFPI)*static_cast<float>(tempani.xyz.x);
3076  if (t == ourcockpit.ourplyrC)
3077  {
3078  short roomIndex = -1;
3079 
3080  if (gameclass->GUI->player[t].frame == REF_BUILDING)
3081  {
3082  if (gameclass->GUI->player[t].bldg == 1) // bradbury apartment
3083  {
3084  RECT proposedRoom = WhichRoom(rooms, proposedX, proposedY, &roomIndex);
3085  if (RectEquality(proposedRoom, RECT()))
3086  proposedRoom = WhichRoom(rooms, static_cast<float>(gameclass->GUI->player[t].x), proposedY, &roomIndex);
3087  if (RectEquality(proposedRoom, RECT()))
3088  proposedRoom = WhichRoom(rooms, proposedX, static_cast<float>(gameclass->GUI->player[t].y), &roomIndex);
3089  if (RectEquality(proposedRoom, RECT()))
3090  proposedRoom = WhichRoom(rooms, static_cast<float>(gameclass->GUI->player[t].x), static_cast<float>(gameclass->GUI->player[t].y), &roomIndex);
3091  if (RectEquality(proposedRoom, RECT()))
3092  {
3093  roomIndex = 7;
3094  proposedRoom = rooms.at(7);
3095  logger->Log("Had to reposition the player to the foyer (Bradbury Building)", Logger::Level::Error);
3096  }
3097 
3098  if (proposedX > static_cast<float>(proposedRoom.right))
3099  proposedX = static_cast<float>(proposedRoom.right);
3100  if (proposedX < static_cast<float>(proposedRoom.left))
3101  proposedX = static_cast<float>(proposedRoom.left);
3102  if (proposedY < static_cast<float>(proposedRoom.bottom))
3103  proposedY = static_cast<float>(proposedRoom.bottom);
3104  if (proposedY > static_cast<float>(proposedRoom.top))
3105  proposedY = static_cast<float>(proposedRoom.top);
3106 
3107  if (RectEquality(proposedRoom, rooms.at(0)) && proposedY == proposedRoom.top)
3109  else if (RectEquality(proposedRoom, rooms.at(3)))
3111 
3112  if (RectEquality(proposedRoom, rooms.at(7)))
3113  {
3116  }
3117  else
3119  }
3120  else if (gameclass->GUI->player[t].bldg == 2) // control tower
3121  {
3122  if (proposedX > 830)
3123  proposedX = 830;
3124  else if (proposedX < -785)
3125  proposedX = -785;
3126  if (proposedY > 780)
3127  proposedY = 780;
3128  else if (proposedY < -707)
3129  proposedY = -707;
3130 
3131  // over stairwell
3132  if (proposedX > -253 && proposedX<230 && proposedY>-258 && proposedY < 212)
3133  {
3134  // which edge are they closest to?
3135  const int northEdge = abs(-258 - static_cast<int>(proposedY));
3136  const int southEdge = abs(212 - static_cast<int>(proposedY));
3137  const int eastEdge = abs(-253 - static_cast<int>(proposedX));
3138  const int westEdge = abs(230 - static_cast<int>(proposedX));
3139  if (westEdge < eastEdge && westEdge < northEdge && westEdge < southEdge)
3140  proposedX = 230;
3141  else if (eastEdge < westEdge && eastEdge < northEdge && eastEdge < southEdge)
3142  proposedX = -253;
3143  else if (southEdge < northEdge && southEdge < westEdge && southEdge < eastEdge)
3144  proposedY = 212;
3145  else if (northEdge < southEdge && northEdge < westEdge && northEdge < eastEdge)
3146  proposedY = -258;
3147  }
3148  }
3149  }
3150  else if (gameclass->GUI->player[t].frame == REF_SIMBAY)
3151  {
3152  RECT proposedRoom = WhichRoom(rooms, proposedX, proposedY, &roomIndex);
3153  if (RectEquality(proposedRoom, RECT()))
3154  proposedRoom = WhichRoom(rooms, static_cast<float>(gameclass->GUI->player[t].x), proposedY, &roomIndex);
3155  if (RectEquality(proposedRoom, RECT()))
3156  proposedRoom = WhichRoom(rooms, proposedX, static_cast<float>(gameclass->GUI->player[t].y), &roomIndex);
3157  if (RectEquality(proposedRoom, RECT()))
3158  proposedRoom = WhichRoom(rooms, static_cast<float>(gameclass->GUI->player[t].x), static_cast<float>(gameclass->GUI->player[t].y), &roomIndex);
3159  if (RectEquality(proposedRoom, RECT()))
3160  {
3161  roomIndex = 0;
3162  proposedRoom = rooms.at(0);
3163  logger->Log("Had to reposition the player to the west entrance (Simulator Bay)", Logger::Level::Error);
3164  }
3165 
3166  if (proposedX > static_cast<float>(proposedRoom.right))
3167  proposedX = static_cast<float>(proposedRoom.right);
3168  if (proposedX < static_cast<float>(proposedRoom.left))
3169  proposedX = static_cast<float>(proposedRoom.left);
3170  if (proposedY < static_cast<float>(proposedRoom.bottom))
3171  proposedY = static_cast<float>(proposedRoom.bottom);
3172  if (proposedY > static_cast<float>(proposedRoom.top))
3173  proposedY = static_cast<float>(proposedRoom.top);
3174 
3175  //if (RectEquality(proposedRoom, rooms.at(0)) && proposedY == proposedRoom.top)
3176  // gameclass->GUI->informationDialog->PopUpHelp(ActiveHelp::AptWindows);
3177  //else if (RectEquality(proposedRoom, rooms.at(3)))
3178  // gameclass->GUI->informationDialog->PopUpHelp(ActiveHelp::KeyboardBindings, false);
3179 
3180  //if (RectEquality(proposedRoom, rooms.at(7)))
3181  //{
3182  // if (!gameclass->GUI->informationDialog->PopUpHelp(ActiveHelp::Garage))
3183  // gameclass->GUI->informationDialog->PopUpHelp(ActiveHelp::Intermedia2, false);
3184  //}
3185  //else
3186  // gameclass->GUI->informationDialog->DismissHelp(ActiveHelp::Intermedia2, GUI_REMINDME);
3187  }
3188 
3189  if (oldRoomIndex != roomIndex)
3190  {
3191  SClientPacket ourpacket; // NOLINT
3192  ourpacket.type = 6; // character movement
3193  ourpacket.f_x = static_cast<float>(roomIndex);
3194  ourpacket.f_y = 0.0f; // UNUSED
3195  ourpacket.f_z = 0.0f; // UNUSED
3196  ourpacket.f_w = 0.0f; // UNUSED
3197  gameclass->networking->SendToServer(&ourpacket, sizeof(SClientPacket), true);
3198  oldRoomIndex = roomIndex;
3199  }
3200 
3201  ourcockpit.chaireye.x = proposedX * INTERIOR_SCALE;
3202  ourcockpit.chaireye.y = proposedY * INTERIOR_SCALE;
3203  //ourcockpit.chaireye.z = gameclass->GUI->player[t].smoothz + 236.0f*InteriorScaleC; // don't touch ... this comes from server character height
3204  }
3205 
3206  gameclass->GUI->player[t].smoothx = proposedX * INTERIOR_SCALE;
3207  gameclass->GUI->player[t].smoothy = proposedY * INTERIOR_SCALE;
3208  gameclass->GUI->player[t].smoothz = static_cast<float>(tempani.xyz.z)*INTERIOR_SCALE;
3209  gameclass->GUI->player[t].x = static_cast<int>(proposedX);
3210  gameclass->GUI->player[t].y = static_cast<int>(proposedY);
3211  }
3212  }
3213  else
3214  {
3215  ourcockpit.chaireye.x = 0.0f;
3217  ourcockpit.chaireye.z = 0.0f;
3218  }
3219 
3220 #ifdef _DEBUG
3221  otherFrameMoveTimer->stopTimer();
3222 #endif
3223 
3224 
3225 #ifdef _DEBUG
3226  weatherFrameMoveTimer->startTimer();
3227 #endif
3228  ptrWeather->FrameMove(fElapsedTime);
3229 #ifdef _DEBUG
3230  weatherFrameMoveTimer->stopTimer();
3231 #endif
3232 
3233 
3234 #ifdef _DEBUG
3235  cockpitFrameMoveTimer->startTimer();
3236 #endif
3237  ptrCockpit->FrameMove(fElapsedTime);
3238 #ifdef _DEBUG
3239  cockpitFrameMoveTimer->stopTimer();
3240 #endif
3241 
3242 
3243 #ifdef _DEBUG
3244  instrumentsFrameMoveTimer->startTimer();
3245 #endif
3246  ptrInstruments->FrameMove(fElapsedTime);
3247 #ifdef _DEBUG
3248  instrumentsFrameMoveTimer->stopTimer();
3249 #endif
3250 
3251 
3252  lateralmod = false;
3253  verticalmod = false;
3254  yawmod = false;
3255 
3256  logger->AddToCallStack("Viewscreen::OnFrameMove DONE");
3257 }
#define radiusC
Definition: globals.h:88
float rolltilt
Definition: Viewscreen.h:313
float baydoorextent
Definition: globals.h:572
#define MAX_RAINDROPS
Definition: globals.h:70
float GetCloudCeilingMslKm() const
Definition: weather.cpp:945
D3DXMATRIX matWorld
Definition: globals.h:428
float LeadingEdgeFlapsPosition
Definition: Bus.h:326
float timer[PlotType::PlotTypeEnum]
Definition: globals.h:524
#define firework3C
Definition: globals.h:51
#define firework1C
Definition: globals.h:49
bool DismissHelp(int helpId, int nControlID=GUI_UNDERSTOOD)
Ssorter sortme[buildingVBC]
Definition: globals.cpp:166
D3DXVECTOR3 chaireye
Definition: globals.h:618
float tat_mod_qz_x
Definition: propulsion.h:82
Scockpit ourcockpit
Definition: globals.cpp:176
#define oneOvergForceKmSSC
Definition: globals.h:91
float yawInput
Definition: Viewscreen.h:237
D3DLIGHT9 sunlight
Definition: Viewscreen.h:217
float rollAccelerationSnapshot
Definition: propulsion.h:83
float dockOffsetKmY
Definition: globals.h:700
D3DXMATRIX matrixBase
Definition: globals.h:491
VECTOR2SHORT tcp
Definition: grid.h:34
void DumpSofTracking()
bool TurnOffTVM() const
Definition: GameClass.cpp:2243
#define MAX_ENGINES
Definition: Bus.h:14
s_mesh_component * componentarray
Definition: globals.h:497
D3DXVECTOR3 dockingvel
Definition: globals.h:540
D3DXVECTOR3 cockpitArmKm
Definition: globals.h:620
double ProgramTime
Definition: Bus.h:373
#define heartanimateC
Definition: globals.h:53
float LocalTimeMinutes
Definition: Bus.h:359
D3DXVECTOR3 acc
Definition: globals.h:542
float LatitudeRad
Definition: Bus.h:235
D3DXVECTOR3 acciter
Definition: globals.h:542
float power
Definition: globals.h:608
float yawdeflect
Definition: globals.h:562
float LandingGearExtended
Definition: Bus.h:224
float fuel
Definition: globals.cpp:143
short dihvanimate
Definition: globals.cpp:71
float targetLeftright
Definition: Viewscreen.h:311
D3DXQUATERNION orientation
Definition: globals.h:499
float RightBrake
Definition: Bus.h:289
void FrameMove(float fElapsedTime) const
Definition: cockpit.cpp:35
float y
Definition: globals.h:208
Config config
Definition: GameClass.h:102
D3DXVECTOR3 lookvec
Definition: Viewscreen.h:230
Definition: globals.h:782
short heartloop
Definition: Viewscreen.h:265
D3DXVECTOR3 posnorml
Definition: Viewscreen.h:248
bool g_bAboveClouds
Definition: globals.cpp:22
float oldflasher
Definition: globals.cpp:66
D3DXVECTOR3 position
Definition: Viewscreen.h:247
std::vector< Command > commandStream
Definition: Bus.h:342
void Poll()
Definition: FreeTrack.cpp:50
D3DXVECTOR3 position
Definition: globals.h:549
float GetArcDist(D3DXVECTOR3 from, D3DXVECTOR3 to, bool includeAltDiff)
Definition: MathUtilities.h:37
#define cloudTopsMslC
Definition: globals.h:92
char causechain
Definition: Viewscreen.h:241
float touchdownG
Definition: globals.cpp:69
bool RectEquality(RECT rect1, RECT rect2)
Definition: MathUtilities.h:92
float FuelWeightLbs
Definition: Bus.h:362
GameClass * gameclass
Definition: Viewscreen.h:292
short scanDisplayVesselLimit
Definition: globals.h:702
D3DXQUATERNION orientation
Definition: globals.h:558
void Update(float fElapsedTime)
Definition: propulsion.cpp:125
D3DXVECTOR3 compassnorth
Definition: Viewscreen.h:43
float DebugFloat7
Definition: Bus.h:414
void SendToServer(void *pData, DWORD dwSize, bool bGuaranteed, PacketOrdering order=ORDERING_NONE) const
Definition: Networking.cpp:59
D3DXMATRIX matrixLook
Definition: Viewscreen.h:220
float counterj
Definition: Viewscreen.h:315
char startcycle
Definition: globals.h:608
float tireRotationRadians
Definition: globals.h:573
unsigned char BCLobjC
Definition: globals.cpp:28
float serviceCeilingKm
Definition: globals.h:631
int flapMaxDegrees
Definition: globals.h:692
long topscroll
Definition: globals.cpp:94
short oldRoomIndex
Definition: Viewscreen.h:245
D3DXVECTOR3 terpos
Definition: globals.h:449
D3DXVECTOR2 CalculateLatLng(D3DXVECTOR3 position)
Definition: MathUtilities.h:17
float f_Uphours
Definition: globals.cpp:25
VECTOR2SHORT CalculateCGC(D3DXVECTOR3 position, char cube) const
InformationDialog * informationDialog
Definition: gui.h:789
float frameRateHeartbeat
Definition: Viewscreen.h:36
void AutopilotDisconnect() const
Definition: GameClass.cpp:2233
instruments * ptrInstruments
Definition: Viewscreen.h:289
float counteri
Definition: Viewscreen.h:315
void Movement(short t, float ElapsedTime)
unsigned long compare
Definition: globals.h:505
double precisiony
Definition: globals.h:550
FIREWORKS fireworks[fireworksC]
Definition: globals.cpp:181
D3DXVECTOR3 position
Definition: globals.h:280
float yawAccelerationSnapshot
Definition: propulsion.h:83
void FrameMove(float fElapsed)
Definition: Displays.cpp:439
s_network_objects playerships[MAX_SCAN]
Definition: globals.cpp:174
float cash
Definition: globals.cpp:146
float speedRetract
Definition: globals.h:412
unsigned char ourmoonC
Definition: globals.cpp:27
float dihvelapsed
Definition: globals.cpp:74
float leftright
Definition: Viewscreen.h:311
D3DXVECTOR3 velocity
Definition: globals.h:500
void FrameMove(float fElapsedTime)
Definition: instruments.cpp:19
float rollInput
Definition: Viewscreen.h:237
float displayHeight
Definition: GameClass.h:129
float weapontimer[2]
Definition: globals.cpp:142
weapon * ptrWeapon
Definition: Viewscreen.h:280
long dihvtimeseq
Definition: globals.cpp:73
D3DXCOLOR alphascreen
Definition: Viewscreen.h:231
float updown
Definition: Viewscreen.h:312
float f_compareFOV
Definition: globals.cpp:130
void Update(float fElapsedTime) const
Definition: joystick.cpp:84
float pitchAccelerationSnapshot
Definition: propulsion.h:83
float H2Ooffsetu
Definition: Viewscreen.h:267
float extended
Definition: globals.h:427
D3DVERTEX * vertexbackup
Definition: globals.h:345
float deathfuel
Definition: globals.cpp:144
InputConfig inputConfigLookVertical
Definition: config.h:38
s_city_stuff citystuff
Definition: globals.cpp:172
float end
Definition: globals.h:785
float interlace
Definition: Viewscreen.h:270
float f_ACL
Definition: globals.cpp:16
float leftlimit
Definition: Viewscreen.h:314
D3DXQUATERNION orientleft
Definition: globals.h:558
std::vector< Module * > modules
Definition: GameClass.h:117
void ToggleFullScreen(bool goFullScreen)
Definition: GameClass.cpp:269
float gammascreenOverride
Definition: weather.h:85
short scanslot[MAX_SCAN]
Definition: Viewscreen.h:276
weather * ptrWeather
Definition: Viewscreen.h:287
#define weaponsinkerreadyC
Definition: globals.h:68
void SendEvent(EventType eventType, float extent=0.0f) const
Definition: Networking.cpp:111
float displayWidth
Definition: GameClass.h:129
bool verticalmod
Definition: Viewscreen.h:244
D3DXVECTOR3 dockInterface
Definition: globals.cpp:47
bool sentgearvoice
Definition: globals.h:623
float lookhdg
Definition: Viewscreen.h:234
float shockramp
Definition: globals.h:795
float PressureAltitudeKm
Definition: Bus.h:25
float turnin
Definition: globals.h:661
float x
Definition: globals.h:223
float uplimit
Definition: Viewscreen.h:314
float x
Definition: FreeTrack.h:80
std::vector< RECT > rooms
Definition: Viewscreen.h:42
Sani GetAni(float f_time, unsigned char ani) const
joystick * ptrJoystick
Definition: Viewscreen.h:283
void Update(float fElapsedTime)
Definition: keyboard.cpp:156
bool advanceframe
Definition: Viewscreen.h:240
void PopUpDialog()
float moving
Definition: globals.h:660
static RECT WhichRoom(const std::vector< tagRECT > &rooms, float x, float y, short *roomIndex)
Definition: framemove.cpp:264
LPDIRECTINPUTDEVICE8 g_pJoystick
Definition: InputConfig.h:22
float DebugFloat9
Definition: Bus.h:416
POINT ptCursor
Definition: gui.h:724
D3DXVECTOR3 veliter
Definition: globals.h:541
std::string name
Definition: Command.h:11
D3DXVECTOR3 NormalAcceleration
Definition: Bus.h:34
D3DXVECTOR3 nominalypr
Definition: globals.h:417
float lookAzimuthDegrees
Definition: Viewscreen.h:234
const D3DXVECTOR3 northpoleC
float impatientime
Definition: globals.h:662
unsigned char UCLobjC
Definition: globals.cpp:29
D3DXMATRIX matrixLookAdj
Definition: Viewscreen.h:220
bool ThrustReverserCommand[MAX_ENGINES]
Definition: Bus.h:61
s_mesh_component * componentarray
Definition: globals.h:578
bool g_bEnabled
Definition: globals.cpp:149
static DialogBase * dialogs[D_ENUMERATION]
Definition: DialogBase.h:39
#define fireworksC
Definition: globals.h:746
void LostScannerTarget(const char *msg) const
Definition: GameClass.cpp:2191
float targetUpdown
Definition: Viewscreen.h:312
propulsion * ptrPropulsion
Definition: Viewscreen.h:285
float tiltlimitL
Definition: Viewscreen.h:314
bool TurnOffDOR() const
Definition: GameClass.cpp:2262
float startupextend
Definition: globals.h:608
D3DXMATRIX matrixReal
Definition: globals.h:491
bool lateralmod
Definition: Viewscreen.h:244
float flapExtent
Definition: globals.h:655
s_universe_object allobjects[maxstarC]
Definition: globals.cpp:170
void RequestScannerData() const
Definition: GameClass.cpp:132
float scanrange
Definition: globals.h:645
float GetWindspeedKms() const
Definition: weather.cpp:905
float z
Definition: FreeTrack.h:80
bool IsAdmin
Definition: gui.h:777
bool AssertTelemetry(const char *location, short id)
Definition: framemove.cpp:7
void Update(float fElapsedTime)
Definition: weapon.cpp:80
D3DXMATRIX matrixWorld
Definition: globals.h:491
D3DXVECTOR3 posleft
Definition: globals.h:541
float rolldeflect
Definition: globals.h:562
void FrameMove(float fElapsedTime)
Definition: weather.cpp:11
Networking * networking
Definition: GameClass.h:107
#define shipdockscaleC
Definition: globals.h:27
float DebugFloat2
Definition: Bus.h:409
keyboard * ptrKeyboard
Definition: Viewscreen.h:282
bool PopUpHelp(short helpId, bool allowDismiss=true, bool isLearnMore=false)
float x
Definition: globals.h:208
float f_MSL
Definition: globals.cpp:36
bool outside
Definition: Viewscreen.h:272
D3DXVECTOR3 sumofforces
Definition: globals.cpp:103
double precisionx
Definition: globals.h:550
SPlayerData player[MAX_ONLINEPLAYERS]
Definition: gui.h:765
float Clamp(float val, float min, float max)
Definition: MathUtilities.h:3
short texture
Definition: globals.h:750
D3DXVECTOR3 rainarray[MAX_RAINDROPS]
Definition: Viewscreen.h:259
#define weaponlongarmreadyC
Definition: globals.h:69
std::vector< std::string > sofTracking
Definition: Viewscreen.h:51
D3DXVECTOR3 xyz
Definition: globals.h:787
bool vdatChanged
Definition: globals.h:670
bool g_bRunning
Definition: globals.cpp:151
bool FlightFreeze
Definition: Bus.h:374
bool g_bRightDown
Definition: gui.h:720
float speedExtend
Definition: globals.h:412
float dockOffsetKmZ
Definition: globals.h:699
SoundConfig soundConfigComms
Definition: config.h:44
float qz
Definition: propulsion.h:80
void OnFrameMove(double fTime, float fElapsedTime)
Definition: framemove.cpp:283
void KillScannerData() const
Definition: GameClass.cpp:125
D3DXVECTOR3 shockmag
Definition: globals.h:798
float pitchInput
Definition: Viewscreen.h:237
LPDIRECT3DVERTEXBUFFER9 m_avRainDrops
Definition: Viewscreen.h:114
unsigned long compare[PlotType::PlotTypeEnum]
Definition: globals.h:523
float verticaltime
Definition: Viewscreen.h:243
char msg[199]
Definition: Viewscreen.h:33
bool spaceCapable
Definition: globals.h:605
D3DXCOLOR specular
Definition: globals.h:531
BUILDZONE buildzone[buildingVBC]
Definition: globals.cpp:165
float timetoshock
Definition: globals.h:794
float dockingOrientationZ
Definition: globals.h:701
Definition: Command.h:5
void ChangeVolume(SoundConfig *config, float modVolume)
Definition: Sound.cpp:504
short targetC
Definition: Bus.h:378
float rightlimit
Definition: Viewscreen.h:314
short attachto
Definition: globals.h:407
void Process()
Definition: grid.cpp:166
Ssorter sortmetemp
Definition: globals.cpp:166
float LongitudeDeg
Definition: Bus.h:234
float y
Definition: FreeTrack.h:80
float pitchdeflect
Definition: globals.h:562
float DebugFloat1
Definition: Bus.h:408
D3DXVECTOR3 velocity
Definition: globals.cpp:9
const D3DXVECTOR3 centerC
float TrailingEdgeFlapsPosition
Definition: Bus.h:324
float flasher
Definition: globals.cpp:65
short buildzone
Definition: globals.h:467
D3DXVECTOR3 velocity
Definition: globals.h:540
Sound * sound
Definition: GameClass.h:108
float LatitudeDeg
Definition: Bus.h:234
float GetAttenuation(bool applyDensity) const
Definition: Sound.cpp:1062
float z
Definition: globals.h:208
D3DXVECTOR3 headlightvec
Definition: Viewscreen.h:230
float tireCircumferenceKm
Definition: globals.h:563
static D3DXVECTOR3 CalculateBarycentric(D3DXVECTOR3 *position, D3DXVECTOR3 *gthrust, float *radius)
D3DXVECTOR3 velleft
Definition: globals.h:541
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
grid * ptrGrid
Definition: Viewscreen.h:279
void OutsideView(bool outside)
Definition: framemove.cpp:254
unsigned long compare
Definition: globals.h:552
void GlobalAttenuate(float prmGaTimeToFadeOut, float prmGaTimeToHold, float prmGaTimeToFadeIn, int soundEnum, float prmExTimeToFadeIn, float prmExTimeToHold, float prmExTimeToFadeOut, float volumeAdj=1.0f)
Definition: Sound.cpp:489
bool g_bGVfilter
Definition: gui.h:721
std::vector< SShockWave > shockwaves
Definition: globals.cpp:56
unsigned char hitpoints
Definition: globals.h:663
float gearextent
Definition: globals.h:621
D3DXVECTOR3 dockMarker
Definition: globals.cpp:46
#define firework2C
Definition: globals.h:50
float chairFwdRemaining
Definition: globals.h:616
float tatCelsius
Definition: propulsion.h:79
#define maxstarC
Definition: globals.h:24
D3DXMATRIX matrixBase
Definition: globals.h:556
float deathinhibit
Definition: globals.cpp:51
float chairfwdeye
Definition: globals.h:616
float counterk
Definition: Viewscreen.h:315
#define maxdockC
Definition: globals.h:25
#define buildingVBC
Definition: globals.h:54
D3DXVECTOR3 position
Definition: globals.h:619
bool yawmod
Definition: Viewscreen.h:244
float Play(int soundEnum)
Definition: Sound.cpp:577
#define INTERIOR_SCALE
Definition: globals.h:28
s_polygon_extras2 polyextras2
Definition: Viewscreen.h:255
D3DXMATRIX matrixView
Definition: Viewscreen.h:220
float LocalTimeHours
Definition: Bus.h:358
bool inuse
Definition: globals.h:749
float downlimit
Definition: Viewscreen.h:314
float g_UniverseTime
Definition: globals.cpp:24
float tiltlimitR
Definition: Viewscreen.h:314
#define maxcompareC
Definition: globals.h:61
SoundConfig soundConfigRadio
Definition: config.h:46
HMI * GUI
Definition: GameClass.h:110
D3DXVECTOR3 positer
Definition: globals.h:541
short ourplyrC
Definition: globals.h:659
float groundSpeedKms
Definition: globals.cpp:38
char CalculateCube(D3DXVECTOR3 position) const
float dockprogress
Definition: globals.cpp:44
#define weaponfuzerreadyC
Definition: globals.h:67
char dead
Definition: globals.cpp:49
float scandist[MAX_SCAN]
Definition: Viewscreen.h:277
short index[4500]
Definition: globals.h:347
unsigned short components
Definition: globals.h:496
LOCALGRID2 gridarray[64][64]
Definition: globals.cpp:153
D3DXVECTOR3 accleft
Definition: globals.h:542
FreeTrack * ptrFreeTrack
Definition: Viewscreen.h:284
cockpit * ptrCockpit
Definition: Viewscreen.h:288
float DebugFloat8
Definition: Bus.h:415
void Stop(int soundEnum)
Definition: Sound.cpp:1946
D3DXVECTOR3 barycentric
Definition: globals.h:540
D3DXMATRIX matGridRot
Definition: Viewscreen.h:221
#define cloudTopsRadiusC
Definition: globals.h:94
float delay
Definition: Command.h:8
float lampTest
Definition: Viewscreen.h:271
void PlayEx(int soundEnum, bool loop, float volume=1.0f, float frequencyMod=1.0f, float pan=0.0f, bool restart=true)
Definition: Sound.cpp:606
D3DXVECTOR4 gammascreen
Definition: Viewscreen.h:232
float LeftBrake
Definition: Bus.h:289
float GetTurbidity() const
Definition: weather.cpp:913
float lowframeTime
Definition: Viewscreen.h:35
D3DXQUATERNION orientiter
Definition: globals.h:558
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
Bus * bus
Definition: GameClass.h:112
SoundConfig soundConfigComputer
Definition: config.h:43
unsigned short causearray
Definition: Viewscreen.h:242
D3DXVECTOR3 hingeCG
Definition: globals.h:423
bool dihvcoming
Definition: globals.cpp:75
long scanscroll
Definition: globals.cpp:93
VECTOR2SHORT tcp
Definition: Bus.h:236
float speed[PlotType::PlotTypeEnum]
Definition: globals.h:524
float dist
Definition: globals.h:466
float lateraltime
Definition: Viewscreen.h:243
float shockspeed
Definition: globals.h:796
D3DXVECTOR3 position
Definition: globals.h:493
char gearshift
Definition: globals.h:652
float RandomFloat()
Definition: MathUtilities.h:98
bool ProximityAlert
Definition: Bus.h:376
Logger * logger
Definition: Viewscreen.h:293
double precisionz
Definition: globals.h:550
Displays * displays
Definition: GameClass.h:114
bool inhibitvisibility
Definition: globals.h:565
D3DXCOLOR specular
Definition: globals.h:281
InputConfig inputConfigLookLateral
Definition: config.h:37
D3DXVECTOR3 center[4500]
Definition: globals.h:346
D3DXVECTOR3 dockoffset
Definition: globals.h:549
unsigned short components
Definition: globals.h:577
float HeadingMagneticDegrees
Definition: Bus.h:31
float EngineThrustLever[MAX_ENGINES]
Definition: Bus.h:264
short raindrops
Definition: Viewscreen.h:260
char flicker
Definition: Viewscreen.h:269
SVesselDC vdat
Definition: globals.h:669