USING "rage_builtins.sch" USING "globals.sch" USING "commands_streaming.sch" USING "commands_entity.sch" USING "script_ped.sch" USING "commands_cutscene.sch" USING "script_maths.sch" #if IS_DEBUG_BUILD bool bSkipcheck #ENDIF func bool is_point_in_screeen_area(vector vWorldCoord, float x1, float y1, float x2, float y2) #if IS_DEBUG_BUILD if bSkipcheck = TRUE bSkipcheck = FALSE return TRUE ENDIF #ENDIF float sX, sY GET_SCREEN_COORD_FROM_WORLD_COORD(vWorldCoord,sX,sY) if sX>= x1 and sX<=x2 if sY>=y1 and sy<=y2 return TRUE ENDIF ENDIF return FALSE ENDFUNC #IF IS_DEBUG_BUILD proc showVectorOnScreen(float x, float y, float numtoDisplay, STRING displayText=NULL) TEXT_LABEL_31 txLb = displayText txLb += " " txLb += floor(numtoDisplay) txLb += "." numtoDisplay -= floor(numtoDisplay) numtoDisplay *= 1000 IF numtoDisplay < 100 txLb += "0" ENDIF IF numtoDisplay < 10 txLb += "0" ENDIF txLb += floor(numtoDisplay) SET_TEXT_SCALE(0.4,0.4) DISPLAY_TEXT_WITH_LITERAL_STRING(x,y,"STRING",txLb) //DISPLAY_TEXT() ENDPROC proc showFloatOnScreen(float x, float y, float numtoDisplay, STRING displayText=NULL, float fScale = 0.4) TEXT_LABEL_31 txLb = displayText txLb += " " if numtoDisplay < 0 txLb += "-" ENDIF numtoDisplay = ABSF(numtoDisplay) txLb += floor(numtoDisplay) txLb += "." numtoDisplay -= floor(numtoDisplay) numtoDisplay *= 1000 IF numtoDisplay < 100 txLb += "0" ENDIF IF numtoDisplay < 10 txLb += "0" ENDIF txLb += floor(numtoDisplay) SET_TEXT_SCALE(fScale,fScale) DISPLAY_TEXT_WITH_LITERAL_STRING(x,y,"STRING",txLb) //DISPLAY_TEXT() ENDPROC proc showIntOnScreen(float x, float y, int numtoDisplay, STRING displayText=NULL, float fScale = 0.4) TEXT_LABEL_31 txLb = displayText txLb += " " txLb += numtoDisplay SET_TEXT_SCALE(fScale,fScale) DISPLAY_TEXT_WITH_LITERAL_STRING(x,y,"STRING",txLb) //DISPLAY_TEXT() ENDPROC PROC outputDebugData(String textToSave, int iData=-1, float fData=-1.0, string stringB=NULL) string filepath = "X:/gta5/build/dev" string filename = "saveDebugData.txt" SAVE_STRING_TO_NAMED_DEBUG_FILE(textToSave,filepath,filename) if iData != -1 SAVE_INT_TO_NAMED_DEBUG_FILE(iData,filepath,filename) ENDIF if fData != -1.0 SAVE_FLOAT_TO_NAMED_DEBUG_FILE(fData,filepath,filename) ENDIF IF NOT IS_STRING_NULL(stringB) SAVE_STRING_TO_NAMED_DEBUG_FILE(stringB,filepath,filename) ENDIF SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(filepath,filename) ENDPROC PROC outputDebugVector(String textToSave, vector aVector) string filepath = "X:/gta5/build/dev" string filename = "saveDebugData.txt" SAVE_STRING_TO_NAMED_DEBUG_FILE(textToSave,filepath,filename) SAVE_STRING_TO_NAMED_DEBUG_FILE("<<",filepath,filename) SAVE_FLOAT_TO_NAMED_DEBUG_FILE(aVector.x,filepath,filename) SAVE_STRING_TO_NAMED_DEBUG_FILE(",",filepath,filename) SAVE_FLOAT_TO_NAMED_DEBUG_FILE(aVector.y,filepath,filename) SAVE_STRING_TO_NAMED_DEBUG_FILE(",",filepath,filename) SAVE_FLOAT_TO_NAMED_DEBUG_FILE(aVector.z,filepath,filename) SAVE_STRING_TO_NAMED_DEBUG_FILE(">>",filepath,filename) SAVE_NEWLINE_TO_NAMED_DEBUG_FILE(filepath,filename) ENDPROC FUNC bool IS_STRING_A_VEHICLE_MODEL(STRING sVehicleModel) int i MODEL_NAMES model i=0 while GET_VEHICLE_MODEL_FROM_INDEX(i,model) if ARE_STRINGS_EQUAL(GET_MODEL_NAME_FOR_DEBUG(model),sVehicleModel) RETURN TRUE ENDIF i++ ENDWHILE return FALSE ENDFUNC #ENDIF //PURPOSE: Check if one entity is approaching another. Being used to make a ped dive out the way of an approaching vehicle. fdiveHeading returns the direction to make the ped dive. FUNC BOOL IS_ENTITY_APPROACHING_ENTITY(ENTITY_INDEX entFrom, ENTITY_INDEX entTo, float &fdiveHeading, FLOAT observeWithinRange=15.0, FLOAT ApproachDetectionWidth=3.0, float timetoImpact=1.0) //vector vFor //float fAngToEnt //observeWithinRange= observeWithinRange UNUSED_PARAMETER(fdiveHeading) IF NOT IS_ENTITY_DEAD(entFrom) AND NOT IS_ENTITY_DEAD(entTo) // IF fDist < observeWithinRange vector vForward = GET_ENTITY_FORWARD_VECTOR(entFrom) vForward = NORMALISE_VECTOR(vForward) vForward *= observeWithinRange // DRAW_DEBUG_LINE(GET_ENTITY_COORDS(entFrom),GET_ENTITY_COORDS(entFrom)+vForward) IF IS_ENTITY_IN_ANGLED_AREA(entTo,GET_ENTITY_COORDS(entFrom),GET_ENTITY_COORDS(entFrom)+vForward,ApproachDetectionWidth,false,FALSE) float fDist = GET_DISTANCE_BETWEEN_ENTITIES(entFrom,entTo) if fDist / GET_ENTITY_SPEED(entFrom) < timetoImpact or timetoImpact <= 0.0 return TRUE ENDIF ENDIF //vector vGap = GET_ENTITY_COORDS(entLooker) - GET_ENTITY_COORDS(entApproacher) //float fAnga = ATAN2(vFor.y,vFor.x) //heading of master entity //float fAngb = ATAN2(vGap.y,vGap.x) //heading from master entity to target entity //fAngToEnt = fangb - fAnga //if fAngToEnt < 80.0 //float fint = SIN(fAngToEnt) * fDist // showFloatOnScreen(0.1,0.2,fDist,"Dist between ents=") // showFloatOnScreen(0.1,0.24,fAngA,"fAngA") // showFloatOnScreen(0.1,0.28,fAngb,"fAngAfAngb") // showFloatOnScreen(0.1,0.32,fAngToEnt,"fAngToEnt") // showFloatOnScreen(0.1,0.36,fint,"intercept gap") /* if fint < ApproachDetectionWidth if fDist / GET_ENTITY_SPEED(entApproacher) < timetoImpact if fint > 0 fDiveHeading = fAnga ELSE fDiveHeading = fAnga ENDIF RETURN TRUE ENDIF ENDIF ENDIF */ //ENDIF ENDIF RETURN FALSE ENDFUNC FUNC bool GET_UNUSED_RANDOM_ENTRY(int &iReturn, int &BitStorage, int iRandLow, int iRandHigh, bool resetAfterEachCall=FALSE, bool resetWhenFilled=FALSE) int i, unsetBitCounter = 0 for i = iRandLow to iRandHigh//-1 IF NOT IS_BIT_SET(BitStorage,i) unsetBitCounter++ ENDIF ENDFOR int iValue = GET_RANDOM_INT_IN_RANGE(0,unsetBitCounter) for i = iRandLow to iRandHigh IF NOT IS_BIT_SET(BitStorage,i) IF iValue = 0 if resetAfterEachCall = TRUE BitStorage=0 ENDIF SET_BIT(BitStorage,i) iReturn = i return true ELSE iValue-- ENDIF ENDIF ENDFOR if resetWhenFilled = TRUE BitStorage = 0 iReturn = GET_RANDOM_INT_IN_RANGE(0,unsetBitCounter) SET_BIT(BitStorage,iReturn) return true ENDIF return FALSE ENDFUNC /* func STRING add_int_to_textLabel(string txtLabel, int intToAdd) TEXT_LABEL_15 txt = txtLabel txt += intToAdd string poop poop = GET_FIRST_N_CHARACTERS_OF_LITERAL_STRING(txt,GET_LENGTH_OF_LITERAL_STRING(txt)) // //SAVE_STRING_TO_DEBUG_FILE(poop) //SAVE_NEWLINE_TO_DEBUG_FILE() return poop //return GET_STRING_FROM_STRING(txt,0,GET_LENGTH_OF_LITERAL_STRING(txt)) ENDFUNC */ FUNC FLOAT RESTRICT_HEADING(float fHeading, float min=-180.0, float max=180.0) while fHeading < min fHeading += 360.0 ENDWHILE while fHeading > max fHeading -= 360.0 ENDWHILE return fHeading ENDFUNC func vector getRandomPointOnLine(vector v1, vector v2) return v1+((v2-v1)*GET_RANDOM_FLOAT_IN_RANGE()) ENDFUNC func int GET_PLAYBACK_NUMBER_FOR_VEHICLE_VIA_RECID(vehicle_index veh) veh=veh #IF IS_DEBUG_BUILD if IS_VEHICLE_DRIVEABLE(veh) if IS_PLAYBACK_GOING_ON_FOR_VEHICLE(veh) RECORDING_ID rID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(veh) string sRecordingName = GET_VEHICLE_RECORDING_NAME(rID) int iRecNo STRING_TO_INT(GET_STRING_FROM_STRING(sRecordingName,GET_LENGTH_OF_LITERAL_STRING(sRecordingName)-3,GET_LENGTH_OF_LITERAL_STRING(sRecordingName)),iRecNo) return iRecNo //sVehRecName=GET_STRING_FROM_STRING(sVehRecName,0,GET_LENGTH_OF_LITERAL_STRING(sVehRecName)-3) ENDIF ENDIF #ENDIF return 0 ENDFUNC func bool GET_PLAYBACK_NAME_FOR_VEHICLE_VIA_RECID(vehicle_index veh, string sRecName) sRecName=sRecName veh=veh #IF IS_DEBUG_BUILD if IS_VEHICLE_DRIVEABLE(veh) if IS_PLAYBACK_GOING_ON_FOR_VEHICLE(veh) RECORDING_ID rID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(veh) string sRecordingName = GET_VEHICLE_RECORDING_NAME(rID) sRecName=GET_STRING_FROM_STRING(sRecordingName,0,GET_LENGTH_OF_LITERAL_STRING(sRecordingName)-3) return TRUE ENDIF ENDIF #ENDIF return FALSE ENDFUNC func int get_lowest_float_entry(float f1, float f2, float f3=-1.0, float f4=-1.0) float fValues[4] fValues[0] = f1 fValues[1] = f2 fValues[2] = f3 fValues[3] = f4 float lowestFloat = fValues[0] int lowestEntry = 0 int i for i = 1 to 3 if fValues[i] != -1.0 if fValues[i] < lowestFloat lowestFloat = fValues[i] lowestEntry = i ENDIF ENDIF ENDFOR return lowestEntry ENDFUNC