Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @name Simulated_Engine
- @inputs [POD, Chassis, Engine, Flywheel, Slave, FuelTank]:wirelink
- @outputs [Engine_Active, Engine_RPM, Engine_Torque, Flywheel_PowerInertia, Engine_Ignition, Gearbox_Gear, Gearbox_Clutch, Turbo_Boost, Turbo_PSI, Fuel_Capacity, Fuel_Liters, Flywheel_RPM]:number
- @persist [C, E, S, T]:entity
- @persist [Engine_IdleRev, Engine_RevLimiter, Engine_Bore, Engine_Stroke, Engine_Cylinders, Engine_Airflow, Engine_Configuration, Engine_Displacement, Engine_PeakTorque, Engine_Redline, Engine_Mass, Engine_FlywheelMass, Engine_Idle]:number [Engine_TorqueTable]:array
- @persist [Fuel_Enabled, Fuel_Capacity, Fuel_Air_Ratio, Fuel_Density, Air_Density]:number
- @persist [Gearbox_FinalDrive, Gearbox_Delay, Gearbox_LockValue, Gearbox_ClutchSpeed]:number [Gearbox_Ratios]:array
- @persist [Turbo, Turbo_Exp, Turbo_Inertia, Turbo_FlowScale, Turbo_DragScale, Turbo_PSIMax, Turbo_AirPressure, Turbo_MaxFlow, Turbo_MaxRPM]:number
- @persist [Engine_SoundOn, Engine_SoundOff]:string
- @trigger none
- @persist [Gearbox_Ratio, Gearbox_Gear, Gearbox_Lock, Gearbox_Clutch]:number
- @persist [Throttle_Delay, Clutch_Delay]:number
- @persist [Fuel_Liters]:number
- @persist [Brake, Engine_IdleThrottle, Engine_Ignition, Engine_PowerCut, Engine_Volume, Flywheel_PowerInertia]:number
- @persist [Turbo_RPM]:number
- if (duped() | dupefinished()) {reset()} else {runOnTick(1)}
- if (first()) {
- Engine_Bore = 84
- Engine_Stroke = 89.6
- Engine_Cylinders = 6
- Engine_Airflow = 135.5
- Engine_Idle = 800
- Engine_IdleRev = 0.1
- Engine_RevLimiter = 1
- Engine_TorqueTable = array(0.6, 0.7, 0.8, 0.74, 0.5)
- Engine_FlywheelMass = 12
- Engine_Configuration = 0
- Engine_Configurations = table(
- 0 = "Inline-",
- 1 = "V"
- )
- Gearbox_Ratios = array(
- 4.11,
- 2.315,
- 1.542,
- 1.179,
- 1.000,
- 0.846
- )
- Gearbox_Ratios[-1, number] = -3.727
- Gearbox_FinalDrive = 3.154
- Gearbox_Delay = 150
- Gearbox_ClutchSpeed = 0.1
- Gearbox_LockValue = 0.05
- Fuel_Enabled = 1
- Fuel_Air_Ratio = 1 / 12.5
- Fuel_Density = 0.72 # 0.72 | 0.745 ( Petrol | Diesel )
- Air_Density = 0.0012
- Engine_Displacement = round((Engine_Cylinders * pi() * Engine_Bore ^ 2 * Engine_Stroke / 4000000), 1)
- Engine_PeakTorque = round((Engine_Stroke / Engine_Bore * Engine_Displacement * Engine_Airflow) * (Engine_Stroke / Engine_Bore), 2)
- Engine_PeakTorque *= 0.8
- #Engine_Redline = round((Engine_Bore / Engine_Stroke / Engine_Cylinders * Engine_Airflow * 2000 / 6), 0)
- #Engine_Redline *= (Engine_Bore / Engine_Stroke)
- #Engine_Redline -= Engine_Redline % 100
- Engine_Redline = 7500 # Override original value
- Engine_Mass = round((floor(Engine_Displacement * 45 + Engine_Cylinders * 4 + clamp(Engine_Configuration, 0, 1) * 10)), 0)
- Engine_Mass += Engine_FlywheelMass
- Engine_Mass += (Gearbox_Ratios:count() * 8.66)
- Turbo = 1
- Turbo_Exp = 1.95
- Turbo_Inertia = 0.025
- Turbo_FlowScale = 75
- Turbo_DragScale = 0.01
- Turbo_PSIMax = 30
- Turbo_AirPressure = 24.7
- Turbo_MaxFlow = Engine_Redline * ((Turbo_PSIMax + Turbo_AirPressure) / Turbo_AirPressure)
- Turbo_MaxRPM = 140000
- C = Chassis:entity()
- S = Slave:entity()
- S:setMass(5e4)
- S:propGravity(0)
- E = Engine:entity()
- E:setMass(Engine_Mass)
- #E:propInertia(maxVec(vec(Engine_Mass, Engine_Mass, 2), vec(40, 40, 2)))
- T = FuelTank:entity()
- Fuel_Capacity = T:boxSize():length()
- Fuel_Liters = Fuel_Capacity
- foreach (K, V:entity = Flywheel["Entities", array]) {
- V:setMass(Engine_Mass)
- V:propInertia(maxVec(vec(Engine_Mass, Engine_Mass, 2), vec(40, 40, 2)))
- V:propGravity(0)
- }
- setName(
- "Simulated Engine" + "\n"
- + Engine_Configurations[Engine_Configuration, string] + Engine_Cylinders + "\n"
- + "Displacement: " + Engine_Displacement + " L\n"
- + "Peak Torque: " + Engine_PeakTorque + " nm\n"
- + "Redline: " + Engine_Redline + "\n"
- + "Flywheel Mass: " + Engine_FlywheelMass * 0.1 + " kg"
- )
- Engine_SoundOn = "acf_extra/vehiclefx/engines/l4/escort_onmid.WAV"
- Engine_SoundOff = "acf_extra/vehiclefx/engines/l4/escort_onverylow.WAV"
- function void loadSounds() {
- E:soundPlay("On", 0, Engine_SoundOn:lower())
- E:soundPlay("Off", 0, Engine_SoundOff:lower())
- if (Turbo) {
- E:soundPlay("Turbo", 0, "acf_engines/turbine_small.wav")
- }
- }
- loadSounds()
- runOnLast(1)
- }
- POD_Active = POD:number("Active")
- if (changed(POD_Active) | POD_Active) {
- Key_W = POD:number("W")
- Key_S = POD:number("S")
- Key_M1 = POD:number("Mouse1")
- Key_M2 = POD:number("Mouse2")
- Key_F = POD:number("Light")
- Key_R = POD:number("R")
- Key_Sp = POD:number("Shift")
- Key_Sh = POD:number("Space")
- Key_Alt = POD:number("Alt")
- Key_Z = POD:number("Zoom")
- if (changed(Key_Z) && Key_Z) {
- Gearbox_Lock = !Gearbox_Lock
- }
- if (changed(Gearbox_Lock)) {
- foreach (K, V:entity = Flywheel["Entities", array]) {
- if (Gearbox_Lock) {
- Pair = Flywheel["Entities", array][(K + 1) % Flywheel["Entities", array]:count(), entity]
- V:advBallsocketTo(
- K,
- Pair,
- 0,
- 0,
- vec(),
- vec(),
- 0,
- 0,
- vec(-180),
- vec(180),
- vec(Gearbox_LockValue),
- 1,
- 0
- )
- } else {
- removeConstraint(K)
- }
- }
- }
- if (changed(Key_F)) {
- if (Engine_Ignition == 1 && Engine_Active == 0) {
- Engine_Ignition = 2
- }
- if (Engine_Ignition == 2 & !Key_F) {
- Engine_Ignition = 1
- }
- }
- if (changed(Key_F) & Key_F) {
- if (Engine_Ignition == 0) {
- Engine_Ignition = 1
- }
- if (Engine_Ignition == 1 && Engine_Active == 1) {
- Engine_Ignition = 0
- }
- }
- Engine_Ignition = min(Engine_Ignition, (Engine_Active ? 1 : 2))
- if (changed(Engine_Ignition)) {
- if (Engine_Ignition == 2) {
- E:soundPlay("Start", 0, "acf_extra/vehiclefx/starters/starter2.wav")
- soundVolume("Start", 0.5)
- } else {
- soundStop("Start")
- }
- }
- soundPitch("Start", max(Engine_RPM / Engine_Idle, 0.35) * 200)
- Gearbox_Gear += (changed(Key_M1) & Key_M1) - (changed(Key_M2) & Key_M2)
- Gearbox_Gear *= !(changed(Key_R) & Key_R)
- Gearbox_Gear = clamp(Gearbox_Gear, Gearbox_Ratios:minIndex(), Gearbox_Ratios:count())
- if (changed(Gearbox_Gear)) {
- if (Gearbox_Ratios[Gearbox_Gear, number]) {
- Gearbox_Ratio = Gearbox_Ratios[Gearbox_Gear, number] * Gearbox_FinalDrive
- }
- C:soundPlay("Gear_Change", 0, "physics/plaster/ceiling_tile_impact_hard3.wav")
- soundPitch("Gear_Change", 60)
- soundVolume("Gear_Change", 0.3)
- timer("Gear_Change", Gearbox_Delay)
- Throttle_Delay = 1
- Clutch_Delay = 1
- foreach (K, V:entity = Flywheel["Entities", array]) {
- local Mass = max(Engine_Mass * Gearbox_Ratio, Engine_Mass)
- V:setMass(Mass)
- V:propInertia(maxVec(vec(Mass, Mass, 2), vec(40, 40, 2)))
- }
- }
- Brake += (Key_S - Brake) * 0.025
- Brake *= Key_S
- }
- if (clk("Beep")) {
- soundStop("Beep")
- C:soundPlay("Beep", 1, "buttons/bell1.wav")
- soundVolume("Beep", 0.2)
- soundPitch("Beep", 200)
- }
- Engine_Active = (Engine_RPM > 350) * sign(Engine_Ignition)
- if (Engine_Ignition & !Engine_Active) {timer("Beep", 1200)}
- if (changed(Engine_Active) & Engine_Active) {loadSounds(), stoptimer("Beep")}
- if (!Engine_Active & (Engine_Ignition == 2) & (Gearbox_Clutch == 1)) {Engine_RPM += 25}
- Chassis_Feedback = vec()
- Flywheels_RPM = array()
- foreach (K, V:entity = Flywheel["Entities", array]) {
- Flywheels_RPM[K, number] = V:angVelVector():dot(V:toLocalAxis(E:up())) / 6
- if (Key_S) {
- local Force = 500 * Flywheels_RPM[K, number] * Brake
- V:applyTorque(V:toLocalAxis(-E:up()) * Force)
- Chassis_Feedback += Force
- }
- }
- if (Chassis_Feedback) {C:applyTorque(Chassis_Feedback * C:toLocalAxis(E:up()))}
- Flywheel_RPM = Flywheels_RPM:average()
- Gearbox_Clutch -= Gearbox_Clutch * Gearbox_ClutchSpeed
- if (!Gearbox_Gear | Clutch_Delay | Key_S | Key_Sp) {Gearbox_Clutch = 1}
- if (Key_Sh) {Gearbox_Clutch = max(Gearbox_Clutch, 0.25)}
- #Gearbox_Clutch = max(Gearbox_Clutch, 0.02, (Engine_RPM / Engine_Redline) * 0.1)
- Engine_RealRPM = (Engine_RPM * Gearbox_Clutch) + ((Flywheel_RPM * Gearbox_Ratio) * (1 - Gearbox_Clutch))
- Engine_Throttle = (Key_W ? (Key_Alt ? 1 : 0.50) : 0)
- Engine_IdleThrottle += ((min(Engine_RPM, Engine_RealRPM) < Engine_Idle) ? Engine_IdleRev : -Engine_IdleRev)
- Engine_IdleThrottle = clamp(Engine_IdleThrottle, 0, 0.5) * Engine_Active
- Engine_Throttle = max(Engine_Throttle, Engine_IdleThrottle)
- if (Fuel_Enabled) {
- Fuel_Liters -= ((((Engine_Displacement * (Engine_RPM/2)) * Air_Density * Fuel_Air_Ratio)/Fuel_Density)/(65*60) * max(Engine_Throttle, 0.01)) * Engine_Active
- Fuel_Liters = clamp(Fuel_Liters, 0, T:boxSize():length())
- Engine_Active *= (Fuel_Liters > 0)
- T:setMass(round((Fuel_Liters * Fuel_Density) + (T:boxSize():length() * 0.1), 1))
- }
- Engine_Throttle *= Engine_Active
- Engine_Throttle *= !Throttle_Delay
- Engine_PowerCut += ((Engine_RealRPM > Engine_Redline) ? 0.05 : -0.05)
- Engine_PowerCut = clamp(Engine_PowerCut, 0, 1) * round(Engine_Throttle)
- if (clk("Gear_Change")) {Throttle_Delay = 0, Clutch_Delay = 0}
- Factor = clamp((Engine_RPM / Engine_Redline), 0, 1)
- Engine_Torque = (5 * (1 - Factor) ^ 4 * Factor * Engine_TorqueTable[1, number]) + (10 * (1 - Factor) ^ 3 * Factor ^ 2 * Engine_TorqueTable[2, number]) + (10 * (1 - Factor) ^ 2 * Factor ^ 3 * Engine_TorqueTable[3, number]) + (5 * (1 - Factor) * Factor ^ 4 * Engine_TorqueTable[4, number]) + (Factor ^ 5 * Engine_TorqueTable[5, number])
- Engine_Torque = clamp(Engine_Torque, 0, 1)
- if (Turbo) {
- Turbo_PSI = Turbo_PSIMax * Turbo_RPM / Turbo_MaxRPM
- Turbo_Boost = (Turbo_PSI + Turbo_AirPressure) / Turbo_AirPressure
- Turbo_Flow = max(Engine_RPM, 1) * Turbo_Boost / Turbo_MaxFlow
- Turbo_Drag = (Turbo_MaxFlow * Turbo_DragScale) * (Turbo_RPM / Turbo_MaxRPM) * (1 - Engine_Throttle) / Turbo_Inertia
- Turbo_RPM = clamp(Turbo_RPM + (Turbo_FlowScale * (Turbo_Flow ^ Turbo_Exp)) / Turbo_Inertia - Turbo_Drag, 1, Turbo_MaxRPM)
- soundVolume("Turbo", (Turbo_Flow / 1.5 - 0.25))
- soundPitch("Turbo", 75 + 50 * Turbo_RPM / Turbo_MaxRPM)
- if (changed(Engine_Throttle) & !Engine_Throttle) {
- soundStop("BOV")
- E:soundPlay("BOV", 1, "acf_extra/vehiclefx/boost/turbo_hiss1.wav")
- soundVolume("BOV", max((Turbo_RPM / Turbo_MaxRPM) - 0.2, 0))
- soundPitch("BOV", 85 + 25 * (Turbo_RPM / Turbo_MaxRPM))
- }
- Engine_Torque *= (Turbo_Boost / 1.25)
- }
- Flywheel_PowerInertia += ((Engine_PeakTorque * Engine_Torque) - Flywheel_PowerInertia) / Engine_FlywheelMass
- Flywheel_PowerInertia = max(Flywheel_PowerInertia, (Engine_PeakTorque * Engine_Torque))
- if (Gearbox_Clutch < 1) {
- Engine_Inertia = clamp(Engine_RealRPM, 0, Engine_Redline) - (Flywheel_RPM * Gearbox_Ratio)
- Engine_Inertia *= (1 - Gearbox_Clutch)
- Engine_Inertia /= Engine_Redline
- Engine_Throttle -= ((0.285 * (Engine_RealRPM / Engine_Redline)) * (Engine_Throttle <= 0))
- Flywheel_Power = Flywheel_PowerInertia
- Flywheel_Power *= Gearbox_Ratio
- Flywheel_Power *= (1 - Gearbox_Clutch)
- Flywheel_Power *= min(clamp(Engine_Throttle, -1, ((1 - Engine_PowerCut) ^ 2)) + Engine_Inertia, 1)
- Flywheel_Power *= clamp(1 - (((Engine_RealRPM / Engine_RPM) - 1) * Engine_Throttle), -1, 1) ^ Engine_FlywheelMass
- if (Flywheel_Power) {
- foreach (K, V:entity = Flywheel["Entities", array]) {
- V:applyOffsetForce(E:right() * (Flywheel_Power / Flywheel["Entities", array]:count()), V:pos() - (E:forward() * 39.37))
- V:applyOffsetForce(E:right() * -(Flywheel_Power / Flywheel["Entities", array]:count()), V:pos() + (E:forward() * 39.37))
- }
- C:applyOffsetForce(E:right() * -Flywheel_Power, E:pos() - (E:forward() * 39.37))
- C:applyOffsetForce(E:right() * Flywheel_Power, E:pos() + (E:forward() * 39.37))
- }
- Gearbox_Feedback = (Flywheel_RPM * Gearbox_Ratio) - Engine_RPM
- Gearbox_Feedback /= Engine_FlywheelMass
- }
- Gearbox_Feedback *= (1 - Gearbox_Clutch)
- Engine_Feedback = (sign(Engine_Throttle) * Engine_Redline - Engine_RPM) * (sign(Engine_Throttle) ? (abs(Engine_Throttle * Engine_Torque)) : (Engine_Active ? 0.03 : 0.13)) / 4
- Engine_Feedback *= Gearbox_Clutch
- Engine_RPM += min(Gearbox_Feedback + Engine_Feedback, (Engine_Redline - Engine_RPM) / (Engine_FlywheelMass * (Engine_Stroke / Engine_Bore)))
- if (Engine_RPM > (Engine_Redline * 0.95) && Engine_RevLimiter) {Engine_RPM = Engine_Redline * 0.9}
- Engine_RPM = min(Engine_RPM, Engine_Redline)
- Engine_RPM *= random(0.995, 1.005)
- Engine_Volume += (max(Engine_Throttle ^ 1.25, (Engine_RPM / 9000) * 0.25) - Engine_Volume) * 0.2
- soundPitch("On", (Engine_RPM / 9000) * 155 + (50 * Engine_Active))
- soundVolume("On", Engine_Volume * 0.75)
- soundPitch("Off", (Engine_RPM / 9000) * 155 + (50 * Engine_Active))
- soundVolume("Off", ((1 - Engine_Volume) ^ 1.5) * 0.25)
- S:propFreeze(1)
- S:setAng(E:angles())
- if (last()) {
- foreach (K, V:entity = Flywheel["Entities", array]) {
- removeConstraint(K)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement