Files
2025-09-29 00:52:08 +02:00

382 lines
12 KiB
Python
Executable File

////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////// Written by: DAVID BEDDOES Jul 2006 ////////////////////////////
//////////////////////// Designed by David Beddoes & Simon Lashley ////////////////////////////
//////////////////////// Coverted for GTAO by Luke Bazalgette ////////////////////////////
//////////////////////// PUZZLE CONSOLE GAME ////////////////////////////
//////////////////////// QUB3D ////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
USING "globals.sch"
USING "model_enums.sch"
USING "rage_builtins.sch"
USING "types.sch"
USING "puzzle_helpers.sch"
USING "net_events.sch"
USING "net_wait_zero.sch"
USING "net_mission.sch"
USING "degenatron_games_movie.sch"
///////////////////////////////////////
////// **** MAIN CONTROLLER **** //////
///////////////////////////////////////
PROC MAIN_GAME_CONTROLLER()
IF NOT is_game_over
IF NOT is_this_tutorial
// Update the animation if it's not in a playing state
IF pz_AnimStruct.pzAnimClipActive != PZ_ANIM_CLIP_PLAY_IDLE
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_PLAY_IDLE
pz_AnimStruct.animationToPlay = ARCADE_CABINET_ANIM_CLIP_PLAY_IDLE
pz_AnimStruct.sQub3dAnimEvent.bLoopAnim = TRUE
pz_AnimStruct.sQub3dAnimEvent.bHoldLastFrame = FALSE
PLAY_ARCADE_CABINET_ANIMATION(pz_AnimStruct.sQub3dAnimEvent, pz_AnimStruct.animationToPlay) // Start with the default idle animation.
CDEBUG1LN(DEBUG_MINIGAME, sPrefixDebugQub3d, "MAIN_GAME_CONTROLLER - Start ingame idle anim")
// Restart the Net timer from the start.
RESET_NET_TIMER(pz_AnimStruct.sAnimTimer)
START_NET_TIMER(pz_AnimStruct.sAnimTimer)
ENDIF
IF is_a_box_in_motion
POWERUP_UPDATE() // Power up
IF NOT colour_removal_powerup_in_effect
AND NOT eraser_powerup_in_effect
AND NOT bomb_powerup_in_effect
FALLING_BLOCK_CONTROLLER()
ENDIF
ELIF READY_TO_CREATE_NEXT_BLOCK()
CREATE_RANDOM_BLOCK()
ENDIF
DISPLAY_IN_GAME_TEXT()
IF is_game_over
AND !is_a_box_in_motion
IF NOT is_this_tutorial
PLAY_SOUND_FRONTEND(soundId, game_over_sfx)
IF ingame_music_playing
//STOP_STREAM()
STOP_SOUND(Qub3dMusicSoundID)
ingame_music_playing = FALSE
ENDIF
ENDIF
// PLAY BACK REACTION!
CDEBUG1LN(DEBUG_MINIGAME, sPrefixDebugQub3d, "RUN GAME_OVER sequence. SCORE:", total_score)
// Did not make the top
IF total_score < sAGLeaderboardData.sLeaderboard[4].iScore
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_LOSE
ENDIF
// Did not make the board
IF total_score < sAGLeaderboardData.sLeaderboard[ciCASINO_ARCADE_LEADERBOARD_POSITIONS-1].iScore
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_LOSE_BIG
ENDIF
// Poor score
IF total_score < 500
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_KICK
ENDIF
// Made top 5
IF total_score >= sAGLeaderboardData.sLeaderboard[4].iScore
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_WIN
ENDIF
// New high score!
IF total_score >= sAGLeaderboardData.sLeaderboard[0].iScore
pz_AnimStruct.pzAnimClipActive = PZ_ANIM_CLIP_WIN_BIG
ENDIF
IF (total_score >= session_high_score)
session_high_score = total_score
ENDIF
// Process Challenges
BOOL bAwardTrophy = TRUE
IF total_score >= g_sMptunables.iARCADE_QUB3D_KING
IF NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_KINGOFQUB3D)
SET_BIT(sQub3dTelemetry.challenges, ENUM_TO_INT(PZ_CHALLENGE_KING_OF_QUB3D))
SET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_KINGOFQUB3D, TRUE)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TSHIRT_HELP(ARCADE_GAME_TSHIRTS_KINGQ)
ENDIF
ENDIF
IF total_score >= g_sMptunables.iARCADE_QUB3D_GOD
IF NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_GODOFQUB3D)
SET_BIT(sQub3dTelemetry.challenges, ENUM_TO_INT(PZ_CHALLENGE_GOD_OF_QUB3D))
SET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_GODOFQUB3D, TRUE)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TSHIRT_HELP(ARCADE_GAME_TSHIRTS_GODQ)
ENDIF
ENDIF
// Didn't use any powerups this session.
IF sQub3dTelemetry.powerUps = 0
AND current_level >= 20
IF NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUBISM)
SET_BIT(sQub3dTelemetry.challenges, ENUM_TO_INT(PZ_CHALLENGE_QUBISM))
SET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUBISM, TRUE)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TSHIRT_HELP(ARCADE_GAME_TSHIRTS_QUBISM)
ENDIF
ENDIF
IF NOT bRemovedFromPlay
AND current_level >= 20
IF NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUIBITS)
SET_BIT(sQub3dTelemetry.challenges, ENUM_TO_INT(PZ_CHALLENGE_QUBITS))
SET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUIBITS, TRUE)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TSHIRT_HELP(ARCADE_GAME_TSHIRTS_QUBITS)
ENDIF
ENDIF
IF NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUIBITS)
OR NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_QUBISM)
OR NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_KINGOFQUB3D)
OR NOT GET_MP_BOOL_CHARACTER_AWARD(MP_AWARD_GODOFQUB3D)
bAwardTrophy = FALSE
ENDIF
sQub3dTelemetry.reward = 0
IF bAwardTrophy
IF NOT ARCADE_CABINET_FLOW_NOTIFICATIONS_IS_LOCAL_BIT_SET(ARCADE_NOTIFICATION_LOCAL_BIT_QUB3D_TROPHY)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_LOCAL_BIT(ARCADE_NOTIFICATION_LOCAL_BIT_QUB3D_TROPHY)
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TROPHY_HELP(ARCADE_GAME_TROPHY_QUB3D, DOES_PLAYER_OWN_A_CASINO_APARTMENT(PLAYER_ID()))
ARCADE_CABINET_FLOW_NOTIFICATIONS_SET_SHOW_TSHIRT_HELP(ARCADE_GAME_TSHIRTS_QUB3D)
sQub3dTelemetry.reward = ARCADE_GAME_GET_TROPHY_ID_FOR_TELEMETRY(ARCADE_GAME_TROPHY_QUB3D)
ENDIF
ENDIF
PZ_SEND_TELEMETRY()
SET_CAM_ACTIVE(game_cam, FALSE)
SET_CAM_ACTIVE_WITH_INTERP(anim_cam, game_cam, 4000, GRAPH_TYPE_VERY_SLOW_IN_VERY_SLOW_OUT)
time_started = TO_FLOAT(GET_GAME_TIMER())
// going to high score table
current_mission_stage = HI_SCORE_ENTRY
// for front end display of score
ENDIF
ELSE
/// tutorial code goes here?
TUTORIAL_CONTROLLER()
ENDIF
ELSE
DISPLAY_FRONT_END_MENU()
ENDIF
ENDPROC
// Place any functions you call once in this function.
PROC PRE_GAME_SETUP(MP_MISSION_DATA missionScriptArgs)
// This marks the script as a net script, and handles any instancing setup.
missionScriptArgs = missionScriptArgs
NETWORK_SET_SCRIPT_IS_SAFE_FOR_NETWORK_GAME()
// This script will not be paused if another script calls PAUSE_GAME
SET_THIS_SCRIPT_CAN_BE_PAUSED(FALSE)
PUZZLE_INIT_COLOUR_STRUCTS()
QUB3D_INIT_VARS(INT_TO_ENUM(ARCADE_CABINET_PROPERTY, missionScriptArgs.mdGenericInt))
QUB3D_REQUEST_ASSETS()
// Initialise game state
current_mission_stage = PIXTRO_SETUP
is_mission_in_progress = TRUE
ENDPROC
////////////////////
// *** SCRIPT *** //
////////////////////
SCRIPT(MP_MISSION_DATA missionScriptArgs)
missionScriptArgs.mdID.idMission = eAM_QUB3D_ARCADE_CABINET
IF NETWORK_IS_GAME_IN_PROGRESS()
PRE_GAME_SETUP(missionScriptArgs)
ENDIF
WHILE is_mission_in_progress
IF QUB3D_IS_NETWORK_DISCONNECTED()
CLEANUP_MISSION_PUZZLE()
EXIT
ENDIF
CHECK_FOR_STANDARD_MINI_EXIT()
MP_LOOP_WAIT_ZERO()
#if IS_DEBUG_BUILD
IF IS_KEYBOARD_KEY_PRESSED(KEY_F)
CDEBUG1LN(DEBUG_MINIGAME, "Ending QUB3D game - Via debug key press")
// clean up the mission
CLEANUP_MISSION_PUZZLE()
EXIT
ENDIF
// debug
WIDGET_UPDATE()
IF DOES_ENTITY_EXIST(skybox_object)
SET_ENTITY_ROTATION(skybox_object, skybox_rot)
SET_ENTITY_COORDS(skybox_object, skybox_pos)
ENDIF
IF DOES_CAM_EXIST(game_cam)
IF !bMinimiseCams
IF NOT IS_CAM_RENDERING(game_cam)
RENDER_SCRIPT_CAMS(TRUE, FALSE)
ENDIF
ELSE
IF IS_CAM_RENDERING(game_cam)
RENDER_SCRIPT_CAMS(FALSE, FALSE)
ENDIF
ENDIF
ENDIF
#endif
// Wait for all assets to load.
IF NOT QUB3D_HAVE_REQUESTED_ASSETS_LOADED()
CDEBUG1LN(DEBUG_MINIGAME, sPrefixDebugQub3d, "QUB3D_HAVE_REQUESTED_ASSETS_LOADED - Returning FALSE")
RELOOP
ENDIF
IF HAS_NETWORK_TIME_STARTED()
ARCADE_GAMES_LEADERBOARD_LOAD(CASINO_ARCADE_GAME_QUB3D)
ARCADE_GAMES_LEADERBOARD_PROCESS_EVENTS()
ENDIF
ARCADE_GAMES_HELP_TEXT_PRE_UPDATE()
ARCADE_CABINET_COMMON_EVERY_FRAME_PROCESSING(QUB3D_HAVE_REQUESTED_ASSETS_LOADED())
IF current_mission_stage != PIXTRO_SETUP
ARCADE_GAMES_POSTFX_DRAW()
ENDIF
// main mission loop goes here
SWITCH current_mission_stage
CASE PIXTRO_SETUP
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), rgbaBlackOut)
DG_START_MOVIE(puzzleIDPixtroIntro,"_Pixtro_Intro_80s_2")
current_mission_stage = PIXTRO_LOGO
BREAK
CASE PIXTRO_LOGO
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), rgbaBlackOut)
BOOL bContinue
bContinue = DG_DRAW_MOVIE(puzzleIDPixtroIntro,
1.0 * GET_ASPECT_RATIO_MODIFIER_FROM_ASPECT_RATIO(), 1.0)
IF bContinue
OR QUB3d_IS_MENU_ACCEPT_BUTTON_JUST_PRESSED()
// Intialise Intro components
QUB3D_CLEAN_UP_MOVIE(puzzleIDPixtroIntro)
current_mission_stage = WAITING_TO_START_STAGE
ENDIF
BREAK
// waiting to start the mission
CASE WAITING_TO_START_STAGE
QUB3D_SETUP_VIEW()
IF DOES_ENTITY_EXIST(grid_object)
SETUP_THE_ANIM_CAM(game_grid_pos, game_grid_heading)
ENDIF
/// initialise the grid
ARCADE_GAMES_POSTFX_INIT(CASINO_ARCADE_GAME_QUB3D)
ARCADE_GAMES_SOUND_INIT(CASINO_ARCADE_GAME_QUB3D)
INITIALISE_THE_GRID()
BREAK
CASE STARTING_NEW_GAME
IF NOT DOES_ENTITY_EXIST(grid_box[max_row][max_col].box_object)
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), rgbaBlackOut)
ENDIF
INITIALISE_THE_GRID()
IF GET_CAM_ANIM_CURRENT_PHASE(anim_cam) <= 0.2
SET_CAM_ACTIVE_WITH_INTERP(game_cam, anim_cam, 2000, GRAPH_TYPE_VERY_SLOW_IN_VERY_SLOW_OUT)
ELSE
SET_CAM_ACTIVE(game_cam, TRUE)
ENDIF
SET_CAM_ACTIVE(anim_cam, FALSE)
BREAK
/// controller for the game
CASE GAME_IN_PROGRESS
MAIN_GAME_CONTROLLER()
BREAK
CASE HI_SCORE_ENTRY
// Exit if account is not permitted.
IF NOT IS_ACCOUNT_OVER_17_FOR_UGC()
RESTORE_TO_FRONT_END_STATUS()
BREAK
ENDIF
HIGH_SCORE_TABLE_NEW()
BREAK
CASE HI_SCORE_DISPLAY
IF NOT IS_ACCOUNT_OVER_17_FOR_UGC()
RESTORE_TO_FRONT_END_STATUS()
BREAK
ENDIF
IF HAS_STREAMED_TEXTURE_DICT_LOADED(high_score_textures)
// Draw darkened background
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2.0, cfBASE_SCREEN_HEIGHT/2.0), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), rgbaDarkSeeThrough)
ARCADE_GAMES_LEADERBOARD_DRAW(FALSE, FALSE)
ENDIF
IF Qub3D_IS_MENU_ACCEPT_BUTTON_JUST_PRESSED()
RESTORE_TO_FRONT_END_STATUS()
ENDIF
BREAK
DEFAULT
BREAK
ENDSWITCH
PUZZLE_PROCESS_PLAYER_PED_ANIMS()
IF HAS_STREAMED_TEXTURE_DICT_LOADED(puzzle_textures)
ARCADE_DRAW_PIXELSPACE_SPRITE(puzzle_textures, "Facade", INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2.0, cfBASE_SCREEN_HEIGHT/2.0), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), 0.0, rgbaWhiteOut)
ENDIF
// Add to the run timer at the end of the frame
fRunTimer += (0+@1000)
ENDWHILE
ENDSCRIPT