Rigs of Rods 2026.01
Soft-body Physics Simulation
Loading...
Searching...
No Matches
Engine.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2023 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Engine.h"
23
24#include "AppContext.h"
25#include "ApproxMath.h" // frand()
26#include "Actor.h"
27#include "ActorManager.h"
28#include "Console.h"
29#include "InputEngine.h"
30#include "ScriptEngine.h"
31#include "SoundScriptManager.h"
32#include "TorqueCurve.h"
33
34using namespace Ogre;
35using namespace RoR;
36
37Engine::Engine(float _min_rpm, float _max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector<float> forward_gears, float diff_ratio, ActorPtr actor) :
38 m_air_pressure(0.0f)
39 , m_auto_cur_acc(0.0f)
40 , m_auto_mode(SimGearboxMode::AUTO)
41 , m_autoselect(DRIVE)
42 , m_braking_torque(-torque / 5.0f)
43 , m_clutch_force(10000.0f)
44 , m_clutch_time(0.2f)
45 , m_contact(false)
46 , m_cur_acc(0.0f)
47 , m_cur_clutch(0.0f)
48 , m_cur_clutch_torque(0.0f)
49 , m_cur_engine_rpm(0.0f)
50 , m_cur_engine_torque(0.0f)
51 , m_cur_gear(0)
52 , m_cur_gear_range(0)
53 , m_cur_wheel_revolutions(0.0f)
54 , m_ref_wheel_revolutions(0.0f)
55 , m_diff_ratio(diff_ratio)
56 , m_tcase_ratio(1.0f)
57 , m_engine_torque(torque)
58 , m_engine_has_air(true)
59 , m_engine_has_turbo(true)
60 , m_hydropump_state(0.0f)
61 , m_engine_idle_rpm(std::min(std::abs(_min_rpm), 800.0f))
62 , m_engine_inertia(10.0f)
63 , m_kickdown_delay_counter(0)
64 , m_max_idle_mixture(0.1f)
65 , m_engine_max_rpm(std::abs(_max_rpm))
66 , m_min_idle_mixture(0.0f)
67 , m_engine_min_rpm(std::abs(_min_rpm))
68 , m_num_gears((int)forward_gears.size())
69 , m_post_shift_time(0.2f)
70 , m_post_shift_clock(0.0f)
71 , m_post_shifting(0)
72 , m_engine_is_priming(false)
73 , m_engine_is_running(false)
74 , m_shift_behaviour(0.0f)
75 , m_shift_time(0.5f)
76 , m_shift_clock(0.0f)
77 , m_shifting(0)
78 , m_shift_val(0)
79 , m_engine_stall_rpm(300.0f)
80 , m_starter(0)
81 , m_torque_curve(new TorqueCurve())
82 , m_actor(actor)
83 , m_engine_turbo_mode(OLD)
84 , m_engine_type('t')
85 , m_upshift_delay_counter(0)
86 , m_engine_is_electric(false)
87 , m_turbo_inertia_factor(1)
88 , m_num_turbos(1)
89 , m_max_turbo_rpm(200000.0f)
90 , m_turbo_engine_rpm_operation(0.0f)
91 , m_turbo_ver(1)
92 , m_min_bov_psi(11)
93 , m_min_wastegate_psi(20)
94 , m_turbo_has_wastegate(false)
95 , m_turbo_has_bov(false)
96 , m_turbo_flutters(false)
97 , m_turbo_wg_threshold_p(0)
98 , m_turbo_wg_threshold_n(0)
99 , m_turbo_has_antilag(false)
100 , m_antilag_rand_chance(0.9975)
101 , m_antilag_min_rpm(3000)
102 , m_antilag_power_factor(170)
103{
107
108 for (int i = 0; i < MAXTURBO; i++)
109 {
111 m_cur_turbo_rpm[i] = 0;
112 }
113
114 // Assemble gear vector in format [R|N|1...]
115 m_gear_ratios.push_back(-reverse_gear * diff_ratio);
116 m_gear_ratios.push_back(neutral_gear * diff_ratio);
117 for (float gear : forward_gears)
118 m_gear_ratios.push_back(gear * diff_ratio);
119}
120
122{
123 // delete NULL is safe
124 delete m_torque_curve;
125 m_torque_curve = NULL;
126}
127
128void Engine::SetTurboOptions(int type, float tinertiaFactor, int nturbos, float param1, float param2, float param3, float param4, float param5, float param6, float param7, float param8, float param9, float param10, float param11)
129{
130 m_engine_has_turbo = true;
132
133 if (nturbos > MAXTURBO)
134 {
135 m_num_turbos = 4;
136 LOG("Turbo: No more than 4 turbos allowed"); //TODO: move this under RigParser
137 }
138 else
139 m_num_turbos = nturbos;
140
141 m_turbo_ver = type;
142 m_turbo_inertia_factor = tinertiaFactor;
143
144 if (param2 != 9999)
146
147 if (m_turbo_ver == 1)
148 {
149 for (int i = 0; i < m_num_turbos; i++)
150 m_engine_addi_torque[i] = param1 / m_num_turbos; //Additional torque
151 }
152 else
153 {
154 float turbo_max_psi = param1; //maxPSI
155 m_max_turbo_rpm = turbo_max_psi * 10000;
156
157 //Duh
158 if (param3 == 1)
159 m_turbo_has_bov = true;
160 else
161 m_turbo_has_bov = false;
162
163 if (param3 != 9999)
164 m_min_bov_psi = param4;
165
166 if (param5 == 1)
168 else
169 m_turbo_has_wastegate = false;
170
171 if (param6 != 9999)
172 m_min_wastegate_psi = param6 * 10000;
173
174 if (param7 != 9999)
175 {
176 m_turbo_wg_threshold_n = 1 - param7;
177 m_turbo_wg_threshold_p = 1 + param7;
178 }
179
180 if (param8 == 1)
181 m_turbo_has_antilag = true;
182 else
183 m_turbo_has_antilag = false;
184
185 if (param9 != 9999)
186 m_antilag_rand_chance = param9;
187
188 if (param10 != 9999)
189 m_antilag_min_rpm = param10;
190
191 if (param11 != 9999)
192 m_antilag_power_factor = param11;
193 }
194}
195
196void Engine::SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking)
197{
198 m_engine_inertia = einertia;
199 m_engine_type = etype;
200 m_clutch_force = eclutch;
201
202 if (ctime > 0)
203 m_clutch_time = ctime;
204 if (stime > 0)
205 m_shift_time = stime;
206 if (pstime > 0)
207 m_post_shift_time = pstime;
208 if (irpm > 0)
209 m_engine_idle_rpm = irpm;
210 if (srpm > 0)
211 m_engine_stall_rpm = srpm;
212 if (maximix > 0)
213 m_max_idle_mixture = maximix;
214 if (minimix > 0)
215 m_min_idle_mixture = minimix;
216 if (ebraking > 0)
217 m_braking_torque = -ebraking;
218
219 m_shift_time = std::max(0.0f, m_shift_time);
220 m_post_shift_time = std::max(0.0f, m_post_shift_time);
221 m_clutch_time = Math::Clamp(m_clutch_time, 0.0f, 0.9f * m_shift_time);
222
223 m_engine_stall_rpm = Math::Clamp(m_engine_stall_rpm, 0.0f, 0.9f * m_engine_idle_rpm);
224
225 if (etype == 'c')
226 {
227 // it's a car!
228 m_engine_has_air = false;
229 m_engine_has_turbo = false;
230 m_engine_is_electric = false;
231 // set default clutch force
232 if (m_clutch_force < 0.0f)
233 {
234 m_clutch_force = 5000.0f;
235 }
236 }
237 else if (etype == 'e') //electric
238 {
240 m_engine_has_air = false;
241 m_engine_has_turbo = false;
242 if (m_clutch_force < 0.0f)
243 {
244 m_clutch_force = 5000.0f;
245 }
246 }
247 else
248 {
249 m_engine_is_electric = false;
250 // it's a truck
251 if (m_clutch_force < 0.0f)
252 {
253 m_clutch_force = 10000.0f;
254 }
255 }
256}
257
258void Engine::UpdateEngine(float dt, int doUpdate)
259{
260 // if engine air intake is defined and under water, stop engine
261 const auto water = App::GetGameContext()->GetTerrain()->getWater();
262 if (m_air_intake_node != NODENUM_INVALID && water)
263 {
264 if (water->IsUnderWater(m_actor->ar_nodes[m_air_intake_node].AbsPosition))
265 {
266 this->stopEngine();
267 }
268 }
269
270 float acc = m_cur_acc;
271
272 acc = std::max(getIdleMixture(), acc);
273 acc = std::max(getPrimeMixture(), acc);
274
275 if (doUpdate)
276 {
278 }
279
281 {
282 // air pressure
284 if (m_air_pressure > 50000.0f)
285 {
287 m_air_pressure = 0.0f;
288 }
289 }
290
292 {
294 {
295 // update turbo speed (lag)
296 float turbotorque = 0.0f;
297 float turboInertia = 0.000003f;
298
299 // braking (compression)
300 turbotorque -= m_cur_turbo_rpm[0] / 200000.0f;
301
302 // powering (exhaust) with limiter
303 if (m_cur_turbo_rpm[0] < 200000.0f && m_engine_is_running && m_cur_acc > 0.06f)
304 {
305 turbotorque += 1.5f * m_cur_acc * (m_cur_engine_rpm / m_engine_max_rpm);
306 }
307 else
308 {
309 turbotorque += 0.1f * (m_cur_engine_rpm / m_engine_max_rpm);
310 }
311
312 // integration
313 m_cur_turbo_rpm[0] += dt * turbotorque / turboInertia;
314 }
315 else
316 {
317 for (int i = 0; i < m_num_turbos; i++)
318 {
319 // update turbo speed (lag)
320 // reset each of the values for each turbo
321 float turbotorque = 0.0f;
322 float turboBOVtorque = 0.0f;
323
324 float turboInertia = 0.000003f * m_turbo_inertia_factor;
325
326 // braking (compression)
327 turbotorque -= m_cur_turbo_rpm[i] / m_max_turbo_rpm;
328 turboBOVtorque -= m_turbo_bov_rpm[i] / m_max_turbo_rpm;
329
330 // powering (exhaust) with limiter
332 {
333 if (m_cur_turbo_rpm[i] <= m_max_turbo_rpm && m_engine_is_running && acc > 0.06f)
334 {
336 {
338 {
340 }
341 else
342 {
343 m_turbo_flutters = true;
344 turbotorque -= (m_cur_turbo_rpm[i] / m_max_turbo_rpm) * 1.5;
345 }
346
348 {
351 {
352 m_turbo_flutters = false;
354 }
355 }
356 }
357 else
359 }
360 else
361 {
363 }
364
365 //Update waste gate, it's like a BOV on the exhaust part of the turbo, acts as a limiter
367 {
368 if (m_cur_turbo_rpm[i] > m_min_wastegate_psi * 0.95)
369 turboInertia = turboInertia * 0.7; //Kill inertia so it flutters
370 else
371 turboInertia = turboInertia * 1.3; //back to normal inertia
372 }
373 }
374
375 //simulate compressor surge
376 if (!m_turbo_has_bov)
377 {
378 if (m_cur_turbo_rpm[i] > 13 * 10000 && m_cur_acc < 0.06f)
379 {
380 turbotorque += (turbotorque * 2.5);
381 }
382 }
383
384 // anti lag
385 if (m_turbo_has_antilag && m_cur_acc < 0.5)
386 {
387 float f = frand();
389 {
391 {
392 turbotorque -= (turbotorque * (f * m_antilag_power_factor));
394 }
395 }
396 else
397 {
399 }
400 }
401
402 // update main turbo rpm
403 m_cur_turbo_rpm[i] += dt * turbotorque / turboInertia;
404
405 //Update BOV
406 //It's basicly an other turbo which is limmited to the main one's rpm, but it doesn't affect its rpm. It only affects the power going into the engine.
407 //This one is used to simulate the pressure between the engine and the compressor.
408 //I should make the whole turbo code work this way. -Max98
409 if (m_turbo_has_bov)
410 {
412 turboBOVtorque += 1.5f * acc * (((m_cur_engine_rpm) / (m_engine_max_rpm)));
413 else
414 turboBOVtorque += 0.07f * (((m_cur_engine_rpm) / (m_engine_max_rpm)));
415
416 if (m_cur_acc < 0.06 && m_cur_turbo_rpm[i] > m_min_bov_psi * 10000)
417 {
419 m_turbo_bov_rpm[i] += dt * turboBOVtorque / (turboInertia * 0.1);
420 }
421 else
422 {
425 m_turbo_bov_rpm[i] += dt * turboBOVtorque / (turboInertia * 0.05);
426 else
427 m_turbo_bov_rpm[i] += dt * turboBOVtorque / turboInertia;
428 }
429 }
430 }
431 }
432 }
433
434 // update engine speed
435 float totaltorque = 0.0f;
436
437 // engine braking
439 {
440 totaltorque += m_braking_torque * m_cur_engine_rpm / m_engine_max_rpm * (1.0f - m_cur_acc);
441 }
442 else if (!m_contact || !m_starter)
443 {
444 totaltorque += m_braking_torque;
445 }
446
447 // braking by hydropump
448 if (m_cur_engine_rpm > 100.0f)
449 {
450 totaltorque -= 8.0f * m_hydropump_state / (m_cur_engine_rpm * 0.105f * dt);
451 }
452
454 {
456 totaltorque += m_cur_engine_torque;
457 }
458
459 // engine stall
461 {
463 {
464 this->stopEngine();
465 }
466 }
467
468 // engine start
470 {
472 {
473 if (m_starter)
474 m_engine_is_running = true;
475 }
476 else
477 {
479 {
480 if (m_starter)
481 {
482 totaltorque += m_engine_torque * exp(-2.7f * m_cur_engine_rpm / m_engine_idle_rpm) - m_braking_torque;
483 }
484 }
485 else
486 {
487 m_engine_is_running = true;
489 }
490 }
491 }
492
493 // clutch
494 if (m_cur_gear)
495 {
496 totaltorque -= m_cur_clutch_torque / m_gear_ratios[m_cur_gear + 1];
497 }
498
499 // integration
500 m_cur_engine_rpm += dt * totaltorque / m_engine_inertia;
501
502 // update clutch torque
503 if (m_cur_gear)
504 {
505 float force_threshold = 1.5f * std::max(m_engine_torque, getEnginePower()) * std::abs(m_gear_ratios[2]);
506 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
508 m_cur_clutch_torque = Math::Clamp(m_cur_clutch_torque, -force_threshold, +force_threshold);
509 m_cur_clutch_torque *= 1.0f - approx_exp(-std::abs(gearboxspinner - m_cur_wheel_revolutions));
510 }
511 else
512 {
513 m_cur_clutch_torque = 0.0f;
514 }
515
516 m_cur_engine_rpm = std::max(0.0f, m_cur_engine_rpm);
517
519 {
520 // auto-shift
521 if (m_shifting)
522 {
523 m_shift_clock += dt;
524
525 if (m_shift_val)
526 {
527 float declutchTime = std::min(m_shift_time - m_clutch_time, m_clutch_time);
528 if (m_shift_clock <= declutchTime)
529 {
530 // depress the clutch
531 float ratio = pow(1.0f - (m_shift_clock / declutchTime), 2);
532 m_cur_clutch = std::min(ratio, m_cur_clutch);
533 m_cur_acc = std::min(ratio, m_auto_cur_acc);
534 }
535 else
536 {
537 // engage a gear
539 if (m_autoselect != NEUTRAL)
540 {
542 m_cur_gear = std::max(-1, m_cur_gear);
543 m_cur_gear = std::min(m_cur_gear, m_num_gears);
544 }
545 m_shift_val = 0;
546 }
547 }
548
550 {
551 // we're done m_shifting
554 m_shifting = 0;
555 m_post_shifting = 1;
556 m_post_shift_clock = 0.0f;
557 }
559 {
560 // release the clutch <-- Done below
561 float timer = m_shift_clock - (m_shift_time - m_clutch_time);
562 float ratio = sqrt(timer / m_clutch_time);
563 m_cur_acc = (m_auto_cur_acc / 2.0f) * ratio;
564 }
565 }
566
567 if (m_post_shifting)
568 {
569 m_post_shift_clock += dt;
571 {
572 m_post_shifting = 0;
573 }
574 else if (m_auto_cur_acc > 0.0f)
575 {
577 m_cur_acc = (m_auto_cur_acc / 2.0f) + (m_auto_cur_acc / 2.0f) * ratio;
578 }
579 else if (m_cur_gear)
580 {
581 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
582 if (m_cur_wheel_revolutions > gearboxspinner)
583 {
584 float ratio = sqrt(m_post_shift_clock / m_post_shift_time);
585 m_cur_clutch = std::max(m_cur_clutch, ratio);
586 }
587 }
588 }
589
590 // auto clutch
591 float declutchRPM = m_engine_min_rpm * 0.75f + m_engine_stall_rpm * 0.25f;
592 if (m_cur_gear == 0 || m_cur_engine_rpm < declutchRPM)
593 {
594 m_cur_clutch = 0.0f;
595 }
596 else if (m_cur_engine_rpm < m_engine_min_rpm && m_engine_min_rpm > declutchRPM)
597 {
598 float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_min_rpm - declutchRPM);
599 m_cur_clutch = std::min(clutch * clutch, m_cur_clutch);
600 }
602 {
603 float threshold = 1.5f * getEnginePower(m_cur_engine_rpm) * std::abs(m_gear_ratios[2]);
604 float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1];
605 float clutchTorque = (gearboxspinner - m_cur_wheel_revolutions) * m_clutch_force;
606 float reTorque = Math::Clamp(clutchTorque, -threshold, +threshold) / m_gear_ratios[m_cur_gear + 1];
607
608 float range = (m_engine_max_rpm - m_engine_min_rpm) * 0.4f * sqrt(std::max(0.2f, acc));
609 float powerRatio = std::min((m_cur_engine_rpm - m_engine_min_rpm) / range, 1.0f);
610 float engineTorque = getEnginePower() * std::min(m_cur_acc, 0.9f) * powerRatio;
611
612 float torqueDiff = std::min(engineTorque, std::abs(reTorque));
613 float clutch = torqueDiff / reTorque;
614 m_cur_clutch = std::max(m_cur_clutch, clutch);
615 }
616
617 m_cur_clutch = std::max(0.0f, m_cur_clutch);
618 m_cur_clutch = std::min(m_cur_clutch, 1.0f);
619 }
620
621 if (doUpdate && !m_shifting && !m_post_shifting)
622 {
623 // gear hack
624 float velocity = m_actor->ar_nodes[0].Velocity.length();
625
626 Vector3 hdir = m_actor->GetCameraDir();
627 if (hdir != Vector3::ZERO)
628 {
629 velocity = hdir.dotProduct(m_actor->ar_nodes[0].Velocity);
630 }
631
632 if (m_actor->ar_wheels[0].wh_radius != 0)
633 {
635 }
636
638 {
640 {
641 if ((m_autoselect == DRIVE && m_cur_gear < m_num_gears && m_cur_clutch > 0.99f) || (m_autoselect == TWO && m_cur_gear < std::min(2, m_num_gears)))
642 {
644 shift(1);
645 }
646 }
649 {
650 shift(-1);
651 }
652
653 int newGear = m_cur_gear;
654
655 m_rpms.push_front(m_cur_engine_rpm);
656 m_accs.push_front(acc);
657 m_brakes.push_front(m_actor->ar_brake);
658
659 float avgRPM50 = 0.0f;
660 float avgRPM200 = 0.0f;
661 float avgAcc50 = 0.0f;
662 float avgAcc200 = 0.0f;
663 float avgBrake50 = 0.0f;
664 float avgBrake200 = 0.0f;
665
666 for (unsigned int i = 0; i < m_accs.size(); i++)
667 {
668 if (i < 50)
669 {
670 avgRPM50 += m_rpms[i];
671 avgAcc50 += m_accs[i];
672 avgBrake50 += m_brakes[i];
673 }
674
675 avgRPM200 += m_rpms[i];
676 avgAcc200 += m_accs[i];
677 avgBrake200 += m_brakes[i];
678 }
679
680 avgRPM50 /= std::min(m_rpms.size(), (std::deque<float>::size_type)50);
681 avgAcc50 /= std::min(m_accs.size(), (std::deque<float>::size_type)50);
682 avgBrake50 /= std::min(m_brakes.size(), (std::deque<float>::size_type)50);
683
684 avgRPM200 /= m_rpms.size();
685 avgAcc200 /= m_accs.size();
686 avgBrake200 /= m_brakes.size();
687
688 if (avgAcc50 > 0.8f || avgAcc200 > 0.8f || avgBrake50 > 0.8f || avgBrake200 > 0.8f)
689 {
690 m_shift_behaviour = std::min(m_shift_behaviour + 0.01f, 1.0f);
691 }
692 else if (acc < 0.5f && avgAcc50 < 0.5f && avgAcc200 < 0.5f && m_actor->ar_brake < 0.5f && avgBrake50 < 0.5f && avgBrake200 < 0.5)
693 {
694 m_shift_behaviour /= 1.01;
695 }
696
698 {
702 {
703 newGear--;
704 }
705 }
706 else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
707 {
711 {
712 newGear--;
713 }
714 }
715 else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
716 {
720 {
721 newGear--;
722 }
723 }
724 else if (m_cur_gear < (m_autoselect == TWO ? std::min(2, m_num_gears) : m_num_gears) &&
725 avgBrake200 < 0.2f && acc < std::min(avgAcc200 + 0.1f, 1.0f) && m_cur_engine_rpm > avgRPM200 - m_full_rpm_range / 20.0f)
726 {
728 {
730 {
731 newGear++;
732 }
733 }
734 else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range)
735 {
737 {
738 newGear++;
739 }
740 }
741 else if (avgAcc200 < 0.2f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range / 2.0f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range)
742 {
744 {
745 newGear++;
746 }
747 }
748
749 if (newGear > m_cur_gear)
750 {
753 {
754 newGear = m_cur_gear;
755 }
756 }
757 else
758 {
760 }
761 }
762
763 if (newGear < m_cur_gear && m_kickdown_delay_counter > 0)
764 {
765 newGear = m_cur_gear;
766 }
768
769 if (newGear < m_cur_gear && std::abs(m_cur_wheel_revolutions * (m_gear_ratios[newGear + 1] - m_gear_ratios[m_cur_gear + 1])) > m_one_third_rpm_range / 6.0f ||
770 newGear > m_cur_gear && std::abs(m_cur_wheel_revolutions * (m_gear_ratios[newGear + 1] - m_gear_ratios[m_cur_gear + 1])) > m_one_third_rpm_range / 3.0f)
771 {
772 if (std::abs(m_actor->getGForces().y) < 0.25f)
773 shiftTo(newGear);
774 }
775
776 if (m_accs.size() > 200)
777 {
778 m_rpms.pop_back();
779 m_accs.pop_back();
780 m_brakes.pop_back();
781 }
782 // avoid over-revving
784 {
786 {
787 float clutch = 0.0f + 1.0f / (1.0f + std::abs(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1] - m_engine_max_rpm * 1.25f) / 2.0f);
788 m_cur_clutch = std::min(clutch, m_cur_clutch);
789 }
790 if (m_cur_gear * m_cur_wheel_revolutions < -10.0f)
791 {
792 float clutch = 0.0f + 1.0f / (1.0f + std::abs(-10.0f - m_cur_gear * m_cur_wheel_revolutions) / 2.0f);
793 m_cur_clutch = std::min(clutch, m_cur_clutch);
794 }
795 }
796 }
797 }
798}
799
801{
802#ifdef USE_OPENAL
804 {
805 for (int i = 0; i < m_num_turbos; i++)
806 {
808 }
809 }
810
814
815 // reverse gear beep
816 if (m_cur_gear == -1 && m_engine_is_running)
817 {
819 }
820 else
821 {
823 }
824#endif // USE_OPENAL
825}
826
828{
829 m_auto_mode = static_cast<SimGearboxMode>(
830 (static_cast<int>(m_auto_mode) + 1) % (static_cast<int>(SimGearboxMode::MANUAL_RANGES) + 1));
831
833 {
834 if (m_cur_gear > 0)
836 if (m_cur_gear < 0)
838 if (m_cur_gear == 0)
840 }
841 else
842 {
844 }
845
847 {
849 }
850}
851
856
858{
859 this->m_auto_mode = mode;
860}
861
862void Engine::setAcc(float val)
863{
864 m_cur_acc = val;
865}
866
868{
870 {
871 return m_cur_turbo_rpm[0] / 10000.0f;
872 }
873
874 float turboPSI = 0;
875
876 if (m_turbo_has_bov)
877 {
878 for (int i = 0; i < m_num_turbos; i++)
879 turboPSI += m_turbo_bov_rpm[i] / 10000.0f;
880 }
881 else
882 {
883 for (int i = 0; i < m_num_turbos; i++)
884 turboPSI += m_cur_turbo_rpm[i] / 10000.0f;
885 }
886
887 return turboPSI;
888}
889
891{
892 return m_cur_acc;
893}
894
895void Engine::pushNetworkState(float rpm, float acc, float clutch, int gear, bool running, bool contact, char automode, char autoselect)
896{
897 m_cur_engine_rpm = rpm;
898 m_cur_acc = acc;
899 m_cur_clutch = clutch;
900 m_cur_gear = gear;
901 m_engine_is_running = running;
902 m_contact = contact;
903 if (automode != -1)
904 {
905 m_auto_mode = static_cast<SimGearboxMode>(automode);
906 }
907 if (autoselect != -1)
908 {
909 m_autoselect = (autoswitch)autoselect;
910 }
911}
912
914{
916 {
917 return m_cur_acc * (1.0f - m_cur_turbo_rpm[0] /* doesn't matter */ / m_max_turbo_rpm);// * m_engine_torque / 5000.0f;
918 }
919
920 return -1;
921}
922
924{
925 return m_cur_clutch_torque;
926}
927
928void Engine::setRPM(float rpm)
929{
930 m_cur_engine_rpm = rpm;
931}
932
934{
936}
937
938void Engine::setHydroPump(float work)
939{
940 m_hydropump_state = work;
941}
942
943void Engine::setWheelSpin(float rpm)
944{
946}
947
948void Engine::setTCaseRatio(float ratio)
949{
950 if (ratio < 1.0f)
951 return;
952
953 for (std::vector<float>::iterator it = m_gear_ratios.begin(); it != m_gear_ratios.end(); ++it)
954 {
955 (*it) /= m_tcase_ratio;
956 }
957
958 m_tcase_ratio = ratio;
959
960 for (std::vector<float>::iterator it = m_gear_ratios.begin(); it != m_gear_ratios.end(); ++it)
961 {
962 (*it) *= m_tcase_ratio;
963 }
964}
965
967{
968 // Pos: -1=reverse, 0 = neutral, 1 = 1st gear, 2 = 2nd gear, etc.
969 // --------------------------------------------------------------
970
971 if (pos < -1 || pos > m_num_gears)
972 return 0.f;
973
974 // Strip off the DiffRatio and TCaseRatio from the internal gear ratio
975 return (m_gear_ratios[pos + 1] / m_tcase_ratio) / m_diff_ratio;
976}
977
978// for hydros acceleration
980{
981 float minWorkingRPM = m_engine_idle_rpm * 1.1f; // minWorkingRPM > m_engine_idle_rpm avoids commands deadlocking the engine
982
983 float rpmRatio = (m_cur_engine_rpm - minWorkingRPM) / (m_engine_max_rpm - minWorkingRPM);
984 rpmRatio = std::max(0.0f, rpmRatio); // Avoids a negative rpmRatio when m_cur_engine_rpm < minWorkingRPM
985 rpmRatio = std::min(rpmRatio, 1.0f); // Avoids a rpmRatio > 1.0f when m_cur_engine_rpm > m_engine_max_rpm
986
987 float crankfactor = 5.0f * rpmRatio;
988
989 return crankfactor;
990}
991
993{
995 if (m_contact)
996 {
998 }
999 else
1000 {
1002 }
1003}
1004
1006{
1007 this->offStart();
1008 m_contact = true;
1010 m_engine_is_running = true;
1012 {
1013 m_cur_gear = 1;
1014 }
1016 {
1018 }
1021}
1022
1024{
1025 m_air_pressure = 0.0f;
1027 m_contact = false;
1028 m_cur_acc = 0.0f;
1029 m_cur_clutch = 0.0f;
1030 m_cur_clutch_torque = 0.0f;
1031 m_cur_engine_rpm = 0.0f;
1032 m_cur_gear = 0;
1033 m_post_shifting = 0;
1034 m_engine_is_running = false;
1035 m_shifting = 0;
1036 m_shift_val = 0;
1038 {
1040 }
1041 for (int i = 0; i < m_num_turbos; i++)
1042 {
1043 m_cur_turbo_rpm[i] = 0.0f;
1044 m_turbo_bov_rpm[i] = 0.0f;
1045 }
1046}
1047
1049{
1050 return m_cur_gear;
1051}
1052
1053// low level gear changing
1055{
1056 m_cur_gear = v;
1057}
1058
1060{
1061 return m_cur_gear_range;
1062}
1063
1065{
1066 m_cur_gear_range = v;
1067}
1068
1078
1080{
1081 return (-m_braking_torque * std::pow(m_cur_engine_rpm / m_engine_max_rpm, 2.0f)) / getEnginePower();
1082}
1083
1084// high level controls
1085void Engine::autoSetAcc(float val)
1086{
1087 m_auto_cur_acc = val;
1088 if (!m_shifting)
1089 {
1090 setAcc(val);
1091 }
1092}
1093
1094void Engine::shift(int val)
1095{
1096 if (!val || m_cur_gear + val < -1 || m_cur_gear + val > getNumGears())
1097 return;
1099 {
1100 m_shift_val = val;
1101 m_shifting = 1;
1102 m_shift_clock = 0.0f;
1103 }
1104 else
1105 {
1106 if (m_cur_clutch > 0.25f)
1107 {
1109 }
1110 else
1111 {
1113 m_cur_gear += val;
1114 }
1115 }
1116}
1117
1118void Engine::shiftTo(int newGear)
1119{
1120 shift(newGear - m_cur_gear);
1121}
1122
1124{
1125 if (m_autoselect == MANUALMODE)
1126 return;
1127
1129 {
1131 }
1132
1133 if (m_autoselect == REAR)
1134 {
1135 m_cur_gear = -1;
1136 }
1137 else if (m_autoselect == NEUTRAL)
1138 {
1139 m_cur_gear = 0;
1140 }
1141 else if (m_autoselect == ONE)
1142 {
1143 m_cur_gear = 1;
1144 }
1145 else
1146 {
1147 // search for an appropriate gear
1148 int newGear = 1;
1149
1150 while (newGear < m_num_gears && m_cur_wheel_revolutions > 0.0f && m_cur_wheel_revolutions * m_gear_ratios[newGear + 1] > m_engine_max_rpm - 100.0f)
1151 {
1152 newGear++;
1153 }
1154
1155 m_cur_gear = newGear;
1156
1157 if (m_autoselect == TWO)
1158 {
1159 m_cur_gear = std::min(m_cur_gear, 2);
1160 }
1161 }
1162}
1163
1165{
1166 m_autoselect = (autoswitch)mode;
1169 updateShifts();
1170}
1171
1173{
1174 if (m_autoselect != REAR)
1175 {
1177 updateShifts();
1178 }
1179}
1180
1182{
1185 {
1187 updateShifts();
1188 }
1189}
1190
1192{
1193 return (int)m_autoselect;
1194}
1195
1197{
1199 {
1200 val = std::max(0.0f, val);
1201 m_cur_clutch = 1.0 - val;
1202 }
1203}
1204
1206{
1207 if (!m_engine_has_turbo)
1208 return 0.0f;
1209 if (m_engine_turbo_mode != NEW)
1210 return 0.0f;
1211
1212 float atValue = 0.0f; // torque (turbo integreation)
1213
1214 if (m_turbo_ver == 1)
1215 {
1216 for (int i = 0; i < m_num_turbos; i++)
1217 {
1219 }
1220 }
1221 else
1222 {
1223 atValue = (((getTurboPSI() * 6.8) * m_engine_torque) / 100); //1psi = 6% more power
1224 }
1225
1226 return atValue;
1227}
1228
1230{
1231 // engine power with limiter
1232 float tqValue = 1.0f; // ratio (0-1)
1233
1234 if (m_torque_curve)
1235 {
1236 tqValue = m_torque_curve->getEngineTorque(rpm);
1237 }
1238
1239 return (m_engine_torque * tqValue) + getTurboPower();
1240}
1241
1243{
1245 return m_max_idle_mixture;
1246 return m_min_idle_mixture;
1247}
1248
1250{
1252 {
1253 float crankfactor = getCrankFactor();
1254
1255 if (crankfactor < 0.9f)
1256 {
1257 // crankfactor is between 0.0f and 0.9f
1258 return 1.0f;
1259 }
1260 else if (crankfactor < 1.0f)
1261 {
1262 // crankfactor is between 0.9f and 1.0f
1263 return 10.0f * (1.0f - crankfactor);
1264 }
1265 }
1266
1267 return 0.0f;
1268}
1269
1271{
1273 float brake = m_actor->getEventValue(EV_TRUCK_BRAKE);
1274
1277 {
1278 float acclModifier = 0.0f;
1280 {
1281 acclModifier += 0.25f;
1282 }
1284 {
1285 acclModifier += 0.50f;
1286 }
1287 accl *= acclModifier;
1288 }
1289
1292 {
1293 float brakeModifier = 0.0f;
1295 {
1296 brakeModifier += 0.25f;
1297 }
1299 {
1300 brakeModifier += 0.50f;
1301 }
1302 brake *= brakeModifier;
1303 }
1304
1305
1306 // arcade controls are only working with auto-clutch!
1307 if (!m_actor->ar_arcade_controls || (this->getAutoMode() >= SimGearboxMode::MANUAL))
1308 {
1309 // classic mode, realistic
1310 this->autoSetAcc(accl);
1311 m_actor->ar_brake = brake;
1312 }
1313 else
1314 {
1315 // start engine
1316 if (this->hasContact() && !this->isRunning() && (accl > 0 || brake > 0))
1317 {
1318 this->startEngine();
1319 }
1320
1321 // arcade controls: hey - people wanted it x| ... <- and it's convenient
1322 if (this->getGear() >= 0)
1323 {
1324 // neutral or drive forward, everything is as its used to be: brake is brake and accel. is accel.
1325 this->autoSetAcc(accl);
1326 m_actor->ar_brake = brake;
1327 }
1328 else
1329 {
1330 // reverse gear, reverse controls: brake is accel. and accel. is brake.
1331 this->autoSetAcc(brake);
1332 m_actor->ar_brake = accl;
1333 }
1334
1335 // only when the truck really is not moving anymore
1336 if (fabs(m_actor->ar_avg_wheel_speed) <= 1.0f)
1337 {
1338 Ogre::Vector3 hdir = m_actor->getDirection();
1339 float velocity = hdir.dotProduct(m_actor->ar_nodes[0].Velocity);
1340
1341 // switching point, does the user want to drive forward from backward or the other way round? change gears?
1342 if (velocity < 1.0f && brake > 0.5f && accl < 0.5f && this->getGear() > 0)
1343 {
1344 // we are on the brake, jump to reverse gear
1345 if (this->getAutoMode() == SimGearboxMode::AUTO)
1346 {
1348 }
1349 else
1350 {
1351 this->setGear(-1);
1352 }
1353 }
1354 else if (velocity > -1.0f && brake < 0.5f && accl > 0.5f && this->getGear() < 0)
1355 {
1356 // we are on the gas pedal, jump to first gear when we were in rear gear
1357 if (this->getAutoMode() == SimGearboxMode::AUTO)
1358 {
1360 }
1361 else
1362 {
1363 this->setGear(1);
1364 }
1365 }
1366 }
1367 }
1368
1369 // gear management
1370 if (this->getAutoMode() == SimGearboxMode::AUTO)
1371 {
1373 {
1374 this->autoShiftUp();
1375 }
1377 {
1378 this->autoShiftDown();
1379 }
1380 }
1381
1383 {
1384 this->toggleContact();
1385 }
1386
1387 if (m_actor->getEventBoolValue(EV_TRUCK_STARTER) && this->hasContact() && !this->isRunning())
1388 {
1389 m_starter = true;
1392 }
1393 else
1394 {
1395 m_starter = false;
1397 }
1398
1400 {
1401 // toggle Auto shift
1402 this->toggleAutoMode();
1403
1404 // force gui update
1406
1408 ToLocalizedString(this->getAutoMode()), "cog.png");
1409 }
1410
1411 // joy clutch
1415 {
1416 float clutchModifier = 0.0f;
1418 {
1419 clutchModifier += 0.25f;
1420 }
1422 {
1423 clutchModifier += 0.50f;
1424 }
1425 clutch *= clutchModifier;
1426 }
1427 this->setManualClutch(clutch);
1428
1429 SimGearboxMode shiftmode = this->getAutoMode();
1430
1431 if (shiftmode <= SimGearboxMode::MANUAL) // auto, semi auto and sequential shifting
1432 {
1434 {
1435 this->shift(1);
1436 }
1438 {
1439 if (shiftmode > SimGearboxMode::SEMI_AUTO ||
1441 shiftmode == SimGearboxMode::SEMI_AUTO && this->getGear() > 0 ||
1442 shiftmode == SimGearboxMode::AUTO)
1443 {
1444 this->shift(-1);
1445 }
1446 }
1447 else if (shiftmode != SimGearboxMode::AUTO)
1448 {
1450 {
1451 this->shiftTo(0);
1452 }
1454 {
1455 this->shiftTo(-1);
1456 }
1457 else
1458 {
1459 for (int i = 1; i < 19; i++)
1460 {
1462 {
1463 this->shiftTo(i);
1464 }
1465 }
1466 }
1467 }
1468 }
1469 else //if (shiftmode > SimGearboxMode::MANUAL) // h-shift or h-shift with ranges shifting
1470 {
1471 bool gear_changed = false;
1472 bool found = false;
1473 int curgear = this->getGear();
1474 int curgearrange = this->getGearRange();
1475 int gearoffset = std::max(0, curgear - curgearrange * 6);
1476
1477 // one can select range only if in neutral
1478 if (shiftmode == SimGearboxMode::MANUAL_RANGES && curgear == 0)
1479 {
1480 if (m_actor->getEventBoolValueBounce(EV_TRUCK_SHIFT_LOWRANGE) && curgearrange != 0)
1481 {
1482 this->setGearRange(0);
1483 gear_changed = true;
1484 }
1485 else if (m_actor->getEventBoolValueBounce(EV_TRUCK_SHIFT_MIDRANGE) && curgearrange != 1 && this->getNumGearsRanges() > 1)
1486 {
1487 this->setGearRange(1);
1488 gear_changed = true;
1489 }
1490 else if (m_actor->getEventBoolValueBounce(EV_TRUCK_SHIFT_HIGHRANGE) && curgearrange != 2 && this->getNumGearsRanges() > 2)
1491 {
1492 this->setGearRange(2);
1493 gear_changed = true;
1494 }
1496 {
1497 this->setGearRange((curgearrange + 1) % this->getNumGearsRanges());
1498 gear_changed = true;
1500 fmt::format(_L("Range cycled (current: {}/available: {})"),
1501 this->getGearRange(), this->getNumGearsRanges()), "cog.png");
1502 }
1503
1504 if (gear_changed)
1505 {
1506 switch (this->getGearRange())
1507 {
1508 case 0:
1510 break;
1511 case 1:
1513 break;
1514 case 2:
1516 break;
1517 default:
1518 break;
1519 }
1520 }
1521 }
1522 //zaxxon
1523 if (curgear == -1)
1524 {
1526 }
1527 else if (curgear > 0 && curgear < 19)
1528 {
1529 gear_changed = !m_actor->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + gearoffset - 1); // range mode
1530 }
1531
1532 if (gear_changed || curgear == 0)
1533 {
1535 {
1536 this->shiftTo(-1);
1537 found = true;
1538 }
1540 {
1541 this->shiftTo(0);
1542 found = true;
1543 }
1544 else
1545 {
1546 if (shiftmode == SimGearboxMode::MANUAL_STICK)
1547 {
1548 for (int i = 1; i < 19 && !found; i++)
1549 {
1551 {
1552 this->shiftTo(i);
1553 found = true;
1554 }
1555 }
1556 }
1557 else // SimGearboxMode::MANUALMANUAL_RANGES
1558 {
1559 for (int i = 1; i < 7 && !found; i++)
1560 {
1562 {
1563 this->shiftTo(i + curgearrange * 6);
1564 found = true;
1565 }
1566 }
1567 }
1568 }
1569 if (!found)
1570 {
1571 this->shiftTo(0);
1572 }
1573 } // end of if (gear_changed)
1574 } // end of shitmode > SimGearboxMode::MANUAL
1575}
System integration layer; inspired by OgreBites::ApplicationContext.
void LOG(const char *msg)
Legacy alias - formerly a macro.
float frand()
Definition ApproxMath.h:31
float approx_exp(const float x)
Definition ApproxMath.h:68
#define MAXTURBO
Definition Engine.h:258
#define _L
Handles controller inputs from player.
static const float RAD_PER_SEC_TO_RPM
Convert radian/second to RPM (60/2*PI)
#define SOUND_START(_ACTOR_, _TRIG_)
#define SOUND_STOP(_ACTOR_, _TRIG_)
#define SOUND_PLAY_ONCE(_ACTOR_, _TRIG_)
#define SOUND_MODULATE(_ACTOR_, _MOD_, _VALUE_)
torquecurve loader.
bool getEventBoolValueBounce(int eventID, float time=0.2f)
Definition Actor.cpp:3034
wheel_t ar_wheels[MAX_WHEELS]
Definition Actor.h:419
bool getEventBoolValue(int eventID)
Definition Actor.cpp:3029
node_t * ar_nodes
Definition Actor.h:365
Ogre::Vector3 getDirection()
average actor velocity, calculated using the actor positions of the last two frames
Definition Actor.cpp:365
float getEventValue(int eventID, bool pure=false, InputSourceType valueSource=InputSourceType::IST_ANY)
Definition Actor.cpp:3015
ActorInstanceID_t ar_instance_id
Static attr; session-unique ID.
Definition Actor.h:464
float ar_avg_wheel_speed
Physics state; avg wheel speed in m/s.
Definition Actor.h:497
Ogre::Real ar_brake
Physics state; braking intensity.
Definition Actor.h:494
void RequestUpdateHudFeatures()
Definition Actor.h:345
Ogre::Vector3 GetCameraDir()
Definition Actor.h:341
Ogre::Vector3 getGForces()
Definition Actor.h:91
bool ar_arcade_controls
Should we use arcade controls? This gets updated for the player actor according to 'io_arcade_control...
Definition Actor.h:610
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_NOTICE
Definition Console.h:51
float getCrankFactor()
Definition Engine.cpp:979
float m_tcase_ratio
Engine.
Definition Engine.h:215
float m_engine_addi_torque[MAXTURBO]
Definition Engine.h:264
int m_turbo_ver
Definition Engine.h:259
void setWheelSpin(float rpm)
Definition Engine.cpp:943
void autoShiftSet(int mode)
Definition Engine.cpp:1164
void pushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select=-1)
Definition Engine.cpp:895
float m_antilag_power_factor
Definition Engine.h:277
std::deque< float > m_rpms
Definition Engine.h:253
char m_engine_type
't' = truck (default), 'c' = car ('engoption' attr #2)
Definition Engine.h:209
void UpdateInputEvents(float dt)
Definition Engine.cpp:1270
float m_cur_engine_torque
Engine.
Definition Engine.h:213
bool m_turbo_has_antilag
Definition Engine.h:274
bool m_turbo_has_bov
Definition Engine.h:266
float m_one_third_rpm_range
Definition Engine.h:248
float m_hydropump_state
Engine.
Definition Engine.h:217
SimGearboxMode getAutoMode()
Definition Engine.cpp:852
int m_post_shifting
Definition Engine.h:239
float getAccToHoldRPM()
estimate required throttle input to hold the current rpm
Definition Engine.cpp:1079
void setGearRange(int v)
low level gear changing (bypasses shifting logic)
Definition Engine.cpp:1064
void startEngine()
Quick engine start. Plays sounds.
Definition Engine.cpp:1005
float m_cur_wheel_revolutions
Gears; measured wheel revolutions.
Definition Engine.h:191
int m_engine_turbo_mode
Engine attribute.
Definition Engine.h:207
float m_diff_ratio
Global gear ratio ('engine' attr #4)
Definition Engine.h:214
NodeNum_t m_air_intake_node
Node number of the air intake node (if any) - defaults to cinecam ref node (classic behavior) but can...
Definition Engine.h:228
int m_max_turbo_rpm
Definition Engine.h:263
int m_shift_val
Definition Engine.h:241
float m_post_shift_clock
Definition Engine.h:236
float m_engine_inertia
('engoption' attr #1)
Definition Engine.h:220
float m_antilag_rand_chance
Definition Engine.h:276
float m_min_wastegate_psi
Definition Engine.h:270
float getTurboPower()
Definition Engine.cpp:1205
float m_cur_engine_rpm
Engine.
Definition Engine.h:212
void setPrime(bool p)
Definition Engine.cpp:933
float m_engine_idle_rpm
('engoption' attr #8)
Definition Engine.h:223
bool m_turbo_has_wastegate
Definition Engine.h:269
float getSmoke()
Definition Engine.cpp:913
void autoShiftDown()
Definition Engine.cpp:1181
bool m_engine_has_air
Engine attribute.
Definition Engine.h:205
float m_max_idle_mixture
Maximum throttle to maintain the idle RPM ('engoption' attr #9)
Definition Engine.h:219
void setHydroPump(float work)
Definition Engine.cpp:938
void SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking)
Definition Engine.cpp:196
float getTorque()
Definition Engine.cpp:923
void setTCaseRatio(float ratio)
Set current transfer case gear (reduction) ratio.
Definition Engine.cpp:948
void UpdateEngine(float dt, int doUpdate)
Definition Engine.cpp:258
float m_auto_cur_acc
Definition Engine.h:246
float getEnginePower()
Definition Engine.h:107
int getNumGears() const
Definition Engine.h:63
bool m_contact
Ignition switch is in ON/RUN position.
Definition Engine.h:231
std::deque< float > m_accs
Definition Engine.h:254
float m_cur_turbo_rpm[MAXTURBO]
Definition Engine.h:260
std::deque< float > m_brakes
Definition Engine.h:255
TorqueCurve * m_torque_curve
Definition Engine.h:226
void offStart()
Quick start of vehicle engine.
Definition Engine.cpp:1023
float m_turbo_wg_threshold_n
Definition Engine.h:273
float m_braking_torque
Engine attribute.
Definition Engine.h:210
int m_cur_gear
Gears; Current gear {-1 = reverse, 0 = neutral, 1...21 = forward}.
Definition Engine.h:192
int m_cur_gear_range
Gears.
Definition Engine.h:193
float m_turbo_bov_rpm[MAXTURBO]
Definition Engine.h:267
int m_kickdown_delay_counter
Definition Engine.h:252
float m_air_pressure
Definition Engine.h:227
float m_half_rpm_range
Definition Engine.h:249
float m_turbo_wg_threshold_p
Definition Engine.h:272
float m_turbo_engine_rpm_operation
Definition Engine.h:265
Engine(float min_rpm, float max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector< float > gears, float dratio, ActorPtr actor)
Definition Engine.cpp:37
int m_min_bov_psi
Definition Engine.h:268
float m_shift_time
Time (in seconds) that it takes to shift ('engoption' attr #4)
Definition Engine.h:237
float m_cur_clutch
Definition Engine.h:200
autoswitch m_autoselect
Definition Engine.h:245
float m_full_rpm_range
Definition Engine.h:247
float getPrimeMixture()
Definition Engine.cpp:1249
bool m_turbo_flutters
Definition Engine.h:271
float m_antilag_min_rpm
Definition Engine.h:275
float m_clutch_time
Time (in seconds) the clutch takes to apply ('engoption' attr #5)
Definition Engine.h:199
void setGear(int v)
low level gear changing (bypasses shifting logic)
Definition Engine.cpp:1054
float m_shift_clock
Definition Engine.h:238
ActorPtr m_actor
Definition Engine.h:187
bool m_engine_has_turbo
Engine attribute.
Definition Engine.h:206
std::vector< float > m_gear_ratios
[R|N|1|...] ('engine' attrs #4[global],#5[R],#6[N],#7[1]...)
Definition Engine.h:195
void autoSetAcc(float val)
Definition Engine.cpp:1085
float m_cur_clutch_torque
Definition Engine.h:201
float m_ref_wheel_revolutions
Gears; estimated wheel revolutions based on current vehicle speed along the longi....
Definition Engine.h:190
float m_min_idle_mixture
Minimum throttle to maintain the idle RPM ('engoption' attr #10)
Definition Engine.h:218
void stopEngine()
stall engine
Definition Engine.cpp:1069
int m_num_gears
Num. forward gears.
Definition Engine.h:194
int getAutoShift()
Definition Engine.cpp:1191
bool m_starter
Ignition switch is in START position.
Definition Engine.h:232
SimGearboxMode m_auto_mode
Definition Engine.h:244
int m_upshift_delay_counter
Definition Engine.h:251
void SetTurboOptions(int type, float tinertiaFactor, int nturbos, float param1, float param2, float param3, float param4, float param5, float param6, float param7, float param8, float param9, float param10, float param11)
Definition Engine.cpp:128
float m_clutch_force
('engoption' attr #3)
Definition Engine.h:198
void autoShiftUp()
Definition Engine.cpp:1172
void setAutoMode(SimGearboxMode mode)
Definition Engine.cpp:857
void setManualClutch(float val)
Definition Engine.cpp:1196
bool m_engine_is_priming
Engine.
Definition Engine.h:225
int getGear()
Definition Engine.cpp:1048
void shift(int val)
Changes gear by a relative offset. Plays sounds.
Definition Engine.cpp:1094
bool m_engine_is_electric
Engine attribute.
Definition Engine.h:204
float m_engine_min_rpm
Shift down RPM ('engine' attr #1)
Definition Engine.h:222
float getIdleMixture()
Definition Engine.cpp:1242
float m_post_shift_time
Time (in seconds) until full torque is transferred ('engoption' attr #6)
Definition Engine.h:235
bool m_engine_is_running
Engine state.
Definition Engine.h:208
void toggleContact()
Ignition.
Definition Engine.cpp:992
void toggleAutoMode()
Definition Engine.cpp:827
void updateShifts()
Changes gears. Plays sounds.
Definition Engine.cpp:1123
float m_engine_max_rpm
Shift up RPM ('engine' attr #2)
Definition Engine.h:221
float m_engine_stall_rpm
('engoption' attr #7)
Definition Engine.h:224
int getNumGearsRanges() const
Definition Engine.h:64
void setAcc(float val)
Definition Engine.cpp:862
float getAcc()
Definition Engine.cpp:890
float m_shift_behaviour
Definition Engine.h:250
void UpdateEngineAudio()
Definition Engine.cpp:800
float m_cur_acc
Engine.
Definition Engine.h:211
float m_turbo_inertia_factor
Definition Engine.h:261
float m_engine_torque
Torque in N/m ('engine' attr #3)
Definition Engine.h:216
int m_num_turbos
Definition Engine.h:262
void shiftTo(int val)
Changes gear to given value. Plays sounds.
Definition Engine.cpp:1118
bool isRunning()
Definition Engine.h:102
void setRPM(float rpm)
Definition Engine.cpp:928
int getGearRange()
Definition Engine.cpp:1059
float getGearRatio(int pos)
-1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...)
Definition Engine.cpp:966
int m_shifting
Definition Engine.h:240
float getTurboPSI()
Definition Engine.cpp:867
bool hasContact()
Ignition.
Definition Engine.h:103
const TerrainPtr & GetTerrain()
Wavefield * getWater()
Definition Terrain.h:87
This class loads and processes a torque curve for a vehicle.
Definition TorqueCurve.h:43
Ogre::Real getEngineTorque(Ogre::Real rpm)
Returns the calculated engine torque based on the given RPM, interpolating the torque curve spline.
@ SS_TRIG_TURBOBACKFIRE
@ SS_TRIG_TURBOWASTEGATE
@ SS_TRIG_AIR_PURGE
@ SS_TRIG_GEARSLIDE
@ SS_TRIG_REVERSE_GEAR
@ EV_TRUCK_ACCELERATE
accelerate the truck
@ EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50
manual clutch with 50 percent pedal input
@ EV_TRUCK_SHIFT_GEAR01
shift directly into this gear
@ EV_TRUCK_SHIFT_MIDRANGE
select middle range (7-12) for H-shaft
@ EV_TRUCK_SHIFT_HIGHRANGE
select high range (13-18) for H-shaft
@ EV_TRUCK_SHIFT_LOWRANGE
select low range (1-6) for H-shaft
@ EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25
manual clutch with 25 percent pedal input
@ EV_TRUCK_AUTOSHIFT_UP
shift automatic transmission one gear up
@ EV_TRUCK_ACCELERATE_MODIFIER_50
accelerate with 50 percent pedal input
@ EV_TRUCK_MANUAL_CLUTCH
manual clutch (for manual transmission)
@ EV_TRUCK_SHIFT_UP
shift one gear up in manual transmission mode
@ EV_TRUCK_TOGGLE_CONTACT
toggle ignition
@ EV_TRUCK_AUTOSHIFT_DOWN
shift automatic transmission one gear down
@ EV_TRUCK_SHIFT_NEUTRAL
shift to neutral gear in manual transmission mode
@ EV_TRUCK_SWITCH_SHIFT_MODES
toggle between transmission modes
@ EV_TRUCK_BRAKE
brake
@ EV_TRUCK_SHIFT_GEAR_REVERSE
shift directly into this gear
@ EV_TRUCK_CYCLE_GEAR_RANGES
cycle through the ranges
@ EV_TRUCK_STARTER
hold to start the engine
@ EV_TRUCK_SHIFT_DOWN
shift one gear down in manual transmission mode
@ EV_TRUCK_BRAKE_MODIFIER_25
brake with 25 percent pedal input
@ EV_TRUCK_BRAKE_MODIFIER_50
brake with 50 percent pedal input
@ EV_TRUCK_ACCELERATE_MODIFIER_25
accelerate with 25 percent pedal input
void TRIGGER_EVENT_ASYNC(scriptEvents type, int arg1, int arg2ex=0, int arg3ex=0, int arg4ex=0, std::string arg5ex="", std::string arg6ex="", std::string arg7ex="", std::string arg8ex="")
Asynchronously (via MSG_SIM_SCRIPT_EVENT_TRIGGERED) invoke script function eventCallbackEx(),...
SimGearboxMode
std::string ToLocalizedString(SimGearboxMode e)
@ MANUAL_STICK
Fully manual: stick shift.
@ MANUAL_RANGES
Fully manual: stick shift with ranges.
@ SEMI_AUTO
Manual shift with auto clutch.
@ MANUAL
Fully manual: sequential shift.
@ AUTO
Automatic shift.
GameContext * GetGameContext()
Console * GetConsole()
static const NodeNum_t NODENUM_INVALID
@ SE_TRUCK_ENGINE_DIED
triggered when the vehicle's engine dies (from underrev, water, etc), the argument refers to the acto...
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)
Definition SimData.h:267
Ogre::Vector3 Velocity
Definition SimData.h:268
Ogre::Real wh_radius
Definition SimData.h:411