//╒═════════════════════════════════════════════════════════════════════════════╕ //│ Author: Ben Rollinson Date: 10/04/13 │ //╞═════════════════════════════════════════════════════════════════════════════╡ //│ │ //│ Lester Handler │ //│ │ //│ Manages Lester when he hangs around on his laptop after missions. │ //│ │ //╘═════════════════════════════════════════════════════════════════════════════╛ //Compile out Title Update changes to header functions. //Must be before includes. //CONST_INT USE_TU_CHANGES 0 // Removed by Kenneth R. USING "globals.sch" USING "rage_builtins.sch" USING "dialogue_public.sch" USING "random_events_public.sch" USING "brains.sch" CONST_INT BIT_LESTER_OWNED 0 CONST_INT BIT_PLAYER_LEFT_AREA 1 PED_INDEX pedLester OBJECT_INDEX objLesterStick OBJECT_INDEX objLaptop SEQUENCE_INDEX seqLesterUseLaptop REL_GROUP_HASH rghLester structPedsForConversation sPedForConversation TWEAK_FLOAT f_Hacking_Render_Target_x 0.080 TWEAK_FLOAT f_Hacking_Render_Target_y 0.170 TWEAK_FLOAT f_Hacking_Render_Target_width 0.270 TWEAK_FLOAT f_Hacking_Render_Target_height 0.450 //WIDGET_GROUP_ID widget_debug INT iState = 0 INT iLesterChatTimer = 0 INT rt_laptop SCALEFORM_INDEX sflaptop // release the rendertarget for the LAPTOP PROC RELEASE_LAPTOP_RENDERTARGET() IF IS_NAMED_RENDERTARGET_REGISTERED("tvscreen") RELEASE_NAMED_RENDERTARGET("tvscreen") ENDIF ENDPROC PROC RELEASE_FAKE_LAPTOP_MOVIE() RELEASE_LAPTOP_RENDERTARGET() SET_SCALEFORM_MOVIE_AS_NO_LONGER_NEEDED(sflaptop) ENDPROC PROC Cleanup_Handler() CPRINTLN(DEBUG_HEIST, " Handler cleaning up Lester.") SET_PED_AS_NO_LONGER_NEEDED(pedLester) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_CS_WALKING_STICK) SET_OBJECT_AS_NO_LONGER_NEEDED(objLesterStick) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_CS_WALKING_STICK) SET_OBJECT_AS_NO_LONGER_NEEDED(objLaptop) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_LAPTOP_LESTER2) SET_SCRIPT_AS_NO_LONGER_NEEDED("re_lured") REMOVE_ANIM_DICT("MISSHEIST_JEWEL@HACKING") REMOVE_MODEL_HIDE(<<707.3041, -967.6456, 30.3760>>, 1.00, PROP_LAPTOP_LESTER2, FALSE) REMOVE_RELATIONSHIP_GROUP(rghLester) RELEASE_FAKE_LAPTOP_MOVIE() CPRINTLN(DEBUG_HEIST, " Handler terminated.") TERMINATE_THIS_THREAD() ENDPROC // request the fake LAPTOP movie FUNC BOOL HAVE_LAPTOP_ASSETS_LOADED() sflaptop = REQUEST_SCALEFORM_MOVIE("JHPB_02_Laptop") IF HAS_SCALEFORM_MOVIE_LOADED(sflaptop) RETURN TRUE ENDIF RETURN FALSE ENDFUNC // draw fake LAPTOP PROC DRAW_FAKE_LAPTOP_SCREEN() if HAVE_LAPTOP_ASSETS_LOADED() IF DOES_ENTITY_EXIST(objlaptop) SET_TEXT_RENDER_ID(rt_laptop) DRAW_SCALEFORM_MOVIE(sflaptop, f_Hacking_Render_Target_x, f_Hacking_Render_Target_y,f_Hacking_Render_Target_width,f_Hacking_Render_Target_height, 255, 255, 255, 255) SET_TEXT_RENDER_ID(GET_DEFAULT_SCRIPT_RENDERTARGET_RENDER_ID()) ENDIF endif ENDPROC SCRIPT(StructLesterHandover sLesterHandover) CPRINTLN(DEBUG_HEIST, " Lester handler started.") IF HAS_FORCE_CLEANUP_OCCURRED(DEFAULT_FORCE_CLEANUP_FLAGS|FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_DEBUG_MENU|FORCE_CLEANUP_FLAG_REPEAT_PLAY) CPRINTLN(DEBUG_HEIST, " Handler was forced to clean up.") Cleanup_Handler() ENDIF IF IS_REPEAT_PLAY_ACTIVE() CPRINTLN(DEBUG_HEIST, " Cleaning up as a repeat play is running.") Cleanup_Handler() ENDIF pedLester = sLesterHandover.pedHandover //Load handler assets. CPRINTLN(DEBUG_HEIST, " Starting assets loading...") REQUEST_ANIM_DICT("MISSHEIST_JEWEL@HACKING") REQUEST_MODEL(PROP_CS_WALKING_STICK) REQUEST_MODEL(PROP_LAPTOP_LESTER2) WHILE NOT HAS_ANIM_DICT_LOADED("MISSHEIST_JEWEL@HACKING") OR NOT HAS_MODEL_LOADED(PROP_CS_WALKING_STICK) OR NOT HAS_MODEL_LOADED(PROP_LAPTOP_LESTER2) WAIT(0) ENDWHILE //--------------- Setup the render target for the screen --------------------- IF NOT IS_NAMED_RENDERTARGET_REGISTERED("tvscreen") REGISTER_NAMED_RENDERTARGET("tvscreen") ENDIF IF NOT IS_NAMED_RENDERTARGET_LINKED(PROP_LAPTOP_LESTER2) LINK_NAMED_RENDERTARGET(PROP_LAPTOP_LESTER2) ENDIF rt_laptop = GET_NAMED_RENDERTARGET_RENDER_ID("tvscreen") CPRINTLN(DEBUG_HEIST, " ...Assets loaded.") //#if IS_DEBUG_BUILD // widget_debug = START_WIDGET_GROUP("LESTER-HANDLER") // ADD_WIDGET_FLOAT_SLIDER("PosX", f_Hacking_Render_Target_x, -1.0, 1.0, 0.01) // ADD_WIDGET_FLOAT_SLIDER("PosY", f_Hacking_Render_Target_y, -1.0, 1.0, 0.01) // ADD_WIDGET_FLOAT_SLIDER("Width", f_Hacking_Render_Target_width, -1.0, 1.0, 0.01) // ADD_WIDGET_FLOAT_SLIDER("Height", f_Hacking_Render_Target_height, -1.0, 1.0, 0.01) // STOP_WIDGET_GROUP() // SET_LOCATES_HEADER_WIDGET_GROUP(widget_debug) //#endif WHILE NOT IS_BIT_SET(iState, BIT_PLAYER_LEFT_AREA) //Wait for global Lester ped to exist and grab ownership of it. IF NOT IS_BIT_SET(iState, BIT_LESTER_OWNED) IF DOES_ENTITY_EXIST(pedLester) IF NOT IS_PED_INJURED(pedLester) //Take ownership of Lester. SET_ENTITY_AS_MISSION_ENTITY(pedLester, FALSE, TRUE) CPRINTLN(DEBUG_HEIST, " Handler took ownership of global Lester ped index.") //Configure Lester to be as non interactable as possible. ADD_RELATIONSHIP_GROUP("Lester Group", rghLester) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, rghLester, RELGROUPHASH_PLAYER) SET_RELATIONSHIP_BETWEEN_GROUPS(ACQUAINTANCE_TYPE_PED_LIKE, RELGROUPHASH_PLAYER, rghLester) SET_PED_RELATIONSHIP_GROUP_HASH(pedLester, rghLester) SET_PED_DIES_WHEN_INJURED(pedLester, FALSE) SET_PED_CAN_BE_TARGETTED(pedLester, FALSE) SET_PED_SUFFERS_CRITICAL_HITS(pedLester, FALSE) SET_PED_CAN_EVASIVE_DIVE(pedLester, FALSE) SET_ENTITY_IS_TARGET_PRIORITY(pedLester, FALSE) SET_PED_CAN_RAGDOLL(pedLester, FALSE) SET_PED_ID_RANGE(pedLester, 250.00) SET_PED_TARGET_LOSS_RESPONSE(pedLester, TLR_NEVER_LOSE_TARGET) SET_ENTITY_IS_TARGET_PRIORITY(pedLester, FALSE) SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(pedLester, TRUE) SET_PED_CONFIG_FLAG(pedLester, PCF_KeepRelationshipGroupAfterCleanUp, TRUE) SET_PED_CONFIG_FLAG(pedLester, PCF_WillFlyThroughWindscreen, FALSE) SET_PED_CONFIG_FLAG(pedLester, PCF_DisableExplosionReactions, TRUE) SET_PED_CONFIG_FLAG(pedLester, PCF_RunFromFiresAndExplosions, FALSE) SET_PED_CONFIG_FLAG(pedLester, PCF_OnlyAttackLawIfPlayerIsWanted, TRUE) SET_PED_CONFIG_FLAG(pedLester, PCF_CannotBeTargeted, TRUE) SET_ENTITY_PROOFS(pedLester, TRUE, TRUE, TRUE, TRUE, TRUE) //Set Lester to use his laptop. VECTOR vLesterPos = << 707.320, -966.830, 30.413 >> VECTOR vLesterRot = << 0.000, 0.000, -171.500 >> OPEN_SEQUENCE_TASK(seqLesterUseLaptop) TASK_PLAY_ANIM_ADVANCED(NULL, "MISSHEIST_JEWEL@HACKING", "HACK_INTRO", vLesterPos, vLesterRot, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_NOT_INTERRUPTABLE|AF_USE_KINEMATIC_PHYSICS) TASK_PLAY_ANIM_ADVANCED(NULL, "MISSHEIST_JEWEL@HACKING", "HACK_LOOP", vLesterPos, vLesterRot, NORMAL_BLEND_IN, NORMAL_BLEND_OUT, -1, AF_LOOPING|AF_NOT_INTERRUPTABLE|AF_USE_KINEMATIC_PHYSICS) CLOSE_SEQUENCE_TASK(seqLesterUseLaptop) TASK_PERFORM_SEQUENCE(pedLester, seqLesterUseLaptop) FORCE_PED_AI_AND_ANIMATION_UPDATE(pedLester) FREEZE_ENTITY_POSITION(pedLester, TRUE) ADD_PED_FOR_DIALOGUE(sPedForConversation, 3, pedLester, "LESTER") CPRINTLN(DEBUG_HEIST, " Lester state configured.") //Create Lester's stick. objLesterStick = CREATE_OBJECT(PROP_CS_WALKING_STICK, <<706.987366,-967.094543,30.400000>>, FALSE, FALSE, FALSE) SET_ENTITY_COORDS (objLesterStick, <<706.987366,-967.094543,30.400000>>) SET_ENTITY_ROTATION (objLesterStick, <<90.00, 0.00, 160.00>>) SET_ENTITY_INVINCIBLE(objLesterStick, TRUE) SET_ENTITY_PROOFS(objLesterStick, TRUE, TRUE, TRUE, TRUE, TRUE) FREEZE_ENTITY_POSITION(objLesterStick, TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_CS_WALKING_STICK) CPRINTLN(DEBUG_HEIST, " Walking stick created.") //Create dummy laptop and proof it. CREATE_MODEL_HIDE(<<707.3041, -967.6456, 30.3760>>, 1.00, PROP_LAPTOP_01A, FALSE)/// objLaptop = CREATE_OBJECT(PROP_LAPTOP_LESTER2, <<707.3041, -967.6456, 30.3760>>) SET_ENTITY_HEADING(objLaptop, 183.14) FREEZE_ENTITY_POSITION(objLaptop, TRUE) SET_ENTITY_INVINCIBLE(objLaptop, TRUE) SET_ENTITY_PROOFS(objLaptop, TRUE, TRUE, TRUE, TRUE, TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_LAPTOP_LESTER2) CPRINTLN(DEBUG_HEIST, "Lester's dummy laptop created.") SET_BIT(iState, BIT_LESTER_OWNED) ENDIF ENDIF //Lester owned. Trigger dialogue and wait for cleanup conditions. ELIF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) IF NOT IS_ENTITY_DEAD(pedLester) FLOAT fDistanceSquaredFromLester = VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), GET_ENTITY_COORDS(pedLester)) //CPRINTLN(DEBUG_HEIST, " Distance from Lester is ", fDistanceSquaredFromLester) //Play dialogue every 20 seconds if Michael gets close to Lester. IF GET_CURRENT_PLAYER_PED_ENUM() = CHAR_MICHAEL IF fDistanceSquaredFromLester < 4 IF GET_GAME_TIMER() > iLesterChatTimer IF NOT IS_ANY_CONVERSATION_ONGOING_OR_QUEUED() IF CREATE_CONVERSATION(sPedForConversation, "JHFAUD", "JHF_LEAVE", CONV_PRIORITY_AMBIENT_MEDIUM) CPRINTLN(DEBUG_HEIST, " Michael triggered Lester dialogue.") iLesterChatTimer = GET_GAME_TIMER() + 25000 ENDIF ENDIF ENDIF ENDIF ENDIF //Check for player leaving area so we can clean up. IF g_eLastMissionPassed = SP_HEIST_JEWELRY_1 IF NOT g_bForceNextLuredEvent = TRUE AND IS_ENTITY_IN_ANGLED_AREA(PLAYER_PED_ID(), <<718.074890,-976.047180,22.914824>>, <<718.059265,-979.454956,27.119097>>, 5.750000) //unlock lured SET_RANDOM_EVENT_AVAILABLE(RE_LURED, TRUE) g_iLastRandomEventLaunch = 0 g_bForceNextLuredEvent = TRUE //Reactivate the worldpoint //this needs to be set to use REACTIVATE_NAMED_WORLD_BRAINS_WAITING_TILL_OUT_OF_RANGE() in v341 REACTIVATE_ALL_WORLD_BRAINS_THAT_ARE_WAITING_TILL_OUT_OF_RANGE() ENDIF ENDIF DRAW_FAKE_LAPTOP_SCREEN() IF fDistanceSquaredFromLester > 2500 CPRINTLN(DEBUG_HEIST, " The player has left the area.") SET_BIT(iState, BIT_PLAYER_LEFT_AREA) ENDIF ENDIF ENDIF WAIT(0) ENDWHILE Cleanup_Handler() ENDSCRIPT