// script_DEBUG.sch // // Common procedures/functions used for debug in the game. USING "globals.sch" #IF IS_DEBUG_BUILD USING "shared_debug.sch" #ENDIF USING "types.sch" USING "script_MISC.sch" USING "script_player.sch" USING "commands_entity.sch" USING "commands_object.sch" USING "commands_vehicle.sch" USING "commands_camera.sch" //// ******************************************************************************************* //// TO STRING FUNCTIONS AND PROCEDURES //// ******************************************************************************************* /// PURPOSE: a string of the time in miliseconds (in the format 11:11:1111) /// PARAMS: /// ms - Time in ms /// RETURNS: a string of the time in miliseconds (in the format 11:11:1111 /// AUTHOR: alwyn.roberts@rockstarnorth.com #IF IS_DEBUG_BUILD FUNC STRING GET_STRING_FROM_MILISECONDS(INT ms) INT iHours = ((ms/1000)/(60*60)) INT iMinutes = (((ms/1000)/60)-iHours*60) //(ms/1000)/60 INT iSeconds = ((ms-(((iMinutes+(iHours*60))*60)*1000))/1000) //(ms-(iMinutes*60*1000))/1000 INT iMiliseconds = ms-((iSeconds+((iMinutes+(iHours*60))*60))*1000) //ms-((iSeconds+(iMinutes*60))*1000) TEXT_LABEL_63 tl IF iHours > 0 tl += iHours tl += ":" IF iMinutes < 10 tl += "0" IF iMinutes < 0 tl += iMinutes tl += ":" IF iSeconds < 10 tl += "0" ENDIF ENDIF ENDIF ENDIF IF iMinutes > 0 tl += iMinutes tl += ":" IF iSeconds < 10 tl += "0" ENDIF ENDIF tl += iSeconds tl += "." IF iMiliseconds >= 0 tl += iMiliseconds ELSE tl += (iMiliseconds*-1) ENDIF IF iMiliseconds < 10 tl += "00" ELIF iMiliseconds < 100 tl += "0" ENDIF RETURN GET_FIRST_N_CHARACTERS_OF_LITERAL_STRING(tl, GET_LENGTH_OF_LITERAL_STRING(tl)) ENDFUNC #ENDIF // IS_DEBUG_BUILD // PURPOSE: Convert a time in msec to a format of: 0h 0m 0s #IF IS_DEBUG_BUILD FUNC STRING Convert_Msec_To_HMS_String(INT ms) INT iHours = ((ms/1000)/(60*60)) INT iMinutes = (((ms/1000)/60)-iHours*60) //(ms/1000)/60 INT iSeconds = ((ms-(((iMinutes+(iHours*60))*60)*1000))/1000) //(ms-(iMinutes*60*1000))/1000 TEXT_LABEL_15 tl15 = "" BOOL stringStarted = FALSE IF (iHours > 0) tl15 += iHours tl15 += "h " stringStarted = TRUE ENDIF IF NOT (stringStarted) IF (iMinutes > 0) stringStarted = TRUE ENDIF ENDIF IF (stringStarted) tl15 += iMinutes tl15 += "m " ENDIF tl15 += iSeconds tl15 += "s" RETURN (GET_FIRST_N_CHARACTERS_OF_LITERAL_STRING(tl15, GET_LENGTH_OF_LITERAL_STRING(tl15))) ENDFUNC #ENDIF /// PURPOSE: Returns the float passed as a string to 4 decimal places. /// PARAMS: /// f - A float, +ve or -ve. /// RETURNS: a string of the float passed. /// AUTHOR: alwyn.roberts@rockstarnorth.com #IF IS_DEBUG_BUILD FUNC STRING GET_STRING_FROM_FLOAT(FLOAT f, INT decimal_places = 4) TEXT_LABEL float_text_label INT string_length // Handle -ve values. IF f < 0 INT iCeil_f = CEIL(f) IF iCeil_f = 0 float_text_label = "-" ENDIF float_text_label += iCeil_f ELSE float_text_label += FLOOR(f) ENDIF float_text_label += "." string_length = GET_LENGTH_OF_LITERAL_STRING(float_text_label) FLOAT fFloat_remainder_a = f%1.0 FLOAT fFloat_remainder_b = (fFloat_remainder_a)*10000.0 INT iFloat_remainder_c = ROUND((fFloat_remainder_b)) INT iAddedZeros = 0 IF absi(iFloat_remainder_c) < 10 float_text_label += "000" iAddedZeros = 3 ELIF absi(iFloat_remainder_c) < 100 float_text_label += "00" iAddedZeros = 2 ELIF absi(iFloat_remainder_c) < 1000 float_text_label += "0" iAddedZeros = 1 ENDIF INT iFloat_remainder_d = ABSI(iFloat_remainder_c) float_text_label += iFloat_remainder_d INT iToAddZeros = 0 IF iFloat_remainder_d < 10 iToAddZeros = 3 ELIF iFloat_remainder_d < 100 iToAddZeros = 2 ELIF iFloat_remainder_d < 1000 iToAddZeros = 1 ENDIF IF iToAddZeros > iAddedZeros //might need to add zeros to end of text label... ENDIF RETURN GET_FIRST_N_CHARACTERS_OF_LITERAL_STRING(float_text_label, string_length + decimal_places) ENDFUNC /// PURPOSE: /// Returns an integer bitfield as a string. /// PARAMS: /// iBitfield - INT you want printed as a bitfield /// RETURNS: /// A string of this format... /// "BIT0 0000 0000 0000 0000 0000 0000 0000 0000 BIT31" FUNC STRING GET_STRING_FROM_BITFIELD( INT iBinaryField ) TEXT_LABEL_63 tBuffer = "BIT0 " INT iIndex = 0 FOR iIndex = 1 TO 32 IF IS_BIT_SET( iBinaryField, 0 ) tBuffer += 1 ELSE tBuffer += 0 ENDIF IF iIndex % 4 = 0 tBuffer += " " ENDIF iBinaryField = SHIFT_RIGHT(iBinaryField, 1) ENDFOR tBuffer += "BIT31" RETURN GET_FIRST_N_CHARACTERS_OF_LITERAL_STRING(tBuffer, GET_LENGTH_OF_LITERAL_STRING(tBuffer)) ENDFUNC /// PURPOSE: /// Returns a bool as a string (TRUE/FALSE). /// PARAMS: /// bBool - /// RETURNS: /// FUNC STRING GET_STRING_FROM_BOOL(BOOL bBool) IF bBool = TRUE RETURN("TRUE") ELSE RETURN("FALSE") ENDIF ENDFUNC #ENDIF // IS_DEBUG_BUILD int i_sd_time_to_break_out, i_sd_time_started // PURPOSE : temp stuff until the mocap rolls in PROC DISPLAY_PLACEHOLDER_TEXT(STRING strText, BOOL b_fade_in_after = TRUE) //------| If screen is faded out - We then instantly fade in then draw the rectangle. //------| If screen is faded in - We then want the screen to fade out nicely then to instantly fade in for the rect stuff. BOOL b_skip_timer= FALSE INT i_duration = 11000 INT i_sd_current_time = GET_GAME_TIMER() i_sd_time_started = i_sd_current_time i_sd_time_to_break_out = i_sd_current_time + i_duration SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) WHILE NOT (i_sd_current_time >= i_sd_time_to_break_out) AND NOT b_skip_timer IF IS_CUTSCENE_SKIP_BUTTON_PRESSED() AND ((i_sd_current_time - i_sd_time_started) > 1000) b_skip_timer = TRUE ENDIF //Steve T HIDE_HUD_AND_RADAR_THIS_FRAME () DRAW_RECT(0.5, 0.5, 1.0, 1.0, 0, 0, 0, 255) SET_TEXT_CENTRE(TRUE) SET_TEXT_COLOUR(255, 255, 255, 255) SET_TEXT_SCALE(0.3, 0.5) SET_SCRIPT_GFX_DRAW_ORDER(GFX_ORDER_AFTER_FADE) DISPLAY_TEXT(0.5, 0.5, strText) i_sd_current_time = GET_GAME_TIMER() WAIT(0) ENDWHILE //Steve T //DO_SCREEN_FADE_OUT(0) IF b_fade_in_after //SCRIPT_ASSERT() // DO_SCREEN_FADE_IN(1000) ELSE // FADE_OUT_AND_WAIT(0) ENDIF SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) ENDPROC #IF IS_DEBUG_BUILD /// PURPOSE: /// Converts the current position and rotation of the debug cam into an attach and point offset relative to a given vehicle. /// This is useful for quickly creating cameras that will be attached to/pointed at vehicles. /// PARAMS: /// veh - The vehicle to attach to and point at. If NULL, the nearest vehicle will be used PROC OUTPUT_DEBUG_CAM_RELATIVE_TO_VEHICLE(VEHICLE_INDEX veh = NULL) CAMERA_INDEX cam = GET_DEBUG_CAM() IF DOES_CAM_EXIST(cam) IF NOT DOES_ENTITY_EXIST(veh) INT i_search_flags = VEHICLE_SEARCH_FLAG_RETURN_MISSION_VEHICLES i_search_flags |= VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_PLAYER i_search_flags |= VEHICLE_SEARCH_FLAG_RETURN_RANDOM_VEHICLES i_search_flags |= VEHICLE_SEARCH_FLAG_RETURN_LAW_ENFORCER_VEHICLES i_search_flags |= VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_A_DEAD_OR_DYING_PED i_search_flags |= VEHICLE_SEARCH_FLAG_RETURN_VEHICLES_CONTAINING_GROUP_MEMBERS i_search_flags |= VEHICLE_SEARCH_FLAG_ALLOW_VEHICLE_OCCUPANTS_TO_BE_PERFORMING_A_SCRIPTED_TASK veh = GET_CLOSEST_VEHICLE(GET_CAM_COORD(cam), 500.0, DUMMY_MODEL_FOR_SCRIPT, i_search_flags) ENDIF IF IS_VEHICLE_DRIVEABLE(veh) VECTOR v_cam_pos = GET_CAM_COORD(cam) VECTOR v_cam_rot = GET_CAM_ROT(cam) VECTOR v_veh_rot = GET_ENTITY_ROTATION(veh) IF v_veh_rot.z > 180.0 v_veh_rot.z = -180.0 -(180.0 - v_veh_rot.z) ENDIF VECTOR v_cam_dir = <<-SIN(v_cam_rot.z) * COS(v_cam_rot.x), COS(v_cam_rot.z) * COS(v_cam_rot.x), SIN(v_cam_rot.x)>> VECTOR v_cam_front_pos = v_cam_pos + (v_cam_dir * 3.0) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ATTACH_CAM_TO_ENTITY(cam, veh, ") SAVE_VECTOR_TO_DEBUG_FILE(GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(veh, v_cam_pos)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("POINT_CAM_AT_ENTITY(cam, veh, ") SAVE_VECTOR_TO_DEBUG_FILE(GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(veh, v_cam_front_pos)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("SET_CAM_FOV(cam, ") SAVE_FLOAT_TO_DEBUG_FILE(GET_CAM_FOV(cam)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() //Source data VECTOR v_veh_pos = GET_ENTITY_COORDS(veh) SAVE_STRING_TO_DEBUG_FILE("Camera world coords: ") SAVE_VECTOR_TO_DEBUG_FILE(v_cam_pos) SAVE_STRING_TO_DEBUG_FILE(" Camera rotation: ") SAVE_VECTOR_TO_DEBUG_FILE(v_cam_rot) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("Vehicle world coords: ") SAVE_VECTOR_TO_DEBUG_FILE(v_veh_pos) SAVE_STRING_TO_DEBUG_FILE(" Vehicle rotation: ") SAVE_VECTOR_TO_DEBUG_FILE(v_veh_rot) SAVE_NEWLINE_TO_DEBUG_FILE() ENDIF ENDIF ENDPROC #ENDIF #IF IS_DEBUG_BUILD /// PURPOSE: /// Converts the current position and rotation of the debug cam into an attach and point offset relative to a given entity. /// This is useful for quickly creating cameras that will be attached to/pointed at entities. /// PARAMS: /// entity - The entity to attach to and point at. PROC OUTPUT_DEBUG_CAM_RELATIVE_TO_ENTITY(ENTITY_INDEX entity) CAMERA_INDEX cam = GET_DEBUG_CAM() IF DOES_CAM_EXIST(cam) IF NOT IS_ENTITY_DEAD(entity) VECTOR v_cam_pos = GET_CAM_COORD(cam) VECTOR v_cam_rot = GET_CAM_ROT(cam) VECTOR v_entity_rot = GET_ENTITY_ROTATION(entity) IF v_entity_rot.z > 180.0 v_entity_rot.z = -180.0 -(180.0 - v_entity_rot.z) ENDIF VECTOR v_cam_dir = <<-SIN(v_cam_rot.z) * COS(v_cam_rot.x), COS(v_cam_rot.z) * COS(v_cam_rot.x), SIN(v_cam_rot.x)>> VECTOR v_cam_front_pos = v_cam_pos + (v_cam_dir * 3.0) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("ATTACH_CAM_TO_ENTITY(cam, entity, ") SAVE_VECTOR_TO_DEBUG_FILE(GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(entity, v_cam_pos)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("POINT_CAM_AT_ENTITY(cam, entity, ") SAVE_VECTOR_TO_DEBUG_FILE(GET_OFFSET_FROM_ENTITY_GIVEN_WORLD_COORDS(entity, v_cam_front_pos)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("SET_CAM_FOV(cam, ") SAVE_FLOAT_TO_DEBUG_FILE(GET_CAM_FOV(cam)) SAVE_STRING_TO_DEBUG_FILE(")") SAVE_NEWLINE_TO_DEBUG_FILE() //Source data VECTOR v_entity_pos = GET_ENTITY_COORDS(entity) SAVE_STRING_TO_DEBUG_FILE("Camera world coords: ") SAVE_VECTOR_TO_DEBUG_FILE(v_cam_pos) SAVE_STRING_TO_DEBUG_FILE(" Camera rotation: ") SAVE_VECTOR_TO_DEBUG_FILE(v_cam_rot) SAVE_NEWLINE_TO_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE("Entity world coords: ") SAVE_VECTOR_TO_DEBUG_FILE(v_entity_pos) SAVE_STRING_TO_DEBUG_FILE(" Entity rotation: ") SAVE_VECTOR_TO_DEBUG_FILE(v_entity_rot) SAVE_NEWLINE_TO_DEBUG_FILE() ENDIF ENDIF ENDPROC #ENDIF // PURPOSE : References a string to fool the compiler PROC DUMMY_REFERENCE_STRING(STRING dummyText) IF ARE_STRINGS_EQUAL(dummyText, dummyText) ENDIF ENDPROC // PURPOSE : References a bool to fool the compiler PROC DUMMY_REFERENCE_BOOL(BOOL dummyBOOL) IF dummyBOOL ENDIF ENDPROC // PURPOSE : References an integer to fool the compiler PROC DUMMY_REFERENCE_INT(INT dummyINT) IF dummyINT > 0 ENDIF ENDPROC // PURPOSE : References a float to fool the compiler PROC DUMMY_REFERENCE_FLOAT(FLOAT dummyFLOAT) IF dummyFLOAT <> 0 ENDIF ENDPROC // PURPOSE : References a vector to fool the compiler PROC DUMMY_REFERENCE_VECTOR(VECTOR dummyVECTOR) IF VDIST(dummyVECTOR, dummyVECTOR) > 1 ENDIF ENDPROC //Steve T doctored this hack.. HAS_PICKUP was removed by John G. //PURPOSE : References a pickup to fool the compiler PROC DUMMY_REFERENCE_PICKUP(PICKUP_INDEX dummyPICKUP) IF dummyPICKUP = dummyPICKUP ENDIF //IF HAS_PICKUP_BEEN_COLLECTED(dummyPICKUP) //ENDIF ENDPROC /// PURPOSE: /// Can pass vectors straight into command, unlike GET_HEADING_FROM_VECTOR_2D /// PARAMS: /// VECTOR V1, VECTOR V2 FUNC FLOAT GET_HEADING_BETWEEN_VECTORS_2D(VECTOR V1, VECTOR V2) RETURN GET_HEADING_FROM_VECTOR_2D(V2.x-V1.x,V2.y-V1.y) ENDFUNC #IF IS_DEBUG_BUILD /// PURPOSE: /// Draws debug text in position above the specified position with Z coordinate offset. /// PARAMS: /// vPosition - Position to draw the debug text above. /// sText - String to draw on screen. /// fZOffset - Z coordinate offset to apply to draw position. /// iRed - Red component of RGB for the debug text. /// iGreen - Green component of RGB for the debug text. /// iBlue - Blue component of RGB for the debug text. /// iAlpha - Alpha for the debug text. PROC DRAW_DEBUG_TEXT_ABOVE_COORDS(VECTOR vPosition, STRING sText, FLOAT fZOffset, INT iRed = 255, INT iGreen = 0, INT iBlue = 0, INT iAlpha = 255) VECTOR vNewPosition = vPosition vNewPosition.Z = vPosition.Z + fZOffset DRAW_DEBUG_TEXT(sText, vNewPosition, iRed, iGreen, iBlue, iAlpha) ENDPROC /// PURPOSE: /// Draws debug text in position above the specified entity with Z coordinate offset. /// PARAMS: /// EntityIndex - Entity to draw debug text above. /// sText - String to draw on screen. /// fZOffset - Z coordinate offset to apply to draw position. /// iRed - Red component of RGB for the debug text. /// iGreen - Green component of RGB for the debug text. /// iBlue - Blue component of RGB for the debug text. /// iAlpha - Alpha for the debug text. PROC DRAW_DEBUG_TEXT_ABOVE_ENTITY(ENTITY_INDEX EntityIndex, STRING sText, FLOAT fZOffset, INT iRed = 255, INT iGreen = 0, INT iBlue = 0, INT iAlpha = 255) IF DOES_ENTITY_EXIST(EntityIndex) IF NOT IS_ENTITY_DEAD(EntityIndex) VECTOR vPosition = GET_ENTITY_COORDS(EntityIndex) vPosition.Z = vPosition.Z + fZOffset DRAW_DEBUG_TEXT(sText, vPosition, iRed, iGreen, iBlue, iAlpha) ENDIF ENDIF ENDPROC /// PURPOSE: /// Draws debug vehicle recording name, number and playback time in position above the specified vehcile with Z coordinate offset. /// PARAMS: /// VehicleIndex - Vehicle index to check for vehicle recording name, number and playback time. /// fZOffset - Z coordinate offset to apply to draw position. /// iRed - Red component of RGB for the debug text. /// iGreen - Green component of RGB for the debug text. /// iBlue - Blue component of RGB for the debug text. /// iAlpha - Alpha for the debug text. PROC DRAW_DEBUG_VEHICLE_RECORDING_INFO(VEHICLE_INDEX VehicleIndex, FLOAT fZOffset, INT iRed = 255, INT iGreen = 0, INT iBlue = 0, INT iAlpha = 255) IF DOES_ENTITY_EXIST(VehicleIndex) IF NOT IS_ENTITY_DEAD(VehicleIndex) IF IS_PLAYBACK_GOING_ON_FOR_VEHICLE(VehicleIndex) TEXT_LABEL_63 sRecordingName RECORDING_ID iRecordingID = GET_CURRENT_PLAYBACK_FOR_VEHICLE(VehicleIndex) INT iRecordingPlaybackTime = FLOOR(GET_TIME_POSITION_IN_RECORDING(VehicleIndex)) sRecordingName = GET_VEHICLE_RECORDING_NAME(iRecordingID) sRecordingName += ": " sRecordingName += iRecordingPlaybackTime DRAW_DEBUG_TEXT_ABOVE_ENTITY(VehicleIndex, sRecordingName, fZOffset, iRed, iGreen, iBlue, iAlpha) ENDIF ENDIF ENDIF ENDPROC ///PURPOSE: /// Draws a solid angled area to help distinguish it from other angled areas. (Remember SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE) PROC DRAW_DEBUG_POLY_ANGLED_AREA(VECTOR vCoord1, VECTOR vCoord2, FLOAT fWidth, INT iRed = 255, INT iGreen = 0, INT iBlue = 0, INT iAlpha = 128, BOOL bDebugLines = TRUE, BOOL bDebugSolid = TRUE) IF bDebugSolid //Bottom DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) //Top DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) //Left DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) //Right DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) //Front DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) //Back DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) DRAW_DEBUG_POLY(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue, iAlpha) ENDIF IF bDebugLines OR bDebugSolid = FALSE //Bottom DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) //Top DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) //Edges DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) DRAW_DEBUG_LINE(GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), GET_OFFSET_FROM_COORD_AND_HEADING_IN_WORLD_COORDS(<>, GET_HEADING_BETWEEN_VECTORS_2D(<>, <>), <<-(fWidth / 2), 0.0, 0.0>>), iRed, iGreen, iBlue) ENDIF ENDPROC FUNC BOOL GET_DRAW_DEBUG_COMMANDLINE_PARAM_EXISTS(STRING sParam = NULL, BOOL bBypassAllFlag = FALSE) IF GET_COMMANDLINE_PARAM_EXISTS("sc_DrawDebugStuff") STRING sArgs = GET_COMMANDLINE_PARAM("sc_DrawDebugStuff") IF IS_STRING_NULL_OR_EMPTY(sParam) sParam = GET_THIS_SCRIPT_NAME() ENDIF //First, check string is not null. IF IS_STRING_NULL_OR_EMPTY(sArgs) ASSERTLN("GET_DRAW_DEBUG_COMMANDLINE_PARAM_EXISTS: The character string was null.") RETURN FALSE ENDIF IF ARE_STRINGS_EQUAL("all", sArgs) AND NOT bBypassAllFlag RETURN TRUE ENDIF // Get string length. INT stringLength = GET_LENGTH_OF_LITERAL_STRING(sArgs) //Use this int to store the character indexes at which the string is split. //There are a maxumum of 2 breaks as there is a maximum of 3 playable characters. INT iBreakIndex[2] INT iNumBreaksFound = 0 //Step through the string and record break indexes. INT iStringIndex REPEAT (stringLength-1) iStringIndex IF ARE_STRINGS_EQUAL(GET_STRING_FROM_STRING(sArgs, iStringIndex, iStringIndex+1), ";") IF iNumBreaksFound = COUNT_OF(iBreakIndex) ASSERTLN("GET_DRAW_DEBUG_COMMANDLINE_PARAM_EXISTS: Too many character names contained in character string, please update size of iBreakIndex[", COUNT_OF(iBreakIndex), "]") RETURN FALSE ENDIF iBreakIndex[iNumBreaksFound] = iStringIndex iNumBreaksFound++ ENDIF ENDREPEAT //Now split up the string around the break points and save the individual names into the provided text labels. IF iNumBreaksFound > 0 IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, 0, iBreakIndex[0])) RETURN TRUE ENDIF IF iNumBreaksFound = 1 IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, iBreakIndex[0]+1, stringLength)) RETURN TRUE ENDIF ELIF iNumBreaksFound = 2 IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, iBreakIndex[0]+1, iBreakIndex[1])) RETURN TRUE ENDIF IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, iBreakIndex[1]+1, stringLength)) RETURN TRUE ENDIF ENDIF //// might be more efficient if we up iBreakIndex[] // INT iBreak // REPEAT iNumBreaksFound iBreak // IF iBreak = 0 // IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, 0, iBreakIndex[iBreak])) // RETURN TRUE // ENDIF // ELIF iBreak != iNumBreaksFound-1 // IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, iBreakIndex[iBreak-1]+1, iBreakIndex[iBreak])) // RETURN TRUE // ENDIF // ELSE // IF ARE_STRINGS_EQUAL(sParam, GET_STRING_FROM_STRING(sArgs, iBreakIndex[iBreak-1]+1, stringLength)) // RETURN TRUE // ENDIF // ENDIF // ENDREPEAT ELSE IF ARE_STRINGS_EQUAL(sParam, sArgs) RETURN TRUE ENDIF ENDIF ENDIF IF GET_COMMANDLINE_PARAM_EXISTS("sc_DrawDebugFamilyStuff") PRINTLN("GET_DRAW_DEBUG_COMMANDLINE_PARAM_EXISTS: replace \"sc_DrawDebugFamilyStuff\" with custom \"sc_DrawDebugStuff=custom\".") RETURN TRUE ENDIF RETURN FALSE ENDFUNC #ENDIF