diff --git a/doc/angelscript/Script2Game/BeamClass.h b/doc/angelscript/Script2Game/BeamClass.h index 232bc4a086..653c1549f8 100644 --- a/doc/angelscript/Script2Game/BeamClass.h +++ b/doc/angelscript/Script2Game/BeamClass.h @@ -177,7 +177,13 @@ class BeamClass /** * Retrieve the waypoint AI object. */ - VehicleAiClass getVehicleAI(); + VehicleAiClass @getVehicleAI(); + + + /** + * Retrieve engine/transmission simulator. + */ + EngineClassPtr @getEngine(); //! @} diff --git a/doc/angelscript/Script2Game/EngineClass.h b/doc/angelscript/Script2Game/EngineClass.h new file mode 100644 index 0000000000..1179f852ed --- /dev/null +++ b/doc/angelscript/Script2Game/EngineClass.h @@ -0,0 +1,134 @@ + +namespace Script2Game { + +/** \addtogroup ScriptSideAPIs + * @{ + */ + +/** \addtogroup Script2Game + * @{ + */ + +enum autoswitch +{ + REAR, + NEUTRAL, + DRIVE, + TWO, + ONE, + MANUALMODE +}; + +/** + * @brief Binding of RoR::EngineSim; A land vehicle engine + transmission + * @note Obtain the object using `BeamClass::getEngine()`. + */ +class EngineSimClass +{ +public: + + /// @name Definition; keyword 'engine' + /// @{ + float getShiftDownRPM() const; //!< Shift down RPM ('engine' attr #1) + float getShiftUpRPM() const; //!< Shift up RPM ('engine' attr #2) + float getEngineTorque() const; //!< Torque in N/m ('engine' attr #3) + float getDiffRatio() const; //!< Global gear ratio ('engine' attr #4) + float getGearRatio(int pos); //!< -1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...) + int getNumGears() const; + int getNumGearsRanges() const; + /// @} + + /// @name Definition, Keyword 'engoption' + /// @{ + float getEngineInertia() const; //!< ('engoption' attr #1) + char getEngineType() const; //!< 't' = truck (default), 'c' = car, 'e' = electric car ('engoption' attr #2) + bool isElectric() const; + bool hasAir() const; + bool hasTurbo() const; + float getClutchForce() const; //!< ('engoption' attr #3) + float getShiftTime() const; //!< Time (in seconds) that it takes to shift ('engoption' attr #4) + float getClutchTime() const; //!< Time (in seconds) the clutch takes to apply ('engoption' attr #5) + float getPostShiftTime() const; //!< Time (in seconds) until full torque is transferred ('engoption' attr #6) + float getStallRMP() const; //!< ('engoption' attr #7) + float getIdleRPM() const; //!< ('engoption' attr #8) + float getMaxIdleMixture() const; //!< Maximum throttle to maintain the idle RPM ('engoption' attr #9) + float getMinIdleMixture() const; //!< Minimum throttle to maintain the idle RPM ('engoption' attr #10) + float getBrakingTorque() const; + /// @} + + /// @name General state getters + /// @{ + float getAcc(); + float getClutch(); + float getCrankFactor(); + float getRPM(); + float getSmoke(); + float getTorque(); + float getTurboPSI(); + SimGearboxMode getAutoMode(); + int getGear(); + int getGearRange(); + bool isRunning(); + bool hasContact(); //!< Ignition + float getEngineTorque(); + float getInputShaftRPM(); + float getDriveRatio(); + float getEnginePower(); + float getEnginePower(float rpm); + float getTurboPower(); + float getIdleMixture(); + float getPrimeMixture(); + autoswitch getAutoShift(); + float getAccToHoldRPM(); //!< estimate required throttle input to hold the current rpm + float getWheelSpin(); //!< Current wheel RPM + /// @} + + /// @name Shifting diagnostic + /// @{ + float getPostShiftClock(); + float getShiftClock(); + bool isPostShifting(); + bool isShifting(); + int getShifTargetGear(); + float getAutoShiftBehavior(); + int getUpshiftDelayCounter(); + int getKickdownDelayCounter(); + /// @} + + /// @name General state changes + /// @{ + void pushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select = -1); + void setAcc(float val); + void autoSetAcc(float val); + void setClutch(float clutch); + void setRPM(float rpm); + void setWheelSpin(float rpm); + void setAutoMode(SimGearboxMode mode); + void setPrime(bool p); + void setHydroPump(float work); + void setManualClutch(float val); + void setTCaseRatio(float ratio); //!< Set current transfer case gear (reduction) ratio + void toggleContact(); //!< Ignition + void offStart(); //!< Quick start of vehicle engine. + void startEngine(); //!< Quick engine start. Plays sounds. + void stopEngine(); //!< stall engine + /// @} + + /// @name Shifting + /// @{ + void toggleAutoMode(); + void autoShiftDown(); + void autoShiftSet(autoswitch mode); + void autoShiftUp(); + void setGear(int v); //!< low level gear changing (bypasses shifting logic) + void setGearRange(int v); //!< low level gear changing (bypasses shifting logic) + void shift(int val); //!< Changes gear by a relative offset. Plays sounds. + void shiftTo(int val); //!< Changes gear to given value. Plays sounds. + /// @} + +}; + +/// @} //addtogroup Script2Game +/// @} //addtogroup ScriptSideAPIs + +} //namespace Script2Game diff --git a/doc/angelscript/Script2Game/globals.h b/doc/angelscript/Script2Game/globals.h index 49cc17cdd4..26886488aa 100644 --- a/doc/angelscript/Script2Game/globals.h +++ b/doc/angelscript/Script2Game/globals.h @@ -722,6 +722,42 @@ enum ActorSimAttr ACTORSIMATTR_TC_RATIO, //!< Regulating force, safe values: <1 - 20> ACTORSIMATTR_TC_PULSE_TIME, //!< Pulse duration in seconds, safe values <0.005 - 1> ACTORSIMATTR_TC_WHEELSLIP_CONSTANT //!< Minimum wheel slip threshold, safe value = 0.25 + + // Engine + ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM, //!< Automatic transmission - Param #1 of 'engine' + ACTORSIMATTR_ENGINE_SHIFTUP_RPM, //!< Automatic transmission - Param #2 of 'engine' + ACTORSIMATTR_ENGINE_TORQUE, //!< Engine torque in newton-meters (N/m) - Param #3 of 'engine' + ACTORSIMATTR_ENGINE_DIFF_RATIO, //!< Differential ratio (aka global gear ratio) - Param #4 of 'engine' + ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY, //!< Gearbox - Format: " []..."; Param #5 and onwards of 'engine'. + + // Engoption + ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA, //!< - Param #1 of 'engoption' + ACTORSIMATTR_ENGOPTION_ENGINE_TYPE, //!< - Param #2 of 'engoption' + ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE, //!< - Param #3 of 'engoption' + ACTORSIMATTR_ENGOPTION_SHIFT_TIME, //!< - Param #4 of 'engoption' + ACTORSIMATTR_ENGOPTION_CLUTCH_TIME, //!< - Param #5 of 'engoption' + ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME, //!< Time (in seconds) until full torque is transferred - Param #6 of 'engoption' + ACTORSIMATTR_ENGOPTION_STALL_RPM, //!< RPM where engine stalls - Param #7 of 'engoption' + ACTORSIMATTR_ENGOPTION_IDLE_RPM, //!< Target idle RPM - Param #8 of 'engoption' + ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE, //!< Max throttle to maintain idle RPM - Param #9 of 'engoption' + ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE, //!< Min throttle to maintain idle RPM - Param #10 of 'engoption' + ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE, //!< How much engine brakes on zero throttle - Param #11 of 'engoption' + + // Engturbo2 (actually 'engturbo' with Param #1 [type] set to "2" - the recommended variant) + ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR, //!< Time to spool up - Param #2 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_NUM_TURBOS, //!< Number of turbos - Param #3 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_MAX_RPM, //!< MaxPSI * 10000 ~ calculated from Param #4 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP, //!< Engine RPM threshold for turbo to operate - Param #5 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_BOV_ENABLED, //!< Blow-off valve - Param #6 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI, //!< Blow-off valve PSI threshold - Param #7 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED, //!< - Param #8 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI, //!< - Param #9 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N, //!< 1 - WgThreshold ~ calculated from Param #10 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P, //!< 1 + WgThreshold ~ calculated from Param #10 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED, //!< - Param #11 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE, //!< - Param #12 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM, //!< - Param #13 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER, //!< - Param #14 of 'engturbo2' }; } // namespace Script2Game diff --git a/resources/scripts/example_actor_engineDiag.as b/resources/scripts/example_actor_engineDiag.as new file mode 100644 index 0000000000..6258f1ceb6 --- /dev/null +++ b/resources/scripts/example_actor_engineDiag.as @@ -0,0 +1,351 @@ +/// \title Engine tweak + Clutch diag script +/// \brief Shows config params and state of engine simulation +/// \author ohlidalp 2024-2025, see https://github.com/RigsOfRods/rigs-of-rods/pull/3177 + + // Window [X] button handler +#include "imgui_utils.as" +imgui_utils::CloseWindowPrompt closeBtnHandler; + +// #region Plots + +vector2 cfgPlotSize(0.f, 45.f); // 0=autoresize + +// assume 60FPS = circa 3 sec +const int MAX_SAMPLES = 3*60; +array clutchBuf(MAX_SAMPLES, 0.f); +array rpmBuf(MAX_SAMPLES, 0.f); +array clutchTorqueBuf(MAX_SAMPLES, 0.f); + +void updateFloatBuf(array@ buf, float f) +{ + buf.removeAt(0); + buf.insertLast(f); +} + +void updateEnginePlotBuffers(EngineClass@ engine) +{ + // Engine state values + updateFloatBuf(clutchBuf, engine.getClutch()); + updateFloatBuf(rpmBuf, engine.getRPM()); + updateFloatBuf(clutchTorqueBuf, engine.getTorque()); + +} + +// #endregion + +// #region frameStep +void frameStep(float dt) +{ + + if (ImGui::Begin("Engine Tool", closeBtnHandler.windowOpen, 0)) + { + // Draw the "Terminate this script?" prompt on the top (if not disabled by config). + closeBtnHandler.draw(); + + // force minimum width + ImGui::Dummy(vector2(250, 1)); + + BeamClass@ playerVehicle = game.getCurrentTruck(); + if (@playerVehicle == null) + { + ImGui::Text("You are on foot."); + } + else + { + EngineClass@ engine = playerVehicle.getEngine(); + if (@engine == null) + { + ImGui::Text("Your vehicle doesn't have an engine"); + } + else + { + updateEnginePlotBuffers(engine); + + drawEngineDiagUI(playerVehicle, engine); + } + } + + ImGui::End(); + } +} +// #endregion + +// #region UI drawing helpers +void drawTableRow(string key, float val) +{ + ImGui::TextDisabled(key); ImGui::NextColumn(); ImGui::Text(formatFloat(val, "", 0, 3)); ImGui::NextColumn(); +} + +void drawTableRow(string key, int val) +{ + ImGui::TextDisabled(key); ImGui::NextColumn(); ImGui::Text(''+val); ImGui::NextColumn(); +} + +void drawTableRow(string key, bool val) +{ + ImGui::TextDisabled(key); ImGui::NextColumn(); ImGui::Text(val ? 'true' : 'false'); ImGui::NextColumn(); +} + +void drawTableRowPlot(string key, array@ buf, float rangeMin, float rangeMax) +{ + ImGui::TextDisabled(key); + ImGui::NextColumn(); + plotFloatBuf(buf, rangeMin, rangeMax); + ImGui::NextColumn(); +} + +void plotFloatBuf(array@ buf, float rangeMin, float rangeMax) +{ + //DOC: "void PlotLines(const string&in label, array&in values, int values_count, int values_offset = 0, const string&in overlay_text = string(), float scale_min = FLT_MAX, float scale_max = FLT_MAX, vector2 graph_size = vector2(0,0))", + ImGui::PlotLines("", buf, MAX_SAMPLES, 0, "", rangeMin, rangeMax, cfgPlotSize); + ImGui::SameLine(); + float val = buf[buf.length()-1]; + ImGui::Text(formatFloat(val, "", 0, 3)); +} + +// Attributes can be edited realtime (on every keystroke) or using the [Focus] button. +// Focused editing means all other inputs are disabled and [Apply/Reset] buttons must be used. +ActorSimAttr gFocusedEditingAttr = ACTORSIMATTR_NONE; +float gFocusedEditingValue = 0.f; +float cfgAttrInputboxWidth = 125.f; +color cfgAttrUnfocusedBgColor = color(0.14, 0.14, 0.14, 1.0); +void drawAttrInputRow(BeamClass@ actor, ActorSimAttr attr, string label) +{ + ImGui::PushID(label); + ImGui::TextDisabled(label); + ImGui::NextColumn(); + if (gFocusedEditingAttr == ACTORSIMATTR_NONE) + { + // Focused editing inactive - draw [Focus] button + float val = actor.getSimAttribute(attr); + ImGui::SetNextItemWidth(cfgAttrInputboxWidth); + if (ImGui::InputFloat("", val)) + { + actor.setSimAttribute(attr, val); + } + ImGui::SameLine(); + if (ImGui::SmallButton("Focus")) + { + gFocusedEditingAttr = attr; + gFocusedEditingValue = val; + } + } + else if (gFocusedEditingAttr == attr) + { + // This attr is focused - draw [Apply/Reset] buttons + ImGui::SetNextItemWidth(cfgAttrInputboxWidth); + ImGui::InputFloat("##"+label, gFocusedEditingValue); + ImGui::SameLine(); + if (ImGui::Button("Apply")) + { + actor.setSimAttribute(attr, gFocusedEditingValue); + gFocusedEditingAttr = ACTORSIMATTR_NONE; + gFocusedEditingValue = 0.f; + } + ImGui::SameLine(); + if (ImGui::SmallButton("Reset")) + { + gFocusedEditingAttr = ACTORSIMATTR_NONE; + gFocusedEditingValue = 0.f; + } + } + else + { + // Some other attr is focused - just draw a label padded to size of inputbox. + string valStr = "" + actor.getSimAttribute(attr); + ImGui::PushStyleColor(ImGuiCol_FrameBg, cfgAttrUnfocusedBgColor); + ImGui::BeginChildFrame(uint(attr), vector2(cfgAttrInputboxWidth, ImGui::GetTextLineHeight()) + 3 * 2); + ImGui::Text(valStr); + ImGui::EndChildFrame(); // Must be called either way - inconsistent with other End*** funcs. + ImGui::PopStyleColor(); // FrameBg + } + ImGui::NextColumn(); + ImGui::PopID(); // label +} + +void drawAttributesCommonHelp() +{ + if (ImGui::CollapsingHeader("How to read and edit attributes:")) + { + ImGui::TextDisabled("Each value is displayed twice (for debugging) from different sources:"); + ImGui::TextDisabled("1. the 'get***' value is what EngineClass object reports via `get***()` functions."); + ImGui::TextDisabled("2. the UPPERCASE value is what ActorClass object reports via `getSimAttribute()` function."); + ImGui::TextDisabled("There are exceptions, a few values have multiple EngineClass getters or lack Attribute handle"); + ImGui::Dummy(vector2(10,10)); + ImGui::TextDisabled("Attributes can be edited realtime (on every keystroke) or using the [Focus] button."); + ImGui::TextDisabled("Focused editing means all other inputs are disabled and [Apply/Reset] buttons must be used."); + ImGui::Separator(); + ImGui::Separator(); + } +} + +//#endregion + +// #region Main window - 'engine' args tab +void drawEngineAttributesTab(BeamClass@ actor, EngineClass@ engine) +{ + drawAttributesCommonHelp(); + + ImGui::Columns(2); + + drawTableRow("getShiftDownRPM", engine.getShiftDownRPM()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM, "SHIFTDOWN_RPM"); + ImGui::Separator(); + drawTableRow("getShiftUpRPM", engine.getShiftUpRPM()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_SHIFTUP_RPM, "SHIFTUP_RPM"); + ImGui::Separator(); + drawTableRow("getEngineTorque", engine.getEngineTorque()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_TORQUE, "TORQUE"); + ImGui::Separator(); + drawTableRow("getDiffRatio", engine.getDiffRatio()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGINE_DIFF_RATIO, "DIFF_RATIO"); + ImGui::Separator(); + + //float getGearRatio(int) const" + //int getNumGears() const + //int getNumGearsRanges() const + ImGui::TextDisabled("gears (rev, neutral, "+engine.getNumGears()+" forward)"); + ImGui::NextColumn(); + for (int i = -1; i <= engine.getNumGears(); i++) + { + ImGui::NextColumn(); + ImGui::TextDisabled(">"); + ImGui::NextColumn(); + ImGui::Text(formatFloat(engine.getGearRatio(i), "", 0, 3)); + } + ImGui::Columns(1); +} +//#endregion + +// #region Main window - 'engoption' args tab +void drawEngoptionAttributesTab(BeamClass@ actor, EngineClass@ engine) +{ + drawAttributesCommonHelp(); + + ImGui::Columns(2); + + drawTableRow("getEngineInertia", engine.getEngineInertia()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA, "ENGINE_INERTIA"); + ImGui::Separator(); + drawTableRow("getEngineType", engine.getEngineType()); //uint8 + drawTableRow("isElectric", engine.isElectric()); // bool + drawTableRow("hasAir", engine.hasAir()); // bool + drawTableRow("hasTurbo", engine.hasTurbo()); // bool + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_ENGINE_TYPE, "ENGINE_TYPE"); + ImGui::Separator(); + drawTableRow("getClutchForce", engine.getClutchForce()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE, "CLUTCH_FORCE"); + ImGui::Separator(); + drawTableRow("getShiftTime", engine.getShiftTime()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_SHIFT_TIME, "SHIFT_TIME"); + ImGui::Separator(); + drawTableRow("getClutchTime", engine.getClutchTime()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_CLUTCH_TIME, "CLUTCH_TIME"); + ImGui::Separator(); + drawTableRow("getPostShiftTime", engine.getPostShiftTime()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME, "POST_SHIFT_TIME"); + ImGui::Separator(); + + drawTableRow("getStallRPM", engine.getStallRPM()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_STALL_RPM, "STALL_RPM"); + ImGui::Separator(); + drawTableRow("getIdleRPM", engine.getIdleRPM()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_IDLE_RPM, "IDLE_RPM"); + ImGui::Separator(); + drawTableRow("getMaxIdleMixture", engine.getMaxIdleMixture()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE, "MAX_IDLE_MIXTURE"); + ImGui::Separator(); + drawTableRow("getMinIdleMixture", engine.getMinIdleMixture()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE, "MIN_IDLE_MIXTURE"); + ImGui::Separator(); + drawTableRow("getBrakingTorque", engine.getBrakingTorque()); + drawAttrInputRow(actor, ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE, "BRAKING_TORQUE"); + ImGui::Separator(); + + ImGui::Columns(1); +} +// #endregion + +// #region Main window - simulation state tab +void drawSimulationStateTab(EngineClass@ engine) +{ + ImGui::Columns(2); + + drawTableRow("getAcc", engine.getAcc()); + drawTableRowPlot("getClutch (0.0 - 1.0)", clutchBuf, 0.f, 1.f); + drawTableRow("getCrankFactor", engine.getCrankFactor()); + drawTableRowPlot("getRPM (0 - 10000)", rpmBuf, 0.f, 10000.f); + drawTableRow("getSmoke", engine.getSmoke()); + float clutchTorquePlotMax = engine.getEngineTorque() * engine.getGearRatio(1) * 2.5f; // magic + drawTableRowPlot("getTorque (0 - "+clutchTorquePlotMax+")", clutchTorqueBuf, 0.f, clutchTorquePlotMax); + drawTableRow("getTurboPSI", engine.getTurboPSI()); + drawTableRow("getAutoMode", engine.getAutoMode());//SimGearboxMode + drawTableRow("getGear", engine.getGear()); + drawTableRow("getGearRange", engine.getGearRange()); + drawTableRow("isRunning", engine.isRunning()); // bool + drawTableRow("hasContact", engine.hasContact()); //bool + drawTableRow("getAutoShift", engine.getAutoShift()); //autoswitch + drawTableRow("getCurEngineTorque", engine.getCurEngineTorque()); + drawTableRow("getInputShaftRPM", engine.getInputShaftRPM()); + drawTableRow("getDriveRatio", engine.getDriveRatio()); + drawTableRow("getEnginePower", engine.getEnginePower()); + drawTableRow("getTurboPower", engine.getTurboPower()); + drawTableRow("getIdleMixture", engine.getIdleMixture()); + drawTableRow("getPrimeMixture", engine.getPrimeMixture()); + drawTableRow("getAccToHoldRPM", engine.getAccToHoldRPM()); + + ImGui::Columns(1); +} +// #endregion + +// #region Main window +void drawEngineDiagUI(BeamClass@ actor, EngineClass@ engine) +{ + if (ImGui::BeginTabBar("engineDiagTabs")) + { + if (ImGui::BeginTabItem('engine args')) + { + drawEngineAttributesTab(actor, engine); + ImGui::EndTabItem(); + } + + + if (ImGui::BeginTabItem("engoption args")) + { + drawEngoptionAttributesTab(actor, engine); + ImGui::EndTabItem(); + } + + if (ImGui::BeginTabItem('state')) + { drawSimulationStateTab(engine); + + ImGui::EndTabItem(); + } + + ImGui::EndTabBar(); + } +} + +// #endregion + +float fmax(float a, float b) +{ + return (a > b) ? a : b; +} + +float fabs(float a) +{ + return a > 0.f ? a : -a; +} + +float fclamp(float val, float minv, float maxv) +{ + return val < minv ? minv : (val > maxv) ? maxv : val; +} + +float fexp(float val) +{ + const float eConstant = 2.71828183; + return pow(eConstant, val); +} + diff --git a/resources/scripts/script_editor.as b/resources/scripts/script_editor.as index 212a7c51ca..34426004f1 100644 --- a/resources/scripts/script_editor.as +++ b/resources/scripts/script_editor.as @@ -1489,6 +1489,7 @@ string SPECIALCHARS = "{}\n\t \0"; regionFoundWithName = trimRight(trimLeft(this.buffer.substr(regionTitleStart, endOffset - regionTitleStart))); regionBodyStartOffset = endOffset+1; //game.log("DBG analyzeBuffer(): regionFound: withName="+regionFoundWithName+" atLineIdx="+regionFoundAtLineIdx+" bodyStartOffset="+regionBodyStartOffset); + //game.log("DBG ^ startOffset="+startOffset+", regionTitleStart="+regionTitleStart+", endOffset="+endOffset); } // Process #endregion @@ -2381,12 +2382,15 @@ string trimLeft(string s) string trimRight(string s) { + if (s.length() == 0) + return s; + for (uint i = s.length()-1; i > 0 ; i--) { if (!isCharBlank(s[i])) return s.substr(0, i+1); } - return ""; + return s; } RegionInfo@ findRegion(dictionary@ regionDict, string name) // Helper which checks first (not inserting NULL entry) diff --git a/source/main/AppContext.cpp b/source/main/AppContext.cpp index f7163dd5eb..08121df84d 100644 --- a/source/main/AppContext.cpp +++ b/source/main/AppContext.cpp @@ -28,6 +28,7 @@ #include "Console.h" #include "ContentManager.h" #include "DashBoardManager.h" +#include "Engine.h" #include "ErrorUtils.h" #include "GameContext.h" #include "GUIManager.h" diff --git a/source/main/CMakeLists.txt b/source/main/CMakeLists.txt index 3262a86f93..b71ae14be9 100644 --- a/source/main/CMakeLists.txt +++ b/source/main/CMakeLists.txt @@ -17,7 +17,7 @@ set(SOURCE_FILES gameplay/CharacterFactory.{h,cpp} gameplay/ChatSystem.{h,cpp} gameplay/CruiseControl.cpp - gameplay/EngineSim.{h,cpp} + gameplay/Engine.{h,cpp} gameplay/Landusemap.{h,cpp} gameplay/RaceSystem.{h,cpp} gameplay/RepairMode.{h,cpp} @@ -235,6 +235,7 @@ if (ROR_USE_ANGELSCRIPT) scripting/bindings/ActorAngelscript.cpp scripting/bindings/CacheSystemAngelscript.cpp scripting/bindings/ConsoleAngelscript.cpp + scripting/bindings/EngineAngelscript.cpp scripting/bindings/GameScriptAngelscript.cpp scripting/bindings/GenericFileFormatAngelscript.cpp scripting/bindings/ImGuiAngelscript.cpp diff --git a/source/main/ForwardDeclarations.h b/source/main/ForwardDeclarations.h index d8459e98e7..07c19a428f 100644 --- a/source/main/ForwardDeclarations.h +++ b/source/main/ForwardDeclarations.h @@ -107,7 +107,7 @@ namespace RoR class DashBoardManager; class DustPool; class DiscordRpc; - class EngineSim; + class Engine; class Flexable; class FlexAirfoil; class FlexBody; @@ -218,6 +218,7 @@ namespace RoR typedef RefCountingObjectPtr ActorPtr; typedef RefCountingObjectPtr CacheEntryPtr; + typedef RefCountingObjectPtr EnginePtr; typedef RefCountingObjectPtr GenericDocumentPtr; typedef RefCountingObjectPtr GenericDocContextPtr; typedef RefCountingObjectPtr LocalStoragePtr; diff --git a/source/main/GameContext.cpp b/source/main/GameContext.cpp index 9403ed9e6c..8643c71e2c 100644 --- a/source/main/GameContext.cpp +++ b/source/main/GameContext.cpp @@ -28,7 +28,7 @@ #include "Collisions.h" #include "Console.h" #include "DashBoardManager.h" -#include "EngineSim.h" +#include "Engine.h" #include "GfxScene.h" #include "GUIManager.h" #include "GUI_FrictionSettings.h" @@ -317,8 +317,8 @@ ActorPtr GameContext::SpawnActor(ActorSpawnRequest& rq) if (fresh_actor->ar_engine) { - fresh_actor->ar_engine->SetAutoMode(RoR::SimGearboxMode::AUTO); - fresh_actor->ar_engine->autoShiftSet(EngineSim::DRIVE); + fresh_actor->ar_engine->setAutoMode(RoR::SimGearboxMode::AUTO); + fresh_actor->ar_engine->autoShiftSet(Engine::DRIVE); } } else if (rq.asr_origin == ActorSpawnRequest::Origin::NETWORK) diff --git a/source/main/gameplay/CruiseControl.cpp b/source/main/gameplay/CruiseControl.cpp index 1ac3f9a856..cce750bfd3 100644 --- a/source/main/gameplay/CruiseControl.cpp +++ b/source/main/gameplay/CruiseControl.cpp @@ -21,7 +21,7 @@ #include "Actor.h" -#include "EngineSim.h" +#include "Engine.h" #include "InputEngine.h" #include @@ -35,7 +35,7 @@ void Actor::cruisecontrolToggle() if (cc_mode) { cc_target_speed = ar_avg_wheel_speed; - cc_target_rpm = ar_engine->GetEngineRpm(); + cc_target_rpm = ar_engine->getRPM(); } else { @@ -47,10 +47,10 @@ void Actor::cruisecontrolToggle() void Actor::UpdateCruiseControl(float dt) { - if ((ar_engine->GetGear() > 0 && App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE) > 0.05f) || - (ar_engine->GetGear() > 0 && cc_target_speed < cc_target_speed_lower_limit) || - (ar_engine->GetGear() > 0 && ar_parking_brake) || - (ar_engine->GetGear() < 0) || + if ((ar_engine->getGear() > 0 && App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE) > 0.05f) || + (ar_engine->getGear() > 0 && cc_target_speed < cc_target_speed_lower_limit) || + (ar_engine->getGear() > 0 && ar_parking_brake) || + (ar_engine->getGear() < 0) || !ar_engine->isRunning() || !ar_engine->hasContact()) { @@ -58,22 +58,22 @@ void Actor::UpdateCruiseControl(float dt) return; } - if (ar_engine->GetGear() != 0 && App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH) > 0.05f) + if (ar_engine->getGear() != 0 && App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH) > 0.05f) return; - float acc = ar_engine->GetAccToHoldRPM(); + float acc = ar_engine->getAccToHoldRPM(); - if (ar_engine->GetGear() > 0) + if (ar_engine->getGear() > 0) { // Try to maintain the target speed float power_weight_ratio = getTotalMass(true) / ar_engine->getEnginePower(); acc += (cc_target_speed - ar_wheel_speed) * power_weight_ratio * 0.25; } - else if (ar_engine->GetGear() == 0) // out of gear + else if (ar_engine->getGear() == 0) // out of gear { // Try to maintain the target rpm - float speed_range = (ar_engine->getMaxRPM() - ar_engine->getMinRPM()) / 50.0f; - acc += ar_engine->GetEngineInertia() * (cc_target_rpm - ar_engine->GetEngineRpm()) / speed_range; + float speed_range = (ar_engine->getShiftUpRPM() - ar_engine->getShiftDownRPM()) / 50.0f; + acc += ar_engine->getEngineInertia() * (cc_target_rpm - ar_engine->getRPM()) / speed_range; } cc_accs.push_front(Ogre::Math::Clamp(acc, -1.0f, +1.0f)); @@ -89,11 +89,11 @@ void Actor::UpdateCruiseControl(float dt) } avg_acc /= cc_accs.size(); - ar_engine->autoSetAcc(Ogre::Math::Clamp(avg_acc, ar_engine->GetAcceleration(), 1.0f)); + ar_engine->autoSetAcc(Ogre::Math::Clamp(avg_acc, ar_engine->getAcc(), 1.0f)); if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_CRUISE_CONTROL_ACCL)) { - if (ar_engine->GetGear() > 0) + if (ar_engine->getGear() > 0) { cc_target_speed *= pow(2.0f, dt / 5.0f); cc_target_speed = std::max(cc_target_speed_lower_limit, cc_target_speed); @@ -102,23 +102,23 @@ void Actor::UpdateCruiseControl(float dt) cc_target_speed = std::min(cc_target_speed, sl_speed_limit); } } - else if (ar_engine->GetGear() == 0) // out of gear + else if (ar_engine->getGear() == 0) // out of gear { cc_target_rpm *= pow(2.0f, dt / 5.0f); - cc_target_rpm = std::min(cc_target_rpm, ar_engine->getMaxRPM()); + cc_target_rpm = std::min(cc_target_rpm, ar_engine->getShiftUpRPM()); } } if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_CRUISE_CONTROL_DECL)) { - if (ar_engine->GetGear() > 0) + if (ar_engine->getGear() > 0) { cc_target_speed *= pow(0.5f, dt / 5.0f); cc_target_speed = std::max(cc_target_speed_lower_limit, cc_target_speed); } - else if (ar_engine->GetGear() == 0) // out of gear + else if (ar_engine->getGear() == 0) // out of gear { cc_target_rpm *= pow(0.5f, dt / 5.0f); - cc_target_rpm = std::max(ar_engine->getMinRPM(), cc_target_rpm); + cc_target_rpm = std::max(ar_engine->getShiftDownRPM(), cc_target_rpm); } } if (App::GetInputEngine()->getEventBoolValue(EV_TRUCK_CRUISE_CONTROL_READJUST)) @@ -128,7 +128,7 @@ void Actor::UpdateCruiseControl(float dt) { cc_target_speed = std::min(cc_target_speed, sl_speed_limit); } - cc_target_rpm = ar_engine->GetEngineRpm(); + cc_target_rpm = ar_engine->getRPM(); } if (cc_can_brake) diff --git a/source/main/gameplay/EngineSim.cpp b/source/main/gameplay/Engine.cpp similarity index 85% rename from source/main/gameplay/EngineSim.cpp rename to source/main/gameplay/Engine.cpp index e0a2b765ba..f38830a090 100644 --- a/source/main/gameplay/EngineSim.cpp +++ b/source/main/gameplay/Engine.cpp @@ -2,7 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer - Copyright 2013-2020 Petr Ohlidal + Copyright 2013-2023 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -19,7 +19,7 @@ along with Rigs of Rods. If not, see . */ -#include "EngineSim.h" +#include "Engine.h" #include "AppContext.h" #include "ApproxMath.h" // frand() @@ -34,10 +34,10 @@ using namespace Ogre; using namespace RoR; -EngineSim::EngineSim(float _min_rpm, float _max_rpm, float torque, std::vector gears, float dratio, ActorPtr actor) : +Engine::Engine(float _min_rpm, float _max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector forward_gears, float diff_ratio, ActorPtr actor) : m_air_pressure(0.0f) , m_auto_cur_acc(0.0f) - , m_auto_mode(AUTOMATIC) + , m_auto_mode(SimGearboxMode::AUTO) , m_autoselect(DRIVE) , m_braking_torque(-torque / 5.0f) , m_clutch_force(10000.0f) @@ -52,10 +52,9 @@ EngineSim::EngineSim(float _min_rpm, float _max_rpm, float torque, std::vector::iterator it = m_gear_ratios.begin(); it != m_gear_ratios.end(); ++it) - { - (*it) *= m_diff_ratio; - } - for (int i = 0; i < MAXTURBO; i++) { m_engine_addi_torque[i] = 0; m_cur_turbo_rpm[i] = 0; } + + // Assemble gear vector in format [R|N|1...] + m_gear_ratios.push_back(-reverse_gear * diff_ratio); + m_gear_ratios.push_back(neutral_gear * diff_ratio); + for (float gear : forward_gears) + m_gear_ratios.push_back(gear * diff_ratio); } -EngineSim::~EngineSim() +Engine::~Engine() { // delete NULL is safe delete m_torque_curve; m_torque_curve = NULL; } -void EngineSim::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) +void 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) { m_engine_has_turbo = true; m_engine_turbo_mode = NEW; @@ -194,7 +193,7 @@ void EngineSim::SetTurboOptions(int type, float tinertiaFactor, int nturbos, flo } } -void EngineSim::SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking) +void Engine::SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking) { m_engine_inertia = einertia; m_engine_type = etype; @@ -256,7 +255,7 @@ void EngineSim::SetEngineOptions(float einertia, char etype, float eclutch, floa } } -void EngineSim::UpdateEngineSim(float dt, int doUpdate) +void Engine::UpdateEngine(float dt, int doUpdate) { float acc = m_cur_acc; @@ -452,7 +451,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) { if (m_engine_is_running && m_cur_engine_rpm < m_engine_stall_rpm) { - this->StopEngine(); + this->stopEngine(); } } @@ -496,7 +495,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) float force_threshold = 1.5f * std::max(m_engine_torque, getEnginePower()) * std::abs(m_gear_ratios[2]); float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1]; m_cur_clutch_torque = (gearboxspinner - m_cur_wheel_revolutions) * m_cur_clutch * m_clutch_force; - m_cur_clutch_torque = Math::Clamp(m_cur_clutch_torque, -force_threshold, +force_threshold); + m_cur_clutch_torque = Math::Clamp(m_cur_clutch_torque, -force_threshold, +force_threshold); m_cur_clutch_torque *= 1.0f - approx_exp(-std::abs(gearboxspinner - m_cur_wheel_revolutions)); } else @@ -506,7 +505,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) m_cur_engine_rpm = std::max(0.0f, m_cur_engine_rpm); - if (m_auto_mode < MANUAL) + if (m_auto_mode < SimGearboxMode::MANUAL) { // auto-shift if (m_shifting) @@ -541,7 +540,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) { // we're done m_shifting SOUND_STOP(m_actor, SS_TRIG_SHIFT); - SetAcceleration(m_auto_cur_acc); + setAcc(m_auto_cur_acc); m_shifting = 0; m_post_shifting = 1; m_post_shift_clock = 0.0f; @@ -579,25 +578,25 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) } // auto clutch - float declutchRPM = m_engine_min_rpm * 0.75f + m_engine_stall_rpm * 0.25f; + float declutchRPM = m_engine_shiftup_rpm * 0.75f + m_engine_stall_rpm * 0.25f; if (m_cur_gear == 0 || m_cur_engine_rpm < declutchRPM) { m_cur_clutch = 0.0f; } - else if (m_cur_engine_rpm < m_engine_min_rpm && m_engine_min_rpm > declutchRPM) + else if (m_cur_engine_rpm < m_engine_shiftup_rpm && m_engine_shiftup_rpm > declutchRPM) { - float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_min_rpm - declutchRPM); + float clutch = (m_cur_engine_rpm - declutchRPM) / (m_engine_shiftup_rpm - declutchRPM); m_cur_clutch = std::min(clutch * clutch, m_cur_clutch); } - else if (!m_shift_val && m_cur_engine_rpm > m_engine_min_rpm && m_cur_clutch < 1.0f) + else if (!m_shift_val && m_cur_engine_rpm > m_engine_shiftup_rpm && m_cur_clutch < 1.0f) { float threshold = 1.5f * getEnginePower(m_cur_engine_rpm) * std::abs(m_gear_ratios[2]); float gearboxspinner = m_cur_engine_rpm / m_gear_ratios[m_cur_gear + 1]; float clutchTorque = (gearboxspinner - m_cur_wheel_revolutions) * m_clutch_force; float reTorque = Math::Clamp(clutchTorque, -threshold, +threshold) / m_gear_ratios[m_cur_gear + 1]; - float range = (m_engine_max_rpm - m_engine_min_rpm) * 0.4f * sqrt(std::max(0.2f, acc)); - float powerRatio = std::min((m_cur_engine_rpm - m_engine_min_rpm) / range, 1.0f); + float range = (m_engine_max_rpm - m_engine_shiftup_rpm) * 0.4f * sqrt(std::max(0.2f, acc)); + float powerRatio = std::min((m_cur_engine_rpm - m_engine_shiftup_rpm) / range, 1.0f); float engineTorque = getEnginePower() * std::min(m_cur_acc, 0.9f) * powerRatio; float torqueDiff = std::min(engineTorque, std::abs(reTorque)); @@ -625,7 +624,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) m_ref_wheel_revolutions = velocity / m_actor->ar_wheels[0].wh_radius * RAD_PER_SEC_TO_RPM; } - if (!m_engine_is_electric && m_auto_mode == AUTOMATIC && (m_autoselect == DRIVE || m_autoselect == TWO) && m_cur_gear > 0) + if (!m_engine_is_electric && m_auto_mode == SimGearboxMode::AUTO && (m_autoselect == DRIVE || m_autoselect == TWO) && m_cur_gear > 0) { if ((m_cur_engine_rpm > m_engine_max_rpm - 100.0f && m_cur_gear > 1) || m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1] > m_engine_max_rpm - 100.0f) { @@ -635,7 +634,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) shift(1); } } - else if (m_cur_gear > 1 && m_ref_wheel_revolutions * m_gear_ratios[m_cur_gear] < m_engine_max_rpm && (m_cur_engine_rpm < m_engine_min_rpm || (m_cur_engine_rpm < m_engine_min_rpm + m_shift_behaviour * m_half_rpm_range / 2.0f && + else if (m_cur_gear > 1 && m_ref_wheel_revolutions * m_gear_ratios[m_cur_gear] < m_engine_max_rpm && (m_cur_engine_rpm < m_engine_shiftup_rpm || (m_cur_engine_rpm < m_engine_shiftup_rpm + m_shift_behaviour * m_half_rpm_range / 2.0f && getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear]) > getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1])))) { shift(-1); @@ -694,18 +693,18 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) newGear--; } } - else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range) + else if (avgAcc50 > 0.6f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range) { - if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_min_rpm + m_half_rpm_range && + if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_shiftup_rpm + m_half_rpm_range && getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear]) * m_gear_ratios[newGear] > getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear + 1]) * m_gear_ratios[newGear + 1]) { newGear--; } } - else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_min_rpm + m_half_rpm_range) + else if (avgAcc50 > 0.4f && acc < 0.8f && acc > avgAcc50 + 0.1f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range) { - if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_min_rpm + m_one_third_rpm_range && + if (newGear > 1 && m_cur_wheel_revolutions * m_gear_ratios[newGear] < m_engine_shiftup_rpm + m_one_third_rpm_range && getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear]) * m_gear_ratios[newGear] > getEnginePower(m_cur_wheel_revolutions * m_gear_ratios[newGear + 1]) * m_gear_ratios[newGear + 1]) { @@ -715,23 +714,23 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) else if (m_cur_gear < (m_autoselect == TWO ? std::min(2, m_num_gears) : m_num_gears) && avgBrake200 < 0.2f && acc < std::min(avgAcc200 + 0.1f, 1.0f) && m_cur_engine_rpm > avgRPM200 - m_full_rpm_range / 20.0f) { - if (avgAcc200 < 0.6f && avgAcc200 > 0.4f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range && m_cur_engine_rpm < m_engine_max_rpm - m_one_third_rpm_range) + if (avgAcc200 < 0.6f && avgAcc200 > 0.4f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range && m_cur_engine_rpm < m_engine_max_rpm - m_one_third_rpm_range) { - if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range) + if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range) { newGear++; } } - else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_min_rpm + m_one_third_rpm_range) + else if (avgAcc200 < 0.4f && avgAcc200 > 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range) { - if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range / 2.0f) + if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f) { newGear++; } } - 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) + else if (avgAcc200 < 0.2f && m_cur_engine_rpm > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f && m_cur_engine_rpm < m_engine_shiftup_rpm + m_half_rpm_range) { - if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_min_rpm + m_one_third_rpm_range / 2.0f) + if (m_cur_wheel_revolutions * m_gear_ratios[newGear + 2] > m_engine_shiftup_rpm + m_one_third_rpm_range / 2.0f) { newGear++; } @@ -771,7 +770,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) m_brakes.pop_back(); } // avoid over-revving - if (m_auto_mode <= SEMIAUTO && m_cur_gear != 0) + if (m_auto_mode <= SimGearboxMode::SEMI_AUTO && m_cur_gear != 0) { if (std::abs(m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1]) > m_engine_max_rpm * 1.25f) { @@ -788,7 +787,7 @@ void EngineSim::UpdateEngineSim(float dt, int doUpdate) } } -void EngineSim::UpdateEngineAudio() +void Engine::UpdateEngineAudio() { #ifdef USE_OPENAL if (m_engine_has_turbo) @@ -815,11 +814,12 @@ void EngineSim::UpdateEngineAudio() #endif // USE_OPENAL } -void EngineSim::ToggleAutoShiftMode() +void Engine::toggleAutoMode() { - m_auto_mode = (m_auto_mode + 1) % (MANUAL_RANGES + 1); + m_auto_mode = static_cast( + (static_cast(m_auto_mode) + 1) % (static_cast(SimGearboxMode::MANUAL_RANGES) + 1)); - if (m_auto_mode == AUTOMATIC) + if (m_auto_mode == SimGearboxMode::AUTO) { if (m_cur_gear > 0) m_autoselect = DRIVE; @@ -833,28 +833,28 @@ void EngineSim::ToggleAutoShiftMode() m_autoselect = MANUALMODE; } - if (m_auto_mode == MANUAL_RANGES) + if (m_auto_mode == SimGearboxMode::MANUAL_RANGES) { m_cur_gear_range = 0; } } -RoR::SimGearboxMode EngineSim::GetAutoShiftMode() +RoR::SimGearboxMode Engine::getAutoMode() { return (RoR::SimGearboxMode)this->m_auto_mode; } -void EngineSim::SetAutoMode(RoR::SimGearboxMode mode) +void Engine::setAutoMode(RoR::SimGearboxMode mode) { - this->m_auto_mode = (shiftmodes)mode; + this->m_auto_mode = mode; } -void EngineSim::SetAcceleration(float val) +void Engine::setAcc(float val) { m_cur_acc = val; } -float EngineSim::GetTurboPsi() +float Engine::getTurboPSI() { if (m_engine_turbo_mode == OLD) { @@ -877,12 +877,12 @@ float EngineSim::GetTurboPsi() return turboPSI; } -float EngineSim::GetAcceleration() +float Engine::getAcc() { return m_cur_acc; } -void EngineSim::PushNetworkState(float rpm, float acc, float clutch, int gear, bool running, bool contact, char automode, char autoselect) +void Engine::pushNetworkState(float rpm, float acc, float clutch, int gear, bool running, bool contact, char automode, char autoselect) { m_cur_engine_rpm = rpm; m_cur_acc = acc; @@ -892,7 +892,7 @@ void EngineSim::PushNetworkState(float rpm, float acc, float clutch, int gear, b m_contact = contact; if (automode != -1) { - m_auto_mode = automode; + m_auto_mode = static_cast(automode); } if (autoselect != -1) { @@ -900,7 +900,7 @@ void EngineSim::PushNetworkState(float rpm, float acc, float clutch, int gear, b } } -float EngineSim::GetSmoke() +float Engine::getSmoke() { if (m_engine_is_running) { @@ -910,32 +910,32 @@ float EngineSim::GetSmoke() return -1; } -float EngineSim::GetTorque() +float Engine::getTorque() { return m_cur_clutch_torque; } -void EngineSim::SetEngineRpm(float rpm) +void Engine::setRPM(float rpm) { m_cur_engine_rpm = rpm; } -void EngineSim::SetEnginePriming(bool p) +void Engine::setPrime(bool p) { m_engine_is_priming = p; } -void EngineSim::SetHydroPumpWork(float work) +void Engine::setHydroPump(float work) { m_hydropump_state = work; } -void EngineSim::SetWheelSpin(float rpm) +void Engine::setWheelSpin(float rpm) { m_cur_wheel_revolutions = rpm; } -void EngineSim::SetTCaseRatio(float ratio) +void Engine::setTCaseRatio(float ratio) { if (ratio < 1.0f) return; @@ -953,8 +953,20 @@ void EngineSim::SetTCaseRatio(float ratio) } } +float Engine::getGearRatio(int pos) +{ + // Pos: -1=reverse, 0 = neutral, 1 = 1st gear, 2 = 2nd gear, etc. + // -------------------------------------------------------------- + + if (pos < -1 || pos > m_num_gears) + return 0.f; + + // Strip off the DiffRatio and TCaseRatio from the internal gear ratio + return (m_gear_ratios[pos + 1] / m_tcase_ratio) / m_diff_ratio; +} + // for hydros acceleration -float EngineSim::GetCrankFactor() +float Engine::getCrankFactor() { float minWorkingRPM = m_engine_idle_rpm * 1.1f; // minWorkingRPM > m_engine_idle_rpm avoids commands deadlocking the engine @@ -967,22 +979,7 @@ float EngineSim::GetCrankFactor() return crankfactor; } -void EngineSim::SetClutch(float clutch) -{ - m_cur_clutch = clutch; -} - -float EngineSim::GetClutch() -{ - return m_cur_clutch; -} - -float EngineSim::GetClutchForce() -{ - return m_clutch_force; -} - -void EngineSim::toggleContact() +void Engine::toggleContact() { m_contact = !m_contact; if (m_contact) @@ -995,17 +992,17 @@ void EngineSim::toggleContact() } } -void EngineSim::StartEngine() +void Engine::startEngine() { - this->OffStart(); + this->offStart(); m_contact = true; m_cur_engine_rpm = m_engine_idle_rpm; m_engine_is_running = true; - if (m_auto_mode <= SEMIAUTO) + if (m_auto_mode <= SimGearboxMode::SEMI_AUTO) { m_cur_gear = 1; } - if (m_auto_mode == AUTOMATIC) + if (m_auto_mode == SimGearboxMode::AUTO) { m_autoselect = DRIVE; } @@ -1013,7 +1010,7 @@ void EngineSim::StartEngine() SOUND_START(m_actor, SS_TRIG_ENGINE); } -void EngineSim::OffStart() +void Engine::offStart() { m_air_pressure = 0.0f; m_autoselect = MANUALMODE; @@ -1027,7 +1024,7 @@ void EngineSim::OffStart() m_engine_is_running = false; m_shifting = 0; m_shift_val = 0; - if (m_auto_mode == AUTOMATIC) + if (m_auto_mode == SimGearboxMode::AUTO) { m_autoselect = NEUTRAL; } @@ -1038,28 +1035,28 @@ void EngineSim::OffStart() } } -int EngineSim::GetGear() +int Engine::getGear() { return m_cur_gear; } // low level gear changing -void EngineSim::SetGear(int v) +void Engine::setGear(int v) { m_cur_gear = v; } -int EngineSim::GetGearRange() +int Engine::getGearRange() { return m_cur_gear_range; } -void EngineSim::SetGearRange(int v) +void Engine::setGearRange(int v) { m_cur_gear_range = v; } -void EngineSim::StopEngine() +void Engine::stopEngine() { if (!m_engine_is_running) return; @@ -1069,26 +1066,26 @@ void EngineSim::StopEngine() SOUND_STOP(m_actor, SS_TRIG_ENGINE); } -float EngineSim::GetAccToHoldRPM() +float Engine::getAccToHoldRPM() { return (-m_braking_torque * std::pow(m_cur_engine_rpm / m_engine_max_rpm, 2.0f)) / getEnginePower(); } // high level controls -void EngineSim::autoSetAcc(float val) +void Engine::autoSetAcc(float val) { m_auto_cur_acc = val; if (!m_shifting) { - SetAcceleration(val); + setAcc(val); } } -void EngineSim::shift(int val) +void Engine::shift(int val) { if (!val || m_cur_gear + val < -1 || m_cur_gear + val > getNumGears()) return; - if (m_auto_mode < MANUAL) + if (m_auto_mode < SimGearboxMode::MANUAL) { m_shift_val = val; m_shifting = 1; @@ -1108,12 +1105,12 @@ void EngineSim::shift(int val) } } -void EngineSim::shiftTo(int newGear) +void Engine::shiftTo(int newGear) { shift(newGear - m_cur_gear); } -void EngineSim::updateShifts() +void Engine::updateShifts() { if (m_autoselect == MANUALMODE) return; @@ -1154,7 +1151,7 @@ void EngineSim::updateShifts() } } -void EngineSim::autoShiftSet(int mode) +void Engine::autoShiftSet(int mode) { m_autoselect = (autoswitch)mode; if (m_engine_is_electric && m_autoselect > DRIVE) @@ -1162,7 +1159,7 @@ void EngineSim::autoShiftSet(int mode) updateShifts(); } -void EngineSim::autoShiftUp() +void Engine::autoShiftUp() { if (m_autoselect != REAR) { @@ -1171,7 +1168,7 @@ void EngineSim::autoShiftUp() } } -void EngineSim::autoShiftDown() +void Engine::autoShiftDown() { if ((m_engine_is_electric && m_autoselect != DRIVE) || (!m_engine_is_electric && m_autoselect != ONE)) @@ -1181,21 +1178,21 @@ void EngineSim::autoShiftDown() } } -int EngineSim::getAutoShift() +int Engine::getAutoShift() { return (int)m_autoselect; } -void EngineSim::setManualClutch(float val) +void Engine::setManualClutch(float val) { - if (m_auto_mode >= MANUAL) + if (m_auto_mode >= SimGearboxMode::MANUAL) { val = std::max(0.0f, val); m_cur_clutch = 1.0 - val; } } -float EngineSim::getTurboPower() +float Engine::getTurboPower() { if (!m_engine_has_turbo) return 0.0f; @@ -1213,13 +1210,13 @@ float EngineSim::getTurboPower() } else { - atValue = (((GetTurboPsi() * 6.8) * m_engine_torque) / 100); //1psi = 6% more power + atValue = (((getTurboPSI() * 6.8) * m_engine_torque) / 100); //1psi = 6% more power } return atValue; } -float EngineSim::getEnginePower(float rpm) +float Engine::getEnginePower(float rpm) { // engine power with limiter float tqValue = 1.0f; // ratio (0-1) @@ -1232,18 +1229,18 @@ float EngineSim::getEnginePower(float rpm) return (m_engine_torque * tqValue) + getTurboPower(); } -float EngineSim::getIdleMixture() +float Engine::getIdleMixture() { if (m_cur_engine_rpm <= m_engine_idle_rpm) return m_max_idle_mixture; return m_min_idle_mixture; } -float EngineSim::getPrimeMixture() +float Engine::getPrimeMixture() { if (m_engine_is_priming) { - float crankfactor = GetCrankFactor(); + float crankfactor = getCrankFactor(); if (crankfactor < 0.9f) { @@ -1260,7 +1257,7 @@ float EngineSim::getPrimeMixture() return 0.0f; } -void EngineSim::UpdateInputEvents(float dt) +void Engine::UpdateInputEvents(float dt) { float accl = App::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE); float brake = App::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE); @@ -1296,7 +1293,7 @@ void EngineSim::UpdateInputEvents(float dt) } // arcade controls are only working with auto-clutch! - if (!App::io_arcade_controls->getBool() || (this->GetAutoShiftMode() >= SimGearboxMode::MANUAL)) + if (!App::io_arcade_controls->getBool() || (this->getAutoMode() >= SimGearboxMode::MANUAL)) { // classic mode, realistic this->autoSetAcc(accl); @@ -1307,11 +1304,11 @@ void EngineSim::UpdateInputEvents(float dt) // start engine if (this->hasContact() && !this->isRunning() && (accl > 0 || brake > 0)) { - this->StartEngine(); + this->startEngine(); } // arcade controls: hey - people wanted it x| ... <- and it's convenient - if (this->GetGear() >= 0) + if (this->getGear() >= 0) { // neutral or drive forward, everything is as its used to be: brake is brake and accel. is accel. this->autoSetAcc(accl); @@ -1331,35 +1328,35 @@ void EngineSim::UpdateInputEvents(float dt) float velocity = hdir.dotProduct(m_actor->ar_nodes[0].Velocity); // switching point, does the user want to drive forward from backward or the other way round? change gears? - if (velocity < 1.0f && brake > 0.5f && accl < 0.5f && this->GetGear() > 0) + if (velocity < 1.0f && brake > 0.5f && accl < 0.5f && this->getGear() > 0) { // we are on the brake, jump to reverse gear - if (this->GetAutoShiftMode() == SimGearboxMode::AUTO) + if (this->getAutoMode() == SimGearboxMode::AUTO) { - this->autoShiftSet(EngineSim::REAR); + this->autoShiftSet(Engine::REAR); } else { - this->SetGear(-1); + this->setGear(-1); } } - else if (velocity > -1.0f && brake < 0.5f && accl > 0.5f && this->GetGear() < 0) + else if (velocity > -1.0f && brake < 0.5f && accl > 0.5f && this->getGear() < 0) { // we are on the gas pedal, jump to first gear when we were in rear gear - if (this->GetAutoShiftMode() == SimGearboxMode::AUTO) + if (this->getAutoMode() == SimGearboxMode::AUTO) { - this->autoShiftSet(EngineSim::DRIVE); + this->autoShiftSet(Engine::DRIVE); } else { - this->SetGear(1); + this->setGear(1); } } } } // gear management - if (this->GetAutoShiftMode() == SimGearboxMode::AUTO) + if (this->getAutoMode() == SimGearboxMode::AUTO) { if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_AUTOSHIFT_UP)) { @@ -1391,20 +1388,34 @@ void EngineSim::UpdateInputEvents(float dt) if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SWITCH_SHIFT_MODES)) { // toggle Auto shift - this->ToggleAutoShiftMode(); + this->toggleAutoMode(); // force gui update m_actor->RequestUpdateHudFeatures(); App::GetConsole()->putMessage(RoR::Console::CONSOLE_MSGTYPE_INFO, RoR::Console::CONSOLE_SYSTEM_NOTICE, - ToLocalizedString(this->GetAutoShiftMode()), "cog.png"); + ToLocalizedString(this->getAutoMode()), "cog.png"); } // joy clutch - float cval = App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH); - this->setManualClutch(cval); + float clutch = App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH); + if (App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25) || + App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50)) + { + float clutchModifier = 0.0f; + if (App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25)) + { + clutchModifier += 0.25f; + } + if (App::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50)) + { + clutchModifier += 0.50f; + } + clutch *= clutchModifier; + } + this->setManualClutch(clutch); - SimGearboxMode shiftmode = this->GetAutoShiftMode(); + SimGearboxMode shiftmode = this->getAutoMode(); if (shiftmode <= SimGearboxMode::MANUAL) // auto, semi auto and sequential shifting { @@ -1416,7 +1427,7 @@ void EngineSim::UpdateInputEvents(float dt) { if (shiftmode > SimGearboxMode::SEMI_AUTO || shiftmode == SimGearboxMode::SEMI_AUTO && (!App::io_arcade_controls->getBool()) || - shiftmode == SimGearboxMode::SEMI_AUTO && this->GetGear() > 0 || + shiftmode == SimGearboxMode::SEMI_AUTO && this->getGear() > 0 || shiftmode == SimGearboxMode::AUTO) { this->shift(-1); @@ -1448,8 +1459,8 @@ void EngineSim::UpdateInputEvents(float dt) { bool gear_changed = false; bool found = false; - int curgear = this->GetGear(); - int curgearrange = this->GetGearRange(); + int curgear = this->getGear(); + int curgearrange = this->getGearRange(); int gearoffset = std::max(0, curgear - curgearrange * 6); // one can select range only if in neutral @@ -1457,31 +1468,31 @@ void EngineSim::UpdateInputEvents(float dt) { if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_LOWRANGE) && curgearrange != 0) { - this->SetGearRange(0); + this->setGearRange(0); gear_changed = true; } else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_MIDRANGE) && curgearrange != 1 && this->getNumGearsRanges() > 1) { - this->SetGearRange(1); + this->setGearRange(1); gear_changed = true; } else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_HIGHRANGE) && curgearrange != 2 && this->getNumGearsRanges() > 2) { - this->SetGearRange(2); + this->setGearRange(2); gear_changed = true; } else if (App::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_CYCLE_GEAR_RANGES)) { - this->SetGearRange((curgearrange + 1) % this->getNumGearsRanges()); + this->setGearRange((curgearrange + 1) % this->getNumGearsRanges()); gear_changed = true; App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, fmt::format(_L("Range cycled (current: {}/available: {})"), - this->GetGearRange(), this->getNumGearsRanges()), "cog.png"); + this->getGearRange(), this->getNumGearsRanges()), "cog.png"); } if (gear_changed) { - switch (this->GetGearRange()) + switch (this->getGearRange()) { case 0: App::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Low range selected"), "cog.png"); diff --git a/source/main/gameplay/Engine.h b/source/main/gameplay/Engine.h new file mode 100644 index 0000000000..07ef68e639 --- /dev/null +++ b/source/main/gameplay/Engine.h @@ -0,0 +1,281 @@ +/* + This source file is part of Rigs of Rods + Copyright 2005-2012 Pierre-Michel Ricordel + Copyright 2007-2012 Thomas Fischer + Copyright 2013-2023 Petr Ohlidal + + For more information, see http://www.rigsofrods.org/ + + Rigs of Rods is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3, as + published by the Free Software Foundation. + + Rigs of Rods is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Rigs of Rods. If not, see . +*/ + +#pragma once + +/// @file + +#include "Application.h" +#include "RefCountingObject.h" + +#include +#include + +namespace RoR { + +/// @addtogroup Gameplay +/// @{ + +/// @addtogroup Trucks +/// @{ + +/// A land vehicle engine + transmission +class Engine : public RefCountingObject +{ + friend class ActorSpawner; + friend class Actor; // For `get/setSimAttribute()` + +public: + + Engine(float min_rpm, float max_rpm, float torque, float reverse_gear, float neutral_gear, std::vector gears, float dratio, ActorPtr actor); + ~Engine(); + + + void SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking); + 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); + + /// @name Definition; keyword 'engine' + /// @{ + float getShiftDownRPM() const { return m_engine_shiftup_rpm; } //!< Shift down RPM ('engine' attr #1) + float getShiftUpRPM() const { return m_engine_max_rpm; } //!< Shift up RPM ('engine' attr #2) + float getEngineTorque() const { return m_engine_torque; } //!< Torque in N/m ('engine' attr #3) + float getDiffRatio() const { return m_diff_ratio; } //!< Global gear ratio ('engine' attr #4) + float getGearRatio(int pos); //!< -1=R, 0=N, 1... ('engine' attrs #5[R],#6[N],#7[1]...) + int getNumGears() const { return m_num_gears; } + int getNumGearsRanges() const { return getNumGears() / 6 + 1; } + /// @} + + /// @name Definition, Keyword 'engoption' + /// @{ + float getEngineInertia() const { return m_engine_inertia; } //!< ('engoption' attr #1) + char getEngineType() const { return m_engine_type; } //!< 't' = truck (default), 'c' = car, 'e' = electric car ('engoption' attr #2) + bool isElectric() const { return m_engine_is_electric; } + bool hasAir() const { return m_engine_has_air; } + bool hasTurbo() const { return m_engine_has_turbo; } + float getClutchForce() const { return m_clutch_force; } //!< ('engoption' attr #3) + float getShiftTime() const { return m_shift_time; } //!< Time (in seconds) that it takes to shift ('engoption' attr #4) + float getClutchTime() const { return m_clutch_time; } //!< Time (in seconds) the clutch takes to apply ('engoption' attr #5) + float getPostShiftTime() const { return m_post_shift_time; } //!< Time (in seconds) until full torque is transferred ('engoption' attr #6) + float getStallRPM() const { return m_engine_stall_rpm; } //!< ('engoption' attr #7) + float getIdleRPM() const { return m_engine_idle_rpm; } //!< ('engoption' attr #8) + float getMaxIdleMixture() const { return m_max_idle_mixture; } //!< Maximum throttle to maintain the idle RPM ('engoption' attr #9) + float getMinIdleMixture() const { return m_min_idle_mixture; } //!< Minimum throttle to maintain the idle RPM ('engoption' attr #10) + float getBrakingTorque() const { return m_braking_torque; } + /// @} + + /// @name Definition, Keyword 'torquecurve' + /// @{ + TorqueCurve* getTorqueCurve() { return m_torque_curve; } + /// @} + + /// @name General state getters + /// @{ + float getAcc(); + float getClutch() const { return m_cur_clutch; }; + float getCrankFactor(); + float getRPM() { return m_cur_engine_rpm; } + float getSmoke(); + float getTorque(); + float getTurboPSI(); + SimGearboxMode getAutoMode(); + int getGear(); + int getGearRange(); + bool isRunning() { return m_engine_is_running; } + bool hasContact() { return m_contact; } //!< Ignition + float getCurEngineTorque() { return m_cur_engine_torque; } + float getInputShaftRPM() { return m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1]; } + float getDriveRatio() { return m_gear_ratios[m_cur_gear + 1]; } + float getEnginePower() { return getEnginePower(m_cur_engine_rpm); } + float getEnginePower(float rpm); + float getTurboPower(); + float getIdleMixture(); + float getPrimeMixture(); + int getAutoShift(); + float getAccToHoldRPM(); //!< estimate required throttle input to hold the current rpm + float getWheelSpin() const { return m_cur_wheel_revolutions; } //!< Wheel RPM + /// @} + + /// @name Shifting diagnostic + /// @{ + float getPostShiftClock() { return m_post_shift_clock; } + float getShiftClock() { return m_shift_clock; } + bool isPostShifting() { return m_post_shifting != 0; } + bool isShifting() { return m_shifting != 0; } + int getShifTargetGear() { return m_shift_val; } + float getAutoShiftBehavior() { return m_shift_behaviour; } + int getUpshiftDelayCounter() { return m_upshift_delay_counter; } + int getKickdownDelayCounter() { return m_kickdown_delay_counter; } + /// @} + + /// @name General state changes + /// @{ + void pushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select = -1); + void setAcc(float val); + void autoSetAcc(float val); + void setClutch(float clutch) { m_cur_clutch = clutch; } + void setRPM(float rpm); + void setWheelSpin(float rpm); + void setAutoMode(SimGearboxMode mode); + void setPrime(bool p); + void setHydroPump(float work); + void setManualClutch(float val); + void setTCaseRatio(float ratio); //!< Set current transfer case gear (reduction) ratio + void toggleContact(); //!< Ignition + void offStart(); //!< Quick start of vehicle engine. + void startEngine(); //!< Quick engine start. Plays sounds. + void stopEngine(); //!< stall engine + /// @} + + /// @name Shifting + /// @{ + void toggleAutoMode(); + void autoShiftDown(); + void autoShiftSet(int mode); + void autoShiftUp(); + void setGear(int v); //!< low level gear changing (bypasses shifting logic) + void setGearRange(int v); //!< low level gear changing (bypasses shifting logic) + void shift(int val); //!< Changes gear by a relative offset. Plays sounds. + void shiftTo(int val); //!< Changes gear to given value. Plays sounds. + /// @} + + /// @name Updates + /// @{ + void updateShifts(); //!< Changes gears. Plays sounds. + void UpdateEngine(float dt, int doUpdate); + void UpdateEngineAudio(); + void UpdateInputEvents(float dt); + /// @} + + enum autoswitch + { + REAR, + NEUTRAL, + DRIVE, + TWO, + ONE, + MANUALMODE + }; + + enum turbomode + { + OLD, + NEW + }; + +private: + + // Vehicle + ActorPtr m_actor; + + // Gearbox + float m_ref_wheel_revolutions; //!< Gears; estimated wheel revolutions based on current vehicle speed along the longi. axis + float m_cur_wheel_revolutions; //!< Gears; measured wheel revolutions + int m_cur_gear; //!< Gears; Current gear {-1 = reverse, 0 = neutral, 1...21 = forward} + int m_cur_gear_range; //!< Gears + int m_num_gears; //!< Num. forward gears + std::vector m_gear_ratios; //!< [R|N|1|...] ('engine' attrs #4[global],#5[R],#6[N],#7[1]...) + + // Clutch + float m_clutch_force; //!< ('engoption' attr #3) + float m_clutch_time; //!< Time (in seconds) the clutch takes to apply ('engoption' attr #5) + float m_cur_clutch; + float m_cur_clutch_torque; + + // Engine + bool m_engine_is_electric; //!< Engine attribute + bool m_engine_has_air; //!< Engine attribute + bool m_engine_has_turbo; //!< Engine attribute + int m_engine_turbo_mode; //!< Engine attribute + bool m_engine_is_running; //!< Engine state + char m_engine_type; //!< 't' = truck (default), 'c' = car ('engoption' attr #2) + float m_braking_torque; //!< Engine attribute + float m_cur_acc; //!< Engine + float m_cur_engine_rpm; //!< Engine + float m_cur_engine_torque; //!< Engine + float m_diff_ratio; //!< Global gear ratio ('engine' attr #4) + float m_tcase_ratio; //!< Engine + float m_engine_torque; //!< Torque in N/m ('engine' attr #3) + float m_hydropump_state; //!< Engine + float m_min_idle_mixture; //!< Minimum throttle to maintain the idle RPM ('engoption' attr #10) + float m_max_idle_mixture; //!< Maximum throttle to maintain the idle RPM ('engoption' attr #9) + float m_engine_inertia; //!< ('engoption' attr #1) + float m_engine_max_rpm; //!< Shift up RPM ('engine' attr #2) + float m_engine_shiftup_rpm; //!< Shift down RPM ('engine' attr #1) + float m_engine_idle_rpm; //!< ('engoption' attr #8) + float m_engine_stall_rpm; //!< ('engoption' attr #7) + bool m_engine_is_priming; //!< Engine + TorqueCurve* m_torque_curve; + float m_air_pressure; + + // Ignition + bool m_contact; //!< Ignition switch is in ON/RUN position. + bool m_starter; //!< Ignition switch is in START position. + + // Shifting + float m_post_shift_time; //!< Time (in seconds) until full torque is transferred ('engoption' attr #6) + float m_post_shift_clock; + float m_shift_time; //!< Time (in seconds) that it takes to shift ('engoption' attr #4) + float m_shift_clock; + int m_post_shifting; + int m_shifting; + int m_shift_val; + + // Auto transmission + SimGearboxMode m_auto_mode; + autoswitch m_autoselect; + float m_auto_cur_acc; + float m_full_rpm_range; + float m_one_third_rpm_range; + float m_half_rpm_range; + float m_shift_behaviour; + int m_upshift_delay_counter; + int m_kickdown_delay_counter; + std::deque m_rpms; + std::deque m_accs; + std::deque m_brakes; + + // Turbo +#define MAXTURBO 4 + int m_turbo_ver; + float m_cur_turbo_rpm[MAXTURBO]; + float m_turbo_inertia_factor; + int m_num_turbos; + int m_max_turbo_rpm; + float m_engine_addi_torque[MAXTURBO]; + float m_turbo_engine_rpm_operation; + bool m_turbo_has_bov; + float m_turbo_bov_rpm[MAXTURBO]; + int m_min_bov_psi; + bool m_turbo_has_wastegate; + float m_min_wastegate_psi; + bool m_turbo_flutters; + float m_turbo_wg_threshold_p; + float m_turbo_wg_threshold_n; + bool m_turbo_has_antilag; + float m_antilag_min_rpm; + float m_antilag_rand_chance; + float m_antilag_power_factor; +}; + +/// @} // addtogroup Trucks +/// @} // addtogroup Gameplay + +} // namespace RoR diff --git a/source/main/gameplay/EngineSim.h b/source/main/gameplay/EngineSim.h deleted file mode 100644 index 2fe04c68e0..0000000000 --- a/source/main/gameplay/EngineSim.h +++ /dev/null @@ -1,252 +0,0 @@ -/* - This source file is part of Rigs of Rods - Copyright 2005-2012 Pierre-Michel Ricordel - Copyright 2007-2012 Thomas Fischer - Copyright 2013-2020 Petr Ohlidal - - For more information, see http://www.rigsofrods.org/ - - Rigs of Rods is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License version 3, as - published by the Free Software Foundation. - - Rigs of Rods is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Rigs of Rods. If not, see . -*/ - -#pragma once - -#include "Application.h" - -namespace RoR { - -/// @addtogroup Gameplay -/// @{ - -/// @addtogroup Trucks -/// @{ - -/// A land vehicle engine + transmission -class EngineSim -{ - friend class ActorSpawner; - -public: - - EngineSim(float min_rpm, float max_rpm, float torque, std::vector gears, float dratio, ActorPtr actor); - ~EngineSim(); - - /// Sets current engine state; - /// @param gear Current gear {-1 = reverse, 0 = neutral, 1...21 = forward} - void PushNetworkState(float engine_rpm, float acc, float clutch, int gear, bool running, bool contact, char auto_mode, char auto_select=-1); - - /// Sets engine options. - /// @param einertia Engine inertia - /// @param etype Engine type {'t' = truck (default), 'c' = car} - /// @param eclutch - /// @param ctime Clutch time - /// @param stime Shift time - /// @param pstime Post-shift time - /// @param irpm Idle RPM - /// @param srpm Stall RPM - /// @param maximix Max. idle mixture - /// @param minimix Min. idle mixture - void SetEngineOptions(float einertia, char etype, float eclutch, float ctime, float stime, float pstime, float irpm, float srpm, float maximix, float minimix, float ebraking); - - /// Sets turbo options. - /// @param tinertiatinertiaFactor Turbo inertia factor - /// @param nturbos Number of turbos - /// @param additionalTorque Torque that will be added to the engine at max turbo rpm - 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); - - void SetAcceleration(float val); - void SetAutoMode(RoR::SimGearboxMode mode); - void SetClutch(float clutch); - float GetAcceleration(); - float GetClutch(); - float GetClutchForce(); - float GetCrankFactor(); - float GetSmoke(); - float GetTorque(); - float GetTurboPsi(); - RoR::SimGearboxMode GetAutoShiftMode(); - void SetEngineRpm(float rpm); //!< Set current engine RPM. - void SetEnginePriming(bool p); //!< Set current engine prime. - void SetHydroPumpWork(float work); //!< Set current hydro pump work. - void SetWheelSpin(float rpm); //!< Set current wheel spinning speed. - void SetTCaseRatio(float ratio); //!< Set current transfer case gear (reduction) ratio - void ToggleAutoShiftMode(); - void OffStart(); //!< Quick start of vehicle engine. - void StartEngine(); //!< Quick engine start. Plays sounds. - int GetGear(); //!< low level gear changing - int GetGearRange(); //!< low level gear changing - void SetGear(int v); //!< low level gear changing - void SetGearRange(int v); //!< low level gear changing - void StopEngine(); //!< stall engine - float GetAccToHoldRPM(); //!< estimate required throttle input to hold the current rpm - bool HasTurbo() const { return m_engine_has_turbo; }; - bool isRunning() const { return m_engine_is_running; }; - int GetAutoMode() const { return static_cast(m_auto_mode); }; - char GetEngineType() const { return m_engine_type; }; - float getIdleRPM() const { return m_engine_idle_rpm; }; - float getMaxRPM() const { return m_engine_max_rpm; }; - float getMinRPM() const { return m_engine_min_rpm; }; - int getNumGears() const { return static_cast(m_gear_ratios.size() - 2); }; - int getNumGearsRanges() const{ return getNumGears() / 6 + 1; }; - TorqueCurve* getTorqueCurve() { return m_torque_curve; }; - float GetEngineRpm() const { return m_cur_engine_rpm; } - float GetEngineTorque() const { return m_cur_engine_torque; } - float GetInputShaftRpm() { return m_cur_wheel_revolutions * m_gear_ratios[m_cur_gear + 1]; }; - float GetDriveRatio() { return m_gear_ratios[m_cur_gear + 1]; }; - float GetEngineInertia() { return m_engine_inertia; }; - float getEnginePower() { return getEnginePower(m_cur_engine_rpm); }; - float getEnginePower(float rpm); - float getTurboPower(); - float getIdleMixture(); - float getPrimeMixture(); - int getAutoShift(); - void autoSetAcc(float val); - void autoShiftDown(); - void autoShiftSet(int mode); - void autoShiftUp(); - void setManualClutch(float val); - void shift(int val); //!< Changes gear by a relative offset. Plays sounds. - void shiftTo(int val); //!< Changes gear to given value. Plays sounds. - void updateShifts(); //!< Changes gears. Plays sounds. - void UpdateEngineSim(float dt, int doUpdate); - void UpdateEngineAudio(); - void UpdateInputEvents(float dt); - - // Ignition - void toggleContact(); - bool hasContact() const { return m_contact; }; - - enum autoswitch - { - REAR, - NEUTRAL, - DRIVE, - TWO, - ONE, - MANUALMODE - }; - - enum turbomode - { - OLD, - NEW - }; - -private: - - enum shiftmodes - { - AUTOMATIC, - SEMIAUTO, - MANUAL, - MANUAL_STICK, - MANUAL_RANGES - }; - - // Vehicle - ActorPtr m_actor; - - // Gearbox - float m_ref_wheel_revolutions; //!< Gears; estimated wheel revolutions based on current vehicle speed along the longi. axis - float m_cur_wheel_revolutions; //!< Gears; measured wheel revolutions - int m_cur_gear; //!< Gears; Current gear {-1 = reverse, 0 = neutral, 1...21 = forward} - int m_cur_gear_range; //!< Gears - int m_num_gears; //!< Gears - std::vector m_gear_ratios; //!< Gears - - // Clutch - float m_clutch_force; //!< Clutch attribute - float m_clutch_time; //!< Clutch attribute - float m_cur_clutch; - float m_cur_clutch_torque; - - // Engine - bool m_engine_is_electric; //!< Engine attribute - bool m_engine_has_air; //!< Engine attribute - bool m_engine_has_turbo; //!< Engine attribute - int m_engine_turbo_mode; //!< Engine attribute - bool m_engine_is_running; //!< Engine state - char m_engine_type; //!< Engine attribute {'t' = truck (default), 'c' = car} - float m_braking_torque; //!< Engine attribute - float m_cur_acc; //!< Engine - float m_cur_engine_rpm; //!< Engine - float m_cur_engine_torque; //!< Engine - float m_diff_ratio; //!< Engine - float m_tcase_ratio; //!< Engine - float m_engine_torque; //!< Engine attribute - float m_hydropump_state; //!< Engine - float m_min_idle_mixture; //!< Engine attribute - float m_max_idle_mixture; //!< Engine attribute - float m_engine_inertia; //!< Engine attribute - float m_engine_max_rpm; //!< Engine attribute - float m_engine_min_rpm; //!< Engine attribute - float m_engine_idle_rpm; //!< Engine attribute - float m_engine_stall_rpm; //!< Engine attribute - bool m_engine_is_priming; //!< Engine - TorqueCurve* m_torque_curve; - float m_air_pressure; - - // Ignition - bool m_contact; //!< Ignition switch is in ON/RUN position. - bool m_starter; //!< Ignition switch is in START position. - - // Shifting - float m_post_shift_time; //!< Shift attribute - float m_post_shift_clock; - float m_shift_time; //!< Shift attribute - float m_shift_clock; - int m_post_shifting; - int m_shifting; - int m_shift_val; - - // Auto transmission - int m_auto_mode; //!< Transmission mode (@see enum EngineSim::shiftmodes) - autoswitch m_autoselect; - float m_auto_cur_acc; - float m_full_rpm_range; - float m_one_third_rpm_range; - float m_half_rpm_range; - float m_shift_behaviour; - int m_upshift_delay_counter; - int m_kickdown_delay_counter; - std::deque m_rpms; - std::deque m_accs; - std::deque m_brakes; - - // Turbo -#define MAXTURBO 4 - int m_turbo_ver; - float m_cur_turbo_rpm[MAXTURBO]; - float m_turbo_inertia_factor; - int m_num_turbos; - int m_max_turbo_rpm; - float m_engine_addi_torque[MAXTURBO]; - float m_turbo_engine_rpm_operation; - bool m_turbo_has_bov; - float m_turbo_bov_rpm[MAXTURBO]; - int m_min_bov_psi; - bool m_turbo_has_wastegate; - float m_min_wastegate_psi; - bool m_turbo_flutters; - float m_turbo_wg_threshold_p; - float m_turbo_wg_threshold_n; - bool m_turbo_has_antilag; - float m_antilag_min_rpm; - float m_antilag_rand_chance; - float m_antilag_power_factor; -}; - -/// @} // addtogroup Trucks -/// @} // addtogroup Gameplay - -} // namespace RoR diff --git a/source/main/gameplay/VehicleAI.cpp b/source/main/gameplay/VehicleAI.cpp index 3b7a0f9f5f..3420e99bf2 100644 --- a/source/main/gameplay/VehicleAI.cpp +++ b/source/main/gameplay/VehicleAI.cpp @@ -26,7 +26,7 @@ #include "Actor.h" #include "Console.h" -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "AeroEngine.h" #include "ScrewProp.h" @@ -348,7 +348,7 @@ void VehicleAI::update(float dt, int doUpdate) { // Start engine if not running if (!beam->ar_engine->isRunning()) - beam->ar_engine->StartEngine(); + beam->ar_engine->startEngine(); beam->ar_parking_brake = false; float kmh_wheel_speed = beam->getWheelSpeed() * 3.6; diff --git a/source/main/gfx/GfxActor.cpp b/source/main/gfx/GfxActor.cpp index bbf88ec676..a7294cedeb 100644 --- a/source/main/gfx/GfxActor.cpp +++ b/source/main/gfx/GfxActor.cpp @@ -27,7 +27,7 @@ #include "Collisions.h" #include "DashBoardManager.h" #include "DustPool.h" // General particle gfx -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "GfxScene.h" #include "GUIManager.h" @@ -1881,18 +1881,18 @@ void RoR::GfxActor::UpdateSimDataBuffer() if (m_actor->ar_engine != nullptr) { m_simbuf.simbuf_has_engine = true; - m_simbuf.simbuf_gear = m_actor->ar_engine->GetGear(); + m_simbuf.simbuf_gear = m_actor->ar_engine->getGear(); m_simbuf.simbuf_autoshift = m_actor->ar_engine->getAutoShift(); - m_simbuf.simbuf_engine_rpm = m_actor->ar_engine->GetEngineRpm(); - m_simbuf.simbuf_engine_turbo_psi= m_actor->ar_engine->GetTurboPsi(); - m_simbuf.simbuf_engine_accel = m_actor->ar_engine->GetAcceleration(); - m_simbuf.simbuf_engine_torque = m_actor->ar_engine->GetEngineTorque(); - m_simbuf.simbuf_inputshaft_rpm = m_actor->ar_engine->GetInputShaftRpm(); - m_simbuf.simbuf_drive_ratio = m_actor->ar_engine->GetDriveRatio(); - m_simbuf.simbuf_clutch = m_actor->ar_engine->GetClutch(); + m_simbuf.simbuf_engine_rpm = m_actor->ar_engine->getRPM(); + m_simbuf.simbuf_engine_turbo_psi= m_actor->ar_engine->getTurboPSI(); + m_simbuf.simbuf_engine_accel = m_actor->ar_engine->getAcc(); + m_simbuf.simbuf_engine_torque = m_actor->ar_engine->getCurEngineTorque(); + m_simbuf.simbuf_inputshaft_rpm = m_actor->ar_engine->getInputShaftRPM(); + m_simbuf.simbuf_drive_ratio = m_actor->ar_engine->getDriveRatio(); + m_simbuf.simbuf_clutch = m_actor->ar_engine->getClutch(); m_simbuf.simbuf_num_gears = m_actor->ar_engine->getNumGears(); - m_simbuf.simbuf_engine_max_rpm = m_actor->ar_engine->getMaxRPM(); - m_simbuf.simbuf_engine_smoke = m_actor->ar_engine->GetSmoke(); + m_simbuf.simbuf_engine_max_rpm = m_actor->ar_engine->getShiftUpRPM(); + m_simbuf.simbuf_engine_smoke = m_actor->ar_engine->getSmoke(); } if (m_actor->m_num_wheel_diffs > 0) { @@ -2593,7 +2593,7 @@ void RoR::GfxActor::CalcPropAnimation(PropAnim& anim, float& cstate, int& div, f if (has_engine && anim.animFlags & PROP_ANIM_FLAG_GEAR) { - bool match = static_cast(anim.animOpt3) == m_actor->ar_engine->GetGear(); + bool match = static_cast(anim.animOpt3) == m_actor->ar_engine->getGear(); cstate += static_cast(match); div++; } diff --git a/source/main/gui/panels/GUI_VehicleInfoTPanel.cpp b/source/main/gui/panels/GUI_VehicleInfoTPanel.cpp index 023b2780ed..3366857143 100644 --- a/source/main/gui/panels/GUI_VehicleInfoTPanel.cpp +++ b/source/main/gui/panels/GUI_VehicleInfoTPanel.cpp @@ -25,7 +25,7 @@ #include "Actor.h" #include "SimData.h" #include "Language.h" -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "GfxActor.h" #include "GUIManager.h" @@ -747,7 +747,7 @@ void VehicleInfoTPanel::DrawVehicleBasicsUI(RoR::GfxActor* actorx) this->DrawShiftModeButton(actorx); - switch (actorx->GetActor()->ar_engine->GetAutoShiftMode()) + switch (actorx->GetActor()->ar_engine->getAutoMode()) { case SimGearboxMode::AUTO: DrawSingleBulletRow("Shift Up", EV_TRUCK_AUTOSHIFT_UP); @@ -1064,13 +1064,13 @@ void VehicleInfoTPanel::DrawShiftModeButton(RoR::GfxActor* actorx) { if (DrawSingleButtonRow(App::GetInputEngine()->getEventBoolValue(EV_TRUCK_SWITCH_SHIFT_MODES), m_shift_icon, "Shift Mode", EV_TRUCK_SWITCH_SHIFT_MODES)) { - actorx->GetActor()->ar_engine->ToggleAutoShiftMode(); + actorx->GetActor()->ar_engine->toggleAutoMode(); // force gui update actorx->GetActor()->RequestUpdateHudFeatures(); // Inform player via chatbox const char* msg = nullptr; - switch (actorx->GetActor()->ar_engine->GetAutoShiftMode()) + switch (actorx->GetActor()->ar_engine->getAutoMode()) { case SimGearboxMode::AUTO: msg = "Automatic shift"; break; @@ -1097,7 +1097,7 @@ void VehicleInfoTPanel::DrawEngineButton(RoR::GfxActor* actorx) } else if (actorx->GetActor()->ar_engine) { - actorx->GetActor()->ar_engine->StartEngine(); + actorx->GetActor()->ar_engine->startEngine(); } } } diff --git a/source/main/network/OutGauge.cpp b/source/main/network/OutGauge.cpp index 80b74e58cf..b1dcffc2a8 100644 --- a/source/main/network/OutGauge.cpp +++ b/source/main/network/OutGauge.cpp @@ -25,7 +25,7 @@ #include "Actor.h" #include "ActorManager.h" #include "DashBoardManager.h" -#include "EngineSim.h" +#include "Engine.h" #include "RoRVersion.h" #include @@ -139,15 +139,15 @@ bool OutGauge::Update(float dt, ActorPtr truck) else if (truck && truck->ar_engine) { // truck and engine valid - if (truck->ar_engine->HasTurbo()) + if (truck->ar_engine->hasTurbo()) { gd.Flags |= OG_TURBO; } - gd.Gear = std::max(0, truck->ar_engine->GetGear() + 1); // we only support one reverse gear + gd.Gear = std::max(0, truck->ar_engine->getGear() + 1); // we only support one reverse gear gd.PLID = 0; gd.Speed = fabs(truck->ar_wheel_speed); - gd.RPM = truck->ar_engine->GetEngineRpm(); - gd.Turbo = truck->ar_engine->GetTurboPsi() * 0.0689475729f; + gd.RPM = truck->ar_engine->getRPM(); + gd.Turbo = truck->ar_engine->getTurboPSI() * 0.0689475729f; gd.EngTemp = 0; // TODO gd.Fuel = 0; // TODO gd.OilPressure = 0; // TODO @@ -182,9 +182,9 @@ bool OutGauge::Update(float dt, ActorPtr truck) if (truck->alb_mode) gd.ShowLights |= DL_ABS; - gd.Throttle = truck->ar_engine->GetAcceleration(); + gd.Throttle = truck->ar_engine->getAcc(); gd.Brake = truck->ar_brake; - gd.Clutch = 1 - truck->ar_engine->GetClutch(); // 0-1 + gd.Clutch = 1 - truck->ar_engine->getClutch(); // 0-1 strncpy(gd.Display1, truck->ar_design_name.c_str(), 15); if (truck->ar_design_name.length() > 15) diff --git a/source/main/physics/Actor.cpp b/source/main/physics/Actor.cpp index d683129b63..386b2c3415 100644 --- a/source/main/physics/Actor.cpp +++ b/source/main/physics/Actor.cpp @@ -35,7 +35,7 @@ #include "DashBoardManager.h" #include "Differentials.h" #include "DynamicCollisions.h" -#include "EngineSim.h" +#include "Engine.h" #include "ErrorUtils.h" #include "FlexAirfoil.h" #include "FlexBody.h" @@ -124,12 +124,6 @@ void Actor::dispose() ar_num_soundsources = 0; #endif // USE_OPENAL - if (ar_engine != nullptr) - { - delete ar_engine; - ar_engine = nullptr; - } - if (ar_autopilot != nullptr) { delete ar_autopilot; @@ -144,6 +138,7 @@ void Actor::dispose() delete m_replay_handler; m_replay_handler = nullptr; + ar_engine = nullptr; // RefCountingObjectPtr<> will handle the cleanup. ar_vehicle_ai = nullptr; // RefCountingObjectPtr<> will handle the cleanup. // remove all scene nodes @@ -633,7 +628,7 @@ void Actor::calcNetwork() bool contact = ((flagmask & NETMASK_ENGINE_CONT) != 0); bool running = ((flagmask & NETMASK_ENGINE_RUN) != 0); - ar_engine->PushNetworkState(engspeed, engforce, engclutch, gear, running, contact, automode); + ar_engine->pushNetworkState(engspeed, engforce, engclutch, gear, running, contact, automode); } // set particle cannon @@ -1445,7 +1440,7 @@ void Actor::toggleTransferCaseGearRatio() auto gear_ratios = &m_transfer_case->tr_gear_ratios; std::rotate(gear_ratios->begin(), gear_ratios->begin() + 1, gear_ratios->end()); - ar_engine->SetTCaseRatio(m_transfer_case->tr_gear_ratios[0]); + ar_engine->setTCaseRatio(m_transfer_case->tr_gear_ratios[0]); } } @@ -1655,9 +1650,9 @@ void Actor::SyncReset(bool reset_position) { if (App::sim_spawn_running->getBool()) { - ar_engine->StartEngine(); + ar_engine->startEngine(); } - ar_engine->SetWheelSpin(0.0f); + ar_engine->setWheelSpin(0.0f); } int num_axle_diffs = (m_transfer_case && m_transfer_case->tr_4wd_mode) ? m_num_axle_diffs + 1 : m_num_axle_diffs; @@ -1976,17 +1971,17 @@ void Actor::sendStreamData() send_oob->time = App::GetGameContext()->GetActorManager()->GetNetTime(); if (ar_engine) { - send_oob->engine_speed = ar_engine->GetEngineRpm(); - send_oob->engine_force = ar_engine->GetAcceleration(); - send_oob->engine_clutch = ar_engine->GetClutch(); - send_oob->engine_gear = ar_engine->GetGear(); + send_oob->engine_speed = ar_engine->getRPM(); + send_oob->engine_force = ar_engine->getAcc(); + send_oob->engine_clutch = ar_engine->getClutch(); + send_oob->engine_gear = ar_engine->getGear(); if (ar_engine->hasContact()) send_oob->flagmask += NETMASK_ENGINE_CONT; if (ar_engine->isRunning()) send_oob->flagmask += NETMASK_ENGINE_RUN; - switch (ar_engine->GetAutoShiftMode()) + switch (ar_engine->getAutoMode()) { case RoR::SimGearboxMode::AUTO: send_oob->flagmask += NETMASK_ENGINE_MODE_AUTOMATIC; break; @@ -2147,7 +2142,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // torque if (ar_engine && hydrobeam.hb_anim_flags & ANIM_FLAG_TORQUE) { - float torque = ar_engine->GetCrankFactor(); + float torque = ar_engine->getCrankFactor(); if (torque <= 0.0f) torque = 0.0f; if (torque >= ar_anim_previous_crank) @@ -2165,7 +2160,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) if (ar_engine && (hydrobeam.hb_anim_flags & ANIM_FLAG_SHIFTER) && hydrobeam.hb_anim_param == 3.0f) { - int shifter = ar_engine->GetGear(); + int shifter = ar_engine->getGear(); if (shifter > m_previous_gear) { cstate = 1.0f; @@ -2199,7 +2194,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // shifterman1, left/right if (ar_engine && (hydrobeam.hb_anim_flags & ANIM_FLAG_SHIFTER) && hydrobeam.hb_anim_param == 1.0f) { - int shifter = ar_engine->GetGear(); + int shifter = ar_engine->getGear(); if (!shifter) { cstate = -0.5f; @@ -2218,7 +2213,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // shifterman2, up/down if (ar_engine && (hydrobeam.hb_anim_flags & ANIM_FLAG_SHIFTER) && hydrobeam.hb_anim_param == 2.0f) { - int shifter = ar_engine->GetGear(); + int shifter = ar_engine->getGear(); cstate = 0.5f; if (shifter < 0) { @@ -2234,7 +2229,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // shifterlinear, to amimate cockpit gearselect gauge and autotransmission stick if (ar_engine && (hydrobeam.hb_anim_flags & ANIM_FLAG_SHIFTER) && hydrobeam.hb_anim_param == 4.0f) { - int shifter = ar_engine->GetGear(); + int shifter = ar_engine->getGear(); int numgears = ar_engine->getNumGears(); cstate -= (shifter + 2.0) / (numgears + 2.0); div++; @@ -2259,7 +2254,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // engine tacho ( scales with maxrpm, default is 3500 ) if (ar_engine && hydrobeam.hb_anim_flags & ANIM_FLAG_TACHO) { - float tacho = ar_engine->GetEngineRpm() / ar_engine->getMaxRPM(); + float tacho = ar_engine->getRPM() / ar_engine->getShiftUpRPM(); cstate -= tacho; div++; } @@ -2267,7 +2262,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // turbo if (ar_engine && hydrobeam.hb_anim_flags & ANIM_FLAG_TURBO) { - float turbo = ar_engine->GetTurboPsi() * 3.34; + float turbo = ar_engine->getTurboPSI() * 3.34; cstate -= turbo / 67.0f; div++; } @@ -2282,7 +2277,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // accelerator if (ar_engine && hydrobeam.hb_anim_flags & ANIM_FLAG_ACCEL) { - float accel = ar_engine->GetAcceleration(); + float accel = ar_engine->getAcc(); cstate -= accel + 0.06f; //( small correction, get acc is nver smaller then 0.06. div++; @@ -2291,7 +2286,7 @@ void Actor::CalcAnimators(hydrobeam_t const& hydrobeam, float &cstate, int &div) // clutch if (ar_engine && hydrobeam.hb_anim_flags & ANIM_FLAG_CLUTCH) { - float clutch = ar_engine->GetClutch(); + float clutch = ar_engine->getClutch(); cstate -= fabs(1.0f - clutch); div++; } @@ -3855,7 +3850,7 @@ void Actor::updateDashBoards(float dt) if (ar_engine) { // gears first - int gear = ar_engine->GetGear(); + int gear = ar_engine->getGear(); ar_dashboard->setInt(DD_ENGINE_GEAR, gear); int numGears = (int)ar_engine->getNumGears(); @@ -3875,13 +3870,13 @@ void Actor::updateDashBoards(float dt) // R N D 2 1 String int cg = ar_engine->getAutoShift(); - if (cg != EngineSim::MANUALMODE) + if (cg != Engine::MANUALMODE) { - str = ((cg == EngineSim::REAR) ? "#ffffff" : "#868686") + String("R\n"); - str += ((cg == EngineSim::NEUTRAL) ? "#ff0012" : "#8a000a") + String("N\n"); - str += ((cg == EngineSim::DRIVE) ? "#12ff00" : "#248c00") + String("D\n"); - str += ((cg == EngineSim::TWO) ? "#ffffff" : "#868686") + String("2\n"); - str += ((cg == EngineSim::ONE) ? "#ffffff" : "#868686") + String("1"); + str = ((cg == Engine::REAR) ? "#ffffff" : "#868686") + String("R\n"); + str += ((cg == Engine::NEUTRAL) ? "#ff0012" : "#8a000a") + String("N\n"); + str += ((cg == Engine::DRIVE) ? "#12ff00" : "#248c00") + String("D\n"); + str += ((cg == Engine::TWO) ? "#ffffff" : "#868686") + String("2\n"); + str += ((cg == Engine::ONE) ? "#ffffff" : "#868686") + String("1"); } else { @@ -3895,19 +3890,19 @@ void Actor::updateDashBoards(float dt) ar_dashboard->setInt(DD_ENGINE_AUTO_GEAR, autoGear); // clutch - float clutch = ar_engine->GetClutch(); + float clutch = ar_engine->getClutch(); ar_dashboard->setFloat(DD_ENGINE_CLUTCH, clutch); // accelerator - float acc = ar_engine->GetAcceleration(); + float acc = ar_engine->getAcc(); ar_dashboard->setFloat(DD_ACCELERATOR, acc); // RPM - float rpm = ar_engine->GetEngineRpm(); + float rpm = ar_engine->getRPM(); ar_dashboard->setFloat(DD_ENGINE_RPM, rpm); // turbo - float turbo = ar_engine->GetTurboPsi() * 3.34f; // MAGIC :/ + float turbo = ar_engine->getTurboPSI() * 3.34f; // MAGIC :/ ar_dashboard->setFloat(DD_ENGINE_TURBO, turbo); // ignition @@ -3919,7 +3914,7 @@ void Actor::updateDashBoards(float dt) ar_dashboard->setBool(DD_ENGINE_BATTERY, batt); // clutch warning - bool cw = (fabs(ar_engine->GetTorque()) >= ar_engine->GetClutchForce() * 10.0f); + bool cw = (fabs(ar_engine->getTorque()) >= ar_engine->getClutchForce() * 10.0f); ar_dashboard->setBool(DD_ENGINE_CLUTCH_WARNING, cw); } @@ -4127,8 +4122,8 @@ void Actor::updateDashBoards(float dt) if (hasEngine) { - hasturbo = ar_engine->HasTurbo(); - autogearVisible = (ar_engine->getAutoShift() != EngineSim::MANUALMODE); + hasturbo = ar_engine->hasTurbo(); + autogearVisible = (ar_engine->getAutoShift() != Engine::MANUALMODE); } ar_dashboard->setEnabled(DD_ENGINE_TURBO, hasturbo); @@ -4316,23 +4311,23 @@ void Actor::calculateLocalGForces() void Actor::engineTriggerHelper(int engineNumber, EngineTriggerType type, float triggerValue) { // engineNumber tells us which engine - EngineSim* e = ar_engine; // placeholder: actors do not have multiple engines yet + EnginePtr e = ar_engine; // placeholder: actors do not have multiple engines yet switch (type) { case TRG_ENGINE_CLUTCH: if (e) - e->SetClutch(triggerValue); + e->setClutch(triggerValue); break; case TRG_ENGINE_BRAKE: ar_brake = triggerValue; break; case TRG_ENGINE_ACC: if (e) - e->SetAcceleration(triggerValue); + e->setAcc(triggerValue); break; case TRG_ENGINE_RPM: - // TODO: Implement setTargetRPM in the EngineSim.cpp + // TODO: Implement setTargetRPM in the Engine.cpp break; case TRG_ENGINE_SHIFTUP: if (e) @@ -4748,9 +4743,47 @@ void Actor::setSimAttribute(ActorSimAttr attr, float val) // PLEASE maintain the same order as in `enum ActorSimAttr` switch (attr) { + // TractionControl case ACTORSIMATTR_TC_RATIO: tc_ratio = val; return; case ACTORSIMATTR_TC_PULSE_TIME: tc_pulse_time = val; return; case ACTORSIMATTR_TC_WHEELSLIP_CONSTANT: tc_wheelslip_constant = val; return; + + // Engine + case ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM: if (ar_engine) { ar_engine->m_engine_shiftup_rpm = val; } return; + case ACTORSIMATTR_ENGINE_SHIFTUP_RPM: if (ar_engine) { ar_engine->m_engine_max_rpm = val; } return; + case ACTORSIMATTR_ENGINE_TORQUE: if (ar_engine) { ar_engine->m_engine_torque = val; } return; + case ACTORSIMATTR_ENGINE_DIFF_RATIO: if (ar_engine) { ar_engine->m_diff_ratio = val; } return; + case ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY: return; + + // Engoption + case ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA: if (ar_engine) { ar_engine->m_engine_inertia = val; } return; + case ACTORSIMATTR_ENGOPTION_ENGINE_TYPE: if (ar_engine) { ar_engine->m_engine_type = (char)val; } return; + case ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE: if (ar_engine) { ar_engine->m_clutch_force = val; } return; + case ACTORSIMATTR_ENGOPTION_SHIFT_TIME: if (ar_engine) { ar_engine->m_shift_time = val; } return; + case ACTORSIMATTR_ENGOPTION_CLUTCH_TIME: if (ar_engine) { ar_engine->m_clutch_time = val; } return; + case ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME: if (ar_engine) { ar_engine->m_post_shift_time = val; } return; + case ACTORSIMATTR_ENGOPTION_STALL_RPM: if (ar_engine) { ar_engine->m_engine_stall_rpm = val; } return; + case ACTORSIMATTR_ENGOPTION_IDLE_RPM: if (ar_engine) { ar_engine->m_engine_idle_rpm = val; } return; + case ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE: if (ar_engine) { ar_engine->m_max_idle_mixture = val; } return; + case ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE: if (ar_engine) { ar_engine->m_min_idle_mixture = val; } return; + case ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE: if (ar_engine) { ar_engine->m_braking_torque = val; } return; + + // Engturbo2 (actually 'engturbo' with type=2) + case ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_inertia_factor = val; } return; + case ACTORSIMATTR_ENGTURBO2_NUM_TURBOS: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_num_turbos = val; } return; + case ACTORSIMATTR_ENGTURBO2_MAX_RPM: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_max_turbo_rpm = val; } return; + case ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_engine_rpm_operation = val; } return; + case ACTORSIMATTR_ENGTURBO2_BOV_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_has_bov = (bool)val; } return; + case ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_min_bov_psi = val; } return; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_has_wastegate = (bool)val; } return; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_min_wastegate_psi = val; } return; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_wg_threshold_n = val; } return; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_wg_threshold_p = val; } return; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_turbo_has_antilag = (bool)val; } return; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_antilag_rand_chance = val; } return; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_antilag_min_rpm = val; } return; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER: if (ar_engine && ar_engine->m_turbo_ver == 2) { ar_engine->m_antilag_power_factor = val; } return; + default: return; } } @@ -4760,9 +4793,47 @@ float Actor::getSimAttribute(ActorSimAttr attr) // PLEASE maintain the same order as in `enum ActorSimAttr` switch (attr) { + // TractionControl case ACTORSIMATTR_TC_RATIO: return tc_ratio; case ACTORSIMATTR_TC_PULSE_TIME: return tc_pulse_time; case ACTORSIMATTR_TC_WHEELSLIP_CONSTANT: return tc_wheelslip_constant; + + // Engine + case ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM: if (ar_engine) { return ar_engine->m_engine_shiftup_rpm; } return 0.f; + case ACTORSIMATTR_ENGINE_SHIFTUP_RPM: if (ar_engine) { return ar_engine->m_engine_max_rpm; } return 0.f; + case ACTORSIMATTR_ENGINE_TORQUE: if (ar_engine) { return ar_engine->m_engine_torque; } return 0.f; + case ACTORSIMATTR_ENGINE_DIFF_RATIO: if (ar_engine) { return ar_engine->m_diff_ratio; } return 0.f; + case ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY: return 0.f; + + // Engoption + case ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA: if (ar_engine) { return ar_engine->m_engine_inertia; } return 0.f; + case ACTORSIMATTR_ENGOPTION_ENGINE_TYPE: if (ar_engine) { return (float)ar_engine->m_engine_type; } return 0.f; + case ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE: if (ar_engine) { return ar_engine->m_clutch_force; } return 0.f; + case ACTORSIMATTR_ENGOPTION_SHIFT_TIME: if (ar_engine) { return ar_engine->m_shift_time; } return 0.f; + case ACTORSIMATTR_ENGOPTION_CLUTCH_TIME: if (ar_engine) { return ar_engine->m_clutch_time; } return 0.f; + case ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME: if (ar_engine) { return ar_engine->m_post_shift_time; } return 0.f; + case ACTORSIMATTR_ENGOPTION_STALL_RPM: if (ar_engine) { return ar_engine->m_engine_stall_rpm; } return 0.f; + case ACTORSIMATTR_ENGOPTION_IDLE_RPM: if (ar_engine) { return ar_engine->m_engine_idle_rpm; } return 0.f; + case ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE: if (ar_engine) { return ar_engine->m_max_idle_mixture; } return 0.f; + case ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE: if (ar_engine) { return ar_engine->m_min_idle_mixture; } return 0.f; + case ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE: if (ar_engine) { return ar_engine->m_braking_torque; } return 0.f; + + // Engturbo2 (actually 'engturbo' with type=2) + case ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_turbo_inertia_factor; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_NUM_TURBOS: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_num_turbos; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_MAX_RPM: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_max_turbo_rpm; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_turbo_engine_rpm_operation; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_BOV_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { return (float)ar_engine->m_turbo_has_bov; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_min_bov_psi; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { return (float)ar_engine->m_turbo_has_wastegate; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_min_wastegate_psi; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_turbo_wg_threshold_n; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_turbo_wg_threshold_p; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED: if (ar_engine && ar_engine->m_turbo_ver == 2) { return (float)ar_engine->m_turbo_has_antilag; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_antilag_rand_chance; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_antilag_min_rpm; } return 0.f; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER: if (ar_engine && ar_engine->m_turbo_ver == 2) { return ar_engine->m_antilag_power_factor; } return 0.f; + default: return 0.f; } } diff --git a/source/main/physics/Actor.h b/source/main/physics/Actor.h index 051622b597..e29d7edb0a 100644 --- a/source/main/physics/Actor.h +++ b/source/main/physics/Actor.h @@ -24,6 +24,7 @@ #include "Application.h" #include "CmdKeyInertia.h" #include "Differentials.h" +#include "Engine.h" #include "GfxActor.h" #include "PerVehicleCameraContext.h" #include "RigDef_Prerequisites.h" @@ -222,6 +223,7 @@ class Actor : public RefCountingObject // not exported to scripting: Replay* getReplay(); TyrePressure& getTyrePressure() { return m_tyre_pressure; } + EnginePtr getEngine() { return ar_engine; } //! @} /// @name Organizational @@ -371,7 +373,7 @@ class Actor : public RefCountingObject ActorInstanceID_t ar_instance_id = ACTORINSTANCEID_INVALID; //!< Static attr; session-unique ID unsigned int ar_vector_index = 0; //!< Sim attr; actor element index in std::vector ActorType ar_driveable = NOT_DRIVEABLE; //!< Sim attr; marks vehicle type and features - EngineSim* ar_engine = nullptr; + EnginePtr ar_engine; NodeNum_t ar_cinecam_node[MAX_CAMERAS] = {NODENUM_INVALID}; //!< Sim attr; Cine-camera node indexes int ar_num_cinecams = 0; //!< Sim attr; Autopilot* ar_autopilot = nullptr; diff --git a/source/main/physics/ActorForcesEuler.cpp b/source/main/physics/ActorForcesEuler.cpp index 3aadf60cce..1d4a36c383 100644 --- a/source/main/physics/ActorForcesEuler.cpp +++ b/source/main/physics/ActorForcesEuler.cpp @@ -30,7 +30,7 @@ #include "Collisions.h" #include "Console.h" #include "Differentials.h" -#include "EngineSim.h" +#include "Engine.h" #include "FlexAirfoil.h" #include "GameContext.h" #include "Replay.h" @@ -164,7 +164,7 @@ void Actor::CalcDifferentials() { if (ar_engine && m_num_proped_wheels > 0) { - float torque = ar_engine->GetTorque() / m_num_proped_wheels; + float torque = ar_engine->getTorque() / m_num_proped_wheels; if (m_has_axles_section) { torque *= 2.0f; // Required to stay backwards compatible @@ -458,7 +458,7 @@ void Actor::CalcWheels(bool doUpdate, int num_steps) if (ar_engine) { - ar_engine->SetWheelSpin(ar_wheel_spin * RAD_PER_SEC_TO_RPM); // Update the driveshaft speed + ar_engine->setWheelSpin(ar_wheel_spin * RAD_PER_SEC_TO_RPM); // Update the driveshaft speed } if (doUpdate) @@ -744,14 +744,14 @@ void Actor::CalcCommands(bool doUpdate) // hydraulics ready? if (ar_engine) - ar_engine_hydraulics_ready = ar_engine->GetEngineRpm() > ar_engine->getIdleRPM() * 0.95f; + ar_engine_hydraulics_ready = ar_engine->getRPM() > ar_engine->getIdleRPM() * 0.95f; else ar_engine_hydraulics_ready = true; // crankfactor float crankfactor = 1.0f; if (ar_engine) - crankfactor = ar_engine->GetCrankFactor(); + crankfactor = ar_engine->getCrankFactor(); // speed up machines if (ar_driveable == MACHINE) @@ -985,8 +985,8 @@ void Actor::CalcCommands(bool doUpdate) if (ar_engine) { - ar_engine->SetHydroPumpWork(work); - ar_engine->SetEnginePriming(requested); + ar_engine->setHydroPump(work); + ar_engine->setPrime(requested); } if (doUpdate && this == App::GetGameContext()->GetPlayerActor().GetRef()) @@ -1084,7 +1084,7 @@ void Actor::CalcTruckEngine(bool doUpdate) { if (ar_engine) { - ar_engine->UpdateEngineSim(PHYSICS_DT, doUpdate); + ar_engine->UpdateEngine(PHYSICS_DT, doUpdate); } } @@ -1618,7 +1618,7 @@ void Actor::CalcNodes() // engine stall if (i == ar_cinecam_node[0] && ar_engine) { - ar_engine->StopEngine(); + ar_engine->stopEngine(); } } ar_nodes[i].nd_under_water = is_under_water; diff --git a/source/main/physics/ActorManager.cpp b/source/main/physics/ActorManager.cpp index c9b6127c06..f45804bda2 100644 --- a/source/main/physics/ActorManager.cpp +++ b/source/main/physics/ActorManager.cpp @@ -33,7 +33,7 @@ #include "Collisions.h" #include "DashBoardManager.h" #include "DynamicCollisions.h" -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "GfxScene.h" #include "GUIManager.h" @@ -268,9 +268,9 @@ ActorPtr ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr if (actor->ar_engine) { if (!actor->m_preloaded_with_terrain && App::sim_spawn_running->getBool()) - actor->ar_engine->StartEngine(); + actor->ar_engine->startEngine(); else - actor->ar_engine->OffStart(); + actor->ar_engine->offStart(); } // pressurize tires if (actor->getTyrePressure().IsEnabled()) @@ -303,7 +303,7 @@ ActorPtr ActorManager::CreateNewActor(ActorSpawnRequest rq, RigDef::DocumentPtr actor->ar_state = ActorState::NETWORKED_OK; if (actor->ar_engine) { - actor->ar_engine->StartEngine(); + actor->ar_engine->startEngine(); } } @@ -1067,7 +1067,7 @@ void ActorManager::UpdateActors(ActorPtr player_actor) } if (actor->ar_state == ActorState::LOCAL_SLEEPING) { - actor->ar_engine->UpdateEngineSim(dt, 1); + actor->ar_engine->UpdateEngine(dt, 1); } actor->ar_engine->UpdateEngineAudio(); } @@ -1442,25 +1442,25 @@ void ActorManager::UpdateTruckFeatures(ActorPtr vehicle, float dt) return; #endif // USE_ANGELSCRIPT - EngineSim* engine = vehicle->ar_engine; + EnginePtr engine = vehicle->ar_engine; if (engine && engine->hasContact() && - engine->GetAutoShiftMode() == SimGearboxMode::AUTO && - engine->getAutoShift() != EngineSim::NEUTRAL) + engine->getAutoMode() == SimGearboxMode::AUTO && + engine->getAutoShift() != Engine::NEUTRAL) { Ogre::Vector3 dirDiff = vehicle->getDirection(); Ogre::Degree pitchAngle = Ogre::Radian(asin(dirDiff.dotProduct(Ogre::Vector3::UNIT_Y))); if (std::abs(pitchAngle.valueDegrees()) > 2.0f) { - if (engine->getAutoShift() > EngineSim::NEUTRAL && vehicle->ar_avg_wheel_speed < +0.02f && pitchAngle.valueDegrees() > 0.0f || - engine->getAutoShift() < EngineSim::NEUTRAL && vehicle->ar_avg_wheel_speed > -0.02f && pitchAngle.valueDegrees() < 0.0f) + if (engine->getAutoShift() > Engine::NEUTRAL && vehicle->ar_avg_wheel_speed < +0.02f && pitchAngle.valueDegrees() > 0.0f || + engine->getAutoShift() < Engine::NEUTRAL && vehicle->ar_avg_wheel_speed > -0.02f && pitchAngle.valueDegrees() < 0.0f) { // anti roll back in SimGearboxMode::AUTO (DRIVE, TWO, ONE) mode // anti roll forth in SimGearboxMode::AUTO (REAR) mode float g = std::abs(App::GetGameContext()->GetTerrain()->getGravity()); float downhill_force = std::abs(sin(pitchAngle.valueRadians()) * vehicle->getTotalMass()) * g; - float engine_force = std::abs(engine->GetTorque()) / vehicle->getAvgPropedWheelRadius(); + float engine_force = std::abs(engine->getTorque()) / vehicle->getAvgPropedWheelRadius(); float ratio = std::max(0.0f, 1.0f - (engine_force / downhill_force)); if (vehicle->ar_avg_wheel_speed * pitchAngle.valueDegrees() > 0.0f) { @@ -1469,7 +1469,7 @@ void ActorManager::UpdateTruckFeatures(ActorPtr vehicle, float dt) vehicle->ar_brake = sqrt(ratio); } } - else if (vehicle->ar_brake == 0.0f && !vehicle->ar_parking_brake && engine->GetTorque() == 0.0f) + else if (vehicle->ar_brake == 0.0f && !vehicle->ar_parking_brake && engine->getTorque() == 0.0f) { float ratio = std::max(0.0f, 0.2f - std::abs(vehicle->ar_avg_wheel_speed)) / 0.2f; vehicle->ar_brake = ratio; @@ -1483,15 +1483,15 @@ void ActorManager::UpdateTruckFeatures(ActorPtr vehicle, float dt) if (vehicle->sl_enabled) { // check speed limit - if (engine && engine->GetGear() != 0) + if (engine && engine->getGear() != 0) { float accl = (vehicle->sl_speed_limit - std::abs(vehicle->ar_wheel_speed / 1.02f)) * 2.0f; - engine->SetAcceleration(Ogre::Math::Clamp(accl, 0.0f, engine->GetAcceleration())); + engine->setAcc(Ogre::Math::Clamp(accl, 0.0f, engine->getAcc())); } } BITMASK_SET(vehicle->m_lightmask, RoRnet::LIGHTMASK_BRAKES, (vehicle->ar_brake > 0.01f && !vehicle->ar_parking_brake)); - BITMASK_SET(vehicle->m_lightmask, RoRnet::LIGHTMASK_REVERSE, (vehicle->ar_engine && vehicle->ar_engine->GetGear() < 0)); + BITMASK_SET(vehicle->m_lightmask, RoRnet::LIGHTMASK_REVERSE, (vehicle->ar_engine && vehicle->ar_engine->getGear() < 0)); } void ActorManager::CalcFreeForces() diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index 631e23f54d..4cd0d1a4ad 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -45,7 +45,7 @@ #include "Collisions.h" #include "DashBoardManager.h" #include "Differentials.h" -#include "EngineSim.h" +#include "Engine.h" #include "FlexAirfoil.h" #include "FlexBody.h" #include "FlexMesh.h" @@ -421,7 +421,7 @@ void ActorSpawner::FinalizeRig() } //Gearbox - m_actor->ar_engine->SetAutoMode(App::sim_gearbox_mode->getEnum()); + m_actor->ar_engine->setAutoMode(App::sim_gearbox_mode->getEnum()); } // Sanitize trigger_cmdshort and trigger_cmdlong @@ -5446,31 +5446,23 @@ void ActorSpawner::ProcessEngoption(RigDef::Engoption & def) void ActorSpawner::ProcessEngine(RigDef::Engine & def) { - /* Process it */ + /* This is a land vehicle */ m_actor->ar_driveable = TRUCK; - /* Process gear list to EngineSim-compatible format */ - /* TODO: Move this to EngineSim::EngineSim() */ - std::vector gears_compat; - gears_compat.reserve(2 + def.gear_ratios.size()); - gears_compat.push_back(def.reverse_gear_ratio); - gears_compat.push_back(def.neutral_gear_ratio); - std::vector::iterator itor = def.gear_ratios.begin(); - for (; itor < def.gear_ratios.end(); itor++) - { - gears_compat.push_back(*itor); - } - - m_actor->ar_engine = new EngineSim( + /* Process it */ + m_actor->ar_engine = new Engine( def.shift_down_rpm, def.shift_up_rpm, def.torque, - gears_compat, + def.reverse_gear_ratio, + def.neutral_gear_ratio, + def.gear_ratios, def.global_gear_ratio, m_actor ); - m_actor->ar_engine->SetAutoMode(App::sim_gearbox_mode->getEnum()); + /* Apply game configuration */ + m_actor->ar_engine->setAutoMode(App::sim_gearbox_mode->getEnum()); }; void ActorSpawner::ProcessHelp(RigDef::Help & def) @@ -6339,7 +6331,7 @@ void ActorSpawner::SetupDefaultSoundSources(ActorPtr const& vehicle) } if (vehicle->ar_engine->m_engine_type == 'c') AddSoundSourceInstance(vehicle, "tracks/default_car", ar_exhaust_pos_node); - if (vehicle->ar_engine->HasTurbo()) + if (vehicle->ar_engine->hasTurbo()) { if (vehicle->ar_engine->m_turbo_inertia_factor >= 3) AddSoundSourceInstance(vehicle, "tracks/default_turbo_big", ar_exhaust_pos_node); @@ -6852,7 +6844,7 @@ void ActorSpawner::FinalizeGfxSetup() { if (App::gfx_speedo_imperial->getBool()) { - if (m_actor->ar_engine->getMaxRPM() > 3500) + if (m_actor->ar_engine->getShiftUpRPM() > 3500) { m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_mph.layout", false); //7000 rpm tachometer thanks to Klink m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_mph.layout", true); @@ -6865,7 +6857,7 @@ void ActorSpawner::FinalizeGfxSetup() } else { - if (m_actor->ar_engine->getMaxRPM() > 3500) + if (m_actor->ar_engine->getShiftUpRPM() > 3500) { m_actor->ar_dashboard->loadDashBoard("default_dashboard7000.layout", false); //7000 rpm tachometer thanks to Klink m_actor->ar_dashboard->loadDashBoard("default_dashboard7000.layout", true); @@ -6881,7 +6873,7 @@ void ActorSpawner::FinalizeGfxSetup() { if (App::gfx_speedo_imperial->getBool()) { - if (m_actor->ar_engine->getMaxRPM() > 3500) + if (m_actor->ar_engine->getShiftUpRPM() > 3500) { m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_analog_mph.layout", false); //7000 rpm tachometer thanks to Klink m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_analog_mph.layout", true); @@ -6894,7 +6886,7 @@ void ActorSpawner::FinalizeGfxSetup() } else { - if (m_actor->ar_engine->getMaxRPM() > 3500) + if (m_actor->ar_engine->getShiftUpRPM() > 3500) { m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_analog.layout", false); //7000 rpm tachometer thanks to Klink m_actor->ar_dashboard->loadDashBoard("default_dashboard7000_analog.layout", true); diff --git a/source/main/physics/Savegame.cpp b/source/main/physics/Savegame.cpp index 7445a049ea..fc6de9f49a 100644 --- a/source/main/physics/Savegame.cpp +++ b/source/main/physics/Savegame.cpp @@ -28,7 +28,7 @@ #include "CacheSystem.h" #include "ContentManager.h" #include "Console.h" -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "GUIManager.h" #include "GUI_MessageBox.h" @@ -523,9 +523,9 @@ bool ActorManager::SaveScene(Ogre::String filename) // Engine, anti-lock brake, traction control if (actor->ar_engine) { - j_entry.AddMember("engine_gear", actor->ar_engine->GetGear(), j_doc.GetAllocator()); - j_entry.AddMember("engine_rpm", actor->ar_engine->GetEngineRpm(), j_doc.GetAllocator()); - j_entry.AddMember("engine_auto_mode", actor->ar_engine->GetAutoMode(), j_doc.GetAllocator()); + j_entry.AddMember("engine_gear", actor->ar_engine->getGear(), j_doc.GetAllocator()); + j_entry.AddMember("engine_rpm", actor->ar_engine->getRPM(), j_doc.GetAllocator()); + j_entry.AddMember("engine_auto_mode", static_cast(actor->ar_engine->getAutoMode()), j_doc.GetAllocator()); j_entry.AddMember("engine_auto_select", actor->ar_engine->getAutoShift(), j_doc.GetAllocator()); j_entry.AddMember("engine_is_running", actor->ar_engine->isRunning(), j_doc.GetAllocator()); j_entry.AddMember("engine_has_contact", actor->ar_engine->hasContact(), j_doc.GetAllocator()); @@ -810,12 +810,12 @@ void ActorManager::RestoreSavedState(ActorPtr actor, rapidjson::Value const& j_e if (running != actor->ar_engine->isRunning()) { if (running) - actor->ar_engine->StartEngine(); + actor->ar_engine->startEngine(); else - actor->ar_engine->StopEngine(); + actor->ar_engine->stopEngine(); } - actor->ar_engine->PushNetworkState(rpm, 0.0f, 0.0f, gear, running, contact, automode, autoselect); - actor->ar_engine->SetWheelSpin(j_entry["wheel_spin"].GetFloat() * RAD_PER_SEC_TO_RPM); + actor->ar_engine->pushNetworkState(rpm, 0.0f, 0.0f, gear, running, contact, automode, autoselect); + actor->ar_engine->setWheelSpin(j_entry["wheel_spin"].GetFloat() * RAD_PER_SEC_TO_RPM); actor->alb_mode = j_entry["alb_mode"].GetBool(); actor->tc_mode = j_entry["tc_mode"].GetBool(); actor->cc_mode = j_entry["cc_mode"].GetBool(); diff --git a/source/main/physics/SimData.cpp b/source/main/physics/SimData.cpp index 1a577b7281..cfe253c26c 100644 --- a/source/main/physics/SimData.cpp +++ b/source/main/physics/SimData.cpp @@ -114,6 +114,43 @@ const char* RoR::ActorSimAttrToString(ActorSimAttr attr) case ACTORSIMATTR_TC_RATIO: return "TC_RATIO"; case ACTORSIMATTR_TC_PULSE_TIME: return "TC_PULSE_TIME"; case ACTORSIMATTR_TC_WHEELSLIP_CONSTANT: return "TC_WHEELSLIP_CONSTANT"; - default: ""; + + // Engine + case ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM: return "ENGINE_SHIFTDOWN_RPM"; + case ACTORSIMATTR_ENGINE_SHIFTUP_RPM: return "ENGINE_SHIFTUP_RPM"; + case ACTORSIMATTR_ENGINE_TORQUE: return "ENGINE_TORQUE"; + case ACTORSIMATTR_ENGINE_DIFF_RATIO: return "ENGINE_DIFF_RATIO"; + case ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY: return "ENGINE_GEAR_RATIOS_ARRAY"; + + // Engoption + case ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA: return "ENGOPTION_ENGINE_INERTIA"; + case ACTORSIMATTR_ENGOPTION_ENGINE_TYPE: return "ENGOPTION_ENGINE_TYPE"; + case ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE: return "ENGOPTION_CLUTCH_FORCE"; + case ACTORSIMATTR_ENGOPTION_SHIFT_TIME: return "ENGOPTION_SHIFT_TIME"; + case ACTORSIMATTR_ENGOPTION_CLUTCH_TIME: return "ENGOPTION_CLUTCH_TIME"; + case ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME: return "ENGOPTION_POST_SHIFT_TIME"; + case ACTORSIMATTR_ENGOPTION_STALL_RPM: return "ENGOPTION_STALL_RPM"; + case ACTORSIMATTR_ENGOPTION_IDLE_RPM: return "ENGOPTION_IDLE_RPM"; + case ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE: return "ENGOPTION_MAX_IDLE_MIXTURE"; + case ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE: return "ENGOPTION_MIN_IDLE_MIXTURE"; + case ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE: return "ENGOPTION_BRAKING_TORQUE"; + + // Engturbo2 (actually 'engturbo' with type=2) + case ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR: return "ENGTURBO2_INERTIA_FACTOR"; + case ACTORSIMATTR_ENGTURBO2_NUM_TURBOS: return "ENGTURBO2_NUM_TURBOS"; + case ACTORSIMATTR_ENGTURBO2_MAX_RPM: return "ENGTURBO2_MAX_RPM"; + case ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP: return "ENGTURBO2_ENGINE_RPM_OP"; + case ACTORSIMATTR_ENGTURBO2_BOV_ENABLED: return "ENGTURBO2_BOV_ENABLED"; + case ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI: return "ENGTURBO2_BOV_MIN_PSI"; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED: return "ENGTURBO2_WASTEGATE_ENABLED"; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI: return "ENGTURBO2_WASTEGATE_MAX_PSI"; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N: return "ENGTURBO2_WASTEGATE_THRESHOLD_N"; + case ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P: return "ENGTURBO2_WASTEGATE_THRESHOLD_P"; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED: return "ENGTURBO2_ANTILAG_ENABLED"; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE: return "ENGTURBO2_ANTILAG_CHANCE"; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM: return "ENGTURBO2_ANTILAG_MIN_RPM"; + case ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER: return "ENGTURBO2_ANTILAG_POWER"; + + default: return ""; } } diff --git a/source/main/physics/SimData.h b/source/main/physics/SimData.h index e446c78609..5634891a4e 100644 --- a/source/main/physics/SimData.h +++ b/source/main/physics/SimData.h @@ -914,7 +914,7 @@ struct ActorLinkingRequest }; /// Parameter to `Actor::setSimAttribute()` and `Actor::getSimAttribute()`; allows advanced users to tweak physics internals via script. -/// Each value represents a variable, either directly in `Actor` or a subsystem, i.e. `EngineSim`. +/// Each value represents a variable, either directly in `Actor` or a subsystem, i.e. `Engine`. /// PAY ATTENTION to the 'safe value' limits below - those may not be checked when setting attribute values! enum ActorSimAttr { @@ -923,7 +923,44 @@ enum ActorSimAttr // TractionControl ACTORSIMATTR_TC_RATIO, //!< Regulating force, safe values: <1 - 20> ACTORSIMATTR_TC_PULSE_TIME, //!< Pulse duration in seconds, safe values <0.00005 - 1> - ACTORSIMATTR_TC_WHEELSLIP_CONSTANT //!< Minimum wheel slip threshold, safe value = 0.25 + ACTORSIMATTR_TC_WHEELSLIP_CONSTANT, //!< Minimum wheel slip threshold, safe value = 0.25 + + // Engine + ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM, //!< Automatic transmission - Param #1 of 'engine' + ACTORSIMATTR_ENGINE_SHIFTUP_RPM, //!< Automatic transmission - Param #2 of 'engine' + ACTORSIMATTR_ENGINE_TORQUE, //!< Engine torque in newton-meters (N/m) - Param #3 of 'engine' + ACTORSIMATTR_ENGINE_DIFF_RATIO, //!< Differential ratio (aka global gear ratio) - Param #4 of 'engine' + ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY, //!< Gearbox - Format: " []..."; Param #5 and onwards of 'engine'. + + // Engoption + ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA, //!< - Param #1 of 'engoption' + ACTORSIMATTR_ENGOPTION_ENGINE_TYPE, //!< - Param #2 of 'engoption' + ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE, //!< - Param #3 of 'engoption' + ACTORSIMATTR_ENGOPTION_SHIFT_TIME, //!< - Param #4 of 'engoption' + ACTORSIMATTR_ENGOPTION_CLUTCH_TIME, //!< - Param #5 of 'engoption' + ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME, //!< Time (in seconds) until full torque is transferred - Param #6 of 'engoption' + ACTORSIMATTR_ENGOPTION_STALL_RPM, //!< RPM where engine stalls - Param #7 of 'engoption' + ACTORSIMATTR_ENGOPTION_IDLE_RPM, //!< Target idle RPM - Param #8 of 'engoption' + ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE, //!< Max throttle to maintain idle RPM - Param #9 of 'engoption' + ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE, //!< Min throttle to maintain idle RPM - Param #10 of 'engoption' + ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE, //!< How much engine brakes on zero throttle - Param #11 of 'engoption' + + // Engturbo2 (actually 'engturbo' with Param #1 [type] set to "2" - the recommended variant) + ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR, //!< Time to spool up - Param #2 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_NUM_TURBOS, //!< Number of turbos - Param #3 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_MAX_RPM, //!< MaxPSI * 10000 ~ calculated from Param #4 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP, //!< Engine RPM threshold for turbo to operate - Param #5 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_BOV_ENABLED, //!< Blow-off valve - Param #6 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI, //!< Blow-off valve PSI threshold - Param #7 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED, //!< - Param #8 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI, //!< - Param #9 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N, //!< 1 - WgThreshold ~ calculated from Param #10 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P, //!< 1 + WgThreshold ~ calculated from Param #10 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED, //!< - Param #11 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE, //!< - Param #12 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM, //!< - Param #13 of 'engturbo2' + ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER, //!< - Param #14 of 'engturbo2' + }; const char* ActorSimAttrToString(ActorSimAttr attr); diff --git a/source/main/scripting/GameScript.cpp b/source/main/scripting/GameScript.cpp index 53d682b5b9..529dde5808 100644 --- a/source/main/scripting/GameScript.cpp +++ b/source/main/scripting/GameScript.cpp @@ -44,7 +44,7 @@ #include "Collisions.h" #include "Console.h" #include "CurlHelpers.h" -#include "EngineSim.h" +#include "Engine.h" #include "GameContext.h" #include "GfxScene.h" #include "GUIManager.h" @@ -965,9 +965,9 @@ void GameScript::boostCurrentTruck(float factor) ActorPtr actor = App::GetGameContext()->GetPlayerActor(); if (actor && actor->ar_engine) { - float rpm = actor->ar_engine->GetEngineRpm(); + float rpm = actor->ar_engine->getRPM(); rpm += 2000.0f * factor; - actor->ar_engine->SetEngineRpm(rpm); + actor->ar_engine->setRPM(rpm); } } diff --git a/source/main/scripting/ScriptEngine.cpp b/source/main/scripting/ScriptEngine.cpp index 8a298a68b7..1605f9e544 100644 --- a/source/main/scripting/ScriptEngine.cpp +++ b/source/main/scripting/ScriptEngine.cpp @@ -172,6 +172,7 @@ void ScriptEngine::init() RegisterImGuiBindings(engine); // ImGUi:: RegisterVehicleAi(engine); // VehicleAIClass, aiEvents, AiValues RegisterConsole(engine); // ConsoleClass, CVarClass, CVarFlags + RegisterEngine(engine); // EngineClass, enum autoswitch, enum RegisterActor(engine); // BeamClass RegisterProceduralRoad(engine);// procedural_point, ProceduralRoadClass, ProceduralObjectClass, ProceduralManagerClass RegisterTerrain(engine); // TerrainClass diff --git a/source/main/scripting/bindings/ActorAngelscript.cpp b/source/main/scripting/bindings/ActorAngelscript.cpp index da247a2950..cf2c8725d8 100644 --- a/source/main/scripting/bindings/ActorAngelscript.cpp +++ b/source/main/scripting/bindings/ActorAngelscript.cpp @@ -82,9 +82,43 @@ void RoR::RegisterActor(asIScriptEngine *engine) // enum ActorSimAttr result = engine->RegisterEnum("ActorSimAttr"); ROR_ASSERT(result >= 0); result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_NONE", (int)ACTORSIMATTR_NONE); ROR_ASSERT(result >= 0); + // ... TractionControl result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_TC_RATIO", (int)ACTORSIMATTR_TC_RATIO); ROR_ASSERT(result >= 0); result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_TC_PULSE_TIME", (int)ACTORSIMATTR_TC_PULSE_TIME); ROR_ASSERT(result >= 0); result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_TC_WHEELSLIP_CONSTANT", (int)ACTORSIMATTR_TC_WHEELSLIP_CONSTANT); ROR_ASSERT(result >= 0); + // ... Engine + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM", (int)ACTORSIMATTR_ENGINE_SHIFTDOWN_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGINE_SHIFTUP_RPM", (int)ACTORSIMATTR_ENGINE_SHIFTUP_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGINE_TORQUE", (int)ACTORSIMATTR_ENGINE_TORQUE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGINE_DIFF_RATIO", (int)ACTORSIMATTR_ENGINE_DIFF_RATIO); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY", (int)ACTORSIMATTR_ENGINE_GEAR_RATIOS_ARRAY); ROR_ASSERT(result >= 0); + // ... Engoption + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA", (int)ACTORSIMATTR_ENGOPTION_ENGINE_INERTIA); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_ENGINE_TYPE", (int)ACTORSIMATTR_ENGOPTION_ENGINE_TYPE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE", (int)ACTORSIMATTR_ENGOPTION_CLUTCH_FORCE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_SHIFT_TIME", (int)ACTORSIMATTR_ENGOPTION_SHIFT_TIME); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_CLUTCH_TIME", (int)ACTORSIMATTR_ENGOPTION_CLUTCH_TIME); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME", (int)ACTORSIMATTR_ENGOPTION_POST_SHIFT_TIME); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_STALL_RPM", (int)ACTORSIMATTR_ENGOPTION_STALL_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_IDLE_RPM", (int)ACTORSIMATTR_ENGOPTION_IDLE_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE", (int)ACTORSIMATTR_ENGOPTION_MAX_IDLE_MIXTURE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE", (int)ACTORSIMATTR_ENGOPTION_MIN_IDLE_MIXTURE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE", (int)ACTORSIMATTR_ENGOPTION_BRAKING_TORQUE); ROR_ASSERT(result >= 0); + // ... Engturbo2 (actually'engturbo'withtype=2) + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR", (int)ACTORSIMATTR_ENGTURBO2_INERTIA_FACTOR); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_NUM_TURBOS", (int)ACTORSIMATTR_ENGTURBO2_NUM_TURBOS); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_MAX_RPM", (int)ACTORSIMATTR_ENGTURBO2_MAX_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP", (int)ACTORSIMATTR_ENGTURBO2_ENGINE_RPM_OP); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_BOV_ENABLED", (int)ACTORSIMATTR_ENGTURBO2_BOV_ENABLED); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI", (int)ACTORSIMATTR_ENGTURBO2_BOV_MIN_PSI); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED", (int)ACTORSIMATTR_ENGTURBO2_WASTEGATE_ENABLED); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI", (int)ACTORSIMATTR_ENGTURBO2_WASTEGATE_MAX_PSI); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N", (int)ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_N); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P", (int)ACTORSIMATTR_ENGTURBO2_WASTEGATE_THRESHOLD_P); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED", (int)ACTORSIMATTR_ENGTURBO2_ANTILAG_ENABLED); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE", (int)ACTORSIMATTR_ENGTURBO2_ANTILAG_CHANCE); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM", (int)ACTORSIMATTR_ENGTURBO2_ANTILAG_MIN_RPM); ROR_ASSERT(result >= 0); + result = engine->RegisterEnumValue("ActorSimAttr", "ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER", (int)ACTORSIMATTR_ENGTURBO2_ANTILAG_POWER); ROR_ASSERT(result >= 0); // class Actor (historically Beam) Actor::RegisterRefCountingObject(engine, "BeamClass"); @@ -130,6 +164,7 @@ void RoR::RegisterActor(asIScriptEngine *engine) // - subsystems (PLEASE maintain the same order as 'Actor.h' and 'doc/angelscript/.../BeamClass.h') result = engine->RegisterObjectMethod("BeamClass", "VehicleAIClassPtr @getVehicleAI()", asMETHOD(Actor,getVehicleAI), asCALL_THISCALL); ROR_ASSERT(result>=0); + result = engine->RegisterObjectMethod("BeamClass", "EngineClassPtr @getEngine()", asMETHOD(Actor, getEngine), asCALL_THISCALL); ROR_ASSERT(result >= 0); result = engine->RegisterObjectMethod("BeamClass", "Ogre::MaterialPtr getManagedMaterialInstance(const string &in)", asMETHOD(Actor,getManagedMaterialInstance), asCALL_THISCALL); ROR_ASSERT(result>=0); result = engine->RegisterObjectMethod("BeamClass", "array@ getManagedMaterialNames()", asFUNCTIONPR([](Actor* self) -> CScriptArray*{ return RoR::VectorToScriptArray(self->getManagedMaterialNames(), "string"); }, (Actor*), CScriptArray*), asCALL_CDECL_OBJFIRST); ROR_ASSERT(result>=0); diff --git a/source/main/scripting/bindings/AngelScriptBindings.h b/source/main/scripting/bindings/AngelScriptBindings.h index 420e4030e8..9660f7a6ef 100644 --- a/source/main/scripting/bindings/AngelScriptBindings.h +++ b/source/main/scripting/bindings/AngelScriptBindings.h @@ -82,6 +82,10 @@ void RegisterSoundScript(AngelScript::asIScriptEngine* engine); /// defined in CacheSystemAngelscript.cpp void RegisterCacheSystem(AngelScript::asIScriptEngine* engine); +/// Register class Engine and related enums, defined in EngineAngelscript.cpp +void RegisterEngine(AngelScript::asIScriptEngine* engine); + + /// @} //addtogroup Scripting } // namespace RoR diff --git a/source/main/scripting/bindings/EngineAngelscript.cpp b/source/main/scripting/bindings/EngineAngelscript.cpp new file mode 100644 index 0000000000..796baaa717 --- /dev/null +++ b/source/main/scripting/bindings/EngineAngelscript.cpp @@ -0,0 +1,139 @@ +/* + This source file is part of Rigs of Rods + Copyright 2005-2012 Pierre-Michel Ricordel + Copyright 2007-2012 Thomas Fischer + Copyright 2013-2023 Petr Ohlidal + + For more information, see http://www.rigsofrods.org/ + + Rigs of Rods is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License version 3, as + published by the Free Software Foundation. + + Rigs of Rods is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Rigs of Rods. If not, see . +*/ + +/// @file + +#include "AngelScriptBindings.h" +#include "Engine.h" + +#include + +using namespace AngelScript; + +void RoR::RegisterEngine(asIScriptEngine* engine) +{ + int r; + + r = engine->RegisterEnum("autoswitch"); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_REAR", Engine::REAR); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_NEUTRAL", Engine::NEUTRAL); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_DRIVE", Engine::DRIVE); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_TWO", Engine::TWO); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_ONE", Engine::ONE); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("autoswitch", "AUTOSWITCH_MANUALMODE", Engine::MANUALMODE); ROR_ASSERT(r >= 0); + + r = engine->RegisterEnum("SimGearboxMode"); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("SimGearboxMode", "AUTO", static_cast(SimGearboxMode::AUTO)); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("SimGearboxMode", "SEMI_AUTO", static_cast(SimGearboxMode::SEMI_AUTO)); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("SimGearboxMode", "MANUAL", static_cast(SimGearboxMode::MANUAL)); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("SimGearboxMode", "MANUAL_STICK", static_cast(SimGearboxMode::MANUAL_STICK)); ROR_ASSERT(r >= 0); + r = engine->RegisterEnumValue("SimGearboxMode", "MANUAL_RANGES", static_cast(SimGearboxMode::MANUAL_RANGES)); ROR_ASSERT(r >= 0); + + // class Engine + Engine::RegisterRefCountingObject(engine, "EngineClass"); + EnginePtr::RegisterRefCountingObjectPtr(engine, "EngineClassPtr", "EngineClass"); + + // > Definition, Keyword 'engine' + r = engine->RegisterObjectMethod("EngineClass", "float getShiftDownRPM() const", asMETHOD(Engine, getShiftDownRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getShiftUpRPM() const", asMETHOD(Engine, getShiftUpRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getEngineTorque() const", asMETHOD(Engine, getEngineTorque), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getDiffRatio() const", asMETHOD(Engine, getDiffRatio), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getGearRatio(int) const", asMETHODPR(Engine, getGearRatio, (int), float), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getNumGears() const", asMETHOD(Engine, getNumGears), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getNumGearsRanges() const", asMETHOD(Engine, getNumGearsRanges), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // > Definition, Keyword 'engoption' + r = engine->RegisterObjectMethod("EngineClass", "float getEngineInertia() const", asMETHOD(Engine, getEngineInertia), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "uint8 getEngineType() const", asMETHOD(Engine, getEngineType), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool isElectric() const", asMETHOD(Engine, isElectric), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool hasAir() const", asMETHOD(Engine, hasAir), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool hasTurbo() const", asMETHOD(Engine, hasTurbo), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getClutchForce() const", asMETHOD(Engine, getClutchForce), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getShiftTime() const", asMETHOD(Engine, getShiftTime), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getClutchTime() const", asMETHOD(Engine, getClutchTime), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getPostShiftTime() const", asMETHOD(Engine, getPostShiftTime), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getStallRPM() const", asMETHOD(Engine, getStallRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getIdleRPM() const", asMETHOD(Engine, getIdleRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getMaxIdleMixture() const", asMETHOD(Engine, getMaxIdleMixture), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getMinIdleMixture() const", asMETHOD(Engine, getMinIdleMixture), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getBrakingTorque() const", asMETHOD(Engine, getBrakingTorque), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // > General state getters + r = engine->RegisterObjectMethod("EngineClass", "float getAcc()", asMETHOD(Engine, getAcc), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getClutch()", asMETHOD(Engine, getClutch), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getCrankFactor()", asMETHOD(Engine, getCrankFactor), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getRPM()", asMETHOD(Engine, getRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getSmoke()", asMETHOD(Engine, getSmoke), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getTorque()", asMETHOD(Engine, getTorque), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getTurboPSI()", asMETHOD(Engine, getTurboPSI), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "SimGearboxMode getAutoMode()", asMETHOD(Engine, getAutoMode), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getGear()", asMETHOD(Engine, getGear), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getGearRange()", asMETHOD(Engine, getGearRange), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool isRunning()", asMETHOD(Engine, isRunning), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool hasContact()", asMETHOD(Engine, hasContact), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getCurEngineTorque()", asMETHOD(Engine, getCurEngineTorque), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getInputShaftRPM()", asMETHOD(Engine, getInputShaftRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getDriveRatio()", asMETHOD(Engine, getDriveRatio), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getEnginePower()", asMETHODPR(Engine, getEnginePower, (), float), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getEnginePower(float)", asMETHODPR(Engine, getEnginePower, (float), float), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getTurboPower()", asMETHOD(Engine, getTurboPower), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getIdleMixture()", asMETHOD(Engine, getIdleMixture), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getPrimeMixture()", asMETHOD(Engine, getPrimeMixture), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "autoswitch getAutoShift()", asMETHOD(Engine, getAutoShift), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getAccToHoldRPM()", asMETHOD(Engine, getAccToHoldRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getWheelSpin()", asMETHOD(Engine, getWheelSpin), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // > shifting diagnostic + r = engine->RegisterObjectMethod("EngineClass", "float getPostShiftClock()", asMETHOD(Engine, getPostShiftClock), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getShiftClock()", asMETHOD(Engine, getShiftClock), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool isPostShifting()", asMETHOD(Engine, isPostShifting), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "bool isShifting()", asMETHOD(Engine, isShifting), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getShifTargetGear()", asMETHOD(Engine, getShifTargetGear), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "float getAutoShiftBehavior()", asMETHOD(Engine, getAutoShiftBehavior), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getUpshiftDelayCounter()", asMETHOD(Engine, getUpshiftDelayCounter), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "int getKickdownDelayCounter()", asMETHOD(Engine, getKickdownDelayCounter), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // > State setters + r = engine->RegisterObjectMethod("EngineClass", "void setAcc(float val)", asMETHOD(Engine, setAcc), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void autoSetAcc(float val)", asMETHOD(Engine, autoSetAcc), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setClutch(float clutch)", asMETHOD(Engine, setClutch), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setRPM(float rpm)", asMETHOD(Engine, setRPM), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setWheelSpin(float rpm)", asMETHOD(Engine, setWheelSpin), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setAutoMode(SimGearboxMode mode)", asMETHOD(Engine, setAutoMode), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setPrime(bool p)", asMETHOD(Engine, setPrime), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setHydroPump(float work)", asMETHOD(Engine, setHydroPump), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setManualClutch(float val)", asMETHOD(Engine, setManualClutch), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setTCaseRatio(float ratio)", asMETHOD(Engine, setTCaseRatio), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void toggleContact()", asMETHOD(Engine, toggleContact), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void offStart()", asMETHOD(Engine, offStart), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void startEngine()", asMETHOD(Engine, startEngine), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void stopEngine()", asMETHOD(Engine, stopEngine), asCALL_THISCALL); ROR_ASSERT(r >= 0); + + // > Shifting + r = engine->RegisterObjectMethod("EngineClass", "void toggleAutoMode()", asMETHOD(Engine, toggleAutoMode), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void autoShiftDown()", asMETHOD(Engine, autoShiftDown), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void autoShiftSet(autoswitch mode)", asMETHOD(Engine, autoShiftSet), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void autoShiftUp()", asMETHOD(Engine, autoShiftUp), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setGear(int v)", asMETHOD(Engine, setGear), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void setGearRange(int v)", asMETHOD(Engine, setGearRange), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void shift(int val)", asMETHOD(Engine, shift), asCALL_THISCALL); ROR_ASSERT(r >= 0); + r = engine->RegisterObjectMethod("EngineClass", "void shiftTo(int val)", asMETHOD(Engine, shiftTo), asCALL_THISCALL); ROR_ASSERT(r >= 0); +} diff --git a/source/main/utils/InputEngine.cpp b/source/main/utils/InputEngine.cpp index 3479a84c6f..bf4a5e47ba 100644 --- a/source/main/utils/InputEngine.cpp +++ b/source/main/utils/InputEngine.cpp @@ -172,6 +172,8 @@ InputEvent eventInfo[] = { {"TRUCK_AUTOSHIFT_DOWN", EV_TRUCK_AUTOSHIFT_DOWN, "Keyboard PGDOWN", _LC("InputEvent", "shift automatic transmission one gear down")}, {"TRUCK_AUTOSHIFT_UP", EV_TRUCK_AUTOSHIFT_UP, "Keyboard PGUP", _LC("InputEvent", "shift automatic transmission one gear up")}, {"TRUCK_MANUAL_CLUTCH", EV_TRUCK_MANUAL_CLUTCH, "Keyboard LSHIFT", _LC("InputEvent", "manual clutch (for manual transmission)")}, + {"TRUCK_MANUAL_CLUTCH_MODIFIER_25",EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25,"Keyboard ALT+LSHIFT", _LC("InputEvent", "manual clutch with 25 percent pedal input")}, + {"TRUCK_MANUAL_CLUTCH_MODIFIER_50",EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50,"Keyboard CTRL+LSHIFT", _LC("InputEvent", "manual clutch with 50 percent pedal input")}, {"TRUCK_SHIFT_DOWN", EV_TRUCK_SHIFT_DOWN, "Keyboard Z", _LC("InputEvent", "shift one gear down in manual transmission mode")}, {"TRUCK_SHIFT_NEUTRAL", EV_TRUCK_SHIFT_NEUTRAL, "Keyboard D", _LC("InputEvent", "shift to neutral gear in manual transmission mode")}, {"TRUCK_SHIFT_UP", EV_TRUCK_SHIFT_UP, "Keyboard A", _LC("InputEvent", "shift one gear up in manual transmission mode")}, diff --git a/source/main/utils/InputEngine.h b/source/main/utils/InputEngine.h index d704fd870b..d691c9c8cb 100644 --- a/source/main/utils/InputEngine.h +++ b/source/main/utils/InputEngine.h @@ -324,6 +324,8 @@ enum events EV_TRUCK_LIGHTTOGGLE09, //!< toggle custom light 9 EV_TRUCK_LIGHTTOGGLE10, //!< toggle custom light 10 EV_TRUCK_MANUAL_CLUTCH, //!< manual clutch (for manual transmission) + EV_TRUCK_MANUAL_CLUTCH_MODIFIER_25,//!< manual clutch with 25 percent pedal input + EV_TRUCK_MANUAL_CLUTCH_MODIFIER_50,//!< manual clutch with 50 percent pedal input EV_TRUCK_PARKING_BRAKE, //!< toggle parking brake EV_TRUCK_TRAILER_PARKING_BRAKE, //!< toggle trailer parking brake EV_TRUCK_RIGHT_MIRROR_LEFT,