Files
gtav-src/script/dev_ng/singleplayer/include/public/RC_Area_public.sch
T
2025-09-29 00:52:08 +02:00

513 lines
15 KiB
Scheme
Executable File

// Functions only used when setting up an RC mission
USING "rage_builtins.sch"
USING "globals.sch"
USING "RC_Helper_Functions.sch"
CONST_INT TEST_POLY_MAX_VERTS 15
STRUCT TEST_POLY
// Poly points
VECTOR v[TEST_POLY_MAX_VERTS]
INT iVertCount
// Bounding sphere
VECTOR vCentre
FLOAT fRadius
BOOL bIsOpen
ENDSTRUCT
#IF IS_DEBUG_BUILD
USING "shared_debug.sch"
#ENDIF
//#IF IS_DEBUG_BUILD
// WIDGET_GROUP_ID m_RCAreaWidgetGroup
// VECTOR vDebugMousePosition
// VECTOR vDebugPolyPoints[TEST_POLY_MAX_VERTS]
// BOOL bResetPoint[TEST_POLY_MAX_VERTS]
// BOOL bEditPoint[TEST_POLY_MAX_VERTS]
// BOOL bRecalculateDebugPoly = FALSE
// BOOL bShowDebugPolyPoints = TRUE
// BOOL bShowDebugPoly = FALSE
// BOOL bPrintDebugPoly = FALSE
// INT iActivePoint = -1
// TEST_POLY m_DebugPoly
//#ENDIF
/// PURPOSE:
/// Check if a poly is valid - Needs to have at least 3 points for this to be the case.
/// PARAMS:
/// poly - the poly to be setup
FUNC BOOL IS_TEST_POLY_VALID(TEST_POLY& poly)
RETURN (poly.iVertCount >= 3)
ENDFUNC
/// PURPOSE:
/// Resets a polygon to have no vertices, so user can add some
/// PARAMS:
/// poly - the poly to be setup
PROC OPEN_TEST_POLY(TEST_POLY& poly)
IF poly.bIsOpen
SCRIPT_ASSERT("OPEN_TEST_POLY() - Trying to open poly for setup, when it is already open")
ENDIF
poly.iVertCount = 0
poly.vCentre = << 0,0,0 >>
poly.fRadius = 0.0
poly.bIsOpen = TRUE
ENDPROC
/// PURPOSE:
/// Adds a vertex to a polygon, needs to be called at least 3 times for a polygon to be usable.
/// Vertices can be added clockwise or anti-clockwise, but must be added in order.
/// Poly must be opened with OPEN_TEST_POLY() before adding verts, and closed with CLOSE_TEST_POLY() after.
/// PARAMS:
/// poly - the poly to be added to
/// vert - the vertex to add
PROC ADD_TEST_POLY_VERT(TEST_POLY& poly, VECTOR vert)
IF poly.bIsOpen = FALSE
SCRIPT_ASSERT("ADD_TEST_POLY_VERT() - Trying to add vert to poly when it is not open")
ENDIF
IF poly.iVertCount >= TEST_POLY_MAX_VERTS
SCRIPT_ASSERT("Tried to add too many verts to a test poly.")
ENDIF
poly.v[poly.iVertCount] = vert
poly.iVertCount++
ENDPROC
/// PURPOSE:
/// Finishes the setup process for a poly, and calculates a bounding sphere for it
/// PARAMS:
/// poly - the poly to be finalised
PROC CLOSE_TEST_POLY(TEST_POLY& poly)
IF poly.bIsOpen = FALSE
SCRIPT_ASSERT("CLOSE_TEST_POLY() - Trying to close poly when it is not open")
ENDIF
IF poly.iVertCount < 3
SCRIPT_ASSERT("CLOSE_TEST_POLY() - Trying to close poly with less than 3 vertices")
ENDIF
// Find bounding sphere of poly
INT i
REPEAT poly.iVertCount i
poly.vCentre += poly.v[i]
ENDREPEAT
poly.vCentre /= TO_FLOAT(i)
REPEAT poly.iVertCount i
FLOAT fDist = VDIST2(poly.vCentre, poly.v[i])
IF fDist > poly.fRadius
poly.fRadius = fDist
ENDIF
ENDREPEAT
poly.fRadius = SQRT(poly.fRadius)
poly.bIsOpen = FALSE
ENDPROC
/// PURPOSE:
/// This is useful for debugging the shape of your poly.
/// It draws a marker on every vertex of the poly. You will need to call it every frame.
/// PARAMS:
/// poly - the poly to draw
/// r, g, b - red/green/blue values (max 255)
/// a - alpha value (max 255)
PROC DISPLAY_POLY(TEST_POLY& poly, INT r = 255, INT g = 100, INT b = 100, INT a = 100)
INT i
REPEAT poly.iVertCount i
DRAW_MARKER(MARKER_CYLINDER, poly.v[i], <<1,0,0>>, <<0,0,0>>, <<1,1,10>>, r, g, b, a)
ENDREPEAT
ENDPROC
/// PURPOSE:
/// This is useful for debugging the shape of your poly.
/// It draws a marker on every vertex of the poly. You will need to call it every frame.
/// It draws each vertex a different colour so you can check none of the vertices are out of order (it colours the first vertex blue and the last one red, with gradient in between)
/// PARAMS:
/// poly - the poly to draw
/// r, g, b - red/green/blue values (max 255)
/// a - alpha value (max 255)
PROC DISPLAY_POLY2(TEST_POLY& poly, INT a = 100)
INT i
REPEAT poly.iVertCount i
DRAW_MARKER(MARKER_CYLINDER, poly.v[i], <<1,0,0>>, <<0,0,0>>, <<1,1,10>>, (255 * i) / poly.iVertCount, 0, 255 - ((255*i) / poly.iVertCount), a)
ENDREPEAT
ENDPROC
/// PURPOSE:
/// Checks if the point is enclosed within the polygon when looking down from above (the test is only 2D and is in the X,Y plane). Returns true if it is.
/// PARAMS:
/// poly - the poly to test
/// vert - the point to test (if this point is inside the poly, returns true)
FUNC BOOL IS_POINT_IN_POLY_2D(TEST_POLY& poly, VECTOR point)
// Check poly has enough sides
IF poly.iVertCount < 3
SCRIPT_ASSERT("IS_POINT_IN_POLY_2D: A poly must have at least 3 vertices before doing a point test")
ENDIF
BOOL bAreNodesOdd = FALSE
INT i = 0
INT j = poly.iVertCount - 1 // j is always the point that comes before i (usually i - 1). - On the first loop, i is 0, so j is poly.iVertCount - 1.
// Loop through each edge of poly
WHILE (i < poly.iVertCount)
// If an odd number of edges are to the left of the point, the point is inside the poly, otherwise it is outside
IF poly.v[i].y < point.y AND poly.v[j].y >= point.y
OR poly.v[j].y < point.y AND poly.v[i].y >= point.y
IF poly.v[i].x + (point.y-poly.v[i].y) / (poly.v[j].y-poly.v[i].y) * (poly.v[j].x-poly.v[i].x) < point.x
bAreNodesOdd = NOT bAreNodesOdd
ENDIF
ENDIF
j = i
i++
ENDWHILE
RETURN bAreNodesOdd
ENDFUNC
/// PURPOSE:
/// Makes a copy of a polygon, expanding each vertex outwards by the distance specified.
/// This is useful for warning the player they have left an area, then generating a larger, encapsulating area to fail the player for having gone too far from that original area.
/// Please note - if a coder saw this function they would cry. It is very inefficient. Only call this once at the start of your mission. DEFINITELY NOT EVERY FRAME!!
/// and be careful in the case of concave polygons, who knows what could happen
/// PARAMS:
/// in - the poly to copy
/// out - where to copy to
/// fMargin - how much further out each vertex should be (negative numbers here won't produce a smaller poly, it will always be bigger)
PROC COPY_EXPANDED_POLY(TEST_POLY& out, TEST_POLY& in, FLOAT fMargin)
// Check poly has enough sides
IF in.iVertCount < 3
SCRIPT_ASSERT("EXPAND_POLY: A poly must have at least 3 vertices to be valid")
ENDIF
INT i = in.iVertCount - 1
INT j = 0
INT k = 1
VECTOR edge0
VECTOR edge1
VECTOR normal
out.iVertCount = in.iVertCount
// Loop through each edge of poly
WHILE (j < in.iVertCount)
edge0 = in.v[j] - in.v[i]
edge1 = in.v[k] - in.v[j]
edge0 /= SQRT((edge0.x*edge0.x) + (edge0.y*edge0.y))
edge1 /= SQRT((edge1.x*edge1.x) + (edge1.y*edge1.y))
normal = edge0 - edge1
normal /= SQRT((normal.x*normal.x) + (normal.y*normal.y))
IF IS_POINT_IN_POLY_2D(in, in.v[j] + normal)
normal = -normal
ENDIF
out.v[j] = in.v[j] + (normal * fMargin)
i = j
j++
k = (k + 1) % in.iVertCount
ENDWHILE
ENDPROC
/*PROC COPY_SCALED_POLY(TEST_POLY& out, TEST_POLY& in, FLOAT fScale = 1.0)
IF in.iVertCount >= TEST_POLY_MAX_VERTS
SCRIPT_ASSERT("COPY_SCALED_POLY: poly has too many vertices")
ENDIF
INT i
IF fScale = 1.0
// Copy all verts
REPEAT in.iVertCount i
out.v[i] += in.v[i]
ENDREPEAT
out.iVertCount = in.iVertCount
ELSE
// Find centre
VECTOR vCentre = <<0, 0, 0>>
REPEAT in.iVertCount i
vCentre += in.v[i]
ENDREPEAT
vCentre.x /= TO_FLOAT(in.iVertCount)
vCentre.y /= TO_FLOAT(in.iVertCount)
// Scale each vertex from the centre point
REPEAT in.iVertCount i
out.v[i] = vCentre + ((in.v[i] - vCentre) * fScale)
ENDREPEAT
out.iVertCount = in.iVertCount
ENDIF
ENDPROC*/
//----------------------
// DEBUG FUNCTIONS
//----------------------
//#IF IS_DEBUG_BUILD
//
/////------------------------------------------------------------------------------
///// FUNCTION:
///// SETUP_TEST_POLY_WIDGETS()
///// PURPOSE:
///// SETS UP WIDGET SO WE CAN DISPLAY TEST POLYS
/////------------------------------------------------------------------------------
//PROC SETUP_TEST_POLY_WIDGETS()
// INT i
// TEXT_LABEL sLabel
//
// iActivePoint = -1
// m_RCAreaWidgetGroup = START_WIDGET_GROUP("Test Poly Editor")
//
// ADD_WIDGET_BOOL("Show Points", bShowDebugPolyPoints)
// ADD_WIDGET_BOOL("Show Final Polygon", bShowDebugPoly)
// ADD_WIDGET_BOOL("Recalculate Polygon", bRecalculateDebugPoly)
//
// START_WIDGET_GROUP("Points")
// REPEAT COUNT_OF(vDebugPolyPoints) i
// sLabel = "Point"
// sLabel += i
// START_WIDGET_GROUP(sLabel)
// ADD_WIDGET_BOOL("Edit Point", bEditPoint[i])
// ADD_WIDGET_VECTOR_SLIDER("Position", vDebugPolyPoints[i], -5000.0, 5000.0, 10.0)
// ADD_WIDGET_BOOL("Reset Point", bResetPoint[i])
// STOP_WIDGET_GROUP()
// ENDREPEAT
// STOP_WIDGET_GROUP()
//
// ADD_WIDGET_BOOL("Dump Polygon To Debug", bPrintDebugPoly)
// ADD_WIDGET_INT_READ_ONLY("Current Point", iActivePoint)
// STOP_WIDGET_GROUP()
//ENDPROC
//
/////------------------------------------------------------------------------------
///// FUNCTION:
///// SETUP_TEST_POLY_WIDGETS()
///// PURPOSE:
///// SETS UP WIDGET SO WE CAN DISPLAY TEST POLYS
/////------------------------------------------------------------------------------
//PROC COPY_TO_DEBUG_TEST_POLY(TEST_POLY& src)
// INT i
// OPEN_TEST_POLY(m_DebugPoly)
// REPEAT COUNT_OF(src.v) i
// IF NOT IS_VECTOR_ZERO(src.v[i])
// ADD_TEST_POLY_VERT(m_DebugPoly, src.v[i])
// ENDIF
// ENDREPEAT
// CLOSE_TEST_POLY(m_DebugPoly)
//ENDPROC
//
/////------------------------------------------------------------------------------
///// FUNCTION:
///// UPDATE_TEST_POLY_WIDGETS()
///// PURPOSE:
///// CALL THIS EVERY FRAME SO THE WIDGETS WORK
/////------------------------------------------------------------------------------
//PROC UPDATE_TEST_POLY_WIDGETS()
// INT i
// INT i2
// INT iLastPoint
// VECTOR tmp
// FLOAT sx, sy
//
// /* handles selecting points in real time
//
// */
//
// i = 0
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF (bEditPoint[i])
// iActivePoint = i
// bEditPoint[i] = FALSE
// ENDIF
// ENDREPEAT
//
// // right button cycles active point
// IF IS_MOUSE_BUTTON_JUST_PRESSED(MB_RIGHT_BTN)
// iActivePoint ++
// IF (iActivePoint >= COUNT_OF(vDebugPolyPoints))
// iActivePoint = 0
// ENDIF
//
// IF IS_VECTOR_ZERO(vDebugPolyPoints[iActivePoint])
// iActivePoint = 0
// ENDIF
// ENDIF
//
//
// // handles dragging active point in real time
// IF (iActivePoint <> -1)
// IF IS_MOUSE_BUTTON_JUST_PRESSED(MB_LEFT_BTN)
//
// IF IS_MOUSE_BUTTON_PRESSED(MB_RIGHT_BTN) AND NOT IS_VECTOR_ZERO(vDebugMousePosition)
// vDebugPolyPoints[iActivePoint] = vDebugMousePosition
// ELSE
// i = 0
// i2 = -1
//
// // check to see if we are near any points
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF (GET_DISTANCE_BETWEEN_COORDS(vDebugMousePosition, vDebugPolyPoints[i], FALSE) < 4.0)
// i2 = i
// ENDIF
// ENDREPEAT
//
// // if so make that point the active point - else create a new point
// IF (i2 <> -1)
// iActivePoint = i2
// ELSE
// i = 0
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF IS_VECTOR_ZERO(vDebugPolyPoints[i]) AND NOT IS_VECTOR_ZERO(vDebugMousePosition)
// vDebugPolyPoints[i] = vDebugMousePosition
// iActivePoint = i
// i = 999999
// ENDIF
// ENDREPEAT
// ENDIF
// ENDIF
// ELIF IS_MOUSE_BUTTON_PRESSED(MB_LEFT_BTN)
// IF IS_MOUSE_BUTTON_PRESSED(MB_RIGHT_BTN) AND NOT IS_VECTOR_ZERO(vDebugMousePosition)
// vDebugPolyPoints[iActivePoint] = vDebugMousePosition
// ENDIF
// ENDIF
// ENDIF
//
//
//
// // handles rendering debug poly
// IF (bShowDebugPolyPoints)
// SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE)
//
// // renders points of poly while editing
// i = 0
// REPEAT COUNT_OF(vDebugPolyPoints) i
// i2 = i + 1
// IF (i2 >= (COUNT_OF(vDebugPolyPoints) - 1))
// i2 = 0
// ENDIF
//
// // draw a sphere at the point and a line going up just incase points are buried.
// tmp = vDebugPolyPoints[i] + <<0, 0, 10.0>>
//
// IF (iActivePoint = i)
// DRAW_DEBUG_SPHERE(vDebugPolyPoints[i], 1.0, 0, 255, 0, 255)
// ELSE
// DRAW_DEBUG_SPHERE(vDebugPolyPoints[i], 1.0)
// ENDIF
//
// DRAW_DEBUG_LINE(vDebugPolyPoints[i], tmp)
// DRAW_DEBUG_LINE(vDebugPolyPoints[i], vDebugPolyPoints[i2])
//
// // show point number
// IF NOT IS_VECTOR_ZERO(vDebugPolyPoints[i])
// IF GET_SCREEN_COORD_FROM_WORLD_COORD(vDebugPolyPoints[i], sx, sy)
// SET_TEXT_SCALE(0.25, 0.25)
// DISPLAY_TEXT_WITH_NUMBER(sx, sy, "NUMBER", i)
// ENDIF
// iLastPoint = i
// ENDIF
//
// ENDREPEAT
//
// DRAW_DEBUG_LINE(vDebugPolyPoints[0], vDebugPolyPoints[iLastPoint])
// ENDIF
//
//
//
// // handle resetting the poly points if the buttons are clicked
// // force recalculate if poly point is clicked
// i = 0
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF (bResetPoint[i])
// bResetPoint[i] = FALSE
// vDebugPolyPoints[i] = <<0, 0, 0>>
// bRecalculateDebugPoly = TRUE
// ENDIF
// ENDREPEAT
//
// // recalculate the poly
// IF (bRecalculateDebugPoly)
// i = 0
// OPEN_TEST_POLY(m_DebugPoly)
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF NOT IS_VECTOR_ZERO(vDebugPolyPoints[i])
// ADD_TEST_POLY_VERT(m_DebugPoly, vDebugPolyPoints[i])
// ENDIF
// ENDREPEAT
// CLOSE_TEST_POLY(m_DebugPoly)
// bRecalculateDebugPoly = FALSE
// ENDIF
//
// // actually display the poly using sam's routine
// IF IS_TEST_POLY_VALID(m_DebugPoly) AND (bShowDebugPoly)
// DISPLAY_POLY2(m_DebugPoly)
// ENDIF
//
// // handle writing debug poly to TTY
// IF (bPrintDebugPoly)
// bPrintDebugPoly = FALSE
//
// SAVE_NEWLINE_TO_DEBUG_FILE()
// SAVE_STRING_TO_DEBUG_FILE("-------------- TEST POLY SCRIPT OUTPUT ---------------------")
// SAVE_NEWLINE_TO_DEBUG_FILE()
//
// SAVE_STRING_TO_DEBUG_FILE("OPEN_TEST_POLY(m_DebugPoly)")
// SAVE_NEWLINE_TO_DEBUG_FILE()
//
// REPEAT COUNT_OF(vDebugPolyPoints) i
// IF NOT IS_VECTOR_ZERO(vDebugPolyPoints[i])
// SAVE_STRING_TO_DEBUG_FILE("ADD_TEST_POLY_VERT(m_DebugPoly, ")
// SAVE_VECTOR_TO_DEBUG_FILE(vDebugPolyPoints[i])
// SAVE_STRING_TO_DEBUG_FILE(")")
// SAVE_NEWLINE_TO_DEBUG_FILE()
// ENDIF
// ENDREPEAT
//
// SAVE_STRING_TO_DEBUG_FILE("CLOSE_TEST_POLY(m_DebugPoly)")
// SAVE_NEWLINE_TO_DEBUG_FILE()
//
// SAVE_STRING_TO_DEBUG_FILE("-------------- END TEST POLY SCRIPT OUTPUT -----------------")
// SAVE_NEWLINE_TO_DEBUG_FILE()
// ENDIF
//
// // get mouse position and use that
// vDebugMousePosition = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS()
//ENDPROC
//
/////------------------------------------------------------------------------------
///// FUNCTION:
///// CLEANUP_TEST_POLY_WIDGETS()
///// PURPOSE:
///// TIDY UP THE TEST POLY WIDGETS
/////------------------------------------------------------------------------------
//PROC CLEANUP_TEST_POLY_WIDGETS()
// IF DOES_WIDGET_GROUP_EXIST(m_RCAreaWidgetGroup)
// DELETE_WIDGET_GROUP(m_RCAreaWidgetGroup)
// ENDIF
//ENDPROC
//#ENDIF