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

1910 lines
73 KiB
Scheme
Executable File

USING "invade_persuade_using.sch"
USING "arcade_games_postfx.sch"
// ------------------------------ HELPERS ------------------------------
/// PURPOSE:
/// Draws a black rectangle over the entire screen
PROC IAP_DRAW_FULL_SCREEN_RECT(RGBA_COLOUR_STRUCT &rgba)
#IF IS_DEBUG_BUILD
IF g_bMinimizeArcadeCabinetDrawing
DRAW_RECT(g_fMinimizeArcadeCabinetCentreX, g_fMinimizeArcadeCabinetCentreY, g_fMinimizeArcadeCabinetCentreScale, g_fMinimizeArcadeCabinetCentreScale, 0, 0, 0, 255)
ELIF !g_bBlockArcadeCabinetDrawing
#ENDIF
DRAW_RECT(cfSCREEN_CENTER, cfSCREEN_CENTER, 1, 1, rgba.iR, rgba.iG, rgba.iB, rgba.iA)
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
ENDPROC
/// PURPOSE:
/// Draws stTextLabel in the center of the screen
PROC IAP_DRAW_CENTER_TEXT(STRING stTextLabel)
//Title Text
SET_TEXT_SCALE(cfIAP_CENTER_TEXT_SCALE, cfIAP_CENTER_TEXT_SCALE)
SET_TEXT_COLOUR(255, 255, 255, 255)
SET_TEXT_CENTRE(TRUE)
SET_TEXT_FONT(FONT_STANDARD)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT(stTextLabel)
END_TEXT_COMMAND_DISPLAY_TEXT(cfSCREEN_CENTER, cfSCREEN_CENTER)
ENDPROC
/// PURPOSE:
/// Returns the alpha for flashing damage effects and text this frame
/// RETURNS:
///
FUNC INT IAP_GET_FLASHING_ALPHA()
RETURN ROUND(ABSF(TAN(TO_FLOAT(GET_GAME_TIMER()))) * 255)
ENDFUNC
/// PURPOSE:
/// Draws the facade at the edges of the screen
PROC IAP_DRAW_FACADE()
ARCADE_CABINET_DRAW_SPRITE("MPInvPersMessages", "facade", cfSCREEN_CENTER, cfSCREEN_CENTER, 1.0, 1.0, 0.0, sIAPData.sColours.rgbaSprite)
ENDPROC
/// PURPOSE:
/// Draws a coloured border around the play area
PROC IAP_DRAW_SCREEN_BORDER(RGBA_COLOUR_STRUCT rgba)
rgba.iA = ROUND(ABSF(TAN(TO_FLOAT(GET_GAME_TIMER()))) * 50) + 150
ARCADE_CABINET_DRAW_SPRITE("MpInvPersHud", "border",
cfSCREEN_CENTER + 0.002604167, cfSCREEN_CENTER, 1.0, 1.0, 0.0, rgba)
ENDPROC
// ------------------------------ TEXT ------------------------------
/// PURPOSE:
/// Draws a number using the pixel font sprites
/// PARAMS:
/// vPos - Position the number string starts or ends at
/// bRightAlign - If the number end at the the vPos or start there
/// bDollarSign - If true a $ will go before the number
/// bSmall - Text drawn at half size
/// iMaxDigits - Number of digits drawn, max = ciIAP_FONT_MAX_DIGITS, 0s will be added to pad number up to this value
/// IF iMaxDigits is set to ciIAP_FONT_DIGIT_COUNT it will show the number exactly
PROC IAP_DRAW_NUMBER_FROM_POS(INT iNumber, VECTOR_2D vPos, RGBA_COLOUR_STRUCT rgba, BOOL bRightAlign = FALSE, BOOL bDollarSign = FALSE, BOOL bSmall = FALSE, INT iMaxDigits = ciIAP_FONT_MAX_DIGITS)
TEXT_LABEL_15 tl15Digits[ciIAP_FONT_MAX_DIGITS]
INT i
INT iCurrentValue = iNumber
INT iCommaBS
VECTOR_2D vScale = INIT_VECTOR_2D(PICK_FLOAT(bSmall, cfIAP_FONT_SCALE_SMALL_X, cfIAP_FONT_SCALE_LARGE_X), PICK_FLOAT(bSmall, cfIAP_FONT_SCALE_SMALL_Y, cfIAP_FONT_SCALE_LARGE_Y))
VECTOR_2D vCommaScale = INIT_VECTOR_2D(PICK_FLOAT(bSmall, cfIAP_FONT_COMMA_SCALE_SMALL_X, cfIAP_FONT_COMMA_SCALE_LARGE_X), PICK_FLOAT(bSmall, cfIAP_FONT_COMMA_SCALE_SMALL_Y, cfIAP_FONT_COMMA_SCALE_LARGE_Y))
BOOL bBailWhenAllDrawn = (iMaxDigits = ciIAP_FONT_DIGIT_COUNT)
IF bBailWhenAllDrawn
iMaxDigits = ciIAP_FONT_MAX_DIGITS
ENDIF
FOR i = 0 TO ciIAP_FONT_MAX_DIGITS - 1
tl15Digits[i] = "number_"
tl15Digits[i] += (iCurrentValue % 10)
iCurrentValue /=10
IF iCurrentValue > 0
AND (i + 1) % 3 = 0
SET_BIT(iCommaBS, i)
ENDIF
IF bBailWhenAllDrawn
AND iCurrentValue = 0
iMaxDigits = i + 1
BREAKLOOP
ENDIF
ENDFOR
FLOAT fCurrentX = vPos.x
IF bRightAlign
fCurrentX -= (vScale.x/2)
FOR i = 0 TO iMaxDigits - 1
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", tl15Digits[i], fCurrentX, vPos.y, vScale.x, vScale.y, 0.0, rgba)
IF IS_BIT_SET(iCommaBS, i)
fCurrentX -= (vCommaScale.x)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "comma", fCurrentX, vPos.y, vCommaScale.x, vCommaScale.y, 0.0, rgba)
ENDIF
fCurrentX -= (vScale.x)
ENDFOR
IF bDollarSign
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "dollar", fCurrentX, vPos.y, vScale.x, vScale.y, 0.0, rgba)
ENDIF
ELSE
fCurrentX += (vScale.x/2)
IF bDollarSign
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "dollar", fCurrentX, vPos.y, vScale.x, vScale.y, 0.0, rgba)
fCurrentX += (vScale.x)
ENDIF
FOR i = iMaxDigits - 1 TO 0 STEP -1
IF IS_BIT_SET(iCommaBS, i)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "comma", fCurrentX, vPos.y, vCommaScale.x, vCommaScale.y, 0.0, rgba)
fCurrentX += (vCommaScale.x)
ENDIF
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", tl15Digits[i], fCurrentX, vPos.y, vScale.x, vScale.y, 0.0, rgba)
fCurrentX += (vScale.x)
ENDFOR
ENDIF
ENDPROC
// ------------------------------ HUD ------------------------------
/// PURPOSE:
/// Draws the lives display on the top HUD
PROC IAP_DRAW_LIVES_HUD()
VECTOR_2D vScale = INIT_VECTOR_2D(cfIAP_LIVES_HUD_SCALE_X, cfIAP_LIVES_HUD_SCALE_Y)
VECTOR_2D vPos = INIT_VECTOR_2D(cfIAP_LIVES_HUD_POS_X, cfIAP_HUD_Y)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "lives", vPos.x, vPos.y, vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
INT iLives = sIAPData.sPlayerTank.iLives
IF sIAPData.sPlayerTank.iLives < 0
iLives = 0
ENDIF
IAP_DRAW_NUMBER_FROM_POS(iLives, INIT_VECTOR_2D(vPos.x + cfIAP_LIVES_TEXT_OFFSET_X, vPos.y + cfIAP_LIVES_TEXT_OFFSET_Y), sIAPData.sColours.rgbaHudText, FALSE, FALSE, FALSE, 2)
ENDPROC
/// PURPOSE:
/// Draws the health display on the top HUD
PROC IAP_DRAW_HEALTH_HUD()
VECTOR_2D vScale = INIT_VECTOR_2D(cfIAP_HEALTH_HUD_SCALE_X, cfIAP_HEALTH_HUD_SCALE_Y)
VECTOR_2D vPos = INIT_VECTOR_2D(cfIAP_HEALTH_HUD_POS_X, cfIAP_HUD_Y)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "health", vPos.x, vPos.y, vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
IF sIAPData.sPlayerTank.iDisplayHealth < sIAPData.sPlayerTank.iHealth
sIAPData.sPlayerTank.iDisplayHealth = CLAMP_INT(sIAPData.sPlayerTank.iDisplayHealth + sIAPData.iUpdateFrames30FPS, 0, sIAPData.sPlayerTank.iHealth)
ELIF sIAPData.sPlayerTank.iDisplayHealth > sIAPData.sPlayerTank.iHealth
sIAPData.sPlayerTank.iDisplayHealth = CLAMP_INT(sIAPData.sPlayerTank.iDisplayHealth - sIAPData.iUpdateFrames30FPS, sIAPData.sPlayerTank.iHealth, ciIAP_MAX_HEALTH)
ENDIF
INT i
IF NOT IS_BIT_SET(sIAPData.sPlayerTank.iPlayerTankBitset, ciIAP_PLAYER_TANK_BS_SHIELD_ACTIVE)
RGBA_COLOUR_STRUCT healthRgba
IF sIAPData.sPlayerTank.iDisplayHealth > 1
INIT_RGBA_STRUCT(healthRgba, 154, 255, 0, 255)
ELSE
INIT_RGBA_STRUCT(healthRgba, 246, 8, 21, 255)
ENDIF
vPos.x = cfIAP_HEALTH_SEGMENT_START_POS_X
vScale = INIT_VECTOR_2D(cfIAP_HEALTH_SEGMENT_HUD_SCALE_X, cfIAP_HEALTH_SEGMENT_HUD_SCALE_Y)
FOR i = 0 TO sIAPData.sPlayerTank.iDisplayHealth - 1
FLOAT fPosX = vPos.x + (i * cfIAP_HEALTH_SEGMENT_OFFSET_X) + (vScale.x / 2)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "healthsegment", fPosX, vPos.y, vScale.x, vScale.y, 0.0, healthRgba)
ENDFOR
ELSE
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "shield_ui", cfIAP_HEALTH_SHIELD_HUD_POS_X, vPos.y, cfIAP_HEALTH_SHIELD_HUD_SCALE_X, cfIAP_HEALTH_SHIELD_HUD_SCALE_Y, 0.0, sIAPData.sColours.rgbaSprite)
ENDIF
ENDPROC
/// PURPOSE:
/// Draws the score display on the top HUD
PROC IAP_DRAW_SCORE_HUD()
VECTOR_2D vScale = INIT_VECTOR_2D(cfIAP_SCORE_HUD_SCALE_X, cfIAP_SCORE_HUD_SCALE_Y)
VECTOR_2D vPos = INIT_VECTOR_2D(cfIAP_SCORE_HUD_POS_X, cfIAP_HUD_Y)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "score", vPos.x, vPos.y, vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
IAP_DRAW_NUMBER_FROM_POS(sIAPData.iScoreToShow, INIT_VECTOR_2D(cfIAP_LIVES_TEXT_WRAP_MAX, vPos.y + cfIAP_SCORE_TEXT_OFFSET_Y), sIAPData.sColours.rgbaHudText, TRUE, FALSE, FALSE, ciIAP_FONT_DIGIT_COUNT)
ENDPROC
/// PURPOSE:
/// Draws the distance display on the top HUD
PROC IAP_DRAW_DISTANCE_HUD()
VECTOR_2D vScale = INIT_VECTOR_2D(cfIAP_DISTANCE_HUD_SCALE_X, cfIAP_DISTANCE_HUD_SCALE_Y)
VECTOR_2D vPos = INIT_VECTOR_2D(cfIAP_DISTANCE_HUD_POS_X, cfIAP_HUD_Y)
TEXT_LABEL_63 tl63Sprite = "distance"
IF sIAPData.sCurrentStageData.fStageDistance = ciIAP_STAGE_INFINITE_LENGTH
tl63Sprite += "_inf"
ENDIF
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", tl63Sprite, vPos.x, vPos.y, vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
INT iDistanceTravelled = FLOOR(sIAPData.fDistanceTravelled / cfIAP_DISTANCE_CONVERSION)
IF sIAPData.eCurrentStage = IAP_STAGE_MOON
IAP_DRAW_NUMBER_FROM_POS(iDistanceTravelled * 1000, INIT_VECTOR_2D(vPos.x + cfIAP_DISTANCE_TEXT_BEST_OFFSET_X, vPos.y + cfIAP_DISTANCE_TEXT_OFFSET_Y), sIAPData.sColours.rgbaHudText, TRUE, FALSE, TRUE, ciIAP_FONT_DIGIT_COUNT)
IAP_DRAW_NUMBER_FROM_POS(sIAPData.iCachedMaxMoonDistance * 1000, INIT_VECTOR_2D(vPos.x + cfIAP_DISTANCE_TEXT_OFFSET_X, vPos.y + cfIAP_DISTANCE_TEXT_OFFSET_Y), sIAPData.sColours.rgbaHudText, TRUE, FALSE, TRUE, ciIAP_FONT_DIGIT_COUNT)
ELSE
IAP_DRAW_NUMBER_FROM_POS(iDistanceTravelled * 1000, INIT_VECTOR_2D(vPos.x + cfIAP_DISTANCE_TEXT_OFFSET_X, vPos.y + cfIAP_DISTANCE_TEXT_OFFSET_Y), sIAPData.sColours.rgbaHudText, TRUE, FALSE, TRUE, ciIAP_FONT_DIGIT_COUNT)
ENDIF
IF sIAPData.sCurrentStageData.fStageDistance != ciIAP_STAGE_INFINITE_LENGTH
FLOAT fAlpha = (sIAPData.fDistanceTravelled / cfIAP_DISTANCE_CONVERSION) / sIAPData.sCurrentStageData.fStageDistance
IF fAlpha > 1.0
fAlpha = 1.0
ENDIF
FLOAT fRectX = LERP_FLOAT(vPos.x + cfIAP_DISTANCE_RECT_POS_X - (cfIAP_DISTANCE_BAR_HUD_SCALE_X/ 2), vPos.x + cfIAP_DISTANCE_RECT_POS_X, fAlpha)
FLOAT fRectScaleX = LERP_FLOAT(0, cfIAP_DISTANCE_BAR_HUD_SCALE_X, fAlpha)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersHud", "distancearrow", fRectX + (fRectScaleX/2), vPos.y, cfIAP_DISTANCE_ARROW_HUD_SCALE_X, cfIAP_DISTANCE_ARROW_HUD_SCALE_Y, 0.0, sIAPData.sColours.rgbaSprite)
RGBA_COLOUR_STRUCT rgba
INIT_RGBA_STRUCT(rgba, 154, 255, 0, 125)
DRAW_RECT_FROM_VECTOR_2D(INIT_VECTOR_2D(fRectX, vPos.y + cfIAP_DISTANCE_RECT_POS_Y), INIT_VECTOR_2D(fRectScaleX, cfIAP_DISTANCE_BAR_HUD_SCALE_Y), rgba)
ENDIF
ENDPROC
/// PURPOSE:
/// Draws the top HUD bar
PROC IAP_DRAW_HUD()
IAP_DRAW_LIVES_HUD()
IAP_DRAW_HEALTH_HUD()
IAP_DRAW_SCORE_HUD()
IAP_DRAW_DISTANCE_HUD()
ENDPROC
// ------------------------------ FLOATING TEXT ------------------------------
PROC IAP_DRAW_FLOATING_TEXT_AT_POSITION(STRING stLabel, FLOAT fX, FLOAT fY, INT iIntToDisplay = HIGHEST_INT)
INT fTextAlpha = IAP_GET_FLASHING_ALPHA()
SET_TEXT_SCALE(0.5, 0.5)
SET_TEXT_COLOUR(255, 255, 255, fTextAlpha)
SET_TEXT_CENTRE(TRUE)
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
IF fTextAlpha > 200
SET_TEXT_DROP_SHADOW()
ENDIF
BEGIN_TEXT_COMMAND_DISPLAY_TEXT(stLabel)
IF iIntToDisplay != HIGHEST_INT
ADD_TEXT_COMPONENT_INTEGER(iIntToDisplay)
ENDIF
END_TEXT_COMMAND_DISPLAY_TEXT(fX, fY)
ENDPROC
/// PURPOSE:
/// Draws flashign floating text above the player's tank
PROC IAP_DRAW_ABOVE_PLAYER_TEXT()
IF NATIVE_TO_INT(GET_NETWORK_TIME()) > sIAPData.sPlayerTank.sAbovePlayerText.iStartTime + ciIAP_ABOVE_PLAYER_TEXT_DURATION
EXIT
ENDIF
FLOAT fAlpha = TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME()) - sIAPData.sPlayerTank.sAbovePlayerText.iStartTime) / ciIAP_ABOVE_PLAYER_TEXT_DURATION
IAP_DRAW_FLOATING_TEXT_AT_POSITION(sIAPData.sPlayerTank.sAbovePlayerText.tl63Text,
sIAPData.sPlayerTank.vPosition.x + cfIAP_TURRET_OFFSET_X,
INTERP_FLOAT(sIAPData.sPlayerTank.vPosition.y + cfIAP_ABOVE_PLAYER_TEXT_START_OFFSET, sIAPData.sPlayerTank.vPosition.y + cfIAP_ABOVE_PLAYER_TEXT_END_OFFSET, fAlpha, INTERPTYPE_SMOOTHSTEP))
ENDPROC
/// PURPOSE:
/// Draws all score text at their onscreen positions
PROC IAP_DRAW_SCORE_TEXT()
INT i
FOR i = 0 TO ciIAP_MAX_SCORE_TEXT - 1
IF NATIVE_TO_INT(GET_NETWORK_TIME()) > sIAPData.sScoreText[i].iStartTime + ciIAP_SCORE_TEXT_DURATION
RELOOP
ENDIF
FLOAT fAlpha = TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME()) - sIAPData.sScoreText[i].iStartTime) / ciIAP_SCORE_TEXT_DURATION
FLOAT fX = sIAPData.sScoreText[i].vPos.x
IF fX < (cfIAP_FACADE_WIDTH * 1.1)
RELOOP
ENDIF
IAP_DRAW_FLOATING_TEXT_AT_POSITION("IAP_SCORE", fX,
INTERP_FLOAT(sIAPData.sScoreText[i].vPos.y + cfIAP_SCORE_TEXT_START_OFFSET, sIAPData.sScoreText[i].vPos.y + cfIAP_SCORE_TEXT_END_OFFSET, fAlpha, INTERPTYPE_SMOOTHSTEP),
sIAPData.sScoreText[i].iScore)
ENDFOR
ENDPROC
// ------------------------------ STAGE ------------------------------
/// PURPOSE:
/// Draws the current stage
PROC IAP_DRAW_STAGE()
INT i
FLOAT fXOffset
//Background Colour
IAP_DRAW_FULL_SCREEN_RECT(sIAPData.sCurrentStageData.rgbaStageBackground)
FOR i = 0 TO sIAPData.sCurrentStageData.iMaxActiveBackgroundSprites - 1
fXOffset = sIAPData.sCurrentStageData.vBackgroundSpriteScale.x * i
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sCurrentStageData.stBackgroundSprite, sIAPData.sParallax.fBackgroundPosX + fXOffset, sIAPData.sCurrentStageData.fBackgroundYPos + cfIAP_BACKGROUND_Y_OFFSET,
sIAPData.sCurrentStageData.vBackgroundSpriteScale.x, sIAPData.sCurrentStageData.vBackgroundSpriteScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
FOR i = 0 TO sIAPData.sCurrentStageData.iMaxActiveMidground1Sprites - 1
fXOffset = sIAPData.sCurrentStageData.vMidground1SpriteScale.x * i
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sCurrentStageData.stMidground1Sprite, sIAPData.sParallax.fMidground1PosX + fXOffset, sIAPData.sCurrentStageData.fMidground1YPos + cfIAP_MIDGROUND1_Y_OFFSET,
sIAPData.sCurrentStageData.vMidground1SpriteScale.x, sIAPData.sCurrentStageData.vMidground1SpriteScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
FOR i = 0 TO sIAPData.sCurrentStageData.iMaxActiveMidground2Sprites - 1
fXOffset = sIAPData.sCurrentStageData.vMidground2SpriteScale.x * i
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sCurrentStageData.stMidground2Sprite, sIAPData.sParallax.fMidground2PosX + fXOffset, sIAPData.sCurrentStageData.fMidground2YPos + cfIAP_MIDGROUND2_Y_OFFSET,
sIAPData.sCurrentStageData.vMidground2SpriteScale.x, sIAPData.sCurrentStageData.vMidground2SpriteScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
FOR i = 0 TO sIAPData.sCurrentStageData.iMaxActiveMidground3Sprites - 1
fXOffset = sIAPData.sCurrentStageData.vMidground3SpriteScale.x * i
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sCurrentStageData.stMidground3Sprite, sIAPData.sParallax.fMidground3PosX + fXOffset, sIAPData.sCurrentStageData.fMidground3YPos + cfIAP_MIDGROUND3_Y_OFFSET,
sIAPData.sCurrentStageData.vMidground3SpriteScale.x, sIAPData.sCurrentStageData.vMidground3SpriteScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
FOR i = 0 TO sIAPData.sCurrentStageData.iMaxActiveForegroundSprites - 1
IF sIAPData.sParallax.iActiveForegroundSpriteIndexes[i] = ciIAP_PARALLAX_PITFALL
VECTOR_2D vScale = sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_PITFALL_INDEX())].vSpriteScale
IF IAP_IS_RECT_COMPLETELY_OUTSIDE_OF_GAME_AREA(INIT_VECTOR_2D(sIAPData.sParallax.fForegroundPosX[i], sIAPData.sCurrentStageData.fForegroundYPos), vScale)
RELOOP
ENDIF
#IF IS_DEBUG_BUILD
IF sIAPData.sDebugStruct.bDrawCollisionDebug
FLOAT fX = (sIAPData.sParallax.fForegroundPosX[i] - (vScale.x/2)) + IAP_GET_CURRENT_STAGE_PITFALL_GROUND_WIDTH_LEFT()
DRAW_DEBUG_LINE_2D_FROM_VECTOR_2D(INIT_VECTOR_2D(fX, sIAPData.sCurrentStageData.fBaseY), INIT_VECTOR_2D(fX, 1.0), sIAPData.sColours.rgbaDamage)
fX = (sIAPData.sParallax.fForegroundPosX[i] + (vScale.x / 2)) - IAP_GET_CURRENT_STAGE_PITFALL_GROUND_WIDTH_RIGHT()
DRAW_DEBUG_LINE_2D_FROM_VECTOR_2D(INIT_VECTOR_2D(fX, sIAPData.sCurrentStageData.fBaseY), INIT_VECTOR_2D(fX, 1.0), sIAPData.sColours.rgbaDamage)
ENDIF
#ENDIF
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_PITFALL_INDEX())].stSpritePrefix, sIAPData.sParallax.fForegroundPosX[i], sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_PITFALL_INDEX())].fBaseYOffset,
vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
RELOOP
ENDIF
IF sIAPData.sParallax.iActiveForegroundSpriteIndexes[i] = ciIAP_PARALLAX_RAISED_LEDGE
VECTOR_2D vScale = sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_LEDGE_INDEX())].vSpriteScale
IF IAP_IS_RECT_COMPLETELY_OUTSIDE_OF_GAME_AREA(INIT_VECTOR_2D(sIAPData.sParallax.fForegroundPosX[i], sIAPData.sCurrentStageData.fForegroundYPos), vScale)
RELOOP
ENDIF
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_LEDGE_INDEX())].stSpritePrefix, sIAPData.sParallax.fForegroundPosX[i], sIAPData.sObjectData[ENUM_TO_INT(IAP_GET_CURRENT_STAGE_LEDGE_INDEX())].fBaseYOffset,
vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
RELOOP
ENDIF
IF IAP_IS_RECT_COMPLETELY_OUTSIDE_OF_GAME_AREA(INIT_VECTOR_2D(sIAPData.sParallax.fForegroundPosX[i], sIAPData.sCurrentStageData.fForegroundYPos), sIAPData.sCurrentStageData.vForegroundSpriteScale)
RELOOP
ENDIF
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, sIAPData.sCurrentStageData.stForegroundSprite, sIAPData.sParallax.fForegroundPosX[i], sIAPData.sCurrentStageData.fForegroundYPos,
sIAPData.sCurrentStageData.vForegroundSpriteScale.x, sIAPData.sCurrentStageData.vForegroundSpriteScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
ENDPROC
/// PURPOSE:
/// Draws the weather effects over the stage if the current stage supports them
PROC IAP_DRAW_WEATHER()
IF NOT IAP_DOES_CURRENT_STAGE_HAVE_WEATHER_EFFECTS()
EXIT
ENDIF
INT i, j
FOR i = 0 TO ciIAP_MAX_BLIZZARD_SPRITES_X - 1
FOR j = 0 TO ciIAP_MAX_BLIZZARD_SPRITES_Y - 1
ARCADE_CABINET_DRAW_SPRITE(sIAPData.stLoadedStageTextureDictionary, "blizzard",
sIAPData.vBaseWeatherPos.x + (i * cfIAP_WEATHER_SPRITE_SCALE_X) + (cfIAP_WEATHER_SPRITE_SCALE_X / 2),
sIAPData.vBaseWeatherPos.y - (j * cfIAP_WEATHER_SPRITE_SCALE_Y) - (cfIAP_WEATHER_SPRITE_SCALE_Y / 2),
cfIAP_WEATHER_SPRITE_SCALE_X, cfIAP_WEATHER_SPRITE_SCALE_Y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
ENDFOR
ENDPROC
/// PURPOSE:
/// Interps between rgba0 and rgba1 by fAlpha
FUNC RGBA_COLOUR_STRUCT IAP_INTERP_COLOUR(RGBA_COLOUR_STRUCT rgba0, RGBA_COLOUR_STRUCT rgba1, FLOAT fAlpha)
rgba0.iR = ROUND(TO_FLOAT(rgba1.iR - rgba0.iR) * fAlpha + rgba0.iR)
rgba0.iG = ROUND(TO_FLOAT(rgba1.iG - rgba0.iG) * fAlpha + rgba0.iG)
rgba0.iB = ROUND(TO_FLOAT(rgba1.iB - rgba0.iB) * fAlpha + rgba0.iB)
rgba0.iA = ROUND(TO_FLOAT(rgba1.iA - rgba0.iA) * fAlpha + rgba0.iA)
RETURN rgba0
ENDFUNC
// ------------------------------ EXPLOSIONS ------------------------------
/// PURPOSE:
/// Returns the sprite prefix for the explosion type
FUNC STRING IAP_GET_EXPLOSION_SPRITE(IAP_EXPLOSION eExplosionType)
SWITCH eExplosionType
CASE IAP_EXPLOSION_MEDIUM
RETURN "explosion_med"
CASE IAP_EXPLOSION_SMOKE
RETURN "tank_smoke"
ENDSWITCH
RETURN "INVALID EXPLOSION"
ENDFUNC
/// PURPOSE:
/// Returns the max anim frame for the explosion type
FUNC INT IAP_GET_EXPLOSION_MAX_ANIM_FRAME(IAP_EXPLOSION eExplosionType)
SWITCH eExplosionType
CASE IAP_EXPLOSION_MEDIUM
RETURN ciIAP_EXPLOSION_FRAMES
CASE IAP_EXPLOSION_SMOKE
RETURN ciIAP_SMOKE_FRAMES
ENDSWITCH
RETURN 0
ENDFUNC
/// PURPOSE:
/// Returns the sprite scale for the explosion type
FUNC VECTOR_2D IAP_GET_EXPLOSION_SCALE(IAP_EXPLOSION eExplosionType)
SWITCH eExplosionType
CASE IAP_EXPLOSION_MEDIUM
RETURN INIT_VECTOR_2D(cfIAP_EXPLOSION_SPRITE_SCALE_X / 2, cfIAP_EXPLOSION_SPRITE_SCALE_Y / 2)
CASE IAP_EXPLOSION_SMOKE
RETURN INIT_VECTOR_2D(0.020833, 0.037037)
ENDSWITCH
RETURN INIT_VECTOR_2D(-1, -1)
ENDFUNC
/// PURPOSE:
/// Draws all the explosions on screen
PROC IAP_DRAW_EXPLOSIONS()
INT i
FOR i = 0 TO ciIAP_MAX_EXPLOSIONS - 1
IF sIAPData.sExplosions[i].iAnimFrame <= -1
RELOOP
ENDIF
TEXT_LABEL_63 tl63Sprite = IAP_GET_EXPLOSION_SPRITE(sIAPData.sExplosions[i].eExplosionType)
VECTOR_2D vScale = IAP_GET_EXPLOSION_SCALE(sIAPData.sExplosions[i].eExplosionType)
INT iMaxFrames = IAP_GET_EXPLOSION_MAX_ANIM_FRAME(sIAPData.sExplosions[i].eExplosionType)
tl63Sprite += (sIAPData.sExplosions[i].iAnimFrame + 1)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63Sprite,
sIAPData.sExplosions[i].vPosition.x, sIAPData.sExplosions[i].vPosition.y,
vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
sIAPData.sExplosions[i].iAnimFrame += sIAPData.iUpdateFrames15FPS
IF sIAPData.sExplosions[i].iAnimFrame >= iMaxFrames
sIAPData.sExplosions[i].iAnimFrame = -1
ENDIF
ENDFOR
ENDPROC
/// PURPOSE:
/// Draws a pattern on the screen with explosions
PROC IAP_DRAW_NUKE_EXPLOSIONS(FLOAT fAlpha)
IF fAlpha < 0.8
sIAPData.iNukeAnimFrame = 0
ELIF sIAPData.iNukeAnimFrame >= IAP_GET_EXPLOSION_MAX_ANIM_FRAME(IAP_EXPLOSION_MEDIUM)
EXIT
ENDIF
//Star
VECTOR_2D vScale = MULTIPLY_VECTOR_2D(IAP_GET_EXPLOSION_SCALE(IAP_EXPLOSION_MEDIUM), 2.0)
vScale.x = INTERP_FLOAT(0, vScale.x, fAlpha, INTERPTYPE_ACCEL)
vScale.y = INTERP_FLOAT(0, vScale.y, fAlpha, INTERPTYPE_ACCEL)
TEXT_LABEL_63 tl63Sprite = IAP_GET_EXPLOSION_SPRITE(IAP_EXPLOSION_MEDIUM)
tl63Sprite += (sIAPData.iNukeAnimFrame + 1)
VECTOR_2D vStarPoints[10]
//Top
vStarPoints[0] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 0) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( -460) * (1/cfBASE_SCREEN_HEIGHT)))
//Top Right
vStarPoints[1] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 120) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( -120) * (1/cfBASE_SCREEN_HEIGHT)))
//Right Point
vStarPoints[2] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 480) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( -110) * (1/cfBASE_SCREEN_HEIGHT)))
//Mid Right
vStarPoints[3] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 195) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( 90) * (1/cfBASE_SCREEN_HEIGHT)))
//Bottom Right Point
vStarPoints[4] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 300) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( 460) * (1/cfBASE_SCREEN_HEIGHT)))
//Bottom
vStarPoints[5] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( 0) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +((255) * (1/cfBASE_SCREEN_HEIGHT)))
//Bottom Left Point
vStarPoints[6] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( -300) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( 460) * (1/cfBASE_SCREEN_HEIGHT)))
//Mid Left
vStarPoints[7] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( -195) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( 90) * (1/cfBASE_SCREEN_HEIGHT)))
//Left Point
vStarPoints[8] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( -480) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( -110) * (1/cfBASE_SCREEN_HEIGHT)))
//Top Left
vStarPoints[9] = INIT_VECTOR_2D(cfSCREEN_CENTER +(( -120) * (1/cfBASE_SCREEN_WIDTH)), cfSCREEN_CENTER +(( -120) * (1/cfBASE_SCREEN_HEIGHT)))
VECTOR_2D vScreenCenter = INIT_VECTOR_2D(cfSCREEN_CENTER, cfSCREEN_CENTER)
INT i
FOR i = 0 TO COUNT_OF(vStarPoints) - 1
VECTOR_2D vPos = LERP_VECTOR_2D(vScreenCenter, vStarPoints[i], fAlpha)
vPos.x = INTERP_FLOAT(vScreenCenter.x, vStarPoints[i].x, CLAMP(fAlpha, 0.0, 0.75), INTERPTYPE_DECEL)
vPos.y = INTERP_FLOAT(vScreenCenter.y, vStarPoints[i].y, CLAMP(fAlpha, 0.0, 0.75), INTERPTYPE_DECEL)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63Sprite,
vPos.x, vPos.y, vScale.x, vScale.y, 0.0, sIAPData.sColours.rgbaSprite)
ENDFOR
IF fAlpha >= 0.8
sIAPData.iNukeAnimFrame += sIAPData.iUpdateFrames15FPS
ENDIF
ENDPROC
/// PURPOSE:
/// Draws the nuke effect over the stage if active
PROC IAP_DRAW_NUKE()
IF NOT IAP_IS_NUKE_ACTIVE()
EXIT
ENDIF
FLOAT fAlpha
RGBA_COLOUR_STRUCT rgba
IF NOT HAS_NET_TIMER_EXPIRED(sIAPData.tdNukeTimer, ciIAP_PICKUP_NUKE_START_DURATION)
fAlpha = TO_FLOAT(GET_NET_TIMER_DIFFERENCE_WITH_CURRENT_TIME(sIAPData.tdNukeTimer)) / ciIAP_PICKUP_NUKE_START_DURATION
rgba = IAP_INTERP_COLOUR(sIAPData.sColours.rgbaDamage, sIAPData.sColours.rgbaSprite, fAlpha)
rgba.iA = ROUND(INTERP_FLOAT(0, 255, fAlpha, INTERPTYPE_ACCEL))
IAP_DRAW_FULL_SCREEN_RECT(rgba)
IAP_DRAW_NUKE_EXPLOSIONS(fAlpha)
ELSE
fAlpha = TO_FLOAT(GET_NET_TIMER_DIFFERENCE_WITH_CURRENT_TIME(sIAPData.tdNukeTimer) - ciIAP_PICKUP_NUKE_START_DURATION) / ciIAP_PICKUP_NUKE_DURATION
rgba = IAP_INTERP_COLOUR(sIAPData.sColours.rgbaSprite, sIAPData.sColours.rgbaDamage, fAlpha)
rgba.iA = ROUND(INTERP_FLOAT(255, 0, fAlpha, INTERPTYPE_DECEL))
IAP_DRAW_FULL_SCREEN_RECT(rgba)
IAP_DRAW_NUKE_EXPLOSIONS(1.0)
ENDIF
ENDPROC
// ------------------------------ PLAYER TANK ------------------------------
/// PURPOSE:
/// Draws the player's tank exploding
PROC IAP_DRAW_PLAYER_TANK_EXPLOSION()
IF sIAPData.sPlayerTank.iTankBaseAnimFrame >= ciIAP_TANK_EXPLOSION_ANIM_FRAMES
EXIT
ENDIF
IAP_DRAW_SCREEN_BORDER(sIAPData.sColours.rgbaDamage)
TEXT_LABEL_63 tl63Sprite = "tank_death"
tl63Sprite += (sIAPData.sPlayerTank.iTankBaseAnimFrame + 1)
ARCADE_CABINET_DRAW_SPRITE(IAP_GET_PLAYER_TEXTURE_DICT(), tl63Sprite,
sIAPData.sPlayerTank.vPosition.x, sIAPData.sPlayerTank.vPosition.y + cfIAP_PLAYER_TANK_EXPLOSION_OFFSET_Y,
cfIAP_PLAYER_TANK_EXPLOSION_SCALE_X, cfIAP_PLAYER_TANK_EXPLOSION_SCALE_Y, 0.0, sIAPData.sColours.rgbaSprite)
ENDPROC
/// PURPOSE:
/// Returns true if the player is flashing due to respawning, damage or healing
FUNC BOOL IAP_SHOULD_PLAYER_TANK_FLASH()
RETURN sIAPData.sPlayerTank.iLastDamagedTime + ciIAP_PLAYER_DAMAGE_RED_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
OR sIAPData.sPlayerTank.iLastHealedTime + ciIAP_PLAYER_HEAL_GREEN_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
OR sIAPData.sPlayerTank.iRespawnTime + ciIAP_PLAYER_RESPAWN_INVULN_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
ENDFUNC
/// PURPOSE:
/// Returns the scale of the current player tank body sprite
FUNC VECTOR_2D IAP_GET_PLAYER_TANK_SPRITE_SCALE()
IF IAP_IS_PLAYER_TANK_IN_AIR()
RETURN INIT_VECTOR_2D(cfIAP_PLAYER_TANK_JUMP_SCALE_X, cfIAP_PLAYER_TANK_JUMP_SCALE_Y)
ELSE
RETURN INIT_VECTOR_2D(cfIAP_PLAYER_TANK_SCALE_X, cfIAP_PLAYER_TANK_SCALE_Y)
ENDIF
ENDFUNC
/// PURPOSE:
/// Draws the shield sprite behind the player tank
PROC IAP_DRAW_PLAYER_TANK_SHIELD(RGBA_COLOUR_STRUCT rgba)
TEXT_LABEL_63 tl63ShieldSprite = "tank_shield"
tl63ShieldSprite += (sIAPData.sPlayerTank.iTankBaseAnimFrame + 1)
FLOAT fShieldYOffset = PICK_FLOAT(IAP_IS_PLAYER_TANK_IN_AIR(), cfIAP_SHIELD_OFFSET_JUMPING_Y, cfIAP_SHIELD_OFFSET_DEFAULT_Y)
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63ShieldSprite,
sIAPData.sPlayerTank.vPosition.x + cfIAP_SHIELD_OFFSET_X, sIAPData.sPlayerTank.vPosition.y + fShieldYOffset,
cfIAP_SHIELD_SCALE_X, cfIAP_SHIELD_SCALE_Y, 0.0, rgba)
ENDPROC
/// PURPOSE:
/// Returns the current sprite including anim frame for the player tank's turret
FUNC TEXT_LABEL_63 IAP_GET_PLAYER_TANK_TURRET_SPRITE()
TEXT_LABEL_63 tl63Turret
SWITCH sIAPData.sPlayerTank.eWeaponType
CASE IAP_PLAYER_WEAPON_DEFAULT
tl63Turret = "turret_fire"
tl63Turret += (sIAPData.sPlayerTank.iTankShootAnimFrame + 1)
BREAK
CASE IAP_PLAYER_WEAPON_FLAMETHROWER
tl63Turret = "turret_flame"
IF sIAPData.sPlayerTank.eTurretState = IAP_PLAYER_TURRET_STATE_SHOOTING
tl63Turret += "2"
ELSE
tl63Turret += "1"
ENDIF
BREAK
CASE IAP_PLAYER_WEAPON_ROCKET_LAUNCHER
tl63Turret = "turret_rocket"
tl63Turret += (sIAPData.sPlayerTank.iTankShootAnimFrame + 1)
BREAK
CASE IAP_PLAYER_WEAPON_PLASMA
tl63Turret += "turret_beam"
IF sIAPData.sPlayerTank.eTurretState = IAP_PLAYER_TURRET_STATE_SHOOTING
tl63Turret += "_fire"
tl63Turret += (sIAPData.sPlayerTank.iTankShootAnimFrame + 1)
ENDIF
BREAK
ENDSWITCH
RETURN tl63Turret
ENDFUNC
/// PURPOSE:
/// Draws the player tank's turret
PROC IAP_DRAW_PLAYER_TANK_TURRET(RGBA_COLOUR_STRUCT rgba)
FLOAT fJumpOffset = PICK_FLOAT(IAP_IS_PLAYER_TANK_IN_AIR(), cfIAP_PLAYER_TANK_JUMP_SPRITE_OFFSET_Y, 0.0)
VECTOR_2D vTurretCenter = INIT_VECTOR_2D(sIAPData.sPlayerTank.vPosition.x + cfIAP_TURRET_OFFSET_X, sIAPData.sPlayerTank.vPosition.y + cfIAP_TURRET_SPRITE_OFFSET_Y + fJumpOffset)
vTurretCenter.x = ((vTurretCenter.x * cfBASE_SCREEN_WIDTH) - ((cfBASE_SCREEN_WIDTH - cfBASE_SCREEN_HEIGHT) / 2)) / cfBASE_SCREEN_HEIGHT
VECTOR_2D vTurretSpriteCenter = ROTATE_VECTOR_2D_AROUND_VECTOR_2D(vTurretCenter, ADD_VECTOR_2D(vTurretCenter, INIT_VECTOR_2D(cfIAP_TURRET_SPRITE_OFFSET_X, 0)), sIAPData.sPlayerTank.iTurretDirection * cfIAP_TURRET_DIRECTION_INCREMENT)
TEXT_LABEL_63 tl63Sprite = IAP_GET_PLAYER_TANK_TURRET_SPRITE()
ARCADE_CABINET_DRAW_SPRITE_ROTATED(IAP_GET_PLAYER_TEXTURE_DICT(), tl63Sprite,
vTurretSpriteCenter.x, vTurretSpriteCenter.y,
cfIAP_TURRET_SCALE_X, cfIAP_TURRET_SCALE_Y,
sIAPData.sPlayerTank.iTurretDirection * cfIAP_TURRET_DIRECTION_INCREMENT, rgba)
ENDPROC
//// PURPOSE:
/// Draws the player tank and turret
PROC IAP_DRAW_PLAYER_TANK()
IF sIAPData.sPlayerTank.eTankState = IAP_PLAYER_TANK_STATE_EXPLODING
IAP_DRAW_PLAYER_TANK_EXPLOSION()
EXIT
ENDIF
RGBA_COLOUR_STRUCT rgba = sIAPData.sColours.rgbaSprite
IF sIAPData.sPlayerTank.iLastDamagedTime + ciIAP_PLAYER_DAMAGE_RED_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
IAP_DRAW_SCREEN_BORDER(sIAPData.sColours.rgbaDamage)
rgba = sIAPData.sColours.rgbaDamage
ELIF sIAPData.sPlayerTank.iLastHealedTime + ciIAP_PLAYER_HEAL_GREEN_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
IAP_DRAW_SCREEN_BORDER(sIAPData.sColours.rgbaHeal)
rgba = sIAPData.sColours.rgbaHeal
ENDIF
IF IAP_SHOULD_PLAYER_TANK_FLASH()
rgba.iA = IAP_GET_FLASHING_ALPHA()
ENDIF
IF IS_BIT_SET(sIAPData.sPlayerTank.iPlayerTankBitset, ciIAP_PLAYER_TANK_BS_SHIELD_ACTIVE)
IAP_DRAW_PLAYER_TANK_SHIELD(rgba)
ENDIF
IAP_DRAW_PLAYER_TANK_TURRET(rgba)
VECTOR_2D vScale = IAP_GET_PLAYER_TANK_SPRITE_SCALE()
TEXT_LABEL_63 stTankSprite = sIAPData.sPlayerTank.stTankSprite
stTankSprite += (sIAPData.sPlayerTank.iTankBaseAnimFrame + 1)
ARCADE_CABINET_DRAW_SPRITE(IAP_GET_PLAYER_TEXTURE_DICT(), stTankSprite,
sIAPData.sPlayerTank.vPosition.x, sIAPData.sPlayerTank.vPosition.y,
vScale.x, vScale.y, 0.0, rgba)
ENDPROC
// ------------------------------ PROJECTILES ------------------------------
/// PURPOSE:
/// Draws a segment of the player's plasma beam
/// PARAMS:
/// iProjectileIndex -
PROC IAP_DRAW_PLASMA_BEAM_SEGMENT(INT iProjectileIndex)
VECTOR_2D vScale = sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].eProjectileType].vSpriteScale
VECTOR_2D vPixelOrigin = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_PIXELSPACE(sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vOrigin)
VECTOR_2D vPixelEnd = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_PIXELSPACE(sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection)
VECTOR_2D vMidPoint = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_SCREENSPACE(DIVIDE_VECTOR_2D(ADD_VECTOR_2D(vPixelOrigin,vPixelEnd), 2))
FLOAT fSin, fCos
VECTOR_2D vFlatEnd
IF NOT IS_FLOAT_IN_RANGE(sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation, -cfARCADE_MINIGAME_FLOAT_TOLERANCE, cfARCADE_MINIGAME_FLOAT_TOLERANCE)
fSin = SIN(sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation)
fCos = COS(sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation)
vFlatEnd = ROTATE_VECTOR_2D_AROUND_VECTOR_2D_PRECOMPUTE(vPixelOrigin, vPixelEnd, -fSin, fCos)
ELSE
vFlatEnd = vPixelEnd
ENDIF
vFlatEnd = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_SCREENSPACE(vFlatEnd)
vMidPoint.x = ((vMidPoint.x * cfBASE_SCREEN_WIDTH) - ((cfBASE_SCREEN_WIDTH - cfBASE_SCREEN_HEIGHT) / 2)) / cfBASE_SCREEN_HEIGHT
vFlatEnd.x = ((vFlatEnd.x * cfBASE_SCREEN_WIDTH) - ((cfBASE_SCREEN_WIDTH - cfBASE_SCREEN_HEIGHT) / 2)) / cfBASE_SCREEN_HEIGHT
FLOAT vOriginX = ((sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vOrigin.x * cfBASE_SCREEN_WIDTH) - ((cfBASE_SCREEN_WIDTH - cfBASE_SCREEN_HEIGHT) / 2)) / cfBASE_SCREEN_HEIGHT
FLOAT fScaleX = ABSF(vFlatEnd.x - vOriginX)
//Background glow
RGBA_COLOUR_STRUCT rgba = sIAPData.sColours.rgbaPlasma
rgba.iA = ROUND(ABSF((TO_FLOAT(GET_GAME_TIMER()) * 0.1) % 1) * 100) + 155
ARCADE_CABINET_DRAW_SPRITE_ROTATED("MPInvPersCommon", "Beam_Glow_Tapered", vMidPoint.x, vMidPoint.y, vScale.y / 2, fScaleX, sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation + 90, rgba)
//Blue middle
rgba.iA = ROUND(ABSF(TAN((TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME()) + sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].iShotTime)) * 0.5)) * 180) + 75
ARCADE_CABINET_DRAW_SPRITE_ROTATED("MPInvPersCommon", "beam_middle", vMidPoint.x, vMidPoint.y, vScale.y, fScaleX, sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation + 90, rgba)
//White top
rgba = sIAPData.sColours.rgbaSprite
INIT_RGBA_STRUCT(rgba, 255, 255, 255, 255)
rgba.iA = ROUND(ABSF(SIN(TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME()) + sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].iShotTime))) * 155) + 100
ARCADE_CABINET_DRAW_SPRITE_ROTATED("MPInvPersCommon", "beam_top", vMidPoint.x, vMidPoint.y, vScale.y, fScaleX, sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].fRotation + 90, rgba)
//Contact point
rgba = sIAPData.sColours.rgbaSprite
IF sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection.x > cfIAP_FACADE_WIDTH
AND sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection.x < 1 - cfIAP_FACADE_WIDTH
AND sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection.y > 0
TEXT_LABEL_63 tl63Sprite = sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].eProjectileType].stSprite
IF sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].eProjectileType].iMaxAnimFrames > 0
tl63Sprite += (sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].iAnimFrame + 1)
ENDIF
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63Sprite, sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection.x, sIAPData.sPlayerTank.sProjectileInstances[iProjectileIndex].vDirection.y, vScale.x, vScale.y, 0.0, rgba)
ENDIF
ENDPROC
/// PURPOSE:
/// Draws all of the player's projectiles
PROC IAP_DRAW_PLAYER_PROJECTILES()
INT i
FOR i = 0 TO ciIAP_MAX_PLAYER_PROJECTILES - 1
IF sIAPData.sPlayerTank.sProjectileInstances[i].iShotTime = -HIGHEST_INT
RELOOP
ENDIF
IF NATIVE_TO_INT(GET_NETWORK_TIME()) > sIAPData.sPlayerTank.sProjectileInstances[i].iShotTime + sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType].iSpeed
RELOOP
ENDIF
IF sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType = IAP_PROJECTILE_TYPE_PLASMA
IAP_DRAW_PLASMA_BEAM_SEGMENT(i)
RELOOP
ENDIF
TEXT_LABEL_63 tl63Sprite = sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType].stSprite
IF sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType].iMaxAnimFrames > 0
tl63Sprite += (sIAPData.sPlayerTank.sProjectileInstances[i].iAnimFrame + 1)
ENDIF
VECTOR_2D vScale = sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType].vSpriteScale
FLOAT fRotation = sIAPData.sPlayerTank.sProjectileInstances[i].fRotation
//Apply scale effect to flamethrower projectiles
IF sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType = IAP_PROJECTILE_TYPE_FLAME
FLOAT fAlpha = TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME()) - sIAPData.sPlayerTank.sProjectileInstances[i].iShotTime) / (sIAPData.sProjectileData[sIAPData.sPlayerTank.sProjectileInstances[i].eProjectileType].iSpeed * 0.75)
IF fAlpha > 1.0
fAlpha = 1.0
ENDIF
vScale.x = INTERP_FLOAT(vScale.x / 2, vScale.x, fAlpha, INTERPTYPE_ACCEL)
vScale.y = INTERP_FLOAT(vScale.y / 2, vScale.y, fAlpha, INTERPTYPE_ACCEL)
ENDIF
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63Sprite, sIAPData.sPlayerTank.sProjectileInstances[i].vThisFramePos.x, sIAPData.sPlayerTank.sProjectileInstances[i].vThisFramePos.y, vScale.x, vScale.y, fRotation, sIAPData.sColours.rgbaSprite)
ENDFOR
ENDPROC
/// PURPOSE:
/// Draws all enemy projectiles
PROC IAP_DRAW_ENEMY_PROJECTILES()
INT i
FOR i = 0 TO ciIAP_MAX_ENEMY_PROJECTILES - 1
IF sIAPData.sEnemyProjectileInstances[i].iShotTime = -HIGHEST_INT
RELOOP
ENDIF
IF NATIVE_TO_INT(GET_NETWORK_TIME()) > sIAPData.sEnemyProjectileInstances[i].iShotTime + sIAPData.sProjectileData[sIAPData.sEnemyProjectileInstances[i].eProjectileType].iSpeed
RELOOP
ENDIF
TEXT_LABEL_63 tl63Sprite = sIAPData.sProjectileData[sIAPData.sEnemyProjectileInstances[i].eProjectileType].stSprite
IF sIAPData.eCurrentStage = IAP_STAGE_MOON
AND sIAPData.sEnemyProjectileInstances[i].eProjectileType = IAP_PROJECTILE_TYPE_FALLING_BARREL
tl63Sprite += "_moon"
ENDIF
IF sIAPData.sProjectileData[sIAPData.sEnemyProjectileInstances[i].eProjectileType].iMaxAnimFrames > 0
tl63Sprite += (sIAPData.sEnemyProjectileInstances[i].iAnimFrame + 1)
ENDIF
ARCADE_CABINET_DRAW_SPRITE("MPInvPersCommon", tl63Sprite, sIAPData.sEnemyProjectileInstances[i].vThisFramePos.x, sIAPData.sEnemyProjectileInstances[i].vThisFramePos.y, sIAPData.sProjectileData[sIAPData.sEnemyProjectileInstances[i].eProjectileType].vSpriteScale.x, sIAPData.sProjectileData[sIAPData.sEnemyProjectileInstances[i].eProjectileType].vSpriteScale.y, sIAPData.sEnemyProjectileInstances[i].fRotation, sIAPData.sColours.rgbaSprite)
ENDFOR
ENDPROC
// ------------------------------ OBJECTS ------------------------------
/// PURPOSE:
/// Returns the RGBA colour for the given pickup's open effect
/// PARAMS:
FUNC RGBA_COLOUR_STRUCT IAP_GET_PICKUP_OPEN_EFFECT_COLOUR(IAP_OBJECT ePickupType)
RGBA_COLOUR_STRUCT rgba
SWITCH ePickupType
CASE IAP_OBJECT_PICKUP_FLAMETHROWER
INIT_RGBA_STRUCT(rgba, 255, 139, 63, 255)
BREAK
CASE IAP_OBJECT_PICKUP_ROCKETS
INIT_RGBA_STRUCT(rgba, 139, 0, 255, 255)
BREAK
CASE IAP_OBJECT_PICKUP_HEALTH
CASE IAP_OBJECT_PICKUP_LIFE
CASE IAP_OBJECT_PICKUP_SCORE
INIT_RGBA_STRUCT(rgba, 154, 255, 0, 255)
BREAK
CASE IAP_OBJECT_PICKUP_PLASMA
INIT_RGBA_STRUCT(rgba, 24, 203, 247, 255)
BREAK
CASE IAP_OBJECT_PICKUP_ENEMY
INIT_RGBA_STRUCT(rgba, 205, 0, 0, 255)
BREAK
CASE IAP_OBJECT_PICKUP_RANDOM
INIT_RGBA_STRUCT(rgba, 244, 11, 225, 255)
BREAK
CASE IAP_OBJECT_PICKUP_SHIELD
INIT_RGBA_STRUCT(rgba, 94, 250, 255, 255)
BREAK
CASE IAP_OBJECT_PICKUP_TRIPLE
INIT_RGBA_STRUCT(rgba, 205, 0, 0, 255)
BREAK
CASE IAP_OBJECT_PICKUP_NUKE
INIT_RGBA_STRUCT(rgba, 107, 150, 255, 255)
BREAK
ENDSWITCH
RETURN rgba
ENDFUNC
/// PURPOSE:
/// Returns the max anim frames for the object based on its current state
FUNC INT IAP_GET_CURRENT_MAX_ANIM_FRAMES_FOR_OBJECT(INT iObjectIndex)
//Special Cases
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
RETURN ciIAP_PICKUP_OPEN_FRAMES
ENDIF
RETURN ciIAP_EXPLOSION_FRAMES
ENDIF
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
AND (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) != 0
RETURN ciIAP_PITFALL_CRUMBLE_ANIM_FRAMES
ENDIF
SWITCH sIAPData.sObjectInstances[iObjectIndex].eState
CASE IAP_OBJECT_STATE_SHOOTING
RETURN sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].iShootingAnimationFrames
CASE IAP_OBJECT_STATE_DEFAULT
CASE IAP_OBJECT_STATE_FALLING
RETURN sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].iAnimationFrames
ENDSWITCH
RETURN 0
ENDFUNC
/// PURPOSE:
/// Returns the sprite prefix for the object based on its current state
FUNC STRING IAP_GET_CURRENT_SPRITE_FOR_OBJECT(INT iObjectIndex)
//Special Cases
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
AND (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) != 0
RETURN "pit_collapse"
ENDIF
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
RETURN "crate_open"
ENDIF
RETURN "explosion_med"
ENDIF
SWITCH sIAPData.sObjectInstances[iObjectIndex].eState
CASE IAP_OBJECT_STATE_SHOOTING
RETURN sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].stShootingSpritePrefix
CASE IAP_OBJECT_STATE_DEFAULT
CASE IAP_OBJECT_STATE_FALLING
RETURN sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].stSpritePrefix
ENDSWITCH
RETURN "INVALID STATE"
ENDFUNC
/// PURPOSE:
/// Returns the sprite scale for the object based on its current state
FUNC VECTOR_2D IAP_GET_CURRENT_SPRITE_SCALE_FOR_OBJECT(INT iObjectIndex)
//Special Cases
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
AND (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) != 0
RETURN IAP_GET_CURRENT_STAGE_PITFALL_CRUMBLE_SCALE()
ENDIF
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
RETURN INIT_VECTOR_2D(cfIAP_PICKUP_OPEN_EFFECT_SPRITE_SCALE_X, cfIAP_PICKUP_OPEN_EFFECT_SPRITE_SCALE_Y)
ENDIF
RETURN INIT_VECTOR_2D(cfIAP_EXPLOSION_SPRITE_SCALE_X, cfIAP_EXPLOSION_SPRITE_SCALE_Y)
ENDIF
RETURN INIT_VECTOR_2D(sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].vSpriteScale.x,
sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].vSpriteScale.y)
ENDFUNC
/// PURPOSE:
/// Returns the texture dictionary the object's current sprite is contained in
FUNC STRING IAP_GET_TEXTURE_DICTIONARY_FOR_OBJECT(INT iObjectIndex)
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
AND (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) != 0
RETURN sIAPData.stLoadedStageTextureDictionary
ENDIF
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
OR sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_OIL
RETURN "MpInvPersCommon"
ENDIF
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
RETURN "MPInvPersCommon"
ENDIF
RETURN sIAPData.stLoadedStageTextureDictionary
ENDFUNC
/// PURPOSE:
/// Checks if the object should be drawn this frame
/// False if it has died and finished exploding
/// False if it is completely off screen
FUNC BOOL IAP_SHOULD_DRAW_OBJECT_THIS_FRAME(INT iObjectIndex)
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
AND sIAPData.sObjectInstances[iObjectIndex].iAnimFrame > IAP_GET_CURRENT_MAX_ANIM_FRAMES_FOR_OBJECT(iObjectIndex)
//Explosion finished
RETURN FALSE
ENDIF
IF IAP_IS_RECT_COMPLETELY_OUTSIDE_OF_GAME_AREA(sIAPData.sObjectInstances[iObjectIndex].vPosition, IAP_GET_CURRENT_SPRITE_SCALE_FOR_OBJECT(iObjectIndex))
RETURN FALSE
ENDIF
RETURN TRUE
ENDFUNC
/// PURPOSE:
/// Returns the RGBA colour the object's sprite should be drawn with this frame
FUNC RGBA_COLOUR_STRUCT IAP_GET_OBJECT_SPRITE_COLOUR(INT iObjectIndex)
IF sIAPData.sObjectInstances[iObjectIndex].iHealth = 0
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
RETURN IAP_GET_PICKUP_OPEN_EFFECT_COLOUR(sIAPData.sObjectInstances[iObjectIndex].eObjectType)
ENDIF
RETURN sIAPData.sColours.rgbaSprite
ENDIF
IF sIAPData.sObjectInstances[iObjectIndex].iLastDamagedTime + ciIAP_OBJECT_DAMAGE_RED_TIME > NATIVE_TO_INT(GET_NETWORK_TIME())
RGBA_COLOUR_STRUCT rgba
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_OIL
INIT_RGBA_STRUCT(rgba, 0, IAP_GET_FLASHING_ALPHA(), 0, 255)
ELSE
INIT_RGBA_STRUCT(rgba, 255, 0, 0, IAP_GET_FLASHING_ALPHA())
ENDIF
RETURN rgba
ENDIF
RETURN sIAPData.sColours.rgbaSprite
ENDFUNC
/// PURPOSE:
/// Draws the flag anim on top of a claimed oil stockpile
PROC IAP_DRAW_OIL_FLAG(INT iObjectIndex)
IF sIAPData.sObjectInstances[iObjectIndex].iLastDamagedTime = -HIGHEST_INT
//Not claimed
EXIT
ENDIF
TEXT_LABEL_63 tl63SpriteFlag = "capture_flag"
IF IAP_GET_CURRENT_MAX_ANIM_FRAMES_FOR_OBJECT(iObjectIndex) > 0
tl63SpriteFlag += (sIAPData.sObjectInstances[iObjectIndex].iAnimFrame + 1)
ENDIF
VECTOR_2D vScale = IAP_GET_CURRENT_SPRITE_SCALE_FOR_OBJECT(iObjectIndex)
ARCADE_CABINET_DRAW_SPRITE("MpInvPersCommon", tl63SpriteFlag, sIAPData.sObjectInstances[iObjectIndex].vPosition.x + (cfIAP_FLAG_SPRITE_SCALE_X / 2), sIAPData.sObjectInstances[iObjectIndex].vPosition.y - (vScale.y/2) - sIAPData.sObjectInstances[iObjectIndex].vDesiredPosition.y,
cfIAP_FLAG_SPRITE_SCALE_X, cfIAP_FLAG_SPRITE_SCALE_Y, 0.0, sIAPData.sColours.rgbaSprite)
ENDPROC
/// PURPOSE:
/// Draws all stage objects
PROC IAP_DRAW_STAGE_OBJECTS()
FLOAT fSinNumber = SIN(TO_FLOAT(GET_GAME_TIMER()) * 0.5)
INT iObjectIndex
FOR iObjectIndex = 0 TO ciIAP_MAX_ACTIVE_OBJECTS - 1
IF sIAPData.sObjectInstances[iObjectIndex].eObjectType = IAP_OBJECT_NONE
RELOOP
ENDIF
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_LEDGE
//Drawn as part of the stage
RELOOP
ENDIF
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
//Pitfall is as part of the stage
IF (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) = 0
//No crumbling pit
RELOOP
ENDIF
IF sIAPData.sObjectInstances[iObjectIndex].iAnimFrame >= IAP_GET_CURRENT_MAX_ANIM_FRAMES_FOR_OBJECT(iObjectIndex)
//pit has crumbled
RELOOP
ENDIF
ENDIF
IF NOT IAP_SHOULD_DRAW_OBJECT_THIS_FRAME(iObjectIndex)
RELOOP
ENDIF
STRING stTextureDict = IAP_GET_TEXTURE_DICTIONARY_FOR_OBJECT(iObjectIndex)
VECTOR_2D vScale = IAP_GET_CURRENT_SPRITE_SCALE_FOR_OBJECT(iObjectIndex)
RGBA_COLOUR_STRUCT rgba = IAP_GET_OBJECT_SPRITE_COLOUR(iObjectIndex)
TEXT_LABEL_63 tl63Sprite = IAP_GET_CURRENT_SPRITE_FOR_OBJECT(iObjectIndex)
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_OIL
IAP_DRAW_OIL_FLAG(iObjectIndex)
ELSE
IF IAP_GET_CURRENT_MAX_ANIM_FRAMES_FOR_OBJECT(iObjectIndex) > 0
tl63Sprite += (sIAPData.sObjectInstances[iObjectIndex].iAnimFrame + 1)
ENDIF
ENDIF
FLOAT fRotation = 0.0
VECTOR_2D vPos = sIAPData.sObjectInstances[iObjectIndex].vPosition
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PICKUP
AND sIAPData.sObjectInstances[iObjectIndex].eState = IAP_OBJECT_STATE_FALLING
//Rotate pickups back and forth while falling
fRotation = (fSinNumber) * cfIAP_PICKUP_ROTATION
VECTOR_2D vParachutePos = vPos
vParachutePos.y -= (vScale.y / 2) + (cfIAP_PICKUP_PARACHUTE_SPRITE_SCALE_Y/2)
vParachutePos = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_PIXELSPACE(vParachutePos)
vParachutePos = ROTATE_VECTOR_2D_AROUND_VECTOR_2D(ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_PIXELSPACE(vPos), vParachutePos, fRotation)
vParachutePos = ARCADE_CABINET_CONVERT_TO_VECTOR_2D_TO_SCREENSPACE(vParachutePos)
ARCADE_CABINET_DRAW_SPRITE(stTextureDict, "parachute",
vParachutePos.x, vParachutePos.y, cfIAP_PICKUP_PARACHUTE_SPRITE_SCALE_X, cfIAP_PICKUP_PARACHUTE_SPRITE_SCALE_Y, fRotation, rgba)
ENDIF
IF sIAPData.sObjectData[ENUM_TO_INT(sIAPData.sObjectInstances[iObjectIndex].eObjectType)].eObjectType = IAP_OBJECT_TYPE_PITFALL
AND (sIAPData.sObjectInstances[iObjectIndex].iFlags & ciIAP_OBJECT_FLAG_PITFALL_CRUMBLING) != 0
vPos = ADD_VECTOR_2D(vPos, IAP_GET_CURRENT_STAGE_PITFALL_CRUMBLE_OFFSET())
ENDIF
ARCADE_CABINET_DRAW_SPRITE(stTextureDict, tl63Sprite,
vPos.x, vPos.y, vScale.x, vScale.y, fRotation, rgba)
ENDFOR
ENDPROC
// ------------------------------ MIDDLE TEXT SEQUENCES ------------------------------
/// PURPOSE:
/// Updates the middle text anim frame by this frame's update
PROC IAP_UPDATE_MIDDLE_TEXT_SEQUENCE_ANIM_FRAME()
sIAPData.iMiddleTextAnimFrame += sIAPData.iUpdateFrames30FPS
ENDPROC
/// PURPOSE:
/// Returns the sprite of the animated text sequence
FUNC STRING IAP_GET_MIDDLE_TEXT_SEQUENCE_SPRITE(IAP_MIDDLE_TEXT_SEQ eSequence)
SWITCH eSequence
CASE IAP_MIDDLE_TEXT_SEQ_GET_READY
RETURN "get ready_"
CASE IAP_MIDDLE_TEXT_SEQ_GO
RETURN "go_"
CASE IAP_MIDDLE_TEXT_SEQ_GAMEOVER
RETURN "gameover_"
CASE IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED
RETURN "stageclear_"
DEFAULT
RETURN "INVALID SEQUENCE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the max frames of the animated text sequence
FUNC INT IAP_GET_MIDDLE_TEXT_SEQUENCE_FRAMES(IAP_MIDDLE_TEXT_SEQ eSequence)
SWITCH eSequence
CASE IAP_MIDDLE_TEXT_SEQ_GET_READY
RETURN ciIAP_GET_READY_MESSAGE_FRAMES
CASE IAP_MIDDLE_TEXT_SEQ_GO
RETURN ciIAP_GO_MESSAGE_FRAMES
CASE IAP_MIDDLE_TEXT_SEQ_GAMEOVER
RETURN ciIAP_GAMEOVER_MESSAGE_FRAMES
CASE IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED
RETURN ciIAP_STAGE_CLEARED_MESSAGE_FRAMES
DEFAULT
RETURN -1
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the scale of the animated text sequence
FUNC VECTOR_2D IAP_GET_MIDDLE_TEXT_SEQUENCE_SCALE(IAP_MIDDLE_TEXT_SEQ eSequence)
SWITCH eSequence
CASE IAP_MIDDLE_TEXT_SEQ_GET_READY
RETURN INIT_VECTOR_2D(cfIAP_GET_READY_MESSAGE_SCALE_X, cfIAP_GET_READY_MESSAGE_SCALE_Y)
CASE IAP_MIDDLE_TEXT_SEQ_GO
RETURN INIT_VECTOR_2D(cfIAP_GO_MESSAGE_SCALE_X, cfIAP_GO_MESSAGE_SCALE_Y)
CASE IAP_MIDDLE_TEXT_SEQ_GAMEOVER
RETURN INIT_VECTOR_2D(cfIAP_GAMEOVER_MESSAGE_SCALE_X, cfIAP_GAMEOVER_MESSAGE_SCALE_Y)
CASE IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED
RETURN INIT_VECTOR_2D(cfIAP_STAGE_CLEARED_MESSAGE_SCALE_X, cfIAP_STAGE_CLEARED_MESSAGE_SCALE_Y)
DEFAULT
RETURN INIT_VECTOR_2D(-1, -1)
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the scale of the animated text sequence
FUNC STRING IAP_GET_MIDDLE_TEXT_SEQUENCE_TEXTURE_DICT(IAP_MIDDLE_TEXT_SEQ eSequence)
SWITCH eSequence
CASE IAP_MIDDLE_TEXT_SEQ_GET_READY
CASE IAP_MIDDLE_TEXT_SEQ_GO
RETURN "MPInvPersMessages"
CASE IAP_MIDDLE_TEXT_SEQ_GAMEOVER
CASE IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED
RETURN "MPInvPersMessages2"
DEFAULT
RETURN "INVALID SEQUENCE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Draws an animated text sequence in the center of the screen
PROC IAP_DRAW_MIDDLE_TEXT_SEQUENCE(IAP_MIDDLE_TEXT_SEQ eSequence)
INT iFrameToDraw = IAP_GET_MIDDLE_TEXT_SEQUENCE_FRAMES(eSequence)
IF sIAPData.iMiddleTextAnimFrame > -1 AND sIAPData.iMiddleTextAnimFrame < IAP_GET_MIDDLE_TEXT_SEQUENCE_FRAMES(eSequence)
iFrameToDraw = sIAPData.iMiddleTextAnimFrame + 1
ENDIF
VECTOR_2D vScale = IAP_GET_MIDDLE_TEXT_SEQUENCE_SCALE(eSequence)
TEXT_LABEL_63 tl63Sprite = IAP_GET_MIDDLE_TEXT_SEQUENCE_SPRITE(eSequence)
tl63Sprite += iFrameToDraw
FLOAT fYMod = 0.0
IF (eSequence = IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED OR eSequence = IAP_MIDDLE_TEXT_SEQ_GAMEOVER)
AND sIAPData.iMiddleTextAnimFrame >= IAP_GET_MIDDLE_TEXT_SEQUENCE_FRAMES(eSequence) + ciIAP_STAGE_CLEAR_TALLY_DELAY_FRAMES + ciIAP_STAGE_CLEAR_SCALE_UP_FRAMES
fYMod = -(cfIAP_STAGE_CLEARED_MESSAGE_SCALE_Y)
ENDIF
ARCADE_CABINET_DRAW_SPRITE(IAP_GET_MIDDLE_TEXT_SEQUENCE_TEXTURE_DICT(eSequence), tl63Sprite, cfSCREEN_CENTER, cfSCREEN_CENTER + fYMod, vScale.x, vScale.y, 0, sIAPData.sColours.rgbaSprite)
IAP_UPDATE_MIDDLE_TEXT_SEQUENCE_ANIM_FRAME()
ENDPROC
/// PURPOSE:
/// Draws text in the scoring tally values column
PROC IAP_DRAW_SCORING_TALLY_TEXT_VALUE(INT iValue, FLOAT fYPos, BOOL bDollars = FALSE, INT iDigits = ciIAP_FONT_DIGIT_COUNT)
IAP_DRAW_NUMBER_FROM_POS(iValue, INIT_VECTOR_2D(cfIAP_STAGE_CLEAR_TALLY_TEXT_VALUE_COLUMN_WRAP_MIN, fYPos), sIAPData.sColours.rgbaSprite, FALSE, bDollars, FALSE, iDigits)
ENDPROC
/// PURPOSE:
/// Draws the end scoring tally and middle message BG
PROC IAP_DRAW_OUTRO_SCORING_TALLY()
VECTOR_2D vScale = INIT_VECTOR_2D(1.0, cfIAP_STAGE_CLEAR_BACKGROUND_MIN_Y)
INT iMaxFrames = IAP_GET_MIDDLE_TEXT_SEQUENCE_FRAMES(IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED)
BOOL bDrawTally = FALSE
IF sIAPData.iMiddleTextAnimFrame < iMaxFrames
vScale.y += ((cfIAP_STAGE_CLEAR_BACKGROUND_MID_Y - cfIAP_STAGE_CLEAR_BACKGROUND_MIN_Y) / iMaxFrames) * sIAPData.iMiddleTextAnimFrame
ELIF sIAPData.iMiddleTextAnimFrame < iMaxFrames + ciIAP_STAGE_CLEAR_TALLY_DELAY_FRAMES
vScale.y = cfIAP_STAGE_CLEAR_BACKGROUND_MID_Y
ELIF sIAPData.iMiddleTextAnimFrame < iMaxFrames + ciIAP_STAGE_CLEAR_TALLY_DELAY_FRAMES + ciIAP_STAGE_CLEAR_SCALE_UP_FRAMES
vScale.y = cfIAP_STAGE_CLEAR_BACKGROUND_MID_Y + ((cfIAP_STAGE_CLEAR_BACKGROUND_MAX_Y - cfIAP_STAGE_CLEAR_BACKGROUND_MID_Y) / ciIAP_STAGE_CLEAR_SCALE_UP_FRAMES) * (sIAPData.iMiddleTextAnimFrame - iMaxFrames - ciIAP_STAGE_CLEAR_TALLY_DELAY_FRAMES)
ELSE
vScale.y = cfIAP_STAGE_CLEAR_BACKGROUND_MAX_Y
bDrawTally = TRUE
ENDIF
DRAW_RECT_FROM_VECTOR_2D(INIT_VECTOR_2D(cfSCREEN_CENTER, cfSCREEN_CENTER), ADD_VECTOR_2D(vScale, INIT_VECTOR_2D(0, cfIAP_STAGE_CLEAR_BORDER_Y)), sIAPData.sColours.rgbaScoringBorder)
DRAW_RECT_FROM_VECTOR_2D(INIT_VECTOR_2D(cfSCREEN_CENTER, cfSCREEN_CENTER), vScale, sIAPData.sColours.rgbaScoringBg)
IF NOT bDrawTally
EXIT
ENDIF
FLOAT fY = cfIAP_STAGE_CLEAR_TALLY_TEXT_POS_Y
//Armor
ARCADE_CABINET_DRAW_SPRITE("MpInvPersHud", "title_armour", cfIAP_STAGE_CLEAR_TALLY_TEXT_TITLE_COLUMN_WRAP_MAX - (cfIAP_FONT_TITLE_SCALE_X/2), fY, cfIAP_FONT_TITLE_SCALE_X, cfIAP_FONT_TITLE_SCALE_Y, 0, sIAPData.sColours.rgbaScoringText)
IAP_DRAW_SCORING_TALLY_TEXT_VALUE(sIAPData.iEndArmourToShow, fY)
fY += cfIAP_STAGE_CLEAR_TALLY_TEXT_SPACING_Y
//Lives
ARCADE_CABINET_DRAW_SPRITE("MpInvPersHud", "title_lives", cfIAP_STAGE_CLEAR_TALLY_TEXT_TITLE_COLUMN_WRAP_MAX - (cfIAP_FONT_TITLE_SCALE_X/2), fY, cfIAP_FONT_TITLE_SCALE_X, cfIAP_FONT_TITLE_SCALE_Y, 0, sIAPData.sColours.rgbaScoringText)
IAP_DRAW_SCORING_TALLY_TEXT_VALUE(sIAPData.iEndLivesToShow, fY)
fY += cfIAP_STAGE_CLEAR_TALLY_TEXT_SPACING_Y
//Distance
ARCADE_CABINET_DRAW_SPRITE("MpInvPersHud", "title_distance", cfIAP_STAGE_CLEAR_TALLY_TEXT_TITLE_COLUMN_WRAP_MAX - (cfIAP_FONT_TITLE_SCALE_X/2), fY, cfIAP_FONT_TITLE_SCALE_X, cfIAP_FONT_TITLE_SCALE_Y, 0, sIAPData.sColours.rgbaScoringText)
IAP_DRAW_SCORING_TALLY_TEXT_VALUE(sIAPData.iEndDistanceToShow * 1000, fY)
fY += cfIAP_STAGE_CLEAR_TALLY_TEXT_SPACING_Y / 2
//Bar
DRAW_RECT_FROM_VECTOR_2D(INIT_VECTOR_2D(cfSCREEN_CENTER + cfIAP_STAGE_CLEAR_TALLY_RECT_OFFSET_X, fY + cfIAP_STAGE_CLEAR_TALLY_RECT_OFFSET_Y), INIT_VECTOR_2D(cfIAP_STAGE_CLEAR_TALLY_RECT_WIDTH, cfIAP_STAGE_CLEAR_TALLY_RECT_HEIGHT), sIAPData.sColours.rgbaScoringText)
fY += cfIAP_STAGE_CLEAR_TALLY_TEXT_SPACING_Y
//Total
ARCADE_CABINET_DRAW_SPRITE("MpInvPersHud", "title_total", cfIAP_STAGE_CLEAR_TALLY_TEXT_TITLE_COLUMN_WRAP_MAX - (cfIAP_FONT_TITLE_SCALE_X/2), fY, cfIAP_FONT_TITLE_SCALE_X, cfIAP_FONT_TITLE_SCALE_Y, 0, sIAPData.sColours.rgbaScoringText)
IAP_DRAW_SCORING_TALLY_TEXT_VALUE(sIAPData.iScoreToShow, fY, TRUE)
ENDPROC
// ------------------------------ INTRO SCREENS ------------------------------
/// PURPOSE:
/// Draws the intro movie and returns true when the intro movie has completed
FUNC BOOL IAP_DRAW_DEGENETRON_INTRO_MOVIE()
DRAW_BINK_MOVIE(sIAPData.binkDegenIntro, cfSCREEN_CENTER, cfSCREEN_CENTER, 1.0 * fAspectRatioModifier, 1.0, 0.0, 255, 255, 255, 255)
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
IF GET_BINK_MOVIE_TIME(sIAPData.binkDegenIntro) >= 99.0
CDEBUG1LN(DEBUG_MINIGAME, "[IAP] [JS] IAP_DRAW_DEGENETRON_INTRO_MOVIE - stopping and releasing intro movie")
STOP_BINK_MOVIE(sIAPData.binkDegenIntro)
RELEASE_BINK_MOVIE(sIAPData.binkDegenIntro)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Draws the ron oil screen with opacity set to iAlpha
PROC IAP_DRAW_RON_OIL_INTRO(INT iAlpha = 255)
RGBA_COLOUR_STRUCT rgba
IAP_DRAW_FULL_SCREEN_RECT(sIAPData.sColours.rgbaBlack)
INIT_RGBA_STRUCT(rgba, 236, 109, 0, iAlpha)
IAP_DRAW_FULL_SCREEN_RECT(rgba)
DRAW_RECT_FROM_VECTOR_2D(INIT_VECTOR_2D(cfSCREEN_CENTER, cfSCREEN_CENTER), INIT_VECTOR_2D(cfIAP_PLAY_AREA_WIDTH, 1.0), sIAPData.sColours.rgbaBlack)
rgba = sIAPData.sColours.rgbaSprite
rgba.iA = iAlpha
ARCADE_CABINET_DRAW_SPRITE("MpInvPersCommon", "ron_splash", cfSCREEN_CENTER, cfSCREEN_CENTER, cfIAP_PLAY_AREA_WIDTH, 1.0, 0, rgba)
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
/// PURPOSE:
/// Draws the ron oil screen with opacity set to iAlpha
PROC IAP_DRAW_TITLE_SCREEN()
DRAW_BINK_MOVIE(sIAPData.binkIntroLoop, cfSCREEN_CENTER, cfSCREEN_CENTER, 1.0 * fAspectRatioModifier, 1.0, 0.0, 255, 255, 255, 255)
IF GET_CURRENT_LANGUAGE() != LANGUAGE_ENGLISH
IF GET_BINK_MOVIE_TIME(sIAPData.binkIntroLoop) < 30.0
BEGIN_TEXT_COMMAND_PRINT("IAP_INTRO")
END_TEXT_COMMAND_PRINT(1, TRUE)
ENDIF
ENDIF
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ LOADING SCREEN ------------------------------
/// PURPOSE:
/// Returns the loading screen background sprite for the current stage
FUNC STRING IAP_GET_CURRENT_LOADING_SCREEN_BG_SPRITE()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
RETURN "mission_select_screen1"
CASE IAP_STAGE_RUSSIA
RETURN "mission_select_screen2"
CASE IAP_STAGE_CHINA
RETURN "mission_select_screen3"
CASE IAP_STAGE_CANADA
RETURN "mission_select_screen4"
CASE IAP_STAGE_MOON
RETURN "mission_select_screen5"
DEFAULT
RETURN "INVALID STAGE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the loading screen text sprite for the current stage
FUNC STRING IAP_GET_CURRENT_LOADING_SCREEN_TEXT_SPRITE()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
RETURN "lvl_text_1"
CASE IAP_STAGE_RUSSIA
RETURN "lvl_text_2"
CASE IAP_STAGE_CHINA
RETURN "lvl_text_3"
CASE IAP_STAGE_CANADA
RETURN "lvl_text_4"
CASE IAP_STAGE_MOON
RETURN "lvl_text_5"
DEFAULT
RETURN "INVALID STAGE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the loading screen mission name sprite for the current stage
FUNC STRING IAP_GET_CURRENT_LOADING_SCREEN_MISSION_NAME_SPRITE()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
RETURN "lvl_name_1"
CASE IAP_STAGE_RUSSIA
RETURN "lvl_name_2"
CASE IAP_STAGE_CHINA
RETURN "lvl_name_3"
CASE IAP_STAGE_CANADA
RETURN "lvl_name_4"
CASE IAP_STAGE_MOON
RETURN "lvl_name_5"
DEFAULT
RETURN "INVALID STAGE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the width of the loading screen mission name sprite for the current stage
FUNC FLOAT GET_IAP_MISSION_NAME_WIDTH()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
RETURN cfIAP_LOADING_TEXT_SCALE_X_IRAQ
CASE IAP_STAGE_RUSSIA
RETURN cfIAP_LOADING_TEXT_SCALE_X_RUSSIA
CASE IAP_STAGE_CHINA
RETURN cfIAP_LOADING_TEXT_SCALE_X_CHINA
CASE IAP_STAGE_CANADA
RETURN cfIAP_LOADING_TEXT_SCALE_X_CANADA
CASE IAP_STAGE_MOON
RETURN cfIAP_LOADING_TEXT_SCALE_X_MOON
DEFAULT
RETURN 0.0
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the loading screen country sprite for the current stage
FUNC STRING IAP_GET_CURRENT_LOADING_SCREEN_COUNTRY_SPRITE()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
RETURN "country_1"
CASE IAP_STAGE_RUSSIA
RETURN "country_2"
CASE IAP_STAGE_CHINA
RETURN "country_3"
CASE IAP_STAGE_CANADA
RETURN "country_4"
CASE IAP_STAGE_MOON
RETURN "country_5"
DEFAULT
RETURN "INVALID STAGE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Returns the texture dictionary the current stage's loading screen is in
FUNC STRING IAP_GET_CURRENT_LOADING_SCREEN_TEXTURE_DICT()
SWITCH sIAPData.eCurrentStage
CASE IAP_STAGE_IRAQ
CASE IAP_STAGE_RUSSIA
CASE IAP_STAGE_CHINA
CASE IAP_STAGE_CANADA
RETURN "MpInvPersHud"
CASE IAP_STAGE_MOON
RETURN "MPInvPersCommon"
DEFAULT
RETURN "INVALID STAGE"
ENDSWITCH
ENDFUNC
/// PURPOSE:
/// Draws the flashing country on the loading screen
PROC IAP_DRAW_LOADING_COUNTRY()
VECTOR_2D vScale
VECTOR_2D vPos
SWITCH (sIAPData.eCurrentStage)
CASE IAP_STAGE_IRAQ
vScale = INIT_VECTOR_2D(0.016667, 0.029630)
vPos = INIT_VECTOR_2D(0.542708, 0.329630)
BREAK
CASE IAP_STAGE_RUSSIA
vScale = INIT_VECTOR_2D(0.158333, 0.088889)
vPos = INIT_VECTOR_2D(0.602083, 0.266667)
BREAK
CASE IAP_STAGE_CHINA
vScale = INIT_VECTOR_2D(0.075000, 0.088889)
vPos = INIT_VECTOR_2D(0.617708, 0.322222)
BREAK
CASE IAP_STAGE_CANADA
vScale = INIT_VECTOR_2D(0.100000, 0.096296)
vPos = INIT_VECTOR_2D(0.384375, 0.257407)
BREAK
CASE IAP_STAGE_MOON
vScale = INIT_VECTOR_2D(0.208333, 0.370370)
vPos = INIT_VECTOR_2D(0.504167 + (0.000520833*2), 0.416667)
BREAK
ENDSWITCH
vPos = ADD_VECTOR_2D(vPos, INIT_VECTOR_2D(-0.004166667, 0.005555556))
RGBA_COLOUR_STRUCT rgba = sIAPData.sColours.rgbaSprite
rgba.iA = ROUND(INTERP_FLOAT(25, 255, ABSF(SIN(TO_FLOAT(GET_GAME_TIMER()) * cfIAP_LOADING_SCREEN_COUNTRY_FLASH_MOD)), INTERPTYPE_SMOOTHSTEP))
ARCADE_CABINET_DRAW_SPRITE(IAP_GET_CURRENT_LOADING_SCREEN_TEXTURE_DICT(), IAP_GET_CURRENT_LOADING_SCREEN_COUNTRY_SPRITE(), vPos.x, vPos.y, vScale.x, vScale.y, 0, rgba)
IF GET_CURRENT_LANGUAGE() != LANGUAGE_ENGLISH
TEXT_LABEL_15 tl15Desc = "IAP_STAGE_D_"
tl15Desc += ENUM_TO_INT(sIAPData.eCurrentStage)
BEGIN_TEXT_COMMAND_PRINT(tl15Desc)
END_TEXT_COMMAND_PRINT(1, TRUE)
ENDIF
ENDPROC
/// PURPOSE:
/// Draws the stage loading screen
PROC IAP_DRAW_STAGE_LOADING_SCREEN()
IAP_DRAW_FULL_SCREEN_RECT(sIAPData.sColours.rgbaBlack)
ARCADE_CABINET_DRAW_SPRITE(IAP_GET_CURRENT_LOADING_SCREEN_TEXTURE_DICT(), IAP_GET_CURRENT_LOADING_SCREEN_BG_SPRITE(), cfSCREEN_CENTER, cfSCREEN_CENTER, cfIAP_LOADING_SCREEN_SCALE_X, cfIAP_LOADING_SCREEN_SCALE_Y, 0, sIAPData.sColours.rgbaSprite)
IAP_DRAW_LOADING_COUNTRY()
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ STAGE INTRO ------------------------------
/// PURPOSE:
/// Draws the stage intro
PROC IAP_DRAW_STAGE_INTRO()
IAP_DRAW_STAGE()
IAP_DRAW_PLAYER_TANK()
IAP_DRAW_WEATHER()
IAP_DRAW_MIDDLE_TEXT_SEQUENCE(IAP_MIDDLE_TEXT_SEQ_GET_READY)
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ RUNNING ------------------------------
/// PURPOSE:
/// Draws the game while running
PROC IAP_DRAW_STAGE_RUNNING()
IAP_DRAW_STAGE()
IAP_DRAW_STAGE_OBJECTS()
IAP_DRAW_ENEMY_PROJECTILES()
IAP_DRAW_PLAYER_PROJECTILES()
IAP_DRAW_PLAYER_TANK()
IAP_DRAW_EXPLOSIONS()
IAP_DRAW_WEATHER()
IAP_DRAW_NUKE()
IAP_DRAW_ABOVE_PLAYER_TEXT()
IAP_DRAW_SCORE_TEXT()
IAP_DRAW_HUD()
IF HAS_NET_TIMER_STARTED(sIAPData.tdStageTimer)
AND NOT HAS_NET_TIMER_EXPIRED(sIAPData.tdStageTimer, ciIAP_GO_TIME)
IAP_DRAW_MIDDLE_TEXT_SEQUENCE(IAP_MIDDLE_TEXT_SEQ_GO)
ENDIF
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ GAMEOVER ------------------------------
/// PURPOSE:
/// Draws the gameover stage
PROC IAP_DRAW_STAGE_GAMEOVER()
IAP_DRAW_STAGE()
IAP_DRAW_STAGE_OBJECTS()
IAP_DRAW_PLAYER_TANK()
IAP_DRAW_SCORE_TEXT()
IAP_DRAW_WEATHER()
IAP_DRAW_NUKE()
IAP_DRAW_SCORE_TEXT()
IAP_DRAW_HUD()
IAP_DRAW_OUTRO_SCORING_TALLY()
IAP_DRAW_MIDDLE_TEXT_SEQUENCE(IAP_MIDDLE_TEXT_SEQ_GAMEOVER)
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ STAGE OUTRO ------------------------------
/// PURPOSE:
/// Draws the stage outro
PROC IAP_DRAW_STAGE_OUTRO()
IAP_DRAW_STAGE()
IAP_DRAW_STAGE_OBJECTS()
IAP_DRAW_PLAYER_PROJECTILES()
IAP_DRAW_PLAYER_TANK()
IAP_DRAW_EXPLOSIONS()
IAP_DRAW_WEATHER()
IAP_DRAW_NUKE()
IAP_DRAW_SCORE_TEXT()
IAP_DRAW_HUD()
IAP_DRAW_OUTRO_SCORING_TALLY()
IAP_DRAW_MIDDLE_TEXT_SEQUENCE(IAP_MIDDLE_TEXT_SEQ_STAGE_CLEARED)
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC
// ------------------------------ LEADERBOARD ------------------------------
/// PURPOSE:
/// Returns the string for the lbd position
FUNC STRING IAP_GET_POSITION_STRING(INT iPosition)
SWITCH iPosition
CASE 0 RETURN "IAP_1ST"
CASE 1 RETURN "IAP_2ND"
CASE 2 RETURN "IAP_3RD"
CASE 3 RETURN "IAP_4TH"
CASE 4 RETURN "IAP_5TH"
CASE 5 RETURN "IAP_6TH"
CASE 6 RETURN "IAP_7TH"
CASE 7 RETURN "IAP_8TH"
CASE 8 RETURN "IAP_9TH"
CASE 9 RETURN "IAP_10TH"
ENDSWITCH
RETURN ""
ENDFUNC
/// PURPOSE:
/// Draws the leaderboard
PROC IAP_DRAW_LEADERBOARD()
DRAW_BINK_MOVIE(sIAPData.binkLeaderboard, cfSCREEN_CENTER, cfSCREEN_CENTER, 1.0 * fAspectRatioModifier, 1.0, 0.0, 255, 255, 255, 255)
INT iUnpackedInitials[ciARCADE_CABINET_LEADERBOARD_INITIALS]
FLOAT fY = cfIAP_LBD_STARTING_POS_Y
INT iPositionLoop = 0
FOR iPositionLoop = 0 TO ciCASINO_ARCADE_LEADERBOARD_POSITIONS - 1
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND (sIAPData.iCurrentInitial < ciARCADE_CABINET_LEADERBOARD_INITIALS - 1
OR SC_PROFANITY_GET_CHECK_IS_VALID(sIAPData.iLbdInitialProfanityToken))
ARCADE_UNPACK_LEADERBOARD_INITIALS(sIAPData.iInitials, iUnpackedInitials)
ELSE
ARCADE_UNPACK_LEADERBOARD_INITIALS(sIAPData.sLeaderboard[iPositionLoop].iInitials, iUnpackedInitials)
ENDIF
INT iAlpha = 255
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
iAlpha = ROUND(ABSF(SIN(TO_FLOAT(NATIVE_TO_INT(GET_NETWORK_TIME())) * 0.5) * 80)) + 175
ENDIF
//Position
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
SET_TEXT_COLOUR(0, 0, 0, iAlpha)
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_POSITION_POS_X + cfIAP_DROP_SHADOW_OFFSET_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT(IAP_GET_POSITION_STRING(iPositionLoop))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY + cfIAP_DROP_SHADOW_OFFSET_Y)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
SET_TEXT_COLOUR(255, 255, 255, iAlpha)
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_POSITION_POS_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT(IAP_GET_POSITION_STRING(iPositionLoop))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY)
//Initials
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 0
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringBorder.iR, sIAPData.sColours.rgbaScoringBorder.iG, sIAPData.sColours.rgbaScoringBorder.iB, 255)
ELSE
SET_TEXT_COLOUR(0, 0, 0, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_1_POS_X + cfIAP_DROP_SHADOW_OFFSET_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[0]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY + cfIAP_DROP_SHADOW_OFFSET_Y)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 0
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringText.iR, sIAPData.sColours.rgbaScoringText.iG, sIAPData.sColours.rgbaScoringText.iB, 255)
ELSE
SET_TEXT_COLOUR(255, 255, 255, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_1_POS_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[0]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 1
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringBorder.iR, sIAPData.sColours.rgbaScoringBorder.iG, sIAPData.sColours.rgbaScoringBorder.iB, 255)
ELSE
SET_TEXT_COLOUR(0, 0, 0, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_2_POS_X + cfIAP_DROP_SHADOW_OFFSET_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[1]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY + cfIAP_DROP_SHADOW_OFFSET_Y)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 1
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringText.iR, sIAPData.sColours.rgbaScoringText.iG, sIAPData.sColours.rgbaScoringText.iB, 255)
ELSE
SET_TEXT_COLOUR(255, 255, 255, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_2_POS_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[1]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 2
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringBorder.iR, sIAPData.sColours.rgbaScoringBorder.iG, sIAPData.sColours.rgbaScoringBorder.iB, 255)
ELSE
SET_TEXT_COLOUR(0, 0, 0, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_3_POS_X + cfIAP_DROP_SHADOW_OFFSET_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[2]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY + cfIAP_DROP_SHADOW_OFFSET_Y)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
IF sIAPData.sLeaderboard[iPositionLoop].bPlayer
AND sIAPData.iCurrentInitial = 2
SET_TEXT_COLOUR(sIAPData.sColours.rgbaScoringText.iR, sIAPData.sColours.rgbaScoringText.iG, sIAPData.sColours.rgbaScoringText.iB, 255)
ELSE
SET_TEXT_COLOUR(255, 255, 255, iAlpha)
ENDIF
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_INITIAL_3_POS_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("STRING")
ADD_TEXT_COMPONENT_SUBSTRING_PLAYER_NAME(ARCADE_GET_CHAR_FROM_INT(iUnpackedInitials[2]))
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY)
//Score
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
SET_TEXT_COLOUR(0, 0, 0, iAlpha)
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_SCORE_POS_X + cfIAP_DROP_SHADOW_OFFSET_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("IAP_SCR")
ADD_TEXT_COMPONENT_INTEGER(sIAPData.sLeaderboard[iPositionLoop].iScore)
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY + cfIAP_DROP_SHADOW_OFFSET_Y)
SET_TEXT_SCALE(cfIAP_LBD_TEXT_SCALE, cfIAP_LBD_TEXT_SCALE)
SET_TEXT_COLOUR(255, 255, 255, iAlpha)
SET_TEXT_RIGHT_JUSTIFY(TRUE)
SET_TEXT_WRAP(APPLY_ASPECT_MOD_TO_X(0.0), APPLY_ASPECT_MOD_TO_X(cfIAP_LBD_SCORE_POS_X))
SET_TEXT_FONT(FONT_STYLE_PRICEDOWN)
BEGIN_TEXT_COMMAND_DISPLAY_TEXT("IAP_SCR")
ADD_TEXT_COMPONENT_INTEGER(sIAPData.sLeaderboard[iPositionLoop].iScore)
END_TEXT_COMMAND_DISPLAY_TEXT(APPLY_ASPECT_MOD_TO_X(cfSCREEN_CENTER), fY)
fY += cfIAP_LBD_SPACING_Y
ENDFOR
ARCADE_GAMES_POSTFX_DRAW()
IAP_DRAW_FACADE()
ENDPROC