| 187 | } |
| 188 | |
| 189 | void OnRealtimeTick(uint delta_ms) override |
| 190 | { |
| 191 | /* Move the main game viewport according to intro viewport commands. */ |
| 192 | |
| 193 | if (intro_viewport_commands.empty()) return; |
| 194 | |
| 195 | bool suppress_panning = true; |
| 196 | if (this->mouse_idle_pos.x != _cursor.pos.x || this->mouse_idle_pos.y != _cursor.pos.y) { |
| 197 | this->mouse_idle_pos = _cursor.pos; |
| 198 | this->mouse_idle_time = 2000; |
| 199 | } else if (this->mouse_idle_time > delta_ms) { |
| 200 | this->mouse_idle_time -= delta_ms; |
| 201 | } else { |
| 202 | this->mouse_idle_time = 0; |
| 203 | suppress_panning = false; |
| 204 | } |
| 205 | |
| 206 | /* Determine whether to move to the next command or stay at current. */ |
| 207 | bool changed_command = false; |
| 208 | if (this->cur_viewport_command_index >= intro_viewport_commands.size()) { |
| 209 | /* Reached last, rotate back to start of the list. */ |
| 210 | this->cur_viewport_command_index = 0; |
| 211 | changed_command = true; |
| 212 | } else { |
| 213 | /* Check if current command has elapsed and switch to next. */ |
| 214 | this->cur_viewport_command_time += delta_ms; |
| 215 | if (this->cur_viewport_command_time >= intro_viewport_commands[this->cur_viewport_command_index].delay) { |
| 216 | this->cur_viewport_command_index = (this->cur_viewport_command_index + 1) % intro_viewport_commands.size(); |
| 217 | this->cur_viewport_command_time = 0; |
| 218 | changed_command = true; |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | IntroGameViewportCommand &vc = intro_viewport_commands[this->cur_viewport_command_index]; |
| 223 | Window *mw = GetMainWindow(); |
| 224 | |
| 225 | /* Early exit if the current command hasn't elapsed and isn't animated. */ |
| 226 | if (!changed_command && !vc.pan_to_next && vc.vehicle == VehicleID::Invalid()) return; |
| 227 | |
| 228 | /* Suppress panning commands, while user interacts with GUIs. */ |
| 229 | if (!changed_command && suppress_panning) return; |
| 230 | |
| 231 | /* Reset the zoom level. */ |
| 232 | if (changed_command) FixTitleGameZoom(vc.zoom_adjust); |
| 233 | |
| 234 | /* Calculate current command position (updates followed vehicle coordinates). */ |
| 235 | Point pos = vc.PositionForViewport(*mw->viewport); |
| 236 | |
| 237 | /* Calculate panning (linear interpolation between current and next command position). */ |
| 238 | if (vc.pan_to_next) { |
| 239 | size_t next_command_index = (this->cur_viewport_command_index + 1) % intro_viewport_commands.size(); |
| 240 | IntroGameViewportCommand &nvc = intro_viewport_commands[next_command_index]; |
| 241 | Point pos2 = nvc.PositionForViewport(*mw->viewport); |
| 242 | const double t = this->cur_viewport_command_time / (double)vc.delay; |
| 243 | pos.x = pos.x + (int)(t * (pos2.x - pos.x)); |
| 244 | pos.y = pos.y + (int)(t * (pos2.y - pos.y)); |
| 245 | } |
| 246 |
nothing calls this directly
no test coverage detected