949 {
951
953 {
954 #ifdef DIAG_DEVELOPER
955 if (DEBUG_OUTPUT_TYPE & EVehicleDebugOutputType.CONTACT)
956 {
957 if (m_ContactCalled)
958 {
960 Debug.Log(
"--------------------------------------------------------------------");
961 m_ContactCalled = false;
962 }
963 }
964 #endif
965
966
970 #ifdef DEVELOPER
971 m_DebugMessageCleanTime += timeSlice;
972 if (m_DebugMessageCleanTime >= DEBUG_MESSAGE_CLEAN_TIME_SECONDS)
973 {
974 m_DebugMessageCleanTime = 0;
975 m_DebugContactDamageMessage = "";
976 }
977 #endif
978 }
979
980 if (
m_Time >= GameConstants.CARS_FLUIDS_TICK )
981 {
983
985
987
988
989 if (isServerOrOwner && EngineIsOn())
990 {
992 EngineStop();
993
994
995
998 }
999
1001 {
1003 {
1005 {
1006 SetHealth("Engine", "Health", GameConstants.DAMAGE_RUINED_VALUE);
1007 }
1008 }
1009 }
1010
1012 if ( EngineIsOn() )
1013 {
1015 {
1016 float dmg;
1017
1018 if ( EngineGetRPM() >= EngineGetRPMRedline() )
1019 {
1020 if (EngineGetRPM() > EngineGetRPMMax())
1021 AddHealth( "Engine", "Health", -GetMaxHealth("Engine", "") * 0.05 );
1022
1023
1024 dmg = EngineGetRPM() * 0.001 * Math.RandomFloat( 0.02, 1.0 );
1025 ProcessDirectDamage(
DamageType.CUSTOM, null,
"Engine",
"EnviroDmg", vector.Zero, dmg);
1026 SetEngineZoneReceivedHit(true);
1027 }
1028 else
1029 {
1030 SetEngineZoneReceivedHit(false);
1031 }
1032 }
1033
1034 if (isServerOrOwner)
1035 {
1038 {
1041 }
1042
1045
1048
1051
1054 }
1055
1057 {
1059 {
1060 if ( GetFluidFraction(
CarFluid.COOLANT ) < 0.5 && GetFluidFraction(
CarFluid.COOLANT ) >= 0 )
1061 {
1062
1063 dmg = ( 1 - GetFluidFraction(
CarFluid.COOLANT) ) * Math.RandomFloat( 0.02, 10.00 );
1064 AddHealth( "Engine", "Health", -dmg );
1065 SetEngineZoneReceivedHit(true);
1066 }
1067 }
1068 }
1069
1070
1071 if (!
g_Game.IsDedicatedServer())
1072 {
1074 {
1078 }
1079
1081 {
1083 {
1086 }
1087
1089 {
1090 if (GetFluidFraction(
CarFluid.COOLANT) > 0)
1092 else
1094 }
1095 }
1096 else
1097 {
1100 }
1101 }
1102 }
1103 else
1104 {
1105
1106 if ( !
g_Game.IsDedicatedServer() )
1107 {
1109 {
1112 }
1113
1115 {
1118 }
1119 }
1120 }
1121
1122 }
1123
1124
1125 if ( !
g_Game.IsDedicatedServer() )
1126 {
1128 for (int i = 0; i < WheelCount(); i++)
1129 {
1132 bool haveParticle = false;
1133
1134 CarWheel wheel = CarWheel.Cast(WheelGetEntity(i));
1135 if (wheel && WheelHasContact(i))
1136 {
1137 float wheelSpeed = WheelGetAngularVelocity(i) * wheel.GetRadius();
1138
1139 vector wheelPos = WheelGetContactPosition(i);
1141
1142 vector transform[3];
1143 transform[2] = WheelGetDirection(i);
1144 transform[1] = vector.
Up;
1145 transform[0] = transform[2] * transform[1];
1146
1148
1149 float bodySpeed = wheelVel[2];
1150
1151 bool applyEffect = false;
1152 if ((wheelSpeed > 0 && bodySpeed > 0) || (wheelSpeed < 0 && bodySpeed < 0))
1153 {
1154 applyEffect = Math.AbsFloat(wheelSpeed) > Math.AbsFloat(bodySpeed) + EffWheelSmoke.WHEEL_SMOKE_THRESHOLD;
1155 }
1156 else
1157 {
1158 applyEffect = Math.AbsFloat(wheelSpeed) > EffWheelSmoke.WHEEL_SMOKE_THRESHOLD;
1159 }
1160
1161 if (applyEffect)
1162 {
1163 haveParticle = true;
1164
1165 string surface;
1166 g_Game.SurfaceGetType(wheelPos[0], wheelPos[2], surface);
1167 wheelPos = WorldToModel(wheelPos);
1168
1169 if (!SEffectManager.IsEffectExist(ptrEff))
1170 {
1171 eff = new EffWheelSmoke();
1173 ptrEff = SEffectManager.PlayOnObject(eff, this, wheelPos, "0 1 -1");
1177 }
1178 else
1179 {
1180 if (!eff.IsPlaying() && Surface.GetWheelParticleID(surface) != 0)
1184 }
1185 }
1186 }
1187
1188 if (!haveParticle)
1189 {
1190 if (eff && eff.IsPlaying())
1192 }
1193 }
1194 }
1195 }
CarFluid
Type of vehicle's fluid. (native, do not change or extend)
DamageType
exposed from C++ (do not change)
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 vector dBodyGetVelocityAt(notnull IEntity body, vector globalpos)
proto native vector GetVelocity(notnull IEntity ent)
Returns linear velocity.