895 {
897
899 {
900 #ifdef DIAG_DEVELOPER
901 if (DEBUG_OUTPUT_TYPE & EVehicleDebugOutputType.CONTACT)
902 {
903 if (m_ContactCalled)
904 {
906 Debug.Log(
"--------------------------------------------------------------------");
907 m_ContactCalled = false;
908 }
909 }
910 #endif
911
912
916 #ifdef DEVELOPER
917 m_DebugMessageCleanTime += timeSlice;
918 if (m_DebugMessageCleanTime >= DEBUG_MESSAGE_CLEAN_TIME_SECONDS)
919 {
920 m_DebugMessageCleanTime = 0;
921 m_DebugContactDamageMessage = "";
922 }
923 #endif
924 }
925
926 if (
m_Time >= GameConstants.CARS_FLUIDS_TICK )
927 {
929
931
933
934
935 if (isServerOrOwner && EngineIsOn())
936 {
938 EngineStop();
939
940
941
944 }
945
947 {
949 {
951 {
952 SetHealth("Engine", "Health", GameConstants.DAMAGE_RUINED_VALUE);
953 }
954 }
955 }
956
958 if ( EngineIsOn() )
959 {
961 {
962 float dmg;
963
964 if ( EngineGetRPM() >= EngineGetRPMRedline() )
965 {
966 if (EngineGetRPM() > EngineGetRPMMax())
967 AddHealth( "Engine", "Health", -GetMaxHealth("Engine", "") * 0.05 );
968
969
970 dmg = EngineGetRPM() * 0.001 * Math.RandomFloat( 0.02, 1.0 );
971 ProcessDirectDamage(
DamageType.CUSTOM, null,
"Engine",
"EnviroDmg", vector.Zero, dmg);
972 SetEngineZoneReceivedHit(true);
973 }
974 else
975 {
976 SetEngineZoneReceivedHit(false);
977 }
978 }
979
980 if (isServerOrOwner)
981 {
984 {
987 }
988
991
994
997
1000 }
1001
1003 {
1005 {
1006 if ( GetFluidFraction(
CarFluid.COOLANT ) < 0.5 && GetFluidFraction(
CarFluid.COOLANT ) >= 0 )
1007 {
1008
1009 dmg = ( 1 - GetFluidFraction(
CarFluid.COOLANT) ) * Math.RandomFloat( 0.02, 10.00 );
1010 AddHealth( "Engine", "Health", -dmg );
1011 SetEngineZoneReceivedHit(true);
1012 }
1013 }
1014 }
1015
1016
1017 if (!
GetGame().IsDedicatedServer())
1018 {
1020 {
1024 }
1025
1027 {
1029 {
1032 }
1033
1035 {
1036 if (GetFluidFraction(
CarFluid.COOLANT) > 0)
1038 else
1040 }
1041 }
1042 else
1043 {
1046 }
1047 }
1048 }
1049 else
1050 {
1051
1052 if ( !
GetGame().IsDedicatedServer() )
1053 {
1055 {
1058 }
1059
1061 {
1064 }
1065 }
1066 }
1067
1068 }
1069
1070
1071 if ( !
GetGame().IsDedicatedServer() )
1072 {
1074 for (int i = 0; i < WheelCount(); i++)
1075 {
1078 bool haveParticle = false;
1079
1080 CarWheel wheel = CarWheel.Cast(WheelGetEntity(i));
1081 if (wheel && WheelHasContact(i))
1082 {
1083 float wheelSpeed = WheelGetAngularVelocity(i) * wheel.GetRadius();
1084
1085 vector wheelPos = WheelGetContactPosition(i);
1087
1088 vector transform[3];
1089 transform[2] = WheelGetDirection(i);
1090 transform[1] = vector.
Up;
1091 transform[0] = transform[2] * transform[1];
1092
1094
1095 float bodySpeed = wheelVel[2];
1096
1097 bool applyEffect = false;
1098 if ((wheelSpeed > 0 && bodySpeed > 0) || (wheelSpeed < 0 && bodySpeed < 0))
1099 {
1100 applyEffect = Math.AbsFloat(wheelSpeed) > Math.AbsFloat(bodySpeed) + EffWheelSmoke.WHEEL_SMOKE_THRESHOLD;
1101 }
1102 else
1103 {
1104 applyEffect = Math.AbsFloat(wheelSpeed) > EffWheelSmoke.WHEEL_SMOKE_THRESHOLD;
1105 }
1106
1107 if (applyEffect)
1108 {
1109 haveParticle = true;
1110
1111 string surface;
1113 wheelPos = WorldToModel(wheelPos);
1114
1115 if (!SEffectManager.IsEffectExist(ptrEff))
1116 {
1117 eff = new EffWheelSmoke();
1119 ptrEff = SEffectManager.PlayOnObject(eff, this, wheelPos, "0 1 -1");
1123 }
1124 else
1125 {
1126 if (!eff.IsPlaying() && Surface.GetWheelParticleID(surface) != 0)
1130 }
1131 }
1132 }
1133
1134 if (!haveParticle)
1135 {
1136 if (eff && eff.IsPlaying())
1138 }
1139 }
1140 }
1141 }
CarFluid
Type of vehicle's fluid. (native, do not change or extend)
DamageType
exposed from C++ (do not change)
proto float SurfaceGetType(float x, float z, out string type)
Returns: Y position the surface was found.
void LeakFluid(CarFluid fluid)
vector m_VelocityPrevTick
ref EffVehicleSmoke m_coolantFx
Particles.
void CarPartsHealthCheck()
void CheckContactCache()
Responsible for damaging the car according to contact events from OnContact.
ref EffVehicleSmoke m_exhaustFx
ref array< int > m_WheelSmokePtcFx
void CheckVitalItem(bool isVital, int slotId)
ref array< ref EffWheelSmoke > m_WheelSmokeFx
void SetSurface(string surface)
override void Stop()
Stops all elements this effect consists of.
override void Start()
Plays all elements this effect consists of.
override void SetCurrentLocalPosition(vector pos, bool updateCached=true)
Set the current local position of the managed Particle.
proto native float Length()
Returns length of vector (magnitude)
proto vector InvMultiply3(vector mat[3])
Invert-transforms vector.
proto native CGame GetGame()
proto native vector dBodyGetVelocityAt(notnull IEntity body, vector globalpos)
proto native vector GetVelocity(notnull IEntity ent)
Returns linear velocity.